scsi: ufs: add dedicated workqueue with high priority
authorhgchu <hg.chu@samsung.com>
Fri, 12 Jan 2018 04:12:25 +0000 (13:12 +0900)
committerJaeHun Jung <jh0801.jung@samsung.com>
Tue, 8 May 2018 08:20:24 +0000 (17:20 +0900)
Change-Id: Id317ef9527702ae7a2d5b85f51fddc0a4aaa5c84
Signed-off-by: hgchu <hg.chu@samsung.com>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

index 54fe87af197b9d4e0500458ef1877d2ef15f0003..3983c38cbf4f7b9a61ac07674e8bb206eeef2890 100644 (file)
@@ -1517,7 +1517,7 @@ start:
                hba->clk_gating.state = REQ_CLKS_ON;
                trace_ufshcd_clk_gating(dev_name(hba->dev),
                                        hba->clk_gating.state);
-               schedule_work(&hba->clk_gating.ungate_work);
+               queue_work(hba->ufshcd_workq, &hba->clk_gating.ungate_work);
                /*
                 * fall through to check if we should wait for this
                 * work to be done or not.
@@ -1643,7 +1643,7 @@ static void __ufshcd_release(struct ufs_hba *hba)
 
        hba->clk_gating.state = REQ_CLKS_OFF;
        trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state);
-       schedule_delayed_work(&hba->clk_gating.gate_work,
+       queue_delayed_work(hba->ufshcd_workq, &hba->clk_gating.gate_work,
                        msecs_to_jiffies(hba->clk_gating.delay_ms));
 }
 
@@ -1715,10 +1715,18 @@ out:
        return count;
 }
 
-static void ufshcd_init_clk_gating(struct ufs_hba *hba)
+static int ufshcd_init_clk_gating(struct ufs_hba *hba)
 {
+       int ret = 0;
+
        if (!ufshcd_is_clkgating_allowed(hba))
-               return;
+               goto out;
+
+       hba->ufshcd_workq = alloc_workqueue("ufshcd_wq", WQ_HIGHPRI, 0);
+       if (!hba->ufshcd_workq) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        hba->clk_gating.delay_ms = LINK_H8_DELAY;
        INIT_DELAYED_WORK(&hba->clk_gating.gate_work, ufshcd_gate_work);
@@ -1741,12 +1749,16 @@ static void ufshcd_init_clk_gating(struct ufs_hba *hba)
        hba->clk_gating.enable_attr.attr.mode = 0644;
        if (device_create_file(hba->dev, &hba->clk_gating.enable_attr))
                dev_err(hba->dev, "Failed to create sysfs for clkgate_enable\n");
+               
+out:
+       return ret;             
 }
 
 static void ufshcd_exit_clk_gating(struct ufs_hba *hba)
 {
        if (!ufshcd_is_clkgating_allowed(hba))
                return;
+       destroy_workqueue(hba->ufshcd_workq);
        device_remove_file(hba->dev, &hba->clk_gating.delay_attr);
        device_remove_file(hba->dev, &hba->clk_gating.enable_attr);
 }
@@ -8217,7 +8229,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
        /* Initialize device management tag acquire wait queue */
        init_waitqueue_head(&hba->dev_cmd.tag_wq);
 
-       ufshcd_init_clk_gating(hba);
+       
+       err = ufshcd_init_clk_gating(hba);
+       if (err) {
+               dev_err(hba->dev, "init clk_gating failed\n");
+               goto out_disable;
+       }
 
        /*
         * In order to avoid any spurious interrupt immediately after
index 00930bc7984c79b94a89ad0e04d989567d5dd992..0d85630b7536b215991e8e08cdef79424e510730 100644 (file)
@@ -630,6 +630,7 @@ struct ufs_hba {
        struct ufs_init_prefetch init_prefetch_data;
 
        /* Work Queues */
+       struct workqueue_struct *ufshcd_workq;
        struct work_struct eh_work;
        struct work_struct eeh_work;