lkml.org 
[lkml]   [2021]   [Dec]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 54/76] mmc: core: Disable card detect during shutdown
    Date
    From: Ulf Hansson <ulf.hansson@linaro.org>

    commit 66c915d09b942fb3b2b0cb2f56562180901fba17 upstream.

    It's seems prone to problems by allowing card detect and its corresponding
    mmc_rescan() work to run, during platform shutdown. For example, we may end
    up turning off the power while initializing a card, which potentially could
    damage it.

    To avoid this scenario, let's add ->shutdown_pre() callback for the mmc host
    class device and then turn of the card detect from there.

    Reported-by: Al Cooper <alcooperx@gmail.com>
    Suggested-by: Adrian Hunter <adrian.hunter@intel.com>
    Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20211203141555.105351-1-ulf.hansson@linaro.org
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/mmc/core/core.c | 7 ++++++-
    drivers/mmc/core/core.h | 1 +
    drivers/mmc/core/host.c | 9 +++++++++
    3 files changed, 16 insertions(+), 1 deletion(-)

    --- a/drivers/mmc/core/core.c
    +++ b/drivers/mmc/core/core.c
    @@ -2327,7 +2327,7 @@ void mmc_start_host(struct mmc_host *hos
    _mmc_detect_change(host, 0, false);
    }

    -void mmc_stop_host(struct mmc_host *host)
    +void __mmc_stop_host(struct mmc_host *host)
    {
    if (host->slot.cd_irq >= 0) {
    mmc_gpio_set_cd_wake(host, false);
    @@ -2336,6 +2336,11 @@ void mmc_stop_host(struct mmc_host *host

    host->rescan_disable = 1;
    cancel_delayed_work_sync(&host->detect);
    +}
    +
    +void mmc_stop_host(struct mmc_host *host)
    +{
    + __mmc_stop_host(host);

    /* clear pm flags now and let card drivers set them as needed */
    host->pm_flags = 0;
    --- a/drivers/mmc/core/core.h
    +++ b/drivers/mmc/core/core.h
    @@ -69,6 +69,7 @@ static inline void mmc_delay(unsigned in

    void mmc_rescan(struct work_struct *work);
    void mmc_start_host(struct mmc_host *host);
    +void __mmc_stop_host(struct mmc_host *host);
    void mmc_stop_host(struct mmc_host *host);

    void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
    --- a/drivers/mmc/core/host.c
    +++ b/drivers/mmc/core/host.c
    @@ -79,9 +79,18 @@ static void mmc_host_classdev_release(st
    kfree(host);
    }

    +static int mmc_host_classdev_shutdown(struct device *dev)
    +{
    + struct mmc_host *host = cls_dev_to_mmc_host(dev);
    +
    + __mmc_stop_host(host);
    + return 0;
    +}
    +
    static struct class mmc_host_class = {
    .name = "mmc_host",
    .dev_release = mmc_host_classdev_release,
    + .shutdown_pre = mmc_host_classdev_shutdown,
    .pm = MMC_HOST_CLASS_DEV_PM_OPS,
    };


    \
     
     \ /
      Last update: 2021-12-27 16:43    [W:2.274 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site