/* Copyright (c) 2012-2019, 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/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/err.h>
#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) + 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_UPPER_LOWER_INT_DISABLE	0xffffffff
#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)
#define TSENS_TM_LOWER_THRESHOLD_VALUE(n)	((n) & 0xfff)
#define TSENS_TM_UPPER_THRESHOLD_VALUE(n)	(((n) & 0xfff000) >> 12)
#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) + 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) + 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)
#define TSENS_TM_SN_STATUS_CRITICAL_STATUS	BIT(19)
#define TSENS_TM_SN_STATUS_UPPER_STATUS		BIT(18)
#define TSENS_TM_SN_STATUS_LOWER_STATUS		BIT(17)
#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_DEBUG_WDOG_TRIGGER_COUNT		5
#define TSENS_TM_WATCHDOG_LOG(n)		((n) + 0x13c)
#define TSENS_EN				BIT(0)
#define TSENS_CTRL_SENSOR_EN_MASK(n)		((n >> 3) & 0xffff)
#define TSENS_TM_TRDY(n)			((n) + 0xe4)
#define TSENS_TM_TRDY_FIRST_ROUND_COMPLETE	BIT(3)
#define TSENS_TM_TRDY_FIRST_ROUND_COMPLETE_SHIFT	3

static void msm_tsens_convert_temp(int last_temp, int *temp)
{
	int code_mask = ~TSENS_TM_CODE_BIT_MASK;

	if (last_temp & TSENS_TM_CODE_SIGN_BIT) {
		/* Sign extension for negative value */
		last_temp |= code_mask;
	}

	*temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG;
}

