mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 09:34:12 +08:00
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management fixes from Zhang Rui: "Specifics: - several fixes and cleanups on Rockchip thermal drivers. - add the missing support of RK3368 SoCs in Rockchip driver. - small fixes on of-thermal, power_allocator, rcar driver, IMX, and QCOM drivers, and also compilation fixes, on thermal.h, when thermal is not selected" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: imx: thermal: use CPU temperature grade info for thresholds thermal: fix thermal_zone_bind_cooling_device prototype Revert "thermal: qcom_spmi: allow compile test" thermal: rcar_thermal: remove redundant operation thermal: of-thermal: Reduce log level for message when can't fine thermal zone thermal: power_allocator: Use temperature reading from tz thermal: rockchip: Support the RK3368 SoCs in thermal driver thermal: rockchip: consistently use int for temperatures thermal: rockchip: Add the sort mode for adc value increment or decrement thermal: rockchip: improve the conversion function thermal: rockchip: trivial: fix typo in commit thermal: rockchip: better to compatible the driver for different SoCs dt-bindings: rockchip-thermal: Support the RK3368 SoCs compatible
This commit is contained in:
commit
75a29ec1e8
@ -1,7 +1,9 @@
|
|||||||
* Temperature Sensor ADC (TSADC) on rockchip SoCs
|
* Temperature Sensor ADC (TSADC) on rockchip SoCs
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : "rockchip,rk3288-tsadc"
|
- compatible : should be "rockchip,<name>-tsadc"
|
||||||
|
"rockchip,rk3288-tsadc": found on RK3288 SoCs
|
||||||
|
"rockchip,rk3368-tsadc": found on RK3368 SoCs
|
||||||
- reg : physical base address of the controller and length of memory mapped
|
- reg : physical base address of the controller and length of memory mapped
|
||||||
region.
|
region.
|
||||||
- interrupts : The interrupt number to the cpu. The interrupt specifier format
|
- interrupts : The interrupt number to the cpu. The interrupt specifier format
|
||||||
|
@ -382,7 +382,7 @@ endmenu
|
|||||||
|
|
||||||
config QCOM_SPMI_TEMP_ALARM
|
config QCOM_SPMI_TEMP_ALARM
|
||||||
tristate "Qualcomm SPMI PMIC Temperature Alarm"
|
tristate "Qualcomm SPMI PMIC Temperature Alarm"
|
||||||
depends on OF && (SPMI || COMPILE_TEST) && IIO
|
depends on OF && SPMI && IIO
|
||||||
select REGMAP_SPMI
|
select REGMAP_SPMI
|
||||||
help
|
help
|
||||||
This enables a thermal sysfs driver for Qualcomm plug-and-play (QPNP)
|
This enables a thermal sysfs driver for Qualcomm plug-and-play (QPNP)
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#define TEMPSENSE2_PANIC_VALUE_SHIFT 16
|
#define TEMPSENSE2_PANIC_VALUE_SHIFT 16
|
||||||
#define TEMPSENSE2_PANIC_VALUE_MASK 0xfff0000
|
#define TEMPSENSE2_PANIC_VALUE_MASK 0xfff0000
|
||||||
|
|
||||||
|
#define OCOTP_MEM0 0x0480
|
||||||
#define OCOTP_ANA1 0x04e0
|
#define OCOTP_ANA1 0x04e0
|
||||||
|
|
||||||
/* The driver supports 1 passive trip point and 1 critical trip point */
|
/* The driver supports 1 passive trip point and 1 critical trip point */
|
||||||
@ -64,12 +65,6 @@ enum imx_thermal_trip {
|
|||||||
IMX_TRIP_NUM,
|
IMX_TRIP_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* It defines the temperature in millicelsius for passive trip point
|
|
||||||
* that will trigger cooling action when crossed.
|
|
||||||
*/
|
|
||||||
#define IMX_TEMP_PASSIVE 85000
|
|
||||||
|
|
||||||
#define IMX_POLLING_DELAY 2000 /* millisecond */
|
#define IMX_POLLING_DELAY 2000 /* millisecond */
|
||||||
#define IMX_PASSIVE_DELAY 1000
|
#define IMX_PASSIVE_DELAY 1000
|
||||||
|
|
||||||
@ -100,12 +95,14 @@ struct imx_thermal_data {
|
|||||||
u32 c1, c2; /* See formula in imx_get_sensor_data() */
|
u32 c1, c2; /* See formula in imx_get_sensor_data() */
|
||||||
int temp_passive;
|
int temp_passive;
|
||||||
int temp_critical;
|
int temp_critical;
|
||||||
|
int temp_max;
|
||||||
int alarm_temp;
|
int alarm_temp;
|
||||||
int last_temp;
|
int last_temp;
|
||||||
bool irq_enabled;
|
bool irq_enabled;
|
||||||
int irq;
|
int irq;
|
||||||
struct clk *thermal_clk;
|
struct clk *thermal_clk;
|
||||||
const struct thermal_soc_data *socdata;
|
const struct thermal_soc_data *socdata;
|
||||||
|
const char *temp_grade;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void imx_set_panic_temp(struct imx_thermal_data *data,
|
static void imx_set_panic_temp(struct imx_thermal_data *data,
|
||||||
@ -285,10 +282,12 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
|||||||
{
|
{
|
||||||
struct imx_thermal_data *data = tz->devdata;
|
struct imx_thermal_data *data = tz->devdata;
|
||||||
|
|
||||||
|
/* do not allow changing critical threshold */
|
||||||
if (trip == IMX_TRIP_CRITICAL)
|
if (trip == IMX_TRIP_CRITICAL)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
if (temp < 0 || temp > IMX_TEMP_PASSIVE)
|
/* do not allow passive to be set higher than critical */
|
||||||
|
if (temp < 0 || temp > data->temp_critical)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
data->temp_passive = temp;
|
data->temp_passive = temp;
|
||||||
@ -404,17 +403,39 @@ static int imx_get_sensor_data(struct platform_device *pdev)
|
|||||||
data->c1 = temp64;
|
data->c1 = temp64;
|
||||||
data->c2 = n1 * data->c1 + 1000 * t1;
|
data->c2 = n1 * data->c1 + 1000 * t1;
|
||||||
|
|
||||||
/*
|
/* use OTP for thermal grade */
|
||||||
* Set the default passive cooling trip point,
|
ret = regmap_read(map, OCOTP_MEM0, &val);
|
||||||
* can be changed from userspace.
|
if (ret) {
|
||||||
*/
|
dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret);
|
||||||
data->temp_passive = IMX_TEMP_PASSIVE;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The maximum die temp is specified by the Temperature Grade */
|
||||||
|
switch ((val >> 6) & 0x3) {
|
||||||
|
case 0: /* Commercial (0 to 95C) */
|
||||||
|
data->temp_grade = "Commercial";
|
||||||
|
data->temp_max = 95000;
|
||||||
|
break;
|
||||||
|
case 1: /* Extended Commercial (-20 to 105C) */
|
||||||
|
data->temp_grade = "Extended Commercial";
|
||||||
|
data->temp_max = 105000;
|
||||||
|
break;
|
||||||
|
case 2: /* Industrial (-40 to 105C) */
|
||||||
|
data->temp_grade = "Industrial";
|
||||||
|
data->temp_max = 105000;
|
||||||
|
break;
|
||||||
|
case 3: /* Automotive (-40 to 125C) */
|
||||||
|
data->temp_grade = "Automotive";
|
||||||
|
data->temp_max = 125000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The maximum die temperature set to 20 C higher than
|
* Set the critical trip point at 5C under max
|
||||||
* IMX_TEMP_PASSIVE.
|
* Set the passive trip point at 10C under max (can change via sysfs)
|
||||||
*/
|
*/
|
||||||
data->temp_critical = 1000 * 20 + data->temp_passive;
|
data->temp_critical = data->temp_max - (1000 * 5);
|
||||||
|
data->temp_passive = data->temp_max - (1000 * 10);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -551,6 +572,11 @@ static int imx_thermal_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
|
||||||
|
" critical:%dC passive:%dC\n", data->temp_grade,
|
||||||
|
data->temp_max / 1000, data->temp_critical / 1000,
|
||||||
|
data->temp_passive / 1000);
|
||||||
|
|
||||||
/* Enable measurements at ~ 10 Hz */
|
/* Enable measurements at ~ 10 Hz */
|
||||||
regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
|
regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
|
||||||
measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
|
measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
|
||||||
|
@ -964,7 +964,7 @@ void of_thermal_destroy_zones(void)
|
|||||||
|
|
||||||
np = of_find_node_by_name(NULL, "thermal-zones");
|
np = of_find_node_by_name(NULL, "thermal-zones");
|
||||||
if (!np) {
|
if (!np) {
|
||||||
pr_err("unable to find thermal zones\n");
|
pr_debug("unable to find thermal zones\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,6 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
|
|||||||
/**
|
/**
|
||||||
* pid_controller() - PID controller
|
* pid_controller() - PID controller
|
||||||
* @tz: thermal zone we are operating in
|
* @tz: thermal zone we are operating in
|
||||||
* @current_temp: the current temperature in millicelsius
|
|
||||||
* @control_temp: the target temperature in millicelsius
|
* @control_temp: the target temperature in millicelsius
|
||||||
* @max_allocatable_power: maximum allocatable power for this thermal zone
|
* @max_allocatable_power: maximum allocatable power for this thermal zone
|
||||||
*
|
*
|
||||||
@ -191,7 +190,6 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
|
|||||||
* Return: The power budget for the next period.
|
* Return: The power budget for the next period.
|
||||||
*/
|
*/
|
||||||
static u32 pid_controller(struct thermal_zone_device *tz,
|
static u32 pid_controller(struct thermal_zone_device *tz,
|
||||||
int current_temp,
|
|
||||||
int control_temp,
|
int control_temp,
|
||||||
u32 max_allocatable_power)
|
u32 max_allocatable_power)
|
||||||
{
|
{
|
||||||
@ -211,7 +209,7 @@ static u32 pid_controller(struct thermal_zone_device *tz,
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = control_temp - current_temp;
|
err = control_temp - tz->temperature;
|
||||||
err = int_to_frac(err);
|
err = int_to_frac(err);
|
||||||
|
|
||||||
/* Calculate the proportional term */
|
/* Calculate the proportional term */
|
||||||
@ -332,7 +330,6 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int allocate_power(struct thermal_zone_device *tz,
|
static int allocate_power(struct thermal_zone_device *tz,
|
||||||
int current_temp,
|
|
||||||
int control_temp)
|
int control_temp)
|
||||||
{
|
{
|
||||||
struct thermal_instance *instance;
|
struct thermal_instance *instance;
|
||||||
@ -418,8 +415,7 @@ static int allocate_power(struct thermal_zone_device *tz,
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
power_range = pid_controller(tz, current_temp, control_temp,
|
power_range = pid_controller(tz, control_temp, max_allocatable_power);
|
||||||
max_allocatable_power);
|
|
||||||
|
|
||||||
divvy_up_power(weighted_req_power, max_power, num_actors,
|
divvy_up_power(weighted_req_power, max_power, num_actors,
|
||||||
total_weighted_req_power, power_range, granted_power,
|
total_weighted_req_power, power_range, granted_power,
|
||||||
@ -444,8 +440,8 @@ static int allocate_power(struct thermal_zone_device *tz,
|
|||||||
trace_thermal_power_allocator(tz, req_power, total_req_power,
|
trace_thermal_power_allocator(tz, req_power, total_req_power,
|
||||||
granted_power, total_granted_power,
|
granted_power, total_granted_power,
|
||||||
num_actors, power_range,
|
num_actors, power_range,
|
||||||
max_allocatable_power, current_temp,
|
max_allocatable_power, tz->temperature,
|
||||||
control_temp - current_temp);
|
control_temp - tz->temperature);
|
||||||
|
|
||||||
kfree(req_power);
|
kfree(req_power);
|
||||||
unlock:
|
unlock:
|
||||||
@ -612,7 +608,7 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
|
|||||||
static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int switch_on_temp, control_temp, current_temp;
|
int switch_on_temp, control_temp;
|
||||||
struct power_allocator_params *params = tz->governor_data;
|
struct power_allocator_params *params = tz->governor_data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -622,15 +618,9 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
|||||||
if (trip != params->trip_max_desired_temperature)
|
if (trip != params->trip_max_desired_temperature)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = thermal_zone_get_temp(tz, ¤t_temp);
|
|
||||||
if (ret) {
|
|
||||||
dev_warn(&tz->device, "Failed to get temperature: %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
|
ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
|
||||||
&switch_on_temp);
|
&switch_on_temp);
|
||||||
if (!ret && (current_temp < switch_on_temp)) {
|
if (!ret && (tz->temperature < switch_on_temp)) {
|
||||||
tz->passive = 0;
|
tz->passive = 0;
|
||||||
reset_pid_controller(params);
|
reset_pid_controller(params);
|
||||||
allow_maximum_power(tz);
|
allow_maximum_power(tz);
|
||||||
@ -648,7 +638,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return allocate_power(tz, current_temp, control_temp);
|
return allocate_power(tz, control_temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct thermal_governor thermal_gov_power_allocator = {
|
static struct thermal_governor thermal_gov_power_allocator = {
|
||||||
|
@ -361,6 +361,24 @@ static irqreturn_t rcar_thermal_irq(int irq, void *data)
|
|||||||
/*
|
/*
|
||||||
* platform functions
|
* platform functions
|
||||||
*/
|
*/
|
||||||
|
static int rcar_thermal_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct rcar_thermal_common *common = platform_get_drvdata(pdev);
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct rcar_thermal_priv *priv;
|
||||||
|
|
||||||
|
rcar_thermal_for_each_priv(priv, common) {
|
||||||
|
if (rcar_has_irq_support(priv))
|
||||||
|
rcar_thermal_irq_disable(priv);
|
||||||
|
thermal_zone_device_unregister(priv->zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_runtime_put(dev);
|
||||||
|
pm_runtime_disable(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rcar_thermal_probe(struct platform_device *pdev)
|
static int rcar_thermal_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rcar_thermal_common *common;
|
struct rcar_thermal_common *common;
|
||||||
@ -377,6 +395,8 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
|||||||
if (!common)
|
if (!common)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, common);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&common->head);
|
INIT_LIST_HEAD(&common->head);
|
||||||
spin_lock_init(&common->lock);
|
spin_lock_init(&common->lock);
|
||||||
common->dev = dev;
|
common->dev = dev;
|
||||||
@ -454,43 +474,16 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
|||||||
rcar_thermal_common_write(common, ENR, enr_bits);
|
rcar_thermal_common_write(common, ENR, enr_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, common);
|
|
||||||
|
|
||||||
dev_info(dev, "%d sensor probed\n", i);
|
dev_info(dev, "%d sensor probed\n", i);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_unregister:
|
error_unregister:
|
||||||
rcar_thermal_for_each_priv(priv, common) {
|
rcar_thermal_remove(pdev);
|
||||||
if (rcar_has_irq_support(priv))
|
|
||||||
rcar_thermal_irq_disable(priv);
|
|
||||||
thermal_zone_device_unregister(priv->zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_runtime_put(dev);
|
|
||||||
pm_runtime_disable(dev);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_thermal_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct rcar_thermal_common *common = platform_get_drvdata(pdev);
|
|
||||||
struct device *dev = &pdev->dev;
|
|
||||||
struct rcar_thermal_priv *priv;
|
|
||||||
|
|
||||||
rcar_thermal_for_each_priv(priv, common) {
|
|
||||||
if (rcar_has_irq_support(priv))
|
|
||||||
rcar_thermal_irq_disable(priv);
|
|
||||||
thermal_zone_device_unregister(priv->zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_runtime_put(dev);
|
|
||||||
pm_runtime_disable(dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct of_device_id rcar_thermal_dt_ids[] = {
|
static const struct of_device_id rcar_thermal_dt_ids[] = {
|
||||||
{ .compatible = "renesas,rcar-thermal", },
|
{ .compatible = "renesas,rcar-thermal", },
|
||||||
{},
|
{},
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
|
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
|
||||||
|
* Caesar Wang <wxt@rock-chips.com>
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
* version 2, as published by the Free Software Foundation.
|
* version 2, as published by the Free Software Foundation.
|
||||||
@ -45,17 +48,50 @@ enum tshut_polarity {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The system has three Temperature Sensors. channel 0 is reserved,
|
* The system has two Temperature Sensors.
|
||||||
* channel 1 is for CPU, and channel 2 is for GPU.
|
* sensor0 is for CPU, and sensor1 is for GPU.
|
||||||
*/
|
*/
|
||||||
enum sensor_id {
|
enum sensor_id {
|
||||||
SENSOR_CPU = 1,
|
SENSOR_CPU = 0,
|
||||||
SENSOR_GPU,
|
SENSOR_GPU,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The conversion table has the adc value and temperature.
|
||||||
|
* ADC_DECREMENT is the adc value decremnet.(e.g. v2_code_table)
|
||||||
|
* ADC_INCREMNET is the adc value incremnet.(e.g. v3_code_table)
|
||||||
|
*/
|
||||||
|
enum adc_sort_mode {
|
||||||
|
ADC_DECREMENT = 0,
|
||||||
|
ADC_INCREMENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max sensors is two in rockchip SoCs.
|
||||||
|
* Two sensors: CPU and GPU sensor.
|
||||||
|
*/
|
||||||
|
#define SOC_MAX_SENSORS 2
|
||||||
|
|
||||||
|
struct chip_tsadc_table {
|
||||||
|
const struct tsadc_table *id;
|
||||||
|
|
||||||
|
/* the array table size*/
|
||||||
|
unsigned int length;
|
||||||
|
|
||||||
|
/* that analogic mask data */
|
||||||
|
u32 data_mask;
|
||||||
|
|
||||||
|
/* the sort mode is adc value that increment or decrement in table */
|
||||||
|
enum adc_sort_mode mode;
|
||||||
|
};
|
||||||
|
|
||||||
struct rockchip_tsadc_chip {
|
struct rockchip_tsadc_chip {
|
||||||
|
/* The sensor id of chip correspond to the ADC channel */
|
||||||
|
int chn_id[SOC_MAX_SENSORS];
|
||||||
|
int chn_num;
|
||||||
|
|
||||||
/* The hardware-controlled tshut property */
|
/* The hardware-controlled tshut property */
|
||||||
long tshut_temp;
|
int tshut_temp;
|
||||||
enum tshut_mode tshut_mode;
|
enum tshut_mode tshut_mode;
|
||||||
enum tshut_polarity tshut_polarity;
|
enum tshut_polarity tshut_polarity;
|
||||||
|
|
||||||
@ -65,37 +101,40 @@ struct rockchip_tsadc_chip {
|
|||||||
void (*control)(void __iomem *reg, bool on);
|
void (*control)(void __iomem *reg, bool on);
|
||||||
|
|
||||||
/* Per-sensor methods */
|
/* Per-sensor methods */
|
||||||
int (*get_temp)(int chn, void __iomem *reg, int *temp);
|
int (*get_temp)(struct chip_tsadc_table table,
|
||||||
void (*set_tshut_temp)(int chn, void __iomem *reg, long temp);
|
int chn, void __iomem *reg, int *temp);
|
||||||
|
void (*set_tshut_temp)(struct chip_tsadc_table table,
|
||||||
|
int chn, void __iomem *reg, int temp);
|
||||||
void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);
|
void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);
|
||||||
|
|
||||||
|
/* Per-table methods */
|
||||||
|
struct chip_tsadc_table table;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rockchip_thermal_sensor {
|
struct rockchip_thermal_sensor {
|
||||||
struct rockchip_thermal_data *thermal;
|
struct rockchip_thermal_data *thermal;
|
||||||
struct thermal_zone_device *tzd;
|
struct thermal_zone_device *tzd;
|
||||||
enum sensor_id id;
|
int id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_SENSORS 2 /* Ignore unused sensor 0 */
|
|
||||||
|
|
||||||
struct rockchip_thermal_data {
|
struct rockchip_thermal_data {
|
||||||
const struct rockchip_tsadc_chip *chip;
|
const struct rockchip_tsadc_chip *chip;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct reset_control *reset;
|
struct reset_control *reset;
|
||||||
|
|
||||||
struct rockchip_thermal_sensor sensors[NUM_SENSORS];
|
struct rockchip_thermal_sensor sensors[SOC_MAX_SENSORS];
|
||||||
|
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct clk *pclk;
|
struct clk *pclk;
|
||||||
|
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
|
|
||||||
long tshut_temp;
|
int tshut_temp;
|
||||||
enum tshut_mode tshut_mode;
|
enum tshut_mode tshut_mode;
|
||||||
enum tshut_polarity tshut_polarity;
|
enum tshut_polarity tshut_polarity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TSADC V2 Sensor info define: */
|
/* TSADC Sensor info define: */
|
||||||
#define TSADCV2_AUTO_CON 0x04
|
#define TSADCV2_AUTO_CON 0x04
|
||||||
#define TSADCV2_INT_EN 0x08
|
#define TSADCV2_INT_EN 0x08
|
||||||
#define TSADCV2_INT_PD 0x0c
|
#define TSADCV2_INT_PD 0x0c
|
||||||
@ -117,6 +156,8 @@ struct rockchip_thermal_data {
|
|||||||
#define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8)
|
#define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8)
|
||||||
|
|
||||||
#define TSADCV2_DATA_MASK 0xfff
|
#define TSADCV2_DATA_MASK 0xfff
|
||||||
|
#define TSADCV3_DATA_MASK 0x3ff
|
||||||
|
|
||||||
#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4
|
#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4
|
||||||
#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4
|
#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4
|
||||||
#define TSADCV2_AUTO_PERIOD_TIME 250 /* msec */
|
#define TSADCV2_AUTO_PERIOD_TIME 250 /* msec */
|
||||||
@ -124,7 +165,7 @@ struct rockchip_thermal_data {
|
|||||||
|
|
||||||
struct tsadc_table {
|
struct tsadc_table {
|
||||||
u32 code;
|
u32 code;
|
||||||
long temp;
|
int temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct tsadc_table v2_code_table[] = {
|
static const struct tsadc_table v2_code_table[] = {
|
||||||
@ -165,21 +206,61 @@ static const struct tsadc_table v2_code_table[] = {
|
|||||||
{3421, 125000},
|
{3421, 125000},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 rk_tsadcv2_temp_to_code(long temp)
|
static const struct tsadc_table v3_code_table[] = {
|
||||||
|
{0, -40000},
|
||||||
|
{106, -40000},
|
||||||
|
{108, -35000},
|
||||||
|
{110, -30000},
|
||||||
|
{112, -25000},
|
||||||
|
{114, -20000},
|
||||||
|
{116, -15000},
|
||||||
|
{118, -10000},
|
||||||
|
{120, -5000},
|
||||||
|
{122, 0},
|
||||||
|
{124, 5000},
|
||||||
|
{126, 10000},
|
||||||
|
{128, 15000},
|
||||||
|
{130, 20000},
|
||||||
|
{132, 25000},
|
||||||
|
{134, 30000},
|
||||||
|
{136, 35000},
|
||||||
|
{138, 40000},
|
||||||
|
{140, 45000},
|
||||||
|
{142, 50000},
|
||||||
|
{144, 55000},
|
||||||
|
{146, 60000},
|
||||||
|
{148, 65000},
|
||||||
|
{150, 70000},
|
||||||
|
{152, 75000},
|
||||||
|
{154, 80000},
|
||||||
|
{156, 85000},
|
||||||
|
{158, 90000},
|
||||||
|
{160, 95000},
|
||||||
|
{162, 100000},
|
||||||
|
{163, 105000},
|
||||||
|
{165, 110000},
|
||||||
|
{167, 115000},
|
||||||
|
{169, 120000},
|
||||||
|
{171, 125000},
|
||||||
|
{TSADCV3_DATA_MASK, 125000},
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table,
|
||||||
|
int temp)
|
||||||
{
|
{
|
||||||
int high, low, mid;
|
int high, low, mid;
|
||||||
|
|
||||||
low = 0;
|
low = 0;
|
||||||
high = ARRAY_SIZE(v2_code_table) - 1;
|
high = table.length - 1;
|
||||||
mid = (high + low) / 2;
|
mid = (high + low) / 2;
|
||||||
|
|
||||||
if (temp < v2_code_table[low].temp || temp > v2_code_table[high].temp)
|
if (temp < table.id[low].temp || temp > table.id[high].temp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
if (temp == v2_code_table[mid].temp)
|
if (temp == table.id[mid].temp)
|
||||||
return v2_code_table[mid].code;
|
return table.id[mid].code;
|
||||||
else if (temp < v2_code_table[mid].temp)
|
else if (temp < table.id[mid].temp)
|
||||||
high = mid - 1;
|
high = mid - 1;
|
||||||
else
|
else
|
||||||
low = mid + 1;
|
low = mid + 1;
|
||||||
@ -189,29 +270,54 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
|
static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code,
|
||||||
|
int *temp)
|
||||||
{
|
{
|
||||||
unsigned int low = 1;
|
unsigned int low = 1;
|
||||||
unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
|
unsigned int high = table.length - 1;
|
||||||
unsigned int mid = (low + high) / 2;
|
unsigned int mid = (low + high) / 2;
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
unsigned long denom;
|
unsigned long denom;
|
||||||
|
|
||||||
BUILD_BUG_ON(ARRAY_SIZE(v2_code_table) < 2);
|
WARN_ON(table.length < 2);
|
||||||
|
|
||||||
code &= TSADCV2_DATA_MASK;
|
switch (table.mode) {
|
||||||
if (code < v2_code_table[high].code)
|
case ADC_DECREMENT:
|
||||||
return -EAGAIN; /* Incorrect reading */
|
code &= table.data_mask;
|
||||||
|
if (code < table.id[high].code)
|
||||||
|
return -EAGAIN; /* Incorrect reading */
|
||||||
|
|
||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
if (code >= v2_code_table[mid].code &&
|
if (code >= table.id[mid].code &&
|
||||||
code < v2_code_table[mid - 1].code)
|
code < table.id[mid - 1].code)
|
||||||
break;
|
break;
|
||||||
else if (code < v2_code_table[mid].code)
|
else if (code < table.id[mid].code)
|
||||||
low = mid + 1;
|
low = mid + 1;
|
||||||
else
|
else
|
||||||
high = mid - 1;
|
high = mid - 1;
|
||||||
mid = (low + high) / 2;
|
|
||||||
|
mid = (low + high) / 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ADC_INCREMENT:
|
||||||
|
code &= table.data_mask;
|
||||||
|
if (code < table.id[low].code)
|
||||||
|
return -EAGAIN; /* Incorrect reading */
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
if (code >= table.id[mid - 1].code &&
|
||||||
|
code < table.id[mid].code)
|
||||||
|
break;
|
||||||
|
else if (code > table.id[mid].code)
|
||||||
|
low = mid + 1;
|
||||||
|
else
|
||||||
|
high = mid - 1;
|
||||||
|
|
||||||
|
mid = (low + high) / 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Invalid the conversion table\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -220,24 +326,28 @@ static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
|
|||||||
* temperature between 2 table entries is linear and interpolate
|
* temperature between 2 table entries is linear and interpolate
|
||||||
* to produce less granular result.
|
* to produce less granular result.
|
||||||
*/
|
*/
|
||||||
num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
|
num = table.id[mid].temp - v2_code_table[mid - 1].temp;
|
||||||
num *= v2_code_table[mid - 1].code - code;
|
num *= abs(table.id[mid - 1].code - code);
|
||||||
denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
|
denom = abs(table.id[mid - 1].code - table.id[mid].code);
|
||||||
*temp = v2_code_table[mid - 1].temp + (num / denom);
|
*temp = table.id[mid - 1].temp + (num / denom);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rk_tsadcv2_initialize - initialize TASDC Controller
|
* rk_tsadcv2_initialize - initialize TASDC Controller.
|
||||||
* (1) Set TSADCV2_AUTO_PERIOD, configure the interleave between
|
*
|
||||||
* every two accessing of TSADC in normal operation.
|
* (1) Set TSADC_V2_AUTO_PERIOD:
|
||||||
* (2) Set TSADCV2_AUTO_PERIOD_HT, configure the interleave between
|
* Configure the interleave between every two accessing of
|
||||||
* every two accessing of TSADC after the temperature is higher
|
* TSADC in normal operation.
|
||||||
* than COM_SHUT or COM_INT.
|
*
|
||||||
* (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE,
|
* (2) Set TSADCV2_AUTO_PERIOD_HT:
|
||||||
* if the temperature is higher than COMP_INT or COMP_SHUT for
|
* Configure the interleave between every two accessing of
|
||||||
* "debounce" times, TSADC controller will generate interrupt or TSHUT.
|
* 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,
|
static void rk_tsadcv2_initialize(void __iomem *regs,
|
||||||
enum tshut_polarity tshut_polarity)
|
enum tshut_polarity tshut_polarity)
|
||||||
@ -279,20 +389,22 @@ static void rk_tsadcv2_control(void __iomem *regs, bool enable)
|
|||||||
writel_relaxed(val, regs + TSADCV2_AUTO_CON);
|
writel_relaxed(val, regs + TSADCV2_AUTO_CON);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp)
|
static int rk_tsadcv2_get_temp(struct chip_tsadc_table table,
|
||||||
|
int chn, void __iomem *regs, int *temp)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
val = readl_relaxed(regs + TSADCV2_DATA(chn));
|
val = readl_relaxed(regs + TSADCV2_DATA(chn));
|
||||||
|
|
||||||
return rk_tsadcv2_code_to_temp(val, temp);
|
return rk_tsadcv2_code_to_temp(table, val, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp)
|
static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table,
|
||||||
|
int chn, void __iomem *regs, int temp)
|
||||||
{
|
{
|
||||||
u32 tshut_value, val;
|
u32 tshut_value, val;
|
||||||
|
|
||||||
tshut_value = rk_tsadcv2_temp_to_code(temp);
|
tshut_value = rk_tsadcv2_temp_to_code(table, temp);
|
||||||
writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));
|
writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));
|
||||||
|
|
||||||
/* TSHUT will be valid */
|
/* TSHUT will be valid */
|
||||||
@ -318,6 +430,10 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
|
static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
|
||||||
|
.chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */
|
||||||
|
.chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */
|
||||||
|
.chn_num = 2, /* two channels for tsadc */
|
||||||
|
|
||||||
.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
|
.tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
|
||||||
.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
|
.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
|
||||||
.tshut_temp = 95000,
|
.tshut_temp = 95000,
|
||||||
@ -328,6 +444,37 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
|
|||||||
.get_temp = rk_tsadcv2_get_temp,
|
.get_temp = rk_tsadcv2_get_temp,
|
||||||
.set_tshut_temp = rk_tsadcv2_tshut_temp,
|
.set_tshut_temp = rk_tsadcv2_tshut_temp,
|
||||||
.set_tshut_mode = rk_tsadcv2_tshut_mode,
|
.set_tshut_mode = rk_tsadcv2_tshut_mode,
|
||||||
|
|
||||||
|
.table = {
|
||||||
|
.id = v2_code_table,
|
||||||
|
.length = ARRAY_SIZE(v2_code_table),
|
||||||
|
.data_mask = TSADCV2_DATA_MASK,
|
||||||
|
.mode = ADC_DECREMENT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rockchip_tsadc_chip rk3368_tsadc_data = {
|
||||||
|
.chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
|
||||||
|
.chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
|
||||||
|
.chn_num = 2, /* two channels for tsadc */
|
||||||
|
|
||||||
|
.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,
|
||||||
|
|
||||||
|
.table = {
|
||||||
|
.id = v3_code_table,
|
||||||
|
.length = ARRAY_SIZE(v3_code_table),
|
||||||
|
.data_mask = TSADCV3_DATA_MASK,
|
||||||
|
.mode = ADC_INCREMENT,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id of_rockchip_thermal_match[] = {
|
static const struct of_device_id of_rockchip_thermal_match[] = {
|
||||||
@ -335,6 +482,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
|
|||||||
.compatible = "rockchip,rk3288-tsadc",
|
.compatible = "rockchip,rk3288-tsadc",
|
||||||
.data = (void *)&rk3288_tsadc_data,
|
.data = (void *)&rk3288_tsadc_data,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.compatible = "rockchip,rk3368-tsadc",
|
||||||
|
.data = (void *)&rk3368_tsadc_data,
|
||||||
|
},
|
||||||
{ /* end */ },
|
{ /* end */ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
|
MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
|
||||||
@ -357,7 +508,7 @@ static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
|
|||||||
|
|
||||||
thermal->chip->irq_ack(thermal->regs);
|
thermal->chip->irq_ack(thermal->regs);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
|
for (i = 0; i < thermal->chip->chn_num; i++)
|
||||||
thermal_zone_device_update(thermal->sensors[i].tzd);
|
thermal_zone_device_update(thermal->sensors[i].tzd);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
@ -370,7 +521,8 @@ static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
|
|||||||
const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip;
|
const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
retval = tsadc->get_temp(sensor->id, thermal->regs, out_temp);
|
retval = tsadc->get_temp(tsadc->table,
|
||||||
|
sensor->id, thermal->regs, out_temp);
|
||||||
dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
|
dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
|
||||||
sensor->id, *out_temp, retval);
|
sensor->id, *out_temp, retval);
|
||||||
|
|
||||||
@ -389,7 +541,7 @@ static int rockchip_configure_from_dt(struct device *dev,
|
|||||||
|
|
||||||
if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {
|
if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {
|
||||||
dev_warn(dev,
|
dev_warn(dev,
|
||||||
"Missing tshut temp property, using default %ld\n",
|
"Missing tshut temp property, using default %d\n",
|
||||||
thermal->chip->tshut_temp);
|
thermal->chip->tshut_temp);
|
||||||
thermal->tshut_temp = thermal->chip->tshut_temp;
|
thermal->tshut_temp = thermal->chip->tshut_temp;
|
||||||
} else {
|
} else {
|
||||||
@ -397,7 +549,7 @@ static int rockchip_configure_from_dt(struct device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (thermal->tshut_temp > INT_MAX) {
|
if (thermal->tshut_temp > INT_MAX) {
|
||||||
dev_err(dev, "Invalid tshut temperature specified: %ld\n",
|
dev_err(dev, "Invalid tshut temperature specified: %d\n",
|
||||||
thermal->tshut_temp);
|
thermal->tshut_temp);
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
@ -442,13 +594,14 @@ static int
|
|||||||
rockchip_thermal_register_sensor(struct platform_device *pdev,
|
rockchip_thermal_register_sensor(struct platform_device *pdev,
|
||||||
struct rockchip_thermal_data *thermal,
|
struct rockchip_thermal_data *thermal,
|
||||||
struct rockchip_thermal_sensor *sensor,
|
struct rockchip_thermal_sensor *sensor,
|
||||||
enum sensor_id id)
|
int id)
|
||||||
{
|
{
|
||||||
const struct rockchip_tsadc_chip *tsadc = thermal->chip;
|
const struct rockchip_tsadc_chip *tsadc = thermal->chip;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
|
tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
|
||||||
tsadc->set_tshut_temp(id, thermal->regs, thermal->tshut_temp);
|
tsadc->set_tshut_temp(tsadc->table, id, thermal->regs,
|
||||||
|
thermal->tshut_temp);
|
||||||
|
|
||||||
sensor->thermal = thermal;
|
sensor->thermal = thermal;
|
||||||
sensor->id = id;
|
sensor->id = id;
|
||||||
@ -481,7 +634,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
|
|||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int irq;
|
int irq;
|
||||||
int i;
|
int i, j;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
match = of_match_node(of_rockchip_thermal_match, np);
|
match = of_match_node(of_rockchip_thermal_match, np);
|
||||||
@ -556,22 +709,19 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);
|
thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);
|
||||||
|
|
||||||
error = rockchip_thermal_register_sensor(pdev, thermal,
|
for (i = 0; i < thermal->chip->chn_num; i++) {
|
||||||
&thermal->sensors[0],
|
error = rockchip_thermal_register_sensor(pdev, thermal,
|
||||||
SENSOR_CPU);
|
&thermal->sensors[i],
|
||||||
if (error) {
|
thermal->chip->chn_id[i]);
|
||||||
dev_err(&pdev->dev,
|
if (error) {
|
||||||
"failed to register CPU thermal sensor: %d\n", error);
|
dev_err(&pdev->dev,
|
||||||
goto err_disable_pclk;
|
"failed to register sensor[%d] : error = %d\n",
|
||||||
}
|
i, error);
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
error = rockchip_thermal_register_sensor(pdev, thermal,
|
thermal_zone_of_sensor_unregister(&pdev->dev,
|
||||||
&thermal->sensors[1],
|
thermal->sensors[j].tzd);
|
||||||
SENSOR_GPU);
|
goto err_disable_pclk;
|
||||||
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,
|
error = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||||
@ -581,22 +731,23 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
|
|||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"failed to request tsadc irq: %d\n", error);
|
"failed to request tsadc irq: %d\n", error);
|
||||||
goto err_unregister_gpu_sensor;
|
goto err_unregister_sensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
thermal->chip->control(thermal->regs, true);
|
thermal->chip->control(thermal->regs, true);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
|
for (i = 0; i < thermal->chip->chn_num; i++)
|
||||||
rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
|
rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, thermal);
|
platform_set_drvdata(pdev, thermal);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_unregister_gpu_sensor:
|
err_unregister_sensor:
|
||||||
thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[1].tzd);
|
while (i--)
|
||||||
err_unregister_cpu_sensor:
|
thermal_zone_of_sensor_unregister(&pdev->dev,
|
||||||
thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[0].tzd);
|
thermal->sensors[i].tzd);
|
||||||
|
|
||||||
err_disable_pclk:
|
err_disable_pclk:
|
||||||
clk_disable_unprepare(thermal->pclk);
|
clk_disable_unprepare(thermal->pclk);
|
||||||
err_disable_clk:
|
err_disable_clk:
|
||||||
@ -610,7 +761,7 @@ static int rockchip_thermal_remove(struct platform_device *pdev)
|
|||||||
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
|
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) {
|
for (i = 0; i < thermal->chip->chn_num; i++) {
|
||||||
struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
|
struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
|
||||||
|
|
||||||
rockchip_thermal_toggle_sensor(sensor, false);
|
rockchip_thermal_toggle_sensor(sensor, false);
|
||||||
@ -631,7 +782,7 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
|
|||||||
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
|
struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
|
for (i = 0; i < thermal->chip->chn_num; i++)
|
||||||
rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
|
rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
|
||||||
|
|
||||||
thermal->chip->control(thermal->regs, false);
|
thermal->chip->control(thermal->regs, false);
|
||||||
@ -663,18 +814,19 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
|
|||||||
|
|
||||||
thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);
|
thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) {
|
for (i = 0; i < thermal->chip->chn_num; i++) {
|
||||||
enum sensor_id id = thermal->sensors[i].id;
|
int id = thermal->sensors[i].id;
|
||||||
|
|
||||||
thermal->chip->set_tshut_mode(id, thermal->regs,
|
thermal->chip->set_tshut_mode(id, thermal->regs,
|
||||||
thermal->tshut_mode);
|
thermal->tshut_mode);
|
||||||
thermal->chip->set_tshut_temp(id, thermal->regs,
|
thermal->chip->set_tshut_temp(thermal->chip->table,
|
||||||
|
id, thermal->regs,
|
||||||
thermal->tshut_temp);
|
thermal->tshut_temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
thermal->chip->control(thermal->regs, true);
|
thermal->chip->control(thermal->regs, true);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
|
for (i = 0; i < thermal->chip->chn_num; i++)
|
||||||
rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
|
rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
|
||||||
|
|
||||||
pinctrl_pm_select_default_state(dev);
|
pinctrl_pm_select_default_state(dev);
|
||||||
|
@ -438,7 +438,8 @@ static inline void thermal_zone_device_unregister(
|
|||||||
static inline int thermal_zone_bind_cooling_device(
|
static inline int thermal_zone_bind_cooling_device(
|
||||||
struct thermal_zone_device *tz, int trip,
|
struct thermal_zone_device *tz, int trip,
|
||||||
struct thermal_cooling_device *cdev,
|
struct thermal_cooling_device *cdev,
|
||||||
unsigned long upper, unsigned long lower)
|
unsigned long upper, unsigned long lower,
|
||||||
|
unsigned int weight)
|
||||||
{ return -ENODEV; }
|
{ return -ENODEV; }
|
||||||
static inline int thermal_zone_unbind_cooling_device(
|
static inline int thermal_zone_unbind_cooling_device(
|
||||||
struct thermal_zone_device *tz, int trip,
|
struct thermal_zone_device *tz, int trip,
|
||||||
|
Loading…
Reference in New Issue
Block a user