Commit 5d2f4730 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tty/serial updates from Greg KH:
 "Here are some small updates for tty/serial drivers for 6.18-rc1.

  Not many changes overall, just the usual:

   - abi cleanups and reworking of the tty functions by Jiri by adding
     console lock guard logic

   - 8250_platform driver updates

   - qcom-geni driver updates

   - other minor serial driver updates

   - some more vt escape codes added

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (43 commits)
  tty: serial: fix help message for SERIAL_CPM
  serial: 8250: omap: Support wakeup pinctrl state on suspend
  dt-bindings: serial: 8250_omap: Add wakeup pinctrl state
  serial: max310x: improve interrupt handling
  vt: move vc_saved_screen to within tty allocated judgment
  Revert "m68k: make HPDCA and HPAPCI bools"
  tty: remove redundant condition checks
  tty/vt: Add missing return value for VT_RESIZE in vt_ioctl()
  vt: remove redundant check on vc_mode in con_font_set()
  serial: qcom-geni: Add DFS clock mode support to GENI UART driver
  m68k: make HPDCA and HPAPCI bools
  tty: n_gsm: Don't block input queue by waiting MSC
  serial: qcom-geni: Fix off-by-one error in ida_alloc_range()
  serdev: Drop dev_pm_domain_detach() call
  serial: sc16is7xx: drop redundant conversion to bool
  vt: add support for smput/rmput escape codes
  serial: stm32: allow selecting console when the driver is module
  serial: 8250_core: fix coding style issue
  tty: serial: Modify the use of dev_err_probe()
  s390/char/con3270: use tty_port_tty guard()
  ...
parents cc07b0a3 f4abab35
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -71,6 +71,22 @@ properties:
  overrun-throttle-ms: true
  wakeup-source: true

  pinctrl-0:
    description: Default pinctrl state

  pinctrl-1:
    description: Wakeup pinctrl state

  pinctrl-names:
    description:
      When present should contain at least "default" describing the default pin
      states. The second state called "wakeup" describes the pins in their
      wakeup configuration required to exit sleep states.
    minItems: 1
    items:
      - const: default
      - const: wakeup

required:
  - compatible
  - reg
+32 −0
Original line number Diff line number Diff line
@@ -221,3 +221,35 @@ static int __init sgi_ds1286_devinit(void)
}

device_initcall(sgi_ds1286_devinit);

#define SGI_ZILOG_BASE	(HPC3_CHIP0_BASE + \
			 offsetof(struct hpc3_regs, pbus_extregs[6]) + \
			 offsetof(struct sgioc_regs, uart))

static struct resource sgi_zilog_resources[] = {
	{
		.start	= SGI_ZILOG_BASE,
		.end	= SGI_ZILOG_BASE + 15,
		.flags	= IORESOURCE_MEM
	},
	{
		.start	= SGI_SERIAL_IRQ,
		.end	= SGI_SERIAL_IRQ,
		.flags	= IORESOURCE_IRQ
	}
};

static struct platform_device zilog_device = {
	.name		= "ip22zilog",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(sgi_zilog_resources),
	.resource	= sgi_zilog_resources,
};


static int __init sgi_zilog_devinit(void)
{
	return platform_device_register(&zilog_device);
}

