aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/devices.c83
1 files changed, 44 insertions, 39 deletions
diff --git a/init/devices.c b/init/devices.c
index c30303f..ac54ced 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -87,7 +87,8 @@ struct perm_node {
struct platform_node {
char *name;
- int name_len;
+ char *path;
+ int path_len;
struct listnode list;
};
@@ -222,61 +223,69 @@ static void make_device(const char *path,
#endif
}
-static void add_platform_device(const char *name)
+static void add_platform_device(const char *path)
{
- int name_len = strlen(name);
+ int path_len = strlen(path);
struct listnode *node;
struct platform_node *bus;
+ const char *name = path;
+
+ if (!strncmp(path, "/devices/", 9)) {
+ name += 9;
+ if (!strncmp(name, "platform/", 9))
+ name += 9;
+ }
list_for_each_reverse(node, &platform_names) {
bus = node_to_item(node, struct platform_node, list);
- if ((bus->name_len < name_len) &&
- (name[bus->name_len] == '/') &&
- !strncmp(name, bus->name, bus->name_len))
+ if ((bus->path_len < path_len) &&
+ (path[bus->path_len] == '/') &&
+ !strncmp(path, bus->path, bus->path_len))
/* subdevice of an existing platform, ignore it */
return;
}
- INFO("adding platform device %s\n", name);
+ INFO("adding platform device %s (%s)\n", name, path);
bus = calloc(1, sizeof(struct platform_node));
- bus->name = strdup(name);
- bus->name_len = name_len;
+ bus->path = strdup(path);
+ bus->path_len = path_len;
+ bus->name = bus->path + (name - path);
list_add_tail(&platform_names, &bus->list);
}
/*
- * given a name that may start with a platform device, find the length of the
+ * given a path that may start with a platform device, find the length of the
* platform device prefix. If it doesn't start with a platform device, return
* 0.
*/
-static const char *find_platform_device(const char *name)
+static struct platform_node *find_platform_device(const char *path)
{
- int name_len = strlen(name);
+ int path_len = strlen(path);
struct listnode *node;
struct platform_node *bus;
list_for_each_reverse(node, &platform_names) {
bus = node_to_item(node, struct platform_node, list);
- if ((bus->name_len < name_len) &&
- (name[bus->name_len] == '/') &&
- !strncmp(name, bus->name, bus->name_len))
- return bus->name;
+ if ((bus->path_len < path_len) &&
+ (path[bus->path_len] == '/') &&
+ !strncmp(path, bus->path, bus->path_len))
+ return bus;
}
return NULL;
}
-static void remove_platform_device(const char *name)
+static void remove_platform_device(const char *path)
{
struct listnode *node;
struct platform_node *bus;
list_for_each_reverse(node, &platform_names) {
bus = node_to_item(node, struct platform_node, list);
- if (!strcmp(name, bus->name)) {
- INFO("removing platform device %s\n", name);
- free(bus->name);
+ if (!strcmp(path, bus->path)) {
+ INFO("removing platform device %s\n", bus->name);
+ free(bus->path);
list_remove(node);
free(bus);
return;
@@ -362,8 +371,10 @@ static char **get_character_device_symlinks(struct uevent *uevent)
char **links;
int link_num = 0;
int width;
+ struct platform_node *pdev;
- if (strncmp(uevent->path, "/devices/platform/", 18))
+ pdev = find_platform_device(uevent->path);
+ if (!pdev)
return NULL;
links = malloc(sizeof(char *) * 2);
@@ -372,7 +383,7 @@ static char **get_character_device_symlinks(struct uevent *uevent)
memset(links, 0, sizeof(char *) * 2);
/* skip "/devices/platform/<driver>" */
- parent = strchr(uevent->path + 18, '/');
+ parent = strchr(uevent->path + pdev->path_len, '/');
if (!*parent)
goto err;
@@ -409,7 +420,7 @@ err:
static char **parse_platform_block_device(struct uevent *uevent)
{
const char *device;
- const char *path;
+ struct platform_node *pdev;
char *slash;
int width;
char buf[256];
@@ -421,18 +432,16 @@ static char **parse_platform_block_device(struct uevent *uevent)
unsigned int size;
struct stat info;
+ pdev = find_platform_device(uevent->path);
+ if (!pdev)
+ return NULL;
+ device = pdev->name;
+
char **links = malloc(sizeof(char *) * 4);
if (!links)
return NULL;
memset(links, 0, sizeof(char *) * 4);
- /* Drop "/devices/platform/" */
- path = uevent->path;
- device = path + 18;
- device = find_platform_device(device);
- if (!device)
- goto err;
-
INFO("found platform device %s\n", device);
snprintf(link_path, sizeof(link_path), "/dev/block/platform/%s", device);
@@ -454,17 +463,13 @@ static char **parse_platform_block_device(struct uevent *uevent)
links[link_num] = NULL;
}
- slash = strrchr(path, '/');
+ slash = strrchr(uevent->path, '/');
if (asprintf(&links[link_num], "%s/%s", link_path, slash + 1) > 0)
link_num++;
else
links[link_num] = NULL;
return links;
-
-err:
- free(links);
- return NULL;
}
static void handle_device(const char *action, const char *devpath,
@@ -497,12 +502,12 @@ static void handle_device(const char *action, const char *devpath,
static void handle_platform_device_event(struct uevent *uevent)
{
- const char *name = uevent->path + 18; /* length of /devices/platform/ */
+ const char *path = uevent->path;
if (!strcmp(uevent->action, "add"))
- add_platform_device(name);
+ add_platform_device(path);
else if (!strcmp(uevent->action, "remove"))
- remove_platform_device(name);
+ remove_platform_device(path);
}
static const char *parse_device_name(struct uevent *uevent, unsigned int len)
@@ -540,7 +545,7 @@ static void handle_block_device_event(struct uevent *uevent)
snprintf(devpath, sizeof(devpath), "%s%s", base, name);
make_dir(base, 0755);
- if (!strncmp(uevent->path, "/devices/platform/", 18))
+ if (!strncmp(uevent->path, "/devices/", 9))
links = parse_platform_block_device(uevent);
handle_device(uevent->action, devpath, uevent->path, 1,