Commit 9f5f30e7 authored by Viresh Kumar's avatar Viresh Kumar Committed by Greg Kroah-Hartman
Browse files

greybus: driver corresponds to a bundle, not interface



A Greybus driver will bind to a bundle, not an interface. Lets follow
this rule in code.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 8e2e22d7
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -22,8 +22,18 @@ static ssize_t device_id_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(device_id);

static ssize_t class_type_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	struct gb_bundle *bundle = to_gb_bundle(dev);

	return sprintf(buf, "%d\n", bundle->class_type);
}
static DEVICE_ATTR_RO(class_type);

static struct attribute *bundle_attrs[] = {
	&dev_attr_device_id.attr,
	&dev_attr_class_type.attr,
	NULL,
};

@@ -41,6 +51,44 @@ struct device_type greybus_bundle_type = {
	.release =	gb_bundle_release,
};

static int gb_bundle_match_one_id(struct gb_bundle *bundle,
				     const struct greybus_bundle_id *id)
{
	if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) &&
	    (id->vendor != bundle->intf->vendor))
		return 0;

	if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) &&
	    (id->product != bundle->intf->product))
		return 0;

	if ((id->match_flags & GREYBUS_ID_MATCH_SERIAL) &&
	    (id->unique_id != bundle->intf->unique_id))
		return 0;

	if ((id->match_flags & GREYBUS_ID_MATCH_CLASS_TYPE) &&
	    (id->class_type != bundle->class_type))
		return 0;

	return 1;
}

const struct greybus_bundle_id *
gb_bundle_match_id(struct gb_bundle *bundle,
		   const struct greybus_bundle_id *id)
{
	if (id == NULL)
		return NULL;

	for (; id->vendor || id->product || id->unique_id || id->class_type ||
	       id->driver_info; id++) {
		if (gb_bundle_match_one_id(bundle, id))
			return id;
	}

	return NULL;
}


/* XXX This could be per-host device or per-module */
static DEFINE_SPINLOCK(gb_bundles_lock);
+4 −0
Original line number Diff line number Diff line
@@ -37,4 +37,8 @@ int gb_bundles_init(struct gb_interface *intf, u8 device_id);
struct gb_bundle *gb_bundle_find(struct gb_interface *intf, u8 bundle_id);
void gb_bundle_bind_protocols(void);

const struct greybus_bundle_id *
	gb_bundle_match_id(struct gb_bundle *bundle,
			   const struct greybus_bundle_id *id);

#endif /* __BUNDLE_H */
+9 −9
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ EXPORT_SYMBOL_GPL(greybus_disabled);
static int greybus_module_match(struct device *dev, struct device_driver *drv)
{
	struct greybus_driver *driver = to_greybus_driver(drv);
	struct gb_interface *intf = to_gb_interface(dev);
	const struct greybus_interface_id *id;
	struct gb_bundle *bundle = to_gb_bundle(dev);
	const struct greybus_bundle_id *id;

	id = gb_interface_match_id(intf, driver->id_table);
	id = gb_bundle_match_id(bundle, driver->id_table);
	if (id)
		return 1;
	/* FIXME - Dynamic ids? */
@@ -97,16 +97,16 @@ struct bus_type greybus_bus_type = {
static int greybus_probe(struct device *dev)
{
	struct greybus_driver *driver = to_greybus_driver(dev->driver);
	struct gb_interface *intf = to_gb_interface(dev);
	const struct greybus_interface_id *id;
	struct gb_bundle *bundle = to_gb_bundle(dev);
	const struct greybus_bundle_id *id;
	int retval;

	/* match id */
	id = gb_interface_match_id(intf, driver->id_table);
	id = gb_bundle_match_id(bundle, driver->id_table);
	if (!id)
		return -ENODEV;

	retval = driver->probe(intf, id);
	retval = driver->probe(bundle, id);
	if (retval)
		return retval;

@@ -116,9 +116,9 @@ static int greybus_probe(struct device *dev)
static int greybus_remove(struct device *dev)
{
	struct greybus_driver *driver = to_greybus_driver(dev->driver);
	struct gb_interface *intf = to_gb_interface(dev);
	struct gb_bundle *bundle = to_gb_bundle(dev);

	driver->disconnect(intf);
	driver->disconnect(bundle);
	return 0;
}

+6 −6
Original line number Diff line number Diff line
@@ -120,14 +120,14 @@ void greybus_remove_hd(struct greybus_host_device *hd);
struct greybus_driver {
	const char *name;

	int (*probe)(struct gb_interface *intf,
		     const struct greybus_interface_id *id);
	void (*disconnect)(struct gb_interface *intf);
	int (*probe)(struct gb_bundle *bundle,
		     const struct greybus_bundle_id *id);
	void (*disconnect)(struct gb_bundle *bundle);

	int (*suspend)(struct gb_interface *intf, pm_message_t message);
	int (*resume)(struct gb_interface *intf);
	int (*suspend)(struct gb_bundle *bundle, pm_message_t message);
	int (*resume)(struct gb_bundle *bundle);

	const struct greybus_interface_id *id_table;
	const struct greybus_bundle_id *id_table;

	struct device_driver driver;
};
+4 −2
Original line number Diff line number Diff line
@@ -9,18 +9,20 @@
#include <linux/mod_devicetable.h>


struct greybus_interface_id {
struct greybus_bundle_id {
	__u16	match_flags;
	__u16	vendor;
	__u16	product;
	__u8	class_type;
	__u64	unique_id;

	kernel_ulong_t	driver_info __aligned(sizeof(kernel_ulong_t));
};

/* Used to match the greybus_interface_id */
/* Used to match the greybus_bundle_id */
#define GREYBUS_ID_MATCH_VENDOR		BIT(0)
#define GREYBUS_ID_MATCH_PRODUCT	BIT(1)
#define GREYBUS_ID_MATCH_SERIAL		BIT(2)
#define GREYBUS_ID_MATCH_CLASS_TYPE	BIT(3)

#endif /* __LINUX_GREYBUS_ID_H */
Loading