1
0
Fork 0

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>
hifive-unleashed-5.1
Viresh Kumar 2015-04-01 20:32:04 +05:30 committed by Greg Kroah-Hartman
parent 8e2e22d783
commit 9f5f30e712
7 changed files with 71 additions and 55 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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 */

View File

@ -40,40 +40,6 @@ ATTRIBUTE_GROUPS(interface);
/* 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,

View File

@ -44,10 +44,6 @@ static inline void *gb_interface_get_drvdata(struct gb_interface *intf)
/* 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);