]>
Commit | Line | Data |
---|---|---|
30612cd9 MP |
1 | /* |
2 | * Core driver for the imx pin controller in imx1/21/27 | |
3 | * | |
4 | * Copyright (C) 2013 Pengutronix | |
5 | * Author: Markus Pargmann <mpa@pengutronix.de> | |
6 | * | |
7 | * Based on pinctrl-imx.c: | |
8 | * Author: Dong Aisheng <dong.aisheng@linaro.org> | |
9 | * Copyright (C) 2012 Freescale Semiconductor, Inc. | |
10 | * Copyright (C) 2012 Linaro Ltd. | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU General Public License as published by | |
14 | * the Free Software Foundation; either version 2 of the License, or | |
15 | * (at your option) any later version. | |
16 | */ | |
17 | ||
18 | #include <linux/bitops.h> | |
19 | #include <linux/err.h> | |
20 | #include <linux/init.h> | |
21 | #include <linux/io.h> | |
22 | #include <linux/module.h> | |
23 | #include <linux/of.h> | |
24 | #include <linux/of_device.h> | |
25 | #include <linux/pinctrl/machine.h> | |
26 | #include <linux/pinctrl/pinconf.h> | |
27 | #include <linux/pinctrl/pinctrl.h> | |
28 | #include <linux/pinctrl/pinmux.h> | |
29 | #include <linux/slab.h> | |
30 | ||
edad3b2a | 31 | #include "../core.h" |
30612cd9 MP |
32 | #include "pinctrl-imx1.h" |
33 | ||
34 | struct imx1_pinctrl { | |
35 | struct device *dev; | |
36 | struct pinctrl_dev *pctl; | |
37 | void __iomem *base; | |
38 | const struct imx1_pinctrl_soc_info *info; | |
39 | }; | |
40 | ||
41 | /* | |
42 | * MX1 register offsets | |
43 | */ | |
44 | ||
45 | #define MX1_DDIR 0x00 | |
46 | #define MX1_OCR 0x04 | |
47 | #define MX1_ICONFA 0x0c | |
795779df | 48 | #define MX1_ICONFB 0x14 |
30612cd9 MP |
49 | #define MX1_GIUS 0x20 |
50 | #define MX1_GPR 0x38 | |
51 | #define MX1_PUEN 0x40 | |
52 | ||
53 | #define MX1_PORT_STRIDE 0x100 | |
54 | ||
55 | ||
56 | /* | |
57 | * MUX_ID format defines | |
58 | */ | |
59 | #define MX1_MUX_FUNCTION(val) (BIT(0) & val) | |
60 | #define MX1_MUX_GPIO(val) ((BIT(1) & val) >> 1) | |
61 | #define MX1_MUX_DIR(val) ((BIT(2) & val) >> 2) | |
62 | #define MX1_MUX_OCONF(val) (((BIT(4) | BIT(5)) & val) >> 4) | |
63 | #define MX1_MUX_ICONFA(val) (((BIT(8) | BIT(9)) & val) >> 8) | |
64 | #define MX1_MUX_ICONFB(val) (((BIT(10) | BIT(11)) & val) >> 10) | |
65 | ||
66 | ||
67 | /* | |
68 | * IMX1 IOMUXC manages the pins based on ports. Each port has 32 pins. IOMUX | |
69 | * control register are seperated into function, output configuration, input | |
70 | * configuration A, input configuration B, GPIO in use and data direction. | |
71 | * | |
72 | * Those controls that are represented by 1 bit have a direct mapping between | |
73 | * bit position and pin id. If they are represented by 2 bit, the lower 16 pins | |
74 | * are in the first register and the upper 16 pins in the second (next) | |
75 | * register. pin_id is stored in bit (pin_id%16)*2 and the bit above. | |
76 | */ | |
77 | ||
78 | /* | |
79 | * Calculates the register offset from a pin_id | |
80 | */ | |
81 | static void __iomem *imx1_mem(struct imx1_pinctrl *ipctl, unsigned int pin_id) | |
82 | { | |
83 | unsigned int port = pin_id / 32; | |
84 | return ipctl->base + port * MX1_PORT_STRIDE; | |
85 | } | |
86 | ||
87 | /* | |
88 | * Write to a register with 2 bits per pin. The function will automatically | |
89 | * use the next register if the pin is managed in the second register. | |
90 | */ | |
91 | static void imx1_write_2bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, | |
92 | u32 value, u32 reg_offset) | |
93 | { | |
94 | void __iomem *reg = imx1_mem(ipctl, pin_id) + reg_offset; | |
95 | int offset = (pin_id % 16) * 2; /* offset, regardless of register used */ | |
96 | int mask = ~(0x3 << offset); /* Mask for 2 bits at offset */ | |
97 | u32 old_val; | |
98 | u32 new_val; | |
99 | ||
30612cd9 MP |
100 | /* Use the next register if the pin's port pin number is >=16 */ |
101 | if (pin_id % 32 >= 16) | |
102 | reg += 0x04; | |
103 | ||
795779df CR |
104 | dev_dbg(ipctl->dev, "write: register 0x%p offset %d value 0x%x\n", |
105 | reg, offset, value); | |
106 | ||
30612cd9 MP |
107 | /* Get current state of pins */ |
108 | old_val = readl(reg); | |
109 | old_val &= mask; | |
110 | ||
111 | new_val = value & 0x3; /* Make sure value is really 2 bit */ | |
112 | new_val <<= offset; | |
113 | new_val |= old_val;/* Set new state for pin_id */ | |
114 | ||
115 | writel(new_val, reg); | |
116 | } | |
117 | ||
118 | static void imx1_write_bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, | |
119 | u32 value, u32 reg_offset) | |
120 | { | |
121 | void __iomem *reg = imx1_mem(ipctl, pin_id) + reg_offset; | |
122 | int offset = pin_id % 32; | |
123 | int mask = ~BIT_MASK(offset); | |
124 | u32 old_val; | |
125 | u32 new_val; | |
126 | ||
127 | /* Get current state of pins */ | |
128 | old_val = readl(reg); | |
129 | old_val &= mask; | |
130 | ||
131 | new_val = value & 0x1; /* Make sure value is really 1 bit */ | |
132 | new_val <<= offset; | |
133 | new_val |= old_val;/* Set new state for pin_id */ | |
134 | ||
135 | writel(new_val, reg); | |
136 | } | |
137 | ||
138 | static int imx1_read_2bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, | |
139 | u32 reg_offset) | |
140 | { | |
141 | void __iomem *reg = imx1_mem(ipctl, pin_id) + reg_offset; | |
e3365d09 | 142 | int offset = (pin_id % 16) * 2; |
30612cd9 MP |
143 | |
144 | /* Use the next register if the pin's port pin number is >=16 */ | |
145 | if (pin_id % 32 >= 16) | |
146 | reg += 0x04; | |
147 | ||
148 | return (readl(reg) & (BIT(offset) | BIT(offset+1))) >> offset; | |
149 | } | |
150 | ||
151 | static int imx1_read_bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, | |
152 | u32 reg_offset) | |
153 | { | |
154 | void __iomem *reg = imx1_mem(ipctl, pin_id) + reg_offset; | |
155 | int offset = pin_id % 32; | |
156 | ||
157 | return !!(readl(reg) & BIT(offset)); | |
158 | } | |
159 | ||
160 | static const inline struct imx1_pin_group *imx1_pinctrl_find_group_by_name( | |
161 | const struct imx1_pinctrl_soc_info *info, | |
162 | const char *name) | |
163 | { | |
164 | const struct imx1_pin_group *grp = NULL; | |
165 | int i; | |
166 | ||
167 | for (i = 0; i < info->ngroups; i++) { | |
168 | if (!strcmp(info->groups[i].name, name)) { | |
169 | grp = &info->groups[i]; | |
170 | break; | |
171 | } | |
172 | } | |
173 | ||
174 | return grp; | |
175 | } | |
176 | ||
177 | static int imx1_get_groups_count(struct pinctrl_dev *pctldev) | |
178 | { | |
179 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
180 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
181 | ||
182 | return info->ngroups; | |
183 | } | |
184 | ||
185 | static const char *imx1_get_group_name(struct pinctrl_dev *pctldev, | |
186 | unsigned selector) | |
187 | { | |
188 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
189 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
190 | ||
191 | return info->groups[selector].name; | |
192 | } | |
193 | ||
194 | static int imx1_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, | |
195 | const unsigned int **pins, | |
196 | unsigned *npins) | |
197 | { | |
198 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
199 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
200 | ||
201 | if (selector >= info->ngroups) | |
202 | return -EINVAL; | |
203 | ||
204 | *pins = info->groups[selector].pin_ids; | |
205 | *npins = info->groups[selector].npins; | |
206 | ||
207 | return 0; | |
208 | } | |
209 | ||
210 | static void imx1_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, | |
211 | unsigned offset) | |
212 | { | |
213 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
214 | ||
215 | seq_printf(s, "GPIO %d, function %d, direction %d, oconf %d, iconfa %d, iconfb %d", | |
216 | imx1_read_bit(ipctl, offset, MX1_GIUS), | |
217 | imx1_read_bit(ipctl, offset, MX1_GPR), | |
218 | imx1_read_bit(ipctl, offset, MX1_DDIR), | |
219 | imx1_read_2bit(ipctl, offset, MX1_OCR), | |
220 | imx1_read_2bit(ipctl, offset, MX1_ICONFA), | |
221 | imx1_read_2bit(ipctl, offset, MX1_ICONFB)); | |
222 | } | |
223 | ||
224 | static int imx1_dt_node_to_map(struct pinctrl_dev *pctldev, | |
225 | struct device_node *np, | |
226 | struct pinctrl_map **map, unsigned *num_maps) | |
227 | { | |
228 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
229 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
230 | const struct imx1_pin_group *grp; | |
231 | struct pinctrl_map *new_map; | |
232 | struct device_node *parent; | |
233 | int map_num = 1; | |
234 | int i, j; | |
235 | ||
236 | /* | |
237 | * first find the group of this node and check if we need create | |
238 | * config maps for pins | |
239 | */ | |
240 | grp = imx1_pinctrl_find_group_by_name(info, np->name); | |
241 | if (!grp) { | |
242 | dev_err(info->dev, "unable to find group for node %s\n", | |
243 | np->name); | |
244 | return -EINVAL; | |
245 | } | |
246 | ||
247 | for (i = 0; i < grp->npins; i++) | |
248 | map_num++; | |
249 | ||
250 | new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL); | |
251 | if (!new_map) | |
252 | return -ENOMEM; | |
253 | ||
254 | *map = new_map; | |
255 | *num_maps = map_num; | |
256 | ||
257 | /* create mux map */ | |
258 | parent = of_get_parent(np); | |
259 | if (!parent) { | |
260 | kfree(new_map); | |
261 | return -EINVAL; | |
262 | } | |
263 | new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; | |
264 | new_map[0].data.mux.function = parent->name; | |
265 | new_map[0].data.mux.group = np->name; | |
266 | of_node_put(parent); | |
267 | ||
268 | /* create config map */ | |
269 | new_map++; | |
270 | for (i = j = 0; i < grp->npins; i++) { | |
271 | new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN; | |
272 | new_map[j].data.configs.group_or_pin = | |
273 | pin_get_name(pctldev, grp->pins[i].pin_id); | |
274 | new_map[j].data.configs.configs = &grp->pins[i].config; | |
275 | new_map[j].data.configs.num_configs = 1; | |
276 | j++; | |
277 | } | |
278 | ||
279 | dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", | |
280 | (*map)->data.mux.function, (*map)->data.mux.group, map_num); | |
281 | ||
282 | return 0; | |
283 | } | |
284 | ||
285 | static void imx1_dt_free_map(struct pinctrl_dev *pctldev, | |
286 | struct pinctrl_map *map, unsigned num_maps) | |
287 | { | |
288 | kfree(map); | |
289 | } | |
290 | ||
291 | static const struct pinctrl_ops imx1_pctrl_ops = { | |
292 | .get_groups_count = imx1_get_groups_count, | |
293 | .get_group_name = imx1_get_group_name, | |
294 | .get_group_pins = imx1_get_group_pins, | |
295 | .pin_dbg_show = imx1_pin_dbg_show, | |
296 | .dt_node_to_map = imx1_dt_node_to_map, | |
297 | .dt_free_map = imx1_dt_free_map, | |
298 | ||
299 | }; | |
300 | ||
03e9f0ca LW |
301 | static int imx1_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, |
302 | unsigned group) | |
30612cd9 MP |
303 | { |
304 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
305 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
306 | const struct imx1_pin *pins; | |
307 | unsigned int npins; | |
308 | int i; | |
309 | ||
310 | /* | |
311 | * Configure the mux mode for each pin in the group for a specific | |
312 | * function. | |
313 | */ | |
314 | pins = info->groups[group].pins; | |
315 | npins = info->groups[group].npins; | |
316 | ||
317 | WARN_ON(!pins || !npins); | |
318 | ||
319 | dev_dbg(ipctl->dev, "enable function %s group %s\n", | |
320 | info->functions[selector].name, info->groups[group].name); | |
321 | ||
322 | for (i = 0; i < npins; i++) { | |
323 | unsigned int mux = pins[i].mux_id; | |
324 | unsigned int pin_id = pins[i].pin_id; | |
325 | unsigned int afunction = MX1_MUX_FUNCTION(mux); | |
326 | unsigned int gpio_in_use = MX1_MUX_GPIO(mux); | |
327 | unsigned int direction = MX1_MUX_DIR(mux); | |
328 | unsigned int gpio_oconf = MX1_MUX_OCONF(mux); | |
329 | unsigned int gpio_iconfa = MX1_MUX_ICONFA(mux); | |
330 | unsigned int gpio_iconfb = MX1_MUX_ICONFB(mux); | |
331 | ||
332 | dev_dbg(pctldev->dev, "%s, pin 0x%x, function %d, gpio %d, direction %d, oconf %d, iconfa %d, iconfb %d\n", | |
333 | __func__, pin_id, afunction, gpio_in_use, | |
334 | direction, gpio_oconf, gpio_iconfa, | |
335 | gpio_iconfb); | |
336 | ||
337 | imx1_write_bit(ipctl, pin_id, gpio_in_use, MX1_GIUS); | |
338 | imx1_write_bit(ipctl, pin_id, direction, MX1_DDIR); | |
339 | ||
340 | if (gpio_in_use) { | |
341 | imx1_write_2bit(ipctl, pin_id, gpio_oconf, MX1_OCR); | |
342 | imx1_write_2bit(ipctl, pin_id, gpio_iconfa, | |
343 | MX1_ICONFA); | |
344 | imx1_write_2bit(ipctl, pin_id, gpio_iconfb, | |
345 | MX1_ICONFB); | |
346 | } else { | |
347 | imx1_write_bit(ipctl, pin_id, afunction, MX1_GPR); | |
348 | } | |
349 | } | |
350 | ||
351 | return 0; | |
352 | } | |
353 | ||
354 | static int imx1_pmx_get_funcs_count(struct pinctrl_dev *pctldev) | |
355 | { | |
356 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
357 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
358 | ||
359 | return info->nfunctions; | |
360 | } | |
361 | ||
362 | static const char *imx1_pmx_get_func_name(struct pinctrl_dev *pctldev, | |
363 | unsigned selector) | |
364 | { | |
365 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
366 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
367 | ||
368 | return info->functions[selector].name; | |
369 | } | |
370 | ||
371 | static int imx1_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, | |
372 | const char * const **groups, | |
373 | unsigned * const num_groups) | |
374 | { | |
375 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
376 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
377 | ||
378 | *groups = info->functions[selector].groups; | |
379 | *num_groups = info->functions[selector].num_groups; | |
380 | ||
381 | return 0; | |
382 | } | |
383 | ||
384 | static const struct pinmux_ops imx1_pmx_ops = { | |
385 | .get_functions_count = imx1_pmx_get_funcs_count, | |
386 | .get_function_name = imx1_pmx_get_func_name, | |
387 | .get_function_groups = imx1_pmx_get_groups, | |
03e9f0ca | 388 | .set_mux = imx1_pmx_set, |
30612cd9 MP |
389 | }; |
390 | ||
391 | static int imx1_pinconf_get(struct pinctrl_dev *pctldev, | |
392 | unsigned pin_id, unsigned long *config) | |
393 | { | |
394 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
395 | ||
396 | *config = imx1_read_bit(ipctl, pin_id, MX1_PUEN); | |
397 | ||
398 | return 0; | |
399 | } | |
400 | ||
401 | static int imx1_pinconf_set(struct pinctrl_dev *pctldev, | |
402 | unsigned pin_id, unsigned long *configs, | |
403 | unsigned num_configs) | |
404 | { | |
405 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
30612cd9 MP |
406 | int i; |
407 | ||
408 | for (i = 0; i != num_configs; ++i) { | |
409 | imx1_write_bit(ipctl, pin_id, configs[i] & 0x01, MX1_PUEN); | |
410 | ||
411 | dev_dbg(ipctl->dev, "pinconf set pullup pin %s\n", | |
9571b25d | 412 | pin_desc_get(pctldev, pin_id)->name); |
30612cd9 MP |
413 | } |
414 | ||
415 | return 0; | |
416 | } | |
417 | ||
418 | static void imx1_pinconf_dbg_show(struct pinctrl_dev *pctldev, | |
419 | struct seq_file *s, unsigned pin_id) | |
420 | { | |
421 | unsigned long config; | |
422 | ||
423 | imx1_pinconf_get(pctldev, pin_id, &config); | |
424 | seq_printf(s, "0x%lx", config); | |
425 | } | |
426 | ||
427 | static void imx1_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, | |
428 | struct seq_file *s, unsigned group) | |
429 | { | |
430 | struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
431 | const struct imx1_pinctrl_soc_info *info = ipctl->info; | |
432 | struct imx1_pin_group *grp; | |
433 | unsigned long config; | |
434 | const char *name; | |
435 | int i, ret; | |
436 | ||
437 | if (group > info->ngroups) | |
438 | return; | |
439 | ||
440 | seq_puts(s, "\n"); | |
441 | grp = &info->groups[group]; | |
442 | for (i = 0; i < grp->npins; i++) { | |
443 | name = pin_get_name(pctldev, grp->pins[i].pin_id); | |
444 | ret = imx1_pinconf_get(pctldev, grp->pins[i].pin_id, &config); | |
445 | if (ret) | |
446 | return; | |
447 | seq_printf(s, "%s: 0x%lx", name, config); | |
448 | } | |
449 | } | |
450 | ||
451 | static const struct pinconf_ops imx1_pinconf_ops = { | |
452 | .pin_config_get = imx1_pinconf_get, | |
453 | .pin_config_set = imx1_pinconf_set, | |
454 | .pin_config_dbg_show = imx1_pinconf_dbg_show, | |
455 | .pin_config_group_dbg_show = imx1_pinconf_group_dbg_show, | |
456 | }; | |
457 | ||
458 | static struct pinctrl_desc imx1_pinctrl_desc = { | |
459 | .pctlops = &imx1_pctrl_ops, | |
460 | .pmxops = &imx1_pmx_ops, | |
461 | .confops = &imx1_pinconf_ops, | |
462 | .owner = THIS_MODULE, | |
463 | }; | |
464 | ||
465 | static int imx1_pinctrl_parse_groups(struct device_node *np, | |
466 | struct imx1_pin_group *grp, | |
467 | struct imx1_pinctrl_soc_info *info, | |
468 | u32 index) | |
469 | { | |
470 | int size; | |
471 | const __be32 *list; | |
472 | int i; | |
473 | ||
474 | dev_dbg(info->dev, "group(%d): %s\n", index, np->name); | |
475 | ||
476 | /* Initialise group */ | |
477 | grp->name = np->name; | |
478 | ||
479 | /* | |
480 | * the binding format is fsl,pins = <PIN MUX_ID CONFIG> | |
481 | */ | |
482 | list = of_get_property(np, "fsl,pins", &size); | |
483 | /* we do not check return since it's safe node passed down */ | |
484 | if (!size || size % 12) { | |
485 | dev_notice(info->dev, "Not a valid fsl,pins property (%s)\n", | |
486 | np->name); | |
487 | return -EINVAL; | |
488 | } | |
489 | ||
490 | grp->npins = size / 12; | |
491 | grp->pins = devm_kzalloc(info->dev, | |
492 | grp->npins * sizeof(struct imx1_pin), GFP_KERNEL); | |
493 | grp->pin_ids = devm_kzalloc(info->dev, | |
494 | grp->npins * sizeof(unsigned int), GFP_KERNEL); | |
495 | ||
496 | if (!grp->pins || !grp->pin_ids) | |
497 | return -ENOMEM; | |
498 | ||
499 | for (i = 0; i < grp->npins; i++) { | |
500 | grp->pins[i].pin_id = be32_to_cpu(*list++); | |
501 | grp->pins[i].mux_id = be32_to_cpu(*list++); | |
502 | grp->pins[i].config = be32_to_cpu(*list++); | |
503 | ||
504 | grp->pin_ids[i] = grp->pins[i].pin_id; | |
505 | } | |
506 | ||
507 | return 0; | |
508 | } | |
509 | ||
510 | static int imx1_pinctrl_parse_functions(struct device_node *np, | |
511 | struct imx1_pinctrl_soc_info *info, | |
512 | u32 index) | |
513 | { | |
514 | struct device_node *child; | |
515 | struct imx1_pmx_func *func; | |
516 | struct imx1_pin_group *grp; | |
517 | int ret; | |
518 | static u32 grp_index; | |
519 | u32 i = 0; | |
520 | ||
521 | dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); | |
522 | ||
523 | func = &info->functions[index]; | |
524 | ||
525 | /* Initialise function */ | |
526 | func->name = np->name; | |
527 | func->num_groups = of_get_child_count(np); | |
5aa498b9 | 528 | if (func->num_groups == 0) |
30612cd9 MP |
529 | return -EINVAL; |
530 | ||
531 | func->groups = devm_kzalloc(info->dev, | |
532 | func->num_groups * sizeof(char *), GFP_KERNEL); | |
533 | ||
534 | if (!func->groups) | |
535 | return -ENOMEM; | |
536 | ||
537 | for_each_child_of_node(np, child) { | |
538 | func->groups[i] = child->name; | |
539 | grp = &info->groups[grp_index++]; | |
540 | ret = imx1_pinctrl_parse_groups(child, grp, info, i++); | |
0563df2c VT |
541 | if (ret == -ENOMEM) { |
542 | of_node_put(child); | |
30612cd9 | 543 | return ret; |
0563df2c | 544 | } |
30612cd9 MP |
545 | } |
546 | ||
547 | return 0; | |
548 | } | |
549 | ||
550 | static int imx1_pinctrl_parse_dt(struct platform_device *pdev, | |
551 | struct imx1_pinctrl *pctl, struct imx1_pinctrl_soc_info *info) | |
552 | { | |
553 | struct device_node *np = pdev->dev.of_node; | |
554 | struct device_node *child; | |
555 | int ret; | |
556 | u32 nfuncs = 0; | |
557 | u32 ngroups = 0; | |
558 | u32 ifunc = 0; | |
559 | ||
560 | if (!np) | |
561 | return -ENODEV; | |
562 | ||
563 | for_each_child_of_node(np, child) { | |
564 | ++nfuncs; | |
565 | ngroups += of_get_child_count(child); | |
566 | } | |
567 | ||
568 | if (!nfuncs) { | |
569 | dev_err(&pdev->dev, "No pin functions defined\n"); | |
570 | return -EINVAL; | |
571 | } | |
572 | ||
573 | info->nfunctions = nfuncs; | |
574 | info->functions = devm_kzalloc(&pdev->dev, | |
575 | nfuncs * sizeof(struct imx1_pmx_func), GFP_KERNEL); | |
576 | ||
577 | info->ngroups = ngroups; | |
578 | info->groups = devm_kzalloc(&pdev->dev, | |
579 | ngroups * sizeof(struct imx1_pin_group), GFP_KERNEL); | |
580 | ||
581 | ||
582 | if (!info->functions || !info->groups) | |
583 | return -ENOMEM; | |
584 | ||
585 | for_each_child_of_node(np, child) { | |
586 | ret = imx1_pinctrl_parse_functions(child, info, ifunc++); | |
0563df2c VT |
587 | if (ret == -ENOMEM) { |
588 | of_node_put(child); | |
30612cd9 | 589 | return -ENOMEM; |
0563df2c | 590 | } |
30612cd9 MP |
591 | } |
592 | ||
593 | return 0; | |
594 | } | |
595 | ||
596 | int imx1_pinctrl_core_probe(struct platform_device *pdev, | |
597 | struct imx1_pinctrl_soc_info *info) | |
598 | { | |
599 | struct imx1_pinctrl *ipctl; | |
600 | struct resource *res; | |
601 | struct pinctrl_desc *pctl_desc; | |
602 | int ret; | |
603 | ||
604 | if (!info || !info->pins || !info->npins) { | |
605 | dev_err(&pdev->dev, "wrong pinctrl info\n"); | |
606 | return -EINVAL; | |
607 | } | |
608 | info->dev = &pdev->dev; | |
609 | ||
610 | /* Create state holders etc for this driver */ | |
611 | ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL); | |
612 | if (!ipctl) | |
613 | return -ENOMEM; | |
614 | ||
615 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
616 | if (!res) | |
617 | return -ENOENT; | |
618 | ||
619 | ipctl->base = devm_ioremap_nocache(&pdev->dev, res->start, | |
620 | resource_size(res)); | |
5e1109ad WY |
621 | if (!ipctl->base) |
622 | return -ENOMEM; | |
30612cd9 MP |
623 | |
624 | pctl_desc = &imx1_pinctrl_desc; | |
625 | pctl_desc->name = dev_name(&pdev->dev); | |
626 | pctl_desc->pins = info->pins; | |
627 | pctl_desc->npins = info->npins; | |
628 | ||
629 | ret = imx1_pinctrl_parse_dt(pdev, ipctl, info); | |
630 | if (ret) { | |
631 | dev_err(&pdev->dev, "fail to probe dt properties\n"); | |
632 | return ret; | |
633 | } | |
634 | ||
635 | ipctl->info = info; | |
636 | ipctl->dev = info->dev; | |
637 | platform_set_drvdata(pdev, ipctl); | |
e55e025d | 638 | ipctl->pctl = devm_pinctrl_register(&pdev->dev, pctl_desc, ipctl); |
323de9ef | 639 | if (IS_ERR(ipctl->pctl)) { |
30612cd9 | 640 | dev_err(&pdev->dev, "could not register IMX pinctrl driver\n"); |
323de9ef | 641 | return PTR_ERR(ipctl->pctl); |
30612cd9 MP |
642 | } |
643 | ||
31d610f1 MP |
644 | ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); |
645 | if (ret) { | |
646 | pinctrl_unregister(ipctl->pctl); | |
647 | dev_err(&pdev->dev, "Failed to populate subdevices\n"); | |
648 | return ret; | |
649 | } | |
650 | ||
30612cd9 MP |
651 | dev_info(&pdev->dev, "initialized IMX pinctrl driver\n"); |
652 | ||
653 | return 0; | |
654 | } |