device_initcall(sgi_zilog_devinit);
+8 −10
Original line number Diff line number Diff line
@@ -970,8 +970,6 @@ static void tty3270_resize(struct raw3270_view *view,
	char **old_rcl_lines, **new_rcl_lines;
	char *old_prompt, *new_prompt;
	char *old_input, *new_input;
	struct tty_struct *tty;
	struct winsize ws;
	size_t prompt_sz;
	int new_allocated, old_allocated = tp->allocated_lines;

@@ -1023,14 +1021,14 @@ static void tty3270_resize(struct raw3270_view *view,
	kfree(old_prompt);
	tty3270_free_recall(old_rcl_lines);
	tty3270_set_timer(tp, 1);
	/* Informat tty layer about new size */
	tty = tty_port_tty_get(&tp->port);
	if (!tty)
		return;
	ws.ws_row = tty3270_tty_rows(tp);
	ws.ws_col = tp->view.cols;
	tty_do_resize(tty, &ws);
	tty_kref_put(tty);
	/* Inform the tty layer about new size */
	scoped_guard(tty_port_tty, &tp->port) {
		struct winsize ws = {
			.ws_row = tty3270_tty_rows(tp),
			.ws_col = tp->view.cols,
		};
		tty_do_resize(scoped_tty(), &ws);
	}
	return;
out_screen:
	tty3270_free_screen(screen, new_rows);
+1 −1
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ static void hvc_console_print(struct console *co, const char *b,
					hvc_console_flush(cons_ops[index],
						      vtermnos[index]);
				}
			} else if (r > 0) {
			} else {
				i -= r;
				if (i > 0)
					memmove(c, c+r, i);
+103 −156
Original line number Diff line number Diff line
@@ -442,11 +442,8 @@ static void __mxser_start_tx(struct mxser_port *info)

static void mxser_start_tx(struct mxser_port *info)
{
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	guard(spinlock_irqsave)(&info->slock);
	__mxser_start_tx(info);
	spin_unlock_irqrestore(&info->slock, flags);
}

static void __mxser_stop_tx(struct mxser_port *info)
@@ -465,17 +462,15 @@ static bool mxser_carrier_raised(struct tty_port *port)
static void mxser_dtr_rts(struct tty_port *port, bool active)
{
	struct mxser_port *mp = container_of(port, struct mxser_port, port);
	unsigned long flags;
	u8 mcr;

	spin_lock_irqsave(&mp->slock, flags);
	guard(spinlock_irqsave)(&mp->slock);
	mcr = inb(mp->ioaddr + UART_MCR);
	if (active)
		mcr |= UART_MCR_DTR | UART_MCR_RTS;
	else
		mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
	outb(mcr, mp->ioaddr + UART_MCR);
	spin_unlock_irqrestore(&mp->slock, flags);
}

static int mxser_set_baud(struct tty_struct *tty, speed_t newspd)
@@ -828,10 +823,8 @@ static void mxser_stop_rx(struct mxser_port *info)
static void mxser_shutdown_port(struct tty_port *port)
{
	struct mxser_port *info = container_of(port, struct mxser_port, port);
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);

	scoped_guard(spinlock_irqsave, &info->slock) {
		mxser_stop_rx(info);

		/*
@@ -849,11 +842,9 @@ static void mxser_shutdown_port(struct tty_port *port)
		/* read data port to reset things */
		(void)inb(info->ioaddr + UART_RX);


		if (info->board->must_hwid)
			mxser_must_no_sw_flow_control(info->ioaddr);

	spin_unlock_irqrestore(&info->slock, flags);
	}

	/* make sure ISR is not running while we free the buffer */
	synchronize_irq(info->board->irq);
@@ -880,15 +871,13 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
static void mxser_flush_buffer(struct tty_struct *tty)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	scoped_guard(spinlock_irqsave, &info->slock) {
		kfifo_reset(&info->port.xmit_fifo);

		outb(info->FCR | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
		     info->ioaddr + UART_FCR);

	spin_unlock_irqrestore(&info->slock, flags);
	}

	tty_wakeup(tty);
}
@@ -901,14 +890,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
static ssize_t mxser_write(struct tty_struct *tty, const u8 *buf, size_t count)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;
	size_t written;
	bool is_empty;

	spin_lock_irqsave(&info->slock, flags);
	scoped_guard(spinlock_irqsave, &info->slock) {
		written = kfifo_in(&info->port.xmit_fifo, buf, count);
		is_empty = kfifo_is_empty(&info->port.xmit_fifo);
	spin_unlock_irqrestore(&info->slock, flags);
	}

	if (!is_empty && !tty->flow.stopped)
		if (!tty->hw_stopped || mxser_16550A_or_MUST(info))
@@ -920,14 +908,9 @@ static ssize_t mxser_write(struct tty_struct *tty, const u8 *buf, size_t count)
static int mxser_put_char(struct tty_struct *tty, u8 ch)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&info->slock, flags);
	ret = kfifo_put(&info->port.xmit_fifo, ch);
	spin_unlock_irqrestore(&info->slock, flags);

	return ret;
	guard(spinlock_irqsave)(&info->slock);
	return kfifo_put(&info->port.xmit_fifo, ch);
}