static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
{
	struct tsens_device *tmdev = NULL;
	unsigned int code;
	void __iomem *sensor_addr, *trdy;
	int last_temp = 0, last_temp2 = 0, last_temp3 = 0;

	if (!sensor)
		return -EINVAL;

	tmdev = sensor->tmdev;
	sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_tm_addr);
	trdy = TSENS_TM_TRDY(tmdev->tsens_tm_addr);

	code = readl_relaxed_no_log(trdy);
	if (!((code & TSENS_TM_TRDY_FIRST_ROUND_COMPLETE) >>
			TSENS_TM_TRDY_FIRST_ROUND_COMPLETE_SHIFT)) {
		pr_err("TSENS device first round not complete0x%x\n", code);
		return -ENODATA;
	}

	code = readl_relaxed_no_log(sensor_addr +
			(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
	last_temp = code & TSENS_TM_SN_LAST_TEMP_MASK;

	if (code & TSENS_TM_SN_STATUS_VALID_BIT) {
		msm_tsens_convert_temp(last_temp, temp);
		goto dbg;
	}

	code = readl_relaxed_no_log(sensor_addr +
		(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
	last_temp2 = code & TSENS_TM_SN_LAST_TEMP_MASK;
	if (code & TSENS_TM_SN_STATUS_VALID_BIT) {
		last_temp = last_temp2;
		msm_tsens_convert_temp(last_temp, temp);
		goto dbg;
	}

	code = readl_relaxed_no_log(sensor_addr +
			(sensor->hw_id <<
			TSENS_STATUS_ADDR_OFFSET));
	last_temp3 = code & TSENS_TM_SN_LAST_TEMP_MASK;
	if (code & TSENS_TM_SN_STATUS_VALID_BIT) {
		last_temp = last_temp3;
		msm_tsens_convert_temp(last_temp, temp);
		goto dbg;
	}

	if (last_temp == last_temp2)
		last_temp = last_temp2;
	else if (last_temp2 == last_temp3)
		last_temp = last_temp3;

	msm_tsens_convert_temp(last_temp, temp);

dbg:
	if (tmdev->ops->dbg)
		tmdev->ops->dbg(tmdev, (u32) sensor->hw_id,
					TSENS_DBG_LOG_TEMP_READS, temp);

	return 0;
}

static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
			int trip, enum thermal_trip_activation_mode mode)
{
	struct tsens_device *tmdev = NULL;
	unsigned int reg_cntl, mask;
	int rc = 0;

	/* clear the interrupt and unmask */
	if (!tm_sensor || trip < 0)
		return -EINVAL;

	tmdev = tm_sensor->tmdev;
	if (!tmdev)
		return -EINVAL;


	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_tm_addr));
		if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
			writel_relaxed(reg_cntl | (1 << mask),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		else
			writel_relaxed(reg_cntl & ~(1 << mask),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		break;
	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_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_tm_addr)));
		else
			writel_relaxed(reg_cntl &
				~(TSENS_TM_UPPER_INT_SET(mask)),
				(TSENS_TM_UPPER_LOWER_INT_MASK
				(tmdev->tsens_tm_addr)));
		break;
	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_tm_addr));
		if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
			writel_relaxed(reg_cntl | (1 << mask),
			(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_tm_addr)));
		break;
	default:
		rc = -EINVAL;
	}

	/* Activate and enable the respective trip threshold setting */
	mb();

	return rc;
}

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

	if (!tm_sensor)
		return -EINVAL;

	tmdev = tm_sensor->tmdev;
	if (!tmdev)
		return -EINVAL;

	spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);

	if (high_temp != INT_MAX) {
		tmdev->sensor[tm_sensor->hw_id].
				thr_state.high_temp = high_temp;
		reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_tm_addr)) +
				(tm_sensor->hw_id *
				TSENS_TM_SN_ADDR_OFFSET));
		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 | high_temp,
			(TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_tm_addr) +
			(tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
	}

	if (low_temp != INT_MIN) {
		tmdev->sensor[tm_sensor->hw_id].
				thr_state.low_temp = low_temp;
		reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_tm_addr)) +
				(tm_sensor->hw_id *
				TSENS_TM_SN_ADDR_OFFSET));
		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 | low_temp,
			(TSENS_TM_SN_UPPER_LOWER_THRESHOLD
				(tmdev->tsens_tm_addr) +
			(tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
	}

	/* Set trip temperature thresholds */
	mb();

	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("trip high enable error :%d\n", rc);
			goto fail;
		}
	} else {
		rc = tsens_tm_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_HI,
				THERMAL_TRIP_ACTIVATION_DISABLED);
		if (rc) {
			pr_err("trip high disable error :%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("trip low enable activation error :%d\n", rc);
			goto fail;
		}
	} else {
		rc = tsens_tm_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_LOW,
				THERMAL_TRIP_ACTIVATION_DISABLED);
		if (rc) {
			pr_err("trip low disable error :%d\n", rc);
			goto fail;
		}
	}

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

static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
{
	struct tsens_device *tm = data;
	unsigned int i, status, wd_log, wd_mask;
	unsigned long flags;
	void __iomem *sensor_status_addr, *sensor_int_mask_addr;
	void __iomem *sensor_critical_addr;
	void __iomem *wd_critical_addr, *wd_log_addr;

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

	if (tm->ctrl_data->wd_bark) {
		wd_mask = readl_relaxed(wd_critical_addr);
		if (wd_mask & TSENS_TM_CRITICAL_WD_BARK) {
			/*
			 * Clear watchdog interrupt and
			 * increment global wd count
			 */
			writel_relaxed(wd_mask | TSENS_TM_CRITICAL_WD_BARK,
				(TSENS_TM_CRITICAL_INT_CLEAR
				(tm->tsens_tm_addr)));
			writel_relaxed(wd_mask & ~(TSENS_TM_CRITICAL_WD_BARK),
				(TSENS_TM_CRITICAL_INT_CLEAR
				(tm->tsens_tm_addr)));
			wd_log = readl_relaxed(wd_log_addr);
			if (wd_log >= TSENS_DEBUG_WDOG_TRIGGER_COUNT) {
				pr_err("Watchdog count:%d\n", wd_log);
				if (tm->ops->dbg)
					tm->ops->dbg(tm, 0,
					TSENS_DBG_LOG_BUS_ID_DATA, NULL);
				BUG();
			}

			return IRQ_HANDLED;
		}
	}

	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;
		status = readl_relaxed(sensor_status_addr + addr_offset);
		int_mask = readl_relaxed(sensor_int_mask_addr);

		if ((status & TSENS_TM_SN_STATUS_CRITICAL_STATUS) &&
			!(int_mask & (1 << tm->sensor[i].hw_id))) {
			int_mask = readl_relaxed(sensor_int_mask_addr);
			int_mask_val = (1 << tm->sensor[i].hw_id);
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_CRITICAL_INT_MASK(
					tm->tsens_tm_addr));
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_CRITICAL_INT_CLEAR
					(tm->tsens_tm_addr));
			writel_relaxed(0,
				TSENS_TM_CRITICAL_INT_CLEAR(
					tm->tsens_tm_addr));
			tm->sensor[i].thr_state.
				crit_th_state =
				THERMAL_TRIP_ACTIVATION_DISABLED;
		}
		spin_unlock_irqrestore(&tm->tsens_crit_lock, flags);
	}

	/* Mask critical interrupt */
	mb();

	return IRQ_HANDLED;
}

