serial: 8250: add IRQ trigger support
Vikram Pandita [Sat, 19 Sep 2009 20:13:19 +0000 (13:13 -0700)]
There is currently no provision for passing IRQ trigger flags for
serial IRQs with triggering requirements (such as GPIO IRQs)

This patch adds irqflags to plat_serial8250_port that can be passed
from board file to reqest_irq() of 8250 driver

Changes are backward compatible with boards passing UPF_SHARE_IRQ flag

Tested on Zoom2 board that has IRQF_TRIGGER_RISING requirement for 8250 irq

[Moved new flag to end to fix bugs in the original with the old_serial array
-- Alan]

Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

drivers/serial/8250.c
drivers/serial/8250.h
include/linux/serial_8250.h
include/linux/serial_core.h

index fb867a9..83168a6 100644 (file)
@@ -1677,7 +1677,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
                INIT_LIST_HEAD(&up->list);
                i->head = &up->list;
                spin_unlock_irq(&i->lock);
-
+               irq_flags |= up->port.irqflags;
                ret = request_irq(up->port.irq, serial8250_interrupt,
                                  irq_flags, "serial", i);
                if (ret < 0)
@@ -2026,7 +2026,7 @@ static int serial8250_startup(struct uart_port *port)
                 * allow register changes to become visible.
                 */
                spin_lock_irqsave(&up->port.lock, flags);
-               if (up->port.flags & UPF_SHARE_IRQ)
+               if (up->port.irqflags & IRQF_SHARED)
                        disable_irq_nosync(up->port.irq);
 
                wait_for_xmitr(up, UART_LSR_THRE);
@@ -2039,7 +2039,7 @@ static int serial8250_startup(struct uart_port *port)
                iir = serial_in(up, UART_IIR);
                serial_out(up, UART_IER, 0);
 
-               if (up->port.flags & UPF_SHARE_IRQ)
+               if (up->port.irqflags & IRQF_SHARED)
                        enable_irq(up->port.irq);
                spin_unlock_irqrestore(&up->port.lock, flags);
 
@@ -2671,6 +2671,7 @@ static void __init serial8250_isa_init_ports(void)
             i++, up++) {
                up->port.iobase   = old_serial_port[i].port;
                up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
+               up->port.irqflags = old_serial_port[i].irqflags;
                up->port.uartclk  = old_serial_port[i].baud_base * 16;
                up->port.flags    = old_serial_port[i].flags;
                up->port.hub6     = old_serial_port[i].hub6;
@@ -2679,7 +2680,7 @@ static void __init serial8250_isa_init_ports(void)
                up->port.regshift = old_serial_port[i].iomem_reg_shift;
                set_io_from_upio(&up->port);
                if (share_irqs)
-                       up->port.flags |= UPF_SHARE_IRQ;
+                       up->port.irqflags |= IRQF_SHARED;
        }
 }
 
@@ -2869,6 +2870,7 @@ int __init early_serial_setup(struct uart_port *port)
        p->iobase       = port->iobase;
        p->membase      = port->membase;
        p->irq          = port->irq;
+       p->irqflags     = port->irqflags;
        p->uartclk      = port->uartclk;
        p->fifosize     = port->fifosize;
        p->regshift     = port->regshift;
@@ -2942,6 +2944,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
                port.iobase             = p->iobase;
                port.membase            = p->membase;
                port.irq                = p->irq;
+               port.irqflags           = p->irqflags;
                port.uartclk            = p->uartclk;
                port.regshift           = p->regshift;
                port.iotype             = p->iotype;
@@ -2954,7 +2957,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
                port.serial_out         = p->serial_out;
                port.dev                = &dev->dev;
                if (share_irqs)
-                       port.flags |= UPF_SHARE_IRQ;
+                       port.irqflags |= IRQF_SHARED;
                ret = serial8250_register_port(&port);
                if (ret < 0) {
                        dev_err(&dev->dev, "unable to register port at index %d "
@@ -3096,6 +3099,7 @@ int serial8250_register_port(struct uart_port *port)
                uart->port.iobase       = port->iobase;
                uart->port.membase      = port->membase;
                uart->port.irq          = port->irq;
+               uart->port.irqflags     = port->irqflags;
                uart->port.uartclk      = port->uartclk;
                uart->port.fifosize     = port->fifosize;
                uart->port.regshift     = port->regshift;
index 5202603..6e19ea3 100644 (file)
@@ -25,6 +25,7 @@ struct old_serial_port {
        unsigned char io_type;
        unsigned char *iomem_base;
        unsigned short iomem_reg_shift;
+       unsigned long irqflags;
 };
 
 /*
index d4d2a78..fb46aba 100644 (file)
@@ -22,6 +22,7 @@ struct plat_serial8250_port {
        void __iomem    *membase;       /* ioremap cookie or NULL */
        resource_size_t mapbase;        /* resource base */
        unsigned int    irq;            /* interrupt number */
+       unsigned long   irqflags;       /* request_irq flags */
        unsigned int    uartclk;        /* UART clock rate */
        void            *private_data;
        unsigned char   regshift;       /* register shift */
index 23d2fb0..3cd255f 100644 (file)
@@ -265,6 +265,7 @@ struct uart_port {
        unsigned int            (*serial_in)(struct uart_port *, int);
        void                    (*serial_out)(struct uart_port *, int, int);
        unsigned int            irq;                    /* irq number */
+       unsigned long           irqflags;               /* irq flags  */
        unsigned int            uartclk;                /* base uart clock */
        unsigned int            fifosize;               /* tx fifo size */
        unsigned char           x_char;                 /* xon/xoff char */