}
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,
};
.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);
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 */
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? */
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;
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;
}
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;
};
#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 */
/* XXX This could be per-host device */
static DEFINE_SPINLOCK(gb_interfaces_lock);
-static int gb_interface_match_one_id(struct gb_interface *intf,
- const struct greybus_interface_id *id)
-{
- if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) &&
- (id->vendor != intf->vendor))
- return 0;
-
- if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) &&
- (id->product != intf->product))
- return 0;
-
- if ((id->match_flags & GREYBUS_ID_MATCH_SERIAL) &&
- (id->unique_id != intf->unique_id))
- return 0;
-
- return 1;
-}
-
-const struct greybus_interface_id *
-gb_interface_match_id(struct gb_interface *intf,
- const struct greybus_interface_id *id)
-{
- if (id == NULL)
- return NULL;
-
- for (; id->vendor || id->product || id->unique_id ||
- id->driver_info; id++) {
- if (gb_interface_match_one_id(intf, id))
- return id;
- }
-
- return NULL;
-}
-
// FIXME, odds are you don't want to call this function, rework the caller to
// not need it please.
struct gb_interface *gb_interface_find(struct greybus_host_device *hd,
/* Greybus "private" definitions */
-const struct greybus_interface_id *
- gb_interface_match_id(struct gb_interface *intf,
- const struct greybus_interface_id *id);
-
struct gb_interface *gb_interface_find(struct greybus_host_device *hd,
u8 interface_id);