TTY/Serial fixes for 4.0-rc3

Here are some tty and serial driver fixes for 4.0-rc3.
 
 Along with the atime fix that you know about, here are some other serial
 driver bugfixes as well.  Most notable is a wait_until_sent bugfix that
 was traced back to being around since before 2.6.12 that Johan has fixed
 up.
 
 All have been in linux-next successfully.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlT8RCYACgkQMUfUDdst+yk62QCgycxS4giC2hyRver3dyvaNR6g
 zYYAn2w0uRndW+AqP4Tls54isRz6owpF
 =gA2k
 -----END PGP SIGNATURE-----

Merge tag 'tty-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial fixes from Greg KH:
 "Here are some tty and serial driver fixes for 4.0-rc3.

  Along with the atime fix that you know about, here are some other
  serial driver bugfixes as well.  Most notable is a wait_until_sent
  bugfix that was traced back to being around since before 2.6.12 that
  Johan has fixed up.

  All have been in linux-next successfully"

* tag 'tty-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  TTY: fix tty_wait_until_sent maximum timeout
  TTY: fix tty_wait_until_sent on 64-bit machines
  USB: serial: fix infinite wait_until_sent timeout
  TTY: bfin_jtag_comm: remove incorrect wait_until_sent operation
  net: irda: fix wait_until_sent poll timeout
  serial: uapi: Declare all userspace-visible io types
  serial: core: Fix iotype userspace breakage
  serial: sprd: Fix missing spin_unlock in sprd_handle_irq()
  console: Fix console name size mismatch
  tty: fix up atime/mtime mess, take four
  serial: 8250_dw: Fix get_mctrl behaviour
  serial:8250:8250_pci: delete unneeded quirk entries
  serial:8250:8250_pci: fix redundant entry report for WCH_CH352_2S
  Change email address for 8250_pci
  serial: 8250: Revert "tty: serial: 8250_core: read only RX if there is something in the FIFO"
  Revert "tty/serial: of_serial: add DT alias ID handling"
This commit is contained in:
Linus Torvalds 2015-03-08 12:25:40 -07:00
commit bbbce516bb
15 changed files with 89 additions and 61 deletions

View file

@ -21,6 +21,18 @@ Optional properties:
- reg-io-width : the size (in bytes) of the IO accesses that should be
performed on the device. If this property is not present then single byte
accesses are used.
- dcd-override : Override the DCD modem status signal. This signal will always
be reported as active instead of being obtained from the modem status
register. Define this if your serial port does not use this pin.
- dsr-override : Override the DTS modem status signal. This signal will always
be reported as active instead of being obtained from the modem status
register. Define this if your serial port does not use this pin.
- cts-override : Override the CTS modem status signal. This signal will always
be reported as active instead of being obtained from the modem status
register. Define this if your serial port does not use this pin.
- ri-override : Override the RI modem status signal. This signal will always be
reported as inactive instead of being obtained from the modem status register.
Define this if your serial port does not use this pin.
Example:
@ -31,6 +43,10 @@ Example:
interrupts = <10>;
reg-shift = <2>;
reg-io-width = <4>;
dcd-override;
dsr-override;
cts-override;
ri-override;
};
Example with one clock:

View file

