diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index e46474cc477b..9315a06343f7 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -60,6 +60,19 @@ In the following, can be vdd (flash core voltage) or vdd-io (I/O voltag - pinctrl-names - pinctrl-0, pinctrl-1,.. pinctrl-n + - qcom,cpu-affinity: this is a string that specifies the pm QoS request + type. The supported cpu affinity modes are : + "all_cores" - PM_QOS_REQ_ALL_CORES is applicable to all CPU cores that + are online and this would have a power impact when there are more + number of CPUs. + "affine_irq" - PM_QOS_REQ_AFFINE_IRQ request type shall update/apply + the vote only to that CPU to which this IRQ's affinity is set to. + "affine_cores" - PM_QOS_REQ_AFFINE_CORES request type is used for + targets that have little cluster and will update/apply the vote to + all the cores in the little cluster. + The default CPU affinity mode is PM_QOS_REQ_AFFINE_IRQ to maintain + backward compatibility. + Example: aliases { diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index e23b169beeef..8ef9478a549e 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -266,6 +266,7 @@ struct sdhci_msm_pltfm_data { struct sdhci_msm_bus_voting_data *voting_data; u32 *sup_clk_table; unsigned char sup_clk_cnt; + enum pm_qos_req_type cpu_affinity_type; }; struct sdhci_msm_bus_vote { @@ -1402,6 +1403,30 @@ out: return ret; } +#ifdef CONFIG_SMP +static void sdhci_msm_populate_affinity_type(struct sdhci_msm_pltfm_data *pdata, + struct device_node *np) +{ + const char *cpu_affinity = NULL; + + pdata->cpu_affinity_type = PM_QOS_REQ_AFFINE_IRQ; + if (!of_property_read_string(np, "qcom,cpu-affinity", + &cpu_affinity)) { + if (!strcmp(cpu_affinity, "all_cores")) + pdata->cpu_affinity_type = PM_QOS_REQ_ALL_CORES; + else if (!strcmp(cpu_affinity, "affine_cores")) + pdata->cpu_affinity_type = PM_QOS_REQ_AFFINE_CORES; + else if (!strcmp(cpu_affinity, "affine_irq")) + pdata->cpu_affinity_type = PM_QOS_REQ_AFFINE_IRQ; + } +} +#else +static void sdhci_msm_populate_affinity_type(struct sdhci_msm_pltfm_data *pdata, + struct device_node *np) +{ +} +#endif + /* Parse platform data */ static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev) { @@ -1508,6 +1533,8 @@ static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev) if (of_get_property(np, "qcom,nonhotplug", NULL)) pdata->nonhotplug = true; + sdhci_msm_populate_affinity_type(pdata, np); + return pdata; out: return NULL; @@ -3061,6 +3088,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) msm_host->mmc->caps2 |= MMC_CAP2_NONHOTPLUG; host->cpu_dma_latency_us = msm_host->pdata->cpu_dma_latency_us; + host->pm_qos_req_dma.type = msm_host->pdata->cpu_affinity_type; init_completion(&msm_host->pwr_irq_completion); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a65e9575632f..116e6083032f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3218,7 +3218,6 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host); #ifdef CONFIG_SMP static void sdhci_set_pmqos_req_type(struct sdhci_host *host) { - /* * The default request type PM_QOS_REQ_ALL_CORES is * applicable to all CPU cores that are online and @@ -3226,9 +3225,14 @@ static void sdhci_set_pmqos_req_type(struct sdhci_host *host) * number of CPUs. This new PM_QOS_REQ_AFFINE_IRQ request * type shall update/apply the vote only to that CPU to * which this IRQ's affinity is set to. + * PM_QOS_REQ_AFFINE_CORES request type is used for targets that have + * little cluster and will update/apply the vote to all the cores in + * the little cluster. */ - host->pm_qos_req_dma.type = PM_QOS_REQ_AFFINE_IRQ; - host->pm_qos_req_dma.irq = host->irq; + if (host->pm_qos_req_dma.type == PM_QOS_REQ_AFFINE_CORES) + host->pm_qos_req_dma.cpus_affine.bits[0] = 0x0F; + else if (host->pm_qos_req_dma.type == PM_QOS_REQ_AFFINE_IRQ) + host->pm_qos_req_dma.irq = host->irq; } #else static void sdhci_set_pmqos_req_type(struct sdhci_host *host)