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