drivers/staging/greybus/gbphy.c

Source file repositories/reference/linux-study-clean/drivers/staging/greybus/gbphy.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/greybus/gbphy.c
Extension
.c
Size
8571 bytes
Lines
359
Domain
Driver Families
Bucket
drivers/staging
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 gbphy_dev_match(struct device *dev, const struct device_driver *drv)
{
	const struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv);
	struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
	const struct gbphy_device_id *id;

	id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
	if (id)
		return 1;

	return 0;
}

static int gbphy_dev_probe(struct device *dev)
{
	struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
	struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
	const struct gbphy_device_id *id;
	int ret;

	id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
	if (!id)
		return -ENODEV;

	/* for old kernels we need get_sync to resume parent devices */
	ret = gb_pm_runtime_get_sync(gbphy_dev->bundle);
	if (ret < 0)
		return ret;

	pm_runtime_set_autosuspend_delay(dev, GB_GBPHY_AUTOSUSPEND_MS);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_get_noresume(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	/*
	 * Drivers should call put on the gbphy dev before returning
	 * from probe if they support runtime pm.
	 */
	ret = gbphy_drv->probe(gbphy_dev, id);
	if (ret) {
		pm_runtime_disable(dev);
		pm_runtime_set_suspended(dev);
		pm_runtime_put_noidle(dev);
		pm_runtime_dont_use_autosuspend(dev);
	}

	gb_pm_runtime_put_autosuspend(gbphy_dev->bundle);

	return ret;
}

static void gbphy_dev_remove(struct device *dev)
{
	struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
	struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);

	gbphy_drv->remove(gbphy_dev);

	pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	pm_runtime_put_noidle(dev);
	pm_runtime_dont_use_autosuspend(dev);
}

static const struct bus_type gbphy_bus_type = {
	.name =		"gbphy",
	.match =	gbphy_dev_match,
	.probe =	gbphy_dev_probe,
	.remove =	gbphy_dev_remove,
	.uevent =	gbphy_dev_uevent,
};

int gb_gbphy_register_driver(struct gbphy_driver *driver,
			     struct module *owner, const char *mod_name)
{
	int retval;

	if (greybus_disabled())
		return -ENODEV;

	driver->driver.bus = &gbphy_bus_type;
	driver->driver.name = driver->name;
	driver->driver.owner = owner;
	driver->driver.mod_name = mod_name;

	retval = driver_register(&driver->driver);
	if (retval)
		return retval;

Annotation

Implementation Notes