1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Core driver for the S32 CC (Common Chassis) pin controller |
4 | * |
5 | * Copyright 2017-2022 NXP |
6 | * Copyright (C) 2022 SUSE LLC |
7 | * Copyright 2015-2016 Freescale Semiconductor, Inc. |
8 | */ |
9 | |
10 | #include <linux/bitops.h> |
11 | #include <linux/err.h> |
12 | #include <linux/gpio/driver.h> |
13 | #include <linux/init.h> |
14 | #include <linux/io.h> |
15 | #include <linux/module.h> |
16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/pinctrl/machine.h> |
19 | #include <linux/pinctrl/pinconf.h> |
20 | #include <linux/pinctrl/pinctrl.h> |
21 | #include <linux/pinctrl/pinmux.h> |
22 | #include <linux/regmap.h> |
23 | #include <linux/seq_file.h> |
24 | #include <linux/slab.h> |
25 | |
26 | #include "../core.h" |
27 | #include "../pinconf.h" |
28 | #include "../pinctrl-utils.h" |
29 | #include "pinctrl-s32.h" |
30 | |
31 | #define S32_PIN_ID_SHIFT 4 |
32 | #define S32_PIN_ID_MASK GENMASK(31, S32_PIN_ID_SHIFT) |
33 | |
34 | #define S32_MSCR_SSS_MASK GENMASK(2, 0) |
35 | #define S32_MSCR_PUS BIT(12) |
36 | #define S32_MSCR_PUE BIT(13) |
37 | #define S32_MSCR_SRE(X) (((X) & GENMASK(3, 0)) << 14) |
38 | #define S32_MSCR_IBE BIT(19) |
39 | #define S32_MSCR_ODE BIT(20) |
40 | #define S32_MSCR_OBE BIT(21) |
41 | |
42 | static struct regmap_config s32_regmap_config = { |
43 | .reg_bits = 32, |
44 | .val_bits = 32, |
45 | .reg_stride = 4, |
46 | }; |
47 | |
48 | static u32 get_pin_no(u32 pinmux) |
49 | { |
50 | return (pinmux & S32_PIN_ID_MASK) >> S32_PIN_ID_SHIFT; |
51 | } |
52 | |
53 | static u32 get_pin_func(u32 pinmux) |
54 | { |
55 | return pinmux & GENMASK(3, 0); |
56 | } |
57 | |
58 | struct s32_pinctrl_mem_region { |
59 | struct regmap *map; |
60 | const struct s32_pin_range *pin_range; |
61 | char name[8]; |
62 | }; |
63 | |
64 | /* |
65 | * Holds pin configuration for GPIO's. |
66 | * @pin_id: Pin ID for this GPIO |
67 | * @config: Pin settings |
68 | * @list: Linked list entry for each gpio pin |
69 | */ |
70 | struct gpio_pin_config { |
71 | unsigned int pin_id; |
72 | unsigned int config; |
73 | struct list_head list; |
74 | }; |
75 | |
76 | /* |
77 | * Pad config save/restore for power suspend/resume. |
78 | */ |
79 | struct s32_pinctrl_context { |
80 | unsigned int *pads; |
81 | }; |
82 | |
83 | /* |
84 | * @dev: a pointer back to containing device |
85 | * @pctl: a pointer to the pinctrl device structure |
86 | * @regions: reserved memory regions with start/end pin |
87 | * @info: structure containing information about the pin |
88 | * @gpio_configs: Saved configurations for GPIO pins |
89 | * @gpiop_configs_lock: lock for the `gpio_configs` list |
90 | * @s32_pinctrl_context: Configuration saved over system sleep |
91 | */ |
92 | struct s32_pinctrl { |
93 | struct device *dev; |
94 | struct pinctrl_dev *pctl; |
95 | struct s32_pinctrl_mem_region *regions; |
96 | struct s32_pinctrl_soc_info *info; |
97 | struct list_head gpio_configs; |
98 | spinlock_t gpio_configs_lock; |
99 | #ifdef CONFIG_PM_SLEEP |
100 | struct s32_pinctrl_context saved_context; |
101 | #endif |
102 | }; |
103 | |
104 | static struct s32_pinctrl_mem_region * |
105 | s32_get_region(struct pinctrl_dev *pctldev, unsigned int pin) |
106 | { |
107 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
108 | const struct s32_pin_range *pin_range; |
109 | unsigned int mem_regions = ipctl->info->soc_data->mem_regions; |
110 | unsigned int i; |
111 | |
112 | for (i = 0; i < mem_regions; i++) { |
113 | pin_range = ipctl->regions[i].pin_range; |
114 | if (pin >= pin_range->start && pin <= pin_range->end) |
115 | return &ipctl->regions[i]; |
116 | } |
117 | |
118 | return NULL; |
119 | } |
120 | |
121 | static inline int s32_check_pin(struct pinctrl_dev *pctldev, |
122 | unsigned int pin) |
123 | { |
124 | return s32_get_region(pctldev, pin) ? 0 : -EINVAL; |
125 | } |
126 | |
127 | static inline int s32_regmap_read(struct pinctrl_dev *pctldev, |
128 | unsigned int pin, unsigned int *val) |
129 | { |
130 | struct s32_pinctrl_mem_region *region; |
131 | unsigned int offset; |
132 | |
133 | region = s32_get_region(pctldev, pin); |
134 | if (!region) |
135 | return -EINVAL; |
136 | |
137 | offset = (pin - region->pin_range->start) * |
138 | regmap_get_reg_stride(map: region->map); |
139 | |
140 | return regmap_read(map: region->map, reg: offset, val); |
141 | } |
142 | |
143 | static inline int s32_regmap_write(struct pinctrl_dev *pctldev, |
144 | unsigned int pin, |
145 | unsigned int val) |
146 | { |
147 | struct s32_pinctrl_mem_region *region; |
148 | unsigned int offset; |
149 | |
150 | region = s32_get_region(pctldev, pin); |
151 | if (!region) |
152 | return -EINVAL; |
153 | |
154 | offset = (pin - region->pin_range->start) * |
155 | regmap_get_reg_stride(map: region->map); |
156 | |
157 | return regmap_write(map: region->map, reg: offset, val); |
158 | |
159 | } |
160 | |
161 | static inline int s32_regmap_update(struct pinctrl_dev *pctldev, unsigned int pin, |
162 | unsigned int mask, unsigned int val) |
163 | { |
164 | struct s32_pinctrl_mem_region *region; |
165 | unsigned int offset; |
166 | |
167 | region = s32_get_region(pctldev, pin); |
168 | if (!region) |
169 | return -EINVAL; |
170 | |
171 | offset = (pin - region->pin_range->start) * |
172 | regmap_get_reg_stride(map: region->map); |
173 | |
174 | return regmap_update_bits(map: region->map, reg: offset, mask, val); |
175 | } |
176 | |
177 | static int s32_get_groups_count(struct pinctrl_dev *pctldev) |
178 | { |
179 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
180 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
181 | |
182 | return info->ngroups; |
183 | } |
184 | |
185 | static const char *s32_get_group_name(struct pinctrl_dev *pctldev, |
186 | unsigned int selector) |
187 | { |
188 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
189 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
190 | |
191 | return info->groups[selector].data.name; |
192 | } |
193 | |
194 | static int s32_get_group_pins(struct pinctrl_dev *pctldev, |
195 | unsigned int selector, const unsigned int **pins, |
196 | unsigned int *npins) |
197 | { |
198 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
199 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
200 | |
201 | *pins = info->groups[selector].data.pins; |
202 | *npins = info->groups[selector].data.npins; |
203 | |
204 | return 0; |
205 | } |
206 | |
207 | static void s32_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, |
208 | unsigned int offset) |
209 | { |
210 | seq_printf(m: s, fmt: "%s" , dev_name(dev: pctldev->dev)); |
211 | } |
212 | |
213 | static int s32_dt_group_node_to_map(struct pinctrl_dev *pctldev, |
214 | struct device_node *np, |
215 | struct pinctrl_map **map, |
216 | unsigned int *reserved_maps, |
217 | unsigned int *num_maps, |
218 | const char *func_name) |
219 | { |
220 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
221 | struct device *dev = ipctl->dev; |
222 | unsigned long *cfgs = NULL; |
223 | unsigned int n_cfgs, reserve = 1; |
224 | int n_pins, ret; |
225 | |
226 | n_pins = of_property_count_elems_of_size(np, propname: "pinmux" , elem_size: sizeof(u32)); |
227 | if (n_pins < 0) { |
228 | dev_warn(dev, "Can't find 'pinmux' property in node %pOFn\n" , np); |
229 | } else if (!n_pins) { |
230 | return -EINVAL; |
231 | } |
232 | |
233 | ret = pinconf_generic_parse_dt_config(np, pctldev, configs: &cfgs, nconfigs: &n_cfgs); |
234 | if (ret) { |
235 | dev_err(dev, "%pOF: could not parse node property\n" , np); |
236 | return ret; |
237 | } |
238 | |
239 | if (n_cfgs) |
240 | reserve++; |
241 | |
242 | ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps, |
243 | reserve); |
244 | if (ret < 0) |
245 | goto free_cfgs; |
246 | |
247 | ret = pinctrl_utils_add_map_mux(pctldev, map, reserved_maps, num_maps, |
248 | group: np->name, function: func_name); |
249 | if (ret < 0) |
250 | goto free_cfgs; |
251 | |
252 | if (n_cfgs) { |
253 | ret = pinctrl_utils_add_map_configs(pctldev, map, reserved_maps, |
254 | num_maps, group: np->name, configs: cfgs, num_configs: n_cfgs, |
255 | type: PIN_MAP_TYPE_CONFIGS_GROUP); |
256 | if (ret < 0) |
257 | goto free_cfgs; |
258 | } |
259 | |
260 | free_cfgs: |
261 | kfree(objp: cfgs); |
262 | return ret; |
263 | } |
264 | |
265 | static int s32_dt_node_to_map(struct pinctrl_dev *pctldev, |
266 | struct device_node *np_config, |
267 | struct pinctrl_map **map, |
268 | unsigned int *num_maps) |
269 | { |
270 | unsigned int reserved_maps; |
271 | struct device_node *np; |
272 | int ret = 0; |
273 | |
274 | reserved_maps = 0; |
275 | *map = NULL; |
276 | *num_maps = 0; |
277 | |
278 | for_each_available_child_of_node(np_config, np) { |
279 | ret = s32_dt_group_node_to_map(pctldev, np, map, |
280 | reserved_maps: &reserved_maps, num_maps, |
281 | func_name: np_config->name); |
282 | if (ret < 0) { |
283 | of_node_put(node: np); |
284 | break; |
285 | } |
286 | } |
287 | |
288 | if (ret) |
289 | pinctrl_utils_free_map(pctldev, map: *map, num_maps: *num_maps); |
290 | |
291 | return ret; |
292 | |
293 | } |
294 | |
295 | static const struct pinctrl_ops s32_pctrl_ops = { |
296 | .get_groups_count = s32_get_groups_count, |
297 | .get_group_name = s32_get_group_name, |
298 | .get_group_pins = s32_get_group_pins, |
299 | .pin_dbg_show = s32_pin_dbg_show, |
300 | .dt_node_to_map = s32_dt_node_to_map, |
301 | .dt_free_map = pinctrl_utils_free_map, |
302 | }; |
303 | |
304 | static int s32_pmx_set(struct pinctrl_dev *pctldev, unsigned int selector, |
305 | unsigned int group) |
306 | { |
307 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
308 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
309 | int i, ret; |
310 | struct s32_pin_group *grp; |
311 | |
312 | /* |
313 | * Configure the mux mode for each pin in the group for a specific |
314 | * function. |
315 | */ |
316 | grp = &info->groups[group]; |
317 | |
318 | dev_dbg(ipctl->dev, "set mux for function %s group %s\n" , |
319 | info->functions[selector].name, grp->data.name); |
320 | |
321 | /* Check beforehand so we don't have a partial config. */ |
322 | for (i = 0; i < grp->data.npins; i++) { |
323 | if (s32_check_pin(pctldev, pin: grp->data.pins[i]) != 0) { |
324 | dev_err(info->dev, "invalid pin: %u in group: %u\n" , |
325 | grp->data.pins[i], group); |
326 | return -EINVAL; |
327 | } |
328 | } |
329 | |
330 | for (i = 0, ret = 0; i < grp->data.npins && !ret; i++) { |
331 | ret = s32_regmap_update(pctldev, pin: grp->data.pins[i], |
332 | S32_MSCR_SSS_MASK, val: grp->pin_sss[i]); |
333 | if (ret) { |
334 | dev_err(info->dev, "Failed to set pin %u\n" , |
335 | grp->data.pins[i]); |
336 | return ret; |
337 | } |
338 | } |
339 | |
340 | return 0; |
341 | } |
342 | |
343 | static int s32_pmx_get_funcs_count(struct pinctrl_dev *pctldev) |
344 | { |
345 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
346 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
347 | |
348 | return info->nfunctions; |
349 | } |
350 | |
351 | static const char *s32_pmx_get_func_name(struct pinctrl_dev *pctldev, |
352 | unsigned int selector) |
353 | { |
354 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
355 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
356 | |
357 | return info->functions[selector].name; |
358 | } |
359 | |
360 | static int s32_pmx_get_groups(struct pinctrl_dev *pctldev, |
361 | unsigned int selector, |
362 | const char * const **groups, |
363 | unsigned int * const num_groups) |
364 | { |
365 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
366 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
367 | |
368 | *groups = info->functions[selector].groups; |
369 | *num_groups = info->functions[selector].ngroups; |
370 | |
371 | return 0; |
372 | } |
373 | |
374 | static int s32_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, |
375 | struct pinctrl_gpio_range *range, |
376 | unsigned int offset) |
377 | { |
378 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
379 | struct gpio_pin_config *gpio_pin; |
380 | unsigned int config; |
381 | unsigned long flags; |
382 | int ret; |
383 | |
384 | ret = s32_regmap_read(pctldev, pin: offset, val: &config); |
385 | if (ret) |
386 | return ret; |
387 | |
388 | /* Save current configuration */ |
389 | gpio_pin = kmalloc(size: sizeof(*gpio_pin), GFP_KERNEL); |
390 | if (!gpio_pin) |
391 | return -ENOMEM; |
392 | |
393 | gpio_pin->pin_id = offset; |
394 | gpio_pin->config = config; |
395 | |
396 | spin_lock_irqsave(&ipctl->gpio_configs_lock, flags); |
397 | list_add(new: &gpio_pin->list, head: &ipctl->gpio_configs); |
398 | spin_unlock_irqrestore(lock: &ipctl->gpio_configs_lock, flags); |
399 | |
400 | /* GPIO pin means SSS = 0 */ |
401 | config &= ~S32_MSCR_SSS_MASK; |
402 | |
403 | return s32_regmap_write(pctldev, pin: offset, val: config); |
404 | } |
405 | |
406 | static void s32_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, |
407 | struct pinctrl_gpio_range *range, |
408 | unsigned int offset) |
409 | { |
410 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
411 | struct gpio_pin_config *gpio_pin, *tmp; |
412 | unsigned long flags; |
413 | int ret; |
414 | |
415 | spin_lock_irqsave(&ipctl->gpio_configs_lock, flags); |
416 | |
417 | list_for_each_entry_safe(gpio_pin, tmp, &ipctl->gpio_configs, list) { |
418 | if (gpio_pin->pin_id == offset) { |
419 | ret = s32_regmap_write(pctldev, pin: gpio_pin->pin_id, |
420 | val: gpio_pin->config); |
421 | if (ret != 0) |
422 | goto unlock; |
423 | |
424 | list_del(entry: &gpio_pin->list); |
425 | kfree(objp: gpio_pin); |
426 | break; |
427 | } |
428 | } |
429 | |
430 | unlock: |
431 | spin_unlock_irqrestore(lock: &ipctl->gpio_configs_lock, flags); |
432 | } |
433 | |
434 | static int s32_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, |
435 | struct pinctrl_gpio_range *range, |
436 | unsigned int offset, |
437 | bool input) |
438 | { |
439 | unsigned int config; |
440 | unsigned int mask = S32_MSCR_IBE | S32_MSCR_OBE; |
441 | |
442 | if (input) { |
443 | /* Disable output buffer and enable input buffer */ |
444 | config = S32_MSCR_IBE; |
445 | } else { |
446 | /* Disable input buffer and enable output buffer */ |
447 | config = S32_MSCR_OBE; |
448 | } |
449 | |
450 | return s32_regmap_update(pctldev, pin: offset, mask, val: config); |
451 | } |
452 | |
453 | static const struct pinmux_ops s32_pmx_ops = { |
454 | .get_functions_count = s32_pmx_get_funcs_count, |
455 | .get_function_name = s32_pmx_get_func_name, |
456 | .get_function_groups = s32_pmx_get_groups, |
457 | .set_mux = s32_pmx_set, |
458 | .gpio_request_enable = s32_pmx_gpio_request_enable, |
459 | .gpio_disable_free = s32_pmx_gpio_disable_free, |
460 | .gpio_set_direction = s32_pmx_gpio_set_direction, |
461 | }; |
462 | |
463 | /* Set the reserved elements as -1 */ |
464 | static const int support_slew[] = {208, -1, -1, -1, 166, 150, 133, 83}; |
465 | |
466 | static int s32_get_slew_regval(int arg) |
467 | { |
468 | unsigned int i; |
469 | |
470 | /* Translate a real slew rate (MHz) to a register value */ |
471 | for (i = 0; i < ARRAY_SIZE(support_slew); i++) { |
472 | if (arg == support_slew[i]) |
473 | return i; |
474 | } |
475 | |
476 | return -EINVAL; |
477 | } |
478 | |
479 | static inline void s32_pin_set_pull(enum pin_config_param param, |
480 | unsigned int *mask, unsigned int *config) |
481 | { |
482 | switch (param) { |
483 | case PIN_CONFIG_BIAS_DISABLE: |
484 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: |
485 | *config &= ~(S32_MSCR_PUS | S32_MSCR_PUE); |
486 | break; |
487 | case PIN_CONFIG_BIAS_PULL_UP: |
488 | *config |= S32_MSCR_PUS | S32_MSCR_PUE; |
489 | break; |
490 | case PIN_CONFIG_BIAS_PULL_DOWN: |
491 | *config &= ~S32_MSCR_PUS; |
492 | *config |= S32_MSCR_PUE; |
493 | break; |
494 | default: |
495 | return; |
496 | } |
497 | |
498 | *mask |= S32_MSCR_PUS | S32_MSCR_PUE; |
499 | } |
500 | |
501 | static int s32_parse_pincfg(unsigned long pincfg, unsigned int *mask, |
502 | unsigned int *config) |
503 | { |
504 | enum pin_config_param param; |
505 | u32 arg; |
506 | int ret; |
507 | |
508 | param = pinconf_to_config_param(config: pincfg); |
509 | arg = pinconf_to_config_argument(config: pincfg); |
510 | |
511 | switch (param) { |
512 | /* All pins are persistent over suspend */ |
513 | case PIN_CONFIG_PERSIST_STATE: |
514 | return 0; |
515 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
516 | *config |= S32_MSCR_ODE; |
517 | *mask |= S32_MSCR_ODE; |
518 | break; |
519 | case PIN_CONFIG_OUTPUT_ENABLE: |
520 | if (arg) |
521 | *config |= S32_MSCR_OBE; |
522 | else |
523 | *config &= ~S32_MSCR_OBE; |
524 | *mask |= S32_MSCR_OBE; |
525 | break; |
526 | case PIN_CONFIG_INPUT_ENABLE: |
527 | if (arg) |
528 | *config |= S32_MSCR_IBE; |
529 | else |
530 | *config &= ~S32_MSCR_IBE; |
531 | *mask |= S32_MSCR_IBE; |
532 | break; |
533 | case PIN_CONFIG_SLEW_RATE: |
534 | ret = s32_get_slew_regval(arg); |
535 | if (ret < 0) |
536 | return ret; |
537 | *config |= S32_MSCR_SRE((u32)ret); |
538 | *mask |= S32_MSCR_SRE(~0); |
539 | break; |
540 | case PIN_CONFIG_BIAS_DISABLE: |
541 | case PIN_CONFIG_BIAS_PULL_UP: |
542 | case PIN_CONFIG_BIAS_PULL_DOWN: |
543 | s32_pin_set_pull(param, mask, config); |
544 | break; |
545 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: |
546 | *config &= ~(S32_MSCR_ODE | S32_MSCR_OBE | S32_MSCR_IBE); |
547 | *mask |= S32_MSCR_ODE | S32_MSCR_OBE | S32_MSCR_IBE; |
548 | s32_pin_set_pull(param, mask, config); |
549 | break; |
550 | default: |
551 | return -EOPNOTSUPP; |
552 | } |
553 | |
554 | return 0; |
555 | } |
556 | |
557 | static int s32_pinconf_mscr_update(struct pinctrl_dev *pctldev, |
558 | unsigned int pin_id, |
559 | unsigned long *configs, |
560 | unsigned int num_configs) |
561 | { |
562 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
563 | unsigned int config = 0, mask = 0; |
564 | int i, ret; |
565 | |
566 | ret = s32_check_pin(pctldev, pin: pin_id); |
567 | if (ret) |
568 | return ret; |
569 | |
570 | dev_dbg(ipctl->dev, "pinconf set pin %s with %u configs\n" , |
571 | pin_get_name(pctldev, pin_id), num_configs); |
572 | |
573 | for (i = 0; i < num_configs; i++) { |
574 | ret = s32_parse_pincfg(pincfg: configs[i], mask: &mask, config: &config); |
575 | if (ret) |
576 | return ret; |
577 | } |
578 | |
579 | if (!config && !mask) |
580 | return 0; |
581 | |
582 | dev_dbg(ipctl->dev, "update: pin %u cfg 0x%x\n" , pin_id, config); |
583 | |
584 | return s32_regmap_update(pctldev, pin: pin_id, mask, val: config); |
585 | } |
586 | |
587 | static int s32_pinconf_get(struct pinctrl_dev *pctldev, |
588 | unsigned int pin_id, |
589 | unsigned long *config) |
590 | { |
591 | return s32_regmap_read(pctldev, pin: pin_id, val: (unsigned int *)config); |
592 | } |
593 | |
594 | static int s32_pinconf_set(struct pinctrl_dev *pctldev, |
595 | unsigned int pin_id, unsigned long *configs, |
596 | unsigned int num_configs) |
597 | { |
598 | return s32_pinconf_mscr_update(pctldev, pin_id, configs, |
599 | num_configs); |
600 | } |
601 | |
602 | static int s32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned int selector, |
603 | unsigned long *configs, unsigned int num_configs) |
604 | { |
605 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
606 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
607 | struct s32_pin_group *grp; |
608 | int i, ret; |
609 | |
610 | grp = &info->groups[selector]; |
611 | for (i = 0; i < grp->data.npins; i++) { |
612 | ret = s32_pinconf_mscr_update(pctldev, pin_id: grp->data.pins[i], |
613 | configs, num_configs); |
614 | if (ret) |
615 | return ret; |
616 | } |
617 | |
618 | return 0; |
619 | } |
620 | |
621 | static void s32_pinconf_dbg_show(struct pinctrl_dev *pctldev, |
622 | struct seq_file *s, unsigned int pin_id) |
623 | { |
624 | unsigned int config; |
625 | int ret; |
626 | |
627 | ret = s32_regmap_read(pctldev, pin: pin_id, val: &config); |
628 | if (ret) |
629 | return; |
630 | |
631 | seq_printf(m: s, fmt: "0x%x" , config); |
632 | } |
633 | |
634 | static void s32_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, |
635 | struct seq_file *s, unsigned int selector) |
636 | { |
637 | struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); |
638 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
639 | struct s32_pin_group *grp; |
640 | unsigned int config; |
641 | const char *name; |
642 | int i, ret; |
643 | |
644 | seq_puts(m: s, s: "\n" ); |
645 | grp = &info->groups[selector]; |
646 | for (i = 0; i < grp->data.npins; i++) { |
647 | name = pin_get_name(pctldev, pin: grp->data.pins[i]); |
648 | ret = s32_regmap_read(pctldev, pin: grp->data.pins[i], val: &config); |
649 | if (ret) |
650 | return; |
651 | seq_printf(m: s, fmt: "%s: 0x%x\n" , name, config); |
652 | } |
653 | } |
654 | |
655 | static const struct pinconf_ops s32_pinconf_ops = { |
656 | .pin_config_get = s32_pinconf_get, |
657 | .pin_config_set = s32_pinconf_set, |
658 | .pin_config_group_set = s32_pconf_group_set, |
659 | .pin_config_dbg_show = s32_pinconf_dbg_show, |
660 | .pin_config_group_dbg_show = s32_pinconf_group_dbg_show, |
661 | }; |
662 | |
663 | #ifdef CONFIG_PM_SLEEP |
664 | static bool s32_pinctrl_should_save(struct s32_pinctrl *ipctl, |
665 | unsigned int pin) |
666 | { |
667 | const struct pin_desc *pd = pin_desc_get(pctldev: ipctl->pctl, pin); |
668 | |
669 | if (!pd) |
670 | return false; |
671 | |
672 | /* |
673 | * Only restore the pin if it is actually in use by the kernel (or |
674 | * by userspace). |
675 | */ |
676 | if (pd->mux_owner || pd->gpio_owner) |
677 | return true; |
678 | |
679 | return false; |
680 | } |
681 | |
682 | int s32_pinctrl_suspend(struct device *dev) |
683 | { |
684 | struct platform_device *pdev = to_platform_device(dev); |
685 | struct s32_pinctrl *ipctl = platform_get_drvdata(pdev); |
686 | const struct pinctrl_pin_desc *pin; |
687 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
688 | struct s32_pinctrl_context *saved_context = &ipctl->saved_context; |
689 | int i; |
690 | int ret; |
691 | unsigned int config; |
692 | |
693 | for (i = 0; i < info->soc_data->npins; i++) { |
694 | pin = &info->soc_data->pins[i]; |
695 | |
696 | if (!s32_pinctrl_should_save(ipctl, pin: pin->number)) |
697 | continue; |
698 | |
699 | ret = s32_regmap_read(pctldev: ipctl->pctl, pin: pin->number, val: &config); |
700 | if (ret) |
701 | return -EINVAL; |
702 | |
703 | saved_context->pads[i] = config; |
704 | } |
705 | |
706 | return 0; |
707 | } |
708 | |
709 | int s32_pinctrl_resume(struct device *dev) |
710 | { |
711 | struct platform_device *pdev = to_platform_device(dev); |
712 | struct s32_pinctrl *ipctl = platform_get_drvdata(pdev); |
713 | const struct s32_pinctrl_soc_info *info = ipctl->info; |
714 | const struct pinctrl_pin_desc *pin; |
715 | struct s32_pinctrl_context *saved_context = &ipctl->saved_context; |
716 | int ret, i; |
717 | |
718 | for (i = 0; i < info->soc_data->npins; i++) { |
719 | pin = &info->soc_data->pins[i]; |
720 | |
721 | if (!s32_pinctrl_should_save(ipctl, pin: pin->number)) |
722 | continue; |
723 | |
724 | ret = s32_regmap_write(pctldev: ipctl->pctl, pin: pin->number, |
725 | val: saved_context->pads[i]); |
726 | if (ret) |
727 | return ret; |
728 | } |
729 | |
730 | return 0; |
731 | } |
732 | #endif |
733 | |
734 | static int s32_pinctrl_parse_groups(struct device_node *np, |
735 | struct s32_pin_group *grp, |
736 | struct s32_pinctrl_soc_info *info) |
737 | { |
738 | const __be32 *p; |
739 | struct device *dev; |
740 | struct property *prop; |
741 | unsigned int *pins, *sss; |
742 | int i, npins; |
743 | u32 pinmux; |
744 | |
745 | dev = info->dev; |
746 | |
747 | dev_dbg(dev, "group: %pOFn\n" , np); |
748 | |
749 | /* Initialise group */ |
750 | grp->data.name = np->name; |
751 | |
752 | npins = of_property_count_elems_of_size(np, propname: "pinmux" , elem_size: sizeof(u32)); |
753 | if (npins < 0) { |
754 | dev_err(dev, "Failed to read 'pinmux' property in node %s.\n" , |
755 | grp->data.name); |
756 | return -EINVAL; |
757 | } |
758 | if (!npins) { |
759 | dev_err(dev, "The group %s has no pins.\n" , grp->data.name); |
760 | return -EINVAL; |
761 | } |
762 | |
763 | grp->data.npins = npins; |
764 | |
765 | pins = devm_kcalloc(dev: info->dev, n: npins, size: sizeof(*pins), GFP_KERNEL); |
766 | sss = devm_kcalloc(dev: info->dev, n: npins, size: sizeof(*sss), GFP_KERNEL); |
767 | if (!pins || !sss) |
768 | return -ENOMEM; |
769 | |
770 | i = 0; |
771 | of_property_for_each_u32(np, "pinmux" , prop, p, pinmux) { |
772 | pins[i] = get_pin_no(pinmux); |
773 | sss[i] = get_pin_func(pinmux); |
774 | |
775 | dev_dbg(info->dev, "pin: 0x%x, sss: 0x%x" , pins[i], sss[i]); |
776 | i++; |
777 | } |
778 | |
779 | grp->data.pins = pins; |
780 | grp->pin_sss = sss; |
781 | |
782 | return 0; |
783 | } |
784 | |
785 | static int s32_pinctrl_parse_functions(struct device_node *np, |
786 | struct s32_pinctrl_soc_info *info, |
787 | u32 index) |
788 | { |
789 | struct device_node *child; |
790 | struct pinfunction *func; |
791 | struct s32_pin_group *grp; |
792 | const char **groups; |
793 | u32 i = 0; |
794 | int ret = 0; |
795 | |
796 | dev_dbg(info->dev, "parse function(%u): %pOFn\n" , index, np); |
797 | |
798 | func = &info->functions[index]; |
799 | |
800 | /* Initialise function */ |
801 | func->name = np->name; |
802 | func->ngroups = of_get_child_count(np); |
803 | if (func->ngroups == 0) { |
804 | dev_err(info->dev, "no groups defined in %pOF\n" , np); |
805 | return -EINVAL; |
806 | } |
807 | |
808 | groups = devm_kcalloc(dev: info->dev, n: func->ngroups, |
809 | size: sizeof(*func->groups), GFP_KERNEL); |
810 | if (!groups) |
811 | return -ENOMEM; |
812 | |
813 | for_each_child_of_node(np, child) { |
814 | groups[i] = child->name; |
815 | grp = &info->groups[info->grp_index++]; |
816 | ret = s32_pinctrl_parse_groups(np: child, grp, info); |
817 | if (ret) { |
818 | of_node_put(node: child); |
819 | return ret; |
820 | } |
821 | i++; |
822 | } |
823 | |
824 | func->groups = groups; |
825 | |
826 | return 0; |
827 | } |
828 | |
829 | static int s32_pinctrl_probe_dt(struct platform_device *pdev, |
830 | struct s32_pinctrl *ipctl) |
831 | { |
832 | struct s32_pinctrl_soc_info *info = ipctl->info; |
833 | struct device_node *np = pdev->dev.of_node; |
834 | struct device_node *child; |
835 | struct resource *res; |
836 | struct regmap *map; |
837 | void __iomem *base; |
838 | unsigned int mem_regions = info->soc_data->mem_regions; |
839 | int ret; |
840 | u32 nfuncs = 0; |
841 | u32 i = 0; |
842 | |
843 | if (!np) |
844 | return -ENODEV; |
845 | |
846 | if (mem_regions == 0 || mem_regions >= 10000) { |
847 | dev_err(&pdev->dev, "mem_regions is invalid: %u\n" , mem_regions); |
848 | return -EINVAL; |
849 | } |
850 | |
851 | ipctl->regions = devm_kcalloc(dev: &pdev->dev, n: mem_regions, |
852 | size: sizeof(*ipctl->regions), GFP_KERNEL); |
853 | if (!ipctl->regions) |
854 | return -ENOMEM; |
855 | |
856 | for (i = 0; i < mem_regions; i++) { |
857 | base = devm_platform_get_and_ioremap_resource(pdev, index: i, res: &res); |
858 | if (IS_ERR(ptr: base)) |
859 | return PTR_ERR(ptr: base); |
860 | |
861 | snprintf(buf: ipctl->regions[i].name, |
862 | size: sizeof(ipctl->regions[i].name), fmt: "map%u" , i); |
863 | |
864 | s32_regmap_config.name = ipctl->regions[i].name; |
865 | s32_regmap_config.max_register = resource_size(res) - |
866 | s32_regmap_config.reg_stride; |
867 | |
868 | map = devm_regmap_init_mmio(&pdev->dev, base, |
869 | &s32_regmap_config); |
870 | if (IS_ERR(ptr: map)) { |
871 | dev_err(&pdev->dev, "Failed to init regmap[%u]\n" , i); |
872 | return PTR_ERR(ptr: map); |
873 | } |
874 | |
875 | ipctl->regions[i].map = map; |
876 | ipctl->regions[i].pin_range = &info->soc_data->mem_pin_ranges[i]; |
877 | } |
878 | |
879 | nfuncs = of_get_child_count(np); |
880 | if (nfuncs <= 0) { |
881 | dev_err(&pdev->dev, "no functions defined\n" ); |
882 | return -EINVAL; |
883 | } |
884 | |
885 | info->nfunctions = nfuncs; |
886 | info->functions = devm_kcalloc(dev: &pdev->dev, n: nfuncs, |
887 | size: sizeof(*info->functions), GFP_KERNEL); |
888 | if (!info->functions) |
889 | return -ENOMEM; |
890 | |
891 | info->ngroups = 0; |
892 | for_each_child_of_node(np, child) |
893 | info->ngroups += of_get_child_count(np: child); |
894 | |
895 | info->groups = devm_kcalloc(dev: &pdev->dev, n: info->ngroups, |
896 | size: sizeof(*info->groups), GFP_KERNEL); |
897 | if (!info->groups) |
898 | return -ENOMEM; |
899 | |
900 | i = 0; |
901 | for_each_child_of_node(np, child) { |
902 | ret = s32_pinctrl_parse_functions(np: child, info, index: i++); |
903 | if (ret) { |
904 | of_node_put(node: child); |
905 | return ret; |
906 | } |
907 | } |
908 | |
909 | return 0; |
910 | } |
911 | |
912 | int s32_pinctrl_probe(struct platform_device *pdev, |
913 | const struct s32_pinctrl_soc_data *soc_data) |
914 | { |
915 | struct s32_pinctrl *ipctl; |
916 | int ret; |
917 | struct pinctrl_desc *s32_pinctrl_desc; |
918 | struct s32_pinctrl_soc_info *info; |
919 | #ifdef CONFIG_PM_SLEEP |
920 | struct s32_pinctrl_context *saved_context; |
921 | #endif |
922 | |
923 | if (!soc_data || !soc_data->pins || !soc_data->npins) { |
924 | dev_err(&pdev->dev, "wrong pinctrl info\n" ); |
925 | return -EINVAL; |
926 | } |
927 | |
928 | info = devm_kzalloc(dev: &pdev->dev, size: sizeof(*info), GFP_KERNEL); |
929 | if (!info) |
930 | return -ENOMEM; |
931 | |
932 | info->soc_data = soc_data; |
933 | info->dev = &pdev->dev; |
934 | |
935 | /* Create state holders etc for this driver */ |
936 | ipctl = devm_kzalloc(dev: &pdev->dev, size: sizeof(*ipctl), GFP_KERNEL); |
937 | if (!ipctl) |
938 | return -ENOMEM; |
939 | |
940 | ipctl->info = info; |
941 | ipctl->dev = info->dev; |
942 | platform_set_drvdata(pdev, data: ipctl); |
943 | |
944 | INIT_LIST_HEAD(list: &ipctl->gpio_configs); |
945 | spin_lock_init(&ipctl->gpio_configs_lock); |
946 | |
947 | s32_pinctrl_desc = |
948 | devm_kmalloc(dev: &pdev->dev, size: sizeof(*s32_pinctrl_desc), GFP_KERNEL); |
949 | if (!s32_pinctrl_desc) |
950 | return -ENOMEM; |
951 | |
952 | s32_pinctrl_desc->name = dev_name(dev: &pdev->dev); |
953 | s32_pinctrl_desc->pins = info->soc_data->pins; |
954 | s32_pinctrl_desc->npins = info->soc_data->npins; |
955 | s32_pinctrl_desc->pctlops = &s32_pctrl_ops; |
956 | s32_pinctrl_desc->pmxops = &s32_pmx_ops; |
957 | s32_pinctrl_desc->confops = &s32_pinconf_ops; |
958 | s32_pinctrl_desc->owner = THIS_MODULE; |
959 | |
960 | ret = s32_pinctrl_probe_dt(pdev, ipctl); |
961 | if (ret) { |
962 | dev_err(&pdev->dev, "fail to probe dt properties\n" ); |
963 | return ret; |
964 | } |
965 | |
966 | ipctl->pctl = devm_pinctrl_register(dev: &pdev->dev, pctldesc: s32_pinctrl_desc, |
967 | driver_data: ipctl); |
968 | if (IS_ERR(ptr: ipctl->pctl)) |
969 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: ipctl->pctl), |
970 | fmt: "could not register s32 pinctrl driver\n" ); |
971 | |
972 | #ifdef CONFIG_PM_SLEEP |
973 | saved_context = &ipctl->saved_context; |
974 | saved_context->pads = |
975 | devm_kcalloc(dev: &pdev->dev, n: info->soc_data->npins, |
976 | size: sizeof(*saved_context->pads), |
977 | GFP_KERNEL); |
978 | if (!saved_context->pads) |
979 | return -ENOMEM; |
980 | #endif |
981 | |
982 | dev_info(&pdev->dev, "initialized s32 pinctrl driver\n" ); |
983 | |
984 | return 0; |
985 | } |
986 | |