All of lore.kernel.org
 help / color / mirror / Atom feed
* [V3 0/4] ARM: mmp: Add mmc support on pxa910 DKB board
@ 2011-09-21 13:07 Jun Nie
  2011-09-21 13:07 ` [PATCH] mmc: check SDIO card wake up during suspending Jun Nie
       [not found] ` <1316610446-24183-5-git-send-email-njun@marvell.com>
  0 siblings, 2 replies; 3+ messages in thread
From: Jun Nie @ 2011-09-21 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset add mmc support on PXA910 DKB board.
It is similiar with V2 in Apr, just align with modified sdhci-pxav2
version driver.

Jun Nie (4):
  ARM: mmp: add pxa910 mmc resource
  ARM: mmp: append mmc 2v8 regulator on dkb board
  ARM: mmp: support sd card on pxa910 dkb board
  ARM: mmp: support emmc on dkb board

 arch/arm/mach-mmp/include/mach/mfp-pxa910.h |   15 ++++
 arch/arm/mach-mmp/include/mach/pxa910.h     |   15 ++++
 arch/arm/mach-mmp/include/mach/regs-apmu.h  |    1 +
 arch/arm/mach-mmp/pxa910.c                  |    9 +++
 arch/arm/mach-mmp/ttc_dkb.c                 |  100 +++++++++++++++++++++++++++
 5 files changed, 140 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] mmc: check SDIO card wake up during suspending
  2011-09-21 13:07 [V3 0/4] ARM: mmp: Add mmc support on pxa910 DKB board Jun Nie
@ 2011-09-21 13:07 ` Jun Nie
       [not found] ` <1316610446-24183-5-git-send-email-njun@marvell.com>
  1 sibling, 0 replies; 3+ messages in thread
From: Jun Nie @ 2011-09-21 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

It is possible that SDIO card issue card interrupt to wake up
system just after SDIO func driver and SDIO card firmware commit
suspend state, while system is still in suspending process and
mmc interrupt is not release yet.

Interrupt storm may happen if func driver does not notify firmware
to clear the wake up source. If func driver issue SDIO bus transaction
to have firmware clear the source and driver try to handle the wake
up event, system may enter suspend before all transaction done.
In this case, SDIO card will not enter lower power mode never. But
system can not be wake up for only card insert/remove/interrupt irq are
listed in wake up source in SD spec. Data/command done irq can
not wake up system.

This patch check SDIO card interrupt and stop system suspend if there
are card interrupt after func driver suspend.

