Merge "drivers: thermal: qcom: Add tsens driver changes for hibernation mode"
This commit is contained in:
commit
41e8b85288
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018, Linaro Limited
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
@ -97,6 +97,10 @@ static const struct tsens_ops ops_generic_v2 = {
|
||||
.init = init_common,
|
||||
.get_temp = get_temp_tsens_valid,
|
||||
.get_cold_status = get_cold_int_status,
|
||||
.suspend = tsens_v2_tsens_suspend,
|
||||
.resume = tsens_v2_tsens_resume,
|
||||
.freeze = tsens_v2_tsens_freeze,
|
||||
.restore = tsens_v2_tsens_restore,
|
||||
};
|
||||
|
||||
struct tsens_plat_data data_tsens_v2 = {
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Linaro Ltd.
|
||||
* Copyright (c) 2021, 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021, 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
@ -18,6 +18,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "tsens.h"
|
||||
#include "thermal_zone_internal.h"
|
||||
|
||||
@ -1015,7 +1016,25 @@ static int __maybe_unused tsens_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
|
||||
static int __maybe_unused tsens_freeze(struct device *dev)
|
||||
{
|
||||
struct tsens_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (priv->ops && priv->ops->freeze)
|
||||
return priv->ops->freeze(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused tsens_restore(struct device *dev)
|
||||
{
|
||||
struct tsens_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (priv->ops && priv->ops->restore)
|
||||
return priv->ops->restore(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id tsens_table[] = {
|
||||
{
|
||||
@ -1062,7 +1081,7 @@ static const struct thermal_zone_of_device_ops tsens_cold_of_ops = {
|
||||
|
||||
|
||||
static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
|
||||
irq_handler_t thread_fn)
|
||||
irq_handler_t thread_fn, int *irq_num)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
int ret, irq;
|
||||
@ -1072,6 +1091,7 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
|
||||
return -ENODEV;
|
||||
|
||||
irq = platform_get_irq_byname(pdev, irqname);
|
||||
*irq_num = irq;
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
/* For old DTs with no IRQ defined */
|
||||
@ -1093,6 +1113,90 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tsens_reinit(struct tsens_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->ul_lock, flags);
|
||||
|
||||
if (priv->feat->has_watchdog) {
|
||||
regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);
|
||||
regmap_field_write(priv->rf[CC_MON_MASK], 1);
|
||||
}
|
||||
|
||||
if (tsens_version(priv) >= VER_0_1)
|
||||
tsens_enable_irq(priv);
|
||||
|
||||
spin_unlock_irqrestore(&priv->ul_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsens_v2_tsens_suspend(struct tsens_priv *priv)
|
||||
{
|
||||
if (!priv->tm_disable_on_suspend)
|
||||
return 0;
|
||||
|
||||
if (priv->uplow_irq > 0) {
|
||||
disable_irq_nosync(priv->uplow_irq);
|
||||
disable_irq_wake(priv->uplow_irq);
|
||||
}
|
||||
|
||||
if (priv->feat->crit_int && priv->crit_irq > 0) {
|
||||
disable_irq_nosync(priv->crit_irq);
|
||||
disable_irq_wake(priv->crit_irq);
|
||||
}
|
||||
|
||||
if (priv->cold_irq > 0) {
|
||||
disable_irq_nosync(priv->cold_irq);
|
||||
disable_irq_wake(priv->cold_irq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsens_v2_tsens_resume(struct tsens_priv *priv)
|
||||
{
|
||||
if (!priv->tm_disable_on_suspend)
|
||||
return 0;
|
||||
|
||||
tsens_reinit(priv);
|
||||
|
||||
if (priv->uplow_irq > 0) {
|
||||
enable_irq(priv->uplow_irq);
|
||||
enable_irq_wake(priv->uplow_irq);
|
||||
}
|
||||
|
||||
if (priv->feat->crit_int && priv->crit_irq > 0) {
|
||||
enable_irq(priv->crit_irq);
|
||||
enable_irq_wake(priv->crit_irq);
|
||||
}
|
||||
|
||||
if (priv->cold_irq > 0) {
|
||||
enable_irq(priv->cold_irq);
|
||||
enable_irq_wake(priv->cold_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsens_v2_tsens_freeze(struct tsens_priv *priv)
|
||||
{
|
||||
|
||||
if (priv->ops && priv->ops->suspend)
|
||||
return priv->ops->suspend(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsens_v2_tsens_restore(struct tsens_priv *priv)
|
||||
{
|
||||
|
||||
if (priv->ops && priv->ops->resume)
|
||||
return priv->ops->resume(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsens_register(struct tsens_priv *priv)
|
||||
{
|
||||
int i, temp, ret;
|
||||
@ -1122,14 +1226,15 @@ static int tsens_register(struct tsens_priv *priv)
|
||||
priv->ops->enable(priv, i);
|
||||
}
|
||||
|
||||
ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
|
||||
ret = tsens_register_irq(priv, "uplow",
|
||||
tsens_irq_thread, &priv->uplow_irq);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (priv->feat->crit_int)
|
||||
ret = tsens_register_irq(priv, "critical",
|
||||
tsens_critical_irq_thread);
|
||||
tsens_critical_irq_thread, &priv->crit_irq);
|
||||
|
||||
if (priv->feat->cold_int) {
|
||||
priv->cold_sensor = devm_kzalloc(priv->dev,
|
||||
@ -1144,13 +1249,14 @@ static int tsens_register(struct tsens_priv *priv)
|
||||
priv->cold_sensor->hw_id,
|
||||
priv->cold_sensor,
|
||||
&tsens_cold_of_ops);
|
||||
if (IS_ERR(tzd)) {
|
||||
ret = 0;
|
||||
return ret;
|
||||
if (!IS_ERR_OR_NULL(tzd)) {
|
||||
priv->cold_sensor->tzd = tzd;
|
||||
ret = tsens_register_irq(priv, "cold",
|
||||
tsens_cold_irq_thread, &priv->cold_irq);
|
||||
}
|
||||
|
||||
priv->cold_sensor->tzd = tzd;
|
||||
ret = tsens_register_irq(priv, "cold", tsens_cold_irq_thread);
|
||||
ret = tsens_register_irq(priv, "cold", tsens_cold_irq_thread, &priv->cold_irq);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1227,6 +1333,9 @@ static int tsens_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
priv->tm_disable_on_suspend =
|
||||
of_property_read_bool(np, "tm-disable-on-suspend");
|
||||
|
||||
return tsens_register(priv);
|
||||
}
|
||||
|
||||
@ -1242,6 +1351,11 @@ static int tsens_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops tsens_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(tsens_suspend, tsens_resume)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(tsens_freeze, tsens_restore)
|
||||
};
|
||||
|
||||
static struct platform_driver tsens_driver = {
|
||||
.probe = tsens_probe,
|
||||
.remove = tsens_remove,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2015, 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021, 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021, 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __QCOM_TSENS_H__
|
||||
@ -83,6 +83,8 @@ struct tsens_ops {
|
||||
int (*resume)(struct tsens_priv *priv);
|
||||
int (*get_trend)(struct tsens_sensor *s, enum thermal_trend *trend);
|
||||
int (*get_cold_status)(const struct tsens_sensor *s, bool *cold_status);
|
||||
int (*freeze)(struct tsens_priv *priv);
|
||||
int (*restore)(struct tsens_priv *priv);
|
||||
};
|
||||
|
||||
#define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
|
||||
@ -610,6 +612,13 @@ struct tsens_priv {
|
||||
const struct reg_field *fields;
|
||||
const struct tsens_ops *ops;
|
||||
|
||||
/* add to save irq number to re-use it at runtime */
|
||||
int uplow_irq;
|
||||
int crit_irq;
|
||||
int cold_irq;
|
||||
|
||||
bool tm_disable_on_suspend;
|
||||
|
||||
struct dentry *debug_root;
|
||||
struct dentry *debug;
|
||||
struct tsens_sensor *cold_sensor;
|
||||
@ -626,6 +635,11 @@ int init_common(struct tsens_priv *priv);
|
||||
int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
|
||||
int get_temp_common(const struct tsens_sensor *s, int *temp);
|
||||
int get_cold_int_status(const struct tsens_sensor *s, bool *cold_status);
|
||||
int tsens_v2_tsens_suspend(struct tsens_priv *priv);
|
||||
int tsens_v2_tsens_resume(struct tsens_priv *priv);
|
||||
int tsens_v2_tsens_freeze(struct tsens_priv *priv);
|
||||
int tsens_v2_tsens_restore(struct tsens_priv *priv);
|
||||
|
||||
|
||||
/* TSENS target */
|
||||
extern struct tsens_plat_data data_8960;
|
||||
|
Loading…
Reference in New Issue
Block a user