]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'tty/tty-next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:14 +0000 (14:59 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:14 +0000 (14:59 +0200)
Conflicts:
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/imx.c

52 files changed:
Documentation/serial/driver
Documentation/sysrq.txt
drivers/tty/bfin_jtag_comm.c
drivers/tty/hvc/hvc_dcc.c
drivers/tty/hvc/hvc_vio.c
drivers/tty/n_tty.c
drivers/tty/nozomi.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/8250/8250_em.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/Kconfig
drivers/tty/serial/amba-pl010.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/arc_uart.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/bfin_sport_uart.c
drivers/tty/serial/bfin_uart.c
drivers/tty/serial/clps711x.c
drivers/tty/serial/ifx6x60.c
drivers/tty/serial/imx.c
drivers/tty/serial/ip22zilog.c
drivers/tty/serial/max310x.c
drivers/tty/serial/mfd.c
drivers/tty/serial/mpc52xx_uart.c
drivers/tty/serial/mpsc.c
drivers/tty/serial/mrst_max3110.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/sa1100.c
drivers/tty/serial/samsung.c
drivers/tty/serial/samsung.h
drivers/tty/serial/sccnxp.c
drivers/tty/serial/serial-tegra.c
drivers/tty/serial/serial_txx9.c
drivers/tty/serial/sirfsoc_uart.c
drivers/tty/serial/sunsab.c
drivers/tty/serial/sunsu.c
drivers/tty/serial/sunzilog.c
drivers/tty/serial/ucc_uart.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/sysrq.c
drivers/tty/tty_port.c
drivers/tty/vt/vt.c
include/linux/atmel_serial.h
include/linux/serial_core.h
include/linux/sysrq.h
include/linux/tty.h
kernel/sysctl.c
lib/Kconfig.debug

index 067c47d4691747757b9b0a36efc37d95e79df1e3..c3a7689a90e69260aa1ca76910db8a1aaa258662 100644 (file)
@@ -264,10 +264,6 @@ hardware.
        Locking: none.
        Interrupts: caller dependent.
 
-  set_wake(port,state)
-       Enable/disable power management wakeup on serial activity.  Not
-       currently implemented.
-
   type(port)
        Return a pointer to a string constant describing the specified
        port, or return NULL, in which case the string 'unknown' is
index 8cb4d7842a5ffa001eb4c0e56bed1198ffdb8d96..0e307c94809a02586d59c13ca8c56985b632cfaf 100644 (file)
@@ -11,27 +11,29 @@ regardless of whatever else it is doing, unless it is completely locked up.
 You need to say "yes" to 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' when
 configuring the kernel. When running a kernel with SysRq compiled in,
 /proc/sys/kernel/sysrq controls the functions allowed to be invoked via
-the SysRq key. By default the file contains 1 which means that every
-possible SysRq request is allowed (in older versions SysRq was disabled
-by default, and you were required to specifically enable it at run-time
-but this is not the case any more). Here is the list of possible values
-in /proc/sys/kernel/sysrq:
+the SysRq key. The default value in this file is set by the
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE config symbol, which itself defaults
+to 1. Here is the list of possible values in /proc/sys/kernel/sysrq:
    0 - disable sysrq completely
    1 - enable all functions of sysrq
   >1 - bitmask of allowed sysrq functions (see below for detailed function
        description):
-          2 - enable control of console logging level
-          4 - enable control of keyboard (SAK, unraw)
-          8 - enable debugging dumps of processes etc.
-         16 - enable sync command
-         32 - enable remount read-only
-         64 - enable signalling of processes (term, kill, oom-kill)
-        128 - allow reboot/poweroff
-        256 - allow nicing of all RT tasks
+          2 =   0x2 - enable control of console logging level
+          4 =   0x4 - enable control of keyboard (SAK, unraw)
+          8 =   0x8 - enable debugging dumps of processes etc.
+         16 =  0x10 - enable sync command
+         32 =  0x20 - enable remount read-only
+         64 =  0x40 - enable signalling of processes (term, kill, oom-kill)
+        128 =  0x80 - allow reboot/poweroff
+        256 = 0x100 - allow nicing of all RT tasks
 
 You can set the value in the file by the following command:
     echo "number" >/proc/sys/kernel/sysrq
 
+The number may be written here either as decimal or as hexadecimal
+with the 0x prefix. CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE must always be
+written in hexadecimal.
+
 Note that the value of /proc/sys/kernel/sysrq influences only the invocation
 via a keyboard. Invocation of any operation via /proc/sysrq-trigger is always
 allowed (by a user with admin privileges).
index a93a424873faf638a004a3cabbc5f381d381027a..8096fcbe2dc171d4742b561fdcaa0f60e1894547 100644 (file)
@@ -349,7 +349,7 @@ bfin_jc_early_write(struct console *co, const char *buf, unsigned int count)
        bfin_jc_straight_buffer_write(buf, count);
 }
 
-static struct __initdata console bfin_jc_early_console = {
+static struct console bfin_jc_early_console __initdata = {
        .name   = "early_BFJC",
        .write   = bfin_jc_early_write,
        .flags   = CON_ANYTIME | CON_PRINTBUFFER,
index 44fbebab5075f98f337d880288993b01ad9e7271..3502a7bbb69eee716f21b5b5b89c14fd3f9627fb 100644 (file)
@@ -86,6 +86,21 @@ static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
        return i;
 }
 
+static bool hvc_dcc_check(void)
+{
+       unsigned long time = jiffies + (HZ / 10);
+
+       /* Write a test character to check if it is handled */
+       __dcc_putchar('\n');
+
+       while (time_is_after_jiffies(time)) {
+               if (!(__dcc_getstatus() & DCC_STATUS_TX))
+                       return true;
+       }
+
+       return false;
+}
+
 static const struct hv_ops hvc_dcc_get_put_ops = {
        .get_chars = hvc_dcc_get_chars,
        .put_chars = hvc_dcc_put_chars,
@@ -93,6 +108,9 @@ static const struct hv_ops hvc_dcc_get_put_ops = {
 
 static int __init hvc_dcc_console_init(void)
 {
+       if (!hvc_dcc_check())
+               return -ENODEV;
+
        hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
        return 0;
 }
@@ -100,6 +118,9 @@ console_initcall(hvc_dcc_console_init);
 
 static int __init hvc_dcc_init(void)
 {
+       if (!hvc_dcc_check())
+               return -ENODEV;
+
        hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
        return 0;
 }
index c791b18cdd086a1fa22b470ba8b9904dd0fc01e3..b594abfbf21e76d58acc1df534a30f603670fb5a 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/prom.h>
 #include <asm/hvsi.h>
 #include <asm/udbg.h>
+#include <asm/machdep.h>
 
 #include "hvc_console.h"
 
@@ -457,7 +458,9 @@ void __init hvc_vio_init_early(void)
        if (hvterm_priv0.proto == HV_PROTOCOL_HVSI)
                goto out;
 #endif
-       add_preferred_console("hvc", 0, NULL);
+       /* Check whether the user has requested a different console. */
+       if (!strstr(cmd_line, "console="))
+               add_preferred_console("hvc", 0, NULL);
        hvc_instantiate(0, 0, ops);
 out:
        of_node_put(stdout_node);
index 7a744b69c3d144516388d3e8a4bc2fc440fd4d34..7cdd1eb9406c11ccb4870560490f0c6036f92032 100644 (file)
@@ -767,7 +767,7 @@ static size_t __process_echoes(struct tty_struct *tty)
         * of echo overrun before the next commit), then discard enough
         * data at the tail to prevent a subsequent overrun */
        while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
-               if (echo_buf(ldata, tail == ECHO_OP_START)) {
+               if (echo_buf(ldata, tail) == ECHO_OP_START) {
                        if (echo_buf(ldata, tail) == ECHO_OP_ERASE_TAB)
                                tail += 3;
                        else
@@ -1752,20 +1752,14 @@ int is_ignored(int sig)
 static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
        struct n_tty_data *ldata = tty->disc_data;
-       int canon_change = 1;
 
-       if (old)
-               canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;
-       if (canon_change) {
+       if (!old || (old->c_lflag ^ tty->termios.c_lflag) & ICANON) {
                bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
                ldata->line_start = ldata->canon_head = ldata->read_tail;
                ldata->erasing = 0;
                ldata->lnext = 0;
        }
 
-       if (canon_change && !L_ICANON(tty) && read_cnt(ldata))
-               wake_up_interruptible(&tty->read_wait);
-
        ldata->icanon = (L_ICANON(tty) != 0);
 
        if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
@@ -1820,9 +1814,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
         * Fix tty hang when I_IXON(tty) is cleared, but the tty
         * been stopped by STOP_CHAR(tty) before it.
         */
-       if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
+       if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped)
                start_tty(tty);
-       }
 
        /* The termios change make the tty ready for I/O */
        wake_up_interruptible(&tty->write_wait);
index d6080c3831ef98b72d8269dc3750f58f6d55bfba..cd04293695576aeec9cd25fdce8de91b97f7fd2c 100644 (file)
@@ -959,7 +959,7 @@ static int receive_flow_control(struct nozomi *dc)
                dev_err(&dc->pdev->dev,
                        "ERROR: flow control received for non-existing port\n");
                return 0;
-       };
+       }
 
        DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl),
           *((u16 *)&ctrl_dl));
@@ -1025,7 +1025,7 @@ static enum ctrl_port_type port2ctrl(enum port_type port,
                dev_err(&dc->pdev->dev,
                        "ERROR: send flow control " \
                        "received for non-existing port\n");
-       };
+       }
        return CTRL_ERROR;
 }
 
@@ -1805,7 +1805,7 @@ static int ntty_ioctl(struct tty_struct *tty,
        default:
                DBG1("ERR: 0x%08X, %d", cmd, cmd);
                break;
-       };
+       }
 
        return rval;
 }
index 570df9d2a5d2f46afc72a23d1e373f2c5aa4f3ba..e33d38cb170f97e4055a0a17eb0f4e7bc0b45d0e 100644 (file)
@@ -2322,7 +2322,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
                fcr = uart_config[port->type].fcr;
-               if (baud < 2400 || fifo_bug) {
+               if ((baud < 2400 && !up->dma) || fifo_bug) {
                        fcr &= ~UART_FCR_TRIGGER_MASK;
                        fcr |= UART_FCR_TRIGGER_1;
                }
index daf710f5c3fc68e0197012ea129edf1a41a7ea14..4658e3e0ec4256d9b2e31f890ea72822abf47f93 100644 (file)
 
 
 struct dw8250_data {
-       int             last_lcr;
-       int             last_mcr;
-       int             line;
-       struct clk      *clk;
-       u8              usr_reg;
+       u8                      usr_reg;
+       int                     last_mcr;
+       int                     line;
+       struct clk              *clk;
+       struct uart_8250_dma    dma;
 };
 
 static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
@@ -76,17 +76,33 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
        return value;
 }
 
+static void dw8250_force_idle(struct uart_port *p)
+{
+       serial8250_clear_and_reinit_fifos(container_of
+                                         (p, struct uart_8250_port, port));
+       (void)p->serial_in(p, UART_RX);
+}
+
 static void dw8250_serial_out(struct uart_port *p, int offset, int value)
 {
        struct dw8250_data *d = p->private_data;
 
-       if (offset == UART_LCR)
-               d->last_lcr = value;
-
        if (offset == UART_MCR)
                d->last_mcr = value;
 
        writeb(value, p->membase + (offset << p->regshift));
+
+       /* Make sure LCR write wasn't ignored */
+       if (offset == UART_LCR) {
+               int tries = 1000;
+               while (tries--) {
+                       if (value == p->serial_in(p, UART_LCR))
+                               return;
+                       dw8250_force_idle(p);
+                       writeb(value, p->membase + (UART_LCR << p->regshift));
+               }
+               dev_err(p->dev, "Couldn't set LCR to %d\n", value);
+       }
 }
 
 static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
@@ -107,13 +123,22 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
 {
        struct dw8250_data *d = p->private_data;
 
-       if (offset == UART_LCR)
-               d->last_lcr = value;
-
        if (offset == UART_MCR)
                d->last_mcr = value;
 
        writel(value, p->membase + (offset << p->regshift));
+
+       /* Make sure LCR write wasn't ignored */
+       if (offset == UART_LCR) {
+               int tries = 1000;
+               while (tries--) {
+                       if (value == p->serial_in(p, UART_LCR))
+                               return;
+                       dw8250_force_idle(p);
+                       writel(value, p->membase + (UART_LCR << p->regshift));
+               }
+               dev_err(p->dev, "Couldn't set LCR to %d\n", value);
+       }
 }
 
 static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
@@ -131,9 +156,8 @@ static int dw8250_handle_irq(struct uart_port *p)
        if (serial8250_handle_irq(p, iir)) {
                return 1;
        } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
