[openwrt/openwrt] ipq806x: use newer tsens patch

LEDE Commits lede-commits at lists.infradead.org
Thu May 6 22:05:47 PDT 2021


ynezz pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/96f10c9d7a88717e84782449122b958e5a15eddd

commit 96f10c9d7a88717e84782449122b958e5a15eddd
Author: Ansuel Smith <ansuelsmth at gmail.com>
AuthorDate: Mon Mar 1 01:02:09 2021 +0100

    ipq806x: use newer tsens patch
    
    Use improved tsens patch proposed upstream.
    
    Signed-off-by: Ansuel Smith <ansuelsmth at gmail.com>
---
 .../patches-5.10/0063-1-ipq806x-tsens-driver.patch | 616 ---------------------
 ...3-2-tsens-support-configurable-interrupts.patch | 437 ---------------
 .../patches-5.10/0063-3-tsens-fix-kernel-5_4.patch |  68 ---
 .../0063-4-ip806x-tsense-rework-driver.patch       | 107 ----
 ...ers-thermal-tsens-Add-VER_0-tsens-version.patch | 292 ++++++++++
 ...thermal-tsens-Don-t-hardcode-sensor-slope.patch |  33 ++
 ...hermal-tsens-Convert-msm8960-to-reg_field.patch | 124 +++++
 ...thermal-tsens-Use-init_common-for-msm8960.patch |  86 +++
 ...rmal-tsens-Fix-bug-in-sensor-enable-for-m.patch |  71 +++
 ...rmal-tsens-Replace-custom-8960-apis-with-.patch | 114 ++++
 ...rmal-tsens-Drop-unused-define-for-msm8960.patch |  70 +++
 ...ermal-tsens-Add-support-for-ipq8064-tsens.patch |  31 ++
 ...s-thermal-tsens-Document-ipq8064-bindings.patch | 115 ++++
 ...thermal-tsens-Fix-wrong-slope-on-msm-8960.patch |  37 ++
 14 files changed, 973 insertions(+), 1228 deletions(-)

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
index 80954c17fd..0000000000
--- a/target/linux/ipq806x/patches-5.10/0063-1-ipq806x-tsens-driver.patch
+++ /dev/null
@@ -1,616 +0,0 @@
-From 3302e1e1a3cfa4e67fda2a61d6f0c42205d40932 Mon Sep 17 00:00:00 2001
-From: Rajith Cherian <rajith at 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 at 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 at 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
index 585bd62a58..0000000000
--- a/target/linux/ipq806x/patches-5.10/0063-2-tsens-support-configurable-interrupts.patch
+++ /dev/null
@@ -1,437 +0,0 @@
-From 4e87400732c77765afae2ea89ed43837457aa604 Mon Sep 17 00:00:00 2001
-From: Rajith Cherian <rajith at 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 at 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
index 6c056db3b7..0000000000
--- a/target/linux/ipq806x/patches-5.10/0063-3-tsens-fix-kernel-5_4.patch
+++ /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
index 67fc8db7a3..0000000000
--- a/target/linux/ipq806x/patches-5.10/0063-4-ip806x-tsense-rework-driver.patch
+++ /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
index 0000000000..d4c85a06a5
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch
@@ -0,0 +1,292 @@
+From 5c7d1181056feef0b58fb2f556f55e170ba5b479 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath at linaro.org>
+Reported-by: kernel test robot <lkp at intel.com>
+Reported-by: Dan Carpenter <dan.carpenter at 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
index 0000000000..44de19b7a8
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch
@@ -0,0 +1,33 @@
+From efa0d50a6c5ec7619371dfe4d3e6ca54b73787d5 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..d8779c689a
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch
@@ -0,0 +1,124 @@
+From 6bac2e2fa36c2d7c304768a689d8b73155b90aa2 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Acked-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..4b12609e96
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch
@@ -0,0 +1,86 @@
+From c04f98a496929f75d75c65115d5717423c3d0634 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..4f8a6769a0
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch
@@ -0,0 +1,71 @@
+From b3e8bd33b84a6b6c863bd1733bd15b5f1483b8ab Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Acked-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..657f8b801b
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch
@@ -0,0 +1,114 @@
+From 1ff9f982051759e0387e8c7e793b49c48eae291d Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Acked-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..d0e383d035
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch
@@ -0,0 +1,70 @@
+From 5716a61239c6ac9ceb137e825e93c3aea06c4634 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..928e8fd695
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch
@@ -0,0 +1,31 @@
+From 0d0c22a59bf2672b57e23da9a9ea743e91b71f54 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Reviewed-by: Thara Gopinath <thara.gopinath at 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
index 0000000000..121f857182
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch
@@ -0,0 +1,115 @@
+From ac369071920d427dd484cf74cddba2774bba45f5 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at gmail.com>
+Reviewed-by: Rob Herring <robh at 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
index 0000000000..2212d41caf
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.10/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch
@@ -0,0 +1,37 @@
+From 68e720ed73c8f038c8c500e4c49c1e65a993a448 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth at 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 at 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
+



More information about the lede-commits mailing list