@ -210,18 +210,6 @@ bfin_jc_chars_in_buffer(struct tty_struct *tty)
return circ_cnt(&bfin_jc_write_buf);
}
static void
bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout)
{
unsigned long expire = jiffies + timeout;
while (!circ_empty(&bfin_jc_write_buf)) {
if (signal_pending(current))
break;
if (time_after(jiffies, expire))
break;
}
}
static const struct tty_operations bfin_jc_ops = {
.open = bfin_jc_open,
.close = bfin_jc_close,
@ -230,7 +218,6 @@ static const struct tty_operations bfin_jc_ops = {
.flush_chars = bfin_jc_flush_chars,
.write_room = bfin_jc_write_room,
.chars_in_buffer = bfin_jc_chars_in_buffer,
.wait_until_sent = bfin_jc_wait_until_sent,
};
static int __init bfin_jc_init(void)

View file

@ -2138,8 +2138,8 @@ int serial8250_do_startup(struct uart_port *port)
/*
* Clear the interrupt registers.
*/
if (serial_port_in(port, UART_LSR) & UART_LSR_DR)
serial_port_in(port, UART_RX);
serial_port_in(port, UART_LSR);
serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
@ -2300,8 +2300,8 @@ dont_test_tx_en:
* saved flags to avoid getting false values from polling
* routines or the previous session.
*/
if (serial_port_in(port, UART_LSR) & UART_LSR_DR)
serial_port_in(port, UART_RX);
serial_port_in(port, UART_LSR);
serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
up->lsr_saved_flags = 0;
@ -2394,8 +2394,7 @@ void serial8250_do_shutdown(struct uart_port *port)
* Read data port to reset things, and then unlink from
* the IRQ chain.
*/
if (serial_port_in(port, UART_LSR) & UART_LSR_DR)
serial_port_in(port, UART_RX);
serial_port_in(port, UART_RX);
serial8250_rpm_put(up);
del_timer_sync(&up->timer);

View file

@ -59,6 +59,8 @@ struct dw8250_data {
u8 usr_reg;
int last_mcr;
int line;
int msr_mask_on;
int msr_mask_off;
struct clk *clk;
struct clk *pclk;
struct reset_control *rst;
@ -81,6 +83,12 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
value &= ~UART_MSR_DCTS;
}
/* Override any modem control signals if needed */
if (offset == UART_MSR) {
value |= d->msr_mask_on;
value &= ~d->msr_mask_off;
}
return value;
}
@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p,
if (id >= 0)
p->line = id;
if (of_property_read_bool(np, "dcd-override")) {
/* Always report DCD as active */
data->msr_mask_on |= UART_MSR_DCD;
data->msr_mask_off |= UART_MSR_DDCD;
}
if (of_property_read_bool(np, "dsr-override")) {
/* Always report DSR as active */
data->msr_mask_on |= UART_MSR_DSR;
data->msr_mask_off |= UART_MSR_DDSR;
}
if (of_property_read_bool(np, "cts-override")) {
/* Always report DSR as active */
data->msr_mask_on |= UART_MSR_DSR;
data->msr_mask_off |= UART_MSR_DDSR;
}
if (of_property_read_bool(np, "ri-override")) {
/* Always report Ring indicator as inactive */
data->msr_mask_off |= UART_MSR_RI;
data->msr_mask_off |= UART_MSR_TERI;
}
/* clock got configured through clk api, all done */
if (p->uartclk)
return 0;

View file

@ -69,7 +69,7 @@ static void moan_device(const char *str, struct pci_dev *dev)
"Please send the output of lspci -vv, this\n"
"message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
"manufacturer and name of serial board or\n"
"modem board to rmk+serial@arm.linux.org.uk.\n",
"modem board to <linux-serial@vger.kernel.org>.\n",
pci_name(dev), str, dev->vendor, dev->device,
dev->subsystem_vendor, dev->subsystem_device);
}
@ -1987,13 +1987,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.setup = byt_serial_setup,
},
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_QRK_UART,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_default_setup,
},
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BSW_UART1,
@ -2199,13 +2192,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
/*
* PLX
*/
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9030,
.subvendor = PCI_SUBVENDOR_ID_PERLE,
.subdevice = PCI_ANY_ID,
.setup = pci_default_setup,
},
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9050,
@ -5415,10 +5401,6 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0, pbn_b0_bt_2_115200 },
{ PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S,
PCI_ANY_ID, PCI_ANY_ID,
0, 0, pbn_b0_bt_2_115200 },
{ PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S,
PCI_ANY_ID, PCI_ANY_ID,
0, 0, pbn_wch384_4 },

View file