-               /* Clear the USR and write the LCR again. */
+               /* Clear the USR */
                (void)p->serial_in(p, d->usr_reg);
-               p->serial_out(p, UART_LCR, d->last_lcr);
 
                return 1;
        }
@@ -153,6 +177,14 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
                pm_runtime_put_sync_suspend(port->dev);
 }
 
+static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
+{
+       struct dw8250_data *data = param;
+
+       return chan->chan_id == data->dma.tx_chan_id ||
+              chan->chan_id == data->dma.rx_chan_id;
+}
+
 static void dw8250_setup_port(struct uart_8250_port *up)
 {
        struct uart_port        *p = &up->port;
@@ -241,7 +273,8 @@ static int dw8250_probe_of(struct uart_port *p,
 }
 
 #ifdef CONFIG_ACPI
-static int dw8250_probe_acpi(struct uart_8250_port *up)
+static int dw8250_probe_acpi(struct uart_8250_port *up,
+                            struct dw8250_data *data)
 {
        const struct acpi_device_id *id;
        struct uart_port *p = &up->port;
@@ -260,9 +293,7 @@ static int dw8250_probe_acpi(struct uart_8250_port *up)
        if (!p->uartclk)
                p->uartclk = (unsigned int)id->driver_data;
 
-       up->dma = devm_kzalloc(p->dev, sizeof(*up->dma), GFP_KERNEL);
-       if (!up->dma)
-               return -ENOMEM;
+       up->dma = &data->dma;
 
        up->dma->rxconf.src_maxburst = p->fifosize / 4;
        up->dma->txconf.dst_maxburst = p->fifosize / 4;
@@ -270,7 +301,8 @@ static int dw8250_probe_acpi(struct uart_8250_port *up)
        return 0;
 }
 #else
-static inline int dw8250_probe_acpi(struct uart_8250_port *up)
+static inline int dw8250_probe_acpi(struct uart_8250_port *up,
+                                   struct dw8250_data *data)
 {
        return -ENODEV;
 }
@@ -314,6 +346,12 @@ static int dw8250_probe(struct platform_device *pdev)
                uart.port.uartclk = clk_get_rate(data->clk);
        }
 
+       data->dma.rx_chan_id = -1;
+       data->dma.tx_chan_id = -1;
+       data->dma.rx_param = data;
+       data->dma.tx_param = data;
+       data->dma.fn = dw8250_dma_filter;
+
        uart.port.iotype = UPIO_MEM;
        uart.port.serial_in = dw8250_serial_in;
        uart.port.serial_out = dw8250_serial_out;
@@ -324,7 +362,7 @@ static int dw8250_probe(struct platform_device *pdev)
                if (err)
                        return err;
        } else if (ACPI_HANDLE(&pdev->dev)) {
-               err = dw8250_probe_acpi(&uart);
+               err = dw8250_probe_acpi(&uart, data);
                if (err)
                        return err;
        } else {
index 5f3bba12c159eb4ceaef924495929f19eb5b4247..d1a9078003bd35caa7f6ee0f8a2f6d256751686c 100644 (file)
@@ -122,7 +122,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
        up.port.dev = &pdev->dev;
        up.port.private_data = priv;
 
-       clk_enable(priv->sclk);
+       clk_prepare_enable(priv->sclk);
        up.port.uartclk = clk_get_rate(priv->sclk);
 
        up.port.iotype = UPIO_MEM32;
@@ -134,7 +134,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
        ret = serial8250_register_8250_port(&up);
        if (ret < 0) {
                dev_err(&pdev->dev, "unable to register 8250 port\n");
-               clk_disable(priv->sclk);
+               clk_disable_unprepare(priv->sclk);
                return ret;
        }
 
@@ -148,7 +148,7 @@ static int serial8250_em_remove(struct platform_device *pdev)
        struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
 
        serial8250_unregister_port(priv->line);
-       clk_disable(priv->sclk);
+       clk_disable_unprepare(priv->sclk);
        return 0;
 }
 
index c810da7c7a8843d452ced857d64863993365b464..4697a514b80a6d2cafcd6a2800d8cdc820c6594f 100644 (file)
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License.
  */
+#undef DEBUG
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -27,8 +28,6 @@
 
 #include "8250.h"
 
-#undef SERIAL_DEBUG_PCI
-
 /*
  * init function returns:
  *  > 0 - number of ports
@@ -63,7 +62,7 @@ static int pci_default_setup(struct serial_private*,
 
 static void moan_device(const char *str, struct pci_dev *dev)
 {
-       printk(KERN_WARNING
+       dev_err(&dev->dev,
               "%s: %s\n"
               "Please send the output of lspci -vv, this\n"
               "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
@@ -233,7 +232,7 @@ static int pci_inteli960ni_init(struct pci_dev *dev)
        /* is firmware started? */
        pci_read_config_dword(dev, 0x44, (void *)&oldval);
        if (oldval == 0x00001000L) { /* RESET value */
-               printk(KERN_DEBUG "Local i960 firmware missing");
+               dev_dbg(&dev->dev, "Local i960 firmware missing\n");
                return -ENODEV;
        }
        return 0;
@@ -827,7 +826,7 @@ static int pci_netmos_9900_numports(struct pci_dev *dev)
                if (sub_serports > 0) {
                        return sub_serports;
                } else {
-                       printk(KERN_NOTICE "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
+                       dev_err(&dev->dev, "NetMos/Mostech serial driver ignoring port on ambiguous config.\n");
                        return 0;
                }
        }
@@ -931,7 +930,7 @@ static int pci_ite887x_init(struct pci_dev *dev)
        }
 
        if (!inta_addr[i]) {
-               printk(KERN_ERR "ite887x: could not find iobase\n");
+               dev_err(&dev->dev, "ite887x: could not find iobase\n");
                return -ENODEV;
        }
 
@@ -1024,9 +1023,9 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)
        /* Tornado device */
        if (deviceID == 0x07000200) {
                number_uarts = ioread8(p + 4);
-               printk(KERN_DEBUG
+               dev_dbg(&dev->dev,
                        "%d ports detected on Oxford PCI Express device\n",
-                                                               number_uarts);
+                       number_uarts);
        }
        pci_iounmap(dev, p);
        return number_uarts;
@@ -1308,6 +1307,29 @@ static int pci_default_setup(struct serial_private *priv,
        return setup_port(priv, port, bar, offset, board->reg_shift);
 }
 
+static int pci_pericom_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_8250_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset, maxnr;
+
+       bar = FL_GET_BASE(board->flags);
+       if (board->flags & FL_BASE_BARS)
+               bar += idx;
+       else
+               offset += idx * board->uart_offset;
+
+       maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
+               (board->reg_shift + 3);
+
+       if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
+               return 1;
+
+       port->port.uartclk = 14745600;
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
 static int
 ce4100_serial_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
@@ -1324,6 +1346,120 @@ ce4100_serial_setup(struct serial_private *priv,
        return ret;
 }
 
+#define PCI_DEVICE_ID_INTEL_BYT_UART1  0x0f0a
+#define PCI_DEVICE_ID_INTEL_BYT_UART2  0x0f0c
+
+#define BYT_PRV_CLK                    0x800
+#define BYT_PRV_CLK_EN                 (1 << 0)
+#define BYT_PRV_CLK_M_VAL_SHIFT                1
+#define BYT_PRV_CLK_N_VAL_SHIFT                16
+#define BYT_PRV_CLK_UPDATE             (1 << 31)
+
+#define BYT_GENERAL_REG                        0x808
+#define BYT_GENERAL_DIS_RTS_N_OVERRIDE (1 << 3)
+
+#define BYT_TX_OVF_INT                 0x820
+#define BYT_TX_OVF_INT_MASK            (1 << 1)
+
+static void
+byt_set_termios(struct uart_port *p, struct ktermios *termios,
+               struct ktermios *old)
+{
+       unsigned int baud = tty_termios_baud_rate(termios);
+       unsigned int m = 6912;
+       unsigned int n = 15625;
+       u32 reg;
+
+       /* For baud rates 1M, 2M, 3M and 4M the dividers must be adjusted. */
+       if (baud == 1000000 || baud == 2000000 || baud == 4000000) {
+               m = 64;
+               n = 100;
+
+               p->uartclk = 64000000;
+       } else if (baud == 3000000) {
+               m = 48;
+               n = 100;
+
+               p->uartclk = 48000000;
+       } else {
+               p->uartclk = 44236800;
+       }
+
+       /* Reset the clock */
+       reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT);
+       writel(reg, p->membase + BYT_PRV_CLK);
+       reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;
+       writel(reg, p->membase + BYT_PRV_CLK);
+
+       /*
+        * If auto-handshake mechanism is not enabled,
+        * disable rts_n override
+        */
+       reg = readl(p->membase + BYT_GENERAL_REG);
+       reg &= ~BYT_GENERAL_DIS_RTS_N_OVERRIDE;
+       if (termios->c_cflag & CRTSCTS)
+               reg |= BYT_GENERAL_DIS_RTS_N_OVERRIDE;
+       writel(reg, p->membase + BYT_GENERAL_REG);
+
+       serial8250_do_set_termios(p, termios, old);
+}
+
+static bool byt_dma_filter(struct dma_chan *chan, void *param)
+{
+       return chan->chan_id == *(int *)param;
+}
+
+static int
+byt_serial_setup(struct serial_private *priv,
+                const struct pciserial_board *board,
+                struct uart_8250_port *port, int idx)
+{
+       struct uart_8250_dma *dma;
+       int ret;
+
+       dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL);
+       if (!dma)
+               return -ENOMEM;
+
+       switch (priv->dev->device) {
+       case PCI_DEVICE_ID_INTEL_BYT_UART1:
+               dma->rx_chan_id = 3;
+               dma->tx_chan_id = 2;
+               break;
+       case PCI_DEVICE_ID_INTEL_BYT_UART2:
+               dma->rx_chan_id = 5;
+               dma->tx_chan_id = 4;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dma->rxconf.slave_id = dma->rx_chan_id;
+       dma->rxconf.src_maxburst = 16;
+
+       dma->txconf.slave_id = dma->tx_chan_id;
+       dma->txconf.dst_maxburst = 16;
+
+       dma->fn = byt_dma_filter;
+       dma->rx_param = &dma->rx_chan_id;
+       dma->tx_param = &dma->tx_chan_id;
+
+       ret = pci_default_setup(priv, board, port, idx);
+       port->port.iotype = UPIO_MEM;
+       port->port.type = PORT_16550A;
+       port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+       port->port.set_termios = byt_set_termios;
+       port->port.fifosize = 64;
+       port->tx_loadsz = 64;
+       port->dma = dma;
+       port->capabilities = UART_CAP_FIFO | UART_CAP_AFE;
+
+       /* Disable Tx counter interrupts */
+       writel(BYT_TX_OVF_INT_MASK, port->port.membase + BYT_TX_OVF_INT);
+
+       return ret;
+}
+
 static int
 pci_omegapci_setup(struct serial_private *priv,
                      const struct pciserial_board *board,
@@ -1344,17 +1480,80 @@ pci_brcm_trumanage_setup(struct serial_private *priv,
        return ret;
 }
 
+static int pci_fintek_setup(struct serial_private *priv,
+                           const struct pciserial_board *board,
+                           struct uart_8250_port *port, int idx)
+{
+       struct pci_dev *pdev = priv->dev;
+       unsigned long base;
+       unsigned long iobase;
+       unsigned long ciobase = 0;
+       u8 config_base;
+
+       /*
+        * We are supposed to be able to read these from the PCI config space,
+        * but the values there don't seem to match what we need to use, so
+        * just use these hard-coded values for now, as they are correct.
+        */
+       switch (idx) {
+       case 0: iobase = 0xe000; config_base = 0x40; break;
+       case 1: iobase = 0xe008; config_base = 0x48; break;
+       case 2: iobase = 0xe010; config_base = 0x50; break;
+       case 3: iobase = 0xe018; config_base = 0x58; break;
+       case 4: iobase = 0xe020; config_base = 0x60; break;
+       case 5: iobase = 0xe028; config_base = 0x68; break;
+       case 6: iobase = 0xe030; config_base = 0x70; break;
+       case 7: iobase = 0xe038; config_base = 0x78; break;
+       case 8: iobase = 0xe040; config_base = 0x80; break;
+       case 9: iobase = 0xe048; config_base = 0x88; break;
+       case 10: iobase = 0xe050; config_base = 0x90; break;
+       case 11: iobase = 0xe058; config_base = 0x98; break;
+       default:
+               /* Unknown number of ports, get out of here */
+               return -EINVAL;
+       }
+
+       if (idx < 4) {
+               base = pci_resource_start(priv->dev, 3);
+               ciobase = (int)(base + (0x8 * idx));
+       }
+
+       dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n",
+               __func__, idx, iobase, ciobase, config_base);
+
+       /* Enable UART I/O port */
+       pci_write_config_byte(pdev, config_base + 0x00, 0x01);
+
+       /* Select 128-byte FIFO and 8x FIFO threshold */
+       pci_write_config_byte(pdev, config_base + 0x01, 0x33);
+
+       /* LSB UART */
+       pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff));
+
+       /* MSB UART */
+       pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8));
+
+       /* irq number, this usually fails, but the spec says to do it anyway. */
+       pci_write_config_byte(pdev, config_base + 0x06, pdev->irq);
+
+       port->port.iotype = UPIO_PORT;
+       port->port.iobase = iobase;
+       port->port.mapbase = 0;
+       port->port.membase = NULL;
+       port->port.regshift = 0;
+
+       return 0;
+}
+
 static int skip_tx_en_setup(struct serial_private *priv,
                        const struct pciserial_board *board,
                        struct uart_8250_port *port, int idx)
 {
        port->port.flags |= UPF_NO_TXEN_TEST;
-       printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
-                         "[%04x:%04x] subsystem [%04x:%04x]\n",
-                         priv->dev->vendor,
-                         priv->dev->device,
-                         priv->dev->subsystem_vendor,
-                         priv->dev->subsystem_device);
+       dev_dbg(&priv->dev->dev,
+               "serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n",
+               priv->dev->vendor, priv->dev->device,
+               priv->dev->subsystem_vendor, priv->dev->subsystem_device);
 
        return pci_default_setup(priv, board, port, idx);
 }
