Loading drivers/mmc/host/sdhci-msm.c +10 −0 Original line number Diff line number Diff line Loading @@ -2432,7 +2432,16 @@ out: return rc; } static void sdhci_msm_cfg_power_irq(struct sdhci_host *host, bool enable) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = pltfm_host->priv; if (enable) enable_irq(msm_host->pwr_irq); else disable_irq(msm_host->pwr_irq); } static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable) { Loading Loading @@ -2873,6 +2882,7 @@ static struct sdhci_ops sdhci_msm_ops = { .dump_vendor_regs = sdhci_msm_dump_vendor_regs, .config_auto_tuning_cmd = sdhci_msm_config_auto_tuning_cmd, .enable_controller_clock = sdhci_msm_enable_controller_clock, .cfg_power_irq = sdhci_msm_cfg_power_irq, }; static int sdhci_msm_cfg_mpm_pin_wakeup(struct sdhci_host *host, unsigned mode) Loading drivers/mmc/host/sdhci.c +37 −20 Original line number Diff line number Diff line Loading @@ -1633,11 +1633,39 @@ static int sdhci_get_tuning_cmd(struct sdhci_host *host) return MMC_SEND_TUNING_BLOCK; } static void sdhci_cfg_irq(struct sdhci_host *host, bool enable, bool sync) { if (enable && !host->irq_enabled) { enable_irq(host->irq); host->irq_enabled = true; } else if (!enable && host->irq_enabled) { if (sync) disable_irq(host->irq); else disable_irq_nosync(host->irq); host->irq_enabled = false; } } #define SDHCI_SPIN_LOCK(host, enable) \ do { \ if (enable) { \ sdhci_cfg_irq(host, !enable, true); \ if (host->ops->cfg_power_irq) \ host->ops->cfg_power_irq(host, !enable);\ spin_lock(&host->lock); \ } else { \ spin_unlock(&host->lock); \ sdhci_cfg_irq(host, !enable, true); \ if (host->ops->cfg_power_irq) \ host->ops->cfg_power_irq(host, !enable);\ } \ } while (0) static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sdhci_host *host; int present; unsigned long flags; u32 tuning_opcode; host = mmc_priv(mmc); Loading Loading @@ -1671,7 +1699,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) SDHCI_CARD_PRESENT; } spin_lock_irqsave(&host->lock, flags); SDHCI_SPIN_LOCK(host, true); WARN_ON(host->mrq != NULL); Loading Loading @@ -1717,9 +1745,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) MMC_SEND_TUNING_BLOCK; host->mrq = NULL; host->flags &= ~SDHCI_NEEDS_RETUNING; spin_unlock_irqrestore(&host->lock, flags); SDHCI_SPIN_LOCK(host, false); sdhci_execute_tuning(mmc, tuning_opcode); spin_lock_irqsave(&host->lock, flags); SDHCI_SPIN_LOCK(host, true); /* Restore original mmc_request structure */ host->mrq = mrq; Loading @@ -1742,7 +1770,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) } mmiowb(); spin_unlock_irqrestore(&host->lock, flags); SDHCI_SPIN_LOCK(host, false); } static void sdhci_cfg_async_intr(struct sdhci_host *host, bool enable) Loading @@ -1761,17 +1789,6 @@ static void sdhci_cfg_async_intr(struct sdhci_host *host, bool enable) SDHCI_HOST_CONTROL2); } static void sdhci_cfg_irq(struct sdhci_host *host, bool enable) { if (enable && !host->irq_enabled) { enable_irq(host->irq); host->irq_enabled = true; } else if (!enable && host->irq_enabled) { disable_irq_nosync(host->irq); host->irq_enabled = false; } } static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) { unsigned long flags; Loading @@ -1789,7 +1806,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) spin_lock_irqsave(&host->lock, flags); /* lock is being released intermittently below, hence disable irq */ sdhci_cfg_irq(host, false); sdhci_cfg_irq(host, false, false); spin_unlock_irqrestore(&host->lock, flags); if (ios->clock) { sdhci_set_clock(host, ios->clock); Loading Loading @@ -1832,7 +1849,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) } spin_lock_irqsave(&host->lock, flags); if (!host->clock) { sdhci_cfg_irq(host, true); sdhci_cfg_irq(host, true, false); spin_unlock_irqrestore(&host->lock, flags); mutex_unlock(&host->ios_mutex); return; Loading Loading @@ -2013,7 +2030,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) sdhci_set_clock(host, ios->clock); } spin_lock_irqsave(&host->lock, flags); sdhci_cfg_irq(host, true); sdhci_cfg_irq(host, true, false); spin_unlock_irqrestore(&host->lock, flags); mmiowb(); mutex_unlock(&host->ios_mutex); Loading Loading @@ -3000,7 +3017,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) if (!host->clock && host->mmc->card && mmc_card_sdio(host->mmc->card)) { /* SDIO async. interrupt is level-sensitive */ sdhci_cfg_irq(host, false); sdhci_cfg_irq(host, false, false); pr_debug("%s: got async-irq: clocks: %d gated: %d host-irq[en:1/dis:0]: %d\n", mmc_hostname(host->mmc), host->clock, host->mmc->clk_gated, host->irq_enabled); Loading drivers/mmc/host/sdhci.h +1 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ struct sdhci_ops { bool enable, u32 type); int (*enable_controller_clock)(struct sdhci_host *host); void (*cfg_power_irq)(struct sdhci_host *host, bool enable); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS Loading Loading
drivers/mmc/host/sdhci-msm.c +10 −0 Original line number Diff line number Diff line Loading @@ -2432,7 +2432,16 @@ out: return rc; } static void sdhci_msm_cfg_power_irq(struct sdhci_host *host, bool enable) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = pltfm_host->priv; if (enable) enable_irq(msm_host->pwr_irq); else disable_irq(msm_host->pwr_irq); } static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable) { Loading Loading @@ -2873,6 +2882,7 @@ static struct sdhci_ops sdhci_msm_ops = { .dump_vendor_regs = sdhci_msm_dump_vendor_regs, .config_auto_tuning_cmd = sdhci_msm_config_auto_tuning_cmd, .enable_controller_clock = sdhci_msm_enable_controller_clock, .cfg_power_irq = sdhci_msm_cfg_power_irq, }; static int sdhci_msm_cfg_mpm_pin_wakeup(struct sdhci_host *host, unsigned mode) Loading
drivers/mmc/host/sdhci.c +37 −20 Original line number Diff line number Diff line Loading @@ -1633,11 +1633,39 @@ static int sdhci_get_tuning_cmd(struct sdhci_host *host) return MMC_SEND_TUNING_BLOCK; } static void sdhci_cfg_irq(struct sdhci_host *host, bool enable, bool sync) { if (enable && !host->irq_enabled) { enable_irq(host->irq); host->irq_enabled = true; } else if (!enable && host->irq_enabled) { if (sync) disable_irq(host->irq); else disable_irq_nosync(host->irq); host->irq_enabled = false; } } #define SDHCI_SPIN_LOCK(host, enable) \ do { \ if (enable) { \ sdhci_cfg_irq(host, !enable, true); \ if (host->ops->cfg_power_irq) \ host->ops->cfg_power_irq(host, !enable);\ spin_lock(&host->lock); \ } else { \ spin_unlock(&host->lock); \ sdhci_cfg_irq(host, !enable, true); \ if (host->ops->cfg_power_irq) \ host->ops->cfg_power_irq(host, !enable);\ } \ } while (0) static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sdhci_host *host; int present; unsigned long flags; u32 tuning_opcode; host = mmc_priv(mmc); Loading Loading @@ -1671,7 +1699,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) SDHCI_CARD_PRESENT; } spin_lock_irqsave(&host->lock, flags); SDHCI_SPIN_LOCK(host, true); WARN_ON(host->mrq != NULL); Loading Loading @@ -1717,9 +1745,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) MMC_SEND_TUNING_BLOCK; host->mrq = NULL; host->flags &= ~SDHCI_NEEDS_RETUNING; spin_unlock_irqrestore(&host->lock, flags); SDHCI_SPIN_LOCK(host, false); sdhci_execute_tuning(mmc, tuning_opcode); spin_lock_irqsave(&host->lock, flags); SDHCI_SPIN_LOCK(host, true); /* Restore original mmc_request structure */ host->mrq = mrq; Loading @@ -1742,7 +1770,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) } mmiowb(); spin_unlock_irqrestore(&host->lock, flags); SDHCI_SPIN_LOCK(host, false); } static void sdhci_cfg_async_intr(struct sdhci_host *host, bool enable) Loading @@ -1761,17 +1789,6 @@ static void sdhci_cfg_async_intr(struct sdhci_host *host, bool enable) SDHCI_HOST_CONTROL2); } static void sdhci_cfg_irq(struct sdhci_host *host, bool enable) { if (enable && !host->irq_enabled) { enable_irq(host->irq); host->irq_enabled = true; } else if (!enable && host->irq_enabled) { disable_irq_nosync(host->irq); host->irq_enabled = false; } } static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) { unsigned long flags; Loading @@ -1789,7 +1806,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) spin_lock_irqsave(&host->lock, flags); /* lock is being released intermittently below, hence disable irq */ sdhci_cfg_irq(host, false); sdhci_cfg_irq(host, false, false); spin_unlock_irqrestore(&host->lock, flags); if (ios->clock) { sdhci_set_clock(host, ios->clock); Loading Loading @@ -1832,7 +1849,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) } spin_lock_irqsave(&host->lock, flags); if (!host->clock) { sdhci_cfg_irq(host, true); sdhci_cfg_irq(host, true, false); spin_unlock_irqrestore(&host->lock, flags); mutex_unlock(&host->ios_mutex); return; Loading Loading @@ -2013,7 +2030,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) sdhci_set_clock(host, ios->clock); } spin_lock_irqsave(&host->lock, flags); sdhci_cfg_irq(host, true); sdhci_cfg_irq(host, true, false); spin_unlock_irqrestore(&host->lock, flags); mmiowb(); mutex_unlock(&host->ios_mutex); Loading Loading @@ -3000,7 +3017,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) if (!host->clock && host->mmc->card && mmc_card_sdio(host->mmc->card)) { /* SDIO async. interrupt is level-sensitive */ sdhci_cfg_irq(host, false); sdhci_cfg_irq(host, false, false); pr_debug("%s: got async-irq: clocks: %d gated: %d host-irq[en:1/dis:0]: %d\n", mmc_hostname(host->mmc), host->clock, host->mmc->clk_gated, host->irq_enabled); Loading
drivers/mmc/host/sdhci.h +1 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ struct sdhci_ops { bool enable, u32 type); int (*enable_controller_clock)(struct sdhci_host *host); void (*cfg_power_irq)(struct sdhci_host *host, bool enable); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS Loading