Message ID | 20170123112432.08337d26.john@metanate.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi John, On 01/23/2017 08:24 PM, John Keeping wrote: > Hi, > > On Fri, 20 Jan 2017 15:08:57 +0900, Jaehoon Chung wrote: >> On 01/17/2017 10:38 PM, Romain Perier wrote: >>> In my case I can reproduce the issue on the rock2 and the firefly-rk3288. A workaround is to >>> >>> comment the line ".pm = <&pm_ops_foo>" . >> >> Sorry for late. I'm checking runtime PM for this. >> After that, i will decide whether revert or not. > > I hit this problem on Rock2 when trying 4.10-rc4. The following patch > fixes it for me. Could you check with Ulf's repository? https://git.kernel.org/cgit/linux/kernel/git/ulfh/mmc.git/commit/?h=next&id=e86738ac78c22956f1c787ebafefc83d43cab30a Shawn's patch was applied. If also occurred the same issue, let me know, plz. > > I'm not sure if this is safe in general or whether it should be guarded > by a quirk that is enabled for RK3288. > > -- >8 -- > Subject: [PATCH] mmc: dw_mmc: restore CIU state on resume > > At least on RK3288, asserting SDMMC_CTRL_RESET causes the CIU to reset > and disable the clock. We need to send SDMMC_CMD_UPD_CLK after doing > this in order to avoid the MMC host hanging. > > Signed-off-by: John Keeping <john@metanate.com> > --- > drivers/mmc/host/dw_mmc.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index b44306b886cb..e7504dabcfb6 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -3311,6 +3311,7 @@ int dw_mci_runtime_resume(struct device *dev) > { > int i, ret = 0; > struct dw_mci *host = dev_get_drvdata(dev); > + u32 sdmmc_cmd_bits = SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT; > > if (host->cur_slot && > (mmc_can_gpio_cd(host->cur_slot->mmc) || > @@ -3357,6 +3358,9 @@ int dw_mci_runtime_resume(struct device *dev) > if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) { > dw_mci_set_ios(slot->mmc, &slot->mmc->ios); > dw_mci_setup_bus(slot, true); > + } else { > + /* restore CIU */ > + mci_send_cmd(slot, sdmmc_cmd_bits, 0); > } > } > >
On Mon, 23 Jan 2017 21:53:02 +0900, Jaehoon Chung wrote: > On 01/23/2017 08:24 PM, John Keeping wrote: > > Hi, > > > > On Fri, 20 Jan 2017 15:08:57 +0900, Jaehoon Chung wrote: > >> On 01/17/2017 10:38 PM, Romain Perier wrote: > >>> In my case I can reproduce the issue on the rock2 and the firefly-rk3288. A workaround is to > >>> > >>> comment the line ".pm = <&pm_ops_foo>" . > >> > >> Sorry for late. I'm checking runtime PM for this. > >> After that, i will decide whether revert or not. > > > > I hit this problem on Rock2 when trying 4.10-rc4. The following patch > > fixes it for me. > > Could you check with Ulf's repository? > > https://git.kernel.org/cgit/linux/kernel/git/ulfh/mmc.git/commit/?h=next&id=e86738ac78c22956f1c787ebafefc83d43cab30a > > Shawn's patch was applied. If also occurred the same issue, let me know, plz. I missed that patch, it also fixes the issue for me. > > I'm not sure if this is safe in general or whether it should be guarded > > by a quirk that is enabled for RK3288. > > > > -- >8 -- > > Subject: [PATCH] mmc: dw_mmc: restore CIU state on resume > > > > At least on RK3288, asserting SDMMC_CTRL_RESET causes the CIU to reset > > and disable the clock. We need to send SDMMC_CMD_UPD_CLK after doing > > this in order to avoid the MMC host hanging. > > > > Signed-off-by: John Keeping <john@metanate.com> > > --- > > drivers/mmc/host/dw_mmc.c | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > > index b44306b886cb..e7504dabcfb6 100644 > > --- a/drivers/mmc/host/dw_mmc.c > > +++ b/drivers/mmc/host/dw_mmc.c > > @@ -3311,6 +3311,7 @@ int dw_mci_runtime_resume(struct device *dev) > > { > > int i, ret = 0; > > struct dw_mci *host = dev_get_drvdata(dev); > > + u32 sdmmc_cmd_bits = SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT; > > > > if (host->cur_slot && > > (mmc_can_gpio_cd(host->cur_slot->mmc) || > > @@ -3357,6 +3358,9 @@ int dw_mci_runtime_resume(struct device *dev) > > if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) { > > dw_mci_set_ios(slot->mmc, &slot->mmc->ios); > > dw_mci_setup_bus(slot, true); > > + } else { > > + /* restore CIU */ > > + mci_send_cmd(slot, sdmmc_cmd_bits, 0); > > } > > } > > > > >
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index b44306b886cb..e7504dabcfb6 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3311,6 +3311,7 @@ int dw_mci_runtime_resume(struct device *dev) { int i, ret = 0; struct dw_mci *host = dev_get_drvdata(dev); + u32 sdmmc_cmd_bits = SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT; if (host->cur_slot && (mmc_can_gpio_cd(host->cur_slot->mmc) || @@ -3357,6 +3358,9 @@ int dw_mci_runtime_resume(struct device *dev) if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) { dw_mci_set_ios(slot->mmc, &slot->mmc->ios); dw_mci_setup_bus(slot, true); + } else { + /* restore CIU */ + mci_send_cmd(slot, sdmmc_cmd_bits, 0); } }