Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07b10616 authored by Siddartha Mohanadoss's avatar Siddartha Mohanadoss
Browse files

thermal: tsens: Update TSENS driver



Update using of_thermal set_trips() API to set high
and low temperature trip thresholds. This utility
allows of_thermal to provide the aggregated high
and low temperature threshold to the driver. As
part of handling trip notification check if the
threshold was crossed against current temperature.
If the trip threshold is not crossed rearm the trip
threshold instead of notifying the client.

Update driver to not read the port ID or client ID
passed as an optional property from devicetree.
These properties are not required after switching to
register the respective port ID for each controller
using of-thermal during sensor registration. In
addition add separate properties for the SROT and TM
region. The regions may not have a fixed address offset.

Change-Id: If6be9e520a98380f7b7c65eca46d3c8951d5e551
Signed-off-by: default avatarSiddartha Mohanadoss <smohanad@codeaurora.org>
parent a66b9ffd
Loading
Loading
Loading
Loading
+8 −17
Original line number Diff line number Diff line
@@ -21,34 +21,25 @@ Required properties:
	       The compatible property is used to identify the respective controller to use
	       for the corresponding SoC.
- reg : offset and length of the TSENS registers with associated property in reg-names
	as "tsens_physical" for TSENS TM physical address region.
	as "tsens_srot_physical" for TSENS SROT physical address region. TSENS TM
	physical address region as "tsens_tm_physical".
- reg-names : resource names used for the physical address of the TSENS
	      registers. Should be "tsens_physical" for physical address of the TSENS.
	      registers. Should be "tsens_srot_physical" for physical address of the TSENS
	      SROT region and "tsens_tm_physical" for physical address of the TM region.
- interrupts : TSENS interrupt to notify Upper/Lower and Critical temperature threshold.
- interrupt-names: Should be "tsens-upper-lower" for temperature threshold.
		   Add "tsens-critical" for Critical temperature threshold notification
		   in addition to "tsens-upper-lower" for 8996 TSENS since
		   8996 supports Upper/Lower and Critical temperature threshold.
- qcom,sensors : Total number of available Temperature sensors for TSENS.

Optional properties:
- qcom,sensor-id : If the flag is present map the TSENS sensors based on the
		remote sensors that are enabled in HW. Ensure the mapping is not
		more than the number of supported sensors.
- qcom,client-id : If the flag is present use it to identify the SW ID mapping
		used to associate it with the controller and the physical sensor
		mapping within the controller. The physical sensor mapping within
		each controller is done using the qcom,sensor-id property. If the
		property is not present the SW ID mapping with default from 0 to
		total number of supported sensors with each controller instance.

Example:

tsens@fc4a8000 {
	compatible = "qcom,msm-tsens";
	reg = <0xfc4a8000 0x2000>;,
	reg-names = "tsens_physical";
	reg = <0xfc4a8000 0x10>,
		<0xfc4b8000 0x1ff>;
	reg-names = "tsens_srot_physical",
		    "tsens_tm_physical";
	interrupts = <0 184 0>;
	interrupt-names = "tsens-upper-lower";
	qcom,sensors = <11>;
};
+45 −79
Original line number Diff line number Diff line
@@ -24,29 +24,28 @@

LIST_HEAD(tsens_device_list);

static int tsens_get_temp(struct tsens_sensor *s, int *temp)
static int tsens_get_temp(void *data, int *temp)
{
	struct tsens_sensor *s = data;
	struct tsens_device *tmdev = s->tmdev;

	return tmdev->ops->get_temp(s, temp);
}

static int tsens_set_trip_temp(struct tsens_sensor *s, int trip, int temp)
static int tsens_set_trip_temp(void *data, int low_temp, int high_temp)
{
	struct tsens_sensor *s = data;
	struct tsens_device *tmdev = s->tmdev;

	if (tmdev->ops->set_trip_temp)
		return tmdev->ops->set_trip_temp(s, trip, temp);
	if (tmdev->ops->set_trips)
		return tmdev->ops->set_trips(s, low_temp, high_temp);

	return 0;
}

