mmc: core: keep consistent with upstream
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / core / core.c
index 08c5d7fa6cf9fe2a5ce21cc4902af9d12fce8926..5afb319bb40e2fcc2dd57357c8619c6304eb2308 100644 (file)
@@ -29,8 +29,8 @@
 #include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/of.h>
-#include <linux/wakelock.h>
 
+#define CREATE_TRACE_POINTS
 #include <trace/events/mmc.h>
 
 #include <linux/mmc/card.h>
 #include "sd_ops.h"
 #include "sdio_ops.h"
 
+EXPORT_TRACEPOINT_SYMBOL_GPL(mmc_blk_erase_start);
+EXPORT_TRACEPOINT_SYMBOL_GPL(mmc_blk_erase_end);
+EXPORT_TRACEPOINT_SYMBOL_GPL(mmc_blk_rw_start);
+EXPORT_TRACEPOINT_SYMBOL_GPL(mmc_blk_rw_end);
+
 /* If the device is not responding */
 #define MMC_CORE_TIMEOUT_MS    (10 * 60 * 1000) /* 10 minute timeout */
 
@@ -58,8 +63,6 @@
  */
 #define MMC_BKOPS_MAX_TIMEOUT  (4 * 60 * 1000) /* max time to wait in ms */
 
-static struct workqueue_struct *workqueue;
-static struct wake_lock mmc_delayed_work_wake_lock;
 static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
 
 /*
@@ -70,22 +73,16 @@ static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
 bool use_spi_crc = 1;
 module_param(use_spi_crc, bool, 0);
 
-/*
- * Internal function. Schedule delayed work in the MMC work queue.
- */
 static int mmc_schedule_delayed_work(struct delayed_work *work,
                                     unsigned long delay)
 {
-       wake_lock(&mmc_delayed_work_wake_lock);
-       return queue_delayed_work(workqueue, work, delay);
-}
-
-/*
- * Internal function. Flush all scheduled work from the MMC work queue.
- */
-static void mmc_flush_scheduled_work(void)
-{
-       flush_workqueue(workqueue);
+       /*
+        * We use the system_freezable_wq, because of two reasons.
+        * First, it allows several works (not the same work item) to be
+        * executed simultaneously. Second, the queue becomes frozen when
+        * userspace becomes frozen during system PM.
+        */
+       return queue_delayed_work(system_freezable_wq, work, delay);
 }
 
 #ifdef CONFIG_FAIL_MMC_REQUEST
@@ -1135,6 +1132,11 @@ void mmc_set_initial_state(struct mmc_host *host)
        host->ios.bus_width = MMC_BUS_WIDTH_1;
        host->ios.timing = MMC_TIMING_LEGACY;
        host->ios.drv_type = 0;
+       host->ios.enhanced_strobe = false;
+
+       if ((host->caps2 & MMC_CAP2_HS400_ES) &&
+               host->ops->hs400_enhanced_strobe)
+               host->ops->hs400_enhanced_strobe(host, &host->ios);
 
        mmc_set_ios(host);
 }
@@ -2602,7 +2604,6 @@ void mmc_rescan(struct work_struct *work)
        struct mmc_host *host =
                container_of(work, struct mmc_host, detect.work);
        int i;
-       bool extend_wakelock = false;
 
        if (host->trigger_card_event && host->ops->card_event) {
                host->ops->card_event(host);
@@ -2629,12 +2630,6 @@ void mmc_rescan(struct work_struct *work)
 
        host->detect_change = 0;
 
-       /* If the card was removed the bus will be marked
-        * as dead - extend the wakelock so userspace
-        * can respond */
-       if (host->bus_dead)
-               extend_wakelock = 1;
-
        /*
         * Let mmc_bus_put() free the bus/bus_ops if we've found that
         * the card is no longer present.
@@ -2664,20 +2659,14 @@ void mmc_rescan(struct work_struct *work)
 
        mmc_claim_host(host);
        for (i = 0; i < ARRAY_SIZE(freqs); i++) {
-               if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) {
-                       extend_wakelock = true;
+               if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
                        break;
-               }
                if (freqs[i] <= host->f_min)
                        break;
        }
        mmc_release_host(host);
 
  out:
-       if (extend_wakelock)
-               wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
-       else
-               wake_unlock(&mmc_delayed_work_wake_lock);
        if (host->caps & MMC_CAP_NEEDS_POLL)
                mmc_schedule_delayed_work(&host->detect, HZ);
 }
@@ -2712,7 +2701,6 @@ void mmc_stop_host(struct mmc_host *host)
 
        host->rescan_disable = 1;
        cancel_delayed_work_sync(&host->detect);
-       mmc_flush_scheduled_work();
 
        /* clear pm flags now and let card drivers set them as needed */
        host->pm_flags = 0;
@@ -2901,16 +2889,9 @@ static int __init mmc_init(void)
 {
        int ret;
 
-       workqueue = alloc_ordered_workqueue("kmmcd", 0);
-       if (!workqueue)
-               return -ENOMEM;
-
-       wake_lock_init(&mmc_delayed_work_wake_lock, WAKE_LOCK_SUSPEND,
-                      "mmc_delayed_work");
-
        ret = mmc_register_bus();
        if (ret)
-               goto destroy_workqueue;
+               return ret;
 
        ret = mmc_register_host_class();
        if (ret)
@@ -2926,10 +2907,6 @@ unregister_host_class:
        mmc_unregister_host_class();
 unregister_bus:
        mmc_unregister_bus();
-destroy_workqueue:
-       destroy_workqueue(workqueue);
-       wake_lock_destroy(&mmc_delayed_work_wake_lock);
-
        return ret;
 }
 
@@ -2938,8 +2915,6 @@ static void __exit mmc_exit(void)
        sdio_unregister_bus();
        mmc_unregister_host_class();
        mmc_unregister_bus();
-       destroy_workqueue(workqueue);
-       wake_lock_destroy(&mmc_delayed_work_wake_lock);
 }
 
 subsys_initcall(mmc_init);