aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-11-29 06:52:39 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-01-03 03:10:02 -0500
commit97607d157c133ab18dfcd77fa836e37fa950a44a (patch)
treef9ac62a9534295f24ab40a2890bfd285bc157a03
parent542e704f3ffee1dc4539c9e8191e4dc215220f5e (diff)
pinctrl: make a copy of pinmux map
This makes a deep copy of the pinmux function map instead of keeping the copy supplied from the platform around. This makes it possible to tag the platforms map with __initdata as is also done as part of this patch. Rationale: a certain target platform (PXA) has numerous pinmux maps, many of which will be lying around unused after boot in a multi-platform binary. Instead, deep-copy the one we're going to use and tag them all __initdata so they go away after boot. ChangeLog v1->v2: - Fixup the deep copy, missed a few items on the struct, plus mark bool member non-const since we're making runtime copies if this stuff now. ChangeLog v2->v3: - Make a shallow copy (just copy the array of map structs) as Arnd noticed, string constants never get discarded by the kernel anyway, so these pointers may be safely copied over. Reviewed-by: Arnd Bergmann <arnd.bergmann@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/pinctrl.txt4
-rw-r--r--arch/arm/mach-u300/core.c2
-rw-r--r--drivers/pinctrl/pinmux.c44
-rw-r--r--include/linux/pinctrl/machine.h2
4 files changed, 38 insertions, 14 deletions
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
index 3846264c597..c8fd136eac8 100644
--- a/Documentation/pinctrl.txt
+++ b/Documentation/pinctrl.txt
@@ -697,7 +697,7 @@ spi on the second function mapping:
697 697
698#include <linux/pinctrl/machine.h> 698#include <linux/pinctrl/machine.h>
699 699
700static const struct pinmux_map pmx_mapping[] = { 700static const struct pinmux_map __initdata pmx_mapping[] = {
701 { 701 {
702 .ctrl_dev_name = "pinctrl.0", 702 .ctrl_dev_name = "pinctrl.0",
703 .function = "spi0", 703 .function = "spi0",
@@ -734,7 +734,7 @@ Since the above construct is pretty common there is a helper macro to make
734it even more compact which assumes you want to use pinctrl.0 and position 734it even more compact which assumes you want to use pinctrl.0 and position
7350 for mapping, for example: 7350 for mapping, for example:
736 736
737static struct pinmux_map pmx_mapping[] = { 737static struct pinmux_map __initdata pmx_mapping[] = {
738 PINMUX_MAP_PRIMARY("I2CMAP", "i2c0", "foo-i2c.0"), 738 PINMUX_MAP_PRIMARY("I2CMAP", "i2c0", "foo-i2c.0"),
739}; 739};
740 740
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index ac0791e924b..839fa15c4eb 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -1605,7 +1605,7 @@ static struct platform_device pinmux_device = {
1605}; 1605};
1606 1606
1607/* Pinmux settings */ 1607/* Pinmux settings */
1608static struct pinmux_map u300_pinmux_map[] = { 1608static struct pinmux_map __initdata u300_pinmux_map[] = {
1609 /* anonymous maps for chip power and EMIFs */ 1609 /* anonymous maps for chip power and EMIFs */
1610 PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"), 1610 PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"),
1611 PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"), 1611 PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"),
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index f3e4f031fe1..f6e7d583998 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -21,6 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/string.h>
24#include <linux/sysfs.h> 25#include <linux/sysfs.h>
25#include <linux/debugfs.h> 26#include <linux/debugfs.h>
26#include <linux/seq_file.h> 27#include <linux/seq_file.h>
@@ -33,7 +34,7 @@ static DEFINE_MUTEX(pinmux_list_mutex);
33static LIST_HEAD(pinmux_list); 34static LIST_HEAD(pinmux_list);
34 35
35/* Global pinmux maps, we allow one set only */ 36/* Global pinmux maps, we allow one set only */
36static struct pinmux_map const *pinmux_maps; 37static struct pinmux_map *pinmux_maps;
37static unsigned pinmux_maps_num; 38static unsigned pinmux_maps_num;
38 39
39/** 40/**
@@ -333,7 +334,9 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
333 334
334/** 335/**
335 * pinmux_register_mappings() - register a set of pinmux mappings 336 * pinmux_register_mappings() - register a set of pinmux mappings
336 * @maps: the pinmux mappings table to register 337 * @maps: the pinmux mappings table to register, this should be marked with
338 * __initdata so it can be discarded after boot, this function will
339 * perform a shallow copy for the mapping entries.
337 * @num_maps: the number of maps in the mapping table 340 * @num_maps: the number of maps in the mapping table
338 * 341 *
339 * Only call this once during initialization of your machine, the function is 342 * Only call this once during initialization of your machine, the function is
@@ -344,32 +347,48 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
344int __init pinmux_register_mappings(struct pinmux_map const *maps, 347int __init pinmux_register_mappings(struct pinmux_map const *maps,
345 unsigned num_maps) 348 unsigned num_maps)
346{ 349{
350 int ret = 0;
347 int i; 351 int i;
348 352
349 if (pinmux_maps != NULL) { 353 if (pinmux_maps_num != 0) {
350 pr_err("pinmux mappings already registered, you can only " 354 pr_err("pinmux mappings already registered, you can only "
351 "register one set of maps\n"); 355 "register one set of maps\n");
352 return -EINVAL; 356 return -EINVAL;
353 } 357 }
354 358
355 pr_debug("add %d pinmux maps\n", num_maps); 359 pr_debug("add %d pinmux maps\n", num_maps);
360
361 /*
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
356 for (i = 0; i < num_maps; i++) { 370 for (i = 0; i < num_maps; i++) {
357 /* Sanity check the mapping */ 371 /* Sanity check the mapping while copying it */
358 if (!maps[i].name) { 372 if (!maps[i].name) {
359 pr_err("failed to register map %d: " 373 pr_err("failed to register map %d: "
360 "no map name given\n", i); 374 "no map name given\n", i);
361 return -EINVAL; 375 ret = -EINVAL;
376 goto err_out_free;
362 } 377 }
378
363 if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { 379 if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
364 pr_err("failed to register map %s (%d): " 380 pr_err("failed to register map %s (%d): "
365 "no pin control device given\n", 381 "no pin control device given\n",
366 maps[i].name, i); 382 maps[i].name, i);
367 return -EINVAL; 383 ret = -EINVAL;
384 goto err_out_free;
368 } 385 }
386
369 if (!maps[i].function) { 387 if (!maps[i].function) {
370 pr_err("failed to register map %s (%d): " 388 pr_err("failed to register map %s (%d): "
371 "no function ID given\n", maps[i].name, i); 389 "no function ID given\n", maps[i].name, i);
372 return -EINVAL; 390 ret = -EINVAL;
391 goto err_out_free;
373 } 392 }
374 393
375 if (!maps[i].dev && !maps[i].dev_name) 394 if (!maps[i].dev && !maps[i].dev_name)
@@ -380,12 +399,17 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
380 pr_debug("register map %s, function %s\n", 399 pr_debug("register map %s, function %s\n",
381 maps[i].name, 400 maps[i].name,
382 maps[i].function); 401 maps[i].function);
383 }
384 402
385 pinmux_maps = maps; 403 pinmux_maps_num++;
386 pinmux_maps_num = num_maps; 404 }
387 405
388 return 0; 406 return 0;
407
408err_out_free:
409 kfree(pinmux_maps);
410 pinmux_maps = NULL;
411 pinmux_maps_num = 0;
412 return ret;
389} 413}
390 414
391/** 415/**
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h
index 88863531d86..f5372319d99 100644
--- a/include/linux/pinctrl/machine.h
+++ b/include/linux/pinctrl/machine.h
@@ -48,7 +48,7 @@ struct pinmux_map {
48 const char *group; 48 const char *group;
49 struct device *dev; 49 struct device *dev;
50 const char *dev_name; 50 const char *dev_name;
51 const bool hog_on_boot; 51 bool hog_on_boot;
52}; 52};
53 53
54/* 54/*