diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-07-15 12:38:30 -0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-07-29 09:17:48 -0400 |
commit | acac8ed5e2aa2c0d364d06f364fd9ed0dc27d28a (patch) | |
tree | ead3d7bedad1e373dd69c481161149bce69f47d8 /drivers/pinctrl/sh-pfc | |
parent | 28818fa5dadfd458fa7e17c8be26b2d7edffa8bf (diff) |
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>
Diffstat (limited to 'drivers/pinctrl/sh-pfc')
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.c | 70 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.h | 8 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/gpio.c | 21 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-r8a73a4.c | 17 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 9 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 49 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/sh_pfc.h | 2 |
7 files changed, 88 insertions, 88 deletions
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 96b02246796a..cb47bcee0aab 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c | |||
@@ -82,17 +82,14 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) | |||
82 | unsigned int offset; | 82 | unsigned int offset; |
83 | unsigned int i; | 83 | unsigned int i; |
84 | 84 | ||
85 | if (pfc->info->ranges == NULL) | 85 | for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) { |
86 | return pin; | 86 | const struct sh_pfc_pin_range *range = &pfc->ranges[i]; |
87 | |||
88 | for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) { | ||
89 | const struct pinmux_range *range = &pfc->info->ranges[i]; | ||
90 | 87 | ||
91 | if (pin <= range->end) | 88 | if (pin <= range->end) |
92 | return pin >= range->begin | 89 | return pin >= range->start |
93 | ? offset + pin - range->begin : -1; | 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 | return -EINVAL; | 95 | return -EINVAL; |
@@ -341,6 +338,59 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | |||
341 | return 0; | 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 | #ifdef CONFIG_OF | 394 | #ifdef CONFIG_OF |
345 | static const struct of_device_id sh_pfc_of_table[] = { | 395 | static const struct of_device_id sh_pfc_of_table[] = { |
346 | #ifdef CONFIG_PINCTRL_PFC_R8A73A4 | 396 | #ifdef CONFIG_PINCTRL_PFC_R8A73A4 |
@@ -431,6 +481,10 @@ static int sh_pfc_probe(struct platform_device *pdev) | |||
431 | 481 | ||
432 | pinctrl_provide_dummies(); | 482 | pinctrl_provide_dummies(); |
433 | 483 | ||
484 | ret = sh_pfc_init_ranges(pfc); | ||
485 | if (ret < 0) | ||
486 | return ret; | ||
487 | |||
434 | /* | 488 | /* |
435 | * Initialize pinctrl bindings first | 489 | * Initialize pinctrl bindings first |
436 | */ | 490 | */ |
diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 93963a19b340..a1b23762ac90 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h | |||
@@ -25,6 +25,11 @@ struct sh_pfc_window { | |||
25 | struct sh_pfc_chip; | 25 | struct sh_pfc_chip; |
26 | struct sh_pfc_pinctrl; | 26 | struct sh_pfc_pinctrl; |
27 | 27 | ||
28 | struct sh_pfc_pin_range { | ||
29 | u16 start; | ||
30 | u16 end; | ||
31 | }; | ||
32 | |||
28 | struct sh_pfc { | 33 | struct sh_pfc { |
29 | struct device *dev; | 34 | struct device *dev; |
30 | const struct sh_pfc_soc_info *info; | 35 | const struct sh_pfc_soc_info *info; |
@@ -34,6 +39,9 @@ struct sh_pfc { | |||
34 | unsigned int num_windows; | 39 | unsigned int num_windows; |
35 | struct sh_pfc_window *window; | 40 | struct sh_pfc_window *window; |
36 | 41 | ||
42 | struct sh_pfc_pin_range *ranges; | ||
43 | unsigned int nr_ranges; | ||
44 | |||
37 | unsigned int nr_gpio_pins; | 45 | unsigned int nr_gpio_pins; |
38 | 46 | ||
39 | struct sh_pfc_chip *gpio; | 47 | struct sh_pfc_chip *gpio; |
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 7661be5054a0..78fcb8029afd 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c | |||
@@ -334,10 +334,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *), | |||
334 | 334 | ||
335 | int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | 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 | struct sh_pfc_chip *chip; | 337 | struct sh_pfc_chip *chip; |
340 | unsigned int nr_ranges; | ||
341 | unsigned int i; | 338 | unsigned int i; |
342 | int ret; | 339 | int ret; |
343 | 340 | ||
@@ -368,23 +365,13 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | |||
368 | pfc->gpio = chip; | 365 | pfc->gpio = chip; |
369 | 366 | ||
370 | /* Register the GPIO to pin mappings. */ | 367 | /* Register the GPIO to pin mappings. */ |
371 | if (pfc->info->ranges == NULL) { | 368 | for (i = 0; i < pfc->nr_ranges; ++i) { |
372 | def_range.begin = 0; | 369 | const struct sh_pfc_pin_range *range = &pfc->ranges[i]; |
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 | } | ||
380 | |||
381 | for (i = 0; i < nr_ranges; ++i) { | ||
382 | const struct pinmux_range *range = &ranges[i]; | ||
383 | 370 | ||
384 | ret = gpiochip_add_pin_range(&chip->gpio_chip, | 371 | ret = gpiochip_add_pin_range(&chip->gpio_chip, |
385 | dev_name(pfc->dev), | 372 | dev_name(pfc->dev), |
386 | range->begin, range->begin, | 373 | range->start, range->start, |
387 | range->end - range->begin + 1); | 374 | range->end - range->start + 1); |
388 | if (ret < 0) | 375 | if (ret < 0) |
389 | return ret; | 376 | return ret; |
390 | } | 377 | } |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c b/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c index 04ecb5e9e18e..05d96ae36fca 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c | |||
@@ -1398,20 +1398,6 @@ static struct sh_pfc_pin pinmux_pins[] = { | |||
1398 | R8A73A4_PIN_IO_PU_PD(328), R8A73A4_PIN_IO_PU_PD(329), | 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 | /* - IRQC ------------------------------------------------------------------- */ | 1401 | /* - IRQC ------------------------------------------------------------------- */ |
1416 | #define IRQC_PINS_MUX(pin, irq_mark) \ | 1402 | #define IRQC_PINS_MUX(pin, irq_mark) \ |
1417 | static const unsigned int irqc_irq##irq_mark##_pins[] = { \ | 1403 | static const unsigned int irqc_irq##irq_mark##_pins[] = { \ |
@@ -2756,9 +2742,6 @@ const struct sh_pfc_soc_info r8a73a4_pinmux_info = { | |||
2756 | .pins = pinmux_pins, | 2742 | .pins = pinmux_pins, |
2757 | .nr_pins = ARRAY_SIZE(pinmux_pins), | 2743 | .nr_pins = ARRAY_SIZE(pinmux_pins), |
2758 | 2744 | ||
2759 | .ranges = pinmux_ranges, | ||
2760 | .nr_ranges = ARRAY_SIZE(pinmux_ranges), | ||
2761 | |||
2762 | .groups = pinmux_groups, | 2745 | .groups = pinmux_groups, |
2763 | .nr_groups = ARRAY_SIZE(pinmux_groups), | 2746 | .nr_groups = ARRAY_SIZE(pinmux_groups), |
2764 | .functions = pinmux_functions, | 2747 | .functions = pinmux_functions, |
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index acf83921d75b..1f4dbe45737a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c | |||
@@ -1446,13 +1446,6 @@ static struct sh_pfc_pin pinmux_pins[] = { | |||
1446 | SH73A0_PIN_O(309), | 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 | /* Pin numbers for pins without a corresponding GPIO port number are computed | 1449 | /* Pin numbers for pins without a corresponding GPIO port number are computed |
1457 | * from the row and column numbers with a 1000 offset to avoid collisions with | 1450 | * from the row and column numbers with a 1000 offset to avoid collisions with |
1458 | * GPIO port numbers. | 1451 | * GPIO port numbers. |
@@ -3894,8 +3887,6 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = { | |||
3894 | 3887 | ||
3895 | .pins = pinmux_pins, | 3888 | .pins = pinmux_pins, |
3896 | .nr_pins = ARRAY_SIZE(pinmux_pins), | 3889 | .nr_pins = ARRAY_SIZE(pinmux_pins), |
3897 | .ranges = pinmux_ranges, | ||
3898 | .nr_ranges = ARRAY_SIZE(pinmux_ranges), | ||
3899 | .groups = pinmux_groups, | 3890 | .groups = pinmux_groups, |
3900 | .nr_groups = ARRAY_SIZE(pinmux_groups), | 3891 | .nr_groups = ARRAY_SIZE(pinmux_groups), |
3901 | .functions = pinmux_functions, | 3892 | .functions = pinmux_functions, |
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 314255d79bff..8649ec3910a3 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c | |||
@@ -587,22 +587,9 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = { | |||
587 | /* PFC ranges -> pinctrl pin descs */ | 587 | /* PFC ranges -> pinctrl pin descs */ |
588 | static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) | 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 | unsigned int i; | 590 | unsigned int i; |
595 | 591 | ||
596 | if (pfc->info->ranges == NULL) { | 592 | /* Allocate and initialize the pins and configs arrays. */ |
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 | |||
606 | pmx->pins = devm_kzalloc(pfc->dev, | 593 | pmx->pins = devm_kzalloc(pfc->dev, |
607 | sizeof(*pmx->pins) * pfc->info->nr_pins, | 594 | sizeof(*pmx->pins) * pfc->info->nr_pins, |
608 | GFP_KERNEL); | 595 | GFP_KERNEL); |
@@ -615,32 +602,24 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) | |||
615 | if (unlikely(!pmx->configs)) | 602 | if (unlikely(!pmx->configs)) |
616 | return -ENOMEM; | 603 | return -ENOMEM; |
617 | 604 | ||
618 | for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { | 605 | for (i = 0; i < pfc->info->nr_pins; ++i) { |
619 | const struct pinmux_range *range = &ranges[i]; | 606 | const struct sh_pfc_pin *info = &pfc->info->pins[i]; |
620 | unsigned int number; | 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; | 610 | /* If the pin number is equal to -1 all pins are considered */ |
623 | number++, nr_pins++) { | 611 | pin->number = info->pin != (u16)-1 ? info->pin : i; |
624 | struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins]; | 612 | pin->name = info->name; |
625 | struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; | 613 | cfg->type = PINMUX_TYPE_NONE; |
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 | } | ||
633 | } | 614 | } |
634 | 615 | ||
635 | pfc->nr_gpio_pins = ranges[nr_ranges-1].end + 1; | 616 | return 0; |
636 | |||
637 | return nr_ranges; | ||
638 | } | 617 | } |
639 | 618 | ||
640 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc) | 619 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc) |
641 | { | 620 | { |
642 | struct sh_pfc_pinctrl *pmx; | 621 | struct sh_pfc_pinctrl *pmx; |
643 | int nr_ranges; | 622 | int ret; |
644 | 623 | ||
645 | pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); | 624 | pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); |
646 | if (unlikely(!pmx)) | 625 | if (unlikely(!pmx)) |
@@ -649,9 +628,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) | |||
649 | pmx->pfc = pfc; | 628 | pmx->pfc = pfc; |
650 | pfc->pinctrl = pmx; | 629 | pfc->pinctrl = pmx; |
651 | 630 | ||
652 | nr_ranges = sh_pfc_map_pins(pfc, pmx); | 631 | ret = sh_pfc_map_pins(pfc, pmx); |
653 | if (unlikely(nr_ranges < 0)) | 632 | if (ret < 0) |
654 | return nr_ranges; | 633 | return ret; |
655 | 634 | ||
656 | pmx->pctl_desc.name = DRV_NAME; | 635 | pmx->pctl_desc.name = DRV_NAME; |
657 | pmx->pctl_desc.owner = THIS_MODULE; | 636 | pmx->pctl_desc.owner = THIS_MODULE; |
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 839e69548a2c..2469b35cfda7 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h | |||
@@ -125,8 +125,6 @@ struct sh_pfc_soc_info { | |||
125 | 125 | ||
126 | const struct sh_pfc_pin *pins; | 126 | const struct sh_pfc_pin *pins; |
127 | unsigned int nr_pins; | 127 | unsigned int nr_pins; |
128 | const struct pinmux_range *ranges; | ||
129 | unsigned int nr_ranges; | ||
130 | const struct sh_pfc_pin_group *groups; | 128 | const struct sh_pfc_pin_group *groups; |
131 | unsigned int nr_groups; | 129 | unsigned int nr_groups; |
132 | const struct sh_pfc_function *functions; | 130 | const struct sh_pfc_function *functions; |