Commit bbbce516 authored by Linus Torvalds's avatar Linus Torvalds

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"
parents 47df986b c37bc682
...@@ -21,6 +21,18 @@ Optional properties: ...@@ -21,6 +21,18 @@ Optional properties:
- reg-io-width : the size (in bytes) of the IO accesses that should be - 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 performed on the device. If this property is not present then single byte
accesses are used. 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: Example:
...@@ -31,6 +43,10 @@ Example: ...@@ -31,6 +43,10 @@ Example:
interrupts = <10>; interrupts = <10>;
reg-shift = <2>; reg-shift = <2>;
reg-io-width = <4>; reg-io-width = <4>;
dcd-override;
dsr-override;
cts-override;
ri-override;
}; };
Example with one clock: Example with one clock:
......
...@@ -210,18 +210,6 @@ bfin_jc_chars_in_buffer(struct tty_struct *tty) ...@@ -210,18 +210,6 @@ bfin_jc_chars_in_buffer(struct tty_struct *tty)
return circ_cnt(&bfin_jc_write_buf); 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 = { static const struct tty_operations bfin_jc_ops = {
.open = bfin_jc_open, .open = bfin_jc_open,
.close = bfin_jc_close, .close = bfin_jc_close,
...@@ -230,7 +218,6 @@ static const struct tty_operations bfin_jc_ops = { ...@@ -230,7 +218,6 @@ static const struct tty_operations bfin_jc_ops = {
.flush_chars = bfin_jc_flush_chars, .flush_chars = bfin_jc_flush_chars,
.write_room = bfin_jc_write_room, .write_room = bfin_jc_write_room,
.chars_in_buffer = bfin_jc_chars_in_buffer, .chars_in_buffer = bfin_jc_chars_in_buffer,
.wait_until_sent = bfin_jc_wait_until_sent,
}; };
static int __init bfin_jc_init(void) static int __init bfin_jc_init(void)
......
...@@ -2138,8 +2138,8 @@ int serial8250_do_startup(struct uart_port *port) ...@@ -2138,8 +2138,8 @@ int serial8250_do_startup(struct uart_port *port)
/* /*
* Clear the interrupt registers. * Clear the interrupt registers.
*/ */
if (serial_port_in(port, UART_LSR) & UART_LSR_DR) serial_port_in(port, UART_LSR);
serial_port_in(port, UART_RX); serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR); serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR); serial_port_in(port, UART_MSR);
...@@ -2300,8 +2300,8 @@ int serial8250_do_startup(struct uart_port *port) ...@@ -2300,8 +2300,8 @@ int serial8250_do_startup(struct uart_port *port)
* saved flags to avoid getting false values from polling * saved flags to avoid getting false values from polling
* routines or the previous session. * routines or the previous session.
*/ */
if (serial_port_in(port, UART_LSR) & UART_LSR_DR) serial_port_in(port, UART_LSR);
serial_port_in(port, UART_RX); serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR); serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR); serial_port_in(port, UART_MSR);
up->lsr_saved_flags = 0; up->lsr_saved_flags = 0;
...@@ -2394,8 +2394,7 @@ void serial8250_do_shutdown(struct uart_port *port) ...@@ -2394,8 +2394,7 @@ void serial8250_do_shutdown(struct uart_port *port)
* Read data port to reset things, and then unlink from * Read data port to reset things, and then unlink from
* the IRQ chain. * 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); serial8250_rpm_put(up);
del_timer_sync(&up->timer); del_timer_sync(&up->timer);
......
...@@ -59,6 +59,8 @@ struct dw8250_data { ...@@ -59,6 +59,8 @@ struct dw8250_data {
u8 usr_reg; u8 usr_reg;
int last_mcr; int last_mcr;
int line; int line;
int msr_mask_on;
int msr_mask_off;
struct clk *clk; struct clk *clk;
struct clk *pclk; struct clk *pclk;
struct reset_control *rst; struct reset_control *rst;
...@@ -81,6 +83,12 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) ...@@ -81,6 +83,12 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
value &= ~UART_MSR_DCTS; 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; return value;
} }
...@@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p, ...@@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p,
if (id >= 0) if (id >= 0)
p->line = id; 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 */ /* clock got configured through clk api, all done */
if (p->uartclk) if (p->uartclk)
return 0; return 0;
......
...@@ -69,7 +69,7 @@ static void moan_device(const char *str, struct pci_dev *dev) ...@@ -69,7 +69,7 @@ static void moan_device(const char *str, struct pci_dev *dev)
"Please send the output of lspci -vv, this\n" "Please send the output of lspci -vv, this\n"
"message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
"manufacturer and name of serial board or\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, pci_name(dev), str, dev->vendor, dev->device,
dev->subsystem_vendor, dev->subsystem_device); dev->subsystem_vendor, dev->subsystem_device);
} }
...@@ -1987,13 +1987,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { ...@@ -1987,13 +1987,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.setup = byt_serial_setup, .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, .vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BSW_UART1, .device = PCI_DEVICE_ID_INTEL_BSW_UART1,
...@@ -2199,13 +2192,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { ...@@ -2199,13 +2192,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
/* /*
* PLX * 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, .vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9050, .device = PCI_DEVICE_ID_PLX_9050,
...@@ -5415,10 +5401,6 @@ static struct pci_device_id serial_pci_tbl[] = { ...@@ -5415,10 +5401,6 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
0, 0, pbn_b0_bt_2_115200 }, 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, { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
0, 0, pbn_wch384_4 }, 0, 0, pbn_wch384_4 },
......
...@@ -133,10 +133,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, ...@@ -133,10 +133,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
if (of_find_property(np, "no-loopback-test", NULL)) if (of_find_property(np, "no-loopback-test", NULL))
port->flags |= UPF_SKIP_TEST; port->flags |= UPF_SKIP_TEST;
ret = of_alias_get_id(np, "serial");
if (ret >= 0)
port->line = ret;
port->dev = &ofdev->dev; port->dev = &ofdev->dev;
switch (type) { switch (type) {
......
...@@ -293,8 +293,10 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) ...@@ -293,8 +293,10 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
ims = serial_in(port, SPRD_IMSR); ims = serial_in(port, SPRD_IMSR);
if (!ims) if (!ims) {
spin_unlock(&port->lock);
return IRQ_NONE; return IRQ_NONE;
}
serial_out(port, SPRD_ICLR, ~0); serial_out(port, SPRD_ICLR, ~0);
......
...@@ -1028,8 +1028,8 @@ EXPORT_SYMBOL(start_tty); ...@@ -1028,8 +1028,8 @@ EXPORT_SYMBOL(start_tty);
/* We limit tty time update visibility to every 8 seconds or so. */ /* We limit tty time update visibility to every 8 seconds or so. */
static void tty_update_time(struct timespec *time) static void tty_update_time(struct timespec *time)
{ {
unsigned long sec = get_seconds() & ~7; unsigned long sec = get_seconds();
if ((long)(sec - time->tv_sec) > 0) if (abs(sec - time->tv_sec) & ~7)
time->tv_sec = sec; time->tv_sec = sec;
} }
......
...@@ -217,11 +217,17 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) ...@@ -217,11 +217,17 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
#endif #endif
if (!timeout) if (!timeout)
timeout = MAX_SCHEDULE_TIMEOUT; timeout = MAX_SCHEDULE_TIMEOUT;
if (wait_event_interruptible_timeout(tty->write_wait,
!tty_chars_in_buffer(tty), timeout) >= 0) { timeout = wait_event_interruptible_timeout(tty->write_wait,
if (tty->ops->wait_until_sent) !tty_chars_in_buffer(tty), timeout);
tty->ops->wait_until_sent(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); EXPORT_SYMBOL(tty_wait_until_sent);
......
...@@ -258,7 +258,8 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) ...@@ -258,7 +258,8 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
* character or at least one jiffy. * character or at least one jiffy.
*/ */
period = max_t(unsigned long, (10 * HZ / bps), 1); 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", dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n",
__func__, jiffies_to_msecs(timeout), __func__, jiffies_to_msecs(timeout),
...@@ -268,7 +269,7 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) ...@@ -268,7 +269,7 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
schedule_timeout_interruptible(period); schedule_timeout_interruptible(period);
if (signal_pending(current)) if (signal_pending(current))
break; break;
if (time_after(jiffies, expire)) if (timeout && time_after(jiffies, expire))
break; break;
} }
} }
......
...@@ -143,13 +143,13 @@ struct uart_port { ...@@ -143,13 +143,13 @@ struct uart_port {
unsigned char iotype; /* io access style */ unsigned char iotype; /* io access style */
unsigned char unused1; unsigned char unused1;
#define UPIO_PORT (0) /* 8b I/O port access */ #define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */
#define UPIO_HUB6 (1) /* Hub6 ISA card */ #define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */
#define UPIO_MEM (2) /* 8b MMIO access */ #define UPIO_MEM (SERIAL_IO_MEM) /* 8b MMIO access */
#define UPIO_MEM32 (3) /* 32b little endian */ #define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */
#define UPIO_MEM32BE (4) /* 32b big endian */ #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */
#define UPIO_AU (5) /* Au1x00 and RT288x type IO */ #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */
#define UPIO_TSI (6) /* Tsi108/109 type IO */ #define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */
unsigned int read_status_mask; /* driver specific */ unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */
......
...@@ -65,6 +65,10 @@ struct serial_struct { ...@@ -65,6 +65,10 @@ struct serial_struct {
#define SERIAL_IO_PORT 0 #define SERIAL_IO_PORT 0
#define SERIAL_IO_HUB6 1 #define SERIAL_IO_HUB6 1
#define SERIAL_IO_MEM 2 #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_CLEAR_FIFO 0x01
#define UART_USE_FIFO 0x02 #define UART_USE_FIFO 0x02
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
struct console_cmdline struct console_cmdline
{ {
char name[8]; /* Name of the driver */ char name[16]; /* Name of the driver */
int index; /* Minor dev. to use */ int index; /* Minor dev. to use */
char *options; /* Options for the driver */ char *options; /* Options for the driver */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE #ifdef CONFIG_A11Y_BRAILLE_CONSOLE
......
...@@ -2464,6 +2464,7 @@ void register_console(struct console *newcon) ...@@ -2464,6 +2464,7 @@ void register_console(struct console *newcon)
for (i = 0, c = console_cmdline; for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0]; i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) { i++, c++) {
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0) if (strcmp(c->name, newcon->name) != 0)
continue; continue;
if (newcon->index >= 0 && if (newcon->index >= 0 &&
......
...@@ -798,7 +798,9 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) ...@@ -798,7 +798,9 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
orig_jiffies = jiffies; orig_jiffies = jiffies;
/* Set poll time to 200 ms */ /* 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); spin_lock_irqsave(&self->spinlock, flags);
while (self->tx_skb && self->tx_skb->len) { while (self->tx_skb && self->tx_skb->len) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment