Skip to content

Commit 47b2d3d

Browse files
Niklas Söderlundrafaeljw
authored andcommitted
thermal/drivers/rcar_gen3_thermal: Fix device initialization
The thermal zone is registered before the device is register and the thermal coefficients are calculated, providing a window for very incorrect readings. The reason why the zone was register before the device was fully initialized was that the presence of the set_trips() callback is used to determine if the driver supports interrupt or not, as it is not defined if the device is incapable of interrupts. Fix this by using the operations structure in the private data instead of the zone to determine if interrupts are available or not, and initialize the device before registering the zone. Signed-off-by: Niklas Söderlund <[email protected]> Reviewed-by: Wolfram Sang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Daniel Lezcano <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent aef43e0 commit 47b2d3d

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

drivers/thermal/rcar_gen3_thermal.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ struct rcar_gen3_thermal_priv {
8989
struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
9090
struct thermal_zone_device_ops ops;
9191
unsigned int num_tscs;
92-
void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc);
92+
void (*thermal_init)(struct rcar_gen3_thermal_priv *priv,
93+
struct rcar_gen3_thermal_tsc *tsc);
9394
int ptat[3];
9495
};
9596

@@ -240,7 +241,7 @@ static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
240241
for (i = 0; i < priv->num_tscs; i++) {
241242
status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR);
242243
rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0);
243-
if (status)
244+
if (status && priv->tscs[i]->zone)
244245
thermal_zone_device_update(priv->tscs[i]->zone,
245246
THERMAL_EVENT_UNSPECIFIED);
246247
}
@@ -311,7 +312,8 @@ static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
311312
return true;
312313
}
313314

314-
static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc)
315+
static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_priv *priv,
316+
struct rcar_gen3_thermal_tsc *tsc)
315317
{
316318
rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR);
317319
rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0);
@@ -322,7 +324,7 @@ static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc)
322324

323325
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
324326
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
325-
if (tsc->zone->ops->set_trips)
327+
if (priv->ops.set_trips)
326328
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN,
327329
IRQ_TEMPD1 | IRQ_TEMP2);
328330

@@ -338,7 +340,8 @@ static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc)
338340
usleep_range(1000, 2000);
339341
}
340342

341-
static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
343+
static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv,
344+
struct rcar_gen3_thermal_tsc *tsc)
342345
{
343346
u32 reg_val;
344347

@@ -350,7 +353,7 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
350353

351354
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0);
352355
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
353-
if (tsc->zone->ops->set_trips)
356+
if (priv->ops.set_trips)
354357
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN,
355358
IRQ_TEMPD1 | IRQ_TEMP2);
356359

@@ -514,6 +517,9 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
514517
for (i = 0; i < priv->num_tscs; i++) {
515518
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
516519

520+
priv->thermal_init(priv, tsc);
521+
rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1);
522+
517523
zone = devm_thermal_of_zone_register(dev, i, tsc, &priv->ops);
518524
if (IS_ERR(zone)) {
519525
dev_err(dev, "Sensor %u: Can't register thermal zone\n", i);
@@ -522,9 +528,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
522528
}
523529
tsc->zone = zone;
524530

525-
priv->thermal_init(tsc);
526-
rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1);
527-
528531
tsc->zone->tzp->no_hwmon = false;
529532
ret = thermal_add_hwmon_sysfs(tsc->zone);
530533
if (ret)
@@ -562,7 +565,7 @@ static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev)
562565
for (i = 0; i < priv->num_tscs; i++) {
563566
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
564567

565-
priv->thermal_init(tsc);
568+
priv->thermal_init(priv, tsc);
566569
}
567570

568571
return 0;

0 commit comments

Comments
 (0)