mmc: core: If controller drv had not registed shutdown callback,
authorlintao <lintao@rock-chips.com>
Fri, 14 Mar 2014 01:26:54 +0000 (09:26 +0800)
committerlintao <lintao@rock-chips.com>
Fri, 14 Mar 2014 01:26:54 +0000 (09:26 +0800)
           mmc_bus_shutdown SHOULD NOT fall throught it

           We find  kernel panic when rebooting system for nandflash based machine

           [  105.821908] PC is at mmc_bus_shutdown+0xc/0x18
           [  105.826376] LR is at device_shutdown+0x114/0x174
           [  105.831015] pc : [<c03e1818>]    lr : [<c02c94a0>]    psr: 600f0013
           [  105.831015] sp : cf0d9e58  ip : 00000000  fp : 00036864
           [  105.842499] r10: cdd888fc  r9 : cf0d8000  r8 : c09e001c
           [  105.847738] r7 : c0f9edd4  r6 : cdd8f1c8  r5 : cdd888c8  r4 : cdd888d4
           [  105.854275] r3 : 00000000  r2 : 00000001  r1 : 00000002  r0 : cdd888c0
           [  105.860815] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
           [  105.867963] Control: 10c53c7d  Table: 6df9004a  DAC: 00000015
             .....
           [  106.799170] [<c03e1818>] (mmc_bus_shutdown+0xc/0x18) from [<c02c94a0>] (device_shutdown+0x114/0x174)
           [  106.808341] [<c02c94a0>] (device_shutdown+0x114/0x174) from [<c003ec10>] (kernel_restart+0xc/0x50)
           [  106.817331] [<c003ec10>] (kernel_restart+0xc/0x50) from [<c003edbc>] (SyS_reboot+0x160/0x1dc)
           [  106.825891] [<c003edbc>] (SyS_reboot+0x160/0x1dc) from [<c000da80>] (ret_fast_syscall+0x0/0x48)

drivers/mmc/core/bus.c

index 42c1bbc47daa6328e622eba2857f0053585b3e38..37b4be81e530051d64a16efac47202c6e9dd6f36 100644 (file)
@@ -126,8 +126,19 @@ static void mmc_bus_shutdown(struct device *dev)
 {
        struct mmc_driver *drv = to_mmc_driver(dev->driver);
        struct mmc_card *card = mmc_dev_to_card(dev);
+       struct mmc_host *host = card->host;
+       int ret;
+
+       if (dev->driver && drv->shutdown)
+           drv->shutdown(card);
+
+    if (host->bus_ops->shutdown) {
+        ret = host->bus_ops->shutdown(host);
+
+        if (ret)
+            pr_warn("%s: error %d during shutdown\n",mmc_hostname(host), ret);
+       }
 
-       drv->shutdown(card);
 }
 
 #ifdef CONFIG_PM_SLEEP