mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 00:34:20 +08:00
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 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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user