aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-02-20 01:45:43 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-02-22 11:59:31 -0500
commitb2b3e66e40bb60b1aa222d2f712c019653215390 (patch)
tree94806f8a31ba5baa2b172b67234c08643fbcefd9 /drivers/pinctrl
parent8b9c139f166cd55d76728a5910fa862a4e16e833 (diff)
pinctrl: Store mapping table as a list of chunks
Instead of storing a single array of mapping table entries, which requires realloc()ing that array each time it's extended and copying the new data, simply store a list of pointers to the individual chunks. This also removes the need to copy the mapping table at all; a pointer is maintained to the original table, this saving memory. A macro for_each_maps() is introduced to hide the additional complexity of iterating over the map entries. This change will also simplify removing chunks of entries from the mapping table. This isn't important right now, but will be in the future, when mapping table entries are dynamically added when parsing them from the device tree, and removed when drivers no longer need to interact with pinctrl. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/core.c120
1 files changed, 75 insertions, 45 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index feadf1c31133..50bcc511193e 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -7,6 +7,8 @@
7 * 7 *
8 * Author: Linus Walleij <linus.walleij@linaro.org> 8 * Author: Linus Walleij <linus.walleij@linaro.org>
9 * 9 *
10 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
11 *
10 * License terms: GNU General Public License (GPL) version 2 12 * License terms: GNU General Public License (GPL) version 2
11 */ 13 */
12#define pr_fmt(fmt) "pinctrl core: " fmt 14#define pr_fmt(fmt) "pinctrl core: " fmt
@@ -31,6 +33,18 @@
31#include "pinconf.h" 33#include "pinconf.h"
32 34
33/** 35/**
36 * struct pinctrl_maps - a list item containing part of the mapping table
37 * @node: mapping table list node
38 * @maps: array of mapping table entries
39 * @num_maps: the number of entries in @maps
40 */
41struct pinctrl_maps {
42 struct list_head node;
43 struct pinctrl_map const *maps;
44 unsigned num_maps;
45};
46
47/**
34 * struct pinctrl_hog - a list item to stash control hogs 48 * struct pinctrl_hog - a list item to stash control hogs
35 * @node: pin control hog list node 49 * @node: pin control hog list node
36 * @map: map entry responsible for this hogging 50 * @map: map entry responsible for this hogging
@@ -51,8 +65,14 @@ static DEFINE_MUTEX(pinctrl_list_mutex);
51static LIST_HEAD(pinctrl_list); 65static LIST_HEAD(pinctrl_list);
52 66
53/* Global pinctrl maps */ 67/* Global pinctrl maps */
54static struct pinctrl_map *pinctrl_maps; 68static DEFINE_MUTEX(pinctrl_maps_mutex);
55static unsigned pinctrl_maps_num; 69static LIST_HEAD(pinctrl_maps);
70
71#define for_each_maps(_maps_node_, _i_, _map_) \
72 list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
73 for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
74 _i_ < _maps_node_->num_maps; \
75 i++, _map_ = &_maps_node_->maps[_i_])
56 76
57const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) 77const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
58{ 78{
@@ -454,23 +474,17 @@ int pinctrl_gpio_direction_output(unsigned gpio)
454} 474}
455EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); 475EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output);
456 476
457/** 477static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name)
458 * pinctrl_get() - retrieves the pin controller handle for a certain device
459 * @dev: the device to get the pin controller handle for
460 * @name: an optional specific control mapping name or NULL, the name is only
461 * needed if you want to have more than one mapping per device, or if you
462 * need an anonymous pin control (not tied to any specific device)
463 */
464struct pinctrl *pinctrl_get(struct device *dev, const char *name)
465{ 478{
466 struct pinctrl_map const *map = NULL;
467 struct pinctrl_dev *pctldev = NULL; 479 struct pinctrl_dev *pctldev = NULL;
468 const char *devname = NULL; 480 const char *devname = NULL;
469 struct pinctrl *p; 481 struct pinctrl *p;
470 bool found_map; 482 bool found_map;
471 unsigned num_maps = 0; 483 unsigned num_maps = 0;
472 int ret = -ENODEV; 484 int ret = -ENODEV;
485 struct pinctrl_maps *maps_node;
473 int i; 486 int i;
487 struct pinctrl_map const *map;
474 488
475 /* We must have dev or ID or both */ 489 /* We must have dev or ID or both */
476 if (!dev && !name) 490 if (!dev && !name)
@@ -494,8 +508,7 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name)
494 pinmux_init_pinctrl_handle(p); 508 pinmux_init_pinctrl_handle(p);
495 509
496 /* Iterate over the pin control maps to locate the right ones */ 510 /* Iterate over the pin control maps to locate the right ones */
497 for (i = 0; i < pinctrl_maps_num; i++) { 511 for_each_maps(maps_node, i, map) {
498 map = &pinctrl_maps[i];
499 found_map = false; 512 found_map = false;
500 513
501 /* 514 /*
@@ -515,7 +528,6 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name)
515 pr_debug("in map, found pctldev %s to handle function %s", 528 pr_debug("in map, found pctldev %s to handle function %s",
516 dev_name(pctldev->dev), map->function); 529 dev_name(pctldev->dev), map->function);
517 530
518
519 /* 531 /*
520 * If we're looking for a specific named map, this must match, 532 * If we're looking for a specific named map, this must match,
521 * else we loop and look for the next. 533 * else we loop and look for the next.
@@ -574,6 +586,24 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name)
574 586
575 return p; 587 return p;
576} 588}
589
590/**
591 * pinctrl_get() - retrieves the pin controller handle for a certain device
592 * @dev: the device to get the pin controller handle for
593 * @name: an optional specific control mapping name or NULL, the name is only
594 * needed if you want to have more than one mapping per device, or if you
595 * need an anonymous pin control (not tied to any specific device)
596 */
597struct pinctrl *pinctrl_get(struct device *dev, const char *name)
598{
599 struct pinctrl *p;
600
601 mutex_lock(&pinctrl_maps_mutex);
602 p = pinctrl_get_locked(dev, name);
603 mutex_unlock(&pinctrl_maps_mutex);
604
605 return p;
606}
577EXPORT_SYMBOL_GPL(pinctrl_get); 607EXPORT_SYMBOL_GPL(pinctrl_get);
578 608
579/** 609/**
@@ -649,8 +679,8 @@ EXPORT_SYMBOL_GPL(pinctrl_disable);
649int pinctrl_register_mappings(struct pinctrl_map const *maps, 679int pinctrl_register_mappings(struct pinctrl_map const *maps,
650 unsigned num_maps) 680 unsigned num_maps)
651{ 681{
652 void *tmp_maps;
653 int i; 682 int i;
683 struct pinctrl_maps *maps_node;
654 684
655 pr_debug("add %d pinmux maps\n", num_maps); 685 pr_debug("add %d pinmux maps\n", num_maps);
656 686
@@ -684,31 +714,23 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps,
684 maps[i].function); 714 maps[i].function);
685 } 715 }
686 716
687 /* 717 maps_node = kzalloc(sizeof(*maps_node), GFP_KERNEL);
688 * Make a copy of the map array - string pointers will end up in the 718 if (!maps_node) {
689 * kernel const section anyway so these do not need to be deep copied. 719 pr_err("failed to alloc struct pinctrl_maps\n");
690 */ 720 return -ENOMEM;
691 if (!pinctrl_maps_num) { 721 }
692 /* On first call, just copy them */
693 tmp_maps = kmemdup(maps,
694 sizeof(struct pinctrl_map) * num_maps,
695 GFP_KERNEL);
696 if (!tmp_maps)
697 return -ENOMEM;
698 } else {
699 /* Subsequent calls, reallocate array to new size */
700 size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num;
701 size_t newsize = sizeof(struct pinctrl_map) * num_maps;
702 722
703 tmp_maps = krealloc(pinctrl_maps, 723 maps_node->num_maps = num_maps;
704 oldsize + newsize, GFP_KERNEL); 724 maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL);
705 if (!tmp_maps) 725 if (!maps_node->maps) {
706 return -ENOMEM; 726 kfree(maps_node);
707 memcpy((tmp_maps + oldsize), maps, newsize); 727 return -ENOMEM;
708 } 728 }
709 729
710 pinctrl_maps = tmp_maps; 730 mutex_lock(&pinctrl_maps_mutex);
711 pinctrl_maps_num += num_maps; 731 list_add_tail(&maps_node->node, &pinctrl_maps);
732 mutex_unlock(&pinctrl_maps_mutex);
733
712 return 0; 734 return 0;
713} 735}
714 736
@@ -724,7 +746,7 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev,
724 if (!hog) 746 if (!hog)
725 return -ENOMEM; 747 return -ENOMEM;
726 748
727 p = pinctrl_get(pctldev->dev, map->name); 749 p = pinctrl_get_locked(pctldev->dev, map->name);
728 if (IS_ERR(p)) { 750 if (IS_ERR(p)) {
729 kfree(hog); 751 kfree(hog);
730 dev_err(pctldev->dev, 752 dev_err(pctldev->dev,
@@ -768,23 +790,28 @@ int pinctrl_hog_maps(struct pinctrl_dev *pctldev)
768 struct device *dev = pctldev->dev; 790 struct device *dev = pctldev->dev;
769 const char *devname = dev_name(dev); 791 const char *devname = dev_name(dev);
770 int ret; 792 int ret;
793 struct pinctrl_maps *maps_node;
771 int i; 794 int i;
795 struct pinctrl_map const *map;
772 796
773 INIT_LIST_HEAD(&pctldev->pinctrl_hogs); 797 INIT_LIST_HEAD(&pctldev->pinctrl_hogs);
774 mutex_init(&pctldev->pinctrl_hogs_lock); 798 mutex_init(&pctldev->pinctrl_hogs_lock);
775 799
776 for (i = 0; i < pinctrl_maps_num; i++) { 800 mutex_lock(&pinctrl_maps_mutex);
777 struct pinctrl_map const *map = &pinctrl_maps[i]; 801 for_each_maps(maps_node, i, map) {
778
779 if (map->ctrl_dev_name && 802 if (map->ctrl_dev_name &&
780 !strcmp(map->ctrl_dev_name, devname) && 803 !strcmp(map->ctrl_dev_name, devname) &&
781 !strcmp(map->dev_name, devname)) { 804 !strcmp(map->dev_name, devname)) {
782 /* OK time to hog! */ 805 /* OK time to hog! */
783 ret = pinctrl_hog_map(pctldev, map); 806 ret = pinctrl_hog_map(pctldev, map);
784 if (ret) 807 if (ret) {
808 mutex_unlock(&pinctrl_maps_mutex);
785 return ret; 809 return ret;
810 }
786 } 811 }
787 } 812 }
813 mutex_unlock(&pinctrl_maps_mutex);
814
788 return 0; 815 return 0;
789} 816}
790 817
@@ -900,13 +927,14 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
900 927
901static int pinctrl_maps_show(struct seq_file *s, void *what) 928static int pinctrl_maps_show(struct seq_file *s, void *what)
902{ 929{
930 struct pinctrl_maps *maps_node;
903 int i; 931 int i;
932 struct pinctrl_map const *map;
904 933
905 seq_puts(s, "Pinctrl maps:\n"); 934 seq_puts(s, "Pinctrl maps:\n");
906 935
907 for (i = 0; i < pinctrl_maps_num; i++) { 936 mutex_lock(&pinctrl_maps_mutex);
908 struct pinctrl_map const *map = &pinctrl_maps[i]; 937 for_each_maps(maps_node, i, map) {
909
910 seq_printf(s, "%s:\n", map->name); 938 seq_printf(s, "%s:\n", map->name);
911 if (map->dev_name) 939 if (map->dev_name)
912 seq_printf(s, " device: %s\n", 940 seq_printf(s, " device: %s\n",
@@ -919,6 +947,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what)
919 seq_printf(s, " group: %s\n", map->group ? map->group : 947 seq_printf(s, " group: %s\n", map->group ? map->group :
920 "(default)"); 948 "(default)");
921 } 949 }
950 mutex_unlock(&pinctrl_maps_mutex);
951
922 return 0; 952 return 0;
923} 953}
924 954