From patchwork Mon Jun 13 12:43:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Luba X-Patchwork-Id: 581566 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49212C43334 for ; Mon, 13 Jun 2022 17:27:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238445AbiFMR1q (ORCPT ); Mon, 13 Jun 2022 13:27:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234721AbiFMR1Z (ORCPT ); Mon, 13 Jun 2022 13:27:25 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 63CEB60075; Mon, 13 Jun 2022 05:43:41 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4329D1042; Mon, 13 Jun 2022 05:43:41 -0700 (PDT) Received: from e123648.arm.com (unknown [10.57.35.216]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 26DB63F73B; Mon, 13 Jun 2022 05:43:39 -0700 (PDT) From: Lukasz Luba To: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Cc: daniel.lezcano@linaro.org, amitk@kernel.org, rui.zhang@intel.com, lukasz.luba@arm.com, viresh.kumar@linaro.org, rafael@kernel.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, mingo@redhat.com Subject: [PATCH v2 1/4] thermal: cpufreq_cooling: Use private callback ops for each cooling device Date: Mon, 13 Jun 2022 13:43:24 +0100 Message-Id: <20220613124327.30766-2-lukasz.luba@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220613124327.30766-1-lukasz.luba@arm.com> References: <20220613124327.30766-1-lukasz.luba@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org It is very unlikely that one CPU cluster would have the EM and some other won't have it (because EM registration failed or DT lacks needed entry). Although, we should avoid modifying global variable with callbacks anyway. Redesign this and add safety for such situation. Signed-off-by: Lukasz Luba Acked-by: Viresh Kumar --- drivers/thermal/cpufreq_cooling.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index b8151d95a806..ad8b86f5281b 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -59,6 +59,7 @@ struct time_in_idle { * @cdev: thermal_cooling_device pointer to keep track of the * registered cooling device. * @policy: cpufreq policy. + * @cooling_ops: cpufreq callbacks to thermal cooling device ops * @idle_time: idle time stats * @qos_req: PM QoS contraint to apply * @@ -71,6 +72,7 @@ struct cpufreq_cooling_device { unsigned int max_level; struct em_perf_domain *em; struct cpufreq_policy *policy; + struct thermal_cooling_device_ops cooling_ops; #ifndef CONFIG_SMP struct time_in_idle *idle_time; #endif @@ -485,14 +487,6 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, return ret; } -/* Bind cpufreq callbacks to thermal cooling device ops */ - -static struct thermal_cooling_device_ops cpufreq_cooling_ops = { - .get_max_state = cpufreq_get_max_state, - .get_cur_state = cpufreq_get_cur_state, - .set_cur_state = cpufreq_set_cur_state, -}; - /** * __cpufreq_cooling_register - helper function to create cpufreq cooling device * @np: a valid struct device_node to the cooling device device tree node @@ -554,7 +548,10 @@ __cpufreq_cooling_register(struct device_node *np, /* max_level is an index, not a counter */ cpufreq_cdev->max_level = i - 1; - cooling_ops = &cpufreq_cooling_ops; + cooling_ops = &cpufreq_cdev->cooling_ops; + cooling_ops->get_max_state = cpufreq_get_max_state; + cooling_ops->get_cur_state = cpufreq_get_cur_state; + cooling_ops->set_cur_state = cpufreq_set_cur_state; #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR if (em_is_sane(cpufreq_cdev, em)) { From patchwork Mon Jun 13 12:43:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Luba X-Patchwork-Id: 581890 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E555C433EF for ; Mon, 13 Jun 2022 17:27:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239391AbiFMR1q (ORCPT ); Mon, 13 Jun 2022 13:27:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234080AbiFMR1Z (ORCPT ); Mon, 13 Jun 2022 13:27:25 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BF4EE129C01; Mon, 13 Jun 2022 05:43:43 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 942F21596; Mon, 13 Jun 2022 05:43:43 -0700 (PDT) Received: from e123648.arm.com (unknown [10.57.35.216]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 77EB83F73B; Mon, 13 Jun 2022 05:43:41 -0700 (PDT) From: Lukasz Luba To: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Cc: daniel.lezcano@linaro.org, amitk@kernel.org, rui.zhang@intel.com, lukasz.luba@arm.com, viresh.kumar@linaro.org, rafael@kernel.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, mingo@redhat.com Subject: [PATCH v2 2/4] thermal: cpufreq_cooling : Refactor thermal_power_cpu_get_power tracing Date: Mon, 13 Jun 2022 13:43:25 +0100 Message-Id: <20220613124327.30766-3-lukasz.luba@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220613124327.30766-1-lukasz.luba@arm.com> References: <20220613124327.30766-1-lukasz.luba@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Simplify the thermal_power_cpu_get_power trace event by removing complicated cpumask and variable length array. Now the tools parsing trace output don't have to hassle to get this power data. The simplified format version uses 'policy->cpu'. Remove also the 'load' information completely since there is very little value of it in this trace event. To get the CPUs' load (or utilization) there are other dedicated trace hooks in the kernel. This patch also simplifies and speeds-up the main cooling code when that trace event is enabled. Rename the trace event to avoid confusion of tools which parse the trace file. Acked-by: Viresh Kumar Signed-off-by: Lukasz Luba --- drivers/thermal/cpufreq_cooling.c | 18 +----------------- include/trace/events/thermal.h | 28 ++++++++-------------------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index ad8b86f5281b..492a67e267e8 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -216,16 +216,9 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev, u32 total_load = 0; struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; struct cpufreq_policy *policy = cpufreq_cdev->policy; - u32 *load_cpu = NULL; freq = cpufreq_quick_get(policy->cpu); - if (trace_thermal_power_cpu_get_power_enabled()) { - u32 ncpus = cpumask_weight(policy->related_cpus); - - load_cpu = kcalloc(ncpus, sizeof(*load_cpu), GFP_KERNEL); - } - for_each_cpu(cpu, policy->related_cpus) { u32 load; @@ -235,22 +228,13 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev, load = 0; total_load += load; - if (load_cpu) - load_cpu[i] = load; - - i++; } cpufreq_cdev->last_load = total_load; *power = get_dynamic_power(cpufreq_cdev, freq); - if (load_cpu) { - trace_thermal_power_cpu_get_power(policy->related_cpus, freq, - load_cpu, i, *power); - - kfree(load_cpu); - } + trace_thermal_power_cpu_get_power_simple(policy->cpu, *power); return 0; } diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h index 8a5f04888abd..e58bf3072f32 100644 --- a/include/trace/events/thermal.h +++ b/include/trace/events/thermal.h @@ -92,34 +92,22 @@ TRACE_EVENT(thermal_zone_trip, ); #ifdef CONFIG_CPU_THERMAL -TRACE_EVENT(thermal_power_cpu_get_power, - TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load, - size_t load_len, u32 dynamic_power), +TRACE_EVENT(thermal_power_cpu_get_power_simple, + TP_PROTO(int cpu, u32 power), - TP_ARGS(cpus, freq, load, load_len, dynamic_power), + TP_ARGS(cpu, power), TP_STRUCT__entry( - __bitmask(cpumask, num_possible_cpus()) - __field(unsigned long, freq ) - __dynamic_array(u32, load, load_len) - __field(size_t, load_len ) - __field(u32, dynamic_power ) + __field(int, cpu) + __field(u32, power) ), TP_fast_assign( - __assign_bitmask(cpumask, cpumask_bits(cpus), - num_possible_cpus()); - __entry->freq = freq; - memcpy(__get_dynamic_array(load), load, - load_len * sizeof(*load)); - __entry->load_len = load_len; - __entry->dynamic_power = dynamic_power; + __entry->cpu = cpu; + __entry->power = power; ), - TP_printk("cpus=%s freq=%lu load={%s} dynamic_power=%d", - __get_bitmask(cpumask), __entry->freq, - __print_array(__get_dynamic_array(load), __entry->load_len, 4), - __entry->dynamic_power) + TP_printk("cpu=%d power=%u", __entry->cpu, __entry->power) ); TRACE_EVENT(thermal_power_cpu_limit, From patchwork Mon Jun 13 12:43:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Luba X-Patchwork-Id: 581565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B0A8CCA47D for ; Mon, 13 Jun 2022 17:27:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233958AbiFMR1r (ORCPT ); Mon, 13 Jun 2022 13:27:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36886 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239055AbiFMR10 (ORCPT ); Mon, 13 Jun 2022 13:27:26 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0C4C9113FB3; Mon, 13 Jun 2022 05:43:46 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E4BE41480; Mon, 13 Jun 2022 05:43:45 -0700 (PDT) Received: from e123648.arm.com (unknown [10.57.35.216]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C9F333F73B; Mon, 13 Jun 2022 05:43:43 -0700 (PDT) From: Lukasz Luba To: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Cc: daniel.lezcano@linaro.org, amitk@kernel.org, rui.zhang@intel.com, lukasz.luba@arm.com, viresh.kumar@linaro.org, rafael@kernel.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, mingo@redhat.com Subject: [PATCH v2 3/4] thermal: cpufreq_cooling: Update outdated comments Date: Mon, 13 Jun 2022 13:43:26 +0100 Message-Id: <20220613124327.30766-4-lukasz.luba@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220613124327.30766-1-lukasz.luba@arm.com> References: <20220613124327.30766-1-lukasz.luba@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The code has moved and left some comments stale. Update them where there is a need. Acked-by: Viresh Kumar Signed-off-by: Lukasz Luba --- drivers/thermal/cpufreq_cooling.c | 44 +++++++++++++------------------ 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 492a67e267e8..50f8b90abba6 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -206,7 +206,7 @@ static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_cdev, * complex code may be needed if experiments show that it's not * accurate enough. * - * Return: 0 on success, -E* if getting the static power failed. + * Return: 0 on success, this function doesn't fail. */ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev, u32 *power) @@ -249,9 +249,8 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev, * milliwatts assuming 100% load. Store the calculated power in * @power. * - * Return: 0 on success, -EINVAL if the cooling device state could not - * be converted into a frequency or other -E* if there was an error - * when calculating the static power. + * Return: 0 on success, -EINVAL if the cooling device state is bigger + * than maximum allowed. */ static int cpufreq_state2power(struct thermal_cooling_device *cdev, unsigned long state, u32 *power) @@ -281,15 +280,11 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev, * Calculate a cooling device state for the cpus described by @cdev * that would allow them to consume at most @power mW and store it in * @state. Note that this calculation depends on external factors - * such as the cpu load or the current static power. Calling this - * function with the same power as input can yield different cooling - * device states depending on those external factors. - * - * Return: 0 on success, -ENODEV if no cpus are online or -EINVAL if - * the calculated frequency could not be converted to a valid state. - * The latter should not happen unless the frequencies available to - * cpufreq have changed since the initialization of the cpu cooling - * device. + * such as the CPUs load. Calling this function with the same power + * as input can yield different cooling device states depending on those + * external factors. + * + * Return: 0 on success, this function doesn't fail. */ static int cpufreq_power2state(struct thermal_cooling_device *cdev, u32 power, unsigned long *state) @@ -401,7 +396,7 @@ static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev, * Callback for the thermal cooling device to return the cpufreq * max cooling state. * - * Return: 0 on success, an error code otherwise. + * Return: 0 on success, this function doesn't fail. */ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) @@ -420,7 +415,7 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, * Callback for the thermal cooling device to return the cpufreq * current cooling state. * - * Return: 0 on success, an error code otherwise. + * Return: 0 on success, this function doesn't fail. */ static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) @@ -479,7 +474,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, * @em: Energy Model of the cpufreq policy * * This interface function registers the cpufreq cooling device with the name - * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq + * "cpufreq-%s". This API can support multiple instances of cpufreq * cooling devices. It also gives the opportunity to link the cooling device * with a device tree node, in order to bind it via the thermal DT code. * @@ -590,8 +585,8 @@ __cpufreq_cooling_register(struct device_node *np, * @policy: cpufreq policy * * This interface function registers the cpufreq cooling device with the name - * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq - * cooling devices. + * "cpufreq-%s". This API can support multiple instances of cpufreq cooling + * devices. * * Return: a valid struct thermal_cooling_device pointer on success, * on failure, it returns a corresponding ERR_PTR(). @@ -608,17 +603,14 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register); * @policy: cpufreq policy * * This interface function registers the cpufreq cooling device with the name - * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq - * cooling devices. Using this API, the cpufreq cooling device will be - * linked to the device tree node provided. + * "cpufreq-%s". This API can support multiple instances of cpufreq cooling + * devices. Using this API, the cpufreq cooling device will be linked to the + * device tree node provided. * * Using this function, the cooling device will implement the power - * extensions by using a simple cpu power model. The cpus must have + * extensions by using the Energy Model (if present). The cpus must have * registered their OPPs using the OPP library. * - * It also takes into account, if property present in policy CPU node, the - * static power consumed by the cpu. - * * Return: a valid struct thermal_cooling_device pointer on success, * and NULL on failure. */ @@ -654,7 +646,7 @@ EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); * cpufreq_cooling_unregister - function to remove cpufreq cooling device. * @cdev: thermal cooling device pointer. * - * This interface function unregisters the "thermal-cpufreq-%x" cooling device. + * This interface function unregisters the "cpufreq-%x" cooling device. */ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { From patchwork Mon Jun 13 12:43:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Luba X-Patchwork-Id: 581567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BB98C43334 for ; Mon, 13 Jun 2022 17:25:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241022AbiFMRZU (ORCPT ); Mon, 13 Jun 2022 13:25:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240438AbiFMRZI (ORCPT ); Mon, 13 Jun 2022 13:25:08 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 691CB129C05; Mon, 13 Jun 2022 05:43:48 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4104215A1; Mon, 13 Jun 2022 05:43:48 -0700 (PDT) Received: from e123648.arm.com (unknown [10.57.35.216]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 26B143F73B; Mon, 13 Jun 2022 05:43:46 -0700 (PDT) From: Lukasz Luba To: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Cc: daniel.lezcano@linaro.org, amitk@kernel.org, rui.zhang@intel.com, lukasz.luba@arm.com, viresh.kumar@linaro.org, rafael@kernel.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, mingo@redhat.com Subject: [PATCH v2 4/4] thermal: devfreq_cooling: Extend the devfreq_cooling_device with ops Date: Mon, 13 Jun 2022 13:43:27 +0100 Message-Id: <20220613124327.30766-5-lukasz.luba@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220613124327.30766-1-lukasz.luba@arm.com> References: <20220613124327.30766-1-lukasz.luba@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Remove unneeded global variable devfreq_cooling_ops which is used only as a copy pattern. Instead, extend the struct devfreq_cooling_device with the needed ops structure. This also simplifies the allocation/free code during the setup/cleanup. Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 8c76f9655e57..67b618b1afc8 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -28,6 +28,7 @@ * struct devfreq_cooling_device - Devfreq cooling device * devfreq_cooling_device registered. * @cdev: Pointer to associated thermal cooling device. + * @cooling_ops: devfreq callbacks to thermal cooling device ops * @devfreq: Pointer to associated devfreq device. * @cooling_state: Current cooling state. * @freq_table: Pointer to a table with the frequencies sorted in descending @@ -48,6 +49,7 @@ */ struct devfreq_cooling_device { struct thermal_cooling_device *cdev; + struct thermal_cooling_device_ops cooling_ops; struct devfreq *devfreq; unsigned long cooling_state; u32 *freq_table; @@ -290,12 +292,6 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev, return 0; } -static struct thermal_cooling_device_ops devfreq_cooling_ops = { - .get_max_state = devfreq_cooling_get_max_state, - .get_cur_state = devfreq_cooling_get_cur_state, - .set_cur_state = devfreq_cooling_set_cur_state, -}; - /** * devfreq_cooling_gen_tables() - Generate frequency table. * @dfc: Pointer to devfreq cooling device. @@ -363,18 +359,18 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, char *name; int err, num_opps; - ops = kmemdup(&devfreq_cooling_ops, sizeof(*ops), GFP_KERNEL); - if (!ops) - return ERR_PTR(-ENOMEM); dfc = kzalloc(sizeof(*dfc), GFP_KERNEL); - if (!dfc) { - err = -ENOMEM; - goto free_ops; - } + if (!dfc) + return ERR_PTR(-ENOMEM); dfc->devfreq = df; + ops = &dfc->cooling_ops; + ops->get_max_state = devfreq_cooling_get_max_state; + ops->get_cur_state = devfreq_cooling_get_cur_state; + ops->set_cur_state = devfreq_cooling_set_cur_state; + em = em_pd_get(dev); if (em && !em_is_artificial(em)) { dfc->em_pd = em; @@ -437,8 +433,6 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, kfree(dfc->freq_table); free_dfc: kfree(dfc); -free_ops: - kfree(ops); return ERR_PTR(err); } @@ -520,13 +514,11 @@ EXPORT_SYMBOL_GPL(devfreq_cooling_em_register); void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) { struct devfreq_cooling_device *dfc; - const struct thermal_cooling_device_ops *ops; struct device *dev; if (IS_ERR_OR_NULL(cdev)) return; - ops = cdev->ops; dfc = cdev->devdata; dev = dfc->devfreq->dev.parent; @@ -537,6 +529,5 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) kfree(dfc->freq_table); kfree(dfc); - kfree(ops); } EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);