Commit 94d89efb authored by Jorg Schummer's avatar Jorg Schummer Committed by Pierre Ossman

mmc: mmc_rescan detects card change in one run

With this patch, mmc_rescan can detect the removal of an mmc card and
the insertion of (possibly another) card in the same run. This means
that a card change can be detected without having to call
mmc_detect_change multiple times.

This change generalises the core such that it can be easily used by
hosts which provide a mechanism to detect only the presence of a card
reader cover, which has to be taken off in order to insert a card. Other
hosts ("card detect" or "MMC_CAP_NEEDS_POLL") each receive an event when
a card is removed and when a card is inserted, so it is sufficient for
them if mmc_rescan handles only one event at a time. "Cover detect"
hosts, however, only receive events about the cover status. This means
that between 2 subsequent events, both a card removal and a card
insertion can occur. In this case, the pre-patch version of mmc_rescan
would only detect the removal of the previous card but not the insertion
of the new card.
Signed-off-by: default avatarJorg Schummer <ext-jorg.2.schummer@nokia.com>
Signed-off-by: default avatarPierre Ossman <pierre@ossman.eu>
parent f3ad1165
...@@ -855,7 +855,23 @@ void mmc_rescan(struct work_struct *work) ...@@ -855,7 +855,23 @@ void mmc_rescan(struct work_struct *work)
mmc_bus_get(host); mmc_bus_get(host);
if (host->bus_ops == NULL) { /* if there is a card registered, check whether it is still present */
if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
host->bus_ops->detect(host);
mmc_bus_put(host);
mmc_bus_get(host);
/* if there still is a card present, stop here */
if (host->bus_ops != NULL) {
mmc_bus_put(host);
goto out;
}
/* detect a newly inserted card */
/* /*
* Only we can add a new handler, so it's safe to * Only we can add a new handler, so it's safe to
* release the lock here. * release the lock here.
...@@ -904,12 +920,7 @@ void mmc_rescan(struct work_struct *work) ...@@ -904,12 +920,7 @@ void mmc_rescan(struct work_struct *work)
mmc_release_host(host); mmc_release_host(host);
mmc_power_off(host); mmc_power_off(host);
} else {
if (host->bus_ops->detect && !host->bus_dead)
host->bus_ops->detect(host);
mmc_bus_put(host);
}
out: out:
if (host->caps & MMC_CAP_NEEDS_POLL) if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ); mmc_schedule_delayed_work(&host->detect, HZ);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment