Commit 5314b154 authored by Mateusz Majewski's avatar Mateusz Majewski Committed by Daniel Lezcano

thermal/drivers/exynos: Use set_trips ops

Currently, each trip point defined in the device tree corresponds to a
single hardware interrupt. This commit instead switches to using two
hardware interrupts, whose values are set dynamically using the
set_trips callback. Additionally, the critical temperature threshold is
handled specifically.

Setting interrupts in this way also fixes a long-standing lockdep
warning, which was caused by calling thermal_zone_get_trips with our
lock being held. Do note that this requires TMU initialization to be
split into two parts, as done by the parent commit: parts of the
initialization call into the thermal_zone_device structure and so must
be done after its registration, but the initialization is also
responsible for setting up calibration, which must be done before
thermal_zone_device registration, which will call set_trips for the
first time; if the calibration is not done in time, the interrupt values
will be silently wrong!
Reviewed-by: default avatarLukasz Luba <lukasz.luba@arm.com>
Signed-off-by: default avatarMateusz Majewski <m.majewski2@samsung.com>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20231201095625.301884-10-m.majewski2@samsung.com
parent af00d488
......@@ -158,10 +158,12 @@ enum soc_type {
* in the positive-TC generator block
* 0 < reference_voltage <= 31
* @tzd: pointer to thermal_zone_device structure
* @ntrip: number of supported trip points.
* @enabled: current status of TMU device
* @tmu_set_trip_temp: SoC specific method to set trip (rising threshold)
* @tmu_set_trip_hyst: SoC specific to set hysteresis (falling threshold)
* @tmu_set_low_temp: SoC specific method to set trip (falling threshold)
* @tmu_set_high_temp: SoC specific method to set trip (rising threshold)
* @tmu_set_crit_temp: SoC specific method to set critical temperature
* @tmu_disable_low: SoC specific method to disable an interrupt (falling threshold)
* @tmu_disable_high: SoC specific method to disable an interrupt (rising threshold)
* @tmu_initialize: SoC specific TMU initialization method
* @tmu_control: SoC specific TMU control method
* @tmu_read: SoC specific TMU temperature read method
......@@ -183,13 +185,13 @@ struct exynos_tmu_data {
u8 gain;
u8 reference_voltage;
struct thermal_zone_device *tzd;
unsigned int ntrip;
bool enabled;
void (*tmu_set_trip_temp)(struct exynos_tmu_data *data, int trip,
u8 temp);
void (*tmu_set_trip_hyst)(struct exynos_tmu_data *data, int trip,
u8 temp, u8 hyst);
void (*tmu_set_low_temp)(struct exynos_tmu_data *data, u8 temp);
void (*tmu_set_high_temp)(struct exynos_tmu_data *data, u8 temp);
void (*tmu_set_crit_temp)(struct exynos_tmu_data *data, u8 temp);
void (*tmu_disable_low)(struct exynos_tmu_data *data);
void (*tmu_disable_high)(struct exynos_tmu_data *data);
void (*tmu_initialize)(struct platform_device *pdev);
void (*tmu_control)(struct platform_device *pdev, bool on);
int (*tmu_read)(struct exynos_tmu_data *data);
......@@ -279,49 +281,28 @@ static int exynos_thermal_zone_configure(struct platform_device *pdev)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tzd = data->tzd;
int i, num_trips = thermal_zone_get_num_trips(tzd);
int ret = 0, temp;
int ret, temp;
ret = thermal_zone_get_crit_temp(tzd, &temp);
if (ret) {
/* FIXME: Remove this special case */
if (data->soc == SOC_ARCH_EXYNOS5433)
return 0;
if (ret && data->soc != SOC_ARCH_EXYNOS5433) { /* FIXME */
dev_err(&pdev->dev,
"No CRITICAL trip point defined in device tree!\n");
goto out;
return ret;
}
mutex_lock(&data->lock);
if (num_trips > data->ntrip) {
dev_info(&pdev->dev,
"More trip points than supported by this TMU.\n");
dev_info(&pdev->dev,
"%d trip points should be configured in polling mode.\n",
num_trips - data->ntrip);
}
clk_enable(data->clk);
num_trips = min_t(int, num_trips, data->ntrip);
/* Write temperature code for rising and falling threshold */
for (i = 0; i < num_trips; i++) {
struct thermal_trip trip;
data->tmu_set_crit_temp(data, temp / MCELSIUS);
ret = thermal_zone_get_trip(tzd, i, &trip);
if (ret)
goto err;
data->tmu_set_trip_temp(data, i, trip.temperature / MCELSIUS);
data->tmu_set_trip_hyst(data, i, trip.temperature / MCELSIUS,
trip.hysteresis / MCELSIUS);
}
err:
clk_disable(data->clk);
mutex_unlock(&data->lock);
out:
return ret;
return 0;
}
static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
......@@ -354,17 +335,74 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
mutex_unlock(&data->lock);
}
static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data,
int trip_id, u8 temp)
static void exynos_tmu_update_bit(struct exynos_tmu_data *data, int reg_off,
int bit_off, bool enable)
{
u32 interrupt_en;
interrupt_en = readl(data->base + reg_off);
if (enable)
interrupt_en |= BIT(bit_off);
else
interrupt_en &= ~BIT(bit_off);
writel(interrupt_en, data->base + reg_off);
}
static void exynos_tmu_update_temp(struct exynos_tmu_data *data, int reg_off,
int bit_off, u8 temp)
{
u16 tmu_temp_mask;
u32 th;
tmu_temp_mask =
(data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
: EXYNOS_TMU_TEMP_MASK;
th = readl(data->base + reg_off);
th &= ~(tmu_temp_mask << bit_off);
th |= temp_to_code(data, temp) << bit_off;
writel(th, data->base + reg_off);
}
static void exynos4210_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
{
/*
* Failing thresholds are not supported on Exynos 4210.
* We use polling instead.
*/
}
static void exynos4210_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
{
temp = temp_to_code(data, temp);
writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip_id * 4);
writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + 4);
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, true);
}
static void exynos4210_tmu_disable_low(struct exynos_tmu_data *data)
{
/* Again, this is handled by polling. */
}
/* failing thresholds are not supported on Exynos4210 */
static void exynos4210_tmu_set_trip_hyst(struct exynos_tmu_data *data,
int trip, u8 temp, u8 hyst)
static void exynos4210_tmu_disable_high(struct exynos_tmu_data *data)
{
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, false);
}
static void exynos4210_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
{
/*
* Hardware critical temperature handling is not supported on Exynos 4210.
* We still set the critical temperature threshold, but this is only to
* make sure it is handled as soon as possible. It is just a normal interrupt.
*/
temp = temp_to_code(data, temp);
writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + 12);
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_RISE0_SHIFT + 12, true);
}
static void exynos4210_tmu_initialize(struct platform_device *pdev)
......@@ -376,33 +414,31 @@ static void exynos4210_tmu_initialize(struct platform_device *pdev)
writeb(0, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
}
static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data,
int trip, u8 temp)
static void exynos4412_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
{
u32 th, con;
th = readl(data->base + EXYNOS_THD_TEMP_RISE);
th &= ~(0xff << 8 * trip);
th |= temp_to_code(data, temp) << 8 * trip;
writel(th, data->base + EXYNOS_THD_TEMP_RISE);
exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_FALL, 0, temp);
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
}
if (trip == 3) {
con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
con |= BIT(EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
}
static void exynos4412_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
{
exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_RISE, 8, temp);
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, true);
}
static void exynos4412_tmu_set_trip_hyst(struct exynos_tmu_data *data,
int trip, u8 temp, u8 hyst)
static void exynos4412_tmu_disable_low(struct exynos_tmu_data *data)
{
u32 th;
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_FALL0_SHIFT, false);
}
th = readl(data->base + EXYNOS_THD_TEMP_FALL);
th &= ~(0xff << 8 * trip);
if (hyst)
th |= temp_to_code(data, temp - hyst) << 8 * trip;
writel(th, data->base + EXYNOS_THD_TEMP_FALL);
static void exynos4412_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
{
exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_RISE, 24, temp);
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
}
static void exynos4412_tmu_initialize(struct platform_device *pdev)
......@@ -432,44 +468,39 @@ static void exynos4412_tmu_initialize(struct platform_device *pdev)
sanitize_temp_error(data, trim_info);
}
static void exynos5433_tmu_set_trip_temp(struct exynos_tmu_data *data,
int trip, u8 temp)
static void exynos5433_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
{
unsigned int reg_off, j;
u32 th;
if (trip > 3) {
reg_off = EXYNOS5433_THD_TEMP_RISE7_4;
j = trip - 4;
} else {
reg_off = EXYNOS5433_THD_TEMP_RISE3_0;
j = trip;
}
exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_FALL3_0, 0, temp);
exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
}
th = readl(data->base + reg_off);
th &= ~(0xff << j * 8);
th |= (temp_to_code(data, temp) << j * 8);
writel(th, data->base + reg_off);
static void exynos5433_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
{
exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_RISE3_0, 8, temp);
exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
}
static void exynos5433_tmu_set_trip_hyst(struct exynos_tmu_data *data,
int trip, u8 temp, u8 hyst)
static void exynos5433_tmu_disable_low(struct exynos_tmu_data *data)
{
unsigned int reg_off, j;
u32 th;
exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_FALL0_SHIFT, false);
}
if (trip > 3) {
reg_off = EXYNOS5433_THD_TEMP_FALL7_4;
j = trip - 4;
} else {
reg_off = EXYNOS5433_THD_TEMP_FALL3_0;
j = trip;
}
static void exynos5433_tmu_disable_high(struct exynos_tmu_data *data)
{
exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
}
th = readl(data->base + reg_off);
th &= ~(0xff << j * 8);
th |= (temp_to_code(data, temp - hyst) << j * 8);
writel(th, data->base + reg_off);
static void exynos5433_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
{
exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_RISE7_4, 24, temp);
exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
}
static void exynos5433_tmu_initialize(struct platform_device *pdev)
......@@ -505,34 +536,41 @@ static void exynos5433_tmu_initialize(struct platform_device *pdev)
cal_type ? 2 : 1);
}
static void exynos7_tmu_set_trip_temp(struct exynos_tmu_data *data,
int trip, u8 temp)
static void exynos7_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
{
unsigned int reg_off, bit_off;
u32 th;
reg_off = ((7 - trip) / 2) * 4;
bit_off = ((8 - trip) % 2);
exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_FALL7_6 + 12, 0, temp);
exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, true);
}
th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
th |= temp_to_code(data, temp) << (16 * bit_off);
writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
static void exynos7_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
{
exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_RISE7_6 + 12, 16, temp);
exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
}
static void exynos7_tmu_set_trip_hyst(struct exynos_tmu_data *data,
int trip, u8 temp, u8 hyst)
static void exynos7_tmu_disable_low(struct exynos_tmu_data *data)
{
unsigned int reg_off, bit_off;
u32 th;
exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, false);
}
reg_off = ((7 - trip) / 2) * 4;
bit_off = ((8 - trip) % 2);
static void exynos7_tmu_disable_high(struct exynos_tmu_data *data)
{
exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
}
th = readl(data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off);
th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
th |= temp_to_code(data, temp - hyst) << (16 * bit_off);
writel(th, data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off);
static void exynos7_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
{
/*
* Like Exynos 4210, Exynos 7 does not seem to support critical temperature
* handling in hardware. Again, we still set a separate interrupt for it.
*/
exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_RISE7_6 + 0, 16, temp);
exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
}
static void exynos7_tmu_initialize(struct platform_device *pdev)
......@@ -547,87 +585,44 @@ static void exynos7_tmu_initialize(struct platform_device *pdev)
static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tz = data->tzd;
struct thermal_trip trip;
unsigned int con, interrupt_en = 0, i;
unsigned int con;
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
if (on) {
for (i = 0; i < data->ntrip; i++) {
if (thermal_zone_get_trip(tz, i, &trip))
continue;
interrupt_en |=
BIT(EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4);
}
if (data->soc != SOC_ARCH_EXYNOS4210)
interrupt_en |=
interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
if (on)
con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
} else {
else
con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
}
writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
}
static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tz = data->tzd;
struct thermal_trip trip;
unsigned int con, interrupt_en = 0, pd_det_en, i;
unsigned int con, pd_det_en;
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
if (on) {
for (i = 0; i < data->ntrip; i++) {
if (thermal_zone_get_trip(tz, i, &trip))
continue;
interrupt_en |=
BIT(EXYNOS7_TMU_INTEN_RISE0_SHIFT + i);
}
interrupt_en |=
interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
if (on)
con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
} else
else
con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN);
writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
}
static void exynos7_tmu_control(struct platform_device *pdev, bool on)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tz = data->tzd;
struct thermal_trip trip;
unsigned int con, interrupt_en = 0, i;
unsigned int con;
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
if (on) {
for (i = 0; i < data->ntrip; i++) {
if (thermal_zone_get_trip(tz, i, &trip))
continue;
interrupt_en |=
BIT(EXYNOS7_TMU_INTEN_RISE0_SHIFT + i);
}
interrupt_en |=
interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
con |= BIT(EXYNOS7_PD_DET_EN_SHIFT);
} else {
......@@ -635,7 +630,6 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on)
con &= ~BIT(EXYNOS7_PD_DET_EN_SHIFT);
}
writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN);
writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
}
......@@ -873,13 +867,15 @@ static int exynos_map_dt_data(struct platform_device *pdev)
switch (data->soc) {
case SOC_ARCH_EXYNOS4210:
data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp;
data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst;
data->tmu_set_low_temp = exynos4210_tmu_set_low_temp;
data->tmu_set_high_temp = exynos4210_tmu_set_high_temp;
data->tmu_disable_low = exynos4210_tmu_disable_low;
data->tmu_disable_high = exynos4210_tmu_disable_high;
data->tmu_set_crit_temp = exynos4210_tmu_set_crit_temp;
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;
data->ntrip = 4;
data->gain = 15;
data->reference_voltage = 7;
data->efuse_value = 55;
......@@ -892,14 +888,16 @@ static int exynos_map_dt_data(struct platform_device *pdev)
case SOC_ARCH_EXYNOS5260:
case SOC_ARCH_EXYNOS5420:
case SOC_ARCH_EXYNOS5420_TRIMINFO:
data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp;
data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst;
data->tmu_set_low_temp = exynos4412_tmu_set_low_temp;
data->tmu_set_high_temp = exynos4412_tmu_set_high_temp;
data->tmu_disable_low = exynos4412_tmu_disable_low;
data->tmu_disable_high = exynos4210_tmu_disable_high;
data->tmu_set_crit_temp = exynos4412_tmu_set_crit_temp;
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;
data->ntrip = 4;
data->gain = 8;
data->reference_voltage = 16;
data->efuse_value = 55;
......@@ -911,14 +909,16 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->max_efuse_value = 100;
break;
case SOC_ARCH_EXYNOS5433:
data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp;
data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst;
data->tmu_set_low_temp = exynos5433_tmu_set_low_temp;
data->tmu_set_high_temp = exynos5433_tmu_set_high_temp;
data->tmu_disable_low = exynos5433_tmu_disable_low;
data->tmu_disable_high = exynos5433_tmu_disable_high;
data->tmu_set_crit_temp = exynos5433_tmu_set_crit_temp;
data->tmu_initialize = exynos5433_tmu_initialize;
data->tmu_control = exynos5433_tmu_control;
data->tmu_read = exynos4412_tmu_read;
data->tmu_set_emulation = exynos4412_tmu_set_emulation;
data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
data->ntrip = 8;
data->gain = 8;
if (res.start == EXYNOS5433_G3D_BASE)
data->reference_voltage = 23;
......@@ -929,14 +929,16 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->max_efuse_value = 150;
break;
case SOC_ARCH_EXYNOS7:
data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp;
data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst;
data->tmu_set_low_temp = exynos7_tmu_set_low_temp;
data->tmu_set_high_temp = exynos7_tmu_set_high_temp;
data->tmu_disable_low = exynos7_tmu_disable_low;
data->tmu_disable_high = exynos7_tmu_disable_high;
data->tmu_set_crit_temp = exynos7_tmu_set_crit_temp;
data->tmu_initialize = exynos7_tmu_initialize;
data->tmu_control = exynos7_tmu_control;
data->tmu_read = exynos7_tmu_read;
data->tmu_set_emulation = exynos4412_tmu_set_emulation;
data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
data->ntrip = 8;
data->gain = 9;
data->reference_voltage = 17;
data->efuse_value = 75;
......@@ -972,9 +974,32 @@ static int exynos_map_dt_data(struct platform_device *pdev)
return 0;
}
static int exynos_set_trips(struct thermal_zone_device *tz, int low, int high)
{
struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
mutex_lock(&data->lock);
clk_enable(data->clk);
if (low > INT_MIN)
data->tmu_set_low_temp(data, low / MCELSIUS);
else
data->tmu_disable_low(data);
if (high < INT_MAX)
data->tmu_set_high_temp(data, high / MCELSIUS);
else
data->tmu_disable_high(data);
clk_disable(data->clk);
mutex_unlock(&data->lock);
return 0;
}
static const struct thermal_zone_device_ops exynos_sensor_ops = {
.get_temp = exynos_get_temp,
.set_emul_temp = exynos_tmu_set_emulation,
.set_trips = exynos_set_trips,
};
static int exynos_tmu_probe(struct platform_device *pdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment