Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97d0c931 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tty/serial driver fixes from Greg KH:
 "Here are a few bug fixes for the tty core that resolve reported
  issues, and some serial driver fixes as well (including the
  much-reported imx driver problem)

  All of these have been in linux-next with no reported problems"

* tag 'tty-4.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  drivers/tty: require read access for controlling terminal
  serial: 8250: add uart_config entry for PORT_RT2880
  tty: fix data race on tty_buffer.commit
  tty: fix data race in tty_buffer_flush
  tty: fix data race in flush_to_ldisc
  tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c
  serial: atmel: fix error path of probe function
  tty: don't leak cdev in tty_cdev_add()
  Revert "serial: imx: remove unbalanced clk_prepare"
parents 91dbc047 0c556271
Loading
Loading
Loading
Loading
+5 −10
Original line number Diff line number Diff line
@@ -343,7 +343,6 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
		spin_lock_irqsave(&tty->ctrl_lock, flags);
		tty->ctrl_status |= TIOCPKT_FLUSHREAD;
		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
		if (waitqueue_active(&tty->link->read_wait))
		wake_up_interruptible(&tty->link->read_wait);
	}
}
@@ -1382,7 +1381,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
			put_tty_queue(c, ldata);
			smp_store_release(&ldata->canon_head, ldata->read_head);
			kill_fasync(&tty->fasync, SIGIO, POLL_IN);
			if (waitqueue_active(&tty->read_wait))
			wake_up_interruptible_poll(&tty->read_wait, POLLIN);
			return 0;
		}
@@ -1667,7 +1665,6 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,

	if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) {
		kill_fasync(&tty->fasync, SIGIO, POLL_IN);
		if (waitqueue_active(&tty->read_wait))
		wake_up_interruptible_poll(&tty->read_wait, POLLIN);
	}
}
@@ -1887,9 +1884,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
	}

	/* The termios change make the tty ready for I/O */
	if (waitqueue_active(&tty->write_wait))
	wake_up_interruptible(&tty->write_wait);
	if (waitqueue_active(&tty->read_wait))
	wake_up_interruptible(&tty->read_wait);
}

+8 −0
Original line number Diff line number Diff line
@@ -261,6 +261,14 @@ configured less than Maximum supported fifo bytes */
				  UART_FCR7_64BYTE,
		.flags		= UART_CAP_FIFO,
	},
	[PORT_RT2880] = {
		.name		= "Palmchip BK-3103",
		.fifo_size	= 16,
		.tx_loadsz	= 16,
		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
		.rxtrig_bytes	= {1, 4, 8, 14},
		.flags		= UART_CAP_FIFO,
	},
};

/* Uart divisor latch read */
+1 −1
Original line number Diff line number Diff line
@@ -2786,7 +2786,7 @@ static int atmel_serial_probe(struct platform_device *pdev)
	ret = atmel_init_gpios(port, &pdev->dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to initialize GPIOs.");
		goto err;
		goto err_clear_bit;
	}

	ret = atmel_init_port(port, pdev);
+14 −6
Original line number Diff line number Diff line
@@ -1631,12 +1631,12 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
	int locked = 1;
	int retval;

	retval = clk_prepare_enable(sport->clk_per);
	retval = clk_enable(sport->clk_per);
	if (retval)
		return;
	retval = clk_prepare_enable(sport->clk_ipg);
	retval = clk_enable(sport->clk_ipg);
	if (retval) {
		clk_disable_unprepare(sport->clk_per);
		clk_disable(sport->clk_per);
		return;
	}

@@ -1675,8 +1675,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
	if (locked)
		spin_unlock_irqrestore(&sport->port.lock, flags);

	clk_disable_unprepare(sport->clk_ipg);
	clk_disable_unprepare(sport->clk_per);
	clk_disable(sport->clk_ipg);
	clk_disable(sport->clk_per);
}

/*
@@ -1777,6 +1777,14 @@ imx_console_setup(struct console *co, char *options)

	retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);

	clk_disable(sport->clk_ipg);
	if (retval) {
		clk_unprepare(sport->clk_ipg);
		goto error_console;
	}

	retval = clk_prepare(sport->clk_per);
	if (retval)
		clk_disable_unprepare(sport->clk_ipg);

error_console:
+17 −5
Original line number Diff line number Diff line
@@ -242,7 +242,10 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
	atomic_inc(&buf->priority);

	mutex_lock(&buf->lock);
	while ((next = buf->head->next) != NULL) {
	/* paired w/ release in __tty_buffer_request_room; ensures there are
	 * no pending memory accesses to the freed buffer
	 */
	while ((next = smp_load_acquire(&buf->head->next)) != NULL) {
		tty_buffer_free(port, buf->head);
		buf->head = next;
	}
@@ -290,7 +293,10 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size,
		if (n != NULL) {
			n->flags = flags;
			buf->tail = n;
			b->commit = b->used;
			/* paired w/ acquire in flush_to_ldisc(); ensures
			 * flush_to_ldisc() sees buffer data.
			 */
			smp_store_release(&b->commit, b->used);
			/* paired w/ acquire in flush_to_ldisc(); ensures the
			 * latest commit value can be read before the head is
			 * advanced to the next buffer
@@ -393,7 +399,10 @@ void tty_schedule_flip(struct tty_port *port)
{
	struct tty_bufhead *buf = &port->buf;

	buf->tail->commit = buf->tail->used;
	/* paired w/ acquire in flush_to_ldisc(); ensures
	 * flush_to_ldisc() sees buffer data.
	 */
	smp_store_release(&buf->tail->commit, buf->tail->used);
	schedule_work(&buf->work);
}
EXPORT_SYMBOL(tty_schedule_flip);
@@ -467,7 +476,7 @@ static void flush_to_ldisc(struct work_struct *work)
	struct tty_struct *tty;
	struct tty_ldisc *disc;

	tty = port->itty;
	tty = READ_ONCE(port->itty);
	if (tty == NULL)
		return;

@@ -491,7 +500,10 @@ static void flush_to_ldisc(struct work_struct *work)
		 * is advancing to the next buffer
		 */
		next = smp_load_acquire(&head->next);
		count = head->commit - head->read;
		/* paired w/ release in __tty_buffer_request_room() or in
		 * tty_buffer_flush(); ensures we see the committed buffer data
		 */
		count = smp_load_acquire(&head->commit) - head->read;
		if (!count) {
			if (next == NULL) {
				check_other_closed(tty);
Loading