sound/ac97/bus.c

Source file repositories/reference/linux-study-clean/sound/ac97/bus.c

File Facts

System
Linux kernel
Corpus path
sound/ac97/bus.c
Extension
.c
Size
12576 bytes
Lines
527
Domain
Driver Families
Bucket
sound/ac97
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static int ac97_bus_match(struct device *dev, const struct device_driver *drv)
{
	struct ac97_codec_device *adev = to_ac97_device(dev);
	const struct ac97_codec_driver *adrv = to_ac97_driver(drv);
	const struct ac97_id *id = adrv->id_table;
	int i = 0;

	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
		return false;

	do {
		if (ac97_ids_match(id[i].id, adev->vendor_id, id[i].mask))
			return true;
	} while (id[i++].id);

	return false;
}

static int ac97_bus_probe(struct device *dev)
{
	struct ac97_codec_device *adev = to_ac97_device(dev);
	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
	int ret;

	ret = ac97_get_enable_clk(adev);
	if (ret)
		return ret;

	pm_runtime_get_noresume(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	ret = adrv->probe(adev);
	if (ret == 0)
		return 0;

	pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	pm_runtime_put_noidle(dev);
	ac97_put_disable_clk(adev);

	return ret;
}

static void ac97_bus_remove(struct device *dev)
{
	struct ac97_codec_device *adev = to_ac97_device(dev);
	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
	int ret;

	ret = pm_runtime_resume_and_get(dev);
	if (ret < 0)
		return;

	adrv->remove(adev);
	pm_runtime_put_noidle(dev);
	ac97_put_disable_clk(adev);

	pm_runtime_disable(dev);
}

const struct bus_type ac97_bus_type = {
	.name		= "ac97bus",
	.dev_groups	= ac97_dev_groups,
	.match		= ac97_bus_match,
	.pm		= pm_ptr(&ac97_pm),
	.probe		= ac97_bus_probe,
	.remove		= ac97_bus_remove,
};

static int __init ac97_bus_init(void)
{
	return bus_register(&ac97_bus_type);
}
subsys_initcall(ac97_bus_init);

static void __exit ac97_bus_exit(void)
{
	bus_unregister(&ac97_bus_type);
}
module_exit(ac97_bus_exit);

MODULE_DESCRIPTION("AC97 bus interface");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");

Annotation

Implementation Notes