1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Pin Control and GPIO driver for SuperH Pin Function Controller. |
4 | * |
5 | * Authors: Magnus Damm, Paul Mundt, Laurent Pinchart |
6 | * |
7 | * Copyright (C) 2008 Magnus Damm |
8 | * Copyright (C) 2009 - 2012 Paul Mundt |
9 | */ |
10 | |
11 | #define DRV_NAME "sh-pfc" |
12 | |
13 | #include <linux/bitops.h> |
14 | #include <linux/err.h> |
15 | #include <linux/errno.h> |
16 | #include <linux/init.h> |
17 | #include <linux/io.h> |
18 | #include <linux/ioport.h> |
19 | #include <linux/kernel.h> |
20 | #include <linux/math.h> |
21 | #include <linux/of.h> |
22 | #include <linux/pinctrl/machine.h> |
23 | #include <linux/platform_device.h> |
24 | #include <linux/psci.h> |
25 | #include <linux/slab.h> |
26 | #include <linux/sys_soc.h> |
27 | |
28 | #include "core.h" |
29 | |
30 | static int sh_pfc_map_resources(struct sh_pfc *pfc, |
31 | struct platform_device *pdev) |
32 | { |
33 | struct sh_pfc_window *windows; |
34 | unsigned int *irqs = NULL; |
35 | unsigned int num_windows; |
36 | struct resource *res; |
37 | unsigned int i; |
38 | int num_irqs; |
39 | |
40 | /* Count the MEM and IRQ resources. */ |
41 | for (num_windows = 0;; num_windows++) { |
42 | res = platform_get_resource(pdev, IORESOURCE_MEM, num_windows); |
43 | if (!res) |
44 | break; |
45 | } |
46 | if (num_windows == 0) |
47 | return -EINVAL; |
48 | |
49 | num_irqs = platform_irq_count(pdev); |
50 | if (num_irqs < 0) |
51 | return num_irqs; |
52 | |
53 | /* Allocate memory windows and IRQs arrays. */ |
54 | windows = devm_kcalloc(dev: pfc->dev, n: num_windows, size: sizeof(*windows), |
55 | GFP_KERNEL); |
56 | if (windows == NULL) |
57 | return -ENOMEM; |
58 | |
59 | pfc->num_windows = num_windows; |
60 | pfc->windows = windows; |
61 | |
62 | if (num_irqs) { |
63 | irqs = devm_kcalloc(dev: pfc->dev, n: num_irqs, size: sizeof(*irqs), |
64 | GFP_KERNEL); |
65 | if (irqs == NULL) |
66 | return -ENOMEM; |
67 | |
68 | pfc->num_irqs = num_irqs; |
69 | pfc->irqs = irqs; |
70 | } |
71 | |
72 | /* Fill them. */ |
73 | for (i = 0; i < num_windows; i++) { |
74 | windows->virt = devm_platform_get_and_ioremap_resource(pdev, index: i, res: &res); |
75 | if (IS_ERR(ptr: windows->virt)) |
76 | return -ENOMEM; |
77 | windows->phys = res->start; |
78 | windows->size = resource_size(res); |
79 | windows++; |
80 | } |
81 | for (i = 0; i < num_irqs; i++) |
82 | *irqs++ = platform_get_irq(pdev, i); |
83 | |
84 | return 0; |
85 | } |
86 | |
87 | static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, u32 reg) |
88 | { |
89 | struct sh_pfc_window *window; |
90 | phys_addr_t address = reg; |
91 | unsigned int i; |
92 | |
93 | /* scan through physical windows and convert address */ |
94 | for (i = 0; i < pfc->num_windows; i++) { |
95 | window = pfc->windows + i; |
96 | |
97 | if (address < window->phys) |
98 | continue; |
99 | |
100 | if (address >= (window->phys + window->size)) |
101 | continue; |
102 | |
103 | return window->virt + (address - window->phys); |
104 | } |
105 | |
106 | BUG(); |
107 | return NULL; |
108 | } |
109 | |
110 | int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) |
111 | { |
112 | unsigned int offset; |
113 | unsigned int i; |
114 | |
115 | for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) { |
116 | const struct sh_pfc_pin_range *range = &pfc->ranges[i]; |
117 | |
118 | if (pin <= range->end) |
119 | return pin >= range->start |
120 | ? offset + pin - range->start : -1; |
121 | |
122 | offset += range->end - range->start + 1; |
123 | } |
124 | |
125 | return -EINVAL; |
126 | } |
127 | |
128 | static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r) |
129 | { |
130 | if (enum_id < r->begin) |
131 | return 0; |
132 | |
133 | if (enum_id > r->end) |
134 | return 0; |
135 | |
136 | return 1; |
137 | } |
138 | |
139 | u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width) |
140 | { |
141 | switch (reg_width) { |
142 | case 8: |
143 | return ioread8(mapped_reg); |
144 | case 16: |
145 | return ioread16(mapped_reg); |
146 | case 32: |
147 | return ioread32(mapped_reg); |
148 | } |
149 | |
150 | BUG(); |
151 | return 0; |
152 | } |
153 | |
154 | void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width, |
155 | u32 data) |
156 | { |
157 | switch (reg_width) { |
158 | case 8: |
159 | iowrite8(data, mapped_reg); |
160 | return; |
161 | case 16: |
162 | iowrite16(data, mapped_reg); |
163 | return; |
164 | case 32: |
165 | iowrite32(data, mapped_reg); |
166 | return; |
167 | } |
168 | |
169 | BUG(); |
170 | } |
171 | |
172 | u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg) |
173 | { |
174 | return sh_pfc_read_raw_reg(mapped_reg: sh_pfc_phys_to_virt(pfc, reg), reg_width: 32); |
175 | } |
176 | |
177 | static void sh_pfc_unlock_reg(struct sh_pfc *pfc, u32 reg, u32 data) |
178 | { |
179 | u32 unlock; |
180 | |
181 | if (!pfc->info->unlock_reg) |
182 | return; |
183 | |
184 | if (pfc->info->unlock_reg >= 0x80000000UL) |
185 | unlock = pfc->info->unlock_reg; |
186 | else |
187 | /* unlock_reg is a mask */ |
188 | unlock = reg & ~pfc->info->unlock_reg; |
189 | |
190 | sh_pfc_write_raw_reg(mapped_reg: sh_pfc_phys_to_virt(pfc, reg: unlock), reg_width: 32, data: ~data); |
191 | } |
192 | |
193 | void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data) |
194 | { |
195 | sh_pfc_unlock_reg(pfc, reg, data); |
196 | sh_pfc_write_raw_reg(mapped_reg: sh_pfc_phys_to_virt(pfc, reg), reg_width: 32, data); |
197 | } |
198 | |
199 | static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, |
200 | const struct pinmux_cfg_reg *crp, |
201 | unsigned int in_pos, |
202 | void __iomem **mapped_regp, u32 *maskp, |
203 | unsigned int *posp) |
204 | { |
205 | unsigned int k; |
206 | |
207 | *mapped_regp = sh_pfc_phys_to_virt(pfc, reg: crp->reg); |
208 | |
209 | if (crp->field_width) { |
210 | *maskp = (1 << crp->field_width) - 1; |
211 | *posp = crp->reg_width - ((in_pos + 1) * crp->field_width); |
212 | } else { |
213 | *maskp = (1 << crp->var_field_width[in_pos]) - 1; |
214 | *posp = crp->reg_width; |
215 | for (k = 0; k <= in_pos; k++) |
216 | *posp -= abs(crp->var_field_width[k]); |
217 | } |
218 | } |
219 | |
220 | static void sh_pfc_write_config_reg(struct sh_pfc *pfc, |
221 | const struct pinmux_cfg_reg *crp, |
222 | unsigned int field, u32 value) |
223 | { |
224 | void __iomem *mapped_reg; |
225 | unsigned int pos; |
226 | u32 mask, data; |
227 | |
228 | sh_pfc_config_reg_helper(pfc, crp, in_pos: field, mapped_regp: &mapped_reg, maskp: &mask, posp: &pos); |
229 | |
230 | dev_dbg(pfc->dev, "write_reg addr = %x, value = 0x%x, field = %u, " |
231 | "r_width = %u, f_width = %u\n" , |
232 | crp->reg, value, field, crp->reg_width, hweight32(mask)); |
233 | |
234 | mask = ~(mask << pos); |
235 | value = value << pos; |
236 | |
237 | data = sh_pfc_read_raw_reg(mapped_reg, reg_width: crp->reg_width); |
238 | data &= mask; |
239 | data |= value; |
240 | |
241 | sh_pfc_unlock_reg(pfc, reg: crp->reg, data); |
242 | sh_pfc_write_raw_reg(mapped_reg, reg_width: crp->reg_width, data); |
243 | } |
244 | |
245 | static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id, |
246 | const struct pinmux_cfg_reg **crp, |
247 | unsigned int *fieldp, u32 *valuep) |
248 | { |
249 | unsigned int k = 0; |
250 | |
251 | while (1) { |
252 | const struct pinmux_cfg_reg *config_reg = |
253 | pfc->info->cfg_regs + k; |
254 | unsigned int r_width = config_reg->reg_width; |
255 | unsigned int f_width = config_reg->field_width; |
256 | unsigned int curr_width; |
257 | unsigned int bit_pos; |
258 | unsigned int pos = 0; |
259 | unsigned int m = 0; |
260 | |
261 | if (!r_width) |
262 | break; |
263 | |
264 | for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width, m++) { |
265 | u32 ncomb; |
266 | u32 n; |
267 | |
268 | if (f_width) { |
269 | curr_width = f_width; |
270 | } else { |
271 | curr_width = abs(config_reg->var_field_width[m]); |
272 | if (config_reg->var_field_width[m] < 0) |
273 | continue; |
274 | } |
275 | |
276 | ncomb = 1 << curr_width; |
277 | for (n = 0; n < ncomb; n++) { |
278 | if (config_reg->enum_ids[pos + n] == enum_id) { |
279 | *crp = config_reg; |
280 | *fieldp = m; |
281 | *valuep = n; |
282 | return 0; |
283 | } |
284 | } |
285 | pos += ncomb; |
286 | } |
287 | k++; |
288 | } |
289 | |
290 | return -EINVAL; |
291 | } |
292 | |
293 | static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos, |
294 | u16 *enum_idp) |
295 | { |
296 | const u16 *data = pfc->info->pinmux_data; |
297 | unsigned int k; |
298 | |
299 | if (pos) { |
300 | *enum_idp = data[pos + 1]; |
301 | return pos + 1; |
302 | } |
303 | |
304 | for (k = 0; k < pfc->info->pinmux_data_size; k++) { |
305 | if (data[k] == mark) { |
306 | *enum_idp = data[k + 1]; |
307 | return k + 1; |
308 | } |
309 | } |
310 | |
311 | dev_err(pfc->dev, "cannot locate data/mark enum_id for mark %d\n" , |
312 | mark); |
313 | return -EINVAL; |
314 | } |
315 | |
316 | int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) |
317 | { |
318 | const struct pinmux_range *range; |
319 | int pos = 0; |
320 | |
321 | switch (pinmux_type) { |
322 | case PINMUX_TYPE_GPIO: |
323 | case PINMUX_TYPE_FUNCTION: |
324 | range = NULL; |
325 | break; |
326 | |
327 | #ifdef CONFIG_PINCTRL_SH_PFC_GPIO |
328 | case PINMUX_TYPE_OUTPUT: |
329 | range = &pfc->info->output; |
330 | break; |
331 | |
332 | case PINMUX_TYPE_INPUT: |
333 | range = &pfc->info->input; |
334 | break; |
335 | #endif /* CONFIG_PINCTRL_SH_PFC_GPIO */ |
336 | |
337 | default: |
338 | return -EINVAL; |
339 | } |
340 | |
341 | /* Iterate over all the configuration fields we need to update. */ |
342 | while (1) { |
343 | const struct pinmux_cfg_reg *cr; |
344 | unsigned int field; |
345 | u16 enum_id; |
346 | u32 value; |
347 | int in_range; |
348 | int ret; |
349 | |
350 | pos = sh_pfc_mark_to_enum(pfc, mark, pos, enum_idp: &enum_id); |
351 | if (pos < 0) |
352 | return pos; |
353 | |
354 | if (!enum_id) |
355 | break; |
356 | |
357 | /* Check if the configuration field selects a function. If it |
358 | * doesn't, skip the field if it's not applicable to the |
359 | * requested pinmux type. |
360 | */ |
361 | in_range = sh_pfc_enum_in_range(enum_id, r: &pfc->info->function); |
362 | if (!in_range) { |
363 | if (pinmux_type == PINMUX_TYPE_FUNCTION) { |
364 | /* Functions are allowed to modify all |
365 | * fields. |
366 | */ |
367 | in_range = 1; |
368 | } else if (pinmux_type != PINMUX_TYPE_GPIO) { |
369 | /* Input/output types can only modify fields |
370 | * that correspond to their respective ranges. |
371 | */ |
372 | in_range = sh_pfc_enum_in_range(enum_id, r: range); |
373 | |
374 | /* |
375 | * special case pass through for fixed |
376 | * input-only or output-only pins without |
377 | * function enum register association. |
378 | */ |
379 | if (in_range && enum_id == range->force) |
380 | continue; |
381 | } |
382 | /* GPIOs are only allowed to modify function fields. */ |
383 | } |
384 | |
385 | if (!in_range) |
386 | continue; |
387 | |
388 | ret = sh_pfc_get_config_reg(pfc, enum_id, crp: &cr, fieldp: &field, valuep: &value); |
389 | if (ret < 0) |
390 | return ret; |
391 | |
392 | sh_pfc_write_config_reg(pfc, crp: cr, field, value); |
393 | } |
394 | |
395 | return 0; |
396 | } |
397 | |
398 | static int sh_pfc_init_ranges(struct sh_pfc *pfc) |
399 | { |
400 | struct sh_pfc_pin_range *range; |
401 | unsigned int nr_ranges; |
402 | unsigned int i; |
403 | |
404 | if (pfc->info->pins[0].pin == (u16)-1) { |
405 | /* Pin number -1 denotes that the SoC doesn't report pin numbers |
406 | * in its pin arrays yet. Consider the pin numbers range as |
407 | * continuous and allocate a single range. |
408 | */ |
409 | pfc->nr_ranges = 1; |
410 | pfc->ranges = devm_kzalloc(dev: pfc->dev, size: sizeof(*pfc->ranges), |
411 | GFP_KERNEL); |
412 | if (pfc->ranges == NULL) |
413 | return -ENOMEM; |
414 | |
415 | pfc->ranges->start = 0; |
416 | pfc->ranges->end = pfc->info->nr_pins - 1; |
417 | pfc->nr_gpio_pins = pfc->info->nr_pins; |
418 | |
419 | return 0; |
420 | } |
421 | |
422 | /* Count, allocate and fill the ranges. The PFC SoC data pins array must |
423 | * be sorted by pin numbers, and pins without a GPIO port must come |
424 | * last. |
425 | */ |
426 | for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) { |
427 | if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) |
428 | nr_ranges++; |
429 | } |
430 | |
431 | pfc->nr_ranges = nr_ranges; |
432 | pfc->ranges = devm_kcalloc(dev: pfc->dev, n: nr_ranges, size: sizeof(*pfc->ranges), |
433 | GFP_KERNEL); |
434 | if (pfc->ranges == NULL) |
435 | return -ENOMEM; |
436 | |
437 | range = pfc->ranges; |
438 | range->start = pfc->info->pins[0].pin; |
439 | |
440 | for (i = 1; i < pfc->info->nr_pins; ++i) { |
441 | if (pfc->info->pins[i-1].pin == pfc->info->pins[i].pin - 1) |
442 | continue; |
443 | |
444 | range->end = pfc->info->pins[i-1].pin; |
445 | if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO)) |
446 | pfc->nr_gpio_pins = range->end + 1; |
447 | |
448 | range++; |
449 | range->start = pfc->info->pins[i].pin; |
450 | } |
451 | |
452 | range->end = pfc->info->pins[i-1].pin; |
453 | if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO)) |
454 | pfc->nr_gpio_pins = range->end + 1; |
455 | |
456 | return 0; |
457 | } |
458 | |
459 | #ifdef CONFIG_OF |
460 | static const struct of_device_id sh_pfc_of_table[] = { |
461 | #ifdef CONFIG_PINCTRL_PFC_EMEV2 |
462 | { |
463 | .compatible = "renesas,pfc-emev2" , |
464 | .data = &emev2_pinmux_info, |
465 | }, |
466 | #endif |
467 | #ifdef CONFIG_PINCTRL_PFC_R8A73A4 |
468 | { |
469 | .compatible = "renesas,pfc-r8a73a4" , |
470 | .data = &r8a73a4_pinmux_info, |
471 | }, |
472 | #endif |
473 | #ifdef CONFIG_PINCTRL_PFC_R8A7740 |
474 | { |
475 | .compatible = "renesas,pfc-r8a7740" , |
476 | .data = &r8a7740_pinmux_info, |
477 | }, |
478 | #endif |
479 | #ifdef CONFIG_PINCTRL_PFC_R8A7742 |
480 | { |
481 | .compatible = "renesas,pfc-r8a7742" , |
482 | .data = &r8a7742_pinmux_info, |
483 | }, |
484 | #endif |
485 | #ifdef CONFIG_PINCTRL_PFC_R8A7743 |
486 | { |
487 | .compatible = "renesas,pfc-r8a7743" , |
488 | .data = &r8a7743_pinmux_info, |
489 | }, |
490 | #endif |
491 | #ifdef CONFIG_PINCTRL_PFC_R8A7744 |
492 | { |
493 | .compatible = "renesas,pfc-r8a7744" , |
494 | .data = &r8a7744_pinmux_info, |
495 | }, |
496 | #endif |
497 | #ifdef CONFIG_PINCTRL_PFC_R8A7745 |
498 | { |
499 | .compatible = "renesas,pfc-r8a7745" , |
500 | .data = &r8a7745_pinmux_info, |
501 | }, |
502 | #endif |
503 | #ifdef CONFIG_PINCTRL_PFC_R8A77470 |
504 | { |
505 | .compatible = "renesas,pfc-r8a77470" , |
506 | .data = &r8a77470_pinmux_info, |
507 | }, |
508 | #endif |
509 | #ifdef CONFIG_PINCTRL_PFC_R8A774A1 |
510 | { |
511 | .compatible = "renesas,pfc-r8a774a1" , |
512 | .data = &r8a774a1_pinmux_info, |
513 | }, |
514 | #endif |
515 | #ifdef CONFIG_PINCTRL_PFC_R8A774B1 |
516 | { |
517 | .compatible = "renesas,pfc-r8a774b1" , |
518 | .data = &r8a774b1_pinmux_info, |
519 | }, |
520 | #endif |
521 | #ifdef CONFIG_PINCTRL_PFC_R8A774C0 |
522 | { |
523 | .compatible = "renesas,pfc-r8a774c0" , |
524 | .data = &r8a774c0_pinmux_info, |
525 | }, |
526 | #endif |
527 | #ifdef CONFIG_PINCTRL_PFC_R8A774E1 |
528 | { |
529 | .compatible = "renesas,pfc-r8a774e1" , |
530 | .data = &r8a774e1_pinmux_info, |
531 | }, |
532 | #endif |
533 | #ifdef CONFIG_PINCTRL_PFC_R8A7778 |
534 | { |
535 | .compatible = "renesas,pfc-r8a7778" , |
536 | .data = &r8a7778_pinmux_info, |
537 | }, |
538 | #endif |
539 | #ifdef CONFIG_PINCTRL_PFC_R8A7779 |
540 | { |
541 | .compatible = "renesas,pfc-r8a7779" , |
542 | .data = &r8a7779_pinmux_info, |
543 | }, |
544 | #endif |
545 | #ifdef CONFIG_PINCTRL_PFC_R8A7790 |
546 | { |
547 | .compatible = "renesas,pfc-r8a7790" , |
548 | .data = &r8a7790_pinmux_info, |
549 | }, |
550 | #endif |
551 | #ifdef CONFIG_PINCTRL_PFC_R8A7791 |
552 | { |
553 | .compatible = "renesas,pfc-r8a7791" , |
554 | .data = &r8a7791_pinmux_info, |
555 | }, |
556 | #endif |
557 | #ifdef CONFIG_PINCTRL_PFC_R8A7792 |
558 | { |
559 | .compatible = "renesas,pfc-r8a7792" , |
560 | .data = &r8a7792_pinmux_info, |
561 | }, |
562 | #endif |
563 | #ifdef CONFIG_PINCTRL_PFC_R8A7793 |
564 | { |
565 | .compatible = "renesas,pfc-r8a7793" , |
566 | .data = &r8a7793_pinmux_info, |
567 | }, |
568 | #endif |
569 | #ifdef CONFIG_PINCTRL_PFC_R8A7794 |
570 | { |
571 | .compatible = "renesas,pfc-r8a7794" , |
572 | .data = &r8a7794_pinmux_info, |
573 | }, |
574 | #endif |
575 | #ifdef CONFIG_PINCTRL_PFC_R8A77951 |
576 | { |
577 | .compatible = "renesas,pfc-r8a7795" , |
578 | .data = &r8a77951_pinmux_info, |
579 | }, |
580 | #endif |
581 | #ifdef CONFIG_PINCTRL_PFC_R8A77960 |
582 | { |
583 | .compatible = "renesas,pfc-r8a7796" , |
584 | .data = &r8a77960_pinmux_info, |
585 | }, |
586 | #endif |
587 | #ifdef CONFIG_PINCTRL_PFC_R8A77961 |
588 | { |
589 | .compatible = "renesas,pfc-r8a77961" , |
590 | .data = &r8a77961_pinmux_info, |
591 | }, |
592 | #endif |
593 | #ifdef CONFIG_PINCTRL_PFC_R8A77965 |
594 | { |
595 | .compatible = "renesas,pfc-r8a77965" , |
596 | .data = &r8a77965_pinmux_info, |
597 | }, |
598 | #endif |
599 | #ifdef CONFIG_PINCTRL_PFC_R8A77970 |
600 | { |
601 | .compatible = "renesas,pfc-r8a77970" , |
602 | .data = &r8a77970_pinmux_info, |
603 | }, |
604 | #endif |
605 | #ifdef CONFIG_PINCTRL_PFC_R8A77980 |
606 | { |
607 | .compatible = "renesas,pfc-r8a77980" , |
608 | .data = &r8a77980_pinmux_info, |
609 | }, |
610 | #endif |
611 | #ifdef CONFIG_PINCTRL_PFC_R8A77990 |
612 | { |
613 | .compatible = "renesas,pfc-r8a77990" , |
614 | .data = &r8a77990_pinmux_info, |
615 | }, |
616 | #endif |
617 | #ifdef CONFIG_PINCTRL_PFC_R8A77995 |
618 | { |
619 | .compatible = "renesas,pfc-r8a77995" , |
620 | .data = &r8a77995_pinmux_info, |
621 | }, |
622 | #endif |
623 | #ifdef CONFIG_PINCTRL_PFC_R8A779A0 |
624 | { |
625 | .compatible = "renesas,pfc-r8a779a0" , |
626 | .data = &r8a779a0_pinmux_info, |
627 | }, |
628 | #endif |
629 | #ifdef CONFIG_PINCTRL_PFC_R8A779F0 |
630 | { |
631 | .compatible = "renesas,pfc-r8a779f0" , |
632 | .data = &r8a779f0_pinmux_info, |
633 | }, |
634 | #endif |
635 | #ifdef CONFIG_PINCTRL_PFC_R8A779G0 |
636 | { |
637 | .compatible = "renesas,pfc-r8a779g0" , |
638 | .data = &r8a779g0_pinmux_info, |
639 | }, |
640 | #endif |
641 | #ifdef CONFIG_PINCTRL_PFC_R8A779H0 |
642 | { |
643 | .compatible = "renesas,pfc-r8a779h0" , |
644 | .data = &r8a779h0_pinmux_info, |
645 | }, |
646 | #endif |
647 | #ifdef CONFIG_PINCTRL_PFC_SH73A0 |
648 | { |
649 | .compatible = "renesas,pfc-sh73a0" , |
650 | .data = &sh73a0_pinmux_info, |
651 | }, |
652 | #endif |
653 | { /* sentinel */ } |
654 | }; |
655 | #endif |
656 | |
657 | #if defined(CONFIG_ARM_PSCI_FW) |
658 | static void sh_pfc_nop_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx) |
659 | { |
660 | } |
661 | |
662 | static void sh_pfc_save_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx) |
663 | { |
664 | pfc->saved_regs[idx] = sh_pfc_read(pfc, reg); |
665 | } |
666 | |
667 | static void sh_pfc_restore_reg(struct sh_pfc *pfc, u32 reg, unsigned int idx) |
668 | { |
669 | sh_pfc_write(pfc, reg, pfc->saved_regs[idx]); |
670 | } |
671 | |
672 | static unsigned int sh_pfc_walk_regs(struct sh_pfc *pfc, |
673 | void (*do_reg)(struct sh_pfc *pfc, u32 reg, unsigned int idx)) |
674 | { |
675 | unsigned int i, n = 0; |
676 | |
677 | if (pfc->info->cfg_regs) |
678 | for (i = 0; pfc->info->cfg_regs[i].reg; i++) |
679 | do_reg(pfc, pfc->info->cfg_regs[i].reg, n++); |
680 | |
681 | if (pfc->info->drive_regs) |
682 | for (i = 0; pfc->info->drive_regs[i].reg; i++) |
683 | do_reg(pfc, pfc->info->drive_regs[i].reg, n++); |
684 | |
685 | if (pfc->info->bias_regs) |
686 | for (i = 0; pfc->info->bias_regs[i].puen || |
687 | pfc->info->bias_regs[i].pud; i++) { |
688 | if (pfc->info->bias_regs[i].puen) |
689 | do_reg(pfc, pfc->info->bias_regs[i].puen, n++); |
690 | if (pfc->info->bias_regs[i].pud) |
691 | do_reg(pfc, pfc->info->bias_regs[i].pud, n++); |
692 | } |
693 | |
694 | if (pfc->info->ioctrl_regs) |
695 | for (i = 0; pfc->info->ioctrl_regs[i].reg; i++) |
696 | do_reg(pfc, pfc->info->ioctrl_regs[i].reg, n++); |
697 | |
698 | return n; |
699 | } |
700 | |
701 | static int sh_pfc_suspend_init(struct sh_pfc *pfc) |
702 | { |
703 | unsigned int n; |
704 | |
705 | /* This is the best we can do to check for the presence of PSCI */ |
706 | if (!psci_ops.cpu_suspend) |
707 | return 0; |
708 | |
709 | n = sh_pfc_walk_regs(pfc, sh_pfc_nop_reg); |
710 | if (!n) |
711 | return 0; |
712 | |
713 | pfc->saved_regs = devm_kmalloc_array(pfc->dev, n, |
714 | sizeof(*pfc->saved_regs), |
715 | GFP_KERNEL); |
716 | if (!pfc->saved_regs) |
717 | return -ENOMEM; |
718 | |
719 | dev_dbg(pfc->dev, "Allocated space to save %u regs\n" , n); |
720 | return 0; |
721 | } |
722 | |
723 | static int sh_pfc_suspend_noirq(struct device *dev) |
724 | { |
725 | struct sh_pfc *pfc = dev_get_drvdata(dev); |
726 | |
727 | if (pfc->saved_regs) |
728 | sh_pfc_walk_regs(pfc, sh_pfc_save_reg); |
729 | return 0; |
730 | } |
731 | |
732 | static int sh_pfc_resume_noirq(struct device *dev) |
733 | { |
734 | struct sh_pfc *pfc = dev_get_drvdata(dev); |
735 | |
736 | if (pfc->saved_regs) |
737 | sh_pfc_walk_regs(pfc, sh_pfc_restore_reg); |
738 | return 0; |
739 | } |
740 | #define pm_psci_sleep_ptr(_ptr) pm_sleep_ptr(_ptr) |
741 | #else |
742 | static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; } |
743 | static int sh_pfc_suspend_noirq(struct device *dev) { return 0; } |
744 | static int sh_pfc_resume_noirq(struct device *dev) { return 0; } |
745 | #define pm_psci_sleep_ptr(_ptr) PTR_IF(false, (_ptr)) |
746 | #endif /* CONFIG_ARM_PSCI_FW */ |
747 | |
748 | static DEFINE_NOIRQ_DEV_PM_OPS(sh_pfc_pm, sh_pfc_suspend_noirq, sh_pfc_resume_noirq); |
749 | |
750 | #ifdef DEBUG |
751 | #define SH_PFC_MAX_REGS 300 |
752 | #define SH_PFC_MAX_ENUMS 5000 |
753 | |
754 | static unsigned int sh_pfc_errors __initdata; |
755 | static unsigned int sh_pfc_warnings __initdata; |
756 | static bool sh_pfc_bias_done __initdata; |
757 | static bool sh_pfc_drive_done __initdata; |
758 | static bool sh_pfc_power_done __initdata; |
759 | static struct { |
760 | u32 reg; |
761 | u32 bits; |
762 | } *sh_pfc_regs __initdata; |
763 | static u32 sh_pfc_num_regs __initdata; |
764 | static u16 *sh_pfc_enums __initdata; |
765 | static u32 sh_pfc_num_enums __initdata; |
766 | |
767 | #define sh_pfc_err(fmt, ...) \ |
768 | do { \ |
769 | pr_err("%s: " fmt, drvname, ##__VA_ARGS__); \ |
770 | sh_pfc_errors++; \ |
771 | } while (0) |
772 | |
773 | #define sh_pfc_err_once(type, fmt, ...) \ |
774 | do { \ |
775 | if (!sh_pfc_ ## type ## _done) { \ |
776 | sh_pfc_ ## type ## _done = true; \ |
777 | sh_pfc_err(fmt, ##__VA_ARGS__); \ |
778 | } \ |
779 | } while (0) |
780 | |
781 | #define sh_pfc_warn(fmt, ...) \ |
782 | do { \ |
783 | pr_warn("%s: " fmt, drvname, ##__VA_ARGS__); \ |
784 | sh_pfc_warnings++; \ |
785 | } while (0) |
786 | |
787 | static bool __init is0s(const u16 *enum_ids, unsigned int n) |
788 | { |
789 | unsigned int i; |
790 | |
791 | for (i = 0; i < n; i++) |
792 | if (enum_ids[i]) |
793 | return false; |
794 | |
795 | return true; |
796 | } |
797 | |
798 | static bool __init same_name(const char *a, const char *b) |
799 | { |
800 | return a && b && !strcmp(a, b); |
801 | } |
802 | |
803 | static void __init sh_pfc_check_reg(const char *drvname, u32 reg, u32 bits) |
804 | { |
805 | unsigned int i; |
806 | |
807 | for (i = 0; i < sh_pfc_num_regs; i++) { |
808 | if (reg != sh_pfc_regs[i].reg) |
809 | continue; |
810 | |
811 | if (bits & sh_pfc_regs[i].bits) |
812 | sh_pfc_err("reg 0x%x: bits 0x%x conflict\n" , reg, |
813 | bits & sh_pfc_regs[i].bits); |
814 | |
815 | sh_pfc_regs[i].bits |= bits; |
816 | return; |
817 | } |
818 | |
819 | if (sh_pfc_num_regs == SH_PFC_MAX_REGS) { |
820 | pr_warn_once("%s: Please increase SH_PFC_MAX_REGS\n" , drvname); |
821 | return; |
822 | } |
823 | |
824 | sh_pfc_regs[sh_pfc_num_regs].reg = reg; |
825 | sh_pfc_regs[sh_pfc_num_regs].bits = bits; |
826 | sh_pfc_num_regs++; |
827 | } |
828 | |
829 | static int __init sh_pfc_check_enum(const char *drvname, u16 enum_id) |
830 | { |
831 | unsigned int i; |
832 | |
833 | for (i = 0; i < sh_pfc_num_enums; i++) { |
834 | if (enum_id == sh_pfc_enums[i]) |
835 | return -EINVAL; |
836 | } |
837 | |
838 | if (sh_pfc_num_enums == SH_PFC_MAX_ENUMS) { |
839 | pr_warn_once("%s: Please increase SH_PFC_MAX_ENUMS\n" , drvname); |
840 | return 0; |
841 | } |
842 | |
843 | sh_pfc_enums[sh_pfc_num_enums++] = enum_id; |
844 | return 0; |
845 | } |
846 | |
847 | static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg, |
848 | const u16 *enums, unsigned int n) |
849 | { |
850 | unsigned int i; |
851 | |
852 | for (i = 0; i < n; i++) { |
853 | if (enums[i] && sh_pfc_check_enum(drvname, enum_id: enums[i])) |
854 | sh_pfc_err("reg 0x%x enum_id %u conflict\n" , reg, |
855 | enums[i]); |
856 | } |
857 | } |
858 | |
859 | static const struct sh_pfc_pin __init *sh_pfc_find_pin( |
860 | const struct sh_pfc_soc_info *info, u32 reg, unsigned int pin) |
861 | { |
862 | const char *drvname = info->name; |
863 | unsigned int i; |
864 | |
865 | if (pin == SH_PFC_PIN_NONE) |
866 | return NULL; |
867 | |
868 | for (i = 0; i < info->nr_pins; i++) { |
869 | if (pin == info->pins[i].pin) |
870 | return &info->pins[i]; |
871 | } |
872 | |
873 | sh_pfc_err("reg 0x%x: pin %u not found\n" , reg, pin); |
874 | return NULL; |
875 | } |
876 | |
877 | static void __init sh_pfc_check_cfg_reg(const char *drvname, |
878 | const struct pinmux_cfg_reg *cfg_reg) |
879 | { |
880 | unsigned int i, n, rw, r; |
881 | int fw; |
882 | |
883 | sh_pfc_check_reg(drvname, reg: cfg_reg->reg, |
884 | GENMASK(cfg_reg->reg_width - 1, 0)); |
885 | |
886 | if (cfg_reg->field_width) { |
887 | fw = cfg_reg->field_width; |
888 | n = (cfg_reg->reg_width / fw) << fw; |
889 | for (i = 0, r = 0; i < n; i += 1 << fw) { |
890 | if (is0s(enum_ids: &cfg_reg->enum_ids[i], n: 1 << fw)) |
891 | r++; |
892 | } |
893 | |
894 | if ((r << fw) * sizeof(u16) > cfg_reg->reg_width / fw) |
895 | sh_pfc_warn("reg 0x%x can be described with variable-width reserved fields\n" , |
896 | cfg_reg->reg); |
897 | |
898 | /* Skip field checks (done at build time) */ |
899 | goto check_enum_ids; |
900 | } |
901 | |
902 | for (i = 0, n = 0, rw = 0; (fw = cfg_reg->var_field_width[i]); i++) { |
903 | if (fw < 0) { |
904 | rw += -fw; |
905 | } else { |
906 | if (is0s(enum_ids: &cfg_reg->enum_ids[n], n: 1 << fw)) |
907 | sh_pfc_warn("reg 0x%x: field [%u:%u] can be described as reserved\n" , |
908 | cfg_reg->reg, rw, rw + fw - 1); |
909 | n += 1 << fw; |
910 | rw += fw; |
911 | } |
912 | } |
913 | |
914 | if (rw != cfg_reg->reg_width) |
915 | sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n" , |
916 | cfg_reg->reg, rw, cfg_reg->reg_width); |
917 | |
918 | if (n != cfg_reg->nr_enum_ids) { |
919 | sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n" , |
920 | cfg_reg->reg, cfg_reg->nr_enum_ids, n); |
921 | n = cfg_reg->nr_enum_ids; |
922 | } |
923 | |
924 | check_enum_ids: |
925 | sh_pfc_check_reg_enums(drvname, reg: cfg_reg->reg, enums: cfg_reg->enum_ids, n); |
926 | } |
927 | |
928 | static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info, |
929 | const struct pinmux_drive_reg *drive) |
930 | { |
931 | const char *drvname = info->name; |
932 | const struct sh_pfc_pin *pin; |
933 | unsigned int i; |
934 | |
935 | for (i = 0; i < ARRAY_SIZE(drive->fields); i++) { |
936 | const struct pinmux_drive_reg_field *field = &drive->fields[i]; |
937 | |
938 | if (!field->pin && !field->offset && !field->size) |
939 | continue; |
940 | |
941 | sh_pfc_check_reg(drvname: info->name, reg: drive->reg, |
942 | GENMASK(field->offset + field->size - 1, |
943 | field->offset)); |
944 | |
945 | pin = sh_pfc_find_pin(info, reg: drive->reg, pin: field->pin); |
946 | if (pin && !(pin->configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH)) |
947 | sh_pfc_err("drive_reg 0x%x: field %u: pin %s lacks SH_PFC_PIN_CFG_DRIVE_STRENGTH flag\n" , |
948 | drive->reg, i, pin->name); |
949 | } |
950 | } |
951 | |
952 | static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info, |
953 | const struct pinmux_bias_reg *bias) |
954 | { |
955 | const char *drvname = info->name; |
956 | const struct sh_pfc_pin *pin; |
957 | unsigned int i; |
958 | u32 bits; |
959 | |
960 | for (i = 0, bits = 0; i < ARRAY_SIZE(bias->pins); i++) |
961 | if (bias->pins[i] != SH_PFC_PIN_NONE) |
962 | bits |= BIT(i); |
963 | |
964 | if (bias->puen) |
965 | sh_pfc_check_reg(drvname: info->name, reg: bias->puen, bits); |
966 | if (bias->pud) |
967 | sh_pfc_check_reg(drvname: info->name, reg: bias->pud, bits); |
968 | for (i = 0; i < ARRAY_SIZE(bias->pins); i++) { |
969 | pin = sh_pfc_find_pin(info, reg: bias->puen, pin: bias->pins[i]); |
970 | if (!pin) |
971 | continue; |
972 | |
973 | if (bias->puen && bias->pud) { |
974 | /* |
975 | * Pull-enable and pull-up/down control registers |
976 | * As some SoCs have pins that support only pull-up |
977 | * or pull-down, we just check for one of them |
978 | */ |
979 | if (!(pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN)) |
980 | sh_pfc_err("bias_reg 0x%x:%u: pin %s lacks one or more SH_PFC_PIN_CFG_PULL_* flags\n" , |
981 | bias->puen, i, pin->name); |
982 | } else if (bias->puen) { |
983 | /* Pull-up control register only */ |
984 | if (!(pin->configs & SH_PFC_PIN_CFG_PULL_UP)) |
985 | sh_pfc_err("bias_reg 0x%x:%u: pin %s lacks SH_PFC_PIN_CFG_PULL_UP flag\n" , |
986 | bias->puen, i, pin->name); |
987 | } else if (bias->pud) { |
988 | /* Pull-down control register only */ |
989 | if (!(pin->configs & SH_PFC_PIN_CFG_PULL_DOWN)) |
990 | sh_pfc_err("bias_reg 0x%x:%u: pin %s lacks SH_PFC_PIN_CFG_PULL_DOWN flag\n" , |
991 | bias->pud, i, pin->name); |
992 | } |
993 | } |
994 | } |
995 | |
996 | static void __init sh_pfc_compare_groups(const char *drvname, |
997 | const struct sh_pfc_pin_group *a, |
998 | const struct sh_pfc_pin_group *b) |
999 | { |
1000 | unsigned int i; |
1001 | size_t len; |
1002 | |
1003 | if (same_name(a: a->name, b: b->name)) |
1004 | sh_pfc_err("group %s: name conflict\n" , a->name); |
1005 | |
1006 | if (a->nr_pins > b->nr_pins) |
1007 | swap(a, b); |
1008 | |
1009 | len = a->nr_pins * sizeof(a->pins[0]); |
1010 | for (i = 0; i <= b->nr_pins - a->nr_pins; i++) { |
1011 | if (a->pins == b->pins + i || a->mux == b->mux + i || |
1012 | memcmp(p: a->pins, q: b->pins + i, size: len) || |
1013 | memcmp(p: a->mux, q: b->mux + i, size: len)) |
1014 | continue; |
1015 | |
1016 | if (a->nr_pins == b->nr_pins) |
1017 | sh_pfc_warn("group %s can be an alias for %s\n" , |
1018 | a->name, b->name); |
1019 | else |
1020 | sh_pfc_warn("group %s is a subset of %s\n" , a->name, |
1021 | b->name); |
1022 | } |
1023 | } |
1024 | |
1025 | static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) |
1026 | { |
1027 | const struct pinmux_drive_reg *drive_regs = info->drive_regs; |
1028 | #define drive_nfields ARRAY_SIZE(drive_regs->fields) |
1029 | #define drive_ofs(i) drive_regs[(i) / drive_nfields] |
1030 | #define drive_reg(i) drive_ofs(i).reg |
1031 | #define drive_bit(i) ((i) % drive_nfields) |
1032 | #define drive_field(i) drive_ofs(i).fields[drive_bit(i)] |
1033 | const struct pinmux_bias_reg *bias_regs = info->bias_regs; |
1034 | #define bias_npins ARRAY_SIZE(bias_regs->pins) |
1035 | #define bias_ofs(i) bias_regs[(i) / bias_npins] |
1036 | #define bias_puen(i) bias_ofs(i).puen |
1037 | #define bias_pud(i) bias_ofs(i).pud |
1038 | #define bias_bit(i) ((i) % bias_npins) |
1039 | #define bias_pin(i) bias_ofs(i).pins[bias_bit(i)] |
1040 | const char *drvname = info->name; |
1041 | unsigned int *refcnts; |
1042 | unsigned int i, j, k; |
1043 | |
1044 | pr_info("sh_pfc: Checking %s\n" , drvname); |
1045 | sh_pfc_num_regs = 0; |
1046 | sh_pfc_num_enums = 0; |
1047 | sh_pfc_bias_done = false; |
1048 | sh_pfc_drive_done = false; |
1049 | sh_pfc_power_done = false; |
1050 | |
1051 | /* Check pins */ |
1052 | for (i = 0; i < info->nr_pins; i++) { |
1053 | const struct sh_pfc_pin *pin = &info->pins[i]; |
1054 | unsigned int x; |
1055 | |
1056 | if (!pin->name) { |
1057 | sh_pfc_err("empty pin %u\n" , i); |
1058 | continue; |
1059 | } |
1060 | for (j = 0; j < i; j++) { |
1061 | const struct sh_pfc_pin *pin2 = &info->pins[j]; |
1062 | |
1063 | if (same_name(a: pin->name, b: pin2->name)) |
1064 | sh_pfc_err("pin %s: name conflict\n" , |
1065 | pin->name); |
1066 | |
1067 | if (pin->pin != (u16)-1 && pin->pin == pin2->pin) |
1068 | sh_pfc_err("pin %s/%s: pin %u conflict\n" , |
1069 | pin->name, pin2->name, pin->pin); |
1070 | |
1071 | if (pin->enum_id && pin->enum_id == pin2->enum_id) |
1072 | sh_pfc_err("pin %s/%s: enum_id %u conflict\n" , |
1073 | pin->name, pin2->name, |
1074 | pin->enum_id); |
1075 | } |
1076 | |
1077 | if (pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN) { |
1078 | if (!info->ops || !info->ops->get_bias || |
1079 | !info->ops->set_bias) |
1080 | sh_pfc_err_once(bias, "SH_PFC_PIN_CFG_PULL_* flag set but .[gs]et_bias() not implemented\n" ); |
1081 | |
1082 | if (!bias_regs && |
1083 | (!info->ops || !info->ops->pin_to_portcr)) |
1084 | sh_pfc_err_once(bias, "SH_PFC_PIN_CFG_PULL_UP flag set but no bias_regs defined and .pin_to_portcr() not implemented\n" ); |
1085 | } |
1086 | |
1087 | if ((pin->configs & SH_PFC_PIN_CFG_PULL_UP_DOWN) && bias_regs) { |
1088 | const struct pinmux_bias_reg *bias_reg = |
1089 | rcar_pin_to_bias_reg(info, pin: pin->pin, bit: &x); |
1090 | |
1091 | if (!bias_reg || |
1092 | ((pin->configs & SH_PFC_PIN_CFG_PULL_UP) && |
1093 | !bias_reg->puen)) |
1094 | sh_pfc_err("pin %s: SH_PFC_PIN_CFG_PULL_UP flag set but pin not in bias_regs\n" , |
1095 | pin->name); |
1096 | |
1097 | if (!bias_reg || |
1098 | ((pin->configs & SH_PFC_PIN_CFG_PULL_DOWN) && |
1099 | !bias_reg->pud)) |
1100 | sh_pfc_err("pin %s: SH_PFC_PIN_CFG_PULL_DOWN flag set but pin not in bias_regs\n" , |
1101 | pin->name); |
1102 | } |
1103 | |
1104 | if (pin->configs & SH_PFC_PIN_CFG_DRIVE_STRENGTH) { |
1105 | if (!drive_regs) { |
1106 | sh_pfc_err_once(drive, "SH_PFC_PIN_CFG_DRIVE_STRENGTH flag set but drive_regs missing\n" ); |
1107 | } else { |
1108 | for (j = 0; drive_reg(j); j++) { |
1109 | if (!drive_field(j).pin && |
1110 | !drive_field(j).offset && |
1111 | !drive_field(j).size) |
1112 | continue; |
1113 | |
1114 | if (drive_field(j).pin == pin->pin) |
1115 | break; |
1116 | } |
1117 | |
1118 | if (!drive_reg(j)) |
1119 | sh_pfc_err("pin %s: SH_PFC_PIN_CFG_DRIVE_STRENGTH flag set but not in drive_regs\n" , |
1120 | pin->name); |
1121 | } |
1122 | } |
1123 | |
1124 | if (pin->configs & SH_PFC_PIN_CFG_IO_VOLTAGE_MASK) { |
1125 | if (!info->ops || !info->ops->pin_to_pocctrl) |
1126 | sh_pfc_err_once(power, "SH_PFC_PIN_CFG_IO_VOLTAGE set but .pin_to_pocctrl() not implemented\n" ); |
1127 | else if (info->ops->pin_to_pocctrl(pin->pin, &x) < 0) |
1128 | sh_pfc_err("pin %s: SH_PFC_PIN_CFG_IO_VOLTAGE set but invalid pin_to_pocctrl()\n" , |
1129 | pin->name); |
1130 | } else if (info->ops && info->ops->pin_to_pocctrl && |
1131 | info->ops->pin_to_pocctrl(pin->pin, &x) >= 0) { |
1132 | sh_pfc_warn("pin %s: SH_PFC_PIN_CFG_IO_VOLTAGE not set but valid pin_to_pocctrl()\n" , |
1133 | pin->name); |
1134 | } |
1135 | } |
1136 | |
1137 | /* Check groups and functions */ |
1138 | refcnts = kcalloc(n: info->nr_groups, size: sizeof(*refcnts), GFP_KERNEL); |
1139 | if (!refcnts) |
1140 | return; |
1141 | |
1142 | for (i = 0; i < info->nr_functions; i++) { |
1143 | const struct sh_pfc_function *func = &info->functions[i]; |
1144 | |
1145 | if (!func->name) { |
1146 | sh_pfc_err("empty function %u\n" , i); |
1147 | continue; |
1148 | } |
1149 | for (j = 0; j < i; j++) { |
1150 | if (same_name(a: func->name, b: info->functions[j].name)) |
1151 | sh_pfc_err("function %s: name conflict\n" , |
1152 | func->name); |
1153 | } |
1154 | for (j = 0; j < func->nr_groups; j++) { |
1155 | for (k = 0; k < info->nr_groups; k++) { |
1156 | if (same_name(a: func->groups[j], |
1157 | b: info->groups[k].name)) { |
1158 | refcnts[k]++; |
1159 | break; |
1160 | } |
1161 | } |
1162 | |
1163 | if (k == info->nr_groups) |
1164 | sh_pfc_err("function %s: group %s not found\n" , |
1165 | func->name, func->groups[j]); |
1166 | } |
1167 | } |
1168 | |
1169 | for (i = 0; i < info->nr_groups; i++) { |
1170 | const struct sh_pfc_pin_group *group = &info->groups[i]; |
1171 | |
1172 | if (!group->name) { |
1173 | sh_pfc_err("empty group %u\n" , i); |
1174 | continue; |
1175 | } |
1176 | for (j = 0; j < i; j++) |
1177 | sh_pfc_compare_groups(drvname, a: group, b: &info->groups[j]); |
1178 | |
1179 | if (!refcnts[i]) |
1180 | sh_pfc_err("orphan group %s\n" , group->name); |
1181 | else if (refcnts[i] > 1) |
1182 | sh_pfc_warn("group %s referenced by %u functions\n" , |
1183 | group->name, refcnts[i]); |
1184 | } |
1185 | |
1186 | kfree(objp: refcnts); |
1187 | |
1188 | /* Check config register descriptions */ |
1189 | for (i = 0; info->cfg_regs && info->cfg_regs[i].reg; i++) |
1190 | sh_pfc_check_cfg_reg(drvname, cfg_reg: &info->cfg_regs[i]); |
1191 | |
1192 | /* Check drive strength registers */ |
1193 | for (i = 0; drive_regs && drive_regs[i].reg; i++) |
1194 | sh_pfc_check_drive_reg(info, drive: &drive_regs[i]); |
1195 | |
1196 | for (i = 0; drive_regs && drive_reg(i); i++) { |
1197 | if (!drive_field(i).pin && !drive_field(i).offset && |
1198 | !drive_field(i).size) |
1199 | continue; |
1200 | |
1201 | for (j = 0; j < i; j++) { |
1202 | if (drive_field(i).pin == drive_field(j).pin && |
1203 | drive_field(j).offset && drive_field(j).size) { |
1204 | sh_pfc_err("drive_reg 0x%x:%zu/0x%x:%zu: pin conflict\n" , |
1205 | drive_reg(i), drive_bit(i), |
1206 | drive_reg(j), drive_bit(j)); |
1207 | } |
1208 | } |
1209 | } |
1210 | |
1211 | /* Check bias registers */ |
1212 | for (i = 0; bias_regs && (bias_regs[i].puen || bias_regs[i].pud); i++) |
1213 | sh_pfc_check_bias_reg(info, bias: &bias_regs[i]); |
1214 | |
1215 | for (i = 0; bias_regs && (bias_puen(i) || bias_pud(i)); i++) { |
1216 | if (bias_pin(i) == SH_PFC_PIN_NONE) |
1217 | continue; |
1218 | |
1219 | for (j = 0; j < i; j++) { |
1220 | if (bias_pin(i) != bias_pin(j)) |
1221 | continue; |
1222 | |
1223 | if (bias_puen(i) && bias_puen(j)) |
1224 | sh_pfc_err("bias_reg 0x%x:%zu/0x%x:%zu: pin conflict\n" , |
1225 | bias_puen(i), bias_bit(i), |
1226 | bias_puen(j), bias_bit(j)); |
1227 | if (bias_pud(i) && bias_pud(j)) |
1228 | sh_pfc_err("bias_reg 0x%x:%zu/0x%x:%zu: pin conflict\n" , |
1229 | bias_pud(i), bias_bit(i), |
1230 | bias_pud(j), bias_bit(j)); |
1231 | } |
1232 | } |
1233 | |
1234 | /* Check ioctrl registers */ |
1235 | for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++) |
1236 | sh_pfc_check_reg(drvname, reg: info->ioctrl_regs[i].reg, U32_MAX); |
1237 | |
1238 | /* Check data registers */ |
1239 | for (i = 0; info->data_regs && info->data_regs[i].reg; i++) { |
1240 | sh_pfc_check_reg(drvname, reg: info->data_regs[i].reg, |
1241 | GENMASK(info->data_regs[i].reg_width - 1, 0)); |
1242 | sh_pfc_check_reg_enums(drvname, reg: info->data_regs[i].reg, |
1243 | enums: info->data_regs[i].enum_ids, |
1244 | n: info->data_regs[i].reg_width); |
1245 | } |
1246 | |
1247 | #ifdef CONFIG_PINCTRL_SH_FUNC_GPIO |
1248 | /* Check function GPIOs */ |
1249 | for (i = 0; i < info->nr_func_gpios; i++) { |
1250 | const struct pinmux_func *func = &info->func_gpios[i]; |
1251 | |
1252 | if (!func->name) { |
1253 | sh_pfc_err("empty function gpio %u\n" , i); |
1254 | continue; |
1255 | } |
1256 | for (j = 0; j < i; j++) { |
1257 | if (same_name(a: func->name, b: info->func_gpios[j].name)) |
1258 | sh_pfc_err("func_gpio %s: name conflict\n" , |
1259 | func->name); |
1260 | } |
1261 | if (sh_pfc_check_enum(drvname, enum_id: func->enum_id)) |
1262 | sh_pfc_err("%s enum_id %u conflict\n" , func->name, |
1263 | func->enum_id); |
1264 | } |
1265 | #endif |
1266 | } |
1267 | |
1268 | static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) |
1269 | { |
1270 | unsigned int i; |
1271 | |
1272 | if (!IS_ENABLED(CONFIG_SUPERH) && |
1273 | !of_find_matching_node(NULL, matches: pdrv->driver.of_match_table)) |
1274 | return; |
1275 | |
1276 | sh_pfc_regs = kcalloc(SH_PFC_MAX_REGS, size: sizeof(*sh_pfc_regs), |
1277 | GFP_KERNEL); |
1278 | if (!sh_pfc_regs) |
1279 | return; |
1280 | |
1281 | sh_pfc_enums = kcalloc(SH_PFC_MAX_ENUMS, size: sizeof(*sh_pfc_enums), |
1282 | GFP_KERNEL); |
1283 | if (!sh_pfc_enums) |
1284 | goto free_regs; |
1285 | |
1286 | pr_warn("sh_pfc: Checking builtin pinmux tables\n" ); |
1287 | |
1288 | for (i = 0; pdrv->id_table[i].name[0]; i++) |
1289 | sh_pfc_check_info(info: (void *)pdrv->id_table[i].driver_data); |
1290 | |
1291 | #ifdef CONFIG_OF |
1292 | for (i = 0; pdrv->driver.of_match_table[i].compatible[0]; i++) |
1293 | sh_pfc_check_info(info: pdrv->driver.of_match_table[i].data); |
1294 | #endif |
1295 | |
1296 | pr_warn("sh_pfc: Detected %u errors and %u warnings\n" , sh_pfc_errors, |
1297 | sh_pfc_warnings); |
1298 | |
1299 | kfree(objp: sh_pfc_enums); |
1300 | free_regs: |
1301 | kfree(objp: sh_pfc_regs); |
1302 | } |
1303 | |
1304 | #else /* !DEBUG */ |
1305 | static inline void sh_pfc_check_driver(struct platform_driver *pdrv) {} |
1306 | #endif /* !DEBUG */ |
1307 | |
1308 | static int sh_pfc_probe(struct platform_device *pdev) |
1309 | { |
1310 | const struct sh_pfc_soc_info *info; |
1311 | struct sh_pfc *pfc; |
1312 | int ret; |
1313 | |
1314 | if (pdev->dev.of_node) |
1315 | info = of_device_get_match_data(dev: &pdev->dev); |
1316 | else |
1317 | info = (const void *)platform_get_device_id(pdev)->driver_data; |
1318 | |
1319 | pfc = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pfc), GFP_KERNEL); |
1320 | if (pfc == NULL) |
1321 | return -ENOMEM; |
1322 | |
1323 | pfc->info = info; |
1324 | pfc->dev = &pdev->dev; |
1325 | |
1326 | ret = sh_pfc_map_resources(pfc, pdev); |
1327 | if (unlikely(ret < 0)) |
1328 | return ret; |
1329 | |
1330 | spin_lock_init(&pfc->lock); |
1331 | |
1332 | if (info->ops && info->ops->init) { |
1333 | ret = info->ops->init(pfc); |
1334 | if (ret < 0) |
1335 | return ret; |
1336 | |
1337 | /* .init() may have overridden pfc->info */ |
1338 | info = pfc->info; |
1339 | } |
1340 | |
1341 | ret = sh_pfc_suspend_init(pfc); |
1342 | if (ret) |
1343 | return ret; |
1344 | |
1345 | /* Enable dummy states for those platforms without pinctrl support */ |
1346 | if (!of_have_populated_dt()) |
1347 | pinctrl_provide_dummies(); |
1348 | |
1349 | ret = sh_pfc_init_ranges(pfc); |
1350 | if (ret < 0) |
1351 | return ret; |
1352 | |
1353 | /* |
1354 | * Initialize pinctrl bindings first |
1355 | */ |
1356 | ret = sh_pfc_register_pinctrl(pfc); |
1357 | if (unlikely(ret != 0)) |
1358 | return ret; |
1359 | |
1360 | #ifdef CONFIG_PINCTRL_SH_PFC_GPIO |
1361 | /* |
1362 | * Then the GPIO chip |
1363 | */ |
1364 | ret = sh_pfc_register_gpiochip(pfc); |
1365 | if (unlikely(ret != 0)) { |
1366 | /* |
1367 | * If the GPIO chip fails to come up we still leave the |
1368 | * PFC state as it is, given that there are already |
1369 | * extant users of it that have succeeded by this point. |
1370 | */ |
1371 | dev_notice(pfc->dev, "failed to init GPIO chip, ignoring...\n" ); |
1372 | } |
1373 | #endif |
1374 | |
1375 | platform_set_drvdata(pdev, data: pfc); |
1376 | |
1377 | dev_info(pfc->dev, "%s support registered\n" , info->name); |
1378 | |
1379 | return 0; |
1380 | } |
1381 | |
1382 | static const struct platform_device_id sh_pfc_id_table[] = { |
1383 | #ifdef CONFIG_PINCTRL_PFC_SH7203 |
1384 | { "pfc-sh7203" , (kernel_ulong_t)&sh7203_pinmux_info }, |
1385 | #endif |
1386 | #ifdef CONFIG_PINCTRL_PFC_SH7264 |
1387 | { "pfc-sh7264" , (kernel_ulong_t)&sh7264_pinmux_info }, |
1388 | #endif |
1389 | #ifdef CONFIG_PINCTRL_PFC_SH7269 |
1390 | { "pfc-sh7269" , (kernel_ulong_t)&sh7269_pinmux_info }, |
1391 | #endif |
1392 | #ifdef CONFIG_PINCTRL_PFC_SH7720 |
1393 | { "pfc-sh7720" , (kernel_ulong_t)&sh7720_pinmux_info }, |
1394 | #endif |
1395 | #ifdef CONFIG_PINCTRL_PFC_SH7722 |
1396 | { "pfc-sh7722" , (kernel_ulong_t)&sh7722_pinmux_info }, |
1397 | #endif |
1398 | #ifdef CONFIG_PINCTRL_PFC_SH7723 |
1399 | { "pfc-sh7723" , (kernel_ulong_t)&sh7723_pinmux_info }, |
1400 | #endif |
1401 | #ifdef CONFIG_PINCTRL_PFC_SH7724 |
1402 | { "pfc-sh7724" , (kernel_ulong_t)&sh7724_pinmux_info }, |
1403 | #endif |
1404 | #ifdef CONFIG_PINCTRL_PFC_SH7734 |
1405 | { "pfc-sh7734" , (kernel_ulong_t)&sh7734_pinmux_info }, |
1406 | #endif |
1407 | #ifdef CONFIG_PINCTRL_PFC_SH7757 |
1408 | { "pfc-sh7757" , (kernel_ulong_t)&sh7757_pinmux_info }, |
1409 | #endif |
1410 | #ifdef CONFIG_PINCTRL_PFC_SH7785 |
1411 | { "pfc-sh7785" , (kernel_ulong_t)&sh7785_pinmux_info }, |
1412 | #endif |
1413 | #ifdef CONFIG_PINCTRL_PFC_SH7786 |
1414 | { "pfc-sh7786" , (kernel_ulong_t)&sh7786_pinmux_info }, |
1415 | #endif |
1416 | #ifdef CONFIG_PINCTRL_PFC_SHX3 |
1417 | { "pfc-shx3" , (kernel_ulong_t)&shx3_pinmux_info }, |
1418 | #endif |
1419 | { /* sentinel */ } |
1420 | }; |
1421 | |
1422 | static struct platform_driver sh_pfc_driver = { |
1423 | .probe = sh_pfc_probe, |
1424 | .id_table = sh_pfc_id_table, |
1425 | .driver = { |
1426 | .name = DRV_NAME, |
1427 | .of_match_table = of_match_ptr(sh_pfc_of_table), |
1428 | .pm = pm_psci_sleep_ptr(&sh_pfc_pm), |
1429 | }, |
1430 | }; |
1431 | |
1432 | static int __init sh_pfc_init(void) |
1433 | { |
1434 | sh_pfc_check_driver(pdrv: &sh_pfc_driver); |
1435 | return platform_driver_register(&sh_pfc_driver); |
1436 | } |
1437 | postcore_initcall(sh_pfc_init); |
1438 | |