aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pinctrl/sh-pfc/core.c19
-rw-r--r--drivers/pinctrl/sh-pfc/core.h2
-rw-r--r--drivers/pinctrl/sh-pfc/gpio.c37
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c58
-rw-r--r--drivers/pinctrl/sh-pfc/sh_pfc.h2
5 files changed, 91 insertions, 27 deletions
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
index 667db99fb510..798248261f30 100644
--- a/drivers/pinctrl/sh-pfc/core.c
+++ b/drivers/pinctrl/sh-pfc/core.c
@@ -80,7 +80,24 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
80 80
81struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin) 81struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin)
82{ 82{
83 return &pfc->info->pins[pin]; 83 unsigned int offset;
84 unsigned int i;
85
86 if (pfc->info->ranges == NULL)
87 return &pfc->info->pins[pin];
88
89 for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) {
90 const struct pinmux_range *range = &pfc->info->ranges[i];
91
92 if (pin <= range->end)
93 return pin >= range->begin
94 ? &pfc->info->pins[offset + pin - range->begin]
95 : NULL;
96
97 offset += range->end - range->begin + 1;
98 }
99
100 return NULL;
84} 101}
85 102
86static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) 103static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h
index 6ea3d4f3d05e..b8b3e872cc19 100644
--- a/drivers/pinctrl/sh-pfc/core.h
+++ b/drivers/pinctrl/sh-pfc/core.h
@@ -32,6 +32,8 @@ struct sh_pfc {
32 unsigned int num_windows; 32 unsigned int num_windows;
33 struct sh_pfc_window *window; 33 struct sh_pfc_window *window;
34 34
35 unsigned int nr_pins;
36
35 struct sh_pfc_chip *gpio; 37 struct sh_pfc_chip *gpio;
36 struct sh_pfc_chip *func; 38 struct sh_pfc_chip *func;
37 39
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index 32a9c7870a16..806e2dd62137 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -45,7 +45,7 @@ static int gpio_pin_request(struct gpio_chip *gc, unsigned offset)
45 struct sh_pfc *pfc = gpio_to_pfc(gc); 45 struct sh_pfc *pfc = gpio_to_pfc(gc);
46 struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); 46 struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset);
47 47
48 if (pin->enum_id == 0) 48 if (pin == NULL || pin->enum_id == 0)
49 return -EINVAL; 49 return -EINVAL;
50 50
51 return pinctrl_request_gpio(offset); 51 return pinctrl_request_gpio(offset);
@@ -127,7 +127,7 @@ static void gpio_pin_setup(struct sh_pfc_chip *chip)
127 gc->dev = pfc->dev; 127 gc->dev = pfc->dev;
128 gc->owner = THIS_MODULE; 128 gc->owner = THIS_MODULE;
129 gc->base = 0; 129 gc->base = 0;
130 gc->ngpio = pfc->info->nr_pins; 130 gc->ngpio = pfc->nr_pins;
131} 131}
132 132
133/* ----------------------------------------------------------------------------- 133/* -----------------------------------------------------------------------------
@@ -184,7 +184,7 @@ static void gpio_function_setup(struct sh_pfc_chip *chip)
184 184
185 gc->label = pfc->info->name; 185 gc->label = pfc->info->name;
186 gc->owner = THIS_MODULE; 186 gc->owner = THIS_MODULE;
187 gc->base = pfc->info->nr_pins; 187 gc->base = pfc->nr_pins;
188 gc->ngpio = pfc->info->nr_func_gpios; 188 gc->ngpio = pfc->info->nr_func_gpios;
189} 189}
190 190
@@ -219,20 +219,43 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, void(*setup)(struct sh_pfc_chip *))
219 219
220int sh_pfc_register_gpiochip(struct sh_pfc *pfc) 220int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
221{ 221{
222 const struct pinmux_range *ranges;
223 struct pinmux_range def_range;
222 struct sh_pfc_chip *chip; 224 struct sh_pfc_chip *chip;
225 unsigned int nr_ranges;
226 unsigned int i;
223 int ret; 227 int ret;
224 228
229 /* Register the real GPIOs chip. */
225 chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); 230 chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup);
226 if (IS_ERR(chip)) 231 if (IS_ERR(chip))
227 return PTR_ERR(chip); 232 return PTR_ERR(chip);
228 233
229 pfc->gpio = chip; 234 pfc->gpio = chip;
230 235
231 ret = gpiochip_add_pin_range(&chip->gpio_chip, dev_name(pfc->dev), 0, 0, 236 /* Register the GPIO to pin mappings. */
232 chip->gpio_chip.ngpio); 237 if (pfc->info->ranges == NULL) {
233 if (ret < 0) 238 def_range.begin = 0;
234 return ret; 239 def_range.end = pfc->info->nr_pins - 1;
240 ranges = &def_range;
241 nr_ranges = 1;
242 } else {
243 ranges = pfc->info->ranges;
244 nr_ranges = pfc->info->nr_ranges;
245 }
246
247 for (i = 0; i < nr_ranges; ++i) {
248 const struct pinmux_range *range = &ranges[i];
249
250 ret = gpiochip_add_pin_range(&chip->gpio_chip,
251 dev_name(pfc->dev),
252 range->begin, range->begin,
253 range->end - range->begin + 1);
254 if (ret < 0)
255 return ret;
256 }
235 257
258 /* Register the function GPIOs chip. */
236 chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup); 259 chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup);
237 if (IS_ERR(chip)) 260 if (IS_ERR(chip))
238 return PTR_ERR(chip); 261 return PTR_ERR(chip);
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))
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
index 43c858d98321..dbcaa600ccc6 100644
--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
+++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
@@ -111,6 +111,8 @@ struct sh_pfc_soc_info {
111 111
112 struct sh_pfc_pin *pins; 112 struct sh_pfc_pin *pins;
113 unsigned int nr_pins; 113 unsigned int nr_pins;
114 const struct pinmux_range *ranges;
115 unsigned int nr_ranges;
114 struct pinmux_func *func_gpios; 116 struct pinmux_func *func_gpios;
115 unsigned int nr_func_gpios; 117 unsigned int nr_func_gpios;
116 118