drivers/bus/fsl-mc/fsl-mc-bus.c
Source file repositories/reference/linux-study-clean/drivers/bus/fsl-mc/fsl-mc-bus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/bus/fsl-mc/fsl-mc-bus.c- Extension
.c- Size
- 32779 bytes
- Lines
- 1299
- Domain
- Driver Families
- Bucket
- drivers/bus
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/module.hlinux/of_device.hlinux/of_address.hlinux/ioport.hlinux/platform_device.hlinux/slab.hlinux/limits.hlinux/bitops.hlinux/dma-mapping.hlinux/acpi.hlinux/iommu.hlinux/dma-map-ops.hfsl-mc-private.h
Detected Declarations
struct fsl_mcstruct fsl_mc_addr_translation_rangefunction fsl_mc_bus_matchfunction fsl_mc_bus_ueventfunction fsl_mc_probefunction fsl_mc_removefunction fsl_mc_shutdownfunction fsl_mc_dma_configurefunction fsl_mc_dma_cleanupfunction modalias_showfunction scan_fsl_mc_busfunction rescan_storefunction fsl_mc_bus_set_autorescanfunction fsl_mc_bus_get_autorescanfunction autorescan_storefunction autorescan_showfunction module_fsl_mc_driverfunction fsl_mc_driver_unregisterfunction mc_get_versionfunction fsl_mc_get_root_dprcfunction get_dprc_attrfunction get_dprc_icidfunction translate_mc_addrfunction fsl_mc_device_get_mmio_regionsfunction fsl_mc_is_root_dprcfunction fsl_mc_device_releasefunction fsl_mc_device_addfunction get_dprc_icidfunction fsl_mc_device_removefunction get_mc_addr_translation_rangesfunction fsl_mc_read_gsrfunction fsl_mc_firmware_checkfunction fsl_mc_bus_probefunction fsl_mc_bus_removefunction fsl_mc_bus_notifierfunction fsl_mc_bus_driver_initexport fsl_mc_bus_typeexport fsl_mc_bus_dprc_typeexport fsl_mc_bus_dpni_typeexport fsl_mc_bus_dpio_typeexport fsl_mc_bus_dpsw_typeexport fsl_mc_bus_dpbp_typeexport fsl_mc_bus_dpcon_typeexport fsl_mc_bus_dpmcp_typeexport fsl_mc_bus_dpmac_typeexport fsl_mc_bus_dprtc_typeexport fsl_mc_bus_dpseci_typeexport fsl_mc_bus_dpdmux_type
Annotated Snippet
static int fsl_mc_bus_match(struct device *dev, const struct device_driver *drv)
{
const struct fsl_mc_device_id *id;
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
const struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
bool found = false;
int ret;
/* When driver_override is set, only bind to the matching driver */
ret = device_match_driver_override(dev, drv);
if (ret > 0) {
found = true;
goto out;
}
if (ret == 0)
goto out;
if (!mc_drv->match_id_table)
goto out;
/*
* If the object is not 'plugged' don't match.
* Only exception is the root DPRC, which is a special case.
*/
if ((mc_dev->obj_desc.state & FSL_MC_OBJ_STATE_PLUGGED) == 0 &&
!fsl_mc_is_root_dprc(&mc_dev->dev))
goto out;
/*
* Traverse the match_id table of the given driver, trying to find
* a matching for the given device.
*/
for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) {
if (id->vendor == mc_dev->obj_desc.vendor &&
strcmp(id->obj_type, mc_dev->obj_desc.type) == 0) {
found = true;
break;
}
}
out:
dev_dbg(dev, "%smatched\n", found ? "" : "not ");
return found;
}
/*
* fsl_mc_bus_uevent - callback invoked when a device is added
*/
static int fsl_mc_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
if (add_uevent_var(env, "MODALIAS=fsl-mc:v%08Xd%s",
mc_dev->obj_desc.vendor,
mc_dev->obj_desc.type))
return -ENOMEM;
return 0;
}
static int fsl_mc_probe(struct device *dev)
{
struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
if (mc_drv->probe)
return mc_drv->probe(mc_dev);
return 0;
}
static void fsl_mc_remove(struct device *dev)
{
struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
if (mc_drv->remove)
mc_drv->remove(mc_dev);
}
static void fsl_mc_shutdown(struct device *dev)
{
struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
if (dev->driver && mc_drv->shutdown)
mc_drv->shutdown(mc_dev);
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/of_device.h`, `linux/of_address.h`, `linux/ioport.h`, `linux/platform_device.h`, `linux/slab.h`, `linux/limits.h`, `linux/bitops.h`.
- Detected declarations: `struct fsl_mc`, `struct fsl_mc_addr_translation_range`, `function fsl_mc_bus_match`, `function fsl_mc_bus_uevent`, `function fsl_mc_probe`, `function fsl_mc_remove`, `function fsl_mc_shutdown`, `function fsl_mc_dma_configure`, `function fsl_mc_dma_cleanup`, `function modalias_show`.
- Atlas domain: Driver Families / drivers/bus.
- Implementation status: pattern 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.