drivers/soundwire/bus_type.c
Source file repositories/reference/linux-study-clean/drivers/soundwire/bus_type.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/soundwire/bus_type.c- Extension
.c- Size
- 5877 bytes
- Lines
- 247
- Domain
- Driver Families
- Bucket
- drivers/soundwire
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/mod_devicetable.hlinux/pm_domain.hlinux/soundwire/sdw.hlinux/soundwire/sdw_type.hbus.hirq.hsysfs_local.h
Detected Declarations
function sdw_get_device_idfunction sdw_bus_matchfunction sdw_slave_modaliasfunction sdw_slave_ueventfunction sdw_bus_probefunction sdw_bus_removefunction sdw_bus_shutdownfunction __sdw_register_driverfunction sdw_unregister_driverfunction sdw_bus_initfunction sdw_bus_exitexport sdw_bus_typeexport __sdw_register_driverexport sdw_unregister_driver
Annotated Snippet
static int sdw_bus_match(struct device *dev, const struct device_driver *ddrv)
{
struct sdw_slave *slave;
const struct sdw_driver *drv;
int ret = 0;
if (is_sdw_slave(dev)) {
slave = dev_to_sdw_dev(dev);
drv = drv_to_sdw_driver(ddrv);
ret = !!sdw_get_device_id(slave, drv);
}
return ret;
}
int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size)
{
/* modalias is sdw:m<mfg_id>p<part_id>v<version>c<class_id> */
return snprintf(buf, size, "sdw:m%04Xp%04Xv%02Xc%02X\n",
slave->id.mfg_id, slave->id.part_id,
slave->id.sdw_version, slave->id.class_id);
}
int sdw_slave_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct sdw_slave *slave = dev_to_sdw_dev(dev);
char modalias[32];
sdw_slave_modalias(slave, modalias, sizeof(modalias));
if (add_uevent_var(env, "MODALIAS=%s", modalias))
return -ENOMEM;
return 0;
}
static int sdw_bus_probe(struct device *dev)
{
struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
const struct sdw_device_id *id;
int ret;
/*
* fw description is mandatory to bind
*/
if (!dev->fwnode)
return -ENODEV;
if (!IS_ENABLED(CONFIG_ACPI) && !dev->of_node)
return -ENODEV;
id = sdw_get_device_id(slave, drv);
if (!id)
return -ENODEV;
/*
* attach to power domain but don't turn on (last arg)
*/
ret = dev_pm_domain_attach(dev, 0);
if (ret)
return ret;
ret = ida_alloc_max(&slave->bus->slave_ida, SDW_FW_MAX_DEVICES - 1, GFP_KERNEL);
if (ret < 0) {
dev_err(dev, "Failed to allocated ID: %d\n", ret);
return ret;
}
slave->index = ret;
ret = drv->probe(slave, id);
if (ret) {
ida_free(&slave->bus->slave_ida, slave->index);
return ret;
}
mutex_lock(&slave->sdw_dev_lock);
/* device is probed so let's read the properties now */
if (drv->ops && drv->ops->read_prop)
drv->ops->read_prop(slave);
if (slave->prop.use_domain_irq)
sdw_irq_create_mapping(slave);
/* init the dynamic sysfs attributes we need */
ret = sdw_slave_sysfs_dpn_init(slave);
if (ret < 0)
dev_warn(dev, "failed to initialise sysfs: %d\n", ret);
Annotation
- Immediate include surface: `linux/module.h`, `linux/mod_devicetable.h`, `linux/pm_domain.h`, `linux/soundwire/sdw.h`, `linux/soundwire/sdw_type.h`, `bus.h`, `irq.h`, `sysfs_local.h`.
- Detected declarations: `function sdw_get_device_id`, `function sdw_bus_match`, `function sdw_slave_modalias`, `function sdw_slave_uevent`, `function sdw_bus_probe`, `function sdw_bus_remove`, `function sdw_bus_shutdown`, `function __sdw_register_driver`, `function sdw_unregister_driver`, `function sdw_bus_init`.
- Atlas domain: Driver Families / drivers/soundwire.
- 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.