brintos

brintos / linux-shallow public Read only

0
0
Text · 34.3 KiB · 0b4421b Raw
1375 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.4 * Copyright (c) 2019, 2020, Linaro Ltd.5 */6 7#include <linux/debugfs.h>8#include <linux/err.h>9#include <linux/io.h>10#include <linux/module.h>11#include <linux/nvmem-consumer.h>12#include <linux/of.h>13#include <linux/of_address.h>14#include <linux/of_platform.h>15#include <linux/mfd/syscon.h>16#include <linux/platform_device.h>17#include <linux/pm.h>18#include <linux/regmap.h>19#include <linux/slab.h>20#include <linux/suspend.h>21#include <linux/thermal.h>22#include "../thermal_hwmon.h"23#include "tsens.h"24 25/**26 * struct tsens_irq_data - IRQ status and temperature violations27 * @up_viol:        upper threshold violated28 * @up_thresh:      upper threshold temperature value29 * @up_irq_mask:    mask register for upper threshold irqs30 * @up_irq_clear:   clear register for uppper threshold irqs31 * @low_viol:       lower threshold violated32 * @low_thresh:     lower threshold temperature value33 * @low_irq_mask:   mask register for lower threshold irqs34 * @low_irq_clear:  clear register for lower threshold irqs35 * @crit_viol:      critical threshold violated36 * @crit_thresh:    critical threshold temperature value37 * @crit_irq_mask:  mask register for critical threshold irqs38 * @crit_irq_clear: clear register for critical threshold irqs39 *40 * Structure containing data about temperature threshold settings and41 * irq status if they were violated.42 */43struct tsens_irq_data {44	u32 up_viol;45	int up_thresh;46	u32 up_irq_mask;47	u32 up_irq_clear;48	u32 low_viol;49	int low_thresh;50	u32 low_irq_mask;51	u32 low_irq_clear;52	u32 crit_viol;53	u32 crit_thresh;54	u32 crit_irq_mask;55	u32 crit_irq_clear;56};57 58char *qfprom_read(struct device *dev, const char *cname)59{60	struct nvmem_cell *cell;61	ssize_t data;62	char *ret;63 64	cell = nvmem_cell_get(dev, cname);65	if (IS_ERR(cell))66		return ERR_CAST(cell);67 68	ret = nvmem_cell_read(cell, &data);69	nvmem_cell_put(cell);70 71	return ret;72}73 74int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup)75{76	u32 mode;77	u32 base1, base2;78	char name[] = "sXX_pY_backup"; /* s10_p1_backup */79	int i, ret;80 81	if (priv->num_sensors > MAX_SENSORS)82		return -EINVAL;83 84	ret = snprintf(name, sizeof(name), "mode%s", backup ? "_backup" : "");85	if (ret < 0)86		return ret;87 88	ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &mode);89	if (ret == -ENOENT)90		dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n");91	if (ret < 0)92		return ret;93 94	dev_dbg(priv->dev, "calibration mode is %d\n", mode);95 96	ret = snprintf(name, sizeof(name), "base1%s", backup ? "_backup" : "");97	if (ret < 0)98		return ret;99 100	ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base1);101	if (ret < 0)102		return ret;103 104	ret = snprintf(name, sizeof(name), "base2%s", backup ? "_backup" : "");105	if (ret < 0)106		return ret;107 108	ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base2);109	if (ret < 0)110		return ret;111 112	for (i = 0; i < priv->num_sensors; i++) {113		ret = snprintf(name, sizeof(name), "s%d_p1%s", priv->sensor[i].hw_id,114			       backup ? "_backup" : "");115		if (ret < 0)116			return ret;117 118		ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]);119		if (ret)120			return ret;121 122		ret = snprintf(name, sizeof(name), "s%d_p2%s", priv->sensor[i].hw_id,123			       backup ? "_backup" : "");124		if (ret < 0)125			return ret;126 127		ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]);128		if (ret)129			return ret;130	}131 132	switch (mode) {133	case ONE_PT_CALIB:134		for (i = 0; i < priv->num_sensors; i++)135			p1[i] = p1[i] + (base1 << shift);136		break;137	case TWO_PT_CALIB:138	case TWO_PT_CALIB_NO_OFFSET:139		for (i = 0; i < priv->num_sensors; i++)140			p2[i] = (p2[i] + base2) << shift;141		fallthrough;142	case ONE_PT_CALIB2:143	case ONE_PT_CALIB2_NO_OFFSET:144		for (i = 0; i < priv->num_sensors; i++)145			p1[i] = (p1[i] + base1) << shift;146		break;147	default:148		dev_dbg(priv->dev, "calibrationless mode\n");149		for (i = 0; i < priv->num_sensors; i++) {150			p1[i] = 500;151			p2[i] = 780;152		}153	}154 155	/* Apply calibration offset workaround except for _NO_OFFSET modes */156	switch (mode) {157	case TWO_PT_CALIB:158		for (i = 0; i < priv->num_sensors; i++)159			p2[i] += priv->sensor[i].p2_calib_offset;160		fallthrough;161	case ONE_PT_CALIB2:162		for (i = 0; i < priv->num_sensors; i++)163			p1[i] += priv->sensor[i].p1_calib_offset;164		break;165	}166 167	return mode;168}169 170int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift)171{172	u32 p1[MAX_SENSORS], p2[MAX_SENSORS];173	int mode;174 175	mode = tsens_read_calibration(priv, shift, p1, p2, false);176	if (mode < 0)177		return mode;178 179	compute_intercept_slope(priv, p1, p2, mode);180 181	return 0;182}183 184int tsens_calibrate_common(struct tsens_priv *priv)185{186	return tsens_calibrate_nvmem(priv, 2);187}188 189static u32 tsens_read_cell(const struct tsens_single_value *cell, u8 len, u32 *data0, u32 *data1)190{191	u32 val;192	u32 *data = cell->blob ? data1 : data0;193 194	if (cell->shift + len <= 32) {195		val = data[cell->idx] >> cell->shift;196	} else {197		u8 part = 32 - cell->shift;198 199		val = data[cell->idx] >> cell->shift;200		val |= data[cell->idx + 1] << part;201	}202 203	return val & ((1 << len) - 1);204}205 206int tsens_read_calibration_legacy(struct tsens_priv *priv,207				  const struct tsens_legacy_calibration_format *format,208				  u32 *p1, u32 *p2,209				  u32 *cdata0, u32 *cdata1)210{211	u32 mode, invalid;212	u32 base1, base2;213	int i;214 215	mode = tsens_read_cell(&format->mode, 2, cdata0, cdata1);216	invalid = tsens_read_cell(&format->invalid, 1, cdata0, cdata1);217	if (invalid)218		mode = NO_PT_CALIB;219	dev_dbg(priv->dev, "calibration mode is %d\n", mode);220 221	base1 = tsens_read_cell(&format->base[0], format->base_len, cdata0, cdata1);222	base2 = tsens_read_cell(&format->base[1], format->base_len, cdata0, cdata1);223 224	for (i = 0; i < priv->num_sensors; i++) {225		p1[i] = tsens_read_cell(&format->sp[i][0], format->sp_len, cdata0, cdata1);226		p2[i] = tsens_read_cell(&format->sp[i][1], format->sp_len, cdata0, cdata1);227	}228 229	switch (mode) {230	case ONE_PT_CALIB:231		for (i = 0; i < priv->num_sensors; i++)232			p1[i] = p1[i] + (base1 << format->base_shift);233		break;234	case TWO_PT_CALIB:235		for (i = 0; i < priv->num_sensors; i++)236			p2[i] = (p2[i] + base2) << format->base_shift;237		fallthrough;238	case ONE_PT_CALIB2:239		for (i = 0; i < priv->num_sensors; i++)240			p1[i] = (p1[i] + base1) << format->base_shift;241		break;242	default:243		dev_dbg(priv->dev, "calibrationless mode\n");244		for (i = 0; i < priv->num_sensors; i++) {245			p1[i] = 500;246			p2[i] = 780;247		}248	}249 250	return mode;251}252 253/*254 * Use this function on devices where slope and offset calculations255 * depend on calibration data read from qfprom. On others the slope256 * and offset values are derived from tz->tzp->slope and tz->tzp->offset257 * resp.258 */259void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,260			     u32 *p2, u32 mode)261{262	int i;263	int num, den;264 265	for (i = 0; i < priv->num_sensors; i++) {266		dev_dbg(priv->dev,267			"%s: sensor%d - data_point1:%#x data_point2:%#x\n",268			__func__, i, p1[i], p2 ? p2[i] : 0);269 270		if (!priv->sensor[i].slope)271			priv->sensor[i].slope = SLOPE_DEFAULT;272		if (mode == TWO_PT_CALIB || mode == TWO_PT_CALIB_NO_OFFSET) {273			/*274			 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/275			 *	temp_120_degc - temp_30_degc (x2 - x1)276			 */277			num = p2[i] - p1[i];278			num *= SLOPE_FACTOR;279			den = CAL_DEGC_PT2 - CAL_DEGC_PT1;280			priv->sensor[i].slope = num / den;281		}282 283		priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -284				(CAL_DEGC_PT1 *285				priv->sensor[i].slope);286		dev_dbg(priv->dev, "%s: offset:%d\n", __func__,287			priv->sensor[i].offset);288	}289}290 291static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)292{293	u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);294 295	pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);296	return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);297}298 299static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)300{301	int degc, num, den;302 303	num = (adc_code * SLOPE_FACTOR) - s->offset;304	den = s->slope;305 306	if (num > 0)307		degc = num + (den / 2);308	else if (num < 0)309		degc = num - (den / 2);310	else311		degc = num;312 313	degc /= den;314 315	return degc;316}317 318/**319 * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.320 * @s:     Pointer to sensor struct321 * @field: Index into regmap_field array pointing to temperature data322 *323 * This function handles temperature returned in ADC code or deciCelsius324 * depending on IP version.325 *326 * Return: Temperature in milliCelsius on success, a negative errno will327 * be returned in error cases328 */329static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)330{331	struct tsens_priv *priv = s->priv;332	u32 resolution;333	u32 temp = 0;334	int ret;335 336	resolution = priv->fields[LAST_TEMP_0].msb -337		priv->fields[LAST_TEMP_0].lsb;338 339	ret = regmap_field_read(priv->rf[field], &temp);340	if (ret)341		return ret;342 343	/* Convert temperature from ADC code to milliCelsius */344	if (priv->feat->adc)345		return code_to_degc(temp, s) * 1000;346 347	/* deciCelsius -> milliCelsius along with sign extension */348	return sign_extend32(temp, resolution) * 100;349}350 351/**352 * tsens_mC_to_hw - Convert temperature to hardware register value353 * @s: Pointer to sensor struct354 * @temp: temperature in milliCelsius to be programmed to hardware355 *356 * This function outputs the value to be written to hardware in ADC code357 * or deciCelsius depending on IP version.358 *359 * Return: ADC code or temperature in deciCelsius.360 */361static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)362{363	struct tsens_priv *priv = s->priv;364 365	/* milliC to adc code */366	if (priv->feat->adc)367		return degc_to_code(temp / 1000, s);368 369	/* milliC to deciC */370	return temp / 100;371}372 373static inline enum tsens_ver tsens_version(struct tsens_priv *priv)374{375	return priv->feat->ver_major;376}377 378static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,379				   enum tsens_irq_type irq_type, bool enable)380{381	u32 index = 0;382 383	switch (irq_type) {384	case UPPER:385		index = UP_INT_CLEAR_0 + hw_id;386		break;387	case LOWER:388		index = LOW_INT_CLEAR_0 + hw_id;389		break;390	case CRITICAL:391		/* No critical interrupts before v2 */392		return;393	}394	regmap_field_write(priv->rf[index], enable ? 0 : 1);395}396 397static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,398				   enum tsens_irq_type irq_type, bool enable)399{400	u32 index_mask = 0, index_clear = 0;401 402	/*403	 * To enable the interrupt flag for a sensor:404	 *    - clear the mask bit405	 * To disable the interrupt flag for a sensor:406	 *    - Mask further interrupts for this sensor407	 *    - Write 1 followed by 0 to clear the interrupt408	 */409	switch (irq_type) {410	case UPPER:411		index_mask  = UP_INT_MASK_0 + hw_id;412		index_clear = UP_INT_CLEAR_0 + hw_id;413		break;414	case LOWER:415		index_mask  = LOW_INT_MASK_0 + hw_id;416		index_clear = LOW_INT_CLEAR_0 + hw_id;417		break;418	case CRITICAL:419		index_mask  = CRIT_INT_MASK_0 + hw_id;420		index_clear = CRIT_INT_CLEAR_0 + hw_id;421		break;422	}423 424	if (enable) {425		regmap_field_write(priv->rf[index_mask], 0);426	} else {427		regmap_field_write(priv->rf[index_mask],  1);428		regmap_field_write(priv->rf[index_clear], 1);429		regmap_field_write(priv->rf[index_clear], 0);430	}431}432 433/**434 * tsens_set_interrupt - Set state of an interrupt435 * @priv: Pointer to tsens controller private data436 * @hw_id: Hardware ID aka. sensor number437 * @irq_type: irq_type from enum tsens_irq_type438 * @enable: false = disable, true = enable439 *440 * Call IP-specific function to set state of an interrupt441 *442 * Return: void443 */444static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,445				enum tsens_irq_type irq_type, bool enable)446{447	dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,448		irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",449		enable ? "en" : "dis");450	if (tsens_version(priv) > VER_1_X)451		tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);452	else453		tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);454}455 456/**457 * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold458 * @priv: Pointer to tsens controller private data459 * @hw_id: Hardware ID aka. sensor number460 * @d: Pointer to irq state data461 *462 * Return: 0 if threshold was not violated, 1 if it was violated and negative463 * errno in case of errors464 */465static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,466				    struct tsens_irq_data *d)467{468	int ret;469 470	ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);471	if (ret)472		return ret;473	ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);474	if (ret)475		return ret;476 477	if (priv->feat->crit_int) {478		ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],479					&d->crit_viol);480		if (ret)481			return ret;482	}483 484	if (d->up_viol || d->low_viol || d->crit_viol)485		return 1;486 487	return 0;488}489 490static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,491				const struct tsens_sensor *s,492				struct tsens_irq_data *d)493{494	int ret;495 496	ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);497	if (ret)498		return ret;499	ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);500	if (ret)501		return ret;502	if (tsens_version(priv) > VER_1_X) {503		ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);504		if (ret)505			return ret;506		ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);507		if (ret)508			return ret;509		ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],510					&d->crit_irq_clear);511		if (ret)512			return ret;513		ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],514					&d->crit_irq_mask);515		if (ret)516			return ret;517 518		d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);519	} else {520		/* No mask register on older TSENS */521		d->up_irq_mask = 0;522		d->low_irq_mask = 0;523		d->crit_irq_clear = 0;524		d->crit_irq_mask = 0;525		d->crit_thresh = 0;526	}527 528	d->up_thresh  = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);529	d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);530 531	dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",532		hw_id, __func__,533		(d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",534		d->low_viol, d->up_viol, d->crit_viol,535		d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,536		d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);537	dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,538		(d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",539		d->low_thresh, d->up_thresh, d->crit_thresh);540 541	return 0;542}543 544static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)545{546	if (ver > VER_1_X)547		return mask & (1 << hw_id);548 549	/* v1, v0.1 don't have a irq mask register */550	return 0;551}552 553/**554 * tsens_critical_irq_thread() - Threaded handler for critical interrupts555 * @irq: irq number556 * @data: tsens controller private data557 *558 * Check FSM watchdog bark status and clear if needed.559 * Check all sensors to find ones that violated their critical threshold limits.560 * Clear and then re-enable the interrupt.561 *562 * The level-triggered interrupt might deassert if the temperature returned to563 * within the threshold limits by the time the handler got scheduled. We564 * consider the irq to have been handled in that case.565 *566 * Return: IRQ_HANDLED567 */568static irqreturn_t tsens_critical_irq_thread(int irq, void *data)569{570	struct tsens_priv *priv = data;571	struct tsens_irq_data d;572	int temp, ret, i;573	u32 wdog_status, wdog_count;574 575	if (priv->feat->has_watchdog) {576		ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],577					&wdog_status);578		if (ret)579			return ret;580 581		if (wdog_status) {582			/* Clear WDOG interrupt */583			regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);584			regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);585			ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],586						&wdog_count);587			if (ret)588				return ret;589			if (wdog_count)590				dev_dbg(priv->dev, "%s: watchdog count: %d\n",591					__func__, wdog_count);592 593			/* Fall through to handle critical interrupts if any */594		}595	}596 597	for (i = 0; i < priv->num_sensors; i++) {598		const struct tsens_sensor *s = &priv->sensor[i];599		u32 hw_id = s->hw_id;600 601		if (!s->tzd)602			continue;603		if (!tsens_threshold_violated(priv, hw_id, &d))604			continue;605		ret = get_temp_tsens_valid(s, &temp);606		if (ret) {607			dev_err(priv->dev, "[%u] %s: error reading sensor\n",608				hw_id, __func__);609			continue;610		}611 612		tsens_read_irq_state(priv, hw_id, s, &d);613		if (d.crit_viol &&614		    !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {615			/* Mask critical interrupts, unused on Linux */616			tsens_set_interrupt(priv, hw_id, CRITICAL, false);617		}618	}619 620	return IRQ_HANDLED;621}622 623/**624 * tsens_irq_thread - Threaded interrupt handler for uplow interrupts625 * @irq: irq number626 * @data: tsens controller private data627 *628 * Check all sensors to find ones that violated their threshold limits. If the629 * temperature is still outside the limits, call thermal_zone_device_update() to630 * update the thresholds, else re-enable the interrupts.631 *632 * The level-triggered interrupt might deassert if the temperature returned to633 * within the threshold limits by the time the handler got scheduled. We634 * consider the irq to have been handled in that case.635 *636 * Return: IRQ_HANDLED637 */638static irqreturn_t tsens_irq_thread(int irq, void *data)639{640	struct tsens_priv *priv = data;641	struct tsens_irq_data d;642	int i;643 644	for (i = 0; i < priv->num_sensors; i++) {645		const struct tsens_sensor *s = &priv->sensor[i];646		u32 hw_id = s->hw_id;647 648		if (!s->tzd)649			continue;650		if (!tsens_threshold_violated(priv, hw_id, &d))651			continue;652 653		thermal_zone_device_update(s->tzd, THERMAL_EVENT_UNSPECIFIED);654 655		if (tsens_version(priv) < VER_0_1) {656			/* Constraint: There is only 1 interrupt control register for all657			 * 11 temperature sensor. So monitoring more than 1 sensor based658			 * on interrupts will yield inconsistent result. To overcome this659			 * issue we will monitor only sensor 0 which is the master sensor.660			 */661			break;662		}663	}664 665	return IRQ_HANDLED;666}667 668/**669 * tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts670 * @irq: irq number671 * @data: tsens controller private data672 *673 * Handle the combined interrupt as if it were 2 separate interrupts, so call the674 * critical handler first and then the up/low one.675 *676 * Return: IRQ_HANDLED677 */678static irqreturn_t tsens_combined_irq_thread(int irq, void *data)679{680	irqreturn_t ret;681 682	ret = tsens_critical_irq_thread(irq, data);683	if (ret != IRQ_HANDLED)684		return ret;685 686	return tsens_irq_thread(irq, data);687}688 689static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)690{691	struct tsens_sensor *s = thermal_zone_device_priv(tz);692	struct tsens_priv *priv = s->priv;693	struct device *dev = priv->dev;694	struct tsens_irq_data d;695	unsigned long flags;696	int high_val, low_val, cl_high, cl_low;697	u32 hw_id = s->hw_id;698 699	if (tsens_version(priv) < VER_0_1) {700		/* Pre v0.1 IP had a single register for each type of interrupt701		 * and thresholds702		 */703		hw_id = 0;704	}705 706	dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",707		hw_id, __func__, low, high);708 709	cl_high = clamp_val(high, priv->feat->trip_min_temp, priv->feat->trip_max_temp);710	cl_low  = clamp_val(low, priv->feat->trip_min_temp, priv->feat->trip_max_temp);711 712	high_val = tsens_mC_to_hw(s, cl_high);713	low_val  = tsens_mC_to_hw(s, cl_low);714 715	spin_lock_irqsave(&priv->ul_lock, flags);716 717	tsens_read_irq_state(priv, hw_id, s, &d);718 719	/* Write the new thresholds and clear the status */720	regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);721	regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);722	tsens_set_interrupt(priv, hw_id, LOWER, true);723	tsens_set_interrupt(priv, hw_id, UPPER, true);724 725	spin_unlock_irqrestore(&priv->ul_lock, flags);726 727	dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",728		hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);729 730	return 0;731}732 733static int tsens_enable_irq(struct tsens_priv *priv)734{735	int ret;736	int val = tsens_version(priv) > VER_1_X ? 7 : 1;737 738	ret = regmap_field_write(priv->rf[INT_EN], val);739	if (ret < 0)740		dev_err(priv->dev, "%s: failed to enable interrupts\n",741			__func__);742 743	return ret;744}745 746static void tsens_disable_irq(struct tsens_priv *priv)747{748	regmap_field_write(priv->rf[INT_EN], 0);749}750 751int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)752{753	struct tsens_priv *priv = s->priv;754	int hw_id = s->hw_id;755	u32 temp_idx = LAST_TEMP_0 + hw_id;756	u32 valid_idx = VALID_0 + hw_id;757	u32 valid;758	int ret;759 760	/* VER_0 doesn't have VALID bit */761	if (tsens_version(priv) == VER_0)762		goto get_temp;763 764	/* Valid bit is 0 for 6 AHB clock cycles.765	 * At 19.2MHz, 1 AHB clock is ~60ns.766	 * We should enter this loop very, very rarely.767	 * Wait 1 us since it's the min of poll_timeout macro.768	 * Old value was 400 ns.769	 */770	ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid,771					     valid, 1, 20 * USEC_PER_MSEC);772	if (ret)773		return ret;774 775get_temp:776	/* Valid bit is set, OK to read the temperature */777	*temp = tsens_hw_to_mC(s, temp_idx);778 779	return 0;780}781 782int get_temp_common(const struct tsens_sensor *s, int *temp)783{784	struct tsens_priv *priv = s->priv;785	int hw_id = s->hw_id;786	int last_temp = 0, ret, trdy;787	unsigned long timeout;788 789	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);790	do {791		if (tsens_version(priv) == VER_0) {792			ret = regmap_field_read(priv->rf[TRDY], &trdy);793			if (ret)794				return ret;795			if (!trdy)796				continue;797		}798 799		ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);800		if (ret)801			return ret;802 803		*temp = code_to_degc(last_temp, s) * 1000;804 805		return 0;806	} while (time_before(jiffies, timeout));807 808	return -ETIMEDOUT;809}810 811#ifdef CONFIG_DEBUG_FS812static int dbg_sensors_show(struct seq_file *s, void *data)813{814	struct platform_device *pdev = s->private;815	struct tsens_priv *priv = platform_get_drvdata(pdev);816	int i;817 818	seq_printf(s, "max: %2d\nnum: %2d\n\n",819		   priv->feat->max_sensors, priv->num_sensors);820 821	seq_puts(s, "      id    slope   offset\n--------------------------\n");822	for (i = 0;  i < priv->num_sensors; i++) {823		seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,824			   priv->sensor[i].slope, priv->sensor[i].offset);825	}826 827	return 0;828}829 830static int dbg_version_show(struct seq_file *s, void *data)831{832	struct platform_device *pdev = s->private;833	struct tsens_priv *priv = platform_get_drvdata(pdev);834	u32 maj_ver, min_ver, step_ver;835	int ret;836 837	if (tsens_version(priv) > VER_0_1) {838		ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);839		if (ret)840			return ret;841		ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);842		if (ret)843			return ret;844		ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);845		if (ret)846			return ret;847		seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);848	} else {849		seq_printf(s, "0.%d.0\n", priv->feat->ver_major);850	}851 852	return 0;853}854 855DEFINE_SHOW_ATTRIBUTE(dbg_version);856DEFINE_SHOW_ATTRIBUTE(dbg_sensors);857 858static void tsens_debug_init(struct platform_device *pdev)859{860	struct tsens_priv *priv = platform_get_drvdata(pdev);861 862	priv->debug_root = debugfs_lookup("tsens", NULL);863	if (!priv->debug_root)864		priv->debug_root = debugfs_create_dir("tsens", NULL);865 866	/* A directory for each instance of the TSENS IP */867	priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);868	debugfs_create_file("version", 0444, priv->debug, pdev, &dbg_version_fops);869	debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);870}871#else872static inline void tsens_debug_init(struct platform_device *pdev) {}873#endif874 875static const struct regmap_config tsens_config = {876	.name		= "tm",877	.reg_bits	= 32,878	.val_bits	= 32,879	.reg_stride	= 4,880};881 882static const struct regmap_config tsens_srot_config = {883	.name		= "srot",884	.reg_bits	= 32,885	.val_bits	= 32,886	.reg_stride	= 4,887};888 889int __init init_common(struct tsens_priv *priv)890{891	void __iomem *tm_base, *srot_base;892	struct device *dev = priv->dev;893	u32 ver_minor;894	struct resource *res;895	u32 enabled;896	int ret, i, j;897	struct platform_device *op = of_find_device_by_node(priv->dev->of_node);898 899	if (!op)900		return -EINVAL;901 902	if (op->num_resources > 1) {903		/* DT with separate SROT and TM address space */904		priv->tm_offset = 0;905		res = platform_get_resource(op, IORESOURCE_MEM, 1);906		srot_base = devm_ioremap_resource(dev, res);907		if (IS_ERR(srot_base)) {908			ret = PTR_ERR(srot_base);909			goto err_put_device;910		}911 912		priv->srot_map = devm_regmap_init_mmio(dev, srot_base,913						       &tsens_srot_config);914		if (IS_ERR(priv->srot_map)) {915			ret = PTR_ERR(priv->srot_map);916			goto err_put_device;917		}918	} else {919		/* old DTs where SROT and TM were in a contiguous 2K block */920		priv->tm_offset = 0x1000;921	}922 923	if (tsens_version(priv) >= VER_0_1) {924		res = platform_get_resource(op, IORESOURCE_MEM, 0);925		tm_base = devm_ioremap_resource(dev, res);926		if (IS_ERR(tm_base)) {927			ret = PTR_ERR(tm_base);928			goto err_put_device;929		}930 931		priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);932	} else { /* VER_0 share the same gcc regs using a syscon */933		struct device *parent = priv->dev->parent;934 935		if (parent)936			priv->tm_map = syscon_node_to_regmap(parent->of_node);937	}938 939	if (IS_ERR_OR_NULL(priv->tm_map)) {940		if (!priv->tm_map)941			ret = -ENODEV;942		else943			ret = PTR_ERR(priv->tm_map);944		goto err_put_device;945	}946 947	/* VER_0 have only tm_map */948	if (!priv->srot_map)949		priv->srot_map = priv->tm_map;950 951	if (tsens_version(priv) > VER_0_1) {952		for (i = VER_MAJOR; i <= VER_STEP; i++) {953			priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,954							      priv->fields[i]);955			if (IS_ERR(priv->rf[i])) {956				ret = PTR_ERR(priv->rf[i]);957				goto err_put_device;958			}959		}960		ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);961		if (ret)962			goto err_put_device;963	}964 965	priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,966						     priv->fields[TSENS_EN]);967	if (IS_ERR(priv->rf[TSENS_EN])) {968		ret = PTR_ERR(priv->rf[TSENS_EN]);969		goto err_put_device;970	}971	/* in VER_0 TSENS need to be explicitly enabled */972	if (tsens_version(priv) == VER_0)973		regmap_field_write(priv->rf[TSENS_EN], 1);974 975	ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);976	if (ret)977		goto err_put_device;978	if (!enabled) {979		dev_err(dev, "%s: device not enabled\n", __func__);980		ret = -ENODEV;981		goto err_put_device;982	}983 984	priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,985						      priv->fields[SENSOR_EN]);986	if (IS_ERR(priv->rf[SENSOR_EN])) {987		ret = PTR_ERR(priv->rf[SENSOR_EN]);988		goto err_put_device;989	}990	priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,991						   priv->fields[INT_EN]);992	if (IS_ERR(priv->rf[INT_EN])) {993		ret = PTR_ERR(priv->rf[INT_EN]);994		goto err_put_device;995	}996 997	priv->rf[TSENS_SW_RST] =998		devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]);999	if (IS_ERR(priv->rf[TSENS_SW_RST])) {1000		ret = PTR_ERR(priv->rf[TSENS_SW_RST]);1001		goto err_put_device;1002	}1003 1004	priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]);1005	if (IS_ERR(priv->rf[TRDY])) {1006		ret = PTR_ERR(priv->rf[TRDY]);1007		goto err_put_device;1008	}1009 1010	/* This loop might need changes if enum regfield_ids is reordered */1011	for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {1012		for (i = 0; i < priv->feat->max_sensors; i++) {1013			int idx = j + i;1014 1015			priv->rf[idx] = devm_regmap_field_alloc(dev,1016								priv->tm_map,1017								priv->fields[idx]);1018			if (IS_ERR(priv->rf[idx])) {1019				ret = PTR_ERR(priv->rf[idx]);1020				goto err_put_device;1021			}1022		}1023	}1024 1025	if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {1026		/* Loop might need changes if enum regfield_ids is reordered */1027		for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {1028			for (i = 0; i < priv->feat->max_sensors; i++) {1029				int idx = j + i;1030 1031				priv->rf[idx] =1032					devm_regmap_field_alloc(dev,1033								priv->tm_map,1034								priv->fields[idx]);1035				if (IS_ERR(priv->rf[idx])) {1036					ret = PTR_ERR(priv->rf[idx]);1037					goto err_put_device;1038				}1039			}1040		}1041	}1042 1043	if (tsens_version(priv) > VER_1_X &&  ver_minor > 2) {1044		/* Watchdog is present only on v2.3+ */1045		priv->feat->has_watchdog = 1;1046		for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {1047			priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,1048							      priv->fields[i]);1049			if (IS_ERR(priv->rf[i])) {1050				ret = PTR_ERR(priv->rf[i]);1051				goto err_put_device;1052			}1053		}1054		/*1055		 * Watchdog is already enabled, unmask the bark.1056		 * Disable cycle completion monitoring1057		 */1058		regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);1059		regmap_field_write(priv->rf[CC_MON_MASK], 1);1060	}1061 1062	spin_lock_init(&priv->ul_lock);1063 1064	/* VER_0 interrupt doesn't need to be enabled */1065	if (tsens_version(priv) >= VER_0_1)1066		tsens_enable_irq(priv);1067 1068err_put_device:1069	put_device(&op->dev);1070	return ret;1071}1072 1073static int tsens_get_temp(struct thermal_zone_device *tz, int *temp)1074{1075	struct tsens_sensor *s = thermal_zone_device_priv(tz);1076	struct tsens_priv *priv = s->priv;1077 1078	return priv->ops->get_temp(s, temp);1079}1080 1081static int  __maybe_unused tsens_suspend(struct device *dev)1082{1083	struct tsens_priv *priv = dev_get_drvdata(dev);1084 1085	if (priv->ops && priv->ops->suspend)1086		return priv->ops->suspend(priv);1087 1088	return 0;1089}1090 1091static int __maybe_unused tsens_resume(struct device *dev)1092{1093	struct tsens_priv *priv = dev_get_drvdata(dev);1094 1095	if (priv->ops && priv->ops->resume)1096		return priv->ops->resume(priv);1097 1098	return 0;1099}1100 1101static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);1102 1103static const struct of_device_id tsens_table[] = {1104	{1105		.compatible = "qcom,ipq8064-tsens",1106		.data = &data_8960,1107	}, {1108		.compatible = "qcom,ipq8074-tsens",1109		.data = &data_ipq8074,1110	}, {1111		.compatible = "qcom,mdm9607-tsens",1112		.data = &data_9607,1113	}, {1114		.compatible = "qcom,msm8226-tsens",1115		.data = &data_8226,1116	}, {1117		.compatible = "qcom,msm8909-tsens",1118		.data = &data_8909,1119	}, {1120		.compatible = "qcom,msm8916-tsens",1121		.data = &data_8916,1122	}, {1123		.compatible = "qcom,msm8939-tsens",1124		.data = &data_8939,1125	}, {1126		.compatible = "qcom,msm8956-tsens",1127		.data = &data_8956,1128	}, {1129		.compatible = "qcom,msm8960-tsens",1130		.data = &data_8960,1131	}, {1132		.compatible = "qcom,msm8974-tsens",1133		.data = &data_8974,1134	}, {1135		.compatible = "qcom,msm8976-tsens",1136		.data = &data_8976,1137	}, {1138		.compatible = "qcom,msm8996-tsens",1139		.data = &data_8996,1140	}, {1141		.compatible = "qcom,tsens-v1",1142		.data = &data_tsens_v1,1143	}, {1144		.compatible = "qcom,tsens-v2",1145		.data = &data_tsens_v2,1146	},1147	{}1148};1149MODULE_DEVICE_TABLE(of, tsens_table);1150 1151static const struct thermal_zone_device_ops tsens_of_ops = {1152	.get_temp = tsens_get_temp,1153	.set_trips = tsens_set_trips,1154};1155 1156static int tsens_register_irq(struct tsens_priv *priv, char *irqname,1157			      irq_handler_t thread_fn)1158{1159	struct platform_device *pdev;1160	int ret, irq;1161 1162	pdev = of_find_device_by_node(priv->dev->of_node);1163	if (!pdev)1164		return -ENODEV;1165 1166	irq = platform_get_irq_byname(pdev, irqname);1167	if (irq < 0) {1168		ret = irq;1169		/* For old DTs with no IRQ defined */1170		if (irq == -ENXIO)1171			ret = 0;1172	} else {1173		/* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */1174		if (tsens_version(priv) == VER_0)1175			ret = devm_request_threaded_irq(&pdev->dev, irq,1176							thread_fn, NULL,1177							IRQF_TRIGGER_RISING,1178							dev_name(&pdev->dev),1179							priv);1180		else1181			ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,1182							thread_fn, IRQF_ONESHOT,1183							dev_name(&pdev->dev),1184							priv);1185 1186		if (ret)1187			dev_err(&pdev->dev, "%s: failed to get irq\n",1188				__func__);1189		else1190			enable_irq_wake(irq);1191	}1192 1193	put_device(&pdev->dev);1194	return ret;1195}1196 1197#ifdef CONFIG_SUSPEND1198static int tsens_reinit(struct tsens_priv *priv)1199{1200	if (tsens_version(priv) >= VER_2_X) {1201		/*1202		 * Re-enable the watchdog, unmask the bark.1203		 * Disable cycle completion monitoring1204		 */1205		if (priv->feat->has_watchdog) {1206			regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);1207			regmap_field_write(priv->rf[CC_MON_MASK], 1);1208		}1209 1210		/* Re-enable interrupts */1211		tsens_enable_irq(priv);1212	}1213 1214	return 0;1215}1216 1217int tsens_resume_common(struct tsens_priv *priv)1218{1219	if (pm_suspend_target_state == PM_SUSPEND_MEM)1220		tsens_reinit(priv);1221 1222	return 0;1223}1224 1225#endif /* !CONFIG_SUSPEND */1226 1227static int tsens_register(struct tsens_priv *priv)1228{1229	int i, ret;1230	struct thermal_zone_device *tzd;1231 1232	for (i = 0;  i < priv->num_sensors; i++) {1233		priv->sensor[i].priv = priv;1234		tzd = devm_thermal_of_zone_register(priv->dev, priv->sensor[i].hw_id,1235						    &priv->sensor[i],1236						    &tsens_of_ops);1237		if (IS_ERR(tzd))1238			continue;1239		priv->sensor[i].tzd = tzd;1240		if (priv->ops->enable)1241			priv->ops->enable(priv, i);1242 1243		devm_thermal_add_hwmon_sysfs(priv->dev, tzd);1244	}1245 1246	/* VER_0 require to set MIN and MAX THRESH1247	 * These 2 regs are set using the:1248	 * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C1249	 * - CRIT_THRESH_1 for MIN THRESH hardcoded to   0°C1250	 */1251	if (tsens_version(priv) < VER_0_1) {1252		regmap_field_write(priv->rf[CRIT_THRESH_0],1253				   tsens_mC_to_hw(priv->sensor, 120000));1254 1255		regmap_field_write(priv->rf[CRIT_THRESH_1],1256				   tsens_mC_to_hw(priv->sensor, 0));1257	}1258 1259	if (priv->feat->combo_int) {1260		ret = tsens_register_irq(priv, "combined",1261					 tsens_combined_irq_thread);1262	} else {1263		ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);1264		if (ret < 0)1265			return ret;1266 1267		if (priv->feat->crit_int)1268			ret = tsens_register_irq(priv, "critical",1269						 tsens_critical_irq_thread);1270	}1271 1272	return ret;1273}1274 1275static int tsens_probe(struct platform_device *pdev)1276{1277	int ret, i;1278	struct device *dev;1279	struct device_node *np;1280	struct tsens_priv *priv;1281	const struct tsens_plat_data *data;1282	const struct of_device_id *id;1283	u32 num_sensors;1284 1285	if (pdev->dev.of_node)1286		dev = &pdev->dev;1287	else1288		dev = pdev->dev.parent;1289 1290	np = dev->of_node;1291 1292	id = of_match_node(tsens_table, np);1293	if (id)1294		data = id->data;1295	else1296		data = &data_8960;1297 1298	num_sensors = data->num_sensors;1299 1300	if (np)1301		of_property_read_u32(np, "#qcom,sensors", &num_sensors);1302 1303	if (num_sensors <= 0) {1304		dev_err(dev, "%s: invalid number of sensors\n", __func__);1305		return -EINVAL;1306	}1307 1308	priv = devm_kzalloc(dev,1309			     struct_size(priv, sensor, num_sensors),1310			     GFP_KERNEL);1311	if (!priv)1312		return -ENOMEM;1313 1314	priv->dev = dev;1315	priv->num_sensors = num_sensors;1316	priv->ops = data->ops;1317	for (i = 0;  i < priv->num_sensors; i++) {1318		if (data->hw_ids)1319			priv->sensor[i].hw_id = data->hw_ids[i];1320		else1321			priv->sensor[i].hw_id = i;1322	}1323	priv->feat = data->feat;1324	priv->fields = data->fields;1325 1326	platform_set_drvdata(pdev, priv);1327 1328	if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)1329		return -EINVAL;1330 1331	ret = priv->ops->init(priv);1332	if (ret < 0) {1333		dev_err(dev, "%s: init failed\n", __func__);1334		return ret;1335	}1336 1337	if (priv->ops->calibrate) {1338		ret = priv->ops->calibrate(priv);1339		if (ret < 0)1340			return dev_err_probe(dev, ret, "%s: calibration failed\n",1341					     __func__);1342	}1343 1344	ret = tsens_register(priv);1345	if (!ret)1346		tsens_debug_init(pdev);1347 1348	return ret;1349}1350 1351static void tsens_remove(struct platform_device *pdev)1352{1353	struct tsens_priv *priv = platform_get_drvdata(pdev);1354 1355	debugfs_remove_recursive(priv->debug_root);1356	tsens_disable_irq(priv);1357	if (priv->ops->disable)1358		priv->ops->disable(priv);1359}1360 1361static struct platform_driver tsens_driver = {1362	.probe = tsens_probe,1363	.remove_new = tsens_remove,1364	.driver = {1365		.name = "qcom-tsens",1366		.pm	= &tsens_pm_ops,1367		.of_match_table = tsens_table,1368	},1369};1370module_platform_driver(tsens_driver);1371 1372MODULE_LICENSE("GPL v2");1373MODULE_DESCRIPTION("QCOM Temperature Sensor driver");1374MODULE_ALIAS("platform:qcom-tsens");1375