aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/8250.c39
-rw-r--r--include/linux/serial_8250.h2
2 files changed, 37 insertions, 4 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index f2dfec82faf8..833e011a426f 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -509,6 +509,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
509 outb(value, p->iobase + offset); 509 outb(value, p->iobase + offset);
510} 510}
511 511
512static int serial8250_default_handle_irq(struct uart_port *port);
513
512static void set_io_from_upio(struct uart_port *p) 514static void set_io_from_upio(struct uart_port *p)
513{ 515{
514 struct uart_8250_port *up = 516 struct uart_8250_port *up =
@@ -557,6 +559,7 @@ static void set_io_from_upio(struct uart_port *p)
557 } 559 }
558 /* Remember loaded iotype */ 560 /* Remember loaded iotype */
559 up->cur_iotype = p->iotype; 561 up->cur_iotype = p->iotype;
562 p->handle_irq = serial8250_default_handle_irq;
560} 563}
561 564
562static void 565static void
@@ -1621,6 +1624,28 @@ static void serial8250_handle_port(struct uart_8250_port *up)
1621 spin_unlock_irqrestore(&up->port.lock, flags); 1624 spin_unlock_irqrestore(&up->port.lock, flags);
1622} 1625}
1623 1626
1627int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
1628{
1629 struct uart_8250_port *up =
1630 container_of(port, struct uart_8250_port, port);
1631
1632 if (!(iir & UART_IIR_NO_INT)) {
1633 serial8250_handle_port(up);
1634 return 1;
1635 }
1636
1637 return 0;
1638}
1639
1640static int serial8250_default_handle_irq(struct uart_port *port)
1641{
1642 struct uart_8250_port *up =
1643 container_of(port, struct uart_8250_port, port);
1644 unsigned int iir = serial_in(up, UART_IIR);
1645
1646 return serial8250_handle_irq(port, iir);
1647}
1648
1624/* 1649/*
1625 * This is the serial driver's interrupt routine. 1650 * This is the serial driver's interrupt routine.
1626 * 1651 *
@@ -1648,13 +1673,12 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
1648 l = i->head; 1673 l = i->head;
1649 do { 1674 do {
1650 struct uart_8250_port *up; 1675 struct uart_8250_port *up;
1651 unsigned int iir; 1676 struct uart_port *port;
1652 1677
1653 up = list_entry(l, struct uart_8250_port, list); 1678 up = list_entry(l, struct uart_8250_port, list);
1679 port = &up->port;
1654 1680
1655 iir = serial_in(up, UART_IIR); 1681 if (port->handle_irq(port)) {
1656 if (!(iir & UART_IIR_NO_INT)) {
1657 serial8250_handle_port(up);
1658 1682
1659 handled = 1; 1683 handled = 1;
1660 1684
@@ -3048,6 +3072,10 @@ int __init early_serial_setup(struct uart_port *port)
3048 p->serial_in = port->serial_in; 3072 p->serial_in = port->serial_in;
3049 if (port->serial_out) 3073 if (port->serial_out)
3050 p->serial_out = port->serial_out; 3074 p->serial_out = port->serial_out;
3075 if (port->handle_irq)
3076 p->handle_irq = port->handle_irq;
3077 else
3078 p->handle_irq = serial8250_default_handle_irq;
3051 3079
3052 return 0; 3080 return 0;
3053} 3081}
@@ -3116,6 +3144,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
3116 port.type = p->type; 3144 port.type = p->type;
3117 port.serial_in = p->serial_in; 3145 port.serial_in = p->serial_in;
3118 port.serial_out = p->serial_out; 3146 port.serial_out = p->serial_out;
3147 port.handle_irq = p->handle_irq;
3119 port.set_termios = p->set_termios; 3148 port.set_termios = p->set_termios;
3120 port.pm = p->pm; 3149 port.pm = p->pm;
3121 port.dev = &dev->dev; 3150 port.dev = &dev->dev;
@@ -3281,6 +3310,8 @@ int serial8250_register_port(struct uart_port *port)
3281 uart->port.serial_in = port->serial_in; 3310 uart->port.serial_in = port->serial_in;
3282 if (port->serial_out) 3311 if (port->serial_out)
3283 uart->port.serial_out = port->serial_out; 3312 uart->port.serial_out = port->serial_out;
3313 if (port->handle_irq)
3314 uart->port.handle_irq = port->handle_irq;
3284 /* Possibly override set_termios call */ 3315 /* Possibly override set_termios call */
3285 if (port->set_termios) 3316 if (port->set_termios)
3286 uart->port.set_termios = port->set_termios; 3317 uart->port.set_termios = port->set_termios;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 97f5b45bbc07..1f05bbeac01e 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -35,6 +35,7 @@ struct plat_serial8250_port {
35 void (*set_termios)(struct uart_port *, 35 void (*set_termios)(struct uart_port *,
36 struct ktermios *new, 36 struct ktermios *new,
37 struct ktermios *old); 37 struct ktermios *old);
38 int (*handle_irq)(struct uart_port *);
38 void (*pm)(struct uart_port *, unsigned int state, 39 void (*pm)(struct uart_port *, unsigned int state,
39 unsigned old); 40 unsigned old);
40}; 41};
@@ -80,6 +81,7 @@ extern void serial8250_do_set_termios(struct uart_port *port,
80 struct ktermios *termios, struct ktermios *old); 81 struct ktermios *termios, struct ktermios *old);
81extern void serial8250_do_pm(struct uart_port *port, unsigned int state, 82extern void serial8250_do_pm(struct uart_port *port, unsigned int state,
82 unsigned int oldstate); 83 unsigned int oldstate);
84int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
83 85
84extern void serial8250_set_isa_configurator(void (*v) 86extern void serial8250_set_isa_configurator(void (*v)
85 (int port, struct uart_port *up, 87 (int port, struct uart_port *up,