diff options
author | Andrew Kilkenny <akilkenny@xes-inc.com> | 2008-10-16 01:04:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 14:21:48 -0400 |
commit | 60be75515e45167d48d3677ae05b522ba7762d40 (patch) | |
tree | b3c0fc8e96f2ae2ea98e6ed3eb1dc78a49311337 | |
parent | 53a2fe5804e849f39d9723dfdaaea527ec9d1eac (diff) |
edac mpc85xx: add support for mpc8572
This adds support for the dual-core MPC8572 processor. We have
to support making SPR changes on each core. Also, since we can
have multiple memory controllers sharing an interrupt, flag the
interrupts with IRQF_SHARED.
Signed-off-by: Andrew Kilkenny <akilkenny@xes-inc.com>
Signed-off-by: Nate Case <ncase@xes-inc.com>
Acked-by: Dave Jiang <djiang@mvista.com>
Signed-off-by: Doug Thompson <dougthompson@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/edac/mpc85xx_edac.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 2265d9ca1535..0cfcb2d075a0 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/mod_devicetable.h> | 18 | #include <linux/mod_devicetable.h> |
19 | #include <linux/edac.h> | 19 | #include <linux/edac.h> |
20 | #include <linux/smp.h> | ||
20 | 21 | ||
21 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
22 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
@@ -40,7 +41,7 @@ static u32 orig_pci_err_en; | |||
40 | #endif | 41 | #endif |
41 | 42 | ||
42 | static u32 orig_l2_err_disable; | 43 | static u32 orig_l2_err_disable; |
43 | static u32 orig_hid1; | 44 | static u32 orig_hid1[2]; |
44 | 45 | ||
45 | /************************ MC SYSFS parts ***********************************/ | 46 | /************************ MC SYSFS parts ***********************************/ |
46 | 47 | ||
@@ -647,6 +648,9 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { | |||
647 | { | 648 | { |
648 | .compatible = "fsl,8568-l2-cache-controller", | 649 | .compatible = "fsl,8568-l2-cache-controller", |
649 | }, | 650 | }, |
651 | { | ||
652 | .compatible = "fsl,mpc8572-l2-cache-controller", | ||
653 | }, | ||
650 | {}, | 654 | {}, |
651 | }; | 655 | }; |
652 | 656 | ||
@@ -912,7 +916,8 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, | |||
912 | /* register interrupts */ | 916 | /* register interrupts */ |
913 | pdata->irq = irq_of_parse_and_map(op->node, 0); | 917 | pdata->irq = irq_of_parse_and_map(op->node, 0); |
914 | res = devm_request_irq(&op->dev, pdata->irq, | 918 | res = devm_request_irq(&op->dev, pdata->irq, |
915 | mpc85xx_mc_isr, IRQF_DISABLED, | 919 | mpc85xx_mc_isr, |
920 | IRQF_DISABLED | IRQF_SHARED, | ||
916 | "[EDAC] MC err", mci); | 921 | "[EDAC] MC err", mci); |
917 | if (res < 0) { | 922 | if (res < 0) { |
918 | printk(KERN_ERR "%s: Unable to request irq %d for " | 923 | printk(KERN_ERR "%s: Unable to request irq %d for " |
@@ -980,6 +985,9 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { | |||
980 | { | 985 | { |
981 | .compatible = "fsl,8568-memory-controller", | 986 | .compatible = "fsl,8568-memory-controller", |
982 | }, | 987 | }, |
988 | { | ||
989 | .compatible = "fsl,mpc8572-memory-controller", | ||
990 | }, | ||
983 | {}, | 991 | {}, |
984 | }; | 992 | }; |
985 | 993 | ||
@@ -995,6 +1003,14 @@ static struct of_platform_driver mpc85xx_mc_err_driver = { | |||
995 | }, | 1003 | }, |
996 | }; | 1004 | }; |
997 | 1005 | ||
1006 | |||
1007 | static void __init mpc85xx_mc_clear_rfxe(void *data) | ||
1008 | { | ||
1009 | orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1); | ||
1010 | mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000)); | ||
1011 | } | ||
1012 | |||
1013 | |||
998 | static int __init mpc85xx_mc_init(void) | 1014 | static int __init mpc85xx_mc_init(void) |
999 | { | 1015 | { |
1000 | int res = 0; | 1016 | int res = 0; |
@@ -1030,19 +1046,22 @@ static int __init mpc85xx_mc_init(void) | |||
1030 | * need to clear HID1[RFXE] to disable machine check int | 1046 | * need to clear HID1[RFXE] to disable machine check int |
1031 | * so we can catch it | 1047 | * so we can catch it |
1032 | */ | 1048 | */ |
1033 | if (edac_op_state == EDAC_OPSTATE_INT) { | 1049 | if (edac_op_state == EDAC_OPSTATE_INT) |
1034 | orig_hid1 = mfspr(SPRN_HID1); | 1050 | on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0); |
1035 | mtspr(SPRN_HID1, (orig_hid1 & ~0x20000)); | ||
1036 | } | ||
1037 | 1051 | ||
1038 | return 0; | 1052 | return 0; |
1039 | } | 1053 | } |
1040 | 1054 | ||
1041 | module_init(mpc85xx_mc_init); | 1055 | module_init(mpc85xx_mc_init); |
1042 | 1056 | ||
1057 | static void __exit mpc85xx_mc_restore_hid1(void *data) | ||
1058 | { | ||
1059 | mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]); | ||
1060 | } | ||
1061 | |||
1043 | static void __exit mpc85xx_mc_exit(void) | 1062 | static void __exit mpc85xx_mc_exit(void) |
1044 | { | 1063 | { |
1045 | mtspr(SPRN_HID1, orig_hid1); | 1064 | on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); |
1046 | #ifdef CONFIG_PCI | 1065 | #ifdef CONFIG_PCI |
1047 | of_unregister_platform_driver(&mpc85xx_pci_err_driver); | 1066 | of_unregister_platform_driver(&mpc85xx_pci_err_driver); |
1048 | #endif | 1067 | #endif |