greybus: Generate greybus wide unique ids for endo devices

Currently we name the endo device as "endo". And it shows up with the
same name in sysfs directory: /sys/bus/greybus/devices/.

But each device in kernel should be represented by a unique id in
kernel, and "endo" isn't unique.

Lets generate unique ids for endo devices. The ida mechanism for
allocating ids may be overkill but it works.

Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Viresh Kumar 2015-06-07 09:13:15 +05:30 committed by Greg Kroah-Hartman
parent d7353ceada
commit 4a04187008
3 changed files with 43 additions and 1 deletions

View file

@ -18,6 +18,8 @@
#include "greybus.h"
extern struct ida greybus_endo_id_map;
/* Allow greybus to be disabled at boot if needed */
static bool nogreybus;
#ifdef MODULE
@ -263,6 +265,8 @@ static int __init gb_init(void)
goto error_bus;
}
ida_init(&greybus_endo_id_map);
retval = gb_ap_init();
if (retval) {
pr_err("gb_ap_init failed\n");

View file

@ -43,6 +43,8 @@
#define max_endo_interface_id(endo_layout) \
(4 + ((endo_layout)->max_ribs + 1) * 2)
struct ida greybus_endo_id_map;
/* endo sysfs attributes */
static ssize_t serial_number_show(struct device *dev,
struct device_attribute *attr, char *buf)
@ -432,18 +434,51 @@ static int create_modules(struct gb_endo *endo)
return 0;
}
/*
* Allocate an available Id to uniquely identify the endo device. The lowest
* available id is returned, so the first call is guaranteed to allocate endo Id
* 0.
*
* Assigns the endo's id and returns 0 if successful.
* Returns error otherwise.
*/
static int gb_endo_id_alloc(struct gb_endo *endo)
{
int id;
id = ida_simple_get(&greybus_endo_id_map, 0, 0, GFP_ATOMIC);
if (id < 0)
return id;
endo->dev_id = (u16)id;
return 0;
}
/*
* Free a previously-allocated Endo Id.
*/
static void gb_endo_id_free(struct gb_endo *endo)
{
ida_simple_remove(&greybus_endo_id_map, endo->dev_id);
}
static int gb_endo_register(struct greybus_host_device *hd,
struct gb_endo *endo)
{
int retval;
retval = gb_endo_id_alloc(endo);
if (retval)
return retval;
endo->dev.parent = hd->parent;
endo->dev.init_name = "endo";
endo->dev.bus = &greybus_bus_type;
endo->dev.type = &greybus_endo_type;
endo->dev.groups = endo_groups;
endo->dev.dma_mask = hd->parent->dma_mask;
device_initialize(&endo->dev);
dev_set_name(&endo->dev, "endo%hu", endo->dev_id);
// FIXME
// Get the version and serial number from the SVC, right now we are
@ -456,6 +491,7 @@ static int gb_endo_register(struct greybus_host_device *hd,
dev_err(hd->parent, "failed to add endo device of id 0x%04x\n",
endo->id);
put_device(&endo->dev);
gb_endo_id_free(endo);
}
return retval;
@ -511,6 +547,7 @@ void gb_endo_remove(struct gb_endo *endo)
/* remove all modules for this endo */
gb_module_remove_all(endo);
gb_endo_id_free(endo);
device_unregister(&endo->dev);
}

View file

@ -40,6 +40,7 @@ struct gb_endo {
struct device dev;
struct endo_layout layout;
struct gb_svc_info svc_info;
u16 dev_id;
u16 id;
u8 ap_intf_id;
};