drivers/thermal/sun8i_thermal.c
Source file repositories/reference/linux-study-clean/drivers/thermal/sun8i_thermal.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thermal/sun8i_thermal.c- Extension
.c- Size
- 19714 bytes
- Lines
- 737
- 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.
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitmap.hlinux/cleanup.hlinux/clk.hlinux/device.hlinux/interrupt.hlinux/module.hlinux/nvmem-consumer.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/regmap.hlinux/reset.hlinux/slab.hlinux/thermal.hthermal_hwmon.h
Detected Declarations
struct tsensorstruct ths_thermal_chipstruct ths_devicefunction sun8i_ths_calc_tempfunction sun50i_h5_calc_tempfunction sun8i_ths_get_tempfunction sun8i_h3_irq_ackfunction sun50i_h6_irq_ackfunction sun8i_irq_threadfunction for_each_set_bitfunction sun8i_h3_ths_calibratefunction sun50i_h6_ths_calibratefunction sun8i_ths_calibratefunction sun8i_ths_reset_control_assertfunction sun8i_ths_resource_initfunction sun8i_h3_thermal_initfunction sun50i_h6_thermal_initfunction sun8i_ths_registerfunction deferralfunction sun8i_ths_probe
Annotated Snippet
struct tsensor {
struct ths_device *tmdev;
struct thermal_zone_device *tzd;
int id;
};
struct ths_thermal_chip {
bool has_mod_clk;
bool has_bus_clk_reset;
bool needs_sram;
int sensor_num;
int offset;
int scale;
int ft_deviation;
int temp_data_base;
int (*calibrate)(struct ths_device *tmdev,
u16 *caldata, int callen);
int (*init)(struct ths_device *tmdev);
unsigned long (*irq_ack)(struct ths_device *tmdev);
int (*calc_temp)(struct ths_device *tmdev,
int id, int reg);
};
struct ths_device {
const struct ths_thermal_chip *chip;
struct device *dev;
struct regmap *regmap;
struct regmap_field *sram_regmap_field;
struct reset_control *reset;
struct clk *bus_clk;
struct clk *mod_clk;
struct tsensor sensor[MAX_SENSOR_NUM];
};
/* The H616 needs to have a bit 16 in the SRAM control register cleared. */
static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16);
/* Temp Unit: millidegree Celsius */
static int sun8i_ths_calc_temp(struct ths_device *tmdev,
int id, int reg)
{
return tmdev->chip->offset - (reg * tmdev->chip->scale / 10);
}
static int sun50i_h5_calc_temp(struct ths_device *tmdev,
int id, int reg)
{
if (reg >= 0x500)
return -1191 * reg / 10 + 223000;
else if (!id)
return -1452 * reg / 10 + 259000;
else
return -1590 * reg / 10 + 276000;
}
static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct tsensor *s = thermal_zone_device_priv(tz);
struct ths_device *tmdev = s->tmdev;
int val = 0;
regmap_read(tmdev->regmap, tmdev->chip->temp_data_base +
0x4 * s->id, &val);
/* ths have no data yet */
if (!val)
return -EAGAIN;
*temp = tmdev->chip->calc_temp(tmdev, s->id, val);
/*
* According to the original sdk, there are some platforms(rarely)
* that add a fixed offset value after calculating the temperature
* value. We can't simply put it on the formula for calculating the
* temperature above, because the formula for calculating the
* temperature above is also used when the sensor is calibrated. If
* do this, the correct calibration formula is hard to know.
*/
*temp += tmdev->chip->ft_deviation;
return 0;
}
static const struct thermal_zone_device_ops ths_ops = {
.get_temp = sun8i_ths_get_temp,
};
static const struct regmap_config config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
Annotation
- Immediate include surface: `linux/bitmap.h`, `linux/cleanup.h`, `linux/clk.h`, `linux/device.h`, `linux/interrupt.h`, `linux/module.h`, `linux/nvmem-consumer.h`, `linux/of.h`.
- Detected declarations: `struct tsensor`, `struct ths_thermal_chip`, `struct ths_device`, `function sun8i_ths_calc_temp`, `function sun50i_h5_calc_temp`, `function sun8i_ths_get_temp`, `function sun8i_h3_irq_ack`, `function sun50i_h6_irq_ack`, `function sun8i_irq_thread`, `function for_each_set_bit`.
- Atlas domain: Driver Families / drivers/thermal.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.