@@ -1662,6 +1861,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = kt_serial_setup,
        },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_UART1,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = byt_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_UART2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = byt_serial_setup,
+       },
        /*
         * ITE
         */
@@ -1825,6 +2038,31 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .setup          = pci_default_setup,
                .exit           = pci_plx9050_exit,
        },
+       /*
+        * Pericom
+        */
+       {
+               .vendor         = 0x12d8,
+               .device         = 0x7952,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_pericom_setup,
+       },
+       {
+               .vendor         = 0x12d8,
+               .device         = 0x7954,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_pericom_setup,
+       },
+       {
+               .vendor         = 0x12d8,
+               .device         = 0x7958,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_pericom_setup,
+       },
+
        /*
         * PLX
         */
@@ -2255,6 +2493,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_brcm_trumanage_setup,
        },
+       {
+               .vendor         = 0x1c29,
+               .device         = 0x1104,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_fintek_setup,
+       },
+       {
+               .vendor         = 0x1c29,
+               .device         = 0x1108,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_fintek_setup,
+       },
+       {
+               .vendor         = 0x1c29,
+               .device         = 0x1112,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_fintek_setup,
+       },
 
        /*
         * Default "match everything" terminator entry
@@ -2449,9 +2708,13 @@ enum pci_board_num_t {
        pbn_ADDIDATA_PCIe_4_3906250,
        pbn_ADDIDATA_PCIe_8_3906250,
        pbn_ce4100_1_115200,
+       pbn_byt,
        pbn_omegapci,
        pbn_NETMOS9900_2s_115200,
        pbn_brcm_trumanage,
+       pbn_fintek_4,
+       pbn_fintek_8,
+       pbn_fintek_12,
 };
 
 /*
@@ -3185,6 +3448,13 @@ static struct pciserial_board pci_boards[] = {
                .base_baud      = 921600,
                .reg_shift      = 2,
        },
+       [pbn_byt] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 2764800,
+               .uart_offset    = 0x80,
+               .reg_shift      = 2,
+       },
        [pbn_omegapci] = {
                .flags          = FL_BASE0,
                .num_ports      = 8,
@@ -3202,6 +3472,24 @@ static struct pciserial_board pci_boards[] = {
                .reg_shift      = 2,
                .base_baud      = 115200,
        },
+       [pbn_fintek_4] = {
+               .num_ports      = 4,
+               .uart_offset    = 8,
+               .base_baud      = 115200,
+               .first_offset   = 0x40,
+       },
+       [pbn_fintek_8] = {
+               .num_ports      = 8,
+               .uart_offset    = 8,
+               .base_baud      = 115200,
+               .first_offset   = 0x40,
+       },
+       [pbn_fintek_12] = {
+               .num_ports      = 12,
+               .uart_offset    = 8,
+               .base_baud      = 115200,
+               .first_offset   = 0x40,
+       },
 };
 
 static const struct pci_device_id blacklist[] = {
@@ -3362,14 +3650,15 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
                if (quirk->setup(priv, board, &uart, i))
                        break;
 
-#ifdef SERIAL_DEBUG_PCI
-               printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
-                      uart.port.iobase, uart.port.irq, uart.port.iotype);
-#endif
+               dev_dbg(&dev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
+                       uart.port.iobase, uart.port.irq, uart.port.iotype);
 
                priv->line[i] = serial8250_register_8250_port(&uart);
                if (priv->line[i] < 0) {
-                       printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
+                       dev_err(&dev->dev,
+                               "Couldn't register serial port %lx, irq %d, type %d, error %d\n",
+                               uart.port.iobase, uart.port.irq,
+                               uart.port.iotype, priv->line[i]);
                        break;
                }
        }
@@ -3462,7 +3751,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
        }
 
        if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
-               printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
+               dev_err(&dev->dev, "invalid driver_data: %ld\n",
                        ent->driver_data);
                return -EINVAL;
        }
@@ -3520,8 +3809,6 @@ static void pciserial_remove_one(struct pci_dev *dev)
 {
        struct serial_private *priv = pci_get_drvdata(dev);
 
-       pci_set_drvdata(dev, NULL);
-
        pciserial_remove_ports(priv);
 
        pci_disable_device(dev);
@@ -3555,7 +3842,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
                err = pci_enable_device(dev);
                /* FIXME: We cannot simply error out here */
                if (err)
-                       printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n");
+                       dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n");
                pciserial_resume_ports(priv);
        }
        return 0;
@@ -4848,6 +5135,15 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
                PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
                pbn_ce4100_1_115200 },
+       /* Intel BayTrail */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART1,
+               PCI_ANY_ID,  PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+               pbn_byt },
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART2,
+               PCI_ANY_ID,  PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+               pbn_byt },
 
        /*
         * Cronyx Omega PCI
@@ -4918,6 +5214,11 @@ static struct pci_device_id serial_pci_tbl[] = {
                0,
                0, pbn_exar_XR17V358 },
 
+       /* Fintek PCI serial cards */
+       { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 },
+       { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 },
+       { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 },
+
        /*
         * These entries match devices with class COMMUNICATION_SERIAL,
         * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
index febd45cd50273532e99c1a4d790d2690c6ae750d..701ca60076ed80b537fcc32fe8fdce52ea6fd9dc 100644 (file)
@@ -1512,6 +1512,7 @@ config SERIAL_FSL_LPUART_CONSOLE
 config SERIAL_ST_ASC
        tristate "ST ASC serial port support"
        select SERIAL_CORE
+       depends on ARM || COMPILE_TEST
        help
          This driver is for the on-chip Asychronous Serial Controller on
          STMicroelectronics STi SoCs.
index 8b90f0b6dfdfe7838c43863350d93f9fccc41dae..33bd8606be6272d93f82e8aa6279cc00f6da87f0 100644 (file)
@@ -728,7 +728,6 @@ static int pl010_probe(struct amba_device *dev, const struct amba_id *id)
        amba_set_drvdata(dev, uap);
        ret = uart_add_one_port(&amba_reg, &uap->port);
        if (ret) {
-               amba_set_drvdata(dev, NULL);
                amba_ports[i] = NULL;
                clk_put(uap->clk);
  unmap:
@@ -745,8 +744,6 @@ static int pl010_remove(struct amba_device *dev)
        struct uart_amba_port *uap = amba_get_drvdata(dev);
        int i;
 
-       amba_set_drvdata(dev, NULL);
-
        uart_remove_one_port(&amba_reg, &uap->port);
 
        for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
index aaa22867e656dc60a65e4249ff231b76fb907c83..7203864992a523509ee0f0f42f47c36714a886aa 100644 (file)
@@ -2147,7 +2147,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
        amba_set_drvdata(dev, uap);
        ret = uart_add_one_port(&amba_reg, &uap->port);
        if (ret) {
-               amba_set_drvdata(dev, NULL);
                amba_ports[i] = NULL;
                pl011_dma_remove(uap);
        }
@@ -2160,8 +2159,6 @@ static int pl011_remove(struct amba_device *dev)
        struct uart_amba_port *uap = amba_get_drvdata(dev);
        int i;
 
-       amba_set_drvdata(dev, NULL);
-
        uart_remove_one_port(&amba_reg, &uap->port);
 
        for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
index 569872f4c9b848fea0f81eab72dd29865b0ded41..c9f5c9dcc15c48e7a15171db06f957bfe7fc6bfd 100644 (file)
@@ -533,7 +533,7 @@ arc_uart_init_one(struct platform_device *pdev, int dev_id)
        unsigned long *plat_data;
        struct arc_uart_port *uart = &arc_uart_ports[dev_id];
 
-       plat_data = (unsigned long *)dev_get_platdata(&pdev->dev);
+       plat_data = dev_get_platdata(&pdev->dev);
        if (!plat_data)
                return -ENODEV;
 
index 6b0f75eac8a26de2c6a3a83eac061ae7a03295cd..c7d99af46a966f1fdc9b9ebf0359756180e90b20 100644 (file)
@@ -99,6 +99,7 @@ static void atmel_stop_rx(struct uart_port *port);
 #define UART_PUT_RTOR(port,v)  __raw_writel(v, (port)->membase + ATMEL_US_RTOR)
 #define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR)
 #define UART_GET_IP_NAME(port) __raw_readl((port)->membase + ATMEL_US_NAME)
+#define UART_GET_IP_VERSION(port) __raw_readl((port)->membase + ATMEL_US_VERSION)
 
  /* PDC registers */
 #define UART_PUT_PTCR(port,v)  __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
@@ -1503,6 +1504,7 @@ static void atmel_get_ip_name(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
        int name = UART_GET_IP_NAME(port);
+       u32 version;
        int usart, uart;
        /* usart and uart ascii */
        usart = 0x55534152;
@@ -1517,7 +1519,22 @@ static void atmel_get_ip_name(struct uart_port *port)
                dev_dbg(port->dev, "This is uart\n");
                atmel_port->is_usart = false;
        } else {
-               dev_err(port->dev, "Not supported ip name, set to uart\n");
+               /* fallback for older SoCs: use version field */
+               version = UART_GET_IP_VERSION(port);
+               switch (version) {
+               case 0x302:
+               case 0x10213:
+                       dev_dbg(port->dev, "This version is usart\n");
+                       atmel_port->is_usart = true;
+                       break;
+               case 0x203:
+               case 0x10202:
+                       dev_dbg(port->dev, "This version is uart\n");
+                       atmel_port->is_usart = false;
+                       break;
+               default:
+                       dev_err(port->dev, "Not supported ip name nor version, set to uart\n");
+               }
        }
 }
 
index 87636cc61a2130db719a4e8d92a277cf2cb52cd3..4f229703328b6e2be09e0cfb111e8e81f8be1c79 100644 (file)
@@ -766,9 +766,8 @@ static int sport_uart_probe(struct platform_device *pdev)
                        return -ENOMEM;
                }
 
-               ret = peripheral_request_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev),
-                       DRV_NAME);
+               ret = peripheral_request_list(dev_get_platdata(&pdev->dev),
+                                               DRV_NAME);
                if (ret) {
                        dev_err(&pdev->dev,
                                "Fail to request SPORT peripherals\n");
@@ -844,8 +843,7 @@ static int sport_uart_probe(struct platform_device *pdev)
 out_error_unmap:
                iounmap(sport->port.membase);
 out_error_free_peripherals:
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
 out_error_free_mem:
                kfree(sport);
                bfin_sport_uart_ports[pdev->id] = NULL;
@@ -864,8 +862,7 @@ static int sport_uart_remove(struct platform_device *pdev)
        if (sport) {
                uart_remove_one_port(&sport_uart_reg, &sport->port);
                iounmap(sport->port.membase);
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
                kfree(sport);
                bfin_sport_uart_ports[pdev->id] = NULL;
        }
index 3c75e8e0402831dc5a94dda760a2b31a9c7fd7da..869ceba2ec57b54f54a2d0a5693640e72e8125bf 100644 (file)
@@ -680,7 +680,7 @@ static int bfin_serial_startup(struct uart_port *port)
                default:
                        uart_dma_ch_rx = uart_dma_ch_tx = 0;
                        break;
-               };
+               }
 
                if (uart_dma_ch_rx &&
                        request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) {
@@ -726,7 +726,7 @@ static int bfin_serial_startup(struct uart_port *port)
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
        if (uart->cts_pin >= 0) {
                if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int,
-                       IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
+                       0, "BFIN_UART_MODEM_STATUS", uart)) {
                        uart->cts_pin = -1;
                        dev_info(port->dev, "Unable to attach BlackFin UART Modem Status interrupt.\n");
                }
