Commit df2fbf5b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'thermal-v5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux

Pull thermal updates from Daniel Lezcano:

 - Add the hwmon support on the i.MX SC (Anson Huang)

 - Thermal framework cleanups (self-encapsulation, pointless stubs,
   private structures) (Daniel Lezcano)

 - Use the PM QoS frequency changes for the devfreq cooling device
   (Matthias Kaehlcke)

 - Remove duplicate error messages from platform_get_irq() error
   handling (Markus Elfring)

 - Add support for the bandgap sensors (Keerthy)

 - Statically initialize .get_mode/.set_mode ops (Andrzej Pietrasiewicz)

 - Add Renesas R-Car maintainer entry (Niklas Söderlund)

 - Fix error checking after calling ti_bandgap_get_sensor_data() for the
   TI SoC thermal (Sudip Mukherjee)

 - Add latency constraint for the idle injection, the DT binding and the
   change the registering function (Daniel Lezcano)

 - Convert the thermal framework binding to the Yaml schema (Amit
   Kucheria)

 - Replace zero-length array with flexible-array on i.MX 8MM (Gustavo A.
   R. Silva)

 - Thermal framework cleanups (alphabetic order for heads, replace
   module.h by export.h, make file naming consistent) (Amit Kucheria)

 - Merge tsens-common into the tsens driver (Amit Kucheria)

 - Fix platform dependency for the Qoriq driver (Geert Uytterhoeven)

 - Clean up the rcar_thermal_update_temp() function in the rcar thermal
   driver (Niklas Söderlund)

 - Fix the TMSAR register for the TMUv2 on the Qoriq platform (Yuantian
   Tang)

 - Export GDDV, OEM vendor variables, and don't require IDSP for the
   int340x thermal driver - trivial conflicts fixed (Matthew Garrett)

* tag 'thermal-v5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (48 commits)
  thermal/int340x_thermal: Don't require IDSP to exist
  thermal/int340x_thermal: Export OEM vendor variables
  thermal/int340x_thermal: Export GDDV
  thermal: qoriq: Update the settings for TMUv2
  thermal: rcar_thermal: Clean up rcar_thermal_update_temp()
  thermal: qoriq: Add platform dependencies
  drivers: thermal: tsens: Merge tsens-common.c into tsens.c
  thermal/of: Rename of-thermal.c
  thermal/governors: Prefix all source files with gov_
  thermal/drivers/user_space: Sort headers alphabetically
  thermal/drivers/of-thermal: Sort headers alphabetically
  thermal/drivers/cpufreq_cooling: Replace module.h with export.h
  thermal/drivers/cpufreq_cooling: Sort headers alphabetically
  thermal/drivers/clock_cooling: Include export.h
  thermal/drivers/clock_cooling: Sort headers alphabetically
  thermal/drivers/thermal_hwmon: Include export.h
  thermal/drivers/thermal_hwmon: Sort headers alphabetically
  thermal/drivers/thermal_helpers: Include export.h
  thermal/drivers/thermal_helpers: Sort headers alphabetically
  thermal/core: Replace module.h with export.h
  ...
