diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-07-25 10:01:35 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-07-30 16:54:38 -0400 |
commit | 455cc256eb23915100e203fb33ee143afd127954 (patch) | |
tree | 1ad0c410fef0f7d82587347c3d3e4d4c9646dcee /arch/mips/pci/ops-tx4927.c | |
parent | 07517529225ae4ce770271f83d8cd1004733a01d (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>
Diffstat (limited to 'arch/mips/pci/ops-tx4927.c')
-rw-r--r-- | arch/mips/pci/ops-tx4927.c | 62 |
1 files changed, 62 insertions, 0 deletions
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 | ||
21 | static struct { | 23 | static struct { |
@@ -431,6 +433,66 @@ void tx4927_report_pcic_status(void) | |||
431 | } | 433 | } |
432 | } | 434 | } |
433 | 435 | ||
436 | static 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 | |||
460 | void 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 | |||
470 | irqreturn_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 |
435 | static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) | 497 | static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) |
436 | { | 498 | { |