drivers/firmware/arm_scmi/bus.c
Source file repositories/reference/linux-study-clean/drivers/firmware/arm_scmi/bus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/firmware/arm_scmi/bus.c- Extension
.c- Size
- 16877 bytes
- Lines
- 613
- Domain
- Driver Families
- Bucket
- drivers/firmware
- 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/atomic.hlinux/types.hlinux/module.hlinux/of.hlinux/kernel.hlinux/slab.hlinux/device.hcommon.h
Detected Declarations
struct scmi_requested_devfunction scmi_protocol_device_requestfunction list_for_each_entryfunction scmi_protocol_table_registerfunction scmi_protocol_device_unrequestfunction list_for_each_entry_safefunction scmi_protocol_table_unregisterfunction scmi_dev_match_by_id_tablefunction scmi_dev_match_idfunction scmi_dev_matchfunction scmi_match_by_id_tablefunction scmi_dev_probefunction scmi_dev_removefunction scmi_device_ueventfunction modalias_showfunction protocol_id_showfunction name_showfunction scmi_pm_suspendfunction scmi_pm_resumefunction scmi_driver_registerfunction scmi_driver_unregisterfunction scmi_device_releasefunction __scmi_device_destroyfunction __scmi_device_createfunction instancesfunction _scmi_device_createfunction scmi_device_destroyfunction __scmi_devices_unregisterfunction scmi_devices_unregisterfunction scmi_bus_initfunction scmi_bus_exitmodule init scmi_bus_initexport scmi_requested_devices_nhexport scmi_bus_typeexport scmi_driver_registerexport scmi_driver_unregisterexport scmi_device_createexport scmi_device_destroy
Annotated Snippet
static int scmi_dev_match(struct device *dev, const struct device_driver *drv)
{
const struct scmi_driver *scmi_drv = to_scmi_driver(drv);
struct scmi_device *scmi_dev = to_scmi_dev(dev);
return scmi_dev_match_id(scmi_dev, scmi_drv);
}
static int scmi_match_by_id_table(struct device *dev, const void *data)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
const struct scmi_device_id *id_table = data;
return scmi_dev_match_by_id_table(scmi_dev, id_table);
}
static struct scmi_device *scmi_child_dev_find(struct device *parent,
int prot_id, const char *name)
{
struct scmi_device_id id_table[2] = { 0 };
struct device *dev;
id_table[0].protocol_id = prot_id;
id_table[0].name = name;
dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
if (!dev)
return NULL;
/* Drop the refcnt bumped implicitly by device_find_child */
put_device(dev);
return to_scmi_dev(dev);
}
static int scmi_dev_probe(struct device *dev)
{
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
struct scmi_device *scmi_dev = to_scmi_dev(dev);
if (!scmi_dev->handle)
return -EPROBE_DEFER;
return scmi_drv->probe(scmi_dev);
}
static void scmi_dev_remove(struct device *dev)
{
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
struct scmi_device *scmi_dev = to_scmi_dev(dev);
if (scmi_drv->remove)
scmi_drv->remove(scmi_dev);
}
static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct scmi_device *scmi_dev = to_scmi_dev(dev);
return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
scmi_dev->name);
}
static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT,
dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
scmi_dev->name);
}
static DEVICE_ATTR_RO(modalias);
static ssize_t protocol_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
return sprintf(buf, "0x%02x\n", scmi_dev->protocol_id);
}
static DEVICE_ATTR_RO(protocol_id);
static ssize_t name_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
return sprintf(buf, "%s\n", scmi_dev->name);
Annotation
- Immediate include surface: `linux/atomic.h`, `linux/types.h`, `linux/module.h`, `linux/of.h`, `linux/kernel.h`, `linux/slab.h`, `linux/device.h`, `common.h`.
- Detected declarations: `struct scmi_requested_dev`, `function scmi_protocol_device_request`, `function list_for_each_entry`, `function scmi_protocol_table_register`, `function scmi_protocol_device_unrequest`, `function list_for_each_entry_safe`, `function scmi_protocol_table_unregister`, `function scmi_dev_match_by_id_table`, `function scmi_dev_match_id`, `function scmi_dev_match`.
- Atlas domain: Driver Families / drivers/firmware.
- 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.