drivers/thermal/broadcom/brcmstb_thermal.c

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

File Facts

System
Linux kernel
Corpus path
drivers/thermal/broadcom/brcmstb_thermal.c
Extension
.c
Size
10173 bytes
Lines
380
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 avs_tmon_trip {
	/* HW bit to enable the trip */
	u32 enable_offs;
	u32 enable_mask;

	/* HW field to read the trip temperature */
	u32 reg_offs;
	u32 reg_msk;
	int reg_shift;
};

static struct avs_tmon_trip avs_tmon_trips[] = {
	/* Trips when temperature is below threshold */
	[TMON_TRIP_TYPE_LOW] = {
		.enable_offs	= AVS_TMON_EN_TEMP_INT_SRCS,
		.enable_mask	= AVS_TMON_EN_TEMP_INT_SRCS_low,
		.reg_offs	= AVS_TMON_INT_THRESH,
		.reg_msk	= AVS_TMON_INT_THRESH_low_msk,
		.reg_shift	= AVS_TMON_INT_THRESH_low_shift,
	},
	/* Trips when temperature is above threshold */
	[TMON_TRIP_TYPE_HIGH] = {
		.enable_offs	= AVS_TMON_EN_TEMP_INT_SRCS,
		.enable_mask	= AVS_TMON_EN_TEMP_INT_SRCS_high,
		.reg_offs	= AVS_TMON_INT_THRESH,
		.reg_msk	= AVS_TMON_INT_THRESH_high_msk,
		.reg_shift	= AVS_TMON_INT_THRESH_high_shift,
	},
	/* Automatically resets chip when above threshold */
	[TMON_TRIP_TYPE_RESET] = {
		.enable_offs	= AVS_TMON_EN_OVERTEMP_RESET,
		.enable_mask	= AVS_TMON_EN_OVERTEMP_RESET_msk,
		.reg_offs	= AVS_TMON_RESET_THRESH,
		.reg_msk	= AVS_TMON_RESET_THRESH_msk,
		.reg_shift	= AVS_TMON_RESET_THRESH_shift,
	},
};

struct brcmstb_thermal_params {
	unsigned int offset;
	unsigned int mult;
	const struct thermal_zone_device_ops *of_ops;
};

struct brcmstb_thermal_priv {
	void __iomem *tmon_base;
	struct device *dev;
	struct thermal_zone_device *thermal;
	/* Process specific thermal parameters used for calculations */
	const struct brcmstb_thermal_params *temp_params;
};

/* Convert a HW code to a temperature reading (millidegree celsius) */
static inline int avs_tmon_code_to_temp(struct brcmstb_thermal_priv *priv,
					u32 code)
{
	int offset = priv->temp_params->offset;
	int mult = priv->temp_params->mult;

	return (offset - (int)((code & AVS_TMON_TEMP_MASK) * mult));
}

/*
 * Convert a temperature value (millidegree celsius) to a HW code
 *
 * @temp: temperature to convert
 * @low: if true, round toward the low side
 */
static inline u32 avs_tmon_temp_to_code(struct brcmstb_thermal_priv *priv,
					int temp, bool low)
{
	int offset = priv->temp_params->offset;
	int mult = priv->temp_params->mult;

	if (temp < AVS_TMON_TEMP_MIN)
		return AVS_TMON_TEMP_MAX;	/* Maximum code value */

	if (temp >= offset)
		return 0;	/* Minimum code value */

	if (low)
		return (u32)(DIV_ROUND_UP(offset - temp, mult));
	else
		return (u32)((offset - temp) / mult);
}

static int brcmstb_get_temp(struct thermal_zone_device *tz, int *temp)
{
	struct brcmstb_thermal_priv *priv = thermal_zone_device_priv(tz);
	u32 val;

Annotation

Implementation Notes