From b28c171a2a3471e4808383026161ae76b39f305a Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Wed, 30 Mar 2022 01:03:02 +0530 Subject: [PATCH] driver: thermal: qcom: clear all mitigation when thermal zone is disabled Whenever a thermal zone is in trip violated state, there is a chance that the same thermal zone mode can be disabled either via thermal core API or via thermal zone sysfs. But thermal core doesn't guarantee that it will clear all mitigation on disabling thermal zone. Monitor thermal zone mode_change callback in different sensor drivers and add support to clear all mitigation on thermal zone disablement. Change-Id: I82720be5b1b9016d218f9a1c39315da794a2a330 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- drivers/thermal/qcom/bcl_pmic5.c | 3 ++ drivers/thermal/qcom/bcl_soc.c | 6 ++- drivers/thermal/qcom/policy_engine.c | 4 ++ drivers/thermal/qcom/qmi_sensors_v2.c | 5 +- drivers/thermal/qcom/thermal_zone_internal.h | 50 ++++++++++++++++++++ drivers/thermal/qcom/tsens.c | 8 +++- 6 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 drivers/thermal/qcom/thermal_zone_internal.h diff --git a/drivers/thermal/qcom/bcl_pmic5.c b/drivers/thermal/qcom/bcl_pmic5.c index da2cf3478d48..2efe7dd7c1fa 100644 --- a/drivers/thermal/qcom/bcl_pmic5.c +++ b/drivers/thermal/qcom/bcl_pmic5.c @@ -22,6 +22,7 @@ #include #include #include +#include "thermal_zone_internal.h" #define BCL_DRIVER_NAME "bcl_pmic5" #define BCL_MONITOR_EN 0x46 @@ -799,6 +800,7 @@ static void bcl_lvl_init(struct platform_device *pdev, return; } thermal_zone_device_update(lbat->tz_dev, THERMAL_DEVICE_UP); + qti_update_tz_ops(lbat->tz_dev, true); } static void bcl_probe_lvls(struct platform_device *pdev, @@ -856,6 +858,7 @@ static int bcl_remove(struct platform_device *pdev) continue; thermal_zone_of_sensor_unregister(&pdev->dev, bcl_perph->param[i].tz_dev); + qti_update_tz_ops(bcl_perph->param[i].tz_dev, false); } return 0; diff --git a/drivers/thermal/qcom/bcl_soc.c b/drivers/thermal/qcom/bcl_soc.c index a8dbfd3868d7..d3caa67f7808 100644 --- a/drivers/thermal/qcom/bcl_soc.c +++ b/drivers/thermal/qcom/bcl_soc.c @@ -16,6 +16,7 @@ #include #include #include +#include "thermal_zone_internal.h" #define BCL_DRIVER_NAME "bcl_soc_peripheral" @@ -119,9 +120,11 @@ static int bcl_soc_remove(struct platform_device *pdev) { power_supply_unreg_notifier(&bcl_perph->psy_nb); flush_work(&bcl_perph->soc_eval_work); - if (bcl_perph->tz_dev) + if (bcl_perph->tz_dev) { thermal_zone_of_sensor_unregister(&pdev->dev, bcl_perph->tz_dev); + qti_update_tz_ops(bcl_perph->tz_dev, false); + } return 0; } @@ -156,6 +159,7 @@ static int bcl_soc_probe(struct platform_device *pdev) bcl_perph->tz_dev = NULL; goto bcl_soc_probe_exit; } + qti_update_tz_ops(bcl_perph->tz_dev, true); thermal_zone_device_update(bcl_perph->tz_dev, THERMAL_DEVICE_UP); schedule_work(&bcl_perph->soc_eval_work); diff --git a/drivers/thermal/qcom/policy_engine.c b/drivers/thermal/qcom/policy_engine.c index edd128242428..bb2b0f7fdbfa 100644 --- a/drivers/thermal/qcom/policy_engine.c +++ b/drivers/thermal/qcom/policy_engine.c @@ -12,6 +12,7 @@ #include #include #include +#include "thermal_zone_internal.h" #define PE_SENS_DRIVER "policy-engine-sensor" #define PE_INT_ENABLE_OFFSET 0x530 @@ -168,6 +169,8 @@ static int pe_sens_device_probe(struct platform_device *pdev) pe_sens->tz_dev = NULL; return ret; } + qti_update_tz_ops(pe_sens->tz_dev, true); + writel_relaxed(PE_INTR_CFG, pe_sens->regmap + PE_INT_ENABLE_OFFSET); writel_relaxed(PE_INTR_CLEAR, pe_sens->regmap + PE_INT_STATUS_OFFSET); writel_relaxed(PE_STS_CLEAR, pe_sens->regmap + PE_INT_STATUS1_OFFSET); @@ -194,6 +197,7 @@ static int pe_sens_device_remove(struct platform_device *pdev) (struct pe_sensor_data *)dev_get_drvdata(&pdev->dev); thermal_zone_of_sensor_unregister(pe_sens->dev, pe_sens->tz_dev); + qti_update_tz_ops(pe_sens->tz_dev, false); return 0; } diff --git a/drivers/thermal/qcom/qmi_sensors_v2.c b/drivers/thermal/qcom/qmi_sensors_v2.c index 3c2ec59c137b..e5918f721332 100644 --- a/drivers/thermal/qcom/qmi_sensors_v2.c +++ b/drivers/thermal/qcom/qmi_sensors_v2.c @@ -19,6 +19,7 @@ #include "thermal_sensor_service_v02.h" #include "qmi_sensors.h" +#include "thermal_zone_internal.h" #define QMI_SENS_DRIVER "qmi-therm-sensors-v2" #define QMI_TS_RESP_TOUT msecs_to_jiffies(100) @@ -292,8 +293,9 @@ static int qmi_register_sensor_device(struct qmi_sensor *qmi_sens) qmi_sens->tz_dev = NULL; return ret; } - pr_debug("Sensor register success for %s\n", qmi_sens->qmi_name); + qti_update_tz_ops(qmi_sens->tz_dev, true); + pr_debug("Sensor register success for %s\n", qmi_sens->qmi_name); return 0; } @@ -472,6 +474,7 @@ static void qmi_ts_cleanup(void) if (qmi_sens->tz_dev) { thermal_zone_of_sensor_unregister( qmi_sens->dev, qmi_sens->tz_dev); + qti_update_tz_ops(qmi_sens->tz_dev, false); qmi_sens->tz_dev = NULL; } diff --git a/drivers/thermal/qcom/thermal_zone_internal.h b/drivers/thermal/qcom/thermal_zone_internal.h new file mode 100644 index 000000000000..a037c2a167b0 --- /dev/null +++ b/drivers/thermal/qcom/thermal_zone_internal.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __QTI_THERMAL_ZONE_INTERNAL_H +#define __QTI_THERMAL_ZONE_INTERNAL_H + +#include +#include "../thermal_core.h" + +/* Generic helpers for thermal zone -> change_mode ops */ +static inline int qti_tz_change_mode(struct thermal_zone_device *tz, + enum thermal_device_mode mode) +{ + struct thermal_instance *instance; + + tz->passive = 0; + tz->temperature = THERMAL_TEMP_INVALID; + tz->prev_low_trip = -INT_MAX; + tz->prev_high_trip = INT_MAX; + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + instance->initialized = false; + if (mode == THERMAL_DEVICE_DISABLED) { + instance->target = THERMAL_NO_TARGET; + instance->cdev->updated = false; + thermal_cdev_update(instance->cdev); + } + } + + return 0; +} + +static inline int qti_update_tz_ops(struct thermal_zone_device *tz, bool enable) +{ + if (!tz || !tz->ops) + return -EINVAL; + + mutex_lock(&tz->lock); + if (enable) { + if (!tz->ops->change_mode) + tz->ops->change_mode = qti_tz_change_mode; + } else { + tz->ops->change_mode = NULL; + } + mutex_unlock(&tz->lock); + return 0; +} + +#endif // __QTI_THERMAL_ZONE_INTERNAL_H diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 93020c395357..70cfad1ecfe5 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. * Copyright (c) 2019, 2020, Linaro Ltd. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -21,6 +21,7 @@ #include #include "../thermal_hwmon.h" #include "tsens.h" +#include "thermal_zone_internal.h" /** * struct tsens_irq_data - IRQ status and temperature violations @@ -1085,6 +1086,7 @@ static int tsens_register(struct tsens_priv *priv) if (devm_thermal_add_hwmon_sysfs(tzd)) dev_warn(priv->dev, "Failed to add hwmon sysfs attributes\n"); + qti_update_tz_ops(tzd, true); } /* VER_0 require to set MIN and MAX THRESH @@ -1189,12 +1191,16 @@ static int tsens_probe(struct platform_device *pdev) static int tsens_remove(struct platform_device *pdev) { struct tsens_priv *priv = platform_get_drvdata(pdev); + int i; debugfs_remove_recursive(priv->debug_root); tsens_disable_irq(priv); if (priv->ops->disable) priv->ops->disable(priv); + for (i = 0; i < priv->num_sensors; i++) + if (priv->sensor[i].tzd) + qti_update_tz_ops(priv->sensor[i].tzd, false); return 0; }