diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250_pci.c | 120 | ||||
-rw-r--r-- | drivers/serial/8250_pnp.c | 2 | ||||
-rw-r--r-- | drivers/serial/crisv10.c | 67 | ||||
-rw-r--r-- | drivers/serial/m32r_sio.c | 2 | ||||
-rw-r--r-- | drivers/serial/m32r_sio.h | 6 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 40 | ||||
-rw-r--r-- | drivers/serial/serial_cs.c | 1 | ||||
-rw-r--r-- | drivers/serial/serial_txx9.c | 30 |
8 files changed, 180 insertions, 88 deletions
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 1ea1ed82c35..0e357562ce9 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1036,6 +1036,7 @@ enum pci_board_num_t { pbn_b0_2_115200, pbn_b0_4_115200, pbn_b0_5_115200, + pbn_b0_8_115200, pbn_b0_1_921600, pbn_b0_2_921600, @@ -1172,6 +1173,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { .base_baud = 115200, .uart_offset = 8, }, + [pbn_b0_8_115200] = { + .flags = FL_BASE0, + .num_ports = 8, + .base_baud = 115200, + .uart_offset = 8, + }, [pbn_b0_1_921600] = { .flags = FL_BASE0, @@ -2566,6 +2573,119 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, 0, 0, pbn_b2_8_921600 }, + + /* + * Mainpine series cards: Fairly standard layout but fools + * parts of the autodetect in some cases and uses otherwise + * unmatched communications subclasses in the PCI Express case + */ + + { /* RockForceDUO */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0200, + 0, 0, pbn_b0_2_115200 }, + { /* RockForceQUATRO */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0300, + 0, 0, pbn_b0_4_115200 }, + { /* RockForceDUO+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0400, + 0, 0, pbn_b0_2_115200 }, + { /* RockForceQUATRO+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0500, + 0, 0, pbn_b0_4_115200 }, + { /* RockForce+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0600, + 0, 0, pbn_b0_2_115200 }, + { /* RockForce+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0700, + 0, 0, pbn_b0_4_115200 }, + { /* RockForceOCTO+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0800, + 0, 0, pbn_b0_8_115200 }, + { /* RockForceDUO+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0C00, + 0, 0, pbn_b0_2_115200 }, + { /* RockForceQUARTRO+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x0D00, + 0, 0, pbn_b0_4_115200 }, + { /* RockForceOCTO+ */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x1D00, + 0, 0, pbn_b0_8_115200 }, + { /* RockForceD1 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2000, + 0, 0, pbn_b0_1_115200 }, + { /* RockForceF1 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2100, + 0, 0, pbn_b0_1_115200 }, + { /* RockForceD2 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2200, + 0, 0, pbn_b0_2_115200 }, + { /* RockForceF2 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2300, + 0, 0, pbn_b0_2_115200 }, + { /* RockForceD4 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2400, + 0, 0, pbn_b0_4_115200 }, + { /* RockForceF4 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2500, + 0, 0, pbn_b0_4_115200 }, + { /* RockForceD8 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2600, + 0, 0, pbn_b0_8_115200 }, + { /* RockForceF8 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x2700, + 0, 0, pbn_b0_8_115200 }, + { /* IQ Express D1 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3000, + 0, 0, pbn_b0_1_115200 }, + { /* IQ Express F1 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3100, + 0, 0, pbn_b0_1_115200 }, + { /* IQ Express D2 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3200, + 0, 0, pbn_b0_2_115200 }, + { /* IQ Express F2 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3300, + 0, 0, pbn_b0_2_115200 }, + { /* IQ Express D4 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3400, + 0, 0, pbn_b0_4_115200 }, + { /* IQ Express F4 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3500, + 0, 0, pbn_b0_4_115200 }, + { /* IQ Express D8 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3C00, + 0, 0, pbn_b0_8_115200 }, + { /* IQ Express F8 */ + PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE, + PCI_VENDOR_ID_MAINPINE, 0x3D00, + 0, 0, pbn_b0_8_115200 }, + + /* * PA Semi PA6T-1682M on-chip UART */ diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 301c8c0be9d..926f58a674a 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -327,6 +327,8 @@ static const struct pnp_device_id pnp_dev_table[] = { { "WACF004", 0 }, { "WACF005", 0 }, { "WACF006", 0 }, + { "WACF007", 0 }, + { "WACF008", 0 }, /* Compaq touchscreen */ { "FPI2002", 0 }, /* Fujitsu Stylistic touchscreens */ diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 312bef6bd58..7e8724d3571 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c @@ -514,6 +514,8 @@ struct tty_driver *serial_driver; * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128 * BUF_SIZE can't be > 128 */ +#define CRIS_BUF_SIZE 512 + /* Currently 16 descriptors x 128 bytes = 2048 bytes */ #define SERIAL_DESCR_BUF_SIZE 256 @@ -2497,55 +2499,18 @@ static void flush_to_flip_buffer(struct e100_serial *info) return; } - length = tty->flip.count; - /* Don't flip more than the ldisc has room for. - * The return value from ldisc.receive_room(tty) - might not be up to - * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the - * processed and not accounted for yet. - * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way. - * Lets buffer data here and let flow control take care of it. - * Since we normally flip large chunks, the ldisc don't react - * with throttle until too late if we flip to much. - */ - max_flip_size = tty->ldisc.receive_room(tty); - if (max_flip_size < 0) - max_flip_size = 0; - if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */ - length + info->recv_cnt + /* We have this queued */ - 2*SERIAL_DESCR_BUF_SIZE + /* This could be on the way */ - TTY_THRESHOLD_THROTTLE)) { /* Some slack */ - /* check TTY_THROTTLED first so it indicates our state */ - if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { - DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size)); - rs_throttle(tty); - } -#if 0 - else if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */ - length + info->recv_cnt + /* We have this queued */ - SERIAL_DESCR_BUF_SIZE + /* This could be on the way */ - TTY_THRESHOLD_THROTTLE)) { /* Some slack */ - DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size)); - rs_throttle(tty); - } -#endif - } - - if (max_flip_size > TTY_FLIPBUF_SIZE) - max_flip_size = TTY_FLIPBUF_SIZE; - - while ((buffer = info->first_recv_buffer) && length < max_flip_size) { + while ((buffer = info->first_recv_buffer) != NULL) { unsigned int count = buffer->length; - if (length + count > max_flip_size) - count = max_flip_size - length; + count = tty_buffer_request_room(tty, count); + if (count == 0) /* Throttle ?? */ + break; - memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count); - memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count); - tty->flip.flag_buf_ptr[length] = buffer->error; + if (count > 1) + tty_insert_flip_strings(tty, buffer->buffer, count - 1); + tty_insert_flip_char(tty, buffer->buffer[count-1], buffer->error); - length += count; info->recv_cnt -= count; - DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length)); if (count == buffer->length) { info->first_recv_buffer = buffer->next; @@ -2560,14 +2525,6 @@ static void flush_to_flip_buffer(struct e100_serial *info) if (!info->first_recv_buffer) info->last_recv_buffer = NULL; - tty->flip.count = length; - DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) { - DEBUG_LOG(info->line, "ldisc %lu\n", - tty->ldisc.chars_in_buffer(tty)); - DEBUG_LOG(info->line, "flip.count %lu\n", - tty->flip.count); - } - ); restore_flags(flags); DFLIP( @@ -2722,17 +2679,17 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) printk("!NO TTY!\n"); return info; } - if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) { + if (tty->flip.count >= CRIS_BUF_SIZE - TTY_THRESHOLD_THROTTLE) { /* check TTY_THROTTLED first so it indicates our state */ if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count)); rs_throttle(tty); } } - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + if (tty->flip.count >= CRIS_BUF_SIZE) { DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count); tty->flip.work.func((void *) tty); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + if (tty->flip.count >= CRIS_BUF_SIZE) { DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count); return info; /* if TTY_DONT_FLIP is set */ } diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 6e09c8b395e..348ee2c19b5 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c @@ -539,7 +539,7 @@ static void serial_do_unlink(struct irq_info *i, struct uart_sio_port *up) static int serial_link_irq_chain(struct uart_sio_port *up) { struct irq_info *i = irq_lists + up->port.irq; - int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; + int ret, irq_flags = 0; spin_lock_irq(&i->lock); diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h index 849f1b2c253..e9b7e11793b 100644 --- a/drivers/serial/m32r_sio.h +++ b/drivers/serial/m32r_sio.h @@ -46,9 +46,3 @@ struct old_serial_port { #define PROBE_ANY (~0) #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - -#ifdef CONFIG_SERIAL_SIO_SHARE_IRQ -#define M32R_SIO_SHARE_IRQS 1 -#else -#define M32R_SIO_SHARE_IRQS 0 -#endif diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index a3bd3a3f41f..68aa4da0186 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1938,9 +1938,24 @@ static void uart_change_pm(struct uart_state *state, int pm_state) } } +struct uart_match { + struct uart_port *port; + struct uart_driver *driver; +}; + +static int serial_match_port(struct device *dev, void *data) +{ + struct uart_match *match = data; + dev_t devt = MKDEV(match->driver->major, match->driver->minor) + match->port->line; + + return dev->devt == devt; /* Actually, only one tty per port */ +} + int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) { struct uart_state *state = drv->state + port->line; + struct device *tty_dev; + struct uart_match match = {port, drv}; mutex_lock(&state->mutex); @@ -1951,6 +1966,15 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) } #endif + tty_dev = device_find_child(port->dev, &match, serial_match_port); + if (device_may_wakeup(tty_dev)) { + enable_irq_wake(port->irq); + put_device(tty_dev); + mutex_unlock(&state->mutex); + return 0; + } + port->suspended = 1; + if (state->info && state->info->flags & UIF_INITIALIZED) { const struct uart_ops *ops = port->ops; @@ -1999,6 +2023,13 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) } #endif + if (!port->suspended) { + disable_irq_wake(port->irq); + mutex_unlock(&state->mutex); + return 0; + } + port->suspended = 0; + uart_change_pm(state, 0); /* @@ -2278,6 +2309,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) { struct uart_state *state; int ret = 0; + struct device *tty_dev; BUG_ON(in_interrupt()); @@ -2314,7 +2346,13 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) * Register the port whether it's detected or not. This allows * setserial to be used to alter this ports parameters. */ - tty_register_device(drv->tty_driver, port->line, port->dev); + tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev); + if (likely(!IS_ERR(tty_dev))) { + device_can_wakeup(tty_dev) = 1; + device_set_wakeup_enable(tty_dev, 0); + } else + printk(KERN_ERR "Cannot register tty device on line %d\n", + port->line); /* * Ensure UPF_DEAD is not set. diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 7c8d78fbbbf..5afcb2fa7cd 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -911,6 +911,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 0930e2a8551..6846a6c38b6 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -25,19 +25,15 @@ #include <linux/ioport.h> #include <linux/init.h> #include <linux/console.h> -#include <linux/sysrq.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/pci.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> #include <linux/serial_core.h> #include <linux/serial.h> -#include <linux/mutex.h> #include <asm/io.h> -static char *serial_version = "1.10"; +static char *serial_version = "1.11"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -68,8 +64,6 @@ static char *serial_name = "TX39/49 Serial driver"; */ #define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS -#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - struct uart_txx9_port { struct uart_port port; /* No additional info for now */ @@ -756,21 +750,6 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags) serial_txx9_initialize(port); } -static int -serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - unsigned long new_port = ser->port; - if (HIGH_BITS_OFFSET) - new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET; - if (ser->type != port->type || - ser->irq != port->irq || - ser->io_type != port->iotype || - new_port != port->iobase || - (unsigned long)ser->iomem_base != port->mapbase) - return -EINVAL; - return 0; -} - static const char * serial_txx9_type(struct uart_port *port) { @@ -794,7 +773,6 @@ static struct uart_ops serial_txx9_pops = { .release_port = serial_txx9_release_port, .request_port = serial_txx9_request_port, .config_port = serial_txx9_config_port, - .verify_port = serial_txx9_verify_port, }; static struct uart_txx9_port serial_txx9_ports[UART_NR]; @@ -950,7 +928,8 @@ int __init early_serial_txx9_setup(struct uart_port *port) serial_txx9_ports[port->line].port = *port; serial_txx9_ports[port->line].port.ops = &serial_txx9_pops; - serial_txx9_ports[port->line].port.flags |= UPF_BOOT_AUTOCONF; + serial_txx9_ports[port->line].port.flags |= + UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; return 0; } @@ -995,7 +974,8 @@ static int __devinit serial_txx9_register_port(struct uart_port *port) uart->port.irq = port->irq; uart->port.uartclk = port->uartclk; uart->port.iotype = port->iotype; - uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; + uart->port.flags = port->flags + | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; uart->port.mapbase = port->mapbase; if (port->dev) uart->port.dev = port->dev; |