@@ -968,7 +951,7 @@ static int mxser_get_serial_info(struct tty_struct *tty,
	struct tty_port *port = &info->port;
	unsigned int closing_wait, close_delay;

	mutex_lock(&port->mutex);
	guard(mutex)(&port->mutex);

	close_delay = jiffies_to_msecs(info->port.close_delay) / 10;
	closing_wait = info->port.closing_wait;
@@ -984,7 +967,7 @@ static int mxser_get_serial_info(struct tty_struct *tty,
	ss->close_delay = close_delay;
	ss->closing_wait = closing_wait;
	ss->custom_divisor = MXSER_CUSTOM_DIVISOR;
	mutex_unlock(&port->mutex);

	return 0;
}

@@ -994,20 +977,15 @@ static int mxser_set_serial_info(struct tty_struct *tty,
	struct mxser_port *info = tty->driver_data;
	struct tty_port *port = &info->port;
	speed_t baud;
	unsigned long sl_flags;
	unsigned int old_speed, close_delay, closing_wait;
	int retval = 0;

	if (tty_io_error(tty))
		return -EIO;

	mutex_lock(&port->mutex);
	guard(mutex)(&port->mutex);

	if (ss->irq != info->board->irq ||
			ss->port != info->ioaddr) {
		mutex_unlock(&port->mutex);
	if (ss->irq != info->board->irq || ss->port != info->ioaddr)
		return -EINVAL;
	}

	old_speed = port->flags & ASYNC_SPD_MASK;

@@ -1020,10 +998,9 @@ static int mxser_set_serial_info(struct tty_struct *tty,
		if ((ss->baud_base != MXSER_BAUD_BASE) ||
				(close_delay != port->close_delay) ||
				(closing_wait != port->closing_wait) ||
				((ss->flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) {
			mutex_unlock(&port->mutex);
				((ss->flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK)))
			return -EPERM;
		}

		port->flags = (port->flags & ~ASYNC_USR_MASK) |
				(ss->flags & ASYNC_USR_MASK);
	} else {
@@ -1039,10 +1016,9 @@ static int mxser_set_serial_info(struct tty_struct *tty,
				(ss->baud_base != MXSER_BAUD_BASE ||
				ss->custom_divisor !=
				MXSER_CUSTOM_DIVISOR)) {
			if (ss->custom_divisor == 0) {
				mutex_unlock(&port->mutex);
			if (ss->custom_divisor == 0)
				return -EINVAL;
			}

			baud = ss->baud_base / ss->custom_divisor;
			tty_encode_baud_rate(tty, baud, baud);
		}
@@ -1054,16 +1030,17 @@ static int mxser_set_serial_info(struct tty_struct *tty,

	if (tty_port_initialized(port)) {
		if (old_speed != (port->flags & ASYNC_SPD_MASK)) {
			spin_lock_irqsave(&info->slock, sl_flags);
			guard(spinlock_irqsave)(&info->slock);
			mxser_change_speed(tty, NULL);
			spin_unlock_irqrestore(&info->slock, sl_flags);
		}
	} else {
		retval = mxser_activate(port, tty);

		return 0;
	}

	int retval = mxser_activate(port, tty);
	if (retval == 0)
		tty_port_set_initialized(port, true);
	}
	mutex_unlock(&port->mutex);

	return retval;
}

@@ -1080,13 +1057,11 @@ static int mxser_set_serial_info(struct tty_struct *tty,
static int mxser_get_lsr_info(struct mxser_port *info,
		unsigned int __user *value)
{
	unsigned char status;
	unsigned int result;
	unsigned long flags;
	u8 status;

	spin_lock_irqsave(&info->slock, flags);
	scoped_guard(spinlock_irqsave, &info->slock)
		status = inb(info->ioaddr + UART_LSR);
	spin_unlock_irqrestore(&info->slock, flags);
	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
	return put_user(result, value);
}
@@ -1095,16 +1070,15 @@ static int mxser_tiocmget(struct tty_struct *tty)
{
	struct mxser_port *info = tty->driver_data;
	unsigned char control;
	unsigned long flags;
	u8 msr;

	if (tty_io_error(tty))
		return -EIO;

	spin_lock_irqsave(&info->slock, flags);
	scoped_guard(spinlock_irqsave, &info->slock) {
		control = info->MCR;
		msr = mxser_check_modem_status(tty, info);
	spin_unlock_irqrestore(&info->slock, flags);
	}

	return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
		    ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
@@ -1118,12 +1092,11 @@ static int mxser_tiocmset(struct tty_struct *tty,
		unsigned int set, unsigned int clear)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;

	if (tty_io_error(tty))
		return -EIO;

	spin_lock_irqsave(&info->slock, flags);
	guard(spinlock_irqsave)(&info->slock);

	if (set & TIOCM_RTS)
		info->MCR |= UART_MCR_RTS;
@@ -1136,7 +1109,7 @@ static int mxser_tiocmset(struct tty_struct *tty,
		info->MCR &= ~UART_MCR_DTR;

	outb(info->MCR, info->ioaddr + UART_MCR);
	spin_unlock_irqrestore(&info->slock, flags);

	return 0;
}

@@ -1144,12 +1117,11 @@ static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg,
		struct async_icount *cprev)
{
	struct async_icount cnow;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&info->slock, flags);
	cnow = info->icount;	/* atomic copy */
	spin_unlock_irqrestore(&info->slock, flags);
	/* atomic copy */
	scoped_guard(spinlock_irqsave, &info->slock)
		cnow = info->icount;

	ret =	((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
		((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
@@ -1179,19 +1151,17 @@ static int mxser_ioctl_op_mode(struct mxser_port *port, int index, bool set,
		if (opmode & ~OP_MODE_MASK)
			return -EINVAL;

		spin_lock_irq(&port->slock);
		guard(spinlock_irq)(&port->slock);
		val = inb(port->opmode_ioaddr);
		val &= ~(OP_MODE_MASK << shiftbit);
		val |= (opmode << shiftbit);
		outb(val, port->opmode_ioaddr);
		spin_unlock_irq(&port->slock);

		return 0;
	}

	spin_lock_irq(&port->slock);
	scoped_guard(spinlock_irq, &port->slock)
		opmode = inb(port->opmode_ioaddr) >> shiftbit;
	spin_unlock_irq(&port->slock);

	return put_user(opmode & OP_MODE_MASK, u_opmode);
}
@@ -1201,7 +1171,6 @@ static int mxser_ioctl(struct tty_struct *tty,
{
	struct mxser_port *info = tty->driver_data;
	struct async_icount cnow;
	unsigned long flags;
	void __user *argp = (void __user *)arg;

	if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE)
@@ -1221,9 +1190,9 @@ static int mxser_ioctl(struct tty_struct *tty,
		 * Caller should use TIOCGICOUNT to see which one it was
		 */
	case TIOCMIWAIT:
		spin_lock_irqsave(&info->slock, flags);
		cnow = info->icount;	/* note the counters on entry */
		spin_unlock_irqrestore(&info->slock, flags);
		/* note the counters on entry */
		scoped_guard(spinlock_irqsave, &info->slock)
			cnow = info->icount;

		return wait_event_interruptible(info->port.delta_msr_wait,
				mxser_cflags_changed(info, arg, &cnow));
@@ -1246,11 +1215,9 @@ static int mxser_get_icount(struct tty_struct *tty,
{
	struct mxser_port *info = tty->driver_data;
	struct async_icount cnow;
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	scoped_guard(spinlock_irqsave, &info->slock)
		cnow = info->icount;
	spin_unlock_irqrestore(&info->slock, flags);

	icount->frame = cnow.frame;
	icount->brk = cnow.brk;
@@ -1328,34 +1295,28 @@ static void mxser_unthrottle(struct tty_struct *tty)
static void mxser_stop(struct tty_struct *tty)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	guard(spinlock_irqsave)(&info->slock);
	if (info->IER & UART_IER_THRI)
		__mxser_stop_tx(info);
	spin_unlock_irqrestore(&info->slock, flags);
}

static void mxser_start(struct tty_struct *tty)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	guard(spinlock_irqsave)(&info->slock);
	if (!kfifo_is_empty(&info->port.xmit_fifo))
		__mxser_start_tx(info);
	spin_unlock_irqrestore(&info->slock, flags);
}

static void mxser_set_termios(struct tty_struct *tty,
			      const struct ktermios *old_termios)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	scoped_guard(spinlock_irqsave, &info->slock)
		mxser_change_speed(tty, old_termios);
	spin_unlock_irqrestore(&info->slock, flags);

	if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
		tty->hw_stopped = false;
@@ -1367,9 +1328,8 @@ static void mxser_set_termios(struct tty_struct *tty,
		tty->flow.stopped = 0;

		if (info->board->must_hwid) {
			spin_lock_irqsave(&info->slock, flags);
			guard(spinlock_irqsave)(&info->slock);
			mxser_must_set_rx_sw_flow_control(info->ioaddr, false);
			spin_unlock_irqrestore(&info->slock, flags);
		}

		mxser_start(tty);
@@ -1378,14 +1338,8 @@ static void mxser_set_termios(struct tty_struct *tty,

static bool mxser_tx_empty(struct mxser_port *info)
{
	unsigned long flags;
	u8 lsr;

	spin_lock_irqsave(&info->slock, flags);
	lsr = inb(info->ioaddr + UART_LSR);
	spin_unlock_irqrestore(&info->slock, flags);

	return !(lsr & UART_LSR_TEMT);
	guard(spinlock_irqsave)(&info->slock);
	return !(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT);
}

/*
@@ -1459,17 +1413,15 @@ static void mxser_hangup(struct tty_struct *tty)
static int mxser_rs_break(struct tty_struct *tty, int break_state)
{
	struct mxser_port *info = tty->driver_data;
	unsigned long flags;
	u8 lcr;

	spin_lock_irqsave(&info->slock, flags);
	guard(spinlock_irqsave)(&info->slock);
	lcr = inb(info->ioaddr + UART_LCR);
	if (break_state == -1)
		lcr |= UART_LCR_SBC;
	else
		lcr &= ~UART_LCR_SBC;
	outb(lcr, info->ioaddr + UART_LCR);
	spin_unlock_irqrestore(&info->slock, flags);

	return 0;
}
@@ -1600,25 +1552,16 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port

static bool mxser_port_isr(struct mxser_port *port)
{
	struct tty_struct *tty;
	u8 iir, status;
	bool error = false;

	iir = inb(port->ioaddr + UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return true;

	iir &= MOXA_MUST_IIR_MASK;
	tty = tty_port_tty_get(&port->port);
	if (!tty) {
		status = inb(port->ioaddr + UART_LSR);
		outb(port->FCR | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
				port->ioaddr + UART_FCR);
		inb(port->ioaddr + UART_MSR);

		error = true;
		goto put_tty;
	}
	scoped_guard(tty_port_tty, &port->port) {
		struct tty_struct *tty = scoped_tty();

		status = inb(port->ioaddr + UART_LSR);

@@ -1644,10 +1587,15 @@ static bool mxser_port_isr(struct mxser_port *port)
				mxser_transmit_chars(tty, port);
		}

put_tty:
	tty_kref_put(tty);
		return false;
	}

	return error;
	status = inb(port->ioaddr + UART_LSR);
	outb(port->FCR | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
			port->ioaddr + UART_FCR);
	inb(port->ioaddr + UART_MSR);

	return true;
}

/*
@@ -1676,12 +1624,11 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
			port = &brd->ports[i];

			int_cnt = 0;
			spin_lock(&port->slock);
			guard(spinlock)(&port->slock);
			do {
				if (mxser_port_isr(port))
					break;
			} while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
			spin_unlock(&port->slock);
		}
	}

Loading