]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/tty/serial/8250.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / tty / serial / 8250.c
similarity index 95%
rename from drivers/serial/8250.c
rename to drivers/tty/serial/8250.c
index 09a550860dcf7acc702523319332972ed02f7249..3975df6f7fdba6f4bff57f9c7fa05a8ae1bbeadf 100644 (file)
@@ -236,7 +236,8 @@ static const struct serial8250_config uart_config[] = {
                .fifo_size      = 128,
                .tx_loadsz      = 128,
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
        },
        [PORT_16654] = {
                .name           = "ST16654",
@@ -454,21 +455,40 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value)
                writeb(value, p->membase + offset);
 }
 
+/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
+static inline void dwapb_save_out_value(struct uart_port *p, int offset,
+                                       int value)
+{
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
+
+       if (offset == UART_LCR)
+               up->lcr = value;
+}
+
+/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
+static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
+{
+       if (offset == UART_TX || offset == UART_IER)
+               p->serial_in(p, UART_IER);
+}
+
 static void dwapb_serial_out(struct uart_port *p, int offset, int value)
 {
        int save_offset = offset;
        offset = map_8250_out_reg(p, offset) << p->regshift;
-       /* Save the LCR value so it can be re-written when a
-        * Busy Detect interrupt occurs. */
-       if (save_offset == UART_LCR) {
-               struct uart_8250_port *up = (struct uart_8250_port *)p;
-               up->lcr = value;
-       }
+       dwapb_save_out_value(p, save_offset, value);
        writeb(value, p->membase + offset);
-       /* Read the IER to ensure any interrupt is cleared before
-        * returning from ISR. */
-       if (save_offset == UART_TX || save_offset == UART_IER)
-               value = p->serial_in(p, UART_IER);
+       dwapb_check_clear_ier(p, save_offset);
+}
+
+static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
+{
+       int save_offset = offset;
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       dwapb_save_out_value(p, save_offset, value);
+       writel(value, p->membase + offset);
+       dwapb_check_clear_ier(p, save_offset);
 }
 
 static unsigned int io_serial_in(struct uart_port *p, int offset)