Signed-off-by: Jun Nie <njun@marvell.com>
---
 drivers/mmc/core/sdio.c       |   14 ++++++++++++++
 drivers/mmc/core/sdio_irq.c   |    5 +++++
 drivers/mmc/host/sdhci.c      |   14 +++++++++++++-
 include/linux/mmc/card.h      |    2 ++
 include/linux/mmc/sdio_func.h |    2 ++
 5 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index c3ad105..48a4106 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -584,6 +584,14 @@ static int mmc_sdio_suspend(struct mmc_host *host)
 
 	for (i = 0; i < host->card->sdio_funcs; i++) {
 		struct sdio_func *func = host->card->sdio_func[i];
+		/* cancel suspend once we detect external wake up source */
+		if (host->card->pending_interrupt) {
+			host->card->pending_interrupt = 0;
+			err = -EBUSY;
+			printk(KERN_ALERT "%s: wake up event after device suspended\n",
+					mmc_hostname(host));
+			break;
+		}
 		if (func && sdio_func_present(func) && func->dev.driver) {
 			const struct dev_pm_ops *pmops = func->dev.driver->pm;
 			if (!pmops || !pmops->suspend || !pmops->resume) {
@@ -593,10 +601,15 @@ static int mmc_sdio_suspend(struct mmc_host *host)
 				err = pmops->suspend(&func->dev);
 			if (err)
 				break;
+			else
+				/* It is prefer that func driver set it in its
+				   suspend function with mmc_claim_host */
+				func->suspended = true;
 		}
 	}
 	while (err && --i >= 0) {
 		struct sdio_func *func = host->card->sdio_func[i];
+		func->suspended = false;
 		if (func && sdio_func_present(func) && func->dev.driver) {
 			const struct dev_pm_ops *pmops = func->dev.driver->pm;
 			pmops->resume(&func->dev);
@@ -639,6 +652,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
 	 */
 	for (i = 0; !err && i < host->card->sdio_funcs; i++) {
 		struct sdio_func *func = host->card->sdio_func[i];
+		func->suspended = false;
 		if (func && sdio_func_present(func) && func->dev.driver) {
 			const struct dev_pm_ops *pmops = func->dev.driver->pm;
 			err = pmops->resume(&func->dev);
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index bb192f9..2665974 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -49,6 +49,11 @@ static int process_sdio_pending_irqs(struct mmc_card *card)
 					mmc_card_id(card));
 				ret = -EINVAL;
 			} else if (func->irq_handler) {
+				if (func->suspended) {
+					card->pending_interrupt = true;
+					printk(KERN_WARNING "%s: IRQ that arrives in suspend mode"
+						" mode\n", sdio_func_id(func));
+				}
 				func->irq_handler(func);
 				count++;
 			} else {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 782c0ee..670c141 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -24,6 +24,7 @@
 #include <linux/leds.h>
 
 #include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
 
 #include "sdhci.h"
 
@@ -1631,7 +1632,7 @@ out:
 
 int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
 {
-	int ret;
+	int ret = 0;
 
 	sdhci_disable_card_detection(host);
 
@@ -1644,6 +1645,14 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
 	if (host->vmmc)
 		ret = regulator_disable(host->vmmc);
 
+	if (host->mmc->card && host->mmc->card->pending_interrupt) {
+		DBG("*** %s wake up event after suspend, resuming to handle it\n",
+			mmc_hostname(host->mmc));
+		host->mmc->card->pending_interrupt = 0;
+		sdhci_resume_host(host);
+		ret = -EBUSY;
+	}
+
 	return ret;
 }
 
@@ -1659,6 +1668,9 @@ int sdhci_resume_host(struct sdhci_host *host)
 			return ret;
 	}
 
+	if (host->mmc->card && host->mmc->card->pending_interrupt)
+		host->mmc->card->pending_interrupt = 0;
+
 
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if (host->ops->enable_dma)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 8ce0827..2252fe2 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -146,6 +146,8 @@ struct mmc_card {
 	struct sdio_func_tuple	*tuples;	/* unknown common tuples */
 
 	struct dentry		*debugfs_root;
+	/* external interrupt arrived after sdio function suspended */
+	u32			pending_interrupt;
 };
 
 #define mmc_card_mmc(c)		((c)->type == MMC_TYPE_MMC)
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index 31baaf8..5c1c462 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -59,6 +59,8 @@ struct sdio_func {
 	const char		**info;		/* info strings */
 
 	struct sdio_func_tuple *tuples;
+
+	int			suspended; /* SDIO function driver state */
 };
 
 #define sdio_func_present(f)	((f)->state & SDIO_STATE_PRESENT)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [V3 4/4] ARM: mmp: support emmc on dkb board
       [not found] ` <1316610446-24183-5-git-send-email-njun@marvell.com>
@ 2011-09-23  5:58   ` Haojian Zhuang
  0 siblings, 0 replies; 3+ messages in thread
From: Haojian Zhuang @ 2011-09-23  5:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 21, 2011 at 9:07 PM, Jun Nie <njun@marvell.com> wrote:
> Signed-off-by: Jun Nie <njun@marvell.com>
> ---
> ?arch/arm/mach-mmp/ttc_dkb.c | ? 30 ++++++++++++++++++++++++++++++
> ?1 files changed, 30 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
> index f90e5db..0c05ecd 100644
> --- a/arch/arm/mach-mmp/ttc_dkb.c
> +++ b/arch/arm/mach-mmp/ttc_dkb.c
> @@ -50,6 +50,18 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
> ? ? ? ?GPIO47_UART2_RXD,
> ? ? ? ?GPIO48_UART2_TXD,
>
> +#ifdef DKB_EMMC
> + ? ? ? MFP_CFG(DF_IO0, AF1),
> + ? ? ? MFP_CFG(DF_IO1, AF1),
> + ? ? ? MFP_CFG(DF_IO2, AF1),
> + ? ? ? MFP_CFG(DF_IO3, AF1),
> + ? ? ? MFP_CFG(DF_IO4, AF1),
> + ? ? ? MFP_CFG(DF_IO5, AF1),
> + ? ? ? MFP_CFG(DF_IO6, AF1),
> + ? ? ? MFP_CFG(DF_IO7, AF1),
> + ? ? ? MFP_CFG(DF_CLE_SM_OEn, AF1),
> + ? ? ? MFP_CFG(SM_SCLK, AF1),
> +#else
> ? ? ? ?/* DFI */
> ? ? ? ?DF_IO0_ND_IO0,
> ? ? ? ?DF_IO1_ND_IO1,
> @@ -73,6 +85,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
> ? ? ? ?DF_WEn_DF_WEn,
> ? ? ? ?DF_REn_DF_REn,
> ? ? ? ?DF_RDY0_DF_RDY0,
> +#endif /* DKB_EMMC */
If the pin configurations are conflict for different types of one
platform, it's better
to use Kconfig. Since you can avoid to change your sourcecode.
>
> ? ? ? ?/*sdh MMC0*/
> ? ? ? ?MMC1_DAT3_MMC1_DAT3,
> @@ -96,6 +109,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
> ? ? ? ?GPIO15_GPIO,
> ?};
>
> +#ifndef DKB_EMMC
> ?static struct mtd_partition ttc_dkb_onenand_partitions[] = {
> ? ? ? ?{
> ? ? ? ? ? ? ? ?.name ? ? ? ? ? = "bootloader",
> @@ -147,9 +161,12 @@ static struct platform_device ttc_dkb_device_onenand = {
> ? ? ? ? ? ? ? ?.platform_data ?= &ttc_dkb_onenand_info,
> ? ? ? ?},
> ?};
> +#endif /* DKB_EMMC */
>
> ?static struct platform_device *ttc_dkb_devices[] = {
> +#ifndef DKB_EMMC
> ? ? ? ?&ttc_dkb_device_onenand,
> +#endif
> ?};
>
> ?static struct pca953x_platform_data max7312_data[] = {
> @@ -203,6 +220,16 @@ static struct sdhci_pxa_platdata pxa910_sdh_platdata_mmc0 = {
> ? ? ? ?.clk_delay_cycles ? ? ? = 2,
> ?};
>
> +/* MMC2 controller for EMMC */
> +#ifdef DKB_EMMC
> +static struct sdhci_pxa_platdata pxa910_sdh_platdata_mmc2 = {
> + ? ? ? .flags ? ? ? ? ? ? ? ? ?= PXA_FLAG_CARD_PERMANENT
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
> + ? ? ? .clk_delay_sel ? ? ? ? ?= 1,
> + ? ? ? .clk_delay_cycles ? ? ? = 2,
> +};
> +#endif
> +
> ?/* MMC1 controller for SDIO */
> ?static struct sdhci_pxa_platdata pxa910_sdh_platdata_mmc1 = {
> ? ? ? ?.flags ? ? ? ? ? ? ? ? ?= PXA_FLAG_CARD_PERMANENT,
> @@ -216,6 +243,9 @@ static void __init ttc_dkb_init(void)
> ? ? ? ?pxa910_add_uart(1);
> ? ? ? ?pxa910_add_sdhost0(&pxa910_sdh_platdata_mmc0);
> ? ? ? ?pxa910_add_sdhost1(&pxa910_sdh_platdata_mmc1);
> +#ifdef DKB_EMMC
> + ? ? ? pxa910_add_sdhost2(&pxa910_sdh_platdata_mmc2);
> +#endif
>
> ? ? ? ?/* off-chip devices */
> ? ? ? ?pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
> --
> 1.7.0.4
>
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-09-23  5:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-21 13:07 [V3 0/4] ARM: mmp: Add mmc support on pxa910 DKB board Jun Nie
2011-09-21 13:07 ` [PATCH] mmc: check SDIO card wake up during suspending Jun Nie
     [not found] ` <1316610446-24183-5-git-send-email-njun@marvell.com>
2011-09-23  5:58   ` [V3 4/4] ARM: mmp: support emmc on dkb board Haojian Zhuang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.