@ -133,10 +133,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
if (of_find_property(np, "no-loopback-test", NULL))
port->flags |= UPF_SKIP_TEST;
ret = of_alias_get_id(np, "serial");
if (ret >= 0)
port->line = ret;
port->dev = &ofdev->dev;
switch (type) {

View file

@ -293,8 +293,10 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
ims = serial_in(port, SPRD_IMSR);
if (!ims)
if (!ims) {
spin_unlock(&port->lock);
return IRQ_NONE;
}
serial_out(port, SPRD_ICLR, ~0);

View file

@ -1028,8 +1028,8 @@ EXPORT_SYMBOL(start_tty);
/* We limit tty time update visibility to every 8 seconds or so. */
static void tty_update_time(struct timespec *time)
{
unsigned long sec = get_seconds() & ~7;
if ((long)(sec - time->tv_sec) > 0)
unsigned long sec = get_seconds();
if (abs(sec - time->tv_sec) & ~7)
time->tv_sec = sec;
}

View file

@ -217,11 +217,17 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
#endif
if (!timeout)
timeout = MAX_SCHEDULE_TIMEOUT;
if (wait_event_interruptible_timeout(tty->write_wait,
!tty_chars_in_buffer(tty), timeout) >= 0) {
if (tty->ops->wait_until_sent)
tty->ops->wait_until_sent(tty, timeout);
}
timeout = wait_event_interruptible_timeout(tty->write_wait,
!tty_chars_in_buffer(tty), timeout);
if (timeout <= 0)
return;
if (timeout == MAX_SCHEDULE_TIMEOUT)
timeout = 0;
if (tty->ops->wait_until_sent)
tty->ops->wait_until_sent(tty, timeout);
}
EXPORT_SYMBOL(tty_wait_until_sent);

View file

@ -258,7 +258,8 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
* character or at least one jiffy.
*/
period = max_t(unsigned long, (10 * HZ / bps), 1);
period = min_t(unsigned long, period, timeout);
if (timeout)
period = min_t(unsigned long, period, timeout);
dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n",
__func__, jiffies_to_msecs(timeout),
@ -268,7 +269,7 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
schedule_timeout_interruptible(period);
if (signal_pending(current))
break;
if (time_after(jiffies, expire))
if (timeout && time_after(jiffies, expire))
break;
}
}

View file

@ -143,13 +143,13 @@ struct uart_port {
unsigned char iotype; /* io access style */
unsigned char unused1;
#define UPIO_PORT (0) /* 8b I/O port access */
#define UPIO_HUB6 (1) /* Hub6 ISA card */
#define UPIO_MEM (2) /* 8b MMIO access */
#define UPIO_MEM32 (3) /* 32b little endian */
#define UPIO_MEM32BE (4) /* 32b big endian */
#define UPIO_AU (5) /* Au1x00 and RT288x type IO */
#define UPIO_TSI (6) /* Tsi108/109 type IO */
#define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */
#define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */
#define UPIO_MEM (SERIAL_IO_MEM) /* 8b MMIO access */
#define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */
#define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */
#define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */
#define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */

View file

@ -65,6 +65,10 @@ struct serial_struct {
#define SERIAL_IO_PORT 0
#define SERIAL_IO_HUB6 1
#define SERIAL_IO_MEM 2
#define SERIAL_IO_MEM32 3
#define SERIAL_IO_AU 4
#define SERIAL_IO_TSI 5
#define SERIAL_IO_MEM32BE 6
#define UART_CLEAR_FIFO 0x01
#define UART_USE_FIFO 0x02

View file

@ -3,7 +3,7 @@
struct console_cmdline
{
char name[8]; /* Name of the driver */
char name[16]; /* Name of the driver */
int index; /* Minor dev. to use */
char *options; /* Options for the driver */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE

View file

@ -2464,6 +2464,7 @@ void register_console(struct console *newcon)
for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&

View file

@ -798,7 +798,9 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
orig_jiffies = jiffies;
/* Set poll time to 200 ms */
poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200));
poll_time = msecs_to_jiffies(200);
if (timeout)
poll_time = min_t(unsigned long, timeout, poll_time);
spin_lock_irqsave(&self->spinlock, flags);
while (self->tx_skb && self->tx_skb->len) {