Skip to content

Commit

Permalink
Merge tag 'tty-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…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"
  • Loading branch information
torvalds committed Mar 8, 2015
2 parents 47df986 + c37bc68 commit bbbce51
Show file tree
Hide file tree
Showing 15 changed files with 89 additions and 61 deletions.
16 changes: 16 additions & 0 deletions Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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:
Expand Down
13 changes: 0 additions & 13 deletions drivers/tty/bfin_jtag_comm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down
11 changes: 5 additions & 6 deletions drivers/tty/serial/8250/8250_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -2300,8 +2300,8 @@ int serial8250_do_startup(struct uart_port *port)
* 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;
Expand Down Expand Up @@ -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);
Expand Down
32 changes: 32 additions & 0 deletions drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
20 changes: 1 addition & 19 deletions drivers/tty/serial/8250/8250_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 },
Expand Down
4 changes: 0 additions & 4 deletions drivers/tty/serial/of_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion drivers/tty/serial/sprd_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
16 changes: 11 additions & 5 deletions drivers/tty/tty_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions drivers/usb/serial/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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;
}
}
Expand Down
14 changes: 7 additions & 7 deletions include/linux/serial_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
4 changes: 4 additions & 0 deletions include/uapi/linux/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion kernel/printk/console_cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions kernel/printk/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
4 changes: 3 additions & 1 deletion net/irda/ircomm/ircomm_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit bbbce51

Please sign in to comment.