From f9df89d897ee0928aa4e03b30250e87f5d1e788a Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Mon, 6 Jan 2014 09:04:18 -0400 Subject: thermal: introduce clock cooling device This patch introduces a new thermal cooling device based on common clock framework. The original motivation to write this cooling device is to be able to cool down thermal zones using clocks that feed co-processors, such as GPUs, DSPs, Image Processing Co-processors, etc. But it is written in a way that it can be used on top of any clock. The implementation is pretty straight forward. The code creates a thermal cooling device based on a pair of a struct device and a clock name. The struct device is assumed to be usable by the OPP layer. The OPP layer is used as source of the list of possible frequencies. The (cpufreq) frequency table is then used as a map from frequencies to cooling states. Cooling states are indexes to the frequency table. The logic sits on top of common clock framework, specifically on clock pre notifications. Any PRE_RATE_CHANGE is hijacked, and the transition is only allowed when the new rate is within the thermal limit (cooling state -> freq). When a thermal cooling device state transition is requested, the clock is also checked to verify if the current clock rate is within the new thermal limit. Cc: Zhang Rui Cc: Mike Turquette Cc: Nishanth Menon Cc: Pavel Machek Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Greg Kroah-Hartman Cc: linux-pm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Eduardo Valentin Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index f554d25..efbdb8c 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -112,6 +112,18 @@ config CPU_THERMAL If you want this support, you should say Y here. +config CLOCK_THERMAL + bool "Generic clock cooling support" + depends on COMMON_CLK + depends on PM_OPP + help + This entry implements the generic clock cooling mechanism through + frequency clipping. Typically used to cool off co-processors. The + device that is configured to use this cooling mechanism will be + controlled to reduce clock frequency whenever temperature is high. + + If you want this support, you should say Y here. + config THERMAL_EMULATION bool "Thermal emulation mode support" help diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 39c4fe8..9d33532 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -18,6 +18,9 @@ thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o # cpufreq cooling thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o +# clock cooling +thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o + # platform thermal drivers obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o diff --git a/drivers/thermal/clock_cooling.c b/drivers/thermal/clock_cooling.c new file mode 100644 index 0000000..1b4ff0f --- /dev/null +++ b/drivers/thermal/clock_cooling.c @@ -0,0 +1,485 @@ +/* + * drivers/thermal/clock_cooling.c + * + * Copyright (C) 2014 Eduardo Valentin + * + * Copyright (C) 2013 Texas Instruments Inc. + * Contact: Eduardo Valentin + * + * Highly based on cpu_cooling.c. + * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) + * Copyright (C) 2012 Amit Daniel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct clock_cooling_device - data for cooling device with clock + * @id: unique integer value corresponding to each clock_cooling_device + * registered. + * @dev: struct device pointer to the device being used to cool off using + * clock frequencies. + * @cdev: thermal_cooling_device pointer to keep track of the + * registered cooling device. + * @clk_rate_change_nb: reference to notifier block used to receive clock + * rate changes. + * @freq_table: frequency table used to keep track of available frequencies. + * @clock_state: integer value representing the current state of clock + * cooling devices. + * @clock_val: integer value representing the absolute value of the clipped + * frequency. + * @clk: struct clk reference used to enforce clock limits. + * @lock: mutex lock to protect this struct. + * + * This structure is required for keeping information of each + * clock_cooling_device registered. In order to prevent corruption of this a + * mutex @lock is used. + */ +struct clock_cooling_device { + int id; + struct device *dev; + struct thermal_cooling_device *cdev; + struct notifier_block clk_rate_change_nb; + struct cpufreq_frequency_table *freq_table; + unsigned long clock_state; + unsigned long clock_val; + struct clk *clk; + struct mutex lock; /* lock to protect the content of this struct */ +}; +#define to_clock_cooling_device(x) \ + container_of(x, struct clock_cooling_device, clk_rate_change_nb) +static DEFINE_IDR(clock_idr); +static DEFINE_MUTEX(cooling_clock_lock); + +/** + * clock_cooling_get_idr - function to get an unique id. + * @id: int * value generated by this function. + * + * This function will populate @id with an unique + * id, using the idr API. + * + * Return: 0 on success, an error code on failure. + */ +static int clock_cooling_get_idr(int *id) +{ + int ret; + + mutex_lock(&cooling_clock_lock); + ret = idr_alloc(&clock_idr, NULL, 0, 0, GFP_KERNEL); + mutex_unlock(&cooling_clock_lock); + if (unlikely(ret < 0)) + return ret; + *id = ret; + + return 0; +} + +/** + * release_idr - function to free the unique id. + * @id: int value representing the unique id. + */ +static void release_idr(int id) +{ + mutex_lock(&cooling_clock_lock); + idr_remove(&clock_idr, id); + mutex_unlock(&cooling_clock_lock); +} + +/* Below code defines functions to be used for clock as cooling device */ + +enum clock_cooling_property { + GET_LEVEL, + GET_FREQ, + GET_MAXL, +}; + +/** + * clock_cooling_get_property - fetch a property of interest for a give cpu. + * @ccdev: clock cooling device reference + * @input: query parameter + * @output: query return + * @property: type of query (frequency, level, max level) + * + * This is the common function to + * 1. get maximum clock cooling states + * 2. translate frequency to cooling state + * 3. translate cooling state to frequency + * Note that the code may be not in good shape + * but it is written in this way in order to: + * a) reduce duplicate code as most of the code can be shared. + * b) make sure the logic is consistent when translating between + * cooling states and frequencies. + * + * Return: 0 on success, -EINVAL when invalid parameters are passed. + */ +static int clock_cooling_get_property(struct clock_cooling_device *ccdev, + unsigned long input, + unsigned long *output, + enum clock_cooling_property property) +{ + int i; + unsigned long max_level = 0, level = 0; + unsigned int freq = CPUFREQ_ENTRY_INVALID; + int descend = -1; + struct cpufreq_frequency_table *pos, *table = ccdev->freq_table; + + if (!output) + return -EINVAL; + + if (!table) + return -EINVAL; + + cpufreq_for_each_valid_entry(pos, table) { + /* ignore duplicate entry */ + if (freq == pos->frequency) + continue; + + /* get the frequency order */ + if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) + descend = freq > pos->frequency; + + freq = pos->frequency; + max_level++; + } + + /* No valid cpu frequency entry */ + if (max_level == 0) + return -EINVAL; + + /* max_level is an index, not a counter */ + max_level--; + + /* get max level */ + if (property == GET_MAXL) { + *output = max_level; + return 0; + } + + if (property == GET_FREQ) + level = descend ? input : (max_level - input); + + i = 0; + cpufreq_for_each_valid_entry(pos, table) { + /* ignore duplicate entry */ + if (freq == pos->frequency) + continue; + + /* now we have a valid frequency entry */ + freq = pos->frequency; + + if (property == GET_LEVEL && (unsigned int)input == freq) { + /* get level by frequency */ + *output = descend ? i : (max_level - i); + return 0; + } + if (property == GET_FREQ && level == i) { + /* get frequency by level */ + *output = freq; + return 0; + } + i++; + } + + return -EINVAL; +} + +/** + * clock_cooling_get_level - return the cooling level of given clock cooling. + * @cdev: reference of a thermal cooling device of used as clock cooling device + * @freq: the frequency of interest + * + * This function will match the cooling level corresponding to the + * requested @freq and return it. + * + * Return: The matched cooling level on success or THERMAL_CSTATE_INVALID + * otherwise. + */ +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + unsigned long val; + + if (clock_cooling_get_property(ccdev, (unsigned long)freq, &val, + GET_LEVEL)) + return THERMAL_CSTATE_INVALID; + + return val; +} +EXPORT_SYMBOL_GPL(clock_cooling_get_level); + +/** + * clock_cooling_get_frequency - get the absolute value of frequency from level. + * @ccdev: clock cooling device reference + * @level: cooling level + * + * This function matches cooling level with frequency. Based on a cooling level + * of frequency, equals cooling state of cpu cooling device, it will return + * the corresponding frequency. + * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc + * + * Return: 0 on error, the corresponding frequency otherwise. + */ +static unsigned long +clock_cooling_get_frequency(struct clock_cooling_device *ccdev, + unsigned long level) +{ + int ret = 0; + unsigned long freq; + + ret = clock_cooling_get_property(ccdev, level, &freq, GET_FREQ); + if (ret) + return 0; + + return freq; +} + +/** + * clock_cooling_apply - function to apply frequency clipping. + * @ccdev: clock_cooling_device pointer containing frequency clipping data. + * @cooling_state: value of the cooling state. + * + * Function used to make sure the clock layer is aware of current thermal + * limits. The limits are applied by updating the clock rate in case it is + * higher than the corresponding frequency based on the requested cooling_state. + * + * Return: 0 on success, an error code otherwise (-EINVAL in case wrong + * cooling state). + */ +static int clock_cooling_apply(struct clock_cooling_device *ccdev, + unsigned long cooling_state) +{ + unsigned long clip_freq, cur_freq; + int ret = 0; + + /* Here we write the clipping */ + /* Check if the old cooling action is same as new cooling action */ + if (ccdev->clock_state == cooling_state) + return 0; + + clip_freq = clock_cooling_get_frequency(ccdev, cooling_state); + if (!clip_freq) + return -EINVAL; + + cur_freq = clk_get_rate(ccdev->clk); + + mutex_lock(&ccdev->lock); + ccdev->clock_state = cooling_state; + ccdev->clock_val = clip_freq; + /* enforce clock level */ + if (cur_freq > clip_freq) + ret = clk_set_rate(ccdev->clk, clip_freq); + mutex_unlock(&ccdev->lock); + + return ret; +} + +/** + * clock_cooling_clock_notifier - notifier callback on clock rate changes. + * @nb: struct notifier_block * with callback info. + * @event: value showing clock event for which this function invoked. + * @data: callback-specific data + * + * Callback to hijack the notification on clock transition. + * Every time there is a clock change, we intercept all pre change events + * and block the transition in case the new rate infringes thermal limits. + * + * Return: NOTIFY_DONE (success) or NOTIFY_BAD (new_rate > thermal limit). + */ +static int clock_cooling_clock_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct clock_cooling_device *ccdev = to_clock_cooling_device(nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * checks on current state + * TODO: current method is not best we can find as it + * allows possibly voltage transitions, in case DVFS + * layer is also hijacking clock pre notifications. + */ + if (ndata->new_rate > ccdev->clock_val) + return NOTIFY_BAD; + /* fall through */ + case POST_RATE_CHANGE: + case ABORT_RATE_CHANGE: + default: + return NOTIFY_DONE; + } +} + +/* clock cooling device thermal callback functions are defined below */ + +/** + * clock_cooling_get_max_state - callback function to get the max cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the max cooling state. + * + * Callback for the thermal cooling device to return the clock + * max cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int clock_cooling_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + unsigned long count = 0; + int ret; + + ret = clock_cooling_get_property(ccdev, 0, &count, GET_MAXL); + if (!ret) + *state = count; + + return ret; +} + +/** + * clock_cooling_get_cur_state - function to get the current cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the current cooling state. + * + * Callback for the thermal cooling device to return the clock + * current cooling state. + * + * Return: 0 (success) + */ +static int clock_cooling_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + + *state = ccdev->clock_state; + + return 0; +} + +/** + * clock_cooling_set_cur_state - function to set the current cooling state. + * @cdev: thermal cooling device pointer. + * @state: set this variable to the current cooling state. + * + * Callback for the thermal cooling device to change the clock cooling + * current cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int clock_cooling_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct clock_cooling_device *clock_device = cdev->devdata; + + return clock_cooling_apply(clock_device, state); +} + +/* Bind clock callbacks to thermal cooling device ops */ +static struct thermal_cooling_device_ops const clock_cooling_ops = { + .get_max_state = clock_cooling_get_max_state, + .get_cur_state = clock_cooling_get_cur_state, + .set_cur_state = clock_cooling_set_cur_state, +}; + +/** + * clock_cooling_register - function to create clock cooling device. + * @dev: struct device pointer to the device used as clock cooling device. + * @clock_name: string containing the clock used as cooling mechanism. + * + * This interface function registers the clock cooling device with the name + * "thermal-clock-%x". The cooling device is based on clock frequencies. + * The struct device is assumed to be capable of DVFS transitions. + * The OPP layer is used to fetch and fill the available frequencies for + * the referred device. The ordered frequency table is used to control + * the clock cooling device cooling states and to limit clock transitions + * based on the cooling state requested by the thermal framework. + * + * Return: a valid struct thermal_cooling_device pointer on success, + * on failure, it returns a corresponding ERR_PTR(). + */ +struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name) +{ + struct thermal_cooling_device *cdev; + struct clock_cooling_device *ccdev = NULL; + char dev_name[THERMAL_NAME_LENGTH]; + int ret = 0; + + ccdev = devm_kzalloc(dev, sizeof(*ccdev), GFP_KERNEL); + if (!ccdev) + return ERR_PTR(-ENOMEM); + + ccdev->dev = dev; + ccdev->clk = devm_clk_get(dev, clock_name); + if (IS_ERR(ccdev->clk)) + return ERR_CAST(ccdev->clk); + + ret = clock_cooling_get_idr(&ccdev->id); + if (ret) + return ERR_PTR(-EINVAL); + + snprintf(dev_name, sizeof(dev_name), "thermal-clock-%d", ccdev->id); + + cdev = thermal_cooling_device_register(dev_name, ccdev, + &clock_cooling_ops); + if (IS_ERR(cdev)) { + release_idr(ccdev->id); + return ERR_PTR(-EINVAL); + } + ccdev->cdev = cdev; + ccdev->clk_rate_change_nb.notifier_call = clock_cooling_clock_notifier; + + /* Assuming someone has already filled the opp table for this device */ + ret = dev_pm_opp_init_cpufreq_table(dev, &ccdev->freq_table); + if (ret) { + release_idr(ccdev->id); + return ERR_PTR(ret); + } + ccdev->clock_state = 0; + ccdev->clock_val = clock_cooling_get_frequency(ccdev, 0); + + clk_notifier_register(ccdev->clk, &ccdev->clk_rate_change_nb); + + return cdev; +} +EXPORT_SYMBOL_GPL(clock_cooling_register); + +/** + * clock_cooling_unregister - function to remove clock cooling device. + * @cdev: thermal cooling device pointer. + * + * This interface function unregisters the "thermal-clock-%x" cooling device. + */ +void clock_cooling_unregister(struct thermal_cooling_device *cdev) +{ + struct clock_cooling_device *ccdev; + + if (!cdev) + return; + + ccdev = cdev->devdata; + + clk_notifier_unregister(ccdev->clk, &ccdev->clk_rate_change_nb); + dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table); + + thermal_cooling_device_unregister(ccdev->cdev); + release_idr(ccdev->id); +} +EXPORT_SYMBOL_GPL(clock_cooling_unregister); diff --git a/include/linux/clock_cooling.h b/include/linux/clock_cooling.h new file mode 100644 index 0000000..4d1019d --- /dev/null +++ b/include/linux/clock_cooling.h @@ -0,0 +1,65 @@ +/* + * linux/include/linux/clock_cooling.h + * + * Copyright (C) 2014 Eduardo Valentin + * + * Copyright (C) 2013 Texas Instruments Inc. + * Contact: Eduardo Valentin + * + * Highly based on cpu_cooling.c. + * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) + * Copyright (C) 2012 Amit Daniel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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. + */ + +#ifndef __CPU_COOLING_H__ +#define __CPU_COOLING_H__ + +#include +#include +#include + +#ifdef CONFIG_CLOCK_THERMAL +/** + * clock_cooling_register - function to create clock cooling device. + * @dev: struct device pointer to the device used as clock cooling device. + * @clock_name: string containing the clock used as cooling mechanism. + */ +struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name); + +/** + * clock_cooling_unregister - function to remove clock cooling device. + * @cdev: thermal cooling device pointer. + */ +void clock_cooling_unregister(struct thermal_cooling_device *cdev); + +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq); +#else /* !CONFIG_CLOCK_THERMAL */ +static inline struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name) +{ + return NULL; +} +static inline +void clock_cooling_unregister(struct thermal_cooling_device *cdev) +{ +} +static inline +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq) +{ + return THERMAL_CSTATE_INVALID; +} +#endif /* CONFIG_CLOCK_THERMAL */ + +#endif /* __CPU_COOLING_H__ */ -- cgit v0.10.2 From 0199e9938f2c0e7f5476f5983f1763d28f049837 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Fri, 26 Sep 2014 12:43:10 +0300 Subject: of: Add bindings for nvidia,tegra124-soctherm This adds binding documentation and headers for the Tegra124 SOCTHERM device tree node. Signed-off-by: Mikko Perttunen Acked-by: Stephen Warren Acked-by: Eduardo Valentin Signed-off-by: Eduardo Valentin diff --git a/Documentation/devicetree/bindings/thermal/tegra-soctherm.txt b/Documentation/devicetree/bindings/thermal/tegra-soctherm.txt new file mode 100644 index 0000000..ecf3ed7 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/tegra-soctherm.txt @@ -0,0 +1,53 @@ +Tegra124 SOCTHERM thermal management system + +The SOCTHERM IP block contains thermal sensors, support for polled +or interrupt-based thermal monitoring, CPU and GPU throttling based +on temperature trip points, and handling external overcurrent +notifications. It is also used to manage emergency shutdown in an +overheating situation. + +Required properties : +- compatible : "nvidia,tegra124-soctherm". +- reg : Should contain 1 entry: + - SOCTHERM register set +- interrupts : Defines the interrupt used by SOCTHERM +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names : Must include the following entries: + - tsensor + - soctherm +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - soctherm +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description + of this property. See for a + list of valid values when referring to thermal sensors. + + +Example : + + soctherm@0,700e2000 { + compatible = "nvidia,tegra124-soctherm"; + reg = <0x0 0x700e2000 0x0 0x1000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, + <&tegra_car TEGRA124_CLK_SOC_THERM>; + clock-names = "tsensor", "soctherm"; + resets = <&tegra_car 78>; + reset-names = "soctherm"; + + #thermal-sensor-cells = <1>; + }; + +Example: referring to thermal sensors : + + thermal-zones { + cpu { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>; + }; + }; diff --git a/include/dt-bindings/thermal/tegra124-soctherm.h b/include/dt-bindings/thermal/tegra124-soctherm.h new file mode 100644 index 0000000..85aaf66 --- /dev/null +++ b/include/dt-bindings/thermal/tegra124-soctherm.h @@ -0,0 +1,13 @@ +/* + * This header provides constants for binding nvidia,tegra124-soctherm. + */ + +#ifndef _DT_BINDINGS_THERMAL_TEGRA124_SOCTHERM_H +#define _DT_BINDINGS_THERMAL_TEGRA124_SOCTHERM_H + +#define TEGRA124_SOCTHERM_SENSOR_CPU 0 +#define TEGRA124_SOCTHERM_SENSOR_MEM 1 +#define TEGRA124_SOCTHERM_SENSOR_GPU 2 +#define TEGRA124_SOCTHERM_SENSOR_PLLX 3 + +#endif -- cgit v0.10.2 From 26b76f80b32c824ea746cd17c70814f28935afc9 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Fri, 26 Sep 2014 12:43:11 +0300 Subject: ARM: tegra: Add soctherm and thermal zones to Tegra124 device tree This adds the soctherm thermal sensing and management unit to the Tegra124 device tree along with the four thermal zones corresponding to the four thermal sensors provided by soctherm. Signed-off-by: Mikko Perttunen Signed-off-by: Eduardo Valentin diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 478c555..41f8b27 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -3,6 +3,7 @@ #include #include #include +#include #include "skeleton.dtsi" @@ -640,6 +641,18 @@ status = "disabled"; }; + soctherm: thermal-sensor@0,700e2000 { + compatible = "nvidia,tegra124-soctherm"; + reg = <0x0 0x700e2000 0x0 0x1000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, + <&tegra_car TEGRA124_CLK_SOC_THERM>; + clock-names = "tsensor", "soctherm"; + resets = <&tegra_car 78>; + reset-names = "soctherm"; + #thermal-sensor-cells = <1>; + }; + ahub@0,70300000 { compatible = "nvidia,tegra124-ahub"; reg = <0x0 0x70300000 0x0 0x200>, @@ -881,6 +894,40 @@ }; }; + thermal-zones { + cpu { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>; + }; + + mem { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>; + }; + + gpu { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>; + }; + + pllx { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = Date: Fri, 26 Sep 2014 12:43:12 +0300 Subject: ARM: tegra: Add thermal trip points for Jetson TK1 This adds critical trip points to the Jetson TK1 device tree. The device will do a controlled shutdown when either the CPU, GPU or MEM thermal zone reaches 101 degrees Celsius. Signed-off-by: Mikko Perttunen Signed-off-by: Eduardo Valentin diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 029c9a02..f46a789 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts @@ -1941,4 +1941,48 @@ <&tegra_car TEGRA124_CLK_EXTERN1>; clock-names = "pll_a", "pll_a_out0", "mclk"; }; + + thermal-zones { + cpu { + trips { + trip@0 { + temperature = <101000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + /* There are currently no cooling maps because there are no cooling devices */ + }; + }; + + mem { + trips { + trip@0 { + temperature = <101000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + /* There are currently no cooling maps because there are no cooling devices */ + }; + }; + + gpu { + trips { + trip@0 { + temperature = <101000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + /* There are currently no cooling maps because there are no cooling devices */ + }; + }; + }; }; -- cgit v0.10.2 From 66fb84805134c39f00d7c2054c881faa50910390 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Mon, 29 Sep 2014 17:17:31 +0300 Subject: thermal: Add Tegra SOCTHERM thermal management driver This adds support for the Tegra SOCTHERM thermal sensing and management system found in the Tegra124 system-on-chip. This initial driver supports temperature polling for four thermal zones. Signed-off-by: Mikko Perttunen Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index efbdb8c..911c38a 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -197,6 +197,16 @@ config ARMADA_THERMAL Enable this option if you want to have support for thermal management controller present in Armada 370 and Armada XP SoC. +config TEGRA_SOCTHERM + tristate "Tegra SOCTHERM thermal management" + depends on ARCH_TEGRA + help + Enable this option for integrated thermal management support on NVIDIA + Tegra124 systems-on-chip. The driver supports four thermal zones + (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal + zones to manage temperatures. This option is also required for the + emergency thermal reset (thermtrip) feature to function. + config DB8500_CPUFREQ_COOLING tristate "DB8500 cpufreq cooling" depends on ARCH_U8500 diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 9d33532..2b18e3a 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ obj-$(CONFIG_ST_THERMAL) += st/ +obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c new file mode 100644 index 0000000..70f7e9e --- /dev/null +++ b/drivers/thermal/tegra_soctherm.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * Author: + * Mikko Perttunen + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SENSOR_CONFIG0 0 +#define SENSOR_CONFIG0_STOP BIT(0) +#define SENSOR_CONFIG0_TALL_SHIFT 8 +#define SENSOR_CONFIG0_TCALC_OVER BIT(4) +#define SENSOR_CONFIG0_OVER BIT(3) +#define SENSOR_CONFIG0_CPTR_OVER BIT(2) + +#define SENSOR_CONFIG1 4 +#define SENSOR_CONFIG1_TSAMPLE_SHIFT 0 +#define SENSOR_CONFIG1_TIDDQ_EN_SHIFT 15 +#define SENSOR_CONFIG1_TEN_COUNT_SHIFT 24 +#define SENSOR_CONFIG1_TEMP_ENABLE BIT(31) + +#define SENSOR_CONFIG2 8 +#define SENSOR_CONFIG2_THERMA_SHIFT 16 +#define SENSOR_CONFIG2_THERMB_SHIFT 0 + +#define SENSOR_PDIV 0x1c0 +#define SENSOR_PDIV_T124 0x8888 +#define SENSOR_HOTSPOT_OFF 0x1c4 +#define SENSOR_HOTSPOT_OFF_T124 0x00060600 +#define SENSOR_TEMP1 0x1c8 +#define SENSOR_TEMP2 0x1cc + +#define SENSOR_TEMP_MASK 0xffff +#define READBACK_VALUE_MASK 0xff00 +#define READBACK_VALUE_SHIFT 8 +#define READBACK_ADD_HALF BIT(7) +#define READBACK_NEGATE BIT(1) + +#define FUSE_TSENSOR8_CALIB 0x180 +#define FUSE_SPARE_REALIGNMENT_REG_0 0x1fc + +#define FUSE_TSENSOR_CALIB_CP_TS_BASE_MASK 0x1fff +#define FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK (0x1fff << 13) +#define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT 13 + +#define FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK 0x3ff +#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK (0x7ff << 10) +#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT 10 + +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_MASK 0x3f +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK (0x1f << 21) +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT 21 + +#define NOMINAL_CALIB_FT_T124 105 +#define NOMINAL_CALIB_CP_T124 25 + +struct tegra_tsensor_configuration { + u32 tall, tsample, tiddq_en, ten_count, pdiv, tsample_ate, pdiv_ate; +}; + +struct tegra_tsensor { + const struct tegra_tsensor_configuration *config; + u32 base, calib_fuse_offset; + /* Correction values used to modify values read from calibration fuses */ + s32 fuse_corr_alpha, fuse_corr_beta; +}; + +struct tegra_thermctl_zone { + void __iomem *reg; + unsigned int shift; +}; + +static const struct tegra_tsensor_configuration t124_tsensor_config = { + .tall = 16300, + .tsample = 120, + .tiddq_en = 1, + .ten_count = 1, + .pdiv = 8, + .tsample_ate = 480, + .pdiv_ate = 8 +}; + +static const struct tegra_tsensor t124_tsensors[] = { + { + .config = &t124_tsensor_config, + .base = 0xc0, + .calib_fuse_offset = 0x098, + .fuse_corr_alpha = 1135400, + .fuse_corr_beta = -6266900, + }, + { + .config = &t124_tsensor_config, + .base = 0xe0, + .calib_fuse_offset = 0x084, + .fuse_corr_alpha = 1122220, + .fuse_corr_beta = -5700700, + }, + { + .config = &t124_tsensor_config, + .base = 0x100, + .calib_fuse_offset = 0x088, + .fuse_corr_alpha = 1127000, + .fuse_corr_beta = -6768200, + }, + { + .config = &t124_tsensor_config, + .base = 0x120, + .calib_fuse_offset = 0x12c, + .fuse_corr_alpha = 1110900, + .fuse_corr_beta = -6232000, + }, + { + .config = &t124_tsensor_config, + .base = 0x140, + .calib_fuse_offset = 0x158, + .fuse_corr_alpha = 1122300, + .fuse_corr_beta = -5936400, + }, + { + .config = &t124_tsensor_config, + .base = 0x160, + .calib_fuse_offset = 0x15c, + .fuse_corr_alpha = 1145700, + .fuse_corr_beta = -7124600, + }, + { + .config = &t124_tsensor_config, + .base = 0x180, + .calib_fuse_offset = 0x154, + .fuse_corr_alpha = 1120100, + .fuse_corr_beta = -6000500, + }, + { + .config = &t124_tsensor_config, + .base = 0x1a0, + .calib_fuse_offset = 0x160, + .fuse_corr_alpha = 1106500, + .fuse_corr_beta = -6729300, + }, +}; + +struct tegra_soctherm { + struct reset_control *reset; + struct clk *clock_tsensor; + struct clk *clock_soctherm; + void __iomem *regs; + + struct thermal_zone_device *thermctl_tzs[4]; +}; + +struct tsensor_shared_calibration { + u32 base_cp, base_ft; + u32 actual_temp_cp, actual_temp_ft; +}; + +static int calculate_shared_calibration(struct tsensor_shared_calibration *r) +{ + u32 val, shifted_cp, shifted_ft; + int err; + + err = tegra_fuse_readl(FUSE_TSENSOR8_CALIB, &val); + if (err) + return err; + r->base_cp = val & FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK; + r->base_ft = (val & FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK) + >> FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT; + val = ((val & FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK) + >> FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT); + shifted_ft = sign_extend32(val, 4); + + err = tegra_fuse_readl(FUSE_SPARE_REALIGNMENT_REG_0, &val); + if (err) + return err; + shifted_cp = sign_extend32(val, 5); + + r->actual_temp_cp = 2 * NOMINAL_CALIB_CP_T124 + shifted_cp; + r->actual_temp_ft = 2 * NOMINAL_CALIB_FT_T124 + shifted_ft; + + return 0; +} + +static s64 div64_s64_precise(s64 a, s64 b) +{ + s64 r, al; + + /* Scale up for increased precision division */ + al = a << 16; + + r = div64_s64(al * 2 + 1, 2 * b); + return r >> 16; +} + +static int +calculate_tsensor_calibration(const struct tegra_tsensor *sensor, + const struct tsensor_shared_calibration *shared, + u32 *calib) +{ + u32 val; + s32 actual_tsensor_ft, actual_tsensor_cp, delta_sens, delta_temp, + mult, div; + s16 therma, thermb; + s64 tmp; + int err; + + err = tegra_fuse_readl(sensor->calib_fuse_offset, &val); + if (err) + return err; + + actual_tsensor_cp = (shared->base_cp * 64) + sign_extend32(val, 12); + val = (val & FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK) + >> FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT; + actual_tsensor_ft = (shared->base_ft * 32) + sign_extend32(val, 12); + + delta_sens = actual_tsensor_ft - actual_tsensor_cp; + delta_temp = shared->actual_temp_ft - shared->actual_temp_cp; + + mult = sensor->config->pdiv * sensor->config->tsample_ate; + div = sensor->config->tsample * sensor->config->pdiv_ate; + + therma = div64_s64_precise((s64) delta_temp * (1LL << 13) * mult, + (s64) delta_sens * div); + + tmp = (s64)actual_tsensor_ft * shared->actual_temp_cp - + (s64)actual_tsensor_cp * shared->actual_temp_ft; + thermb = div64_s64_precise(tmp, (s64)delta_sens); + + therma = div64_s64_precise((s64)therma * sensor->fuse_corr_alpha, + (s64)1000000LL); + thermb = div64_s64_precise((s64)thermb * sensor->fuse_corr_alpha + + sensor->fuse_corr_beta, (s64)1000000LL); + + *calib = ((u16)therma << SENSOR_CONFIG2_THERMA_SHIFT) | + ((u16)thermb << SENSOR_CONFIG2_THERMB_SHIFT); + + return 0; +} + +static int enable_tsensor(struct tegra_soctherm *tegra, + const struct tegra_tsensor *sensor, + const struct tsensor_shared_calibration *shared) +{ + void __iomem *base = tegra->regs + sensor->base; + unsigned int val; + u32 calib; + int err; + + err = calculate_tsensor_calibration(sensor, shared, &calib); + if (err) + return err; + + val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT; + writel(val, base + SENSOR_CONFIG0); + + val = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT; + val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT; + val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT; + val |= SENSOR_CONFIG1_TEMP_ENABLE; + writel(val, base + SENSOR_CONFIG1); + + writel(calib, base + SENSOR_CONFIG2); + + return 0; +} + +/* + * Translate from soctherm readback format to millicelsius. + * The soctherm readback format in bits is as follows: + * TTTTTTTT H______N + * where T's contain the temperature in Celsius, + * H denotes an addition of 0.5 Celsius and N denotes negation + * of the final value. + */ +static long translate_temp(u16 val) +{ + long t; + + t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000; + if (val & READBACK_ADD_HALF) + t += 500; + if (val & READBACK_NEGATE) + t *= -1; + + return t; +} + +static int tegra_thermctl_get_temp(void *data, long *out_temp) +{ + struct tegra_thermctl_zone *zone = data; + u32 val; + + val = (readl(zone->reg) >> zone->shift) & SENSOR_TEMP_MASK; + *out_temp = translate_temp(val); + + return 0; +} + +static const struct of_device_id tegra_soctherm_of_match[] = { + { .compatible = "nvidia,tegra124-soctherm" }, + { }, +}; +MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match); + +struct thermctl_zone_desc { + unsigned int offset; + unsigned int shift; +}; + +static const struct thermctl_zone_desc t124_thermctl_temp_zones[] = { + { SENSOR_TEMP1, 16 }, + { SENSOR_TEMP2, 16 }, + { SENSOR_TEMP1, 0 }, + { SENSOR_TEMP2, 0 } +}; + +static int tegra_soctherm_probe(struct platform_device *pdev) +{ + struct tegra_soctherm *tegra; + struct thermal_zone_device *tz; + struct tsensor_shared_calibration shared_calib; + struct resource *res; + unsigned int i; + int err; + + const struct tegra_tsensor *tsensors = t124_tsensors; + + tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); + if (!tegra) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + tegra->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(tegra->regs)) + return PTR_ERR(tegra->regs); + + tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm"); + if (IS_ERR(tegra->reset)) { + dev_err(&pdev->dev, "can't get soctherm reset\n"); + return PTR_ERR(tegra->reset); + } + + tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor"); + if (IS_ERR(tegra->clock_tsensor)) { + dev_err(&pdev->dev, "can't get tsensor clock\n"); + return PTR_ERR(tegra->clock_tsensor); + } + + tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm"); + if (IS_ERR(tegra->clock_soctherm)) { + dev_err(&pdev->dev, "can't get soctherm clock\n"); + return PTR_ERR(tegra->clock_soctherm); + } + + reset_control_assert(tegra->reset); + + err = clk_prepare_enable(tegra->clock_soctherm); + if (err) + return err; + + err = clk_prepare_enable(tegra->clock_tsensor); + if (err) { + clk_disable_unprepare(tegra->clock_soctherm); + return err; + } + + reset_control_deassert(tegra->reset); + + /* Initialize raw sensors */ + + err = calculate_shared_calibration(&shared_calib); + if (err) + goto disable_clocks; + + for (i = 0; i < ARRAY_SIZE(t124_tsensors); ++i) { + err = enable_tsensor(tegra, tsensors + i, &shared_calib); + if (err) + goto disable_clocks; + } + + writel(SENSOR_PDIV_T124, tegra->regs + SENSOR_PDIV); + writel(SENSOR_HOTSPOT_OFF_T124, tegra->regs + SENSOR_HOTSPOT_OFF); + + /* Initialize thermctl sensors */ + + for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) { + struct tegra_thermctl_zone *zone = + devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + err = -ENOMEM; + goto unregister_tzs; + } + + zone->reg = tegra->regs + t124_thermctl_temp_zones[i].offset; + zone->shift = t124_thermctl_temp_zones[i].shift; + + tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, + tegra_thermctl_get_temp, + NULL); + if (IS_ERR(tz)) { + err = PTR_ERR(tz); + dev_err(&pdev->dev, "failed to register sensor: %d\n", + err); + goto unregister_tzs; + } + + tegra->thermctl_tzs[i] = tz; + } + + return 0; + +unregister_tzs: + while (i--) + thermal_zone_of_sensor_unregister(&pdev->dev, + tegra->thermctl_tzs[i]); + +disable_clocks: + clk_disable_unprepare(tegra->clock_tsensor); + clk_disable_unprepare(tegra->clock_soctherm); + + return err; +} + +static int tegra_soctherm_remove(struct platform_device *pdev) +{ + struct tegra_soctherm *tegra = platform_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) { + thermal_zone_of_sensor_unregister(&pdev->dev, + tegra->thermctl_tzs[i]); + } + + clk_disable_unprepare(tegra->clock_tsensor); + clk_disable_unprepare(tegra->clock_soctherm); + + return 0; +} + +static struct platform_driver tegra_soctherm_driver = { + .probe = tegra_soctherm_probe, + .remove = tegra_soctherm_remove, + .driver = { + .name = "tegra-soctherm", + .of_match_table = tegra_soctherm_of_match, + }, +}; +module_platform_driver(tegra_soctherm_driver); + +MODULE_AUTHOR("Mikko Perttunen "); +MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver"); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From 2251aef64a38db60f4ae7a4a83f9203c6791f196 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 7 Nov 2014 21:24:39 -0400 Subject: thermal: of: improve of-thermal sensor registration API Different drivers request API extensions in of-thermal. For this reason, additional callbacks are required to fit the new drivers needs. The current API implementation expects the registering sensor driver to provide a get_temp and get_trend callbacks as function parameters. As the amount of callbacks is growing, this patch changes the existing implementation to use a .ops field to hold all the of thermal callbacks to sensor drivers. This patch also changes the existing of-thermal users to fit the new API design. No functional change is introduced in this patch. Cc: Alexandre Courbot Cc: devicetree@vger.kernel.org Cc: Grant Likely Cc: Guenter Roeck Cc: Jean Delvare Cc: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: linux-tegra@vger.kernel.org Cc: lm-sensors@lm-sensors.org Cc: Rob Herring Cc: Stephen Warren Cc: Thierry Reding Cc: Zhang Rui Acked-by: Guenter Roeck Tested-by: Mikko Perttunen Reviewed-by: Mikko Perttunen Reviewed-by: Alexandre Courbot Reviewed-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb3..e7c8bf9 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -176,6 +176,10 @@ static struct attribute *lm75_attrs[] = { }; ATTRIBUTE_GROUPS(lm75); +static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = { + .get_temp = lm75_read_temp, +}; + /*-----------------------------------------------------------------------*/ /* device probe and removal */ @@ -291,10 +295,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) if (IS_ERR(data->hwmon_dev)) return PTR_ERR(data->hwmon_dev); - data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, - 0, + data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0, data->hwmon_dev, - lm75_read_temp, NULL); + &lm75_of_thermal_ops); if (IS_ERR(data->tz)) data->tz = NULL; diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 4ff89b2..bca8521c8 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -486,6 +486,10 @@ static const struct attribute_group ntc_attr_group = { .attrs = ntc_attributes, }; +static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { + .get_temp = ntc_read_temp, +}; + static int ntc_thermistor_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) pdev_id->name); data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, - ntc_read_temp, NULL); + &ntc_of_thermal_ops); if (IS_ERR(data->tz)) { dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); data->tz = NULL; diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 5171995..ba9f478 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102); #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) +static const struct thermal_zone_of_device_ops tmp102_of_thermal_ops = { + .get_temp = tmp102_read_temp, +}; + static int tmp102_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client, } tmp102->hwmon_dev = hwmon_dev; tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, - tmp102_read_temp, NULL); + &tmp102_of_thermal_ops); if (IS_ERR(tmp102->tz)) tmp102->tz = NULL; diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 62143ba..b7982f0 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "thermal_core.h" @@ -77,8 +78,7 @@ struct __thermal_bind_params { * @num_tbps: number of thermal bind params * @tbps: an array of thermal bind params (0..num_tbps - 1) * @sensor_data: sensor private data used while reading temperature and trend - * @get_temp: sensor callback to read temperature - * @get_trend: sensor callback to read temperature trend + * @ops: set of callbacks to handle the thermal zone based on DT */ struct __thermal_zone { @@ -96,8 +96,7 @@ struct __thermal_zone { /* sensor interface */ void *sensor_data; - int (*get_temp)(void *, long *); - int (*get_trend)(void *, long *); + const struct thermal_zone_of_device_ops *ops; }; /*** DT thermal zone device callbacks ***/ @@ -107,10 +106,10 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, { struct __thermal_zone *data = tz->devdata; - if (!data->get_temp) + if (!data->ops->get_temp) return -EINVAL; - return data->get_temp(data->sensor_data, temp); + return data->ops->get_temp(data->sensor_data, temp); } static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, @@ -120,10 +119,10 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, long dev_trend; int r; - if (!data->get_trend) + if (!data->ops->get_trend) return -EINVAL; - r = data->get_trend(data->sensor_data, &dev_trend); + r = data->ops->get_trend(data->sensor_data, &dev_trend); if (r) return r; @@ -324,8 +323,7 @@ static struct thermal_zone_device_ops of_thermal_ops = { static struct thermal_zone_device * thermal_zone_of_add_sensor(struct device_node *zone, struct device_node *sensor, void *data, - int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) + const struct thermal_zone_of_device_ops *ops) { struct thermal_zone_device *tzd; struct __thermal_zone *tz; @@ -336,9 +334,11 @@ thermal_zone_of_add_sensor(struct device_node *zone, tz = tzd->devdata; + if (!ops) + return ERR_PTR(-EINVAL); + mutex_lock(&tzd->lock); - tz->get_temp = get_temp; - tz->get_trend = get_trend; + tz->ops = ops; tz->sensor_data = data; tzd->ops->get_temp = of_thermal_get_temp; @@ -356,8 +356,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, * than one sensors * @data: a private pointer (owned by the caller) that will be passed * back, when a temperature reading is needed. - * @get_temp: a pointer to a function that reads the sensor temperature. - * @get_trend: a pointer to a function that reads the sensor temperature trend. + * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. * * This function will search the list of thermal zones described in device * tree and look for the zone that refer to the sensor device pointed by @@ -382,9 +381,8 @@ thermal_zone_of_add_sensor(struct device_node *zone, * check the return value with help of IS_ERR() helper. */ struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int sensor_id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) +thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, + const struct thermal_zone_of_device_ops *ops) { struct device_node *np, *child, *sensor_np; struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); @@ -426,9 +424,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, if (sensor_specs.np == sensor_np && id == sensor_id) { tzd = thermal_zone_of_add_sensor(child, sensor_np, - data, - get_temp, - get_trend); + data, ops); of_node_put(sensor_specs.np); of_node_put(child); goto exit; @@ -476,8 +472,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev, tzd->ops->get_temp = NULL; tzd->ops->get_trend = NULL; - tz->get_temp = NULL; - tz->get_trend = NULL; + tz->ops = NULL; tz->sensor_data = NULL; mutex_unlock(&tzd->lock); } diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c index 70f7e9e..9197fc0 100644 --- a/drivers/thermal/tegra_soctherm.c +++ b/drivers/thermal/tegra_soctherm.c @@ -317,6 +317,10 @@ static int tegra_thermctl_get_temp(void *data, long *out_temp) return 0; } +static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { + .get_temp = tegra_thermctl_get_temp, +}; + static const struct of_device_id tegra_soctherm_of_match[] = { { .compatible = "nvidia,tegra124-soctherm" }, { }, @@ -416,8 +420,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) zone->shift = t124_thermctl_temp_zones[i].shift; tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, - tegra_thermctl_get_temp, - NULL); + &tegra_of_thermal_ops); if (IS_ERR(tz)) { err = PTR_ERR(tz); dev_err(&pdev->dev, "failed to register sensor: %d\n", diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 9eec26d..5fd0386 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -286,6 +286,11 @@ static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal, return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp); } +static const struct thermal_zone_of_device_ops ti_of_thermal_ops = { + .get_temp = __ti_thermal_get_temp, + .get_trend = __ti_thermal_get_trend, +}; + static struct thermal_zone_device_ops ti_thermal_ops = { .get_temp = ti_thermal_get_temp, .get_trend = ti_thermal_get_trend, @@ -333,8 +338,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, /* in case this is specified by DT */ data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id, - data, __ti_thermal_get_temp, - __ti_thermal_get_trend); + data, &ti_of_thermal_ops); if (IS_ERR(data->ti_thermal)) { /* Create thermal zone */ data->ti_thermal = thermal_zone_device_register(domain, diff --git a/include/linux/thermal.h b/include/linux/thermal.h index ef90838..5bc28a7 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -289,19 +289,31 @@ struct thermal_genl_event { enum events event; }; +/** + * struct thermal_zone_of_device_ops - scallbacks for handling DT based zones + * + * Mandatory: + * @get_temp: a pointer to a function that reads the sensor temperature. + * + * Optional: + * @get_trend: a pointer to a function that reads the sensor temperature trend. + */ +struct thermal_zone_of_device_ops { + int (*get_temp)(void *, long *); + int (*get_trend)(void *, long *); +}; + /* Function declarations */ #ifdef CONFIG_THERMAL_OF struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)); +thermal_zone_of_sensor_register(struct device *dev, int id, void *data, + const struct thermal_zone_of_device_ops *ops); void thermal_zone_of_sensor_unregister(struct device *dev, struct thermal_zone_device *tz); #else static inline struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) +thermal_zone_of_sensor_register(struct device *dev, int id, void *data, + const struct thermal_zone_of_device_ops *ops) { return NULL; } -- cgit v0.10.2 From 77109411d5d24471ffa391dce56ba3559fb87d94 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:56 +0100 Subject: thermal: exynos: remove needless triminfo_data abstraction reg->triminfo_data is used only in exynos_tmu_initialize() and the code has already different paths for Exynos5440 and other SoC types (on which TRIMINFO_DATA register offset is identical) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 49c0924..bb05355 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -182,22 +182,22 @@ static int exynos_tmu_initialize(struct platform_device *pdev) switch (data->id) { case 0: trim_info = readl(data->base + - EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); + EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); break; case 1: - trim_info = readl(data->base + reg->triminfo_data); + trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); break; case 2: trim_info = readl(data->base - - EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); + EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); } } else { /* On exynos5420 the triminfo register is in the shared space */ if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) trim_info = readl(data->base_second + - reg->triminfo_data); + EXYNOS_TMU_REG_TRIMINFO); else - trim_info = readl(data->base + reg->triminfo_data); + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); } data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index c58c766..91e2317 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -76,7 +76,6 @@ enum soc_type { * struct exynos_tmu_register - register descriptors to access registers and * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. - * @triminfo_data: register containing 2 pont trimming data * @triminfo_ctrl: trim info controller register. * @triminfo_ctrl_count: the number of trim info controller register. * @tmu_ctrl: TMU main controller register. @@ -107,8 +106,6 @@ enum soc_type { * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { - u32 triminfo_data; - u32 triminfo_ctrl[MAX_TRIMINFO_CTRL_REG]; u32 triminfo_ctrl_count; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 1724f6c..a6088ff 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -26,7 +26,6 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, @@ -85,7 +84,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON1, .triminfo_ctrl[1] = EXYNOS_TMU_TRIMINFO_CON2, .triminfo_ctrl_count = 2, @@ -168,7 +166,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON2, .triminfo_ctrl_count = 1, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, @@ -262,7 +259,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, @@ -341,7 +337,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, @@ -428,7 +423,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .triminfo_data = EXYNOS5440_TMU_S0_7_TRIM, .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, -- cgit v0.10.2 From 5d022061cabe5b4967d9f5b65d2ce9c121aa458a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:57 +0100 Subject: thermal: exynos: remove needless tmu_status abstraction reg->tmu_status is used only in exynos_tmu_initialize() and it is accessed only if TMU_SUPPORT_READY_STATUS flag is set. This flag is not set for Exynos5440 and TMU_STATUS register offset is identical for all other SoC types so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index bb05355..ac43637 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -154,7 +154,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) clk_enable(data->clk_sec); if (TMU_SUPPORTS(pdata, READY_STATUS)) { - status = readb(data->base + reg->tmu_status); + status = readb(data->base + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 91e2317..7849d8f 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -83,7 +83,6 @@ enum soc_type { * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. - * @tmu_status: register drescribing the TMU status. * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_temp: register containing the base threshold level. * @threshold_th0: Register containing first set of rising levels. @@ -115,8 +114,6 @@ struct exynos_tmu_registers { u32 therm_trip_mode_mask; u32 therm_trip_en_shift; - u32 tmu_status; - u32 tmu_cur_temp; u32 threshold_temp; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index a6088ff..49c8142 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -27,7 +27,6 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP, .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, @@ -92,7 +91,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -173,7 +171,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -263,7 +260,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -341,7 +337,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -427,7 +422,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS5440_TMU_S0_7_STATUS, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h index 63de598..e02ef99 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ b/drivers/thermal/samsung/exynos_tmu_data.h @@ -88,7 +88,6 @@ #define EXYNOS5440_TMU_S0_7_TRIM 0x000 #define EXYNOS5440_TMU_S0_7_CTRL 0x020 #define EXYNOS5440_TMU_S0_7_DEBUG 0x040 -#define EXYNOS5440_TMU_S0_7_STATUS 0x060 #define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 #define EXYNOS5440_TMU_S0_7_TH0 0x110 #define EXYNOS5440_TMU_S0_7_TH1 0x130 -- cgit v0.10.2 From 6b1fbbdebae2016fa8a7505021ff2924e75d9e82 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:58 +0100 Subject: thermal: exynos: remove needless threshold_temp abstraction reg->threshold_temp is used only in exynos_tmu_initialize() and is accessed only on Exynos4210 (other SoC types don't even have threshold_temp entry assigned in their struct exynos_tmu_registers instances) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index ac43637..12e6f16 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -219,7 +219,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold); writeb(threshold_code, - data->base + reg->threshold_temp); + data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); for (i = 0; i < pdata->non_hw_trigger_levels; i++) writeb(pdata->trigger_levels[i], data->base + reg->threshold_th0 + i * sizeof(reg->threshold_th0)); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 7849d8f..d693215 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -84,7 +84,6 @@ enum soc_type { * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. * @tmu_cur_temp: register containing the current temperature of the TMU. - * @threshold_temp: register containing the base threshold level. * @threshold_th0: Register containing first set of rising levels. * @threshold_th1: Register containing second set of rising levels. * @threshold_th2: Register containing third set of rising levels. @@ -116,8 +115,6 @@ struct exynos_tmu_registers { u32 tmu_cur_temp; - u32 threshold_temp; - u32 threshold_th0; u32 threshold_th1; u32 threshold_th2; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 49c8142..8153c41 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -28,7 +28,6 @@ static const struct exynos_tmu_registers exynos4210_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP, .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, -- cgit v0.10.2 From 32f9520569ed6bf75673063b8b1c4f2e46a75c48 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:59 +0100 Subject: thermal: exynos: remove needless triminfo_ctrl abstraction reg->triminfo_ctrl[] is used in only exynos_tmu_initialize() and accessed only if TMU_SUPPORT_TRIM_RELOAD flag is set. This flag is set only on Exynos3250, Exynos4412 and Exynos5250 (other SoC types don't even have triminfo_ctrl[] entries assigned in their struct exynos_tmu_registers instances) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h index 158f5aa..cd44719 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.h +++ b/drivers/thermal/samsung/exynos_thermal_common.h @@ -27,7 +27,6 @@ #define SENSOR_NAME_LEN 16 #define MAX_TRIP_COUNT 8 #define MAX_COOLING_DEVICE 4 -#define MAX_TRIMINFO_CTRL_REG 2 #define ACTIVE_INTERVAL 500 #define IDLE_INTERVAL 10000 diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 12e6f16..160e7fa 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -162,15 +162,14 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } if (TMU_SUPPORTS(pdata, TRIM_RELOAD)) { - for (i = 0; i < reg->triminfo_ctrl_count; i++) { - if (pdata->triminfo_reload[i]) { - ctrl = readl(data->base + - reg->triminfo_ctrl[i]); - ctrl |= pdata->triminfo_reload[i]; - writel(ctrl, data->base + - reg->triminfo_ctrl[i]); - } + if (data->soc == SOC_ARCH_EXYNOS3250) { + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); } + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); } /* Save trimming info in order to perform calibration */ diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index d693215..cee81a1 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -76,8 +76,6 @@ enum soc_type { * struct exynos_tmu_register - register descriptors to access registers and * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. - * @triminfo_ctrl: trim info controller register. - * @triminfo_ctrl_count: the number of trim info controller register. * @tmu_ctrl: TMU main controller register. * @test_mux_addr_shift: shift bits of test mux address. * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. @@ -104,9 +102,6 @@ enum soc_type { * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { - u32 triminfo_ctrl[MAX_TRIMINFO_CTRL_REG]; - u32 triminfo_ctrl_count; - u32 tmu_ctrl; u32 test_mux_addr_shift; u32 therm_trip_mode_shift; @@ -184,7 +179,6 @@ struct exynos_tmu_registers { * @second_point_trim: temp value of the second point trimming * @default_temp_offset: default temperature offset in case of no trimming * @test_mux; information if SoC supports test MUX - * @triminfo_reload: reload value to read TRIMINFO register * @cal_type: calibration type for temperature * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may @@ -215,7 +209,6 @@ struct exynos_tmu_platform_data { u8 second_point_trim; u8 default_temp_offset; u8 test_mux; - u8 triminfo_reload[MAX_TRIMINFO_CTRL_REG]; enum calibration_type cal_type; enum soc_type type; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 8153c41..d4b9a68 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -82,9 +82,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON1, - .triminfo_ctrl[1] = EXYNOS_TMU_TRIMINFO_CON2, - .triminfo_ctrl_count = 2, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, @@ -140,8 +137,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .triminfo_reload[0] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ - .triminfo_reload[1] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ .registers = &exynos3250_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ @@ -163,8 +158,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON2, - .triminfo_ctrl_count = 1, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, @@ -221,7 +214,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .triminfo_reload[0] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ .registers = &exynos4412_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ -- cgit v0.10.2 From bfb2b88c79df839779586e0247456bd79882b145 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:00 +0100 Subject: thermal: exynos: remove needless test_mux_addr_shift abstraction reg->test_mux_addr_shift is used only if pdata->test_mux is non-zero. pdata->test_mux is defined only on Exynos3250 and Exynos4412 (other SoC types don't even have pdata->test_mux entry assigned in their struct exynos_tmu_registers instances) so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 160e7fa..c8d6cdd 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -295,7 +295,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con = readl(data->base + reg->tmu_ctrl); if (pdata->test_mux) - con |= (pdata->test_mux << reg->test_mux_addr_shift); + con |= (pdata->test_mux << EXYNOS4412_MUX_ADDR_SHIFT); con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index cee81a1..0fb10d1 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -77,7 +77,6 @@ enum soc_type { * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. - * @test_mux_addr_shift: shift bits of test mux address. * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. @@ -103,7 +102,6 @@ enum soc_type { */ struct exynos_tmu_registers { u32 tmu_ctrl; - u32 test_mux_addr_shift; u32 therm_trip_mode_shift; u32 therm_trip_mode_mask; u32 therm_trip_en_shift; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d4b9a68..4ca1283 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -83,7 +83,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, @@ -159,7 +158,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, -- cgit v0.10.2 From b9504a6a3d668e4995420e311869291b21b81b37 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:01 +0100 Subject: thermal: exynos: remove needless therm_trip_[mode,mask]_shift abstractions reg->therm_trip_mode_shift and reg->therm_trip_mode_mask are used only in exynos_tmu_control() and accessed only if pdata->noise_cancel_mode is non-zero. pdata->noise_cancel field is not defined on Exynos4210 (also therm_trip_mode_shift and therm_trip_mode_mask entries are not even assigned in exynos4210_tmu_registers but they are assigned to identical values for all other SoC types) so the abstractions are not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index c8d6cdd..fb38411 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -304,9 +304,8 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con |= (pdata->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); if (pdata->noise_cancel_mode) { - con &= ~(reg->therm_trip_mode_mask << - reg->therm_trip_mode_shift); - con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift); + con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT); + con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT); } if (on) { diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 0fb10d1..88c16d7 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -77,8 +77,6 @@ enum soc_type { * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. - * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. - * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_th0: Register containing first set of rising levels. @@ -102,8 +100,6 @@ enum soc_type { */ struct exynos_tmu_registers { u32 tmu_ctrl; - u32 therm_trip_mode_shift; - u32 therm_trip_mode_mask; u32 therm_trip_en_shift; u32 tmu_cur_temp; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 4ca1283..4a44eb7 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -83,8 +83,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -158,8 +156,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -246,8 +242,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -323,8 +317,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -408,8 +400,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, -- cgit v0.10.2 From 77a37a92ca18e4385bfcca9f2762d39fe83110b9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:02 +0100 Subject: thermal: exynos: remove needless therm_trip_en_shift abstraction reg->therm_trip_en_shift is used only in exynos_tmu_initialize() and not accessed on Exynos4210 (also reg->therm_trip_en_shift is not even assigned in exynos4210_tmu_registers but it is assigned to identical value for all other SoC types) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index fb38411..3f3b8cf 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -266,7 +266,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) data->base + reg->threshold_th2); } con = readl(data->base + reg->tmu_ctrl); - con |= (1 << reg->therm_trip_en_shift); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); writel(con, data->base + reg->tmu_ctrl); } } diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 88c16d7..4798313 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -77,7 +77,6 @@ enum soc_type { * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. - * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_th0: Register containing first set of rising levels. * @threshold_th1: Register containing second set of rising levels. @@ -100,7 +99,6 @@ enum soc_type { */ struct exynos_tmu_registers { u32 tmu_ctrl; - u32 therm_trip_en_shift; u32 tmu_cur_temp; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 4a44eb7..a120a8c 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -83,7 +83,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -156,7 +155,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -242,7 +240,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -317,7 +314,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -400,7 +396,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, -- cgit v0.10.2 From 9e288d6430373a679d1ee88ff90813cd6be20dd2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:03 +0100 Subject: thermal: exynos: remove needless emul_temp_shift abstraction reg->emul_temp_shift is used only in exynos_tmu_set_emulation() and accessed only if TMU_SUPPORT_EMULATION flag is set. This flag is not set for Exynos4210 (reg->emul_temp_shift field is not even assigned in exynos4210_tmu_registers and is assigned to identical value for all other SoC types) so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 3f3b8cf..c108a1f 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -383,8 +383,8 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift); val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift); } - val &= ~(EXYNOS_EMUL_DATA_MASK << reg->emul_temp_shift); - val |= (temp_to_code(data, temp) << reg->emul_temp_shift) | + val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); + val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE; } else { val &= ~EXYNOS_EMUL_ENABLE; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 4798313..ed3d816 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @emul_temp_shift: shift bits of emulation temperature. * @emul_time_shift: shift bits of emulation time. * @tmu_irqstatus: register to find which TMU generated interrupts. * @tmu_pmin: register to get/set the Pmin value. @@ -119,7 +118,6 @@ struct exynos_tmu_registers { u32 tmu_intclear; u32 emul_con; - u32 emul_temp_shift; u32 emul_time_shift; u32 tmu_irqstatus; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index a120a8c..c35a6ea 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -94,7 +94,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -167,7 +166,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -252,7 +250,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -327,7 +324,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -411,7 +407,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .tmu_pmin = EXYNOS5440_TMU_PMIN, }; -- cgit v0.10.2 From 6070c2ca37c3b04a007541761b244afebc3e9876 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:04 +0100 Subject: thermal: exynos: remove needless emul_time_shift abstraction reg->emul_time_shift is used only in exynos_tmu_set_emulation() and accessed only if TMU_SUPPORT_EMUL_TIME flag is set. This flag is not set for Exynos4210 and Exynos5440 (reg->emul_time_shift field is not even assigned in exynos[4210,5440]_tmu_registers and is assigned to identical value for all other SoC types) so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index c108a1f..e35c289 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -380,8 +380,8 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) temp /= MCELSIUS; if (TMU_SUPPORTS(pdata, EMUL_TIME)) { - val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift); - val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift); + val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); + val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); } val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index ed3d816..2694298 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @emul_time_shift: shift bits of emulation time. * @tmu_irqstatus: register to find which TMU generated interrupts. * @tmu_pmin: register to get/set the Pmin value. */ @@ -118,7 +117,6 @@ struct exynos_tmu_registers { u32 tmu_intclear; u32 emul_con; - u32 emul_time_shift; u32 tmu_irqstatus; u32 tmu_pmin; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index c35a6ea..cef0b97 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -94,7 +94,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define EXYNOS3250_TMU_DATA \ @@ -166,7 +165,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define EXYNOS4412_TMU_DATA \ @@ -250,7 +248,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define __EXYNOS5260_TMU_DATA \ @@ -324,7 +321,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define __EXYNOS5420_TMU_DATA \ -- cgit v0.10.2 From 421d5d127d422bb98ce96ffa70af713698035f93 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:05 +0100 Subject: thermal: exynos: replace tmu_irqstatus check by Exynos5440 one reg->tmu_irqstatus is set to non-zero value only for Exynos5440 so replace check for non-zero value of reg->tmu_irqstatus by explicitly checking for Exynos5440 SoC type. Then remove no longer needed reg->tmu_irqstatus register abstraction. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index e35c289..839b07b 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -407,15 +407,13 @@ static void exynos_tmu_work(struct work_struct *work) { struct exynos_tmu_data *data = container_of(work, struct exynos_tmu_data, irq_work); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; unsigned int val_type; if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); /* Find which sensor generated this interrupt */ - if (reg->tmu_irqstatus) { - val_type = readl(data->base_second + reg->tmu_irqstatus); + if (data->soc == SOC_ARCH_EXYNOS5440) { + val_type = readl(data->base_second + EXYNOS5440_TMU_IRQ_STATUS); if (!((val_type >> data->id) & 0x1)) goto out; } diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 2694298..5c2cef1 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @tmu_irqstatus: register to find which TMU generated interrupts. * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { @@ -118,7 +117,6 @@ struct exynos_tmu_registers { u32 emul_con; - u32 tmu_irqstatus; u32 tmu_pmin; }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index cef0b97..557b4a5 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -401,7 +401,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, - .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, .tmu_pmin = EXYNOS5440_TMU_PMIN, }; -- cgit v0.10.2 From 0c78b4d88f1c5e09800ad99d705699cda7411d51 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:06 +0100 Subject: thermal: exynos: replace tmu_pmin check by Exynos5440 one reg->tmu_pmin is set to non-zero value only for Exynos5440 so replace check for non-zero value of reg->tmu_pmin by explicitly checking for Exynos5440 SoC type. Then remove no longer needed reg->tmu_pmin register abstraction. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 839b07b..411c465 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -271,8 +271,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } } /*Clear the PMIN in the common TMU register*/ - if (reg->tmu_pmin && !data->id) - writel(0, data->base_second + reg->tmu_pmin); + if (data->soc == SOC_ARCH_EXYNOS5440 && !data->id) + writel(0, data->base_second + EXYNOS5440_TMU_PMIN); out: clk_disable(data->clk); mutex_unlock(&data->lock); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 5c2cef1..e8510aa 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { u32 tmu_ctrl; @@ -116,8 +115,6 @@ struct exynos_tmu_registers { u32 tmu_intclear; u32 emul_con; - - u32 tmu_pmin; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 557b4a5..fe063d4 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -402,7 +402,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, - .tmu_pmin = EXYNOS5440_TMU_PMIN, }; #define EXYNOS5440_TMU_DATA \ -- cgit v0.10.2 From 2516593e4ef0230b184e8ce4dd3de6caed5e6131 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:07 +0100 Subject: thermal: exynos: simplify HW_TRIP level setting Simplify HW_TRIP level setting in exynos_tmu_initialize() (don't pretend that the current code is hardware and configuration independent and just do SoC type check explicitly). Then remove no longer needed reg->threshold_[th2,th3_l0_shift] abstractions (only assigned for Exynos5440 in exynos5440_tmu_registers) and EXYNOS_MAX_TRIGGER_PER_REG define. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 411c465..1c15b37 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -252,18 +252,18 @@ static int exynos_tmu_initialize(struct platform_device *pdev) (pdata->trigger_type[i] == HW_TRIP)) { threshold_code = temp_to_code(data, pdata->trigger_levels[i]); - if (i == EXYNOS_MAX_TRIGGER_PER_REG - 1) { + if (data->soc != SOC_ARCH_EXYNOS5440) { /* 1-4 level to be assigned in th0 reg */ rising_threshold &= ~(0xff << 8 * i); rising_threshold |= threshold_code << 8 * i; writel(rising_threshold, - data->base + reg->threshold_th0); - } else if (i == EXYNOS_MAX_TRIGGER_PER_REG) { + data->base + EXYNOS_THD_TEMP_RISE); + } else { /* 5th level to be assigned in th2 reg */ rising_threshold = - threshold_code << reg->threshold_th3_l0_shift; + threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; writel(rising_threshold, - data->base + reg->threshold_th2); + data->base + EXYNOS5440_TMU_S0_7_TH2); } con = readl(data->base + reg->tmu_ctrl); con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index e8510aa..ebe39b4 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -80,8 +80,6 @@ enum soc_type { * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_th0: Register containing first set of rising levels. * @threshold_th1: Register containing second set of rising levels. - * @threshold_th2: Register containing third set of rising levels. - * @threshold_th3_l0_shift: shift bits of level0 threshold temperature. * @tmu_inten: register containing the different threshold interrupt enable bits. * @inten_rise0_shift: shift bits of rising 0 interrupt bits. @@ -100,8 +98,6 @@ struct exynos_tmu_registers { u32 threshold_th0; u32 threshold_th1; - u32 threshold_th2; - u32 threshold_th3_l0_shift; u32 tmu_inten; u32 inten_rise0_shift; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index fe063d4..f81c940 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -391,8 +391,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, - .threshold_th2 = EXYNOS5440_TMU_S0_7_TH2, - .threshold_th3_l0_shift = EXYNOS5440_TMU_TH_RISE4_SHIFT, .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h index e02ef99..2af312d 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ b/drivers/thermal/samsung/exynos_tmu_data.h @@ -72,8 +72,6 @@ #define EXYNOS_EMUL_DATA_MASK 0xFF #define EXYNOS_EMUL_ENABLE 0x1 -#define EXYNOS_MAX_TRIGGER_PER_REG 4 - /* Exynos5260 specific */ #define EXYNOS5260_TMU_REG_INTEN 0xC0 #define EXYNOS5260_TMU_REG_INTSTAT 0xC4 -- cgit v0.10.2 From 23f146296c6a166b9ba3d810a6a53cb5df6a5b4f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:08 +0100 Subject: thermal: exynos: replace threshold_falling check by Exynos SoC type one Replace pdata->threshold_falling check for non-zero value in exynos_tmu_initialize() by an explicit check for a SoC type (all SoC types except Exynos5440 have pdata->threshold_falling assigned to non-zero value in their struct exynos_tmu_registers instances). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1c15b37..4f7cad9 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -231,7 +231,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) pdata->trigger_levels[i]); rising_threshold &= ~(0xff << 8 * i); rising_threshold |= threshold_code << 8 * i; - if (pdata->threshold_falling) { + if (data->soc != SOC_ARCH_EXYNOS5440) { threshold_code = temp_to_code(data, pdata->trigger_levels[i] - pdata->threshold_falling); -- cgit v0.10.2 From 6f02fa18fbff39919f26c228e2e7f1f5b9b211e9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:09 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_READY_STATUS flag Replace TMU_SUPPORT_READY_STATUS flag check in exynos_tmu_initialize() by an explicit check for a SoC type (all SoC types except Exynos5440 have TMU_SUPPORT_READY_STATUS flag set in their struct exynos_tmu_init_data instances). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 4f7cad9..33ee527 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -153,7 +153,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); - if (TMU_SUPPORTS(pdata, READY_STATUS)) { + if (data->soc != SOC_ARCH_EXYNOS5440) { status = readb(data->base + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index ebe39b4..d3d9205 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -54,8 +54,6 @@ enum soc_type { * be reloaded. * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can * be registered for falling trips also. - * TMU_SUPPORT_READY_STATUS - This feature tells that the TMU current - * state(active/idle) can be checked. * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation * sample time. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU @@ -66,9 +64,8 @@ enum soc_type { #define TMU_SUPPORT_MULTI_INST BIT(1) #define TMU_SUPPORT_TRIM_RELOAD BIT(2) #define TMU_SUPPORT_FALLING_TRIP BIT(3) -#define TMU_SUPPORT_READY_STATUS BIT(4) -#define TMU_SUPPORT_EMUL_TIME BIT(5) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(6) +#define TMU_SUPPORT_EMUL_TIME BIT(4) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(5) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index f81c940..c3271200 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -73,7 +73,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .freq_tab_count = 2, .type = SOC_ARCH_EXYNOS4210, .registers = &exynos4210_tmu_registers, - .features = TMU_SUPPORT_READY_STATUS, }, }, .tmu_count = 1, @@ -133,8 +132,7 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .freq_tab_count = 2, \ .registers = &exynos3250_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ - TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -204,8 +202,7 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .freq_tab_count = 2, \ .registers = &exynos4412_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ - TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -291,7 +288,7 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5260, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_EMUL_TIME) struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -364,14 +361,13 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5250, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_EMUL_TIME) #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME | \ - TMU_SUPPORT_ADDRESS_MULTIPLE) + TMU_SUPPORT_EMUL_TIME | TMU_SUPPORT_ADDRESS_MULTIPLE) struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { -- cgit v0.10.2 From 1e04ee8053b5f0af6bfab52b86a57de1c13c57ef Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:10 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_TRIM_RELOAD flag Replace TMU_SUPPORT_TRIM_RELOAD flag check in exynos_tmu_initialize() by an explicit check for a SoC type (only Exynos3250, Exynos4412 and Exynos5250 have TMU_SUPPORT_READY_STATUS flag set in their struct exynos_tmu_init_data instances). Please note that this requires adding separate SoC type for Exynos5420 so it doesn't get mistaken with Exynos5250. This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 33ee527..e4d75a1 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -161,7 +161,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } } - if (TMU_SUPPORTS(pdata, TRIM_RELOAD)) { + if (data->soc == SOC_ARCH_EXYNOS3250 || + data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS5250) { if (data->soc == SOC_ARCH_EXYNOS3250) { ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; @@ -626,6 +628,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) pdata->type == SOC_ARCH_EXYNOS4412 || pdata->type == SOC_ARCH_EXYNOS5250 || pdata->type == SOC_ARCH_EXYNOS5260 || + pdata->type == SOC_ARCH_EXYNOS5420 || pdata->type == SOC_ARCH_EXYNOS5420_TRIMINFO || pdata->type == SOC_ARCH_EXYNOS5440) data->soc = pdata->type; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index d3d9205..adecc7f 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -40,6 +40,7 @@ enum soc_type { SOC_ARCH_EXYNOS4412, SOC_ARCH_EXYNOS5250, SOC_ARCH_EXYNOS5260, + SOC_ARCH_EXYNOS5420, SOC_ARCH_EXYNOS5420_TRIMINFO, SOC_ARCH_EXYNOS5440, }; @@ -50,8 +51,6 @@ enum soc_type { * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_TRIM_RELOAD - This features shows that trimming can - * be reloaded. * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can * be registered for falling trips also. * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation @@ -62,10 +61,9 @@ enum soc_type { */ #define TMU_SUPPORT_EMULATION BIT(0) #define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_TRIM_RELOAD BIT(2) -#define TMU_SUPPORT_FALLING_TRIP BIT(3) -#define TMU_SUPPORT_EMUL_TIME BIT(4) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(5) +#define TMU_SUPPORT_FALLING_TRIP BIT(2) +#define TMU_SUPPORT_EMUL_TIME BIT(3) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(4) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index c3271200..1ed8bdc 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -131,8 +131,8 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { }, \ .freq_tab_count = 2, \ .registers = &exynos3250_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ + TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -201,8 +201,8 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { }, \ .freq_tab_count = 2, \ .registers = &exynos4412_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ + TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -359,7 +359,7 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5250, \ + .type = SOC_ARCH_EXYNOS5420, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_EMUL_TIME) -- cgit v0.10.2 From 8328a4b1d67fa6a4e0c51c27ddb7cb61b562f33e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:11 +0100 Subject: thermal: exynos: add sanitize_temp_error() helper Factor out code for initializing data->temp_error[1,2] values from exynos_tmu_initialize() into sanitize_temp_error(). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index e4d75a1..b0c0715 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -139,6 +139,25 @@ static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data) writel(val_irq, data->base + reg->tmu_intclear); } +static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + + data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; + data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & + EXYNOS_TMU_TEMP_MASK); + + if (!data->temp_error1 || + (pdata->min_efuse_value > data->temp_error1) || + (data->temp_error1 > pdata->max_efuse_value)) + data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; + + if (!data->temp_error2) + data->temp_error2 = + (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & + EXYNOS_TMU_TEMP_MASK; +} + static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); @@ -200,19 +219,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) else trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); } - data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; - data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & - EXYNOS_TMU_TEMP_MASK); - - if (!data->temp_error1 || - (pdata->min_efuse_value > data->temp_error1) || - (data->temp_error1 > pdata->max_efuse_value)) - data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; - - if (!data->temp_error2) - data->temp_error2 = - (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & - EXYNOS_TMU_TEMP_MASK; + sanitize_temp_error(data, trim_info); rising_threshold = readl(data->base + reg->threshold_th0); -- cgit v0.10.2 From fe87789cd437378e7cf72c43b753703b2a835fc3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:12 +0100 Subject: thermal: exynos: add get_th_reg() helper Factor out code for preparing threshold register value from exynos_tmu_initialize() into get_th_reg(). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index b0c0715..6e82fdd 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -158,6 +158,25 @@ static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) EXYNOS_TMU_TEMP_MASK; } +static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + int i; + + for (i = 0; i < pdata->non_hw_trigger_levels; i++) { + u8 temp = pdata->trigger_levels[i]; + + if (falling) + temp -= pdata->threshold_falling; + else + threshold &= ~(0xff << 8 * i); + + threshold |= temp_to_code(data, temp) << 8 * i; + } + + return threshold; +} + static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); @@ -221,8 +240,6 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } sanitize_temp_error(data, trim_info); - rising_threshold = readl(data->base + reg->threshold_th0); - if (data->soc == SOC_ARCH_EXYNOS4210) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold); @@ -235,18 +252,10 @@ static int exynos_tmu_initialize(struct platform_device *pdev) exynos_tmu_clear_irqs(data); } else { /* Write temperature code for rising and falling threshold */ - for (i = 0; i < pdata->non_hw_trigger_levels; i++) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i]); - rising_threshold &= ~(0xff << 8 * i); - rising_threshold |= threshold_code << 8 * i; - if (data->soc != SOC_ARCH_EXYNOS5440) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i] - - pdata->threshold_falling); - falling_threshold |= threshold_code << 8 * i; - } - } + rising_threshold = readl(data->base + reg->threshold_th0); + rising_threshold = get_th_reg(data, rising_threshold, false); + if (data->soc != SOC_ARCH_EXYNOS5440) + falling_threshold = get_th_reg(data, 0, true); writel(rising_threshold, data->base + reg->threshold_th0); -- cgit v0.10.2 From 72d1100b736d2ff597c5aa73bbef12050c686ee4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:13 +0100 Subject: thermal: exynos: add ->tmu_initialize method Add ->tmu_initialize method to struct exynos_tmu_data and use it in exynos_tmu_initialize(). Then add ->tmu_initialize implementations for Exynos4210, Exynos4412+ and Exynos5440. Finally remove no longer needed reg->threshold_th[0,1], reg->intclr_[fall,rise]_shift and reg->intclr_[rise,fall]_mask abstractions. There are more improvements available in the future on top of this patch like merging HW_TRIP level setting with setting of other levels for Exynos4412+ or adding separate method for clearing IRQs using INTCLEAR register (for Exynos5420, Exynos5260 and Exynos4412+). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6e82fdd..736ef78 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -52,6 +52,7 @@ * @temp_error2: fused value of the second point trim. * @regulator: pointer to the TMU regulator structure. * @reg_conf: pointer to structure to register with core thermal. + * @tmu_initialize: SoC specific TMU initialization method */ struct exynos_tmu_data { int id; @@ -66,6 +67,7 @@ struct exynos_tmu_data { u8 temp_error1, temp_error2; struct regulator *regulator; struct thermal_sensor_conf *reg_conf; + int (*tmu_initialize)(struct platform_device *pdev); }; /* @@ -180,118 +182,13 @@ static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling) static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int status, trim_info = 0, con, ctrl; - unsigned int rising_threshold = 0, falling_threshold = 0; - int ret = 0, threshold_code, i; + int ret; mutex_lock(&data->lock); clk_enable(data->clk); if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); - - if (data->soc != SOC_ARCH_EXYNOS5440) { - status = readb(data->base + EXYNOS_TMU_REG_STATUS); - if (!status) { - ret = -EBUSY; - goto out; - } - } - - if (data->soc == SOC_ARCH_EXYNOS3250 || - data->soc == SOC_ARCH_EXYNOS4412 || - data->soc == SOC_ARCH_EXYNOS5250) { - if (data->soc == SOC_ARCH_EXYNOS3250) { - ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); - ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; - writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); - } - ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); - ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; - writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); - } - - /* Save trimming info in order to perform calibration */ - if (data->soc == SOC_ARCH_EXYNOS5440) { - /* - * For exynos5440 soc triminfo value is swapped between TMU0 and - * TMU2, so the below logic is needed. - */ - switch (data->id) { - case 0: - trim_info = readl(data->base + - EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); - break; - case 1: - trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); - break; - case 2: - trim_info = readl(data->base - - EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); - } - } else { - /* On exynos5420 the triminfo register is in the shared space */ - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) - trim_info = readl(data->base_second + - EXYNOS_TMU_REG_TRIMINFO); - else - trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); - } - sanitize_temp_error(data, trim_info); - - if (data->soc == SOC_ARCH_EXYNOS4210) { - /* Write temperature code for threshold */ - threshold_code = temp_to_code(data, pdata->threshold); - writeb(threshold_code, - data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); - for (i = 0; i < pdata->non_hw_trigger_levels; i++) - writeb(pdata->trigger_levels[i], data->base + - reg->threshold_th0 + i * sizeof(reg->threshold_th0)); - - exynos_tmu_clear_irqs(data); - } else { - /* Write temperature code for rising and falling threshold */ - rising_threshold = readl(data->base + reg->threshold_th0); - rising_threshold = get_th_reg(data, rising_threshold, false); - if (data->soc != SOC_ARCH_EXYNOS5440) - falling_threshold = get_th_reg(data, 0, true); - - writel(rising_threshold, - data->base + reg->threshold_th0); - writel(falling_threshold, - data->base + reg->threshold_th1); - - exynos_tmu_clear_irqs(data); - - /* if last threshold limit is also present */ - i = pdata->max_trigger_level - 1; - if (pdata->trigger_levels[i] && - (pdata->trigger_type[i] == HW_TRIP)) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i]); - if (data->soc != SOC_ARCH_EXYNOS5440) { - /* 1-4 level to be assigned in th0 reg */ - rising_threshold &= ~(0xff << 8 * i); - rising_threshold |= threshold_code << 8 * i; - writel(rising_threshold, - data->base + EXYNOS_THD_TEMP_RISE); - } else { - /* 5th level to be assigned in th2 reg */ - rising_threshold = - threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; - writel(rising_threshold, - data->base + EXYNOS5440_TMU_S0_7_TH2); - } - con = readl(data->base + reg->tmu_ctrl); - con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); - writel(con, data->base + reg->tmu_ctrl); - } - } - /*Clear the PMIN in the common TMU register*/ - if (data->soc == SOC_ARCH_EXYNOS5440 && !data->id) - writel(0, data->base_second + EXYNOS5440_TMU_PMIN); -out: + ret = data->tmu_initialize(pdev); clk_disable(data->clk); mutex_unlock(&data->lock); if (!IS_ERR(data->clk_sec)) @@ -347,6 +244,143 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) mutex_unlock(&data->lock); } +static int exynos4210_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int status; + int ret = 0, threshold_code, i; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } + + sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); + + /* Write temperature code for threshold */ + threshold_code = temp_to_code(data, pdata->threshold); + writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); + + for (i = 0; i < pdata->non_hw_trigger_levels; i++) + writeb(pdata->trigger_levels[i], data->base + + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); + + exynos_tmu_clear_irqs(data); +out: + return ret; +} + +static int exynos4412_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int status, trim_info, con, ctrl, rising_threshold; + int ret = 0, threshold_code, i; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } + + if (data->soc == SOC_ARCH_EXYNOS3250 || + data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS5250) { + if (data->soc == SOC_ARCH_EXYNOS3250) { + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); + } + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); + } + + /* On exynos5420 the triminfo register is in the shared space */ + if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) + trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); + else + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); + + sanitize_temp_error(data, trim_info); + + /* Write temperature code for rising and falling threshold */ + rising_threshold = readl(data->base + EXYNOS_THD_TEMP_RISE); + rising_threshold = get_th_reg(data, rising_threshold, false); + writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); + writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); + + exynos_tmu_clear_irqs(data); + + /* if last threshold limit is also present */ + i = pdata->max_trigger_level - 1; + if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) { + threshold_code = temp_to_code(data, pdata->trigger_levels[i]); + /* 1-4 level to be assigned in th0 reg */ + rising_threshold &= ~(0xff << 8 * i); + rising_threshold |= threshold_code << 8 * i; + writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); + con = readl(data->base + EXYNOS_TMU_REG_CONTROL); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); + } +out: + return ret; +} + +static int exynos5440_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int trim_info = 0, con, rising_threshold; + int ret = 0, threshold_code, i; + + /* + * For exynos5440 soc triminfo value is swapped between TMU0 and + * TMU2, so the below logic is needed. + */ + switch (data->id) { + case 0: + trim_info = readl(data->base + EXYNOS5440_EFUSE_SWAP_OFFSET + + EXYNOS5440_TMU_S0_7_TRIM); + break; + case 1: + trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); + break; + case 2: + trim_info = readl(data->base - EXYNOS5440_EFUSE_SWAP_OFFSET + + EXYNOS5440_TMU_S0_7_TRIM); + } + sanitize_temp_error(data, trim_info); + + /* Write temperature code for rising and falling threshold */ + rising_threshold = readl(data->base + EXYNOS5440_TMU_S0_7_TH0); + rising_threshold = get_th_reg(data, rising_threshold, false); + writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); + writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); + + exynos_tmu_clear_irqs(data); + + /* if last threshold limit is also present */ + i = pdata->max_trigger_level - 1; + if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) { + threshold_code = temp_to_code(data, pdata->trigger_levels[i]); + /* 5th level to be assigned in th2 reg */ + rising_threshold = + threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; + writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH2); + con = readl(data->base + EXYNOS5440_TMU_S0_7_CTRL); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); + writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); + } + /* Clear the PMIN in the common TMU register */ + if (!data->id) + writel(0, data->base_second + EXYNOS5440_TMU_PMIN); + return ret; +} + static int exynos_tmu_read(struct exynos_tmu_data *data) { struct exynos_tmu_platform_data *pdata = data->pdata; @@ -639,16 +673,24 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk_sec; } - if (pdata->type == SOC_ARCH_EXYNOS3250 || - pdata->type == SOC_ARCH_EXYNOS4210 || - pdata->type == SOC_ARCH_EXYNOS4412 || - pdata->type == SOC_ARCH_EXYNOS5250 || - pdata->type == SOC_ARCH_EXYNOS5260 || - pdata->type == SOC_ARCH_EXYNOS5420 || - pdata->type == SOC_ARCH_EXYNOS5420_TRIMINFO || - pdata->type == SOC_ARCH_EXYNOS5440) - data->soc = pdata->type; - else { + data->soc = pdata->type; + + switch (data->soc) { + case SOC_ARCH_EXYNOS4210: + data->tmu_initialize = exynos4210_tmu_initialize; + break; + case SOC_ARCH_EXYNOS3250: + case SOC_ARCH_EXYNOS4412: + case SOC_ARCH_EXYNOS5250: + case SOC_ARCH_EXYNOS5260: + case SOC_ARCH_EXYNOS5420: + case SOC_ARCH_EXYNOS5420_TRIMINFO: + data->tmu_initialize = exynos4412_tmu_initialize; + break; + case SOC_ARCH_EXYNOS5440: + data->tmu_initialize = exynos5440_tmu_initialize; + break; + default: ret = -EINVAL; dev_err(&pdev->dev, "Platform not supported\n"); goto err_clk; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index adecc7f..f186f4f 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -73,8 +73,6 @@ enum soc_type { * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. * @tmu_cur_temp: register containing the current temperature of the TMU. - * @threshold_th0: Register containing first set of rising levels. - * @threshold_th1: Register containing second set of rising levels. * @tmu_inten: register containing the different threshold interrupt enable bits. * @inten_rise0_shift: shift bits of rising 0 interrupt bits. @@ -91,9 +89,6 @@ struct exynos_tmu_registers { u32 tmu_cur_temp; - u32 threshold_th0; - u32 threshold_th1; - u32 tmu_inten; u32 inten_rise0_shift; u32 inten_rise1_shift; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 1ed8bdc..db3b3bc 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -28,7 +28,6 @@ static const struct exynos_tmu_registers exynos4210_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -83,8 +82,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -152,8 +149,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -234,8 +229,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS5260_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -306,8 +299,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -385,8 +376,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, - .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, - .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, -- cgit v0.10.2 From d00671c3ae3f4bfdfbdd1413150ad1a3a135ad1e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:14 +0100 Subject: thermal: exynos: add get_con_reg() helper Factor out code for preparing TMU_CONTROL register value from exynos_tmu_control() into get_con_reg(). This is a preparation for introducing per-SoC type tmu_control method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 736ef78..f65e6d8 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -197,17 +197,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev) return ret; } -static void exynos_tmu_control(struct platform_device *pdev, bool on) +static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) { - struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int con, interrupt_en; - - mutex_lock(&data->lock); - clk_enable(data->clk); - - con = readl(data->base + reg->tmu_ctrl); if (pdata->test_mux) con |= (pdata->test_mux << EXYNOS4412_MUX_ADDR_SHIFT); @@ -223,6 +215,21 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT); } + return con; +} + +static void exynos_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + const struct exynos_tmu_registers *reg = pdata->registers; + unsigned int con, interrupt_en; + + mutex_lock(&data->lock); + clk_enable(data->clk); + + con = get_con_reg(data, readl(data->base + reg->tmu_ctrl)); + if (on) { con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); interrupt_en = -- cgit v0.10.2 From 37f9034f99c3c1ba9087357fbbc2b79fc1a30e72 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:15 +0100 Subject: thermal: exynos: add ->tmu_control method Add ->tmu_control method to struct exynos_tmu_data and use it in exynos_tmu_control(). Then add ->tmu_control implementations for Exynos4210+ and Exynos5440. Finally remove no longer needed reg->tmu_[ctrl,inten], reg->inten_rise[0,1,2,3]_shift and reg->inten_fall0_shift abstractions. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index f65e6d8..938e8e6 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -53,6 +53,7 @@ * @regulator: pointer to the TMU regulator structure. * @reg_conf: pointer to structure to register with core thermal. * @tmu_initialize: SoC specific TMU initialization method + * @tmu_control: SoC specific TMU control method */ struct exynos_tmu_data { int id; @@ -68,6 +69,7 @@ struct exynos_tmu_data { struct regulator *regulator; struct thermal_sensor_conf *reg_conf; int (*tmu_initialize)(struct platform_device *pdev); + void (*tmu_control)(struct platform_device *pdev, bool on); }; /* @@ -221,32 +223,10 @@ static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) static void exynos_tmu_control(struct platform_device *pdev, bool on) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int con, interrupt_en; mutex_lock(&data->lock); clk_enable(data->clk); - - con = get_con_reg(data, readl(data->base + reg->tmu_ctrl)); - - if (on) { - con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); - interrupt_en = - pdata->trigger_enable[3] << reg->inten_rise3_shift | - pdata->trigger_enable[2] << reg->inten_rise2_shift | - pdata->trigger_enable[1] << reg->inten_rise1_shift | - pdata->trigger_enable[0] << reg->inten_rise0_shift; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) - interrupt_en |= - interrupt_en << reg->inten_fall0_shift; - } else { - con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); - interrupt_en = 0; /* Disable all interrupts */ - } - writel(interrupt_en, data->base + reg->tmu_inten); - writel(con, data->base + reg->tmu_ctrl); - + data->tmu_control(pdev, on); clk_disable(data->clk); mutex_unlock(&data->lock); } @@ -388,6 +368,58 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) return ret; } +static void exynos4210_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int con, interrupt_en; + + con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); + + if (on) { + con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = + pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT | + pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT | + pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT | + pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT; + if (TMU_SUPPORTS(pdata, FALLING_TRIP)) + interrupt_en |= + interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; + } else { + con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = 0; /* Disable all interrupts */ + } + writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); +} + +static void exynos5440_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int con, interrupt_en; + + con = get_con_reg(data, readl(data->base + EXYNOS5440_TMU_S0_7_CTRL)); + + if (on) { + con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = + pdata->trigger_enable[3] << EXYNOS5440_TMU_INTEN_RISE3_SHIFT | + pdata->trigger_enable[2] << EXYNOS5440_TMU_INTEN_RISE2_SHIFT | + pdata->trigger_enable[1] << EXYNOS5440_TMU_INTEN_RISE1_SHIFT | + pdata->trigger_enable[0] << EXYNOS5440_TMU_INTEN_RISE0_SHIFT; + if (TMU_SUPPORTS(pdata, FALLING_TRIP)) + interrupt_en |= + interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; + } else { + con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = 0; /* Disable all interrupts */ + } + writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN); + writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); +} + static int exynos_tmu_read(struct exynos_tmu_data *data) { struct exynos_tmu_platform_data *pdata = data->pdata; @@ -685,6 +717,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) switch (data->soc) { case SOC_ARCH_EXYNOS4210: data->tmu_initialize = exynos4210_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; break; case SOC_ARCH_EXYNOS3250: case SOC_ARCH_EXYNOS4412: @@ -693,9 +726,11 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS5420: case SOC_ARCH_EXYNOS5420_TRIMINFO: data->tmu_initialize = exynos4412_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; + data->tmu_control = exynos5440_tmu_control; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index f186f4f..7496b54 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -68,38 +68,17 @@ enum soc_type { #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) /** - * struct exynos_tmu_register - register descriptors to access registers and - * bitfields. The register validity, offsets and bitfield values may vary - * slightly across different exynos SOC's. - * @tmu_ctrl: TMU main controller register. + * struct exynos_tmu_register - register descriptors to access registers. + * The register validity may vary slightly across different exynos SOC's. * @tmu_cur_temp: register containing the current temperature of the TMU. - * @tmu_inten: register containing the different threshold interrupt - enable bits. - * @inten_rise0_shift: shift bits of rising 0 interrupt bits. - * @inten_rise1_shift: shift bits of rising 1 interrupt bits. - * @inten_rise2_shift: shift bits of rising 2 interrupt bits. - * @inten_rise3_shift: shift bits of rising 3 interrupt bits. - * @inten_fall0_shift: shift bits of falling 0 interrupt bits. * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. */ struct exynos_tmu_registers { - u32 tmu_ctrl; - u32 tmu_cur_temp; - - u32 tmu_inten; - u32 inten_rise0_shift; - u32 inten_rise1_shift; - u32 inten_rise2_shift; - u32 inten_rise3_shift; - u32 inten_fall0_shift; - u32 tmu_intstat; - u32 tmu_intclear; - u32 emul_con; }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index db3b3bc..2bfd469 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -26,13 +26,7 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, }; @@ -80,13 +74,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -147,14 +135,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -227,14 +208,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS5260_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, @@ -297,15 +271,7 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - /* INTEN_RISE3 Not availble in exynos5420 */ - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -374,14 +340,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, - .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, - .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS5440_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS5440_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, -- cgit v0.10.2 From b79985ca74b25926cb2d88b60805092c5456bf43 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:16 +0100 Subject: thermal: exynos: add ->tmu_read method Add ->tmu_read method to struct exynos_tmu_data and use it in exynos_tmu_control(). Then add ->tmu_read implementations for Exynos4210, Exynos4412+ and Exynos5440. Finally remove no longer needed reg->tmu_cur_temp abstractions. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 938e8e6..b209593 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -54,6 +54,7 @@ * @reg_conf: pointer to structure to register with core thermal. * @tmu_initialize: SoC specific TMU initialization method * @tmu_control: SoC specific TMU control method + * @tmu_read: SoC specific TMU temperature read method */ struct exynos_tmu_data { int id; @@ -70,6 +71,7 @@ struct exynos_tmu_data { struct thermal_sensor_conf *reg_conf; int (*tmu_initialize)(struct platform_device *pdev); void (*tmu_control)(struct platform_device *pdev, bool on); + int (*tmu_read)(struct exynos_tmu_data *data); }; /* @@ -422,29 +424,17 @@ static void exynos5440_tmu_control(struct platform_device *pdev, bool on) static int exynos_tmu_read(struct exynos_tmu_data *data) { - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - u8 temp_code; - int temp; + int ret; mutex_lock(&data->lock); clk_enable(data->clk); - - temp_code = readb(data->base + reg->tmu_cur_temp); - - if (data->soc == SOC_ARCH_EXYNOS4210) - /* temp_code should range between 75 and 175 */ - if (temp_code < 75 || temp_code > 175) { - temp = -ENODATA; - goto out; - } - - temp = code_to_temp(data, temp_code); -out: + ret = data->tmu_read(data); + if (ret >= 0) + ret = code_to_temp(data, ret); clk_disable(data->clk); mutex_unlock(&data->lock); - return temp; + return ret; } #ifdef CONFIG_THERMAL_EMULATION @@ -494,6 +484,24 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { return -EINVAL; } #endif/*CONFIG_THERMAL_EMULATION*/ +static int exynos4210_tmu_read(struct exynos_tmu_data *data) +{ + int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); + + /* "temp_code" should range between 75 and 175 */ + return (ret < 75 || ret > 175) ? -ENODATA : ret; +} + +static int exynos4412_tmu_read(struct exynos_tmu_data *data) +{ + return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); +} + +static int exynos5440_tmu_read(struct exynos_tmu_data *data) +{ + return readb(data->base + EXYNOS5440_TMU_S0_7_TEMP); +} + static void exynos_tmu_work(struct work_struct *work) { struct exynos_tmu_data *data = container_of(work, @@ -718,6 +726,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS4210: data->tmu_initialize = exynos4210_tmu_initialize; data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4210_tmu_read; break; case SOC_ARCH_EXYNOS3250: case SOC_ARCH_EXYNOS4412: @@ -727,10 +736,12 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS5420_TRIMINFO: data->tmu_initialize = exynos4412_tmu_initialize; data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4412_tmu_read; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; + data->tmu_read = exynos5440_tmu_read; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 7496b54..9460e6e 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -70,13 +70,11 @@ enum soc_type { /** * struct exynos_tmu_register - register descriptors to access registers. * The register validity may vary slightly across different exynos SOC's. - * @tmu_cur_temp: register containing the current temperature of the TMU. * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. */ struct exynos_tmu_registers { - u32 tmu_cur_temp; u32 tmu_intstat; u32 tmu_intclear; u32 emul_con; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 2bfd469..769b89d 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -26,7 +26,6 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, }; @@ -74,7 +73,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -135,7 +133,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -208,7 +205,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, @@ -271,7 +267,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -340,7 +335,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, -- cgit v0.10.2 From 154013ea5fc9de969f6808b4bbb7e986e396f1f1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:17 +0100 Subject: thermal: exynos: add get_emul_con_reg() helper Factor out code for preparing EMUL_CON register value from exynos_tmu_set_emulation() into get_emul_con_reg(). This is a preparation for introducing per-SoC type tmu_set_emulation method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index b209593..1b622ce 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -438,6 +438,28 @@ static int exynos_tmu_read(struct exynos_tmu_data *data) } #ifdef CONFIG_THERMAL_EMULATION +static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, + unsigned long temp) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + + if (temp) { + temp /= MCELSIUS; + + if (TMU_SUPPORTS(pdata, EMUL_TIME)) { + val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); + val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); + } + val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); + val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | + EXYNOS_EMUL_ENABLE; + } else { + val &= ~EXYNOS_EMUL_ENABLE; + } + + return val; +} + static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { struct exynos_tmu_data *data = drv_data; @@ -456,21 +478,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) clk_enable(data->clk); val = readl(data->base + reg->emul_con); - - if (temp) { - temp /= MCELSIUS; - - if (TMU_SUPPORTS(pdata, EMUL_TIME)) { - val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); - val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); - } - val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); - val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | - EXYNOS_EMUL_ENABLE; - } else { - val &= ~EXYNOS_EMUL_ENABLE; - } - + val = get_emul_con_reg(data, val, temp); writel(val, data->base + reg->emul_con); clk_disable(data->clk); -- cgit v0.10.2 From 285d994a51e45ca59a9cde34a3a0ea316e263617 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:18 +0100 Subject: thermal: exynos: add ->tmu_set_emulation method Add ->tmu_set_emulation method to struct exynos_tmu_data and use it in exynos_tmu_set_emulation(). Then add ->tmu_set_emulation implementations for Exynos4412+ and Exynos5440. Finally remove no longer needed reg->emul_con abstraction. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1b622ce..01aa548 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -55,6 +55,7 @@ * @tmu_initialize: SoC specific TMU initialization method * @tmu_control: SoC specific TMU control method * @tmu_read: SoC specific TMU temperature read method + * @tmu_set_emulation: SoC specific TMU emulation setting method */ struct exynos_tmu_data { int id; @@ -72,6 +73,8 @@ struct exynos_tmu_data { int (*tmu_initialize)(struct platform_device *pdev); void (*tmu_control)(struct platform_device *pdev, bool on); int (*tmu_read)(struct exynos_tmu_data *data); + void (*tmu_set_emulation)(struct exynos_tmu_data *data, + unsigned long temp); }; /* @@ -460,12 +463,36 @@ static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, return val; } +static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, + unsigned long temp) +{ + unsigned int val; + u32 emul_con; + + if (data->soc == SOC_ARCH_EXYNOS5260) + emul_con = EXYNOS5260_EMUL_CON; + else + emul_con = EXYNOS_EMUL_CON; + + val = readl(data->base + emul_con); + val = get_emul_con_reg(data, val, temp); + writel(val, data->base + emul_con); +} + +static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, + unsigned long temp) +{ + unsigned int val; + + val = readl(data->base + EXYNOS5440_TMU_S0_7_DEBUG); + val = get_emul_con_reg(data, val, temp); + writel(val, data->base + EXYNOS5440_TMU_S0_7_DEBUG); +} + static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { struct exynos_tmu_data *data = drv_data; struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int val; int ret = -EINVAL; if (!TMU_SUPPORTS(pdata, EMULATION)) @@ -476,11 +503,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) mutex_lock(&data->lock); clk_enable(data->clk); - - val = readl(data->base + reg->emul_con); - val = get_emul_con_reg(data, val, temp); - writel(val, data->base + reg->emul_con); - + data->tmu_set_emulation(data, temp); clk_disable(data->clk); mutex_unlock(&data->lock); return 0; @@ -488,6 +511,8 @@ out: return ret; } #else +#define exynos4412_tmu_set_emulation NULL +#define exynos5440_tmu_set_emulation NULL static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { return -EINVAL; } #endif/*CONFIG_THERMAL_EMULATION*/ @@ -745,11 +770,13 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tmu_initialize = exynos4412_tmu_initialize; data->tmu_control = exynos4210_tmu_control; data->tmu_read = exynos4412_tmu_read; + data->tmu_set_emulation = exynos4412_tmu_set_emulation; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; data->tmu_read = exynos5440_tmu_read; + data->tmu_set_emulation = exynos5440_tmu_set_emulation; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 9460e6e..785eccf 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -72,12 +72,10 @@ enum soc_type { * The register validity may vary slightly across different exynos SOC's. * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. - * @emul_con: TMU emulation controller register. */ struct exynos_tmu_registers { u32 tmu_intstat; u32 tmu_intclear; - u32 emul_con; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 769b89d..d0bb4b3 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -75,7 +75,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, }; #define EXYNOS3250_TMU_DATA \ @@ -135,7 +134,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, }; #define EXYNOS4412_TMU_DATA \ @@ -207,7 +205,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, - .emul_con = EXYNOS5260_EMUL_CON, }; #define __EXYNOS5260_TMU_DATA \ @@ -269,7 +266,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, }; #define __EXYNOS5420_TMU_DATA \ @@ -337,7 +333,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, - .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, }; #define EXYNOS5440_TMU_DATA \ -- cgit v0.10.2 From a7331f72d3eb2bf6a15405459f7c514607402ca6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:19 +0100 Subject: thermal: exynos: add ->tmu_clear_irqs method Add ->tmu_clear_irqs method to struct exynos_tmu_data and use it instead exynos_tmu_clear_irqs(). Then add ->tmu_clear_irqs implementations for Exynos4210+ and Exynos5440. Finally remove no longer needed reg->tmu_int[stat,clear] abstractions and struct exynos_tmu_registers instances. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 01aa548..1b3c2f4 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -56,6 +56,7 @@ * @tmu_control: SoC specific TMU control method * @tmu_read: SoC specific TMU temperature read method * @tmu_set_emulation: SoC specific TMU emulation setting method + * @tmu_clear_irqs: SoC specific TMU interrupts clearing method */ struct exynos_tmu_data { int id; @@ -75,6 +76,7 @@ struct exynos_tmu_data { int (*tmu_read)(struct exynos_tmu_data *data); void (*tmu_set_emulation)(struct exynos_tmu_data *data, unsigned long temp); + void (*tmu_clear_irqs)(struct exynos_tmu_data *data); }; /* @@ -131,23 +133,6 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code) return temp; } -static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data) -{ - const struct exynos_tmu_registers *reg = data->pdata->registers; - unsigned int val_irq; - - val_irq = readl(data->base + reg->tmu_intstat); - /* - * Clear the interrupts. Please note that the documentation for - * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly - * states that INTCLEAR register has a different placing of bits - * responsible for FALL IRQs than INTSTAT register. Exynos5420 - * and Exynos5440 documentation is correct (Exynos4210 doesn't - * support FALL IRQs at all). - */ - writel(val_irq, data->base + reg->tmu_intclear); -} - static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) { struct exynos_tmu_platform_data *pdata = data->pdata; @@ -259,7 +244,7 @@ static int exynos4210_tmu_initialize(struct platform_device *pdev) writeb(pdata->trigger_levels[i], data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); out: return ret; } @@ -304,7 +289,7 @@ static int exynos4412_tmu_initialize(struct platform_device *pdev) writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); /* if last threshold limit is also present */ i = pdata->max_trigger_level - 1; @@ -353,7 +338,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); /* if last threshold limit is also present */ i = pdata->max_trigger_level - 1; @@ -557,7 +542,7 @@ static void exynos_tmu_work(struct work_struct *work) clk_enable(data->clk); /* TODO: take action based on particular interrupt */ - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); clk_disable(data->clk); mutex_unlock(&data->lock); @@ -565,6 +550,40 @@ out: enable_irq(data->irq); } +static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) +{ + unsigned int val_irq; + u32 tmu_intstat, tmu_intclear; + + if (data->soc == SOC_ARCH_EXYNOS5260) { + tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT; + tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR; + } else { + tmu_intstat = EXYNOS_TMU_REG_INTSTAT; + tmu_intclear = EXYNOS_TMU_REG_INTCLEAR; + } + + val_irq = readl(data->base + tmu_intstat); + /* + * Clear the interrupts. Please note that the documentation for + * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly + * states that INTCLEAR register has a different placing of bits + * responsible for FALL IRQs than INTSTAT register. Exynos5420 + * and Exynos5440 documentation is correct (Exynos4210 doesn't + * support FALL IRQs at all). + */ + writel(val_irq, data->base + tmu_intclear); +} + +static void exynos5440_tmu_clear_irqs(struct exynos_tmu_data *data) +{ + unsigned int val_irq; + + val_irq = readl(data->base + EXYNOS5440_TMU_S0_7_IRQ); + /* clear the interrupts */ + writel(val_irq, data->base + EXYNOS5440_TMU_S0_7_IRQ); +} + static irqreturn_t exynos_tmu_irq(int irq, void *id) { struct exynos_tmu_data *data = id; @@ -760,6 +779,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tmu_initialize = exynos4210_tmu_initialize; data->tmu_control = exynos4210_tmu_control; data->tmu_read = exynos4210_tmu_read; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; break; case SOC_ARCH_EXYNOS3250: case SOC_ARCH_EXYNOS4412: @@ -771,12 +791,14 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tmu_control = exynos4210_tmu_control; data->tmu_read = exynos4412_tmu_read; data->tmu_set_emulation = exynos4412_tmu_set_emulation; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; data->tmu_read = exynos5440_tmu_read; data->tmu_set_emulation = exynos5440_tmu_set_emulation; + data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 785eccf..c4c0aa5 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -68,17 +68,6 @@ enum soc_type { #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) /** - * struct exynos_tmu_register - register descriptors to access registers. - * The register validity may vary slightly across different exynos SOC's. - * @tmu_intstat: Register containing the interrupt status values. - * @tmu_intclear: Register for clearing the raised interrupt status. - */ -struct exynos_tmu_registers { - u32 tmu_intstat; - u32 tmu_intclear; -}; - -/** * struct exynos_tmu_platform_data * @threshold: basic temperature for generating interrupt * 25 <= threshold <= 125 [unit: degree Celsius] @@ -127,8 +116,6 @@ struct exynos_tmu_registers { * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may * applicable to only some of the trigger levels. - * @registers: Pointer to structure containing all the TMU controller registers - * and bitfields shifts and masks. * @features: a bitfield value indicating the features supported in SOC like * emulation, multi instance etc * @@ -158,7 +145,6 @@ struct exynos_tmu_platform_data { enum soc_type type; struct freq_clip_table freq_tab[4]; unsigned int freq_tab_count; - const struct exynos_tmu_registers *registers; unsigned int features; }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d0bb4b3..d35ec15 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -25,11 +25,6 @@ #include "exynos_tmu_data.h" #if defined(CONFIG_CPU_EXYNOS4210) -static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { { @@ -64,7 +59,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { }, .freq_tab_count = 2, .type = SOC_ARCH_EXYNOS4210, - .registers = &exynos4210_tmu_registers, }, }, .tmu_count = 1, @@ -72,11 +66,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS3250) -static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - #define EXYNOS3250_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -112,7 +101,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos3250_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_EMUL_TIME) #endif @@ -131,11 +119,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) -static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - #define EXYNOS4412_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -171,7 +154,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos4412_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_EMUL_TIME) #endif @@ -202,11 +184,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS5260) -static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, -}; - #define __EXYNOS5260_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -242,7 +219,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .temp_level = 103, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos5260_tmu_registers, \ #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ @@ -263,11 +239,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS5420) -static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - #define __EXYNOS5420_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -303,7 +274,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .temp_level = 103, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos5420_tmu_registers, \ #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ @@ -330,11 +300,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS5440) -static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, - .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, -}; - #define EXYNOS5440_TMU_DATA \ .trigger_levels[0] = 100, \ .trigger_levels[4] = 105, \ @@ -354,7 +319,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .registers = &exynos5440_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), -- cgit v0.10.2 From e0761533a1d41e7486bddac75ee878e9814ec0e3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:20 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_FALLING_TRIP flag Replace TMU_SUPPORT_FALLING_TRIP flag check in exynos[4210,5440]_tmu_control() by an explicit check for a SoC type (all SoC types except Exynos4210 have TMU_SUPPORT_FALLING_TRIP flag set in their struct exynos_tmu_init_data instances). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1b3c2f4..6795ddc 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -373,7 +373,7 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on) pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT | pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT | pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) + if (data->soc != SOC_ARCH_EXYNOS4210) interrupt_en |= interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; } else { @@ -399,9 +399,7 @@ static void exynos5440_tmu_control(struct platform_device *pdev, bool on) pdata->trigger_enable[2] << EXYNOS5440_TMU_INTEN_RISE2_SHIFT | pdata->trigger_enable[1] << EXYNOS5440_TMU_INTEN_RISE1_SHIFT | pdata->trigger_enable[0] << EXYNOS5440_TMU_INTEN_RISE0_SHIFT; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) - interrupt_en |= - interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; + interrupt_en |= interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; } else { con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); interrupt_en = 0; /* Disable all interrupts */ diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index c4c0aa5..ed83d3d 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -51,8 +51,6 @@ enum soc_type { * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can - * be registered for falling trips also. * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation * sample time. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU @@ -61,9 +59,8 @@ enum soc_type { */ #define TMU_SUPPORT_EMULATION BIT(0) #define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_FALLING_TRIP BIT(2) -#define TMU_SUPPORT_EMUL_TIME BIT(3) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(4) +#define TMU_SUPPORT_EMUL_TIME BIT(2) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(3) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d35ec15..39b9651 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -101,8 +101,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -154,8 +153,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -223,8 +221,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5260, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -278,14 +275,13 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME | TMU_SUPPORT_ADDRESS_MULTIPLE) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME | \ + TMU_SUPPORT_ADDRESS_MULTIPLE) struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -319,8 +315,8 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_MULTI_INST | \ + TMU_SUPPORT_ADDRESS_MULTIPLE), struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- cgit v0.10.2 From d564b55a81e720430f50e301ff330b1c9ec3944c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:21 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_EMUL_TIME flag Replace TMU_SUPPORT_EMUL_TIME flag check in get_emul_con_reg() by an explicit check for a SoC type (all SoC types except Exynos4210 and Exynos5440 have TMU_SUPPORT_EMUL_TIME flag set in their struct exynos_tmu_init_data instances). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6795ddc..209221f 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -427,12 +427,10 @@ static int exynos_tmu_read(struct exynos_tmu_data *data) static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, unsigned long temp) { - struct exynos_tmu_platform_data *pdata = data->pdata; - if (temp) { temp /= MCELSIUS; - if (TMU_SUPPORTS(pdata, EMUL_TIME)) { + if (data->soc != SOC_ARCH_EXYNOS5440) { val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); } diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index ed83d3d..d90852a 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -51,16 +51,13 @@ enum soc_type { * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation - * sample time. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU * sensors shares some common registers. * TMU_SUPPORT - macro to compare the above features with the supplied. */ #define TMU_SUPPORT_EMULATION BIT(0) #define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_EMUL_TIME BIT(2) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(3) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(2) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 39b9651..82f1cba 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -101,7 +101,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -153,7 +153,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -221,7 +221,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5260, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -275,13 +275,12 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME | \ - TMU_SUPPORT_ADDRESS_MULTIPLE) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_ADDRESS_MULTIPLE) struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { -- cgit v0.10.2 From ef3f80fc7f79c32a1b015afcbffce2a2630011a4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:22 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_EMULATION flag Replace TMU_SUPPORT_EMULATION flag check in exynos_tmu_set_emulation() by an explicit check for a SoC type (all SoC types except Exynos4210 have TMU_SUPPORT_EMULATION flag set in their struct exynos_tmu_init_data instances). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 209221f..51d8cc7 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -476,7 +476,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) struct exynos_tmu_platform_data *pdata = data->pdata; int ret = -EINVAL; - if (!TMU_SUPPORTS(pdata, EMULATION)) + if (data->soc == SOC_ARCH_EXYNOS4210) goto out; if (temp && temp < MCELSIUS) diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index d90852a..5ad3f3f 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -47,17 +47,14 @@ enum soc_type { /** * EXYNOS TMU supported features. - * TMU_SUPPORT_EMULATION - This features is used to set user defined - * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU * sensors shares some common registers. * TMU_SUPPORT - macro to compare the above features with the supplied. */ -#define TMU_SUPPORT_EMULATION BIT(0) -#define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(2) +#define TMU_SUPPORT_MULTI_INST BIT(0) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(1) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 82f1cba..4dd8d1c 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -100,8 +100,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .freq_clip_max = 400 * 1000, \ .temp_level = 95, \ }, \ - .freq_tab_count = 2, \ - .features = TMU_SUPPORT_EMULATION + .freq_tab_count = 2 #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -152,8 +151,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .freq_clip_max = 400 * 1000, \ .temp_level = 95, \ }, \ - .freq_tab_count = 2, \ - .features = TMU_SUPPORT_EMULATION + .freq_tab_count = 2 #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -220,8 +218,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5260, \ - .features = TMU_SUPPORT_EMULATION + .type = SOC_ARCH_EXYNOS5260 struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -274,13 +271,12 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5420, \ - .features = TMU_SUPPORT_EMULATION + .type = SOC_ARCH_EXYNOS5420 #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_ADDRESS_MULTIPLE) + .features = TMU_SUPPORT_ADDRESS_MULTIPLE struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -314,8 +310,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_MULTI_INST | \ - TMU_SUPPORT_ADDRESS_MULTIPLE), + .features = (TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- cgit v0.10.2 From 56adb9efeb8115d2a3a807d84a0d037398588911 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:23 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_ADDRESS_MULTIPLE flag Replace TMU_SUPPORT_ADDRESS_MULTIPLE flag check in exynos_map_dt_data() by an explicit check for a SoC type (only Exynos5420 with TRIMINFO quirk and Exynos5440 have TMU_SUPPORT_ADDRESS_MULTIPLE flag set in their struct exynos_tmu_init_data instances). Please note that this requires moving SoC type assignment and verification from exynos_tmu_probe() to exynos_map_dt_data() so it happens earlier (which is a good thing in itself). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 51d8cc7..65eeecc 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -473,7 +473,6 @@ static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { struct exynos_tmu_data *data = drv_data; - struct exynos_tmu_platform_data *pdata = data->pdata; int ret = -EINVAL; if (data->soc == SOC_ARCH_EXYNOS4210) @@ -696,12 +695,47 @@ static int exynos_map_dt_data(struct platform_device *pdev) dev_err(&pdev->dev, "No platform init data supplied.\n"); return -ENODEV; } + data->pdata = pdata; + data->soc = pdata->type; + + switch (data->soc) { + case SOC_ARCH_EXYNOS4210: + data->tmu_initialize = exynos4210_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4210_tmu_read; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; + case SOC_ARCH_EXYNOS3250: + case SOC_ARCH_EXYNOS4412: + case SOC_ARCH_EXYNOS5250: + case SOC_ARCH_EXYNOS5260: + case SOC_ARCH_EXYNOS5420: + case SOC_ARCH_EXYNOS5420_TRIMINFO: + data->tmu_initialize = exynos4412_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4412_tmu_read; + data->tmu_set_emulation = exynos4412_tmu_set_emulation; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; + case SOC_ARCH_EXYNOS5440: + data->tmu_initialize = exynos5440_tmu_initialize; + data->tmu_control = exynos5440_tmu_control; + data->tmu_read = exynos5440_tmu_read; + data->tmu_set_emulation = exynos5440_tmu_set_emulation; + data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; + break; + default: + dev_err(&pdev->dev, "Platform not supported\n"); + return -EINVAL; + } + /* * Check if the TMU shares some registers and then try to map the * memory of common registers. */ - if (!TMU_SUPPORTS(pdata, ADDRESS_MULTIPLE)) + if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO && + data->soc != SOC_ARCH_EXYNOS5440) return 0; if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { @@ -768,40 +802,6 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk_sec; } - data->soc = pdata->type; - - switch (data->soc) { - case SOC_ARCH_EXYNOS4210: - data->tmu_initialize = exynos4210_tmu_initialize; - data->tmu_control = exynos4210_tmu_control; - data->tmu_read = exynos4210_tmu_read; - data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; - break; - case SOC_ARCH_EXYNOS3250: - case SOC_ARCH_EXYNOS4412: - case SOC_ARCH_EXYNOS5250: - case SOC_ARCH_EXYNOS5260: - case SOC_ARCH_EXYNOS5420: - case SOC_ARCH_EXYNOS5420_TRIMINFO: - data->tmu_initialize = exynos4412_tmu_initialize; - data->tmu_control = exynos4210_tmu_control; - data->tmu_read = exynos4412_tmu_read; - data->tmu_set_emulation = exynos4412_tmu_set_emulation; - data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; - break; - case SOC_ARCH_EXYNOS5440: - data->tmu_initialize = exynos5440_tmu_initialize; - data->tmu_control = exynos5440_tmu_control; - data->tmu_read = exynos5440_tmu_read; - data->tmu_set_emulation = exynos5440_tmu_set_emulation; - data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; - break; - default: - ret = -EINVAL; - dev_err(&pdev->dev, "Platform not supported\n"); - goto err_clk; - } - ret = exynos_tmu_initialize(pdev); if (ret) { dev_err(&pdev->dev, "Failed to initialize TMU\n"); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 5ad3f3f..54f018d 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -49,12 +49,9 @@ enum soc_type { * EXYNOS TMU supported features. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU - * sensors shares some common registers. * TMU_SUPPORT - macro to compare the above features with the supplied. */ #define TMU_SUPPORT_MULTI_INST BIT(0) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(1) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 4dd8d1c..13ac00b 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -275,8 +275,7 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = TMU_SUPPORT_ADDRESS_MULTIPLE + .type = SOC_ARCH_EXYNOS5420_TRIMINFO struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -310,7 +309,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .features = (TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), + .features = TMU_SUPPORT_MULTI_INST, struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- cgit v0.10.2 From 17be30cb7f4b4ba5f50946e2d638c1b9162ecfc7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:24 +0100 Subject: thermal: exynos: remove TMU_SUPPORT_MULTI_INST flag Remove unused TMU_SUPPORT_MULTI_INST flag, no longer needed TMU_SUPPORTS() macro and features field from struct exynos_tmu_platform_data. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 54f018d..2eb4cb9 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -46,16 +46,6 @@ enum soc_type { }; /** - * EXYNOS TMU supported features. - * TMU_SUPPORT_MULTI_INST - This features denotes that the soc - * has many instances of TMU. - * TMU_SUPPORT - macro to compare the above features with the supplied. - */ -#define TMU_SUPPORT_MULTI_INST BIT(0) - -#define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) - -/** * struct exynos_tmu_platform_data * @threshold: basic temperature for generating interrupt * 25 <= threshold <= 125 [unit: degree Celsius] @@ -104,8 +94,6 @@ enum soc_type { * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may * applicable to only some of the trigger levels. - * @features: a bitfield value indicating the features supported in SOC like - * emulation, multi instance etc * * This structure is required for configuration of exynos_tmu driver. */ @@ -133,7 +121,6 @@ struct exynos_tmu_platform_data { enum soc_type type; struct freq_clip_table freq_tab[4]; unsigned int freq_tab_count; - unsigned int features; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 13ac00b..d90b050 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -308,8 +308,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .first_point_trim = 25, \ .second_point_trim = 70, \ .default_temp_offset = 25, \ - .type = SOC_ARCH_EXYNOS5440, \ - .features = TMU_SUPPORT_MULTI_INST, + .type = SOC_ARCH_EXYNOS5440 struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- cgit v0.10.2 From 7575983c577c724425d11361acb1fc45834633f3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:25 +0100 Subject: thermal: exynos: remove test_mux pdata field Replace pdata->test_mux check in get_con_reg() by explicitly checking for SoC type. Also since the used pdata->test_mux value is always identical use it directly and remove pdata->test_mux completely. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 65eeecc..2fcb4cd 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -193,8 +193,9 @@ static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) { struct exynos_tmu_platform_data *pdata = data->pdata; - if (pdata->test_mux) - con |= (pdata->test_mux << EXYNOS4412_MUX_ADDR_SHIFT); + if (data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS3250) + con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT); con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 2eb4cb9..8de0f82 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -89,7 +89,6 @@ enum soc_type { * @first_point_trim: temp value of the first point trimming * @second_point_trim: temp value of the second point trimming * @default_temp_offset: default temperature offset in case of no trimming - * @test_mux; information if SoC supports test MUX * @cal_type: calibration type for temperature * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may @@ -115,7 +114,6 @@ struct exynos_tmu_platform_data { u8 first_point_trim; u8 second_point_trim; u8 default_temp_offset; - u8 test_mux; enum calibration_type cal_type; enum soc_type type; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d90b050..708c3e1 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -109,7 +109,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { { EXYNOS3250_TMU_DATA, .type = SOC_ARCH_EXYNOS3250, - .test_mux = EXYNOS4412_MUX_ADDR_VALUE, }, }, .tmu_count = 1, @@ -160,7 +159,6 @@ struct exynos_tmu_init_data const exynos4412_default_tmu_data = { { EXYNOS4412_TMU_DATA, .type = SOC_ARCH_EXYNOS4412, - .test_mux = EXYNOS4412_MUX_ADDR_VALUE, }, }, .tmu_count = 1, -- cgit v0.10.2 From 4c4680a16716ef77826eb11fe8d7c1e70e4eb78d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:26 +0100 Subject: thermal: exynos: remove SoC type ifdefs Maximum theoretical size saving (i.e. with only Exynos5410 SoC support enabled in kernel config so all SoC dependend Exynos thermal driver code was dropped) is 4096 bytes so there is no much sense in keeping these ifdefs (especially given that they are useless once the driver gets updated to use device tree). While at it remove needless 'void *' casts. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 2fcb4cd..6cc6b6e 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -593,35 +593,35 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id) static const struct of_device_id exynos_tmu_match[] = { { .compatible = "samsung,exynos3250-tmu", - .data = (void *)EXYNOS3250_TMU_DRV_DATA, + .data = &exynos3250_default_tmu_data, }, { .compatible = "samsung,exynos4210-tmu", - .data = (void *)EXYNOS4210_TMU_DRV_DATA, + .data = &exynos4210_default_tmu_data, }, { .compatible = "samsung,exynos4412-tmu", - .data = (void *)EXYNOS4412_TMU_DRV_DATA, + .data = &exynos4412_default_tmu_data, }, { .compatible = "samsung,exynos5250-tmu", - .data = (void *)EXYNOS5250_TMU_DRV_DATA, + .data = &exynos5250_default_tmu_data, }, { .compatible = "samsung,exynos5260-tmu", - .data = (void *)EXYNOS5260_TMU_DRV_DATA, + .data = &exynos5260_default_tmu_data, }, { .compatible = "samsung,exynos5420-tmu", - .data = (void *)EXYNOS5420_TMU_DRV_DATA, + .data = &exynos5420_default_tmu_data, }, { .compatible = "samsung,exynos5420-tmu-ext-triminfo", - .data = (void *)EXYNOS5420_TMU_DRV_DATA, + .data = &exynos5420_default_tmu_data, }, { .compatible = "samsung,exynos5440-tmu", - .data = (void *)EXYNOS5440_TMU_DRV_DATA, + .data = &exynos5440_default_tmu_data, }, {}, }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 708c3e1..02a1c34 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -24,7 +24,6 @@ #include "exynos_tmu.h" #include "exynos_tmu_data.h" -#if defined(CONFIG_CPU_EXYNOS4210) struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { { @@ -63,9 +62,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS3250) #define EXYNOS3250_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -101,9 +98,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2 -#endif -#if defined(CONFIG_SOC_EXYNOS3250) struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .tmu_data = { { @@ -113,9 +108,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) #define EXYNOS4412_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -151,9 +144,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2 -#endif -#if defined(CONFIG_SOC_EXYNOS4412) struct exynos_tmu_init_data const exynos4412_default_tmu_data = { .tmu_data = { { @@ -163,9 +154,7 @@ struct exynos_tmu_init_data const exynos4412_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5250) struct exynos_tmu_init_data const exynos5250_default_tmu_data = { .tmu_data = { { @@ -175,9 +164,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5260) #define __EXYNOS5260_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -228,9 +215,7 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { }, .tmu_count = 5, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5420) #define __EXYNOS5420_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -285,9 +270,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { }, .tmu_count = 5, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5440) #define EXYNOS5440_TMU_DATA \ .trigger_levels[0] = 100, \ .trigger_levels[4] = 105, \ @@ -316,4 +299,3 @@ struct exynos_tmu_init_data const exynos5440_default_tmu_data = { }, .tmu_count = 3, }; -#endif diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h index 2af312d..0bfbbf2 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ b/drivers/thermal/samsung/exynos_tmu_data.h @@ -104,53 +104,12 @@ #define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 #define EXYNOS5440_EFUSE_SWAP_OFFSET 8 -#if defined(CONFIG_SOC_EXYNOS3250) extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; -#define EXYNOS3250_TMU_DRV_DATA (&exynos3250_default_tmu_data) -#else -#define EXYNOS3250_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_CPU_EXYNOS4210) extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; -#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data) -#else -#define EXYNOS4210_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS4412) extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; -#define EXYNOS4412_TMU_DRV_DATA (&exynos4412_default_tmu_data) -#else -#define EXYNOS4412_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5250) extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; -#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data) -#else -#define EXYNOS5250_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5260) extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; -#define EXYNOS5260_TMU_DRV_DATA (&exynos5260_default_tmu_data) -#else -#define EXYNOS5260_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5420) extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; -#define EXYNOS5420_TMU_DRV_DATA (&exynos5420_default_tmu_data) -#else -#define EXYNOS5420_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5440) extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; -#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data) -#else -#define EXYNOS5440_TMU_DRV_DATA (NULL) -#endif #endif /*_EXYNOS_TMU_DATA_H*/ -- cgit v0.10.2 From 78f3320d7756c5f5ee34ea01916a91b714548962 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:27 +0100 Subject: thermal: exynos: remove __EXYNOS5420_TMU_DATA macro __EXYNOS5420_TMU_DATA macro is now identical to __EXYNOS5260_TMU_DATA one and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 02a1c34..592c470 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -216,48 +216,12 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_count = 5, }; -#define __EXYNOS5420_TMU_DATA \ - .threshold_falling = 10, \ - .trigger_levels[0] = 85, \ - .trigger_levels[1] = 103, \ - .trigger_levels[2] = 110, \ - .trigger_levels[3] = 120, \ - .trigger_enable[0] = true, \ - .trigger_enable[1] = true, \ - .trigger_enable[2] = true, \ - .trigger_enable[3] = false, \ - .trigger_type[0] = THROTTLE_ACTIVE, \ - .trigger_type[1] = THROTTLE_ACTIVE, \ - .trigger_type[2] = SW_TRIP, \ - .trigger_type[3] = HW_TRIP, \ - .max_trigger_level = 4, \ - .non_hw_trigger_levels = 3, \ - .gain = 8, \ - .reference_voltage = 16, \ - .noise_cancel_mode = 4, \ - .cal_type = TYPE_ONE_POINT_TRIMMING, \ - .efuse_value = 55, \ - .min_efuse_value = 40, \ - .max_efuse_value = 100, \ - .first_point_trim = 25, \ - .second_point_trim = 85, \ - .default_temp_offset = 50, \ - .freq_tab[0] = { \ - .freq_clip_max = 800 * 1000, \ - .temp_level = 85, \ - }, \ - .freq_tab[1] = { \ - .freq_clip_max = 200 * 1000, \ - .temp_level = 103, \ - }, \ - .freq_tab_count = 2, \ - #define EXYNOS5420_TMU_DATA \ - __EXYNOS5420_TMU_DATA \ + __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420 #define EXYNOS5420_TMU_DATA_SHARED \ - __EXYNOS5420_TMU_DATA \ + __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO struct exynos_tmu_init_data const exynos5420_default_tmu_data = { -- cgit v0.10.2 From 2845f6ec81d74344a93693d9b7807ae9c3dae9ed Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:28 +0100 Subject: thermal: exynos: remove exynos_tmu_data.h include There is no longer need to share defines between exynos_tmu.c and exynos_tmu_data.c (as they are now only used by the former file) so move them accordingly. Then move externs for struct exynos_tmu_init_data instances to exynos_tmu.h and remove no longer needed exynos_tmu_data.h include. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6cc6b6e..2a1c4c7 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -33,7 +33,87 @@ #include "exynos_thermal_common.h" #include "exynos_tmu.h" -#include "exynos_tmu_data.h" + +/* Exynos generic registers */ +#define EXYNOS_TMU_REG_TRIMINFO 0x0 +#define EXYNOS_TMU_REG_CONTROL 0x20 +#define EXYNOS_TMU_REG_STATUS 0x28 +#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 +#define EXYNOS_TMU_REG_INTEN 0x70 +#define EXYNOS_TMU_REG_INTSTAT 0x74 +#define EXYNOS_TMU_REG_INTCLEAR 0x78 + +#define EXYNOS_TMU_TEMP_MASK 0xff +#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 +#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f +#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf +#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 +#define EXYNOS_TMU_CORE_EN_SHIFT 0 + +/* Exynos3250 specific registers */ +#define EXYNOS_TMU_TRIMINFO_CON1 0x10 + +/* Exynos4210 specific registers */ +#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 +#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 + +/* Exynos5250, Exynos4412, Exynos3250 specific registers */ +#define EXYNOS_TMU_TRIMINFO_CON2 0x14 +#define EXYNOS_THD_TEMP_RISE 0x50 +#define EXYNOS_THD_TEMP_FALL 0x54 +#define EXYNOS_EMUL_CON 0x80 + +#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 +#define EXYNOS_TRIMINFO_25_SHIFT 0 +#define EXYNOS_TRIMINFO_85_SHIFT 8 +#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 +#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 +#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 + +#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 +#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 +#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 +#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 +#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 + +#define EXYNOS_EMUL_TIME 0x57F0 +#define EXYNOS_EMUL_TIME_MASK 0xffff +#define EXYNOS_EMUL_TIME_SHIFT 16 +#define EXYNOS_EMUL_DATA_SHIFT 8 +#define EXYNOS_EMUL_DATA_MASK 0xFF +#define EXYNOS_EMUL_ENABLE 0x1 + +/* Exynos5260 specific */ +#define EXYNOS5260_TMU_REG_INTEN 0xC0 +#define EXYNOS5260_TMU_REG_INTSTAT 0xC4 +#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 +#define EXYNOS5260_EMUL_CON 0x100 + +/* Exynos4412 specific */ +#define EXYNOS4412_MUX_ADDR_VALUE 6 +#define EXYNOS4412_MUX_ADDR_SHIFT 20 + +/*exynos5440 specific registers*/ +#define EXYNOS5440_TMU_S0_7_TRIM 0x000 +#define EXYNOS5440_TMU_S0_7_CTRL 0x020 +#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 +#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 +#define EXYNOS5440_TMU_S0_7_TH0 0x110 +#define EXYNOS5440_TMU_S0_7_TH1 0x130 +#define EXYNOS5440_TMU_S0_7_TH2 0x150 +#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 +#define EXYNOS5440_TMU_S0_7_IRQ 0x230 +/* exynos5440 common registers */ +#define EXYNOS5440_TMU_IRQ_STATUS 0x000 +#define EXYNOS5440_TMU_PMIN 0x004 + +#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 +#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 +#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 +#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 +#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 +#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 +#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 /** * struct exynos_tmu_data : A structure to hold the private data of the TMU diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 8de0f82..da3009b 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -133,4 +133,12 @@ struct exynos_tmu_init_data { struct exynos_tmu_platform_data tmu_data[]; }; +extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; +extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; +extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; + #endif /* _EXYNOS_TMU_H */ diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 592c470..b239100 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -22,7 +22,6 @@ #include "exynos_thermal_common.h" #include "exynos_tmu.h" -#include "exynos_tmu_data.h" struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h deleted file mode 100644 index 0bfbbf2..0000000 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * exynos_tmu_data.h - Samsung EXYNOS tmu data header file - * - * Copyright (C) 2013 Samsung Electronics - * Amit Daniel Kachhap - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _EXYNOS_TMU_DATA_H -#define _EXYNOS_TMU_DATA_H - -/* Exynos generic registers */ -#define EXYNOS_TMU_REG_TRIMINFO 0x0 -#define EXYNOS_TMU_REG_CONTROL 0x20 -#define EXYNOS_TMU_REG_STATUS 0x28 -#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 -#define EXYNOS_TMU_REG_INTEN 0x70 -#define EXYNOS_TMU_REG_INTSTAT 0x74 -#define EXYNOS_TMU_REG_INTCLEAR 0x78 - -#define EXYNOS_TMU_TEMP_MASK 0xff -#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 -#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f -#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf -#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 -#define EXYNOS_TMU_CORE_EN_SHIFT 0 - -/* Exynos3250 specific registers */ -#define EXYNOS_TMU_TRIMINFO_CON1 0x10 - -/* Exynos4210 specific registers */ -#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 -#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 - -/* Exynos5250, Exynos4412, Exynos3250 specific registers */ -#define EXYNOS_TMU_TRIMINFO_CON2 0x14 -#define EXYNOS_THD_TEMP_RISE 0x50 -#define EXYNOS_THD_TEMP_FALL 0x54 -#define EXYNOS_EMUL_CON 0x80 - -#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 -#define EXYNOS_TRIMINFO_25_SHIFT 0 -#define EXYNOS_TRIMINFO_85_SHIFT 8 -#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 -#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 -#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 - -#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 -#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 -#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 -#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 -#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 - -#define EXYNOS_EMUL_TIME 0x57F0 -#define EXYNOS_EMUL_TIME_MASK 0xffff -#define EXYNOS_EMUL_TIME_SHIFT 16 -#define EXYNOS_EMUL_DATA_SHIFT 8 -#define EXYNOS_EMUL_DATA_MASK 0xFF -#define EXYNOS_EMUL_ENABLE 0x1 - -/* Exynos5260 specific */ -#define EXYNOS5260_TMU_REG_INTEN 0xC0 -#define EXYNOS5260_TMU_REG_INTSTAT 0xC4 -#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 -#define EXYNOS5260_EMUL_CON 0x100 - -/* Exynos4412 specific */ -#define EXYNOS4412_MUX_ADDR_VALUE 6 -#define EXYNOS4412_MUX_ADDR_SHIFT 20 - -/*exynos5440 specific registers*/ -#define EXYNOS5440_TMU_S0_7_TRIM 0x000 -#define EXYNOS5440_TMU_S0_7_CTRL 0x020 -#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 -#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 -#define EXYNOS5440_TMU_S0_7_TH0 0x110 -#define EXYNOS5440_TMU_S0_7_TH1 0x130 -#define EXYNOS5440_TMU_S0_7_TH2 0x150 -#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 -#define EXYNOS5440_TMU_S0_7_IRQ 0x230 -/* exynos5440 common registers */ -#define EXYNOS5440_TMU_IRQ_STATUS 0x000 -#define EXYNOS5440_TMU_PMIN 0x004 - -#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 -#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 -#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 -#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 -#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 -#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 -#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 - -extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; -extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; -extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; - -#endif /*_EXYNOS_TMU_DATA_H*/ -- cgit v0.10.2 From 6962ad52a5971dc2c91b3afe7b8124c4a197bef0 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 24 Nov 2014 12:58:58 +0800 Subject: dt-bindings: document Rockchip thermal This add the necessary binding documentation for the thermal found on Rockchip SoCs Signed-off-by: zhaoyifeng Signed-off-by: Caesar Wang Reviewed-by: Dmitry Torokhov Signed-off-by: Eduardo Valentin diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt new file mode 100644 index 0000000..ef802de --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt @@ -0,0 +1,68 @@ +* Temperature Sensor ADC (TSADC) on rockchip SoCs + +Required properties: +- compatible : "rockchip,rk3288-tsadc" +- reg : physical base address of the controller and length of memory mapped + region. +- interrupts : The interrupt number to the cpu. The interrupt specifier format + depends on the interrupt controller. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Shall be "tsadc" for the converter-clock, and "apb_pclk" for + the peripheral clock. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the name "tsadc-apb". +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. +- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value. +- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO. +- rockchip,hw-tshut-polarity : The hardware-controlled active polarity 0:LOW + 1:HIGH. + +Exiample: +tsadc: tsadc@ff280000 { + compatible = "rockchip,rk3288-tsadc"; + reg = <0xff280000 0x100>; + interrupts = ; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + resets = <&cru SRST_TSADC>; + reset-names = "tsadc-apb"; + pinctrl-names = "default"; + pinctrl-0 = <&otp_out>; + #thermal-sensor-cells = <1>; + rockchip,hw-tshut-temp = <95000>; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; +}; + +Example: referring to thermal sensors: +thermal-zones { + cpu_thermal: cpu_thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&tsadc 1>; + + trips { + cpu_alert0: cpu_alert { + temperature = <70000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; -- cgit v0.10.2 From cbac8f63943773218f7f804754209aaa4fae33f9 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 24 Nov 2014 12:58:59 +0800 Subject: thermal: rockchip: add driver for thermal Thermal is TS-ADC Controller module supports user-defined mode and automatic mode. User-defined mode refers,TSADC all the control signals entirely by software writing to register for direct control. Automaic mode refers to the module automatically poll TSADC output, and the results were checked.If you find that the temperature High in a period of time,an interrupt is generated to the processor down-measures taken;If the temperature over a period of time High, the resulting TSHUT gave CRU module,let it reset the entire chip, or via GPIO give PMIC. Signed-off-by: zhaoyifeng Signed-off-by: Caesar Wang Reviewed-by: Dmitry Torokhov Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 911c38a..af40db0 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -155,6 +155,16 @@ config SPEAR_THERMAL Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework. +config ROCKCHIP_THERMAL + tristate "Rockchip thermal driver" + depends on ARCH_ROCKCHIP + depends on RESET_CONTROLLER + help + Rockchip thermal driver provides support for Temperature sensor + ADC (TS-ADC) found on Rockchip SoCs. It supports one critical + trip point. Cpufreq is used as the cooling device and will throttle + CPUs when the Temperature crosses the passive trip point. + config RCAR_THERMAL tristate "Renesas R-Car thermal driver" depends on ARCH_SHMOBILE || COMPILE_TEST diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 2b18e3a..fa0dc48 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -23,6 +23,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o # platform thermal drivers obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o obj-y += samsung/ diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c new file mode 100644 index 0000000..1bcddfc --- /dev/null +++ b/drivers/thermal/rockchip_thermal.c @@ -0,0 +1,693 @@ +/* + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * If the temperature over a period of time High, + * the resulting TSHUT gave CRU module,let it reset the entire chip, + * or via GPIO give PMIC. + */ +enum tshut_mode { + TSHUT_MODE_CRU = 0, + TSHUT_MODE_GPIO, +}; + +/** + * the system Temperature Sensors tshut(tshut) polarity + * the bit 8 is tshut polarity. + * 0: low active, 1: high active + */ +enum tshut_polarity { + TSHUT_LOW_ACTIVE = 0, + TSHUT_HIGH_ACTIVE, +}; + +/** + * The system has three Temperature Sensors. channel 0 is reserved, + * channel 1 is for CPU, and channel 2 is for GPU. + */ +enum sensor_id { + SENSOR_CPU = 1, + SENSOR_GPU, +}; + +struct rockchip_tsadc_chip { + /* The hardware-controlled tshut property */ + long tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; + + /* Chip-wide methods */ + void (*initialize)(void __iomem *reg, enum tshut_polarity p); + void (*irq_ack)(void __iomem *reg); + void (*control)(void __iomem *reg, bool on); + + /* Per-sensor methods */ + int (*get_temp)(int chn, void __iomem *reg, long *temp); + void (*set_tshut_temp)(int chn, void __iomem *reg, long temp); + void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m); +}; + +struct rockchip_thermal_sensor { + struct rockchip_thermal_data *thermal; + struct thermal_zone_device *tzd; + enum sensor_id id; +}; + +#define NUM_SENSORS 2 /* Ignore unused sensor 0 */ + +struct rockchip_thermal_data { + const struct rockchip_tsadc_chip *chip; + struct platform_device *pdev; + struct reset_control *reset; + + struct rockchip_thermal_sensor sensors[NUM_SENSORS]; + + struct clk *clk; + struct clk *pclk; + + void __iomem *regs; + + long tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; +}; + +/* TSADC V2 Sensor info define: */ +#define TSADCV2_AUTO_CON 0x04 +#define TSADCV2_INT_EN 0x08 +#define TSADCV2_INT_PD 0x0c +#define TSADCV2_DATA(chn) (0x20 + (chn) * 0x04) +#define TSADCV2_COMP_SHUT(chn) (0x40 + (chn) * 0x04) +#define TSADCV2_HIGHT_INT_DEBOUNCE 0x60 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE 0x64 +#define TSADCV2_AUTO_PERIOD 0x68 +#define TSADCV2_AUTO_PERIOD_HT 0x6c + +#define TSADCV2_AUTO_EN BIT(0) +#define TSADCV2_AUTO_DISABLE ~BIT(0) +#define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8) +#define TSADCV2_AUTO_TSHUT_POLARITY_LOW ~BIT(8) + +#define TSADCV2_INT_SRC_EN(chn) BIT(chn) +#define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) + +#define TSADCV2_INT_PD_CLEAR ~BIT(8) + +#define TSADCV2_DATA_MASK 0xfff +#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 +#define TSADCV2_AUTO_PERIOD_TIME 250 /* msec */ +#define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* msec */ + +struct tsadc_table { + unsigned long code; + long temp; +}; + +static const struct tsadc_table v2_code_table[] = { + {TSADCV2_DATA_MASK, -40000}, + {3800, -40000}, + {3792, -35000}, + {3783, -30000}, + {3774, -25000}, + {3765, -20000}, + {3756, -15000}, + {3747, -10000}, + {3737, -5000}, + {3728, 0}, + {3718, 5000}, + {3708, 10000}, + {3698, 15000}, + {3688, 20000}, + {3678, 25000}, + {3667, 30000}, + {3656, 35000}, + {3645, 40000}, + {3634, 45000}, + {3623, 50000}, + {3611, 55000}, + {3600, 60000}, + {3588, 65000}, + {3575, 70000}, + {3563, 75000}, + {3550, 80000}, + {3537, 85000}, + {3524, 90000}, + {3510, 95000}, + {3496, 100000}, + {3482, 105000}, + {3467, 110000}, + {3452, 115000}, + {3437, 120000}, + {3421, 125000}, + {0, 125000}, +}; + +static u32 rk_tsadcv2_temp_to_code(long temp) +{ + int high, low, mid; + + low = 0; + high = ARRAY_SIZE(v2_code_table) - 1; + mid = (high + low) / 2; + + if (temp < v2_code_table[low].temp || temp > v2_code_table[high].temp) + return 0; + + while (low <= high) { + if (temp == v2_code_table[mid].temp) + return v2_code_table[mid].code; + else if (temp < v2_code_table[mid].temp) + high = mid - 1; + else + low = mid + 1; + mid = (low + high) / 2; + } + + return 0; +} + +static long rk_tsadcv2_code_to_temp(u32 code) +{ + int high, low, mid; + + low = 0; + high = ARRAY_SIZE(v2_code_table) - 1; + mid = (high + low) / 2; + + if (code > v2_code_table[low].code || code < v2_code_table[high].code) + return 125000; /* No code available, return max temperature */ + + while (low <= high) { + if (code >= v2_code_table[mid].code && code < + v2_code_table[mid - 1].code) + return v2_code_table[mid].temp; + else if (code < v2_code_table[mid].code) + low = mid + 1; + else + high = mid - 1; + mid = (low + high) / 2; + } + + return 125000; +} + +/** + * rk_tsadcv2_initialize - initialize TASDC Controller + * (1) Set TSADCV2_AUTO_PERIOD, configure the interleave between + * every two accessing of TSADC in normal operation. + * (2) Set TSADCV2_AUTO_PERIOD_HT, configure the interleave between + * every two accessing of TSADC after the temperature is higher + * than COM_SHUT or COM_INT. + * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE, + * if the temperature is higher than COMP_INT or COMP_SHUT for + * "debounce" times, TSADC controller will generate interrupt or TSHUT. + */ +static void rk_tsadcv2_initialize(void __iomem *regs, + enum tshut_polarity tshut_polarity) +{ + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH), + regs + TSADCV2_AUTO_CON); + else + writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW), + regs + TSADCV2_AUTO_CON); + + writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD); + writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, + regs + TSADCV2_HIGHT_INT_DEBOUNCE); + writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME, + regs + TSADCV2_AUTO_PERIOD_HT); + writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, + regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); +} + +static void rk_tsadcv2_irq_ack(void __iomem *regs) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_INT_PD); + writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD); +} + +static void rk_tsadcv2_control(void __iomem *regs, bool enable) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_AUTO_CON); + if (enable) + val |= TSADCV2_AUTO_EN; + else + val &= ~TSADCV2_AUTO_EN; + + writel_relaxed(val, regs + TSADCV2_AUTO_CON); +} + +static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, long *temp) +{ + u32 val; + + /* the A/D value of the channel last conversion need some time */ + val = readl_relaxed(regs + TSADCV2_DATA(chn)); + if (val == 0) + return -EAGAIN; + + *temp = rk_tsadcv2_code_to_temp(val); + + return 0; +} + +static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp) +{ + u32 tshut_value, val; + + tshut_value = rk_tsadcv2_temp_to_code(temp); + writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); + + /* TSHUT will be valid */ + val = readl_relaxed(regs + TSADCV2_AUTO_CON); + writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON); +} + +static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, + enum tshut_mode mode) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_INT_EN); + if (mode == TSHUT_MODE_GPIO) { + val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn); + val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn); + } else { + val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn); + val |= TSADCV2_SHUT_2CRU_SRC_EN(chn); + } + + writel_relaxed(val, regs + TSADCV2_INT_EN); +} + +static const struct rockchip_tsadc_chip rk3288_tsadc_data = { + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv2_irq_ack, + .control = rk_tsadcv2_control, + .get_temp = rk_tsadcv2_get_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, +}; + +static const struct of_device_id of_rockchip_thermal_match[] = { + { + .compatible = "rockchip,rk3288-tsadc", + .data = (void *)&rk3288_tsadc_data, + }, + { /* end */ }, +}; +MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match); + +static void +rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on) +{ + struct thermal_zone_device *tzd = sensor->tzd; + + tzd->ops->set_mode(tzd, + on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED); +} + +static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev) +{ + struct rockchip_thermal_data *thermal = dev; + int i; + + dev_dbg(&thermal->pdev->dev, "thermal alarm\n"); + + thermal->chip->irq_ack(thermal->regs); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + thermal_zone_device_update(thermal->sensors[i].tzd); + + return IRQ_HANDLED; +} + +static int rockchip_thermal_get_temp(void *_sensor, long *out_temp) +{ + struct rockchip_thermal_sensor *sensor = _sensor; + struct rockchip_thermal_data *thermal = sensor->thermal; + const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; + int retval; + + retval = tsadc->get_temp(sensor->id, thermal->regs, out_temp); + dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %ld, retval: %d\n", + sensor->id, *out_temp, retval); + + return retval; +} + +static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = { + .get_temp = rockchip_thermal_get_temp, +}; + +static int rockchip_configure_from_dt(struct device *dev, + struct device_node *np, + struct rockchip_thermal_data *thermal) +{ + u32 shut_temp, tshut_mode, tshut_polarity; + + if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) { + dev_warn(dev, + "Missing tshut temp property, using default %ld\n", + thermal->chip->tshut_temp); + thermal->tshut_temp = thermal->chip->tshut_temp; + } else { + thermal->tshut_temp = shut_temp; + } + + if (thermal->tshut_temp > INT_MAX) { + dev_err(dev, "Invalid tshut temperature specified: %ld\n", + thermal->tshut_temp); + return -ERANGE; + } + + if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) { + dev_warn(dev, + "Missing tshut mode property, using default (%s)\n", + thermal->chip->tshut_mode == TSHUT_MODE_GPIO ? + "gpio" : "cru"); + thermal->tshut_mode = thermal->chip->tshut_mode; + } else { + thermal->tshut_mode = tshut_mode; + } + + if (thermal->tshut_mode > 1) { + dev_err(dev, "Invalid tshut mode specified: %d\n", + thermal->tshut_mode); + return -EINVAL; + } + + if (of_property_read_u32(np, "rockchip,hw-tshut-polarity", + &tshut_polarity)) { + dev_warn(dev, + "Missing tshut-polarity property, using default (%s)\n", + thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ? + "low" : "high"); + thermal->tshut_polarity = thermal->chip->tshut_polarity; + } else { + thermal->tshut_polarity = tshut_polarity; + } + + if (thermal->tshut_polarity > 1) { + dev_err(dev, "Invalid tshut-polarity specified: %d\n", + thermal->tshut_polarity); + return -EINVAL; + } + + return 0; +} + +static int +rockchip_thermal_register_sensor(struct platform_device *pdev, + struct rockchip_thermal_data *thermal, + struct rockchip_thermal_sensor *sensor, + enum sensor_id id) +{ + const struct rockchip_tsadc_chip *tsadc = thermal->chip; + int error; + + tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); + tsadc->set_tshut_temp(id, thermal->regs, thermal->tshut_temp); + + sensor->thermal = thermal; + sensor->id = id; + sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev, id, sensor, + &rockchip_of_thermal_ops); + if (IS_ERR(sensor->tzd)) { + error = PTR_ERR(sensor->tzd); + dev_err(&pdev->dev, "failed to register sensor %d: %d\n", + id, error); + return error; + } + + return 0; +} + +/* + * Reset TSADC Controller, reset all tsadc registers. + */ +static void rockchip_thermal_reset_controller(struct reset_control *reset) +{ + reset_control_assert(reset); + usleep_range(10, 20); + reset_control_deassert(reset); +} + +static int rockchip_thermal_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct rockchip_thermal_data *thermal; + const struct of_device_id *match; + struct resource *res; + int irq; + int i; + int error; + + match = of_match_node(of_rockchip_thermal_match, np); + if (!match) + return -ENXIO; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return -EINVAL; + } + + thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data), + GFP_KERNEL); + if (!thermal) + return -ENOMEM; + + thermal->pdev = pdev; + + thermal->chip = (const struct rockchip_tsadc_chip *)match->data; + if (!thermal->chip) + return -EINVAL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + thermal->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(thermal->regs)) + return PTR_ERR(thermal->regs); + + thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb"); + if (IS_ERR(thermal->reset)) { + error = PTR_ERR(thermal->reset); + dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error); + return error; + } + + thermal->clk = devm_clk_get(&pdev->dev, "tsadc"); + if (IS_ERR(thermal->clk)) { + error = PTR_ERR(thermal->clk); + dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error); + return error; + } + + thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(thermal->pclk)) { + error = PTR_ERR(thermal->clk); + dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", + error); + return error; + } + + error = clk_prepare_enable(thermal->clk); + if (error) { + dev_err(&pdev->dev, "failed to enable converter clock: %d\n", + error); + return error; + } + + error = clk_prepare_enable(thermal->pclk); + if (error) { + dev_err(&pdev->dev, "failed to enable pclk: %d\n", error); + goto err_disable_clk; + } + + rockchip_thermal_reset_controller(thermal->reset); + + error = rockchip_configure_from_dt(&pdev->dev, np, thermal); + if (error) { + dev_err(&pdev->dev, "failed to parse device tree data: %d\n", + error); + goto err_disable_pclk; + } + + thermal->chip->initialize(thermal->regs, thermal->tshut_polarity); + + error = rockchip_thermal_register_sensor(pdev, thermal, + &thermal->sensors[0], + SENSOR_CPU); + if (error) { + dev_err(&pdev->dev, + "failed to register CPU thermal sensor: %d\n", error); + goto err_disable_pclk; + } + + error = rockchip_thermal_register_sensor(pdev, thermal, + &thermal->sensors[1], + SENSOR_GPU); + if (error) { + dev_err(&pdev->dev, + "failed to register GPU thermal sensor: %d\n", error); + goto err_unregister_cpu_sensor; + } + + error = devm_request_threaded_irq(&pdev->dev, irq, NULL, + &rockchip_thermal_alarm_irq_thread, + IRQF_ONESHOT, + "rockchip_thermal", thermal); + if (error) { + dev_err(&pdev->dev, + "failed to request tsadc irq: %d\n", error); + goto err_unregister_gpu_sensor; + } + + thermal->chip->control(thermal->regs, true); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); + + platform_set_drvdata(pdev, thermal); + + return 0; + +err_unregister_gpu_sensor: + thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[1].tzd); +err_unregister_cpu_sensor: + thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[0].tzd); +err_disable_pclk: + clk_disable_unprepare(thermal->pclk); +err_disable_clk: + clk_disable_unprepare(thermal->clk); + + return error; +} + +static int rockchip_thermal_remove(struct platform_device *pdev) +{ + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) { + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; + + rockchip_thermal_toggle_sensor(sensor, false); + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd); + } + + thermal->chip->control(thermal->regs, false); + + clk_disable_unprepare(thermal->pclk); + clk_disable_unprepare(thermal->clk); + + return 0; +} + +static int __maybe_unused rockchip_thermal_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], false); + + thermal->chip->control(thermal->regs, false); + + clk_disable(thermal->pclk); + clk_disable(thermal->clk); + + return 0; +} + +static int __maybe_unused rockchip_thermal_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + int error; + + error = clk_enable(thermal->clk); + if (error) + return error; + + error = clk_enable(thermal->pclk); + if (error) + return error; + + rockchip_thermal_reset_controller(thermal->reset); + + thermal->chip->initialize(thermal->regs, thermal->tshut_polarity); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) { + enum sensor_id id = thermal->sensors[i].id; + + thermal->chip->set_tshut_mode(id, thermal->regs, + thermal->tshut_mode); + thermal->chip->set_tshut_temp(id, thermal->regs, + thermal->tshut_temp); + } + + thermal->chip->control(thermal->regs, true); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops, + rockchip_thermal_suspend, rockchip_thermal_resume); + +static struct platform_driver rockchip_thermal_driver = { + .driver = { + .name = "rockchip-thermal", + .owner = THIS_MODULE, + .pm = &rockchip_thermal_pm_ops, + .of_match_table = of_rockchip_thermal_match, + }, + .probe = rockchip_thermal_probe, + .remove = rockchip_thermal_remove, +}; + +module_platform_driver(rockchip_thermal_driver); + +MODULE_DESCRIPTION("ROCKCHIP THERMAL Driver"); +MODULE_AUTHOR("Rockchip, Inc."); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:rockchip-thermal"); -- cgit v0.10.2 From e920f9b632a687834de5a78c60ac5c4c62327b1d Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 4 Nov 2014 13:00:38 -0300 Subject: thermal: armada: Remove support for A375-Z1 SoC The Armada 375 Z1 SoC revision is no longer supported. This commit removes the quirk needed for the thermal sensor. Acked-by: Jason Cooper Signed-off-by: Ezequiel Garcia Signed-off-by: Eduardo Valentin diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt index 4cf0249..4698e0e 100644 --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt @@ -5,17 +5,9 @@ Required properties: - compatible: Should be set to one of the following: marvell,armada370-thermal marvell,armada375-thermal - marvell,armada375-z1-thermal marvell,armada380-thermal marvell,armadaxp-thermal - Note: As the name suggests, "marvell,armada375-z1-thermal" - applies for the SoC Z1 stepping only. On such stepping - some quirks need to be done and the register offset differs - from the one in the A0 stepping. - The operating system may auto-detect the SoC stepping and - update the compatible and register offsets at runtime. - - reg: Device's register space. Two entries are expected, see the examples below. The first one is required for the sensor register; diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 9d1420a..9c8e783 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -35,10 +35,6 @@ #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) #define PMU_TDC0_START_CAL_MASK (0x1 << 25) -#define A375_Z1_CAL_RESET_LSB 0x8011e214 -#define A375_Z1_CAL_RESET_MSB 0x30a88019 -#define A375_Z1_WORKAROUND_BIT BIT(9) - #define A375_UNIT_CONTROL_SHIFT 27 #define A375_UNIT_CONTROL_MASK 0x7 #define A375_READOUT_INVERT BIT(15) @@ -124,24 +120,12 @@ static void armada375_init_sensor(struct platform_device *pdev, struct armada_thermal_priv *priv) { unsigned long reg; - bool quirk_needed = - !!of_device_is_compatible(pdev->dev.of_node, - "marvell,armada375-z1-thermal"); - - if (quirk_needed) { - /* Ensure these registers have the default (reset) values */ - writel(A375_Z1_CAL_RESET_LSB, priv->control); - writel(A375_Z1_CAL_RESET_MSB, priv->control + 0x4); - } reg = readl(priv->control + 4); reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); reg &= ~A375_READOUT_INVERT; reg &= ~A375_HW_RESETn; - if (quirk_needed) - reg |= A375_Z1_WORKAROUND_BIT; - writel(reg, priv->control + 4); mdelay(20); @@ -260,10 +244,6 @@ static const struct of_device_id armada_thermal_id_table[] = { .data = &armada375_data, }, { - .compatible = "marvell,armada375-z1-thermal", - .data = &armada375_data, - }, - { .compatible = "marvell,armada380-thermal", .data = &armada380_data, }, -- cgit v0.10.2 From 84ffe3ecc2c8b3effc41c0babd2cc24f1edb2aab Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 12 Nov 2014 15:43:29 -0800 Subject: thermal: core: ignore invalid trip temperature Ignore invalid trip temperature less or equal to zero. Some buggy systems have invalid trips, causing system shutdown. Signed-off-by: Srinivas Pandruvada Signed-off-by: Zhang Rui diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 43b9070..5aa5773 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -368,7 +368,7 @@ static void handle_critical_trips(struct thermal_zone_device *tz, tz->ops->get_trip_temp(tz, trip, &trip_temp); /* If we have not crossed the trip_temp, we do not care. */ - if (tz->temperature < trip_temp) + if (trip_temp <= 0 || tz->temperature < trip_temp) return; trace_thermal_zone_trip(tz, trip, trip_type); -- cgit v0.10.2 From b6cc772f64ac7d1917770406844b73a94ca5ef06 Mon Sep 17 00:00:00 2001 From: Javi Merino Date: Tue, 25 Nov 2014 16:00:33 +0000 Subject: thermal: lock the thermal zone when switching governors Currently, userspace can request a governor change while the governor itself is running. Grab the thermal zone lock when changing the governor to prevent this race. Signed-off-by: Javi Merino Signed-off-by: Zhang Rui diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 5aa5773..7b723c7 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -757,6 +757,7 @@ policy_store(struct device *dev, struct device_attribute *attr, snprintf(name, sizeof(name), "%s", buf); mutex_lock(&thermal_governor_lock); + mutex_lock(&tz->lock); gov = __find_governor(strim(name)); if (!gov) @@ -766,6 +767,7 @@ policy_store(struct device *dev, struct device_attribute *attr, ret = count; exit: + mutex_unlock(&tz->lock); mutex_unlock(&thermal_governor_lock); return ret; } -- cgit v0.10.2 From 9d367e5e7b05c71a8c1ac4e9b6e00ba45a79f2fc Mon Sep 17 00:00:00 2001 From: Luis Henriques Date: Wed, 3 Dec 2014 21:20:21 +0000 Subject: thermal: Fix error path in thermal_init() thermal_unregister_governors() and class_unregister() were being called in the wrong order. Fixes: 80a26a5c22b9 ("Thermal: build thermal governors into thermal_sys module") Cc: stable@vger.kernel.org Signed-off-by: Luis Henriques Signed-off-by: Zhang Rui diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 7b723c7..84fdf07 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1837,10 +1837,10 @@ static int __init thermal_init(void) exit_netlink: genetlink_exit(); -unregister_governors: - thermal_unregister_governors(); unregister_class: class_unregister(&thermal_class); +unregister_governors: + thermal_unregister_governors(); error: idr_destroy(&thermal_tz_idr); idr_destroy(&thermal_cdev_idr); -- cgit v0.10.2 From 08dab66ec8431a1f744596cfc9f5fb659b623835 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 8 Dec 2014 18:04:17 +0100 Subject: thermal: of: Extend of-thermal.c to provide number of trip points This patch extends the of-thermal.c to provide information about number of available trip points. Signed-off-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index b7982f0..7facd23 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -112,6 +112,27 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, return data->ops->get_temp(data->sensor_data, temp); } +/** + * of_thermal_get_ntrips - function to export number of available trip + * points. + * @tz: pointer to a thermal zone + * + * This function is a globally visible wrapper to get number of trip points + * stored in the local struct __thermal_zone + * + * Return: number of available trip points, -ENODEV when data not available + */ +int of_thermal_get_ntrips(struct thermal_zone_device *tz) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data || IS_ERR(data)) + return -ENODEV; + + return data->ntrips; +} +EXPORT_SYMBOL_GPL(of_thermal_get_ntrips); + static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) { diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index d15d243..1cc5041 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -89,9 +89,14 @@ static inline void thermal_gov_user_space_unregister(void) {} #ifdef CONFIG_THERMAL_OF int of_parse_thermal_zones(void); void of_thermal_destroy_zones(void); +int of_thermal_get_ntrips(struct thermal_zone_device *); #else static inline int of_parse_thermal_zones(void) { return 0; } static inline void of_thermal_destroy_zones(void) { } +static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) +{ + return 0; +} #endif #endif /* __THERMAL_CORE_H__ */ -- cgit v0.10.2 From a9bf2cc49d9030e374edb9cc0389512a1a1c357e Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 8 Dec 2014 18:04:18 +0100 Subject: thermal: of: Extend of-thermal.c to provide check if trip point is valid This patch extends the of-thermal.c to provide check if trip point is valid. Signed-off-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 7facd23..87b9cfe 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -133,6 +133,27 @@ int of_thermal_get_ntrips(struct thermal_zone_device *tz) } EXPORT_SYMBOL_GPL(of_thermal_get_ntrips); +/** + * of_thermal_is_trip_valid - function to check if trip point is valid + * + * @tz: pointer to a thermal zone + * @trip: trip point to evaluate + * + * This function is responsible for checking if passed trip point is valid + * + * Return: true if trip point is valid, false otherwise + */ +bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data || trip >= data->ntrips || trip < 0) + return false; + + return true; +} +EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); + static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) { diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 1cc5041..58a0dfa 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -90,6 +90,7 @@ static inline void thermal_gov_user_space_unregister(void) {} int of_parse_thermal_zones(void); void of_thermal_destroy_zones(void); int of_thermal_get_ntrips(struct thermal_zone_device *); +bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); #else static inline int of_parse_thermal_zones(void) { return 0; } static inline void of_thermal_destroy_zones(void) { } @@ -97,6 +98,11 @@ static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz) { return 0; } +static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, + int trip) +{ + return 0; +} #endif #endif /* __THERMAL_CORE_H__ */ -- cgit v0.10.2 From ad9914ac3b1f5c12ef2cf1c58a6ddda306fb79d4 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 8 Dec 2014 18:04:19 +0100 Subject: thermal: of: Rename struct __thermal_trip to struct thermal_trip This patch changes name of struct __thermal_trip to thermal_trip and moves declaration of the latter to ./include/linux/thermal.h for better visibility. Signed-off-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 87b9cfe..d3ac117 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -37,21 +37,6 @@ /*** Private data structures to represent thermal device tree data ***/ /** - * 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; - unsigned long int temperature; - unsigned long int hysteresis; - enum thermal_trip_type type; -}; - -/** * struct __thermal_bind_param - a match between trip and cooling device * @cooling_device: a pointer to identify the referred cooling device * @trip_id: the trip point index @@ -88,7 +73,7 @@ struct __thermal_zone { /* trip data */ int ntrips; - struct __thermal_trip *trips; + struct thermal_trip *trips; /* cooling binding data */ int num_tbps; @@ -538,7 +523,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister); */ static int thermal_of_populate_bind_params(struct device_node *np, struct __thermal_bind_params *__tbp, - struct __thermal_trip *trips, + struct thermal_trip *trips, int ntrips) { struct of_phandle_args cooling_spec; @@ -641,7 +626,7 @@ static int thermal_of_get_trip_type(struct device_node *np, * Return: 0 on success, proper error code otherwise */ static int thermal_of_populate_trip(struct device_node *np, - struct __thermal_trip *trip) + struct thermal_trip *trip) { int prop; int ret; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 5bc28a7..b8d91ef 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -303,6 +303,21 @@ struct thermal_zone_of_device_ops { int (*get_trend)(void *, long *); }; +/** + * 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; + unsigned long int temperature; + unsigned long int hysteresis; + enum thermal_trip_type type; +}; + /* Function declarations */ #ifdef CONFIG_THERMAL_OF struct thermal_zone_device * -- cgit v0.10.2 From ce8be7785922de0ef497b20384425ed04f674f9d Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 8 Dec 2014 18:04:20 +0100 Subject: thermal: of: Extend of-thermal to export table of trip points This patch extends the of-thermal.c to export trip points for a given thermal zone. Thermal drivers should use of_thermal_get_trip_points() method to get pointer to table of thermal trip points. Signed-off-by: Lukasz Majewski Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index d3ac117..e062bf5 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -139,6 +139,28 @@ bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) } EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); +/** + * of_thermal_get_trip_points - function to get access to a globally exported + * trip points + * + * @tz: pointer to a thermal zone + * + * This function provides a pointer to trip points table + * + * Return: pointer to trip points table, NULL otherwise + */ +const struct thermal_trip * const +of_thermal_get_trip_points(struct thermal_zone_device *tz) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data) + return NULL; + + return data->trips; +} +EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); + static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) { diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 58a0dfa..9083e75 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -91,6 +91,8 @@ int of_parse_thermal_zones(void); void of_thermal_destroy_zones(void); int of_thermal_get_ntrips(struct thermal_zone_device *); bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); +const struct thermal_trip * const +of_thermal_get_trip_points(struct thermal_zone_device *); #else static inline int of_parse_thermal_zones(void) { return 0; } static inline void of_thermal_destroy_zones(void) { } @@ -103,6 +105,11 @@ static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, { return 0; } +static inline const struct thermal_trip * const +of_thermal_get_trip_points(struct thermal_zone_device *tz) +{ + return NULL; +} #endif #endif /* __THERMAL_CORE_H__ */ -- cgit v0.10.2 From 184a4bf623fa587067851d25435fcb2f41de445b Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 8 Dec 2014 18:04:21 +0100 Subject: thermal: of: Extend current of-thermal.c code to allow setting emulated temp Before this change it was only possible to set get_temp() and get_trend() methods to be used in the common code handling passing parameters via device tree to "cpu-thermal" CPU thermal zone device. Now it is possible to also set emulated value of temperature for debug purposes. Signed-off-by: Lukasz Majewski Acked-by: Eduardo Valentin Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index e062bf5..e145b66 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -161,6 +161,28 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz) } EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); +/** + * of_thermal_set_emul_temp - function to set emulated temperature + * + * @tz: pointer to a thermal zone + * @temp: temperature to set + * + * This function gives the ability to set emulated value of temperature, + * which is handy for debugging + * + * Return: zero on success, error code otherwise + */ +static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, + unsigned long temp) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data->ops || !data->ops->set_emul_temp) + return -EINVAL; + + return data->ops->set_emul_temp(data->sensor_data, temp); +} + static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) { @@ -392,6 +414,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, tzd->ops->get_temp = of_thermal_get_temp; tzd->ops->get_trend = of_thermal_get_trend; + tzd->ops->set_emul_temp = of_thermal_set_emul_temp; mutex_unlock(&tzd->lock); return tzd; @@ -520,6 +543,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev, mutex_lock(&tzd->lock); tzd->ops->get_temp = NULL; tzd->ops->get_trend = NULL; + tzd->ops->set_emul_temp = NULL; tz->ops = NULL; tz->sensor_data = NULL; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index b8d91ef..99be7fc 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -297,10 +297,13 @@ struct thermal_genl_event { * * Optional: * @get_trend: a pointer to a function that reads the sensor temperature trend. + * @set_emul_temp: a pointer to a function that sets sensor emulated + * temperature. */ struct thermal_zone_of_device_ops { int (*get_temp)(void *, long *); int (*get_trend)(void *, long *); + int (*set_emul_temp)(void *, unsigned long); }; /** -- cgit v0.10.2 From 19ecaea26862228a6165232eed0861702700fb20 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 2 Dec 2014 09:11:23 -0800 Subject: thermal/int3400: export uuids INT3400 currently supports only one policy, which can't be changed. This change exports all available policies (uuids) to user space and allow this to be changed. It introduces an attribute group uuids in INT3400 platform driver. There are two attributes exposed: - available_uuids - current_uuid User space can set current_uuid via this interface to one of the available uuids. The uuid change is communicated to firmware, only when the current zone mode is changed to "enabled". So the ideal sequence should be - set INT3400 zone mode to "disabled" - change current_uuid - set INT3400 zone mode to "enabled" Signed-off-by: Srinivas Pandruvada Signed-off-by: Zhang Rui diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index edc1cce..dcb306e 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c @@ -43,6 +43,74 @@ struct int3400_thermal_priv { struct trt *trts; u8 uuid_bitmap; int rel_misc_dev_res; + int current_uuid_index; +}; + +static ssize_t available_uuids_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + int i; + int length = 0; + + for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) { + if (priv->uuid_bitmap & (1 << i)) + if (PAGE_SIZE - length > 0) + length += snprintf(&buf[length], + PAGE_SIZE - length, + "%s\n", + int3400_thermal_uuids[i]); + } + + return length; +} + +static ssize_t current_uuid_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + + if (priv->uuid_bitmap & (1 << priv->current_uuid_index)) + return sprintf(buf, "%s\n", + int3400_thermal_uuids[priv->current_uuid_index]); + else + return sprintf(buf, "INVALID\n"); +} + +static ssize_t current_uuid_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + 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))) { + priv->current_uuid_index = i; + return count; + } + } + + return -EINVAL; +} + +static DEVICE_ATTR(current_uuid, 0644, current_uuid_show, current_uuid_store); +static DEVICE_ATTR_RO(available_uuids); +static struct attribute *uuid_attrs[] = { + &dev_attr_available_uuids.attr, + &dev_attr_current_uuid.attr, + NULL +}; + +static struct attribute_group uuid_attribute_group = { + .attrs = uuid_attrs, + .name = "uuids" }; static int int3400_thermal_get_uuids(struct int3400_thermal_priv *priv) @@ -160,9 +228,9 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal, if (enable != priv->mode) { priv->mode = enable; - /* currently, only PASSIVE COOLING is supported */ result = int3400_thermal_run_osc(priv->adev->handle, - INT3400_THERMAL_PASSIVE_1, enable); + priv->current_uuid_index, + enable); } return result; } @@ -223,7 +291,14 @@ static int int3400_thermal_probe(struct platform_device *pdev) priv->rel_misc_dev_res = acpi_thermal_rel_misc_device_add( priv->adev->handle); + result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group); + if (result) + goto free_zone; + return 0; + +free_zone: + thermal_zone_device_unregister(priv->thermal); free_trt: kfree(priv->trts); free_art: @@ -240,6 +315,7 @@ static int int3400_thermal_remove(struct platform_device *pdev) if (!priv->rel_misc_dev_res) acpi_thermal_rel_misc_device_remove(priv->adev->handle); + sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group); thermal_zone_device_unregister(priv->thermal); kfree(priv->trts); kfree(priv->arts); -- cgit v0.10.2 From 931b9c86d9a518b1374157f103168fb787e6560e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 1 Dec 2014 05:45:42 +0100 Subject: thermal: int3403: Delete a check before thermal_zone_device_unregister() The thermal_zone_device_unregister() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Zhang Rui diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c index 6e9fb62..790b8f6 100644 --- a/drivers/thermal/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/int340x_thermal/int3403_thermal.c @@ -293,8 +293,7 @@ static int int3403_sensor_add(struct int3403_priv *priv) return 0; err_free_obj: - if (obj->tzone) - thermal_zone_device_unregister(obj->tzone); + thermal_zone_device_unregister(obj->tzone); return result; } -- cgit v0.10.2 From b81e5962af2c9453167d7be2efc46f42c42f63d2 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Tue, 4 Nov 2014 15:53:34 -0800 Subject: Thermal/int340x: avoid unnecessary pointer casting Avoid pointer casting which may also lead to problems on big endian 64 bit systems. Reported-by: Dan Carpenter Signed-off-by: Jacob Pan Signed-off-by: Zhang Rui diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index 0d8db80..ac5c405 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -317,21 +317,21 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd, { int ret = 0; unsigned long length = 0; - unsigned long count = 0; + int count = 0; char __user *arg = (void __user *)__arg; struct trt *trts; struct art *arts; switch (cmd) { case ACPI_THERMAL_GET_TRT_COUNT: - ret = acpi_parse_trt(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_trt(acpi_thermal_rel_handle, &count, &trts, false); kfree(trts); if (!ret) return put_user(count, (unsigned long __user *)__arg); return ret; case ACPI_THERMAL_GET_TRT_LEN: - ret = acpi_parse_trt(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_trt(acpi_thermal_rel_handle, &count, &trts, false); kfree(trts); length = count * sizeof(union trt_object); @@ -341,14 +341,14 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd, case ACPI_THERMAL_GET_TRT: return fill_trt(arg); case ACPI_THERMAL_GET_ART_COUNT: - ret = acpi_parse_art(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_art(acpi_thermal_rel_handle, &count, &arts, false); kfree(arts); if (!ret) return put_user(count, (unsigned long __user *)__arg); return ret; case ACPI_THERMAL_GET_ART_LEN: - ret = acpi_parse_art(acpi_thermal_rel_handle, (int *)&count, + ret = acpi_parse_art(acpi_thermal_rel_handle, &count, &arts, false); kfree(arts); length = count * sizeof(union art_object); -- cgit v0.10.2 From 341203167f9138073853cecd1f02d180bf9924ca Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Mon, 17 Nov 2014 14:24:36 +0800 Subject: Thermal: fix platform_no_drv_owner.cocci warnings drivers/thermal/int340x_thermal/int3403_thermal.c:468:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Signed-off-by: Fengguang Wu Acked-by: Zhang Rui Signed-off-by: Zhang Rui diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c index 790b8f6..1bfa6a6 100644 --- a/drivers/thermal/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/int340x_thermal/int3403_thermal.c @@ -470,7 +470,6 @@ static struct platform_driver int3403_driver = { .remove = int3403_remove, .driver = { .name = "int3403 thermal", - .owner = THIS_MODULE, .acpi_match_table = int3403_device_ids, }, }; -- cgit v0.10.2 From 05629296eec7e18038ca90ca4d5fa03824026429 Mon Sep 17 00:00:00 2001 From: Maurice Petallo Date: Fri, 28 Nov 2014 10:11:41 +0800 Subject: thermal: Intel SoC DTS: Don't do thermal zone update inside spin_lock The driver calls spin_lock_irqsave during DTS interrupt. The interrupt handle then calls thermal_zone_device_update which implicitly calls a sleep function and produce the following bug: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 in_atomic(): 1, irqs_disabled(): 1, pid: 920, name: irq/86-soc_dts CPU: 0 PID: 920 Comm: irq/86-soc_dts Tainted: G E 3.17.0-rc2+ #1 Hardware name: Intel Corp. VALLEYVIEW B3 PLATFORM/NOTEBOOK, BIOS BYTICRB1.86C.0092.R31.1408290850 08/29/2014 00000000 00000000 c25dbe74 c1818cfd f3cc488c c25dbe9c c1059305 c1b4063b 00000001 00000001 00000398 f3cc488c f6817644 f6817644 f3ecc6c0 c25dbea8 c18208f2 f6817400 c25dbebc c159b0bb c25dbedc f6817400 f32a2300 c25dbee8 Call Trace: [] dump_stack+0x48/0x60 [] __might_sleep+0xec/0xf4 [] mutex_lock+0x1c/0x34 [] thermal_zone_get_temp+0x34/0x59 [] thermal_zone_device_update+0x2d/0xcb [] ? iosf_mbi_write+0x6c/0x74 [iosf_mbi] [] soc_irq_thread_fn+0x10c/0x163 [intel_soc_dts_thermal] [] irq_thread_fn+0x18/0x2a [] irq_thread+0x81/0x11f [] ? irq_finalize_oneshot+0x7c/0x7c [] ? irq_thread+0x11f/0x11f [] ? wake_threads_waitq+0x31/0x31 [] kthread+0x87/0x8c [] ret_from_kernel_thread+0x21/0x30 [] ? __kthread_parkme+0x55/0x55 Signed-off-by: Maurice Petallo Acked-by: Srinivas Pandruvada Acked-by: Eduardo Valentin CC: Kweh, Hock Leong Signed-off-by: Zhang Rui diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c index a6a0a18..5580f5b 100644 --- a/drivers/thermal/intel_soc_dts_thermal.c +++ b/drivers/thermal/intel_soc_dts_thermal.c @@ -360,6 +360,9 @@ static void proc_thermal_interrupt(void) u32 sticky_out; int status; u32 ptmc_out; + unsigned long flags; + + spin_lock_irqsave(&intr_notify_lock, flags); /* Clear APIC interrupt */ status = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ, @@ -378,21 +381,20 @@ static void proc_thermal_interrupt(void) /* reset sticky bit */ status = iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE, SOC_DTS_OFFSET_PTTSS, sticky_out); + spin_unlock_irqrestore(&intr_notify_lock, flags); + for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { pr_debug("TZD update for zone %d\n", i); thermal_zone_device_update(soc_dts[i]->tzone); } - } + } else + spin_unlock_irqrestore(&intr_notify_lock, flags); } static irqreturn_t soc_irq_thread_fn(int irq, void *dev_data) { - unsigned long flags; - - spin_lock_irqsave(&intr_notify_lock, flags); proc_thermal_interrupt(); - spin_unlock_irqrestore(&intr_notify_lock, flags); pr_debug("proc_thermal_interrupt\n"); return IRQ_HANDLED; -- cgit v0.10.2 From 5a530ff0d88a366736ae4d1021e7358b52e55756 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Thu, 4 Dec 2014 10:53:43 -0800 Subject: thermal/powerclamp: add id for braswell cpu Braswell also has package C-states which can be used for idle injection. This patch adds Braswell CPU ID in intel powerclamp driver. Signed-off-by: Jacob Pan Signed-off-by: Zhang Rui diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 95cb7fc..b46c706 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -689,6 +689,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = { { X86_VENDOR_INTEL, 6, 0x3f}, { X86_VENDOR_INTEL, 6, 0x45}, { X86_VENDOR_INTEL, 6, 0x46}, + { X86_VENDOR_INTEL, 6, 0x4c}, {} }; MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); -- cgit v0.10.2 From e413ad7cca9f541659ac0ddf8f37e2bcfade365a Mon Sep 17 00:00:00 2001 From: Ilkka Koskinen Date: Mon, 8 Dec 2014 18:01:31 -0800 Subject: Thermal/int340x: Clear the error value of the last acpi_bus_get_device() call Previously the return value of the last acpi_bus_get_device() was returned. However, since we only report those issues, it should be cleared to continue as expected. Signed-off-by: Ilkka Koskinen Acked-by: Jacob Pan diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index ac5c405..e4e61b3 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -131,6 +131,8 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, pr_warn("Failed to get target ACPI device\n"); } + result = 0; + *trtp = trts; /* don't count bad entries */ *trt_count -= nr_bad_entries; -- cgit v0.10.2 From af6c9f1657ca6d2ef2b2c0e31ad17c6fbf773baf Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 19 Nov 2014 18:11:00 -0800 Subject: thermal: provide an UAPI header file include/linux/thermal.h contains definitions for the Thermal generic netlink family, but none of the valuable information relevant to user-space such as the Genl family name, multicast group, version or command set and data types is exported to user-space. Export all the relevant generic netlink information to user-space to make this genl family usable by user-space, and while at it, export THERMAL_NAME_LENGTH since it limits name length for thermal_hwmon devices. Kbuild and MAINTAINERS are also updated accordingly to reflect this new file: include/uapi/linux/thermal.h. Signed-off-by: Florian Fainelli Signed-off-by: Zhang Rui diff --git a/MAINTAINERS b/MAINTAINERS index 0ff630d..9c709f5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9295,6 +9295,7 @@ Q: https://patchwork.kernel.org/project/linux-pm/list/ S: Supported F: drivers/thermal/ F: include/linux/thermal.h +F: include/uapi/linux/thermal.h F: include/linux/cpu_cooling.h F: Documentation/devicetree/bindings/thermal/ diff --git a/include/linux/thermal.h b/include/linux/thermal.h index ef90838..70f8740 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -29,10 +29,10 @@ #include #include #include +#include #define THERMAL_TRIPS_NONE -1 #define THERMAL_MAX_TRIPS 12 -#define THERMAL_NAME_LENGTH 20 /* invalid cooling state */ #define THERMAL_CSTATE_INVALID -1UL @@ -49,11 +49,6 @@ #define MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, off) (((t) / 100) + (off)) #define MILLICELSIUS_TO_DECI_KELVIN(t) MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, 2732) -/* Adding event notification support elements */ -#define THERMAL_GENL_FAMILY_NAME "thermal_event" -#define THERMAL_GENL_VERSION 0x01 -#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp" - /* Default Thermal Governor */ #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE) #define DEFAULT_THERMAL_GOVERNOR "step_wise" @@ -86,30 +81,6 @@ enum thermal_trend { THERMAL_TREND_DROP_FULL, /* apply lowest cooling action */ }; -/* Events supported by Thermal Netlink */ -enum events { - THERMAL_AUX0, - THERMAL_AUX1, - THERMAL_CRITICAL, - THERMAL_DEV_FAULT, -}; - -/* attributes of thermal_genl_family */ -enum { - THERMAL_GENL_ATTR_UNSPEC, - THERMAL_GENL_ATTR_EVENT, - __THERMAL_GENL_ATTR_MAX, -}; -#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1) - -/* commands supported by the thermal_genl_family */ -enum { - THERMAL_GENL_CMD_UNSPEC, - THERMAL_GENL_CMD_EVENT, - __THERMAL_GENL_CMD_MAX, -}; -#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1) - struct thermal_zone_device_ops { int (*bind) (struct thermal_zone_device *, struct thermal_cooling_device *); diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 4c94f31..a1943e2 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -383,6 +383,7 @@ header-y += tcp.h header-y += tcp_metrics.h header-y += telephony.h header-y += termios.h +header-y += thermal.h header-y += time.h header-y += times.h header-y += timex.h diff --git a/include/uapi/linux/thermal.h b/include/uapi/linux/thermal.h new file mode 100644 index 0000000..ac55358 --- /dev/null +++ b/include/uapi/linux/thermal.h @@ -0,0 +1,35 @@ +#ifndef _UAPI_LINUX_THERMAL_H +#define _UAPI_LINUX_THERMAL_H + +#define THERMAL_NAME_LENGTH 20 + +/* Adding event notification support elements */ +#define THERMAL_GENL_FAMILY_NAME "thermal_event" +#define THERMAL_GENL_VERSION 0x01 +#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp" + +/* Events supported by Thermal Netlink */ +enum events { + THERMAL_AUX0, + THERMAL_AUX1, + THERMAL_CRITICAL, + THERMAL_DEV_FAULT, +}; + +/* attributes of thermal_genl_family */ +enum { + THERMAL_GENL_ATTR_UNSPEC, + THERMAL_GENL_ATTR_EVENT, + __THERMAL_GENL_ATTR_MAX, +}; +#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1) + +/* commands supported by the thermal_genl_family */ +enum { + THERMAL_GENL_CMD_UNSPEC, + THERMAL_GENL_CMD_EVENT, + __THERMAL_GENL_CMD_MAX, +}; +#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1) + +#endif /* _UAPI_LINUX_THERMAL_H */ -- cgit v0.10.2