Merge 4.7-rc6 into tty-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Jul 2016 15:17:08 +0000 (08:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Jul 2016 15:17:08 +0000 (08:17 -0700)
We want the tty/serial fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
68 files changed:
Documentation/devicetree/bindings/serial/8250.txt
Documentation/devicetree/bindings/serial/renesas,sci-serial.txt
MAINTAINERS
arch/frv/include/asm/serial.h
arch/xtensa/platforms/xt2000/setup.c
drivers/dma/hsu/hsu.c
drivers/dma/hsu/pci.c
drivers/tty/cyclades.c
drivers/tty/ipwireless/tty.c
drivers/tty/mxser.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_dma.c
drivers/tty/serial/8250/8250_early.c
drivers/tty/serial/8250/8250_fintek.c
drivers/tty/serial/8250/8250_ingenic.c
drivers/tty/serial/8250/8250_mid.c
drivers/tty/serial/8250/8250_mtk.c
drivers/tty/serial/8250/8250_omap.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/8250/8250_uniphier.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/Kconfig
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/bcm63xx_uart.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/m32r_sio.c
drivers/tty/serial/max310x.c
drivers/tty/serial/mps2-uart.c
drivers/tty/serial/msm_serial.c
drivers/tty/serial/msm_serial.h [deleted file]
drivers/tty/serial/mvebu-uart.c
drivers/tty/serial/pic32_uart.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/pxa.c
drivers/tty/serial/samsung.c
drivers/tty/serial/samsung.h
drivers/tty/serial/serial-tegra.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/serial_mctrl_gpio.c
drivers/tty/serial/serial_mctrl_gpio.h
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sh-sci.h
drivers/tty/serial/sirfsoc_uart.h
drivers/tty/serial/vt8500_serial.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/vt/consolemap.c
drivers/tty/vt/keyboard.c
drivers/tty/vt/vt.c
drivers/tty/vt/vt_ioctl.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/sisusbvga/sisusb_con.c
drivers/usb/misc/sisusbvga/sisusb_init.h
drivers/video/console/dummycon.c
drivers/video/console/fbcon.c
drivers/video/console/mdacon.c
drivers/video/console/newport_con.c
drivers/video/console/sticon.c
drivers/video/console/vgacon.c
include/linux/console.h
include/linux/console_struct.h
include/linux/dma/hsu.h
include/linux/serial_8250.h
include/linux/serial_core.h
include/linux/vt_kern.h
net/irda/ircomm/ircomm_tty_ioctl.c

index 936ab5b87324ce7cf022320a777342d2507dfd19..f5561ac7e17ed358ce7e6a00c7c0f8913f3464c6 100644 (file)
@@ -42,6 +42,9 @@ Optional properties:
 - auto-flow-control: one way to enable automatic flow control support. The
   driver is allowed to detect support for the capability even without this
   property.
+- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
+  line respectively. It will use specified GPIO instead of the peripheral
+  function pin for the UART feature. If unsure, don't specify this property.
 
 Note:
 * fsl,ns16550:
@@ -63,3 +66,19 @@ Example:
                interrupts = <10>;
                reg-shift = <2>;
        };
+
+Example for OMAP UART using GPIO-based modem control signals:
+
+       uart4: serial@49042000 {
+               compatible = "ti,omap3-uart";
+               reg = <0x49042000 0x400>;
+               interrupts = <80>;
+               ti,hwmods = "uart4";
+               clock-frequency = <48000000>;
+               cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
+               rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+               dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+               dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+               dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+               rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+       };
index 528c3b90f23cb04b931be9637f850e7e315e0415..1e4000d83aee06828c974000e5122567b8fda631 100644 (file)
@@ -31,6 +31,8 @@ Required properties:
     - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART.
     - "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART.
     - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART.
+    - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART.
+    - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART.
     - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART.
     - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART.
     - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART,
@@ -76,6 +78,10 @@ Optional properties:
   - dmas: Must contain a list of two references to DMA specifiers, one for
          transmission, and one for reception.
   - dma-names: Must contain a list of two DMA names, "tx" and "rx".
+  - {cts,dsr,dcd,rng,rts,dtr}-gpios: Specify GPIOs for modem lines, cfr. the
+    generic serial DT bindings in serial.txt.
+  - uart-has-rtscts: Indicates dedicated lines for RTS/CTS hardware flow
+    control, cfr. the generic serial DT bindings in serial.txt.
 
 Example:
        aliases {
index 1209323b7e43f372b65d0b1db48c0cfc0f6a9973..8beb8c98f72bf2514a542164eeecd663c718b812 100644 (file)
@@ -10001,6 +10001,7 @@ SERIAL DRIVERS
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-serial@vger.kernel.org
 S:     Maintained
+F:     Documentation/devicetree/bindings/serial/
 F:     drivers/tty/serial/
 
 SYNOPSYS DESIGNWARE DMAC DRIVER
index bce0d0d07e606e67dbce64bd4a6b133e9ed50905..614c6d76789a19d1743d2f3a0bfb263c230f9759 100644 (file)
@@ -12,7 +12,3 @@
  * the base baud is derived from the clock speed and so is variable
  */
 #define BASE_BAUD 0
-
-#define STD_COM_FLAGS          UPF_BOOT_AUTOCONF
-
-#define SERIAL_PORT_DFNS
index 5f4bd71971d6a317562289f2e9156f60fd07ed02..4904c5c16918c146413d4c00af0febf37b25a0dc 100644 (file)
@@ -113,7 +113,6 @@ void platform_heartbeat(void)
 }
 
 //#define RS_TABLE_SIZE 2
-//#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF|UPF_SKIP_TEST)
 
 #define _SERIAL_PORT(_base,_irq)                                       \
 {                                                                      \
index f8c5cd53307c2c5993add0114720bd8b005e4f21..c5f21efd6090ee35b2cbad7e4ceeb59a391ecc8a 100644 (file)
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan *hsuc)
        hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-       unsigned long flags;
-       u32 sr;
-
-       spin_lock_irqsave(&hsuc->vchan.lock, flags);
-       sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-       spin_unlock_irqrestore(&hsuc->vchan.lock, flags);
-
-       return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *      hsu_dma_get_status() - get DMA channel status
+ *      @chip: HSUART DMA chip
+ *      @nr: DMA channel number
+ *      @status: pointer for DMA Channel Status Register value
+ *
+ *      Description:
+ *      The function reads and clears the DMA Channel Status Register, checks
+ *      if it was a timeout interrupt and returns a corresponding value.
+ *
+ *      Caller should provide a valid pointer for the DMA Channel Status
+ *      Register value that will be returned in @status.
+ *
+ *      Return:
+ *      1 for DMA timeout status, 0 for other DMA status, or error code for
+ *      invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+                      u32 *status)
 {
        struct hsu_dma_chan *hsuc;
-       struct hsu_dma_desc *desc;
        unsigned long flags;
        u32 sr;
 
        /* Sanity check */
        if (nr >= chip->hsu->nr_channels)
-               return IRQ_NONE;
+               return -EINVAL;
 
        hsuc = &chip->hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
         * No matter what situation, need read clear the IRQ status
         * There is a bug, see Errata 5, HSD 2900918
         */
-       sr = hsu_dma_chan_get_sr(hsuc);
+       spin_lock_irqsave(&hsuc->vchan.lock, flags);
+       sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+       spin_unlock_irqrestore(&hsuc->vchan.lock, flags);
+
+       /* Check if any interrupt is pending */
+       sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
        if (!sr)
-               return IRQ_NONE;
+               return -EIO;
 
        /* Timeout IRQ, need wait some time, see Errata 2 */
        if (sr & HSU_CH_SR_DESCTO_ANY)
                udelay(2);
 
+       /*
+        * At this point, at least one of Descriptor Time Out, Channel Error
+        * or Descriptor Done bits must be set. Clear the Descriptor Time Out
+        * bits and if sr is still non-zero, it must be channel error or
+        * descriptor done which are higher priority than timeout and handled
+        * in hsu_dma_do_irq(). Else, it must be a timeout.
+        */
        sr &= ~HSU_CH_SR_DESCTO_ANY;
-       if (!sr)
-               return IRQ_HANDLED;
+
+       *status = sr;
+
+       return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *      hsu_dma_do_irq() - DMA interrupt handler
+ *      @chip: HSUART DMA chip
+ *      @nr: DMA channel number
+ *      @status: Channel Status Register value
+ *
+ *      Description:
+ *      This function handles Channel Error and Descriptor Done interrupts.
+ *      This function should be called after determining that the DMA interrupt
+ *      is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *      Return:
+ *      IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+                          u32 status)
+{
+       struct hsu_dma_chan *hsuc;
+       struct hsu_dma_desc *desc;
+       unsigned long flags;
+
+       /* Sanity check */
+       if (nr >= chip->hsu->nr_channels)
+               return IRQ_NONE;
+
+       hsuc = &chip->hsu->chan[nr];
 
        spin_lock_irqsave(&hsuc->vchan.lock, flags);
        desc = hsuc->desc;
        if (desc) {
-               if (sr & HSU_CH_SR_CHE) {
+               if (status & HSU_CH_SR_CHE) {
                        desc->status = DMA_ERROR;
                } else if (desc->active < desc->nents) {
                        hsu_dma_start_channel(hsuc);
@@ -184,7 +232,7 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
 
        return IRQ_HANDLED;
 }
-EXPORT_SYMBOL_GPL(hsu_dma_irq);
+EXPORT_SYMBOL_GPL(hsu_dma_do_irq);
 
 static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents)
 {
index e2db76bd56d89e9118308cb2dfb5d03b64811c0a..9916058531d93945a4534145ffdee75d4f6be6e2 100644 (file)
@@ -27,13 +27,20 @@ static irqreturn_t hsu_pci_irq(int irq, void *dev)
 {
        struct hsu_dma_chip *chip = dev;
        u32 dmaisr;
+       u32 status;
        unsigned short i;
        irqreturn_t ret = IRQ_NONE;
+       int err;
 
        dmaisr = readl(chip->regs + HSU_PCI_DMAISR);
        for (i = 0; i < chip->hsu->nr_channels; i++) {
-               if (dmaisr & 0x1)
-                       ret |= hsu_dma_irq(chip, i);
+               if (dmaisr & 0x1) {
+                       err = hsu_dma_get_status(chip, i, &status);
+                       if (err > 0)
+                               ret |= IRQ_HANDLED;
+                       else if (err == 0)
+                               ret |= hsu_dma_do_irq(chip, i, status);
+               }
                dmaisr >>= 1;
        }
 
index 3840d6b421c402b4caa8974c88450b5958a2e902..5e4fa920686151f94042af7b9e193d3d0486481f 100644 (file)
@@ -93,8 +93,6 @@ static void cy_send_xchar(struct tty_struct *tty, char ch);
 #define        SERIAL_XMIT_SIZE        (min(PAGE_SIZE, 4096))
 #endif
 
-#define STD_COM_FLAGS (0)
-
 /* firmware stuff */
 #define ZL_MAX_BLOCKS  16
 #define DRIVER_VERSION 0x02010203
@@ -2288,7 +2286,6 @@ static int cy_get_serial_info(struct cyclades_port *info,
                .closing_wait = info->port.closing_wait,
                .baud_base = info->baud,
                .custom_divisor = info->custom_divisor,
-               .hub6 = 0,              /*!!! */
        };
        return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
 }
@@ -3084,7 +3081,6 @@ static int cy_init_card(struct cyclades_card *cinfo)
 
                info->port.closing_wait = CLOSING_WAIT_DELAY;
                info->port.close_delay = 5 * HZ / 10;
-               info->port.flags = STD_COM_FLAGS;
                init_completion(&info->shutdown_wait);
 
                if (cy_is_Z(cinfo)) {
index 345cebb07ae7933156784e46956c78983acf2e29..2685d59d27245ca5a4d7b00d15e7938cdbd4d837 100644 (file)
@@ -252,20 +252,11 @@ static int ipwireless_get_serial_info(struct ipw_tty *tty,
 {
        struct serial_struct tmp;
 
-       if (!retinfo)
-               return (-EFAULT);
-
        memset(&tmp, 0, sizeof(tmp));
        tmp.type = PORT_UNKNOWN;
        tmp.line = tty->index;
-       tmp.port = 0;
-       tmp.irq = 0;
-       tmp.flags = 0;
        tmp.baud_base = 115200;
-       tmp.close_delay = 0;
-       tmp.closing_wait = 0;
-       tmp.custom_divisor = 0;
-       tmp.hub6 = 0;
+
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
                return -EFAULT;
 
index 98d2bd16706d5a483774cd405d22220b757538ed..69294ae154be0f17ae0e56c39d6fa048077b3c9c 100644 (file)
@@ -1219,7 +1219,6 @@ static int mxser_get_serial_info(struct tty_struct *tty,
                .close_delay = info->port.close_delay,
                .closing_wait = info->port.closing_wait,
                .custom_divisor = info->custom_divisor,
-               .hub6 = 0
        };
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
                return -EFAULT;
index 215a99237e952d8ceceb71e2c0eb266229746283..122e0e4029fee9e42f4b1ba37f0439728f0d54a4 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/serial_reg.h>
 #include <linux/dmaengine.h>
 
+#include "../serial_mctrl_gpio.h"
+
 struct uart_8250_dma {
        int (*tx_dma)(struct uart_8250_port *p);
        int (*rx_dma)(struct uart_8250_port *p);
@@ -53,11 +55,9 @@ struct old_serial_port {
        unsigned int port;
        unsigned int irq;
        upf_t        flags;
-       unsigned char hub6;
        unsigned char io_type;
        unsigned char __iomem *iomem_base;
        unsigned short iomem_reg_shift;
-       unsigned long irqflags;
 };
 
 struct serial8250_config {
@@ -131,6 +131,47 @@ void serial8250_rpm_put(struct uart_8250_port *p);
 int serial8250_em485_init(struct uart_8250_port *p);
 void serial8250_em485_destroy(struct uart_8250_port *p);
 
+static inline void serial8250_out_MCR(struct uart_8250_port *up, int value)
+{
+       int mctrl_gpio = 0;
+
+       serial_out(up, UART_MCR, value);
+
+       if (value & UART_MCR_RTS)
+               mctrl_gpio |= TIOCM_RTS;
+       if (value & UART_MCR_DTR)
+               mctrl_gpio |= TIOCM_DTR;
+
+       mctrl_gpio_set(up->gpios, mctrl_gpio);
+}
+
+static inline int serial8250_in_MCR(struct uart_8250_port *up)
+{
+       int mctrl, mctrl_gpio = 0;
+
+       mctrl = serial_in(up, UART_MCR);
+
+       /* save current MCR values */
+       if (mctrl & UART_MCR_RTS)
+               mctrl_gpio |= TIOCM_RTS;
+       if (mctrl & UART_MCR_DTR)
+               mctrl_gpio |= TIOCM_DTR;
+
+       mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio);
+
+       if (mctrl_gpio & TIOCM_RTS)
+               mctrl |= UART_MCR_RTS;
+       else
+               mctrl &= ~UART_MCR_RTS;
+
+       if (mctrl_gpio & TIOCM_DTR)
+               mctrl |= UART_MCR_DTR;
+       else
+               mctrl &= ~UART_MCR_DTR;
+
+       return mctrl;
+}
+
 #if defined(__alpha__) && !defined(CONFIG_PCI)
 /*
  * Digital did something really horribly wrong with the OUT1 and OUT2
@@ -237,9 +278,3 @@ static inline int serial_index(struct uart_port *port)
 {
        return port->minor - 64;
 }
-
-#if 0
-#define DEBUG_INTR(fmt...)     printk(fmt)
-#else
-#define DEBUG_INTR(fmt...)     do { } while (0)
-#endif
index 0fbd7c033a251e7d0cb214ed2bbd1ad1f19f0a76..13ad5c3d2e681893aeaa0d675d17c9f04f06b967 100644 (file)
@@ -114,7 +114,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
        struct list_head *l, *end = NULL;
        int pass_counter = 0, handled = 0;
 
-       DEBUG_INTR("serial8250_interrupt(%d)...", irq);
+       pr_debug("%s(%d): start\n", __func__, irq);
 
        spin_lock(&i->lock);
 
@@ -144,7 +144,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 
        spin_unlock(&i->lock);
 
-       DEBUG_INTR("end.\n");
+       pr_debug("%s(%d): end\n", __func__, irq);
 
        return IRQ_RETVAL(handled);
 }
@@ -546,10 +546,10 @@ static void __init serial8250_isa_init_ports(void)
 
                port->iobase   = old_serial_port[i].port;
                port->irq      = irq_canonicalize(old_serial_port[i].irq);
-               port->irqflags = old_serial_port[i].irqflags;
+               port->irqflags = 0;
                port->uartclk  = old_serial_port[i].baud_base * 16;
                port->flags    = old_serial_port[i].flags;
-               port->hub6     = old_serial_port[i].hub6;
+               port->hub6     = 0;
                port->membase  = old_serial_port[i].iomem_base;
                port->iotype   = old_serial_port[i].io_type;
                port->regshift = old_serial_port[i].iomem_reg_shift;
@@ -675,7 +675,7 @@ static struct console univ8250_console = {
        .device         = uart_console_device,
        .setup          = univ8250_console_setup,
        .match          = univ8250_console_match,
-       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME | CON_CONSDEV,
        .index          = -1,
        .data           = &serial8250_reg,
 };
@@ -974,6 +974,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
 
        uart = serial8250_find_match_or_unused(&up->port);
        if (uart && uart->port.type != PORT_8250_CIR) {
+               struct mctrl_gpios *gpios;
+
                if (uart->port.dev)
                        uart_remove_one_port(&serial8250_reg, &uart->port);
 
@@ -1011,6 +1013,13 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                if (up->port.flags & UPF_FIXED_TYPE)
                        uart->port.type = up->port.type;
 
+               gpios = mctrl_gpio_init(&uart->port, 0);
+               if (IS_ERR(gpios)) {
+                       if (PTR_ERR(gpios) != -ENOSYS)
+                               return PTR_ERR(gpios);
+               } else
+                       uart->gpios = gpios;
+
                serial8250_set_defaults(uart);
 
                /* Possibly override default I/O functions.  */
index 7f33d1c8d1a952bc7c5de2953a796d3a0c044a40..3590d012001f8cf5a10bc8a385ac163abe6b5672 100644 (file)
@@ -145,6 +145,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p)
                dmaengine_terminate_all(dma->rxchan);
        }
 }
+EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
 
 int serial8250_request_dma(struct uart_8250_port *p)
 {
index 8d08ff5c4e34b31f359ebe403a5304f3e89a0fb4..85a12f03240247494366a231d24fa86ba042dfdb 100644 (file)
@@ -150,6 +150,7 @@ EARLYCON_DECLARE(uart, early_serial8250_setup);
 OF_EARLYCON_DECLARE(ns16550, "ns16550", early_serial8250_setup);
 OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup);
 OF_EARLYCON_DECLARE(uart, "nvidia,tegra20-uart", early_serial8250_setup);
+OF_EARLYCON_DECLARE(uart, "snps,dw-apb-uart", early_serial8250_setup);
 
 #ifdef CONFIG_SERIAL_8250_OMAP
 
index 870981dd9e39ed1af8ff9ecdddccb42eea349e55..737b4b3957b0bc2470cde5574eed1e5f7230c90a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pnp.h>
 #include <linux/kernel.h>
 #include <linux/serial_core.h>
+#include <linux/irq.h>
 #include  "8250.h"
 
 #define ADDR_PORT 0
 #define IO_ADDR2 0x60
 #define LDN 0x7
 
+#define IRQ_MODE       0x70
+#define IRQ_SHARE      BIT(4)
+#define IRQ_MODE_MASK  (BIT(6) | BIT(5))
+#define IRQ_LEVEL_LOW  0
+#define IRQ_EDGE_HIGH  BIT(5)
+
 #define RS485  0xF0
 #define RTS_INVERT BIT(5)
 #define RS485_URA BIT(4)
@@ -176,10 +183,37 @@ static int find_base_port(struct fintek_8250 *pdata, u16 io_address)
        return -ENODEV;
 }
 
+static int fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool level_mode)
+{
+       int status;
+       u8 tmp;
+
+       status = fintek_8250_enter_key(pdata->base_port, pdata->key);
+       if (status)
+               return status;
+
+       outb(LDN, pdata->base_port + ADDR_PORT);
+       outb(pdata->index, pdata->base_port + DATA_PORT);
+
+       outb(IRQ_MODE, pdata->base_port + ADDR_PORT);
+       tmp = inb(pdata->base_port + DATA_PORT);
+
+       tmp &= ~IRQ_MODE_MASK;
+       tmp |= IRQ_SHARE;
+       if (!level_mode)
+               tmp |= IRQ_EDGE_HIGH;
+
+       outb(tmp, pdata->base_port + DATA_PORT);
+       fintek_8250_exit_key(pdata->base_port);
+       return 0;
+}
+
 int fintek_8250_probe(struct uart_8250_port *uart)
 {
        struct fintek_8250 *pdata;
        struct fintek_8250 probe_data;
+       struct irq_data *irq_data = irq_get_irq_data(uart->port.irq);
+       bool level_mode = irqd_is_level_type(irq_data);
 
        if (find_base_port(&probe_data, uart->port.iobase))
                return -ENODEV;
@@ -192,5 +226,5 @@ int fintek_8250_probe(struct uart_8250_port *uart)
        uart->port.rs485_config = fintek_8250_rs485_config;
        uart->port.private_data = pdata;
 
-       return 0;
+       return fintek_8250_set_irq_mode(pdata, level_mode);
 }
index b0677f610863d3a6a61423623e7627bae35638d2..4d9dc10e265c9c0dd5d850bea791e25c4475ef55 100644 (file)
@@ -48,7 +48,6 @@ static const struct of_device_id of_match[];
 #define UART_MCR_MDCE  BIT(7)
 #define UART_MCR_FCM   BIT(6)
 
-#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
 static struct earlycon_device *early_device;
 
 static uint8_t __init early_in(struct uart_port *port, int offset)
@@ -141,7 +140,6 @@ OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart",
 EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup);
 OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart",
                    ingenic_early_console_setup);
-#endif /* CONFIG_SERIAL_EARLYCON */
 
 static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
 {
index 86379a79a6a33c6f728892a353454356bbbefb68..339de9cd086612c60d17ef3c581b59df34a0022a 100644 (file)
@@ -96,13 +96,27 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
        struct mid8250 *mid = p->private_data;
+       struct uart_8250_port *up = up_to_u8250p(p);
        unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
+       u32 status;
        int ret = IRQ_NONE;
-
-       if (fisr & BIT(2))
-               ret |= hsu_dma_irq(&mid->dma_chip, 1);
-       if (fisr & BIT(1))
-               ret |= hsu_dma_irq(&mid->dma_chip, 0);
+       int err;
+
+       if (fisr & BIT(2)) {
+               err = hsu_dma_get_status(&mid->dma_chip, 1, &status);
+               if (err > 0) {
+                       serial8250_rx_dma_flush(up);
+                       ret |= IRQ_HANDLED;
+               } else if (err == 0)
+                       ret |= hsu_dma_do_irq(&mid->dma_chip, 1, status);
+       }
+       if (fisr & BIT(1)) {
+               err = hsu_dma_get_status(&mid->dma_chip, 0, &status);
+               if (err > 0)
+                       ret |= IRQ_HANDLED;
+               else if (err == 0)
+                       ret |= hsu_dma_do_irq(&mid->dma_chip, 0, status);
+       }
        if (fisr & BIT(0))
                ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
        return ret;
index 3489fbcb7313a1e1cc59e6591beccf313f865eb0..3611ec9bb4fa27407cc50f157321f8e4ed1708fd 100644 (file)
@@ -301,7 +301,7 @@ static struct platform_driver mtk8250_platform_driver = {
 };
 module_platform_driver(mtk8250_platform_driver);
 
-#if defined(CONFIG_SERIAL_8250_CONSOLE) && !defined(MODULE)
+#ifdef CONFIG_SERIAL_8250_CONSOLE
 static int __init early_mtk8250_setup(struct earlycon_device *device,
                                        const char *options)
 {
index 2c44c792d5865addd380a21dfc70f5f62401d8c5..e14982f36a04dff107b11f1f5e75b2b7a587390a 100644 (file)
@@ -134,18 +134,21 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
        serial8250_do_set_mctrl(port, mctrl);
 
-       /*
-        * Turn off autoRTS if RTS is lowered and restore autoRTS setting
-        * if RTS is raised
-        */
-       lcr = serial_in(up, UART_LCR);
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
-               priv->efr |= UART_EFR_RTS;
-       else
-               priv->efr &= ~UART_EFR_RTS;
-       serial_out(up, UART_EFR, priv->efr);
-       serial_out(up, UART_LCR, lcr);
+       if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios,
+                                               UART_GPIO_RTS))) {
+               /*
+                * Turn off autoRTS if RTS is lowered and restore autoRTS
+                * setting if RTS is raised
+                */
+               lcr = serial_in(up, UART_LCR);
+               serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+               if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
+                       priv->efr |= UART_EFR_RTS;
+               else
+                       priv->efr &= ~UART_EFR_RTS;
+               serial_out(up, UART_EFR, priv->efr);
+               serial_out(up, UART_LCR, lcr);
+       }
 }
 
 /*
@@ -280,7 +283,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
        serial_out(up, UART_EFR, UART_EFR_ECB);
 
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       serial_out(up, UART_MCR, UART_MCR_TCRTLR);
+       serial8250_out_MCR(up, UART_MCR_TCRTLR);
        serial_out(up, UART_FCR, up->fcr);
 
        omap8250_update_scr(up, priv);
@@ -296,7 +299,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
        serial_out(up, UART_LCR, 0);
 
        /* drop TCR + TLR access, we setup XON/XOFF later */