@@ -765,7 +765,7 @@ static void bfin_serial_shutdown(struct uart_port *port)
                break;
        default:
                break;
-       };
+       }
 #endif
        free_irq(uart->rx_irq, uart);
        free_irq(uart->tx_irq, uart);
@@ -1240,7 +1240,7 @@ static int bfin_serial_probe(struct platform_device *pdev)
                         */
 #endif
                ret = peripheral_request_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev),
+                       dev_get_platdata(&pdev->dev),
                        DRIVER_NAME);
                if (ret) {
                        dev_err(&pdev->dev,
@@ -1358,8 +1358,7 @@ static int bfin_serial_probe(struct platform_device *pdev)
 out_error_unmap:
                iounmap(uart->port.membase);
 out_error_free_peripherals:
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
 out_error_free_mem:
                kfree(uart);
                bfin_serial_ports[pdev->id] = NULL;
@@ -1377,8 +1376,7 @@ static int bfin_serial_remove(struct platform_device *pdev)
        if (uart) {
                uart_remove_one_port(&bfin_serial_reg, &uart->port);
                iounmap(uart->port.membase);
-               peripheral_free_list(
-                       (unsigned short *)dev_get_platdata(&pdev->dev));
+               peripheral_free_list(dev_get_platdata(&pdev->dev));
                kfree(uart);
                bfin_serial_ports[pdev->id] = NULL;
        }
@@ -1432,8 +1430,8 @@ static int bfin_earlyprintk_probe(struct platform_device *pdev)
                return -ENOENT;
        }
 
-       ret = peripheral_request_list(
-               (unsigned short *)dev_get_platdata(&pdev->dev), DRIVER_NAME);
+       ret = peripheral_request_list(dev_get_platdata(&pdev->dev),
+                                       DRIVER_NAME);
        if (ret) {
                dev_err(&pdev->dev,
                                "fail to request bfin serial peripherals\n");
@@ -1463,8 +1461,7 @@ static int bfin_earlyprintk_probe(struct platform_device *pdev)
        return 0;
 
 out_error_free_peripherals:
-       peripheral_free_list(
-               (unsigned short *)dev_get_platdata(&pdev->dev));
+       peripheral_free_list(dev_get_platdata(&pdev->dev));
 
        return ret;
 }
index 7e4e4088471cea4cbd6a67c49917b5af2540edc2..8d0b994357c856319b2ffae055d1e605a7a40706 100644 (file)
@@ -459,7 +459,6 @@ static int uart_clps711x_probe(struct platform_device *pdev)
        ret = uart_register_driver(&s->uart);
        if (ret) {
                dev_err(&pdev->dev, "Registering UART driver failed\n");
-               devm_clk_put(&pdev->dev, s->uart_clk);
                return ret;
        }
 
@@ -487,7 +486,6 @@ static int uart_clps711x_remove(struct platform_device *pdev)
        for (i = 0; i < UART_CLPS711X_NR; i++)
                uart_remove_one_port(&s->uart, &s->port[i]);
 
-       devm_clk_put(&pdev->dev, s->uart_clk);
        uart_unregister_driver(&s->uart);
 
        return 0;
index af286e6713eb914ccf30f334b69706a6510b1b97..590390970996b78fb9f274bae440625f433c7a8b 100644 (file)
@@ -1008,7 +1008,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       pl_data = (struct ifx_modem_platform_data *)dev_get_platdata(&spi->dev);
+       pl_data = dev_get_platdata(&spi->dev);
        if (!pl_data) {
                dev_err(&spi->dev, "missing platform data!");
                return -ENODEV;
index 042aa077b5b3e166a8453ac0684da1dd024f6785..b2cfdb661947ec2690fc4840e089688151749a68 100644 (file)
@@ -223,8 +223,7 @@ struct imx_port {
        struct dma_chan         *dma_chan_rx, *dma_chan_tx;
        struct scatterlist      rx_sgl, tx_sgl[2];
        void                    *rx_buf;
-       unsigned int            rx_bytes, tx_bytes;
-       struct work_struct      tsk_dma_rx, tsk_dma_tx;
+       unsigned int            tx_bytes;
        unsigned int            dma_tx_nents;
        wait_queue_head_t       dma_wait;
 };
@@ -505,34 +504,25 @@ static void dma_tx_callback(void *data)
                dev_dbg(sport->port.dev, "exit in %s.\n", __func__);
                return;
        }
-
-       schedule_work(&sport->tsk_dma_tx);
 }
 
-static void dma_tx_work(struct work_struct *w)
+static void imx_dma_tx(struct imx_port *sport)
 {
-       struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_tx);
        struct circ_buf *xmit = &sport->port.state->xmit;
        struct scatterlist *sgl = sport->tx_sgl;
        struct dma_async_tx_descriptor *desc;
        struct dma_chan *chan = sport->dma_chan_tx;
        struct device *dev = sport->port.dev;
        enum dma_status status;
-       unsigned long flags;
        int ret;
 
-       status = chan->device->device_tx_status(chan, (dma_cookie_t)0, NULL);
+       status = dmaengine_tx_status(chan, (dma_cookie_t)0, NULL);
        if (DMA_IN_PROGRESS == status)
                return;
 
-       spin_lock_irqsave(&sport->port.lock, flags);
        sport->tx_bytes = uart_circ_chars_pending(xmit);
-       if (sport->tx_bytes == 0) {
-               spin_unlock_irqrestore(&sport->port.lock, flags);
-               return;
-       }
 
-       if (xmit->tail > xmit->head) {
+       if (xmit->tail > xmit->head && xmit->head > 0) {
                sport->dma_tx_nents = 2;
                sg_init_table(sgl, 2);
                sg_set_buf(sgl, xmit->buf + xmit->tail,
@@ -542,7 +532,6 @@ static void dma_tx_work(struct work_struct *w)
                sport->dma_tx_nents = 1;
                sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
        }
-       spin_unlock_irqrestore(&sport->port.lock, flags);
 
        ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
        if (ret == 0) {
@@ -609,11 +598,7 @@ static void imx_start_tx(struct uart_port *port)
        }
 
        if (sport->dma_is_enabled) {
-               /*
-                * We may in the interrupt context, so arise a work_struct to
-                * do the real job.
-                */
-               schedule_work(&sport->tsk_dma_tx);
+               imx_dma_tx(sport);
                return;
        }
 
@@ -732,6 +717,7 @@ out:
        return IRQ_HANDLED;
 }
 
+static int start_rx_dma(struct imx_port *sport);
 /*
  * If the RXFIFO is filled with some data, and then we
  * arise a DMA operation to receive them.
@@ -750,7 +736,7 @@ static void imx_dma_rxint(struct imx_port *sport)
                writel(temp, sport->port.membase + UCR1);
 
                /* tell the DMA to receive the data. */
-               schedule_work(&sport->tsk_dma_rx);
+               start_rx_dma(sport);
        }
 }
 
@@ -795,8 +781,15 @@ static irqreturn_t imx_int(int irq, void *dev_id)
 static unsigned int imx_tx_empty(struct uart_port *port)
 {
        struct imx_port *sport = (struct imx_port *)port;
+       unsigned int ret;
+
+       ret = (readl(sport->port.membase + USR2) & USR2_TXDC) ?  TIOCSER_TEMT : 0;
 
-       return (readl(sport->port.membase + USR2) & USR2_TXDC) ?  TIOCSER_TEMT : 0;
+       /* If the TX DMA is working, return 0. */
+       if (sport->dma_is_enabled && sport->dma_is_txing)
+               ret = 0;
+
+       return ret;
 }
 
 /*
@@ -865,22 +858,6 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
 }
 
 #define RX_BUF_SIZE    (PAGE_SIZE)
-static int start_rx_dma(struct imx_port *sport);
-static void dma_rx_work(struct work_struct *w)
-{
-       struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_rx);
-       struct tty_port *port = &sport->port.state->port;
-
-       if (sport->rx_bytes) {
-               tty_insert_flip_string(port, sport->rx_buf, sport->rx_bytes);
-               tty_flip_buffer_push(port);
-               sport->rx_bytes = 0;
-       }
-
-       if (sport->dma_is_rxing)
-               start_rx_dma(sport);
-}
-
 static void imx_rx_dma_done(struct imx_port *sport)
 {
        unsigned long temp;
@@ -912,6 +889,7 @@ static void dma_rx_callback(void *data)
        struct imx_port *sport = data;
        struct dma_chan *chan = sport->dma_chan_rx;
        struct scatterlist *sgl = &sport->rx_sgl;
+       struct tty_port *port = &sport->port.state->port;
        struct dma_tx_state state;
        enum dma_status status;
        unsigned int count;
@@ -919,13 +897,15 @@ static void dma_rx_callback(void *data)
        /* unmap it first */
        dma_unmap_sg(sport->port.dev, sgl, 1, DMA_FROM_DEVICE);
 
-       status = chan->device->device_tx_status(chan, (dma_cookie_t)0, &state);
+       status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
        count = RX_BUF_SIZE - state.residue;
        dev_dbg(sport->port.dev, "We get %d bytes.\n", count);
 
        if (count) {
-               sport->rx_bytes = count;
-               schedule_work(&sport->tsk_dma_rx);
+               tty_insert_flip_string(port, sport->rx_buf, count);
+               tty_flip_buffer_push(port);
+
+               start_rx_dma(sport);
        } else
                imx_rx_dma_done(sport);
 }
@@ -1007,7 +987,6 @@ static int imx_uart_dma_init(struct imx_port *sport)
                ret = -ENOMEM;
                goto err;
        }
-       sport->rx_bytes = 0;
 
        /* Prepare for TX : */
        sport->dma_chan_tx = dma_request_slave_channel(dev, "tx");
@@ -1038,11 +1017,7 @@ err:
 static void imx_enable_dma(struct imx_port *sport)
 {
        unsigned long temp;
-       struct tty_port *port = &sport->port.state->port;
 
-       port->low_latency = 1;
-       INIT_WORK(&sport->tsk_dma_tx, dma_tx_work);
-       INIT_WORK(&sport->tsk_dma_rx, dma_rx_work);
        init_waitqueue_head(&sport->dma_wait);
 
        /* set UCR1 */
@@ -1063,7 +1038,6 @@ static void imx_enable_dma(struct imx_port *sport)
 static void imx_disable_dma(struct imx_port *sport)
 {
        unsigned long temp;
-       struct tty_port *port = &sport->port.state->port;
 
        /* clear UCR1 */
        temp = readl(sport->port.membase + UCR1);
@@ -1081,7 +1055,6 @@ static void imx_disable_dma(struct imx_port *sport)
        writel(temp, sport->port.membase + UCR4);
 
        sport->dma_is_enabled = 0;
-       port->low_latency = 0;
 }
 
 /* half the RX buffer size */
@@ -1303,6 +1276,16 @@ static void imx_shutdown(struct uart_port *port)
        clk_disable_unprepare(sport->clk_ipg);
 }
 
+static void imx_flush_buffer(struct uart_port *port)
+{
+       struct imx_port *sport = (struct imx_port *)port;
+
+       if (sport->dma_is_enabled) {
+               sport->tx_bytes = 0;
+               dmaengine_terminate_all(sport->dma_chan_tx);
+       }
+}
+
 static void
 imx_set_termios(struct uart_port *port, struct ktermios *termios,
                   struct ktermios *old)
@@ -1539,7 +1522,7 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
                ret = -EINVAL;
        if (sport->port.uartclk / 16 != ser->baud_base)
                ret = -EINVAL;
-       if ((void *)sport->port.mapbase != ser->iomem_base)
+       if (sport->port.mapbase != (unsigned long)ser->iomem_base)
                ret = -EINVAL;
        if (sport->port.iobase != ser->port)
                ret = -EINVAL;
@@ -1623,6 +1606,7 @@ static struct uart_ops imx_pops = {
        .break_ctl      = imx_break_ctl,
        .startup        = imx_startup,
        .shutdown       = imx_shutdown,
+       .flush_buffer   = imx_flush_buffer,
        .set_termios    = imx_set_termios,
        .type           = imx_type,
        .release_port   = imx_release_port,
index cb3c81eb09964dd6c20a998df74a787717192dcd..1d9420548e169a312e2f6ecacb44948e560c0869 100644 (file)
@@ -832,7 +832,7 @@ ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
                up->curregs[5] |= Tx8;
                up->parity_mask = 0xff;
                break;
-       };
+       }
        up->curregs[4] &= ~0x0c;
        if (cflag & CSTOPB)
                up->curregs[4] |= SB2;
index b2e707aa603a52daeff7762bf81a7e82397fc831..8d71e4047bb300d0e1a12af83f2263297c4a29bc 100644 (file)
@@ -690,7 +690,7 @@ static void max310x_handle_tx(struct uart_port *port)
                        max310x_port_write(port, MAX310X_THR_REG,
                                           xmit->buf[xmit->tail]);
                        xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               };