static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
{
	struct tsens_device *tm = data;
	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_tm_addr);
	sensor_int_mask_addr =
		TSENS_TM_UPPER_LOWER_INT_MASK(tm->tsens_tm_addr);
	sensor_upper_lower_addr =
		TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tm->tsens_tm_addr);

	for (i = 0; i < TSENS_MAX_SENSORS; i++) {
		bool upper_thr = false, lower_thr = false;
		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 *
						TSENS_TM_SN_ADDR_OFFSET;
		status = readl_relaxed(sensor_status_addr + addr_offset);
		threshold = readl_relaxed(sensor_upper_lower_addr +
								addr_offset);
		int_mask = readl_relaxed(sensor_int_mask_addr);

		if ((status & TSENS_TM_SN_STATUS_UPPER_STATUS) &&
			!(int_mask &
				(1 << (tm->sensor[i].hw_id + 16)))) {
			int_mask = readl_relaxed(sensor_int_mask_addr);
			int_mask_val = TSENS_TM_UPPER_INT_SET(
					tm->sensor[i].hw_id);
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_MASK(
					tm->tsens_tm_addr));
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					tm->tsens_tm_addr));
			writel_relaxed(0,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					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_TRIP_ACTIVATION_DISABLED;
			}
		}

		if ((status & TSENS_TM_SN_STATUS_LOWER_STATUS) &&
			!(int_mask &
				(1 << tm->sensor[i].hw_id))) {
			int_mask = readl_relaxed(sensor_int_mask_addr);
			int_mask_val = (1 << tm->sensor[i].hw_id);
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_MASK(
					tm->tsens_tm_addr));
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					tm->tsens_tm_addr));
			writel_relaxed(0,
				TSENS_TM_UPPER_LOWER_INT_CLEAR(
					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_TRIP_ACTIVATION_DISABLED;
			}
		}
		spin_unlock_irqrestore(&tm->tsens_upp_low_lock, flags);

		if (upper_thr || lower_thr) {
			/* Use id for multiple controllers */
			pr_debug("sensor:%d trigger temp (%d degC)\n",
				tm->sensor[i].hw_id, temp);
			of_thermal_handle_trip_temp(tm->sensor[i].tzd, temp);
		}
	}

	/* Disable monitoring sensor trip threshold for triggered sensor */
	mb();

	if (tm->ops->dbg)
		tm->ops->dbg(tm, 0, TSENS_DBG_LOG_INTERRUPT_TIMESTAMP, NULL);

	return IRQ_HANDLED;
}

static int tsens2xxx_hw_sensor_en(struct tsens_device *tmdev,
					u32 sensor_id)
{
	void __iomem *srot_addr;
	unsigned int srot_val, sensor_en;

	srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
	srot_val = readl_relaxed(srot_addr);
	srot_val = TSENS_CTRL_SENSOR_EN_MASK(srot_val);

	sensor_en = ((1 << sensor_id) & srot_val);

	return sensor_en;
}