-       serial_out(up, UART_MCR, up->mcr);
+       serial8250_out_MCR(up, up->mcr);
        serial_out(up, UART_IER, up->ier);
 
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
@@ -446,7 +449,9 @@ static void omap_8250_set_termios(struct uart_port *port,
        priv->efr = 0;
        up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF);
 
-       if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) {
+       if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW
+               && IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios,
+                                                       UART_GPIO_RTS))) {
                /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */
                up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
                priv->efr |= UART_EFR_CTS;
index 8dd250fbd36726dc6fc370a75f7f412eee995766..20ebaea5c414d6d70f371aa9d367cd40327fa909 100644 (file)
@@ -1136,11 +1136,11 @@ static int pci_quatech_rqopr(struct uart_8250_port *port)
 static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr)
 {
        unsigned long base = port->port.iobase;
-       u8 LCR, val;
+       u8 LCR;
 
        LCR = inb(base + UART_LCR);
        outb(0xBF, base + UART_LCR);
-       val = inb(base + UART_SCR);
+       inb(base + UART_SCR);
        outb(qopr, base + UART_SCR);
        outb(LCR, base + UART_LCR);
 }
@@ -1864,6 +1864,16 @@ pci_wch_ch353_setup(struct serial_private *priv,
        return pci_default_setup(priv, board, port, idx);
 }
 
+static int
+pci_wch_ch355_setup(struct serial_private *priv,
+               const struct pciserial_board *board,
+               struct uart_8250_port *port, int idx)
+{
+       port->port.flags |= UPF_FIXED_TYPE;
+       port->port.type = PORT_16550A;
+       return pci_default_setup(priv, board, port, idx);
+}
+
 static int
 pci_wch_ch38x_setup(struct serial_private *priv,
                    const struct pciserial_board *board,
@@ -1915,6 +1925,7 @@ pci_wch_ch38x_setup(struct serial_private *priv,
 #define PCI_DEVICE_ID_WCH_CH353_2S1PF  0x5046
 #define PCI_DEVICE_ID_WCH_CH353_1S1P   0x5053
 #define PCI_DEVICE_ID_WCH_CH353_2S1P   0x7053
+#define PCI_DEVICE_ID_WCH_CH355_4S     0x7173
 #define PCI_VENDOR_ID_AGESTAR          0x5372
 #define PCI_DEVICE_ID_AGESTAR_9375     0x6872
 #define PCI_VENDOR_ID_ASIX             0x9710
@@ -2618,6 +2629,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_wch_ch353_setup,
        },
+       /* WCH CH355 4S card (16550 clone) */
+       {
+               .vendor         = PCI_VENDOR_ID_WCH,
+               .device         = PCI_DEVICE_ID_WCH_CH355_4S,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_wch_ch355_setup,
+       },
        /* WCH CH382 2S card (16850 clone) */
        {
                .vendor         = PCIE_VENDOR_ID_WCH,
@@ -3812,6 +3831,7 @@ static const struct pci_device_id blacklist[] = {
        /* multi-io cards handled by parport_serial */
        { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */
        { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */
+       { PCI_DEVICE(0x4348, 0x7173), }, /* WCH CH355 4S */
        { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */
        { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */
 
@@ -5567,6 +5587,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_ANY_ID, PCI_ANY_ID,
                0, 0, pbn_b0_bt_2_115200 },
 
+       {       PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH355_4S,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0, pbn_b0_bt_4_115200 },
+
        {       PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH382_2S,
                PCI_ANY_ID, PCI_ANY_ID,
                0, 0, pbn_wch382_2 },
index d4036038a4ddbe7bfb50406b2234381698bbe3ca..7481b95c6d846770b10f77a64e8231c7b2ad4e8e 100644 (file)
@@ -527,13 +527,13 @@ static void serial8250_clear_fifos(struct uart_8250_port *p)
 
 static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p)
 {
-       unsigned char mcr = serial_in(p, UART_MCR);
+       unsigned char mcr = serial8250_in_MCR(p);
 
        if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND)
                mcr |= UART_MCR_RTS;
        else
                mcr &= ~UART_MCR_RTS;
-       serial_out(p, UART_MCR, mcr);
+       serial8250_out_MCR(p, mcr);
 }
 
 static void serial8250_em485_handle_start_tx(unsigned long arg);
@@ -785,10 +785,10 @@ static int size_fifo(struct uart_8250_port *up)
        old_lcr = serial_in(up, UART_LCR);
        serial_out(up, UART_LCR, 0);
        old_fcr = serial_in(up, UART_FCR);
-       old_mcr = serial_in(up, UART_MCR);
+       old_mcr = serial8250_in_MCR(up);
        serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
                    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-       serial_out(up, UART_MCR, UART_MCR_LOOP);
+       serial8250_out_MCR(up, UART_MCR_LOOP);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        old_dl = serial_dl_read(up);
        serial_dl_write(up, 0x0001);
@@ -800,7 +800,7 @@ static int size_fifo(struct uart_8250_port *up)
             (count < 256); count++)
                serial_in(up, UART_RX);
        serial_out(up, UART_FCR, old_fcr);
-       serial_out(up, UART_MCR, old_mcr);
+       serial8250_out_MCR(up, old_mcr);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_dl_write(up, old_dl);
        serial_out(up, UART_LCR, old_lcr);
@@ -1040,17 +1040,17 @@ static void autoconfig_16550a(struct uart_8250_port *up)
         * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
         */
        serial_out(up, UART_LCR, 0);
-       status1 = serial_in(up, UART_MCR);
+       status1 = serial8250_in_MCR(up);
        serial_out(up, UART_LCR, 0xE0);
        status2 = serial_in(up, 0x02); /* EXCR1 */
 
        if (!((status2 ^ status1) & UART_MCR_LOOP)) {
                serial_out(up, UART_LCR, 0);
-               serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP);
+               serial8250_out_MCR(up, status1 ^ UART_MCR_LOOP);
                serial_out(up, UART_LCR, 0xE0);
                status2 = serial_in(up, 0x02); /* EXCR1 */
                serial_out(up, UART_LCR, 0);
-               serial_out(up, UART_MCR, status1);
+               serial8250_out_MCR(up, status1);
 
                if ((status2 ^ status1) & UART_MCR_LOOP) {
                        unsigned short quot;
@@ -1224,7 +1224,7 @@ static void autoconfig(struct uart_8250_port *up)
                }
        }
 
-       save_mcr = serial_in(up, UART_MCR);
+       save_mcr = serial8250_in_MCR(up);
        save_lcr = serial_in(up, UART_LCR);
 
        /*
@@ -1237,9 +1237,9 @@ static void autoconfig(struct uart_8250_port *up)
         * that conflicts with COM 1-4 --- we hope!
         */
        if (!(port->flags & UPF_SKIP_TEST)) {
-               serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+               serial8250_out_MCR(up, UART_MCR_LOOP | 0x0A);
                status1 = serial_in(up, UART_MSR) & 0xF0;
-               serial_out(up, UART_MCR, save_mcr);
+               serial8250_out_MCR(up, save_mcr);
                if (status1 != 0x90) {
                        spin_unlock_irqrestore(&port->lock, flags);
                        DEBUG_AUTOCONF("LOOP test failed (%02x) ",
@@ -1305,7 +1305,7 @@ static void autoconfig(struct uart_8250_port *up)
        if (port->type == PORT_RSA)
                serial_out(up, UART_RSA_FRR, 0);
 #endif
-       serial_out(up, UART_MCR, save_mcr);
+       serial8250_out_MCR(up, save_mcr);
        serial8250_clear_fifos(up);
        serial_in(up, UART_RX);
        if (up->capabilities & UART_CAP_UUE)
@@ -1353,19 +1353,18 @@ static void autoconfig_irq(struct uart_8250_port *up)
 
        /* forget possible initially masked and pending IRQ */
        probe_irq_off(probe_irq_on());
-       save_mcr = serial_in(up, UART_MCR);
+       save_mcr = serial8250_in_MCR(up);
        save_ier = serial_in(up, UART_IER);
-       serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+       serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2);
 
        irqs = probe_irq_on();
-       serial_out(up, UART_MCR, 0);
+       serial8250_out_MCR(up, 0);
        udelay(10);
        if (port->flags & UPF_FOURPORT) {
-               serial_out(up, UART_MCR,
-                           UART_MCR_DTR | UART_MCR_RTS);
+               serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
        } else {
-               serial_out(up, UART_MCR,
-                           UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+               serial8250_out_MCR(up,
+                       UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
        }
        serial_out(up, UART_IER, 0x0f); /* enable all intrs */
        serial_in(up, UART_LSR);
@@ -1376,7 +1375,7 @@ static void autoconfig_irq(struct uart_8250_port *up)
        udelay(20);
        irq = probe_irq_off(irqs);
 
-       serial_out(up, UART_MCR, save_mcr);
+       serial8250_out_MCR(up, save_mcr);
        serial_out(up, UART_IER, save_ier);
 
        if (port->flags & UPF_FOURPORT)
@@ -1549,14 +1548,14 @@ static inline void start_tx_rs485(struct uart_port *port)
        del_timer(&em485->stop_tx_timer);
        em485->active_timer = NULL;
 
-       mcr = serial_in(up, UART_MCR);
+       mcr = serial8250_in_MCR(up);
        if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) !=
            !!(mcr & UART_MCR_RTS)) {
                if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND)
                        mcr |= UART_MCR_RTS;
                else
                        mcr &= ~UART_MCR_RTS;
-               serial_out(up, UART_MCR, mcr);
+               serial8250_out_MCR(up, mcr);
 
                if (up->port.rs485.delay_rts_before_send > 0) {
                        em485->active_timer = &em485->start_tx_timer;
@@ -1619,6 +1618,8 @@ static void serial8250_disable_ms(struct uart_port *port)
        if (up->bugs & UART_BUG_NOMSR)
                return;
 
+       mctrl_gpio_disable_ms(up->gpios);
+
        up->ier &= ~UART_IER_MSI;
        serial_port_out(port, UART_IER, up->ier);
 }
@@ -1631,6 +1632,8 @@ static void serial8250_enable_ms(struct uart_port *port)
        if (up->bugs & UART_BUG_NOMSR)
                return;
 
+       mctrl_gpio_enable_ms(up->gpios);
+
        up->ier |= UART_IER_MSI;
 
        serial8250_rpm_get(up);
@@ -1686,7 +1689,7 @@ static void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
                lsr &= port->read_status_mask;
 
                if (lsr & UART_LSR_BI) {
-                       DEBUG_INTR("handling break....");
+                       pr_debug("%s: handling break\n", __func__);
                        flag = TTY_BREAK;
                } else if (lsr & UART_LSR_PE)
                        flag = TTY_PARITY;
@@ -1757,7 +1760,7 @@ void serial8250_tx_chars(struct uart_8250_port *up)
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       DEBUG_INTR("THRE...");
+       pr_debug("%s: THRE\n", __func__);
 
        /*
         * With RPM enabled, we have to wait until the FIFO is empty before the
@@ -1823,7 +1826,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 
        status = serial_port_in(port, UART_LSR);
 
-       DEBUG_INTR("status = %x...", status);
+       pr_debug("%s: status = %x\n", __func__, status);
 
        if (status & (UART_LSR_DR | UART_LSR_BI)) {
                if (!up->dma || handle_rx_dma(up, iir))
@@ -1861,7 +1864,6 @@ static int serial8250_default_handle_irq(struct uart_port *port)
  */
 static int exar_handle_irq(struct uart_port *port)
 {
-       unsigned char int0, int1, int2, int3;
        unsigned int iir = serial_port_in(port, UART_IIR);
        int ret;
 
@@ -1869,10 +1871,10 @@ static int exar_handle_irq(struct uart_port *port)
 
        if ((port->type == PORT_XR17V35X) ||
           (port->type == PORT_XR17D15X)) {
-               int0 = serial_port_in(port, 0x80);
-               int1 = serial_port_in(port, 0x81);
-               int2 = serial_port_in(port, 0x82);
-               int3 = serial_port_in(port, 0x83);
+               serial_port_in(port, 0x80);
+               serial_port_in(port, 0x81);
+               serial_port_in(port, 0x82);
+               serial_port_in(port, 0x83);
        }
 
        return ret;
@@ -1915,7 +1917,8 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port)
                ret |= TIOCM_DSR;
        if (status & UART_MSR_CTS)
                ret |= TIOCM_CTS;
-       return ret;
+
+       return mctrl_gpio_get(up->gpios, &ret);
 }
 EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl);
 
@@ -1944,7 +1947,7 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
        mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
 
-       serial_port_out(port, UART_MCR, mcr);
+       serial8250_out_MCR(up, mcr);
 }
 EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);
 
@@ -1994,8 +1997,6 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 
        /* Wait up to 1s for flow control if necessary */
        if (up->port.flags & UPF_CONS_FLOW) {
-               unsigned int tmout;
-
                for (tmout = 1000000; tmout; tmout--) {
                        unsigned int msr = serial_in(up, UART_MSR);
                        up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
@@ -3093,7 +3094,7 @@ static void serial8250_console_restore(struct uart_8250_port *up)
 
        serial8250_set_divisor(port, baud, quot, frac);
        serial_port_out(port, UART_LCR, up->lcr);
-       serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+       serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
 }
 
 /*
index efd1f9c047b1c0ce0e75d200b07bab8f9a4424a0..b8d9c8c9d02a9762a2be77861554f13e49488a0c 100644 (file)
@@ -35,7 +35,7 @@ struct uniphier8250_priv {
        spinlock_t atomic_write_lock;
 };
 
-#if defined(CONFIG_SERIAL_8250_CONSOLE) && !defined(MODULE)
+#ifdef CONFIG_SERIAL_8250_CONSOLE
 static int __init uniphier_early_console_setup(struct earlycon_device *device,
                                               const char *options)
 {
index e46761d20f7b4c780784d48c9f8de23f47f5134c..c9ec839a5ddf447a6b7b3fe3158ad4104e3024c2 100644 (file)
@@ -6,6 +6,7 @@
 config SERIAL_8250
        tristate "8250/16550 and compatible serial support"
        select SERIAL_CORE
+       select SERIAL_MCTRL_GPIO if GPIOLIB
        ---help---
          This selects whether you want to include the driver for the standard
          serial ports.  The standard answer is Y.  People who might say N
@@ -387,7 +388,8 @@ config SERIAL_8250_MT6577
 
 config SERIAL_8250_UNIPHIER
        tristate "Support for UniPhier on-chip UART"
-       depends on SERIAL_8250 && ARCH_UNIPHIER
+       depends on SERIAL_8250
+       depends on ARCH_UNIPHIER || COMPILE_TEST
        help
          If you have a UniPhier based board and want to use the on-chip
          serial ports, say Y to this option. If unsure, say N.
@@ -395,7 +397,7 @@ config SERIAL_8250_UNIPHIER
 config SERIAL_8250_INGENIC
        tristate "Support for Ingenic SoC serial ports"
        depends on SERIAL_8250
-       depends on (OF_FLATTREE && SERIAL_8250_CONSOLE) || !SERIAL_EARLYCON
+       depends on OF_FLATTREE
        depends on MIPS || COMPILE_TEST
        help
          If you have a system using an Ingenic SoC and wish to make use of
index 7e3a58c8bb67cd80020408a24f216332fc709d9f..518db24a5b36df38e03161d251d68f949453ee05 100644 (file)
@@ -736,6 +736,7 @@ config SERIAL_SH_SCI
        tristate "SuperH SCI(F) serial port support"
        depends on SUPERH || ARCH_RENESAS || H8300 || COMPILE_TEST
        select SERIAL_CORE
+       select SERIAL_MCTRL_GPIO if GPIOLIB
 
 config SERIAL_SH_SCI_NR_UARTS
        int "Maximum number of SCI(F) serial ports"
@@ -1477,7 +1478,7 @@ config SERIAL_MPS2_UART_CONSOLE
 
 config SERIAL_MPS2_UART
        bool "MPS2 UART port"
-       depends on ARM || COMPILE_TEST
+       depends on ARCH_MPS2 || COMPILE_TEST
        select SERIAL_CORE
        help
          This driver support the UART ports on ARM MPS2.
index 1b7331e40d795e1ec5482d6a82871bd5ce050b60..8a9e213387a79fcc335caad27520a68edf03f446 100644 (file)
@@ -2553,11 +2553,17 @@ static int sbsa_uart_probe(struct platform_device *pdev)
        if (!uap)
                return -ENOMEM;
 
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "cannot obtain irq\n");
+               return ret;
+       }
+       uap->port.irq   = ret;
+
        uap->reg_offset = vendor_sbsa.reg_offset;
        uap->vendor     = &vendor_sbsa;
        uap->fifosize   = 32;
        uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM;
-       uap->port.irq   = platform_get_irq(pdev, 0);
        uap->port.ops   = &sbsa_uart_pops;
        uap->fixed_baud = baudrate;
 
index 954941dd812478e4eb9120b40412dd8ba9fadaef..2eaa18ddef6171640729bf8a770363331f5edaa3 100644 (file)
@@ -108,6 +108,12 @@ struct atmel_uart_char {
        u16             ch;
 };
 
+/*
+ * Be careful, the real size of the ring buffer is
+ * sizeof(atmel_uart_char) * ATMEL_SERIAL_RINGSIZE. It means that ring buffer
+ * can contain up to 1024 characters in PIO mode and up to 4096 characters in
+ * DMA mode.
+ */
 #define ATMEL_SERIAL_RINGSIZE 1024
 
 /*
@@ -145,10 +151,10 @@ struct atmel_uart_port {
        dma_cookie_t                    cookie_rx;
        struct scatterlist              sg_tx;
        struct scatterlist              sg_rx;
-       struct tasklet_struct   tasklet;
-       unsigned int            irq_status;
+       struct tasklet_struct   tasklet_rx;
+       struct tasklet_struct   tasklet_tx;
+       atomic_t                tasklet_shutdown;
        unsigned int            irq_status_prev;
-       unsigned int            status_change;
        unsigned int            tx_len;
 
        struct circ_buf         rx_ring;
@@ -281,6 +287,13 @@ static bool atmel_use_fifo(struct uart_port *port)
        return atmel_port->fifo_size;
 }
 
+static void atmel_tasklet_schedule(struct atmel_uart_port *atmel_port,
+                                  struct tasklet_struct *t)
+{
+       if (!atomic_read(&atmel_port->tasklet_shutdown))
+               tasklet_schedule(t);
+}
+
 static unsigned int atmel_get_lines_status(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
@@ -482,19 +495,21 @@ static void atmel_start_tx(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       if (atmel_use_pdc_tx(port)) {
-               if (atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN)
-                       /* The transmitter is already running.  Yes, we
-                          really need this.*/
-                       return;
+       if (atmel_use_pdc_tx(port) && (atmel_uart_readl(port, ATMEL_PDC_PTSR)
+                                      & ATMEL_PDC_TXTEN))
+               /* The transmitter is already running.  Yes, we
+                  really need this.*/
+               return;
 
+       if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
                if ((port->rs485.flags & SER_RS485_ENABLED) &&
                    !(port->rs485.flags & SER_RS485_RX_DURING_TX))
                        atmel_stop_rx(port);
 
+       if (atmel_use_pdc_tx(port))
                /* re-enable PDC transmit */
                atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
-       }
+
        /* Enable interrupts */
        atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
 }
@@ -710,7 +725,7 @@ static void atmel_rx_chars(struct uart_port *port)
                status = atmel_uart_readl(port, ATMEL_US_CSR);
        }
 
-       tasklet_schedule(&atmel_port->tasklet);
+       atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_rx);
 }
 
 /*
@@ -781,7 +796,7 @@ static void atmel_complete_tx_dma(void *arg)
         * remaining data from the beginning of xmit->buf to xmit->head.
         */
        if (!uart_circ_empty(xmit))
-               tasklet_schedule(&atmel_port->tasklet);
+               atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
@@ -966,7 +981,7 @@ static void atmel_complete_rx_dma(void *arg)
        struct uart_port *port = arg;
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       tasklet_schedule(&atmel_port->tasklet);
+       atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_rx);
 }
 
 static void atmel_release_rx_dma(struct uart_port *port)
@@ -1006,7 +1021,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
        if (dmastat == DMA_ERROR) {
                dev_dbg(port->dev, "Get residue error, restart tasklet\n");
                atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT);
-               tasklet_schedule(&atmel_port->tasklet);
+               atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_rx);
                return;
        }
 
@@ -1160,8 +1175,11 @@ static void atmel_uart_timer_callback(unsigned long data)
        struct uart_port *port = (void *)data;
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       tasklet_schedule(&atmel_port->tasklet);
-       mod_timer(&atmel_port->uart_timer, jiffies + uart_poll_timeout(port));
+       if (!atomic_read(&atmel_port->tasklet_shutdown)) {
+               tasklet_schedule(&atmel_port->tasklet_rx);
+               mod_timer(&atmel_port->uart_timer,
+                         jiffies + uart_poll_timeout(port));
+       }
 }
 
 /*
@@ -1183,7 +1201,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending)
                if (pending & (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)) {
                        atmel_uart_writel(port, ATMEL_US_IDR,
                                          (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT));
-                       tasklet_schedule(&atmel_port->tasklet);
+                       atmel_tasklet_schedule(atmel_port,
+                                              &atmel_port->tasklet_rx);
                }
 
                if (pending & (ATMEL_US_RXBRK | ATMEL_US_OVRE |
@@ -1195,7 +1214,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending)
                if (pending & ATMEL_US_TIMEOUT) {
                        atmel_uart_writel(port, ATMEL_US_IDR,
                                          ATMEL_US_TIMEOUT);
-                       tasklet_schedule(&atmel_port->tasklet);
+                       atmel_tasklet_schedule(atmel_port,
+                                              &atmel_port->tasklet_rx);
                }
        }
 
@@ -1225,7 +1245,7 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)
                /* Either PDC or interrupt transmission */
                atmel_uart_writel(port, ATMEL_US_IDR,
                                  atmel_port->tx_done_mask);
-               tasklet_schedule(&atmel_port->tasklet);
+               atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
        }
 }
 
