You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branches 'misc', 'soc', 'soc-eduardo' and 'int3404-thermal' of .git into next
This commit is contained in:
@@ -15,6 +15,10 @@ Optional properties:
|
||||
- clock-latency: Specify the possible maximum transition latency for clock,
|
||||
in unit of nanoseconds.
|
||||
- voltage-tolerance: Specify the CPU voltage tolerance in percentage.
|
||||
- #cooling-cells:
|
||||
- cooling-min-level:
|
||||
- cooling-max-level:
|
||||
Please refer to Documentation/devicetree/bindings/thermal/thermal.txt.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -33,6 +37,9 @@ cpus {
|
||||
198000 850000
|
||||
>;
|
||||
clock-latency = <61036>; /* two CLK32 periods */
|
||||
#cooling-cells = <2>;
|
||||
cooling-min-level = <0>;
|
||||
cooling-max-level = <2>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8501,6 +8501,7 @@ S: Supported
|
||||
F: drivers/thermal/
|
||||
F: include/linux/thermal.h
|
||||
F: include/linux/cpu_cooling.h
|
||||
F: Documentation/devicetree/bindings/thermal/
|
||||
|
||||
THINGM BLINK(1) USB RGB LED DRIVER
|
||||
M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Device Tree Source for OMAP4/5 SoC CPU thermal
|
||||
*
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Contact: Eduardo Valentin <eduardo.valentin@ti.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
cpu_thermal: cpu_thermal {
|
||||
polling-delay-passive = <250>; /* milliseconds */
|
||||
polling-delay = <1000>; /* milliseconds */
|
||||
|
||||
/* sensor ID */
|
||||
thermal-sensors = <&bandgap 0>;
|
||||
|
||||
trips {
|
||||
cpu_alert0: cpu_alert {
|
||||
temperature = <100000>; /* millicelsius */
|
||||
hysteresis = <2000>; /* millicelsius */
|
||||
type = "passive";
|
||||
};
|
||||
cpu_crit: cpu_crit {
|
||||
temperature = <125000>; /* millicelsius */
|
||||
hysteresis = <2000>; /* millicelsius */
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
map0 {
|
||||
trip = <&cpu_alert0>;
|
||||
cooling-device =
|
||||
<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/ {
|
||||
cpus {
|
||||
cpu@0 {
|
||||
cpu0: cpu@0 {
|
||||
/* OMAP443x variants OPP50-OPPNT */
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
@@ -22,12 +22,25 @@
|
||||
1008000 1375000
|
||||
>;
|
||||
clock-latency = <300000>; /* From legacy driver */
|
||||
|
||||
/* cooling options */
|
||||
cooling-min-level = <0>;
|
||||
cooling-max-level = <3>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
};
|
||||
|
||||
bandgap {
|
||||
reg = <0x4a002260 0x4
|
||||
0x4a00232C 0x4>;
|
||||
compatible = "ti,omap4430-bandgap";
|
||||
thermal-zones {
|
||||
#include "omap4-cpu-thermal.dtsi"
|
||||
};
|
||||
|
||||
ocp {
|
||||
bandgap: bandgap {
|
||||
reg = <0x4a002260 0x4
|
||||
0x4a00232C 0x4>;
|
||||
compatible = "ti,omap4430-bandgap";
|
||||
|
||||
#thermal-sensor-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/ {
|
||||
cpus {
|
||||
/* OMAP446x 'standard device' variants OPP50 to OPPTurbo */
|
||||
cpu@0 {
|
||||
cpu0: cpu@0 {
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
350000 1025000
|
||||
@@ -20,6 +20,11 @@
|
||||
920000 1313000
|
||||
>;
|
||||
clock-latency = <300000>; /* From legacy driver */
|
||||
|
||||
/* cooling options */
|
||||
cooling-min-level = <0>;
|
||||
cooling-max-level = <2>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
};
|
||||
|
||||
@@ -30,12 +35,20 @@
|
||||
ti,hwmods = "debugss";
|
||||
};
|
||||
|
||||
bandgap {
|
||||
reg = <0x4a002260 0x4
|
||||
0x4a00232C 0x4
|
||||
0x4a002378 0x18>;
|
||||
compatible = "ti,omap4460-bandgap";
|
||||
interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */
|
||||
gpios = <&gpio3 22 0>; /* tshut */
|
||||
thermal-zones {
|
||||
#include "omap4-cpu-thermal.dtsi"
|
||||
};
|
||||
|
||||
ocp {
|
||||
bandgap: bandgap {
|
||||
reg = <0x4a002260 0x4
|
||||
0x4a00232C 0x4
|
||||
0x4a002378 0x18>;
|
||||
compatible = "ti,omap4460-bandgap";
|
||||
interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */
|
||||
gpios = <&gpio3 22 0>; /* tshut */
|
||||
|
||||
#thermal-sensor-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Device Tree Source for OMAP543x SoC CORE thermal
|
||||
*
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Contact: Eduardo Valentin <eduardo.valentin@ti.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
core_thermal: core_thermal {
|
||||
polling-delay-passive = <250>; /* milliseconds */
|
||||
polling-delay = <1000>; /* milliseconds */
|
||||
|
||||
/* sensor ID */
|
||||
thermal-sensors = <&bandgap 2>;
|
||||
|
||||
trips {
|
||||
core_crit: core_crit {
|
||||
temperature = <125000>; /* milliCelsius */
|
||||
hysteresis = <2000>; /* milliCelsius */
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Device Tree Source for OMAP543x SoC GPU thermal
|
||||
*
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Contact: Eduardo Valentin <eduardo.valentin@ti.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
gpu_thermal: gpu_thermal {
|
||||
polling-delay-passive = <250>; /* milliseconds */
|
||||
polling-delay = <1000>; /* milliseconds */
|
||||
|
||||
/* sensor ID */
|
||||
thermal-sensors = <&bandgap 1>;
|
||||
|
||||
trips {
|
||||
gpu_crit: gpu_crit {
|
||||
temperature = <125000>; /* milliCelsius */
|
||||
hysteresis = <2000>; /* milliCelsius */
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -49,6 +49,10 @@
|
||||
1000000 1060000
|
||||
1500000 1250000
|
||||
>;
|
||||
/* cooling options */
|
||||
cooling-min-level = <0>;
|
||||
cooling-max-level = <2>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
@@ -57,6 +61,12 @@
|
||||
};
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
#include "omap4-cpu-thermal.dtsi"
|
||||
#include "omap5-gpu-thermal.dtsi"
|
||||
#include "omap5-core-thermal.dtsi"
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
/* PPI secure/nonsecure IRQ */
|
||||
@@ -729,13 +739,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
bandgap@4a0021e0 {
|
||||
bandgap: bandgap@4a0021e0 {
|
||||
reg = <0x4a0021e0 0xc
|
||||
0x4a00232c 0xc
|
||||
0x4a002380 0x2c
|
||||
0x4a0023C0 0x3c>;
|
||||
interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
|
||||
compatible = "ti,omap5430-bandgap";
|
||||
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -181,7 +181,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
|
||||
|
||||
config GENERIC_CPUFREQ_CPU0
|
||||
tristate "Generic CPU0 cpufreq driver"
|
||||
depends on HAVE_CLK && REGULATOR && PM_OPP && OF
|
||||
depends on HAVE_CLK && REGULATOR && PM_OPP && OF && THERMAL && CPU_THERMAL
|
||||
help
|
||||
This adds a generic cpufreq driver for CPU0 frequency management.
|
||||
It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@@ -21,6 +23,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
static unsigned int transition_latency;
|
||||
static unsigned int voltage_tolerance; /* in percentage */
|
||||
@@ -29,6 +32,7 @@ static struct device *cpu_dev;
|
||||
static struct clk *cpu_clk;
|
||||
static struct regulator *cpu_reg;
|
||||
static struct cpufreq_frequency_table *freq_table;
|
||||
static struct thermal_cooling_device *cdev;
|
||||
|
||||
static unsigned int cpu0_get_speed(unsigned int cpu)
|
||||
{
|
||||
@@ -201,6 +205,17 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
|
||||
goto out_free_table;
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, just loading the cooling device;
|
||||
* thermal DT code takes care of matching them.
|
||||
*/
|
||||
if (of_find_property(np, "#cooling-cells", NULL)) {
|
||||
cdev = of_cpufreq_cooling_register(np, cpu_present_mask);
|
||||
if (IS_ERR(cdev))
|
||||
pr_err("running cpufreq without cooling device: %ld\n",
|
||||
PTR_ERR(cdev));
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
return 0;
|
||||
|
||||
@@ -213,6 +228,7 @@ out_put_node:
|
||||
|
||||
static int cpu0_cpufreq_remove(struct platform_device *pdev)
|
||||
{
|
||||
cpufreq_cooling_unregister(cdev);
|
||||
cpufreq_unregister_driver(&cpu0_cpufreq_driver);
|
||||
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
|
||||
|
||||
|
||||
+30
-5
@@ -27,6 +27,8 @@
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/thermal.h>
|
||||
#include "lm75.h"
|
||||
|
||||
|
||||
@@ -71,6 +73,7 @@ static const u8 LM75_REG_TEMP[3] = {
|
||||
/* Each client has this additional data */
|
||||
struct lm75_data {
|
||||
struct device *hwmon_dev;
|
||||
struct thermal_zone_device *tz;
|
||||
struct mutex update_lock;
|
||||
u8 orig_conf;
|
||||
u8 resolution; /* In bits, between 9 and 12 */
|
||||
@@ -91,22 +94,36 @@ static struct lm75_data *lm75_update_device(struct device *dev);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
|
||||
{
|
||||
return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
|
||||
}
|
||||
|
||||
/* sysfs attributes for hwmon */
|
||||
|
||||
static int lm75_read_temp(void *dev, long *temp)
|
||||
{
|
||||
struct lm75_data *data = lm75_update_device(dev);
|
||||
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
*temp = lm75_reg_to_mc(data->temp[0], data->resolution);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct lm75_data *data = lm75_update_device(dev);
|
||||
long temp;
|
||||
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
temp = ((data->temp[attr->index] >> (16 - data->resolution)) * 1000)
|
||||
>> (data->resolution - 8);
|
||||
|
||||
return sprintf(buf, "%ld\n", temp);
|
||||
return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index],
|
||||
data->resolution));
|
||||
}
|
||||
|
||||
static ssize_t set_temp(struct device *dev, struct device_attribute *da,
|
||||
@@ -273,6 +290,13 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
data->tz = thermal_zone_of_sensor_register(&client->dev,
|
||||
0,
|
||||
&client->dev,
|
||||
lm75_read_temp, NULL);
|
||||
if (IS_ERR(data->tz))
|
||||
data->tz = NULL;
|
||||
|
||||
dev_info(&client->dev, "%s: sensor '%s'\n",
|
||||
dev_name(data->hwmon_dev), client->name);
|
||||
|
||||
@@ -287,6 +311,7 @@ static int lm75_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lm75_data *data = i2c_get_clientdata(client);
|
||||
|
||||
thermal_zone_of_sensor_unregister(&client->dev, data->tz);
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &lm75_group);
|
||||
lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define DRIVER_NAME "tmp102"
|
||||
|
||||
@@ -50,6 +52,7 @@
|
||||
|
||||
struct tmp102 {
|
||||
struct device *hwmon_dev;
|
||||
struct thermal_zone_device *tz;
|
||||
struct mutex lock;
|
||||
u16 config_orig;
|
||||
unsigned long last_update;
|
||||
@@ -93,6 +96,15 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client)
|
||||
return tmp102;
|
||||
}
|
||||
|
||||
static int tmp102_read_temp(void *dev, long *temp)
|
||||
{
|
||||
struct tmp102 *tmp102 = tmp102_update_device(to_i2c_client(dev));
|
||||
|
||||
*temp = tmp102->temp[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t tmp102_show_temp(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
@@ -204,6 +216,12 @@ static int tmp102_probe(struct i2c_client *client,
|
||||
goto fail_remove_sysfs;
|
||||
}
|
||||
|
||||
tmp102->tz = thermal_zone_of_sensor_register(&client->dev, 0,
|
||||
&client->dev,
|
||||
tmp102_read_temp, NULL);
|
||||
if (IS_ERR(tmp102->tz))
|
||||
tmp102->tz = NULL;
|
||||
|
||||
dev_info(&client->dev, "initialized\n");
|
||||
|
||||
return 0;
|
||||
@@ -220,6 +238,7 @@ static int tmp102_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tmp102 *tmp102 = i2c_get_clientdata(client);
|
||||
|
||||
thermal_zone_of_sensor_unregister(&client->dev, tmp102->tz);
|
||||
hwmon_device_unregister(tmp102->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group);
|
||||
|
||||
|
||||
+22
-1
@@ -29,6 +29,19 @@ config THERMAL_HWMON
|
||||
Say 'Y' here if you want all thermal sensors to
|
||||
have hwmon sysfs interface too.
|
||||
|
||||
config THERMAL_OF
|
||||
bool
|
||||
prompt "APIs to parse thermal data out of device tree"
|
||||
depends on OF
|
||||
default y
|
||||
help
|
||||
This options provides helpers to add the support to
|
||||
read and parse thermal data definitions out of the
|
||||
device tree blob.
|
||||
|
||||
Say 'Y' here if you need to build thermal infrastructure
|
||||
based on device tree.
|
||||
|
||||
choice
|
||||
prompt "Default Thermal governor"
|
||||
default THERMAL_DEFAULT_GOV_STEP_WISE
|
||||
@@ -79,6 +92,7 @@ config THERMAL_GOV_USER_SPACE
|
||||
config CPU_THERMAL
|
||||
bool "generic cpu cooling support"
|
||||
depends on CPU_FREQ
|
||||
depends on THERMAL_OF
|
||||
help
|
||||
This implements the generic cpu cooling mechanism through frequency
|
||||
reduction. An ACPI version of this already exists
|
||||
@@ -121,7 +135,7 @@ config SPEAR_THERMAL
|
||||
|
||||
config RCAR_THERMAL
|
||||
tristate "Renesas R-Car thermal driver"
|
||||
depends on ARCH_SHMOBILE
|
||||
depends on ARCH_SHMOBILE || COMPILE_TEST
|
||||
help
|
||||
Enable this to plug the R-Car thermal sensor driver into the Linux
|
||||
thermal framework.
|
||||
@@ -192,6 +206,13 @@ config X86_PKG_TEMP_THERMAL
|
||||
two trip points which can be set by user to get notifications via thermal
|
||||
notification methods.
|
||||
|
||||
config ACPI_INT3403_THERMAL
|
||||
tristate "ACPI INT3403 thermal driver"
|
||||
depends on X86 && ACPI
|
||||
help
|
||||
This driver uses ACPI INT3403 device objects. If present, it will
|
||||
register each INT3403 thermal sensor as a thermal zone.
|
||||
|
||||
menu "Texas Instruments thermal drivers"
|
||||
source "drivers/thermal/ti-soc-thermal/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -7,6 +7,7 @@ thermal_sys-y += thermal_core.o
|
||||
|
||||
# interface to/from other layers providing sensors
|
||||
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
|
||||
thermal_sys-$(CONFIG_THERMAL_OF) += of-thermal.o
|
||||
|
||||
# governors
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
|
||||
@@ -29,3 +30,4 @@ obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
|
||||
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
||||
obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
|
||||
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
|
||||
obj-$(CONFIG_ACPI_INT3403_THERMAL) += int3403_thermal.o
|
||||
|
||||
@@ -424,18 +424,21 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
|
||||
};
|
||||
|
||||
/**
|
||||
* cpufreq_cooling_register - function to create cpufreq cooling device.
|
||||
* __cpufreq_cooling_register - helper function to create cpufreq cooling device
|
||||
* @np: a valid struct device_node to the cooling device device tree node
|
||||
* @clip_cpus: cpumask of cpus where the frequency constraints will happen.
|
||||
*
|
||||
* This interface function registers the cpufreq cooling device with the name
|
||||
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
|
||||
* cooling devices.
|
||||
* cooling devices. It also gives the opportunity to link the cooling device
|
||||
* with a device tree node, in order to bind it via the thermal DT code.
|
||||
*
|
||||
* Return: a valid struct thermal_cooling_device pointer on success,
|
||||
* on failure, it returns a corresponding ERR_PTR().
|
||||
*/
|
||||
struct thermal_cooling_device *
|
||||
cpufreq_cooling_register(const struct cpumask *clip_cpus)
|
||||
static struct thermal_cooling_device *
|
||||
__cpufreq_cooling_register(struct device_node *np,
|
||||
const struct cpumask *clip_cpus)
|
||||
{
|
||||
struct thermal_cooling_device *cool_dev;
|
||||
struct cpufreq_cooling_device *cpufreq_dev = NULL;
|
||||
@@ -474,8 +477,8 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus)
|
||||
snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
|
||||
cpufreq_dev->id);
|
||||
|
||||
cool_dev = thermal_cooling_device_register(dev_name, cpufreq_dev,
|
||||
&cpufreq_cooling_ops);
|
||||
cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
|
||||
&cpufreq_cooling_ops);
|
||||
if (IS_ERR(cool_dev)) {
|
||||
release_idr(&cpufreq_idr, cpufreq_dev->id);
|
||||
kfree(cpufreq_dev);
|
||||
@@ -495,8 +498,49 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus)
|
||||
|
||||
return cool_dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpufreq_cooling_register - function to create cpufreq cooling device.
|
||||
* @clip_cpus: cpumask of cpus where the frequency constraints will happen.
|
||||
*
|
||||
* This interface function registers the cpufreq cooling device with the name
|
||||
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
|
||||
* cooling devices.
|
||||
*
|
||||
* Return: a valid struct thermal_cooling_device pointer on success,
|
||||
* on failure, it returns a corresponding ERR_PTR().
|
||||
*/
|
||||
struct thermal_cooling_device *
|
||||
cpufreq_cooling_register(const struct cpumask *clip_cpus)
|
||||
{
|
||||
return __cpufreq_cooling_register(NULL, clip_cpus);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
|
||||
|
||||
/**
|
||||
* of_cpufreq_cooling_register - function to create cpufreq cooling device.
|
||||
* @np: a valid struct device_node to the cooling device device tree node
|
||||
* @clip_cpus: cpumask of cpus where the frequency constraints will happen.
|
||||
*
|
||||
* This interface function registers the cpufreq cooling device with the name
|
||||
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
|
||||
* cooling devices. Using this API, the cpufreq cooling device will be
|
||||
* linked to the device tree node provided.
|
||||
*
|
||||
* Return: a valid struct thermal_cooling_device pointer on success,
|
||||
* on failure, it returns a corresponding ERR_PTR().
|
||||
*/
|
||||
struct thermal_cooling_device *
|
||||
of_cpufreq_cooling_register(struct device_node *np,
|
||||
const struct cpumask *clip_cpus)
|
||||
{
|
||||
if (!np)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return __cpufreq_cooling_register(np, clip_cpus);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
|
||||
|
||||
/**
|
||||
* cpufreq_cooling_unregister - function to remove cpufreq cooling device.
|
||||
* @cdev: thermal cooling device pointer.
|
||||
|
||||
@@ -490,27 +490,30 @@ static int imx_thermal_suspend(struct device *dev)
|
||||
{
|
||||
struct imx_thermal_data *data = dev_get_drvdata(dev);
|
||||
struct regmap *map = data->tempmon;
|
||||
u32 val;
|
||||
|
||||
regmap_read(map, TEMPSENSE0, &val);
|
||||
if ((val & TEMPSENSE0_POWER_DOWN) == 0) {
|
||||
/*
|
||||
* If a measurement is taking place, wait for a long enough
|
||||
* time for it to finish, and then check again. If it still
|
||||
* does not finish, something must go wrong.
|
||||
*/
|
||||
udelay(50);
|
||||
regmap_read(map, TEMPSENSE0, &val);
|
||||
if ((val & TEMPSENSE0_POWER_DOWN) == 0)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/*
|
||||
* Need to disable thermal sensor, otherwise, when thermal core
|
||||
* try to get temperature before thermal sensor resume, a wrong
|
||||
* temperature will be read as the thermal sensor is powered
|
||||
* down.
|
||||
*/
|
||||
regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
|
||||
regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
|
||||
data->mode = THERMAL_DEVICE_DISABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_thermal_resume(struct device *dev)
|
||||
{
|
||||
/* Nothing to do for now */
|
||||
struct imx_thermal_data *data = dev_get_drvdata(dev);
|
||||
struct regmap *map = data->tempmon;
|
||||
|
||||
/* Enabled thermal sensor after resume */
|
||||
regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
|
||||
regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
|
||||
data->mode = THERMAL_DEVICE_ENABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -522,6 +525,7 @@ static const struct of_device_id of_imx_thermal_match[] = {
|
||||
{ .compatible = "fsl,imx6q-tempmon", },
|
||||
{ /* end */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
|
||||
|
||||
static struct platform_driver imx_thermal = {
|
||||
.driver = {
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* ACPI INT3403 thermal driver
|
||||
* Copyright (c) 2013, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#define INT3403_TYPE_SENSOR 0x03
|
||||
#define INT3403_PERF_CHANGED_EVENT 0x80
|
||||
#define INT3403_THERMAL_EVENT 0x90
|
||||
|
||||
#define DECI_KELVIN_TO_MILLI_CELSIUS(t, off) (((t) - (off)) * 100)
|
||||
#define KELVIN_OFFSET 2732
|
||||
#define MILLI_CELSIUS_TO_DECI_KELVIN(t, off) (((t) / 100) + (off))
|
||||
|
||||
#define ACPI_INT3403_CLASS "int3403"
|
||||
#define ACPI_INT3403_FILE_STATE "state"
|
||||
|
||||
struct int3403_sensor {
|
||||
struct thermal_zone_device *tzone;
|
||||
unsigned long *thresholds;
|
||||
};
|
||||
|
||||
static int sys_get_curr_temp(struct thermal_zone_device *tzone,
|
||||
unsigned long *temp)
|
||||
{
|
||||
struct acpi_device *device = tzone->devdata;
|
||||
unsigned long long tmp;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(device->handle, "_TMP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
*temp = DECI_KELVIN_TO_MILLI_CELSIUS(tmp, KELVIN_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_get_trip_hyst(struct thermal_zone_device *tzone,
|
||||
int trip, unsigned long *temp)
|
||||
{
|
||||
struct acpi_device *device = tzone->devdata;
|
||||
unsigned long long hyst;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(device->handle, "GTSH", NULL, &hyst);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
*temp = DECI_KELVIN_TO_MILLI_CELSIUS(hyst, KELVIN_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_get_trip_temp(struct thermal_zone_device *tzone,
|
||||
int trip, unsigned long *temp)
|
||||
{
|
||||
struct acpi_device *device = tzone->devdata;
|
||||
struct int3403_sensor *obj = acpi_driver_data(device);
|
||||
|
||||
/*
|
||||
* get_trip_temp is a mandatory callback but
|
||||
* PATx method doesn't return any value, so return
|
||||
* cached value, which was last set from user space.
|
||||
*/
|
||||
*temp = obj->thresholds[trip];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_get_trip_type(struct thermal_zone_device *thermal,
|
||||
int trip, enum thermal_trip_type *type)
|
||||
{
|
||||
/* Mandatory callback, may not mean much here */
|
||||
*type = THERMAL_TRIP_PASSIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_set_trip_temp(struct thermal_zone_device *tzone, int trip,
|
||||
unsigned long temp)
|
||||
{
|
||||
struct acpi_device *device = tzone->devdata;
|
||||
acpi_status status;
|
||||
char name[10];
|
||||
int ret = 0;
|
||||
struct int3403_sensor *obj = acpi_driver_data(device);
|
||||
|
||||
snprintf(name, sizeof(name), "PAT%d", trip);
|
||||
if (acpi_has_method(device->handle, name)) {
|
||||
status = acpi_execute_simple_method(device->handle, name,
|
||||
MILLI_CELSIUS_TO_DECI_KELVIN(temp,
|
||||
KELVIN_OFFSET));
|
||||
if (ACPI_FAILURE(status))
|
||||
ret = -EIO;
|
||||
else
|
||||
obj->thresholds[trip] = temp;
|
||||
} else {
|
||||
ret = -EIO;
|
||||
dev_err(&device->dev, "sys_set_trip_temp: method not found\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops tzone_ops = {
|
||||
.get_temp = sys_get_curr_temp,
|
||||
.get_trip_temp = sys_get_trip_temp,
|
||||
.get_trip_type = sys_get_trip_type,
|
||||
.set_trip_temp = sys_set_trip_temp,
|
||||
.get_trip_hyst = sys_get_trip_hyst,
|
||||
};
|
||||
|
||||
static void acpi_thermal_notify(struct acpi_device *device, u32 event)
|
||||
{
|
||||
struct int3403_sensor *obj;
|
||||
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
obj = acpi_driver_data(device);
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case INT3403_PERF_CHANGED_EVENT:
|
||||
break;
|
||||
case INT3403_THERMAL_EVENT:
|
||||
thermal_zone_device_update(obj->tzone);
|
||||
break;
|
||||
default:
|
||||
dev_err(&device->dev, "Unsupported event [0x%x]\n", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_int3403_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned long long ptyp;
|
||||
acpi_status status;
|
||||
struct int3403_sensor *obj;
|
||||
unsigned long long trip_cnt;
|
||||
int trip_mask = 0;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_evaluate_integer(device->handle, "PTYP", NULL, &ptyp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
|
||||
if (ptyp != INT3403_TYPE_SENSOR)
|
||||
return -EINVAL;
|
||||
|
||||
obj = devm_kzalloc(&device->dev, sizeof(*obj), GFP_KERNEL);
|
||||
if (!obj)
|
||||
return -ENOMEM;
|
||||
|
||||
device->driver_data = obj;
|
||||
|
||||
status = acpi_evaluate_integer(device->handle, "PATC", NULL,
|
||||
&trip_cnt);
|
||||
if (ACPI_FAILURE(status))
|
||||
trip_cnt = 0;
|
||||
|
||||
if (trip_cnt) {
|
||||
/* We have to cache, thresholds can't be readback */
|
||||
obj->thresholds = devm_kzalloc(&device->dev,
|
||||
sizeof(*obj->thresholds) * trip_cnt,
|
||||
GFP_KERNEL);
|
||||
if (!obj->thresholds)
|
||||
return -ENOMEM;
|
||||
trip_mask = BIT(trip_cnt) - 1;
|
||||
}
|
||||
obj->tzone = thermal_zone_device_register(acpi_device_bid(device),
|
||||
trip_cnt, trip_mask, device, &tzone_ops,
|
||||
NULL, 0, 0);
|
||||
if (IS_ERR(obj->tzone)) {
|
||||
result = PTR_ERR(obj->tzone);
|
||||
return result;
|
||||
}
|
||||
|
||||
strcpy(acpi_device_name(device), "INT3403");
|
||||
strcpy(acpi_device_class(device), ACPI_INT3403_CLASS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_int3403_remove(struct acpi_device *device)
|
||||
{
|
||||
struct int3403_sensor *obj;
|
||||
|
||||
obj = acpi_driver_data(device);
|
||||
thermal_zone_device_unregister(obj->tzone);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACPI_MODULE_NAME("int3403");
|
||||
static const struct acpi_device_id int3403_device_ids[] = {
|
||||
{"INT3403", 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, int3403_device_ids);
|
||||
|
||||
static struct acpi_driver acpi_int3403_driver = {
|
||||
.name = "INT3403",
|
||||
.class = ACPI_INT3403_CLASS,
|
||||
.ids = int3403_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_int3403_add,
|
||||
.remove = acpi_int3403_remove,
|
||||
.notify = acpi_thermal_notify,
|
||||
},
|
||||
};
|
||||
|
||||
module_acpi_driver(acpi_int3403_driver);
|
||||
|
||||
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("ACPI INT3403 thermal driver");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -280,7 +280,7 @@ static int exynos_get_trend(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
/* Operation callback functions for thermal zone */
|
||||
static struct thermal_zone_device_ops const exynos_dev_ops = {
|
||||
static struct thermal_zone_device_ops exynos_dev_ops = {
|
||||
.bind = exynos_bind,
|
||||
.unbind = exynos_unbind,
|
||||
.get_temp = exynos_get_temp,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user