static int tsens_init(struct tsens_device *tmdev)
{
	if (tmdev->ops->hw_init)
	return tmdev->ops->hw_init(tmdev);

	return 0;
}

static int tsens_register_interrupts(struct tsens_device *tmdev)
@@ -85,19 +84,16 @@ MODULE_DEVICE_TABLE(of, tsens_table);

static struct thermal_zone_of_device_ops tsens_tm_thermal_zone_ops = {
	.get_temp = tsens_get_temp,
	.set_trip_temp = tsens_set_trip_temp,
	.set_trips = tsens_set_trip_temp,
};

static int get_device_tree_data(struct platform_device *pdev,
				struct tsens_device *tmdev)
{
	struct device_node *of_node = pdev->dev.of_node;
	u32 *hw_id, *client_id;
	u32 rc = 0, i, tsens_num_sensors = 0;
	int tsens_len;
	const struct of_device_id *id;
	const struct tsens_data *data;
	struct resource *res_tsens_mem, *res_mem = NULL;
	struct resource *res_tsens_mem;

	if (!of_match_node(tsens_table, of_node)) {
		pr_err("Need to read SoC specific fuse map\n");
@@ -111,16 +107,6 @@ static int get_device_tree_data(struct platform_device *pdev,
	}

	data = id->data;
	hw_id = devm_kzalloc(&pdev->dev,
		tsens_num_sensors * sizeof(u32), GFP_KERNEL);
	if (!hw_id)
		return -ENOMEM;

	client_id = devm_kzalloc(&pdev->dev,
		tsens_num_sensors * sizeof(u32), GFP_KERNEL);
	if (!client_id)
		return -ENOMEM;

	tmdev->ops = data->ops;
	tmdev->ctrl_data = data;
	tmdev->pdev = pdev;
@@ -132,49 +118,32 @@ static int get_device_tree_data(struct platform_device *pdev,

	/* TSENS register region */
	res_tsens_mem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "tsens_physical");
				IORESOURCE_MEM, "tsens_srot_physical");
	if (!res_tsens_mem) {
		pr_err("Could not get tsens physical address resource\n");
		return -EINVAL;
	}

	tsens_len = res_tsens_mem->end - res_tsens_mem->start + 1;