@@ -1237,14 +1257,27 @@ atmel_handle_status(struct uart_port *port, unsigned int pending,
                    unsigned int status)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+       unsigned int status_change;
 
        if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC
                                | ATMEL_US_CTSIC)) {
-               atmel_port->irq_status = status;
-               atmel_port->status_change = atmel_port->irq_status ^
-                                           atmel_port->irq_status_prev;
+               status_change = status ^ atmel_port->irq_status_prev;
                atmel_port->irq_status_prev = status;
-               tasklet_schedule(&atmel_port->tasklet);
+
+               if (status_change & (ATMEL_US_RI | ATMEL_US_DSR
+                                       | ATMEL_US_DCD | ATMEL_US_CTS)) {
+                       /* TODO: All reads to CSR will clear these interrupts! */
+                       if (status_change & ATMEL_US_RI)
+                               port->icount.rng++;
+                       if (status_change & ATMEL_US_DSR)
+                               port->icount.dsr++;
+                       if (status_change & ATMEL_US_DCD)
+                               uart_handle_dcd_change(port, !(status & ATMEL_US_DCD));
+                       if (status_change & ATMEL_US_CTS)
+                               uart_handle_cts_change(port, !(status & ATMEL_US_CTS));
+
+                       wake_up_interruptible(&port->state->port.delta_msr_wait);
+               }
        }
 }
 
@@ -1571,37 +1604,25 @@ static int atmel_prepare_rx_pdc(struct uart_port *port)
 /*
  * tasklet handling tty stuff outside the interrupt handler.
  */
-static void atmel_tasklet_func(unsigned long data)
+static void atmel_tasklet_rx_func(unsigned long data)
 {
        struct uart_port *port = (struct uart_port *)data;
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-       unsigned int status = atmel_port->irq_status;
-       unsigned int status_change = atmel_port->status_change;
 
        /* The interrupt handler does not take the lock */
        spin_lock(&port->lock);
-
-       atmel_port->schedule_tx(port);
-
-       if (status_change & (ATMEL_US_RI | ATMEL_US_DSR
-                               | ATMEL_US_DCD | ATMEL_US_CTS)) {
-               /* TODO: All reads to CSR will clear these interrupts! */
-               if (status_change & ATMEL_US_RI)
-                       port->icount.rng++;
-               if (status_change & ATMEL_US_DSR)
-                       port->icount.dsr++;
-               if (status_change & ATMEL_US_DCD)
-                       uart_handle_dcd_change(port, !(status & ATMEL_US_DCD));
-               if (status_change & ATMEL_US_CTS)
-                       uart_handle_cts_change(port, !(status & ATMEL_US_CTS));
-
-               wake_up_interruptible(&port->state->port.delta_msr_wait);
-
-               atmel_port->status_change = 0;
-       }
-
        atmel_port->schedule_rx(port);
+       spin_unlock(&port->lock);
+}
+
+static void atmel_tasklet_tx_func(unsigned long data)
+{
+       struct uart_port *port = (struct uart_port *)data;
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
+       /* The interrupt handler does not take the lock */
+       spin_lock(&port->lock);
+       atmel_port->schedule_tx(port);
        spin_unlock(&port->lock);
 }
 
@@ -1785,7 +1806,11 @@ static int atmel_startup(struct uart_port *port)
                return retval;
        }
 
-       tasklet_enable(&atmel_port->tasklet);
+       atomic_set(&atmel_port->tasklet_shutdown, 0);
+       tasklet_init(&atmel_port->tasklet_rx, atmel_tasklet_rx_func,
+                       (unsigned long)port);
+       tasklet_init(&atmel_port->tasklet_tx, atmel_tasklet_tx_func,
+                       (unsigned long)port);
 
        /*
         * Initialize DMA (if necessary)
@@ -1833,7 +1858,6 @@ static int atmel_startup(struct uart_port *port)
 
        /* Save current CSR for comparison in atmel_tasklet_func() */
        atmel_port->irq_status_prev = atmel_get_lines_status(port);
-       atmel_port->irq_status = atmel_port->irq_status_prev;
 
        /*
         * Finally, enable the serial port
@@ -1905,29 +1929,36 @@ static void atmel_shutdown(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
+       /* Disable interrupts at device level */
+       atmel_uart_writel(port, ATMEL_US_IDR, -1);
+
+       /* Prevent spurious interrupts from scheduling the tasklet */
+       atomic_inc(&atmel_port->tasklet_shutdown);
+
        /*
         * Prevent any tasklets being scheduled during
         * cleanup
         */
        del_timer_sync(&atmel_port->uart_timer);
 
+       /* Make sure that no interrupt is on the fly */
+       synchronize_irq(port->irq);
+
        /*
         * Clear out any scheduled tasklets before
         * we destroy the buffers
         */
-       tasklet_disable(&atmel_port->tasklet);
-       tasklet_kill(&atmel_port->tasklet);
+       tasklet_kill(&atmel_port->tasklet_rx);
+       tasklet_kill(&atmel_port->tasklet_tx);
 
        /*
         * Ensure everything is stopped and
-        * disable all interrupts, port and break condition.
+        * disable port and break condition.
         */
        atmel_stop_rx(port);
        atmel_stop_tx(port);
 
        atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);
-       atmel_uart_writel(port, ATMEL_US_IDR, -1);
-
 
        /*
         * Shut-down the DMA.
@@ -2311,10 +2342,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
        port->irq       = pdev->resource[1].start;
        port->rs485_config      = atmel_config_rs485;
 
-       tasklet_init(&atmel_port->tasklet, atmel_tasklet_func,
-                       (unsigned long)port);
-       tasklet_disable(&atmel_port->tasklet);
-
        memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
        if (pdata && pdata->regs) {
@@ -2699,6 +2726,7 @@ static int atmel_serial_probe(struct platform_device *pdev)
        atmel_port->uart.line = ret;
        atmel_serial_probe_fifos(atmel_port, pdev);
 
+       atomic_set(&atmel_port->tasklet_shutdown, 0);
        spin_lock_init(&atmel_port->lock_suspended);
 
        ret = atmel_init_port(atmel_port, pdev);
@@ -2795,7 +2823,8 @@ static int atmel_serial_remove(struct platform_device *pdev)
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
        int ret = 0;
 
-       tasklet_kill(&atmel_port->tasklet);
+       tasklet_kill(&atmel_port->tasklet_rx);
+       tasklet_kill(&atmel_port->tasklet_tx);
 
        device_init_wakeup(&pdev->dev, 0);
 
index c28e5c24da16041087fcc463e8bc19cb45ee23a0..5108fab953aadf665dfb8dc6d8efab9d69781556 100644 (file)
@@ -813,8 +813,12 @@ static int bcm_uart_probe(struct platform_device *pdev)
        struct clk *clk;
        int ret;
 
-       if (pdev->dev.of_node)
-               pdev->id = of_alias_get_id(pdev->dev.of_node, "uart");
+       if (pdev->dev.of_node) {
+               pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+
+               if (pdev->id < 0)
+                       pdev->id = of_alias_get_id(pdev->dev.of_node, "uart");
+       }
 
        if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS)
                return -EINVAL;
index 3d790033744efd060bf42dad1f494a5ee4da0155..7f95f782a48561e5ef466230c1a54dc8cf17455d 100644 (file)
@@ -1830,7 +1830,13 @@ static int lpuart_probe(struct platform_device *pdev)
        sport->port.dev = &pdev->dev;
        sport->port.type = PORT_LPUART;
        sport->port.iotype = UPIO_MEM;
-       sport->port.irq = platform_get_irq(pdev, 0);
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "cannot obtain irq\n");
+               return ret;
+       }
+       sport->port.irq = ret;
+
        if (sport->lpuart32)
                sport->port.ops = &lpuart32_pops;
        else
index 68765f7c2645be08ac3f7651214a119a35150d34..218b7118e85d1288a8d812f05191be5ec5aaa684 100644 (file)
@@ -30,7 +30,6 @@
 #define SUPPORT_SYSRQ
 #endif
 
-#include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/ioport.h>
@@ -51,9 +50,6 @@
 
 #define PASS_LIMIT     256
 
-/* Standard COM flags */
-#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
-
 static const struct {
        unsigned int port;
        unsigned int irq;
@@ -892,7 +888,7 @@ static void __init m32r_sio_init_ports(void)
                up->port.iobase   = old_serial_port[i].port;
                up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
                up->port.uartclk  = BAUD_RATE * 16;
-               up->port.flags    = STD_COM_FLAGS;
+               up->port.flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
                up->port.membase  = 0;
                up->port.iotype   = 0;
                up->port.regshift = 0;
@@ -1060,19 +1056,4 @@ static int __init m32r_sio_init(void)
 
        return ret;
 }
