From patchwork Wed Dec 4 15:39:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 11273111 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A6BC86C1 for ; Wed, 4 Dec 2019 15:39:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 85192206DF for ; Wed, 4 Dec 2019 15:39:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Yv73NxI2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728390AbfLDPjo (ORCPT ); Wed, 4 Dec 2019 10:39:44 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38247 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728324AbfLDPjo (ORCPT ); Wed, 4 Dec 2019 10:39:44 -0500 Received: by mail-wm1-f66.google.com with SMTP id p17so199133wmi.3 for ; Wed, 04 Dec 2019 07:39:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=v9aPs/wpi2L5/d1FqkD06cZ03HNvyIimtXPANJEaaic=; b=Yv73NxI2i/49vDu9InO7rsocVrEzs/pBK32Etx2/SRVL8T0kjo8vJhE68rp0tiWbhR TN8smksr1qo5jOSXE0ktqPNSd1/1dRMfTE8+SS8Bpi6KTZiRYN30m4WydmYSJamc2lRa h7Q72QkNuo+V1taaUC0pltB9ygR1YXD9vcnVa9DsgK+5AkoSGpjoBUSSSb4Msde00w3r 9bLseDoQ7cRk3pYamuekA9GBoLgpn/1m+9JfY5RTnzalwp7L5fRiSrOQyjsz0lt0Kv/a 29yZVw5lyWcz+KydY3Bj9fo5ANJKePNhagEJ4ZKA5elxZfZU8tNWzwcQNWbRfazvixSJ P2sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=v9aPs/wpi2L5/d1FqkD06cZ03HNvyIimtXPANJEaaic=; b=S6YDudRxqiTYQrHfxJ2gmHdT7/8LlQFBa7Dv4co/ewqUrroCaxGvpvw3upIRoQ0MqD hYmltKUwiwH2CM2hwZIxc7CRR1tIIfP6PyCwcfwwDfpDq1uS9KI1OF8l0gAbKR/6XHdu jWWRsztGzWZIfR6QVbzMVMjryViOsb9j2YJu5ySLT9Pm6UVifHhjUqHAue4R8TyLiQnN H79lFjxnzxd2Y0lqZqwzJo6hpFqec8qBeaMZdY6Kt3GiG8DpIqxsySucYKfTtuPmNVvi s/vEeJNWmNe2EtwEKKLVdINAG8iL1XGqhb6PzKliJnlCxg9Dt5BbN6AOnQpL5g1HYpTO 5VwA== X-Gm-Message-State: APjAAAU18Btv0QMlk96X7ANRcipZa9XPkAUPt/DouzGy/6apLWqPUJTM zMaCt3q1dOeqTieFIj3bXOoWwuLifwk= X-Google-Smtp-Source: APXvYqyzXzSi1Dz2RNTWyd9doTVH9IyNsDx+aJ7PDILfFl6RXuMp6CpgceH65/s/1y3foQ3tHpn8xg== X-Received: by 2002:a1c:a98e:: with SMTP id s136mr112577wme.140.1575473981990; Wed, 04 Dec 2019 07:39:41 -0800 (PST) Received: from localhost.localdomain ([2a01:e34:ed2f:f020:a551:321a:c21f:1f92]) by smtp.gmail.com with ESMTPSA id f1sm8631311wrp.93.2019.12.04.07.39.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 07:39:41 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com, rui.zhang@intel.com Cc: rjw@rjwysocki.net, linux-pm@vger.kernel.org, viresh.kumar@linaro.org, amit.kucheria@linaro.org, linux-kernel@vger.kernel.org Subject: [PATCH V4 1/4] thermal/drivers/Kconfig: Convert the CPU cooling device to a choice Date: Wed, 4 Dec 2019 16:39:27 +0100 Message-Id: <20191204153930.9128-1-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The next changes will add a new way to cool down a CPU by injecting idle cycles. With the current configuration, a CPU cooling device is the cpufreq cooling device. As we want to add a new CPU cooling device, let's convert the CPU cooling to a choice giving a list of CPU cooling devices. At this point, there is obviously only one CPU cooling device. There is no functional changes. Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar --- V2: - Default CPU_FREQ_COOLING when CPU_THERMAL is set (Viresh Kumar) --- drivers/thermal/Kconfig | 14 ++++++++++++-- drivers/thermal/Makefile | 2 +- include/linux/cpu_cooling.h | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 001a21abcc28..4e3ee036938b 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -150,8 +150,18 @@ config THERMAL_GOV_POWER_ALLOCATOR config CPU_THERMAL bool "Generic cpu cooling support" - depends on CPU_FREQ depends on THERMAL_OF + help + Enable the CPU cooling features. If the system has no active + cooling device available, this option allows to use the CPU + as a cooling device. + +if CPU_THERMAL + +config CPU_FREQ_THERMAL + bool "CPU frequency cooling device" + depends on CPU_FREQ + default y help This implements the generic cpu cooling mechanism through frequency reduction. An ACPI version of this already exists @@ -159,7 +169,7 @@ config CPU_THERMAL This will be useful for platforms using the generic thermal interface and not the ACPI interface. - If you want this support, you should say Y here. +endif config CLOCK_THERMAL bool "Generic clock cooling support" diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 74a37c7f847a..d3b01cc96981 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -19,7 +19,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o # cpufreq cooling -thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o +thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpu_cooling.o # clock cooling thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index b74732535e4b..3cdd85f987d7 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -19,7 +19,7 @@ struct cpufreq_policy; -#ifdef CONFIG_CPU_THERMAL +#ifdef CONFIG_CPU_FREQ_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. * @policy: cpufreq policy. @@ -40,7 +40,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev); struct thermal_cooling_device * of_cpufreq_cooling_register(struct cpufreq_policy *policy); -#else /* !CONFIG_CPU_THERMAL */ +#else /* !CONFIG_CPU_FREQ_THERMAL */ static inline struct thermal_cooling_device * cpufreq_cooling_register(struct cpufreq_policy *policy) { @@ -58,6 +58,6 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) { return NULL; } -#endif /* CONFIG_CPU_THERMAL */ +#endif /* CONFIG_CPU_FREQ_THERMAL */ #endif /* __CPU_COOLING_H__ */ From patchwork Wed Dec 4 15:39:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 11273113 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C156C930 for ; Wed, 4 Dec 2019 15:39:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 96555206DF for ; Wed, 4 Dec 2019 15:39:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="qsESq1Zl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728396AbfLDPjs (ORCPT ); Wed, 4 Dec 2019 10:39:48 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:33489 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728324AbfLDPjr (ORCPT ); Wed, 4 Dec 2019 10:39:47 -0500 Received: by mail-wm1-f66.google.com with SMTP id y23so5135275wma.0 for ; Wed, 04 Dec 2019 07:39:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eHar8caGVk2CHYCleN7lzgXckcrdAjaPRcEzE+leMkc=; b=qsESq1ZlfGlT7CaPQkcDkqRCPhUkYAp1MvgB6WHuCAtK2sLShsuWQSKYsRZfUbBjDu Aa34HDxy7CO9PAE+CqsIwkYOlE6g1R+xCTygjCW6/FRra8CoMU13b6h1CN807oeWvz1P X4bv54JEPFFcIaCTz1s9fGbZFjSL7TNxQJBFxSldkK9opfBZqWtK0+4w/NNqDLA3SYwb vjaCX9GUrosUFAdqnlqA3nEUzvg8gFhF1Vne6UC9bkeTo6yQv9BXQG8/LS1+wy9ztJ9K neH8DCaRsy421eJKTwbslQObGAG6+xHvBOGn8N0BQfFaC5oh6jjNpI+B3zE2FyiGHH49 XAKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eHar8caGVk2CHYCleN7lzgXckcrdAjaPRcEzE+leMkc=; b=c+3dFhOtlU6g2z5dWAApst9wOprf/4Xj25MlRvkR88by0p18P11UT/+iCyBJumAG1L URFOyDkAX07oCGkBUTiDbwHiNx6gy+Vfc8jrSHoLRuZsjHwZLBFUbhzEbcqEq0lDy80q G6k+CyP6srkWgmiyw49Jb/LIpCvUEvDMggtfZAHAFmzeJIwOi0vg+PcqFQ5BGK0YFvz+ w3TRLl2Q9FCPE30MmKOXmFL/owfqZXIliGqP8z3U1bQDFZ799vBClIGr+GyomgkfWoSE BA8EiLSYqA4FAici3x4XBxjc4RSHVAwCpxztR/XDZ++D6Aj5/6m4abhcs+10IuV7aE/i LFbw== X-Gm-Message-State: APjAAAU1Y9tJAypwHUea/fF1LIuchuXufBnzrthOALAydWBiu6IVfYvl 8VWPv9b8SV1SV4ztOwG+jwbHsA== X-Google-Smtp-Source: APXvYqw1kYniniNowTRLikUrObTHcJHLzEg4O/0rOwjvdKhhUrBQDVQ/JLrIEBaYjmWZR3u1t2vIJw== X-Received: by 2002:a1c:a906:: with SMTP id s6mr180759wme.125.1575473985220; Wed, 04 Dec 2019 07:39:45 -0800 (PST) Received: from localhost.localdomain ([2a01:e34:ed2f:f020:a551:321a:c21f:1f92]) by smtp.gmail.com with ESMTPSA id f1sm8631311wrp.93.2019.12.04.07.39.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 07:39:44 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com, rui.zhang@intel.com Cc: rjw@rjwysocki.net, linux-pm@vger.kernel.org, viresh.kumar@linaro.org, amit.kucheria@linaro.org, linux-kernel@vger.kernel.org Subject: [PATCH V4 2/4] thermal/drivers/cpu_cooling: Add idle cooling device documentation Date: Wed, 4 Dec 2019 16:39:28 +0100 Message-Id: <20191204153930.9128-2-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191204153930.9128-1-daniel.lezcano@linaro.org> References: <20191204153930.9128-1-daniel.lezcano@linaro.org> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Provide some documentation for the idle injection cooling effect in order to let people to understand the rational of the approach for the idle injection CPU cooling device. Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar --- V4: - Fixed typos, replaced 'period' per 'duty cycles', clarified some wording (Amit Kucheria) --- .../driver-api/thermal/cpu-idle-cooling.rst | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 Documentation/driver-api/thermal/cpu-idle-cooling.rst diff --git a/Documentation/driver-api/thermal/cpu-idle-cooling.rst b/Documentation/driver-api/thermal/cpu-idle-cooling.rst new file mode 100644 index 000000000000..13d7fe4e8de8 --- /dev/null +++ b/Documentation/driver-api/thermal/cpu-idle-cooling.rst @@ -0,0 +1,189 @@ + +Situation: +---------- + +Under certain circumstances a SoC can reach a critical temperature +limit and is unable to stabilize the temperature around a temperature +control. When the SoC has to stabilize the temperature, the kernel can +act on a cooling device to mitigate the dissipated power. When the +critical temperature is reached, a decision must be taken to reduce +the temperature, that, in turn impacts performance. + +Another situation is when the silicon temperature continues to +increase even after the dynamic leakage is reduced to its minimum by +clock gating the component. This runaway phenomenon can continue due +to the static leakage. The only solution is to power down the +component, thus dropping the dynamic and static leakage that will +allow the component to cool down. + +Last but not least, the system can ask for a specific power budget but +because of the OPP density, we can only choose an OPP with a power +budget lower than the requested one and under-utilize the CPU, thus +losing performance. In other words, one OPP under-utilizes the CPU +with a power less than the requested power budget and the next OPP +exceeds the power budget. An intermediate OPP could have been used if +it were present. + +Solutions: +---------- + +If we can remove the static and the dynamic leakage for a specific +duration in a controlled period, the SoC temperature will +decrease. Acting on the idle state duration or the idle cycle +injection period, we can mitigate the temperature by modulating the +power budget. + +The Operating Performance Point (OPP) density has a great influence on +the control precision of cpufreq, however different vendors have a +plethora of OPP density, and some have large power gap between OPPs, +that will result in loss of performance during thermal control and +loss of power in other scenarios. + +At a specific OPP, we can assume that injecting idle cycle on all CPUs +belong to the same cluster, with a duration greater than the cluster +idle state target residency, we lead to dropping the static and the +dynamic leakage for this period (modulo the energy needed to enter +this state). So the sustainable power with idle cycles has a linear +relation with the OPP’s sustainable power and can be computed with a +coefficient similar to: + + Power(IdleCycle) = Coef x Power(OPP) + +Idle Injection: +--------------- + +The base concept of the idle injection is to force the CPU to go to an +idle state for a specified time each control cycle, it provides +another way to control CPU power and heat in addition to +cpufreq. Ideally, if all CPUs belonging to the same cluster, inject +their idle cycles synchronously, the cluster can reach its power down +state with a minimum power consumption and reduce the static leakage +to almost zero. However, these idle cycles injection will add extra +latencies as the CPUs will have to wakeup from a deep sleep state. + +We use a fixed duration of idle injection that gives an acceptable +performance penalty and a fixed latency. Mitigation can be increased +or decreased by modulating the duty cycle of the idle injection. + + ^ + | + | + |------- ------- + |_______|_______________________|_______|___________ + + <------> + idle <----------------------> + running + + <-----------------------------> + duty cycle 25% + + +The implementation of the cooling device bases the number of states on +the duty cycle percentage. When no mitigation is happening the cooling +device state is zero, meaning the duty cycle is 0%. + +When the mitigation begins, depending on the governor's policy, a +starting state is selected. With a fixed idle duration and the duty +cycle (aka the cooling device state), the running duration can be +computed. + +The governor will change the cooling device state thus the duty cycle +and this variation will modulate the cooling effect. + + ^ + | + | + |------- ------- + |_______|_______________|_______|___________ + + <------> + idle <--------------> + running + + <-----------------------------> + duty cycle 33% + + + ^ + | + | + |------- ------- + |_______|_______|_______|___________ + + <------> + idle <------> + running + + <-------------> + duty cycle 50% + +The idle injection duration value must comply with the constraints: + +- It is less than or equal to the latency we tolerate when the + mitigation begins. It is platform dependent and will depend on the + user experience, reactivity vs performance trade off we want. This + value should be specified. + +- It is greater than the idle state’s target residency we want to go + for thermal mitigation, otherwise we end up consuming more energy. + +Power considerations +-------------------- + +When we reach the thermal trip point, we have to sustain a specified +power for a specific temperature but at this time we consume: + + Power = Capacitance x Voltage^2 x Frequency x Utilisation + +... which is more than the sustainable power (or there is something +wrong in the system setup). The ‘Capacitance’ and ‘Utilisation’ are a +fixed value, ‘Voltage’ and the ‘Frequency’ are fixed artificially +because we don’t want to change the OPP. We can group the +‘Capacitance’ and the ‘Utilisation’ into a single term which is the +‘Dynamic Power Coefficient (Cdyn)’ Simplifying the above, we have: + + Pdyn = Cdyn x Voltage^2 x Frequency + +The power allocator governor will ask us somehow to reduce our power +in order to target the sustainable power defined in the device +tree. So with the idle injection mechanism, we want an average power +(Ptarget) resulting in an amount of time running at full power on a +specific OPP and idle another amount of time. That could be put in a +equation: + + P(opp)target = ((Trunning x (P(opp)running) + (Tidle x P(opp)idle)) / + (Trunning + Tidle) + ... + + Tidle = Trunning x ((P(opp)running / P(opp)target) - 1) + +At this point if we know the running period for the CPU, that gives us +the idle injection we need. Alternatively if we have the idle +injection duration, we can compute the running duration with: + + Trunning = Tidle / ((P(opp)running / P(opp)target) - 1) + +Practically, if the running power is less than the targeted power, we +end up with a negative time value, so obviously the equation usage is +bound to a power reduction, hence a higher OPP is needed to have the +running power greater than the targeted power. + +However, in this demonstration we ignore three aspects: + + * The static leakage is not defined here, we can introduce it in the + equation but assuming it will be zero most of the time as it is + difficult to get the values from the SoC vendors + + * The idle state wake up latency (or entry + exit latency) is not + taken into account, it must be added in the equation in order to + rigorously compute the idle injection + + * The injected idle duration must be greater than the idle state + target residency, otherwise we end up consuming more energy and + potentially invert the mitigation effect + +So the final equation is: + + Trunning = (Tidle - Twakeup ) x + (((P(opp)dyn + P(opp)static ) - P(opp)target) / P(opp)target ) From patchwork Wed Dec 4 15:39:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 11273117 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 314606C1 for ; Wed, 4 Dec 2019 15:39:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F174820833 for ; Wed, 4 Dec 2019 15:39:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="jqnbcHTk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728471AbfLDPjy (ORCPT ); Wed, 4 Dec 2019 10:39:54 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:39977 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728462AbfLDPjw (ORCPT ); Wed, 4 Dec 2019 10:39:52 -0500 Received: by mail-wm1-f67.google.com with SMTP id t14so185597wmi.5 for ; Wed, 04 Dec 2019 07:39:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PcXlPnuNEwyWXH2XgGE5Q5jgxvOX+q8H8fhmAnCIWmg=; b=jqnbcHTkmt3hcolbu8/YNVm9C3o1ArMylzkLPSo9kU195c7OKo9p4BaA/B4U5RXlk3 TumLh87fZfgxPAeEAFVrPIV5Emy0iEF2t9wkXM4jpez5JC6PrQKrdmW34JNngrPagOkM 6LA+yjjTNLpztFIbtXh873PeINBrtdmSwZ1DCOVFRez3X3Fc3huTsVtTY3GctKsWBgPZ sek5VtwpG49TQjsuiEcxlsrTzCHep0JVH3kSXIDPIKgooDekiCc73wxQwY9IUzyrNtOR lTQwz7nqQPGZhF4ScTOdljchpQA5Ap6SxP3i1IOhdVeLALlvyKLJjQyufVp70a9xdSQg 7EaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PcXlPnuNEwyWXH2XgGE5Q5jgxvOX+q8H8fhmAnCIWmg=; b=ip9eEMSs453LeaB3y0X5z3PVrEv0h0YwE5fSXWk7pU5rlVoyDGkZ4RGkWi3eqn+Wsx RVIye2ZZGaDsNw93Ol207EChdpT5dUxXHYIvdnlfFh/MalbPCs6YtBGZHAORup3WJIvl M3DLDJtnEUzKHuKCSNkzMYfjkiEnYhl73lgkW3ZsfP5Thf/4fQda9na0ufygacd+SbL2 9i/CmjYskIPcHnoTYClUfBlYeRqvbBCacJlOXq5dGpIsxz2FgdEq4OWQ2Q2gRB32omZ+ dTnXBsUK5q0G08wK4b4j1zMA0ZpeZshQ7FAho+w/jfNXwSCZNWt7wjH0cIOTGi1mFC5C t2yw== X-Gm-Message-State: APjAAAWWTPHtbXXsN123dRw+tLAlnj9sr6pQZWtWIEkPQ6iH5BNKRMai YF78E5NGEs2nXSCJtwy3CWTR0g== X-Google-Smtp-Source: APXvYqyo9tXlnnnSnVN5M9NLII/FANpfdeo1gwkTMjrgGv9yuKWrpFgHYVqsvQWKLSQK1wDljrr2lQ== X-Received: by 2002:a7b:cf12:: with SMTP id l18mr143442wmg.66.1575473988499; Wed, 04 Dec 2019 07:39:48 -0800 (PST) Received: from localhost.localdomain ([2a01:e34:ed2f:f020:a551:321a:c21f:1f92]) by smtp.gmail.com with ESMTPSA id f1sm8631311wrp.93.2019.12.04.07.39.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 07:39:47 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com, rui.zhang@intel.com Cc: rjw@rjwysocki.net, linux-pm@vger.kernel.org, viresh.kumar@linaro.org, amit.kucheria@linaro.org, linux-kernel@vger.kernel.org Subject: [PATCH V4 3/4] thermal/drivers/cpu_cooling: Introduce the cpu idle cooling driver Date: Wed, 4 Dec 2019 16:39:29 +0100 Message-Id: <20191204153930.9128-3-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191204153930.9128-1-daniel.lezcano@linaro.org> References: <20191204153930.9128-1-daniel.lezcano@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The cpu idle cooling device offers a new method to cool down a CPU by injecting idle cycles at runtime. It has some similarities with the intel power clamp driver but it is actually designed to be more generic and relying on the idle injection powercap framework. The idle injection duration is fixed while the running duration is variable. That allows to have control on the device reactivity for the user experience. An idle state powering down the CPU or the cluster will allow to drop the static leakage, thus restoring the heat capacity of the SoC. It can be set with a trip point between the hot and the critical points, giving the opportunity to prevent a hard reset of the system when the cpufreq cooling fails to cool down the CPU. With more sophisticated boards having a per core sensor, the idle cooling device allows to cool down a single core without throttling the compute capacity of several cpus belonging to the same clock line, so it could be used in collaboration with the cpufreq cooling device. Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar --- V4: - Fixed typos in the kernel-doc and clarified the changelog (Amit Kucheria) V3: - Add missing parameter documentation (Viresh Kumar) - Fixed function description (Viresh Kumar) - Add entry in MAINTAINER file V2: - Remove idle_duration_us field and use idle_inject API instead (Viresh Kumar) - Fixed function definition wheh CPU_IDLE_COOLING is not set - Inverted the initialization in the init function (Viresh Kumar) --- MAINTAINERS | 3 + drivers/thermal/Kconfig | 7 + drivers/thermal/Makefile | 1 + drivers/thermal/cpuidle_cooling.c | 234 ++++++++++++++++++++++++++++++ include/linux/cpu_cooling.h | 22 +++ 5 files changed, 267 insertions(+) create mode 100644 drivers/thermal/cpuidle_cooling.c diff --git a/MAINTAINERS b/MAINTAINERS index c570f0204b48..d2e92a0360f2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16187,12 +16187,15 @@ F: Documentation/devicetree/bindings/thermal/ THERMAL/CPU_COOLING M: Amit Daniel Kachhap +M: Daniel Lezcano M: Viresh Kumar M: Javi Merino L: linux-pm@vger.kernel.org S: Supported F: Documentation/driver-api/thermal/cpu-cooling-api.rst +F: Documentation/driver-api/thermal/cpu-idle-cooling.rst F: drivers/thermal/cpu_cooling.c +F: drivers/thermal/cpuidle_cooling.c F: include/linux/cpu_cooling.h THINKPAD ACPI EXTRAS DRIVER diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 4e3ee036938b..4ee9953ba5ce 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -169,6 +169,13 @@ config CPU_FREQ_THERMAL This will be useful for platforms using the generic thermal interface and not the ACPI interface. +config CPU_IDLE_THERMAL + bool "CPU idle cooling device" + depends on IDLE_INJECT + help + This implements the CPU cooling mechanism through + idle injection. This will throttle the CPU by injecting + idle cycle. endif config CLOCK_THERMAL diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index d3b01cc96981..9c8aa2d4bd28 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -20,6 +20,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o # cpufreq cooling thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpu_cooling.o +thermal_sys-$(CONFIG_CPU_IDLE_THERMAL) += cpuidle_cooling.o # clock cooling thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c new file mode 100644 index 000000000000..369c5c613f6b --- /dev/null +++ b/drivers/thermal/cpuidle_cooling.c @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Linaro Limited. + * + * Author: Daniel Lezcano + * + */ +#include +#include +#include +#include +#include +#include +#include + +/** + * struct cpuidle_cooling_device - data for the idle cooling device + * @ii_dev: an atomic to keep track of the last task exiting the idle cycle + * @state: a normalized integer giving the state of the cooling device + */ +struct cpuidle_cooling_device { + struct idle_inject_device *ii_dev; + unsigned long state; +}; + +static DEFINE_IDA(cpuidle_ida); + +/** + * cpuidle_cooling_runtime - Running time computation + * @idle_duration_us: the idle cooling device + * @state: a percentile based number + * + * The running duration is computed from the idle injection duration + * which is fixed. If we reach 100% of idle injection ratio, that + * means the running duration is zero. If we have a 50% ratio + * injection, that means we have equal duration for idle and for + * running duration. + * + * The formula is deduced as follows: + * + * running = idle x ((100 / ratio) - 1) + * + * For precision purpose for integer math, we use the following: + * + * running = (idle x 100) / ratio - idle + * + * For example, if we have an injected duration of 50%, then we end up + * with 10ms of idle injection and 10ms of running duration. + * + * Return: An unsigned int for a usec based runtime duration. + */ +static unsigned int cpuidle_cooling_runtime(unsigned int idle_duration_us, + unsigned long state) +{ + if (!state) + return 0; + + return ((idle_duration_us * 100) / state) - idle_duration_us; +} + +/** + * cpuidle_cooling_get_max_state - Get the maximum state + * @cdev : the thermal cooling device + * @state : a pointer to the state variable to be filled + * + * The function always returns 100 as the injection ratio. It is + * percentile based for consistency accross different platforms. + * + * Return: The function can not fail, it is always zero + */ +static int cpuidle_cooling_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + /* + * Depending on the configuration or the hardware, the running + * cycle and the idle cycle could be different. We want to + * unify that to an 0..100 interval, so the set state + * interface will be the same whatever the platform is. + * + * The state 100% will make the cluster 100% ... idle. A 0% + * injection ratio means no idle injection at all and 50% + * means for 10ms of idle injection, we have 10ms of running + * time. + */ + *state = 100; + + return 0; +} + +/** + * cpuidle_cooling_get_cur_state - Get the current cooling state + * @cdev: the thermal cooling device + * @state: a pointer to the state + * + * The function just copies the state value from the private thermal + * cooling device structure, the mapping is 1 <-> 1. + * + * Return: The function can not fail, it is always zero + */ +static int cpuidle_cooling_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct cpuidle_cooling_device *idle_cdev = cdev->devdata; + + *state = idle_cdev->state; + + return 0; +} + +/** + * cpuidle_cooling_set_cur_state - Set the current cooling state + * @cdev: the thermal cooling device + * @state: the target state + * + * The function checks first if we are initiating the mitigation which + * in turn wakes up all the idle injection tasks belonging to the idle + * cooling device. In any case, it updates the internal state for the + * cooling device. + * + * Return: The function can not fail, it is always zero + */ +static int cpuidle_cooling_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct cpuidle_cooling_device *idle_cdev = cdev->devdata; + struct idle_inject_device *ii_dev = idle_cdev->ii_dev; + unsigned long current_state = idle_cdev->state; + unsigned int runtime_us, idle_duration_us; + + idle_cdev->state = state; + + idle_inject_get_duration(ii_dev, &runtime_us, &idle_duration_us); + + runtime_us = cpuidle_cooling_runtime(idle_duration_us, state); + + idle_inject_set_duration(ii_dev, runtime_us, idle_duration_us); + + if (current_state == 0 && state > 0) { + idle_inject_start(ii_dev); + } else if (current_state > 0 && !state) { + idle_inject_stop(ii_dev); + } + + return 0; +} + +/** + * cpuidle_cooling_ops - thermal cooling device ops + */ +static struct thermal_cooling_device_ops cpuidle_cooling_ops = { + .get_max_state = cpuidle_cooling_get_max_state, + .get_cur_state = cpuidle_cooling_get_cur_state, + .set_cur_state = cpuidle_cooling_set_cur_state, +}; + +/** + * cpuidle_of_cooling_register - Idle cooling device initialization function + * @drv: a cpuidle driver structure pointer + * @np: a node pointer to a device tree cooling device node + * + * This function is in charge of creating a cooling device per cpuidle + * driver and register it to thermal framework. + * + * Return: A valid pointer to a thermal cooling device or a PTR_ERR + * corresponding to the error detected in the underlying subsystems. + */ +struct thermal_cooling_device * +__init cpuidle_of_cooling_register(struct device_node *np, + struct cpuidle_driver *drv) +{ + struct idle_inject_device *ii_dev; + struct cpuidle_cooling_device *idle_cdev; + struct thermal_cooling_device *cdev; + char dev_name[THERMAL_NAME_LENGTH]; + int id, ret; + + idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL); + if (!idle_cdev) { + ret = -ENOMEM; + goto out; + } + + id = ida_simple_get(&cpuidle_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + ret = id; + goto out_kfree; + } + + ii_dev = idle_inject_register(drv->cpumask); + if (IS_ERR(ii_dev)) { + ret = PTR_ERR(ii_dev); + goto out_id; + } + + idle_inject_set_duration(ii_dev, 0, TICK_USEC); + + idle_cdev->ii_dev = ii_dev; + + snprintf(dev_name, sizeof(dev_name), "thermal-idle-%d", id); + + cdev = thermal_of_cooling_device_register(np, dev_name, idle_cdev, + &cpuidle_cooling_ops); + if (IS_ERR(cdev)) { + ret = PTR_ERR(cdev); + goto out_unregister; + } + + return cdev; + +out_unregister: + idle_inject_unregister(ii_dev); +out_id: + ida_simple_remove(&cpuidle_ida, id); +out_kfree: + kfree(idle_cdev); +out: + return ERR_PTR(ret); +} + +/** + * cpuidle_cooling_register - Idle cooling device initialization function + * @drv: a cpuidle driver structure pointer + * + * This function is in charge of creating a cooling device per cpuidle + * driver and register it to thermal framework. + * + * Return: A valid pointer to a thermal cooling device, a PTR_ERR + * corresponding to the error detected in the underlying subsystems. + */ +struct thermal_cooling_device * +__init cpuidle_cooling_register(struct cpuidle_driver *drv) +{ + return cpuidle_of_cooling_register(NULL, drv); +} diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index 3cdd85f987d7..da0970183d1f 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -60,4 +60,26 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) } #endif /* CONFIG_CPU_FREQ_THERMAL */ +struct cpuidle_driver; + +#ifdef CONFIG_CPU_IDLE_THERMAL +extern struct thermal_cooling_device * +__init cpuidle_cooling_register(struct cpuidle_driver *drv); +extern struct thermal_cooling_device * +__init cpuidle_of_cooling_register(struct device_node *np, + struct cpuidle_driver *drv); +#else /* CONFIG_CPU_IDLE_THERMAL */ +static inline struct thermal_cooling_device * +__init cpuidle_cooling_register(struct cpuidle_driver *drv) +{ + return ERR_PTR(-EINVAL); +} +static inline struct thermal_cooling_device * +__init cpuidle_of_cooling_register(struct device_node *np, + struct cpuidle_driver *drv) +{ + return ERR_PTR(-EINVAL); +} +#endif /* CONFIG_CPU_IDLE_THERMAL */ + #endif /* __CPU_COOLING_H__ */ From patchwork Wed Dec 4 15:39:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 11273115 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C644E930 for ; Wed, 4 Dec 2019 15:39:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9B79A20881 for ; Wed, 4 Dec 2019 15:39:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="c0n/xZi+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728311AbfLDPjx (ORCPT ); Wed, 4 Dec 2019 10:39:53 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:33912 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728471AbfLDPjw (ORCPT ); Wed, 4 Dec 2019 10:39:52 -0500 Received: by mail-wm1-f65.google.com with SMTP id f4so5122437wmj.1 for ; Wed, 04 Dec 2019 07:39:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1niKCMXXnmGnzZRABJx3hRarOaikbE/OwsjmxwSrkNE=; b=c0n/xZi+mCTzNlQRlLCYjL7pSvvKCB2mFzQHqcD21Rl2yMihwatj4fu8MSQQephKYM a53jHtNdVOTYqPaU2OTmrxTns5ls+7huxMeLT3DF6hgUepdwGGF+jS0dLiaXZ+apjioK O6sCTN1jtZFL4PnYdDcsMiYukIKh36htiy9e2m5GzxW+GzrlyV3Fe+okrXsjG4vwpshO He65muV6t5s792gfmkrfXiBfyEtlVjzecqV/9lrd6qTEiP95sdeLmpHFh6tNENFOrVqu Fpz5JPkPK+doI9Ejk9P3ITy0Gz19Drwy5yrhavCIeo547Rnlrb9P8xDm0qEkJ/ut8xBm NG5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1niKCMXXnmGnzZRABJx3hRarOaikbE/OwsjmxwSrkNE=; b=uXEGaXwIvsOqnL8MlSz6ntPAbqIU/jTL3+Yb/0If0Z5OjGAWhfsZvUCkxDZebq63xW 5AK1UZ95p70iD2FQ+HcbOd1/+UC1i5wxyAe5jgVgtP2VRpprTeCjB6Pr9Azt/PsDxHAQ KhH9FdVYECNgTQtLBgTNAkkVMXxx914wM5bntXBwxsF/h7AM2NcdIuoKH0Phk/Lonfgr VZUzpfWQ5Rb+AiPx4+SzVwglOQjj20NiqhukuQ82YI2too+mXidonfKmlA80bH8SCoQQ zpTC0jj7INtkCqqaLLft4LQgKWdPK/5tICqGRtG3ekWFk2zYj5Va0OdxMH1ktlF6QapQ 2swg== X-Gm-Message-State: APjAAAVzMkYN8tFlSdMuaYEzNx9JIHNIGc9jdC9BMvm6kTWtfFiB+hwJ PLPzXDZ4FoX4j9Hn+iV1Mxqqrg== X-Google-Smtp-Source: APXvYqzGZovPj+AGgg4lhMwHJDGfAEKbPIbXfCW4qwAbL+vEzcG67Zt+AoImghY4NiEo/jaiI/gqWw== X-Received: by 2002:a1c:9d4a:: with SMTP id g71mr239894wme.50.1575473990613; Wed, 04 Dec 2019 07:39:50 -0800 (PST) Received: from localhost.localdomain ([2a01:e34:ed2f:f020:a551:321a:c21f:1f92]) by smtp.gmail.com with ESMTPSA id f1sm8631311wrp.93.2019.12.04.07.39.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 07:39:50 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com, rui.zhang@intel.com Cc: rjw@rjwysocki.net, linux-pm@vger.kernel.org, viresh.kumar@linaro.org, amit.kucheria@linaro.org, linux-kernel@vger.kernel.org Subject: [PATCH V4 4/4] thermal/drivers/cpu_cooling: Rename to cpufreq_cooling Date: Wed, 4 Dec 2019 16:39:30 +0100 Message-Id: <20191204153930.9128-4-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191204153930.9128-1-daniel.lezcano@linaro.org> References: <20191204153930.9128-1-daniel.lezcano@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org As we introduced the idle injection cooling device called cpuidle_cooling, let's be consistent and rename the cpu_cooling to cpufreq_cooling as this one mitigates with OPPs changes. Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar Reviewed-by: Amit Kucheria --- V4: - Added Acked-by and Reviewed-by V3: - Fix missing name conversion (Viresh Kumar) --- Documentation/driver-api/thermal/exynos_thermal.rst | 2 +- MAINTAINERS | 2 +- drivers/thermal/Makefile | 2 +- drivers/thermal/clock_cooling.c | 2 +- drivers/thermal/{cpu_cooling.c => cpufreq_cooling.c} | 6 +++--- include/linux/clock_cooling.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename drivers/thermal/{cpu_cooling.c => cpufreq_cooling.c} (99%) diff --git a/Documentation/driver-api/thermal/exynos_thermal.rst b/Documentation/driver-api/thermal/exynos_thermal.rst index 5bd556566c70..d4e4a5b75805 100644 --- a/Documentation/driver-api/thermal/exynos_thermal.rst +++ b/Documentation/driver-api/thermal/exynos_thermal.rst @@ -67,7 +67,7 @@ TMU driver description: The exynos thermal driver is structured as:: Kernel Core thermal framework - (thermal_core.c, step_wise.c, cpu_cooling.c) + (thermal_core.c, step_wise.c, cpufreq_cooling.c) ^ | | diff --git a/MAINTAINERS b/MAINTAINERS index d2e92a0360f2..26e4be914765 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16194,7 +16194,7 @@ L: linux-pm@vger.kernel.org S: Supported F: Documentation/driver-api/thermal/cpu-cooling-api.rst F: Documentation/driver-api/thermal/cpu-idle-cooling.rst -F: drivers/thermal/cpu_cooling.c +F: drivers/thermal/cpufreq_cooling.c F: drivers/thermal/cpuidle_cooling.c F: include/linux/cpu_cooling.h diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 9c8aa2d4bd28..5c98472ffd8b 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -19,7 +19,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o # cpufreq cooling -thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpu_cooling.o +thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpufreq_cooling.o thermal_sys-$(CONFIG_CPU_IDLE_THERMAL) += cpuidle_cooling.o # clock cooling diff --git a/drivers/thermal/clock_cooling.c b/drivers/thermal/clock_cooling.c index 3ad3256c48fd..7cb3ae4b44ee 100644 --- a/drivers/thermal/clock_cooling.c +++ b/drivers/thermal/clock_cooling.c @@ -7,7 +7,7 @@ * Copyright (C) 2013 Texas Instruments Inc. * Contact: Eduardo Valentin * - * Highly based on cpu_cooling.c. + * Highly based on cpufreq_cooling.c. * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) * Copyright (C) 2012 Amit Daniel */ diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpufreq_cooling.c similarity index 99% rename from drivers/thermal/cpu_cooling.c rename to drivers/thermal/cpufreq_cooling.c index 6b9865c786ba..3a3f9cf94b6d 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * linux/drivers/thermal/cpu_cooling.c + * linux/drivers/thermal/cpufreq_cooling.c * * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) * @@ -694,7 +694,7 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) u32 capacitance = 0; if (!np) { - pr_err("cpu_cooling: OF node not available for cpu%d\n", + pr_err("cpufreq_cooling: OF node not available for cpu%d\n", policy->cpu); return NULL; } @@ -705,7 +705,7 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) cdev = __cpufreq_cooling_register(np, policy, capacitance); if (IS_ERR(cdev)) { - pr_err("cpu_cooling: cpu%d failed to register as cooling device: %ld\n", + pr_err("cpufreq_cooling: cpu%d failed to register as cooling device: %ld\n", policy->cpu, PTR_ERR(cdev)); cdev = NULL; } diff --git a/include/linux/clock_cooling.h b/include/linux/clock_cooling.h index b5cebf766e02..4b0a69863656 100644 --- a/include/linux/clock_cooling.h +++ b/include/linux/clock_cooling.h @@ -7,7 +7,7 @@ * Copyright (C) 2013 Texas Instruments Inc. * Contact: Eduardo Valentin * - * Highly based on cpu_cooling.c. + * Highly based on cpufreq_cooling.c. * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) * Copyright (C) 2012 Amit Daniel */