	res_mem = request_mem_region(res_tsens_mem->start,
				tsens_len, res_tsens_mem->name);
	if (!res_mem) {
		pr_err("Request tsens physical memory region failed\n");
		return -EINVAL;
	tmdev->tsens_srot_addr = devm_ioremap_resource(&pdev->dev,
							res_tsens_mem);
	if (IS_ERR(tmdev->tsens_srot_addr)) {
		dev_err(&pdev->dev, "Failed to IO map TSENS registers.\n");
		return PTR_ERR(tmdev->tsens_srot_addr);
	}

	tmdev->tsens_addr = ioremap(res_mem->start, tsens_len);
	if (!tmdev->tsens_addr) {
		pr_err("Failed to IO map TSENS registers.\n");
	/* TSENS TM register region */
	res_tsens_mem = platform_get_resource_byname(pdev,
				IORESOURCE_MEM, "tsens_tm_physical");
	if (!res_tsens_mem) {
		pr_err("Could not get tsens physical address resource\n");
		return -EINVAL;
	}

	rc = of_property_read_u32_array(of_node,
		"qcom,sensor-id", hw_id, tsens_num_sensors);
	if (rc) {
		pr_err("Default sensor id mapping\n");
		for (i = 0; i < tsens_num_sensors; i++)
			tmdev->sensor[i].hw_id = i;
	} else {
		pr_err("Use specified sensor id mapping\n");
		for (i = 0; i < tsens_num_sensors; i++)
			tmdev->sensor[i].hw_id = hw_id[i];
	}

	rc = of_property_read_u32_array(of_node,
		"qcom,client-id", client_id, tsens_num_sensors);
	if (rc) {
		for (i = 0; i < tsens_num_sensors; i++)
			tmdev->sensor[i].id = i;
		pr_debug("Default client id mapping\n");
	} else {
		for (i = 0; i < tsens_num_sensors; i++)
			tmdev->sensor[i].id = client_id[i];
		pr_debug("Use specified client id mapping\n");
	tmdev->tsens_tm_addr = devm_ioremap_resource(&pdev->dev,
								res_tsens_mem);
	if (IS_ERR(tmdev->tsens_tm_addr)) {
		dev_err(&pdev->dev, "Failed to IO map TSENS TM registers.\n");
		return PTR_ERR(tmdev->tsens_tm_addr);
	}

	return 0;
@@ -182,20 +151,28 @@ static int get_device_tree_data(struct platform_device *pdev,

static int tsens_thermal_zone_register(struct tsens_device *tmdev)
{
	int rc = 0, i = 0;
	int i = 0, sensor_missing = 0;

	for (i = 0; i < tmdev->num_sensors; i++) {
	for (i = 0; i < TSENS_MAX_SENSORS; i++) {
		tmdev->sensor[i].tmdev = tmdev;
		tmdev->sensor[i].tzd = devm_thermal_zone_of_sensor_register(
					&tmdev->pdev->dev, i, &tmdev->sensor[i],
					&tsens_tm_thermal_zone_ops);
		tmdev->sensor[i].hw_id = i;
		tmdev->sensor[i].tzd =
			devm_thermal_zone_of_sensor_register(
			&tmdev->pdev->dev, i,
			&tmdev->sensor[i], &tsens_tm_thermal_zone_ops);
		if (IS_ERR(tmdev->sensor[i].tzd)) {
			pr_err("Error registering sensor:%d\n", i);
			pr_debug("Error registering sensor:%d\n", i);
			sensor_missing++;
			continue;
		}
	}

	return rc;
	if (sensor_missing == TSENS_MAX_SENSORS) {
		pr_err("No TSENS sensors to register?\n");
		return -ENODEV;
	}

	return 0;
}

static int tsens_tm_remove(struct platform_device *pdev)
@@ -207,32 +184,19 @@ static int tsens_tm_remove(struct platform_device *pdev)

int tsens_tm_probe(struct platform_device *pdev)
{
	struct device_node *of_node = pdev->dev.of_node;
	struct tsens_device *tmdev = NULL;
	u32 tsens_num_sensors = 0;
	int rc;

	if (!(pdev->dev.of_node))
		return -ENODEV;

	rc = of_property_read_u32(of_node,
			"qcom,sensors", &tsens_num_sensors);
	if (rc || (!tsens_num_sensors)) {
		dev_err(&pdev->dev, "missing sensors\n");
		return -ENODEV;
	}

	tmdev = devm_kzalloc(&pdev->dev,
			sizeof(struct tsens_device) +
			tsens_num_sensors *
			TSENS_MAX_SENSORS *
			sizeof(struct tsens_sensor),
			GFP_KERNEL);
	if (tmdev == NULL) {
		pr_err("%s: kzalloc() failed.\n", __func__);
	if (tmdev == NULL)
		return -ENOMEM;
	}

	tmdev->num_sensors = tsens_num_sensors;

	rc = get_device_tree_data(pdev, tmdev);
	if (rc) {
@@ -241,8 +205,10 @@ int tsens_tm_probe(struct platform_device *pdev)
	}

	rc = tsens_init(tmdev);
	if (rc)
	if (rc) {
		pr_err("Error initializing TSENS controller\n");
		return rc;
	}

	rc = tsens_thermal_zone_register(tmdev);
	if (rc) {
+5 −4
Original line number Diff line number Diff line
@@ -23,9 +23,9 @@

#define DEBUG_SIZE				10
#define TSENS_MAX_SENSORS			16
#define TSENS_CONTROLLER_ID(n)			((n) + 0x1000)
#define TSENS_CONTROLLER_ID(n)			(n)
#define TSENS_CTRL_ADDR(n)			(n)
#define TSENS_TM_SN_STATUS(n)			((n) + 0x10a0)
#define TSENS_TM_SN_STATUS(n)			((n) + 0xa0)

enum tsens_dbg_type {
	TSENS_DBG_POLL,
@@ -87,7 +87,7 @@ struct tsens_sensor {
struct tsens_ops {
	int (*hw_init)(struct tsens_device *);
	int (*get_temp)(struct tsens_sensor *, int *);
	int (*set_trip_temp)(struct tsens_sensor *, int, int);
	int (*set_trips)(struct tsens_sensor *, int, int);
	int (*interrupts_reg)(struct tsens_device *);
	int (*dbg)(struct tsens_device *, u32, u32, int *);
};
@@ -121,7 +121,8 @@ struct tsens_device {
	u32				num_sensors;
	struct regmap			*map;
	struct regmap_field		*status_field;
	void				*tsens_addr;
	void __iomem			*tsens_srot_addr;
	void __iomem			*tsens_tm_addr;
	const struct tsens_ops		*ops;
	struct tsens_dbg_context	tsens_dbg;
	spinlock_t			tsens_crit_lock;
+137 −98
Original line number Diff line number Diff line
@@ -18,19 +18,20 @@
#include <linux/of.h>
#include <linux/vmalloc.h>
#include "tsens.h"
#include "thermal_core.h"

#define TSENS_DRIVER_NAME			"msm-tsens"

#define TSENS_TM_INT_EN(n)			((n) + 0x1004)
#define TSENS_TM_CRITICAL_INT_STATUS(n)		((n) + 0x1014)
#define TSENS_TM_CRITICAL_INT_CLEAR(n)		((n) + 0x1018)
#define TSENS_TM_CRITICAL_INT_MASK(n)		((n) + 0x101c)
#define TSENS_TM_INT_EN(n)			((n) + 0x4)
#define TSENS_TM_CRITICAL_INT_STATUS(n)		((n) + 0x14)
#define TSENS_TM_CRITICAL_INT_CLEAR(n)		((n) + 0x18)
#define TSENS_TM_CRITICAL_INT_MASK(n)		((n) + 0x1c)
#define TSENS_TM_CRITICAL_WD_BARK		BIT(31)
#define TSENS_TM_CRITICAL_CYCLE_MONITOR		BIT(30)
#define TSENS_TM_CRITICAL_INT_EN		BIT(2)
#define TSENS_TM_UPPER_INT_EN			BIT(1)
#define TSENS_TM_LOWER_INT_EN			BIT(0)
#define TSENS_TM_SN_UPPER_LOWER_THRESHOLD(n)	((n) + 0x1020)
#define TSENS_TM_SN_UPPER_LOWER_THRESHOLD(n)	((n) + 0x20)
#define TSENS_TM_SN_ADDR_OFFSET			0x4
#define TSENS_TM_UPPER_THRESHOLD_SET(n)		((n) << 12)
#define TSENS_TM_UPPER_THRESHOLD_VALUE_SHIFT(n)	((n) >> 12)
@@ -39,13 +40,13 @@
#define TSENS_TM_UPPER_THRESHOLD_MASK		0xfff000
#define TSENS_TM_LOWER_THRESHOLD_MASK		0xfff
#define TSENS_TM_UPPER_THRESHOLD_SHIFT		12
#define TSENS_TM_SN_CRITICAL_THRESHOLD(n)	((n) + 0x1060)
#define TSENS_TM_SN_CRITICAL_THRESHOLD(n)	((n) + 0x60)
#define TSENS_STATUS_ADDR_OFFSET		2
#define TSENS_TM_UPPER_INT_MASK(n)		(((n) & 0xffff0000) >> 16)
#define TSENS_TM_LOWER_INT_MASK(n)		((n) & 0xffff)
#define TSENS_TM_UPPER_LOWER_INT_STATUS(n)	((n) + 0x1008)
#define TSENS_TM_UPPER_LOWER_INT_CLEAR(n)	((n) + 0x100c)
#define TSENS_TM_UPPER_LOWER_INT_MASK(n)	((n) + 0x1010)
#define TSENS_TM_UPPER_LOWER_INT_STATUS(n)	((n) + 0x8)
#define TSENS_TM_UPPER_LOWER_INT_CLEAR(n)	((n) + 0xc)
#define TSENS_TM_UPPER_LOWER_INT_MASK(n)	((n) + 0x10)
#define TSENS_TM_UPPER_INT_SET(n)		(1 << (n + 16))
#define TSENS_TM_SN_CRITICAL_THRESHOLD_MASK	0xfff
#define TSENS_TM_SN_STATUS_VALID_BIT		BIT(21)
@@ -55,6 +56,7 @@
#define TSENS_TM_SN_LAST_TEMP_MASK		0xfff
#define TSENS_TM_CODE_BIT_MASK			0xfff
#define TSENS_TM_CODE_SIGN_BIT			0x800
#define TSENS_TM_SCALE_DECI_MILLIDEG		100

#define TSENS_EN				BIT(0)

@@ -67,7 +69,7 @@ static void msm_tsens_convert_temp(int last_temp, int *temp)
		last_temp |= code_mask;
	}

	*temp = last_temp * 100;
	*temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG;
}

static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
@@ -81,7 +83,7 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
		return -EINVAL;

	tmdev = sensor->tmdev;
	sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_addr);
	sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_tm_addr);

	code = readl_relaxed_no_log(sensor_addr +
			(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
@@ -130,7 +132,6 @@ static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
{
	struct tsens_device *tmdev = NULL;
	unsigned int reg_cntl, mask;
	unsigned long flags;
	int rc = 0;

	/* clear the interrupt and unmask */
@@ -141,56 +142,57 @@ static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
	if (!tmdev)
		return -EINVAL;

	spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);

	mask = (tm_sensor->hw_id);
	switch (trip) {
	case THERMAL_TRIP_CRITICAL:
		tmdev->sensor[tm_sensor->hw_id].
			thr_state.crit_th_state = mode;
		reg_cntl = readl_relaxed(TSENS_TM_CRITICAL_INT_MASK
							(tmdev->tsens_addr));
						(tmdev->tsens_tm_addr));
		if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
			writel_relaxed(reg_cntl | (1 << mask),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_addr)));
				(tmdev->tsens_tm_addr)));
		else
			writel_relaxed(reg_cntl & ~(1 << mask),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_addr)));
				(tmdev->tsens_tm_addr)));
		break;
	case THERMAL_TRIP_ACTIVE:
	case THERMAL_TRIP_CONFIGURABLE_HI:
		tmdev->sensor[tm_sensor->hw_id].
			thr_state.high_th_state = mode;
		reg_cntl = readl_relaxed(TSENS_TM_UPPER_LOWER_INT_MASK
						(tmdev->tsens_addr));
						(tmdev->tsens_tm_addr));
		if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
			writel_relaxed(reg_cntl |
				(TSENS_TM_UPPER_INT_SET(mask)),
				(TSENS_TM_UPPER_LOWER_INT_MASK
				(tmdev->tsens_addr)));
				(tmdev->tsens_tm_addr)));
		else
			writel_relaxed(reg_cntl &
				~(TSENS_TM_UPPER_INT_SET(mask)),
				(TSENS_TM_UPPER_LOWER_INT_MASK
				(tmdev->tsens_addr)));
				(tmdev->tsens_tm_addr)));
		break;
	case THERMAL_TRIP_PASSIVE:
	case THERMAL_TRIP_CONFIGURABLE_LOW:
		tmdev->sensor[tm_sensor->hw_id].
			thr_state.low_th_state = mode;
		reg_cntl = readl_relaxed(TSENS_TM_UPPER_LOWER_INT_MASK
						(tmdev->tsens_addr));
						(tmdev->tsens_tm_addr));
		if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
			writel_relaxed(reg_cntl | (1 << mask),
			(TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_addr)));
			(TSENS_TM_UPPER_LOWER_INT_MASK
						(tmdev->tsens_tm_addr)));
		else
			writel_relaxed(reg_cntl & ~(1 << mask),
			(TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_addr)));
			(TSENS_TM_UPPER_LOWER_INT_MASK
						(tmdev->tsens_tm_addr)));
		break;
	default:
		rc = -EINVAL;
	}

	spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
	/* Activate and enable the respective trip threshold setting */
	mb();