-
-static void __exit m32r_sio_exit(void)
-{
-       int i;
-
-       for (i = 0; i < UART_NR; i++)
-               uart_remove_one_port(&m32r_sio_reg, &m32r_sio_ports[i].port);
-
-       uart_unregister_driver(&m32r_sio_reg);
-}
-
-module_init(m32r_sio_init);
-module_exit(m32r_sio_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic M32R SIO serial driver");
+device_initcall(m32r_sio_init);
index 3f6e0ab725fe29e1bfe9355c824528507d38b2aa..9360801df3c4f674311100efe2b19fca15f79b75 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver
  *
- *  Copyright (C) 2012-2014 Alexander Shiyan <shc_work@mail.ru>
+ *  Copyright (C) 2012-2016 Alexander Shiyan <shc_work@mail.ru>
  *
  *  Based on max3100.c, by Christian Pellegrin <chripell@evolware.org>
  *  Based on max3110.c, by Feng Tang <feng.tang@intel.com>
@@ -32,6 +32,7 @@
 #define MAX310X_NAME                   "max310x"
 #define MAX310X_MAJOR                  204
 #define MAX310X_MINOR                  209
+#define MAX310X_UART_NRMAX             16
 
 /* MAX310X register definitions */
 #define MAX310X_RHR_REG                        (0x00) /* RX FIFO */
 #define MAX310X_LCR_FORCEPARITY_BIT    (1 << 5) /* 9-bit multidrop parity */
 #define MAX310X_LCR_TXBREAK_BIT                (1 << 6) /* TX break enable */
 #define MAX310X_LCR_RTS_BIT            (1 << 7) /* RTS pin control */
-#define MAX310X_LCR_WORD_LEN_5         (0x00)
-#define MAX310X_LCR_WORD_LEN_6         (0x01)
-#define MAX310X_LCR_WORD_LEN_7         (0x02)
-#define MAX310X_LCR_WORD_LEN_8         (0x03)
 
 /* IRDA register bits */
 #define MAX310X_IRDA_IRDAEN_BIT                (1 << 0) /* IRDA mode enable */
@@ -262,10 +259,10 @@ struct max310x_one {
        struct uart_port        port;
        struct work_struct      tx_work;
        struct work_struct      md_work;
+       struct work_struct      rs_work;
 };
 
 struct max310x_port {
-       struct uart_driver      uart;
        struct max310x_devtype  *devtype;
        struct regmap           *regmap;
        struct mutex            mutex;
@@ -276,6 +273,17 @@ struct max310x_port {
        struct max310x_one      p[0];
 };
 
+static struct uart_driver max310x_uart = {
+       .owner          = THIS_MODULE,
+       .driver_name    = MAX310X_NAME,
+       .dev_name       = "ttyMAX",
+       .major          = MAX310X_MAJOR,
+       .minor          = MAX310X_MINOR,
+       .nr             = MAX310X_UART_NRMAX,
+};
+
+static DECLARE_BITMAP(max310x_lines, MAX310X_UART_NRMAX);
+
 static u8 max310x_port_read(struct uart_port *port, u8 reg)
 {
        struct max310x_port *s = dev_get_drvdata(port->dev);
@@ -594,9 +602,7 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
        unsigned int sts, ch, flag;
 
        if (unlikely(rxlen >= port->fifosize)) {
-               dev_warn_ratelimited(port->dev,
-                                    "Port %i: Possible RX FIFO overrun\n",
-                                    port->line);
+               dev_warn_ratelimited(port->dev, "Possible RX FIFO overrun\n");
                port->icount.buf_overrun++;
                /* Ensure sanity of RX level */
                rxlen = port->fifosize;
@@ -715,13 +721,13 @@ static irqreturn_t max310x_ist(int irq, void *dev_id)
 {
        struct max310x_port *s = (struct max310x_port *)dev_id;
 
-       if (s->uart.nr > 1) {
+       if (s->devtype->nr > 1) {
                do {
                        unsigned int val = ~0;
 
                        WARN_ON_ONCE(regmap_read(s->regmap,
                                                 MAX310X_GLOBALIRQ_REG, &val));
-                       val = ((1 << s->uart.nr) - 1) & ~val;
+                       val = ((1 << s->devtype->nr) - 1) & ~val;
                        if (!val)
                                break;
                        max310x_port_irq(s, fls(val) - 1);
@@ -796,7 +802,7 @@ static void max310x_set_termios(struct uart_port *port,
                                struct ktermios *termios,
                                struct ktermios *old)
 {
-       unsigned int lcr, flow = 0;
+       unsigned int lcr = 0, flow = 0;
        int baud;
 
        /* Mask termios capabilities we don't support */
@@ -805,17 +811,16 @@ static void max310x_set_termios(struct uart_port *port,
        /* Word size */
        switch (termios->c_cflag & CSIZE) {
        case CS5:
-               lcr = MAX310X_LCR_WORD_LEN_5;
                break;
        case CS6:
-               lcr = MAX310X_LCR_WORD_LEN_6;
+               lcr = MAX310X_LCR_LENGTH0_BIT;
                break;
        case CS7:
-               lcr = MAX310X_LCR_WORD_LEN_7;
+               lcr = MAX310X_LCR_LENGTH1_BIT;
                break;
        case CS8:
        default:
-               lcr = MAX310X_LCR_WORD_LEN_8;
+               lcr = MAX310X_LCR_LENGTH1_BIT | MAX310X_LCR_LENGTH0_BIT;
                break;
        }
 
@@ -877,36 +882,45 @@ static void max310x_set_termios(struct uart_port *port,
        uart_update_timeout(port, termios->c_cflag, baud);
 }
 
-static int max310x_rs485_config(struct uart_port *port,
-                               struct serial_rs485 *rs485)
+static void max310x_rs_proc(struct work_struct *ws)
 {
+       struct max310x_one *one = container_of(ws, struct max310x_one, rs_work);
        unsigned int val;
 
-       if (rs485->delay_rts_before_send > 0x0f ||
-                   rs485->delay_rts_after_send > 0x0f)
-               return -ERANGE;
+       val = (one->port.rs485.delay_rts_before_send << 4) |
+               one->port.rs485.delay_rts_after_send;
+       max310x_port_write(&one->port, MAX310X_HDPIXDELAY_REG, val);
 
-       val = (rs485->delay_rts_before_send << 4) |
-               rs485->delay_rts_after_send;
-       max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val);
-       if (rs485->flags & SER_RS485_ENABLED) {
-               max310x_port_update(port, MAX310X_MODE1_REG,
+       if (one->port.rs485.flags & SER_RS485_ENABLED) {
+               max310x_port_update(&one->port, MAX310X_MODE1_REG,
                                MAX310X_MODE1_TRNSCVCTRL_BIT,
                                MAX310X_MODE1_TRNSCVCTRL_BIT);
-               max310x_port_update(port, MAX310X_MODE2_REG,
+               max310x_port_update(&one->port, MAX310X_MODE2_REG,
                                MAX310X_MODE2_ECHOSUPR_BIT,
                                MAX310X_MODE2_ECHOSUPR_BIT);
        } else {
-               max310x_port_update(port, MAX310X_MODE1_REG,
+               max310x_port_update(&one->port, MAX310X_MODE1_REG,
                                MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
-               max310x_port_update(port, MAX310X_MODE2_REG,
+               max310x_port_update(&one->port, MAX310X_MODE2_REG,
                                MAX310X_MODE2_ECHOSUPR_BIT, 0);
        }
+}
+
+static int max310x_rs485_config(struct uart_port *port,
+                               struct serial_rs485 *rs485)
+{
+       struct max310x_one *one = container_of(port, struct max310x_one, port);
+
+       if ((rs485->delay_rts_before_send > 0x0f) ||
+           (rs485->delay_rts_after_send > 0x0f))
+               return -ERANGE;
 
        rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_ENABLED;
        memset(rs485->padding, 0, sizeof(rs485->padding));
        port->rs485 = *rs485;
 
+       schedule_work(&one->rs_work);
+
        return 0;
 }
 
@@ -1009,8 +1023,8 @@ static int __maybe_unused max310x_suspend(struct device *dev)
        struct max310x_port *s = dev_get_drvdata(dev);
        int i;
 
-       for (i = 0; i < s->uart.nr; i++) {
-               uart_suspend_port(&s->uart, &s->p[i].port);
+       for (i = 0; i < s->devtype->nr; i++) {
+               uart_suspend_port(&max310x_uart, &s->p[i].port);
                s->devtype->power(&s->p[i].port, 0);
        }
 
@@ -1022,9 +1036,9 @@ static int __maybe_unused max310x_resume(struct device *dev)
        struct max310x_port *s = dev_get_drvdata(dev);
        int i;
 
-       for (i = 0; i < s->uart.nr; i++) {
+       for (i = 0; i < s->devtype->nr; i++) {
                s->devtype->power(&s->p[i].port, 1);
-               uart_resume_port(&s->uart, &s->p[i].port);
+               uart_resume_port(&max310x_uart, &s->p[i].port);
        }
 
        return 0;
@@ -1159,18 +1173,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
        uartclk = max310x_set_ref_clk(s, freq, xtal);
        dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
 
-       /* Register UART driver */
-       s->uart.owner           = THIS_MODULE;
-       s->uart.dev_name        = "ttyMAX";
-       s->uart.major           = MAX310X_MAJOR;
-       s->uart.minor           = MAX310X_MINOR;
-       s->uart.nr              = devtype->nr;
-       ret = uart_register_driver(&s->uart);
-       if (ret) {
-               dev_err(dev, "Registering UART driver failed\n");
-               goto out_clk;
-       }
-
 #ifdef CONFIG_GPIOLIB
        /* Setup GPIO cotroller */
        s->gpio.owner           = THIS_MODULE;
@@ -1183,16 +1185,24 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
        s->gpio.base            = -1;
        s->gpio.ngpio           = devtype->nr * 4;
        s->gpio.can_sleep       = 1;
-       ret = gpiochip_add_data(&s->gpio, s);
+       ret = devm_gpiochip_add_data(dev, &s->gpio, s);
        if (ret)
-               goto out_uart;
+               goto out_clk;
 #endif
 
        mutex_init(&s->mutex);
 
        for (i = 0; i < devtype->nr; i++) {
+               unsigned int line;
+
+               line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX);
+               if (line == MAX310X_UART_NRMAX) {
+                       ret = -ERANGE;
+                       goto out_uart;
+               }
+
                /* Initialize port data */
-               s->p[i].port.line       = i;
+               s->p[i].port.line       = line;
                s->p[i].port.dev        = dev;
                s->p[i].port.irq        = irq;
                s->p[i].port.type       = PORT_MAX310X;
@@ -1214,10 +1224,19 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
                                    MAX310X_MODE1_IRQSEL_BIT);
                /* Initialize queue for start TX */
                INIT_WORK(&s->p[i].tx_work, max310x_wq_proc);
-               /* Initialize queue for changing mode */
+               /* Initialize queue for changing LOOPBACK mode */
                INIT_WORK(&s->p[i].md_work, max310x_md_proc);
+               /* Initialize queue for changing RS485 mode */
+               INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
+
                /* Register port */
-               uart_add_one_port(&s->uart, &s->p[i].port);
+               ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
+               if (ret) {
+                       s->p[i].port.dev = NULL;
+                       goto out_uart;
+               }
+               set_bit(line, max310x_lines);
+
                /* Go to suspend mode */
                devtype->power(&s->p[i].port, 0);
        }
@@ -1230,14 +1249,15 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
 
        dev_err(dev, "Unable to reguest IRQ %i\n", irq);
 
-       mutex_destroy(&s->mutex);
-
-#ifdef CONFIG_GPIOLIB
-       gpiochip_remove(&s->gpio);
-
 out_uart:
-#endif
-       uart_unregister_driver(&s->uart);
+       for (i = 0; i < devtype->nr; i++) {
+               if (s->p[i].port.dev) {
+                       uart_remove_one_port(&max310x_uart, &s->p[i].port);
+                       clear_bit(s->p[i].port.line, max310x_lines);
+               }
+       }
+
+       mutex_destroy(&s->mutex);
 
 out_clk:
        clk_disable_unprepare(s->clk);
@@ -1250,19 +1270,16 @@ static int max310x_remove(struct device *dev)
        struct max310x_port *s = dev_get_drvdata(dev);
        int i;
 
-#ifdef CONFIG_GPIOLIB
-       gpiochip_remove(&s->gpio);
-#endif
-
-       for (i = 0; i < s->uart.nr; i++) {
+       for (i = 0; i < s->devtype->nr; i++) {
                cancel_work_sync(&s->p[i].tx_work);
                cancel_work_sync(&s->p[i].md_work);
-               uart_remove_one_port(&s->uart, &s->p[i].port);
+               cancel_work_sync(&s->p[i].rs_work);
+               uart_remove_one_port(&max310x_uart, &s->p[i].port);
+               clear_bit(s->p[i].port.line, max310x_lines);
                s->devtype->power(&s->p[i].port, 0);
        }
 
        mutex_destroy(&s->mutex);
-       uart_unregister_driver(&s->uart);
        clk_disable_unprepare(s->clk);
 
        return 0;
@@ -1335,7 +1352,7 @@ static const struct spi_device_id max310x_id_table[] = {
 };
 MODULE_DEVICE_TABLE(spi, max310x_id_table);
 
-static struct spi_driver max310x_uart_driver = {
+static struct spi_driver max310x_spi_driver = {
        .driver = {
                .name           = MAX310X_NAME,
                .of_match_table = of_match_ptr(max310x_dt_ids),
@@ -1345,9 +1362,36 @@ static struct spi_driver max310x_uart_driver = {
        .remove         = max310x_spi_remove,
        .id_table       = max310x_id_table,
 };
-module_spi_driver(max310x_uart_driver);
 #endif
 
+static int __init max310x_uart_init(void)
+{
+       int ret;
+
+       bitmap_zero(max310x_lines, MAX310X_UART_NRMAX);
+
+       ret = uart_register_driver(&max310x_uart);
+       if (ret)
+               return ret;
+
+#ifdef CONFIG_SPI_MASTER
+       spi_register_driver(&max310x_spi_driver);
+#endif
+
+       return 0;
+}
+module_init(max310x_uart_init);
+
+static void __exit max310x_uart_exit(void)
+{
+#ifdef CONFIG_SPI_MASTER
+       spi_unregister_driver(&max310x_spi_driver);
+#endif
+
+       uart_unregister_driver(&max310x_uart);
+}
+module_exit(max310x_uart_exit);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
 MODULE_DESCRIPTION("MAX310X serial driver");
index da9e27d3c2639dbe26d1cbd5566053d4bcd72d55..492ec4b375a0739d94026a1c2c53bca4db36b7c9 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * MPS2 UART driver
+ *
  * Copyright (C) 2015 ARM Limited
  *
  * Author: Vladimir Murzin <vladimir.murzin@arm.com>
@@ -17,7 +19,6 @@
 #include <linux/console.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -569,30 +570,20 @@ static int mps2_serial_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int mps2_serial_remove(struct platform_device *pdev)
-{
-       struct mps2_uart_port *mps_port = platform_get_drvdata(pdev);
-
-       uart_remove_one_port(&mps2_uart_driver, &mps_port->port);
-
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id mps2_match[] = {
        { .compatible = "arm,mps2-uart", },
        {},
 };
-MODULE_DEVICE_TABLE(of, mps2_match);
 #endif
 
 static struct platform_driver mps2_serial_driver = {
        .probe = mps2_serial_probe,
-       .remove = mps2_serial_remove,
 
        .driver = {
                .name = DRIVER_NAME,
                .of_match_table = of_match_ptr(mps2_match),
+               .suppress_bind_attrs = true,
        },
 };
 
@@ -610,16 +601,4 @@ static int __init mps2_uart_init(void)
 
        return ret;
 }
-module_init(mps2_uart_init);
-
-static void __exit mps2_uart_exit(void)
-{
-       platform_driver_unregister(&mps2_serial_driver);
-       uart_unregister_driver(&mps2_uart_driver);
-}
-module_exit(mps2_uart_exit);
-
-MODULE_AUTHOR("Vladimir Murzin <vladimir.murzin@arm.com>");
-MODULE_DESCRIPTION("MPS2 UART driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:" DRIVER_NAME);
+arch_initcall(mps2_uart_init);
index b7d80bd57db9cd4eb8397f75f8a83ae40c0dd65c..7312e7e01b7e5901ab676ce99058e50407bc773c 100644 (file)
 # define SUPPORT_SYSRQ
 #endif
 
+#include <linux/kernel.h>
 #include <linux/atomic.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/hrtimer.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
-#include <linux/serial.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-
-#include "msm_serial.h"
-
-#define UARTDM_BURST_SIZE      16   /* in bytes */
-#define UARTDM_TX_AIGN(x)      ((x) & ~0x3) /* valid for > 1p3 */
-#define UARTDM_TX_MAX          256   /* in bytes, valid for <= 1p3 */
-#define UARTDM_RX_SIZE         (UART_XMIT_SIZE / 4)
+#include <linux/wait.h>
+
+#define UART_MR1                       0x0000
+
+#define UART_MR1_AUTO_RFR_LEVEL0       0x3F
+#define UART_MR1_AUTO_RFR_LEVEL1       0x3FF00
+#define UART_DM_MR1_AUTO_RFR_LEVEL1    0xFFFFFF00
+#define UART_MR1_RX_RDY_CTL            BIT(7)
+#define UART_MR1_CTS_CTL               BIT(6)
+
+#define UART_MR2                       0x0004
+#define UART_MR2_ERROR_MODE            BIT(6)
+#define UART_MR2_BITS_PER_CHAR         0x30
+#define UART_MR2_BITS_PER_CHAR_5       (0x0 << 4)
+#define UART_MR2_BITS_PER_CHAR_6       (0x1 << 4)
+#define UART_MR2_BITS_PER_CHAR_7       (0x2 << 4)
+#define UART_MR2_BITS_PER_CHAR_8       (0x3 << 4)
+#define UART_MR2_STOP_BIT_LEN_ONE      (0x1 << 2)
+#define UART_MR2_STOP_BIT_LEN_TWO      (0x3 << 2)
+#define UART_MR2_PARITY_MODE_NONE      0x0
+#define UART_MR2_PARITY_MODE_ODD       0x1
+#define UART_MR2_PARITY_MODE_EVEN      0x2
+#define UART_MR2_PARITY_MODE_SPACE     0x3
+#define UART_MR2_PARITY_MODE           0x3
+
+#define UART_CSR                       0x0008
+
+#define UART_TF                                0x000C
+#define UARTDM_TF                      0x0070
+
+#define UART_CR                                0x0010
+#define UART_CR_CMD_NULL               (0 << 4)
+#define UART_CR_CMD_RESET_RX           (1 << 4)
+#define UART_CR_CMD_RESET_TX           (2 << 4)
+#define UART_CR_CMD_RESET_ERR          (3 << 4)
+#define UART_CR_CMD_RESET_BREAK_INT    (4 << 4)
+#define UART_CR_CMD_START_BREAK                (5 << 4)
+#define UART_CR_CMD_STOP_BREAK         (6 << 4)
+#define UART_CR_CMD_RESET_CTS          (7 << 4)
+#define UART_CR_CMD_RESET_STALE_INT    (8 << 4)
+#define UART_CR_CMD_PACKET_MODE                (9 << 4)
+#define UART_CR_CMD_MODE_RESET         (12 << 4)
+#define UART_CR_CMD_SET_RFR            (13 << 4)
+#define UART_CR_CMD_RESET_RFR          (14 << 4)
+#define UART_CR_CMD_PROTECTION_EN      (16 << 4)
+#define UART_CR_CMD_STALE_EVENT_DISABLE        (6 << 8)
+#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
+#define UART_CR_CMD_FORCE_STALE                (4 << 8)
+#define UART_CR_CMD_RESET_TX_READY     (3 << 8)
+#define UART_CR_TX_DISABLE             BIT(3)
+#define UART_CR_TX_ENABLE              BIT(2)
+#define UART_CR_RX_DISABLE             BIT(1)
+#define UART_CR_RX_ENABLE              BIT(0)
+#define UART_CR_CMD_RESET_RXBREAK_START        ((1 << 11) | (2 << 4))
+
+#define UART_IMR                       0x0014
+#define UART_IMR_TXLEV                 BIT(0)
+#define UART_IMR_RXSTALE               BIT(3)
+#define UART_IMR_RXLEV                 BIT(4)
+#define UART_IMR_DELTA_CTS             BIT(5)
+#define UART_IMR_CURRENT_CTS           BIT(6)
+#define UART_IMR_RXBREAK_START         BIT(10)
+
+#define UART_IPR_RXSTALE_LAST          0x20
+#define UART_IPR_STALE_LSB             0x1F
+#define UART_IPR_STALE_TIMEOUT_MSB     0x3FF80
+#define UART_DM_IPR_STALE_TIMEOUT_MSB  0xFFFFFF80
+
+#define UART_IPR                       0x0018
+#define UART_TFWR                      0x001C
+#define UART_RFWR                      0x0020
+#define UART_HCR                       0x0024
+
+#define UART_MREG                      0x0028
+#define UART_NREG                      0x002C
+#define UART_DREG                      0x0030
+#define UART_MNDREG                    0x0034
+#define UART_IRDA                      0x0038
+#define UART_MISR_MODE                 0x0040
+#define UART_MISR_RESET                        0x0044
+#define UART_MISR_EXPORT               0x0048
+#define UART_MISR_VAL                  0x004C
+#define UART_TEST_CTRL                 0x0050
+
+#define UART_SR                                0x0008
+#define UART_SR_HUNT_CHAR              BIT(7)
+#define UART_SR_RX_BREAK               BIT(6)
+#define UART_SR_PAR_FRAME_ERR          BIT(5)
+#define UART_SR_OVERRUN                        BIT(4)
+#define UART_SR_TX_EMPTY               BIT(3)
+#define UART_SR_TX_READY               BIT(2)
+#define UART_SR_RX_FULL                        BIT(1)
+#define UART_SR_RX_READY               BIT(0)
+
+#define UART_RF                                0x000C
+#define UARTDM_RF                      0x0070
+#define UART_MISR                      0x0010
+#define UART_ISR                       0x0014
+#define UART_ISR_TX_READY              BIT(7)
+
+#define UARTDM_RXFS                    0x50
+#define UARTDM_RXFS_BUF_SHIFT          0x7
+#define UARTDM_RXFS_BUF_MASK           0x7
+
+#define UARTDM_DMEN                    0x3C
+#define UARTDM_DMEN_RX_SC_ENABLE       BIT(5)
+#define UARTDM_DMEN_TX_SC_ENABLE       BIT(4)
+
+#define UARTDM_DMEN_TX_BAM_ENABLE      BIT(2)  /* UARTDM_1P4 */
+#define UARTDM_DMEN_TX_DM_ENABLE       BIT(0)  /* < UARTDM_1P4 */
+
+#define UARTDM_DMEN_RX_BAM_ENABLE      BIT(3)  /* UARTDM_1P4 */
+#define UARTDM_DMEN_RX_DM_ENABLE       BIT(1)  /* < UARTDM_1P4 */
+
+#define UARTDM_DMRX                    0x34
+#define UARTDM_NCF_TX                  0x40
+#define UARTDM_RX_TOTAL_SNAP           0x38
+
+#define UARTDM_BURST_SIZE              16   /* in bytes */
+#define UARTDM_TX_AIGN(x)              ((x) & ~0x3) /* valid for > 1p3 */
+#define UARTDM_TX_MAX                  256   /* in bytes, valid for <= 1p3 */
+#define UARTDM_RX_SIZE                 (UART_XMIT_SIZE / 4)
 
 enum {
        UARTDM_1P1 = 1,
@@ -78,10 +192,65 @@ struct msm_port {
        struct msm_dma          rx_dma;
 };
 
+#define UART_TO_MSM(uart_port) container_of(uart_port, struct msm_port, uart)
+
+static
+void msm_write(struct uart_port *port, unsigned int val, unsigned int off)
+{
+       writel_relaxed(val, port->membase + off);
+}
+
+static
+unsigned int msm_read(struct uart_port *port, unsigned int off)
+{
+       return readl_relaxed(port->membase + off);
+}
+
+/*
+ * Setup the MND registers to use the TCXO clock.
+ */
+static void msm_serial_set_mnd_regs_tcxo(struct uart_port *port)
+{
+       msm_write(port, 0x06, UART_MREG);
+       msm_write(port, 0xF1, UART_NREG);
+       msm_write(port, 0x0F, UART_DREG);
+       msm_write(port, 0x1A, UART_MNDREG);
+       port->uartclk = 1843200;
+}
+
+/*
+ * Setup the MND registers to use the TCXO clock divided by 4.
+ */
+static void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port)
+{
+       msm_write(port, 0x18, UART_MREG);
+       msm_write(port, 0xF6, UART_NREG);
+       msm_write(port, 0x0F, UART_DREG);
+       msm_write(port, 0x0A, UART_MNDREG);
+       port->uartclk = 1843200;
+}
+
+static void msm_serial_set_mnd_regs(struct uart_port *port)
+{
+       struct msm_port *msm_port = UART_TO_MSM(port);
+
+       /*
+        * These registers don't exist so we change the clk input rate
+        * on uartdm hardware instead
+        */
+       if (msm_port->is_uartdm)
+               return;
+
+       if (port->uartclk == 19200000)
+               msm_serial_set_mnd_regs_tcxo(port);
+       else if (port->uartclk == 4800000)
+               msm_serial_set_mnd_regs_tcxoby4(port);
+}
+
 static void msm_handle_tx(struct uart_port *port);
 static void msm_start_rx_dma(struct msm_port *msm_port);
 
-void msm_stop_dma(struct uart_port *port, struct msm_dma *dma)
+static void msm_stop_dma(struct uart_port *port, struct msm_dma *dma)
 {
        struct device *dev = port->dev;
        unsigned int mapped;
@@ -388,10 +557,6 @@ static void msm_complete_rx_dma(void *args)
        val &= ~dma->enable_bit;
        msm_write(port, val, UARTDM_DMEN);
 
-       /* Restore interrupts */
-       msm_port->imr |= UART_IMR_RXLEV | UART_IMR_RXSTALE;
-       msm_write(port, msm_port->imr, UART_IMR);
-
        if (msm_read(port, UART_SR) & UART_SR_OVERRUN) {
                port->icount.overrun++;
                tty_insert_flip_char(tport, 0, TTY_OVERRUN);
@@ -726,7 +891,7 @@ static void msm_handle_tx(struct uart_port *port)
                return;
        }
 
-       pio_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       pio_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
        dma_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 
        dma_min = 1;    /* Always DMA */
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
deleted file mode 100644 (file)
index 1786458..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2007 Google, Inc.
- * Author: Robert Love <rlove@google.com>
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __DRIVERS_SERIAL_MSM_SERIAL_H
-#define __DRIVERS_SERIAL_MSM_SERIAL_H
-
-#define UART_MR1                       0x0000
-
-#define UART_MR1_AUTO_RFR_LEVEL0       0x3F
-#define UART_MR1_AUTO_RFR_LEVEL1       0x3FF00
-#define UART_DM_MR1_AUTO_RFR_LEVEL1    0xFFFFFF00
-#define UART_MR1_RX_RDY_CTL            BIT(7)
-#define UART_MR1_CTS_CTL               BIT(6)
-
-#define UART_MR2                       0x0004
-#define UART_MR2_ERROR_MODE            BIT(6)
-#define UART_MR2_BITS_PER_CHAR         0x30
-#define UART_MR2_BITS_PER_CHAR_5       (0x0 << 4)
-#define UART_MR2_BITS_PER_CHAR_6       (0x1 << 4)
-#define UART_MR2_BITS_PER_CHAR_7       (0x2 << 4)
-#define UART_MR2_BITS_PER_CHAR_8       (0x3 << 4)
-#define UART_MR2_STOP_BIT_LEN_ONE      (0x1 << 2)
-#define UART_MR2_STOP_BIT_LEN_TWO      (0x3 << 2)
-#define UART_MR2_PARITY_MODE_NONE      0x0
-#define UART_MR2_PARITY_MODE_ODD       0x1
-#define UART_MR2_PARITY_MODE_EVEN      0x2
-#define UART_MR2_PARITY_MODE_SPACE     0x3
-#define UART_MR2_PARITY_MODE           0x3
-
-#define UART_CSR                       0x0008
-
-#define UART_TF                0x000C
-#define UARTDM_TF      0x0070
-
-#define UART_CR                                0x0010
-#define UART_CR_CMD_NULL               (0 << 4)
-#define UART_CR_CMD_RESET_RX           (1 << 4)
-#define UART_CR_CMD_RESET_TX           (2 << 4)
-#define UART_CR_CMD_RESET_ERR          (3 << 4)
-#define UART_CR_CMD_RESET_BREAK_INT    (4 << 4)
-#define UART_CR_CMD_START_BREAK                (5 << 4)
-#define UART_CR_CMD_STOP_BREAK         (6 << 4)
-#define UART_CR_CMD_RESET_CTS          (7 << 4)
-#define UART_CR_CMD_RESET_STALE_INT    (8 << 4)
-#define UART_CR_CMD_PACKET_MODE                (9 << 4)
-#define UART_CR_CMD_MODE_RESET         (12 << 4)
-#define UART_CR_CMD_SET_RFR            (13 << 4)
-#define UART_CR_CMD_RESET_RFR          (14 << 4)
-#define UART_CR_CMD_PROTECTION_EN      (16 << 4)
-#define UART_CR_CMD_STALE_EVENT_DISABLE        (6 << 8)
-#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
-#define UART_CR_CMD_FORCE_STALE                (4 << 8)
-#define UART_CR_CMD_RESET_TX_READY     (3 << 8)
-#define UART_CR_TX_DISABLE             BIT(3)
-#define UART_CR_TX_ENABLE              BIT(2)
-#define UART_CR_RX_DISABLE             BIT(1)
-#define UART_CR_RX_ENABLE              BIT(0)
-#define UART_CR_CMD_RESET_RXBREAK_START        ((1 << 11) | (2 << 4))
-
-#define UART_IMR               0x0014
-#define UART_IMR_TXLEV                 BIT(0)
-#define UART_IMR_RXSTALE               BIT(3)
-#define UART_IMR_RXLEV                 BIT(4)
-#define UART_IMR_DELTA_CTS             BIT(5)
-#define UART_IMR_CURRENT_CTS           BIT(6)
-#define UART_IMR_RXBREAK_START         BIT(10)
-
-#define UART_IPR_RXSTALE_LAST          0x20
-#define UART_IPR_STALE_LSB             0x1F
-#define UART_IPR_STALE_TIMEOUT_MSB     0x3FF80
-#define UART_DM_IPR_STALE_TIMEOUT_MSB  0xFFFFFF80
-
-#define UART_IPR       0x0018
-#define UART_TFWR      0x001C
-#define UART_RFWR      0x0020
-#define UART_HCR       0x0024
-
-#define UART_MREG              0x0028
-#define UART_NREG              0x002C
-#define UART_DREG              0x0030
-#define UART_MNDREG            0x0034
-#define UART_IRDA              0x0038
-#define UART_MISR_MODE         0x0040
-#define UART_MISR_RESET                0x0044
-#define UART_MISR_EXPORT       0x0048
-#define UART_MISR_VAL          0x004C
-#define UART_TEST_CTRL         0x0050
-
-#define UART_SR                        0x0008
-#define UART_SR_HUNT_CHAR      BIT(7)
-#define UART_SR_RX_BREAK       BIT(6)
-#define UART_SR_PAR_FRAME_ERR  BIT(5)
-#define UART_SR_OVERRUN                BIT(4)
-#define UART_SR_TX_EMPTY       BIT(3)
-#define UART_SR_TX_READY       BIT(2)
-#define UART_SR_RX_FULL                BIT(1)
-#define UART_SR_RX_READY       BIT(0)
-
-#define UART_RF                        0x000C
-#define UARTDM_RF              0x0070
-#define UART_MISR              0x0010
-#define UART_ISR               0x0014
-#define UART_ISR_TX_READY      BIT(7)
-
-#define UARTDM_RXFS            0x50
-#define UARTDM_RXFS_BUF_SHIFT  0x7
-#define UARTDM_RXFS_BUF_MASK   0x7
-
-#define UARTDM_DMEN            0x3C
-#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
-#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
-
-#define UARTDM_DMEN_TX_BAM_ENABLE BIT(2)       /* UARTDM_1P4 */
-#define UARTDM_DMEN_TX_DM_ENABLE  BIT(0)       /* < UARTDM_1P4 */
-
-#define UARTDM_DMEN_RX_BAM_ENABLE BIT(3)       /* UARTDM_1P4 */
-#define UARTDM_DMEN_RX_DM_ENABLE  BIT(1)       /* < UARTDM_1P4 */
-
-#define UARTDM_DMRX            0x34
-#define UARTDM_NCF_TX          0x40
-#define UARTDM_RX_TOTAL_SNAP   0x38
-
-#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port)
-
-static inline
-void msm_write(struct uart_port *port, unsigned int val, unsigned int off)
-{
-       writel_relaxed(val, port->membase + off);
-}
-
-static inline
-unsigned int msm_read(struct uart_port *port, unsigned int off)
-{
-       return readl_relaxed(port->membase + off);
-}
-
-/*
- * Setup the MND registers to use the TCXO clock.
- */
-static inline void msm_serial_set_mnd_regs_tcxo(struct uart_port *port)
-{
-       msm_write(port, 0x06, UART_MREG);
-       msm_write(port, 0xF1, UART_NREG);
-       msm_write(port, 0x0F, UART_DREG);
-       msm_write(port, 0x1A, UART_MNDREG);
-       port->uartclk = 1843200;
-}
-
-/*
- * Setup the MND registers to use the TCXO clock divided by 4.
- */
-static inline void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port)
-{
-       msm_write(port, 0x18, UART_MREG);
-       msm_write(port, 0xF6, UART_NREG);
-       msm_write(port, 0x0F, UART_DREG);
-       msm_write(port, 0x0A, UART_MNDREG);
-       port->uartclk = 1843200;
-}
-
-static inline
-void msm_serial_set_mnd_regs_from_uartclk(struct uart_port *port)
-{
-       if (port->uartclk == 19200000)
-               msm_serial_set_mnd_regs_tcxo(port);
-       else if (port->uartclk == 4800000)
-               msm_serial_set_mnd_regs_tcxoby4(port);
-}
-
-#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_from_uartclk
-
-#endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */
index ce362bd51de78d65177c889541e80d33aae1779d..45b57c294d13b19b8d47f2e8b2292f68c8167485 100644 (file)
@@ -300,6 +300,8 @@ static int mvebu_uart_startup(struct uart_port *port)
 static void mvebu_uart_shutdown(struct uart_port *port)
 {
        writel(0, port->membase + UART_CTRL);
+
+       free_irq(port->irq, port);
 }
 
 static void mvebu_uart_set_termios(struct uart_port *port,
index 62a43bf5698e5e3c335933ade8659eaa05d1a709..7f8e99bbcb739832824682ebe7321c7c653a22da 100644 (file)
@@ -445,7 +445,6 @@ static int pic32_uart_startup(struct uart_port *port)
                                       sport->idx);
        if (!sport->irq_rx_name) {
                dev_err(port->dev, "%s: kasprintf err!", __func__);
-               kfree(sport->irq_fault_name);
                ret = -ENOMEM;
                goto out_f;
        }
index e156e39d620cebd2ee48304ed80223fd7c96a2c2..b24b0556f5a853c7ac742620a4bfafcb918f9af9 100644 (file)
@@ -1720,7 +1720,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap)
 
        r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(uap->pdev, 0);
-       if (!r_ports || !irq)
+       if (!r_ports || irq <= 0)
                return -ENODEV;
 
        uap->port.mapbase  = r_ports->start;
index 41eab75ba2af89955f90d3802992e0dfb50383c3..cd9d9e87847555ee486e4e0d8ff85ceab5349a7e 100644 (file)
@@ -27,7 +27,6 @@
 #define SUPPORT_SYSRQ
 #endif
 
-#include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/console.h>
@@ -829,7 +828,6 @@ static const struct of_device_id serial_pxa_dt_ids[] = {
        { .compatible = "mrvl,mmp-uart", },
        {}
 };
-MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
 
 static int serial_pxa_probe_dt(struct platform_device *pdev,
                               struct uart_pxa_port *sport)
@@ -914,28 +912,15 @@ static int serial_pxa_probe(struct platform_device *dev)
        return ret;
 }
 
-static int serial_pxa_remove(struct platform_device *dev)
-{
-       struct uart_pxa_port *sport = platform_get_drvdata(dev);
-
-       uart_remove_one_port(&serial_pxa_reg, &sport->port);
-
-       clk_unprepare(sport->clk);
-       clk_put(sport->clk);
-       kfree(sport);
-
-       return 0;
-}
-
 static struct platform_driver serial_pxa_driver = {
         .probe          = serial_pxa_probe,
-        .remove         = serial_pxa_remove,
 
        .driver         = {
                .name   = "pxa2xx-uart",
 #ifdef CONFIG_PM
                .pm     = &serial_pxa_pm_ops,
 #endif
+               .suppress_bind_attrs = true,
                .of_match_table = serial_pxa_dt_ids,
        },
 };
@@ -954,15 +939,4 @@ static int __init serial_pxa_init(void)
 
        return ret;
 }
-
-static void __exit serial_pxa_exit(void)
-{
-       platform_driver_unregister(&serial_pxa_driver);
-       uart_unregister_driver(&serial_pxa_reg);
-}
-
-module_init(serial_pxa_init);
-module_exit(serial_pxa_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pxa2xx-uart");
+device_initcall(serial_pxa_init);
index 99bb23161dd6e5f3ac514f9a9218cd4590467169..ae2095a66708e0b06bf05bfe38d4a0901b158d3d 100644 (file)
@@ -169,8 +169,7 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
                return;
 
        if (s3c24xx_serial_has_interrupt_mask(port))
-               __set_bit(S3C64XX_UINTM_TXD,
-                       portaddrl(port, S3C64XX_UINTM));
+               s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
        else
                disable_irq_nosync(ourport->tx_irq);
 
@@ -235,8 +234,7 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
 
        /* Mask Tx interrupt */
        if (s3c24xx_serial_has_interrupt_mask(port))
-               __set_bit(S3C64XX_UINTM_TXD,
-                         portaddrl(port, S3C64XX_UINTM));
+               s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
        else
                disable_irq_nosync(ourport->tx_irq);
 
@@ -269,8 +267,8 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
 
        /* Unmask Tx interrupt */
        if (s3c24xx_serial_has_interrupt_mask(port))
-               __clear_bit(S3C64XX_UINTM_TXD,
-                           portaddrl(port, S3C64XX_UINTM));
+               s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
+                                 S3C64XX_UINTM);
        else
                enable_irq(ourport->tx_irq);
 
@@ -397,8 +395,8 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
        if (rx_enabled(port)) {
                dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
                if (s3c24xx_serial_has_interrupt_mask(port))
-                       __set_bit(S3C64XX_UINTM_RXD,
-                               portaddrl(port, S3C64XX_UINTM));
+                       s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
+                                       S3C64XX_UINTM);
                else
                        disable_irq_nosync(ourport->rx_irq);
                rx_enabled(port) = 0;
@@ -1069,7 +1067,7 @@ static int s3c64xx_serial_startup(struct uart_port *port)
        spin_unlock_irqrestore(&port->lock, flags);
 
        /* Enable Rx Interrupt */
-       __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM));
+       s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
 
        dbg("s3c64xx_serial_startup ok\n");
        return ret;
@@ -1684,7 +1682,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
                return -ENODEV;
 
        if (port->mapbase != 0)
-               return 0;
+               return -EINVAL;
 
        /* setup info for port */
        port->dev       = &platdev->dev;
@@ -1738,22 +1736,25 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
                ourport->dma = devm_kzalloc(port->dev,
                                            sizeof(*ourport->dma),
                                            GFP_KERNEL);
-               if (!ourport->dma)
-                       return -ENOMEM;
+               if (!ourport->dma) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
        }
 
        ourport->clk    = clk_get(&platdev->dev, "uart");
        if (IS_ERR(ourport->clk)) {
                pr_err("%s: Controller clock not found\n",
                                dev_name(&platdev->dev));
-               return PTR_ERR(ourport->clk);
+               ret = PTR_ERR(ourport->clk);
+               goto err;
        }
 
        ret = clk_prepare_enable(ourport->clk);
        if (ret) {
                pr_err("uart: clock failed to prepare+enable: %d\n", ret);
                clk_put(ourport->clk);
-               return ret;
+               goto err;
        }
 
        /* Keep all interrupts masked and cleared */
@@ -1769,7 +1770,12 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 
        /* reset the fifos (and setup the uart) */
        s3c24xx_serial_resetport(port, cfg);
+
        return 0;
+
+err:
+       port->mapbase = 0;
+       return ret;
 }
 
 /* Device driver serial port probe */
@@ -1836,8 +1842,6 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
        ourport->min_dma_size = max_t(int, ourport->port.fifosize,
                                    dma_get_cache_alignment());
 
-       probe_index++;
-
        dbg("%s: initialising port %p...\n", __func__, ourport);
 
        ret = s3c24xx_serial_init_port(ourport, pdev);
@@ -1867,6 +1871,8 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
        if (ret < 0)
                dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
 
+       probe_index++;
+
        return 0;
 }
 
index fc5deaa4f382def3e5d1bfe69497302a6c3a4abb..2ae4fcee181458ce008c499b266e1e7ecd3d614f 100644 (file)
@@ -117,10 +117,38 @@ struct s3c24xx_uart_port {
 #define portaddrl(port, reg) \
        ((unsigned long *)(unsigned long)((port)->membase + (reg)))
 
-#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
-#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
-
-#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
-#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
+#define rd_regb(port, reg) (readb_relaxed(portaddr(port, reg)))
+#define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg)))
+
+#define wr_regb(port, reg, val) writeb_relaxed(val, portaddr(port, reg))
+#define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg))
+
+/* Byte-order aware bit setting/clearing functions. */
+
+static inline void s3c24xx_set_bit(struct uart_port *port, int idx,
+                                  unsigned int reg)
+{
+       unsigned long flags;
+       u32 val;
+
+       local_irq_save(flags);
+       val = rd_regl(port, reg);
+       val |= (1 << idx);
+       wr_regl(port, reg, val);
+       local_irq_restore(flags);
+}
+
+static inline void s3c24xx_clear_bit(struct uart_port *port, int idx,
+                                    unsigned int reg)
+{
+       unsigned long flags;
+       u32 val;
+
+       local_irq_save(flags);
+       val = rd_regl(port, reg);
+       val &= ~(1 << idx);
+       wr_regl(port, reg, val);
+       local_irq_restore(flags);
+}
 
 #endif
index 1dba6719db8ddef3f3b88812d584822577c2cbb4..731ac35acb3125a2dcee3a6dbeaee93fb2963de2 100644 (file)
@@ -1317,7 +1317,12 @@ static int tegra_uart_probe(struct platform_device *pdev)
        }
 
        u->iotype = UPIO_MEM32;
-       u->irq = platform_get_irq(pdev, 0);
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Couldn't get IRQ\n");
+               return ret;
+       }
+       u->irq = ret;
        u->regshift = 2;
        ret = uart_add_one_port(&tegra_uart_driver, u);
        if (ret < 0) {
index a333c59cba2cf3fdc37d81dda232c1f7474660f5..9fc15335c8c59b70c93e8e6a1026b32da59359e5 100644 (file)
@@ -887,7 +887,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
                /*
                 * Free and release old regions
                 */
-               if (old_type != PORT_UNKNOWN)
+               if (old_type != PORT_UNKNOWN && uport->ops->release_port)
                        uport->ops->release_port(uport);
 
                uport->iobase = new_port;
@@ -900,7 +900,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
                /*
                 * Claim and map the new regions
                 */
-               if (uport->type != PORT_UNKNOWN) {
+               if (uport->type != PORT_UNKNOWN && uport->ops->request_port) {
                        retval = uport->ops->request_port(uport);
                } else {
                        /* Always success - Jean II */
@@ -1125,7 +1125,7 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
                 * If we already have a port type configured,
                 * we must release its resources.
                 */
-               if (uport->type != PORT_UNKNOWN)
+               if (uport->type != PORT_UNKNOWN && uport->ops->release_port)
                        uport->ops->release_port(uport);
 
                flags = UART_CONFIG_TYPE;
@@ -2897,7 +2897,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
        /*
         * Free the port IO and memory resources, if any.
         */
-       if (uport->type != PORT_UNKNOWN)
+       if (uport->type != PORT_UNKNOWN && uport->ops->release_port)
                uport->ops->release_port(uport);
        kfree(uport->tty_groups);
 
index e8dd5097dc5674d928a3f0f8c70658f737bb9aaa..d2da6aa7f27d0eb1ccb4c874711446e3952e5367 100644 (file)
@@ -52,6 +52,9 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
        int value_array[UART_GPIO_MAX];
        unsigned int count = 0;
 
+       if (gpios == NULL)
+               return;
+
        for (i = 0; i < UART_GPIO_MAX; i++)
                if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) {
                        desc_array[count] = gpios->gpio[i];
@@ -73,6 +76,9 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl)
 {
        enum mctrl_gpio_idx i;
 
+       if (gpios == NULL)
+               return *mctrl;
+
        for (i = 0; i < UART_GPIO_MAX; i++) {
                if (gpios->gpio[i] && !mctrl_gpios_desc[i].dir_out) {
                        if (gpiod_get_value(gpios->gpio[i]))
@@ -86,6 +92,27 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl)
 }
 EXPORT_SYMBOL_GPL(mctrl_gpio_get);
 
+unsigned int
+mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl)
+{
+       enum mctrl_gpio_idx i;
+
+       if (gpios == NULL)
+               return *mctrl;
+
+       for (i = 0; i < UART_GPIO_MAX; i++) {
+               if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) {
+                       if (gpiod_get_value(gpios->gpio[i]))
+                               *mctrl |= mctrl_gpios_desc[i].mctrl;
+                       else
+                               *mctrl &= ~mctrl_gpios_desc[i].mctrl;
+               }
+       }
+
+       return *mctrl;
+}
+EXPORT_SYMBOL_GPL(mctrl_gpio_get_outputs);
+
 struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
 {
        struct mctrl_gpios *gpios;
@@ -203,6 +230,9 @@ void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios)
 {
        enum mctrl_gpio_idx i;
 
+       if (gpios == NULL)
+               return;
+
        for (i = 0; i < UART_GPIO_MAX; i++) {
                if (gpios->irq[i])
                        devm_free_irq(gpios->port->dev, gpios->irq[i], gpios);
@@ -218,6 +248,9 @@ void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios)
 {
        enum mctrl_gpio_idx i;
 
+       if (gpios == NULL)
+               return;
+
        /* .enable_ms may be called multiple times */
        if (gpios->mctrl_on)
                return;
@@ -240,6 +273,9 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios)
 {
        enum mctrl_gpio_idx i;
 
+       if (gpios == NULL)
+               return;
+
        if (!gpios->mctrl_on)
                return;
 
index 332a33ab0647cbe3fe5d9b9b13dd1b8b78eb0b84..fa000bcff217004d29d05f5b943329fc07e0ca53 100644 (file)
@@ -48,11 +48,18 @@ struct mctrl_gpios;
 void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl);
 
 /*
- * Get state of the modem control output lines from GPIOs.
+ * Get state of the modem control input lines from GPIOs.
  * The mctrl flags are updated and returned.
  */
 unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl);
 
+/*
+ * Get state of the modem control output lines from GPIOs.
+ * The mctrl flags are updated and returned.
+ */
+unsigned int
+mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl);
+
 /*
  * Returns the associated struct gpio_desc to the modem line gidx
  */
@@ -107,6 +114,12 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl)
        return *mctrl;
 }
 
+static inline unsigned int
+mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl)
+{
+       return *mctrl;
+}
+
 static inline
 struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios,
                                      enum mctrl_gpio_idx gidx)
index 0130feb069aee02fbf5beeecacd9f674cde2e2ff..d86eee38aae6eba5953f0d7e4e5b2021bc6ee9f8 100644 (file)
@@ -57,6 +57,7 @@
 #include <asm/sh_bios.h>
 #endif
 
+#include "serial_mctrl_gpio.h"
 #include "sh-sci.h"
 
 /* Offsets into the sci_port->irqs array */
@@ -111,6 +112,7 @@ struct sci_port {
        unsigned int            error_clear;
        unsigned int            sampling_rate_mask;
        resource_size_t         reg_size;
+       struct mctrl_gpios      *gpios;
 
        /* Break timer */
        struct timer_list       break_timer;
@@ -139,6 +141,8 @@ struct sci_port {
        struct timer_list               rx_timer;
        unsigned int                    rx_timeout;
 #endif
+
+       bool autorts;
 };
 
 #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
@@ -701,7 +705,6 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 {
        struct sci_port *s = to_sci_port(port);
-       const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
 
        /*
         * Use port-specific handler if provided.
@@ -711,21 +714,28 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
                return;
        }
 
-       /*
-        * For the generic path SCSPTR is necessary. Bail out if that's
-        * unavailable, too.
-        */
-       if (!reg->size)
-               return;
-
-       if ((s->cfg->capabilities & SCIx_HAVE_RTSCTS) &&
-           ((!(cflag & CRTSCTS)))) {
-               unsigned short status;
+       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+               u16 ctrl = serial_port_in(port, SCPCR);
+
+               /* Enable RXD and TXD pin functions */
+               ctrl &= ~(SCPCR_RXDC | SCPCR_TXDC);
+               if (to_sci_port(port)->cfg->capabilities & SCIx_HAVE_RTSCTS) {
+                       /* RTS# is output, driven 1 */
+                       ctrl |= SCPCR_RTSC;
+                       serial_port_out(port, SCPDR,
+                               serial_port_in(port, SCPDR) | SCPDR_RTSD);
+                       /* Enable CTS# pin function */
+                       ctrl &= ~SCPCR_CTSC;
+               }
+               serial_port_out(port, SCPCR, ctrl);
+       } else if (sci_getreg(port, SCSPTR)->size) {
+               u16 status = serial_port_in(port, SCSPTR);
 
-               status = serial_port_in(port, SCSPTR);
-               status &= ~SCSPTR_CTSIO;
-               status |= SCSPTR_RTSIO;
-               serial_port_out(port, SCSPTR, status); /* Set RTS = 1 */
+               /* RTS# is output, driven 1 */
+               status |= SCSPTR_RTSIO | SCSPTR_RTSDT;
+               /* CTS# and SCK are inputs */
+               status &= ~(SCSPTR_CTSIO | SCSPTR_SCKIO);
+               serial_port_out(port, SCSPTR, status);
        }
 }
 
@@ -1803,6 +1813,46 @@ static unsigned int sci_tx_empty(struct uart_port *port)
        return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
 }
 
+static void sci_set_rts(struct uart_port *port, bool state)
+{
+       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+               u16 data = serial_port_in(port, SCPDR);
+
+               /* Active low */
+               if (state)
+                       data &= ~SCPDR_RTSD;
+               else
+                       data |= SCPDR_RTSD;
+               serial_port_out(port, SCPDR, data);
+
+               /* RTS# is output */
+               serial_port_out(port, SCPCR,
+                               serial_port_in(port, SCPCR) | SCPCR_RTSC);
+       } else if (sci_getreg(port, SCSPTR)->size) {
+               u16 ctrl = serial_port_in(port, SCSPTR);
+
+               /* Active low */
+               if (state)
+                       ctrl &= ~SCSPTR_RTSDT;
+               else
+                       ctrl |= SCSPTR_RTSDT;
+               serial_port_out(port, SCSPTR, ctrl);
+       }
+}
+
+static bool sci_get_cts(struct uart_port *port)
+{
+       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+               /* Active low */
+               return !(serial_port_in(port, SCPDR) & SCPDR_CTSD);
+       } else if (sci_getreg(port, SCSPTR)->size) {
+               /* Active low */
+               return !(serial_port_in(port, SCSPTR) & SCSPTR_CTSDT);
+       }
+
+       return true;
+}
+
 /*
  * Modem control is a bit of a mixed bag for SCI(F) ports. Generally
  * CTS/RTS is supported in hardware by at least one port and controlled
@@ -1817,6 +1867,8 @@ static unsigned int sci_tx_empty(struct uart_port *port)
  */
 static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
+       struct sci_port *s = to_sci_port(port);
+
        if (mctrl & TIOCM_LOOP) {
                const struct plat_sci_reg *reg;
 
@@ -1829,25 +1881,72 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
                                        serial_port_in(port, SCFCR) |
                                        SCFCR_LOOP);
        }
+
+       mctrl_gpio_set(s->gpios, mctrl);
+
+       if (!(s->cfg->capabilities & SCIx_HAVE_RTSCTS))
+               return;
+
+       if (!(mctrl & TIOCM_RTS)) {
+               /* Disable Auto RTS */
+               serial_port_out(port, SCFCR,
+                               serial_port_in(port, SCFCR) & ~SCFCR_MCE);
+
+               /* Clear RTS */
+               sci_set_rts(port, 0);
+       } else if (s->autorts) {
+               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+                       /* Enable RTS# pin function */
+                       serial_port_out(port, SCPCR,
+                               serial_port_in(port, SCPCR) & ~SCPCR_RTSC);
+               }
+
+               /* Enable Auto RTS */
+               serial_port_out(port, SCFCR,
+                               serial_port_in(port, SCFCR) | SCFCR_MCE);
+       } else {
+               /* Set RTS */
+               sci_set_rts(port, 1);
+       }
 }
 
 static unsigned int sci_get_mctrl(struct uart_port *port)
 {
+       struct sci_port *s = to_sci_port(port);
+       struct mctrl_gpios *gpios = s->gpios;
+       unsigned int mctrl = 0;
+
+       mctrl_gpio_get(gpios, &mctrl);
+
        /*
         * CTS/RTS is handled in hardware when supported, while nothing
-        * else is wired up. Keep it simple and simply assert DSR/CAR.
+        * else is wired up.
         */
-       return TIOCM_DSR | TIOCM_CAR;
+       if (s->autorts) {
+               if (sci_get_cts(port))
+                       mctrl |= TIOCM_CTS;
+       } else if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(gpios, UART_GPIO_CTS))) {
+               mctrl |= TIOCM_CTS;
+       }
+       if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(gpios, UART_GPIO_DSR)))
+               mctrl |= TIOCM_DSR;
+       if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(gpios, UART_GPIO_DCD)))
+               mctrl |= TIOCM_CAR;
+
+       return mctrl;
+}
+
+static void sci_enable_ms(struct uart_port *port)
+{
+       mctrl_gpio_enable_ms(to_sci_port(port)->gpios);
 }
 
 static void sci_break_ctl(struct uart_port *port, int break_state)
 {
-       struct sci_port *s = to_sci_port(port);
-       const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
        unsigned short scscr, scsptr;
 
        /* check wheter the port has SCSPTR */
-       if (!reg->size) {
+       if (!sci_getreg(port, SCSPTR)->size) {
                /*
                 * Not supported by hardware. Most parts couple break and rx
                 * interrupts together, with break detection always enabled.
@@ -1873,7 +1972,6 @@ static void sci_break_ctl(struct uart_port *port, int break_state)
 static int sci_startup(struct uart_port *port)
 {
        struct sci_port *s = to_sci_port(port);
-       unsigned long flags;
        int ret;
 
        dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
@@ -1884,11 +1982,6 @@ static int sci_startup(struct uart_port *port)
 
        sci_request_dma(port);
 
-       spin_lock_irqsave(&port->lock, flags);
-       sci_start_tx(port);
-       sci_start_rx(port);
-       spin_unlock_irqrestore(&port->lock, flags);
-
        return 0;
 }
 
@@ -1896,12 +1989,19 @@ static void sci_shutdown(struct uart_port *port)
 {
        struct sci_port *s = to_sci_port(port);
        unsigned long flags;
+       u16 scr;
 
        dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
 
+       s->autorts = false;
+       mctrl_gpio_disable_ms(to_sci_port(port)->gpios);
+
        spin_lock_irqsave(&port->lock, flags);
        sci_stop_rx(port);
        sci_stop_tx(port);
+       /* Stop RX and TX, disable related interrupts, keep clock source */
+       scr = serial_port_in(port, SCSCR);
+       serial_port_out(port, SCSCR, scr & (SCSCR_CKE1 | SCSCR_CKE0));
        spin_unlock_irqrestore(&port->lock, flags);
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
@@ -2056,6 +2156,15 @@ static void sci_reset(struct uart_port *port)
        reg = sci_getreg(port, SCFCR);
        if (reg->size)
                serial_port_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+
+       sci_clear_SCxSR(port,
+                       SCxSR_RDxF_CLEAR(port) & SCxSR_ERROR_CLEAR(port) &
+                       SCxSR_BREAK_CLEAR(port));
+       if (sci_getreg(port, SCLSR)->size) {
+               status = serial_port_in(port, SCLSR);
+               status &= ~(SCLSR_TO | SCLSR_ORER);
+               serial_port_out(port, SCLSR, status);
+       }
 }
 
 static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -2218,15 +2327,18 @@ done:
 
        sci_init_pins(port, termios->c_cflag);
 
+       port->status &= ~UPSTAT_AUTOCTS;
+       s->autorts = false;
        reg = sci_getreg(port, SCFCR);
        if (reg->size) {
                unsigned short ctrl = serial_port_in(port, SCFCR);
 
-               if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) {
-                       if (termios->c_cflag & CRTSCTS)
-                               ctrl |= SCFCR_MCE;
-                       else
-                               ctrl &= ~SCFCR_MCE;
+               if ((port->flags & UPF_HARD_FLOW) &&
+                   (termios->c_cflag & CRTSCTS)) {
+                       /* There is no CTS interrupt to restart the hardware */
+                       port->status |= UPSTAT_AUTOCTS;
+                       /* MCE is enabled when RTS is raised */
+                       s->autorts = true;
                }
 
                /*
@@ -2300,6 +2412,9 @@ done:
                sci_start_rx(port);
 
        sci_port_disable(s);
+
+       if (UART_ENABLE_MS(port, termios->c_cflag))
+               sci_enable_ms(port);
 }
 
 static void sci_pm(struct uart_port *port, unsigned int state,
@@ -2425,6 +2540,7 @@ static struct uart_ops sci_uart_ops = {
        .start_tx       = sci_start_tx,
        .stop_tx        = sci_stop_tx,
        .stop_rx        = sci_stop_rx,
+       .enable_ms      = sci_enable_ms,
        .break_ctl      = sci_break_ctl,
        .startup        = sci_startup,
        .shutdown       = sci_shutdown,
@@ -2890,6 +3006,9 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id)
        p->regtype = SCI_OF_REGTYPE(match->data);
        p->scscr = SCSCR_RE | SCSCR_TE;
 
+       if (of_find_property(np, "uart-has-rtscts", NULL))
+               p->capabilities |= SCIx_HAVE_RTSCTS;
+
        return p;
 }
 
@@ -2912,6 +3031,21 @@ static int sci_probe_single(struct platform_device *dev,
        if (ret)
                return ret;
 
+       sciport->gpios = mctrl_gpio_init(&sciport->port, 0);
+       if (IS_ERR(sciport->gpios) && PTR_ERR(sciport->gpios) != -ENOSYS)
+               return PTR_ERR(sciport->gpios);
+
+       if (p->capabilities & SCIx_HAVE_RTSCTS) {
+               if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(sciport->gpios,
+                                                       UART_GPIO_CTS)) ||
+                   !IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(sciport->gpios,
+                                                       UART_GPIO_RTS))) {
+                       dev_err(&dev->dev, "Conflicting RTS/CTS config\n");
+                       return -EINVAL;
+               }
+               sciport->port.flags |= UPF_HARD_FLOW;
+       }
+
        ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
        if (ret) {
                sci_cleanup_single(sciport);
index 7a4fa185b93ef30792d58a24d7f26dbb2ec0156e..ffa6d688c335f252c453e821f246b4bbe357ea88 100644 (file)
@@ -105,13 +105,16 @@ enum {
 #define SCFCR_LOOP     BIT(0)  /* Loopback Test */
 
 /* SCLSR (Line Status Register) on (H)SCIF */
+#define SCLSR_TO       BIT(2)  /* Timeout */
 #define SCLSR_ORER     BIT(0)  /* Overrun Error */
 
 /* SCSPTR (Serial Port Register), optional */
-#define SCSPTR_RTSIO   BIT(7)  /* Serial Port RTS Pin Input/Output */
-#define SCSPTR_RTSDT   BIT(6)  /* Serial Port RTS Pin Data */
-#define SCSPTR_CTSIO   BIT(5)  /* Serial Port CTS Pin Input/Output */
-#define SCSPTR_CTSDT   BIT(4)  /* Serial Port CTS Pin Data */
+#define SCSPTR_RTSIO   BIT(7)  /* Serial Port RTS# Pin Input/Output */
+#define SCSPTR_RTSDT   BIT(6)  /* Serial Port RTS# Pin Data */
+#define SCSPTR_CTSIO   BIT(5)  /* Serial Port CTS# Pin Input/Output */
+#define SCSPTR_CTSDT   BIT(4)  /* Serial Port CTS# Pin Data */
+#define SCSPTR_SCKIO   BIT(3)  /* Serial Port Clock Pin Input/Output */
+#define SCSPTR_SCKDT   BIT(2)  /* Serial Port Clock Pin Data */
 #define SCSPTR_SPB2IO  BIT(1)  /* Serial Port Break Input/Output */
 #define SCSPTR_SPB2DT  BIT(0)  /* Serial Port Break Data */
 
@@ -119,12 +122,18 @@ enum {
 #define HSCIF_SRE      BIT(15) /* Sampling Rate Register Enable */
 
 /* SCPCR (Serial Port Control Register), SCIFA/SCIFB only */
-#define SCPCR_RTSC     BIT(4)  /* Serial Port RTS Pin / Output Pin */
-#define SCPCR_CTSC     BIT(3)  /* Serial Port CTS Pin / Input Pin */
+#define SCPCR_RTSC     BIT(4)  /* Serial Port RTS# Pin / Output Pin */
+#define SCPCR_CTSC     BIT(3)  /* Serial Port CTS# Pin / Input Pin */
+#define SCPCR_SCKC     BIT(2)  /* Serial Port SCK Pin / Output Pin */
+#define SCPCR_RXDC     BIT(1)  /* Serial Port RXD Pin / Input Pin */
+#define SCPCR_TXDC     BIT(0)  /* Serial Port TXD Pin / Output Pin */
 
 /* SCPDR (Serial Port Data Register), SCIFA/SCIFB only */
-#define SCPDR_RTSD     BIT(4)  /* Serial Port RTS Output Pin Data */
-#define SCPDR_CTSD     BIT(3)  /* Serial Port CTS Input Pin Data */
+#define SCPDR_RTSD     BIT(4)  /* Serial Port RTS# Output Pin Data */
+#define SCPDR_CTSD     BIT(3)  /* Serial Port CTS# Input Pin Data */
+#define SCPDR_SCKD     BIT(2)  /* Serial Port SCK Output Pin Data */
+#define SCPDR_RXDD     BIT(1)  /* Serial Port RXD Input Pin Data */
+#define SCPDR_TXDD     BIT(0)  /* Serial Port TXD Output Pin Data */
 
 /*
  * BRG Clock Select Register (Some SCIF and HSCIF)
index c3a885b4d76a73b41a3ed94c0abf920c012b88af..43756bd9111c701e4d91a3b9d5e7a7f35c08d546 100644 (file)
@@ -106,7 +106,7 @@ struct sirfsoc_uart_register {
        enum sirfsoc_uart_type uart_type;
 };
 
-u32 uart_usp_ff_full_mask(struct uart_port *port)
+static u32 uart_usp_ff_full_mask(struct uart_port *port)
 {
        u32 full_bit;
 
@@ -114,7 +114,7 @@ u32 uart_usp_ff_full_mask(struct uart_port *port)
        return (1 << full_bit);
 }
 
-u32 uart_usp_ff_empty_mask(struct uart_port *port)
+static u32 uart_usp_ff_empty_mask(struct uart_port *port)
 {
        u32 empty_bit;
 
index b384060e3b1ff3c0c290133d1a0625e05c00d91b..23cfc5e16b45b5200f9c29e5f12b6da3c73e4e62 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/hrtimer.h>
 #include <linux/delay.h>
-#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -730,22 +729,12 @@ static int vt8500_serial_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int vt8500_serial_remove(struct platform_device *pdev)
-{
-       struct vt8500_port *vt8500_port = platform_get_drvdata(pdev);
-
-       clk_disable_unprepare(vt8500_port->clk);
-       uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart);
-
-       return 0;
-}
-
 static struct platform_driver vt8500_platform_driver = {
        .probe  = vt8500_serial_probe,
-       .remove = vt8500_serial_remove,
        .driver = {
                .name = "vt8500_serial",
                .of_match_table = wmt_dt_ids,
+               .suppress_bind_attrs = true,
        },
 };
 
@@ -764,19 +753,4 @@ static int __init vt8500_serial_init(void)
 
        return ret;
 }
-
-static void __exit vt8500_serial_exit(void)
-{
-#ifdef CONFIG_SERIAL_VT8500_CONSOLE
-       unregister_console(&vt8500_console);
-#endif
-       platform_driver_unregister(&vt8500_platform_driver);
-       uart_unregister_driver(&vt8500_uart_driver);
-}
-
-module_init(vt8500_serial_init);
-module_exit(vt8500_serial_exit);
-
-MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
-MODULE_DESCRIPTION("Driver for vt8500 serial device");
-MODULE_LICENSE("GPL v2");
+device_initcall(vt8500_serial_init);
index cd46e64c4255559580ce7adf279300902f504975..9ca1a4d1b66a1e02186a438af498a4ac2ec5ea29 100644 (file)
@@ -976,6 +976,23 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c)
 }
 #endif
 
+static void cdns_uart_pm(struct uart_port *port, unsigned int state,
+                  unsigned int oldstate)
+{
+       struct cdns_uart *cdns_uart = port->private_data;
+
+       switch (state) {
+       case UART_PM_STATE_OFF:
+               clk_disable(cdns_uart->uartclk);
+               clk_disable(cdns_uart->pclk);
+               break;
+       default:
+               clk_enable(cdns_uart->pclk);
+               clk_enable(cdns_uart->uartclk);
+               break;
+       }
+}
+
 static struct uart_ops cdns_uart_ops = {
        .set_mctrl      = cdns_uart_set_mctrl,
        .get_mctrl      = cdns_uart_get_mctrl,
@@ -987,6 +1004,7 @@ static struct uart_ops cdns_uart_ops = {
        .set_termios    = cdns_uart_set_termios,
        .startup        = cdns_uart_startup,
        .shutdown       = cdns_uart_shutdown,
+       .pm             = cdns_uart_pm,
        .type           = cdns_uart_type,
        .verify_port    = cdns_uart_verify_port,
        .request_port   = cdns_uart_request_port,
@@ -1350,12 +1368,12 @@ static int cdns_uart_probe(struct platform_device *pdev)
                return PTR_ERR(cdns_uart_data->uartclk);
        }
 
-       rc = clk_prepare_enable(cdns_uart_data->pclk);
+       rc = clk_prepare(cdns_uart_data->pclk);
        if (rc) {
                dev_err(&pdev->dev, "Unable to enable pclk clock.\n");
                return rc;
        }
-       rc = clk_prepare_enable(cdns_uart_data->uartclk);
+       rc = clk_prepare(cdns_uart_data->uartclk);
        if (rc) {
                dev_err(&pdev->dev, "Unable to enable device clock.\n");
                goto err_out_clk_dis_pclk;
@@ -1422,9 +1440,9 @@ err_out_notif_unreg:
                        &cdns_uart_data->clk_rate_change_nb);
 #endif
 err_out_clk_disable:
-       clk_disable_unprepare(cdns_uart_data->uartclk);
+       clk_unprepare(cdns_uart_data->uartclk);
 err_out_clk_dis_pclk:
-       clk_disable_unprepare(cdns_uart_data->pclk);
+       clk_unprepare(cdns_uart_data->pclk);
 
        return rc;
 }
@@ -1448,8 +1466,8 @@ static int cdns_uart_remove(struct platform_device *pdev)
 #endif
        rc = uart_remove_one_port(&cdns_uart_uart_driver, port);
        port->mapbase = 0;
-       clk_disable_unprepare(cdns_uart_data->uartclk);
-       clk_disable_unprepare(cdns_uart_data->pclk);
+       clk_unprepare(cdns_uart_data->uartclk);
+       clk_unprepare(cdns_uart_data->pclk);
        return rc;
 }
 
index c8c91f0476a22d1510191483009fea621187722d..9d7ab7b66a8a18999c9a0afb94b9a1bfed8bce4a 100644 (file)
@@ -499,9 +499,8 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
        return 0;
 }
 
-/* ui is a leftover from using a hashtable, but might be used again
-   Caller must hold the lock */
-static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
+/* Caller must hold the lock */
+static int con_do_clear_unimap(struct vc_data *vc)
 {
        struct uni_pagedir *p, *q;
 
@@ -524,11 +523,11 @@ static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
        return 0;
 }
 
-int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
+int con_clear_unimap(struct vc_data *vc)
 {
        int ret;
        console_lock();
-       ret = con_do_clear_unimap(vc, ui);
+       ret = con_do_clear_unimap(vc);
        console_unlock();
        return ret;
 }
@@ -556,7 +555,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
                int j, k;
                u16 **p1, *p2, l;
                
-               err1 = con_do_clear_unimap(vc, NULL);
+               err1 = con_do_clear_unimap(vc);
                if (err1) {
                        console_unlock();
                        return err1;
@@ -677,7 +676,7 @@ int con_set_default_unimap(struct vc_data *vc)
        
        /* The default font is always 256 characters */
 
-       err = con_do_clear_unimap(vc, NULL);
+       err = con_do_clear_unimap(vc);
        if (err)
                return err;
     
index f973bfce5d089256086b945fb37148fffebf902d..89a7ab007ff4008f5b29b350589e8a845fec1320 100644 (file)
@@ -579,7 +579,7 @@ static void fn_scroll_forw(struct vc_data *vc)
 
 static void fn_scroll_back(struct vc_data *vc)
 {
-       scrollback(vc, 0);
+       scrollback(vc);
 }
 
 static void fn_show_mem(struct vc_data *vc)
@@ -1745,16 +1745,10 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm)
                        return -EINVAL;
 
                if (ct) {
-                       buf = kmalloc(ct * sizeof(struct kbdiacruc),
-                                                               GFP_KERNEL);
-                       if (buf == NULL)
-                               return -ENOMEM;
-
-                       if (copy_from_user(buf, a->kbdiacruc,
-                                       ct * sizeof(struct kbdiacruc))) {
-                               kfree(buf);
-                               return -EFAULT;
-                       }
+                       buf = memdup_user(a->kbdiacruc,
+                                         ct * sizeof(struct kbdiacruc));
+                       if (IS_ERR(buf))
+                               return PTR_ERR(buf);
                } 
                spin_lock_irqsave(&kbd_event_lock, flags);
                if (ct)
index 5b0fe97c46ca9fb0bff6b66e0638226bf1b5781d..2705ca960e92ea89075b3849839c31202077a276 100644 (file)
@@ -277,13 +277,15 @@ static void notify_update(struct vc_data *vc)
  *     Low-Level Functions
  */
 
-#define IS_FG(vc)      ((vc)->vc_num == fg_console)
+static inline bool con_is_fg(const struct vc_data *vc)
+{
+       return vc->vc_num == fg_console;
+}
 
-#ifdef VT_BUF_VRAM_ONLY
-#define DO_UPDATE(vc)  0
-#else
-#define DO_UPDATE(vc)  (CON_IS_VISIBLE(vc) && !console_blanked)
-#endif
+static inline bool con_should_update(const struct vc_data *vc)
+{
+       return con_is_visible(vc) && !console_blanked;
+}
 
 static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
 {
@@ -321,7 +323,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
                nr = b - t - 1;
        if (b > vc->vc_rows || t >= b || nr < 1)
                return;
-       if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
+       if (con_is_visible(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
                return;
        d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
        s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
@@ -339,7 +341,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
                nr = b - t - 1;
        if (b > vc->vc_rows || t >= b || nr < 1)
                return;
-       if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
+       if (con_is_visible(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
                return;
        s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
        step = vc->vc_cols * nr;
@@ -349,7 +351,6 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
 
 static void do_update_region(struct vc_data *vc, unsigned long start, int count)
 {
-#ifndef VT_BUF_VRAM_ONLY
        unsigned int xx, yy, offset;
        u16 *p;
 
@@ -390,14 +391,13 @@ static void do_update_region(struct vc_data *vc, unsigned long start, int count)
                        start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
                }
        }
-#endif
 }
 
 void update_region(struct vc_data *vc, unsigned long start, int count)
 {
        WARN_CONSOLE_UNLOCKED();
 
-       if (DO_UPDATE(vc)) {
+       if (con_should_update(vc)) {
                hide_cursor(vc);
                do_update_region(vc, start, count);
                set_cursor(vc);
@@ -413,7 +413,6 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
                return vc->vc_sw->con_build_attr(vc, _color, _intensity,
                       _blink, _underline, _reverse, _italic);
 
-#ifndef VT_BUF_VRAM_ONLY
 /*
  * ++roman: I completely changed the attribute format for monochrome
  * mode (!can_do_color). The formerly used MDA (monochrome display
@@ -448,9 +447,6 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
                a <<= 1;
        return a;
        }
-#else
-       return 0;
-#endif
 }
 
 static void update_attr(struct vc_data *vc)
@@ -470,10 +466,9 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
 
        count /= 2;
        p = screenpos(vc, offset, viewed);
-       if (vc->vc_sw->con_invert_region)
+       if (vc->vc_sw->con_invert_region) {
                vc->vc_sw->con_invert_region(vc, p, count);
-#ifndef VT_BUF_VRAM_ONLY
-       else {
+       } else {
                u16 *q = p;
                int cnt = count;
                u16 a;
@@ -501,8 +496,8 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
                        }
                }
        }
-#endif
-       if (DO_UPDATE(vc))
+
+       if (con_should_update(vc))
                do_update_region(vc, (unsigned long) p, count);
        notify_update(vc);
 }
@@ -519,7 +514,7 @@ void complement_pos(struct vc_data *vc, int offset)
        if (old_offset != -1 && old_offset >= 0 &&
            old_offset < vc->vc_screenbuf_size) {
                scr_writew(old, screenpos(vc, old_offset, 1));
-               if (DO_UPDATE(vc))
+               if (con_should_update(vc))
                        vc->vc_sw->con_putc(vc, old, oldy, oldx);
                notify_update(vc);
        }
@@ -534,7 +529,7 @@ void complement_pos(struct vc_data *vc, int offset)
                old = scr_readw(p);
                new = old ^ vc->vc_complement_mask;
                scr_writew(new, p);
-               if (DO_UPDATE(vc)) {
+               if (con_should_update(vc)) {
                        oldx = (offset >> 1) % vc->vc_cols;
                        oldy = (offset >> 1) / vc->vc_cols;
                        vc->vc_sw->con_putc(vc, new, oldy, oldx);
@@ -550,7 +545,7 @@ static void insert_char(struct vc_data *vc, unsigned int nr)
        scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2);
        scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
        vc->vc_need_wrap = 0;
-       if (DO_UPDATE(vc))
+       if (con_should_update(vc))
                do_update_region(vc, (unsigned long) p,
                        vc->vc_cols - vc->vc_x);
 }
@@ -563,7 +558,7 @@ static void delete_char(struct vc_data *vc, unsigned int nr)
        scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
                        nr * 2);
        vc->vc_need_wrap = 0;
-       if (DO_UPDATE(vc))
+       if (con_should_update(vc))
                do_update_region(vc, (unsigned long) p,
                        vc->vc_cols - vc->vc_x);
 }
@@ -583,7 +578,7 @@ static void add_softcursor(struct vc_data *vc)
        if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
        if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
        scr_writew(i, (u16 *) vc->vc_pos);
-       if (DO_UPDATE(vc))
+       if (con_should_update(vc))
                vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
 }
 
@@ -591,7 +586,7 @@ static void hide_softcursor(struct vc_data *vc)
 {
        if (softcursor_original != -1) {
                scr_writew(softcursor_original, (u16 *)vc->vc_pos);
-               if (DO_UPDATE(vc))
+               if (con_should_update(vc))
                        vc->vc_sw->con_putc(vc, softcursor_original,
                                        vc->vc_y, vc->vc_x);
                softcursor_original = -1;
@@ -608,8 +603,7 @@ static void hide_cursor(struct vc_data *vc)
 
 static void set_cursor(struct vc_data *vc)
 {
-       if (!IS_FG(vc) || console_blanked ||
-           vc->vc_mode == KD_GRAPHICS)
+       if (!con_is_fg(vc) || console_blanked || vc->vc_mode == KD_GRAPHICS)
                return;
        if (vc->vc_deccm) {
                if (vc == sel_cons)
@@ -625,7 +619,7 @@ static void set_origin(struct vc_data *vc)
 {
        WARN_CONSOLE_UNLOCKED();
 
-       if (!CON_IS_VISIBLE(vc) ||
+       if (!con_is_visible(vc) ||
            !vc->vc_sw->con_set_origin ||
            !vc->vc_sw->con_set_origin(vc))
                vc->vc_origin = (unsigned long)vc->vc_screenbuf;
@@ -673,12 +667,12 @@ void redraw_screen(struct vc_data *vc, int is_switch)
                struct vc_data *old_vc = vc_cons[fg_console].d;
                if (old_vc == vc)
                        return;
-               if (!CON_IS_VISIBLE(vc))
+               if (!con_is_visible(vc))
                        redraw = 1;
                *vc->vc_display_fg = vc;
                fg_console = vc->vc_num;
                hide_cursor(old_vc);
-               if (!CON_IS_VISIBLE(old_vc)) {
+               if (!con_is_visible(old_vc)) {
                        save_screen(old_vc);
                        set_origin(old_vc);
                }
@@ -954,7 +948,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
                tty_do_resize(tty, &ws);
        }
 
-       if (CON_IS_VISIBLE(vc))
+       if (con_is_visible(vc))
                update_screen(vc);
        vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
        return err;
@@ -1103,11 +1097,9 @@ static void gotoxay(struct vc_data *vc, int new_x, int new_y)
        gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
 }
 
-void scrollback(struct vc_data *vc, int lines)
+void scrollback(struct vc_data *vc)
 {
-       if (!lines)
-               lines = vc->vc_rows / 2;
-       scrolldelta(-lines);
+       scrolldelta(-(vc->vc_rows / 2));
 }
 
 void scrollfront(struct vc_data *vc, int lines)
@@ -1186,7 +1178,7 @@ static void csi_J(struct vc_data *vc, int vpar)
                        scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
                                    vc->vc_screenbuf_size >> 1);
                        set_origin(vc);
-                       if (CON_IS_VISIBLE(vc))
+                       if (con_is_visible(vc))
                                update_screen(vc);
                        /* fall through */
                case 2: /* erase whole display */
@@ -1197,7 +1189,7 @@ static void csi_J(struct vc_data *vc, int vpar)
                        return;
        }
        scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
-       if (DO_UPDATE(vc))
+       if (con_should_update(vc))
                do_update_region(vc, (unsigned long) start, count);
        vc->vc_need_wrap = 0;
 }
@@ -1225,7 +1217,7 @@ static void csi_K(struct vc_data *vc, int vpar)
        }
        scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
        vc->vc_need_wrap = 0;
-       if (DO_UPDATE(vc))
+       if (con_should_update(vc))
                do_update_region(vc, (unsigned long) start, count);
 }
 
@@ -1238,7 +1230,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
        count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
 
        scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
-       if (DO_UPDATE(vc))
+       if (con_should_update(vc))
                vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
        vc->vc_need_wrap = 0;
 }
@@ -1255,48 +1247,87 @@ static void default_attr(struct vc_data *vc)
 
 struct rgb { u8 r; u8 g; u8 b; };
 
-static struct rgb rgb_from_256(int i)
+static void rgb_from_256(int i, struct rgb *c)
 {
-       struct rgb c;
        if (i < 8) {            /* Standard colours. */
-               c.r = i&1 ? 0xaa : 0x00;
-               c.g = i&2 ? 0xaa : 0x00;
-               c.b = i&4 ? 0xaa : 0x00;
+               c->r = i&1 ? 0xaa : 0x00;
+               c->g = i&2 ? 0xaa : 0x00;
+               c->b = i&4 ? 0xaa : 0x00;
        } else if (i < 16) {
-               c.r = i&1 ? 0xff : 0x55;
-               c.g = i&2 ? 0xff : 0x55;
-               c.b = i&4 ? 0xff : 0x55;
+               c->r = i&1 ? 0xff : 0x55;
+               c->g = i&2 ? 0xff : 0x55;
+               c->b = i&4 ? 0xff : 0x55;
        } else if (i < 232) {   /* 6x6x6 colour cube. */
-               c.r = (i - 16) / 36 * 85 / 2;
-               c.g = (i - 16) / 6 % 6 * 85 / 2;
-               c.b = (i - 16) % 6 * 85 / 2;
+               c->r = (i - 16) / 36 * 85 / 2;
+               c->g = (i - 16) / 6 % 6 * 85 / 2;
+               c->b = (i - 16) % 6 * 85 / 2;
        } else                  /* Grayscale ramp. */
-               c.r = c.g = c.b = i * 10 - 2312;
-       return c;
+               c->r = c->g = c->b = i * 10 - 2312;
 }
 
-static void rgb_foreground(struct vc_data *vc, struct rgb c)
+static void rgb_foreground(struct vc_data *vc, const struct rgb *c)
 {
-       u8 hue, max = c.r;
-       if (c.g > max)
-               max = c.g;
-       if (c.b > max)
-               max = c.b;
-       hue = (c.r > max/2 ? 4 : 0)
-           | (c.g > max/2 ? 2 : 0)
-           | (c.b > max/2 ? 1 : 0);
-       if (hue == 7 && max <= 0x55)
-               hue = 0, vc->vc_intensity = 2;
+       u8 hue = 0, max = max3(c->r, c->g, c->b);
+
+       if (c->r > max / 2)
+               hue |= 4;
+       if (c->g > max / 2)
+               hue |= 2;
+       if (c->b > max / 2)
+               hue |= 1;
+
+       if (hue == 7 && max <= 0x55) {
+               hue = 0;
+               vc->vc_intensity = 2;
+       } else if (max > 0xaa)
+               vc->vc_intensity = 2;
        else
-               vc->vc_intensity = (max > 0xaa) + 1;
+               vc->vc_intensity = 1;
+
        vc->vc_color = (vc->vc_color & 0xf0) | hue;
 }
 
-static void rgb_background(struct vc_data *vc, struct rgb c)
+static void rgb_background(struct vc_data *vc, const struct rgb *c)
 {
        /* For backgrounds, err on the dark side. */
        vc->vc_color = (vc->vc_color & 0x0f)
-               | (c.r&0x80) >> 1 | (c.g&0x80) >> 2 | (c.b&0x80) >> 3;
+               | (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3;
+}
+
+/*
+ * 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.
+ *
+ * Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in
+ * supporting them.
+ */
+static int vc_t416_color(struct vc_data *vc, int i,
+               void(*set_color)(struct vc_data *vc, const struct rgb *c))
+{
+       struct rgb c;
+
+       i++;
+       if (i > vc->vc_npar)
+               return i;
+
+       if (vc->vc_par[i] == 5 && i < vc->vc_npar) {
+               /* 256 colours -- ubiquitous */
+               i++;
+               rgb_from_256(vc->vc_par[i], &c);
+       } else if (vc->vc_par[i] == 2 && i <= vc->vc_npar + 3) {
+               /* 24 bit -- extremely rare */
+               c.r = vc->vc_par[i + 1];
+               c.g = vc->vc_par[i + 2];
+               c.b = vc->vc_par[i + 3];
+               i += 3;
+       } else
+               return i;
+
+       set_color(vc, &c);
+
+       return i;
 }
 
 /* console_lock is held */
@@ -1306,135 +1337,91 @@ static void csi_m(struct vc_data *vc)
 
        for (i = 0; i <= vc->vc_npar; i++)
                switch (vc->vc_par[i]) {
-                       case 0: /* all attributes off */
-                               default_attr(vc);
-                               break;
-                       case 1:
-                               vc->vc_intensity = 2;
-                               break;
-                       case 2:
-                               vc->vc_intensity = 0;
-                               break;
-                       case 3:
-                               vc->vc_italic = 1;
-                               break;
-                       case 4:
-                               vc->vc_underline = 1;
-                               break;
-                       case 5:
-                               vc->vc_blink = 1;
-                               break;
-                       case 7:
-                               vc->vc_reverse = 1;
-                               break;
-                       case 10: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Select primary font, don't display
-                                 * control chars if defined, don't set
-                                 * bit 8 on output.
-                                 */
-                               vc->vc_translate = set_translate(vc->vc_charset == 0
-                                               ? vc->vc_G0_charset
-                                               : vc->vc_G1_charset, vc);
-                               vc->vc_disp_ctrl = 0;
-                               vc->vc_toggle_meta = 0;
-                               break;
-                       case 11: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Select first alternate font, lets
-                                 * chars < 32 be displayed as ROM chars.
-                                 */
-                               vc->vc_translate = set_translate(IBMPC_MAP, vc);
-                               vc->vc_disp_ctrl = 1;
-                               vc->vc_toggle_meta = 0;
-                               break;
-                       case 12: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Select second alternate font, toggle
-                                 * high bit before displaying as ROM char.
-                                 */
-                               vc->vc_translate = set_translate(IBMPC_MAP, vc);
-                               vc->vc_disp_ctrl = 1;
-                               vc->vc_toggle_meta = 1;
-                               break;
-                       case 21:
-                       case 22:
-                               vc->vc_intensity = 1;
-                               break;
-                       case 23:
-                               vc->vc_italic = 0;
-                               break;
-                       case 24:
-                               vc->vc_underline = 0;
-                               break;
-                       case 25:
-                               vc->vc_blink = 0;
-                               break;
-                       case 27:
-                               vc->vc_reverse = 0;
-                               break;
-                       case 38: /* 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.
-                                 */
-                               i++;
-                               if (i > vc->vc_npar)
-                                       break;
-                               if (vc->vc_par[i] == 5 &&  /* 256 colours */
-                                   i < vc->vc_npar) {     /* ubiquitous */
-                                       i++;
-                                       rgb_foreground(vc,
-                                               rgb_from_256(vc->vc_par[i]));
-                               } else if (vc->vc_par[i] == 2 &&  /* 24 bit */
-                                          i <= vc->vc_npar + 3) {/* extremely rare */
-                                       struct rgb c = {
-                                               .r = vc->vc_par[i + 1],
-                                               .g = vc->vc_par[i + 2],
-                                               .b = vc->vc_par[i + 3],
-                                       };
-                                       rgb_foreground(vc, c);
-                                       i += 3;
-                               }
-                               /* Subcommands 3 (CMY) and 4 (CMYK) are so insane
-                                * there's no point in supporting them.
-                                */
-                               break;
-                       case 48:
-                               i++;
-                               if (i > vc->vc_npar)
-                                       break;
-                               if (vc->vc_par[i] == 5 &&  /* 256 colours */
-                                   i < vc->vc_npar) {
-                                       i++;
-                                       rgb_background(vc,
-                                               rgb_from_256(vc->vc_par[i]));
-                               } else if (vc->vc_par[i] == 2 && /* 24 bit */
-                                          i <= vc->vc_npar + 3) {
-                                       struct rgb c = {
-                                               .r = vc->vc_par[i + 1],
-                                               .g = vc->vc_par[i + 2],
-                                               .b = vc->vc_par[i + 3],
-                                       };
-                                       rgb_background(vc, c);
-                                       i += 3;
-                               }
-                               break;
-                       case 39:
-                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               break;
-                       case 49:
-                               vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
-                               break;
-                       default:
-                               if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
-                                       vc->vc_color = color_table[vc->vc_par[i] - 30]
-                                               | (vc->vc_color & 0xf0);
-                               else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
-                                       vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
-                                               | (vc->vc_color & 0x0f);
-                               break;
+               case 0: /* all attributes off */
+                       default_attr(vc);
+                       break;
+               case 1:
+                       vc->vc_intensity = 2;
+                       break;
+               case 2:
+                       vc->vc_intensity = 0;
+                       break;
+               case 3:
+                       vc->vc_italic = 1;
+                       break;
+               case 4:
+                       vc->vc_underline = 1;
+                       break;
+               case 5:
+                       vc->vc_blink = 1;
+                       break;
+               case 7:
+                       vc->vc_reverse = 1;
+                       break;
+               case 10: /* ANSI X3.64-1979 (SCO-ish?)
+                         * Select primary font, don't display control chars if
+                         * defined, don't set bit 8 on output.
+                         */
+                       vc->vc_translate = set_translate(vc->vc_charset == 0
+                                       ? vc->vc_G0_charset
+                                       : vc->vc_G1_charset, vc);
+                       vc->vc_disp_ctrl = 0;
+                       vc->vc_toggle_meta = 0;
+                       break;
+               case 11: /* ANSI X3.64-1979 (SCO-ish?)
+                         * Select first alternate font, lets chars < 32 be
+                         * displayed as ROM chars.
+                         */
+                       vc->vc_translate = set_translate(IBMPC_MAP, vc);
+                       vc->vc_disp_ctrl = 1;
+                       vc->vc_toggle_meta = 0;
+                       break;
+               case 12: /* ANSI X3.64-1979 (SCO-ish?)
+                         * Select second alternate font, toggle high bit
+                         * before displaying as ROM char.
+                         */
+                       vc->vc_translate = set_translate(IBMPC_MAP, vc);
+                       vc->vc_disp_ctrl = 1;
+                       vc->vc_toggle_meta = 1;
+                       break;
+               case 21:
+               case 22:
+                       vc->vc_intensity = 1;
+                       break;
+               case 23:
+                       vc->vc_italic = 0;
+                       break;
+               case 24:
+                       vc->vc_underline = 0;
+                       break;
+               case 25:
+                       vc->vc_blink = 0;
+                       break;
+               case 27:
+                       vc->vc_reverse = 0;
+                       break;
+               case 38:
+                       i = vc_t416_color(vc, i, rgb_foreground);
+                       break;
+               case 48:
+                       i = vc_t416_color(vc, i, rgb_background);
+                       break;
+               case 39:
+                       vc->vc_color = (vc->vc_def_color & 0x0f) |
+                               (vc->vc_color & 0xf0);
+                       break;
+               case 49:
+                       vc->vc_color = (vc->vc_def_color & 0xf0) |
+                               (vc->vc_color & 0x0f);
+                       break;
+               default:
+                       if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
+                               vc->vc_color = color_table[vc->vc_par[i] - 30]
+                                       | (vc->vc_color & 0xf0);
+                       else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
+                               vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
+                                       | (vc->vc_color & 0x0f);
+                       break;
                }
        update_attr(vc);
 }
@@ -1496,7 +1483,6 @@ static void set_mode(struct vc_data *vc, int on_off)
                                        clr_kbd(vc, decckm);
                                break;
                        case 3: /* 80/132 mode switch unimplemented */
-                               vc->vc_deccolm = on_off;
 #if 0
                                vc_resize(deccolm ? 132 : 80, vc->vc_rows);
                                /* this alone does not suffice; some user mode
@@ -2178,18 +2164,20 @@ static int is_double_width(uint32_t ucs)
        return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1);
 }
 
+static void con_flush(struct vc_data *vc, unsigned long draw_from,
+               unsigned long draw_to, int *draw_x)
+{
+       if (*draw_x < 0)
+               return;
+
+       vc->vc_sw->con_putcs(vc, (u16 *)draw_from,
+                       (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, *draw_x);
+       *draw_x = -1;
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
-#ifdef VT_BUF_VRAM_ONLY
-#define FLUSH do { } while(0);
-#else
-#define FLUSH if (draw_x >= 0) { \
-       vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \
-       draw_x = -1; \
-       }
-#endif
-
        int c, tc, ok, n = 0, draw_x = -1;
        unsigned int currcons;
        unsigned long draw_from = 0, draw_to = 0;
@@ -2226,7 +2214,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
        charmask = himask ? 0x1ff : 0xff;
 
        /* undraw cursor first */
-       if (IS_FG(vc))
+       if (con_is_fg(vc))
                hide_cursor(vc);
 
        param.vc = vc;
@@ -2381,12 +2369,13 @@ rescan_last_byte:
                                } else {
                                        vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
                                }
-                               FLUSH
+                               con_flush(vc, draw_from, draw_to, &draw_x);
                        }
 
                        while (1) {
                                if (vc->vc_need_wrap || vc->vc_decim)
-                                       FLUSH
+                                       con_flush(vc, draw_from, draw_to,
+                                                       &draw_x);
                                if (vc->vc_need_wrap) {
                                        cr(vc);
                                        lf(vc);
@@ -2397,7 +2386,7 @@ rescan_last_byte:
                                             ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
                                             (vc_attr << 8) + tc,
                                           (u16 *) vc->vc_pos);
-                               if (DO_UPDATE(vc) && draw_x < 0) {
+                               if (con_should_update(vc) && draw_x < 0) {
                                        draw_x = vc->vc_x;
                                        draw_from = vc->vc_pos;
                                }
@@ -2416,9 +2405,8 @@ rescan_last_byte:
                        }
                        notify_write(vc, c);
 
-                       if (inverse) {
-                               FLUSH
-                       }
+                       if (inverse)
+                               con_flush(vc, draw_from, draw_to, &draw_x);
 
                        if (rescan) {
                                rescan = 0;
@@ -2429,15 +2417,14 @@ rescan_last_byte:
                        }
                        continue;
                }
-               FLUSH
+               con_flush(vc, draw_from, draw_to, &draw_x);
                do_con_trol(tty, vc, orig);
        }
-       FLUSH
+       con_flush(vc, draw_from, draw_to, &draw_x);
        console_conditional_schedule();
        console_unlock();
        notify_update(vc);
        return n;
-#undef FLUSH
 }
 
 /*
@@ -2471,7 +2458,7 @@ static void console_callback(struct work_struct *ignored)
        if (scrollback_delta) {
                struct vc_data *vc = vc_cons[fg_console].d;
                clear_selection();
-               if (vc->vc_mode == KD_TEXT)
+               if (vc->vc_mode == KD_TEXT && vc->vc_sw->con_scrolldelta)
                        vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
                scrollback_delta = 0;
        }
@@ -2583,7 +2570,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
                goto quit;
 
        /* undraw cursor first */
-       if (IS_FG(vc))
+       if (con_is_fg(vc))
                hide_cursor(vc);
 
        start = (ushort *)vc->vc_pos;
@@ -2594,7 +2581,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
                c = *b++;
                if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
                        if (cnt > 0) {
-                               if (CON_IS_VISIBLE(vc))
+                               if (con_is_visible(vc))
                                        vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
                                vc->vc_x += cnt;
                                if (vc->vc_need_wrap)
@@ -2626,7 +2613,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
                myx++;
        }
        if (cnt > 0) {
-               if (CON_IS_VISIBLE(vc))
+               if (con_is_visible(vc))
                        vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
                vc->vc_x += cnt;
                if (vc->vc_x == vc->vc_cols) {
@@ -3173,7 +3160,7 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last,
 
                j = i;
 
-               if (CON_IS_VISIBLE(vc)) {
+               if (con_is_visible(vc)) {
                        k = i;
                        save_screen(vc);
                }
@@ -3981,7 +3968,7 @@ static void set_palette(struct vc_data *vc)
 {
        WARN_CONSOLE_UNLOCKED();
 
-       if (vc->vc_mode != KD_GRAPHICS)
+       if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_set_palette)
                vc->vc_sw->con_set_palette(vc, color_table);
 }
 
index 97d5a74558a3a4477e3c5cfb29dd88591fefbe92..f62c598810ff4ca64ec2df66b769ea0b4e6541e0 100644 (file)
@@ -1006,16 +1006,10 @@ int vt_ioctl(struct tty_struct *tty,
                break;
 
        case PIO_UNIMAPCLR:
-             { struct unimapinit ui;
                if (!perm)
                        return -EPERM;
-               ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
-               if (ret)
-                       ret = -EFAULT;
-               else
-                       con_clear_unimap(vc, &ui);
+               con_clear_unimap(vc);
                break;
-             }
 
        case PIO_UNIMAP:
        case GIO_UNIMAP:
index 15666ad7c772fe5a9b960e8e37f5bf93a150bcd1..02abfcdfbf7bc887b4b331a5da9066d5db8c152a 100644 (file)
@@ -1285,18 +1285,22 @@ int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data)
 }
 
 int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
-               u32 dest, int length, size_t *bytes_written)
+               u32 dest, int length)
 {
+       size_t dummy;
+
        return sisusb_write_mem_bulk(sisusb, dest, src, length,
-                       NULL, 0, bytes_written);
+                       NULL, 0, &dummy);
 }
 
 #ifdef SISUSBENDIANTEST
