mmc: sdhci: delay the QoS vote removal
By delaying the QoS vote removal, there is some improvement
in performance in single threaded use cases.
Change-Id: I80545486057c55c697b72b56d57e2ea47cff86b9
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
[xiaonian@codeaurora.org: fixed trivial merge conflict]
Signed-off-by: Xiaonian Wang <xiaonian@codeaurora.org>
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 0a4bcce..1dba926 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -43,6 +43,7 @@
#include "sdhci-msm.h"
#include "cmdq_hci.h"
+#define QOS_REMOVE_DELAY_MS 10
#define CORE_POWER 0x0
#define CORE_SW_RST (1 << 7)
@@ -3149,7 +3150,8 @@
static void sdhci_msm_pm_qos_irq_unvote_work(struct work_struct *work)
{
struct sdhci_msm_pm_qos_irq *pm_qos_irq =
- container_of(work, struct sdhci_msm_pm_qos_irq, unvote_work);
+ container_of(work, struct sdhci_msm_pm_qos_irq,
+ unvote_work.work);
if (atomic_read(&pm_qos_irq->counter))
return;
@@ -3175,7 +3177,7 @@
&& counter > 1)
return;
- cancel_work_sync(&msm_host->pm_qos_irq.unvote_work);
+ cancel_delayed_work_sync(&msm_host->pm_qos_irq.unvote_work);
msm_host->pm_qos_irq.latency = latency->latency[host->power_policy];
pm_qos_update_request(&msm_host->pm_qos_irq.req,
msm_host->pm_qos_irq.latency);
@@ -3201,7 +3203,8 @@
return;
if (async) {
- schedule_work(&msm_host->pm_qos_irq.unvote_work);
+ schedule_delayed_work(&msm_host->pm_qos_irq.unvote_work,
+ msecs_to_jiffies(QOS_REMOVE_DELAY_MS));
return;
}
@@ -3256,7 +3259,7 @@
msm_host->pm_qos_irq.enabled = enable;
if (!enable) {
- cancel_work_sync(&msm_host->pm_qos_irq.unvote_work);
+ cancel_delayed_work_sync(&msm_host->pm_qos_irq.unvote_work);
atomic_set(&msm_host->pm_qos_irq.counter, 0);
msm_host->pm_qos_irq.latency = PM_QOS_DEFAULT_VALUE;
pm_qos_update_request(&msm_host->pm_qos_irq.req,
@@ -3302,7 +3305,7 @@
cpumask_copy(&msm_host->pm_qos_irq.req.cpus_affine,
cpumask_of(msm_host->pdata->pm_qos_data.irq_cpu));
- INIT_WORK(&msm_host->pm_qos_irq.unvote_work,
+ INIT_DELAYED_WORK(&msm_host->pm_qos_irq.unvote_work,
sdhci_msm_pm_qos_irq_unvote_work);
/* For initialization phase, set the performance latency */
irq_latency = &msm_host->pdata->pm_qos_data.irq_latency;
@@ -3396,7 +3399,8 @@
msm_host->pm_qos_group_enable = enable;
if (!enable) {
for (i = 0; i < nr_groups; i++) {
- cancel_work_sync(&msm_host->pm_qos[i].unvote_work);
+ cancel_delayed_work_sync(
+ &msm_host->pm_qos[i].unvote_work);
atomic_set(&msm_host->pm_qos[i].counter, 0);
msm_host->pm_qos[i].latency = PM_QOS_DEFAULT_VALUE;
pm_qos_update_request(&msm_host->pm_qos[i].req,
@@ -3445,7 +3449,7 @@
&& counter > 1)
return;
- cancel_work_sync(&pm_qos_group->unvote_work);
+ cancel_delayed_work_sync(&pm_qos_group->unvote_work);
pm_qos_group->latency = latency->latency[host->power_policy];
pm_qos_update_request(&pm_qos_group->req, pm_qos_group->latency);
@@ -3454,7 +3458,8 @@
static void sdhci_msm_pm_qos_cpu_unvote_work(struct work_struct *work)
{
struct sdhci_msm_pm_qos_group *group =
- container_of(work, struct sdhci_msm_pm_qos_group, unvote_work);
+ container_of(work, struct sdhci_msm_pm_qos_group,
+ unvote_work.work);
if (atomic_read(&group->counter))
return;
@@ -3474,7 +3479,8 @@
return false;
if (async) {
- schedule_work(&msm_host->pm_qos[group].unvote_work);
+ schedule_delayed_work(&msm_host->pm_qos[group].unvote_work,
+ msecs_to_jiffies(QOS_REMOVE_DELAY_MS));
return true;
}
@@ -3504,7 +3510,7 @@
for (i = 0; i < nr_groups; i++) {
group = &msm_host->pm_qos[i];
- INIT_WORK(&group->unvote_work,
+ INIT_DELAYED_WORK(&group->unvote_work,
sdhci_msm_pm_qos_cpu_unvote_work);
atomic_set(&group->counter, 0);
group->req.type = PM_QOS_REQ_AFFINE_CORES;
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index 0edf3b6..2fa2145 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -111,7 +111,7 @@
*/
struct sdhci_msm_pm_qos_group {
struct pm_qos_request req;
- struct work_struct unvote_work;
+ struct delayed_work unvote_work;
atomic_t counter;
s32 latency;
};
@@ -119,7 +119,7 @@
/* PM QoS HW IRQ voting */
struct sdhci_msm_pm_qos_irq {
struct pm_qos_request req;
- struct work_struct unvote_work;
+ struct delayed_work unvote_work;
struct device_attribute enable_attr;
struct device_attribute status_attr;
atomic_t counter;