From: Ansuel Smith <ansuelsmth@gmail.com>
To: Amit Kucheria <amit.kucheria@linaro.org>
Cc: Ansuel Smith <ansuelsmth@gmail.com>,
Andy Gross <agross@kernel.org>,
Bjorn Andersson <bjorn.andersson@linaro.org>,
Zhang Rui <rui.zhang@intel.com>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Rob Herring <robh+dt@kernel.org>,
linux-pm@vger.kernel.org, linux-arm-msm@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH v5 1/7] drivers: thermal: tsens: Add VER_0 tsens version
Date: Sat, 25 Jul 2020 20:13:57 +0200 [thread overview]
Message-ID: <20200725181404.18951-2-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20200725181404.18951-1-ansuelsmth@gmail.com>
VER_0 is used to describe device based on tsens version before v0.1.
These device are devices based on msm8960 for example apq8064 or
ipq806x.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/thermal/qcom/tsens.c | 160 +++++++++++++++++++++++++++--------
drivers/thermal/qcom/tsens.h | 7 +-
2 files changed, 132 insertions(+), 35 deletions(-)
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 9fe9a2b26705..78840c1bc5d2 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -516,6 +516,15 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
hw_id, __func__, temp);
}
+
+ if (tsens_version(priv) < VER_0_1) {
+ /* Constraint: There is only 1 interrupt control register for all
+ * 11 temperature sensor. So monitoring more than 1 sensor based
+ * on interrupts will yield inconsistent result. To overcome this
+ * issue we will monitor only sensor 0 which is the master sensor.
+ */
+ break;
+ }
}
return IRQ_HANDLED;
@@ -531,6 +540,13 @@ static int tsens_set_trips(void *_sensor, int low, int high)
int high_val, low_val, cl_high, cl_low;
u32 hw_id = s->hw_id;
+ if (tsens_version(priv) < VER_0_1) {
+ /* Pre v0.1 IP had a single register for each type of interrupt
+ * and thresholds
+ */
+ hw_id = 0;
+ }
+
dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
hw_id, __func__, low, high);
@@ -550,6 +566,12 @@ static int tsens_set_trips(void *_sensor, int low, int high)
tsens_set_interrupt(priv, hw_id, LOWER, true);
tsens_set_interrupt(priv, hw_id, UPPER, true);
+ /* VER_0 require to set MIN and MAX THRESH */
+ if (tsens_version(priv) < VER_0_1) {
+ regmap_field_write(priv->rf[MIN_THRESH_0], 0);
+ regmap_field_write(priv->rf[MAX_THRESH_0], 120000);
+ }
+
spin_unlock_irqrestore(&priv->ul_lock, flags);
dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
@@ -584,18 +606,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
u32 valid;
int ret;
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- while (!valid) {
- /* Valid bit is 0 for 6 AHB clock cycles.
- * At 19.2MHz, 1 AHB clock is ~60ns.
- * We should enter this loop very, very rarely.
- */
- ndelay(400);
+ /* VER_0 doesn't have VALID bit */
+ if (tsens_version(priv) >= VER_0_1) {
ret = regmap_field_read(priv->rf[valid_idx], &valid);
if (ret)
return ret;
+ while (!valid) {
+ /* Valid bit is 0 for 6 AHB clock cycles.
+ * At 19.2MHz, 1 AHB clock is ~60ns.
+ * We should enter this loop very, very rarely.
+ */
+ ndelay(400);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
+ }
}
/* Valid bit is set, OK to read the temperature */
@@ -765,8 +790,8 @@ int __init init_common(struct tsens_priv *priv)
if (tsens_version(priv) > VER_0_1) {
for (i = VER_MAJOR; i <= VER_STEP; i++) {
- priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
- priv->fields[i]);
+ priv->rf[i] = devm_regmap_field_alloc(
+ dev, priv->srot_map, priv->fields[i]);
if (IS_ERR(priv->rf[i]))
return PTR_ERR(priv->rf[i]);
}
@@ -775,12 +800,80 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}
- priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
- priv->fields[TSENS_EN]);
- if (IS_ERR(priv->rf[TSENS_EN])) {
- ret = PTR_ERR(priv->rf[TSENS_EN]);
- goto err_put_device;
+ if (tsens_version(priv) >= VER_0_1) {
+ priv->rf[TSENS_EN] = devm_regmap_field_alloc(
+ dev, priv->srot_map, priv->fields[TSENS_EN]);
+ if (IS_ERR(priv->rf[TSENS_EN])) {
+ ret = PTR_ERR(priv->rf[TSENS_EN]);
+ goto err_put_device;
+ }
+
+ priv->rf[SENSOR_EN] = devm_regmap_field_alloc(
+ dev, priv->srot_map, priv->fields[SENSOR_EN]);
+ if (IS_ERR(priv->rf[SENSOR_EN])) {
+ ret = PTR_ERR(priv->rf[SENSOR_EN]);
+ goto err_put_device;
+ }
+ priv->rf[INT_EN] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[INT_EN]);
+ if (IS_ERR(priv->rf[INT_EN])) {
+ ret = PTR_ERR(priv->rf[INT_EN]);
+ goto err_put_device;
+ }
+ } else {
+ priv->rf[TSENS_EN] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[TSENS_EN]);
+ if (IS_ERR(priv->rf[TSENS_EN])) {
+ ret = PTR_ERR(priv->rf[TSENS_EN]);
+ goto err_put_device;
+ }
+
+ priv->rf[TSENS_SW_RST] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[TSENS_EN]);
+ if (IS_ERR(priv->rf[TSENS_EN])) {
+ ret = PTR_ERR(priv->rf[TSENS_EN]);
+ goto err_put_device;
+ }
+
+ /* enable TSENS */
+ regmap_field_write(priv->rf[TSENS_EN], 1);
+
+ priv->rf[LOW_INT_CLEAR_0] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[LOW_INT_CLEAR_0]);
+ if (IS_ERR(priv->rf[LOW_INT_CLEAR_0])) {
+ ret = PTR_ERR(priv->rf[LOW_INT_CLEAR_0]);
+ goto err_put_device;
+ }
+
+ priv->rf[UP_INT_CLEAR_0] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[UP_INT_CLEAR_0]);
+ if (IS_ERR(priv->rf[UP_INT_CLEAR_0])) {
+ ret = PTR_ERR(priv->rf[UP_INT_CLEAR_0]);
+ goto err_put_device;
+ }
+
+ priv->rf[MIN_THRESH_0] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[MIN_THRESH_0]);
+ if (IS_ERR(priv->rf[MIN_THRESH_0])) {
+ ret = PTR_ERR(priv->rf[MIN_THRESH_0]);
+ goto err_put_device;
+ }
+
+ priv->rf[MAX_THRESH_0] = devm_regmap_field_alloc(
+ dev, priv->tm_map, priv->fields[MAX_THRESH_0]);
+ if (IS_ERR(priv->rf[MAX_THRESH_0])) {
+ ret = PTR_ERR(priv->rf[MAX_THRESH_0]);
+ goto err_put_device;
+ }
+
+ priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map,
+ priv->fields[TRDY]);
+ if (IS_ERR(priv->rf[TRDY])) {
+ ret = PTR_ERR(priv->rf[TRDY]);
+ goto err_put_device;
+ }
}
+
ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
if (ret)
goto err_put_device;
@@ -790,19 +883,6 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}
- priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
- priv->fields[SENSOR_EN]);
- if (IS_ERR(priv->rf[SENSOR_EN])) {
- ret = PTR_ERR(priv->rf[SENSOR_EN]);
- goto err_put_device;
- }
- priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
- priv->fields[INT_EN]);
- if (IS_ERR(priv->rf[INT_EN])) {
- ret = PTR_ERR(priv->rf[INT_EN]);
- goto err_put_device;
- }
-
/* This loop might need changes if enum regfield_ids is reordered */
for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
for (i = 0; i < priv->feat->max_sensors; i++) {
@@ -856,7 +936,11 @@ int __init init_common(struct tsens_priv *priv)
}
spin_lock_init(&priv->ul_lock);
- tsens_enable_irq(priv);
+
+ /* VER_0 interrupt doesn't need to be enabled */
+ if (tsens_version(priv) >= VER_0_1)
+ tsens_enable_irq(priv);
+
tsens_debug_init(op);
err_put_device:
@@ -952,10 +1036,18 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
if (irq == -ENXIO)
ret = 0;
} else {
- ret = devm_request_threaded_irq(&pdev->dev, irq,
- NULL, thread_fn,
- IRQF_ONESHOT,
- dev_name(&pdev->dev), priv);
+ /* VER_0 have a different interrupt type */
+ if (tsens_version(priv) > VER_0)
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ thread_fn, IRQF_ONESHOT,
+ dev_name(&pdev->dev),
+ priv);
+ else
+ ret = devm_request_threaded_irq(&pdev->dev, irq,
+ thread_fn, NULL,
+ IRQF_TRIGGER_RISING,
+ dev_name(&pdev->dev),
+ priv);
if (ret)
dev_err(&pdev->dev, "%s: failed to get irq\n",
__func__);
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 59d01162c66a..f1120791737c 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -25,7 +25,8 @@ struct tsens_priv;
/* IP version numbers in ascending order */
enum tsens_ver {
- VER_0_1 = 0,
+ VER_0 = 0,
+ VER_0_1,
VER_1_X,
VER_2_X,
};
@@ -441,6 +442,10 @@ enum regfield_ids {
CRIT_THRESH_14,
CRIT_THRESH_15,
+ /* VER_0 MIN MAX THRESH */
+ MIN_THRESH_0,
+ MAX_THRESH_0,
+
/* WATCHDOG */
WDOG_BARK_STATUS,
WDOG_BARK_CLEAR,
--
2.27.0
next prev parent reply other threads:[~2020-07-25 18:14 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-25 18:13 [RFC PATCH v5 0/7] Add support for ipq8064 tsens Ansuel Smith
2020-07-25 18:13 ` Ansuel Smith [this message]
2020-08-11 12:57 ` [RFC PATCH v5 1/7] drivers: thermal: tsens: Add VER_0 tsens version Amit Kucheria
2020-08-11 13:18 ` R: " ansuelsmth
2020-08-13 11:18 ` Amit Kucheria
2020-07-25 18:13 ` [RFC PATCH v5 2/7] drivers: thermal: tsens: Convert msm8960 to reg_field Ansuel Smith
2020-08-11 12:57 ` Amit Kucheria
2020-07-25 18:13 ` [RFC PATCH v5 3/7] drivers: thermal: tsens: Use init_common for msm8960 Ansuel Smith
2020-07-25 18:14 ` [RFC PATCH v5 4/7] drivers: thermal: tsens: Fix wrong get_temp " Ansuel Smith
2020-07-25 18:14 ` [RFC PATCH v5 5/7] drivers: thermal: tsens: Change calib_backup name " Ansuel Smith
2020-07-25 18:14 ` [RFC PATCH v5 6/7] drivers: thermal: tsens: Add support for ipq8064-tsens Ansuel Smith
2020-07-25 18:14 ` [RFC PATCH v5 7/7] dt-bindings: thermal: tsens: Document ipq8064 bindings Ansuel Smith
2020-07-27 19:58 ` Rob Herring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200725181404.18951-2-ansuelsmth@gmail.com \
--to=ansuelsmth@gmail.com \
--cc=agross@kernel.org \
--cc=amit.kucheria@linaro.org \
--cc=bjorn.andersson@linaro.org \
--cc=daniel.lezcano@linaro.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=robh+dt@kernel.org \
--cc=rui.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.