Merge branches 'misc', 'soc', 'soc-eduardo' and 'int3404-thermal' of .git into next

This commit is contained in:
Zhang Rui
2014-01-02 14:22:28 +08:00
28 changed files with 2212 additions and 67 deletions
@@ -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
+1
View File
@@ -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>
+41
View File
@@ -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>;
};
};
};
+18 -5
View File
@@ -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>;
};
};
};
+21 -8
View File
@@ -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>;
};
};
};
+28
View File
@@ -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";
};
};
};
+28
View File
@@ -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";
};
};
};
+13 -1
View File
@@ -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>;
};
};
};
+1 -1
View File
@@ -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)
+16
View File
@@ -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
View File
@@ -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);
+19
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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
+50 -6
View File
@@ -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.
+18 -14
View File
@@ -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 = {
+237
View File
@@ -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