Skip to content

Commit

Permalink
mmc: sdhci: Handle failure of enable_irq_wake()
Browse files Browse the repository at this point in the history
Now that sdhci_enable_irq_wakeups() is a local function, change it to
return whether the IRQ wakeup was successfully enabled. This is in
preparation for adding more conditions for whether IRQ wakeup is enabled.

Note it is assumed, for SDHCI devices, that suspend is more important than
wakeup, so we continue to suspend regardless.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Adrian Hunter authored and Ulf Hansson committed Jan 17, 2018
1 parent 551d6bd commit 58e79b6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
24 changes: 15 additions & 9 deletions drivers/mmc/host/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2828,7 +2828,7 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
* sdhci_disable_irq_wakeups() since it will be set by
* sdhci_enable_card_detection() or sdhci_init().
*/
static void sdhci_enable_irq_wakeups(struct sdhci_host *host)
static bool sdhci_enable_irq_wakeups(struct sdhci_host *host)
{
u8 val;
u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
Expand All @@ -2845,6 +2845,10 @@ static void sdhci_enable_irq_wakeups(struct sdhci_host *host)
}
sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
sdhci_writel(host, irq_val, SDHCI_INT_ENABLE);

host->irq_wake_enabled = !enable_irq_wake(host->irq);

return host->irq_wake_enabled;
}

static void sdhci_disable_irq_wakeups(struct sdhci_host *host)
Expand All @@ -2856,6 +2860,10 @@ static void sdhci_disable_irq_wakeups(struct sdhci_host *host)
val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
val &= ~mask;
sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);

disable_irq_wake(host->irq);

host->irq_wake_enabled = false;
}

int sdhci_suspend_host(struct sdhci_host *host)
Expand All @@ -2864,15 +2872,14 @@ int sdhci_suspend_host(struct sdhci_host *host)

mmc_retune_timer_stop(host->mmc);

if (!device_may_wakeup(mmc_dev(host->mmc))) {
if (!device_may_wakeup(mmc_dev(host->mmc)) ||
!sdhci_enable_irq_wakeups(host)) {
host->ier = 0;
sdhci_writel(host, 0, SDHCI_INT_ENABLE);
sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
free_irq(host->irq, host);
} else {
sdhci_enable_irq_wakeups(host);
enable_irq_wake(host->irq);
}

return 0;
}

Expand Down Expand Up @@ -2900,15 +2907,14 @@ int sdhci_resume_host(struct sdhci_host *host)
mmiowb();
}

if (!device_may_wakeup(mmc_dev(host->mmc))) {
if (host->irq_wake_enabled) {
sdhci_disable_irq_wakeups(host);
} else {
ret = request_threaded_irq(host->irq, sdhci_irq,
sdhci_thread_irq, IRQF_SHARED,
mmc_hostname(host->mmc), host);
if (ret)
return ret;
} else {
sdhci_disable_irq_wakeups(host);
disable_irq_wake(host->irq);
}

sdhci_enable_card_detection(host);
Expand Down
1 change: 1 addition & 0 deletions drivers/mmc/host/sdhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ struct sdhci_host {
bool bus_on; /* Bus power prevents runtime suspend */
bool preset_enabled; /* Preset is enabled */
bool pending_reset; /* Cmd/data reset is pending */
bool irq_wake_enabled; /* IRQ wakeup is enabled */

struct mmc_request *mrqs_done[SDHCI_MAX_MRQS]; /* Requests done */
struct mmc_command *cmd; /* Current command */
Expand Down

0 comments on commit 58e79b6

Please sign in to comment.