drivers/thermal/db8500_thermal.c
Source file repositories/reference/linux-study-clean/drivers/thermal/db8500_thermal.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thermal/db8500_thermal.c- Extension
.c- Size
- 6075 bytes
- Lines
- 244
- 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/cpu_cooling.hlinux/interrupt.hlinux/mfd/dbx500-prcmu.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/slab.hlinux/thermal.h
Detected Declarations
struct db8500_thermal_zonefunction db8500_thermal_get_tempfunction db8500_thermal_update_configfunction prcmu_low_irq_handlerfunction prcmu_high_irq_handlerfunction db8500_thermal_probefunction db8500_thermal_suspendfunction db8500_thermal_resume
Annotated Snippet
struct db8500_thermal_zone {
struct thermal_zone_device *tz;
struct device *dev;
unsigned long interpolated_temp;
unsigned int cur_index;
};
/* Callback to get current temperature */
static int db8500_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct db8500_thermal_zone *th = thermal_zone_device_priv(tz);
/*
* TODO: There is no PRCMU interface to get temperature data currently,
* so a pseudo temperature is returned , it works for thermal framework
* and this will be fixed when the PRCMU interface is available.
*/
*temp = th->interpolated_temp;
return 0;
}
static const struct thermal_zone_device_ops thdev_ops = {
.get_temp = db8500_thermal_get_temp,
};
static void db8500_thermal_update_config(struct db8500_thermal_zone *th,
unsigned int idx,
unsigned long next_low,
unsigned long next_high)
{
prcmu_stop_temp_sense();
th->cur_index = idx;
th->interpolated_temp = (next_low + next_high)/2;
/*
* The PRCMU accept absolute temperatures in celsius so divide
* down the millicelsius with 1000
*/
prcmu_config_hotmon((u8)(next_low/1000), (u8)(next_high/1000));
prcmu_start_temp_sense(PRCMU_DEFAULT_MEASURE_TIME);
}
static irqreturn_t prcmu_low_irq_handler(int irq, void *irq_data)
{
struct db8500_thermal_zone *th = irq_data;
unsigned int idx = th->cur_index;
unsigned long next_low, next_high;
if (idx == 0)
/* Meaningless for thermal management, ignoring it */
return IRQ_HANDLED;
if (idx == 1) {
next_high = db8500_thermal_points[0];
next_low = PRCMU_DEFAULT_LOW_TEMP;
} else {
next_high = db8500_thermal_points[idx - 1];
next_low = db8500_thermal_points[idx - 2];
}
idx -= 1;
db8500_thermal_update_config(th, idx, next_low, next_high);
dev_dbg(th->dev,
"PRCMU set max %ld, min %ld\n", next_high, next_low);
thermal_zone_device_update(th->tz, THERMAL_EVENT_UNSPECIFIED);
return IRQ_HANDLED;
}
static irqreturn_t prcmu_high_irq_handler(int irq, void *irq_data)
{
struct db8500_thermal_zone *th = irq_data;
unsigned int idx = th->cur_index;
unsigned long next_low, next_high;
int num_points = ARRAY_SIZE(db8500_thermal_points);
if (idx < num_points - 1) {
next_high = db8500_thermal_points[idx+1];
next_low = db8500_thermal_points[idx];
idx += 1;
db8500_thermal_update_config(th, idx, next_low, next_high);
dev_dbg(th->dev,
"PRCMU set max %ld, min %ld\n", next_high, next_low);
} else if (idx == num_points - 1)
/* So we roof out 1 degree over the max point */
Annotation
- Immediate include surface: `linux/cpu_cooling.h`, `linux/interrupt.h`, `linux/mfd/dbx500-prcmu.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/slab.h`, `linux/thermal.h`.
- Detected declarations: `struct db8500_thermal_zone`, `function db8500_thermal_get_temp`, `function db8500_thermal_update_config`, `function prcmu_low_irq_handler`, `function prcmu_high_irq_handler`, `function db8500_thermal_probe`, `function db8500_thermal_suspend`, `function db8500_thermal_resume`.
- 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.