Loading drivers/mmc/core/core.c +6 −1 Original line number Diff line number Diff line Loading @@ -2264,7 +2264,7 @@ void mmc_start_host(struct mmc_host *host) _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); Loading @@ -2273,6 +2273,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; Loading drivers/mmc/core/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ static inline void mmc_delay(unsigned int ms) 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, Loading drivers/mmc/core/host.c +9 −0 Original line number Diff line number Diff line Loading @@ -80,9 +80,18 @@ static void mmc_host_classdev_release(struct device *dev) 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, }; Loading drivers/mmc/host/meson-mx-sdhc-mmc.c +16 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) { struct meson_mx_sdhc_host *host = mmc_priv(mmc); bool manual_stop = false; u32 ictl, send; int pack_len; Loading Loading @@ -172,12 +173,27 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc, else /* software flush: */ ictl |= MESON_SDHC_ICTL_DATA_XFER_OK; /* * Mimic the logic from the vendor driver where (only) * SD_IO_RW_EXTENDED commands with more than one block set the * MESON_SDHC_MISC_MANUAL_STOP bit. This fixes the firmware * download in the brcmfmac driver for a BCM43362/1 card. * Without this sdio_memcpy_toio() (with a size of 219557 * bytes) times out if MESON_SDHC_MISC_MANUAL_STOP is not set. */ manual_stop = cmd->data->blocks > 1 && cmd->opcode == SD_IO_RW_EXTENDED; } else { pack_len = 0; ictl |= MESON_SDHC_ICTL_RESP_OK; } regmap_update_bits(host->regmap, MESON_SDHC_MISC, MESON_SDHC_MISC_MANUAL_STOP, manual_stop ? MESON_SDHC_MISC_MANUAL_STOP : 0); if (cmd->opcode == MMC_STOP_TRANSMISSION) send |= MESON_SDHC_SEND_DATA_STOP; Loading Loading
drivers/mmc/core/core.c +6 −1 Original line number Diff line number Diff line Loading @@ -2264,7 +2264,7 @@ void mmc_start_host(struct mmc_host *host) _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); Loading @@ -2273,6 +2273,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; Loading
drivers/mmc/core/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ static inline void mmc_delay(unsigned int ms) 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, Loading
drivers/mmc/core/host.c +9 −0 Original line number Diff line number Diff line Loading @@ -80,9 +80,18 @@ static void mmc_host_classdev_release(struct device *dev) 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, }; Loading
drivers/mmc/host/meson-mx-sdhc-mmc.c +16 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) { struct meson_mx_sdhc_host *host = mmc_priv(mmc); bool manual_stop = false; u32 ictl, send; int pack_len; Loading Loading @@ -172,12 +173,27 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc, else /* software flush: */ ictl |= MESON_SDHC_ICTL_DATA_XFER_OK; /* * Mimic the logic from the vendor driver where (only) * SD_IO_RW_EXTENDED commands with more than one block set the * MESON_SDHC_MISC_MANUAL_STOP bit. This fixes the firmware * download in the brcmfmac driver for a BCM43362/1 card. * Without this sdio_memcpy_toio() (with a size of 219557 * bytes) times out if MESON_SDHC_MISC_MANUAL_STOP is not set. */ manual_stop = cmd->data->blocks > 1 && cmd->opcode == SD_IO_RW_EXTENDED; } else { pack_len = 0; ictl |= MESON_SDHC_ICTL_RESP_OK; } regmap_update_bits(host->regmap, MESON_SDHC_MISC, MESON_SDHC_MISC_MANUAL_STOP, manual_stop ? MESON_SDHC_MISC_MANUAL_STOP : 0); if (cmd->opcode == MMC_STOP_TRANSMISSION) send |= MESON_SDHC_SEND_DATA_STOP; Loading