Commit acac8ed5e2aa2c0d364d06f364fd9ed0dc27d28a
1 parent
28818fa5da
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
sh-pfc: Compute pin ranges automatically
Remove the manually specified ranges from PFC SoC data and compute the ranges automatically. This prevents ranges from being out-of-sync with pins definitions. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Tested-by: Yusuke Goda <yusuke.goda.sx@renesas.com>
Showing 7 changed files with 88 additions and 88 deletions Side-by-side Diff
drivers/pinctrl/sh-pfc/core.c
... | ... | @@ -82,17 +82,14 @@ |
82 | 82 | unsigned int offset; |
83 | 83 | unsigned int i; |
84 | 84 | |
85 | - if (pfc->info->ranges == NULL) | |
86 | - return pin; | |
85 | + for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) { | |
86 | + const struct sh_pfc_pin_range *range = &pfc->ranges[i]; | |
87 | 87 | |
88 | - for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) { | |
89 | - const struct pinmux_range *range = &pfc->info->ranges[i]; | |
90 | - | |
91 | 88 | if (pin <= range->end) |
92 | - return pin >= range->begin | |
93 | - ? offset + pin - range->begin : -1; | |
89 | + return pin >= range->start | |
90 | + ? offset + pin - range->start : -1; | |
94 | 91 | |
95 | - offset += range->end - range->begin + 1; | |
92 | + offset += range->end - range->start + 1; | |
96 | 93 | } |
97 | 94 | |
98 | 95 | return -EINVAL; |
... | ... | @@ -341,6 +338,59 @@ |
341 | 338 | return 0; |
342 | 339 | } |
343 | 340 | |
341 | +static int sh_pfc_init_ranges(struct sh_pfc *pfc) | |
342 | +{ | |
343 | + struct sh_pfc_pin_range *range; | |
344 | + unsigned int nr_ranges; | |
345 | + unsigned int i; | |
346 | + | |
347 | + if (pfc->info->pins[0].pin == (u16)-1) { | |
348 | + /* Pin number -1 denotes that the SoC doesn't report pin numbers | |
349 | + * in its pin arrays yet. Consider the pin numbers range as | |
350 | + * continuous and allocate a single range. | |
351 | + */ | |
352 | + pfc->nr_ranges = 1; | |
353 | + pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges), | |
354 | + GFP_KERNEL); | |
355 | + if (pfc->ranges == NULL) | |
356 | + return -ENOMEM; | |
357 | + | |
358 | + pfc->ranges->start = 0; | |
359 | + pfc->ranges->end = pfc->info->nr_pins - 1; | |
360 | + pfc->nr_gpio_pins = pfc->info->nr_pins; | |
361 | + | |
362 | + return 0; | |
363 | + } | |
364 | + | |
365 | + /* Count, allocate and fill the ranges. */ | |
366 | + for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) { | |
367 | + if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) | |
368 | + nr_ranges++; | |
369 | + } | |
370 | + | |
371 | + pfc->nr_ranges = nr_ranges; | |
372 | + pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges) * nr_ranges, | |
373 | + GFP_KERNEL); | |
374 | + if (pfc->ranges == NULL) | |
375 | + return -ENOMEM; | |
376 | + | |
377 | + range = pfc->ranges; | |
378 | + range->start = pfc->info->pins[0].pin; | |
379 | + | |
380 | + for (i = 1; i < pfc->info->nr_pins; ++i) { | |
381 | + if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) { | |
382 | + range->end = pfc->info->pins[i-1].pin; | |
383 | + range++; | |
384 | + range->start = pfc->info->pins[i].pin; | |
385 | + } | |
386 | + } | |
387 | + | |
388 | + range->end = pfc->info->pins[i-1].pin; | |
389 | + pfc->nr_gpio_pins = range->end + 1; | |
390 | + | |
391 | + return 0; | |
392 | +} | |
393 | + | |
344 | 394 | #ifdef CONFIG_OF |
345 | 395 | static const struct of_device_id sh_pfc_of_table[] = { |
346 | 396 | #ifdef CONFIG_PINCTRL_PFC_R8A73A4 |
... | ... | @@ -430,6 +480,10 @@ |
430 | 480 | } |
431 | 481 | |
432 | 482 | pinctrl_provide_dummies(); |
483 | + | |
484 | + ret = sh_pfc_init_ranges(pfc); | |
485 | + if (ret < 0) | |
486 | + return ret; | |
433 | 487 | |
434 | 488 | /* |
435 | 489 | * Initialize pinctrl bindings first |
drivers/pinctrl/sh-pfc/core.h
... | ... | @@ -25,6 +25,11 @@ |
25 | 25 | struct sh_pfc_chip; |
26 | 26 | struct sh_pfc_pinctrl; |
27 | 27 | |
28 | +struct sh_pfc_pin_range { | |
29 | + u16 start; | |
30 | + u16 end; | |
31 | +}; | |
32 | + | |
28 | 33 | struct sh_pfc { |
29 | 34 | struct device *dev; |
30 | 35 | const struct sh_pfc_soc_info *info; |
... | ... | @@ -33,6 +38,9 @@ |
33 | 38 | |
34 | 39 | unsigned int num_windows; |
35 | 40 | struct sh_pfc_window *window; |
41 | + | |
42 | + struct sh_pfc_pin_range *ranges; | |
43 | + unsigned int nr_ranges; | |
36 | 44 | |
37 | 45 | unsigned int nr_gpio_pins; |
38 | 46 |
drivers/pinctrl/sh-pfc/gpio.c
... | ... | @@ -334,10 +334,7 @@ |
334 | 334 | |
335 | 335 | int sh_pfc_register_gpiochip(struct sh_pfc *pfc) |
336 | 336 | { |
337 | - const struct pinmux_range *ranges; | |
338 | - struct pinmux_range def_range; | |
339 | 337 | struct sh_pfc_chip *chip; |
340 | - unsigned int nr_ranges; | |
341 | 338 | unsigned int i; |
342 | 339 | int ret; |
343 | 340 | |
344 | 341 | |
345 | 342 | |
... | ... | @@ -368,23 +365,13 @@ |
368 | 365 | pfc->gpio = chip; |
369 | 366 | |
370 | 367 | /* Register the GPIO to pin mappings. */ |
371 | - if (pfc->info->ranges == NULL) { | |
372 | - def_range.begin = 0; | |
373 | - def_range.end = pfc->info->nr_pins - 1; | |
374 | - ranges = &def_range; | |
375 | - nr_ranges = 1; | |
376 | - } else { | |
377 | - ranges = pfc->info->ranges; | |
378 | - nr_ranges = pfc->info->nr_ranges; | |
379 | - } | |
368 | + for (i = 0; i < pfc->nr_ranges; ++i) { | |
369 | + const struct sh_pfc_pin_range *range = &pfc->ranges[i]; | |
380 | 370 | |
381 | - for (i = 0; i < nr_ranges; ++i) { | |
382 | - const struct pinmux_range *range = &ranges[i]; | |
383 | - | |
384 | 371 | ret = gpiochip_add_pin_range(&chip->gpio_chip, |
385 | 372 | dev_name(pfc->dev), |
386 | - range->begin, range->begin, | |
387 | - range->end - range->begin + 1); | |
373 | + range->start, range->start, | |
374 | + range->end - range->start + 1); | |
388 | 375 | if (ret < 0) |
389 | 376 | return ret; |
390 | 377 | } |
drivers/pinctrl/sh-pfc/pfc-r8a73a4.c
... | ... | @@ -1398,20 +1398,6 @@ |
1398 | 1398 | R8A73A4_PIN_IO_PU_PD(328), R8A73A4_PIN_IO_PU_PD(329), |
1399 | 1399 | }; |
1400 | 1400 | |
1401 | -static const struct pinmux_range pinmux_ranges[] = { | |
1402 | - {.begin = 0, .end = 30,}, | |
1403 | - {.begin = 32, .end = 40,}, | |
1404 | - {.begin = 64, .end = 85,}, | |
1405 | - {.begin = 96, .end = 126,}, | |
1406 | - {.begin = 128, .end = 134,}, | |
1407 | - {.begin = 160, .end = 178,}, | |
1408 | - {.begin = 192, .end = 222,}, | |
1409 | - {.begin = 224, .end = 250,}, | |
1410 | - {.begin = 256, .end = 283,}, | |
1411 | - {.begin = 288, .end = 308,}, | |
1412 | - {.begin = 320, .end = 329,}, | |
1413 | -}; | |
1414 | - | |
1415 | 1401 | /* - IRQC ------------------------------------------------------------------- */ |
1416 | 1402 | #define IRQC_PINS_MUX(pin, irq_mark) \ |
1417 | 1403 | static const unsigned int irqc_irq##irq_mark##_pins[] = { \ |
... | ... | @@ -2755,9 +2741,6 @@ |
2755 | 2741 | |
2756 | 2742 | .pins = pinmux_pins, |
2757 | 2743 | .nr_pins = ARRAY_SIZE(pinmux_pins), |
2758 | - | |
2759 | - .ranges = pinmux_ranges, | |
2760 | - .nr_ranges = ARRAY_SIZE(pinmux_ranges), | |
2761 | 2744 | |
2762 | 2745 | .groups = pinmux_groups, |
2763 | 2746 | .nr_groups = ARRAY_SIZE(pinmux_groups), |
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
... | ... | @@ -1446,13 +1446,6 @@ |
1446 | 1446 | SH73A0_PIN_O(309), |
1447 | 1447 | }; |
1448 | 1448 | |
1449 | -static const struct pinmux_range pinmux_ranges[] = { | |
1450 | - {.begin = 0, .end = 118,}, | |
1451 | - {.begin = 128, .end = 164,}, | |
1452 | - {.begin = 192, .end = 282,}, | |
1453 | - {.begin = 288, .end = 309,}, | |
1454 | -}; | |
1455 | - | |
1456 | 1449 | /* Pin numbers for pins without a corresponding GPIO port number are computed |
1457 | 1450 | * from the row and column numbers with a 1000 offset to avoid collisions with |
1458 | 1451 | * GPIO port numbers. |
... | ... | @@ -3894,8 +3887,6 @@ |
3894 | 3887 | |
3895 | 3888 | .pins = pinmux_pins, |
3896 | 3889 | .nr_pins = ARRAY_SIZE(pinmux_pins), |
3897 | - .ranges = pinmux_ranges, | |
3898 | - .nr_ranges = ARRAY_SIZE(pinmux_ranges), | |
3899 | 3890 | .groups = pinmux_groups, |
3900 | 3891 | .nr_groups = ARRAY_SIZE(pinmux_groups), |
3901 | 3892 | .functions = pinmux_functions, |
drivers/pinctrl/sh-pfc/pinctrl.c
... | ... | @@ -587,22 +587,9 @@ |
587 | 587 | /* PFC ranges -> pinctrl pin descs */ |
588 | 588 | static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) |
589 | 589 | { |
590 | - const struct pinmux_range *ranges; | |
591 | - struct pinmux_range def_range; | |
592 | - unsigned int nr_ranges; | |
593 | - unsigned int nr_pins; | |
594 | 590 | unsigned int i; |
595 | 591 | |
596 | - if (pfc->info->ranges == NULL) { | |
597 | - def_range.begin = 0; | |
598 | - def_range.end = pfc->info->nr_pins - 1; | |
599 | - ranges = &def_range; | |
600 | - nr_ranges = 1; | |
601 | - } else { | |
602 | - ranges = pfc->info->ranges; | |
603 | - nr_ranges = pfc->info->nr_ranges; | |
604 | - } | |
605 | - | |
592 | + /* Allocate and initialize the pins and configs arrays. */ | |
606 | 593 | pmx->pins = devm_kzalloc(pfc->dev, |
607 | 594 | sizeof(*pmx->pins) * pfc->info->nr_pins, |
608 | 595 | GFP_KERNEL); |
609 | 596 | |
610 | 597 | |
611 | 598 | |
... | ... | @@ -615,32 +602,24 @@ |
615 | 602 | if (unlikely(!pmx->configs)) |
616 | 603 | return -ENOMEM; |
617 | 604 | |
618 | - for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { | |
619 | - const struct pinmux_range *range = &ranges[i]; | |
620 | - unsigned int number; | |
605 | + for (i = 0; i < pfc->info->nr_pins; ++i) { | |
606 | + const struct sh_pfc_pin *info = &pfc->info->pins[i]; | |
607 | + struct sh_pfc_pin_config *cfg = &pmx->configs[i]; | |
608 | + struct pinctrl_pin_desc *pin = &pmx->pins[i]; | |
621 | 609 | |
622 | - for (number = range->begin; number <= range->end; | |
623 | - number++, nr_pins++) { | |
624 | - struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins]; | |
625 | - struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; | |
626 | - const struct sh_pfc_pin *info = | |
627 | - &pfc->info->pins[nr_pins]; | |
628 | - | |
629 | - pin->number = number; | |
630 | - pin->name = info->name; | |
631 | - cfg->type = PINMUX_TYPE_NONE; | |
632 | - } | |
610 | + /* If the pin number is equal to -1 all pins are considered */ | |
611 | + pin->number = info->pin != (u16)-1 ? info->pin : i; | |
612 | + pin->name = info->name; | |
613 | + cfg->type = PINMUX_TYPE_NONE; | |
633 | 614 | } |
634 | 615 | |
635 | - pfc->nr_gpio_pins = ranges[nr_ranges-1].end + 1; | |
636 | - | |
637 | - return nr_ranges; | |
616 | + return 0; | |
638 | 617 | } |
639 | 618 | |
640 | 619 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc) |
641 | 620 | { |
642 | 621 | struct sh_pfc_pinctrl *pmx; |
643 | - int nr_ranges; | |
622 | + int ret; | |
644 | 623 | |
645 | 624 | pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); |
646 | 625 | if (unlikely(!pmx)) |
... | ... | @@ -649,9 +628,9 @@ |
649 | 628 | pmx->pfc = pfc; |
650 | 629 | pfc->pinctrl = pmx; |
651 | 630 | |
652 | - nr_ranges = sh_pfc_map_pins(pfc, pmx); | |
653 | - if (unlikely(nr_ranges < 0)) | |
654 | - return nr_ranges; | |
631 | + ret = sh_pfc_map_pins(pfc, pmx); | |
632 | + if (ret < 0) | |
633 | + return ret; | |
655 | 634 | |
656 | 635 | pmx->pctl_desc.name = DRV_NAME; |
657 | 636 | pmx->pctl_desc.owner = THIS_MODULE; |
drivers/pinctrl/sh-pfc/sh_pfc.h
... | ... | @@ -125,8 +125,6 @@ |
125 | 125 | |
126 | 126 | const struct sh_pfc_pin *pins; |
127 | 127 | unsigned int nr_pins; |
128 | - const struct pinmux_range *ranges; | |
129 | - unsigned int nr_ranges; | |
130 | 128 | const struct sh_pfc_pin_group *groups; |
131 | 129 | unsigned int nr_groups; |
132 | 130 | const struct sh_pfc_function *functions; |