aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sh-pfc/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/sh-pfc/core.c')
-rw-r--r--drivers/pinctrl/sh-pfc/core.c70
1 files changed, 62 insertions, 8 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
341static 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
345static const struct of_device_id sh_pfc_of_table[] = { 395static 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 */