summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>2010-08-09 11:27:14 +0000
committerkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>2010-08-09 11:27:14 +0000
commit6544569ed84b9bac668cb0e99436232aea49472d (patch)
tree90cfb11c00ba5ca879799523580f25bad8afa28f
parent5ae37573d1654ac495fd217144b4bd298dfebe61 (diff)
[cns3xxx]: workaround serial hang with SMP enabled
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22557 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--target/linux/cns3xxx/patches-2.6.31/210-cns3xxx_smp_serial_fix.patch39
1 files changed, 39 insertions, 0 deletions
diff --git a/target/linux/cns3xxx/patches-2.6.31/210-cns3xxx_smp_serial_fix.patch b/target/linux/cns3xxx/patches-2.6.31/210-cns3xxx_smp_serial_fix.patch
new file mode 100644
index 0000000000..a9b45aefe5
--- /dev/null
+++ b/target/linux/cns3xxx/patches-2.6.31/210-cns3xxx_smp_serial_fix.patch
@@ -0,0 +1,39 @@
+--- a/drivers/serial/8250.c
++++ b/drivers/serial/8250.c
+@@ -1743,6 +1743,7 @@ static void serial8250_backup_timeout(un
+ unsigned int iir, ier = 0, lsr;
+ unsigned long flags;
+
++ spin_lock_irqsave(&up->port.lock, flags);
+ /*
+ * Must disable interrupts or else we risk racing with the interrupt
+ * based handler.
+@@ -1760,10 +1761,8 @@ static void serial8250_backup_timeout(un
+ * the "Diva" UART used on the management processor on many HP
+ * ia64 and parisc boxes.
+ */
+- spin_lock_irqsave(&up->port.lock, flags);
+ lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+- spin_unlock_irqrestore(&up->port.lock, flags);
+ if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
+ (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
+ (lsr & UART_LSR_THRE)) {
+@@ -1771,12 +1770,14 @@ static void serial8250_backup_timeout(un
+ iir |= UART_IIR_THRI;
+ }
+
+- if (!(iir & UART_IIR_NO_INT))
+- serial8250_handle_port(up);
+-
+ if (is_real_interrupt(up->port.irq))
+ serial_out(up, UART_IER, ier);
+
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ if (!(iir & UART_IIR_NO_INT))
++ serial8250_handle_port(up);
++
+ /* Standard timer interval plus 0.2s to keep the port running */
+ mod_timer(&up->timer,
+ jiffies + poll_timeout(up->port.timeout) + HZ / 5);