-int sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest,
-               u32 src, int length, size_t *bytes_written)
+static int sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest,
+               u32 src, int length)
 {
+       size_t dummy;
+
        return sisusb_read_mem_bulk(sisusb, src, dest, length,
-                       NULL, bytes_written);
+                       NULL, &dummy);
 }
 #endif
 #endif
@@ -1306,16 +1310,14 @@ static void sisusb_testreadwrite(struct sisusb_usb_data *sisusb)
 {
        static char srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
        char destbuffer[10];
-       size_t dummy;
        int i, j;
 
-       sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy);
+       sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7);
 
        for (i = 1; i <= 7; i++) {
                dev_dbg(&sisusb->sisusb_dev->dev,
                                "sisusb: rwtest %d bytes\n", i);
-               sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase,
-                               i, &dummy);
+               sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i);
                for (j = 0; j < i; j++) {
                        dev_dbg(&sisusb->sisusb_dev->dev,
                                        "rwtest read[%d] = %x\n",
@@ -2276,7 +2278,6 @@ int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
        const struct font_desc *myfont;
        u8 *tempbuf;
        u16 *tempbufb;
-       size_t written;
        static const char bootstring[] =
                "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
        static const char bootlogo[] = "(o_ //\\ V_/_";
@@ -2343,18 +2344,15 @@ int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
                                *(tempbufb++) = 0x0700 | bootstring[i++];
 
                        ret |= sisusb_copy_memory(sisusb, tempbuf,
-                                       sisusb->vrambase, 8192, &written);
+                                       sisusb->vrambase, 8192);
 
                        vfree(tempbuf);
 
                }
 
        } else if (sisusb->scrbuf) {
-
                ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf,
-                               sisusb->vrambase, sisusb->scrbuf_size,
-                               &written);
-
+                               sisusb->vrambase, sisusb->scrbuf_size);
        }
 
        if (sisusb->sisusb_cursor_size_from >= 0 &&
index afa853209f1d599d73e1b939ae0bdfee244ff7c0..460cebf322e39109bb86ca4cb5eac81014ae101e 100644 (file)
@@ -370,7 +370,6 @@ static void
 sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
 {
        struct sisusb_usb_data *sisusb;
-       ssize_t written;
 
        sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num);
        if (!sisusb)
@@ -384,7 +383,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
 
 
        sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
-                               (long)SISUSB_HADDR(x, y), 2, &written);
+                               (long)SISUSB_HADDR(x, y), 2);
 
        mutex_unlock(&sisusb->lock);
 }
