diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-03-01 20:48:32 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-03-02 10:18:24 -0500 |
commit | 46919ae63d4820e76724beb655274ce143f0da0b (patch) | |
tree | a16dfab490eb0d68db9d633f172bab98b1035485 /drivers/pinctrl | |
parent | d4e3198736d9d64e4ba4d2b46ab75cbcf5d0a4e0 (diff) |
pinctrl: introduce PINCTRL_STATE_DEFAULT, define hogs as that state
This provides a single centralized name for the default state.
Update PIN_MAP_* macros to use this state name, instead of requiring the
user to pass a state name in.
With this change, hog entries in the mapping table are defined as those
with state name PINCTRL_STATE_DEFAULT, i.e. all entries have the same
name. This interacts badly with the nested iteration over mapping table
entries in pinctrl_hog_maps() and pinctrl_hog_map() which would now
attempt to claim each hog mapping table entry multiple times. Replacing
the custom hog code with a simple pinctrl_get()/pinctrl_enable().
Update documentation and mapping tables to use this.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Dong Aisheng <dong.aisheng@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/core.c | 145 | ||||
-rw-r--r-- | drivers/pinctrl/core.h | 4 |
2 files changed, 9 insertions, 140 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 376cede29662..f25307b0e00a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -44,18 +44,6 @@ struct pinctrl_maps { | |||
44 | unsigned num_maps; | 44 | unsigned num_maps; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /** | ||
48 | * struct pinctrl_hog - a list item to stash control hogs | ||
49 | * @node: pin control hog list node | ||
50 | * @map: map entry responsible for this hogging | ||
51 | * @pmx: the pin control hogged by this item | ||
52 | */ | ||
53 | struct pinctrl_hog { | ||
54 | struct list_head node; | ||
55 | struct pinctrl_map const *map; | ||
56 | struct pinctrl *p; | ||
57 | }; | ||
58 | |||
59 | /* Global list of pin control devices */ | 47 | /* Global list of pin control devices */ |
60 | static DEFINE_MUTEX(pinctrldev_list_mutex); | 48 | static DEFINE_MUTEX(pinctrldev_list_mutex); |
61 | static LIST_HEAD(pinctrldev_list); | 49 | static LIST_HEAD(pinctrldev_list); |
@@ -702,103 +690,6 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, | |||
702 | return 0; | 690 | return 0; |
703 | } | 691 | } |
704 | 692 | ||
705 | /* Hog a single map entry and add to the hoglist */ | ||
706 | static int pinctrl_hog_map(struct pinctrl_dev *pctldev, | ||
707 | struct pinctrl_map const *map) | ||
708 | { | ||
709 | struct pinctrl_hog *hog; | ||
710 | struct pinctrl *p; | ||
711 | int ret; | ||
712 | |||
713 | hog = kzalloc(sizeof(*hog), GFP_KERNEL); | ||
714 | if (!hog) { | ||
715 | dev_err(pctldev->dev, "failed to alloc struct pinctrl_hog\n"); | ||
716 | return -ENOMEM; | ||
717 | } | ||
718 | |||
719 | p = pinctrl_get_locked(pctldev->dev, map->name); | ||
720 | if (IS_ERR(p)) { | ||
721 | kfree(hog); | ||
722 | dev_err(pctldev->dev, | ||
723 | "could not get the %s pin control mapping for hogging\n", | ||
724 | map->name); | ||
725 | return PTR_ERR(p); | ||
726 | } | ||
727 | |||
728 | ret = pinctrl_enable(p); | ||
729 | if (ret) { | ||
730 | pinctrl_put(p); | ||
731 | kfree(hog); | ||
732 | dev_err(pctldev->dev, | ||
733 | "could not enable the %s pin control mapping for hogging\n", | ||
734 | map->name); | ||
735 | return ret; | ||
736 | } | ||
737 | |||
738 | hog->map = map; | ||
739 | hog->p = p; | ||
740 | |||
741 | dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, | ||
742 | map->function); | ||
743 | list_add_tail(&hog->node, &pctldev->pinctrl_hogs); | ||
744 | |||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | /** | ||
749 | * pinctrl_hog_maps() - hog specific map entries on controller device | ||
750 | * @pctldev: the pin control device to hog entries on | ||
751 | * | ||
752 | * When the pin controllers are registered, there may be some specific pinmux | ||
753 | * map entries that need to be hogged, i.e. get+enabled until the system shuts | ||
754 | * down. | ||
755 | */ | ||
756 | static int pinctrl_hog_maps(struct pinctrl_dev *pctldev) | ||
757 | { | ||
758 | struct device *dev = pctldev->dev; | ||
759 | const char *devname = dev_name(dev); | ||
760 | int ret; | ||
761 | struct pinctrl_maps *maps_node; | ||
762 | int i; | ||
763 | struct pinctrl_map const *map; | ||
764 | |||
765 | INIT_LIST_HEAD(&pctldev->pinctrl_hogs); | ||
766 | |||
767 | mutex_lock(&pinctrl_maps_mutex); | ||
768 | for_each_maps(maps_node, i, map) { | ||
769 | if (!strcmp(map->ctrl_dev_name, devname) && | ||
770 | !strcmp(map->dev_name, devname)) { | ||
771 | /* OK time to hog! */ | ||
772 | ret = pinctrl_hog_map(pctldev, map); | ||
773 | if (ret) { | ||
774 | mutex_unlock(&pinctrl_maps_mutex); | ||
775 | return ret; | ||
776 | } | ||
777 | } | ||
778 | } | ||
779 | mutex_unlock(&pinctrl_maps_mutex); | ||
780 | |||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | /** | ||
785 | * pinctrl_unhog_maps() - unhog specific map entries on controller device | ||
786 | * @pctldev: the pin control device to unhog entries on | ||
787 | */ | ||
788 | static void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) | ||
789 | { | ||
790 | struct list_head *node, *tmp; | ||
791 | |||
792 | list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { | ||
793 | struct pinctrl_hog *hog = | ||
794 | list_entry(node, struct pinctrl_hog, node); | ||
795 | pinctrl_disable(hog->p); | ||
796 | pinctrl_put(hog->p); | ||
797 | list_del(node); | ||
798 | kfree(hog); | ||
799 | } | ||
800 | } | ||
801 | |||
802 | #ifdef CONFIG_DEBUG_FS | 693 | #ifdef CONFIG_DEBUG_FS |
803 | 694 | ||
804 | static int pinctrl_pins_show(struct seq_file *s, void *what) | 695 | static int pinctrl_pins_show(struct seq_file *s, void *what) |
@@ -889,19 +780,6 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) | |||
889 | return 0; | 780 | return 0; |
890 | } | 781 | } |
891 | 782 | ||
892 | static int pinmux_hogs_show(struct seq_file *s, void *what) | ||
893 | { | ||
894 | struct pinctrl_dev *pctldev = s->private; | ||
895 | struct pinctrl_hog *hog; | ||
896 | |||
897 | seq_puts(s, "Pin control map hogs held by device\n"); | ||
898 | |||
899 | list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) | ||
900 | seq_printf(s, "%s\n", hog->map->name); | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static int pinctrl_devices_show(struct seq_file *s, void *what) | 783 | static int pinctrl_devices_show(struct seq_file *s, void *what) |
906 | { | 784 | { |
907 | struct pinctrl_dev *pctldev; | 785 | struct pinctrl_dev *pctldev; |
@@ -988,11 +866,6 @@ static int pinctrl_gpioranges_open(struct inode *inode, struct file *file) | |||
988 | return single_open(file, pinctrl_gpioranges_show, inode->i_private); | 866 | return single_open(file, pinctrl_gpioranges_show, inode->i_private); |
989 | } | 867 | } |
990 | 868 | ||
991 | static int pinmux_hogs_open(struct inode *inode, struct file *file) | ||
992 | { | ||
993 | return single_open(file, pinmux_hogs_show, inode->i_private); | ||
994 | } | ||
995 | |||
996 | static int pinctrl_devices_open(struct inode *inode, struct file *file) | 869 | static int pinctrl_devices_open(struct inode *inode, struct file *file) |
997 | { | 870 | { |
998 | return single_open(file, pinctrl_devices_show, NULL); | 871 | return single_open(file, pinctrl_devices_show, NULL); |
@@ -1029,13 +902,6 @@ static const struct file_operations pinctrl_gpioranges_ops = { | |||
1029 | .release = single_release, | 902 | .release = single_release, |
1030 | }; | 903 | }; |
1031 | 904 | ||
1032 | static const struct file_operations pinmux_hogs_ops = { | ||
1033 | .open = pinmux_hogs_open, | ||
1034 | .read = seq_read, | ||
1035 | .llseek = seq_lseek, | ||
1036 | .release = single_release, | ||
1037 | }; | ||
1038 | |||
1039 | static const struct file_operations pinctrl_devices_ops = { | 905 | static const struct file_operations pinctrl_devices_ops = { |
1040 | .open = pinctrl_devices_open, | 906 | .open = pinctrl_devices_open, |
1041 | .read = seq_read, | 907 | .read = seq_read, |
@@ -1078,8 +944,6 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) | |||
1078 | device_root, pctldev, &pinctrl_groups_ops); | 944 | device_root, pctldev, &pinctrl_groups_ops); |
1079 | debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, | 945 | debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, |
1080 | device_root, pctldev, &pinctrl_gpioranges_ops); | 946 | device_root, pctldev, &pinctrl_gpioranges_ops); |
1081 | debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, | ||
1082 | device_root, pctldev, &pinmux_hogs_ops); | ||
1083 | pinmux_init_device_debugfs(device_root, pctldev); | 947 | pinmux_init_device_debugfs(device_root, pctldev); |
1084 | pinconf_init_device_debugfs(device_root, pctldev); | 948 | pinconf_init_device_debugfs(device_root, pctldev); |
1085 | } | 949 | } |
@@ -1188,7 +1052,9 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, | |||
1188 | mutex_lock(&pinctrldev_list_mutex); | 1052 | mutex_lock(&pinctrldev_list_mutex); |
1189 | list_add_tail(&pctldev->node, &pinctrldev_list); | 1053 | list_add_tail(&pctldev->node, &pinctrldev_list); |
1190 | mutex_unlock(&pinctrldev_list_mutex); | 1054 | mutex_unlock(&pinctrldev_list_mutex); |
1191 | pinctrl_hog_maps(pctldev); | 1055 | pctldev->p = pinctrl_get(pctldev->dev, PINCTRL_STATE_DEFAULT); |
1056 | if (!IS_ERR(pctldev->p)) | ||
1057 | pinctrl_enable(pctldev->p); | ||
1192 | pinctrl_init_device_debugfs(pctldev); | 1058 | pinctrl_init_device_debugfs(pctldev); |
1193 | 1059 | ||
1194 | return pctldev; | 1060 | return pctldev; |
@@ -1211,7 +1077,10 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) | |||
1211 | return; | 1077 | return; |
1212 | 1078 | ||
1213 | pinctrl_remove_device_debugfs(pctldev); | 1079 | pinctrl_remove_device_debugfs(pctldev); |
1214 | pinctrl_unhog_maps(pctldev); | 1080 | if (!IS_ERR(pctldev->p)) { |
1081 | pinctrl_disable(pctldev->p); | ||
1082 | pinctrl_put(pctldev->p); | ||
1083 | } | ||
1215 | /* TODO: check that no pinmuxes are still active? */ | 1084 | /* TODO: check that no pinmuxes are still active? */ |
1216 | mutex_lock(&pinctrldev_list_mutex); | 1085 | mutex_lock(&pinctrldev_list_mutex); |
1217 | list_del(&pctldev->node); | 1086 | list_del(&pctldev->node); |
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 8164e7b4182b..97f8124b4381 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
@@ -27,7 +27,7 @@ struct pinctrl_gpio_range; | |||
27 | * @owner: module providing the pin controller, used for refcounting | 27 | * @owner: module providing the pin controller, used for refcounting |
28 | * @driver_data: driver data for drivers registering to the pin controller | 28 | * @driver_data: driver data for drivers registering to the pin controller |
29 | * subsystem | 29 | * subsystem |
30 | * @pinctrl_hogs: list of pin control maps hogged by this device | 30 | * @p: result of pinctrl_get() for this device |
31 | * @device_root: debugfs root for this device | 31 | * @device_root: debugfs root for this device |
32 | */ | 32 | */ |
33 | struct pinctrl_dev { | 33 | struct pinctrl_dev { |
@@ -39,7 +39,7 @@ struct pinctrl_dev { | |||
39 | struct device *dev; | 39 | struct device *dev; |
40 | struct module *owner; | 40 | struct module *owner; |
41 | void *driver_data; | 41 | void *driver_data; |
42 | struct list_head pinctrl_hogs; | 42 | struct pinctrl *p; |
43 | #ifdef CONFIG_DEBUG_FS | 43 | #ifdef CONFIG_DEBUG_FS |
44 | struct dentry *device_root; | 44 | struct dentry *device_root; |
45 | #endif | 45 | #endif |