summaryrefslogtreecommitdiff
path: root/drivers/thermal/qcom/tsens.c
diff options
context:
space:
mode:
authorAmit Kucheria <amit.kucheria@linaro.org>2019-10-31 21:37:39 +0300
committerDaniel Lezcano <daniel.lezcano@linaro.org>2019-11-07 09:00:26 +0300
commit634e11d5b450a9bcc921219611c5d2cdc0f9066e (patch)
treee0b947b0b5545ac61572c595023cc6fca3a4edf4 /drivers/thermal/qcom/tsens.c
parentbd93ee3cb43b6a0ab4a78edd9e26dcda01b3b77e (diff)
downloadlinux-634e11d5b450a9bcc921219611c5d2cdc0f9066e.tar.xz
drivers: thermal: tsens: Add interrupt support
Depending on the IP version, TSENS supports upper, lower and critical threshold interrupts. We only add support for upper and lower threshold interrupts for now. TSENSv2 has an irq [status|clear|mask] bit tuple for each sensor while earlier versions only have a single bit per sensor to denote status and clear. These differences are handled transparently by the interrupt handler. At each interrupt, we reprogram the new upper and lower threshold in the .set_trip callback. Signed-off-by: Amit Kucheria <amit.kucheria@linaro.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/7508ba143f144407e5dd546107ddae65c380a76f.1572526427.git.amit.kucheria@linaro.org
Diffstat (limited to 'drivers/thermal/qcom/tsens.c')
-rw-r--r--drivers/thermal/qcom/tsens.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 772aa76b50e1..7d317660211e 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -7,6 +7,7 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
@@ -78,12 +79,14 @@ MODULE_DEVICE_TABLE(of, tsens_table);
static const struct thermal_zone_of_device_ops tsens_of_ops = {
.get_temp = tsens_get_temp,
.get_trend = tsens_get_trend,
+ .set_trips = tsens_set_trips,
};
static int tsens_register(struct tsens_priv *priv)
{
- int i;
+ int i, ret, irq;
struct thermal_zone_device *tzd;
+ struct platform_device *pdev;
for (i = 0; i < priv->num_sensors; i++) {
priv->sensor[i].priv = priv;
@@ -96,7 +99,31 @@ static int tsens_register(struct tsens_priv *priv)
if (priv->ops->enable)
priv->ops->enable(priv, i);
}
- return 0;
+
+ pdev = of_find_device_by_node(priv->dev->of_node);
+ if (!pdev)
+ return -ENODEV;
+
+ irq = platform_get_irq_byname(pdev, "uplow");
+ if (irq < 0) {
+ ret = irq;
+ goto err_put_device;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq,
+ NULL, tsens_irq_thread,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ dev_name(&pdev->dev), priv);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to get irq\n", __func__);
+ goto err_put_device;
+ }
+
+ enable_irq_wake(irq);
+
+err_put_device:
+ put_device(&pdev->dev);
+ return ret;
}
static int tsens_probe(struct platform_device *pdev)
@@ -178,6 +205,7 @@ static int tsens_remove(struct platform_device *pdev)
struct tsens_priv *priv = platform_get_drvdata(pdev);
debugfs_remove_recursive(priv->debug_root);
+ tsens_disable_irq(priv);
if (priv->ops->disable)
priv->ops->disable(priv);