@@ -395,7 +394,6 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s,
                         int count, int y, int x)
 {
        struct sisusb_usb_data *sisusb;
-       ssize_t written;
        u16 *dest;
        int i;
 
@@ -420,7 +418,7 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s,
        }
 
        sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
-                               (long)SISUSB_HADDR(x, y), count * 2, &written);
+                               (long)SISUSB_HADDR(x, y), count * 2);
 
        mutex_unlock(&sisusb->lock);
 }
@@ -431,7 +429,6 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
 {
        struct sisusb_usb_data *sisusb;
        u16 eattr = c->vc_video_erase_char;
-       ssize_t written;
        int i, length, cols;
        u16 *dest;
 
@@ -475,41 +472,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
 
 
        sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y),
-                               (long)SISUSB_HADDR(x, y), length, &written);
-
-       mutex_unlock(&sisusb->lock);
-}
-
-/* Interface routine */
-static void
-sisusbcon_bmove(struct vc_data *c, int sy, int sx,
-                        int dy, int dx, int height, int width)
-{
-       struct sisusb_usb_data *sisusb;
-       ssize_t written;
-       int cols, length;
-
-       if (width <= 0 || height <= 0)
-               return;
-
-       sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num);
-       if (!sisusb)
-               return;
-
-       /* sisusb->lock is down */
-
-       cols = sisusb->sisusb_num_columns;
-
-       if (sisusb_is_inactive(c, sisusb)) {
-               mutex_unlock(&sisusb->lock);
-               return;
-       }
-
-       length = ((height * cols) - dx - (cols - width - dx)) * 2;
-
-
-       sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy),
-                               (long)SISUSB_HADDR(dx, dy), length, &written);
+                               (long)SISUSB_HADDR(x, y), length);
 
        mutex_unlock(&sisusb->lock);
 }
