drivers/interconnect/icc-clk.c
Source file repositories/reference/linux-study-clean/drivers/interconnect/icc-clk.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/interconnect/icc-clk.c- Extension
.c- Size
- 4823 bytes
- Lines
- 204
- Domain
- Driver Families
- Bucket
- drivers/interconnect
- 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.
- 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/clk.hlinux/device.hlinux/interconnect-clk.hlinux/interconnect-provider.h
Detected Declarations
struct icc_clk_nodestruct icc_clk_providerfunction icc_clk_setfunction icc_clk_get_bwfunction icc_clk_registerfunction devm_icc_releasefunction devm_icc_clk_registerfunction icc_clk_unregisterexport icc_clk_registerexport devm_icc_clk_registerexport icc_clk_unregister
Annotated Snippet
struct icc_clk_node {
struct clk *clk;
bool enabled;
};
struct icc_clk_provider {
struct icc_provider provider;
int num_clocks;
struct icc_clk_node clocks[] __counted_by(num_clocks);
};
#define to_icc_clk_provider(_provider) \
container_of(_provider, struct icc_clk_provider, provider)
static int icc_clk_set(struct icc_node *src, struct icc_node *dst)
{
struct icc_clk_node *qn = src->data;
int ret;
if (!qn || !qn->clk)
return 0;
if (!src->peak_bw) {
if (qn->enabled)
clk_disable_unprepare(qn->clk);
qn->enabled = false;
return 0;
}
if (!qn->enabled) {
ret = clk_prepare_enable(qn->clk);
if (ret)
return ret;
qn->enabled = true;
}
return clk_set_rate(qn->clk, icc_units_to_bps(src->peak_bw));
}
static int icc_clk_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
{
struct icc_clk_node *qn = node->data;
if (!qn || !qn->clk)
*peak = INT_MAX;
else
*peak = Bps_to_icc(clk_get_rate(qn->clk));
return 0;
}
/**
* icc_clk_register() - register a new clk-based interconnect provider
* @dev: device supporting this provider
* @first_id: an ID of the first provider's node
* @num_clocks: number of instances of struct icc_clk_data
* @data: data for the provider
*
* Registers and returns a clk-based interconnect provider. It is a simple
* wrapper around COMMON_CLK framework, allowing other devices to vote on the
* clock rate.
*
* Return: 0 on success, or an error code otherwise
*/
struct icc_provider *icc_clk_register(struct device *dev,
unsigned int first_id,
unsigned int num_clocks,
const struct icc_clk_data *data)
{
struct icc_clk_provider *qp;
struct icc_provider *provider;
struct icc_onecell_data *onecell;
struct icc_node *node;
int ret, i, j;
onecell = devm_kzalloc(dev, struct_size(onecell, nodes, 2 * num_clocks), GFP_KERNEL);
if (!onecell)
return ERR_PTR(-ENOMEM);
onecell->num_nodes = 2 * num_clocks;
qp = devm_kzalloc(dev, struct_size(qp, clocks, num_clocks), GFP_KERNEL);
if (!qp)
return ERR_PTR(-ENOMEM);
qp->num_clocks = num_clocks;
provider = &qp->provider;
provider->dev = dev;
provider->get_bw = icc_clk_get_bw;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/device.h`, `linux/interconnect-clk.h`, `linux/interconnect-provider.h`.
- Detected declarations: `struct icc_clk_node`, `struct icc_clk_provider`, `function icc_clk_set`, `function icc_clk_get_bw`, `function icc_clk_register`, `function devm_icc_release`, `function devm_icc_clk_register`, `function icc_clk_unregister`, `export icc_clk_register`, `export devm_icc_clk_register`.
- Atlas domain: Driver Families / drivers/interconnect.
- Implementation status: integration implementation candidate.
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.