drivers/thermal/hisi_thermal.c

Source file repositories/reference/linux-study-clean/drivers/thermal/hisi_thermal.c

File Facts

System
Linux kernel
Corpus path
drivers/thermal/hisi_thermal.c
Extension
.c
Size
16775 bytes
Lines
652
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

struct hisi_thermal_sensor {
	struct hisi_thermal_data *data;
	struct thermal_zone_device *tzd;
	const char *irq_name;
	uint32_t id;
	uint32_t thres_temp;
};

struct hisi_thermal_ops {
	int (*get_temp)(struct hisi_thermal_sensor *sensor);
	int (*enable_sensor)(struct hisi_thermal_sensor *sensor);
	int (*disable_sensor)(struct hisi_thermal_sensor *sensor);
	int (*irq_handler)(struct hisi_thermal_sensor *sensor);
	int (*probe)(struct hisi_thermal_data *data);
};

struct hisi_thermal_data {
	const struct hisi_thermal_ops *ops;
	struct hisi_thermal_sensor *sensor;
	struct platform_device *pdev;
	struct clk *clk;
	void __iomem *regs;
	int nr_sensors;
};

/*
 * The temperature computation on the tsensor is as follow:
 *	Unit: millidegree Celsius
 *	Step: 200/255 (0.7843)
 *	Temperature base: -60°C
 *
 * The register is programmed in temperature steps, every step is 785
 * millidegree and begins at -60 000 m°C
 *
 * The temperature from the steps:
 *
 *	Temp = TempBase + (steps x 785)
 *
 * and the steps from the temperature:
 *
 *	steps = (Temp - TempBase) / 785
 *
 */
static inline int hi6220_thermal_step_to_temp(int step)
{
	return HI6220_TEMP_BASE + (step * HI6220_TEMP_STEP);
}

static inline int hi6220_thermal_temp_to_step(int temp)
{
	return DIV_ROUND_UP(temp - HI6220_TEMP_BASE, HI6220_TEMP_STEP);
}

/*
 * for Hi3660,
 *	Step: 189/922 (0.205)
 *	Temperature base: -63.780°C
 *
 * The register is programmed in temperature steps, every step is 205
 * millidegree and begins at -63 780 m°C
 */
static inline int hi3660_thermal_step_to_temp(int step)
{
	return HI3660_TEMP_BASE + step * HI3660_TEMP_STEP;
}

static inline int hi3660_thermal_temp_to_step(int temp)
{
	return DIV_ROUND_UP(temp - HI3660_TEMP_BASE, HI3660_TEMP_STEP);
}

/*
 * The lag register contains 5 bits encoding the temperature in steps.
 *
 * Each time the temperature crosses the threshold boundary, an
 * interrupt is raised. It could be when the temperature is going
 * above the threshold or below. However, if the temperature is
 * fluctuating around this value due to the load, we can receive
 * several interrupts which may not desired.
 *
 * We can setup a temperature representing the delta between the
 * threshold and the current temperature when the temperature is
 * decreasing.
 *
 * For instance: the lag register is 5°C, the threshold is 65°C, when
 * the temperature reaches 65°C an interrupt is raised and when the
 * temperature decrease to 65°C - 5°C another interrupt is raised.
 *
 * A very short lag can lead to an interrupt storm, a long lag
 * increase the latency to react to the temperature changes.  In our

Annotation

Implementation Notes