drivers/of/device.c
Source file repositories/reference/linux-study-clean/drivers/of/device.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/of/device.c- Extension
.c- Size
- 8879 bytes
- Lines
- 316
- Domain
- Driver Families
- Bucket
- drivers/of
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/of.hlinux/of_device.hlinux/of_address.hlinux/of_iommu.hlinux/of_reserved_mem.hlinux/dma-direct.hlinux/dma-map-ops.hlinux/init.hlinux/mod_devicetable.hlinux/slab.hlinux/platform_device.hasm/errno.hof_private.h
Detected Declarations
function of_dma_set_restricted_bufferfunction of_for_each_phandlefunction of_dma_configure_idfunction of_device_modaliasfunction of_device_ueventfunction of_device_uevent_modaliasfunction of_device_make_bus_idexport of_match_deviceexport of_dma_configure_idexport of_device_get_match_dataexport of_device_modaliasexport of_device_ueventexport of_device_uevent_modaliasexport of_device_make_bus_id
Annotated Snippet
of_device_is_available(it.node)) {
if (of_reserved_mem_device_init_by_idx(dev, of_node, i))
dev_warn(dev, "failed to initialise \"restricted-dma-pool\" memory node\n");
of_node_put(it.node);
break;
}
i++;
}
}
/**
* of_dma_configure_id - Setup DMA configuration
* @dev: Device to apply DMA configuration
* @np: Pointer to OF node having DMA configuration
* @force_dma: Whether device is to be set up by of_dma_configure() even if
* DMA capability is not explicitly described by firmware.
* @id: Optional const pointer value input id
*
* Try to get devices's DMA configuration from DT and update it
* accordingly.
*
* If platform code needs to use its own special DMA configuration, it
* can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
* to fix up DMA configuration.
*/
int of_dma_configure_id(struct device *dev, struct device_node *np,
bool force_dma, const u32 *id)
{
const struct bus_dma_region *map = NULL;
struct device_node *bus_np;
u64 mask, end = 0;
bool coherent, set_map = false;
int ret;
if (dev->dma_range_map) {
dev_dbg(dev, "dma_range_map already set\n");
goto skip_map;
}
if (np == dev->of_node)
bus_np = __of_get_dma_parent(np);
else
bus_np = of_node_get(np);
ret = of_dma_get_range(bus_np, &map);
of_node_put(bus_np);
if (ret < 0) {
/*
* For legacy reasons, we have to assume some devices need
* DMA configuration regardless of whether "dma-ranges" is
* correctly specified or not.
*/
if (!force_dma)
return ret == -ENODEV ? 0 : ret;
} else {
/* Determine the overall bounds of all DMA regions */
end = dma_range_map_max(map);
set_map = true;
}
skip_map:
/*
* If @dev is expected to be DMA-capable then the bus code that created
* it should have initialised its dma_mask pointer by this point. For
* now, we'll continue the legacy behaviour of coercing it to the
* coherent mask if not, but we'll no longer do so quietly.
*/
if (!dev->dma_mask) {
dev_warn(dev, "DMA mask not set\n");
dev->dma_mask = &dev->coherent_dma_mask;
}
if (!end && dev->coherent_dma_mask)
end = dev->coherent_dma_mask;
else if (!end)
end = (1ULL << 32) - 1;
/*
* Limit coherent and dma mask based on size and default mask
* set by the driver.
*/
mask = DMA_BIT_MASK(ilog2(end) + 1);
dev->coherent_dma_mask &= mask;
*dev->dma_mask &= mask;
/* ...but only set bus limit and range map if we found valid dma-ranges earlier */
if (set_map) {
dev->bus_dma_limit = end;
dev->dma_range_map = map;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/of.h`, `linux/of_device.h`, `linux/of_address.h`, `linux/of_iommu.h`, `linux/of_reserved_mem.h`, `linux/dma-direct.h`, `linux/dma-map-ops.h`.
- Detected declarations: `function of_dma_set_restricted_buffer`, `function of_for_each_phandle`, `function of_dma_configure_id`, `function of_device_modalias`, `function of_device_uevent`, `function of_device_uevent_modalias`, `function of_device_make_bus_id`, `export of_match_device`, `export of_dma_configure_id`, `export of_device_get_match_data`.
- Atlas domain: Driver Families / drivers/of.
- 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.