Loading drivers/mmc/host/sdhci-msm.c +38 −4 Original line number Diff line number Diff line Loading @@ -3882,7 +3882,8 @@ void sdhci_msm_pm_qos_irq_unvote(struct sdhci_host *host, bool async) return; if (async) { schedule_delayed_work(&msm_host->pm_qos_irq.unvote_work, queue_delayed_work(msm_host->pm_qos_wq, &msm_host->pm_qos_irq.unvote_work, msecs_to_jiffies(QOS_REMOVE_DELAY_MS)); return; } Loading Loading @@ -3960,6 +3961,33 @@ static inline void set_affine_irq(struct sdhci_msm_host *msm_host, struct sdhci_host *host) { } #endif static bool sdhci_msm_pm_qos_wq_init(struct sdhci_msm_host *msm_host) { char *wq = NULL; bool ret = true; wq = kasprintf(GFP_KERNEL, "sdhci_msm_pm_qos/%s", dev_name(&msm_host->pdev->dev)); if (!wq) return false; /* * Create a work queue with flag WQ_MEM_RECLAIM set for * pm_qos_unvote work. Because mmc thread is created with * flag PF_MEMALLOC set, kernel will check for work queue * flag WQ_MEM_RECLAIM when flush the work queue. If work * queue flag WQ_MEM_RECLAIM is not set, kernel warning * will be triggered. */ msm_host->pm_qos_wq = create_workqueue(wq); if (!msm_host->pm_qos_wq) { ret = false; dev_err(&msm_host->pdev->dev, "failed to create pm qos unvote work queue\n"); } kfree(wq); return ret; } void sdhci_msm_pm_qos_irq_init(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); Loading @@ -3984,6 +4012,8 @@ void sdhci_msm_pm_qos_irq_init(struct sdhci_host *host) cpumask_copy(&msm_host->pm_qos_irq.req.cpus_affine, cpumask_of(msm_host->pdata->pm_qos_data.irq_cpu)); sdhci_msm_pm_qos_wq_init(msm_host); INIT_DELAYED_WORK(&msm_host->pm_qos_irq.unvote_work, sdhci_msm_pm_qos_irq_unvote_work); /* For initialization phase, set the performance latency */ Loading Loading @@ -4158,7 +4188,8 @@ bool sdhci_msm_pm_qos_cpu_unvote(struct sdhci_host *host, int cpu, bool async) return false; if (async) { schedule_delayed_work(&msm_host->pm_qos[group].unvote_work, queue_delayed_work(msm_host->pm_qos_wq, &msm_host->pm_qos[group].unvote_work, msecs_to_jiffies(QOS_REMOVE_DELAY_MS)); return true; } Loading Loading @@ -5097,6 +5128,9 @@ static int sdhci_msm_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &msm_host->polling); device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw); pm_runtime_disable(&pdev->dev); if (msm_host->pm_qos_wq) destroy_workqueue(msm_host->pm_qos_wq); sdhci_remove_host(host, dead); sdhci_pltfm_free(pdev); Loading drivers/mmc/host/sdhci-msm.h +2 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,8 @@ struct sdhci_msm_host { bool pltfm_init_done; struct sdhci_msm_regs_restore regs_restore; bool use_7nm_dll; int soc_min_rev; struct workqueue_struct *pm_qos_wq; }; extern char *saved_command_line; Loading Loading
drivers/mmc/host/sdhci-msm.c +38 −4 Original line number Diff line number Diff line Loading @@ -3882,7 +3882,8 @@ void sdhci_msm_pm_qos_irq_unvote(struct sdhci_host *host, bool async) return; if (async) { schedule_delayed_work(&msm_host->pm_qos_irq.unvote_work, queue_delayed_work(msm_host->pm_qos_wq, &msm_host->pm_qos_irq.unvote_work, msecs_to_jiffies(QOS_REMOVE_DELAY_MS)); return; } Loading Loading @@ -3960,6 +3961,33 @@ static inline void set_affine_irq(struct sdhci_msm_host *msm_host, struct sdhci_host *host) { } #endif static bool sdhci_msm_pm_qos_wq_init(struct sdhci_msm_host *msm_host) { char *wq = NULL; bool ret = true; wq = kasprintf(GFP_KERNEL, "sdhci_msm_pm_qos/%s", dev_name(&msm_host->pdev->dev)); if (!wq) return false; /* * Create a work queue with flag WQ_MEM_RECLAIM set for * pm_qos_unvote work. Because mmc thread is created with * flag PF_MEMALLOC set, kernel will check for work queue * flag WQ_MEM_RECLAIM when flush the work queue. If work * queue flag WQ_MEM_RECLAIM is not set, kernel warning * will be triggered. */ msm_host->pm_qos_wq = create_workqueue(wq); if (!msm_host->pm_qos_wq) { ret = false; dev_err(&msm_host->pdev->dev, "failed to create pm qos unvote work queue\n"); } kfree(wq); return ret; } void sdhci_msm_pm_qos_irq_init(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); Loading @@ -3984,6 +4012,8 @@ void sdhci_msm_pm_qos_irq_init(struct sdhci_host *host) cpumask_copy(&msm_host->pm_qos_irq.req.cpus_affine, cpumask_of(msm_host->pdata->pm_qos_data.irq_cpu)); sdhci_msm_pm_qos_wq_init(msm_host); INIT_DELAYED_WORK(&msm_host->pm_qos_irq.unvote_work, sdhci_msm_pm_qos_irq_unvote_work); /* For initialization phase, set the performance latency */ Loading Loading @@ -4158,7 +4188,8 @@ bool sdhci_msm_pm_qos_cpu_unvote(struct sdhci_host *host, int cpu, bool async) return false; if (async) { schedule_delayed_work(&msm_host->pm_qos[group].unvote_work, queue_delayed_work(msm_host->pm_qos_wq, &msm_host->pm_qos[group].unvote_work, msecs_to_jiffies(QOS_REMOVE_DELAY_MS)); return true; } Loading Loading @@ -5097,6 +5128,9 @@ static int sdhci_msm_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &msm_host->polling); device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw); pm_runtime_disable(&pdev->dev); if (msm_host->pm_qos_wq) destroy_workqueue(msm_host->pm_qos_wq); sdhci_remove_host(host, dead); sdhci_pltfm_free(pdev); Loading
drivers/mmc/host/sdhci-msm.h +2 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,8 @@ struct sdhci_msm_host { bool pltfm_init_done; struct sdhci_msm_regs_restore regs_restore; bool use_7nm_dll; int soc_min_rev; struct workqueue_struct *pm_qos_wq; }; extern char *saved_command_line; Loading