From 9feae246963c648b212abad0f0eb8938de5f5fe5 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 22 Sep 2009 16:44:32 -0700 Subject: [PATCH] mmc: add MMC_CAP_NONREMOVABLE host capability eMMC's are not removable, so unsafe resume is OK always. To permit this a new host capability MMC_CAP_NONREMOVABLE has been added and suspend / resume updated accordingly. Signed-off-by: Adrian Hunter Acked-by: Matt Fleming Cc: Ian Molton Cc: "Roberto A. Foglietta" Cc: Jarkko Lavinen Cc: Denis Karpov Cc: Pierre Ossman Cc: Philip Langdale Cc: "Madhusudhan" Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/core/mmc.c | 45 ++++++++++++++++++++++++++++++++-------- drivers/mmc/core/sd.c | 45 ++++++++++++++++++++++++++++++++-------- include/linux/mmc/host.h | 1 + 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 2fb9d5f271ea..995db1853a81 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -507,8 +507,6 @@ static void mmc_detect(struct mmc_host *host) } } -#ifdef CONFIG_MMC_UNSAFE_RESUME - /* * Suspend callback from host. */ @@ -551,12 +549,7 @@ static void mmc_resume(struct mmc_host *host) } -#else - -#define mmc_suspend NULL -#define mmc_resume NULL - -#endif +#ifdef CONFIG_MMC_UNSAFE_RESUME static const struct mmc_bus_ops mmc_ops = { .remove = mmc_remove, @@ -565,6 +558,40 @@ static const struct mmc_bus_ops mmc_ops = { .resume = mmc_resume, }; +static void mmc_attach_bus_ops(struct mmc_host *host) +{ + mmc_attach_bus(host, &mmc_ops); +} + +#else + +static const struct mmc_bus_ops mmc_ops = { + .remove = mmc_remove, + .detect = mmc_detect, + .suspend = NULL, + .resume = NULL, +}; + +static const struct mmc_bus_ops mmc_ops_unsafe = { + .remove = mmc_remove, + .detect = mmc_detect, + .suspend = mmc_suspend, + .resume = mmc_resume, +}; + +static void mmc_attach_bus_ops(struct mmc_host *host) +{ + const struct mmc_bus_ops *bus_ops; + + if (host->caps & MMC_CAP_NONREMOVABLE) + bus_ops = &mmc_ops_unsafe; + else + bus_ops = &mmc_ops; + mmc_attach_bus(host, bus_ops); +} + +#endif + /* * Starting point for MMC card init. */ @@ -575,7 +602,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) BUG_ON(!host); WARN_ON(!host->claimed); - mmc_attach_bus(host, &mmc_ops); + mmc_attach_bus_ops(host); /* * We need to get OCR a different way for SPI. diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 7ad646fe077e..92fa9dceca79 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -561,8 +561,6 @@ static void mmc_sd_detect(struct mmc_host *host) } } -#ifdef CONFIG_MMC_UNSAFE_RESUME - /* * Suspend callback from host. */ @@ -605,12 +603,7 @@ static void mmc_sd_resume(struct mmc_host *host) } -#else - -#define mmc_sd_suspend NULL -#define mmc_sd_resume NULL - -#endif +#ifdef CONFIG_MMC_UNSAFE_RESUME static const struct mmc_bus_ops mmc_sd_ops = { .remove = mmc_sd_remove, @@ -619,6 +612,40 @@ static const struct mmc_bus_ops mmc_sd_ops = { .resume = mmc_sd_resume, }; +static void mmc_sd_attach_bus_ops(struct mmc_host *host) +{ + mmc_attach_bus(host, &mmc_sd_ops); +} + +#else + +static const struct mmc_bus_ops mmc_sd_ops = { + .remove = mmc_sd_remove, + .detect = mmc_sd_detect, + .suspend = NULL, + .resume = NULL, +}; + +static const struct mmc_bus_ops mmc_sd_ops_unsafe = { + .remove = mmc_sd_remove, + .detect = mmc_sd_detect, + .suspend = mmc_sd_suspend, + .resume = mmc_sd_resume, +}; + +static void mmc_sd_attach_bus_ops(struct mmc_host *host) +{ + const struct mmc_bus_ops *bus_ops; + + if (host->caps & MMC_CAP_NONREMOVABLE) + bus_ops = &mmc_sd_ops_unsafe; + else + bus_ops = &mmc_sd_ops; + mmc_attach_bus(host, bus_ops); +} + +#endif + /* * Starting point for SD card init. */ @@ -629,7 +656,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) BUG_ON(!host); WARN_ON(!host->claimed); - mmc_attach_bus(host, &mmc_sd_ops); + mmc_sd_attach_bus_ops(host); /* * We need to get OCR a different way for SPI. diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 631a2fea5264..bb867d2c26bd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -148,6 +148,7 @@ struct mmc_host { #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ #define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ #define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */ +#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */