static int sh_gpio_request(struct gpio_chip *gc, unsigned offset)
{
- return pinctrl_request_gpio(offset);
+ struct sh_pfc *pfc = gpio_to_pfc(gc);
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (offset < pfc->info->nr_pins)
+ return pinctrl_request_gpio(offset);
+
+ pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n");
+
+ spin_lock_irqsave(&pfc->lock, flags);
+
+ if (!sh_pfc_gpio_is_function(pfc, offset))
+ goto done;
+
+ if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION,
+ GPIO_CFG_DRYRUN))
+ goto done;
+
+ if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION,
+ GPIO_CFG_REQ))
+ goto done;
+
+ ret = 0;
+
+done:
+ spin_unlock_irqrestore(&pfc->lock, flags);
+ return ret;
}
static void sh_gpio_free(struct gpio_chip *gc, unsigned offset)
{
- pinctrl_free_gpio(offset);
+ struct sh_pfc *pfc = gpio_to_pfc(gc);
+ unsigned long flags;
+
+ if (offset < pfc->info->nr_pins)
+ return pinctrl_free_gpio(offset);
+
+ spin_lock_irqsave(&pfc->lock, flags);
+
+ sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE);
+
+ spin_unlock_irqrestore(&pfc->lock, flags);
}
static void sh_gpio_set_value(struct sh_pfc *pfc, unsigned gpio, int value)
static int sh_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
+ struct sh_pfc *pfc = gpio_to_pfc(gc);
+
+ if (offset >= pfc->info->nr_pins) {
+ /* Function GPIOs can only be requested, never configured. */
+ return -EINVAL;
+ }
+
return pinctrl_gpio_direction_input(offset);
}
static int sh_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value)
{
+ struct sh_pfc *pfc = gpio_to_pfc(gc);
+
+ if (offset >= pfc->info->nr_pins) {
+ /* Function GPIOs can only be requested, never configured. */
+ return -EINVAL;
+ }
+
sh_gpio_set_value(gpio_to_pfc(gc), offset, value);
return pinctrl_gpio_direction_output(offset);
gc->set = sh_gpio_set;
gc->to_irq = sh_gpio_to_irq;
- WARN_ON(pfc->info->first_gpio != 0); /* needs testing */
-
gc->label = pfc->info->name;
gc->owner = THIS_MODULE;
- gc->base = pfc->info->first_gpio;
- gc->ngpio = (pfc->info->last_gpio - pfc->info->first_gpio) + 1;
+ gc->base = 0;
+ gc->ngpio = pfc->info->nr_pins + pfc->info->nr_func_gpios;
}
int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
pfc->gpio = chip;
- pr_info("%s handling gpio %d -> %d\n",
- pfc->info->name, pfc->info->first_gpio,
- pfc->info->last_gpio);
+ pr_info("%s handling gpio 0 -> %u\n",
+ pfc->info->name,
+ pfc->info->nr_pins + pfc->info->nr_func_gpios - 1);
return 0;
}