ipq806x: use newer tsens patch
authorAnsuel Smith <ansuelsmth@gmail.com>
Mon, 1 Mar 2021 00:02:09 +0000 (01:02 +0100)
committerPetr Štetiar <ynezz@true.cz>
Fri, 7 May 2021 05:05:16 +0000 (07:05 +0200)
Use improved tsens patch proposed upstream.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
14 files changed:
target/linux/ipq806x/patches-5.10/0063-1-ipq806x-tsens-driver.patch [deleted file]
target/linux/ipq806x/patches-5.10/0063-2-tsens-support-configurable-interrupts.patch [deleted file]
target/linux/ipq806x/patches-5.10/0063-3-tsens-fix-kernel-5_4.patch [deleted file]
target/linux/ipq806x/patches-5.10/0063-4-ip806x-tsense-rework-driver.patch [deleted file]
target/linux/ipq806x/patches-5.10/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.10/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch [new file with mode: 0644]

diff --git a/target/linux/ipq806x/patches-5.10/0063-1-ipq806x-tsens-driver.patch b/target/linux/ipq806x/patches-5.10/0063-1-ipq806x-tsens-driver.patch
deleted file mode 100644 (file)
index 80954c1..0000000
+++ /dev/null
@@ -1,616 +0,0 @@
-From 3302e1e1a3cfa4e67fda2a61d6f0c42205d40932 Mon Sep 17 00:00:00 2001
-From: Rajith Cherian <rajith@codeaurora.org>
-Date: Tue, 14 Feb 2017 18:30:43 +0530
-Subject: [PATCH] ipq8064: tsens: Base tsens driver for IPQ8064
-
-Add TSENS driver template to support IPQ8064.
-This is a base file copied from tsens-8960.c
-
-Change-Id: I47c573fdfa2d898243c6a6ba952d1632f91391f7
-Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
-
-ipq8064: tsens: TSENS driver support for IPQ8064
-
-Support for IPQ8064 tsens driver. The driver works
-with the thermal framework. The driver overrides the
-following fucntionalities:
-
-1. Get current temperature.
-2. Get/Set trip temperatures.
-3. Enabled/Disable trip points.
-4. ISR for threshold generated interrupt.
-5. Notify userspace when trip points are hit.
-
-Change-Id: I8bc7204fd627d10875ab13fc1de8cb6c2ed7a918
-Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
----
-
---- a/drivers/thermal/qcom/Makefile
-+++ b/drivers/thermal/qcom/Makefile
-@@ -2,5 +2,5 @@
- obj-$(CONFIG_QCOM_TSENS)      += qcom_tsens.o
- qcom_tsens-y                  += tsens.o tsens-common.o tsens-v0_1.o \
--                                 tsens-8960.o tsens-v2.o tsens-v1.o
-+                                 tsens-8960.o tsens-v2.o tsens-v1.o tsens-ipq8064.o
- obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)    += qcom-spmi-temp-alarm.o
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens-ipq8064.c
-@@ -0,0 +1,551 @@
-+/*
-+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/regmap.h>
-+#include <linux/thermal.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include "tsens.h"
-+
-+#define CAL_MDEGC             30000
-+
-+#define CONFIG_ADDR           0x3640
-+/* CONFIG_ADDR bitmasks */
-+#define CONFIG                        0x9b
-+#define CONFIG_MASK           0xf
-+#define CONFIG_SHIFT          0
-+
-+#define STATUS_CNTL_8064      0x3660
-+#define CNTL_ADDR             0x3620
-+/* CNTL_ADDR bitmasks */
-+#define EN                    BIT(0)
-+#define SW_RST                        BIT(1)
-+#define SENSOR0_EN            BIT(3)
-+#define SLP_CLK_ENA           BIT(26)
-+#define MEASURE_PERIOD                1
-+#define SENSOR0_SHIFT         3
-+
-+/* INT_STATUS_ADDR bitmasks */
-+#define MIN_STATUS_MASK               BIT(0)
-+#define LOWER_STATUS_CLR      BIT(1)
-+#define UPPER_STATUS_CLR      BIT(2)
-+#define MAX_STATUS_MASK               BIT(3)
-+
-+#define THRESHOLD_ADDR                0x3624
-+/* THRESHOLD_ADDR bitmasks */
-+#define THRESHOLD_MAX_CODE            0x20000
-+#define THRESHOLD_MIN_CODE            0
-+#define THRESHOLD_MAX_LIMIT_SHIFT     24
-+#define THRESHOLD_MIN_LIMIT_SHIFT     16
-+#define THRESHOLD_UPPER_LIMIT_SHIFT   8
-+#define THRESHOLD_LOWER_LIMIT_SHIFT   0
-+#define THRESHOLD_MAX_LIMIT_MASK      (THRESHOLD_MAX_CODE << \
-+                                              THRESHOLD_MAX_LIMIT_SHIFT)
-+#define THRESHOLD_MIN_LIMIT_MASK      (THRESHOLD_MAX_CODE << \
-+                                              THRESHOLD_MIN_LIMIT_SHIFT)
-+#define THRESHOLD_UPPER_LIMIT_MASK    (THRESHOLD_MAX_CODE << \
-+                                              THRESHOLD_UPPER_LIMIT_SHIFT)
-+#define THRESHOLD_LOWER_LIMIT_MASK    (THRESHOLD_MAX_CODE << \
-+                                              THRESHOLD_LOWER_LIMIT_SHIFT)
-+
-+/* Initial temperature threshold values */
-+#define LOWER_LIMIT_TH                0x9d /* 95C */
-+#define UPPER_LIMIT_TH                0xa6 /* 105C */
-+#define MIN_LIMIT_TH          0x0
-+#define MAX_LIMIT_TH          0xff
-+
-+#define S0_STATUS_ADDR                0x3628
-+#define STATUS_ADDR_OFFSET    2
-+#define SENSOR_STATUS_SIZE    4
-+#define INT_STATUS_ADDR               0x363c
-+#define TRDY_MASK             BIT(7)
-+#define TIMEOUT_US            100
-+
-+#define TSENS_EN              BIT(0)
-+#define TSENS_SW_RST          BIT(1)
-+#define TSENS_ADC_CLK_SEL     BIT(2)
-+#define SENSOR0_EN            BIT(3)
-+#define SENSOR1_EN            BIT(4)
-+#define SENSOR2_EN            BIT(5)
-+#define SENSOR3_EN            BIT(6)
-+#define SENSOR4_EN            BIT(7)
-+#define SENSORS_EN            (SENSOR0_EN | SENSOR1_EN | \
-+                              SENSOR2_EN | SENSOR3_EN | SENSOR4_EN)
-+#define TSENS_8064_SENSOR5_EN                         BIT(8)
-+#define TSENS_8064_SENSOR6_EN                         BIT(9)
-+#define TSENS_8064_SENSOR7_EN                         BIT(10)
-+#define TSENS_8064_SENSOR8_EN                         BIT(11)
-+#define TSENS_8064_SENSOR9_EN                         BIT(12)
-+#define TSENS_8064_SENSOR10_EN                                BIT(13)
-+#define TSENS_8064_SENSORS_EN                         (SENSORS_EN | \
-+                                              TSENS_8064_SENSOR5_EN | \
-+                                              TSENS_8064_SENSOR6_EN | \
-+                                              TSENS_8064_SENSOR7_EN | \
-+                                              TSENS_8064_SENSOR8_EN | \
-+                                              TSENS_8064_SENSOR9_EN | \
-+                                              TSENS_8064_SENSOR10_EN)
-+
-+#define TSENS_8064_SEQ_SENSORS        5
-+#define TSENS_8064_S4_S5_OFFSET       40
-+#define TSENS_FACTOR          1
-+
-+/* Trips: from very hot to very cold */
-+enum tsens_trip_type {
-+      TSENS_TRIP_STAGE3 = 0,
-+      TSENS_TRIP_STAGE2,
-+      TSENS_TRIP_STAGE1,
-+      TSENS_TRIP_STAGE0,
-+      TSENS_TRIP_NUM,
-+};
-+
-+u32 tsens_8064_slope[] = {
-+                      1176, 1176, 1154, 1176,
-+                      1111, 1132, 1132, 1199,
-+                      1132, 1199, 1132
-+                      };
-+
-+/* Temperature on y axis and ADC-code on x-axis */
-+static inline int code_to_degC(u32 adc_code, const struct tsens_sensor *s)
-+{
-+      int degcbeforefactor, degc;
-+
-+      degcbeforefactor = (adc_code * s->slope) + s->offset;
-+
-+      if (degcbeforefactor == 0)
-+              degc = degcbeforefactor;
-+      else if (degcbeforefactor > 0)
-+              degc = (degcbeforefactor + TSENS_FACTOR/2)
-+                      / TSENS_FACTOR;
-+      else
-+              degc = (degcbeforefactor - TSENS_FACTOR/2)
-+                      / TSENS_FACTOR;
-+
-+      return degc;
-+}
-+
-+static int degC_to_code(int degC, const struct tsens_sensor *s)
-+{
-+      int code = ((degC * TSENS_FACTOR - s->offset) + (s->slope/2))
-+                      / s->slope;
-+
-+      if (code > THRESHOLD_MAX_CODE)
-+              code = THRESHOLD_MAX_CODE;
-+      else if (code < THRESHOLD_MIN_CODE)
-+              code = THRESHOLD_MIN_CODE;
-+      return code;
-+}
-+
-+static int suspend_ipq8064(struct tsens_priv *priv)
-+{
-+      int ret;
-+      unsigned int mask;
-+      struct regmap *map = priv->tm_map;
-+
-+      ret = regmap_read(map, THRESHOLD_ADDR, &priv->ctx.threshold);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_read(map, CNTL_ADDR, &priv->ctx.control);
-+      if (ret)
-+              return ret;
-+
-+      mask = SLP_CLK_ENA | EN;
-+
-+      ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int resume_ipq8064(struct tsens_priv *priv)
-+{
-+      int ret;
-+      struct regmap *map = priv->tm_map;
-+
-+      ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_write(map, THRESHOLD_ADDR, priv->ctx.threshold);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_write(map, CNTL_ADDR, priv->ctx.control);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static void notify_uspace_tsens_fn(struct work_struct *work)
-+{
-+      struct tsens_sensor *s = container_of(work, struct tsens_sensor,
-+                                                              notify_work);
-+
-+      sysfs_notify(&s->tzd->device.kobj, NULL, "type");
-+}
-+
-+static void tsens_scheduler_fn(struct work_struct *work)
-+{
-+      struct tsens_priv *priv = container_of(work, struct tsens_priv,
-+                                      tsens_work);
-+      unsigned int threshold, threshold_low, code, reg, sensor, mask;
-+      unsigned int sensor_addr;
-+      bool upper_th_x, lower_th_x;
-+      int adc_code, ret;
-+
-+      ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg);
-+      if (ret)
-+              return;
-+      reg = reg | LOWER_STATUS_CLR | UPPER_STATUS_CLR;
-+      ret = regmap_write(priv->tm_map, STATUS_CNTL_8064, reg);
-+      if (ret)
-+              return;
-+
-+      mask = ~(LOWER_STATUS_CLR | UPPER_STATUS_CLR);
-+      ret = regmap_read(priv->tm_map, THRESHOLD_ADDR, &threshold);
-+      if (ret)
-+              return;
-+      threshold_low = (threshold & THRESHOLD_LOWER_LIMIT_MASK)
-+                              >> THRESHOLD_LOWER_LIMIT_SHIFT;
-+      threshold = (threshold & THRESHOLD_UPPER_LIMIT_MASK)
-+                              >> THRESHOLD_UPPER_LIMIT_SHIFT;
-+
-+      ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg);
-+      if (ret)
-+              return;
-+
-+      ret = regmap_read(priv->tm_map, CNTL_ADDR, &sensor);
-+      if (ret)
-+              return;
-+      sensor &= (uint32_t) TSENS_8064_SENSORS_EN;
-+      sensor >>= SENSOR0_SHIFT;
-+
-+      /* 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.
-+       */
-+
-+      /* Skip if the sensor is disabled */
-+      if (sensor & 1) {
-+              ret = regmap_read(priv->tm_map, priv->sensor[0].status, &code);
-+              if (ret)
-+                      return;
-+              upper_th_x = code >= threshold;
-+              lower_th_x = code <= threshold_low;
-+              if (upper_th_x)
-+                      mask |= UPPER_STATUS_CLR;
-+              if (lower_th_x)
-+                      mask |= LOWER_STATUS_CLR;
-+              if (upper_th_x || lower_th_x) {
-+                      /* Notify user space */
-+                      schedule_work(&priv->sensor[0].notify_work);
-+                      regmap_read(priv->tm_map, sensor_addr, &adc_code);
-+                      pr_debug("Trigger (%d degrees) for sensor %d\n",
-+                              code_to_degC(adc_code, &priv->sensor[0]), 0);
-+              }
-+      }
-+      regmap_write(priv->tm_map, STATUS_CNTL_8064, reg & mask);
-+
-+      /* force memory to sync */
-+      mb();
-+}
-+
-+static irqreturn_t tsens_isr(int irq, void *data)
-+{
-+      struct tsens_priv *priv = data;
-+
-+      schedule_work(&priv->tsens_work);
-+      return IRQ_HANDLED;
-+}
-+
-+static void hw_init(struct tsens_priv *priv)
-+{
-+      int ret;
-+      unsigned int reg_cntl = 0, reg_cfg = 0, reg_thr = 0;
-+      unsigned int reg_status_cntl = 0;
-+
-+      regmap_read(priv->tm_map, CNTL_ADDR, &reg_cntl);
-+      regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl | TSENS_SW_RST);
-+
-+      reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18)
-+              | (((1 << priv->num_sensors) - 1) << SENSOR0_SHIFT);
-+      regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
-+      regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg_status_cntl);
-+      reg_status_cntl |= LOWER_STATUS_CLR | UPPER_STATUS_CLR
-+                      | MIN_STATUS_MASK | MAX_STATUS_MASK;
-+      regmap_write(priv->tm_map, STATUS_CNTL_8064, reg_status_cntl);
-+      reg_cntl |= TSENS_EN;
-+      regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
-+
-+      regmap_read(priv->tm_map, CONFIG_ADDR, &reg_cfg);
-+      reg_cfg = (reg_cfg & ~CONFIG_MASK) | (CONFIG << CONFIG_SHIFT);
-+      regmap_write(priv->tm_map, CONFIG_ADDR, reg_cfg);
-+
-+      reg_thr |= (LOWER_LIMIT_TH << THRESHOLD_LOWER_LIMIT_SHIFT)
-+              | (UPPER_LIMIT_TH << THRESHOLD_UPPER_LIMIT_SHIFT)
-+              | (MIN_LIMIT_TH << THRESHOLD_MIN_LIMIT_SHIFT)
-+              | (MAX_LIMIT_TH << THRESHOLD_MAX_LIMIT_SHIFT);
-+
-+      regmap_write(priv->tm_map, THRESHOLD_ADDR, reg_thr);
-+
-+      ret = devm_request_irq(priv->dev, priv->tsens_irq, tsens_isr,
-+                      IRQF_TRIGGER_RISING, "tsens_interrupt", priv);
-+      if (ret < 0) {
-+              pr_err("%s: request_irq FAIL: %d\n", __func__, ret);
-+              return;
-+      }
-+
-+      INIT_WORK(&priv->tsens_work, tsens_scheduler_fn);
-+}
-+
-+static int init_ipq8064(struct tsens_priv *priv)
-+{
-+      int ret, i;
-+      u32 reg_cntl, offset = 0;
-+
-+      init_common(priv);
-+      if (!priv->tm_map)
-+              return -ENODEV;
-+
-+      /*
-+       * The status registers for each sensor are discontiguous
-+       * because some SoCs have 5 sensors while others have more
-+       * but the control registers stay in the same place, i.e
-+       * directly after the first 5 status registers.
-+       */
-+      for (i = 0; i < priv->num_sensors; i++) {
-+              if (i >= TSENS_8064_SEQ_SENSORS)
-+                      offset = TSENS_8064_S4_S5_OFFSET;
-+
-+              priv->sensor[i].status = S0_STATUS_ADDR + offset
-+                                      + (i << STATUS_ADDR_OFFSET);
-+              priv->sensor[i].slope = tsens_8064_slope[i];
-+              INIT_WORK(&priv->sensor[i].notify_work,
-+                                              notify_uspace_tsens_fn);
-+      }
-+
-+      reg_cntl = SW_RST;
-+      ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
-+      if (ret)
-+              return ret;
-+
-+      reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
-+      reg_cntl &= ~SW_RST;
-+      ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
-+                                       CONFIG_MASK, CONFIG);
-+
-+      reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
-+      ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
-+      if (ret)
-+              return ret;
-+
-+      reg_cntl |= EN;
-+      ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int calibrate_ipq8064(struct tsens_priv *priv)
-+{
-+      int i;
-+      char *data, *data_backup;
-+
-+      ssize_t num_read = priv->num_sensors;
-+      struct tsens_sensor *s = priv->sensor;
-+
-+      data = qfprom_read(priv->dev, "calib");
-+      if (IS_ERR(data)) {
-+              pr_err("Calibration not found.\n");
-+              return PTR_ERR(data);
-+      }
-+
-+      data_backup = qfprom_read(priv->dev, "calib_backup");
-+      if (IS_ERR(data_backup)) {
-+              pr_err("Backup calibration not found.\n");
-+              return PTR_ERR(data_backup);
-+      }
-+
-+      for (i = 0; i < num_read; i++) {
-+              s[i].calib_data = readb_relaxed(data + i);
-+              s[i].calib_data_backup = readb_relaxed(data_backup + i);
-+
-+              if (s[i].calib_data_backup)
-+                      s[i].calib_data = s[i].calib_data_backup;
-+              if (!s[i].calib_data) {
-+                      pr_err("QFPROM TSENS calibration data not present\n");
-+                      return -ENODEV;
-+              }
-+              s[i].slope = tsens_8064_slope[i];
-+              s[i].offset = CAL_MDEGC - (s[i].calib_data * s[i].slope);
-+      }
-+
-+      hw_init(priv);
-+
-+      return 0;
-+}
-+
-+static int get_temp_ipq8064(struct tsens_priv *priv, int id, int *temp)
-+{
-+      int ret;
-+      u32 code, trdy;
-+      const struct tsens_sensor *s = &priv->sensor[id];
-+      unsigned long timeout;
-+
-+      timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
-+      do {
-+              ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
-+              if (ret)
-+                      return ret;
-+              if (!(trdy & TRDY_MASK))
-+                      continue;
-+              ret = regmap_read(priv->tm_map, s->status, &code);
-+              if (ret)
-+                      return ret;
-+              *temp = code_to_degC(code, s);
-+              return 0;
-+      } while (time_before(jiffies, timeout));
-+
-+      return -ETIMEDOUT;
-+}
-+
-+static int set_trip_temp_ipq8064(void *data, int trip, int temp)
-+{
-+      unsigned int reg_th, reg_cntl;
-+      int ret, code, code_chk, hi_code, lo_code;
-+      const struct tsens_sensor *s = data;
-+      struct tsens_priv *priv = s->priv;
-+
-+      code_chk = code = degC_to_code(temp, s);
-+
-+      if (code < THRESHOLD_MIN_CODE || code > THRESHOLD_MAX_CODE)
-+              return -EINVAL;
-+
-+      ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg_cntl);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_read(priv->tm_map, THRESHOLD_ADDR, &reg_th);
-+      if (ret)
-+              return ret;
-+
-+      hi_code = (reg_th & THRESHOLD_UPPER_LIMIT_MASK)
-+                      >> THRESHOLD_UPPER_LIMIT_SHIFT;
-+      lo_code = (reg_th & THRESHOLD_LOWER_LIMIT_MASK)
-+                      >> THRESHOLD_LOWER_LIMIT_SHIFT;
-+
-+      switch (trip) {
-+      case TSENS_TRIP_STAGE3:
-+              code <<= THRESHOLD_MAX_LIMIT_SHIFT;
-+              reg_th &= ~THRESHOLD_MAX_LIMIT_MASK;
-+              break;
-+      case TSENS_TRIP_STAGE2:
-+              if (code_chk <= lo_code)
-+                      return -EINVAL;
-+              code <<= THRESHOLD_UPPER_LIMIT_SHIFT;
-+              reg_th &= ~THRESHOLD_UPPER_LIMIT_MASK;
-+              break;
-+      case TSENS_TRIP_STAGE1:
-+              if (code_chk >= hi_code)
-+                      return -EINVAL;
-+              code <<= THRESHOLD_LOWER_LIMIT_SHIFT;
-+              reg_th &= ~THRESHOLD_LOWER_LIMIT_MASK;
-+              break;
-+      case TSENS_TRIP_STAGE0:
-+              code <<= THRESHOLD_MIN_LIMIT_SHIFT;
-+              reg_th &= ~THRESHOLD_MIN_LIMIT_MASK;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      ret = regmap_write(priv->tm_map, THRESHOLD_ADDR, reg_th | code);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int set_trip_activate_ipq8064(void *data, int trip,
-+                                      enum thermal_trip_activation_mode mode)
-+{
-+      unsigned int reg_cntl, mask, val;
-+      const struct tsens_sensor *s = data;
-+      struct tsens_priv *priv = s->priv;
-+      int ret;
-+
-+      if (!priv || trip < 0)
-+              return -EINVAL;
-+
-+      ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg_cntl);
-+      if (ret)
-+              return ret;
-+
-+      switch (trip) {
-+      case TSENS_TRIP_STAGE3:
-+              mask = MAX_STATUS_MASK;
-+              break;
-+      case TSENS_TRIP_STAGE2:
-+              mask = UPPER_STATUS_CLR;
-+              break;
-+      case TSENS_TRIP_STAGE1:
-+              mask = LOWER_STATUS_CLR;
-+              break;
-+      case TSENS_TRIP_STAGE0:
-+              mask = MIN_STATUS_MASK;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
-+              val = reg_cntl | mask;
-+      else
-+              val = reg_cntl & ~mask;
-+
-+      ret = regmap_write(priv->tm_map, STATUS_CNTL_8064, val);
-+      if (ret)
-+              return ret;
-+
-+      /* force memory to sync */
-+      mb();
-+      return 0;
-+}
-+
-+const struct tsens_ops ops_ipq8064 = {
-+      .init           = init_ipq8064,
-+      .calibrate      = calibrate_ipq8064,
-+      .get_temp       = get_temp_ipq8064,
-+      .suspend        = suspend_ipq8064,
-+      .resume         = resume_ipq8064,
-+      .set_trip_temp  = set_trip_temp_ipq8064,
-+      .set_trip_activate = set_trip_activate_ipq8064,
-+};
-+
-+const struct tsens_plat_data data_ipq8064 = {
-+      .num_sensors    = 11,
-+      .ops            = &ops_ipq8064,
-+};
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -69,8 +69,11 @@ static const struct of_device_id tsens_t
-       }, {
-               .compatible = "qcom,tsens-v2",
-               .data = &data_tsens_v2,
-+      }, {
-+              .compatible = "qcom,ipq8064-tsens",
-+              .data = &data_ipq8064,
-       },
--      {}
-+      {}
- };
- MODULE_DEVICE_TABLE(of, tsens_table);
---- a/drivers/thermal/qcom/tsens.h
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -324,7 +324,7 @@ extern const struct tsens_plat_data data
- extern const struct tsens_plat_data data_8916, data_8974;
- /* TSENS v1 targets */
--extern const struct tsens_plat_data data_tsens_v1;
-+extern const struct tsens_plat_data data_tsens_v1, data_ipq8064;
- /* TSENS v2 targets */
- extern const struct tsens_plat_data data_8996, data_tsens_v2;
diff --git a/target/linux/ipq806x/patches-5.10/0063-2-tsens-support-configurable-interrupts.patch b/target/linux/ipq806x/patches-5.10/0063-2-tsens-support-configurable-interrupts.patch
deleted file mode 100644 (file)
index 585bd62..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-From 4e87400732c77765afae2ea89ed43837457aa604 Mon Sep 17 00:00:00 2001
-From: Rajith Cherian <rajith@codeaurora.org>
-Date: Wed, 1 Feb 2017 19:00:26 +0530
-Subject: [PATCH] ipq8064: tsens: Support for configurable interrupts
-
-Provide support for adding configurable high and
-configurable low trip temperatures. An interrupts is
-also triggerred when these trip points are hit. The
-interrupts can be activated or deactivated from sysfs.
-This functionality is made available only if
-CONFIG_THERMAL_WRITABLE_TRIPS is defined.
-
-Change-Id: Ib73f3f9459de4fffce7bb985a0312a88291f4934
-Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
----
- .../devicetree/bindings/thermal/qcom-tsens.txt     |  4 ++
- drivers/thermal/of-thermal.c                       | 63 ++++++++++++++++++----
- drivers/thermal/qcom/tsens.c                       | 43 ++++++++++++---
- drivers/thermal/qcom/tsens.h                       | 11 ++++
- drivers/thermal/thermal_core.c                     | 44 ++++++++++++++-
- include/linux/thermal.h                            | 14 +++++
- 6 files changed, 162 insertions(+), 17 deletions(-)
-
---- a/drivers/thermal/of-thermal.c
-+++ b/drivers/thermal/of-thermal.c
-@@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct th
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (!data->ops->get_temp)
-+      if (!data->ops->get_temp || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EINVAL;
-       return data->ops->get_temp(data->sensor_data, temp);
-@@ -102,7 +102,8 @@ static int of_thermal_set_trips(struct t
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (!data->ops || !data->ops->set_trips)
-+      if (!data->ops || !data->ops->set_trips
-+                      || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EINVAL;
-       return data->ops->set_trips(data->sensor_data, low, high);
-@@ -188,6 +189,9 @@ static int of_thermal_set_emul_temp(stru
- {
-       struct __thermal_zone *data = tz->devdata;
-+      if (data->mode == THERMAL_DEVICE_DISABLED)
-+              return -EINVAL;
-+
-       return data->ops->set_emul_temp(data->sensor_data, temp);
- }
-@@ -196,7 +200,7 @@ static int of_thermal_get_trend(struct t
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (!data->ops->get_trend)
-+      if (!data->ops->get_trend || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EINVAL;
-       return data->ops->get_trend(data->sensor_data, trip, trend);
-@@ -297,7 +301,9 @@ static int of_thermal_set_mode(struct th
-       mutex_unlock(&tz->lock);
-       data->mode = mode;
--      thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
-+
-+      if (mode == THERMAL_DEVICE_ENABLED)
-+              thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
-       return 0;
- }
-@@ -307,7 +313,8 @@ static int of_thermal_get_trip_type(stru
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (trip >= data->ntrips || trip < 0)
-+      if (trip >= data->ntrips || trip < 0
-+                              || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EDOM;
-       *type = data->trips[trip].type;
-@@ -315,12 +322,39 @@ static int of_thermal_get_trip_type(stru
-       return 0;
- }
-+static int of_thermal_activate_trip_type(struct thermal_zone_device *tz,
-+                      int trip, enum thermal_trip_activation_mode mode)
-+{
-+      struct __thermal_zone *data = tz->devdata;
-+
-+      if (trip >= data->ntrips || trip < 0
-+                              || (data->mode == THERMAL_DEVICE_DISABLED))
-+              return -EDOM;
-+
-+      /*
-+       * The configurable_hi and configurable_lo trip points can be
-+       * activated and deactivated.
-+       */
-+
-+      if (data->ops->set_trip_activate) {
-+              int ret;
-+
-+              ret = data->ops->set_trip_activate(data->sensor_data,
-+                                                              trip, mode);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
- static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
-                                   int *temp)
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (trip >= data->ntrips || trip < 0)
-+      if (trip >= data->ntrips || trip < 0
-+                              || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EDOM;
-       *temp = data->trips[trip].temperature;
-@@ -333,7 +367,8 @@ static int of_thermal_set_trip_temp(stru
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (trip >= data->ntrips || trip < 0)
-+      if (trip >= data->ntrips || trip < 0
-+                              || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EDOM;
-       if (data->ops->set_trip_temp) {
-@@ -355,7 +390,8 @@ static int of_thermal_get_trip_hyst(stru
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (trip >= data->ntrips || trip < 0)
-+      if (trip >= data->ntrips || trip < 0
-+                              || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EDOM;
-       *hyst = data->trips[trip].hysteresis;
-@@ -368,7 +404,8 @@ static int of_thermal_set_trip_hyst(stru
- {
-       struct __thermal_zone *data = tz->devdata;
--      if (trip >= data->ntrips || trip < 0)
-+      if (trip >= data->ntrips || trip < 0
-+                              || (data->mode == THERMAL_DEVICE_DISABLED))
-               return -EDOM;
-       /* thermal framework should take care of data->mask & (1 << trip) */
-@@ -443,6 +480,9 @@ thermal_zone_of_add_sensor(struct device
-       if (ops->set_emul_temp)
-               tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
-+      if (ops->set_trip_activate)
-+              tzd->ops->set_trip_activate = of_thermal_activate_trip_type;
-+
-       mutex_unlock(&tzd->lock);
-       return tzd;
-@@ -762,7 +802,10 @@ static const char * const trip_types[] =
-       [THERMAL_TRIP_ACTIVE]   = "active",
-       [THERMAL_TRIP_PASSIVE]  = "passive",
-       [THERMAL_TRIP_HOT]      = "hot",
--      [THERMAL_TRIP_CRITICAL] = "critical",
-+      [THERMAL_TRIP_CRITICAL] = "critical_high",
-+      [THERMAL_TRIP_CONFIGURABLE_HI] = "configurable_hi",
-+      [THERMAL_TRIP_CONFIGURABLE_LOW] = "configurable_lo",
-+      [THERMAL_TRIP_CRITICAL_LOW] = "critical_low",
- };
- /**
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -22,7 +22,7 @@ static int tsens_get_temp(void *data, in
- static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
- {
--      const struct tsens_sensor *s = data;
-+      struct tsens_sensor *s = data;
-       struct tsens_priv *priv = s->priv;
-       if (priv->ops->get_trend)
-@@ -31,9 +31,10 @@ static int tsens_get_trend(void *data, i
-       return -ENOTSUPP;
- }
--static int  __maybe_unused tsens_suspend(struct device *dev)
-+static int  __maybe_unused tsens_suspend(void *data)
- {
--      struct tsens_priv *priv = dev_get_drvdata(dev);
-+      struct tsens_sensor *s = data;
-+      struct tsens_priv *priv = s->priv;
-       if (priv->ops && priv->ops->suspend)
-               return priv->ops->suspend(priv);
-@@ -41,9 +42,10 @@ static int  __maybe_unused tsens_suspend
-       return 0;
- }
--static int __maybe_unused tsens_resume(struct device *dev)
-+static int __maybe_unused tsens_resume(void *data)
- {
--      struct tsens_priv *priv = dev_get_drvdata(dev);
-+      struct tsens_sensor *s = data;
-+      struct tsens_priv *priv = s->priv;
-       if (priv->ops && priv->ops->resume)
-               return priv->ops->resume(priv);
-@@ -51,6 +53,30 @@ static int __maybe_unused tsens_resume(s
-       return 0;
- }
-+static int  __maybe_unused tsens_set_trip_temp(void *data, int trip, int temp)
-+{
-+      struct tsens_sensor *s = data;
-+      struct tsens_priv *priv = s->priv;
-+
-+      if (priv->ops && priv->ops->set_trip_temp)
-+              return priv->ops->set_trip_temp(s, trip, temp);
-+
-+      return 0;
-+}
-+
-+static int __maybe_unused tsens_activate_trip_type(void *data, int trip,
-+                                      enum thermal_trip_activation_mode mode)
-+{
-+      struct tsens_sensor *s = data;
-+      struct tsens_priv *priv = s->priv;
-+
-+      if (priv->ops && priv->ops->set_trip_activate)
-+              return priv->ops->set_trip_activate(s, trip, mode);
-+
-+      return 0;
-+}
-+
-+
- static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
- static const struct of_device_id tsens_table[] = {
-@@ -80,6 +106,8 @@ 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_trip_temp = tsens_set_trip_temp,
-+      .set_trip_activate = tsens_activate_trip_type,
- };
- static int tsens_register(struct tsens_priv *priv)
-@@ -123,7 +151,7 @@ static int tsens_probe(struct platform_d
-       if (id)
-               data = id->data;
-       else
--              data = &data_8960;
-+              return -EINVAL;
-       num_sensors = data->num_sensors;
-@@ -144,6 +172,9 @@ static int tsens_probe(struct platform_d
-       priv->dev = dev;
-       priv->num_sensors = num_sensors;
-       priv->ops = data->ops;
-+
-+      priv->tsens_irq = platform_get_irq(pdev, 0);
-+
-       for (i = 0;  i < priv->num_sensors; i++) {
-               if (data->hw_ids)
-                       priv->sensor[i].hw_id = data->hw_ids[i];
---- a/drivers/thermal/qcom/tsens.h
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -40,9 +40,12 @@ enum tsens_ver {
- struct tsens_sensor {
-       struct tsens_priv               *priv;
-       struct thermal_zone_device      *tzd;
-+      struct work_struct              notify_work;
-       int                             offset;
-       unsigned int                    id;
-       unsigned int                    hw_id;
-+      int                             calib_data;
-+      int                             calib_data_backup;
-       int                             slope;
-       u32                             status;
- };
-@@ -57,6 +60,9 @@ struct tsens_sensor {
-  * @suspend: Function to suspend the tsens device
-  * @resume: Function to resume the tsens device
-  * @get_trend: Function to get the thermal/temp trend
-+ * @set_trip_temp: Function to set trip temp
-+ * @get_trip_temp: Function to get trip temp
-+ * @set_trip_activate: Function to activate trip points
-  */
- struct tsens_ops {
-       /* mandatory callbacks */
-@@ -69,6 +75,9 @@ struct tsens_ops {
-       int (*suspend)(struct tsens_priv *priv);
-       int (*resume)(struct tsens_priv *priv);
-       int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend);
-+      int (*set_trip_temp)(void *data, int trip, int temp);
-+      int (*set_trip_activate)(void *data, int trip,
-+                                      enum thermal_trip_activation_mode mode);
- };
- #define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
-@@ -300,6 +309,7 @@ struct tsens_context {
- struct tsens_priv {
-       struct device                   *dev;
-       u32                             num_sensors;
-+      u32                             tsens_irq;
-       struct regmap                   *tm_map;
-       struct regmap                   *srot_map;
-       u32                             tm_offset;
-@@ -308,6 +318,7 @@ struct tsens_priv {
-       const struct tsens_features     *feat;
-       const struct reg_field          *fields;
-       const struct tsens_ops          *ops;
-+      struct work_struct              tsens_work;
-       struct tsens_sensor             sensor[0];
- };
---- a/drivers/thermal/thermal_sysfs.c
-+++ b/drivers/thermal/thermal_sysfs.c
-@@ -113,12 +113,48 @@ trip_point_type_show(struct device *dev,
-               return sprintf(buf, "passive\n");
-       case THERMAL_TRIP_ACTIVE:
-               return sprintf(buf, "active\n");
-+      case THERMAL_TRIP_CONFIGURABLE_HI:
-+              return sprintf(buf, "configurable_hi\n");
-+      case THERMAL_TRIP_CONFIGURABLE_LOW:
-+              return sprintf(buf, "configurable_low\n");
-+      case THERMAL_TRIP_CRITICAL_LOW:
-+              return sprintf(buf, "critical_low\n");
-       default:
-               return sprintf(buf, "unknown\n");
-       }
- }
- static ssize_t
-+trip_point_type_activate(struct device *dev, struct device_attribute *attr,
-+                                              const char *buf, size_t count)
-+{
-+      struct thermal_zone_device *tz = to_thermal_zone(dev);
-+      int trip, ret;
-+      char *enabled = "enabled";
-+      char *disabled = "disabled";
-+
-+      if (!tz->ops->set_trip_activate)
-+              return -EPERM;
-+
-+      if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
-+              return -EINVAL;
-+
-+      if (!strncmp(buf, enabled, strlen(enabled)))
-+              ret = tz->ops->set_trip_activate(tz, trip,
-+                              THERMAL_TRIP_ACTIVATION_ENABLED);
-+      else if (!strncmp(buf, disabled, strlen(disabled)))
-+              ret = tz->ops->set_trip_activate(tz, trip,
-+                              THERMAL_TRIP_ACTIVATION_DISABLED);
-+      else
-+              ret = -EINVAL;
-+
-+      if (ret)
-+              return ret;
-+
-+      return count;
-+}
-+
-+static ssize_t
- trip_point_temp_store(struct device *dev, struct device_attribute *attr,
-                     const char *buf, size_t count)
- {
-@@ -559,6 +595,12 @@ static int create_trip_attrs(struct ther
-               tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
-               attrs[indx] = &tz->trip_type_attrs[indx].attr.attr;
-+              if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS)) {
-+                      tz->trip_type_attrs[indx].attr.store
-+                                              = trip_point_type_activate;
-+                      tz->trip_type_attrs[indx].attr.attr.mode |= S_IWUSR;
-+              }
-+
-               /* create trip temp attribute */
-               snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
-                        "trip_point_%d_temp", indx);
---- a/include/linux/thermal.h
-+++ b/include/linux/thermal.h
-@@ -63,11 +63,19 @@ enum thermal_device_mode {
-       THERMAL_DEVICE_ENABLED,
- };
-+enum thermal_trip_activation_mode {
-+      THERMAL_TRIP_ACTIVATION_DISABLED = 0,
-+      THERMAL_TRIP_ACTIVATION_ENABLED,
-+};
-+
- enum thermal_trip_type {
-       THERMAL_TRIP_ACTIVE = 0,
-       THERMAL_TRIP_PASSIVE,
-       THERMAL_TRIP_HOT,
-       THERMAL_TRIP_CRITICAL,
-+      THERMAL_TRIP_CONFIGURABLE_HI,
-+      THERMAL_TRIP_CONFIGURABLE_LOW,
-+      THERMAL_TRIP_CRITICAL_LOW,
- };
- enum thermal_trend {
-@@ -105,6 +113,8 @@ struct thermal_zone_device_ops {
-               enum thermal_trip_type *);
-       int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
-       int (*set_trip_temp) (struct thermal_zone_device *, int, int);
-+      int (*set_trip_activate) (struct thermal_zone_device *, int,
-+                                      enum thermal_trip_activation_mode);
-       int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
-       int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
-       int (*get_crit_temp) (struct thermal_zone_device *, int *);
-@@ -349,6 +359,8 @@ struct thermal_genl_event {
-  *               temperature.
-  * @set_trip_temp: a pointer to a function that sets the trip temperature on
-  *               hardware.
-+ * @activate_trip_type: a pointer to a function to enable/disable trip
-+ *            temperature interrupts
-  */
- struct thermal_zone_of_device_ops {
-       int (*get_temp)(void *, int *);
-@@ -356,6 +368,8 @@ struct thermal_zone_of_device_ops {
-       int (*set_trips)(void *, int, int);
-       int (*set_emul_temp)(void *, int);
-       int (*set_trip_temp)(void *, int, int);
-+      int (*set_trip_activate)(void *, int,
-+                              enum thermal_trip_activation_mode);
- };
- /**
diff --git a/target/linux/ipq806x/patches-5.10/0063-3-tsens-fix-kernel-5_4.patch b/target/linux/ipq806x/patches-5.10/0063-3-tsens-fix-kernel-5_4.patch
deleted file mode 100644 (file)
index 6c056db..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
---- a/drivers/thermal/qcom/tsens-ipq8064.c
-+++ b/drivers/thermal/qcom/tsens-ipq8064.c
-@@ -18,6 +18,7 @@
- #include <linux/regmap.h>
- #include <linux/thermal.h>
- #include <linux/nvmem-consumer.h>
-+#include <linux/of_platform.h>
- #include <linux/io.h>
- #include <linux/interrupt.h>
- #include "tsens.h"
-@@ -320,15 +321,42 @@ static void hw_init(struct tsens_priv *p
-       INIT_WORK(&priv->tsens_work, tsens_scheduler_fn);
- }
-+static const struct regmap_config tsens_config = {
-+      .name           = "tm",
-+      .reg_bits       = 32,
-+      .val_bits       = 32,
-+      .reg_stride     = 4,
-+};
-+
- static int init_ipq8064(struct tsens_priv *priv)
- {
--      int ret, i;
-+      struct device *dev = priv->dev;
-       u32 reg_cntl, offset = 0;
-+      struct resource *res;
-+      resource_size_t size;
-+      void __iomem *base;
-+      int ret, i;
-+      struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
-+
-+      if (!op)
-+              return -EINVAL;
--      init_common(priv);
--      if (!priv->tm_map)
--              return -ENODEV;
-+      /* old DTs where SROT and TM were in a contiguous 2K block */
-+      priv->tm_offset = 0x1000;
-+      res = platform_get_resource(op, IORESOURCE_MEM, 0);
-+      size = resource_size(res);
-+      base = devm_ioremap(&op->dev, res->start, size);
-+      if (IS_ERR(base)) {
-+              ret = PTR_ERR(base);
-+              goto err_put_device;
-+      }
-+
-+      priv->tm_map = devm_regmap_init_mmio(dev, base, &tsens_config);
-+      if (IS_ERR(priv->tm_map)) {
-+              ret = PTR_ERR(priv->tm_map);
-+              goto err_put_device;
-+      }
-       /*
-        * The status registers for each sensor are discontiguous
-        * because some SoCs have 5 sensors while others have more
-@@ -367,6 +395,10 @@ static int init_ipq8064(struct tsens_pri
-               return ret;
-       return 0;
-+
-+err_put_device:
-+      put_device(&op->dev);
-+      return ret;
- }
- static int calibrate_ipq8064(struct tsens_priv *priv)
diff --git a/target/linux/ipq806x/patches-5.10/0063-4-ip806x-tsense-rework-driver.patch b/target/linux/ipq806x/patches-5.10/0063-4-ip806x-tsense-rework-driver.patch
deleted file mode 100644 (file)
index 67fc8db..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
---- a/drivers/thermal/qcom/tsens-ipq8064.c
-+++ b/drivers/thermal/qcom/tsens-ipq8064.c
-@@ -13,10 +13,12 @@
-  */
- #include <linux/platform_device.h>
-+#include <linux/err.h>
- #include <linux/delay.h>
- #include <linux/bitops.h>
- #include <linux/regmap.h>
- #include <linux/thermal.h>
-+#include <linux/slab.h>
- #include <linux/nvmem-consumer.h>
- #include <linux/of_platform.h>
- #include <linux/io.h>
-@@ -211,9 +213,8 @@ static void tsens_scheduler_fn(struct wo
-       struct tsens_priv *priv = container_of(work, struct tsens_priv,
-                                       tsens_work);
-       unsigned int threshold, threshold_low, code, reg, sensor, mask;
--      unsigned int sensor_addr;
-       bool upper_th_x, lower_th_x;
--      int adc_code, ret;
-+      int ret;
-       ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg);
-       if (ret)
-@@ -262,9 +263,8 @@ static void tsens_scheduler_fn(struct wo
-               if (upper_th_x || lower_th_x) {
-                       /* Notify user space */
-                       schedule_work(&priv->sensor[0].notify_work);
--                      regmap_read(priv->tm_map, sensor_addr, &adc_code);
-                       pr_debug("Trigger (%d degrees) for sensor %d\n",
--                              code_to_degC(adc_code, &priv->sensor[0]), 0);
-+                              code_to_degC(code, &priv->sensor[0]), 0);
-               }
-       }
-       regmap_write(priv->tm_map, STATUS_CNTL_8064, reg & mask);
-@@ -404,40 +404,55 @@ err_put_device:
- static int calibrate_ipq8064(struct tsens_priv *priv)
- {
-       int i;
--      char *data, *data_backup;
--
-+      int ret = 0;
-+      u8 *data, *data_backup;
-+      struct device *dev = priv->dev;
-       ssize_t num_read = priv->num_sensors;
-       struct tsens_sensor *s = priv->sensor;
--      data = qfprom_read(priv->dev, "calib");
-+      data = qfprom_read(dev, "calib");
-       if (IS_ERR(data)) {
--              pr_err("Calibration not found.\n");
--              return PTR_ERR(data);
-+              ret = PTR_ERR(data);
-+              if (ret != -EPROBE_DEFER)
-+                      dev_err(dev, "Calibration not found.");
-+              goto exit;
-       }
--      data_backup = qfprom_read(priv->dev, "calib_backup");
-+      data_backup = qfprom_read(dev, "calib_backup");
-       if (IS_ERR(data_backup)) {
--              pr_err("Backup calibration not found.\n");
--              return PTR_ERR(data_backup);
-+              ret = PTR_ERR(data_backup);
-+              if (ret != -EPROBE_DEFER)
-+                      dev_err(dev, "Backup Calibration not found.");
-+              goto free_data;
-       }
-       for (i = 0; i < num_read; i++) {
-               s[i].calib_data = readb_relaxed(data + i);
--              s[i].calib_data_backup = readb_relaxed(data_backup + i);
-+              
-+              if (!s[i].calib_data) {
-+                      s[i].calib_data_backup = readb_relaxed(data_backup + i);
-+
-+                      if (!s[i].calib_data_backup) {
-+                              dev_err(dev, "QFPROM TSENS calibration data not present");
-+                              ret = -ENODEV;
-+                              goto free_backup;
-+                      }
--              if (s[i].calib_data_backup)
-                       s[i].calib_data = s[i].calib_data_backup;
--              if (!s[i].calib_data) {
--                      pr_err("QFPROM TSENS calibration data not present\n");
--                      return -ENODEV;
-               }
-+
-               s[i].slope = tsens_8064_slope[i];
-               s[i].offset = CAL_MDEGC - (s[i].calib_data * s[i].slope);
-       }
-       hw_init(priv);
--      return 0;
-+free_backup:
-+      kfree(data_backup);
-+free_data:
-+      kfree(data);
-+exit:
-+      return ret;
- }
- static int get_temp_ipq8064(struct tsens_priv *priv, int id, int *temp)
diff --git a/target/linux/ipq806x/patches-5.10/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch b/target/linux/ipq806x/patches-5.10/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch
new file mode 100644 (file)
index 0000000..d4c85a0
--- /dev/null
@@ -0,0 +1,292 @@
+From 5c7d1181056feef0b58fb2f556f55e170ba5b479 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sat, 25 Jul 2020 19:14:59 +0200
+Subject: [PATCH 01/10] drivers: thermal: tsens: Add VER_0 tsens version
+
+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>
+Reviewed-by: Thara Gopinath <thara.gopinath@linaro.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+---
+ drivers/thermal/qcom/tsens.c | 150 ++++++++++++++++++++++++++++-------
+ drivers/thermal/qcom/tsens.h |   4 +-
+ 2 files changed, 124 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index d8ce3a687b80..9a7e991d4bd2 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -12,6 +12,7 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/of_platform.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm.h>
+ #include <linux/regmap.h>
+@@ -515,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;
+@@ -530,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);
+@@ -584,18 +601,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 */
+@@ -608,15 +628,29 @@ int get_temp_common(const struct tsens_sensor *s, int *temp)
+ {
+       struct tsens_priv *priv = s->priv;
+       int hw_id = s->hw_id;
+-      int last_temp = 0, ret;
++      int last_temp = 0, ret, trdy;
++      unsigned long timeout;
+-      ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
+-      if (ret)
+-              return ret;
++      timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
++      do {
++              if (tsens_version(priv) == VER_0) {
++                      ret = regmap_field_read(priv->rf[TRDY], &trdy);
++                      if (ret)
++                              return ret;
++                      if (!trdy)
++                              continue;
++              }
+-      *temp = code_to_degc(last_temp, s) * 1000;
++              ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
++              if (ret)
++                      return ret;
+-      return 0;
++              *temp = code_to_degc(last_temp, s) * 1000;
++
++              return 0;
++      } while (time_before(jiffies, timeout));
++
++      return -ETIMEDOUT;
+ }
+ #ifdef CONFIG_DEBUG_FS
+@@ -738,19 +772,34 @@ int __init init_common(struct tsens_priv *priv)
+               priv->tm_offset = 0x1000;
+       }
+-      res = platform_get_resource(op, IORESOURCE_MEM, 0);
+-      tm_base = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(tm_base)) {
+-              ret = PTR_ERR(tm_base);
+-              goto err_put_device;
++      if (tsens_version(priv) >= VER_0_1) {
++              res = platform_get_resource(op, IORESOURCE_MEM, 0);
++              tm_base = devm_ioremap_resource(dev, res);
++              if (IS_ERR(tm_base)) {
++                      ret = PTR_ERR(tm_base);
++                      goto err_put_device;
++              }
++
++              priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
++      } else { /* VER_0 share the same gcc regs using a syscon */
++              struct device *parent = priv->dev->parent;
++
++              if (parent)
++                      priv->tm_map = syscon_node_to_regmap(parent->of_node);
+       }
+-      priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
+-      if (IS_ERR(priv->tm_map)) {
+-              ret = PTR_ERR(priv->tm_map);
++      if (IS_ERR_OR_NULL(priv->tm_map)) {
++              if (!priv->tm_map)
++                      ret = -ENODEV;
++              else
++                      ret = PTR_ERR(priv->tm_map);
+               goto err_put_device;
+       }
++      /* VER_0 have only tm_map */
++      if (!priv->srot_map)
++              priv->srot_map = priv->tm_map;
++
+       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,
+@@ -769,6 +818,10 @@ int __init init_common(struct tsens_priv *priv)
+               ret = PTR_ERR(priv->rf[TSENS_EN]);
+               goto err_put_device;
+       }
++      /* in VER_0 TSENS need to be explicitly enabled */
++      if (tsens_version(priv) == VER_0)
++              regmap_field_write(priv->rf[TSENS_EN], 1);
++
+       ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
+       if (ret)
+               goto err_put_device;
+@@ -791,6 +844,19 @@ int __init init_common(struct tsens_priv *priv)
+               goto err_put_device;
+       }
++      priv->rf[TSENS_SW_RST] =
++              devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]);
++      if (IS_ERR(priv->rf[TSENS_SW_RST])) {
++              ret = PTR_ERR(priv->rf[TSENS_SW_RST]);
++              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;
++      }
++
+       /* 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++) {
+@@ -806,7 +872,7 @@ int __init init_common(struct tsens_priv *priv)
+               }
+       }
+-      if (priv->feat->crit_int) {
++      if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {
+               /* Loop might need changes if enum regfield_ids is reordered */
+               for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
+                       for (i = 0; i < priv->feat->max_sensors; i++) {
+@@ -844,7 +910,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:
+@@ -943,10 +1013,19 @@ 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 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */
++              if (tsens_version(priv) == VER_0)
++                      ret = devm_request_threaded_irq(&pdev->dev, irq,
++                                                      thread_fn, NULL,
++                                                      IRQF_TRIGGER_RISING,
++                                                      dev_name(&pdev->dev),
++                                                      priv);
++              else
++                      ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
++                                                      thread_fn, IRQF_ONESHOT,
++                                                      dev_name(&pdev->dev),
++                                                      priv);
++
+               if (ret)
+                       dev_err(&pdev->dev, "%s: failed to get irq\n",
+                               __func__);
+@@ -975,6 +1054,19 @@ static int tsens_register(struct tsens_priv *priv)
+                       priv->ops->enable(priv, i);
+       }
++      /* VER_0 require to set MIN and MAX THRESH
++       * These 2 regs are set using the:
++       * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C
++       * - CRIT_THRESH_1 for MIN THRESH hardcoded to   0°C
++       */
++      if (tsens_version(priv) < VER_0_1) {
++              regmap_field_write(priv->rf[CRIT_THRESH_0],
++                                 tsens_mC_to_hw(priv->sensor, 120000));
++
++              regmap_field_write(priv->rf[CRIT_THRESH_1],
++                                 tsens_mC_to_hw(priv->sensor, 0));
++      }
++
+       ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
+       if (ret < 0)
+               return ret;
+diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
+index f40b625f897e..8e6c1fd3ccf5 100644
+--- a/drivers/thermal/qcom/tsens.h
++++ b/drivers/thermal/qcom/tsens.h
+@@ -13,6 +13,7 @@
+ #define CAL_DEGC_PT2          120
+ #define SLOPE_FACTOR          1000
+ #define SLOPE_DEFAULT         3200
++#define TIMEOUT_US            100
+ #define THRESHOLD_MAX_ADC_CODE        0x3ff
+ #define THRESHOLD_MIN_ADC_CODE        0x0
+@@ -25,7 +26,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,
+ };
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch b/target/linux/ipq806x/patches-5.10/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch
new file mode 100644 (file)
index 0000000..44de19b
--- /dev/null
@@ -0,0 +1,33 @@
+From efa0d50a6c5ec7619371dfe4d3e6ca54b73787d5 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Wed, 25 Nov 2020 16:47:21 +0100
+Subject: [PATCH 02/10] drivers: thermal: tsens: Don't hardcode sensor slope
+
+Function compute_intercept_slope hardcode the sensor slope to
+SLOPE_DEFAULT. Change this and use the default value only if a slope is
+not defined. This is needed for tsens VER_0 that has a hardcoded slope
+table.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index 9a7e991d4bd2..38b9936def1a 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -86,7 +86,8 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
+                       "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
+                       __func__, i, p1[i], p2[i]);
+-              priv->sensor[i].slope = SLOPE_DEFAULT;
++              if (!priv->sensor[i].slope)
++                      priv->sensor[i].slope = SLOPE_DEFAULT;
+               if (mode == TWO_PT_CALIB) {
+                       /*
+                        * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch b/target/linux/ipq806x/patches-5.10/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch
new file mode 100644 (file)
index 0000000..d8779c6
--- /dev/null
@@ -0,0 +1,124 @@
+From 6bac2e2fa36c2d7c304768a689d8b73155b90aa2 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Wed, 25 Nov 2020 17:15:51 +0100
+Subject: [PATCH 03/10] drivers: thermal: tsens: Convert msm8960 to reg_field
+
+Convert msm9860 driver to reg_field to use the init_common
+function.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Acked-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens-8960.c | 80 ++++++++++++++++++++++++++++++-
+ 1 file changed, 79 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
+index 2a28a5af209e..3f4fc1ffe679 100644
+--- a/drivers/thermal/qcom/tsens-8960.c
++++ b/drivers/thermal/qcom/tsens-8960.c
+@@ -51,11 +51,22 @@
+ #define MIN_LIMIT_TH          0x0
+ #define MAX_LIMIT_TH          0xff
+-#define S0_STATUS_ADDR                0x3628
+ #define INT_STATUS_ADDR               0x363c
+ #define TRDY_MASK             BIT(7)
+ #define TIMEOUT_US            100
++#define S0_STATUS_OFF         0x3628
++#define S1_STATUS_OFF         0x362c
++#define S2_STATUS_OFF         0x3630
++#define S3_STATUS_OFF         0x3634
++#define S4_STATUS_OFF         0x3638
++#define S5_STATUS_OFF         0x3664  /* Sensors 5-10 found on apq8064/msm8960 */
++#define S6_STATUS_OFF         0x3668
++#define S7_STATUS_OFF         0x366c
++#define S8_STATUS_OFF         0x3670
++#define S9_STATUS_OFF         0x3674
++#define S10_STATUS_OFF                0x3678
++
+ static int suspend_8960(struct tsens_priv *priv)
+ {
+       int ret;
+@@ -269,6 +280,71 @@ static int get_temp_8960(const struct tsens_sensor *s, int *temp)
+       return -ETIMEDOUT;
+ }
++static struct tsens_features tsens_8960_feat = {
++      .ver_major      = VER_0,
++      .crit_int       = 0,
++      .adc            = 1,
++      .srot_split     = 0,
++      .max_sensors    = 11,
++};
++
++static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = {
++      /* ----- SROT ------ */
++      /* No VERSION information */
++
++      /* CNTL */
++      [TSENS_EN]     = REG_FIELD(CNTL_ADDR,  0, 0),
++      [TSENS_SW_RST] = REG_FIELD(CNTL_ADDR,  1, 1),
++      /* 8960 has 5 sensors, 8660 has 11, we only handle 5 */
++      [SENSOR_EN]    = REG_FIELD(CNTL_ADDR,  3, 7),
++
++      /* ----- TM ------ */
++      /* INTERRUPT ENABLE */
++      /* NO INTERRUPT ENABLE */
++
++      /* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */
++      [LOW_THRESH_0]   = REG_FIELD(THRESHOLD_ADDR,  0,  7),
++      [UP_THRESH_0]    = REG_FIELD(THRESHOLD_ADDR,  8, 15),
++      /* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield
++       * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp
++       * MIN_THRESH_0 -> CRIT_THRESH_1
++       * MAX_THRESH_0 -> CRIT_THRESH_0
++       */
++      [CRIT_THRESH_1]   = REG_FIELD(THRESHOLD_ADDR, 16, 23),
++      [CRIT_THRESH_0]   = REG_FIELD(THRESHOLD_ADDR, 24, 31),
++
++      /* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */
++      /* 1 == clear, 0 == normal operation */
++      [LOW_INT_CLEAR_0]   = REG_FIELD(CNTL_ADDR,  9,  9),
++      [UP_INT_CLEAR_0]    = REG_FIELD(CNTL_ADDR, 10, 10),
++
++      /* NO CRITICAL INTERRUPT SUPPORT on 8960 */
++
++      /* Sn_STATUS */
++      [LAST_TEMP_0]  = REG_FIELD(S0_STATUS_OFF,  0,  7),
++      [LAST_TEMP_1]  = REG_FIELD(S1_STATUS_OFF,  0,  7),
++      [LAST_TEMP_2]  = REG_FIELD(S2_STATUS_OFF,  0,  7),
++      [LAST_TEMP_3]  = REG_FIELD(S3_STATUS_OFF,  0,  7),
++      [LAST_TEMP_4]  = REG_FIELD(S4_STATUS_OFF,  0,  7),
++      [LAST_TEMP_5]  = REG_FIELD(S5_STATUS_OFF,  0,  7),
++      [LAST_TEMP_6]  = REG_FIELD(S6_STATUS_OFF,  0,  7),
++      [LAST_TEMP_7]  = REG_FIELD(S7_STATUS_OFF,  0,  7),
++      [LAST_TEMP_8]  = REG_FIELD(S8_STATUS_OFF,  0,  7),
++      [LAST_TEMP_9]  = REG_FIELD(S9_STATUS_OFF,  0,  7),
++      [LAST_TEMP_10] = REG_FIELD(S10_STATUS_OFF, 0,  7),
++
++      /* No VALID field on 8960 */
++      /* TSENS_INT_STATUS bits: 1 == threshold violated */
++      [MIN_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 0, 0),
++      [LOWER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 1, 1),
++      [UPPER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 2, 2),
++      /* No CRITICAL field on 8960 */
++      [MAX_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 3, 3),
++
++      /* TRDY: 1=ready, 0=in progress */
++      [TRDY] = REG_FIELD(INT_STATUS_ADDR, 7, 7),
++};
++
+ static const struct tsens_ops ops_8960 = {
+       .init           = init_8960,
+       .calibrate      = calibrate_8960,
+@@ -282,4 +358,6 @@ static const struct tsens_ops ops_8960 = {
+ struct tsens_plat_data data_8960 = {
+       .num_sensors    = 11,
+       .ops            = &ops_8960,
++      .feat           = &tsens_8960_feat,
++      .fields         = tsens_8960_regfields,
+ };
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch b/target/linux/ipq806x/patches-5.10/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch
new file mode 100644 (file)
index 0000000..4b12609
--- /dev/null
@@ -0,0 +1,86 @@
+From c04f98a496929f75d75c65115d5717423c3d0634 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Wed, 25 Nov 2020 17:16:36 +0100
+Subject: [PATCH 04/10] drivers: thermal: tsens: Use init_common for msm8960
+
+Use init_common and drop custom init for msm8960.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens-8960.c | 52 +------------------------------
+ 1 file changed, 1 insertion(+), 51 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
+index 3f4fc1ffe679..86585f439985 100644
+--- a/drivers/thermal/qcom/tsens-8960.c
++++ b/drivers/thermal/qcom/tsens-8960.c
+@@ -173,56 +173,6 @@ static void disable_8960(struct tsens_priv *priv)
+       regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+ }
+-static int init_8960(struct tsens_priv *priv)
+-{
+-      int ret, i;
+-      u32 reg_cntl;
+-
+-      priv->tm_map = dev_get_regmap(priv->dev, NULL);
+-      if (!priv->tm_map)
+-              return -ENODEV;
+-
+-      /*
+-       * The status registers for each sensor are discontiguous
+-       * because some SoCs have 5 sensors while others have more
+-       * but the control registers stay in the same place, i.e
+-       * directly after the first 5 status registers.
+-       */
+-      for (i = 0; i < priv->num_sensors; i++) {
+-              if (i >= 5)
+-                      priv->sensor[i].status = S0_STATUS_ADDR + 40;
+-              priv->sensor[i].status += i * 4;
+-      }
+-
+-      reg_cntl = SW_RST;
+-      ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
+-      if (ret)
+-              return ret;
+-
+-      if (priv->num_sensors > 1) {
+-              reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
+-              reg_cntl &= ~SW_RST;
+-              ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
+-                                       CONFIG_MASK, CONFIG);
+-      } else {
+-              reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
+-              reg_cntl &= ~CONFIG_MASK_8660;
+-              reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
+-      }
+-
+-      reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
+-      ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+-      if (ret)
+-              return ret;
+-
+-      reg_cntl |= EN;
+-      ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+-      if (ret)
+-              return ret;
+-
+-      return 0;
+-}
+-
+ static int calibrate_8960(struct tsens_priv *priv)
+ {
+       int i;
+@@ -346,7 +296,7 @@ static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = {
+ };
+ static const struct tsens_ops ops_8960 = {
+-      .init           = init_8960,
++      .init           = init_common,
+       .calibrate      = calibrate_8960,
+       .get_temp       = get_temp_8960,
+       .enable         = enable_8960,
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch b/target/linux/ipq806x/patches-5.10/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch
new file mode 100644 (file)
index 0000000..4f8a676
--- /dev/null
@@ -0,0 +1,71 @@
+From b3e8bd33b84a6b6c863bd1733bd15b5f1483b8ab Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Wed, 25 Nov 2020 17:06:55 +0100
+Subject: [PATCH 05/10] drivers: thermal: tsens: Fix bug in sensor enable for
+ msm8960
+
+Device based on tsens VER_0 contains a hardware bug that results in some
+problem with sensor enablement. Sensor id 6-11 can't be enabled
+selectively and all of them must be enabled in one step.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Acked-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens-8960.c | 23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
+index 86585f439985..95fcccafae14 100644
+--- a/drivers/thermal/qcom/tsens-8960.c
++++ b/drivers/thermal/qcom/tsens-8960.c
+@@ -27,9 +27,9 @@
+ #define EN                    BIT(0)
+ #define SW_RST                        BIT(1)
+ #define SENSOR0_EN            BIT(3)
++#define MEASURE_PERIOD                BIT(18)
+ #define SLP_CLK_ENA           BIT(26)
+ #define SLP_CLK_ENA_8660      BIT(24)
+-#define MEASURE_PERIOD                1
+ #define SENSOR0_SHIFT         3
+ /* INT_STATUS_ADDR bitmasks */
+@@ -126,17 +126,34 @@ static int resume_8960(struct tsens_priv *priv)
+ static int enable_8960(struct tsens_priv *priv, int id)
+ {
+       int ret;
+-      u32 reg, mask;
++      u32 reg, mask = BIT(id);
+       ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);
+       if (ret)
+               return ret;
+-      mask = BIT(id + SENSOR0_SHIFT);
++      /* HARDWARE BUG:
++       * On platforms with more than 6 sensors, all remaining sensors
++       * must be enabled together, otherwise undefined results are expected.
++       * (Sensor 6-7 disabled, Sensor 3 disabled...) In the original driver,
++       * all the sensors are enabled in one step hence this bug is not
++       * triggered.
++       */
++      if (id > 5)
++              mask = GENMASK(10, 6);
++
++      mask <<= SENSOR0_SHIFT;
++
++      /* Sensors already enabled. Skip. */
++      if ((reg & mask) == mask)
++              return 0;
++
+       ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
+       if (ret)
+               return ret;
++      reg |= MEASURE_PERIOD;
++
+       if (priv->num_sensors > 1)
+               reg |= mask | SLP_CLK_ENA | EN;
+       else
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch b/target/linux/ipq806x/patches-5.10/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch
new file mode 100644 (file)
index 0000000..657f8b8
--- /dev/null
@@ -0,0 +1,114 @@
+From 1ff9f982051759e0387e8c7e793b49c48eae291d Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Wed, 25 Nov 2020 17:11:05 +0100
+Subject: [PATCH 06/10] drivers: thermal: tsens: Replace custom 8960 apis with
+ generic apis
+
+Rework calibrate function to use common function. Derive the offset from
+a missing hardcoded slope table and the data from the nvmem calib
+efuses.
+Drop custom get_temp function and use generic api.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Acked-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens-8960.c | 56 +++++++++----------------------
+ 1 file changed, 15 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
+index 95fcccafae14..9cc8a7dd23ae 100644
+--- a/drivers/thermal/qcom/tsens-8960.c
++++ b/drivers/thermal/qcom/tsens-8960.c
+@@ -67,6 +67,13 @@
+ #define S9_STATUS_OFF         0x3674
+ #define S10_STATUS_OFF                0x3678
++/* Original slope - 200 to compensate mC to C inaccuracy */
++static u32 tsens_msm8960_slope[] = {
++                      976, 976, 954, 976,
++                      911, 932, 932, 999,
++                      932, 999, 932
++                      };
++
+ static int suspend_8960(struct tsens_priv *priv)
+ {
+       int ret;
+@@ -194,9 +201,7 @@ static int calibrate_8960(struct tsens_priv *priv)
+ {
+       int i;
+       char *data;
+-
+-      ssize_t num_read = priv->num_sensors;
+-      struct tsens_sensor *s = priv->sensor;
++      u32 p1[11];
+       data = qfprom_read(priv->dev, "calib");
+       if (IS_ERR(data))
+@@ -204,49 +209,18 @@ static int calibrate_8960(struct tsens_priv *priv)
+       if (IS_ERR(data))
+               return PTR_ERR(data);
+-      for (i = 0; i < num_read; i++, s++)
+-              s->offset = data[i];
++      for (i = 0; i < priv->num_sensors; i++) {
++              p1[i] = data[i];
++              priv->sensor[i].slope = tsens_msm8960_slope[i];
++      }
++
++      compute_intercept_slope(priv, p1, NULL, ONE_PT_CALIB);
+       kfree(data);
+       return 0;
+ }
+-/* Temperature on y axis and ADC-code on x-axis */
+-static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
+-{
+-      int slope, offset;
+-
+-      slope = thermal_zone_get_slope(s->tzd);
+-      offset = CAL_MDEGC - slope * s->offset;
+-
+-      return adc_code * slope + offset;
+-}
+-
+-static int get_temp_8960(const struct tsens_sensor *s, int *temp)
+-{
+-      int ret;
+-      u32 code, trdy;
+-      struct tsens_priv *priv = s->priv;
+-      unsigned long timeout;
+-
+-      timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+-      do {
+-              ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
+-              if (ret)
+-                      return ret;
+-              if (!(trdy & TRDY_MASK))
+-                      continue;
+-              ret = regmap_read(priv->tm_map, s->status, &code);
+-              if (ret)
+-                      return ret;
+-              *temp = code_to_mdegC(code, s);
+-              return 0;
+-      } while (time_before(jiffies, timeout));
+-
+-      return -ETIMEDOUT;
+-}
+-
+ static struct tsens_features tsens_8960_feat = {
+       .ver_major      = VER_0,
+       .crit_int       = 0,
+@@ -315,7 +289,7 @@ static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = {
+ static const struct tsens_ops ops_8960 = {
+       .init           = init_common,
+       .calibrate      = calibrate_8960,
+-      .get_temp       = get_temp_8960,
++      .get_temp       = get_temp_common,
+       .enable         = enable_8960,
+       .disable        = disable_8960,
+       .suspend        = suspend_8960,
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch b/target/linux/ipq806x/patches-5.10/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch
new file mode 100644 (file)
index 0000000..d0e383d
--- /dev/null
@@ -0,0 +1,70 @@
+From 5716a61239c6ac9ceb137e825e93c3aea06c4634 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 19 Mar 2021 00:48:23 +0100
+Subject: [PATCH 07/10] drivers: thermal: tsens: Drop unused define for msm8960
+
+Drop unused define for msm8960 replaced by generic api and reg_field.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens-8960.c | 24 +-----------------------
+ 1 file changed, 1 insertion(+), 23 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
+index 9cc8a7dd23ae..58d09e927383 100644
+--- a/drivers/thermal/qcom/tsens-8960.c
++++ b/drivers/thermal/qcom/tsens-8960.c
+@@ -10,8 +10,6 @@
+ #include <linux/thermal.h>
+ #include "tsens.h"
+-#define CAL_MDEGC             30000
+-
+ #define CONFIG_ADDR           0x3640
+ #define CONFIG_ADDR_8660      0x3620
+ /* CONFIG_ADDR bitmasks */
+@@ -21,39 +19,19 @@
+ #define CONFIG_SHIFT_8660     28
+ #define CONFIG_MASK_8660      (3 << CONFIG_SHIFT_8660)
+-#define STATUS_CNTL_ADDR_8064 0x3660
+ #define CNTL_ADDR             0x3620
+ /* CNTL_ADDR bitmasks */
+ #define EN                    BIT(0)
+ #define SW_RST                        BIT(1)
+-#define SENSOR0_EN            BIT(3)
++
+ #define MEASURE_PERIOD                BIT(18)
+ #define SLP_CLK_ENA           BIT(26)
+ #define SLP_CLK_ENA_8660      BIT(24)
+ #define SENSOR0_SHIFT         3
+-/* INT_STATUS_ADDR bitmasks */
+-#define MIN_STATUS_MASK               BIT(0)
+-#define LOWER_STATUS_CLR      BIT(1)
+-#define UPPER_STATUS_CLR      BIT(2)
+-#define MAX_STATUS_MASK               BIT(3)
+-
+ #define THRESHOLD_ADDR                0x3624
+-/* THRESHOLD_ADDR bitmasks */
+-#define THRESHOLD_MAX_LIMIT_SHIFT     24
+-#define THRESHOLD_MIN_LIMIT_SHIFT     16
+-#define THRESHOLD_UPPER_LIMIT_SHIFT   8
+-#define THRESHOLD_LOWER_LIMIT_SHIFT   0
+-
+-/* Initial temperature threshold values */
+-#define LOWER_LIMIT_TH                0x50
+-#define UPPER_LIMIT_TH                0xdf
+-#define MIN_LIMIT_TH          0x0
+-#define MAX_LIMIT_TH          0xff
+ #define INT_STATUS_ADDR               0x363c
+-#define TRDY_MASK             BIT(7)
+-#define TIMEOUT_US            100
+ #define S0_STATUS_OFF         0x3628
+ #define S1_STATUS_OFF         0x362c
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch b/target/linux/ipq806x/patches-5.10/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch
new file mode 100644 (file)
index 0000000..928e8fd
--- /dev/null
@@ -0,0 +1,31 @@
+From 0d0c22a59bf2672b57e23da9a9ea743e91b71f54 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sat, 25 Jul 2020 19:55:57 +0200
+Subject: [PATCH 08/10] drivers: thermal: tsens: Add support for ipq8064-tsens
+
+Add support for tsens present in ipq806x SoCs based on generic msm8960
+tsens driver.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath@linaro.org>
+---
+ drivers/thermal/qcom/tsens.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index 38b9936def1a..58073dc5d30b 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -966,6 +966,9 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
+ static const struct of_device_id tsens_table[] = {
+       {
++              .compatible = "qcom,ipq8064-tsens",
++              .data = &data_8960,
++      }, {
+               .compatible = "qcom,msm8916-tsens",
+               .data = &data_8916,
+       }, {
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch b/target/linux/ipq806x/patches-5.10/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch
new file mode 100644 (file)
index 0000000..121f857
--- /dev/null
@@ -0,0 +1,115 @@
+From ac369071920d427dd484cf74cddba2774bba45f5 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 9 Jul 2020 22:35:54 +0200
+Subject: [PATCH 09/10] dt-bindings: thermal: tsens: Document ipq8064 bindings
+
+Document the use of bindings used for msm8960 tsens based devices.
+msm8960 use the same gcc regs and is set as a child of the qcom gcc.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ .../bindings/thermal/qcom-tsens.yaml          | 56 ++++++++++++++++---
+ 1 file changed, 48 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
+index 95462e071ab4..1785b1c75a3c 100644
+--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
++++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
+@@ -19,6 +19,11 @@ description: |
+ properties:
+   compatible:
+     oneOf:
++      - description: msm9860 TSENS based
++        items:
++          - enum:
++              - qcom,ipq8064-tsens
++
+       - description: v0.1 of TSENS
+         items:
+           - enum:
+@@ -73,7 +78,9 @@ properties:
+     maxItems: 2
+     items:
+       - const: calib
+-      - const: calib_sel
++      - enum:
++          - calib_backup
++          - calib_sel
+   "#qcom,sensors":
+     description:
+@@ -88,12 +95,20 @@ properties:
+       Number of cells required to uniquely identify the thermal sensors. Since
+       we have multiple sensors this is set to 1
++required:
++  - compatible
++  - interrupts
++  - interrupt-names
++  - "#thermal-sensor-cells"
++  - "#qcom,sensors"
++
+ allOf:
+   - if:
+       properties:
+         compatible:
+           contains:
+             enum:
++              - qcom,ipq8064-tsens
+               - qcom,msm8916-tsens
+               - qcom,msm8974-tsens
+               - qcom,msm8976-tsens
+@@ -114,17 +129,42 @@ allOf:
+         interrupt-names:
+           minItems: 2
+-required:
+-  - compatible
+-  - reg
+-  - "#qcom,sensors"
+-  - interrupts
+-  - interrupt-names
+-  - "#thermal-sensor-cells"
++  - if:
++      properties:
++        compatible:
++          contains:
++            enum:
++              - qcom,tsens-v0_1
++              - qcom,tsens-v1
++              - qcom,tsens-v2
++
++    then:
++      required:
++        - reg
+ additionalProperties: false
+ examples:
++  - |
++    #include <dt-bindings/interrupt-controller/arm-gic.h>
++    // Example msm9860 based SoC (ipq8064):
++    gcc: clock-controller {
++
++           /* ... */
++
++           tsens: thermal-sensor {
++                compatible = "qcom,ipq8064-tsens";
++
++                 nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>;
++                 nvmem-cell-names = "calib", "calib_backup";
++                 interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
++                 interrupt-names = "uplow";
++
++                 #qcom,sensors = <11>;
++                 #thermal-sensor-cells = <1>;
++          };
++    };
++
+   - |
+     #include <dt-bindings/interrupt-controller/arm-gic.h>
+     // Example 1 (legacy: for pre v1 IP):
+-- 
+2.30.2
+
diff --git a/target/linux/ipq806x/patches-5.10/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch b/target/linux/ipq806x/patches-5.10/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch
new file mode 100644 (file)
index 0000000..2212d41
--- /dev/null
@@ -0,0 +1,37 @@
+From 68e720ed73c8f038c8c500e4c49c1e65a993a448 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Tue, 6 Apr 2021 04:45:31 +0200
+Subject: [PATCH 10/10] drivers: thermal: tsens: Fix wrong slope on msm-8960
+
+Some user using some stats with the old legacy implementation and the
+new implementation using the compute_intercept_slope reported an offset
+of 3C. Fix the slope table to reflect the original temp.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+---
+ drivers/thermal/qcom/tsens-8960.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
+index 58d09e927383..5cc5b3527f1f 100644
+--- a/drivers/thermal/qcom/tsens-8960.c
++++ b/drivers/thermal/qcom/tsens-8960.c
+@@ -45,11 +45,11 @@
+ #define S9_STATUS_OFF         0x3674
+ #define S10_STATUS_OFF                0x3678
+-/* Original slope - 200 to compensate mC to C inaccuracy */
++/* Original slope - 350 to compensate mC to C inaccuracy */
+ static u32 tsens_msm8960_slope[] = {
+-                      976, 976, 954, 976,
+-                      911, 932, 932, 999,
+-                      932, 999, 932
++                      826, 826, 804, 826,
++                      761, 782, 782, 849,
++                      782, 849, 782
+                       };
+ static int suspend_8960(struct tsens_priv *priv)
+-- 
+2.30.2
+