@@ -519,7 +482,6 @@ static int
 sisusbcon_switch(struct vc_data *c)
 {
        struct sisusb_usb_data *sisusb;
-       ssize_t written;
        int length;
 
        /* Returnvalue 0 means we have fully restored screen,
@@ -559,7 +521,7 @@ sisusbcon_switch(struct vc_data *c)
 
        sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin,
                                (long)SISUSB_HADDR(0, 0),
-                               length, &written);
+                               length);
 
        mutex_unlock(&sisusb->lock);
 
@@ -600,7 +562,7 @@ sisusbcon_save_screen(struct vc_data *c)
 }
 
 /* interface routine */
-static int
+static void
 sisusbcon_set_palette(struct vc_data *c, const unsigned char *table)
 {
        struct sisusb_usb_data *sisusb;
@@ -608,18 +570,18 @@ sisusbcon_set_palette(struct vc_data *c, const unsigned char *table)
 
        /* Return value not used by vt */
 
-       if (!CON_IS_VISIBLE(c))
-               return -EINVAL;
+       if (!con_is_visible(c))
+               return;
 
        sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num);
        if (!sisusb)
-               return -EINVAL;
+               return;
 
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
                mutex_unlock(&sisusb->lock);
-               return -EINVAL;
+               return;
        }
 
        for (i = j = 0; i < 16; i++) {
@@ -634,8 +596,6 @@ sisusbcon_set_palette(struct vc_data *c, const unsigned char *table)
        }
 
        mutex_unlock(&sisusb->lock);
-
-       return 0;
 }
 
 /* interface routine */
@@ -644,7 +604,6 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
 {
        struct sisusb_usb_data *sisusb;
        u8 sr1, cr17, pmreg, cr63;
-       ssize_t written;
        int ret = 0;
 
        sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num);
@@ -672,7 +631,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
                                (unsigned char *)c->vc_origin,
                                (u32)(sisusb->vrambase +
                                        (c->vc_origin - sisusb->scrbuf)),
-                               c->vc_screenbuf_size, &written);
+                               c->vc_screenbuf_size);
                sisusb->con_blanked = 1;
                ret = 1;
                break;
@@ -723,24 +682,22 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
 }
 
 /* interface routine */
-static int
+static void
 sisusbcon_scrolldelta(struct vc_data *c, int lines)
 {
        struct sisusb_usb_data *sisusb;
        int margin = c->vc_size_row * 4;
        int ul, we, p, st;
 
-       /* The return value does not seem to be used */
-
        sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num);
        if (!sisusb)
-               return 0;
+               return;
 
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
                mutex_unlock(&sisusb->lock);
-               return 0;
+               return;
        }
 
        if (!lines)             /* Turn scrollback off */
@@ -780,8 +737,6 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines)
        sisusbcon_set_start_address(sisusb, c);
 
        mutex_unlock(&sisusb->lock);
-
-       return 1;
 }
 
 /* Interface routine */
@@ -860,7 +815,6 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
        int cols = sisusb->sisusb_num_columns;
        int length = ((b - t) * cols) * 2;
        u16 eattr = c->vc_video_erase_char;
-       ssize_t written;
 
        /* sisusb->lock is down */
 
@@ -890,7 +844,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
        }
 
        sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t),
-                               (long)SISUSB_HADDR(0, t), length, &written);
+                               (long)SISUSB_HADDR(0, t), length);
 
        mutex_unlock(&sisusb->lock);
 
@@ -903,7 +857,6 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
 {
        struct sisusb_usb_data *sisusb;
        u16 eattr = c->vc_video_erase_char;
-       ssize_t written;
        int copyall = 0;
        unsigned long oldorigin;
        unsigned int delta = lines * c->vc_size_row;
@@ -996,18 +949,18 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
                sisusb_copy_memory(sisusb,
                        (char *)c->vc_origin,
                        (u32)(sisusb->vrambase + originoffset),
-                       c->vc_screenbuf_size, &written);
+                       c->vc_screenbuf_size);
        else if (dir == SM_UP)
                sisusb_copy_memory(sisusb,
                        (char *)c->vc_origin + c->vc_screenbuf_size - delta,
                        (u32)sisusb->vrambase + originoffset +
                                        c->vc_screenbuf_size - delta,
-                       delta, &written);
+                       delta);
        else
                sisusb_copy_memory(sisusb,
                        (char *)c->vc_origin,
                        (u32)(sisusb->vrambase + originoffset),
-                       delta, &written);
+                       delta);
 
        c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
        c->vc_visible_origin = c->vc_origin;
@@ -1273,7 +1226,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
                        struct vc_data *vc = vc_cons[i].d;
 
                        if (vc && vc->vc_sw == &sisusb_con) {
-                               if (CON_IS_VISIBLE(vc)) {
+                               if (con_is_visible(vc)) {
                                        vc->vc_sw->con_cursor(vc, CM_DRAW);
                                }
                                vc->vc_font.height = fh;
@@ -1385,7 +1338,6 @@ static const struct consw sisusb_con = {
        .con_putcs =            sisusbcon_putcs,
        .con_cursor =           sisusbcon_cursor,
        .con_scroll =           sisusbcon_scroll,
-       .con_bmove =            sisusbcon_bmove,
        .con_switch =           sisusbcon_switch,
        .con_blank =            sisusbcon_blank,
        .con_font_set =         sisusbcon_font_set,
@@ -1433,15 +1385,12 @@ static const struct consw sisusb_dummy_con = {
        .con_putcs =            SISUSBCONDUMMY,
        .con_cursor =           SISUSBCONDUMMY,
        .con_scroll =           SISUSBCONDUMMY,
-       .con_bmove =            SISUSBCONDUMMY,
        .con_switch =           SISUSBCONDUMMY,
        .con_blank =            SISUSBCONDUMMY,
        .con_font_set =         SISUSBCONDUMMY,
        .con_font_get =         SISUSBCONDUMMY,
        .con_font_default =     SISUSBCONDUMMY,
        .con_font_copy =        SISUSBCONDUMMY,
-       .con_set_palette =      SISUSBCONDUMMY,
-       .con_scrolldelta =      SISUSBCONDUMMY,
 };
 
 int
index c46ce42d44892cb895f5d7f3a8d49a6083aa58f2..e79a616f0d26ca6d33db4d9504dff49d45aaad33 100644 (file)
@@ -828,7 +828,7 @@ void sisusb_delete(struct kref *kref);
 int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
 int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data);
 int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
-                      u32 dest, int length, size_t * bytes_written);
+                      u32 dest, int length);
 int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
 int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
                         u8 * arg, int cmapsz, int ch512, int dorecalc,
index 0efc52f11ad003ae73063fa12ca2dd7bef86ddbe..9269d568523973a007c559cc0ea8491968f161be 100644 (file)
@@ -64,14 +64,11 @@ const struct consw dummy_con = {
     .con_putcs =       DUMMY,
     .con_cursor =      DUMMY,
     .con_scroll =      DUMMY,
-    .con_bmove =       DUMMY,
     .con_switch =      DUMMY,
     .con_blank =       DUMMY,
     .con_font_set =    DUMMY,
     .con_font_get =    DUMMY,
     .con_font_default =        DUMMY,
     .con_font_copy =   DUMMY,
-    .con_set_palette = DUMMY,
-    .con_scrolldelta = DUMMY,
 };
 EXPORT_SYMBOL_GPL(dummy_con);
index afd3301ac40cc5c0ebbb093140a7a813c69ab391..b87f5cfdaea5cb364fc1043f9df4db835ca2cf5a 100644 (file)
@@ -170,8 +170,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
                        int height, int width);
 static int fbcon_switch(struct vc_data *vc);
 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
-static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
-static int fbcon_scrolldelta(struct vc_data *vc, int lines);
+static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
 
 /*
  *  Internal routines
@@ -381,7 +380,7 @@ static void fb_flashcursor(struct work_struct *work)
        if (ops && ops->currcon != -1)
                vc = vc_cons[ops->currcon].d;
 
-       if (!vc || !CON_IS_VISIBLE(vc) ||
+       if (!vc || !con_is_visible(vc) ||
            registered_fb[con2fb_map[vc->vc_num]] != info ||
            vc->vc_deccm != 1) {
                console_unlock();
@@ -619,7 +618,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
                    erase,
                    vc->vc_size_row * logo_lines);
 
-       if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {
+       if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
                fbcon_clear_margins(vc, 0);
                update_screen(vc);
        }
@@ -1113,7 +1112,7 @@ static void fbcon_init(struct vc_data *vc, int init)
         *
         * We need to do it in fbcon_init() to prevent screen corruption.
         */
