|
@@ -17,6 +17,7 @@
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/mod_devicetable.h>
|
|
|
#include <linux/edac.h>
|
|
|
+#include <linux/smp.h>
|
|
|
|
|
|
#include <linux/of_platform.h>
|
|
|
#include <linux/of_device.h>
|
|
@@ -40,7 +41,7 @@ static u32 orig_pci_err_en;
|
|
|
#endif
|
|
|
|
|
|
static u32 orig_l2_err_disable;
|
|
|
-static u32 orig_hid1;
|
|
|
+static u32 orig_hid1[2];
|
|
|
|
|
|
/************************ MC SYSFS parts ***********************************/
|
|
|
|
|
@@ -647,6 +648,9 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = {
|
|
|
{
|
|
|
.compatible = "fsl,8568-l2-cache-controller",
|
|
|
},
|
|
|
+ {
|
|
|
+ .compatible = "fsl,mpc8572-l2-cache-controller",
|
|
|
+ },
|
|
|
{},
|
|
|
};
|
|
|
|
|
@@ -912,7 +916,8 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
|
|
|
/* register interrupts */
|
|
|
pdata->irq = irq_of_parse_and_map(op->node, 0);
|
|
|
res = devm_request_irq(&op->dev, pdata->irq,
|
|
|
- mpc85xx_mc_isr, IRQF_DISABLED,
|
|
|
+ mpc85xx_mc_isr,
|
|
|
+ IRQF_DISABLED | IRQF_SHARED,
|
|
|
"[EDAC] MC err", mci);
|
|
|
if (res < 0) {
|
|
|
printk(KERN_ERR "%s: Unable to request irq %d for "
|
|
@@ -980,6 +985,9 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
|
|
|
{
|
|
|
.compatible = "fsl,8568-memory-controller",
|
|
|
},
|
|
|
+ {
|
|
|
+ .compatible = "fsl,mpc8572-memory-controller",
|
|
|
+ },
|
|
|
{},
|
|
|
};
|
|
|
|
|
@@ -995,6 +1003,14 @@ static struct of_platform_driver mpc85xx_mc_err_driver = {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+static void __init mpc85xx_mc_clear_rfxe(void *data)
|
|
|
+{
|
|
|
+ orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1);
|
|
|
+ mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int __init mpc85xx_mc_init(void)
|
|
|
{
|
|
|
int res = 0;
|
|
@@ -1030,19 +1046,22 @@ static int __init mpc85xx_mc_init(void)
|
|
|
* need to clear HID1[RFXE] to disable machine check int
|
|
|
* so we can catch it
|
|
|
*/
|
|
|
- if (edac_op_state == EDAC_OPSTATE_INT) {
|
|
|
- orig_hid1 = mfspr(SPRN_HID1);
|
|
|
- mtspr(SPRN_HID1, (orig_hid1 & ~0x20000));
|
|
|
- }
|
|
|
+ if (edac_op_state == EDAC_OPSTATE_INT)
|
|
|
+ on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
module_init(mpc85xx_mc_init);
|
|
|
|
|
|
+static void __exit mpc85xx_mc_restore_hid1(void *data)
|
|
|
+{
|
|
|
+ mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]);
|
|
|
+}
|
|
|
+
|
|
|
static void __exit mpc85xx_mc_exit(void)
|
|
|
{
|
|
|
- mtspr(SPRN_HID1, orig_hid1);
|
|
|
+ on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0);
|
|
|
#ifdef CONFIG_PCI
|
|
|
of_unregister_platform_driver(&mpc85xx_pci_err_driver);
|
|
|
#endif
|