aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinmux.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-11-30 07:28:14 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-01-03 03:10:02 -0500
commit59b099b04981917ee7fbd88b6f50eeaffc9f33cd (patch)
tree454627d0c9617bf2cb878fddc282fa0a25f4736d /drivers/pinctrl/pinmux.c
parent97607d157c133ab18dfcd77fa836e37fa950a44a (diff)
pinctrl: make it possible to add multiple maps
Since we now anyway make a copy of the platform-supplied pinmux map, we can just as well make it possible to call the function adding maps several times, so as to simplify cases (as PXA) where several sets of disparate mappings need to be added depending on target platform. Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> Acked-by: Arnd Bergmann <arnd@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
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/**