+               }
        }
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
index d3db042f649eda154bdbe1e7feb81dc5822f8653..503dcc77b2bd1285a8c3ae79e1ac6384b0392dbd 100644 (file)
@@ -1451,7 +1451,6 @@ static void serial_hsu_remove(struct pci_dev *pdev)
                uart_remove_one_port(&serial_hsu_reg, &up->port);
        }
 
-       pci_set_drvdata(pdev, NULL);
        free_irq(pdev->irq, priv);
        pci_disable_device(pdev);
 }
@@ -1504,4 +1503,4 @@ module_init(hsu_pci_init);
 module_exit(hsu_pci_exit);
 
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:medfield-hsu");
+MODULE_DEVICE_TABLE(pci, pci_ids);
index 5be1df39f9f5f6b8fe0671bba23ba8f566e685f4..ec06505e3ae63704d73f44ad23252b3de7bc6656 100644 (file)
@@ -1301,7 +1301,6 @@ static struct uart_ops mpc52xx_uart_ops = {
        .shutdown       = mpc52xx_uart_shutdown,
        .set_termios    = mpc52xx_uart_set_termios,
 /*     .pm             = mpc52xx_uart_pm,              Not supported yet */
-/*     .set_wake       = mpc52xx_uart_set_wake,        Not supported yet */
        .type           = mpc52xx_uart_type,
        .release_port   = mpc52xx_uart_release_port,
        .request_port   = mpc52xx_uart_request_port,
@@ -1766,7 +1765,7 @@ mpc52xx_uart_of_remove(struct platform_device *op)
 static int
 mpc52xx_uart_of_suspend(struct platform_device *op, pm_message_t state)
 {
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(op);
+       struct uart_port *port = platform_get_drvdata(op);
 
        if (port)
                uart_suspend_port(&mpc52xx_uart_driver, port);
@@ -1777,7 +1776,7 @@ mpc52xx_uart_of_suspend(struct platform_device *op, pm_message_t state)
 static int
 mpc52xx_uart_of_resume(struct platform_device *op)
 {
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(op);
+       struct uart_port *port = platform_get_drvdata(op);
 
        if (port)
                uart_resume_port(&mpc52xx_uart_driver, port);
index 8d702677acc5911c002134f85236090eeb793d10..e30a3ca3cea39f8b34765401e1fad569265f7ebb 100644 (file)
@@ -2030,7 +2030,7 @@ static void mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
 {
        struct mpsc_pdata       *pdata;
 
-       pdata = (struct mpsc_pdata *)dev_get_platdata(&pd->dev);
+       pdata = dev_get_platdata(&pd->dev);
 
        pi->port.uartclk = pdata->brg_clk_freq;
        pi->port.iotype = UPIO_MEM;
index a67e7081f0018d640ecef090394be1f828ec04c5..565779dc7aac80c6a8ce7a20ac53bc6ef76c56fb 100644 (file)
@@ -61,6 +61,7 @@ struct uart_max3110 {
        struct task_struct *main_thread;
        struct task_struct *read_thread;
        struct mutex thread_mutex;
+       struct mutex io_mutex;
 
        u32 baud;
        u16 cur_conf;
@@ -90,6 +91,7 @@ static int max3110_write_then_read(struct uart_max3110 *max,
        struct spi_transfer     x;
        int ret;
 
+       mutex_lock(&max->io_mutex);
        spi_message_init(&message);
        memset(&x, 0, sizeof x);
        x.len = len;
@@ -104,6 +106,7 @@ static int max3110_write_then_read(struct uart_max3110 *max,
 
        /* Do the i/o */
        ret = spi_sync(spi, &message);
+       mutex_unlock(&max->io_mutex);
        return ret;
 }
 
@@ -749,7 +752,8 @@ static int serial_m3110_suspend(struct device *dev)
        struct spi_device *spi = to_spi_device(dev);
        struct uart_max3110 *max = spi_get_drvdata(spi);
 
-       disable_irq(max->irq);
+       if (max->irq > 0)
+               disable_irq(max->irq);
        uart_suspend_port(&serial_m3110_reg, &max->port);
        max3110_out(max, max->cur_conf | WC_SW_SHDI);
        return 0;
@@ -762,7 +766,8 @@ static int serial_m3110_resume(struct device *dev)
 
        max3110_out(max, max->cur_conf);
        uart_resume_port(&serial_m3110_reg, &max->port);
-       enable_irq(max->irq);
+       if (max->irq > 0)
+               enable_irq(max->irq);
        return 0;
 }
 
@@ -803,6 +808,7 @@ static int serial_m3110_probe(struct spi_device *spi)
        max->irq = (u16)spi->irq;
 
        mutex_init(&max->thread_mutex);
+       mutex_init(&max->io_mutex);
 
        max->word_7bits = 0;
        max->parity = 0;
index 10e9d70b5c4066fced345848f592dc11582c1cfb..d8b6fee77a039220ae8d7d8f08a9ff8e08c7066f 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/cacheflush.h>
 
 #define MXS_AUART_PORTS 5
+#define MXS_AUART_FIFO_SIZE            16
 
 #define AUART_CTRL0                    0x00000000
 #define AUART_CTRL0_SET                        0x00000004
@@ -548,6 +549,9 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s)
        s->flags |= MXS_AUART_DMA_ENABLED;
        dev_dbg(s->dev, "enabled the DMA support.");
 
+       /* The DMA buffer is now the FIFO the TTY subsystem can use */
+       s->port.fifosize = UART_XMIT_SIZE;
+
        return 0;
 
 err_out:
@@ -741,6 +745,9 @@ static int mxs_auart_startup(struct uart_port *u)
        writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
                        u->membase + AUART_INTR);
 
+       /* Reset FIFO size (it could have changed if DMA was enabled) */
+       u->fifosize = MXS_AUART_FIFO_SIZE;
+
        /*
         * Enable fifo so all four bytes of a DMA word are written to
         * output (otherwise, only the LSB is written, ie. 1 in 4 bytes)
@@ -1056,7 +1063,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
        s->port.membase = ioremap(r->start, resource_size(r));
        s->port.ops = &mxs_auart_ops;
        s->port.iotype = UPIO_MEM;
-       s->port.fifosize = 16;
+       s->port.fifosize = MXS_AUART_FIFO_SIZE;
        s->port.uartclk = clk_get_rate(s->clk);
        s->port.type = PORT_IMX;
        s->port.dev = s->dev = &pdev->dev;
index 816d1a23f9d0ef725318afbf01448aa587a3371c..c715778a745c34f104dadb11515aa5bca2f14429 100644 (file)
@@ -247,7 +247,7 @@ serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud)
        if(baudAbsDiff16 < 0)
                baudAbsDiff16 = -baudAbsDiff16;
 
-       return (baudAbsDiff13 > baudAbsDiff16);
+       return (baudAbsDiff13 >= baudAbsDiff16);
 }
 
 /*
@@ -258,13 +258,13 @@ serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud)
 static unsigned int
 serial_omap_get_divisor(struct uart_port *port, unsigned int baud)
 {
-       unsigned int divisor;
+       unsigned int mode;
 
        if (!serial_omap_baud_is_mode16(port, baud))
-               divisor = 13;
+               mode = 13;
        else
-               divisor = 16;
-       return port->uartclk/(baud * divisor);
+               mode = 16;
+       return port->uartclk/(mode * baud);
 }
 
 static void serial_omap_enable_ms(struct uart_port *port)
@@ -1060,15 +1060,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line);
 }
 
-static int serial_omap_set_wake(struct uart_port *port, unsigned int state)
-{
-       struct uart_omap_port *up = to_uart_omap_port(port);
-
-       serial_omap_enable_wakeup(up, state);
-
-       return 0;
-}
-
 static void
 serial_omap_pm(struct uart_port *port, unsigned int state,
               unsigned int oldstate)
@@ -1401,7 +1392,6 @@ static struct uart_ops serial_omap_pops = {
        .shutdown       = serial_omap_shutdown,
        .set_termios    = serial_omap_set_termios,
        .pm             = serial_omap_pm,
-       .set_wake       = serial_omap_set_wake,
        .type           = serial_omap_type,
        .release_port   = serial_omap_release_port,
        .request_port   = serial_omap_request_port,
index 44077c0b7670075625650c9d00cc98a63bb90f5c..0aa2b528ef3d76363c3cd9dcc4ebd96adee850a8 100644 (file)
@@ -1614,7 +1614,6 @@ static struct uart_ops pch_uart_ops = {
        .shutdown = pch_uart_shutdown,
        .set_termios = pch_uart_set_termios,
 /*     .pm             = pch_uart_pm,          Not supported yet */
-/*     .set_wake       = pch_uart_set_wake,    Not supported yet */
        .type = pch_uart_type,
        .release_port = pch_uart_release_port,
        .request_port = pch_uart_request_port,
@@ -1996,6 +1995,8 @@ module_exit(pch_uart_module_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Intel EG20T PCH UART PCI Driver");
+MODULE_DEVICE_TABLE(pci, pch_uart_pci_id);
+
 module_param(default_baud, uint, S_IRUGO);
 MODULE_PARM_DESC(default_baud,
                  "Default BAUD for initial driver state and console (default 9600)");
index 246b4c327a543a3ec2d2a6742b9c051b2782887b..481b781b26e370e23fea8d2088311562c15cde87 100644 (file)
@@ -1074,7 +1074,7 @@ static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag,
                uap->curregs[5] |= Tx8;
                uap->parity_mask = 0xff;
                break;
-       };
+       }
        uap->curregs[4] &= ~(SB_MASK);
        if (cflag & CSTOPB)
                uap->curregs[4] |= SB2;
index ba25722a7131ba11246c88a26a800fa7493b69bb..753d4525b36743ab23aaeed37c0205b39fb21788 100644 (file)
@@ -647,7 +647,10 @@ void sa1100_register_uart_fns(struct sa1100_port_fns *fns)
                sa1100_pops.set_mctrl = fns->set_mctrl;
 
        sa1100_pops.pm       = fns->pm;
-       sa1100_pops.set_wake = fns->set_wake;
+       /*
+        * FIXME: fns->set_wake is unused - this should be called from
+        * the suspend() callback if device_may_wakeup(dev)) is set.
+        */
 }
 
 void __init sa1100_register_uart(int idx, int port)
index f3dfa19a1cb86eb4c8dd0b47ea8f23b8bab5f0e8..c1af04d46682657794b4893f3eac571a13acc685 100644 (file)
@@ -407,7 +407,14 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
 
 static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
-       /* todo - possibly remove AFC and do manual CTS */
+       unsigned int umcon = rd_regl(port, S3C2410_UMCON);
+
+       if (mctrl & TIOCM_RTS)
+               umcon |= S3C2410_UMCOM_RTS_LOW;
+       else
+               umcon &= ~S3C2410_UMCOM_RTS_LOW;
+
+       wr_regl(port, S3C2410_UMCON, umcon);
 }
 
 static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
@@ -774,8 +781,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
        if (termios->c_cflag & CSTOPB)
                ulcon |= S3C2410_LCON_STOPB;
 
-       umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;
-
        if (termios->c_cflag & PARENB) {
                if (termios->c_cflag & PARODD)
                        ulcon |= S3C2410_LCON_PODD;
@@ -792,6 +797,15 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
 
        wr_regl(port, S3C2410_ULCON, ulcon);
        wr_regl(port, S3C2410_UBRDIV, quot);
+
+       umcon = rd_regl(port, S3C2410_UMCON);
+       if (termios->c_cflag & CRTSCTS) {
+               umcon |= S3C2410_UMCOM_AFC;
+               /* Disable RTS when RX FIFO contains 63 bytes */
+               umcon &= ~S3C2412_UMCON_AFC_8;
+       } else {
+               umcon &= ~S3C2410_UMCOM_AFC;
+       }
        wr_regl(port, S3C2410_UMCON, umcon);
 
        if (ourport->info->has_divslot)
@@ -1254,7 +1268,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
        ourport->baudclk = ERR_PTR(-EINVAL);
        ourport->info = ourport->drv_data->info;
        ourport->cfg = (dev_get_platdata(&pdev->dev)) ?
-                       (struct s3c2410_uartcfg *)dev_get_platdata(&pdev->dev) :
+                       dev_get_platdata(&pdev->dev) :
                        ourport->drv_data->def_cfg;
 
        ourport->port.fifosize = (ourport->info->fifosize) ?
index aaa617a6c4995e1d978ed88ab33878f232ba8b97..8827e5424cef7d13420114650bdcfa19cad91ea0 100644 (file)
@@ -63,7 +63,7 @@ struct s3c24xx_uart_port {
 
 /* conversion functions */
 
-#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
+#define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
 
 /* register access controls */
 
index 49e9bbfe6cab525454c5b4337b741cbd5fcafcd0..a447f71538ef2c07d77fa92f69247559fa83ebf1 100644 (file)
@@ -986,6 +986,7 @@ static int sccnxp_probe(struct platform_device *pdev)
                return 0;
        }
 
+       uart_unregister_driver(&s->uart);
 err_out:
        if (!IS_ERR(s->regulator))
                return regulator_disable(s->regulator);
index 0489a2bdcdf9a1aff4af5dacd1d7766f9671a523..dfe79ccc4fb3c66f473604c2ac867b181e6e7e00 100644 (file)
@@ -1018,7 +1018,7 @@ static int tegra_uart_startup(struct uart_port *u)
                goto fail_hw_init;
        }
 
