aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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