@@ -198,14 +200,14 @@ static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
}

static int tsens2xxx_set_trip_temp(struct tsens_sensor *tm_sensor,
							int trip, int temp)
						int low_temp, int high_temp)
{
	unsigned int reg_cntl;
	unsigned long flags;
	struct tsens_device *tmdev = NULL;
	int rc = 0;

	if (!tm_sensor || trip < 0)
	if (!tm_sensor)
		return -EINVAL;

	tmdev = tm_sensor->tmdev;
@@ -213,56 +215,65 @@ static int tsens2xxx_set_trip_temp(struct tsens_sensor *tm_sensor,
		return -EINVAL;

	spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);
	switch (trip) {
	case THERMAL_TRIP_CRITICAL:
		tmdev->sensor[tm_sensor->hw_id].
				thr_state.crit_temp = temp;
		temp &= TSENS_TM_SN_CRITICAL_THRESHOLD_MASK;
		writel_relaxed(temp,
			(TSENS_TM_SN_CRITICAL_THRESHOLD(tmdev->tsens_addr) +
			(tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
		break;
	case THERMAL_TRIP_ACTIVE:

	if (high_temp != INT_MAX) {
		tmdev->sensor[tm_sensor->hw_id].
				thr_state.high_temp = temp;
				thr_state.high_temp = high_temp;
		reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_addr)) +
				(tmdev->tsens_tm_addr)) +
				(tm_sensor->hw_id *
				TSENS_TM_SN_ADDR_OFFSET));
		temp = TSENS_TM_UPPER_THRESHOLD_SET(temp);
		temp &= TSENS_TM_UPPER_THRESHOLD_MASK;
		high_temp /= TSENS_TM_SCALE_DECI_MILLIDEG;
		high_temp = TSENS_TM_UPPER_THRESHOLD_SET(high_temp);
		high_temp &= TSENS_TM_UPPER_THRESHOLD_MASK;
		reg_cntl &= ~TSENS_TM_UPPER_THRESHOLD_MASK;
		writel_relaxed(reg_cntl | temp,
			(TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tmdev->tsens_addr) +
		writel_relaxed(reg_cntl | high_temp,
			(TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_tm_addr) +
			(tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
		break;
	case THERMAL_TRIP_PASSIVE:
	}

	if (low_temp != INT_MIN) {
		tmdev->sensor[tm_sensor->hw_id].
				thr_state.low_temp = temp;
				thr_state.low_temp = low_temp;
		reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_addr)) +
				(tmdev->tsens_tm_addr)) +
				(tm_sensor->hw_id *
				TSENS_TM_SN_ADDR_OFFSET));
		temp &= TSENS_TM_LOWER_THRESHOLD_MASK;
		low_temp /= TSENS_TM_SCALE_DECI_MILLIDEG;
		low_temp &= TSENS_TM_LOWER_THRESHOLD_MASK;
		reg_cntl &= ~TSENS_TM_LOWER_THRESHOLD_MASK;
		writel_relaxed(reg_cntl | temp,
			(TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tmdev->tsens_addr) +
		writel_relaxed(reg_cntl | low_temp,
			(TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_tm_addr) +
			(tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
		break;
	default:
		pr_err("Invalid trip to TSENS: %d\n", trip);
		rc = -EINVAL;
	}

	spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
	/* Set trip temperature thresholds */
	mb();

	rc = tsens_tm_activate_trip_type(tm_sensor, trip,
	if (high_temp != INT_MAX) {
		rc = tsens_tm_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_HI,
				THERMAL_TRIP_ACTIVATION_ENABLED);
	if (rc)
		pr_err("Error during trip activation :%d\n", rc);
		if (rc) {
			pr_err("Error during trip high activation :%d\n", rc);
			goto fail;
		}
	}

	if (low_temp != INT_MIN) {
		rc = tsens_tm_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_LOW,
				THERMAL_TRIP_ACTIVATION_ENABLED);
		if (rc) {
			pr_err("Error during trip low activation :%d\n", rc);
			goto fail;
		}
	}

fail:
	spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
	return rc;
}

@@ -277,13 +288,13 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
	void __iomem *wd_critical_addr;
	int wd_mask;

	sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_addr);
	sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_tm_addr);
	sensor_int_mask_addr =
		TSENS_TM_CRITICAL_INT_MASK(tm->tsens_addr);
		TSENS_TM_CRITICAL_INT_MASK(tm->tsens_tm_addr);
	sensor_critical_addr =
		TSENS_TM_SN_CRITICAL_THRESHOLD(tm->tsens_addr);
		TSENS_TM_SN_CRITICAL_THRESHOLD(tm->tsens_tm_addr);
	wd_critical_addr =
		TSENS_TM_CRITICAL_INT_STATUS(tm->tsens_addr);
		TSENS_TM_CRITICAL_INT_STATUS(tm->tsens_tm_addr);

	if (tm->ctrl_data->wd_bark) {
		wd_mask = readl_relaxed(wd_critical_addr);
@@ -294,19 +305,22 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
			 */
			writel_relaxed(wd_mask | TSENS_TM_CRITICAL_WD_BARK,
				(TSENS_TM_CRITICAL_INT_CLEAR
				(tm->tsens_addr)));
				(tm->tsens_tm_addr)));
			writel_relaxed(wd_mask & ~(TSENS_TM_CRITICAL_WD_BARK),
				(TSENS_TM_CRITICAL_INT_CLEAR
				(tm->tsens_addr)));
				(tm->tsens_tm_addr)));
			tm->tsens_dbg.tsens_critical_wd_cnt++;
			return IRQ_HANDLED;
		}
	}

	for (i = 0; i < tm->num_sensors; i++) {
	for (i = 0; i < TSENS_MAX_SENSORS; i++) {
		int int_mask, int_mask_val;
		u32 addr_offset;

		if (IS_ERR(tm->sensor[i].tzd))
			continue;

		spin_lock_irqsave(&tm->tsens_crit_lock, flags);
		addr_offset = tm->sensor[i].hw_id *
						TSENS_TM_SN_ADDR_OFFSET;
@@ -320,13 +334,14 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_CRITICAL_INT_MASK(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_CRITICAL_INT_CLEAR(tm->tsens_addr));
				TSENS_TM_CRITICAL_INT_CLEAR
					(tm->tsens_tm_addr));
			writel_relaxed(0,
				TSENS_TM_CRITICAL_INT_CLEAR(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			tm->sensor[i].thr_state.
					crit_th_state = THERMAL_DEVICE_DISABLED;
		}
@@ -342,22 +357,31 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
{
	struct tsens_device *tm = data;
	unsigned int i, status, threshold;
	unsigned int i, status, threshold, temp;
	unsigned long flags;
	void __iomem *sensor_status_addr;
	void __iomem *sensor_int_mask_addr;
	void __iomem *sensor_upper_lower_addr;
	u32 addr_offset = 0;

	sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_addr);
	sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_tm_addr);
	sensor_int_mask_addr =
		TSENS_TM_UPPER_LOWER_INT_MASK(tm->tsens_addr);
		TSENS_TM_UPPER_LOWER_INT_MASK(tm->tsens_tm_addr);
	sensor_upper_lower_addr =
		TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tm->tsens_addr);
		TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tm->tsens_tm_addr);

	for (i = 0; i < tm->num_sensors; i++) {
	for (i = 0; i < TSENS_MAX_SENSORS; i++) {
		bool upper_thr = false, lower_thr = false;
		int int_mask, int_mask_val = 0;
		int int_mask, int_mask_val = 0, rc;

		if (IS_ERR(tm->sensor[i].tzd))
			continue;

		rc = tsens2xxx_get_temp(&tm->sensor[i], &temp);
		if (rc) {
			pr_debug("Error:%d reading temp sensor:%d\n", rc, i);
			continue;
		}

		spin_lock_irqsave(&tm->tsens_upp_low_lock, flags);
		addr_offset = tm->sensor[i].hw_id *
@@ -376,18 +400,29 @@ static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_MASK(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			writel_relaxed(0,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			if (TSENS_TM_UPPER_THRESHOLD_VALUE(threshold) >
				(temp/TSENS_TM_SCALE_DECI_MILLIDEG)) {
				pr_debug("Re-arm high threshold\n");
				rc = tsens_tm_activate_trip_type(
					&tm->sensor[i],
					THERMAL_TRIP_CONFIGURABLE_HI,
					THERMAL_TRIP_ACTIVATION_ENABLED);
				if (rc)
					pr_err("high rearm failed:%d\n", rc);
			} else {
				upper_thr = true;
				tm->sensor[i].thr_state.
					high_th_state = THERMAL_DEVICE_DISABLED;
			}
		}

		if ((status & TSENS_TM_SN_STATUS_LOWER_STATUS) &&
			!(int_mask &
@@ -397,32 +432,36 @@ static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_MASK(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			writel_relaxed(0,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					tm->tsens_addr));
					tm->tsens_tm_addr));
			if (TSENS_TM_LOWER_THRESHOLD_VALUE(threshold)
				< (temp/TSENS_TM_SCALE_DECI_MILLIDEG)) {
				pr_debug("Re-arm low threshold\n");
				rc = tsens_tm_activate_trip_type(
					&tm->sensor[i],
					THERMAL_TRIP_CONFIGURABLE_LOW,
					THERMAL_TRIP_ACTIVATION_ENABLED);
				if (rc)
					pr_err("low rearm failed:%d\n", rc);
			} else {
				lower_thr = true;
				tm->sensor[i].thr_state.
					low_th_state = THERMAL_DEVICE_DISABLED;
			}
		}
		spin_unlock_irqrestore(&tm->tsens_upp_low_lock, flags);

		if (upper_thr || lower_thr) {
			int temp;
			enum thermal_trip_type trip =
					THERMAL_TRIP_CONFIGURABLE_LOW;

			if (upper_thr)
				trip = THERMAL_TRIP_CONFIGURABLE_HI;
			tsens2xxx_get_temp(&tm->sensor[i], &temp);
			/* Use id for multiple controllers */
			pr_debug("sensor:%d trigger temp (%d degC)\n",
				tm->sensor[i].hw_id,
				(status & TSENS_TM_SN_LAST_TEMP_MASK));
				tm->sensor[i].hw_id, temp);
			of_thermal_handle_trip(tm->sensor[i].tzd);
		}
	}

