Convert the driver to make use of passing ranges to gpiochip_add, and drop the custom implemtation of gpio_ranges. Since gpiochip_add_with_ranges also supports conditional setting of request/free based on the existence of ranges, and pinmux_is_supported held the same information, we can drop the custom request/free calbacks at the same time and just use the generic implementations if needed. Signed-off-by: Jonas Gorski <jogo@xxxxxxxxxxx> --- drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c | 126 +++++++----------------------- 1 file changed, 27 insertions(+), 99 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c b/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c index 1ca7830..d24218f 100644 --- a/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c @@ -75,8 +75,6 @@ * @lock: lock to protect access to I/O registers * @gc: GPIO chip * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs - * @pinmux_is_supported: flag to indicate this GPIO controller contains pins - * that can be individually muxed to GPIO * @pctl: pointer to pinctrl_dev * @pctldesc: pinctrl descriptor */ @@ -91,8 +89,6 @@ struct cygnus_gpio { struct gpio_chip gc; unsigned num_banks; - bool pinmux_is_supported; - struct pinctrl_dev *pctl; struct pinctrl_desc pctldesc; }; @@ -289,28 +285,6 @@ static struct irq_chip cygnus_gpio_irq_chip = { /* * Request the Cygnus IOMUX pinmux controller to mux individual pins to GPIO */ -static int cygnus_gpio_request(struct gpio_chip *gc, unsigned offset) -{ - struct cygnus_gpio *chip = to_cygnus_gpio(gc); - unsigned gpio = gc->base + offset; - - /* not all Cygnus GPIO pins can be muxed individually */ - if (!chip->pinmux_is_supported) - return 0; - - return pinctrl_request_gpio(gpio); -} - -static void cygnus_gpio_free(struct gpio_chip *gc, unsigned offset) -{ - struct cygnus_gpio *chip = to_cygnus_gpio(gc); - unsigned gpio = gc->base + offset; - - if (!chip->pinmux_is_supported) - return; - - pinctrl_free_gpio(gpio); -} static int cygnus_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) { @@ -596,22 +570,12 @@ static const struct pinconf_ops cygnus_pconf_ops = { .pin_config_set = cygnus_pin_config_set, }; -/* - * Map a GPIO in the local gpio_chip pin space to a pin in the Cygnus IOMUX - * pinctrl pin space - */ -struct cygnus_gpio_pin_range { - unsigned offset; - unsigned pin_base; - unsigned num_pins; -}; - -#define CYGNUS_PINRANGE(o, p, n) { .offset = o, .pin_base = p, .num_pins = n } +#define CYGNUS_PINRANGE(o, p, n) { .base = o, .pin_base = p, .npins = n } /* * Pin mapping table for mapping local GPIO pins to Cygnus IOMUX pinctrl pins */ -static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = { +static const struct pinctrl_gpio_range cygnus_gpio_pintable[] = { CYGNUS_PINRANGE(0, 42, 1), CYGNUS_PINRANGE(1, 44, 3), CYGNUS_PINRANGE(4, 48, 1), @@ -666,58 +630,6 @@ static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = { }; /* - * The Cygnus IOMUX controller mainly supports group based mux configuration, - * but certain pins can be muxed to GPIO individually. Only the ASIU GPIO - * controller can support this, so it's an optional configuration - * - * Return -ENODEV means no support and that's fine - */ -static int cygnus_gpio_pinmux_add_range(struct cygnus_gpio *chip) -{ - struct device_node *node = chip->dev->of_node; - struct device_node *pinmux_node; - struct platform_device *pinmux_pdev; - struct gpio_chip *gc = &chip->gc; - int i, ret = 0; - - /* parse DT to find the phandle to the pinmux controller */ - pinmux_node = of_parse_phandle(node, "pinmux", 0); - if (!pinmux_node) - return -ENODEV; - - pinmux_pdev = of_find_device_by_node(pinmux_node); - /* no longer need the pinmux node */ - of_node_put(pinmux_node); - if (!pinmux_pdev) { - dev_err(chip->dev, "failed to get pinmux device\n"); - return -EINVAL; - } - - /* now need to create the mapping between local GPIO and PINMUX pins */ - for (i = 0; i < ARRAY_SIZE(cygnus_gpio_pintable); i++) { - ret = gpiochip_add_pin_range(gc, dev_name(&pinmux_pdev->dev), - cygnus_gpio_pintable[i].offset, - cygnus_gpio_pintable[i].pin_base, - cygnus_gpio_pintable[i].num_pins); - if (ret) { - dev_err(chip->dev, "unable to add GPIO pin range\n"); - goto err_put_device; - } - } - - chip->pinmux_is_supported = true; - - /* no need for pinmux_pdev device reference anymore */ - put_device(&pinmux_pdev->dev); - return 0; - -err_put_device: - put_device(&pinmux_pdev->dev); - gpiochip_remove_pin_ranges(gc); - return ret; -} - -/* * Cygnus GPIO controller supports some PINCONF related configurations such as * pull up, pull down, and drive strength, when the pin is configured to GPIO * @@ -805,6 +717,10 @@ static int cygnus_gpio_probe(struct platform_device *pdev) int irq, ret; const struct of_device_id *match; const struct cygnus_gpio_data *gpio_data; + struct device_node *pinmux_node; + const char *pinctrl_name = NULL; + const struct pinctrl_gpio_range *ranges = NULL; + unsigned int nranges = 0; match = of_match_device(cygnus_gpio_of_match, dev); if (!match) @@ -844,25 +760,37 @@ static int cygnus_gpio_probe(struct platform_device *pdev) gc->label = dev_name(dev); gc->dev = dev; gc->of_node = dev->of_node; - gc->request = cygnus_gpio_request; - gc->free = cygnus_gpio_free; gc->direction_input = cygnus_gpio_direction_input; gc->direction_output = cygnus_gpio_direction_output; gc->set = cygnus_gpio_set; gc->get = cygnus_gpio_get; - ret = gpiochip_add(gc); + /* parse DT to find the phandle to the pinmux controller */ + pinmux_node = of_parse_phandle(dev->of_node, "pinmux", 0); + if (pinmux_node) { + struct platform_device *pinmux_pdev; + + pinmux_pdev = of_find_device_by_node(pinmux_node); + /* no longer need the pinmux node */ + of_node_put(pinmux_node); + if (!pinmux_pdev) { + dev_err(chip->dev, "failed to get pinmux device\n"); + return -EINVAL; + } + + pinctrl_name = dev_name(&pinmux_pdev->dev); + ranges = cygnus_gpio_pintable; + nranges = ARRAY_SIZE(cygnus_gpio_pintable); + + put_device(&pinmux_pdev->dev); + } + + ret = gpiochip_add_with_ranges(gc, pinctrl_name, ranges, nranges); if (ret < 0) { dev_err(dev, "unable to add GPIO chip\n"); return ret; } - ret = cygnus_gpio_pinmux_add_range(chip); - if (ret && ret != -ENODEV) { - dev_err(dev, "unable to add GPIO pin range\n"); - goto err_rm_gpiochip; - } - ret = cygnus_gpio_register_pinconf(chip); if (ret) { dev_err(dev, "unable to register pinconf\n"); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html