[PATCH] MIPS: loongson: fix random early boot hang

2013-02-18 Thread Aaro Koskinen
Some Loongson boards (e.g. Lemote FuLoong mini-PC) use ISA/southbridge
device (CS5536 general purpose timer) for the timer interrupt. It starts
running early and is already enabled during the PCI configuration,
during which there is a small window in pci_read_base() when the register
access is temporarily disabled. If the timer interrupts at this point,
the system will hang. Fix this by adding a fixup that keeps the register
access always enabled.

The hang the patch fixes usually looks like this:

[0.844000] pci :00:0e.0: [1022:2090] type 00 class 0x060100
[0.848000] pci :00:0e.0: reg 10: [io  0xb410-0xb417]
[0.852000] pci :00:0e.0: reg 14: [io  0xb000-0xb0ff]
[0.856000] pci :00:0e.0: reg 18: [io  0xb380-0xb3bf]
[   28.14] BUG: soft lockup - CPU#0 stuck for 23s! [swapper:1]
[   28.14] Modules linked in:
[   28.14] irq event stamp: 37965
[   28.14] hardirqs last  enabled at (37964): [] 
restore_partial+0x6c/0x13c
[   28.14] hardirqs last disabled at (37965): [] 
handle_int+0x144/0x15c
[   28.14] softirqs last  enabled at (24316): [] 
__do_softirq+0x1cc/0x258
[   28.14] softirqs last disabled at (24327): [] 
do_softirq+0xc8/0xd0
[   28.14] Cpu 0
[   28.14] $ 0   :  140044e1 98009f09 
0001
[   28.14] $ 4   : 98009f09  0100 
03b7fff87fbde011
[   28.14] $ 8   : 812b1928 0001e000 04387fbde011 
fff87fbde011
[   28.14] $12   : 000e 807a 0698 

[   28.14] $16   : 0002 81055e20 80786810 

[   28.14] $20   : 000a 807bc244 807e6350 
8077
[   28.14] $24   : 0d80 fffedbe0
[   28.14] $28   : 98009f07c000 98009f07fa10 8105 
802380f8
[   28.14] Hi: 00d0fc00
[   28.14] Lo: 00f82b40
[   28.14] epc   : 8023810c __do_softirq+0xe4/0x258
[   28.14] Not tainted
[   28.14] ra: 802380f8 __do_softirq+0xd0/0x258
[   28.14] Status: 140044e3KX SX UX KERNEL EXL IE
[   28.14] Cause : 10008400
[   28.14] PrId  : 6303 (ICT Loongson-2)

Signed-off-by: Aaro Koskinen 
---
 arch/mips/loongson/common/cs5536/cs5536_isa.c |   14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c 
b/arch/mips/loongson/common/cs5536/cs5536_isa.c
index 4d9f65a..7b31ea7 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_isa.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c
@@ -13,6 +13,7 @@
  * option) any later version.
  */
 
+#include 
 #include 
 #include 
 
@@ -314,3 +315,16 @@ u32 pci_isa_read_reg(int reg)
 
return conf_data;
 }
+
+/*
+ * The mfgpt timer interrupt is running early, so we must keep the south bridge
+ * mmio always enabled. Otherwise we may race with the PCI configuration which
+ * may temporarily disable it. When that happens and the timer interrupt fires,
+ * we are not able to clear it and the system will hang.
+ */
+static void cs5536_isa_mmio_always_on(struct pci_dev *dev)
+{
+   dev->mmio_always_on = 1;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+   PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MIPS: loongson: fix random early boot hang

2013-02-18 Thread Aaro Koskinen
Some Loongson boards (e.g. Lemote FuLoong mini-PC) use ISA/southbridge
device (CS5536 general purpose timer) for the timer interrupt. It starts
running early and is already enabled during the PCI configuration,
during which there is a small window in pci_read_base() when the register
access is temporarily disabled. If the timer interrupts at this point,
the system will hang. Fix this by adding a fixup that keeps the register
access always enabled.

The hang the patch fixes usually looks like this:

[0.844000] pci :00:0e.0: [1022:2090] type 00 class 0x060100
[0.848000] pci :00:0e.0: reg 10: [io  0xb410-0xb417]
[0.852000] pci :00:0e.0: reg 14: [io  0xb000-0xb0ff]
[0.856000] pci :00:0e.0: reg 18: [io  0xb380-0xb3bf]
[   28.14] BUG: soft lockup - CPU#0 stuck for 23s! [swapper:1]
[   28.14] Modules linked in:
[   28.14] irq event stamp: 37965
[   28.14] hardirqs last  enabled at (37964): [80204c0c] 
restore_partial+0x6c/0x13c
[   28.14] hardirqs last disabled at (37965): [80204f8c] 
handle_int+0x144/0x15c
[   28.14] softirqs last  enabled at (24316): [802381f4] 
__do_softirq+0x1cc/0x258
[   28.14] softirqs last disabled at (24327): [80238420] 
do_softirq+0xc8/0xd0
[   28.14] Cpu 0
[   28.14] $ 0   :  140044e1 98009f09 
0001
[   28.14] $ 4   : 98009f09  0100 
03b7fff87fbde011
[   28.14] $ 8   : 812b1928 0001e000 04387fbde011 
fff87fbde011
[   28.14] $12   : 000e 807a 0698 

[   28.14] $16   : 0002 81055e20 80786810 

[   28.14] $20   : 000a 807bc244 807e6350 
8077
[   28.14] $24   : 0d80 fffedbe0
[   28.14] $28   : 98009f07c000 98009f07fa10 8105 
802380f8
[   28.14] Hi: 00d0fc00
[   28.14] Lo: 00f82b40
[   28.14] epc   : 8023810c __do_softirq+0xe4/0x258
[   28.14] Not tainted
[   28.14] ra: 802380f8 __do_softirq+0xd0/0x258
[   28.14] Status: 140044e3KX SX UX KERNEL EXL IE
[   28.14] Cause : 10008400
[   28.14] PrId  : 6303 (ICT Loongson-2)

Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi
---
 arch/mips/loongson/common/cs5536/cs5536_isa.c |   14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c 
b/arch/mips/loongson/common/cs5536/cs5536_isa.c
index 4d9f65a..7b31ea7 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_isa.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c
@@ -13,6 +13,7 @@
  * option) any later version.
  */
 
+#include linux/pci.h
 #include cs5536/cs5536.h
 #include cs5536/cs5536_pci.h
 
@@ -314,3 +315,16 @@ u32 pci_isa_read_reg(int reg)
 
return conf_data;
 }
+
+/*
+ * The mfgpt timer interrupt is running early, so we must keep the south bridge
+ * mmio always enabled. Otherwise we may race with the PCI configuration which
+ * may temporarily disable it. When that happens and the timer interrupt fires,
+ * we are not able to clear it and the system will hang.
+ */
+static void cs5536_isa_mmio_always_on(struct pci_dev *dev)
+{
+   dev-mmio_always_on = 1;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+   PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/