|
@@ -33,7 +33,7 @@
|
|
|
static DEFINE_MUTEX(pinmux_list_mutex);
|
|
|
static LIST_HEAD(pinmux_list);
|
|
|
|
|
|
-/* Global pinmux maps, we allow one set only */
|
|
|
+/* Global pinmux maps */
|
|
|
static struct pinmux_map *pinmux_maps;
|
|
|
static unsigned pinmux_maps_num;
|
|
|
|
|
@@ -347,48 +347,30 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
|
|
|
int __init pinmux_register_mappings(struct pinmux_map const *maps,
|
|
|
unsigned num_maps)
|
|
|
{
|
|
|
- int ret = 0;
|
|
|
+ void *tmp_maps;
|
|
|
int i;
|
|
|
|
|
|
- if (pinmux_maps_num != 0) {
|
|
|
- pr_err("pinmux mappings already registered, you can only "
|
|
|
- "register one set of maps\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
pr_debug("add %d pinmux maps\n", num_maps);
|
|
|
|
|
|
- /*
|
|
|
- * Make a copy of the map array - string pointers will end up in the
|
|
|
- * kernel const section anyway so these do not need to be deep copied.
|
|
|
- */
|
|
|
- pinmux_maps = kmemdup(maps, sizeof(struct pinmux_map) * num_maps,
|
|
|
- GFP_KERNEL);
|
|
|
- if (!pinmux_maps)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
+ /* First sanity check the new mapping */
|
|
|
for (i = 0; i < num_maps; i++) {
|
|
|
- /* Sanity check the mapping while copying it */
|
|
|
if (!maps[i].name) {
|
|
|
pr_err("failed to register map %d: "
|
|
|
"no map name given\n", i);
|
|
|
- ret = -EINVAL;
|
|
|
- goto err_out_free;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
|
|
|
pr_err("failed to register map %s (%d): "
|
|
|
"no pin control device given\n",
|
|
|
maps[i].name, i);
|
|
|
- ret = -EINVAL;
|
|
|
- goto err_out_free;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (!maps[i].function) {
|
|
|
pr_err("failed to register map %s (%d): "
|
|
|
"no function ID given\n", maps[i].name, i);
|
|
|
- ret = -EINVAL;
|
|
|
- goto err_out_free;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (!maps[i].dev && !maps[i].dev_name)
|
|
@@ -399,17 +381,33 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
|
|
|
pr_debug("register map %s, function %s\n",
|
|
|
maps[i].name,
|
|
|
maps[i].function);
|
|
|
+ }
|
|
|
|
|
|
- pinmux_maps_num++;
|
|
|
+ /*
|
|
|
+ * Make a copy of the map array - string pointers will end up in the
|
|
|
+ * kernel const section anyway so these do not need to be deep copied.
|
|
|
+ */
|
|
|
+ if (!pinmux_maps_num) {
|
|
|
+ /* On first call, just copy them */
|
|
|
+ tmp_maps = kmemdup(maps,
|
|
|
+ sizeof(struct pinmux_map) * num_maps,
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!tmp_maps)
|
|
|
+ return -ENOMEM;
|
|
|
+ } else {
|
|
|
+ /* Subsequent calls, reallocate array to new size */
|
|
|
+ size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num;
|
|
|
+ size_t newsize = sizeof(struct pinmux_map) * num_maps;
|
|
|
+
|
|
|
+ tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL);
|
|
|
+ if (!tmp_maps)
|
|
|
+ return -ENOMEM;
|
|
|
+ memcpy((tmp_maps + oldsize), maps, newsize);
|
|
|
}
|
|
|
|
|
|
+ pinmux_maps = tmp_maps;
|
|
|
+ pinmux_maps_num += num_maps;
|
|
|
return 0;
|
|
|
-
|
|
|
-err_out_free:
|
|
|
- kfree(pinmux_maps);
|
|
|
- pinmux_maps = NULL;
|
|
|
- pinmux_maps_num = 0;
|
|
|
- return ret;
|
|
|
}
|
|
|
|
|
|
/**
|