@@ -485,7 +505,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
 
 static void set_io_from_upio(struct uart_port *p)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)p;
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
        switch (p->iotype) {
        case UPIO_HUB6:
                p->serial_in = hub6_serial_in;
@@ -518,6 +539,11 @@ static void set_io_from_upio(struct uart_port *p)
                p->serial_out = dwapb_serial_out;
                break;
 
+       case UPIO_DWAPB32:
+               p->serial_in = mem32_serial_in;
+               p->serial_out = dwapb32_serial_out;
+               break;
+
        default:
                p->serial_in = io_serial_in;
                p->serial_out = io_serial_out;
@@ -536,6 +562,7 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
        case UPIO_MEM32:
        case UPIO_AU:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                p->serial_out(p, offset, value);
                p->serial_in(p, UART_LCR);      /* safe, no side-effects */
                break;
@@ -653,13 +680,13 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
 {
        if (p->capabilities & UART_CAP_SLEEP) {
                if (p->capabilities & UART_CAP_EFR) {
-                       serial_outp(p, UART_LCR, 0xBF);
+                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_outp(p, UART_EFR, UART_EFR_ECB);
                        serial_outp(p, UART_LCR, 0);
                }
                serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
                if (p->capabilities & UART_CAP_EFR) {
-                       serial_outp(p, UART_LCR, 0xBF);
+                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_outp(p, UART_EFR, 0);
                        serial_outp(p, UART_LCR, 0);
                }
@@ -752,7 +779,7 @@ static int size_fifo(struct uart_8250_port *up)
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
                    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
        serial_outp(up, UART_MCR, UART_MCR_LOOP);
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        old_dl = serial_dl_read(up);
        serial_dl_write(up, 0x0001);
        serial_outp(up, UART_LCR, 0x03);
@@ -764,7 +791,7 @@ static int size_fifo(struct uart_8250_port *up)
                serial_inp(up, UART_RX);
        serial_outp(up, UART_FCR, old_fcr);
        serial_outp(up, UART_MCR, old_mcr);
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_dl_write(up, old_dl);
        serial_outp(up, UART_LCR, old_lcr);
 
@@ -782,7 +809,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
        unsigned int id;
 
        old_lcr = serial_inp(p, UART_LCR);
-       serial_outp(p, UART_LCR, UART_LCR_DLAB);
+       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
 
        old_dll = serial_inp(p, UART_DLL);
        old_dlm = serial_inp(p, UART_DLM);
@@ -836,7 +863,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
         * recommended for new designs).
         */
        up->acr = 0;
-       serial_out(up, UART_LCR, 0xBF);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_out(up, UART_EFR, UART_EFR_ECB);
        serial_out(up, UART_LCR, 0x00);
        id1 = serial_icr_read(up, UART_ID1);
@@ -945,7 +972,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
         * Check for presence of the EFR when DLAB is set.
         * Only ST16C650V1 UARTs pass this test.
         */
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        if (serial_in(up, UART_EFR) == 0) {
                serial_outp(up, UART_EFR, 0xA8);
                if (serial_in(up, UART_EFR) != 0) {
@@ -963,7 +990,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
         * Maybe it requires 0xbf to be written to the LCR.
         * (other ST16C650V2 UARTs, TI16C752A, etc)
         */
-       serial_outp(up, UART_LCR, 0xBF);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
        if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
                DEBUG_AUTOCONF("EFRv2 ");
                autoconfig_has_efr(up);
@@ -1024,7 +1051,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
        status1 = serial_in(up, UART_IIR) >> 5;
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
        status2 = serial_in(up, UART_IIR) >> 5;
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
@@ -1183,7 +1210,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
         * We also initialise the EFR (if any) to zero for later.  The
         * EFR occupies the same register location as the FCR and IIR.
         */
-       serial_outp(up, UART_LCR, 0xBF);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_outp(up, UART_EFR, 0);
        serial_outp(up, UART_LCR, 0);
 
@@ -1319,7 +1346,8 @@ static inline void __stop_tx(struct uart_8250_port *p)
 
 static void serial8250_stop_tx(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        __stop_tx(up);
 
@@ -1336,7 +1364,8 @@ static void transmit_chars(struct uart_8250_port *up);
 
 static void serial8250_start_tx(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        if (!(up->ier & UART_IER_THRI)) {
                up->ier |= UART_IER_THRI;
@@ -1364,7 +1393,8 @@ static void serial8250_start_tx(struct uart_port *port)
 
 static void serial8250_stop_rx(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        up->ier &= ~UART_IER_RLSI;
        up->port.read_status_mask &= ~UART_LSR_DR;
@@ -1373,7 +1403,8 @@ static void serial8250_stop_rx(struct uart_port *port)
 
 static void serial8250_enable_ms(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        /* no MSR capabilities */
        if (up->bugs & UART_BUG_NOMSR)
@@ -1581,7 +1612,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
                        handled = 1;
 
                        end = NULL;
-               } else if (up->port.iotype == UPIO_DWAPB &&
+               } else if ((up->port.iotype == UPIO_DWAPB ||
+                           up->port.iotype == UPIO_DWAPB32) &&
                          (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
                        /* The DesignWare APB UART has an Busy Detect (0x07)
                         * interrupt meaning an LCR write attempt occured while the
@@ -1781,7 +1813,8 @@ static void serial8250_backup_timeout(unsigned long data)
 
 static unsigned int serial8250_tx_empty(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
        unsigned int lsr;
 
@@ -1795,7 +1828,8 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
 
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned int status;
        unsigned int ret;
 
@@ -1815,7 +1849,8 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
 
 static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char mcr = 0;
 
        if (mctrl & TIOCM_RTS)
@@ -1836,7 +1871,8 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
 static void serial8250_break_ctl(struct uart_port *port, int break_state)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
 
        spin_lock_irqsave(&up->port.lock, flags);
@@ -1890,7 +1926,8 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 
 static int serial8250_get_poll_char(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char lsr = serial_inp(up, UART_LSR);
 
        if (!(lsr & UART_LSR_DR))
@@ -1904,7 +1941,8 @@ static void serial8250_put_poll_char(struct uart_port *port,
                         unsigned char c)
 {
        unsigned int ier;
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        /*
         *      First save the IER then disable the interrupts
@@ -1938,11 +1976,14 @@ static void serial8250_put_poll_char(struct uart_port *port,
 
 static int serial8250_startup(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
        unsigned char lsr, iir;
        int retval;
 
+       up->port.fifosize = uart_config[up->port.type].fifo_size;
+       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
        up->capabilities = uart_config[up->port.type].flags;
        up->mcr = 0;
 
@@ -1952,7 +1993,7 @@ static int serial8250_startup(struct uart_port *port)
        if (up->port.type == PORT_16C950) {
                /* Wake up and initialize UART */
                up->acr = 0;
-               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_IER, 0);
                serial_outp(up, UART_LCR, 0);
@@ -2002,7 +2043,7 @@ static int serial8250_startup(struct uart_port *port)
        if (up->port.type == PORT_16850) {
                unsigned char fctr;
 
-               serial_outp(up, UART_LCR, 0xbf);
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
                fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
                serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
@@ -2166,7 +2207,8 @@ dont_test_tx_en:
 
 static void serial8250_shutdown(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
 
        /*
@@ -2235,7 +2277,8 @@ void
 serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                          struct ktermios *old)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
@@ -2363,7 +2406,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                if (termios->c_cflag & CRTSCTS)
                        efr |= UART_EFR_CTS;
 
-               serial_outp(up, UART_LCR, 0xBF);
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
                serial_outp(up, UART_EFR, efr);
        }
 
@@ -2435,7 +2478,8 @@ serial8250_set_ldisc(struct uart_port *port, int new)
 void serial8250_do_pm(struct uart_port *port, unsigned int state,
                      unsigned int oldstate)
 {
-       struct uart_8250_port *p = (struct uart_8250_port *)port;
+       struct uart_8250_port *p =
+               container_of(port, struct uart_8250_port, port);
 
        serial8250_set_sleep(p, state != 0);
 }
@@ -2476,6 +2520,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        case UPIO_MEM32:
        case UPIO_MEM:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                if (!up->port.mapbase)
                        break;
 
@@ -2513,6 +2558,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
        case UPIO_MEM32:
        case UPIO_MEM:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                if (!up->port.mapbase)
                        break;
 
@@ -2566,7 +2612,8 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
 
 static void serial8250_release_port(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        serial8250_release_std_resource(up);
        if (up->port.type == PORT_RSA)
@@ -2575,7 +2622,8 @@ static void serial8250_release_port(struct uart_port *port)
 
 static int serial8250_request_port(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        int ret = 0;
 
        ret = serial8250_request_std_resource(up);
@@ -2590,7 +2638,8 @@ static int serial8250_request_port(struct uart_port *port)
 
 static void serial8250_config_port(struct uart_port *port, int flags)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        int probeflags = PROBE_ANY;
        int ret;
 
@@ -2771,7 +2820,8 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 
 static void serial8250_console_putchar(struct uart_port *port, int ch)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        wait_for_xmitr(up, UART_LSR_THRE);
        serial_out(up, UART_TX, ch);