Provide lightweight online and offline operations. This saves us from parsing all the resources each time the CPU is put online. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> --- drivers/cpufreq/qcom-cpufreq-hw.c | 39 +++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index fe638e141003..d38b1552ec13 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -403,11 +403,12 @@ static const struct of_device_id qcom_cpufreq_hw_match[] = { }; MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match); +static int qcom_cpufreq_hw_lmh_online(struct cpufreq_policy *policy); + static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index) { struct qcom_cpufreq_data *data = policy->driver_data; struct platform_device *pdev = cpufreq_get_driver_data(); - int ret; /* * Look for LMh interrupt. If no interrupt line is specified / @@ -419,12 +420,21 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index) if (data->throttle_irq < 0) return data->throttle_irq; - data->cancel_throttle = false; - data->policy = policy; - mutex_init(&data->throttle_lock); INIT_DEFERRABLE_WORK(&data->throttle_work, qcom_lmh_dcvs_poll); + return qcom_cpufreq_hw_lmh_online(policy); +} + +static int qcom_cpufreq_hw_lmh_online(struct cpufreq_policy *policy) +{ + struct qcom_cpufreq_data *data = policy->driver_data; + struct platform_device *pdev = cpufreq_get_driver_data(); + int ret; + + data->cancel_throttle = false; + data->policy = policy; + snprintf(data->irq_name, sizeof(data->irq_name), "dcvsh-irq-%u", policy->cpu); ret = request_threaded_irq(data->throttle_irq, NULL, qcom_lmh_dcvs_handle_irq, IRQF_ONESHOT | IRQF_NO_AUTOEN, data->irq_name, data); @@ -441,10 +451,12 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index) return 0; } -static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) +static int qcom_cpufreq_hw_lmh_offline(struct cpufreq_policy *policy) { + struct qcom_cpufreq_data *data = policy->driver_data; + if (data->throttle_irq <= 0) - return; + return 0; mutex_lock(&data->throttle_lock); data->cancel_throttle = true; @@ -453,6 +465,8 @@ static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) cancel_delayed_work_sync(&data->throttle_work); irq_set_affinity_hint(data->throttle_irq, NULL); free_irq(data->throttle_irq, data); + + return 0; } static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) @@ -567,6 +581,16 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) return ret; } +static int qcom_cpufreq_hw_cpu_online(struct cpufreq_policy *policy) +{ + return qcom_cpufreq_hw_lmh_online(policy); +} + +static int qcom_cpufreq_hw_cpu_offline(struct cpufreq_policy *policy) +{ + return qcom_cpufreq_hw_lmh_offline(policy); +} + static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) { struct device *cpu_dev = get_cpu_device(policy->cpu); @@ -576,7 +600,6 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) dev_pm_opp_remove_all_dynamic(cpu_dev); dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); - qcom_cpufreq_hw_lmh_exit(data); kfree(policy->freq_table); kfree(data); iounmap(base); @@ -608,6 +631,8 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = { .get = qcom_cpufreq_hw_get, .init = qcom_cpufreq_hw_cpu_init, .exit = qcom_cpufreq_hw_cpu_exit, + .online = qcom_cpufreq_hw_cpu_online, + .offline = qcom_cpufreq_hw_cpu_offline, .register_em = cpufreq_register_em_with_opp, .fast_switch = qcom_cpufreq_hw_fast_switch, .name = "qcom-cpufreq-hw", -- 2.34.1