From patchwork Tue Jul 28 10:39:27 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 37706 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6SAgdbb011652 for ; Tue, 28 Jul 2009 10:42:40 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752872AbZG1Kj3 (ORCPT ); Tue, 28 Jul 2009 06:39:29 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1750918AbZG1Kj2 (ORCPT ); Tue, 28 Jul 2009 06:39:28 -0400 Received: from smtp.nokia.com ([192.100.122.230]:32000 "EHLO mgw-mx03.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752199AbZG1KjY (ORCPT ); Tue, 28 Jul 2009 06:39:24 -0400 Received: from esebh105.NOE.Nokia.com (esebh105.ntc.nokia.com [172.21.138.211]) by mgw-mx03.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id n6SAcpJC020627; Tue, 28 Jul 2009 13:39:07 +0300 Received: from vaebh104.NOE.Nokia.com ([10.160.244.30]) by esebh105.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 28 Jul 2009 13:38:56 +0300 Received: from mgw-sa01.ext.nokia.com ([147.243.1.47]) by vaebh104.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Tue, 28 Jul 2009 13:38:55 +0300 Received: from [127.0.1.1] (esdhcp04057.research.nokia.com [172.21.40.57]) by mgw-sa01.ext.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id n6SAcqTD002726; Tue, 28 Jul 2009 13:38:53 +0300 From: Adrian Hunter To: Andrew Morton Cc: Jarkko Lavinen , Adrian Hunter , linux-omap Mailing List , Pierre Ossman , Denis Karpov , Matt Fleming , lkml Date: Tue, 28 Jul 2009 13:39:27 +0300 Message-Id: <20090728103927.2371.39582.sendpatchset@ahunter-laptop> In-Reply-To: <20090728103834.2371.65809.sendpatchset@ahunter-laptop> References: <20090728103834.2371.65809.sendpatchset@ahunter-laptop> Subject: [PATCH V2 7/32] mmc: add host capabilities for SD only and MMC only X-OriginalArrivalTime: 28 Jul 2009 10:38:55.0937 (UTC) FILETIME=[9B930310:01CA0F6F] X-Nokia-AV: Clean Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From f22d0fb3d25771f4e380176e99d55068b78f0c17 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 25 Jul 2009 23:52:37 +0000 Subject: [PATCH] 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 Cc: Adrian Hunter Cc: Ian Molton Cc: "Roberto A. Foglietta" Cc: Jarkko Lavinen Cc: Denis Karpov Cc: Pierre Ossman Cc: Andrew Morton --- 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/omap_hsmmc.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 +++ 21 files changed, 50 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8d03da4..5fe51ff 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1069,7 +1069,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... @@ -1081,6 +1085,10 @@ void mmc_rescan(struct work_struct *work) goto out; } +not_sdio: + if (!(host->caps & MMC_CAP_SD)) + goto not_sd; + /* * ...then normal SD... */ @@ -1091,6 +1099,10 @@ void mmc_rescan(struct work_struct *work) goto out; } +not_sd: + if (!(host->caps & MMC_CAP_MMC)) + goto not_mmc; + /* * ...and finally MMC. */ @@ -1101,6 +1113,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/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 1cf9cfb..056bcaf 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1080,6 +1080,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev) else if (pdata->slots[host->slot_id].wires >= 4) mmc->caps |= MMC_CAP_4_BIT_DATA; + mmc->caps |= MMC_CAP_SDIO | MMC_CAP_SD | MMC_CAP_MMC; + omap_hsmmc_init(host); /* Select DMA lines */ 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 91991b4..a708bb6 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -553,7 +553,8 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) goto unmap_ctl; 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 81bb423..ca6d733 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 */