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: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
8e2e22d783
commit
9f5f30e712
|
@ -22,8 +22,18 @@ static ssize_t device_id_show(struct device *dev, struct device_attribute *attr,
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RO(device_id);
|
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[] = {
|
static struct attribute *bundle_attrs[] = {
|
||||||
&dev_attr_device_id.attr,
|
&dev_attr_device_id.attr,
|
||||||
|
&dev_attr_class_type.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,6 +51,44 @@ struct device_type greybus_bundle_type = {
|
||||||
.release = gb_bundle_release,
|
.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 */
|
/* XXX This could be per-host device or per-module */
|
||||||
static DEFINE_SPINLOCK(gb_bundles_lock);
|
static DEFINE_SPINLOCK(gb_bundles_lock);
|
||||||
|
|
|
@ -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);
|
struct gb_bundle *gb_bundle_find(struct gb_interface *intf, u8 bundle_id);
|
||||||
void gb_bundle_bind_protocols(void);
|
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 */
|
#endif /* __BUNDLE_H */
|
||||||
|
|
|
@ -34,10 +34,10 @@ EXPORT_SYMBOL_GPL(greybus_disabled);
|
||||||
static int greybus_module_match(struct device *dev, struct device_driver *drv)
|
static int greybus_module_match(struct device *dev, struct device_driver *drv)
|
||||||
{
|
{
|
||||||
struct greybus_driver *driver = to_greybus_driver(drv);
|
struct greybus_driver *driver = to_greybus_driver(drv);
|
||||||
struct gb_interface *intf = to_gb_interface(dev);
|
struct gb_bundle *bundle = to_gb_bundle(dev);
|
||||||
const struct greybus_interface_id *id;
|
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)
|
if (id)
|
||||||
return 1;
|
return 1;
|
||||||
/* FIXME - Dynamic ids? */
|
/* FIXME - Dynamic ids? */
|
||||||
|
@ -97,16 +97,16 @@ struct bus_type greybus_bus_type = {
|
||||||
static int greybus_probe(struct device *dev)
|
static int greybus_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
struct greybus_driver *driver = to_greybus_driver(dev->driver);
|
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);
|
||||||
const struct greybus_interface_id *id;
|
const struct greybus_bundle_id *id;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* match id */
|
/* match id */
|
||||||
id = gb_interface_match_id(intf, driver->id_table);
|
id = gb_bundle_match_id(bundle, driver->id_table);
|
||||||
if (!id)
|
if (!id)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
retval = driver->probe(intf, id);
|
retval = driver->probe(bundle, id);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
@ -116,9 +116,9 @@ static int greybus_probe(struct device *dev)
|
||||||
static int greybus_remove(struct device *dev)
|
static int greybus_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
struct greybus_driver *driver = to_greybus_driver(dev->driver);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,14 +120,14 @@ void greybus_remove_hd(struct greybus_host_device *hd);
|
||||||
struct greybus_driver {
|
struct greybus_driver {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
int (*probe)(struct gb_interface *intf,
|
int (*probe)(struct gb_bundle *bundle,
|
||||||
const struct greybus_interface_id *id);
|
const struct greybus_bundle_id *id);
|
||||||
void (*disconnect)(struct gb_interface *intf);
|
void (*disconnect)(struct gb_bundle *bundle);
|
||||||
|
|
||||||
int (*suspend)(struct gb_interface *intf, pm_message_t message);
|
int (*suspend)(struct gb_bundle *bundle, pm_message_t message);
|
||||||
int (*resume)(struct gb_interface *intf);
|
int (*resume)(struct gb_bundle *bundle);
|
||||||
|
|
||||||
const struct greybus_interface_id *id_table;
|
const struct greybus_bundle_id *id_table;
|
||||||
|
|
||||||
struct device_driver driver;
|
struct device_driver driver;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,18 +9,20 @@
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
|
|
||||||
|
|
||||||
struct greybus_interface_id {
|
struct greybus_bundle_id {
|
||||||
__u16 match_flags;
|
__u16 match_flags;
|
||||||
__u16 vendor;
|
__u16 vendor;
|
||||||
__u16 product;
|
__u16 product;
|
||||||
|
__u8 class_type;
|
||||||
__u64 unique_id;
|
__u64 unique_id;
|
||||||
|
|
||||||
kernel_ulong_t driver_info __aligned(sizeof(kernel_ulong_t));
|
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_VENDOR BIT(0)
|
||||||
#define GREYBUS_ID_MATCH_PRODUCT BIT(1)
|
#define GREYBUS_ID_MATCH_PRODUCT BIT(1)
|
||||||
#define GREYBUS_ID_MATCH_SERIAL BIT(2)
|
#define GREYBUS_ID_MATCH_SERIAL BIT(2)
|
||||||
|
#define GREYBUS_ID_MATCH_CLASS_TYPE BIT(3)
|
||||||
|
|
||||||
#endif /* __LINUX_GREYBUS_ID_H */
|
#endif /* __LINUX_GREYBUS_ID_H */
|
||||||
|
|
|
@ -40,40 +40,6 @@ ATTRIBUTE_GROUPS(interface);
|
||||||
/* XXX This could be per-host device */
|
/* XXX This could be per-host device */
|
||||||
static DEFINE_SPINLOCK(gb_interfaces_lock);
|
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
|
// FIXME, odds are you don't want to call this function, rework the caller to
|
||||||
// not need it please.
|
// not need it please.
|
||||||
struct gb_interface *gb_interface_find(struct greybus_host_device *hd,
|
struct gb_interface *gb_interface_find(struct greybus_host_device *hd,
|
||||||
|
|
|
@ -44,10 +44,6 @@ static inline void *gb_interface_get_drvdata(struct gb_interface *intf)
|
||||||
|
|
||||||
/* Greybus "private" definitions */
|
/* 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,
|
struct gb_interface *gb_interface_find(struct greybus_host_device *hd,
|
||||||
u8 interface_id);
|
u8 interface_id);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue