WorkStruct: make allyesconfig
[deliverable/linux.git] / drivers / mmc / mmc.c
index 5b9caa7978d34311839840243e38921255f6da4b..21fd39e4a20f2b437cd05b0c3ae0ee8e42cf83c1 100644 (file)
@@ -475,7 +475,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
        if (bit) {
                bit -= 1;
 
-               ocr = 3 << bit;
+               ocr &= 3 << bit;
 
                host->ios.vdd = bit;
                mmc_set_ios(host);
@@ -1165,27 +1165,40 @@ static void mmc_setup(struct mmc_host *host)
  */
 void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 {
-       if (delay)
-               schedule_delayed_work(&host->detect, delay);
-       else
-               schedule_work(&host->detect);
+       mmc_schedule_delayed_work(&host->detect, delay);
 }
 
 EXPORT_SYMBOL(mmc_detect_change);
 
 
-static void mmc_rescan(void *data)
+static void mmc_rescan(struct work_struct *work)
 {
-       struct mmc_host *host = data;
+       struct mmc_host *host =
+               container_of(work, struct mmc_host, detect.work);
        struct list_head *l, *n;
+       unsigned char power_mode;
 
        mmc_claim_host(host);
 
-       if (host->ios.power_mode == MMC_POWER_ON)
+       /*
+        * Check for removed cards and newly inserted ones. We check for
+        * removed cards first so we can intelligently re-select the VDD.
+        */
+       power_mode = host->ios.power_mode;
+       if (power_mode == MMC_POWER_ON)
                mmc_check_cards(host);
 
        mmc_setup(host);
 
+       /*
+        * Some broken cards process CMD1 even in stand-by state. There is
+        * no reply, but an ILLEGAL_COMMAND error is cached and returned
+        * after next command. We poll for card status here to clear any
+        * possibly pending error.
+        */
+       if (power_mode == MMC_POWER_ON)
+               mmc_check_cards(host);
+
        if (!list_empty(&host->cards)) {
                /*
                 * (Re-)calculate the fastest clock rate which the
@@ -1244,7 +1257,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
                spin_lock_init(&host->lock);
                init_waitqueue_head(&host->wq);
                INIT_LIST_HEAD(&host->cards);
-               INIT_WORK(&host->detect, mmc_rescan, host);
+               INIT_DELAYED_WORK(&host->detect, mmc_rescan);
 
                /*
                 * By default, hosts do not support SGIO or large requests.
@@ -1311,7 +1324,7 @@ EXPORT_SYMBOL(mmc_remove_host);
  */
 void mmc_free_host(struct mmc_host *host)
 {
-       flush_scheduled_work();
+       mmc_flush_scheduled_work();
        mmc_free_host_sysfs(host);
 }
 
@@ -1342,7 +1355,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-       mmc_rescan(host);
+       mmc_rescan(&host->detect.work);
 
        return 0;
 }
This page took 0.025603 seconds and 5 git commands to generate.