Re: [PATCH 7/32] mmc: add host capabilities for SD only and MMC only

Matt Fleming
2009-07-25T23:52:17Z

On Sat, Jul 25, 2009 at 10:45:07PM +0300, Adrian Hunter wrote:
>
> I have no objections if you write such a patch :-)

See also my change to [PATCH 32/32] of this series.

I don't have hardware to test all of the affected drivers but I was
thinking of something along the lines of,

---

mmc: add host capabilities for SD only and MMC only

Some hosts can accept only certain types of cards. For example, an eMMC
is MMC only and a uSD slot may be SD only. However the MMC card scanning
logic checks for all card types one by one.

Add host capabilities to specify which card types can be used, and amend
the card scanning logic to skip scanning for those types which cannot be
used.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
Cc: Adrian Hunter <adrian.hunter@nokia.com>
Cc: Ian Molton <ian@mnementh.co.uk>
Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com>
Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Cc: Denis Karpov <ext-denis.2.karpov@nokia.com>
Cc: Pierre Ossman <pierre@ossman.eu>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
drivers/mmc/core/core.c | 16 +++++++++++++++-
drivers/mmc/host/at91_mci.c | 2 +-
drivers/mmc/host/atmel-mci.c | 1 +
drivers/mmc/host/au1xmmc.c | 3 ++-
drivers/mmc/host/cb710-mmc.c | 3 ++-
drivers/mmc/host/imxmmc.c | 3 ++-
drivers/mmc/host/mmc_spi.c | 2 +-
drivers/mmc/host/mmci.c | 2 ++
drivers/mmc/host/mvsdio.c | 3 ++-
drivers/mmc/host/mxcmmc.c | 3 ++-
drivers/mmc/host/omap.c | 2 +-
drivers/mmc/host/pxamci.c | 2 +-
drivers/mmc/host/s3cmci.c | 3 ++-
drivers/mmc/host/sdhci.c | 2 +-
drivers/mmc/host/sdricoh_cs.c | 3 ++-
drivers/mmc/host/tifm_sd.c | 3 ++-
drivers/mmc/host/tmio_mmc.c | 3 ++-
drivers/mmc/host/via-sdmmc.c | 3 ++-
drivers/mmc/host/wbsd.c | 3 ++-
include/linux/mmc/host.h | 3 +++
20 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c5a7857..7d905f9 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1066,7 +1066,11 @@ void mmc_rescan(struct work_struct *work)
mmc_power_up(host);
mmc_go_idle(host);

- mmc_send_if_cond(host, host->ocr_avail);
+ if ((host->caps & MMC_CAP_SDIO) || (host->caps & MMC_CAP_SD))
+ mmc_send_if_cond(host, host->ocr_avail);
+
+ if (!(host->caps & MMC_CAP_SDIO))
+ goto not_sdio;

/*
* First we search for SDIO...
@@ -1078,6 +1082,10 @@ void mmc_rescan(struct work_struct *work)
goto out;
}

+not_sdio:
+ if (!(host->caps & MMC_CAP_SD))
+ goto not_sd;
+
/*
* ...then normal SD...
*/
@@ -1088,6 +1096,10 @@ void mmc_rescan(struct work_struct *work)
goto out;
}

+not_sd:
+ if (!(host->caps & MMC_CAP_MMC))
+ goto not_mmc;
+
/*
* ...and finally MMC.
*/
@@ -1098,6 +1110,8 @@ void mmc_rescan(struct work_struct *work)
goto out;
}

+not_mmc:
+
mmc_release_host(host);
mmc_power_off(host);

diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index e556d42..aa541a5 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -1007,7 +1007,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc->f_min = 375000;
mmc->f_max = 25000000;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = MMC_CAP_SDIO_IRQ;
+ mmc->caps = MMC_CAP_SDIO_IRQ | MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;

mmc->max_blk_size = 4095;
mmc->max_blk_count = mmc->max_req_size;
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 7b603e4..907841a 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1467,6 +1467,7 @@ static int __init atmci_init_slot(struct atmel_mci *host,
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
mmc->f_max = host->bus_hz / 2;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
if (slot_data->bus_width >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;

diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index d3f5561..4aae609 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -1003,7 +1003,8 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
mmc->max_blk_count = 512;

mmc->ocr_avail = AU1XMMC_OCR;
- mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;

host->status = HOST_S_IDLE;

diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index 11efefb..622b420 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -721,7 +721,8 @@ static int __devinit cb710_mmc_init(struct platform_device *pdev)
mmc->f_max = val;
mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX];
mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;

reader = mmc_priv(mmc);

diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index e0be21a..b6653ba 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -962,7 +962,8 @@ static int __init imxmci_probe(struct platform_device *pdev)
mmc->f_min = 150000;
mmc->f_max = CLK_RATE/2;
mmc->ocr_avail = MMC_VDD_32_33;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;

/* MMC core transfer sizes tunable parameters */
mmc->max_hw_segs = 64;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index a461017..e1a3c7f 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1386,7 +1386,7 @@ static int mmc_spi_probe(struct spi_device *spi)
mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE;
mmc->max_blk_count = MMC_SPI_BLOCKSATONCE;

- mmc->caps = MMC_CAP_SPI;
+ mmc->caps = MMC_CAP_SPI | MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;

/* SPI doesn't need the lowspeed device identification thing for
* MMC or SD cards, since it never comes up in open drain mode.
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index e1aa847..55e882b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -557,6 +557,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
mmc->f_max = min(host->mclk, fmax);
mmc->ocr_avail = plat->ocr_mask;

+ mmc->caps = MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
+
/*
* We can do SGIO
*/
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index 34e2348..1c3f4aa 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -734,7 +734,8 @@ static int __init mvsd_probe(struct platform_device *pdev)

mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
- MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
+ MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;

mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
mmc->f_max = maxfreq;
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index bc14bb1..d67d639 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -700,7 +700,8 @@ static int mxcmci_probe(struct platform_device *pdev)
}

mmc->ops = &mxcmci_ops;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC |
+ MMC_CAP_SD | MMC_CAP_SDIO;

/* MMC core transfer sizes tunable parameters */
mmc->max_hw_segs = 64;
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index e7a331d..d6d23e5 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1314,7 +1314,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)

host->slots[id] = slot;

- mmc->caps = 0;
+ mmc->caps = MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
if (host->pdata->slots[id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;

diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index e55ac79..1a71da3 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -598,7 +598,7 @@ static int pxamci_probe(struct platform_device *pdev)

pxamci_init_ocr(host);

- mmc->caps = 0;
+ mmc->caps = MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
host->cmdat = 0;
if (!cpu_is_pxa25x()) {
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 8c08cd7..9d73289 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1376,7 +1376,8 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)

mmc->ops = &s3cmci_ops;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;
mmc->f_min = host->clk_rate / (host->clk_div * 256);
mmc->f_max = host->clk_rate / host->clk_div;

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6779b4e..6334938 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1768,7 +1768,7 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->ops = &sdhci_ops;
mmc->f_min = host->max_clk / 256;
mmc->f_max = host->max_clk;
- mmc->caps = MMC_CAP_SDIO_IRQ;
+ mmc->caps = MMC_CAP_SDIO_IRQ | MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;

if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
mmc->caps |= MMC_CAP_4_BIT_DATA;
diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c
index cb41e9c..7a24bb1 100644
--- a/drivers/mmc/host/sdricoh_cs.c
+++ b/drivers/mmc/host/sdricoh_cs.c
@@ -443,7 +443,8 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev,
mmc->f_min = 450000;
mmc->f_max = 24000000;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps |= MMC_CAP_4_BIT_DATA;
+ mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;

mmc->max_seg_size = 1024 * 512;
mmc->max_blk_size = 512;
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 82554dd..cb170d5 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -973,7 +973,8 @@ static int tifm_sd_probe(struct tifm_dev *sock)

mmc->ops = &tifm_sd_ops;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;
mmc->f_min = 20000000 / 60;
mmc->f_max = 24000000;

diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index c246191..a14d1af 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -555,7 +555,8 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
}

mmc->ops = &tmio_mmc_ops;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;
mmc->f_max = pdata->hclk;
mmc->f_min = mmc->f_max / 512;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 632858a..c6c652a 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1046,7 +1046,8 @@ static void via_init_mmc_host(struct via_crdr_mmc_host *host)
mmc->f_min = VIA_CRDR_MIN_CLOCK;
mmc->f_max = VIA_CRDR_MAX_CLOCK;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
- mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC;
mmc->ops = &via_sdc_ops;

/*Hardware cannot do scatter lists*/
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 89bf8cd..16f0e5b 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1219,7 +1219,8 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
mmc->f_min = 375000;
mmc->f_max = 24000000;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO |
+ MMC_CAP_SD | MMC_CAP_MMC;

spin_lock_init(&host->lock);

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 4ae5766..3902c5c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -150,6 +150,9 @@ struct mmc_host {
#define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */
#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */
+#define MMC_CAP_SDIO (1 << 10) /* Card can be SDIO */
+#define MMC_CAP_SD (1 << 11) /* Card can be SD */
+#define MMC_CAP_MMC (1 << 12) /* Card can be MMC */

/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
--
1.6.4.rc0