diff options
-rw-r--r-- | drivers/tty/serial/8250.c | 39 | ||||
-rw-r--r-- | include/linux/serial_8250.h | 2 |
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 | ||
512 | static int serial8250_default_handle_irq(struct uart_port *port); | ||
513 | |||
512 | static void set_io_from_upio(struct uart_port *p) | 514 | static 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 | ||
562 | static void | 565 | static 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 | ||
1627 | int 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 | |||
1640 | static 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); |
81 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, | 82 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, |
82 | unsigned int oldstate); | 83 | unsigned int oldstate); |
84 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir); | ||
83 | 85 | ||
84 | extern void serial8250_set_isa_configurator(void (*v) | 86 | extern void serial8250_set_isa_configurator(void (*v) |
85 | (int port, struct uart_port *up, | 87 | (int port, struct uart_port *up, |