drivers/thermal/renesas/rcar_gen3_thermal.c

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

File Facts

System
Linux kernel
Corpus path
drivers/thermal/renesas/rcar_gen3_thermal.c
Extension
.c
Size
16846 bytes
Lines
635
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 rcar_gen3_thermal_fuse_info {
	u32 ptat[3];
	u32 thcode[3];
	u32 mask;
};

struct rcar_gen3_thermal_fuse_default {
	u32 ptat[3];
	u32 thcodes[TSC_MAX_NUM][3];
};

struct rcar_thermal_info {
	int scale;
	int adj_below;
	int adj_above;
	const struct rcar_gen3_thermal_fuse_info *fuses;
	const struct rcar_gen3_thermal_fuse_default *fuse_defaults;
};

struct equation_set_coef {
	int a;
	int b;
};

struct rcar_gen3_thermal_tsc {
	struct rcar_gen3_thermal_priv *priv;
	void __iomem *base;
	struct thermal_zone_device *zone;
	/* Different coefficients are used depending on a threshold. */
	struct {
		struct equation_set_coef below;
		struct equation_set_coef above;
	} coef;
	int thcode[3];
};

struct rcar_gen3_thermal_priv {
	struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
	struct thermal_zone_device_ops ops;
	unsigned int num_tscs;
	int ptat[3];
	int tj_t;
	const struct rcar_thermal_info *info;
};

static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc,
					 u32 reg)
{
	return ioread32(tsc->base + reg);
}

static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
					   u32 reg, u32 data)
{
	iowrite32(data, tsc->base + reg);
}

/*
 * Linear approximation for temperature
 *
 * [temp] = ((thadj - [reg]) * a) / b + adj
 * [reg] = thadj - ([temp] - adj) * b / a
 *
 * The constants a and b are calculated using two triplets of int values PTAT
 * and THCODE. PTAT and THCODE can either be read from hardware or use hard
 * coded values from the driver. The formula to calculate a and b are taken from
 * the datasheet. Different calculations are needed for a and b depending on
 * if the input variables ([temp] or [reg]) are above or below a threshold. The
 * threshold is also calculated from PTAT and THCODE using formulas from the
 * datasheet.
 *
 * The constant thadj is one of the THCODE values, which one to use depends on
 * the threshold and input value.
 *
 * The constants adj is taken verbatim from the datasheet. Two values exists,
 * which one to use depends on the input value and the calculated threshold.
 * Furthermore different SoC models supported by the driver have different sets
 * of values. The values for each model are stored in the device match data.
 */

static void rcar_gen3_thermal_shared_coefs(struct rcar_gen3_thermal_priv *priv)
{
	priv->tj_t =
		DIV_ROUND_CLOSEST((priv->ptat[1] - priv->ptat[2]) * priv->info->scale,
				  priv->ptat[0] - priv->ptat[2])
		+ priv->info->adj_below;
}
static void rcar_gen3_thermal_tsc_coefs(struct rcar_gen3_thermal_priv *priv,
					struct rcar_gen3_thermal_tsc *tsc)
{

Annotation

Implementation Notes