From patchwork Sun Oct 11 15:48:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonas Gorski X-Patchwork-Id: 528757 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 96CEF1402A8 for ; Mon, 12 Oct 2015 02:48:29 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752394AbbJKPs3 (ORCPT ); Sun, 11 Oct 2015 11:48:29 -0400 Received: from arrakis.dune.hu ([78.24.191.176]:54767 "EHLO arrakis.dune.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752380AbbJKPs2 (ORCPT ); Sun, 11 Oct 2015 11:48:28 -0400 Received: from localhost (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id AEDC228054C; Sun, 11 Oct 2015 17:46:53 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham version=3.3.2 X-Virus-Scanned: at arrakis.dune.hu Received: from localhost.localdomain (dslb-088-073-016-160.088.073.pools.vodafone-ip.de [88.73.16.160]) by arrakis.dune.hu (Postfix) with ESMTPSA id 2D2AD28A6C8; Sun, 11 Oct 2015 17:46:39 +0200 (CEST) From: Jonas Gorski To: linux-gpio@vger.kernel.org Cc: Linus Walleij , Alexandre Courbot , Florian Fainelli , Ray Jui , Scott Branden Subject: [PATCH RFC/RFT 2/2] pinctrl-cygnus-gpio: convert to use gpiochip_add_with_ranges Date: Sun, 11 Oct 2015 17:48:19 +0200 Message-Id: <1444578499-17980-3-git-send-email-jogo@openwrt.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1444578499-17980-1-git-send-email-jogo@openwrt.org> References: <1444578499-17980-1-git-send-email-jogo@openwrt.org> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org 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 --- 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");