aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinmux.c')
-rw-r--r--drivers/pinctrl/pinmux.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index f6e7d583998c..a11681b4bd91 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -33,7 +33,7 @@
33static DEFINE_MUTEX(pinmux_list_mutex); 33static DEFINE_MUTEX(pinmux_list_mutex);
34static LIST_HEAD(pinmux_list); 34static LIST_HEAD(pinmux_list);
35 35
36/* Global pinmux maps, we allow one set only */ 36/* Global pinmux maps */
37static struct pinmux_map *pinmux_maps; 37static struct pinmux_map *pinmux_maps;
38static unsigned pinmux_maps_num; 38static unsigned pinmux_maps_num;
39 39
@@ -347,48 +347,30 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
347int __init pinmux_register_mappings(struct pinmux_map const *maps, 347int __init pinmux_register_mappings(struct pinmux_map const *maps,
348 unsigned num_maps) 348 unsigned num_maps)
349{ 349{
350 int ret = 0; 350 void *tmp_maps;
351 int i; 351 int i;
352 352
353 if (pinmux_maps_num != 0) {
354 pr_err("pinmux mappings already registered, you can only "
355 "register one set of maps\n");
356 return -EINVAL;
357 }
358
359 pr_debug("add %d pinmux maps\n", num_maps); 353 pr_debug("add %d pinmux maps\n", num_maps);
360 354
361 /* 355 /* First sanity check the new mapping */
362 * Make a copy of the map array - string pointers will end up in the
363 * kernel const section anyway so these do not need to be deep copied.
364 */
365 pinmux_maps = kmemdup(maps, sizeof(struct pinmux_map) * num_maps,
366 GFP_KERNEL);
367 if (!pinmux_maps)
368 return -ENOMEM;
369
370 for (i = 0; i < num_maps; i++) { 356 for (i = 0; i < num_maps; i++) {
371 /* Sanity check the mapping while copying it */
372 if (!maps[i].name) { 357 if (!maps[i].name) {
373 pr_err("failed to register map %d: " 358 pr_err("failed to register map %d: "
374 "no map name given\n", i); 359 "no map name given\n", i);
375 ret = -EINVAL; 360 return -EINVAL;
376 goto err_out_free;
377 } 361 }
378 362
379 if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { 363 if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
380 pr_err("failed to register map %s (%d): " 364 pr_err("failed to register map %s (%d): "
381 "no pin control device given\n", 365 "no pin control device given\n",
382 maps[i].name, i); 366 maps[i].name, i);
383 ret = -EINVAL; 367 return -EINVAL;
384 goto err_out_free;
385 } 368 }
386 369
387 if (!maps[i].function) { 370 if (!maps[i].function) {
388 pr_err("failed to register map %s (%d): " 371 pr_err("failed to register map %s (%d): "
389 "no function ID given\n", maps[i].name, i); 372 "no function ID given\n", maps[i].name, i);
390 ret = -EINVAL; 373 return -EINVAL;
391 goto err_out_free;
392 } 374 }
393 375
394 if (!maps[i].dev && !maps[i].dev_name) 376 if (!maps[i].dev && !maps[i].dev_name)
@@ -399,17 +381,33 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
399 pr_debug("register map %s, function %s\n", 381 pr_debug("register map %s, function %s\n",
400 maps[i].name, 382 maps[i].name,
401 maps[i].function); 383 maps[i].function);
384 }
402 385
403 pinmux_maps_num++; 386 /*
387 * Make a copy of the map array - string pointers will end up in the
388 * kernel const section anyway so these do not need to be deep copied.
389 */
390 if (!pinmux_maps_num) {
391 /* On first call, just copy them */
392 tmp_maps = kmemdup(maps,
393 sizeof(struct pinmux_map) * num_maps,
394 GFP_KERNEL);
395 if (!tmp_maps)
396 return -ENOMEM;
397 } else {
398 /* Subsequent calls, reallocate array to new size */
399 size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num;
400 size_t newsize = sizeof(struct pinmux_map) * num_maps;
401
402 tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL);
403 if (!tmp_maps)
404 return -ENOMEM;
405 memcpy((tmp_maps + oldsize), maps, newsize);
404 } 406 }
405 407
408 pinmux_maps = tmp_maps;
409 pinmux_maps_num += num_maps;
406 return 0; 410 return 0;
407
408err_out_free:
409 kfree(pinmux_maps);
410 pinmux_maps = NULL;
411 pinmux_maps_num = 0;
412 return ret;
413} 411}
414 412
415/** 413/**