drivers/powercap/dtpm.c
Source file repositories/reference/linux-study-clean/drivers/powercap/dtpm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/powercap/dtpm.c- Extension
.c- Size
- 15636 bytes
- Lines
- 648
- Domain
- Driver Families
- Bucket
- drivers/powercap
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/dtpm.hlinux/init.hlinux/kernel.hlinux/powercap.hlinux/slab.hlinux/mutex.hlinux/of.hdtpm_subsys.h
Detected Declarations
function get_time_window_usfunction set_time_window_usfunction get_max_power_range_uwfunction __get_power_uwfunction list_for_each_entryfunction get_power_uwfunction __dtpm_rebalance_weightfunction list_for_each_entryfunction __dtpm_sub_powerfunction __dtpm_add_powerfunction dtpm_update_powerfunction dtpm_release_zonefunction get_power_limit_uwfunction __set_power_limit_uwfunction list_for_each_entryfunction set_power_limit_uwfunction get_max_power_uwfunction dtpm_initfunction dtpm_unregisterfunction dtpm_registerfunction dtpm_for_each_childfunction dtpm_create_hierarchyfunction __dtpm_destroy_hierarchyfunction dtpm_destroy_hierarchyexport dtpm_create_hierarchyexport dtpm_destroy_hierarchy
Annotated Snippet
list_for_each_entry(child, &dtpm->children, sibling) {
/*
* Integer division rounding will inevitably
* lead to a different min or max value when
* set several times. In order to restore the
* initial value, we force the child's min or
* max power every time if the constraint is
* at the boundaries.
*/
if (power_limit == dtpm->power_max) {
power = child->power_max;
} else if (power_limit == dtpm->power_min) {
power = child->power_min;
} else {
power = DIV_ROUND_CLOSEST_ULL(
power_limit * child->weight, 1024);
}
pr_debug("Setting power limit for '%s': %llu uW\n",
child->zone.name, power);
ret = __set_power_limit_uw(child, cid, power);
if (!ret)
ret = get_power_limit_uw(&child->zone, cid, &power);
if (ret)
break;
dtpm->power_limit += power;
}
}
return ret;
}
static int set_power_limit_uw(struct powercap_zone *pcz,
int cid, u64 power_limit)
{
struct dtpm *dtpm = to_dtpm(pcz);
int ret;
/*
* Don't allow values outside of the power range previously
* set when initializing the power numbers.
*/
power_limit = clamp_val(power_limit, dtpm->power_min, dtpm->power_max);
ret = __set_power_limit_uw(dtpm, cid, power_limit);
pr_debug("%s: power limit: %llu uW, power max: %llu uW\n",
dtpm->zone.name, dtpm->power_limit, dtpm->power_max);
return ret;
}
static const char *get_constraint_name(struct powercap_zone *pcz, int cid)
{
return constraint_name[cid];
}
static int get_max_power_uw(struct powercap_zone *pcz, int id, u64 *max_power)
{
*max_power = to_dtpm(pcz)->power_max;
return 0;
}
static struct powercap_zone_constraint_ops constraint_ops = {
.set_power_limit_uw = set_power_limit_uw,
.get_power_limit_uw = get_power_limit_uw,
.set_time_window_us = set_time_window_us,
.get_time_window_us = get_time_window_us,
.get_max_power_uw = get_max_power_uw,
.get_name = get_constraint_name,
};
static struct powercap_zone_ops zone_ops = {
.get_max_power_range_uw = get_max_power_range_uw,
.get_power_uw = get_power_uw,
.release = dtpm_release_zone,
};
/**
* dtpm_init - Allocate and initialize a dtpm struct
* @dtpm: The dtpm struct pointer to be initialized
* @ops: The dtpm device specific ops, NULL for a virtual node
*/
void dtpm_init(struct dtpm *dtpm, struct dtpm_ops *ops)
{
Annotation
- Immediate include surface: `linux/dtpm.h`, `linux/init.h`, `linux/kernel.h`, `linux/powercap.h`, `linux/slab.h`, `linux/mutex.h`, `linux/of.h`, `dtpm_subsys.h`.
- Detected declarations: `function get_time_window_us`, `function set_time_window_us`, `function get_max_power_range_uw`, `function __get_power_uw`, `function list_for_each_entry`, `function get_power_uw`, `function __dtpm_rebalance_weight`, `function list_for_each_entry`, `function __dtpm_sub_power`, `function __dtpm_add_power`.
- Atlas domain: Driver Families / drivers/powercap.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.