mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
thermal/drivers/qcom/tsens: Switch wake IRQ handling to PM callbacks
This change improves power management by using the standardized PM framework for wake IRQ handling. Move wake IRQ control to the PM suspend/resume path: - store uplow/critical IRQ numbers in struct tsens_priv - enable wake IRQs in tsens_suspend_common() when wakeup is allowed - disable wake IRQs in tsens_resume_common() - mark the device wakeup-capable during probe This aligns TSENS wake behavior with suspend flow and avoids keeping wake IRQs permanently enabled during runtime. Signed-off-by: Priyansh Jain <priyansh.jain@oss.qualcomm.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org> Link: https://patch.msgid.link/20260601-tsens_interrupt_wake_control-v2-1-ce9570946abd@oss.qualcomm.com
This commit is contained in:
parent
995b736ad4
commit
c665de5eeb
|
|
@ -263,7 +263,6 @@ static int __init init_tsens_v2_no_rpm(struct tsens_priv *priv)
|
|||
static const struct tsens_ops ops_generic_v2 = {
|
||||
.init = init_common,
|
||||
.get_temp = get_temp_tsens_valid,
|
||||
.resume = tsens_resume_common,
|
||||
};
|
||||
|
||||
struct tsens_plat_data data_tsens_v2 = {
|
||||
|
|
|
|||
|
|
@ -1129,22 +1129,30 @@ static int tsens_get_temp(struct thermal_zone_device *tz, int *temp)
|
|||
|
||||
static int __maybe_unused tsens_suspend(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct tsens_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (priv->ops && priv->ops->suspend)
|
||||
return priv->ops->suspend(priv);
|
||||
if (priv->ops && priv->ops->suspend) {
|
||||
ret = priv->ops->suspend(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return tsens_suspend_common(priv);
|
||||
}
|
||||
|
||||
static int __maybe_unused tsens_resume(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct tsens_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (priv->ops && priv->ops->resume)
|
||||
return priv->ops->resume(priv);
|
||||
if (priv->ops && priv->ops->resume) {
|
||||
ret = priv->ops->resume(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return tsens_resume_common(priv);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
|
||||
|
|
@ -1215,7 +1223,7 @@ static const struct thermal_zone_device_ops tsens_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;
|
||||
|
|
@ -1248,7 +1256,7 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
|
|||
dev_err(&pdev->dev, "%s: failed to get irq\n",
|
||||
__func__);
|
||||
else
|
||||
enable_irq_wake(irq);
|
||||
*irq_num = irq;
|
||||
}
|
||||
|
||||
put_device(&pdev->dev);
|
||||
|
|
@ -1275,11 +1283,38 @@ static int tsens_reinit(struct tsens_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tsens_suspend_common(struct tsens_priv *priv)
|
||||
{
|
||||
if (!device_may_wakeup(priv->dev))
|
||||
return 0;
|
||||
|
||||
if (priv->feat->combo_int)
|
||||
enable_irq_wake(priv->combined_irq);
|
||||
else {
|
||||
enable_irq_wake(priv->uplow_irq);
|
||||
if (priv->feat->crit_int)
|
||||
enable_irq_wake(priv->crit_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsens_resume_common(struct tsens_priv *priv)
|
||||
{
|
||||
if (pm_suspend_target_state == PM_SUSPEND_MEM)
|
||||
tsens_reinit(priv);
|
||||
|
||||
if (!device_may_wakeup(priv->dev))
|
||||
return 0;
|
||||
|
||||
if (priv->feat->combo_int)
|
||||
disable_irq_wake(priv->combined_irq);
|
||||
else {
|
||||
disable_irq_wake(priv->uplow_irq);
|
||||
if (priv->feat->crit_int)
|
||||
disable_irq_wake(priv->crit_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1319,15 +1354,18 @@ static int tsens_register(struct tsens_priv *priv)
|
|||
|
||||
if (priv->feat->combo_int) {
|
||||
ret = tsens_register_irq(priv, "combined",
|
||||
tsens_combined_irq_thread);
|
||||
tsens_combined_irq_thread, &priv->combined_irq);
|
||||
} else {
|
||||
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)
|
||||
if (priv->feat->crit_int) {
|
||||
ret = tsens_register_irq(priv, "critical",
|
||||
tsens_critical_irq_thread);
|
||||
tsens_critical_irq_thread,
|
||||
&priv->crit_irq);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1386,6 +1424,8 @@ static int tsens_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
device_init_wakeup(dev, true);
|
||||
|
||||
if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -568,6 +568,9 @@ struct tsens_context {
|
|||
* @ops: pointer to list of callbacks supported by this device
|
||||
* @debug_root: pointer to debugfs dentry for all tsens
|
||||
* @debug: pointer to debugfs dentry for tsens controller
|
||||
* @uplow_irq: IRQ number for uplow (upper/lower) threshold interrupts
|
||||
* @crit_irq: IRQ number for critical threshold interrupts
|
||||
* @combined_irq: IRQ number for combined threshold interrupts
|
||||
* @sensor: list of sensors attached to this device
|
||||
*/
|
||||
struct tsens_priv {
|
||||
|
|
@ -589,6 +592,10 @@ struct tsens_priv {
|
|||
struct dentry *debug_root;
|
||||
struct dentry *debug;
|
||||
|
||||
int uplow_irq;
|
||||
int crit_irq;
|
||||
int combined_irq;
|
||||
|
||||
struct tsens_sensor sensor[] __counted_by(num_sensors);
|
||||
};
|
||||
|
||||
|
|
@ -640,8 +647,17 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
|
|||
int get_temp_common(const struct tsens_sensor *s, int *temp);
|
||||
#ifdef CONFIG_SUSPEND
|
||||
int tsens_resume_common(struct tsens_priv *priv);
|
||||
int tsens_suspend_common(struct tsens_priv *priv);
|
||||
#else
|
||||
#define tsens_resume_common NULL
|
||||
static inline int tsens_resume_common(struct tsens_priv *priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int tsens_suspend_common(struct tsens_priv *priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TSENS target */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user