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:
commit
bbbce516bb
15 changed files with 89 additions and 61 deletions
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue