drivers/thermal/ti-soc-thermal/ti-bandgap.c

Source file repositories/reference/linux-study-clean/drivers/thermal/ti-soc-thermal/ti-bandgap.c

File Facts

System
Linux kernel
Corpus path
drivers/thermal/ti-soc-thermal/ti-bandgap.c
Extension
.c
Size
33826 bytes
Lines
1298
Domain
Driver Families
Bucket
drivers/thermal
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (t_hot) {
			ctrl &= ~tsr->mask_hot_mask;
			ctrl |= tsr->mask_cold_mask;
		} else if (t_cold) {
			ctrl &= ~tsr->mask_cold_mask;
			ctrl |= tsr->mask_hot_mask;
		}

		ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);

		dev_dbg(bgp->dev,
			"%s: IRQ from %s sensor: hotevent %d coldevent %d\n",
			__func__, bgp->conf->sensors[i].domain,
			t_hot, t_cold);

		/* report temperature to whom may concern */
		if (bgp->conf->report_temperature)
			bgp->conf->report_temperature(bgp, i);
	}
	spin_unlock(&bgp->lock);

	return IRQ_HANDLED;
}

/**
 * ti_bandgap_tshut_irq_handler() - handles Temperature shutdown signal
 * @irq: IRQ number
 * @data: private data (unused)
 *
 * This is the Tshut handler. Use it only if bandgap device features
 * HAS(TSHUT). If any sensor fires the Tshut signal, we simply shutdown
 * the system.
 *
 * Return: IRQ_HANDLED
 */
static irqreturn_t ti_bandgap_tshut_irq_handler(int irq, void *data)
{
	pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n",
		 __func__);

	orderly_poweroff(true);

	return IRQ_HANDLED;
}

/***   Helper functions which manipulate conversion ADC <-> mi Celsius   ***/

/**
 * ti_bandgap_adc_to_mcelsius() - converts an ADC value to mCelsius scale
 * @bgp: struct ti_bandgap pointer
 * @adc_val: value in ADC representation
 * @t: address where to write the resulting temperature in mCelsius
 *
 * Simple conversion from ADC representation to mCelsius. In case the ADC value
 * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
 * The conversion table is indexed by the ADC values.
 *
 * Return: 0 if conversion was successful, else -ERANGE in case the @adc_val
 * argument is out of the ADC conv table range.
 */
static
int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
{
	const struct ti_bandgap_data *conf = bgp->conf;

	/* look up for temperature in the table and return the temperature */
	if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val)
		return -ERANGE;

	*t = bgp->conf->conv_table[adc_val - conf->adc_start_val];
	return 0;
}

/**
 * ti_bandgap_validate() - helper to check the sanity of a struct ti_bandgap
 * @bgp: struct ti_bandgap pointer
 * @id: bandgap sensor id
 *
 * Checks if the bandgap pointer is valid and if the sensor id is also
 * applicable.
 *
 * Return: 0 if no errors, -EINVAL for invalid @bgp pointer or -ERANGE if
 * @id cannot index @bgp sensors.
 */
static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
{
	if (IS_ERR_OR_NULL(bgp)) {
		pr_err("%s: invalid bandgap pointer\n", __func__);
		return -EINVAL;
	}

Annotation

Implementation Notes