From 4a0418700871936cddec3a2b3c5a029ec0b2d6a3 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sun, 7 Jun 2015 09:13:15 +0530 Subject: [PATCH] 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 Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/core.c | 4 ++++ drivers/staging/greybus/endo.c | 39 +++++++++++++++++++++++++++++++++- drivers/staging/greybus/endo.h | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 0a24822ac4ab..9bbbf374c8c7 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -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"); diff --git a/drivers/staging/greybus/endo.c b/drivers/staging/greybus/endo.c index 4f9ae4b2a8e3..b89b14f59fb2 100644 --- a/drivers/staging/greybus/endo.c +++ b/drivers/staging/greybus/endo.c @@ -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); } diff --git a/drivers/staging/greybus/endo.h b/drivers/staging/greybus/endo.h index e211fb7d53bc..2547b63e59bb 100644 --- a/drivers/staging/greybus/endo.h +++ b/drivers/staging/greybus/endo.h @@ -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; }; -- 2.25.1