diff options
Diffstat (limited to 'drivers/tty/serial')
41 files changed, 311 insertions, 1128 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index e33d38c..570df9d 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -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 && !up->dma) || fifo_bug) { + if (baud < 2400 || fifo_bug) { fcr &= ~UART_FCR_TRIGGER_MASK; fcr |= UART_FCR_TRIGGER_1; } diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 4658e3e..daf710f 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -56,11 +56,11 @@ struct dw8250_data { - u8 usr_reg; - int last_mcr; - int line; - struct clk *clk; - struct uart_8250_dma dma; + int last_lcr; + int last_mcr; + int line; + struct clk *clk; + u8 usr_reg; }; static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) @@ -76,33 +76,17 @@ 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) @@ -123,22 +107,13 @@ 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) @@ -156,8 +131,9 @@ 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 */ + /* Clear the USR and write the LCR again. */ (void)p->serial_in(p, d->usr_reg); + p->serial_out(p, UART_LCR, d->last_lcr); return 1; } @@ -177,14 +153,6 @@ 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; @@ -273,8 +241,7 @@ static int dw8250_probe_of(struct uart_port *p, } #ifdef CONFIG_ACPI -static int dw8250_probe_acpi(struct uart_8250_port *up, - struct dw8250_data *data) +static int dw8250_probe_acpi(struct uart_8250_port *up) { const struct acpi_device_id *id; struct uart_port *p = &up->port; @@ -293,7 +260,9 @@ static int dw8250_probe_acpi(struct uart_8250_port *up, if (!p->uartclk) p->uartclk = (unsigned int)id->driver_data; - up->dma = &data->dma; + up->dma = devm_kzalloc(p->dev, sizeof(*up->dma), GFP_KERNEL); + if (!up->dma) + return -ENOMEM; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; @@ -301,8 +270,7 @@ static int dw8250_probe_acpi(struct uart_8250_port *up, return 0; } #else -static inline int dw8250_probe_acpi(struct uart_8250_port *up, - struct dw8250_data *data) +static inline int dw8250_probe_acpi(struct uart_8250_port *up) { return -ENODEV; } @@ -346,12 +314,6 @@ 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; @@ -362,7 +324,7 @@ static int dw8250_probe(struct platform_device *pdev) if (err) return err; } else if (ACPI_HANDLE(&pdev->dev)) { - err = dw8250_probe_acpi(&uart, data); + err = dw8250_probe_acpi(&uart); if (err) return err; } else { diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c index d1a9078..5f3bba1 100644 --- a/drivers/tty/serial/8250/8250_em.c +++ b/drivers/tty/serial/8250/8250_em.c @@ -122,7 +122,7 @@ static int serial8250_em_probe(struct platform_device *pdev) up.port.dev = &pdev->dev; up.port.private_data = priv; - clk_prepare_enable(priv->sclk); + clk_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_unprepare(priv->sclk); + clk_disable(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_unprepare(priv->sclk); + clk_disable(priv->sclk); return 0; } diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 4697a51..c810da7 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -9,7 +9,6 @@ * 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> @@ -28,6 +27,8 @@ #include "8250.h" +#undef SERIAL_DEBUG_PCI + /* * init function returns: * > 0 - number of ports @@ -62,7 +63,7 @@ static int pci_default_setup(struct serial_private*, static void moan_device(const char *str, struct pci_dev *dev) { - dev_err(&dev->dev, + printk(KERN_WARNING "%s: %s\n" "Please send the output of lspci -vv, this\n" "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" @@ -232,7 +233,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 */ - dev_dbg(&dev->dev, "Local i960 firmware missing\n"); + printk(KERN_DEBUG "Local i960 firmware missing"); return -ENODEV; } return 0; @@ -826,7 +827,7 @@ static int pci_netmos_9900_numports(struct pci_dev *dev) if (sub_serports > 0) { return sub_serports; } else { - dev_err(&dev->dev, "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); + printk(KERN_NOTICE "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); return 0; } } @@ -930,7 +931,7 @@ static int pci_ite887x_init(struct pci_dev *dev) } if (!inta_addr[i]) { - dev_err(&dev->dev, "ite887x: could not find iobase\n"); + printk(KERN_ERR "ite887x: could not find iobase\n"); return -ENODEV; } @@ -1023,9 +1024,9 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev) /* Tornado device */ if (deviceID == 0x07000200) { number_uarts = ioread8(p + 4); - dev_dbg(&dev->dev, + printk(KERN_DEBUG "%d ports detected on Oxford PCI Express device\n", - number_uarts); + number_uarts); } pci_iounmap(dev, p); return number_uarts; @@ -1307,29 +1308,6 @@ 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, @@ -1346,120 +1324,6 @@ 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, @@ -1480,80 +1344,17 @@ 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; - 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); + 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); return pci_default_setup(priv, board, port, idx); } @@ -1861,20 +1662,6 @@ 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 */ @@ -2039,31 +1826,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .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 */ { @@ -2493,27 +2255,6 @@ 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 @@ -2708,13 +2449,9 @@ 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, }; /* @@ -3448,13 +3185,6 @@ 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, @@ -3472,24 +3202,6 @@ 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[] = { @@ -3650,15 +3362,14 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) if (quirk->setup(priv, board, &uart, i)) break; - dev_dbg(&dev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", - uart.port.iobase, uart.port.irq, uart.port.iotype); +#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 priv->line[i] = serial8250_register_8250_port(&uart); if (priv->line[i] < 0) { - 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]); + printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]); break; } } @@ -3751,7 +3462,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) } if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { - dev_err(&dev->dev, "invalid driver_data: %ld\n", + printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n", ent->driver_data); return -EINVAL; } @@ -3809,6 +3520,8 @@ 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); @@ -3842,7 +3555,7 @@ static int pciserial_resume_one(struct pci_dev *dev) err = pci_enable_device(dev); /* FIXME: We cannot simply error out here */ if (err) - dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n"); + printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n"); pciserial_resume_ports(priv); } return 0; @@ -5135,15 +4848,6 @@ 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 @@ -5214,11 +4918,6 @@ 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 diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 2332991..f3b306e 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -41,7 +41,7 @@ config SERIAL_8250_DEPRECATED_OPTIONS accept kernel parameters in both forms like 8250_core.nr_uarts=4 and 8250.nr_uarts=4. We now renamed the module back to 8250, but if anybody noticed in 3.7 and changed their userspace we still have to - keep the 8250_core.* options around until they revert the changes + keep the 8350_core.* options around until they revert the changes they already did. If 8250 is built as a module, this adds 8250_core alias instead. diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a3817ab..febd45c 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -709,7 +709,7 @@ config SERIAL_IP22_ZILOG_CONSOLE config SERIAL_SH_SCI tristate "SuperH SCI(F) serial port support" - depends on HAVE_CLK && (SUPERH || ARM || COMPILE_TEST) + depends on HAVE_CLK && (SUPERH || ARCH_SHMOBILE) select SERIAL_CORE config SERIAL_SH_SCI_NR_UARTS @@ -1512,7 +1512,6 @@ 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. diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 33bd860..8b90f0b 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -728,6 +728,7 @@ 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: @@ -744,6 +745,8 @@ 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++) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 7203864..aaa2286 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2147,6 +2147,7 @@ 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); } @@ -2159,6 +2160,8 @@ 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++) diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index c9f5c9d..569872f 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -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 = dev_get_platdata(&pdev->dev); + plat_data = (unsigned long *)dev_get_platdata(&pdev->dev); if (!plat_data) return -ENODEV; diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index c7d99af..6b0f75e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -99,7 +99,6 @@ 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) @@ -1504,7 +1503,6 @@ 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; @@ -1519,22 +1517,7 @@ static void atmel_get_ip_name(struct uart_port *port) dev_dbg(port->dev, "This is uart\n"); atmel_port->is_usart = false; } else { - /* 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"); - } + dev_err(port->dev, "Not supported ip name, set to uart\n"); } } diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index 4f22970..87636cc 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c @@ -766,8 +766,9 @@ static int sport_uart_probe(struct platform_device *pdev) return -ENOMEM; } - ret = peripheral_request_list(dev_get_platdata(&pdev->dev), - DRV_NAME); + ret = peripheral_request_list( + (unsigned short *)dev_get_platdata(&pdev->dev), + DRV_NAME); if (ret) { dev_err(&pdev->dev, "Fail to request SPORT peripherals\n"); @@ -843,7 +844,8 @@ static int sport_uart_probe(struct platform_device *pdev) out_error_unmap: iounmap(sport->port.membase); out_error_free_peripherals: - peripheral_free_list(dev_get_platdata(&pdev->dev)); + peripheral_free_list( + (unsigned short *)dev_get_platdata(&pdev->dev)); out_error_free_mem: kfree(sport); bfin_sport_uart_ports[pdev->id] = NULL; @@ -862,7 +864,8 @@ 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(dev_get_platdata(&pdev->dev)); + peripheral_free_list( + (unsigned short *)dev_get_platdata(&pdev->dev)); kfree(sport); bfin_sport_uart_ports[pdev->id] = NULL; } diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 869ceba..3c75e8e 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -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, - 0, "BFIN_UART_MODEM_STATUS", uart)) { + IRQF_DISABLED, "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( - dev_get_platdata(&pdev->dev), + (unsigned short *)dev_get_platdata(&pdev->dev), DRIVER_NAME); if (ret) { dev_err(&pdev->dev, @@ -1358,7 +1358,8 @@ static int bfin_serial_probe(struct platform_device *pdev) out_error_unmap: iounmap(uart->port.membase); out_error_free_peripherals: - peripheral_free_list(dev_get_platdata(&pdev->dev)); + peripheral_free_list( + (unsigned short *)dev_get_platdata(&pdev->dev)); out_error_free_mem: kfree(uart); bfin_serial_ports[pdev->id] = NULL; @@ -1376,7 +1377,8 @@ 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(dev_get_platdata(&pdev->dev)); + peripheral_free_list( + (unsigned short *)dev_get_platdata(&pdev->dev)); kfree(uart); bfin_serial_ports[pdev->id] = NULL; } @@ -1430,8 +1432,8 @@ static int bfin_earlyprintk_probe(struct platform_device *pdev) return -ENOENT; } - ret = peripheral_request_list(dev_get_platdata(&pdev->dev), - DRIVER_NAME); + ret = peripheral_request_list( + (unsigned short *)dev_get_platdata(&pdev->dev), DRIVER_NAME); if (ret) { dev_err(&pdev->dev, "fail to request bfin serial peripherals\n"); @@ -1461,7 +1463,8 @@ static int bfin_earlyprintk_probe(struct platform_device *pdev) return 0; out_error_free_peripherals: - peripheral_free_list(dev_get_platdata(&pdev->dev)); + peripheral_free_list( + (unsigned short *)dev_get_platdata(&pdev->dev)); return ret; } diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 8d0b994..7e4e408 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -459,6 +459,7 @@ 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; } @@ -486,6 +487,7 @@ 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; diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 7d76214..1a535f7 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -41,8 +41,6 @@ #include <linux/bootmem.h> #include <linux/dma-mapping.h> #include <linux/fs_uart_pd.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/gpio.h> #include <linux/of_gpio.h> @@ -1209,7 +1207,7 @@ static int cpm_uart_init_port(struct device_node *np, pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; spin_lock_init(&pinfo->port.lock); - pinfo->port.irq = irq_of_parse_and_map(np, 0); + pinfo->port.irq = of_irq_to_resource(np, 0, NULL); if (pinfo->port.irq == NO_IRQ) { ret = -EINVAL; goto out_pram; diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c index 527a969..18f7957 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c @@ -45,7 +45,6 @@ #include <linux/kernel.h> #include <linux/of.h> -#include <linux/of_address.h> #include "cpm_uart.h" diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 5903909..af286e6 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -1008,7 +1008,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) return -ENODEV; } - pl_data = dev_get_platdata(&spi->dev); + pl_data = (struct ifx_modem_platform_data *)dev_get_platdata(&spi->dev); if (!pl_data) { dev_err(&spi->dev, "missing platform data!"); return -ENODEV; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index b2cfdb6..042aa07 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -223,7 +223,8 @@ struct imx_port { struct dma_chan *dma_chan_rx, *dma_chan_tx; struct scatterlist rx_sgl, tx_sgl[2]; void *rx_buf; - unsigned int tx_bytes; + unsigned int rx_bytes, tx_bytes; + struct work_struct tsk_dma_rx, tsk_dma_tx; unsigned int dma_tx_nents; wait_queue_head_t dma_wait; }; @@ -504,25 +505,34 @@ 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 imx_dma_tx(struct imx_port *sport) +static void dma_tx_work(struct work_struct *w) { + 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 = dmaengine_tx_status(chan, (dma_cookie_t)0, NULL); + status = chan->device->device_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 && xmit->head > 0) { + if (xmit->tail > xmit->head) { sport->dma_tx_nents = 2; sg_init_table(sgl, 2); sg_set_buf(sgl, xmit->buf + xmit->tail, @@ -532,6 +542,7 @@ static void imx_dma_tx(struct imx_port *sport) 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) { @@ -598,7 +609,11 @@ static void imx_start_tx(struct uart_port *port) } if (sport->dma_is_enabled) { - imx_dma_tx(sport); + /* + * We may in the interrupt context, so arise a work_struct to + * do the real job. + */ + schedule_work(&sport->tsk_dma_tx); return; } @@ -717,7 +732,6 @@ 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. @@ -736,7 +750,7 @@ static void imx_dma_rxint(struct imx_port *sport) writel(temp, sport->port.membase + UCR1); /* tell the DMA to receive the data. */ - start_rx_dma(sport); + schedule_work(&sport->tsk_dma_rx); } } @@ -781,15 +795,8 @@ 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; - /* If the TX DMA is working, return 0. */ - if (sport->dma_is_enabled && sport->dma_is_txing) - ret = 0; - - return ret; + return (readl(sport->port.membase + USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0; } /* @@ -858,6 +865,22 @@ 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; @@ -889,7 +912,6 @@ 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; @@ -897,15 +919,13 @@ static void dma_rx_callback(void *data) /* unmap it first */ dma_unmap_sg(sport->port.dev, sgl, 1, DMA_FROM_DEVICE); - status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state); + status = chan->device->device_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) { - tty_insert_flip_string(port, sport->rx_buf, count); - tty_flip_buffer_push(port); - - start_rx_dma(sport); + sport->rx_bytes = count; + schedule_work(&sport->tsk_dma_rx); } else imx_rx_dma_done(sport); } @@ -987,6 +1007,7 @@ 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"); @@ -1017,7 +1038,11 @@ 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 */ @@ -1038,6 +1063,7 @@ 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); @@ -1055,6 +1081,7 @@ 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 */ @@ -1276,16 +1303,6 @@ 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) @@ -1522,7 +1539,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 (sport->port.mapbase != (unsigned long)ser->iomem_base) + if ((void *)sport->port.mapbase != ser->iomem_base) ret = -EINVAL; if (sport->port.iobase != ser->port) ret = -EINVAL; @@ -1606,7 +1623,6 @@ 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, diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 1d94205..cb3c81e 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -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; diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 8d71e40..b2e707a 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -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) diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 52c930f..d3db042 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -293,7 +293,7 @@ static void serial_hsu_enable_ms(struct uart_port *port) serial_out(up, UART_IER, up->ier); } -static void hsu_dma_tx(struct uart_hsu_port *up) +void hsu_dma_tx(struct uart_hsu_port *up) { struct circ_buf *xmit = &up->port.state->xmit; struct hsu_dma_buffer *dbuf = &up->txbuf; @@ -340,8 +340,7 @@ static void hsu_dma_tx(struct uart_hsu_port *up) } /* The buffer is already cache coherent */ -static void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, - struct hsu_dma_buffer *dbuf) +void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf) { dbuf->ofs = 0; @@ -387,8 +386,7 @@ static void serial_hsu_stop_tx(struct uart_port *port) /* This is always called in spinlock protected mode, so * modify timeout timer is safe here */ -static void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts, - unsigned long *flags) +void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts, unsigned long *flags) { struct hsu_dma_buffer *dbuf = &up->rxbuf; struct hsu_dma_chan *chan = up->rxc; @@ -1185,7 +1183,7 @@ static struct console serial_hsu_console = { #define SERIAL_HSU_CONSOLE NULL #endif -static struct uart_ops serial_hsu_pops = { +struct uart_ops serial_hsu_pops = { .tx_empty = serial_hsu_tx_empty, .set_mctrl = serial_hsu_set_mctrl, .get_mctrl = serial_hsu_get_mctrl, @@ -1453,6 +1451,7 @@ 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); } @@ -1505,4 +1504,4 @@ module_init(hsu_pci_init); module_exit(hsu_pci_exit); MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(pci, pci_ids); +MODULE_ALIAS("platform:medfield-hsu"); diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index ec06505..5be1df3 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1301,6 +1301,7 @@ 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, @@ -1765,7 +1766,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 = platform_get_drvdata(op); + struct uart_port *port = (struct uart_port *) platform_get_drvdata(op); if (port) uart_suspend_port(&mpc52xx_uart_driver, port); @@ -1776,7 +1777,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 = platform_get_drvdata(op); + struct uart_port *port = (struct uart_port *) platform_get_drvdata(op); if (port) uart_resume_port(&mpc52xx_uart_driver, port); diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index e30a3ca..8d70267 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c @@ -2030,7 +2030,7 @@ static void mpsc_drv_get_platform_data(struct mpsc_port_info *pi, { struct mpsc_pdata *pdata; - pdata = dev_get_platdata(&pd->dev); + pdata = (struct mpsc_pdata *)dev_get_platdata(&pd->dev); pi->port.uartclk = pdata->brg_clk_freq; pi->port.iotype = UPIO_MEM; diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index db0448a..a67e708 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -43,7 +43,6 @@ #include <linux/kthread.h> #include <linux/spi/spi.h> -#include <linux/pm.h> #include "mrst_max3110.h" @@ -62,7 +61,6 @@ 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; @@ -92,7 +90,6 @@ 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; @@ -107,7 +104,6 @@ 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; } @@ -495,9 +491,19 @@ static int serial_m3110_startup(struct uart_port *port) port->state->port.low_latency = 1; if (max->irq) { - /* Enable RX IRQ only */ - config |= WC_RXA_IRQ_ENABLE; - } else { + max->read_thread = NULL; + ret = request_irq(max->irq, serial_m3110_irq, + IRQ_TYPE_EDGE_FALLING, "max3110", max); + if (ret) { + max->irq = 0; + pr_err(PR_FMT "unable to allocate IRQ, polling\n"); + } else { + /* Enable RX IRQ only */ + config |= WC_RXA_IRQ_ENABLE; + } + } + + if (max->irq == 0) { /* If IRQ is disabled, start a read thread for input data */ max->read_thread = kthread_run(max3110_read_thread, max, "max3110_read"); @@ -511,6 +517,8 @@ static int serial_m3110_startup(struct uart_port *port) ret = max3110_out(max, config); if (ret) { + if (max->irq) + free_irq(max->irq, max); if (max->read_thread) kthread_stop(max->read_thread); max->read_thread = NULL; @@ -532,6 +540,9 @@ static void serial_m3110_shutdown(struct uart_port *port) max->read_thread = NULL; } + if (max->irq) + free_irq(max->irq, max); + /* Disable interrupts from this port */ config = WC_TAG | WC_SW_SHDI; max3110_out(max, config); @@ -738,8 +749,7 @@ static int serial_m3110_suspend(struct device *dev) struct spi_device *spi = to_spi_device(dev); struct uart_max3110 *max = spi_get_drvdata(spi); - if (max->irq > 0) - disable_irq(max->irq); + disable_irq(max->irq); uart_suspend_port(&serial_m3110_reg, &max->port); max3110_out(max, max->cur_conf | WC_SW_SHDI); return 0; @@ -752,8 +762,7 @@ static int serial_m3110_resume(struct device *dev) max3110_out(max, max->cur_conf); uart_resume_port(&serial_m3110_reg, &max->port); - if (max->irq > 0) - enable_irq(max->irq); + enable_irq(max->irq); return 0; } @@ -794,7 +803,6 @@ 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; @@ -832,16 +840,6 @@ static int serial_m3110_probe(struct spi_device *spi) goto err_kthread; } - if (max->irq) { - ret = request_irq(max->irq, serial_m3110_irq, - IRQ_TYPE_EDGE_FALLING, "max3110", max); - if (ret) { - max->irq = 0; - dev_warn(&spi->dev, - "unable to allocate IRQ, will use polling method\n"); - } - } - spi_set_drvdata(spi, max); pmax = max; @@ -869,9 +867,6 @@ static int serial_m3110_remove(struct spi_device *dev) free_page((unsigned long)max->con_xmit.buf); - if (max->irq) - free_irq(max->irq, max); - if (max->main_thread) kthread_stop(max->main_thread); diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index d8b6fee..10e9d70 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -39,7 +39,6 @@ #include <asm/cacheflush.h> #define MXS_AUART_PORTS 5 -#define MXS_AUART_FIFO_SIZE 16 #define AUART_CTRL0 0x00000000 #define AUART_CTRL0_SET 0x00000004 @@ -549,9 +548,6 @@ 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: @@ -745,9 +741,6 @@ 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) @@ -1063,7 +1056,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 = MXS_AUART_FIFO_SIZE; + s->port.fifosize = 16; s->port.uartclk = clk_get_rate(s->clk); s->port.type = PORT_IMX; s->port.dev = s->dev = &pdev->dev; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index fa511eb..816d1a2 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -39,7 +39,6 @@ #include <linux/irq.h> #include <linux/pm_runtime.h> #include <linux/of.h> -#include <linux/of_irq.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/platform_data/serial-omap.h> @@ -135,7 +134,6 @@ struct uart_omap_port { struct uart_port port; struct uart_omap_dma uart_dma; struct device *dev; - int wakeirq; unsigned char ier; unsigned char lcr; @@ -177,7 +175,7 @@ struct uart_omap_port { bool is_suspending; }; -#define to_uart_omap_port(p) ((container_of((p), struct uart_omap_port, port))) +#define to_uart_omap_port(p) ((container_of((p), struct uart_omap_port, port))) static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; @@ -216,23 +214,10 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up) return pdata->get_context_loss_count(up->dev); } -static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up, - bool enable) -{ - if (!up->wakeirq) - return; - - if (enable) - enable_irq(up->wakeirq); - else - disable_irq(up->wakeirq); -} - static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) { struct omap_uart_port_info *pdata = dev_get_platdata(up->dev); - serial_omap_enable_wakeirq(up, enable); if (!pdata || !pdata->enable_wakeup) return; @@ -257,12 +242,12 @@ serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud) unsigned int n16 = port->uartclk / (16 * baud); int baudAbsDiff13 = baud - (port->uartclk / (13 * n13)); int baudAbsDiff16 = baud - (port->uartclk / (16 * n16)); - if (baudAbsDiff13 < 0) + if(baudAbsDiff13 < 0) baudAbsDiff13 = -baudAbsDiff13; - if (baudAbsDiff16 < 0) + if(baudAbsDiff16 < 0) baudAbsDiff16 = -baudAbsDiff16; - return (baudAbsDiff13 >= baudAbsDiff16); + return (baudAbsDiff13 > baudAbsDiff16); } /* @@ -273,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 mode; + unsigned int divisor; if (!serial_omap_baud_is_mode16(port, baud)) - mode = 13; + divisor = 13; else - mode = 16; - return port->uartclk/(mode * baud); + divisor = 16; + return port->uartclk/(baud * divisor); } static void serial_omap_enable_ms(struct uart_port *port) @@ -298,40 +283,28 @@ static void serial_omap_enable_ms(struct uart_port *port) static void serial_omap_stop_tx(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); + struct circ_buf *xmit = &up->port.state->xmit; int res; pm_runtime_get_sync(up->dev); - /* Handle RS-485 */ + /* handle rs485 */ if (up->rs485.flags & SER_RS485_ENABLED) { - if (up->scr & OMAP_UART_SCR_TX_EMPTY) { - /* THR interrupt is fired when both TX FIFO and TX - * shift register are empty. This means there's nothing - * left to transmit now, so make sure the THR interrupt - * is fired when TX FIFO is below the trigger level, - * disable THR interrupts and toggle the RS-485 GPIO - * data direction pin if needed. - */ - up->scr &= ~OMAP_UART_SCR_TX_EMPTY; - serial_out(up, UART_OMAP_SCR, up->scr); + /* do nothing if current tx not yet completed */ + res = serial_in(up, UART_LSR) & UART_LSR_TEMT; + if (!res) + return; + + /* if there's no more data to send, turn off rts */ + if (uart_circ_empty(xmit)) { + /* if rts not already disabled */ res = (up->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? 1 : 0; if (gpio_get_value(up->rts_gpio) != res) { - if (up->rs485.delay_rts_after_send > 0) + if (up->rs485.delay_rts_after_send > 0) { mdelay(up->rs485.delay_rts_after_send); + } gpio_set_value(up->rts_gpio, res); } - } else { - /* We're asked to stop, but there's still stuff in the - * UART FIFO, so make sure the THR interrupt is fired - * when both TX FIFO and TX shift register are empty. - * The next THR interrupt (if no transmission is started - * in the meantime) will indicate the end of a - * transmission. Therefore we _don't_ disable THR - * interrupts in this situation. - */ - up->scr |= OMAP_UART_SCR_TX_EMPTY; - serial_out(up, UART_OMAP_SCR, up->scr); - return; } } @@ -411,18 +384,15 @@ static void serial_omap_start_tx(struct uart_port *port) pm_runtime_get_sync(up->dev); - /* Handle RS-485 */ + /* handle rs485 */ if (up->rs485.flags & SER_RS485_ENABLED) { - /* Fire THR interrupts when FIFO is below trigger level */ - up->scr &= ~OMAP_UART_SCR_TX_EMPTY; - serial_out(up, UART_OMAP_SCR, up->scr); - /* if rts not already enabled */ res = (up->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; if (gpio_get_value(up->rts_gpio) != res) { gpio_set_value(up->rts_gpio, res); - if (up->rs485.delay_rts_before_send > 0) + if (up->rs485.delay_rts_before_send > 0) { mdelay(up->rs485.delay_rts_before_send); + } } } @@ -729,20 +699,6 @@ static int serial_omap_startup(struct uart_port *port) if (retval) return retval; - /* Optional wake-up IRQ */ - if (up->wakeirq) { - retval = request_irq(up->wakeirq, serial_omap_irq, - up->port.irqflags, up->name, up); - if (retval) { - free_irq(up->port.irq, up); - return retval; - } - disable_irq(up->wakeirq); - } else { - dev_info(up->port.dev, "no wakeirq for uart%d\n", - up->port.line); - } - dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); pm_runtime_get_sync(up->dev); @@ -831,8 +787,6 @@ static void serial_omap_shutdown(struct uart_port *port) pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); free_irq(up->port.irq, up); - if (up->wakeirq) - free_irq(up->wakeirq, up); } static void serial_omap_uart_qos_work(struct work_struct *work) @@ -984,7 +938,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, */ /* Set receive FIFO threshold to 16 characters and - * transmit FIFO threshold to 32 spaces + * transmit FIFO threshold to 16 spaces */ up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; up->fcr &= ~OMAP_UART_FCR_TX_FIFO_TRIG_MASK; @@ -1106,6 +1060,15 @@ 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) @@ -1390,15 +1353,6 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) up->ier = mode; serial_out(up, UART_IER, up->ier); - /* If RS-485 is disabled, make sure the THR interrupt is fired when - * TX FIFO is below the trigger level. - */ - if (!(up->rs485.flags & SER_RS485_ENABLED) && - (up->scr & OMAP_UART_SCR_TX_EMPTY)) { - up->scr &= ~OMAP_UART_SCR_TX_EMPTY; - serial_out(up, UART_OMAP_SCR, up->scr); - } - spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); @@ -1447,6 +1401,7 @@ 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, @@ -1627,23 +1582,11 @@ static int serial_omap_probe(struct platform_device *pdev) struct uart_omap_port *up; struct resource *mem, *irq; struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); - int ret, uartirq = 0, wakeirq = 0; + int ret; - /* The optional wakeirq may be specified in the board dts file */ if (pdev->dev.of_node) { - uartirq = irq_of_parse_and_map(pdev->dev.of_node, 0); - if (!uartirq) - return -EPROBE_DEFER; - wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1); omap_up_info = of_get_uart_port_info(&pdev->dev); pdev->dev.platform_data = omap_up_info; - } else { - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq) { - dev_err(&pdev->dev, "no irq resource?\n"); - return -ENODEV; - } - uartirq = irq->start; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1652,6 +1595,12 @@ static int serial_omap_probe(struct platform_device *pdev) return -ENODEV; } + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { + dev_err(&pdev->dev, "no irq resource?\n"); + return -ENODEV; + } + if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); @@ -1685,8 +1634,7 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; - up->port.irq = uartirq; - up->wakeirq = wakeirq; + up->port.irq = irq->start; up->port.regshift = 2; up->port.fifosize = 64; @@ -1722,9 +1670,8 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.uartclk = omap_up_info->uartclk; if (!up->port.uartclk) { up->port.uartclk = DEFAULT_CLK_SPEED; - dev_warn(&pdev->dev, - "No clock speed specified: using default: %d\n", - DEFAULT_CLK_SPEED); + dev_warn(&pdev->dev, "No clock speed specified: using default:" + "%d\n", DEFAULT_CLK_SPEED); } up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 0aa2b52..44077c0 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1614,6 +1614,7 @@ 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, @@ -1995,8 +1996,6 @@ 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)"); diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index e9d420f..f87f1a0 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -57,8 +57,6 @@ #include <linux/bitops.h> #include <linux/sysrq.h> #include <linux/mutex.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> #include <asm/sections.h> #include <asm/io.h> #include <asm/irq.h> @@ -1074,7 +1072,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; @@ -2052,9 +2050,6 @@ static int __init pmz_console_init(void) /* Probe ports */ pmz_probe(); - if (pmz_ports_count == 0) - return -ENODEV; - /* TODO: Autoprobe console based on OF */ /* pmz_console.index = i; */ register_console(&pmz_console); diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 753d452..ba25722 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -647,10 +647,7 @@ void sa1100_register_uart_fns(struct sa1100_port_fns *fns) sa1100_pops.set_mctrl = fns->set_mctrl; sa1100_pops.pm = fns->pm; - /* - * FIXME: fns->set_wake is unused - this should be called from - * the suspend() callback if device_may_wakeup(dev)) is set. - */ + sa1100_pops.set_wake = fns->set_wake; } void __init sa1100_register_uart(int idx, int port) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index c1af04d..f3dfa19 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -407,14 +407,7 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port) static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) { - 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); + /* todo - possibly remove AFC and do manual CTS */ } static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) @@ -781,6 +774,8 @@ 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; @@ -797,15 +792,6 @@ 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) @@ -1268,7 +1254,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)) ? - dev_get_platdata(&pdev->dev) : + (struct s3c2410_uartcfg *)dev_get_platdata(&pdev->dev) : ourport->drv_data->def_cfg; ourport->port.fifosize = (ourport->info->fifosize) ? diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 8827e54..aaa617a 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -63,7 +63,7 @@ struct s3c24xx_uart_port { /* conversion functions */ -#define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev) +#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev) /* register access controls */ diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index a447f71..49e9bbf 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -986,7 +986,6 @@ 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); diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index dfe79cc..0489a2b 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -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, 0, + ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED, dev_name(u->dev), tup); if (ret < 0) { dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq); diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 90a080b..440a962 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -1220,6 +1220,8 @@ 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); diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7d8103c..5377502 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1433,7 +1433,7 @@ static void work_fn_rx(struct work_struct *work) desc = s->desc_rx[new]; if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != - DMA_COMPLETE) { + DMA_SUCCESS) { /* Handle incomplete DMA receive */ struct dma_chan *chan = s->chan_rx; struct shdma_desc *sh_desc = container_of(desc, diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index f186a8f..61c1ad0 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -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); - sirfport->rx_completed++; + sirfsoc_rx_submit_one_dma_desc(port, sirfport->rx_completed++); sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT; } count = CIRC_CNT(sirfport->rx_dma_items[sirfport->rx_issued].xmit.head, @@ -706,19 +706,12 @@ 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); - 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++; + sirfsoc_rx_submit_one_dma_desc(port, sirfport->rx_completed++); sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT; } spin_unlock_irqrestore(&sirfport->rx_lock, flags); diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index b7d679c..fb8d0a0 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h @@ -368,6 +368,15 @@ struct sirfsoc_uart_register sirfsoc_uart = { #define SIRFSOC_UART_NR 6 #define SIRFSOC_PORT_TYPE 0xa5 +/* Baud Rate Calculation */ +#define SIRF_MIN_SAMPLE_DIV 0xf +#define SIRF_MAX_SAMPLE_DIV 0x3f +#define SIRF_IOCLK_DIV_MAX 0xffff +#define SIRF_SAMPLE_DIV_SHIFT 16 +#define SIRF_IOCLK_DIV_MASK 0xffff +#define SIRF_SAMPLE_DIV_MASK 0x3f0000 +#define SIRF_BAUD_RATE_SUPPORT_NR 18 + /* Uart Common Use Macro*/ #define SIRFSOC_RX_DMA_BUF_SIZE 256 #define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) @@ -444,6 +453,9 @@ struct sirfsoc_uart_port { int rx_issued; }; +/* Hardware Flow Control */ +#define SIRFUART_AFC_CTRL_RX_THD 0x70 + /* Register Access Control */ #define portaddr(port, reg) ((port)->membase + (reg)) #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg))) diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 380fb53..5d6136b 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -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. diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index db79b76..699cc1b 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -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); } diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 45a8c6a..135a152 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -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); diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index d569ca5..8831748 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -25,8 +25,6 @@ #include <linux/tty.h> #include <linux/tty_flip.h> #include <linux/io.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/dma-mapping.h> @@ -271,7 +269,7 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port) return 1; bdp++; - } + }; } /* diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index e46e9f3..7e4150a 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1,7 +1,7 @@ /* * Xilinx PS UART driver * - * 2011 - 2013 (C) Xilinx Inc. + * 2011 (c) Xilinx Inc. * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public @@ -11,17 +11,13 @@ * */ -#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> @@ -33,22 +29,12 @@ #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 64 /* FIFO size */ +#define XUARTPS_FIFO_SIZE 16 /* 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 * @@ -142,9 +128,6 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); #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 @@ -156,27 +139,15 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); #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 - * @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 + * @refclk Reference clock + * @aperclk APB clock */ 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 @@ -200,23 +171,6 @@ 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); @@ -230,30 +184,6 @@ 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) { @@ -317,196 +247,63 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) } /** - * 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, zero if no valid divisors are found. + * xuartps_set_baud_rate - Calculate and set the baud rate + * @port: Handle to the uart port structure + * @baud: Baud rate to set * - * 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) + * 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) { - u32 cd, bdiv; - unsigned int calc_baud; - unsigned int bestbaud = 0; + unsigned int sel_clk; + unsigned int calc_baud = 0; + unsigned int brgr_val, brdiv_val; unsigned int bauderror; - unsigned int besterror = ~0; - if (baud < clk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX)) { - *div8 = 1; - clk /= 8; - } else { - *div8 = 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++) { - 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) + brgr_val = sel_clk / (baud * (brdiv_val + 1)); + if (brgr_val < 2 || brgr_val > 65535) continue; - calc_baud = clk / (cd * (bdiv + 1)); + calc_baud = sel_clk / (brgr_val * (brdiv_val + 1)); if (baud > calc_baud) bauderror = baud - calc_baud; else bauderror = calc_baud - baud; - if (besterror > bauderror) { - *rbdiv = bdiv; - *rcd = cd; - bestbaud = calc_baud; - besterror = bauderror; + /* use the values when percent error is acceptable */ + if (((bauderror * 100) / baud) < 3) { + calc_baud = baud; + break; } } - /* use the values when percent error is acceptable */ - if (((besterror * 100) / baud) < 3) - bestbaud = baud; - - return bestbaud; -} -/** - * 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 = 0, bdiv = 0; - 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; + /* Set the values for the new baud rate */ + xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET); + xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET); return calc_baud; } -#ifdef CONFIG_COMMON_CLK -/** - * 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; - } -} -#endif - /*----------------------Uart Operations---------------------------*/ /** @@ -549,7 +346,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); @@ -640,7 +437,7 @@ static void xuartps_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int cval = 0; - unsigned int baud, minbaud, maxbaud; + unsigned int baud; unsigned long flags; unsigned int ctrl_reg, mode_reg; @@ -657,14 +454,8 @@ 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 - * 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); + /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */ + baud = uart_get_baud_rate(port, termios, old, 0, 10000000); baud = xuartps_set_baud_rate(port, baud); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); @@ -689,7 +480,7 @@ static void xuartps_set_termios(struct uart_port *port, | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), XUARTPS_CR_OFFSET); - xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET); + xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT; @@ -740,17 +531,13 @@ 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; - } - cval |= mode_reg & 1; - xuartps_writel(cval, XUARTPS_MR_OFFSET); + xuartps_writel(cval , XUARTPS_MR_OFFSET); spin_unlock_irqrestore(&port->lock, flags); } @@ -796,17 +583,11 @@ 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 use most of the FIFO, but it - * can be tuned with a module parameter - */ - xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET); + /* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */ + xuartps_writel(14, XUARTPS_RXWM_OFFSET); - /* - * Receive Timeout register is enabled but it - * can be tuned with a module parameter - */ - xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET); + /* Receive Timeout register is enabled with value of 10 */ + xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); /* Clear out any pending interrupts before enabling them */ xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET); @@ -946,54 +727,6 @@ 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 = { @@ -1026,10 +759,6 @@ 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]; @@ -1108,7 +837,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, ctrl; + unsigned int imr; int locked = 1; if (oops_in_progress) @@ -1120,19 +849,9 @@ 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 @@ -1214,119 +933,6 @@ static struct uart_driver xuartps_uart_driver = { #endif }; -#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); - /* --------------------------------------------------------------------- * Platform bus binding */ @@ -1343,26 +949,27 @@ static int xuartps_probe(struct platform_device *pdev) struct resource *res, *res2; struct xuartps *xuartps_data; - xuartps_data = devm_kzalloc(&pdev->dev, sizeof(*xuartps_data), - GFP_KERNEL); + xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL); if (!xuartps_data) return -ENOMEM; - xuartps_data->aperclk = devm_clk_get(&pdev->dev, "aper_clk"); + xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk"); if (IS_ERR(xuartps_data->aperclk)) { dev_err(&pdev->dev, "aper_clk clock not found.\n"); - return PTR_ERR(xuartps_data->aperclk); + rc = PTR_ERR(xuartps_data->aperclk); + goto err_out_free; } - xuartps_data->refclk = devm_clk_get(&pdev->dev, "ref_clk"); + xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk"); if (IS_ERR(xuartps_data->refclk)) { dev_err(&pdev->dev, "ref_clk clock not found.\n"); - return PTR_ERR(xuartps_data->refclk); + rc = PTR_ERR(xuartps_data->refclk); + goto err_out_clk_put_aper; } rc = clk_prepare_enable(xuartps_data->aperclk); if (rc) { dev_err(&pdev->dev, "Unable to enable APER clock.\n"); - return rc; + goto err_out_clk_put; } rc = clk_prepare_enable(xuartps_data->refclk); if (rc) { @@ -1382,21 +989,13 @@ static int xuartps_probe(struct platform_device *pdev) goto err_out_clk_disable; } -#ifdef CONFIG_COMMON_CLK - 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"); -#endif - /* 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_notif_unreg; + goto err_out_clk_disable; } else { /* Register the port. * This function also registers this device with the tty layer @@ -1407,26 +1006,26 @@ 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_notif_unreg; + goto err_out_clk_disable; } return 0; } -err_out_notif_unreg: -#ifdef CONFIG_COMMON_CLK - clk_notifier_unregister(xuartps_data->refclk, - &xuartps_data->clk_rate_change_nb); -#endif 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; } @@ -1444,14 +1043,13 @@ static int xuartps_remove(struct platform_device *pdev) int rc; /* Remove the xuartps port from the serial core */ -#ifdef CONFIG_COMMON_CLK - clk_notifier_unregister(xuartps_data->refclk, - &xuartps_data->clk_rate_change_nb); -#endif 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; } @@ -1469,7 +1067,6 @@ 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, }, }; |