-       ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED,
+       ret = request_irq(u->irq, tegra_uart_isr, 0,
                                dev_name(u->dev), tup);
        if (ret < 0) {
                dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq);
index 440a962412da9251c10aa60ee6cf25cf2624474a..90a080b1f9ee13cd78d6647245ee91eb1c710da4 100644 (file)
@@ -1220,8 +1220,6 @@ static void pciserial_txx9_remove_one(struct pci_dev *dev)
 {
        struct uart_txx9_port *up = pci_get_drvdata(dev);
 
-       pci_set_drvdata(dev, NULL);
-
        if (up) {
                serial_txx9_unregister_port(up->port.line);
                pci_disable_device(dev);
index 61c1ad03db5b0159d6b7735838a2a0cb800d7bbd..f186a8fb8887119cd036625a129f515bb57f4210 100644 (file)
@@ -529,7 +529,7 @@ static void sirfsoc_rx_tmo_process_tl(unsigned long param)
        while (sirfport->rx_completed != sirfport->rx_issued) {
                sirfsoc_uart_insert_rx_buf_to_tty(sirfport,
                                        SIRFSOC_RX_DMA_BUF_SIZE);
-               sirfsoc_rx_submit_one_dma_desc(port, sirfport->rx_completed++);
+               sirfport->rx_completed++;
                sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT;
        }
        count = CIRC_CNT(sirfport->rx_dma_items[sirfport->rx_issued].xmit.head,
@@ -706,12 +706,19 @@ static void sirfsoc_uart_rx_dma_complete_tl(unsigned long param)
 {
        struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param;
        struct uart_port *port = &sirfport->port;
+       struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
+       struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
        unsigned long flags;
        spin_lock_irqsave(&sirfport->rx_lock, flags);
        while (sirfport->rx_completed != sirfport->rx_issued) {
                sirfsoc_uart_insert_rx_buf_to_tty(sirfport,
                                        SIRFSOC_RX_DMA_BUF_SIZE);
-               sirfsoc_rx_submit_one_dma_desc(port, sirfport->rx_completed++);
+               if (rd_regl(port, ureg->sirfsoc_int_en_reg) &
+                               uint_en->sirfsoc_rx_timeout_en)
+                       sirfsoc_rx_submit_one_dma_desc(port,
+                                       sirfport->rx_completed++);
+               else
+                       sirfport->rx_completed++;
                sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT;
        }
        spin_unlock_irqrestore(&sirfport->rx_lock, flags);
index 5d6136b2a04a8c488e609696952e5517d5cc412a..380fb5355cb26ae68a472a4e6097c57556d0b8e1 100644 (file)
@@ -894,7 +894,7 @@ static int sunsab_console_setup(struct console *con, char *options)
        case B115200: baud = 115200; break;
        case B230400: baud = 230400; break;
        case B460800: baud = 460800; break;
-       };
+       }
 
        /*
         * Temporary fix.
index 699cc1b5f6aa2c5c39cd89a2bb8ea5b192140015..db79b76f5c8e978e09824b719d585cf470d75d68 100644 (file)
@@ -522,7 +522,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break)
                                serio_interrupt(&up->serio, ch, 0);
 #endif
                                break;
-                       };
+                       }
                }
        } while (serial_in(up, UART_LSR) & UART_LSR_DR);
 }
index 135a1520353260e8f6665538ccce381e3036c562..45a8c6aa583797ba717ec3da79a24929a6eb425f 100644 (file)
@@ -319,7 +319,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
                                serio_interrupt(&up->serio, ch, 0);
 #endif
                        break;
-               };
+               }
        }
 }
 
@@ -897,7 +897,7 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
                up->curregs[R5] |= Tx8;
                up->parity_mask = 0xff;
                break;
-       };
+       }
        up->curregs[R4] &= ~0x0c;
        if (cflag & CSTOPB)
                up->curregs[R4] |= SB2;
@@ -1239,7 +1239,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
        default: case B9600: baud = 9600; break;
        case B19200: baud = 19200; break;
        case B38400: baud = 38400; break;
-       };
+       }
 
        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 
index 9de1da0c9d891fddf6eb155f897ba54f341a0591..d569ca58bab6cd9f092361b2656105a57dc11846 100644 (file)
@@ -271,7 +271,7 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port)
                        return 1;
 
                bdp++;
-       };
+       }
 }
 
 /*
index 7e4150aa69c65b34c44e526c5633bf456f1abe2f..c7c96c2f149cb76e613fcc144b06feae18b4b2d6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Xilinx PS UART driver
  *
- * 2011 (c) Xilinx Inc.
+ * 2011 - 2013 (C) Xilinx Inc.
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General Public
  *
  */
 
+#if defined(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
 #include <linux/platform_device.h>
 #include <linux/serial.h>
+#include <linux/console.h>
 #include <linux/serial_core.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
-#include <linux/console.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #define XUARTPS_MAJOR          0       /* use dynamic node allocation */
 #define XUARTPS_MINOR          0       /* works best with devtmpfs */
 #define XUARTPS_NR_PORTS       2
-#define XUARTPS_FIFO_SIZE      16      /* FIFO size */
+#define XUARTPS_FIFO_SIZE      64      /* FIFO size */
 #define XUARTPS_REGISTER_SPACE 0xFFF
 
 #define xuartps_readl(offset)          ioread32(port->membase + offset)
 #define xuartps_writel(val, offset)    iowrite32(val, port->membase + offset)
 
+/* Rx Trigger level */
+static int rx_trigger_level = 56;
+module_param(rx_trigger_level, uint, S_IRUGO);
+MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
+
+/* Rx Timeout */
+static int rx_timeout = 10;
+module_param(rx_timeout, uint, S_IRUGO);
+MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
+
 /********************************Register Map********************************/
 /** UART
  *
 #define XUARTPS_IXR_RXEMPTY    0x00000002 /* RX FIFO empty interrupt. */
 #define XUARTPS_IXR_MASK       0x00001FFF /* Valid bit mask */
 
+/* Goes in read_status_mask for break detection as the HW doesn't do it*/
+#define XUARTPS_IXR_BRK                0x80000000
+
 /** Channel Status Register
  *
  * The channel status register (CSR) is provided to enable the control logic
 #define XUARTPS_SR_TXFULL      0x00000010 /* TX FIFO full */
 #define XUARTPS_SR_RXTRIG      0x00000001 /* Rx Trigger */
 
+/* baud dividers min/max values */
+#define XUARTPS_BDIV_MIN       4
+#define XUARTPS_BDIV_MAX       255
+#define XUARTPS_CD_MAX         65535
+
 /**
  * struct xuartps - device data
- * @refclk     Reference clock
- * @aperclk    APB clock
+ * @port               Pointer to the UART port
+ * @refclk             Reference clock
+ * @aperclk            APB clock
+ * @baud               Current baud rate
+ * @clk_rate_change_nb Notifier block for clock changes
  */
 struct xuartps {
+       struct uart_port        *port;
        struct clk              *refclk;
        struct clk              *aperclk;
+       unsigned int            baud;
+       struct notifier_block   clk_rate_change_nb;
 };
+#define to_xuartps(_nb) container_of(_nb, struct xuartps, clk_rate_change_nb);
 
 /**
  * xuartps_isr - Interrupt handler
@@ -171,6 +200,23 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
         */
        isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET);
 
+       /*
+        * There is no hardware break detection, so we interpret framing
+        * error with all-zeros data as a break sequence. Most of the time,
+        * there's another non-zero byte at the end of the sequence.
+        */
+
+       if (isrstatus & XUARTPS_IXR_FRAMING) {
+               while (!(xuartps_readl(XUARTPS_SR_OFFSET) &
+                                       XUARTPS_SR_RXEMPTY)) {
+                       if (!xuartps_readl(XUARTPS_FIFO_OFFSET)) {
+                               port->read_status_mask |= XUARTPS_IXR_BRK;
+                               isrstatus &= ~XUARTPS_IXR_FRAMING;
+                       }
+               }
+               xuartps_writel(XUARTPS_IXR_FRAMING, XUARTPS_ISR_OFFSET);
+       }
+
        /* drop byte with parity error if IGNPAR specified */
        if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY)
                isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT);
