diff options
author | Kevin Liu <kliu5@marvell.com> | 2013-01-05 04:21:33 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-02-11 13:28:50 -0500 |
commit | ad080d7916a4701fda29a442a69be4fd54d19a2e (patch) | |
tree | 3ff4ae7bf39beb0862e6300953560f98d9bcf5ba /drivers/mmc/host/sdhci.c | |
parent | b0a8dece55ebe792b394e0c73fa365ad24c3ec32 (diff) |
mmc: sdhci: add IRQ wake up support
Don't disable SD Host IRQ during suspend if it is wake up source.
Enable wakeup event during suspend.
Signed-off-by: Jialing Fu <jlfu@marvell.com>
Signed-off-by: Kevin Liu <kliu5@marvell.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 1165376592b9..b93076764ddd 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -2458,6 +2458,32 @@ out: | |||
2458 | \*****************************************************************************/ | 2458 | \*****************************************************************************/ |
2459 | 2459 | ||
2460 | #ifdef CONFIG_PM | 2460 | #ifdef CONFIG_PM |
2461 | void sdhci_enable_irq_wakeups(struct sdhci_host *host) | ||
2462 | { | ||
2463 | u8 val; | ||
2464 | u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE | ||
2465 | | SDHCI_WAKE_ON_INT; | ||
2466 | |||
2467 | val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); | ||
2468 | val |= mask ; | ||
2469 | /* Avoid fake wake up */ | ||
2470 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) | ||
2471 | val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE); | ||
2472 | sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); | ||
2473 | } | ||
2474 | EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); | ||
2475 | |||
2476 | void sdhci_disable_irq_wakeups(struct sdhci_host *host) | ||
2477 | { | ||
2478 | u8 val; | ||
2479 | u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE | ||
2480 | | SDHCI_WAKE_ON_INT; | ||
2481 | |||
2482 | val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); | ||
2483 | val &= ~mask; | ||
2484 | sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); | ||
2485 | } | ||
2486 | EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups); | ||
2461 | 2487 | ||
2462 | int sdhci_suspend_host(struct sdhci_host *host) | 2488 | int sdhci_suspend_host(struct sdhci_host *host) |
2463 | { | 2489 | { |
@@ -2487,9 +2513,13 @@ int sdhci_suspend_host(struct sdhci_host *host) | |||
2487 | return ret; | 2513 | return ret; |
2488 | } | 2514 | } |
2489 | 2515 | ||
2490 | sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK); | 2516 | if (!device_may_wakeup(mmc_dev(host->mmc))) { |
2491 | free_irq(host->irq, host); | 2517 | sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK); |
2492 | 2518 | free_irq(host->irq, host); | |
2519 | } else { | ||
2520 | sdhci_enable_irq_wakeups(host); | ||
2521 | enable_irq_wake(host->irq); | ||
2522 | } | ||
2493 | return ret; | 2523 | return ret; |
2494 | } | 2524 | } |
2495 | 2525 | ||
@@ -2504,10 +2534,15 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
2504 | host->ops->enable_dma(host); | 2534 | host->ops->enable_dma(host); |
2505 | } | 2535 | } |
2506 | 2536 | ||
2507 | ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, | 2537 | if (!device_may_wakeup(mmc_dev(host->mmc))) { |
2508 | mmc_hostname(host->mmc), host); | 2538 | ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, |
2509 | if (ret) | 2539 | mmc_hostname(host->mmc), host); |
2510 | return ret; | 2540 | if (ret) |
2541 | return ret; | ||
2542 | } else { | ||
2543 | sdhci_disable_irq_wakeups(host); | ||
2544 | disable_irq_wake(host->irq); | ||
2545 | } | ||
2511 | 2546 | ||
2512 | if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) && | 2547 | if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) && |
2513 | (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) { | 2548 | (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) { |
@@ -2535,17 +2570,6 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
2535 | } | 2570 | } |
2536 | 2571 | ||
2537 | EXPORT_SYMBOL_GPL(sdhci_resume_host); | 2572 | EXPORT_SYMBOL_GPL(sdhci_resume_host); |
2538 | |||
2539 | void sdhci_enable_irq_wakeups(struct sdhci_host *host) | ||
2540 | { | ||
2541 | u8 val; | ||
2542 | val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); | ||
2543 | val |= SDHCI_WAKE_ON_INT; | ||
2544 | sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); | ||
2545 | } | ||
2546 | |||
2547 | EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); | ||
2548 | |||
2549 | #endif /* CONFIG_PM */ | 2573 | #endif /* CONFIG_PM */ |
2550 | 2574 | ||
2551 | #ifdef CONFIG_PM_RUNTIME | 2575 | #ifdef CONFIG_PM_RUNTIME |