diff options
author | Anjelique Melendez <anjelique.melendez@oss.qualcomm.com> | 2025-07-10 15:45:53 -0700 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2025-07-13 18:01:10 +0200 |
commit | 1f835c6a4c844d7667ba0f8e47e685549719f0d6 (patch) | |
tree | 8a2a29e410fb98e5e1e4084c6f48f92c5663df86 | |
parent | 703f13285a6c5d94e67e5fe2a8c15ee51e1d76ca (diff) |
thermal/drivers/qcom-spmi-temp-alarm: Prepare to support additional Temp Alarm subtypes
In preparation to support newer temp alarm subtypes, add the "ops",
"sync_thresholds" and "configure_trip_temps" references to
spmi_temp_alarm_data. This will allow for each Temp Alarm subtype to define
its own thermal_zone_device_ops and properly initialize and configure
thermal trip temperature.
Signed-off-by: Anjelique Melendez <anjelique.melendez@oss.qualcomm.com>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250710224555.3047790-4-anjelique.melendez@oss.qualcomm.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r-- | drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 607838162c7d0..c8e4db585d2bf 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -77,8 +77,11 @@ static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = { struct qpnp_tm_chip; struct spmi_temp_alarm_data { + const struct thermal_zone_device_ops *ops; const long (*temp_map)[THRESH_COUNT][STAGE_COUNT]; + int (*sync_thresholds)(struct qpnp_tm_chip *chip); int (*get_temp_stage)(struct qpnp_tm_chip *chip); + int (*configure_trip_temps)(struct qpnp_tm_chip *chip); }; struct qpnp_tm_chip { @@ -316,64 +319,95 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data) return IRQ_HANDLED; } +/* Read the hardware default stage threshold temperatures */ +static int qpnp_tm_sync_thresholds(struct qpnp_tm_chip *chip) +{ + u8 reg, threshold; + int ret; + + ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, ®); + if (ret < 0) + return ret; + + threshold = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK; + memcpy(chip->temp_thresh_map, chip->data->temp_map[threshold], + sizeof(chip->temp_thresh_map)); + + return ret; +} + +static int qpnp_tm_configure_trip_temp(struct qpnp_tm_chip *chip) +{ + int crit_temp, ret; + + ret = thermal_zone_get_crit_temp(chip->tz_dev, &crit_temp); + if (ret) + crit_temp = THERMAL_TEMP_INVALID; + + mutex_lock(&chip->lock); + ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); + mutex_unlock(&chip->lock); + + return ret; +} + static const struct spmi_temp_alarm_data spmi_temp_alarm_data = { + .ops = &qpnp_tm_sensor_ops, .temp_map = &temp_map_gen1, + .sync_thresholds = qpnp_tm_sync_thresholds, + .configure_trip_temps = qpnp_tm_configure_trip_temp, .get_temp_stage = qpnp_tm_gen1_get_temp_stage, }; static const struct spmi_temp_alarm_data spmi_temp_alarm_gen2_data = { + .ops = &qpnp_tm_sensor_ops, .temp_map = &temp_map_gen1, + .sync_thresholds = qpnp_tm_sync_thresholds, + .configure_trip_temps = qpnp_tm_configure_trip_temp, .get_temp_stage = qpnp_tm_gen2_get_temp_stage, }; static const struct spmi_temp_alarm_data spmi_temp_alarm_gen2_rev1_data = { + .ops = &qpnp_tm_sensor_ops, .temp_map = &temp_map_gen2_v1, + .sync_thresholds = qpnp_tm_sync_thresholds, + .configure_trip_temps = qpnp_tm_configure_trip_temp, .get_temp_stage = qpnp_tm_gen2_get_temp_stage, }; /* * This function initializes the internal temp value based on only the - * current thermal stage and threshold. Setup threshold control and - * disable shutdown override. + * current thermal stage and threshold. */ -static int qpnp_tm_init(struct qpnp_tm_chip *chip) +static int qpnp_tm_threshold_init(struct qpnp_tm_chip *chip) { - int crit_temp; - u8 threshold; int ret; - u8 reg; - mutex_lock(&chip->lock); - - ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, ®); + ret = chip->data->sync_thresholds(chip); if (ret < 0) - goto out; - - threshold = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK; - memcpy(chip->temp_thresh_map, chip->data->temp_map[threshold], - sizeof(chip->temp_thresh_map)); - - chip->temp = DEFAULT_TEMP; + return ret; ret = chip->data->get_temp_stage(chip); if (ret < 0) - goto out; + return ret; chip->stage = ret; + chip->temp = DEFAULT_TEMP; if (chip->stage) chip->temp = qpnp_tm_decode_temp(chip, chip->stage); - mutex_unlock(&chip->lock); - - ret = thermal_zone_get_crit_temp(chip->tz_dev, &crit_temp); - if (ret) - crit_temp = THERMAL_TEMP_INVALID; + return ret; +} - mutex_lock(&chip->lock); +/* This function initializes threshold control and disables shutdown override. */ +static int qpnp_tm_init(struct qpnp_tm_chip *chip) +{ + int ret; + u8 reg; - ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); + ret = chip->data->configure_trip_temps(chip); if (ret < 0) - goto out; + return ret; /* Enable the thermal alarm PMIC module in always-on mode. */ reg = ALARM_CTRL_FORCE_ENABLE; @@ -381,8 +415,6 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) chip->initialized = true; -out: - mutex_unlock(&chip->lock); return ret; } @@ -481,13 +513,17 @@ static int qpnp_tm_probe(struct platform_device *pdev) } } + ret = qpnp_tm_threshold_init(chip); + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, "threshold init failed\n"); + /* * Register the sensor before initializing the hardware to be able to * read the trip points. get_temp() returns the default temperature * before the hardware initialization is completed. */ chip->tz_dev = devm_thermal_of_zone_register( - &pdev->dev, 0, chip, &qpnp_tm_sensor_ops); + &pdev->dev, 0, chip, chip->data->ops); if (IS_ERR(chip->tz_dev)) return dev_err_probe(&pdev->dev, PTR_ERR(chip->tz_dev), "failed to register sensor\n"); |