@@ -184,6 +230,30 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
                while ((xuartps_readl(XUARTPS_SR_OFFSET) &
                        XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) {
                        data = xuartps_readl(XUARTPS_FIFO_OFFSET);
+
+                       /* Non-NULL byte after BREAK is garbage (99%) */
+                       if (data && (port->read_status_mask &
+                                               XUARTPS_IXR_BRK)) {
+                               port->read_status_mask &= ~XUARTPS_IXR_BRK;
+                               port->icount.brk++;
+                               if (uart_handle_break(port))
+                                       continue;
+                       }
+
+                       /*
+                        * uart_handle_sysrq_char() doesn't work if
+                        * spinlocked, for some reason
+                        */
+                        if (port->sysrq) {
+                               spin_unlock(&port->lock);
+                               if (uart_handle_sysrq_char(port,
+                                                       (unsigned char)data)) {
+                                       spin_lock(&port->lock);
+                                       continue;
+                               }
+                               spin_lock(&port->lock);
+                       }
+
                        port->icount.rx++;
 
                        if (isrstatus & XUARTPS_IXR_PARITY) {
@@ -247,63 +317,194 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
 }
 
 /**
- * xuartps_set_baud_rate - Calculate and set the baud rate
- * @port: Handle to the uart port structure
- * @baud: Baud rate to set
- *
+ * xuartps_calc_baud_divs - Calculate baud rate divisors
+ * @clk: UART module input clock
+ * @baud: Desired baud rate
+ * @rbdiv: BDIV value (return value)
+ * @rcd: CD value (return value)
+ * @div8: Value for clk_sel bit in mod (return value)
  * Returns baud rate, requested baud when possible, or actual baud when there
- *     was too much error
- **/
-static unsigned int xuartps_set_baud_rate(struct uart_port *port,
-                                               unsigned int baud)
+ *     was too much error, zero if no valid divisors are found.
+ *
+ * Formula to obtain baud rate is
+ *     baud_tx/rx rate = clk/CD * (BDIV + 1)
+ *     input_clk = (Uart User Defined Clock or Apb Clock)
+ *             depends on UCLKEN in MR Reg
+ *     clk = input_clk or input_clk/8;
+ *             depends on CLKS in MR reg
+ *     CD and BDIV depends on values in
+ *                     baud rate generate register
+ *                     baud rate clock divisor register
+ */
+static unsigned int xuartps_calc_baud_divs(unsigned int clk, unsigned int baud,
+               u32 *rbdiv, u32 *rcd, int *div8)
 {
-       unsigned int sel_clk;
-       unsigned int calc_baud = 0;
-       unsigned int brgr_val, brdiv_val;
+       u32 cd, bdiv;
+       unsigned int calc_baud;
+       unsigned int bestbaud = 0;
        unsigned int bauderror;
+       unsigned int besterror = ~0;
 
-       /* Formula to obtain baud rate is
-        *      baud_tx/rx rate = sel_clk/CD * (BDIV + 1)
-        *      input_clk = (Uart User Defined Clock or Apb Clock)
-        *              depends on UCLKEN in MR Reg
-        *      sel_clk = input_clk or input_clk/8;
-        *              depends on CLKS in MR reg
-        *      CD and BDIV depends on values in
-        *                      baud rate generate register
-        *                      baud rate clock divisor register
-        */
-       sel_clk = port->uartclk;
-       if (xuartps_readl(XUARTPS_MR_OFFSET) & XUARTPS_MR_CLKSEL)
-               sel_clk = sel_clk / 8;
-
-       /* Find the best values for baud generation */
-       for (brdiv_val = 4; brdiv_val < 255; brdiv_val++) {
+       if (baud < clk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX)) {
+               *div8 = 1;
+               clk /= 8;
+       } else {
+               *div8 = 0;
+       }
 
-               brgr_val = sel_clk / (baud * (brdiv_val + 1));
-               if (brgr_val < 2 || brgr_val > 65535)
+       for (bdiv = XUARTPS_BDIV_MIN; bdiv <= XUARTPS_BDIV_MAX; bdiv++) {
+               cd = DIV_ROUND_CLOSEST(clk, baud * (bdiv + 1));
+               if (cd < 1 || cd > XUARTPS_CD_MAX)
                        continue;
 
-               calc_baud = sel_clk / (brgr_val * (brdiv_val + 1));
+               calc_baud = clk / (cd * (bdiv + 1));
 
                if (baud > calc_baud)
                        bauderror = baud - calc_baud;
                else
                        bauderror = calc_baud - baud;
 
-               /* use the values when percent error is acceptable */
-               if (((bauderror * 100) / baud) < 3) {
-                       calc_baud = baud;
-                       break;
+               if (besterror > bauderror) {
+                       *rbdiv = bdiv;
+                       *rcd = cd;
+                       bestbaud = calc_baud;
+                       besterror = bauderror;
                }
        }
+       /* use the values when percent error is acceptable */
+       if (((besterror * 100) / baud) < 3)
+               bestbaud = baud;
+
+       return bestbaud;
+}
 
-       /* Set the values for the new baud rate */
-       xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET);
-       xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET);
+/**
+ * xuartps_set_baud_rate - Calculate and set the baud rate
+ * @port: Handle to the uart port structure
+ * @baud: Baud rate to set
+ * Returns baud rate, requested baud when possible, or actual baud when there
+ *        was too much error, zero if no valid divisors are found.
+ */
+static unsigned int xuartps_set_baud_rate(struct uart_port *port,
+               unsigned int baud)
+{
+       unsigned int calc_baud;
+       u32 cd, bdiv;
+       u32 mreg;
+       int div8;
+       struct xuartps *xuartps = port->private_data;
+
+       calc_baud = xuartps_calc_baud_divs(port->uartclk, baud, &bdiv, &cd,
+                       &div8);
+
+       /* Write new divisors to hardware */
+       mreg = xuartps_readl(XUARTPS_MR_OFFSET);
+       if (div8)
+               mreg |= XUARTPS_MR_CLKSEL;
+       else
+               mreg &= ~XUARTPS_MR_CLKSEL;
+       xuartps_writel(mreg, XUARTPS_MR_OFFSET);
+       xuartps_writel(cd, XUARTPS_BAUDGEN_OFFSET);
+       xuartps_writel(bdiv, XUARTPS_BAUDDIV_OFFSET);
+       xuartps->baud = baud;
 
        return calc_baud;
 }
 
+/**
+ * xuartps_clk_notitifer_cb - Clock notifier callback
+ * @nb:                Notifier block
+ * @event:     Notify event
+ * @data:      Notifier data
+ * Returns NOTIFY_OK on success, NOTIFY_BAD on error.
+ */
+static int xuartps_clk_notifier_cb(struct notifier_block *nb,
+               unsigned long event, void *data)
+{
+       u32 ctrl_reg;
+       struct uart_port *port;
+       int locked = 0;
+       struct clk_notifier_data *ndata = data;
+       unsigned long flags = 0;
+       struct xuartps *xuartps = to_xuartps(nb);
+
+       port = xuartps->port;
+       if (port->suspended)
+               return NOTIFY_OK;
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+       {
+               u32 bdiv;
+               u32 cd;
+               int div8;
+
+               /*
+                * Find out if current baud-rate can be achieved with new clock
+                * frequency.
+                */
+               if (!xuartps_calc_baud_divs(ndata->new_rate, xuartps->baud,
+                                       &bdiv, &cd, &div8))
+                       return NOTIFY_BAD;
+
+               spin_lock_irqsave(&xuartps->port->lock, flags);
+
+               /* Disable the TX and RX to set baud rate */
+               xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+                               (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS),
+                               XUARTPS_CR_OFFSET);
+
+               spin_unlock_irqrestore(&xuartps->port->lock, flags);
+
+               return NOTIFY_OK;
+       }
+       case POST_RATE_CHANGE:
+               /*
+                * Set clk dividers to generate correct baud with new clock
+                * frequency.
+                */
+
+               spin_lock_irqsave(&xuartps->port->lock, flags);
+
+               locked = 1;
+               port->uartclk = ndata->new_rate;
+
+               xuartps->baud = xuartps_set_baud_rate(xuartps->port,
+                               xuartps->baud);
+               /* fall through */
+       case ABORT_RATE_CHANGE:
+               if (!locked)
+                       spin_lock_irqsave(&xuartps->port->lock, flags);
+
+               /* Set TX/RX Reset */
+               xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST),
+                               XUARTPS_CR_OFFSET);
+
+               while (xuartps_readl(XUARTPS_CR_OFFSET) &
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST))
+                       cpu_relax();
+
+               /*
+                * Clear the RX disable and TX disable bits and then set the TX
+                * enable bit and RX enable bit to enable the transmitter and
+                * receiver.
+                */
+               xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
+               ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET);
+               xuartps_writel(
+                       (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) |
+                       (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
+                       XUARTPS_CR_OFFSET);
+
+               spin_unlock_irqrestore(&xuartps->port->lock, flags);
+
+               return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
 /*----------------------Uart Operations---------------------------*/
 
 /**
@@ -346,7 +547,7 @@ static void xuartps_start_tx(struct uart_port *port)
                port->state->xmit.tail = (port->state->xmit.tail + 1) &
                                        (UART_XMIT_SIZE - 1);
        }
-
+       xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_ISR_OFFSET);
        /* Enable the TX Empty interrupt */
        xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET);
 
@@ -437,7 +638,7 @@ static void xuartps_set_termios(struct uart_port *port,
                                struct ktermios *termios, struct ktermios *old)
 {
        unsigned int cval = 0;
-       unsigned int baud;
+       unsigned int baud, minbaud, maxbaud;
        unsigned long flags;
        unsigned int ctrl_reg, mode_reg;
 
@@ -454,8 +655,14 @@ static void xuartps_set_termios(struct uart_port *port,
                        (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS),
                        XUARTPS_CR_OFFSET);
 
-       /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */
-       baud = uart_get_baud_rate(port, termios, old, 0, 10000000);
+       /*
+        * Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk
+        * min and max baud should be calculated here based on port->uartclk.
+        * this way we get a valid baud and can safely call set_baud()
+        */
+       minbaud = port->uartclk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX * 8);
+       maxbaud = port->uartclk / (XUARTPS_BDIV_MIN + 1);
+       baud = uart_get_baud_rate(port, termios, old, minbaud, maxbaud);
        baud = xuartps_set_baud_rate(port, baud);
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);
@@ -480,7 +687,7 @@ static void xuartps_set_termios(struct uart_port *port,
                        | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
                        XUARTPS_CR_OFFSET);
 
-       xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
+       xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
 
        port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG |
                        XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT;
@@ -531,13 +738,17 @@ static void xuartps_set_termios(struct uart_port *port,
                                cval |= XUARTPS_MR_PARITY_MARK;
                        else
                                cval |= XUARTPS_MR_PARITY_SPACE;
-               } else if (termios->c_cflag & PARODD)
+               } else {
+                       if (termios->c_cflag & PARODD)
                                cval |= XUARTPS_MR_PARITY_ODD;
                        else
                                cval |= XUARTPS_MR_PARITY_EVEN;
-       } else
+               }
+       } else {
                cval |= XUARTPS_MR_PARITY_NONE;
-       xuartps_writel(cval , XUARTPS_MR_OFFSET);
+       }
+       cval |= mode_reg & 1;
+       xuartps_writel(cval, XUARTPS_MR_OFFSET);
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
@@ -583,11 +794,17 @@ static int xuartps_startup(struct uart_port *port)
                | XUARTPS_MR_PARITY_NONE | XUARTPS_MR_CHARLEN_8_BIT,
                 XUARTPS_MR_OFFSET);
 
-       /* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */
-       xuartps_writel(14, XUARTPS_RXWM_OFFSET);
+       /*
+        * Set the RX FIFO Trigger level to use most of the FIFO, but it
+        * can be tuned with a module parameter
+        */
+       xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET);
 
-       /* Receive Timeout register is enabled with value of 10 */
-       xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
+       /*
+        * Receive Timeout register is enabled but it
+        * can be tuned with a module parameter
+        */
+       xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
 
        /* Clear out any pending interrupts before enabling them */
        xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET);
@@ -727,6 +944,54 @@ static void xuartps_enable_ms(struct uart_port *port)
        /* N/A */
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int xuartps_poll_get_char(struct uart_port *port)
+{
+       u32 imr;
+       int c;
+
+       /* Disable all interrupts */
+       imr = xuartps_readl(XUARTPS_IMR_OFFSET);
+       xuartps_writel(imr, XUARTPS_IDR_OFFSET);
+
+       /* Check if FIFO is empty */
+       if (xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY)
+               c = NO_POLL_CHAR;
+       else /* Read a character */
+               c = (unsigned char) xuartps_readl(XUARTPS_FIFO_OFFSET);
+
+       /* Enable interrupts */
+       xuartps_writel(imr, XUARTPS_IER_OFFSET);
+
+       return c;
+}
+
+static void xuartps_poll_put_char(struct uart_port *port, unsigned char c)
+{
+       u32 imr;
+
+       /* Disable all interrupts */
+       imr = xuartps_readl(XUARTPS_IMR_OFFSET);
+       xuartps_writel(imr, XUARTPS_IDR_OFFSET);
+
+       /* Wait until FIFO is empty */
+       while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY))
+               cpu_relax();
+
+       /* Write a character */
+       xuartps_writel(c, XUARTPS_FIFO_OFFSET);
+
+       /* Wait until FIFO is empty */
+       while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY))
+               cpu_relax();
+
+       /* Enable interrupts */
+       xuartps_writel(imr, XUARTPS_IER_OFFSET);
+
+       return;
+}
+#endif
+
 /** The UART operations structure
  */
 static struct uart_ops xuartps_ops = {
@@ -759,6 +1024,10 @@ static struct uart_ops xuartps_ops = {
        .config_port    = xuartps_config_port,  /* Configure when driver
                                                 * adds a xuartps port
                                                 */
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char  = xuartps_poll_get_char,
+       .poll_put_char  = xuartps_poll_put_char,
+#endif
 };
 
 static struct uart_port xuartps_port[2];
@@ -837,7 +1106,7 @@ static void xuartps_console_write(struct console *co, const char *s,
 {
        struct uart_port *port = &xuartps_port[co->index];
        unsigned long flags;
-       unsigned int imr;
+       unsigned int imr, ctrl;
        int locked = 1;
 
        if (oops_in_progress)
@@ -849,9 +1118,19 @@ static void xuartps_console_write(struct console *co, const char *s,
        imr = xuartps_readl(XUARTPS_IMR_OFFSET);
        xuartps_writel(imr, XUARTPS_IDR_OFFSET);
 
+       /*
+        * Make sure that the tx part is enabled. Set the TX enable bit and
+        * clear the TX disable bit to enable the transmitter.
+        */
+       ctrl = xuartps_readl(XUARTPS_CR_OFFSET);
+       xuartps_writel((ctrl & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN,
+               XUARTPS_CR_OFFSET);
+
        uart_console_write(port, s, count, xuartps_console_putchar);
        xuartps_console_wait_tx(port);
 
+       xuartps_writel(ctrl, XUARTPS_CR_OFFSET);
+
        /* restore interrupt state, it seems like there may be a h/w bug
         * in that the interrupt enable register should not need to be
         * written based on the data sheet
@@ -919,6 +1198,119 @@ console_initcall(xuartps_console_init);
 
 #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
 
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xuartps_suspend - suspend event
+ * @device: Pointer to the device structure
+ *
+ * Returns 0
+ */
+static int xuartps_suspend(struct device *device)
+{
+       struct uart_port *port = dev_get_drvdata(device);
+       struct tty_struct *tty;
+       struct device *tty_dev;
+       int may_wake = 0;
+
+       /* Get the tty which could be NULL so don't assume it's valid */
+       tty = tty_port_tty_get(&port->state->port);
+       if (tty) {
+               tty_dev = tty->dev;
+               may_wake = device_may_wakeup(tty_dev);
+               tty_kref_put(tty);
+       }
+
+       /*
+        * Call the API provided in serial_core.c file which handles
+        * the suspend.
+        */
+       uart_suspend_port(&xuartps_uart_driver, port);
+       if (console_suspend_enabled && !may_wake) {
+               struct xuartps *xuartps = port->private_data;
+
+               clk_disable(xuartps->refclk);
+               clk_disable(xuartps->aperclk);
+       } else {
+               unsigned long flags = 0;
+
+               spin_lock_irqsave(&port->lock, flags);
+               /* Empty the receive FIFO 1st before making changes */
+               while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY))
+                       xuartps_readl(XUARTPS_FIFO_OFFSET);
+               /* set RX trigger level to 1 */
+               xuartps_writel(1, XUARTPS_RXWM_OFFSET);
+               /* disable RX timeout interrups */
+               xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IDR_OFFSET);
+               spin_unlock_irqrestore(&port->lock, flags);
+       }
+
+       return 0;
+}
+
+/**
+ * xuartps_resume - Resume after a previous suspend
+ * @device: Pointer to the device structure
+ *
+ * Returns 0
+ */
+static int xuartps_resume(struct device *device)
+{
+       struct uart_port *port = dev_get_drvdata(device);
+       unsigned long flags = 0;
+       u32 ctrl_reg;
+       struct tty_struct *tty;
+       struct device *tty_dev;
+       int may_wake = 0;
+
+       /* Get the tty which could be NULL so don't assume it's valid */
+       tty = tty_port_tty_get(&port->state->port);
+       if (tty) {
+               tty_dev = tty->dev;
+               may_wake = device_may_wakeup(tty_dev);
+               tty_kref_put(tty);
+       }
+
+       if (console_suspend_enabled && !may_wake) {
+               struct xuartps *xuartps = port->private_data;
+
+               clk_enable(xuartps->aperclk);
+               clk_enable(xuartps->refclk);
+
+               spin_lock_irqsave(&port->lock, flags);
+
+               /* Set TX/RX Reset */
+               xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST),
+                               XUARTPS_CR_OFFSET);
+               while (xuartps_readl(XUARTPS_CR_OFFSET) &
+                               (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST))
+                       cpu_relax();
+
+               /* restore rx timeout value */
+               xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
+               /* Enable Tx/Rx */
+               ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET);
+               xuartps_writel(
+                       (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) |
+                       (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
+                       XUARTPS_CR_OFFSET);
+
+               spin_unlock_irqrestore(&port->lock, flags);
+       } else {
+               spin_lock_irqsave(&port->lock, flags);
+               /* restore original rx trigger level */
+               xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET);
+               /* enable RX timeout interrupt */
+               xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET);
+               spin_unlock_irqrestore(&port->lock, flags);
+       }
+
+       return uart_resume_port(&xuartps_uart_driver, port);
+}
+#endif /* ! CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(xuartps_dev_pm_ops, xuartps_suspend, xuartps_resume);
+
 /** Structure Definitions
  */
 static struct uart_driver xuartps_uart_driver = {
@@ -949,27 +1341,26 @@ static int xuartps_probe(struct platform_device *pdev)
        struct resource *res, *res2;
        struct xuartps *xuartps_data;
 
-       xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL);
+       xuartps_data = devm_kzalloc(&pdev->dev, sizeof(*xuartps_data),
+                       GFP_KERNEL);
        if (!xuartps_data)
                return -ENOMEM;
 