static int tsens2xxx_hw_init(struct tsens_device *tmdev)
{
	void __iomem *srot_addr;
	void __iomem *sensor_int_mask_addr;
	unsigned int srot_val, crit_mask, crit_val;
	void __iomem *int_mask_addr;

	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");
		return -ENODEV;
	}

	if (tmdev->ctrl_data->cycle_monitor) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		crit_val = TSENS_TM_CRITICAL_CYCLE_MONITOR;
		if (tmdev->ctrl_data->cycle_compltn_monitor_mask)
			writel_relaxed((crit_mask | crit_val),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		else
			writel_relaxed((crit_mask & ~crit_val),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		/*Update critical cycle monitoring*/
		mb();
	}

	if (tmdev->ctrl_data->wd_bark) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		crit_val = TSENS_TM_CRITICAL_WD_BARK;
		if (tmdev->ctrl_data->wd_bark_mask)
			writel_relaxed((crit_mask | crit_val),
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_tm_addr)));
		else
			writel_relaxed((crit_mask & ~crit_val),
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_tm_addr)));
		/*Update watchdog monitoring*/
		mb();
	}

	int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr);
	writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr);

	writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
		TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
		TSENS_TM_INT_EN(tmdev->tsens_tm_addr));

	spin_lock_init(&tmdev->tsens_crit_lock);
	spin_lock_init(&tmdev->tsens_upp_low_lock);

	if (tmdev->ctrl_data->mtc) {
		if (tmdev->ops->dbg)
			tmdev->ops->dbg(tmdev, 0, TSENS_DBG_MTC_DATA, NULL);
	}

	return 0;
}

static const struct tsens_irqs tsens2xxx_irqs[] = {
	{ "tsens-upper-lower", tsens_tm_irq_thread},
	{ "tsens-critical", tsens_tm_critical_irq_thread},
};

static int tsens2xxx_register_interrupts(struct tsens_device *tmdev)
{
	struct platform_device *pdev;
	int i, rc;

	if (!tmdev)
		return -EINVAL;

	pdev = tmdev->pdev;

	for (i = 0; i < ARRAY_SIZE(tsens2xxx_irqs); i++) {
		int irq;

		irq = platform_get_irq_byname(pdev, tsens2xxx_irqs[i].name);
		if (irq < 0) {
			dev_err(&pdev->dev, "failed to get irq %s\n",
					tsens2xxx_irqs[i].name);
			return irq;
		}

		rc = devm_request_threaded_irq(&pdev->dev, irq, NULL,
				tsens2xxx_irqs[i].handler,
				IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
				tsens2xxx_irqs[i].name, tmdev);
		if (rc) {
			dev_err(&pdev->dev, "failed to get irq %s\n",
					tsens2xxx_irqs[i].name);
			return rc;
		}
		enable_irq_wake(irq);
	}

	return 0;
}

static const struct tsens_ops ops_tsens2xxx = {
	.hw_init	= tsens2xxx_hw_init,
	.get_temp	= tsens2xxx_get_temp,
	.set_trips	= tsens2xxx_set_trip_temp,
	.interrupts_reg	= tsens2xxx_register_interrupts,
	.dbg		= tsens2xxx_dbg,
	.sensor_en	= tsens2xxx_hw_sensor_en,
};

const struct tsens_data data_tsens2xxx = {
	.cycle_monitor			= false,
	.cycle_compltn_monitor_mask	= 1,
	.wd_bark			= false,
	.wd_bark_mask			= 1,
	.ops				= &ops_tsens2xxx,
	.mtc				= true,
};

const struct tsens_data data_tsens23xx = {
	.cycle_monitor			= true,
	.cycle_compltn_monitor_mask	= 1,
	.wd_bark			= true,
	.wd_bark_mask			= 1,
	.ops				= &ops_tsens2xxx,
	.mtc				= false,
};

const struct tsens_data data_tsens24xx = {
	.cycle_monitor			= true,
	.cycle_compltn_monitor_mask	= 1,
	.wd_bark			= true,
	/* Enable Watchdog monitoring by unmasking */
	.wd_bark_mask			= 0,
	.ops				= &ops_tsens2xxx,
	.mtc				= false,
};
