aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-07-25 10:01:35 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-07-30 16:54:38 -0400
commit455cc256eb23915100e203fb33ee143afd127954 (patch)
tree1ad0c410fef0f7d82587347c3d3e4d4c9646dcee
parent07517529225ae4ce770271f83d8cd1004733a01d (diff)
[MIPS] TXx9: PCI error handling
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Date: Thu, 24 Jul 2008 00:25:16 +0900 Subject: [PATCH] txx9: PCI error handling Add more control and detailed report on PCI error interrupt. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/pci/ops-tx3927.c34
-rw-r--r--arch/mips/pci/ops-tx4927.c62
-rw-r--r--arch/mips/pci/pci-tx4927.c10
-rw-r--r--arch/mips/pci/pci-tx4938.c10
-rw-r--r--arch/mips/txx9/jmr3927/irq.c20
-rw-r--r--arch/mips/txx9/jmr3927/setup.c1
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c2
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c1
-rw-r--r--include/asm-mips/txx9/tx3927.h7
-rw-r--r--include/asm-mips/txx9/tx4927.h1
-rw-r--r--include/asm-mips/txx9/tx4927pcic.h3
-rw-r--r--include/asm-mips/txx9/tx4938.h1
12 files changed, 132 insertions, 20 deletions
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
index c6bd79e71e26..31c150196595 100644
--- a/arch/mips/pci/ops-tx3927.c
+++ b/arch/mips/pci/ops-tx3927.c
@@ -37,8 +37,11 @@
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/interrupt.h>
40 41
41#include <asm/addrspace.h> 42#include <asm/addrspace.h>
43#include <asm/txx9irq.h>
44#include <asm/txx9/pci.h>
42#include <asm/txx9/tx3927.h> 45#include <asm/txx9/tx3927.h>
43 46
44static int mkaddr(struct pci_bus *bus, unsigned char devfn, unsigned char where) 47static int mkaddr(struct pci_bus *bus, unsigned char devfn, unsigned char where)
@@ -194,3 +197,34 @@ void __init tx3927_pcic_setup(struct pci_controller *channel,
194 PCI_COMMAND_PARITY | PCI_COMMAND_SERR; 197 PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
195 local_irq_restore(flags); 198 local_irq_restore(flags);
196} 199}
200
201static irqreturn_t tx3927_pcierr_interrupt(int irq, void *dev_id)
202{
203 struct pt_regs *regs = get_irq_regs();
204
205 if (txx9_pci_err_action != TXX9_PCI_ERR_IGNORE) {
206 printk(KERN_WARNING "PCI error interrupt at 0x%08lx.\n",
207 regs->cp0_epc);
208 printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
209 tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
210 }
211 if (txx9_pci_err_action != TXX9_PCI_ERR_PANIC) {
212 /* clear all pci errors */
213 tx3927_pcicptr->pcistat |= TX3927_PCIC_PCISTATIM_ALL;
214 tx3927_pcicptr->istat = TX3927_PCIC_IIM_ALL;
215 tx3927_pcicptr->tstat = TX3927_PCIC_TIM_ALL;
216 tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
217 return IRQ_HANDLED;
218 }
219 console_verbose();
220 panic("PCI error.");
221}
222
223void __init tx3927_setup_pcierr_irq(void)
224{
225 if (request_irq(TXX9_IRQ_BASE + TX3927_IR_PCI,
226 tx3927_pcierr_interrupt,
227 IRQF_DISABLED, "PCI error",
228 (void *)TX3927_PCIC_REG))
229 printk(KERN_WARNING "Failed to request irq for PCIERR\n");
230}
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
index 038e311b069d..5989e747527f 100644
--- a/arch/mips/pci/ops-tx4927.c
+++ b/arch/mips/pci/ops-tx4927.c
@@ -16,6 +16,8 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/interrupt.h>
20#include <asm/txx9/pci.h>
19#include <asm/txx9/tx4927pcic.h> 21#include <asm/txx9/tx4927pcic.h>
20 22
21static struct { 23static struct {
@@ -431,6 +433,66 @@ void tx4927_report_pcic_status(void)
431 } 433 }
432} 434}
433 435
436static void tx4927_dump_pcic_settings1(struct tx4927_pcic_reg __iomem *pcicptr)
437{
438 int i;
439 __u32 __iomem *preg = (__u32 __iomem *)pcicptr;
440
441 printk(KERN_INFO "tx4927 pcic (0x%p) settings:", pcicptr);
442 for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4, preg++) {
443 if (i % 32 == 0) {
444 printk(KERN_CONT "\n");
445 printk(KERN_INFO "%04x:", i);
446 }
447 /* skip registers with side-effects */
448 if (i == offsetof(struct tx4927_pcic_reg, g2pintack)
449 || i == offsetof(struct tx4927_pcic_reg, g2pspc)
450 || i == offsetof(struct tx4927_pcic_reg, g2pcfgadrs)
451 || i == offsetof(struct tx4927_pcic_reg, g2pcfgdata)) {
452 printk(KERN_CONT " XXXXXXXX");
453 continue;
454 }
455 printk(KERN_CONT " %08x", __raw_readl(preg));
456 }
457 printk(KERN_CONT "\n");
458}
459
460void tx4927_dump_pcic_settings(void)
461{
462 int i;
463
464 for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) {
465 if (pcicptrs[i].pcicptr)
466 tx4927_dump_pcic_settings1(pcicptrs[i].pcicptr);
467 }
468}
469
470irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id)
471{
472 struct pt_regs *regs = get_irq_regs();
473 struct tx4927_pcic_reg __iomem *pcicptr =
474 (struct tx4927_pcic_reg __iomem *)(unsigned long)dev_id;
475
476 if (txx9_pci_err_action != TXX9_PCI_ERR_IGNORE) {
477 printk(KERN_WARNING "PCIERR interrupt at 0x%0*lx\n",
478 (int)(2 * sizeof(unsigned long)), regs->cp0_epc);
479 tx4927_report_pcic_status1(pcicptr);
480 }
481 if (txx9_pci_err_action != TXX9_PCI_ERR_PANIC) {
482 /* clear all pci errors */
483 __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
484 | (TX4927_PCIC_PCISTATUS_ALL << 16),
485 &pcicptr->pcistatus);
486 __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pstatus);
487 __raw_writel(TX4927_PCIC_PBASTATUS_ALL, &pcicptr->pbastatus);
488 __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicstatus);
489 return IRQ_HANDLED;
490 }
491 console_verbose();
492 tx4927_dump_pcic_settings1(pcicptr);
493 panic("PCI error.");
494}
495
434#ifdef CONFIG_TOSHIBA_FPCIB0 496#ifdef CONFIG_TOSHIBA_FPCIB0
435static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) 497static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev)
436{ 498{
diff --git a/arch/mips/pci/pci-tx4927.c b/arch/mips/pci/pci-tx4927.c
index 27e86a09dd41..aaa900596792 100644
--- a/arch/mips/pci/pci-tx4927.c
+++ b/arch/mips/pci/pci-tx4927.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/interrupt.h>
18#include <asm/txx9/generic.h> 19#include <asm/txx9/generic.h>
19#include <asm/txx9/tx4927.h> 20#include <asm/txx9/tx4927.h>
20 21
@@ -81,3 +82,12 @@ int __init tx4927_pciclk66_setup(void)
81 pciclk = -1; 82 pciclk = -1;
82 return pciclk; 83 return pciclk;
83} 84}
85
86void __init tx4927_setup_pcierr_irq(void)
87{
88 if (request_irq(TXX9_IRQ_BASE + TX4927_IR_PCIERR,
89 tx4927_pcierr_interrupt,
90 IRQF_DISABLED, "PCI error",
91 (void *)TX4927_PCIC_REG))
92 printk(KERN_WARNING "Failed to request irq for PCIERR\n");
93}
diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c
index e5375511c2b7..60e2c52c2c5e 100644
--- a/arch/mips/pci/pci-tx4938.c
+++ b/arch/mips/pci/pci-tx4938.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/interrupt.h>
18#include <asm/txx9/generic.h> 19#include <asm/txx9/generic.h>
19#include <asm/txx9/tx4938.h> 20#include <asm/txx9/tx4938.h>
20 21
@@ -132,3 +133,12 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
132 } 133 }
133 return -1; 134 return -1;
134} 135}
136
137void __init tx4938_setup_pcierr_irq(void)
138{
139 if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR,
140 tx4927_pcierr_interrupt,
141 IRQF_DISABLED, "PCI error",
142 (void *)TX4927_PCIC_REG))
143 printk(KERN_WARNING "Failed to request irq for PCIERR\n");
144}
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
index 070c9a115e57..f3b60233e99d 100644
--- a/arch/mips/txx9/jmr3927/irq.c
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -103,22 +103,6 @@ static int jmr3927_irq_dispatch(int pending)
103 return irq; 103 return irq;
104} 104}
105 105
106#ifdef CONFIG_PCI
107static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id)
108{
109 printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
110 printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
111 tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
112
113 return IRQ_HANDLED;
114}
115static struct irqaction pcierr_action = {
116 .handler = jmr3927_pcierr_interrupt,
117 .mask = CPU_MASK_NONE,
118 .name = "PCI error",
119};
120#endif
121
122static void __init jmr3927_irq_init(void); 106static void __init jmr3927_irq_init(void);
123 107
124void __init jmr3927_irq_setup(void) 108void __init jmr3927_irq_setup(void)
@@ -143,10 +127,6 @@ void __init jmr3927_irq_setup(void)
143 /* setup IOC interrupt 1 (PCI, MODEM) */ 127 /* setup IOC interrupt 1 (PCI, MODEM) */
144 set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq); 128 set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);
145 129
146#ifdef CONFIG_PCI
147 setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action);
148#endif
149
150 /* enable all CPU interrupt bits. */ 130 /* enable all CPU interrupt bits. */
151 set_c0_status(ST0_IM); /* IE bit is still 0. */ 131 set_c0_status(ST0_IM); /* IE bit is still 0. */
152} 132}
diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c
index 57dc91e7afa6..7c16c402ff60 100644
--- a/arch/mips/txx9/jmr3927/setup.c
+++ b/arch/mips/txx9/jmr3927/setup.c
@@ -199,6 +199,7 @@ static void __init jmr3927_pci_setup(void)
199 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); 199 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
200 } 200 }
201 tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb); 201 tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb);
202 tx3927_setup_pcierr_irq();
202#endif /* CONFIG_PCI */ 203#endif /* CONFIG_PCI */
203} 204}
204 205
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
index 88c05ccee3b2..65b72247d320 100644
--- a/arch/mips/txx9/rbtx4927/setup.c
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -103,6 +103,7 @@ static void __init tx4927_pci_setup(void)
103 tx4927_report_pciclk(); 103 tx4927_report_pciclk();
104 tx4927_pcic_setup(tx4927_pcicptr, c, extarb); 104 tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
105 } 105 }
106 tx4927_setup_pcierr_irq();
106} 107}
107 108
108static void __init tx4937_pci_setup(void) 109static void __init tx4937_pci_setup(void)
@@ -149,6 +150,7 @@ static void __init tx4937_pci_setup(void)
149 tx4938_report_pciclk(); 150 tx4938_report_pciclk();
150 tx4927_pcic_setup(tx4938_pcicptr, c, extarb); 151 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
151 } 152 }
153 tx4938_setup_pcierr_irq();
152} 154}
153 155
154static void __init rbtx4927_arch_init(void) 156static void __init rbtx4927_arch_init(void)
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index fc9034db526e..4454b7901cd3 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -121,6 +121,7 @@ static void __init rbtx4938_pci_setup(void)
121 register_pci_controller(c); 121 register_pci_controller(c);
122 tx4927_pcic_setup(tx4938_pcic1ptr, c, 0); 122 tx4927_pcic_setup(tx4938_pcic1ptr, c, 0);
123 } 123 }
124 tx4938_setup_pcierr_irq();
124#endif /* CONFIG_PCI */ 125#endif /* CONFIG_PCI */
125} 126}
126 127
diff --git a/include/asm-mips/txx9/tx3927.h b/include/asm-mips/txx9/tx3927.h
index ea79e1b16e71..8d62b1ba2c14 100644
--- a/include/asm-mips/txx9/tx3927.h
+++ b/include/asm-mips/txx9/tx3927.h
@@ -236,11 +236,17 @@ struct tx3927_ccfg_reg {
236/* see PCI_STATUS_XXX in linux/pci.h */ 236/* see PCI_STATUS_XXX in linux/pci.h */
237#define PCI_STATUS_NEW_CAP 0x0010 237#define PCI_STATUS_NEW_CAP 0x0010
238 238
239/* bits for ISTAT/IIM */
240#define TX3927_PCIC_IIM_ALL 0x00001600
241
239/* bits for TC */ 242/* bits for TC */
240#define TX3927_PCIC_TC_OF16E 0x00000020 243#define TX3927_PCIC_TC_OF16E 0x00000020
241#define TX3927_PCIC_TC_IF8E 0x00000010 244#define TX3927_PCIC_TC_IF8E 0x00000010
242#define TX3927_PCIC_TC_OF8E 0x00000008 245#define TX3927_PCIC_TC_OF8E 0x00000008
243 246
247/* bits for TSTAT/TIM */
248#define TX3927_PCIC_TIM_ALL 0x0003ffff
249
244/* bits for IOBA/MBA */ 250/* bits for IOBA/MBA */
245/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */ 251/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */
246 252
@@ -320,5 +326,6 @@ struct tx3927_ccfg_reg {
320struct pci_controller; 326struct pci_controller;
321void __init tx3927_pcic_setup(struct pci_controller *channel, 327void __init tx3927_pcic_setup(struct pci_controller *channel,
322 unsigned long sdram_size, int extarb); 328 unsigned long sdram_size, int extarb);
329void tx3927_setup_pcierr_irq(void);
323 330
324#endif /* __ASM_TXX9_TX3927_H */ 331#endif /* __ASM_TXX9_TX3927_H */
diff --git a/include/asm-mips/txx9/tx4927.h b/include/asm-mips/txx9/tx4927.h
index ceb4b79ff4e3..2c26fd17cb4a 100644
--- a/include/asm-mips/txx9/tx4927.h
+++ b/include/asm-mips/txx9/tx4927.h
@@ -249,6 +249,7 @@ void tx4927_time_init(unsigned int tmrnr);
249void tx4927_setup_serial(void); 249void tx4927_setup_serial(void);
250int tx4927_report_pciclk(void); 250int tx4927_report_pciclk(void);
251int tx4927_pciclk66_setup(void); 251int tx4927_pciclk66_setup(void);
252void tx4927_setup_pcierr_irq(void);
252void tx4927_irq_init(void); 253void tx4927_irq_init(void);
253 254
254#endif /* __ASM_TXX9_TX4927_H */ 255#endif /* __ASM_TXX9_TX4927_H */
diff --git a/include/asm-mips/txx9/tx4927pcic.h b/include/asm-mips/txx9/tx4927pcic.h
index e1d78e9ebc06..223841c56131 100644
--- a/include/asm-mips/txx9/tx4927pcic.h
+++ b/include/asm-mips/txx9/tx4927pcic.h
@@ -10,6 +10,7 @@
10#define __ASM_TXX9_TX4927PCIC_H 10#define __ASM_TXX9_TX4927PCIC_H
11 11
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/irqreturn.h>
13 14
14struct tx4927_pcic_reg { 15struct tx4927_pcic_reg {
15 u32 pciid; 16 u32 pciid;
@@ -196,5 +197,7 @@ void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr,
196 struct pci_controller *channel, int extarb); 197 struct pci_controller *channel, int extarb);
197void tx4927_report_pcic_status(void); 198void tx4927_report_pcic_status(void);
198char *tx4927_pcibios_setup(char *str); 199char *tx4927_pcibios_setup(char *str);
200void tx4927_dump_pcic_settings(void);
201irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id);
199 202
200#endif /* __ASM_TXX9_TX4927PCIC_H */ 203#endif /* __ASM_TXX9_TX4927PCIC_H */
diff --git a/include/asm-mips/txx9/tx4938.h b/include/asm-mips/txx9/tx4938.h
index 1ed969d381d6..4fff1c9e08d4 100644
--- a/include/asm-mips/txx9/tx4938.h
+++ b/include/asm-mips/txx9/tx4938.h
@@ -285,6 +285,7 @@ void tx4938_report_pci1clk(void);
285int tx4938_pciclk66_setup(void); 285int tx4938_pciclk66_setup(void);
286struct pci_dev; 286struct pci_dev;
287int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot); 287int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
288void tx4938_setup_pcierr_irq(void);
288void tx4938_irq_init(void); 289void tx4938_irq_init(void);
289 290
290#endif 291#endif