summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorJerry Huang <Chang-Ming.Huang@freescale.com>2011-12-06 09:22:27 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-03-27 22:14:37 (GMT)
commit6f4d0527c298e2562e5db28287a3d00bbc7d6d77 (patch)
treeb10a1457d07fdf233d70ffcda1419d11cbfbab64 /drivers/mmc
parent21140ad1ab51e709674459622fdfaf8c27fec7d3 (diff)
downloadlinux-fsl-qoriq-6f4d0527c298e2562e5db28287a3d00bbc7d6d77.tar.xz
MMC/SD: Add callback function to detect card
In order to check whether the card has been removed, the function mmc_send_status() will send command CMD13 to card and ask the card to send its status register to sdhc driver, which will generate many interrupts repeatedly and make the system performance bad. From the performance test on Freescale's board (such as Iozone for SD), the performance will degrade about 4~6%. There is one another way to get this information, which is to read the register PRSSTAT and check the bit CDPL or CINS. If the card is present, these two bit will set to one. Therefore, add callback function get_cd() to check whether the card has been inserted/removed when the driver supports this feature. If the card is present, 0 will return, if the card is absent, 1 will return. If the controller will not support this feature, -ENOSYS will return. Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com> Change-Id: I283647abef07d9f88e76efed0061fc73f8a78698 Reviewed-on: http://git.am.freescale.net:8181/486 Reviewed-by: Xie Xiaobo-R63061 <X.Xie@freescale.com> Reviewed-by: Phillips Kim-R1AAHA <Kim.Phillips@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/core.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index aaed768..89b793e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2100,7 +2100,7 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
int _mmc_detect_card_removed(struct mmc_host *host)
{
- int ret;
+ int ret = -ENOSYS;
if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive)
return 0;
@@ -2108,7 +2108,19 @@ int _mmc_detect_card_removed(struct mmc_host *host)
if (!host->card || mmc_card_removed(host->card))
return 1;
- ret = host->bus_ops->alive(host);
+ /* First, try host-controller's card detect callback */
+ if (host->ops->get_cd) {
+ ret = host->ops->get_cd(host);
+ /*
+ * The return value from get_cd: 1 for present, 0 for absent,
+ * we need to convert it to: 1 for absent, 0 for present.
+ */
+ if (ret >= 0)
+ ret = !ret;
+ }
+ /* If failed, back to the bus_ops alive() callback */
+ if (ret < 0)
+ ret = host->bus_ops->alive(host);
if (ret) {
mmc_card_set_removed(host->card);
pr_debug("%s: card remove detected\n", mmc_hostname(host));