@@ -442,7 +481,7 @@ static int tsens2xxx_hw_init(struct tsens_device *tmdev)
	unsigned int srot_val;
	int crit_mask;

	srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_addr + 0x4);
	srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
	srot_val = readl_relaxed(srot_addr);
	if (!(srot_val & TSENS_EN)) {
		pr_err("TSENS device is not enabled\n");
@@ -451,18 +490,18 @@ static int tsens2xxx_hw_init(struct tsens_device *tmdev)

	if (tmdev->ctrl_data->cycle_monitor) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_addr);
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		writel_relaxed(
			crit_mask | tmdev->ctrl_data->cycle_compltn_monitor_val,
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_addr)));
			(tmdev->tsens_tm_addr)));
		/*Update critical cycle monitoring*/
		mb();
	}
	writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
		TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
		TSENS_TM_INT_EN(tmdev->tsens_addr));
		TSENS_TM_INT_EN(tmdev->tsens_tm_addr));

	spin_lock_init(&tmdev->tsens_crit_lock);
	spin_lock_init(&tmdev->tsens_upp_low_lock);
@@ -513,7 +552,7 @@ static int tsens2xxx_register_interrupts(struct tsens_device *tmdev)
static const struct tsens_ops ops_tsens2xxx = {
	.hw_init	= tsens2xxx_hw_init,
	.get_temp	= tsens2xxx_get_temp,
	.set_trip_temp	= tsens2xxx_set_trip_temp,
	.set_trips	= tsens2xxx_set_trip_temp,
	.interrupts_reg	= tsens2xxx_register_interrupts,
	.dbg		= tsens2xxx_dbg,
};