mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 19:47:08 +02:00
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 <quic_manafm@quicinc.com>
This commit is contained in:
parent
ec5bc9a94b
commit
b28c171a2a
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
#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;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/thermal.h>
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/interrupt.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
50
drivers/thermal/qcom/thermal_zone_internal.h
Normal file
50
drivers/thermal/qcom/thermal_zone_internal.h
Normal file
|
|
@ -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 <linux/thermal.h>
|
||||
#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
|
||||
|
|
@ -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 <linux/debugfs.h>
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/thermal.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user