aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sh-pfc/pinctrl.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-02-14 19:33:38 -0500
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-03-15 08:33:39 -0400
commit63d573835f835aab4c44d0e0342cf5976fb14b35 (patch)
treed5998a6c0cb914d85c246b0464b2b7e7db959d2a /drivers/pinctrl/sh-pfc/pinctrl.c
parent247127f90ba1fcc234008e00e937537a89eef9ca (diff)
sh-pfc: Add support for sparse pin numbers
The PFC driver assumes that the value of the GPIO_PORTxxx enumeration names are equal to the port number. This isn't true when the port number space is sparse, as with the SH73A0. Fix the issue by adding support for pin numbers ranges specified through SoC data. When no range is specified the driver considers that the PFC implements a single contiguous range for all pins. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/sh-pfc/pinctrl.c')
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
index a60c317d988a..c9e9a1d95230 100644
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -293,29 +293,48 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = {
293 .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, 293 .pin_config_dbg_show = sh_pfc_pinconf_dbg_show,
294}; 294};
295 295
296/* pinmux ranges -> pinctrl pin descs */ 296/* PFC ranges -> pinctrl pin descs */
297static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) 297static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
298{ 298{
299 int i; 299 const struct pinmux_range *ranges;
300 300 struct pinmux_range def_range;
301 pmx->nr_pads = pfc->info->nr_pins; 301 unsigned int nr_ranges;
302 unsigned int nr_pins;
303 unsigned int i;
304
305 if (pfc->info->ranges == NULL) {
306 def_range.begin = 0;
307 def_range.end = pfc->info->nr_pins - 1;
308 ranges = &def_range;
309 nr_ranges = 1;
310 } else {
311 ranges = pfc->info->ranges;
312 nr_ranges = pfc->info->nr_ranges;
313 }
302 314
303 pmx->pads = devm_kzalloc(pfc->dev, sizeof(*pmx->pads) * pmx->nr_pads, 315 pmx->pads = devm_kzalloc(pfc->dev,
316 sizeof(*pmx->pads) * pfc->info->nr_pins,
304 GFP_KERNEL); 317 GFP_KERNEL);
305 if (unlikely(!pmx->pads)) { 318 if (unlikely(!pmx->pads))
306 pmx->nr_pads = 0;
307 return -ENOMEM; 319 return -ENOMEM;
308 }
309 320
310 for (i = 0; i < pmx->nr_pads; i++) { 321 for (i = 0, nr_pins = 0; i < nr_ranges; ++i) {
311 struct pinctrl_pin_desc *pin = pmx->pads + i; 322 const struct pinmux_range *range = &ranges[i];
312 struct sh_pfc_pin *gpio = pfc->info->pins + i; 323 unsigned int number;
324
325 for (number = range->begin; number <= range->end;
326 number++, nr_pins++) {
327 struct pinctrl_pin_desc *pin = &pmx->pads[nr_pins];
328 struct sh_pfc_pin *info = &pfc->info->pins[nr_pins];
313 329
314 pin->number = i; 330 pin->number = number;
315 pin->name = gpio->name; 331 pin->name = info->name;
332 }
316 } 333 }
317 334
318 return 0; 335 pfc->nr_pins = ranges[nr_ranges-1].end + 1;
336
337 return nr_ranges;
319} 338}
320 339
321static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) 340static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
@@ -347,6 +366,7 @@ static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
347int sh_pfc_register_pinctrl(struct sh_pfc *pfc) 366int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
348{ 367{
349 struct sh_pfc_pinctrl *pmx; 368 struct sh_pfc_pinctrl *pmx;
369 int nr_ranges;
350 int ret; 370 int ret;
351 371
352 pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); 372 pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL);
@@ -356,9 +376,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
356 pmx->pfc = pfc; 376 pmx->pfc = pfc;
357 pfc->pinctrl = pmx; 377 pfc->pinctrl = pmx;
358 378
359 ret = sh_pfc_map_gpios(pfc, pmx); 379 nr_ranges = sh_pfc_map_pins(pfc, pmx);
360 if (unlikely(ret != 0)) 380 if (unlikely(nr_ranges < 0))
361 return ret; 381 return nr_ranges;
362 382
363 ret = sh_pfc_map_functions(pfc, pmx); 383 ret = sh_pfc_map_functions(pfc, pmx);
364 if (unlikely(ret != 0)) 384 if (unlikely(ret != 0))
@@ -370,7 +390,7 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
370 pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops; 390 pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops;
371 pmx->pctl_desc.confops = &sh_pfc_pinconf_ops; 391 pmx->pctl_desc.confops = &sh_pfc_pinconf_ops;
372 pmx->pctl_desc.pins = pmx->pads; 392 pmx->pctl_desc.pins = pmx->pads;
373 pmx->pctl_desc.npins = pmx->nr_pads; 393 pmx->pctl_desc.npins = pfc->info->nr_pins;
374 394
375 pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx); 395 pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx);
376 if (IS_ERR(pmx->pctl)) 396 if (IS_ERR(pmx->pctl))