diff options
Diffstat (limited to 'drivers/tty')
49 files changed, 2867 insertions, 1976 deletions
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index cea56033b34..a09ce3ef5d7 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -417,7 +417,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) __FILE__,__LINE__,tbuf,tbuf->count); /* Send the next block of data to device */ - tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); actual = tty->ops->write(tty, tbuf->buf, tbuf->count); /* rollback was possible and has been done */ @@ -459,7 +459,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) } if (!tbuf) - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); /* Clear the re-entry flag */ spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); @@ -491,7 +491,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) return; if (tty != n_hdlc->tty) { - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); return; } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 39d6ab6551e..d2256d08ee7 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -61,7 +61,7 @@ * controlling the space in the read buffer. */ #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ -#define TTY_THRESHOLD_UNTHROTTLE 128 +#define TTY_THRESHOLD_UNTHROTTLE 128 /* * Special byte codes used in the echo buffer to represent operations @@ -405,7 +405,7 @@ static ssize_t process_output_block(struct tty_struct *tty, const unsigned char *buf, unsigned int nr) { int space; - int i; + int i; const unsigned char *cp; mutex_lock(&tty->output_lock); @@ -1607,7 +1607,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) } /** - * copy_from_read_buf - copy read data directly + * copy_from_read_buf - copy read data directly * @tty: terminal device * @b: user data * @nr: size of data @@ -1909,7 +1909,7 @@ do_it_again: if (nr) clear_bit(TTY_PUSH, &tty->flags); } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) - goto do_it_again; + goto do_it_again; n_tty_set_room(tty); return retval; diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index e18604b3fc7..d8653ab6f49 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -446,19 +446,8 @@ static inline void legacy_pty_init(void) { } int pty_limit = NR_UNIX98_PTY_DEFAULT; static int pty_limit_min; static int pty_limit_max = NR_UNIX98_PTY_MAX; -static int tty_count; static int pty_count; -static inline void pty_inc_count(void) -{ - pty_count = (++tty_count) / 2; -} - -static inline void pty_dec_count(void) -{ - pty_count = (--tty_count) / 2; -} - static struct cdev ptmx_cdev; static struct ctl_table pty_table[] = { @@ -600,8 +589,7 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) */ tty_driver_kref_get(driver); tty->count++; - pty_inc_count(); /* tty */ - pty_inc_count(); /* tty->link */ + pty_count++; return 0; err_free_mem: deinitialize_tty_struct(o_tty); @@ -613,15 +601,19 @@ err_free_tty: return -ENOMEM; } -static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) +static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) +{ + pty_count--; +} + +static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) { - pty_dec_count(); } static const struct tty_operations ptm_unix98_ops = { .lookup = ptm_unix98_lookup, .install = pty_unix98_install, - .remove = pty_unix98_remove, + .remove = ptm_unix98_remove, .open = pty_open, .close = pty_close, .write = pty_write, @@ -638,7 +630,7 @@ static const struct tty_operations ptm_unix98_ops = { static const struct tty_operations pty_unix98_ops = { .lookup = pts_unix98_lookup, .install = pty_unix98_install, - .remove = pty_unix98_remove, + .remove = pts_unix98_remove, .open = pty_open, .close = pty_close, .write = pty_write, diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index eeadf1b8e09..9f50c4e3c2b 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -129,32 +129,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX]; static unsigned int probe_rsa_count; #endif /* CONFIG_SERIAL_8250_RSA */ -struct uart_8250_port { - struct uart_port port; - struct timer_list timer; /* "no irq" timer */ - struct list_head list; /* ports on this IRQ */ - unsigned short capabilities; /* port capabilities */ - unsigned short bugs; /* port bugs */ - unsigned int tx_loadsz; /* transmit fifo load size */ - unsigned char acr; - unsigned char ier; - unsigned char lcr; - unsigned char mcr; - unsigned char mcr_mask; /* mask of user bits */ - unsigned char mcr_force; /* mask of forced bits */ - unsigned char cur_iotype; /* Running I/O type */ - - /* - * Some bits in registers are cleared on a read, so they must - * be saved whenever the register is read but the bits will not - * be immediately processed. - */ -#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS - unsigned char lsr_saved_flags; -#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA - unsigned char msr_saved_flags; -}; - struct irq_info { struct hlist_node node; int irq; @@ -1326,8 +1300,6 @@ static void serial8250_stop_tx(struct uart_port *port) } } -static void transmit_chars(struct uart_8250_port *up); - static void serial8250_start_tx(struct uart_port *port) { struct uart_8250_port *up = @@ -1344,7 +1316,7 @@ static void serial8250_start_tx(struct uart_port *port) if ((up->port.type == PORT_RM9000) ? (lsr & UART_LSR_THRE) : (lsr & UART_LSR_TEMT)) - transmit_chars(up); + serial8250_tx_chars(up); } } @@ -1401,11 +1373,16 @@ static void clear_rx_fifo(struct uart_8250_port *up) } while (1); } -static void -receive_chars(struct uart_8250_port *up, unsigned int *status) +/* + * serial8250_rx_chars: processes according to the passed in LSR + * value, and returns the remaining LSR bits not handled + * by this Rx routine. + */ +unsigned char +serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) { struct tty_struct *tty = up->port.state->port.tty; - unsigned char ch, lsr = *status; + unsigned char ch; int max_count = 256; char flag; @@ -1481,10 +1458,11 @@ ignore_char: spin_unlock(&up->port.lock); tty_flip_buffer_push(tty); spin_lock(&up->port.lock); - *status = lsr; + return lsr; } +EXPORT_SYMBOL_GPL(serial8250_rx_chars); -static void transmit_chars(struct uart_8250_port *up) +void serial8250_tx_chars(struct uart_8250_port *up) { struct circ_buf *xmit = &up->port.state->xmit; int count; @@ -1521,8 +1499,9 @@ static void transmit_chars(struct uart_8250_port *up) if (uart_circ_empty(xmit)) __stop_tx(up); } +EXPORT_SYMBOL_GPL(serial8250_tx_chars); -static unsigned int check_modem_status(struct uart_8250_port *up) +unsigned int serial8250_modem_status(struct uart_8250_port *up) { unsigned int status = serial_in(up, UART_MSR); @@ -1544,14 +1523,20 @@ static unsigned int check_modem_status(struct uart_8250_port *up) return status; } +EXPORT_SYMBOL_GPL(serial8250_modem_status); /* * This handles the interrupt from one port. */ -static void serial8250_handle_port(struct uart_8250_port *up) +int serial8250_handle_irq(struct uart_port *port, unsigned int iir) { - unsigned int status; + unsigned char status; unsigned long flags; + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + + if (iir & UART_IIR_NO_INT) + return 0; spin_lock_irqsave(&up->port.lock, flags); @@ -1560,25 +1545,13 @@ static void serial8250_handle_port(struct uart_8250_port *up) DEBUG_INTR("status = %x...", status); if (status & (UART_LSR_DR | UART_LSR_BI)) - receive_chars(up, &status); - check_modem_status(up); + status = serial8250_rx_chars(up, status); + serial8250_modem_status(up); if (status & UART_LSR_THRE) - transmit_chars(up); + serial8250_tx_chars(up); spin_unlock_irqrestore(&up->port.lock, flags); -} - -int serial8250_handle_irq(struct uart_port *port, unsigned int iir) -{ - struct uart_8250_port *up = - container_of(port, struct uart_8250_port, port); - - if (!(iir & UART_IIR_NO_INT)) { - serial8250_handle_port(up); - return 1; - } - - return 0; + return 1; } EXPORT_SYMBOL_GPL(serial8250_handle_irq); @@ -1619,11 +1592,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) do { struct uart_8250_port *up; struct uart_port *port; + bool skip; up = list_entry(l, struct uart_8250_port, list); port = &up->port; + skip = pass_counter && up->port.flags & UPF_IIR_ONCE; - if (port->handle_irq(port)) { + if (!skip && port->handle_irq(port)) { handled = 1; end = NULL; } else if (end == NULL) @@ -1758,11 +1733,8 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) static void serial8250_timeout(unsigned long data) { struct uart_8250_port *up = (struct uart_8250_port *)data; - unsigned int iir; - iir = serial_in(up, UART_IIR); - if (!(iir & UART_IIR_NO_INT)) - serial8250_handle_port(up); + up->port.handle_irq(&up->port); mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); } @@ -1801,7 +1773,7 @@ static void serial8250_backup_timeout(unsigned long data) } if (!(iir & UART_IIR_NO_INT)) - transmit_chars(up); + serial8250_tx_chars(up); if (is_real_interrupt(up->port.irq)) serial_out(up, UART_IER, ier); @@ -1835,7 +1807,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) unsigned int status; unsigned int ret; - status = check_modem_status(up); + status = serial8250_modem_status(up); ret = 0; if (status & UART_MSR_DCD) @@ -2000,7 +1972,7 @@ static int serial8250_startup(struct uart_port *port) serial_outp(up, UART_IER, 0); serial_outp(up, UART_LCR, 0); serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ - serial_outp(up, UART_LCR, 0xBF); + serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_outp(up, UART_EFR, UART_EFR_ECB); serial_outp(up, UART_LCR, 0); } @@ -2848,7 +2820,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) local_irq_save(flags); if (up->port.sysrq) { - /* serial8250_handle_port() already took the lock */ + /* serial8250_handle_irq() already took the lock */ locked = 0; } else if (oops_in_progress) { locked = spin_trylock(&up->port.lock); @@ -2882,7 +2854,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) * while processing with interrupts off. */ if (up->msr_saved_flags) - check_modem_status(up); + serial8250_modem_status(up); if (locked) spin_unlock(&up->port.lock); diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h index 6edf4a6a22d..ae027be57e2 100644 --- a/drivers/tty/serial/8250.h +++ b/drivers/tty/serial/8250.h @@ -13,6 +13,32 @@ #include <linux/serial_8250.h> +struct uart_8250_port { + struct uart_port port; + struct timer_list timer; /* "no irq" timer */ + struct list_head list; /* ports on this IRQ */ + unsigned short capabilities; /* port capabilities */ + unsigned short bugs; /* port bugs */ + unsigned int tx_loadsz; /* transmit fifo load size */ + unsigned char acr; + unsigned char ier; + unsigned char lcr; + unsigned char mcr; + unsigned char mcr_mask; /* mask of user bits */ + unsigned char mcr_force; /* mask of forced bits */ + unsigned char cur_iotype; /* Running I/O type */ + + /* + * Some bits in registers are cleared on a read, so they must + * be saved whenever the register is read but the bits will not + * be immediately processed. + */ +#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS + unsigned char lsr_saved_flags; +#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + unsigned char msr_saved_flags; +}; + struct old_serial_port { unsigned int uart; unsigned int baud_base; diff --git a/drivers/tty/serial/8250_dw.c b/drivers/tty/serial/8250_dw.c index bf1fba640c2..f574eef3075 100644 --- a/drivers/tty/serial/8250_dw.c +++ b/drivers/tty/serial/8250_dw.c @@ -177,17 +177,7 @@ static struct platform_driver dw8250_platform_driver = { .remove = __devexit_p(dw8250_remove), }; -static int __init dw8250_init(void) -{ - return platform_driver_register(&dw8250_platform_driver); -} -module_init(dw8250_init); - -static void __exit dw8250_exit(void) -{ - platform_driver_unregister(&dw8250_platform_driver); -} -module_exit(dw8250_exit); +module_platform_driver(dw8250_platform_driver); MODULE_AUTHOR("Jamie Iles"); MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/8250_fsl.c b/drivers/tty/serial/8250_fsl.c new file mode 100644 index 00000000000..f4d3c47b88e --- /dev/null +++ b/drivers/tty/serial/8250_fsl.c @@ -0,0 +1,63 @@ +#include <linux/serial_reg.h> +#include <linux/serial_8250.h> + +#include "8250.h" + +/* + * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This isn't a full driver; it just provides an alternate IRQ + * handler to deal with an errata. Everything else is just + * using the bog standard 8250 support. + * + * We follow code flow of serial8250_default_handle_irq() but add + * a check for a break and insert a dummy read on the Rx for the + * immediately following IRQ event. + * + * We re-use the already existing "bug handling" lsr_saved_flags + * field to carry the "what we just did" information from the one + * IRQ event to the next one. + */ + +int fsl8250_handle_irq(struct uart_port *port) +{ + unsigned char lsr, orig_lsr; + unsigned long flags; + unsigned int iir; + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + + spin_lock_irqsave(&up->port.lock, flags); + + iir = port->serial_in(port, UART_IIR); + if (iir & UART_IIR_NO_INT) { + spin_unlock_irqrestore(&up->port.lock, flags); + return 0; + } + + /* This is the WAR; if last event was BRK, then read and return */ + if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) { + up->lsr_saved_flags &= ~UART_LSR_BI; + port->serial_in(port, UART_RX); + spin_unlock_irqrestore(&up->port.lock, flags); + return 1; + } + + lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR); + + if (lsr & (UART_LSR_DR | UART_LSR_BI)) + lsr = serial8250_rx_chars(up, lsr); + + serial8250_modem_status(up); + + if (lsr & UART_LSR_THRE) + serial8250_tx_chars(up); + + up->lsr_saved_flags = orig_lsr; + spin_unlock_irqrestore(&up->port.lock, flags); + return 1; +} diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 825937a5f21..da2b0b0a183 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -1092,6 +1092,14 @@ static int skip_tx_en_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int kt_serial_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_port *port, int idx) +{ + port->flags |= UPF_IIR_ONCE; + return skip_tx_en_setup(priv, board, port, idx); +} + static int pci_eg20t_init(struct pci_dev *dev) { #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) @@ -1110,7 +1118,18 @@ pci_xr17c154_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } -/* This should be in linux/pci_ids.h */ +static int try_enable_msi(struct pci_dev *dev) +{ + /* use msi if available, but fallback to legacy otherwise */ + pci_enable_msi(dev); + return 0; +} + +static void disable_msi(struct pci_dev *dev) +{ + pci_disable_msi(dev); +} + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1133,9 +1152,14 @@ pci_xr17c154_setup(struct serial_private *priv, #define PCI_DEVICE_ID_TITAN_800E 0xA014 #define PCI_DEVICE_ID_TITAN_200EI 0xA016 #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 +#define PCI_DEVICE_ID_TITAN_400V3 0xA310 +#define PCI_DEVICE_ID_TITAN_410V3 0xA312 +#define PCI_DEVICE_ID_TITAN_800V3 0xA314 +#define PCI_DEVICE_ID_TITAN_800V3B 0xA315 #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 +#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -1220,6 +1244,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = ce4100_serial_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = try_enable_msi, + .setup = kt_serial_setup, + .exit = disable_msi, + }, /* * ITE */ @@ -3414,6 +3447,18 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi_2_4000000 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 925a1e547a8..f32a2ea7010 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -97,6 +97,11 @@ config SERIAL_8250_PNP This builds standard PNP serial support. You may be able to disable this feature if you only need legacy serial support. +config SERIAL_8250_FSL + bool + depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 + default PPC + config SERIAL_8250_HP300 tristate depends on SERIAL_8250 && HP300 @@ -457,7 +462,7 @@ config SERIAL_SAMSUNG config SERIAL_SAMSUNG_UARTS_4 bool depends on ARM && PLAT_SAMSUNG - default y if CPU_S3C2443 + default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) help Internal node for the common case of 4 Samsung compatible UARTs @@ -465,7 +470,7 @@ config SERIAL_SAMSUNG_UARTS int depends on ARM && PLAT_SAMSUNG default 6 if ARCH_S5P6450 - default 4 if SERIAL_SAMSUNG_UARTS_4 + default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 default 3 help Select the number of available UART ports for the Samsung S3C @@ -495,46 +500,27 @@ config SERIAL_SAMSUNG_CONSOLE your boot loader about how to pass options to the kernel at boot time.) -config SERIAL_S3C2410 - tristate "Samsung S3C2410 Serial port support" - depends on SERIAL_SAMSUNG && CPU_S3C2410 - default y if CPU_S3C2410 - help - Serial port support for the Samsung S3C2410 SoC - -config SERIAL_S3C2412 - tristate "Samsung S3C2412/S3C2413 Serial port support" - depends on SERIAL_SAMSUNG && CPU_S3C2412 - default y if CPU_S3C2412 - help - Serial port support for the Samsung S3C2412 and S3C2413 SoC - -config SERIAL_S3C2440 - tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416) - default y if CPU_S3C2440 - default y if CPU_S3C2442 - select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416 - help - Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC - -config SERIAL_S3C6400 - tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100) - select SERIAL_SAMSUNG_UARTS_4 - default y - help - Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450 - and S5PC100 SoCs - -config SERIAL_S5PV210 - tristate "Samsung S5PV210 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212) - select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212) - default y - help - Serial port support for Samsung's S5P Family of SoC's - +config SERIAL_SIRFSOC + tristate "SiRF SoC Platform Serial port support" + depends on ARM && ARCH_PRIMA2 + select SERIAL_CORE + h |