add linux-v3.7
[openwrt/staging/lynxis/omap.git] / target / linux / lantiq / patches-3.7 / 0108-PINCTRL-lantiq-fixes.patch
1 From 13e754b5fff5be1930e2b8fe534a52b608c9e479 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Mon, 3 Dec 2012 19:27:28 +0100
4 Subject: [PATCH] PINCTRL: lantiq: fixes
5
6 ---
7 drivers/pinctrl/pinctrl-lantiq.c | 54 ++++++++++++++++++-----------
8 drivers/pinctrl/pinctrl-lantiq.h | 1 +
9 drivers/pinctrl/pinctrl-xway.c | 70 ++++++++++++++++++++++++++++++++++----
10 3 files changed, 99 insertions(+), 26 deletions(-)
11
12 Index: linux-3.7-rc8/drivers/pinctrl/pinctrl-lantiq.c
13 ===================================================================
14 --- linux-3.7-rc8.orig/drivers/pinctrl/pinctrl-lantiq.c 2012-12-03 20:22:37.000000000 +0100
15 +++ linux-3.7-rc8/drivers/pinctrl/pinctrl-lantiq.c 2012-12-14 22:59:40.687563565 +0100
16 @@ -64,11 +64,13 @@
17 seq_printf(s, " %s", dev_name(pctldev->dev));
18 }
19
20 -static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
21 +static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
22 struct device_node *np,
23 struct pinctrl_map **map)
24 {
25 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
26 + struct property *pins = of_find_property(np, "lantiq,pins", NULL);
27 + struct property *groups = of_find_property(np, "lantiq,groups", NULL);
28 unsigned long configs[3];
29 unsigned num_configs = 0;
30 struct property *prop;
31 @@ -76,8 +78,20 @@
32 const char *function;
33 int ret, i;
34
35 + if (!pins && !groups) {
36 + dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
37 + np->name);
38 + return;
39 + }
40 +
41 + if (pins && groups) {
42 + dev_err(pctldev->dev, "%s defines both pins and groups\n",
43 + np->name);
44 + return;
45 + }
46 +
47 ret = of_property_read_string(np, "lantiq,function", &function);
48 - if (!ret) {
49 + if (groups && !ret) {
50 of_property_for_each_string(np, "lantiq,groups", prop, group) {
51 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
52 (*map)->name = function;
53 @@ -85,11 +99,6 @@
54 (*map)->data.mux.function = function;
55 (*map)++;
56 }
57 - if (of_find_property(np, "lantiq,pins", NULL))
58 - dev_err(pctldev->dev,
59 - "%s mixes pins and groups settings\n",
60 - np->name);
61 - return 0;
62 }
63
64 for (i = 0; i < info->num_params; i++) {
65 @@ -103,7 +112,7 @@
66 }
67
68 if (!num_configs)
69 - return -EINVAL;
70 + return;
71
72 of_property_for_each_string(np, "lantiq,pins", prop, pin) {
73 (*map)->data.configs.configs = kmemdup(configs,
74 @@ -115,7 +124,16 @@
75 (*map)->data.configs.num_configs = num_configs;
76 (*map)++;
77 }
78 - return 0;
79 + of_property_for_each_string(np, "lantiq,groups", prop, group) {
80 + (*map)->data.configs.configs = kmemdup(configs,
81 + num_configs * sizeof(unsigned long),
82 + GFP_KERNEL);
83 + (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
84 + (*map)->name = group;
85 + (*map)->data.configs.group_or_pin = group;
86 + (*map)->data.configs.num_configs = num_configs;
87 + (*map)++;
88 + }
89 }
90
91 static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
92 @@ -135,23 +153,19 @@
93 {
94 struct pinctrl_map *tmp;
95 struct device_node *np;
96 - int ret;
97 + int max_maps = 0;
98
99 - *num_maps = 0;
100 for_each_child_of_node(np_config, np)
101 - *num_maps += ltq_pinctrl_dt_subnode_size(np);
102 - *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
103 + max_maps += ltq_pinctrl_dt_subnode_size(np);
104 + *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
105 if (!*map)
106 return -ENOMEM;
107 tmp = *map;
108
109 - for_each_child_of_node(np_config, np) {
110 - ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
111 - if (ret < 0) {
112 - ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
113 - return ret;
114 - }
115 - }
116 + for_each_child_of_node(np_config, np)
117 + ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
118 + *num_maps = ((int)(tmp - *map));
119 +
120 return 0;
121 }
122
123 Index: linux-3.7-rc8/drivers/pinctrl/pinctrl-lantiq.h
124 ===================================================================
125 --- linux-3.7-rc8.orig/drivers/pinctrl/pinctrl-lantiq.h 2012-12-03 20:22:37.000000000 +0100
126 +++ linux-3.7-rc8/drivers/pinctrl/pinctrl-lantiq.h 2012-12-14 22:55:26.591557194 +0100
127 @@ -34,6 +34,7 @@
128 LTQ_PINCONF_PARAM_OPEN_DRAIN,
129 LTQ_PINCONF_PARAM_DRIVE_CURRENT,
130 LTQ_PINCONF_PARAM_SLEW_RATE,
131 + LTQ_PINCONF_PARAM_OUTPUT,
132 };
133
134 struct ltq_cfg_param {
135 Index: linux-3.7-rc8/drivers/pinctrl/pinctrl-xway.c
136 ===================================================================
137 --- linux-3.7-rc8.orig/drivers/pinctrl/pinctrl-xway.c 2012-12-14 22:55:26.567557195 +0100
138 +++ linux-3.7-rc8/drivers/pinctrl/pinctrl-xway.c 2012-12-14 22:55:26.595557195 +0100
139 @@ -443,7 +443,7 @@
140 else
141 reg = GPIO_OD(pin);
142 *config = LTQ_PINCONF_PACK(param,
143 - !!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
144 + !gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
145 break;
146
147 case LTQ_PINCONF_PARAM_PULL:
148 @@ -466,6 +466,11 @@
149 *config = LTQ_PINCONF_PACK(param, 1);
150 break;
151
152 + case LTQ_PINCONF_PARAM_OUTPUT:
153 + reg = GPIO_DIR(pin);
154 + *config = LTQ_PINCONF_PACK(param,
155 + gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
156 + break;
157 default:
158 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
159 return -ENOTSUPP;
160 @@ -489,7 +494,10 @@
161 reg = GPIO3_OD;
162 else
163 reg = GPIO_OD(pin);
164 - gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
165 + if (arg == 0)
166 + gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
167 + else
168 + gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
169 break;
170
171 case LTQ_PINCONF_PARAM_PULL:
172 @@ -515,6 +523,14 @@
173 dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
174 break;
175
176 + case LTQ_PINCONF_PARAM_OUTPUT:
177 + reg = GPIO_DIR(pin);
178 + if (arg == 0)
179 + gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
180 + else
181 + gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
182 + break;
183 +
184 default:
185 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
186 return -ENOTSUPP;
187 @@ -522,9 +538,25 @@
188 return 0;
189 }
190
191 +int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
192 + unsigned selector,
193 + unsigned long config)
194 +{
195 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
196 + int i, ret = 0;
197 +
198 + for (i = 0; i < info->grps[selector].npins && !ret; i++)
199 + ret = xway_pinconf_set(pctldev,
200 + info->grps[selector].pins[i], config);
201 +
202 + return ret;
203 +}
204 +
205 +
206 struct pinconf_ops xway_pinconf_ops = {
207 .pin_config_get = xway_pinconf_get,
208 .pin_config_set = xway_pinconf_set,
209 + .pin_config_group_set = xway_pinconf_group_set,
210 };
211
212 static struct pinctrl_desc xway_pctrl_desc = {
213 @@ -532,10 +564,9 @@
214 .confops = &xway_pinconf_ops,
215 };
216
217 -static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
218 +static int mux_apply(struct ltq_pinmux_info *info,
219 int pin, int mux)
220 {
221 - struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
222 int port = PORT(pin);
223 u32 alt1_reg = GPIO_ALT1(pin);
224
225 @@ -555,9 +586,18 @@
226 return 0;
227 }
228
229 +static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
230 + int pin, int mux)
231 +{
232 + struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
233 +
234 + return mux_apply(info, pin, mux);
235 +}
236 +
237 static const struct ltq_cfg_param xway_cfg_params[] = {
238 {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
239 {"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
240 + {"lantiq,output", LTQ_PINCONF_PARAM_OUTPUT},
241 };
242
243 static struct ltq_pinmux_info xway_info = {
244 @@ -598,6 +638,10 @@
245 {
246 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
247
248 + if (PORT(pin) == PORT3)
249 + gpio_setbit(info->membase[0], GPIO3_OD, PORT_PIN(pin));
250 + else
251 + gpio_setbit(info->membase[0], GPIO_OD(pin), PORT_PIN(pin));
252 gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
253 xway_gpio_set(chip, pin, val);
254
255 @@ -618,6 +662,18 @@
256 pinctrl_free_gpio(gpio);
257 }
258
259 +static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
260 +{
261 + struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
262 + int i;
263 +
264 + for (i = 0; i < info->num_exin; i++)
265 + if (info->exin[i] == offset)
266 + return ltq_eiu_get_irq(i);
267 +
268 + return -1;
269 +}
270 +
271 static struct gpio_chip xway_chip = {
272 .label = "gpio-xway",
273 .direction_input = xway_gpio_dir_in,
274 @@ -626,6 +682,7 @@
275 .set = xway_gpio_set,
276 .request = xway_gpio_req,
277 .free = xway_gpio_free,
278 + .to_irq = xway_gpio_to_irq,
279 .base = -1,
280 };
281