diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-09 21:19:44 -0500 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-04-02 21:30:36 -0400 |
commit | ceef91dcc0bca0a39c54d2f0071848b6d5c66b88 (patch) | |
tree | 63d55c592e2fb2e47b1a0bd32d131d828c933fa8 /drivers/pinctrl | |
parent | 1a4fd58f76cf331c93daaa1667daa25db297d0d4 (diff) |
sh-pfc: Skip gpiochip registration when no GPIO resource is found
Boards/platforms that register dedicated GPIO devices will not supply a
memory resource for GPIOs. Try to locate the GPIO memory resource at
initialization time, and skip registration of the gpiochip if the
resource can't be found.
This is a temporary modification to ease the transition to separate GPIO
drivers. It should be reverted when all boards and platforms will have
been moved.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/sh-pfc/gpio.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 317cebb0ee4d..d37efa7dcf90 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c | |||
@@ -101,24 +101,9 @@ static void gpio_setup_data_reg(struct sh_pfc_chip *chip, unsigned gpio) | |||
101 | static int gpio_setup_data_regs(struct sh_pfc_chip *chip) | 101 | static int gpio_setup_data_regs(struct sh_pfc_chip *chip) |
102 | { | 102 | { |
103 | struct sh_pfc *pfc = chip->pfc; | 103 | struct sh_pfc *pfc = chip->pfc; |
104 | unsigned long addr = pfc->info->data_regs[0].reg; | ||
105 | const struct pinmux_data_reg *dreg; | 104 | const struct pinmux_data_reg *dreg; |
106 | unsigned int i; | 105 | unsigned int i; |
107 | 106 | ||
108 | /* Find the window that contain the GPIO registers. */ | ||
109 | for (i = 0; i < pfc->num_windows; ++i) { | ||
110 | struct sh_pfc_window *window = &pfc->window[i]; | ||
111 | |||
112 | if (addr >= window->phys && addr < window->phys + window->size) | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | if (i == pfc->num_windows) | ||
117 | return -EINVAL; | ||
118 | |||
119 | /* GPIO data registers must be in the first memory resource. */ | ||
120 | chip->mem = &pfc->window[i]; | ||
121 | |||
122 | /* Count the number of data registers, allocate memory and initialize | 107 | /* Count the number of data registers, allocate memory and initialize |
123 | * them. | 108 | * them. |
124 | */ | 109 | */ |
@@ -319,7 +304,8 @@ static int gpio_function_setup(struct sh_pfc_chip *chip) | |||
319 | */ | 304 | */ |
320 | 305 | ||
321 | static struct sh_pfc_chip * | 306 | static struct sh_pfc_chip * |
322 | sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *)) | 307 | sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *), |
308 | struct sh_pfc_window *mem) | ||
323 | { | 309 | { |
324 | struct sh_pfc_chip *chip; | 310 | struct sh_pfc_chip *chip; |
325 | int ret; | 311 | int ret; |
@@ -328,6 +314,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *)) | |||
328 | if (unlikely(!chip)) | 314 | if (unlikely(!chip)) |
329 | return ERR_PTR(-ENOMEM); | 315 | return ERR_PTR(-ENOMEM); |
330 | 316 | ||
317 | chip->mem = mem; | ||
331 | chip->pfc = pfc; | 318 | chip->pfc = pfc; |
332 | 319 | ||
333 | ret = setup(chip); | 320 | ret = setup(chip); |
@@ -357,8 +344,24 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | |||
357 | if (pfc->info->data_regs == NULL) | 344 | if (pfc->info->data_regs == NULL) |
358 | return 0; | 345 | return 0; |
359 | 346 | ||
347 | /* Find the memory window that contain the GPIO registers. Boards that | ||
348 | * register a separate GPIO device will not supply a memory resource | ||
349 | * that covers the data registers. In that case don't try to handle | ||
350 | * GPIOs. | ||
351 | */ | ||
352 | for (i = 0; i < pfc->num_windows; ++i) { | ||
353 | struct sh_pfc_window *window = &pfc->window[i]; | ||
354 | |||
355 | if (pfc->info->data_regs[0].reg >= window->phys && | ||
356 | pfc->info->data_regs[0].reg < window->phys + window->size) | ||
357 | break; | ||
358 | } | ||
359 | |||
360 | if (i == pfc->num_windows) | ||
361 | return 0; | ||
362 | |||
360 | /* Register the real GPIOs chip. */ | 363 | /* Register the real GPIOs chip. */ |
361 | chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); | 364 | chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->window[i]); |
362 | if (IS_ERR(chip)) | 365 | if (IS_ERR(chip)) |
363 | return PTR_ERR(chip); | 366 | return PTR_ERR(chip); |
364 | 367 | ||
@@ -390,7 +393,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | |||
390 | if (pfc->info->nr_func_gpios == 0) | 393 | if (pfc->info->nr_func_gpios == 0) |
391 | return 0; | 394 | return 0; |
392 | 395 | ||
393 | chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup); | 396 | chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup, NULL); |
394 | if (IS_ERR(chip)) | 397 | if (IS_ERR(chip)) |
395 | return PTR_ERR(chip); | 398 | return PTR_ERR(chip); |
396 | 399 | ||