Comment 2 for bug 280821

Revision history for this message
Leann Ogasawara (leannogasawara) wrote :

Hi pbeeson,

Thanks for the report. I'll go ahead and open a Hardy nomination. I'm also including the git commit id's whose final patch result is what you have attached:

commit 768aec0b5bccbd460bcf6e9131f19b5a26f3862d
Author: Anton Vorontsov <email address hidden>

    serial: 8250: fix shared interrupts issues with SMP and RT kernels

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index ce948b6..27f34a9 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1874,7 +1874,9 @@ static int serial8250_startup(struct uart_port *port)
                 * the interrupt is enabled. Delays are necessary to
                 * allow register changes to become visible.
                 */
- spin_lock_irqsave(&up->port.lock, flags);
+ spin_lock(&up->port.lock);
+ if (up->port.flags & UPF_SHARE_IRQ)
+ disable_irq_nosync(up->port.irq);

                wait_for_xmitr(up, UART_LSR_THRE);
                serial_out_sync(up, UART_IER, UART_IER_THRI);
@@ -1886,7 +1888,9 @@ static int serial8250_startup(struct uart_port *port)
                iir = serial_in(up, UART_IIR);
                serial_out(up, UART_IER, 0);

- spin_unlock_irqrestore(&up->port.lock, flags);
+ if (up->port.flags & UPF_SHARE_IRQ)
+ enable_irq(up->port.irq);
+ spin_unlock(&up->port.lock);

                /*
                 * If the interrupt is not reasserted, setup a timer to

commit c389d27b5e643d745f55ffb939b1426060ba63d4
Author: Borislav Petkov <email address hidden>

    8250.c: port.lock is irq-safe

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index a97f1ae..342e12f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1885,7 +1885,7 @@ static int serial8250_startup(struct uart_port *port)
                 * the interrupt is enabled. Delays are necessary to
                 * allow register changes to become visible.
                 */
- spin_lock(&up->port.lock);
+ spin_lock_irqsave(&up->port.lock, flags);
                if (up->port.flags & UPF_SHARE_IRQ)
                        disable_irq_nosync(up->port.irq);

@@ -1901,7 +1901,7 @@ static int serial8250_startup(struct uart_port *port)

                if (up->port.flags & UPF_SHARE_IRQ)
                        enable_irq(up->port.irq);
- spin_unlock(&up->port.lock);
+ spin_unlock_irqrestore(&up->port.lock, flags);

                /*
                 * If the interrupt is not reasserted, setup a timer to