-       if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {
+       if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
                if (info->fbops->fb_set_par &&
                    !(ops->flags & FBCON_FLAGS_INIT)) {
                        ret = info->fbops->fb_set_par(info);
@@ -1193,7 +1192,7 @@ static void fbcon_deinit(struct vc_data *vc)
        if (!ops)
                goto finished;
 
-       if (CON_IS_VISIBLE(vc))
+       if (con_is_visible(vc))
                fbcon_del_cursor_timer(info);
 
        ops->flags &= ~FBCON_FLAGS_INIT;
@@ -1398,7 +1397,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
        rows /= vc->vc_font.height;
        vc_resize(vc, cols, rows);
 
-       if (CON_IS_VISIBLE(vc)) {
+       if (con_is_visible(vc)) {
                update_screen(vc);
                if (softback_buf)
                        fbcon_update_softback(vc);
@@ -2146,7 +2145,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
                        return -EINVAL;
 
                DPRINTK("resize now %ix%i\n", var.xres, var.yres);
-               if (CON_IS_VISIBLE(vc)) {
+               if (con_is_visible(vc)) {
                        var.activate = FB_ACTIVATE_NOW |
                                FB_ACTIVATE_FORCE;
                        fb_set_var(info, &var);
@@ -2449,7 +2448,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
        int cnt;
        char *old_data = NULL;
 
-       if (CON_IS_VISIBLE(vc) && softback_lines)
+       if (con_is_visible(vc) && softback_lines)
                fbcon_set_origin(vc);
 
        resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
@@ -2530,9 +2529,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
                cols /= w;
                rows /= h;
                vc_resize(vc, cols, rows);
-               if (CON_IS_VISIBLE(vc) && softback_buf)
+               if (con_is_visible(vc) && softback_buf)
                        fbcon_update_softback(vc);
-       } else if (CON_IS_VISIBLE(vc)
+       } else if (con_is_visible(vc)
                   && vc->vc_mode == KD_TEXT) {
                fbcon_clear_margins(vc, 0);
                update_screen(vc);
@@ -2652,17 +2651,17 @@ static struct fb_cmap palette_cmap = {
        0, 16, palette_red, palette_green, palette_blue, NULL
 };
 
-static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
+static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
 {
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        int i, j, k, depth;
        u8 val;
 
        if (fbcon_is_inactive(vc, info))
-               return -EINVAL;
+               return;
 
-       if (!CON_IS_VISIBLE(vc))
-               return 0;
+       if (!con_is_visible(vc))
+               return;
 
        depth = fb_get_color_depth(&info->var, &info->fix);
        if (depth > 3) {
@@ -2684,7 +2683,7 @@ static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
        } else
                fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
 
-       return fb_set_cmap(&palette_cmap, info);
+       fb_set_cmap(&palette_cmap, info);
 }
 
 static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
@@ -2765,7 +2764,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
        }
 }
 
-static int fbcon_scrolldelta(struct vc_data *vc, int lines)
+static void fbcon_scrolldelta(struct vc_data *vc, int lines)
 {
        struct fb_info *info = registered_fb[con2fb_map[fg_console]];
        struct fbcon_ops *ops = info->fbcon_par;
@@ -2774,9 +2773,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
 
        if (softback_top) {
                if (vc->vc_num != fg_console)
-                       return 0;
+                       return;
                if (vc->vc_mode != KD_TEXT || !lines)
-                       return 0;
+                       return;
                if (logo_shown >= 0) {
                        struct vc_data *conp2 = vc_cons[logo_shown].d;
 
@@ -2809,11 +2808,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
                fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
                fbcon_redraw_softback(vc, disp, lines);
                fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
-               return 0;
+               return;
        }
 
        if (!scrollback_phys_max)
-               return -ENOSYS;
+               return;
 
        scrollback_old = scrollback_current;
        scrollback_current -= lines;
@@ -2822,10 +2821,10 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
        else if (scrollback_current > scrollback_max)
                scrollback_current = scrollback_max;
        if (scrollback_current == scrollback_old)
-               return 0;
+               return;
 
        if (fbcon_is_inactive(vc, info))
-               return 0;
+               return;
 
        fbcon_cursor(vc, CM_ERASE);
 
@@ -2852,7 +2851,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
 
        if (!scrollback_current)
                fbcon_cursor(vc, CM_DRAW);
-       return 0;
 }
 
 static int fbcon_set_origin(struct vc_data *vc)
@@ -2904,7 +2902,7 @@ static void fbcon_modechanged(struct fb_info *info)
        p = &fb_display[vc->vc_num];
        set_blitting_type(vc, info);
 
-       if (CON_IS_VISIBLE(vc)) {
+       if (con_is_visible(vc)) {
                var_to_display(p, &info->var, info);
                cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
@@ -2943,7 +2941,7 @@ static void fbcon_set_all_vcs(struct fb_info *info)
                    registered_fb[con2fb_map[i]] != info)
                        continue;
 
-               if (CON_IS_VISIBLE(vc)) {
+               if (con_is_visible(vc)) {
                        fg = i;
                        continue;
                }
@@ -3182,7 +3180,7 @@ static void fbcon_fb_blanked(struct fb_info *info, int blank)
                        registered_fb[con2fb_map[ops->currcon]] != info)
                return;
 
-       if (CON_IS_VISIBLE(vc)) {
+       if (con_is_visible(vc)) {
                if (blank)
                        do_blank_screen(0);
                else
@@ -3336,7 +3334,6 @@ static const struct consw fb_con = {
        .con_putcs              = fbcon_putcs,
        .con_cursor             = fbcon_cursor,
        .con_scroll             = fbcon_scroll,
-       .con_bmove              = fbcon_bmove,
        .con_switch             = fbcon_switch,
        .con_blank              = fbcon_blank,
        .con_font_set           = fbcon_set_font,
index 8edc062536a80e9e50ceb2ae063469c729b493c3..bacbb044d77cd8dbeb3d6cf0e308796287ff854d 100644 (file)
@@ -444,48 +444,11 @@ static void mdacon_clear(struct vc_data *c, int y, int x,
        }
 }
                         
-static void mdacon_bmove(struct vc_data *c, int sy, int sx, 
-                        int dy, int dx, int height, int width)
-{
-       u16 *src, *dest;
-
-       if (width <= 0 || height <= 0)
-               return;
-               
-       if (sx==0 && dx==0 && width==mda_num_columns) {
-               scr_memmovew(MDA_ADDR(0,dy), MDA_ADDR(0,sy), height*width*2);
-
-       } else if (dy < sy || (dy == sy && dx < sx)) {
-               src  = MDA_ADDR(sx, sy);
-               dest = MDA_ADDR(dx, dy);
-
-               for (; height > 0; height--) {
-                       scr_memmovew(dest, src, width*2);
-                       src  += mda_num_columns;
-                       dest += mda_num_columns;
-               }
-       } else {
-               src  = MDA_ADDR(sx, sy+height-1);
-               dest = MDA_ADDR(dx, dy+height-1);
-
-               for (; height > 0; height--) {
-                       scr_memmovew(dest, src, width*2);
-                       src  -= mda_num_columns;
-                       dest -= mda_num_columns;
-               }
-       }
-}
-
 static int mdacon_switch(struct vc_data *c)
 {
        return 1;       /* redrawing needed */
 }
 
-static int mdacon_set_palette(struct vc_data *c, const unsigned char *table)
-{
-       return -EINVAL;
-}
-
 static int mdacon_blank(struct vc_data *c, int blank, int mode_switch)
 {
        if (mda_type == TYPE_MDA) {
@@ -505,11 +468,6 @@ static int mdacon_blank(struct vc_data *c, int blank, int mode_switch)
        }
 }
 
-static int mdacon_scrolldelta(struct vc_data *c, int lines)
-{
-       return 0;
-}
-
 static void mdacon_cursor(struct vc_data *c, int mode)
 {
        if (mode == CM_ERASE) {
@@ -574,11 +532,8 @@ static const struct consw mda_con = {
        .con_putcs =            mdacon_putcs,
        .con_cursor =           mdacon_cursor,
        .con_scroll =           mdacon_scroll,
-       .con_bmove =            mdacon_bmove,
        .con_switch =           mdacon_switch,
        .con_blank =            mdacon_blank,
-       .con_set_palette =      mdacon_set_palette,
-       .con_scrolldelta =      mdacon_scrolldelta,
        .con_build_attr =       mdacon_build_attr,
        .con_invert_region =    mdacon_invert_region,
 };
index 0553dfe684ef96769ff712513e1f7733235f5833..e3b9521e4ec3e884f75ee7690b8abd4f90cc5eba 100644 (file)
@@ -574,17 +574,6 @@ static int newport_font_set(struct vc_data *vc, struct console_font *font, unsig
        return newport_set_font(vc->vc_num, font);
 }
 
-static int newport_set_palette(struct vc_data *vc, const unsigned char *table)
-{
-       return -EINVAL;
-}
-
-static int newport_scrolldelta(struct vc_data *vc, int lines)
-{
-       /* there is (nearly) no off-screen memory, so we can't scroll back */
-       return 0;
-}
-
 static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
                          int lines)
 {
@@ -684,34 +673,6 @@ static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
        return 1;
 }
 
-static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
-                         int dx, int h, int w)
-{
-       short xs, ys, xe, ye, xoffs, yoffs;
-
-       xs = sx << 3;
-       xe = ((sx + w) << 3) - 1;
-       /*
-        * as bmove is only used to move stuff around in the same line
-        * (h == 1), we don't care about wrap arounds caused by topscan != 0
-        */
-       ys = ((sy << 4) + topscan) & 0x3ff;
-       ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff;
-       xoffs = (dx - sx) << 3;
-       yoffs = (dy - sy) << 4;
-       if (xoffs > 0) {
-               /* move to the right, exchange starting points */
-               swap(xe, xs);
-       }
-       newport_wait(npregs);
-       npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
-                                NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
-                                | NPORT_DMODE0_STOPY);
-       npregs->set.xystarti = (xs << 16) | ys;
-       npregs->set.xyendi = (xe << 16) | ye;
-       npregs->go.xymove = (xoffs << 16) | yoffs;
-}
-
 static int newport_dummy(struct vc_data *c)
 {
        return 0;
@@ -729,13 +690,10 @@ const struct consw newport_con = {
        .con_putcs        = newport_putcs,
        .con_cursor       = newport_cursor,
        .con_scroll       = newport_scroll,
-       .con_bmove        = newport_bmove,
        .con_switch       = newport_switch,
        .con_blank        = newport_blank,
        .con_font_set     = newport_font_set,
        .con_font_default = newport_font_default,
-       .con_set_palette  = newport_set_palette,
-       .con_scrolldelta  = newport_scrolldelta,
        .con_set_origin   = DUMMY,
        .con_save_screen  = DUMMY
 };
index e440c2d9fe7cf51898bff9345c0dbf95881d8e6d..3a10ac19598faf8306be2954891e1b100df8cd77 100644 (file)
@@ -79,11 +79,6 @@ static const char *sticon_startup(void)
     return "STI console";
 }
 
-static int sticon_set_palette(struct vc_data *c, const unsigned char *table)
-{
-    return -EINVAL;
-}
-
 static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
 {
     int redraw_cursor = 0;
@@ -182,22 +177,6 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
     return 0;
 }
 
-static void sticon_bmove(struct vc_data *conp, int sy, int sx, 
-       int dy, int dx, int height, int width)
-{
-    if (!width || !height)
-           return;
-#if 0
-    if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
-       (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
-       ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
-       (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
-               sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/);
-#endif
-
-    sti_bmove(sticon_sti, sy, sx, dy, dx, height, width);
-}
-
 static void sticon_init(struct vc_data *c, int init)
 {
     struct sti_struct *sti = sticon_sti;
@@ -256,11 +235,6 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
     return 1;
 }
 
-static int sticon_scrolldelta(struct vc_data *conp, int lines)
-{
-    return 0;
-}
-
 static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
 {
     int line;
@@ -355,11 +329,8 @@ static const struct consw sti_con = {
        .con_putcs              = sticon_putcs,
        .con_cursor             = sticon_cursor,
        .con_scroll             = sticon_scroll,
-       .con_bmove              = sticon_bmove,
        .con_switch             = sticon_switch,
        .con_blank              = sticon_blank,
-       .con_set_palette        = sticon_set_palette,
-       .con_scrolldelta        = sticon_scrolldelta,
        .con_set_origin         = sticon_set_origin,
        .con_save_screen        = sticon_save_screen, 
        .con_build_attr         = sticon_build_attr,
index 8bf911002cbad18f9f008a0eaa125842c0002a76..11576611a974bae39a356f21ae7ed3b5d5e0a613 100644 (file)
@@ -80,7 +80,7 @@ static void vgacon_deinit(struct vc_data *c);
 static void vgacon_cursor(struct vc_data *c, int mode);
 static int vgacon_switch(struct vc_data *c);
 static int vgacon_blank(struct vc_data *c, int blank, int mode_switch);
-static int vgacon_scrolldelta(struct vc_data *c, int lines);
+static void vgacon_scrolldelta(struct vc_data *c, int lines);
 static int vgacon_set_origin(struct vc_data *c);
 static void vgacon_save_screen(struct vc_data *c);
 static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
@@ -248,18 +248,18 @@ static void vgacon_restore_screen(struct vc_data *c)
        }
 }
 
-static int vgacon_scrolldelta(struct vc_data *c, int lines)
+static void vgacon_scrolldelta(struct vc_data *c, int lines)
 {
        int start, end, count, soff;
 
        if (!lines) {
                c->vc_visible_origin = c->vc_origin;
                vga_set_mem_top(c);
-               return 1;
+               return;
        }
 
        if (!vgacon_scrollback)
-               return 1;
+               return;
 
        if (!vgacon_scrollback_save) {
                vgacon_cursor(c, CM_ERASE);
@@ -320,8 +320,6 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
                        scr_memcpyw(d, s, diff * c->vc_size_row);
        } else
                vgacon_cursor(c, CM_MOVE);
-
-       return 1;
 }
 #else
 #define vgacon_scrollback_startup(...) do { } while (0)
@@ -334,7 +332,7 @@ static void vgacon_restore_screen(struct vc_data *c)
                vgacon_scrolldelta(c, 0);
 }
 
-static int vgacon_scrolldelta(struct vc_data *c, int lines)
+static void vgacon_scrolldelta(struct vc_data *c, int lines)
 {
        if (!lines)             /* Turn scrollback off */
                c->vc_visible_origin = c->vc_origin;
@@ -362,7 +360,6 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
                c->vc_visible_origin = vga_vram_base + (p + ul) % we;
        }
        vga_set_mem_top(c);
-       return 1;
 }
 #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
 
@@ -592,7 +589,7 @@ static void vgacon_init(struct vc_data *c, int init)
 static void vgacon_deinit(struct vc_data *c)
 {
        /* When closing the active console, reset video origin */
-       if (CON_IS_VISIBLE(c)) {
+       if (con_is_visible(c)) {
                c->vc_visible_origin = vga_vram_base;
                vga_set_mem_top(c);
        }
@@ -859,16 +856,13 @@ static void vga_set_palette(struct vc_data *vc, const unsigned char *table)
        }
 }
 
-static int vgacon_set_palette(struct vc_data *vc, const unsigned char *table)
+static void vgacon_set_palette(struct vc_data *vc, const unsigned char *table)
 {
 #ifdef CAN_LOAD_PALETTE
        if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked
-           || !CON_IS_VISIBLE(vc))
-               return -EINVAL;
+           || !con_is_visible(vc))
+               return;
        vga_set_palette(vc, table);
-       return 0;
-#else
-       return -EINVAL;
 #endif
 }
 
@@ -1254,7 +1248,7 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
                struct vc_data *c = vc_cons[i].d;
 
                if (c && c->vc_sw == &vga_con) {
-                       if (CON_IS_VISIBLE(c)) {
+                       if (con_is_visible(c)) {
                                /* void size to cause regs to be rewritten */
                                cursor_size_lastfrom = 0;
                                cursor_size_lastto = 0;
@@ -1318,7 +1312,7 @@ static int vgacon_resize(struct vc_data *c, unsigned int width,
                   return success */
                return (user) ? 0 : -EINVAL;
 
-       if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
+       if (con_is_visible(c) && !vga_is_gfx) /* who knows */
                vgacon_doresize(c, width, height);
        return 0;
 }
@@ -1427,7 +1421,6 @@ const struct consw vga_con = {
        .con_putcs = DUMMY,
        .con_cursor = vgacon_cursor,
        .con_scroll = vgacon_scroll,
-       .con_bmove = DUMMY,
        .con_switch = vgacon_switch,
        .con_blank = vgacon_blank,
        .con_font_set = vgacon_font_set,
index 98c8615dc300cb843766a157deadca248364d686..d530c4627e54ef1091be820a78d3616166ca8906 100644 (file)
@@ -28,6 +28,13 @@ struct tty_struct;
 #define VT100ID "\033[?1;2c"
 #define VT102ID "\033[?6c"
 
+/**
+ * struct consw - callbacks for consoles
+ *
+ * @con_set_palette: sets the palette of the console to @table (optional)
+ * @con_scrolldelta: the contents of the console should be scrolled by @lines.
+ *                  Invoked by user. (optional)
+ */
 struct consw {
        struct module *owner;
        const char *(*con_startup)(void);
@@ -38,7 +45,6 @@ struct consw {
        void    (*con_putcs)(struct vc_data *, const unsigned short *, int, int, int);
        void    (*con_cursor)(struct vc_data *, int);
        int     (*con_scroll)(struct vc_data *, int, int, int, int);
-       void    (*con_bmove)(struct vc_data *, int, int, int, int, int, int);
        int     (*con_switch)(struct vc_data *);
        int     (*con_blank)(struct vc_data *, int, int);
        int     (*con_font_set)(struct vc_data *, struct console_font *, unsigned);
@@ -47,8 +53,9 @@ struct consw {
        int     (*con_font_copy)(struct vc_data *, int);
        int     (*con_resize)(struct vc_data *, unsigned int, unsigned int,
                               unsigned int);
-       int     (*con_set_palette)(struct vc_data *, const unsigned char *);
-       int     (*con_scrolldelta)(struct vc_data *, int);
+       void    (*con_set_palette)(struct vc_data *,
+                       const unsigned char *table);
+       void    (*con_scrolldelta)(struct vc_data *, int lines);
        int     (*con_set_origin)(struct vc_data *);
        void    (*con_save_screen)(struct vc_data *);
        u8      (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
index e329ee2667e1954298cf6c152ba37833d1cc2e0d..6fd3c908a340d234aee8ec8c8a99e0612f9c8a91 100644 (file)
@@ -21,6 +21,38 @@ struct uni_pagedir;
 
 #define NPAR 16
 
+/*
+ * Example: vc_data of a console that was scrolled 3 lines down.
+ *
+ *                              Console buffer
+ * vc_screenbuf ---------> +----------------------+-.
+ *                         | initializing W       |  \
+ *                         | initializing X       |   |
+ *                         | initializing Y       |    > scroll-back area
+ *                         | initializing Z       |   |
+ *                         |                      |  /
+ * vc_visible_origin ---> ^+----------------------+-:
+ * (changes by scroll)    || Welcome to linux     |  \
+ *                        ||                      |   |
+ *           vc_rows --->< | login: root          |   |  visible on console
+ *                        || password:            |    > (vc_screenbuf_size is
+ * vc_origin -----------> ||                      |   |   vc_size_row * vc_rows)
+ * (start when no scroll) || Last login: 12:28    |  /
+ *                        v+----------------------+-:
+ *                         | Have a lot of fun... |  \
+ * vc_pos -----------------|--------v             |   > scroll-front area
+ *                         | ~ # cat_             |  /
+ * vc_scr_end -----------> +----------------------+-:
+ * (vc_origin +            |                      |  \ EMPTY, to be filled by
+ *  vc_screenbuf_size)     |                      |  / vc_video_erase_char
+ *                         +----------------------+-'
+ *                         <---- 2 * vc_cols ----->
+ *                         <---- vc_size_row ----->
+ *
+ * Note that every character in the console buffer is accompanied with an
+ * attribute in the buffer right after the character. This is not depicted
+ * in the figure.
+ */
 struct vc_data {
        struct tty_port port;                   /* Upper level data */
 
@@ -74,7 +106,6 @@ struct vc_data {
        unsigned int    vc_decawm       : 1;    /* Autowrap Mode */
        unsigned int    vc_deccm        : 1;    /* Cursor Visible */
        unsigned int    vc_decim        : 1;    /* Insert Mode */
-       unsigned int    vc_deccolm      : 1;    /* 80/132 Column Mode */
        /* attribute flags */
        unsigned int    vc_intensity    : 2;    /* 0=half-bright, 1=normal, 2=bold */
        unsigned int    vc_italic:1;
@@ -136,6 +167,9 @@ extern void vc_SAK(struct work_struct *work);
 
 #define CUR_DEFAULT CUR_UNDERLINE
 
-#define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp)
+static inline bool con_is_visible(const struct vc_data *vc)
+{
+       return *vc->vc_display_fg == vc;
+}
 
 #endif /* _LINUX_CONSOLE_STRUCT_H */
index 79df69dc629cd61a918ffe185f2fccf9e56ea393..aaff68efba5dab20f33dfcbb102469e4f564cc33 100644 (file)
@@ -39,14 +39,22 @@ struct hsu_dma_chip {
 
 #if IS_ENABLED(CONFIG_HSU_DMA)
 /* Export to the internal users */
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr);
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+                      u32 *status);
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+                          u32 status);
 
 /* Export to the platform drivers */
 int hsu_dma_probe(struct hsu_dma_chip *chip);
 int hsu_dma_remove(struct hsu_dma_chip *chip);
 #else
-static inline irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip,
-                                     unsigned short nr)
+static inline int hsu_dma_get_status(struct hsu_dma_chip *chip,
+                                    unsigned short nr, u32 *status)
+{
+       return 0;
+}
+static inline irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip,
+                                        unsigned short nr, u32 status)
 {
        return IRQ_NONE;
 }
index 48ec7651989b093fc015e44b59657c7000e11012..923266cd294a33c8d98cbe274df0991f6647dafa 100644 (file)
@@ -111,6 +111,7 @@ struct uart_8250_port {
                                                 *   if no_console_suspend
                                                 */
        unsigned char           probe;
+       struct mctrl_gpios      *gpios;
 #define UART_PROBE_RSA (1 << 0)
 
        /*
index a3d7c0d4a03e75016023184a5fea18c91d9d8dbc..2f44e20136545162d15ee9a39c2eae38352580d1 100644 (file)
@@ -352,9 +352,15 @@ struct earlycon_id {
 extern const struct earlycon_id __earlycon_table[];
 extern const struct earlycon_id __earlycon_table_end[];
 
+#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
+#define EARLYCON_USED_OR_UNUSED        __used
+#else
+#define EARLYCON_USED_OR_UNUSED        __maybe_unused
+#endif
+
 #define OF_EARLYCON_DECLARE(_name, compat, fn)                         \
        static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
-            __used __section(__earlycon_table)                         \
+            EARLYCON_USED_OR_UNUSED __section(__earlycon_table)        \
                = { .name = __stringify(_name),                         \
                    .compatible = compat,                               \
                    .setup = fn  }
index 8d7634247fb4e884b65b1236a858ac8cd62477f0..6abd24f258bc1100e97f989714903c404ea75c42 100644 (file)
@@ -45,7 +45,7 @@ void poke_blanked_console(void);
 int con_font_op(struct vc_data *vc, struct console_font_op *op);
 int con_set_cmap(unsigned char __user *cmap);
 int con_get_cmap(unsigned char __user *cmap);
-void scrollback(struct vc_data *vc, int lines);
+void scrollback(struct vc_data *vc);
 void scrollfront(struct vc_data *vc, int lines);
 void clear_buffer_attributes(struct vc_data *vc);
 void update_region(struct vc_data *vc, unsigned long start, int count);
@@ -59,14 +59,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg);
 #ifdef CONFIG_CONSOLE_TRANSLATIONS
 /* consolemap.c */
 
-struct unimapinit;
 struct unipair;
 
 int con_set_trans_old(unsigned char __user * table);
 int con_get_trans_old(unsigned char __user * table);
 int con_set_trans_new(unsigned short __user * table);
 int con_get_trans_new(unsigned short __user * table);
-int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui);
+int con_clear_unimap(struct vc_data *vc);
 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list);
 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list);
 int con_set_default_unimap(struct vc_data *vc);
@@ -92,7 +91,7 @@ static inline int con_get_trans_new(unsigned short __user *table)
 {
        return -EINVAL;
 }
-static inline int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
+static inline int con_clear_unimap(struct vc_data *vc)
 {
        return 0;
 }
index d4fdf8f7b47179b39e475dca9833ee6a6c25c4ca..8f5678cb62635cc5c76bba711091929d6054939e 100644 (file)
@@ -246,9 +246,6 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
 {
        struct serial_struct info;
 
-       if (!retinfo)
-               return -EFAULT;
-
        memset(&info, 0, sizeof(info));
        info.line = self->line;
        info.flags = self->port.flags;
@@ -258,11 +255,6 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
 
        /* For compatibility  */
        info.type = PORT_16550A;
-       info.port = 0;
-       info.irq = 0;
-       info.xmit_fifo_size = 0;
-       info.hub6 = 0;
-       info.custom_divisor = 0;
 
        if (copy_to_user(retinfo, &info, sizeof(*retinfo)))
                return -EFAULT;
This page took 0.130814 seconds and 5 git commands to generate.