bump to v3.8
[openwrt/openwrt.git] / target / linux / lantiq / patches-3.8 / 0007-PINCTRL-lantiq-add-pin_config_group_set-support.patch
1 From 325ba34823f454c35c814d72022ba736ad56a1d4 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Wed, 30 Jan 2013 18:21:48 +0100
4 Subject: [PATCH 07/40] PINCTRL: lantiq: add pin_config_group_set support
5
6 While converting all the boards supported by OpenWrt to OF I noticed that this
7 feature is missing. Adding it makes the devicetrees more readable.
8
9 Signed-off-by: John Crispin <blogic@openwrt.org>
10 ---
11 drivers/pinctrl/pinctrl-lantiq.c | 54 ++++++++++++++++++++++++--------------
12 drivers/pinctrl/pinctrl-xway.c | 15 +++++++++++
13 2 files changed, 49 insertions(+), 20 deletions(-)
14
15 diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c
16 index 15f501d..7d11072 100644
17 --- a/drivers/pinctrl/pinctrl-lantiq.c
18 +++ b/drivers/pinctrl/pinctrl-lantiq.c
19 @@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
20 seq_printf(s, " %s", dev_name(pctldev->dev));
21 }
22
23 -static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
24 +static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
25 struct device_node *np,
26 struct pinctrl_map **map)
27 {
28 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
29 + struct property *pins = of_find_property(np, "lantiq,pins", NULL);
30 + struct property *groups = of_find_property(np, "lantiq,groups", NULL);
31 unsigned long configs[3];
32 unsigned num_configs = 0;
33 struct property *prop;
34 @@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
35 const char *function;
36 int ret, i;
37
38 + if (!pins && !groups) {
39 + dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
40 + np->name);
41 + return;
42 + }
43 +
44 + if (pins && groups) {
45 + dev_err(pctldev->dev, "%s defines both pins and groups\n",
46 + np->name);
47 + return;
48 + }
49 +
50 ret = of_property_read_string(np, "lantiq,function", &function);
51 - if (!ret) {
52 + if (groups && !ret) {
53 of_property_for_each_string(np, "lantiq,groups", prop, group) {
54 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
55 (*map)->name = function;
56 @@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
57 (*map)->data.mux.function = function;
58 (*map)++;
59 }
60 - if (of_find_property(np, "lantiq,pins", NULL))
61 - dev_err(pctldev->dev,
62 - "%s mixes pins and groups settings\n",
63 - np->name);
64 - return 0;
65 }
66
67 for (i = 0; i < info->num_params; i++) {
68 @@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
69 }
70
71 if (!num_configs)
72 - return -EINVAL;
73 + return;
74
75 of_property_for_each_string(np, "lantiq,pins", prop, pin) {
76 (*map)->data.configs.configs = kmemdup(configs,
77 @@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
78 (*map)->data.configs.num_configs = num_configs;
79 (*map)++;
80 }
81 - return 0;
82 + of_property_for_each_string(np, "lantiq,groups", prop, group) {
83 + (*map)->data.configs.configs = kmemdup(configs,
84 + num_configs * sizeof(unsigned long),
85 + GFP_KERNEL);
86 + (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
87 + (*map)->name = group;
88 + (*map)->data.configs.group_or_pin = group;
89 + (*map)->data.configs.num_configs = num_configs;
90 + (*map)++;
91 + }
92 }
93
94 static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
95 @@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
96 {
97 struct pinctrl_map *tmp;
98 struct device_node *np;
99 - int ret;
100 + int max_maps = 0;
101
102 - *num_maps = 0;
103 for_each_child_of_node(np_config, np)
104 - *num_maps += ltq_pinctrl_dt_subnode_size(np);
105 - *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
106 + max_maps += ltq_pinctrl_dt_subnode_size(np);
107 + *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
108 if (!*map)
109 return -ENOMEM;
110 tmp = *map;
111
112 - for_each_child_of_node(np_config, np) {
113 - ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
114 - if (ret < 0) {
115 - ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
116 - return ret;
117 - }
118 - }
119 + for_each_child_of_node(np_config, np)
120 + ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
121 + *num_maps = ((int)(tmp - *map));
122 +
123 return 0;
124 }
125
126 diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
127 index c49c9db..aa4c8b8 100644
128 --- a/drivers/pinctrl/pinctrl-xway.c
129 +++ b/drivers/pinctrl/pinctrl-xway.c
130 @@ -522,9 +522,24 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
131 return 0;
132 }
133
134 +int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
135 + unsigned selector,
136 + unsigned long config)
137 +{
138 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
139 + int i, ret = 0;
140 +
141 + for (i = 0; i < info->grps[selector].npins && !ret; i++)
142 + ret = xway_pinconf_set(pctldev,
143 + info->grps[selector].pins[i], config);
144 +
145 + return ret;
146 +}
147 +
148 static struct pinconf_ops xway_pinconf_ops = {
149 .pin_config_get = xway_pinconf_get,
150 .pin_config_set = xway_pinconf_set,
151 + .pin_config_group_set = xway_pinconf_group_set,
152 };
153
154 static struct pinctrl_desc xway_pctrl_desc = {
155 --
156 1.7.10.4
157