[PATCH] edac: mpc85xx: implement "remove" for mpc85xx_pci_err_driver

From: yanjiang.jin
Date: Wed Nov 16 2016 - 01:27:02 EST


From: Yanjiang Jin <yanjiang.jin@xxxxxxxxxxxxx>

Tested on a T4240QDS board.

If we execute the below steps without this patch:

1. modprobe mpc85xx_edac [The first insmod, everything is well.]
2. modprobe -r mpc85xx_edac
3. modprobe mpc85xx_edac [insmod again, error happens.]

We would get the below error:

BUG: recent printk recursion!
Oops: Kernel access of bad area, sig: 11 [#48]
PREEMPT SMP NR_CPUS=24 CoreNet Generic
Modules linked in: mpc85xx_edac edac_core softdog [last unloaded: mpc85xx_edac]
CPU: 5 PID: 14773 Comm: modprobe Tainted: G D C 4.8.3-rt2
task: c0000005cdc40d40 task.stack: c0000005c8814000
NIP: c0000000005c5b60 LR: c0000000005c895c CTR: c0000000005c8940
REGS: c0000005c8816e20 TRAP: 0300 Tainted: G D C (4.8.3-rt2-WR9.0.0.0_preempt-rt)
MSR: 0000000080029000 <CE,EE,ME> CR: 28222828 XER: 20000000
DEAR: 80000000005392d8 ESR: 0000000000000100 SOFTE: 0
GPR00: c0000000005c8844 c0000005c88170a0 c0000000011db400 c000000001220496
GPR04: c000000001220838 c000000001220838 04ffffff000affff 80000000005392d8
GPR08: c0000000005cb400 c0000000005c8940 fffffffffffffffe 80000000004c9108
GPR12: c000000000bdad80 c00000003fff7300 000000000000fff1 c000000000d1c7f0
GPR16: 0000000000000001 000000000000003f c0000005c8817c20 c000000000bed4e0
GPR20: 0000000000000000 c0000000011fdaa0 0000000000000002 80000000004ccafe
GPR24: c0000005c8817390 0000000000000025 c000000001220458 0000000000000020
GPR28: 00000000000003e0 c000000001220838 80000000004ccafe c000000001220496
NIP [c0000000005c5b60] .string+0x20/0xa0
LR [c0000000005c895c] .vsnprintf+0x1ac/0x490
Call Trace:
[c0000005c88170a0] [c0000000005c8844] .vsnprintf+0x94/0x490 (unreliable)
[c0000005c8817170] [c0000000005c8c58] .vscnprintf+0x18/0x70
[c0000005c88171f0] [c0000000000d5920] .vprintk_emit+0x120/0x600
[c0000005c88172c0] [c000000000bdae44] .printk+0xc4/0xe0
[c0000005c8817340] [80000000004c6f5c] .edac_pci_add_device+0x2fc/0x350 [edac_core]
[c0000005c88173e0] [8000000000759d64] .mpc85xx_pci_err_probe+0x344/0x550 [mpc85xx_edac]
[c0000005c88174c0] [c0000000006952b4] .platform_drv_probe+0x84/0x120
[c0000005c8817550] [c000000000692294] .driver_probe_device+0x2f4/0x3d0
[c0000005c88175f0] [c00000000069248c] .__driver_attach+0x11c/0x120
[c0000005c8817680] [c00000000068f034] .bus_for_each_dev+0x94/0x100
[c0000005c8817720] [c000000000691624] .driver_attach+0x34/0x50
[c0000005c88177a0] [c000000000690e88] .bus_add_driver+0x1b8/0x310
[c0000005c8817840] [c000000000693404] .driver_register+0x94/0x170
[c0000005c88178c0] [c0000000006954b0] .__platform_register_drivers+0xa0/0x150
[c0000005c8817980] [800000000075b51c] .mpc85xx_mc_init+0x60/0xd0 [mpc85xx_edac]
[c0000005c8817a00] [c000000000001a68] .do_one_initcall+0x68/0x1e0
[c0000005c8817ae0] [c000000000bdb2e8] .do_init_module+0x88/0x24c
[c0000005c8817b80] [c00000000011961c] .load_module+0x1e3c/0x2840
[c0000005c8817d20] [c00000000011a320] .SyS_finit_module+0x100/0x130
[c0000005c8817e30] [c000000000000698] system_call+0x38/0xe8
Instruction dump:
4ba71abd 60000000 7ffff214 4bffff20 2ba50fff 7ca72b78 7cca0734 7c852378
40dd0030 2faa0000 394affff 41de0014 <89070000> 38e70001 2fa80000 40fe002c
---[ end trace 0000000000000031 ]---

Signed-off-by: Yanjiang Jin <yanjiang.jin@xxxxxxxxxxxxx>
---
drivers/edac/mpc85xx_edac.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index ff05675..c626021 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -300,6 +300,22 @@ static int mpc85xx_pci_err_probe(struct platform_device *op)
return res;
}

+static int mpc85xx_pci_err_remove(struct platform_device *op)
+{
+ struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
+ struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
+
+ edac_dbg(0, "\n");
+
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, orig_pci_err_cap_dr);
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en);
+
+ edac_pci_del_device(&op->dev);
+ edac_pci_free_ctl_info(pci);
+
+ return 0;
+}
+
static const struct platform_device_id mpc85xx_pci_err_match[] = {
{
.name = "mpc85xx-pci-edac"
@@ -309,6 +325,7 @@ static int mpc85xx_pci_err_probe(struct platform_device *op)

static struct platform_driver mpc85xx_pci_err_driver = {
.probe = mpc85xx_pci_err_probe,
+ .remove = mpc85xx_pci_err_remove,
.id_table = mpc85xx_pci_err_match,
.driver = {
.name = "mpc85xx_pci_err",
--
1.9.1