drivers/greybus/core.c

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

File Facts

System
Linux kernel
Corpus path
drivers/greybus/core.c
Extension
.c
Size
8856 bytes
Lines
379
Domain
Driver Families
Bucket
drivers/greybus
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 greybus_match_device(struct device *dev, const struct device_driver *drv)
{
	const struct greybus_driver *driver = to_greybus_driver(drv);
	struct gb_bundle *bundle;
	const struct greybus_bundle_id *id;

	if (!is_gb_bundle(dev))
		return 0;

	bundle = to_gb_bundle(dev);

	id = greybus_match_id(bundle, driver->id_table);
	if (id)
		return 1;
	/* FIXME - Dynamic ids? */
	return 0;
}

static int greybus_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
	const struct gb_host_device *hd;
	const struct gb_module *module = NULL;
	const struct gb_interface *intf = NULL;
	const struct gb_control *control = NULL;
	const struct gb_bundle *bundle = NULL;
	const struct gb_svc *svc = NULL;

	if (is_gb_host_device(dev)) {
		hd = to_gb_host_device(dev);
	} else if (is_gb_module(dev)) {
		module = to_gb_module(dev);
		hd = module->hd;
	} else if (is_gb_interface(dev)) {
		intf = to_gb_interface(dev);
		module = intf->module;
		hd = intf->hd;
	} else if (is_gb_control(dev)) {
		control = to_gb_control(dev);
		intf = control->intf;
		module = intf->module;
		hd = intf->hd;
	} else if (is_gb_bundle(dev)) {
		bundle = to_gb_bundle(dev);
		intf = bundle->intf;
		module = intf->module;
		hd = intf->hd;
	} else if (is_gb_svc(dev)) {
		svc = to_gb_svc(dev);
		hd = svc->hd;
	} else {
		dev_WARN(dev, "uevent for unknown greybus device \"type\"!\n");
		return -EINVAL;
	}

	if (add_uevent_var(env, "BUS=%u", hd->bus_id))
		return -ENOMEM;

	if (module) {
		if (add_uevent_var(env, "MODULE=%u", module->module_id))
			return -ENOMEM;
	}

	if (intf) {
		if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
			return -ENOMEM;
		if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
				   intf->vendor_id, intf->product_id))
			return -ENOMEM;
	}

	if (bundle) {
		// FIXME
		// add a uevent that can "load" a bundle type
		// This is what we need to bind a driver to so use the info
		// in gmod here as well

		if (add_uevent_var(env, "BUNDLE=%u", bundle->id))
			return -ENOMEM;
		if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
			return -ENOMEM;
	}

	return 0;
}

static void greybus_shutdown(struct device *dev)
{
	if (is_gb_host_device(dev)) {
		struct gb_host_device *hd;

Annotation

Implementation Notes