-       xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk");
+       xuartps_data->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
        if (IS_ERR(xuartps_data->aperclk)) {
                dev_err(&pdev->dev, "aper_clk clock not found.\n");
-               rc = PTR_ERR(xuartps_data->aperclk);
-               goto err_out_free;
+               return PTR_ERR(xuartps_data->aperclk);
        }
-       xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk");
+       xuartps_data->refclk = devm_clk_get(&pdev->dev, "ref_clk");
        if (IS_ERR(xuartps_data->refclk)) {
                dev_err(&pdev->dev, "ref_clk clock not found.\n");
-               rc = PTR_ERR(xuartps_data->refclk);
-               goto err_out_clk_put_aper;
+               return PTR_ERR(xuartps_data->refclk);
        }
 
        rc = clk_prepare_enable(xuartps_data->aperclk);
        if (rc) {
                dev_err(&pdev->dev, "Unable to enable APER clock.\n");
-               goto err_out_clk_put;
+               return rc;
        }
        rc = clk_prepare_enable(xuartps_data->refclk);
        if (rc) {
@@ -989,13 +1380,19 @@ static int xuartps_probe(struct platform_device *pdev)
                goto err_out_clk_disable;
        }
 
+       xuartps_data->clk_rate_change_nb.notifier_call =
+                       xuartps_clk_notifier_cb;
+       if (clk_notifier_register(xuartps_data->refclk,
+                               &xuartps_data->clk_rate_change_nb))
+               dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
        /* Initialize the port structure */
        port = xuartps_get_port();
 
        if (!port) {
                dev_err(&pdev->dev, "Cannot get uart_port structure\n");
                rc = -ENODEV;
-               goto err_out_clk_disable;
+               goto err_out_notif_unreg;
        } else {
                /* Register the port.
                 * This function also registers this device with the tty layer
@@ -1006,26 +1403,24 @@ static int xuartps_probe(struct platform_device *pdev)
                port->dev = &pdev->dev;
                port->uartclk = clk_get_rate(xuartps_data->refclk);
                port->private_data = xuartps_data;
+               xuartps_data->port = port;
                platform_set_drvdata(pdev, port);
                rc = uart_add_one_port(&xuartps_uart_driver, port);
                if (rc) {
                        dev_err(&pdev->dev,
                                "uart_add_one_port() failed; err=%i\n", rc);
-                       goto err_out_clk_disable;
+                       goto err_out_notif_unreg;
                }
                return 0;
        }
 
+err_out_notif_unreg:
+       clk_notifier_unregister(xuartps_data->refclk,
+                       &xuartps_data->clk_rate_change_nb);
 err_out_clk_disable:
        clk_disable_unprepare(xuartps_data->refclk);
 err_out_clk_dis_aper:
        clk_disable_unprepare(xuartps_data->aperclk);
-err_out_clk_put:
-       clk_put(xuartps_data->refclk);
-err_out_clk_put_aper:
-       clk_put(xuartps_data->aperclk);
-err_out_free:
-       kfree(xuartps_data);
 
        return rc;
 }
@@ -1043,13 +1438,12 @@ static int xuartps_remove(struct platform_device *pdev)
        int rc;
 
        /* Remove the xuartps port from the serial core */
+       clk_notifier_unregister(xuartps_data->refclk,
+                       &xuartps_data->clk_rate_change_nb);
        rc = uart_remove_one_port(&xuartps_uart_driver, port);
        port->mapbase = 0;
        clk_disable_unprepare(xuartps_data->refclk);
        clk_disable_unprepare(xuartps_data->aperclk);
-       clk_put(xuartps_data->refclk);
-       clk_put(xuartps_data->aperclk);
-       kfree(xuartps_data);
        return rc;
 }
 
@@ -1067,6 +1461,7 @@ static struct platform_driver xuartps_platform_driver = {
                .owner = THIS_MODULE,
                .name = XUARTPS_NAME,           /* Driver name */
                .of_match_table = xuartps_of_match,
+               .pm = &xuartps_dev_pm_ops,
                },
 };
 
index 40a9fe9d3b10f0170af31c4d8845d8cc609e6bb5..ce396ecdf41268b5de64a7ac3f820438c3bdfffb 100644 (file)
@@ -51,7 +51,7 @@
 #include <asm/irq_regs.h>
 
 /* Whether we react on sysrq keys or just ignore them */
-static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
+static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
 static bool __read_mostly sysrq_always_enabled;
 
 unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED };
index f597e88a705d1fa8e65cf36ae98a61f84f20b9a3..c94d2349dd0620dd183645ee37ddced4551e9ccd 100644 (file)
@@ -140,6 +140,10 @@ EXPORT_SYMBOL(tty_port_destroy);
 static void tty_port_destructor(struct kref *kref)
 {
        struct tty_port *port = container_of(kref, struct tty_port, kref);
+
+       /* check if last port ref was dropped before tty release */
+       if (WARN_ON(port->itty))
+               return;
        if (port->xmit_buf)
                free_page((unsigned long)port->xmit_buf);
        tty_port_destroy(port);
@@ -480,8 +484,6 @@ int tty_port_close_start(struct tty_port *port,
 
        if (port->count) {
                spin_unlock_irqrestore(&port->lock, flags);
-               if (port->ops->drop)
-                       port->ops->drop(port);
                return 0;
        }
        set_bit(ASYNCB_CLOSING, &port->flags);
@@ -500,9 +502,7 @@ int tty_port_close_start(struct tty_port *port,
        /* Flush the ldisc buffering */
        tty_ldisc_flush(tty);
 
-       /* Don't call port->drop for the last reference. Callers will want
-          to drop the last active reference in ->shutdown() or the tty
-          shutdown path */
+       /* Report to caller this is the last port reference */
        return 1;
 }
 EXPORT_SYMBOL(tty_port_close_start);
index 9a8e8c5a0c73a93420fc71b85637db4d510ae241..61b1137d7e56d877fad8b2339c368cd09a5419e1 100644 (file)
@@ -1300,21 +1300,30 @@ static void csi_m(struct vc_data *vc)
                        case 27:
                                vc->vc_reverse = 0;
                                break;
-                       case 38: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Enables underscore, white foreground
-                                 * with white underscore (Linux - use
-                                 * default foreground).
+                       case 38:
+                       case 48: /* ITU T.416
+                                 * Higher colour modes.
+                                 * They break the usual properties of SGR codes
+                                 * and thus need to be detected and ignored by
+                                 * hand.  Strictly speaking, that standard also
+                                 * wants : rather than ; as separators, contrary
+                                 * to ECMA-48, but no one produces such codes
+                                 * and almost no one accepts them.
                                  */
-                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               vc->vc_underline = 1;
+                               i++;
+                               if (i > vc->vc_npar)
+                                       break;
+                               if (vc->vc_par[i] == 5)      /* 256 colours */
+                                       i++;                 /* ubiquitous */
+                               else if (vc->vc_par[i] == 2) /* 24 bit colours */
+                                       i += 3;              /* extremely rare */
+                               /* Subcommands 3 (CMY) and 4 (CMYK) are so insane
+                                * that detecting them is not worth the few extra
+                                * bytes of kernel's size.
+                                */
                                break;
-                       case 39: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Disable underline option.
-                                 * Reset colour to default? It did this
-                                 * before...
-                                 */
+                       case 39:
                                vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               vc->vc_underline = 0;
                                break;
                        case 49:
                                vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
index be201ca2990ce1a0363608b39f2dd210097c57a2..00beddf6be20358ca7cd108b54a45902c4478c8b 100644 (file)
 #define ATMEL_US_IF            0x4c                    /* IrDA Filter Register */
 
 #define ATMEL_US_NAME          0xf0                    /* Ip Name */
+#define ATMEL_US_VERSION       0xfc                    /* Ip Version */
 
 #endif
index b98291ac7f141f0b0cf33b569d7dde0796b60f8c..f729be981da0862a5ec09ee6a35e75312ae8768e 100644 (file)
@@ -66,7 +66,6 @@ struct uart_ops {
        void            (*set_ldisc)(struct uart_port *, int new);
        void            (*pm)(struct uart_port *, unsigned int state,
                              unsigned int oldstate);
-       int             (*set_wake)(struct uart_port *, unsigned int state);
 
        /*
         * Return a string describing the type of the port
index 7faf933cced7018657d2212d543530484ce17ec9..387fa7d05c982b758942f83395e328949324fc1a 100644 (file)
@@ -17,9 +17,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
-/* Enable/disable SYSRQ support by default (0==no, 1==yes). */
-#define SYSRQ_DEFAULT_ENABLE   1
-
 /* Possible values of bitmask for enabling sysrq functions */
 /* 0x0001 is reserved for enable everything */
 #define SYSRQ_ENABLE_LOG       0x0002
index 633cac77f9f97b56155bf5a005aa2899591425ac..97d660ed70c1901407dac9ea49bd1036840e649c 100644 (file)
@@ -180,7 +180,6 @@ struct tty_port_operations {
           IFF the port was initialized. Do not use to free resources. Called
           under the port mutex to serialize against activate/shutdowns */
        void (*shutdown)(struct tty_port *port);
-       void (*drop)(struct tty_port *port);
        /* Called under the port mutex from tty_port_open, serialized using
           the port mutex */
         /* FIXME: long term getting the tty argument *out* of this would be
index 5c704dbf6d45c2196a460d640a508a643cb7f03a..9aa71cec9e0e57246b64fdcdf094b672a9185044 100644 (file)
@@ -190,7 +190,7 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
 
 #ifdef CONFIG_MAGIC_SYSRQ
 /* Note: sysrq code uses it's own private copy */
-static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
+static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
 
 static int sysrq_sysctl_handler(ctl_table *table, int write,
                                void __user *buffer, size_t *lenp,
index 06344d986eb9dde61f341057f431d3183301f54e..29329374ff0d5b94d22157195aae3c453dd3d0f4 100644 (file)
@@ -312,6 +312,15 @@ config MAGIC_SYSRQ
          keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
          unless you really know what this hack does.
 
+config MAGIC_SYSRQ_DEFAULT_ENABLE
+       hex "Enable magic SysRq key functions by default"
+       depends on MAGIC_SYSRQ
+       default 0x1
+       help
+         Specifies which SysRq key functions are enabled by default.
+         This may be set to 1 or 0 to enable or disable them all, or
+         to a bitmask as described in Documentation/sysrq.txt.
+
 config DEBUG_KERNEL
        bool "Kernel debugging"
        help