drivers/interconnect/imx/imx.c
Source file repositories/reference/linux-study-clean/drivers/interconnect/imx/imx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/interconnect/imx/imx.c- Extension
.c- Size
- 8920 bytes
- Lines
- 339
- 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/device.hlinux/interconnect-provider.hlinux/io.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/pm_qos.himx.h
Detected Declarations
struct imx_icc_nodefunction imx_icc_get_bwfunction imx_icc_node_setfunction imx_icc_setfunction imx_icc_node_destroyfunction imx_icc_node_init_qosfunction imx_icc_unregister_nodesfunction imx_icc_register_nodesfunction get_max_node_idfunction imx_icc_registerfunction imx_icc_unregisterexport imx_icc_registerexport imx_icc_unregister
Annotated Snippet
struct imx_icc_node {
const struct imx_icc_node_desc *desc;
const struct imx_icc_noc_setting *setting;
struct device *qos_dev;
struct dev_pm_qos_request qos_req;
struct imx_icc_provider *imx_provider;
};
static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
{
*avg = 0;
*peak = 0;
return 0;
}
static int imx_icc_node_set(struct icc_node *node)
{
struct device *dev = node->provider->dev;
struct imx_icc_node *node_data = node->data;
void __iomem *base;
u32 prio;
u64 freq;
if (node_data->setting && node->peak_bw) {
base = node_data->setting->reg + node_data->imx_provider->noc_base;
if (node_data->setting->mode == IMX_NOC_MODE_FIXED) {
prio = node_data->setting->prio_level;
prio = PRIORITY_COMP_MARK | (prio << 8) | prio;
writel(prio, base + IMX_NOC_PRIO_REG);
writel(node_data->setting->mode, base + IMX_NOC_MODE_REG);
writel(node_data->setting->ext_control, base + IMX_NOC_EXT_CTL_REG);
dev_dbg(dev, "%s: mode: 0x%x, prio: 0x%x, ext_control: 0x%x\n",
node_data->desc->name, node_data->setting->mode, prio,
node_data->setting->ext_control);
} else if (node_data->setting->mode == IMX_NOC_MODE_UNCONFIGURED) {
dev_dbg(dev, "%s: mode not unconfigured\n", node_data->desc->name);
} else {
dev_info(dev, "%s: mode: %d not supported\n",
node_data->desc->name, node_data->setting->mode);
return -EOPNOTSUPP;
}
}
if (!node_data->qos_dev)
return 0;
freq = (node->avg_bw + node->peak_bw) * node_data->desc->adj->bw_mul;
do_div(freq, node_data->desc->adj->bw_div);
dev_dbg(dev, "node %s device %s avg_bw %ukBps peak_bw %ukBps min_freq %llukHz\n",
node->name, dev_name(node_data->qos_dev),
node->avg_bw, node->peak_bw, freq);
if (freq > S32_MAX) {
dev_err(dev, "%s can't request more than S32_MAX freq\n",
node->name);
return -ERANGE;
}
dev_pm_qos_update_request(&node_data->qos_req, freq);
return 0;
}
static int imx_icc_set(struct icc_node *src, struct icc_node *dst)
{
int ret;
ret = imx_icc_node_set(src);
if (ret)
return ret;
return imx_icc_node_set(dst);
}
/* imx_icc_node_destroy() - Destroy an imx icc_node, including private data */
static void imx_icc_node_destroy(struct icc_node *node)
{
struct imx_icc_node *node_data = node->data;
int ret;
if (dev_pm_qos_request_active(&node_data->qos_req)) {
ret = dev_pm_qos_remove_request(&node_data->qos_req);
if (ret)
dev_warn(node->provider->dev,
"failed to remove qos request for %s\n",
dev_name(node_data->qos_dev));
}
put_device(node_data->qos_dev);
Annotation
- Immediate include surface: `linux/device.h`, `linux/interconnect-provider.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/pm_qos.h`.
- Detected declarations: `struct imx_icc_node`, `function imx_icc_get_bw`, `function imx_icc_node_set`, `function imx_icc_set`, `function imx_icc_node_destroy`, `function imx_icc_node_init_qos`, `function imx_icc_unregister_nodes`, `function imx_icc_register_nodes`, `function get_max_node_id`, `function imx_icc_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.