parents 44ebe016 8d485da0
# SPDX-License-Identifier: (GPL-2.0)
# Copyright 2020 Linaro Ltd.
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/thermal-cooling-devices.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Thermal cooling device binding
maintainers:
- Amit Kucheria <amitk@kernel.org>
description: |
Thermal management is achieved in devicetree by describing the sensor hardware
and the software abstraction of cooling devices and thermal zones required to
take appropriate action to mitigate thermal overload.
The following node types are used to completely describe a thermal management
system in devicetree:
- thermal-sensor: device that measures temperature, has SoC-specific bindings
- cooling-device: device used to dissipate heat either passively or actively
- thermal-zones: a container of the following node types used to describe all
thermal data for the platform
This binding describes the cooling devices.
There are essentially two ways to provide control on power dissipation:
- Passive cooling: by means of regulating device performance. A typical
passive cooling mechanism is a CPU that has dynamic voltage and frequency
scaling (DVFS), and uses lower frequencies as cooling states.
- Active cooling: by means of activating devices in order to remove the
dissipated heat, e.g. regulating fan speeds.
Any cooling device has a range of cooling states (i.e. different levels of
heat dissipation). They also have a way to determine the state of cooling in
which the device is. For example, a fan's cooling states correspond to the
different fan speeds possible. Cooling states are referred to by single
unsigned integers, where larger numbers mean greater heat dissipation. The
precise set of cooling states associated with a device should be defined in
a particular device's binding.
select: true
properties:
"#cooling-cells":
description:
Must be 2, in order to specify minimum and maximum cooling state used in
the cooling-maps reference. The first cell is the minimum cooling state
and the second cell is the maximum cooling state requested.
const: 2
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/thermal.h>
// Example 1: Cpufreq cooling device on CPU0
cpus {
#address-cells = <2>;
#size-cells = <0>;
CPU0: cpu@0 {
device_type = "cpu";
compatible = "qcom,kryo385";
reg = <0x0 0x0>;
enable-method = "psci";
cpu-idle-states = <&LITTLE_CPU_SLEEP_0
&LITTLE_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <607>;
dynamic-power-coefficient = <100>;
qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
L3_0: l3-cache {
compatible = "cache";
};
};
};
/* ... */
};
/* ... */
thermal-zones {
cpu0-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
thermal-sensors = <&tsens0 1>;
trips {
cpu0_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
};
cooling-maps {
map0 {
trip = <&cpu0_alert0>;
/* Corresponds to 1000MHz in OPP table */
cooling-device = <&CPU0 5 5>;
};
};
};
/* ... */
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright 2020 Linaro Ltd.
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/thermal-idle.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Thermal idle cooling device binding
maintainers:
- Daniel Lezcano <daniel.lezcano@linaro.org>
description: |
The thermal idle cooling device allows the system to passively
mitigate the temperature on the device by injecting idle cycles,
forcing it to cool down.
This binding describes the thermal idle node.
properties:
$nodename:
const: thermal-idle
description: |
A thermal-idle node describes the idle cooling device properties to
cool down efficiently the attached thermal zone.
'#cooling-cells':
const: 2
description: |
Must be 2, in order to specify minimum and maximum cooling state used in
the cooling-maps reference. The first cell is the minimum cooling state
and the second cell is the maximum cooling state requested.
duration-us:
description: |
The idle duration in microsecond the device should cool down.
exit-latency-us:
description: |
The exit latency constraint in microsecond for the injected
idle state for the device. It is the latency constraint to
apply when selecting an idle state from among all the present
ones.
required:
- '#cooling-cells'
examples:
- |
#include <dt-bindings/thermal/thermal.h>
// Example: Combining idle cooling device on big CPUs with cpufreq cooling device
cpus {
#address-cells = <2>;
#size-cells = <0>;
/* ... */
cpu_b0: cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a72";
reg = <0x0 0x100>;
enable-method = "psci";
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <436>;
#cooling-cells = <2>; /* min followed by max */
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
thermal-idle {
#cooling-cells = <2>;
duration-us = <10000>;
exit-latency-us = <500>;
};
};
cpu_b1: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a72";
reg = <0x0 0x101>;
enable-method = "psci";
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <436>;
#cooling-cells = <2>; /* min followed by max */
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
thermal-idle {
#cooling-cells = <2>;
duration-us = <10000>;
exit-latency-us = <500>;
};
};
/* ... */
};
/* ... */
thermal_zones {
cpu_thermal: cpu {
polling-delay-passive = <100>;
polling-delay = <1000>;
/* ... */
trips {
cpu_alert0: cpu_alert0 {
temperature = <65000>;
hysteresis = <2000>;
type = "passive";
};
cpu_alert1: cpu_alert1 {
temperature = <70000>;
hysteresis = <2000>;
type = "passive";
};
cpu_alert2: cpu_alert2 {
temperature = <75000>;
hysteresis = <2000>;
type = "passive";
};
cpu_crit: cpu_crit {
temperature = <95000>;
hysteresis = <2000>;
type = "critical";
};
};
cooling-maps {
map0 {
trip = <&cpu_alert1>;
cooling-device = <&{/cpus/cpu@100/thermal-idle} 0 15 >,
<&{/cpus/cpu@101/thermal-idle} 0 15>;
};
map1 {
trip = <&cpu_alert2>;
cooling-device =
<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
# SPDX-License-Identifier: (GPL-2.0)
# Copyright 2020 Linaro Ltd.
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/thermal-sensor.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Thermal sensor binding
maintainers:
- Amit Kucheria <amitk@kernel.org>
description: |
Thermal management is achieved in devicetree by describing the sensor hardware
and the software abstraction of thermal zones required to take appropriate
action to mitigate thermal overloads.
The following node types are used to completely describe a thermal management
system in devicetree:
- thermal-sensor: device that measures temperature, has SoC-specific bindings
- cooling-device: device used to dissipate heat either passively or actively
- thermal-zones: a container of the following node types used to describe all
thermal data for the platform
This binding describes the thermal-sensor.
Thermal sensor devices provide temperature sensing capabilities on thermal
zones. Typical devices are I2C ADC converters and bandgaps. Thermal sensor
devices may control one or more internal sensors.
properties:
"#thermal-sensor-cells":
description:
Used to uniquely identify a thermal sensor instance within an IC. Will be
0 on sensor nodes with only a single sensor and at least 1 on nodes
containing several internal sensors.
enum: [0, 1]
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
// Example 1: SDM845 TSENS
soc: soc@0 {
#address-cells = <2>;
#size-cells = <2>;
/* ... */
tsens0: thermal-sensor@c263000 {
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
reg = <0 0x0c263000 0 0x1ff>, /* TM */
<0 0x0c222000 0 0x1ff>; /* SROT */
#qcom,sensors = <13>;
interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uplow", "critical";
#thermal-sensor-cells = <1>;
};
tsens1: thermal-sensor@c265000 {
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
reg = <0 0x0c265000 0 0x1ff>, /* TM */
<0 0x0c223000 0 0x1ff>; /* SROT */
#qcom,sensors = <8>;
interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uplow", "critical";
#thermal-sensor-cells = <1>;
};
};
...
This diff is collapsed.
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/ti,am654-thermal.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments AM654 VTM (DTS) binding
maintainers:
- Keerthy <j-keerthy@ti.com>
properties:
compatible:
const: ti,am654-vtm
reg:
maxItems: 1
power-domains:
maxItems: 1
"#thermal-sensor-cells":
const: 1
required:
- compatible
- reg
- power-domains
- "#thermal-sensor-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/soc/ti,sci_pm_domain.h>
vtm: thermal@42050000 {
compatible = "ti,am654-vtm";
reg = <0x0 0x42050000 0x0 0x25c>;
power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>;
#thermal-sensor-cells = <1>;
};
mpu0_thermal: mpu0_thermal {
polling-delay-passive = <250>; /* milliseconds */
polling-delay = <500>; /* milliseconds */
thermal-sensors = <&vtm0 0>;
trips {
mpu0_crit: mpu0_crit {
temperature = <125000>; /* milliCelsius */
hysteresis = <2000>; /* milliCelsius */
type = "critical";
};
};
};
...
......@@ -14556,6 +14556,15 @@ F: Documentation/devicetree/bindings/i2c/renesas,iic.txt
F: drivers/i2c/busses/i2c-rcar.c
F: drivers/i2c/busses/i2c-sh_mobile.c
RENESAS R-CAR THERMAL DRIVERS
M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
L: linux-renesas-soc@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
F: Documentation/devicetree/bindings/thermal/rcar-thermal.txt
F: drivers/thermal/rcar_gen3_thermal.c
F: drivers/thermal/rcar_thermal.c
RENESAS RIIC DRIVER
M: Chris Brandt <chris.brandt@renesas.com>
S: Supported
......
......@@ -8,6 +8,7 @@
#define pr_fmt(fmt) "CPUidle arm: " fmt
#include <linux/cpu_cooling.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/cpu_pm.h>
......@@ -124,6 +125,8 @@ static int __init arm_idle_init_cpu(int cpu)
if (ret)
goto out_kfree_drv;
cpuidle_cooling_register(drv);
return 0;
out_kfree_drv:
......
......@@ -9,6 +9,7 @@
#define pr_fmt(fmt) "CPUidle PSCI: " fmt
#include <linux/cpuhotplug.h>
#include <linux/cpu_cooling.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/cpu_pm.h>
......@@ -319,6 +320,8 @@ static int __init psci_idle_init_cpu(int cpu)
if (ret)
goto out_kfree_drv;
cpuidle_cooling_register(drv);
return 0;
out_kfree_drv:
......
......@@ -61,12 +61,14 @@ struct idle_inject_thread {
* @timer: idle injection period timer
* @idle_duration_us: duration of CPU idle time to inject
* @run_duration_us: duration of CPU run time to allow
* @latency_us: max allowed latency
* @cpumask: mask of CPUs affected by idle injection
*/
struct idle_inject_device {
struct hrtimer timer;
unsigned int idle_duration_us;
unsigned int run_duration_us;
unsigned int latency_us;
unsigned long cpumask[];
};
......@@ -138,7 +140,8 @@ static void idle_inject_fn(unsigned int cpu)
*/
iit->should_run = 0;
play_idle(READ_ONCE(ii_dev->idle_duration_us));
play_idle_precise(READ_ONCE(ii_dev->idle_duration_us) * NSEC_PER_USEC,
READ_ONCE(ii_dev->latency_us) * NSEC_PER_USEC);
}
/**
......@@ -169,6 +172,16 @@ void idle_inject_get_duration(struct idle_inject_device *ii_dev,
*idle_duration_us = READ_ONCE(ii_dev->idle_duration_us);
}
/**
* idle_inject_set_latency - set the maximum latency allowed
* @latency_us: set the latency requirement for the idle state
*/
void idle_inject_set_latency(struct idle_inject_device *ii_dev,
unsigned int latency_us)
{
WRITE_ONCE(ii_dev->latency_us, latency_us);
}
/**
* idle_inject_start - start idle injections
* @ii_dev: idle injection control device structure
......@@ -297,6 +310,7 @@ struct idle_inject_device *idle_inject_register(struct cpumask *cpumask)
cpumask_copy(to_cpumask(ii_dev->cpumask), cpumask);
hrtimer_init(&ii_dev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ii_dev->timer.function = idle_inject_timer_fn;
ii_dev->latency_us = UINT_MAX;
for_each_cpu(cpu, to_cpumask(ii_dev->cpumask)) {
......
......@@ -273,6 +273,16 @@ config IMX8MM_THERMAL
cpufreq is used as the cooling device to throttle CPUs when the passive
trip is crossed.
config K3_THERMAL
tristate "Texas Instruments K3 thermal support"
depends on ARCH_K3 || COMPILE_TEST
help
If you say yes here you get thermal support for the Texas Instruments
K3 SoC family. The current chip supported is:
- AM654
This includes temperature reading functionality.
config MAX77620_THERMAL
tristate "Temperature sensor driver for Maxim MAX77620 PMIC"
depends on MFD_MAX77620
......@@ -285,8 +295,8 @@ config MAX77620_THERMAL
config QORIQ_THERMAL
tristate "QorIQ Thermal Monitoring Unit"
depends on THERMAL_OF
depends on HAS_IOMEM
depends on THERMAL_OF && HAS_IOMEM
depends on PPC_E500MC || SOC_LS1021A || ARCH_LAYERSCAPE || (ARCH_MXC && ARM64) || COMPILE_TEST
select REGMAP_MMIO
help
Support for Thermal Monitoring Unit (TMU) found on QorIQ platforms.
......
......@@ -9,14 +9,14 @@ thermal_sys-y += thermal_core.o thermal_sysfs.o \
# interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
thermal_sys-$(CONFIG_THERMAL_OF) += of-thermal.o
thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o
# governors
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += gov_fair_share.o
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += gov_step_wise.o
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += gov_user_space.o
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += gov_power_allocator.o
# cpufreq cooling
thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpufreq_cooling.o
......@@ -28,6 +28,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
# devfreq cooling
thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
obj-$(CONFIG_K3_THERMAL) += k3_bandgap.o
# platform thermal drivers
obj-y += broadcom/
obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
......
......@@ -12,15 +12,16 @@
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
*/
#include <linux/clk.h>
#include <linux/clock_cooling.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/idr.h>
#include <linux/mutex.h>
#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/clock_cooling.h>
/**
* struct clock_cooling_device - data for cooling device with clock
......
......@@ -10,17 +10,17 @@
* Viresh Kumar <viresh.kumar@linaro.org>
*
*/
#include <linux/module.h>
#include <linux/thermal.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/cpu_cooling.h>
#include <linux/energy_model.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/idr.h>
#include <linux/pm_opp.h>
#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/cpu_cooling.h>
#include <linux/energy_model.h>
#include <linux/thermal.h>
#include <trace/events/thermal.h>
......
......@@ -5,11 +5,14 @@
* Author: Daniel Lezcano <daniel.lezcano@linaro.org>
*
*/
#define pr_fmt(fmt) "cpuidle cooling: " fmt
#include <linux/cpu_cooling.h>
#include <linux/cpuidle.h>
#include <linux/err.h>
#include <linux/idle_inject.h>
#include <linux/idr.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/thermal.h>
......@@ -154,22 +157,25 @@ static struct thermal_cooling_device_ops cpuidle_cooling_ops = {
};
/**
* cpuidle_of_cooling_register - Idle cooling device initialization function
* __cpuidle_cooling_register: register the cooling device
* @drv: a cpuidle driver structure pointer
* @np: a node pointer to a device tree cooling device node
* @np: a device node structure pointer used for the thermal binding
*
* This function is in charge of creating a cooling device per cpuidle
* driver and register it to thermal framework.
* This function is in charge of allocating the cpuidle cooling device
* structure, the idle injection, initialize them and register the
* cooling device to the thermal framework.
*
* Return: zero on success, or negative value corresponding to the
* error detected in the underlying subsystems.
* Return: zero on success, a negative value returned by one of the
* underlying subsystem in case of error
*/
int cpuidle_of_cooling_register(struct device_node *np,
struct cpuidle_driver *drv)
static int __cpuidle_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;
unsigned int idle_duration_us = TICK_USEC;
unsigned int latency_us = UINT_MAX;
char dev_name[THERMAL_NAME_LENGTH];
int id, ret;
......@@ -191,7 +197,11 @@ int cpuidle_of_cooling_register(struct device_node *np,
goto out_id;
}
idle_inject_set_duration(ii_dev, TICK_USEC, TICK_USEC);
of_property_read_u32(np, "duration-us", &idle_duration_us);
of_property_read_u32(np, "exit-latency-us", &latency_us);
idle_inject_set_duration(ii_dev, TICK_USEC, idle_duration_us);
idle_inject_set_latency(ii_dev, latency_us);
idle_cdev->ii_dev = ii_dev;
......@@ -204,6 +214,9 @@ int cpuidle_of_cooling_register(struct device_node *np,
goto out_unregister;
}
pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",
dev_name, idle_duration_us, latency_us);
return 0;
out_unregister:
......@@ -221,12 +234,38 @@ int cpuidle_of_cooling_register(struct device_node *np,
* @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.
* driver and register it to the thermal framework.
*
* Return: zero on success, or negative value corresponding to the
* error detected in the underlying subsystems.
*/
int cpuidle_cooling_register(struct cpuidle_driver *drv)
void cpuidle_cooling_register(struct cpuidle_driver *drv)
{
return cpuidle_of_cooling_register(NULL, drv);
struct device_node *cooling_node;
struct device_node *cpu_node;
int cpu, ret;
for_each_cpu(cpu, drv->cpumask) {
cpu_node = of_cpu_device_node_get(cpu);
cooling_node = of_get_child_by_name(cpu_node, "thermal-idle");
of_node_put(cpu_node);
if (!cooling_node) {
pr_debug("'thermal-idle' node not found for cpu%d\n", cpu);
continue;
}
ret = __cpuidle_cooling_register(cooling_node, drv);
of_node_put(cooling_node);
if (ret) {
pr_err("Failed to register the cpuidle cooling device" \
"for cpu%d: %d\n", cpu, ret);
break;
}
}
}
......@@ -24,11 +24,13 @@
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/pm_opp.h>
#include <linux/pm_qos.h>
#include <linux/thermal.h>
#include <trace/events/thermal.h>
#define SCALE_ERROR_MITIGATION 100
#define HZ_PER_KHZ 1000
#define SCALE_ERROR_MITIGATION 100
static DEFINE_IDA(devfreq_ida);
......@@ -54,6 +56,8 @@ static DEFINE_IDA(devfreq_ida);
* The 'res_util' range is from 100 to (power_table[state] * 100)
* for the corresponding 'state'.
* @capped_state: index to cooling state with in dynamic power budget
* @req_max_freq: PM QoS request for limiting the maximum frequency
* of the devfreq device.
*/
struct devfreq_cooling_device {
int id;
......@@ -66,49 +70,9 @@ struct devfreq_cooling_device {
struct devfreq_cooling_power *power_ops;
u32 res_util;
int capped_state;
struct dev_pm_qos_request req_max_freq;
};
/**
* partition_enable_opps() - disable all opps above a given state
* @dfc: Pointer to devfreq we are operating on
* @cdev_state: cooling device state we're setting
*
* Go through the OPPs of the device, enabling all OPPs until
* @cdev_state and disabling those frequencies above it.
*/
static int partition_enable_opps(struct devfreq_cooling_device *dfc,
unsigned long cdev_state)
{
int i;
struct device *dev = dfc->devfreq->dev.parent;
for (i = 0; i < dfc->freq_table_size; i++) {
struct dev_pm_opp *opp;
int ret = 0;
unsigned int freq = dfc->freq_table[i];
bool want_enable = i >= cdev_state ? true : false;
opp = dev_pm_opp_find_freq_exact(dev, freq, !want_enable);
if (PTR_ERR(opp) == -ERANGE)
continue;
else if (IS_ERR(opp))
return PTR_ERR(opp);
dev_pm_opp_put(opp);
if (want_enable)
ret = dev_pm_opp_enable(dev, freq);
else
ret = dev_pm_opp_disable(dev, freq);
if (ret)
return ret;
}
return 0;
}
static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
......@@ -135,7 +99,7 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
struct devfreq_cooling_device *dfc = cdev->devdata;
struct devfreq *df = dfc->devfreq;
struct device *dev = df->dev.parent;
int ret;
unsigned long freq;
if (state == dfc->cooling_state)
return 0;
......@@ -145,9 +109,10 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
if (state >= dfc->freq_table_size)
return -EINVAL;
ret = partition_enable_opps(dfc, state);
if (ret)
return ret;
freq = dfc->freq_table[state];
dev_pm_qos_update_request(&dfc->req_max_freq,
DIV_ROUND_UP(freq, HZ_PER_KHZ));
dfc->cooling_state = state;
......@@ -530,9 +495,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
if (err)
goto free_dfc;
err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
err = dev_pm_qos_add_request(df->dev.parent, &dfc->req_max_freq,
DEV_PM_QOS_MAX_FREQUENCY,
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
if (err < 0)
goto free_tables;
err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
if (err < 0)
goto remove_qos_req;
dfc->id = err;
snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
......@@ -553,6 +524,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
release_ida:
ida_simple_remove(&devfreq_ida, dfc->id);
remove_qos_req:
dev_pm_qos_remove_request(&dfc->req_max_freq);
free_tables:
kfree(dfc->power_table);
kfree(dfc->freq_table);
......@@ -601,6 +576,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
thermal_cooling_device_unregister(dfc->cdev);
ida_simple_remove(&devfreq_ida, dfc->id);
dev_pm_qos_remove_request(&dfc->req_max_freq);
kfree(dfc->power_table);
kfree(dfc->freq_table);
......
......@@ -10,8 +10,8 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/thermal.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include "thermal_core.h"
......
......@@ -54,7 +54,7 @@ struct imx8mm_tmu {
void __iomem *base;
struct clk *clk;
const struct thermal_soc_data *socdata;
struct tmu_sensor sensors[0];
struct tmu_sensor sensors[];
};
static int imx8mm_tmu_get_temp(void *data, int *temp)
......
......@@ -14,6 +14,7 @@
#include <linux/thermal.h>
#include "thermal_core.h"
#include "thermal_hwmon.h"
#define IMX_SC_MISC_FUNC_GET_TEMP 13
......@@ -115,6 +116,9 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(sensor->tzd);
break;
}
if (devm_thermal_add_hwmon_sysfs(sensor->tzd))
dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
}
of_node_put(sensor_np);
......
......@@ -13,6 +13,7 @@
#include "acpi_thermal_rel.h"
#define INT3400_THERMAL_TABLE_CHANGED 0x83
#define INT3400_ODVP_CHANGED 0x88
enum int3400_thermal_uuid {
INT3400_THERMAL_PASSIVE_1,
......@@ -41,8 +42,11 @@ static char *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = {
"BE84BABF-C4D4-403D-B495-3128FD44dAC1",
};
struct odvp_attr;
struct int3400_thermal_priv {
struct acpi_device *adev;
struct platform_device *pdev;
struct thermal_zone_device *thermal;
int mode;
int art_count;
......@@ -52,6 +56,36 @@ struct int3400_thermal_priv {
u8 uuid_bitmap;
int rel_misc_dev_res;
int current_uuid_index;
char *data_vault;
int odvp_count;
int *odvp;
struct odvp_attr *odvp_attrs;
};
static int evaluate_odvp(struct int3400_thermal_priv *priv);
struct odvp_attr {
int odvp;
struct int3400_thermal_priv *priv;
struct kobj_attribute attr;
};
static ssize_t data_vault_read(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf, loff_t off, size_t count)
{
memcpy(buf, attr->private + off, count);
return count;
}
static BIN_ATTR_RO(data_vault, 0);
static struct bin_attribute *data_attributes[] = {
&bin_attr_data_vault,
NULL,
};
static const struct attribute_group data_attribute_group = {
.bin_attrs = data_attributes,
};
static ssize_t available_uuids_show(struct device *dev,
......@@ -62,6 +96,9 @@ static ssize_t available_uuids_show(struct device *dev,
int i;
int length = 0;
if (!priv->uuid_bitmap)
return sprintf(buf, "UNKNOWN\n");
for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) {
if (priv->uuid_bitmap & (1 << i))
if (PAGE_SIZE - length > 0)
......@@ -79,11 +116,11 @@ static ssize_t current_uuid_show(struct device *dev,
{
struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
if (priv->uuid_bitmap & (1 << priv->current_uuid_index))
return sprintf(buf, "%s\n",
int3400_thermal_uuids[priv->current_uuid_index]);
else
if (priv->current_uuid_index == -1)
return sprintf(buf, "INVALID\n");
return sprintf(buf, "%s\n",
int3400_thermal_uuids[priv->current_uuid_index]);
}
static ssize_t current_uuid_store(struct device *dev,
......@@ -94,9 +131,16 @@ static ssize_t current_uuid_store(struct device *dev,
int i;
for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; ++i) {
if ((priv->uuid_bitmap & (1 << i)) &&
!(strncmp(buf, int3400_thermal_uuids[i],
sizeof(int3400_thermal_uuids[i]) - 1))) {
if (!strncmp(buf, int3400_thermal_uuids[i],
sizeof(int3400_thermal_uuids[i]) - 1)) {
/*
* If we have a list of supported UUIDs, make sure
* this one is supported.
*/
if (priv->uuid_bitmap &&
!(priv->uuid_bitmap & (1 << i)))
return -EINVAL;
priv->current_uuid_index = i;
return count;
}
......@@ -191,9 +235,110 @@ static int int3400_thermal_run_osc(acpi_handle handle,
result = -EPERM;
kfree(context.ret.pointer);
return result;
}
static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
struct odvp_attr *odvp_attr;
odvp_attr = container_of(attr, struct odvp_attr, attr);
return sprintf(buf, "%d\n", odvp_attr->priv->odvp[odvp_attr->odvp]);
}
static void cleanup_odvp(struct int3400_thermal_priv *priv)
{
int i;
if (priv->odvp_attrs) {
for (i = 0; i < priv->odvp_count; i++) {
sysfs_remove_file(&priv->pdev->dev.kobj,
&priv->odvp_attrs[i].attr.attr);
kfree(priv->odvp_attrs[i].attr.attr.name);
}
kfree(priv->odvp_attrs);
}
kfree(priv->odvp);
priv->odvp_count = 0;
}
static int evaluate_odvp(struct int3400_thermal_priv *priv)
{
struct acpi_buffer odvp = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj = NULL;
acpi_status status;
int i, ret;
status = acpi_evaluate_object(priv->adev->handle, "ODVP", NULL, &odvp);
if (ACPI_FAILURE(status)) {
ret = -EINVAL;
goto out_err;
}
obj = odvp.pointer;
if (obj->type != ACPI_TYPE_PACKAGE) {
ret = -EINVAL;
goto out_err;
}
if (priv->odvp == NULL) {
priv->odvp_count = obj->package.count;
priv->odvp = kmalloc_array(priv->odvp_count, sizeof(int),
GFP_KERNEL);
if (!priv->odvp) {
ret = -ENOMEM;
goto out_err;
}
}
if (priv->odvp_attrs == NULL) {
priv->odvp_attrs = kcalloc(priv->odvp_count,
sizeof(struct odvp_attr),
GFP_KERNEL);
if (!priv->odvp_attrs) {
ret = -ENOMEM;
goto out_err;
}
for (i = 0; i < priv->odvp_count; i++) {
struct odvp_attr *odvp = &priv->odvp_attrs[i];
sysfs_attr_init(&odvp->attr.attr);
odvp->priv = priv;
odvp->odvp = i;
odvp->attr.attr.name = kasprintf(GFP_KERNEL,
"odvp%d", i);
if (!odvp->attr.attr.name) {
ret = -ENOMEM;
goto out_err;
}
odvp->attr.attr.mode = 0444;
odvp->attr.show = odvp_show;
odvp->attr.store = NULL;
ret = sysfs_create_file(&priv->pdev->dev.kobj,
&odvp->attr.attr);
if (ret)
goto out_err;
}
}
for (i = 0; i < obj->package.count; i++) {
if (obj->package.elements[i].type == ACPI_TYPE_INTEGER)
priv->odvp[i] = obj->package.elements[i].integer.value;
}
kfree(obj);
return 0;
out_err:
cleanup_odvp(priv);
kfree(obj);
return ret;
}
static void int3400_notify(acpi_handle handle,
u32 event,
void *data)
......@@ -217,6 +362,9 @@ static void int3400_notify(acpi_handle handle,
kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE,
thermal_prop);
break;
case INT3400_ODVP_CHANGED:
evaluate_odvp(priv);
break;
default:
/* Ignore unknown notification codes sent to INT3400 device */
break;
......@@ -266,11 +414,16 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
priv->current_uuid_index,
enable);
}
evaluate_odvp(priv);
return result;
}
static struct thermal_zone_device_ops int3400_thermal_ops = {
.get_temp = int3400_thermal_get_temp,
.get_mode = int3400_thermal_get_mode,
.set_mode = int3400_thermal_set_mode,
};
static struct thermal_zone_params int3400_thermal_params = {
......@@ -278,6 +431,32 @@ static struct thermal_zone_params int3400_thermal_params = {
.no_hwmon = true,
};
static void int3400_setup_gddv(struct int3400_thermal_priv *priv)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
status = acpi_evaluate_object(priv->adev->handle, "GDDV", NULL,
&buffer);
if (ACPI_FAILURE(status) || !buffer.length)
return;
obj = buffer.pointer;
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 1
|| obj->package.elements[0].type != ACPI_TYPE_BUFFER) {
kfree(buffer.pointer);
return;
}
priv->data_vault = kmemdup(obj->package.elements[0].buffer.pointer,
obj->package.elements[0].buffer.length,
GFP_KERNEL);
bin_attr_data_vault.private = priv->data_vault;
bin_attr_data_vault.size = obj->package.elements[0].buffer.length;
kfree(buffer.pointer);
}
static int int3400_thermal_probe(struct platform_device *pdev)
{
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
......@@ -291,12 +470,17 @@ static int int3400_thermal_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
priv->pdev = pdev;
priv->adev = adev;
result = int3400_thermal_get_uuids(priv);
if (result)
/* Missing IDSP isn't fatal */
if (result && result != -ENODEV)
goto free_priv;
priv->current_uuid_index = -1;
result = acpi_parse_art(priv->adev->handle, &priv->art_count,
&priv->arts, true);
if (result)
......@@ -309,8 +493,9 @@ static int int3400_thermal_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
int3400_thermal_ops.get_mode = int3400_thermal_get_mode;
int3400_thermal_ops.set_mode = int3400_thermal_set_mode;
int3400_setup_gddv(priv);
evaluate_odvp(priv);
priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0,
priv, &int3400_thermal_ops,
......@@ -327,6 +512,13 @@ static int int3400_thermal_probe(struct platform_device *pdev)
if (result)
goto free_rel_misc;
if (priv->data_vault) {
result = sysfs_create_group(&pdev->dev.kobj,
&data_attribute_group);
if (result)
goto free_uuid;
}
result = acpi_install_notify_handler(
priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify,
(void *)priv);
......@@ -336,6 +528,12 @@ static int int3400_thermal_probe(struct platform_device *pdev)
return 0;
free_sysfs:
cleanup_odvp(priv);
if (priv->data_vault) {
sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
kfree(priv->data_vault);
}
free_uuid:
sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
free_rel_misc:
if (!priv->rel_misc_dev_res)
......@@ -357,11 +555,16 @@ static int int3400_thermal_remove(struct platform_device *pdev)
priv->adev->handle, ACPI_DEVICE_NOTIFY,
int3400_notify);
cleanup_odvp(priv);
if (!priv->rel_misc_dev_res)
acpi_thermal_rel_misc_device_remove(priv->adev->handle);
if (priv->data_vault)
sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
thermal_zone_device_unregister(priv->thermal);
kfree(priv->data_vault);
kfree(priv->trts);
kfree(priv->arts);
kfree(priv);
......
// SPDX-License-Identifier: GPL-2.0
/*
* TI Bandgap temperature sensor driver for K3 SoC Family
*
* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/thermal.h>
#include <linux/types.h>
#define K3_VTM_DEVINFO_PWR0_OFFSET 0x4
#define K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK 0xf0
#define K3_VTM_TMPSENS0_CTRL_OFFSET 0x80
#define K3_VTM_REGS_PER_TS 0x10
#define K3_VTM_TS_STAT_DTEMP_MASK 0x3ff
#define K3_VTM_TMPSENS_CTRL_CBIASSEL BIT(0)
#define K3_VTM_TMPSENS_CTRL_SOC BIT(5)
#define K3_VTM_TMPSENS_CTRL_CLRZ BIT(6)
#define K3_VTM_TMPSENS_CTRL_CLKON_REQ BIT(7)
#define K3_VTM_ADC_BEGIN_VAL 540
#define K3_VTM_ADC_END_VAL 944
static const int k3_adc_to_temp[] = {
-40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
-37800, -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200,
-33800, -33400, -33000, -32600, -32200, -31800, -31400, -31000, -30600,
-30200, -29800, -29400, -29000, -28600, -28200, -27700, -27100, -26600,
-26200, -25800, -25400, -25000, -24600, -24200, -23800, -23400, -23000,
-22600, -22200, -21800, -21400, -21000, -20500, -19900, -19400, -19000,
-18600, -18200, -17800, -17400, -17000, -16600, -16200, -15800, -15400,
-15000, -14600, -14200, -13800, -13400, -13000, -12500, -11900, -11400,
-11000, -10600, -10200, -9800, -9400, -9000, -8600, -8200, -7800, -7400,
-7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900, -3400, -3000,
-2600, -2200, -1800, -1400, -1000, -600, -200, 200, 600, 1000, 1400,
1800, 2200, 2600, 3000, 3400, 3900, 4500, 5000, 5400, 5800, 6200, 6600,
7000, 7400, 7800, 8200, 8600, 9000, 9400, 9800, 10200, 10600, 11000,
11400, 11800, 12200, 12700, 13300, 13800, 14200, 14600, 15000, 15400,
15800, 16200, 16600, 17000, 17400, 17800, 18200, 18600, 19000, 19400,
19800, 20200, 20600, 21000, 21400, 21900, 22500, 23000, 23400, 23800,
24200, 24600, 25000, 25400, 25800, 26200, 26600, 27000, 27400, 27800,
28200, 28600, 29000, 29400, 29800, 30200, 30600, 31000, 31400, 31900,
32500, 33000, 33400, 33800, 34200, 34600, 35000, 35400, 35800, 36200,
36600, 37000, 37400, 37800, 38200, 38600, 39000, 39400, 39800, 40200,
40600, 41000, 41400, 41800, 42200, 42600, 43100, 43700, 44200, 44600,
45000, 45400, 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600,
49000, 49400, 49800, 50200, 50600, 51000, 51400, 51800, 52200, 52600,
53000, 53400, 53800, 54200, 54600, 55000, 55400, 55900, 56500, 57000,
57400, 57800, 58200, 58600, 59000, 59400, 59800, 60200, 60600, 61000,
61400, 61800, 62200, 62600, 63000, 63400, 63800, 64200, 64600, 65000,
65400, 65800, 66200, 66600, 67000, 67400, 67800, 68200, 68600, 69000,
69400, 69800, 70200, 70600, 71000, 71500, 72100, 72600, 73000, 73400,
73800, 74200, 74600, 75000, 75400, 75800, 76200, 76600, 77000, 77400,
77800, 78200, 78600, 79000, 79400, 79800, 80200, 80600, 81000, 81400,
81800, 82200, 82600, 83000, 83400, 83800, 84200, 84600, 85000, 85400,
85800, 86200, 86600, 87000, 87400, 87800, 88200, 88600, 89000, 89400,
89800, 90200, 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400,
93800, 94200, 94600, 95000, 95400, 95800, 96200, 96600, 97000, 97500,
98100, 98600, 99000, 99400, 99800, 100200, 100600, 101000, 101400,
101800, 102200, 102600, 103000, 103400, 103800, 104200, 104600, 105000,
105400, 105800, 106200, 106600, 107000, 107400, 107800, 108200, 108600,
109000, 109400, 109800, 110200, 110600, 111000, 111400, 111800, 112200,
112600, 113000, 113400, 113800, 114200, 114600, 115000, 115400, 115800,
116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000, 119400,
119800, 120200, 120600, 121000, 121400, 121800, 122200, 122600, 123000,
123400, 123800, 124200, 124600, 124900, 125000,
};
struct k3_bandgap {
void __iomem *base;
const struct k3_bandgap_data *conf;
};
/* common data structures */
struct k3_thermal_data {
struct thermal_zone_device *tzd;
struct k3_bandgap *bgp;
int sensor_id;
u32 ctrl_offset;
u32 stat_offset;
};
static unsigned int vtm_get_best_value(unsigned int s0, unsigned int s1,
unsigned int s2)
{
int d01 = abs(s0 - s1);
int d02 = abs(s0 - s2);
int d12 = abs(s1 - s2);
if (d01 <= d02 && d01 <= d12)
return (s0 + s1) / 2;
if (d02 <= d01 && d02 <= d12)
return (s0 + s2) / 2;
return (s1 + s2) / 2;
}
static int k3_bgp_read_temp(struct k3_thermal_data *devdata,
int *temp)
{
struct k3_bandgap *bgp;
unsigned int dtemp, s0, s1, s2;
bgp = devdata->bgp;
/*
* Errata is applicable for am654 pg 1.0 silicon. There
* is a variation of the order for 8-10 degree centigrade.
* Work around that by getting the average of two closest
* readings out of three readings everytime we want to
* report temperatures.
*
* Errata workaround.
*/
s0 = readl(bgp->base + devdata->stat_offset) &
K3_VTM_TS_STAT_DTEMP_MASK;
s1 = readl(bgp->base + devdata->stat_offset) &
K3_VTM_TS_STAT_DTEMP_MASK;
s2 = readl(bgp->base + devdata->stat_offset) &
K3_VTM_TS_STAT_DTEMP_MASK;
dtemp = vtm_get_best_value(s0, s1, s2);
if (dtemp < K3_VTM_ADC_BEGIN_VAL || dtemp > K3_VTM_ADC_END_VAL)
return -EINVAL;
*temp = k3_adc_to_temp[dtemp - K3_VTM_ADC_BEGIN_VAL];
return 0;
}
static int k3_thermal_get_temp(void *devdata, int *temp)
{
struct k3_thermal_data *data = devdata;
int ret = 0;
ret = k3_bgp_read_temp(data, temp);
if (ret)
return ret;
return ret;
}
static const struct thermal_zone_of_device_ops k3_of_thermal_ops = {
.get_temp = k3_thermal_get_temp,
};
static const struct of_device_id of_k3_bandgap_match[];
static int k3_bandgap_probe(struct platform_device *pdev)
{
int ret = 0, cnt, val, id;
struct resource *res;
struct device *dev = &pdev->dev;
struct k3_bandgap *bgp;
struct k3_thermal_data *data;
if (ARRAY_SIZE(k3_adc_to_temp) != (K3_VTM_ADC_END_VAL + 1 -
K3_VTM_ADC_BEGIN_VAL))
return -EINVAL;
bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
if (!bgp)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bgp->base = devm_ioremap_resource(dev, res);
if (IS_ERR(bgp->base))
return PTR_ERR(bgp->base);
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
return ret;
}
/* Get the sensor count in the VTM */
val = readl(bgp->base + K3_VTM_DEVINFO_PWR0_OFFSET);
cnt = val & K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK;
cnt >>= __ffs(K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK);
data = devm_kcalloc(dev, cnt, sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto err_alloc;
}
/* Register the thermal sensors */
for (id = 0; id < cnt; id++) {
data[id].sensor_id = id;
data[id].bgp = bgp;
data[id].ctrl_offset = K3_VTM_TMPSENS0_CTRL_OFFSET +
id * K3_VTM_REGS_PER_TS;
data[id].stat_offset = data[id].ctrl_offset + 0x8;
val = readl(data[id].bgp->base + data[id].ctrl_offset);
val |= (K3_VTM_TMPSENS_CTRL_SOC |
K3_VTM_TMPSENS_CTRL_CLRZ |
K3_VTM_TMPSENS_CTRL_CLKON_REQ);
val &= ~K3_VTM_TMPSENS_CTRL_CBIASSEL;
writel(val, data[id].bgp->base + data[id].ctrl_offset);
data[id].tzd =
devm_thermal_zone_of_sensor_register(dev, id,
&data[id],
&k3_of_thermal_ops);
if (IS_ERR(data[id].tzd)) {
dev_err(dev, "thermal zone device is NULL\n");
ret = PTR_ERR(data[id].tzd);
goto err_alloc;
}
}
platform_set_drvdata(pdev, bgp);
return 0;
err_alloc:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
return ret;
}
static int k3_bandgap_remove(struct platform_device *pdev)
{
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}
static const struct of_device_id of_k3_bandgap_match[] = {
{
.compatible = "ti,am654-vtm",
},
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, of_k3_bandgap_match);
static struct platform_driver k3_bandgap_sensor_driver = {
.probe = k3_bandgap_probe,
.remove = k3_bandgap_remove,
.driver = {
.name = "k3-soc-thermal",
.of_match_table = of_k3_bandgap_match,
},
};
module_platform_driver(k3_bandgap_sensor_driver);
MODULE_DESCRIPTION("K3 bandgap temperature sensor driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o \
tsens-8960.o tsens-v2.o tsens-v1.o
qcom_tsens-y += tsens.o tsens-v2.o tsens-v1.o tsens-v0_1.o \
tsens-8960.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
This diff is collapsed.
This diff is collapsed.
......@@ -580,11 +580,6 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo
int init_common(struct tsens_priv *priv);
int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
int get_temp_common(const struct tsens_sensor *s, int *temp);
int tsens_enable_irq(struct tsens_priv *priv);
void tsens_disable_irq(struct tsens_priv *priv);
int tsens_set_trips(void *_sensor, int low, int high);
irqreturn_t tsens_irq_thread(int irq, void *data);
irqreturn_t tsens_critical_irq_thread(int irq, void *data);
/* TSENS target */
extern struct tsens_plat_data data_8960;
......
......@@ -11,6 +11,7 @@
#include <linux/regmap.h>
#include <linux/sizes.h>
#include <linux/thermal.h>
#include <linux/units.h>
#include "thermal_core.h"
#include "thermal_hwmon.h"
......@@ -23,6 +24,7 @@
#define TMTMIR_DEFAULT 0x0000000f
#define TIER_DISABLE 0x0
#define TEUMR0_V2 0x51009c00
#define TMSARA_V2 0xe
#define TMU_VER1 0x1
#define TMU_VER2 0x2
......@@ -50,6 +52,9 @@
* Site Register
*/
#define TRITSR_V BIT(31)
#define REGS_V2_TMSAR(n) (0x304 + 16 * (n)) /* TMU monitoring
* site adjustment register
*/
#define REGS_TTRnCR(n) (0xf10 + 4 * (n)) /* Temperature Range n
* Control Register
*/
......@@ -85,12 +90,21 @@ static int tmu_get_temp(void *p, int *temp)
/*
* REGS_TRITSR(id) has the following layout:
*
* For TMU Rev1:
* 31 ... 7 6 5 4 3 2 1 0
* V TEMP
*
* Where V bit signifies if the measurement is ready and is
* within sensor range. TEMP is an 8 bit value representing
* temperature in C.
* temperature in Celsius.
* For TMU Rev2:
* 31 ... 8 7 6 5 4 3 2 1 0
* V TEMP
*
* Where V bit signifies if the measurement is ready and is
* within sensor range. TEMP is an 9 bit value representing
* temperature in KelVin.
*/
if (regmap_read_poll_timeout(qdata->regmap,
REGS_TRITSR(qsensor->id),
......@@ -100,7 +114,10 @@ static int tmu_get_temp(void *p, int *temp)
10 * USEC_PER_MSEC))
return -ENODATA;
*temp = (val & 0xff) * 1000;
if (qdata->ver == TMU_VER1)
*temp = (val & GENMASK(7, 0)) * MILLIDEGREE_PER_DEGREE;
else
*temp = kelvin_to_millicelsius(val & GENMASK(8, 0));
return 0;
}
......@@ -192,6 +209,8 @@ static int qoriq_tmu_calibration(struct device *dev,
static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
{
int i;
/* Disable interrupt, using polling instead */
regmap_write(data->regmap, REGS_TIER, TIER_DISABLE);
......@@ -202,6 +221,8 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
} else {
regmap_write(data->regmap, REGS_V2_TMTMIR, TMTMIR_DEFAULT);
regmap_write(data->regmap, REGS_V2_TEUMR(0), TEUMR0_V2);
for (i = 0; i < SITES_MAX; i++)
regmap_write(data->regmap, REGS_V2_TMSAR(i), TMSARA_V2);
}
/* Disable monitoring */
......@@ -212,6 +233,7 @@ static const struct regmap_range qoriq_yes_ranges[] = {
regmap_reg_range(REGS_TMR, REGS_TSCFGR),
regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(3)),
regmap_reg_range(REGS_V2_TEUMR(0), REGS_V2_TEUMR(2)),
regmap_reg_range(REGS_V2_TMSAR(0), REGS_V2_TMSAR(15)),
regmap_reg_range(REGS_IPBRR(0), REGS_IPBRR(1)),
/* Read only registers below */
regmap_reg_range(REGS_TRITSR(0), REGS_TRITSR(15)),
......
......@@ -198,8 +198,8 @@ static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
{
struct device *dev = rcar_priv_to_dev(priv);
int i;
u32 ctemp, old, new;
int old, new, ctemp = -EINVAL;
unsigned int i;
mutex_lock(&priv->lock);
......@@ -209,7 +209,6 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
*/
rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL);
ctemp = 0;
old = ~0;
for (i = 0; i < 128; i++) {
/*
......@@ -227,7 +226,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
old = new;
}
if (!ctemp) {
if (ctemp < 0) {
dev_err(dev, "thermal sensor was broken\n");
goto err_out_unlock;
}
......@@ -248,7 +247,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
err_out_unlock:
mutex_unlock(&priv->lock);
return ctemp ? ctemp : -EINVAL;
return ctemp;
}
static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
......
......@@ -1241,10 +1241,8 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
return -ENXIO;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
if (irq < 0)
return -EINVAL;
}
thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data),
GFP_KERNEL);
......
......@@ -94,10 +94,8 @@ static int st_mmap_register_enable_irq(struct st_thermal_sensor *sensor)
int ret;
sensor->irq = platform_get_irq(pdev, 0);
if (sensor->irq < 0) {
dev_err(dev, "failed to register IRQ\n");
if (sensor->irq < 0)
return sensor->irq;
}
ret = devm_request_threaded_irq(dev, sensor->irq,
NULL, st_mmap_thermal_trip_handler,
......
......@@ -385,10 +385,8 @@ static int stm_register_irq(struct stm_thermal_sensor *sensor)
int ret;
sensor->irq = platform_get_irq(pdev, 0);
if (sensor->irq < 0) {
dev_err(dev, "%s: Unable to find IRQ\n", __func__);
if (sensor->irq < 0)
return sensor->irq;
}
ret = devm_request_threaded_irq(dev, sensor->irq,
NULL,
......
......@@ -9,9 +9,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
......@@ -27,10 +27,6 @@
#include "thermal_core.h"
#include "thermal_hwmon.h"
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
MODULE_LICENSE("GPL v2");
static DEFINE_IDA(thermal_tz_ida);
static DEFINE_IDA(thermal_cdev_ida);
......@@ -447,12 +443,6 @@ static void update_temperature(struct thermal_zone_device *tz)
mutex_unlock(&tz->lock);
trace_thermal_temperature(tz);
if (tz->last_temperature == THERMAL_TEMP_INVALID)
dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
tz->temperature);
else
dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
tz->last_temperature, tz->temperature);
}
static void thermal_zone_device_init(struct thermal_zone_device *tz)
......
......@@ -12,6 +12,17 @@
#include <linux/device.h>
#include <linux/thermal.h>
/* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
#define DEFAULT_THERMAL_GOVERNOR "fair_share"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
#define DEFAULT_THERMAL_GOVERNOR "user_space"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
#define DEFAULT_THERMAL_GOVERNOR "power_allocator"
#endif
/* Initial state of a cooling device during binding */
#define THERMAL_NO_TARGET -1UL
......@@ -30,6 +41,44 @@ extern struct thermal_governor *__governor_thermal_table_end[];
__governor < __governor_thermal_table_end; \
__governor++)
struct thermal_attr {
struct device_attribute attr;
char name[THERMAL_NAME_LENGTH];
};
static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
{
return cdev->ops->get_requested_power && cdev->ops->state2power &&
cdev->ops->power2state;
}
int power_actor_get_max_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz, u32 *max_power);
int power_actor_get_min_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz, u32 *min_power);
int power_actor_set_power(struct thermal_cooling_device *cdev,
struct thermal_instance *ti, u32 power);
/**
* struct thermal_trip - representation of a point in temperature domain
* @np: pointer to struct device_node that this trip point was created from
* @temperature: temperature value in miliCelsius
* @hysteresis: relative hysteresis in miliCelsius
* @type: trip point type
*/
struct thermal_trip {
struct device_node *np;
int temperature;
int hysteresis;
enum thermal_trip_type type;
};
int get_tz_trend(struct thermal_zone_device *tz, int trip);
struct thermal_instance *
get_thermal_instance(struct thermal_zone_device *tz,
struct thermal_cooling_device *cdev,
int trip);
/*
* This structure is used to describe the behavior of
* a certain cooling device on a certain trip point
......@@ -69,6 +118,9 @@ void thermal_zone_device_unbind_exception(struct thermal_zone_device *,
int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
int thermal_build_list_of_policies(char *buf);
/* Helpers */
void thermal_zone_set_trips(struct thermal_zone_device *tz);
/* sysfs I/F */
int thermal_zone_create_device_groups(struct thermal_zone_device *, int);
void thermal_zone_destroy_device_groups(struct thermal_zone_device *);
......
......@@ -12,11 +12,12 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <trace/events/thermal.h>
......@@ -113,6 +114,18 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
}
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
/**
* thermal_zone_set_trips - Computes the next trip points for the driver
* @tz: a pointer to a thermal zone device structure
*
* The function computes the next temperature boundaries by browsing
* the trip points. The result is the closer low and high trip points
* to the current temperature. These values are passed to the backend
* driver to let it set its own notification mechanism (usually an
* interrupt).
*
* It does not return a value
*/
void thermal_zone_set_trips(struct thermal_zone_device *tz)
{
int low = -INT_MAX;
......@@ -161,7 +174,6 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
exit:
mutex_unlock(&tz->lock);
}
EXPORT_SYMBOL_GPL(thermal_zone_set_trips);
void thermal_cdev_update(struct thermal_cooling_device *cdev)
{
......
......@@ -10,10 +10,12 @@
* Copyright (C) 2013 Texas Instruments
* Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com>
*/
#include <linux/err.h>
#include <linux/export.h>
#include <linux/hwmon.h>
#include <linux/thermal.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/thermal.h>
#include "thermal_hwmon.h"
/* hwmon sys I/F */
......
......@@ -8,13 +8,13 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/thermal.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/types.h>
#include <linux/string.h>
#include "thermal_core.h"
......
......@@ -772,10 +772,9 @@ static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
int ret;
bgp->irq = platform_get_irq(pdev, 0);
if (bgp->irq < 0) {
dev_err(&pdev->dev, "get_irq failed\n");
if (bgp->irq < 0)
return bgp->irq;
}
ret = request_threaded_irq(bgp->irq, NULL,
ti_bandgap_talert_irq_handler,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
......
......@@ -169,7 +169,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
data = ti_bandgap_get_sensor_data(bgp, id);
if (!data || IS_ERR(data))
if (!IS_ERR_OR_NULL(data))
data = ti_thermal_build_data(bgp, id);
if (!data)
......@@ -196,7 +196,7 @@ int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id)
data = ti_bandgap_get_sensor_data(bgp, id);
if (data && data->ti_thermal) {
if (!IS_ERR_OR_NULL(data) && data->ti_thermal) {
if (data->our_zone)
thermal_zone_device_unregister(data->ti_thermal);
}
......@@ -262,7 +262,7 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
data = ti_bandgap_get_sensor_data(bgp, id);
if (data) {
if (!IS_ERR_OR_NULL(data)) {
cpufreq_cooling_unregister(data->cool_dev);
if (data->policy)
cpufreq_cpu_put(data->policy);
......
......@@ -63,18 +63,10 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy)
struct cpuidle_driver;
#ifdef CONFIG_CPU_IDLE_THERMAL
int cpuidle_cooling_register(struct cpuidle_driver *drv);
int cpuidle_of_cooling_register(struct device_node *np,
struct cpuidle_driver *drv);
void cpuidle_cooling_register(struct cpuidle_driver *drv);
#else /* CONFIG_CPU_IDLE_THERMAL */
static inline int cpuidle_cooling_register(struct cpuidle_driver *drv)
static inline void cpuidle_cooling_register(struct cpuidle_driver *drv)
{
return 0;
}
static inline int cpuidle_of_cooling_register(struct device_node *np,
struct cpuidle_driver *drv)
{
return 0;
}
#endif /* CONFIG_CPU_IDLE_THERMAL */
......
......@@ -26,4 +26,8 @@ void idle_inject_set_duration(struct idle_inject_device *ii_dev,
void idle_inject_get_duration(struct idle_inject_device *ii_dev,
unsigned int *run_duration_us,
unsigned int *idle_duration_us);
void idle_inject_set_latency(struct idle_inject_device *ii_dev,
unsigned int latency_ns);
#endif /* __IDLE_INJECT_H__ */
......@@ -32,20 +32,10 @@
/* use value, which < 0K, to indicate an invalid/uninitialized temperature */
#define THERMAL_TEMP_INVALID -274000
/* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
#define DEFAULT_THERMAL_GOVERNOR "fair_share"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
#define DEFAULT_THERMAL_GOVERNOR "user_space"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
#define DEFAULT_THERMAL_GOVERNOR "power_allocator"
#endif
struct thermal_zone_device;
struct thermal_cooling_device;
struct thermal_instance;
struct thermal_attr;
enum thermal_device_mode {
THERMAL_DEVICE_DISABLED = 0,
......@@ -130,11 +120,6 @@ struct thermal_cooling_device {
struct list_head node;
};
struct thermal_attr {
struct device_attribute attr;
char name[THERMAL_NAME_LENGTH];
};
/**
* struct thermal_zone_device - structure for a thermal zone
* @id: unique id number for each thermal zone
......@@ -347,21 +332,6 @@ struct thermal_zone_of_device_ops {
int (*set_trip_temp)(void *, int, int);
};
/**
* struct thermal_trip - representation of a point in temperature domain
* @np: pointer to struct device_node that this trip point was created from
* @temperature: temperature value in miliCelsius
* @hysteresis: relative hysteresis in miliCelsius
* @type: trip point type
*/
struct thermal_trip {
struct device_node *np;
int temperature;
int hysteresis;
enum thermal_trip_type type;
};
/* Function declarations */
#ifdef CONFIG_THERMAL_OF
int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
......@@ -413,19 +383,7 @@ void devm_thermal_zone_of_sensor_unregister(struct device *dev,
#endif
#if IS_ENABLED(CONFIG_THERMAL)
static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
{
return cdev->ops->get_requested_power && cdev->ops->state2power &&
cdev->ops->power2state;
}
int power_actor_get_max_power(struct thermal_cooling_device *,
struct thermal_zone_device *tz, u32 *max_power);
int power_actor_get_min_power(struct thermal_cooling_device *,
struct thermal_zone_device *tz, u32 *min_power);
int power_actor_set_power(struct thermal_cooling_device *,
struct thermal_instance *, u32);
#ifdef CONFIG_THERMAL
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
void *, struct thermal_zone_device_ops *,
struct thermal_zone_params *, int, int);
......@@ -439,7 +397,6 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
void thermal_zone_device_update(struct thermal_zone_device *,
enum thermal_notify_event);
void thermal_zone_set_trips(struct thermal_zone_device *);
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
void *, const struct thermal_cooling_device_ops *);
......@@ -457,24 +414,9 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
int thermal_zone_get_slope(struct thermal_zone_device *tz);
int thermal_zone_get_offset(struct thermal_zone_device *tz);
int get_tz_trend(struct thermal_zone_device *, int);
struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
struct thermal_cooling_device *, int);
void thermal_cdev_update(struct thermal_cooling_device *);
void thermal_notify_framework(struct thermal_zone_device *, int);
#else
static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
{ return false; }
static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz, u32 *max_power)
{ return 0; }
static inline int power_actor_get_min_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz,
u32 *min_power)
{ return -ENODEV; }
static inline int power_actor_set_power(struct thermal_cooling_device *cdev,
struct thermal_instance *tz, u32 power)
{ return 0; }
static inline struct thermal_zone_device *thermal_zone_device_register(
const char *type, int trips, int mask, void *devdata,
struct thermal_zone_device_ops *ops,
......@@ -484,21 +426,6 @@ static inline struct thermal_zone_device *thermal_zone_device_register(
static inline void thermal_zone_device_unregister(
struct thermal_zone_device *tz)
{ }
static inline int thermal_zone_bind_cooling_device(
struct thermal_zone_device *tz, int trip,
struct thermal_cooling_device *cdev,
unsigned long upper, unsigned long lower,
unsigned int weight)
{ return -ENODEV; }
static inline int thermal_zone_unbind_cooling_device(
struct thermal_zone_device *tz, int trip,
struct thermal_cooling_device *cdev)
{ return -ENODEV; }
static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
{ }
static inline void thermal_zone_set_trips(struct thermal_zone_device *tz)
{ }
static inline struct thermal_cooling_device *
thermal_cooling_device_register(char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
......@@ -530,12 +457,7 @@ static inline int thermal_zone_get_slope(
static inline int thermal_zone_get_offset(
struct thermal_zone_device *tz)
{ return -ENODEV; }
static inline int get_tz_trend(struct thermal_zone_device *tz, int trip)
{ return -ENODEV; }
static inline struct thermal_instance *
get_thermal_instance(struct thermal_zone_device *tz,
struct thermal_cooling_device *cdev, int trip)
{ return ERR_PTR(-ENODEV); }
static inline void thermal_cdev_update(struct thermal_cooling_device *cdev)
{ }
static inline void thermal_notify_framework(struct thermal_zone_device *tz,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment