From patchwork Fri May 10 14:48:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2551221 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id A637EDF2A2 for ; Fri, 10 May 2013 14:48:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755152Ab3EJOse (ORCPT ); Fri, 10 May 2013 10:48:34 -0400 Received: from perceval.ideasonboard.com ([95.142.166.194]:44873 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754631Ab3EJOsc (ORCPT ); Fri, 10 May 2013 10:48:32 -0400 Received: from avalon.ideasonboard.com (ptra-178-50-80-25.mobistar.be [178.50.80.25]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0173E35A4E; Fri, 10 May 2013 16:48:04 +0200 (CEST) From: Laurent Pinchart To: linux-sh@vger.kernel.org Cc: devicetree-discuss@lists.ozlabs.org, Linus Walleij , Magnus Damm Subject: [RFC/PATCH 2/2] gpio-rcar: Add DT support Date: Fri, 10 May 2013 16:48:37 +0200 Message-Id: <1368197317-13169-3-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1368197317-13169-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1368197317-13169-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org Add DT bindings for the gpio-rcar driver and read the device configuration from the DT node at probe time if available. Cc: devicetree-discuss@lists.ozlabs.org Signed-off-by: Laurent Pinchart --- .../devicetree/bindings/gpio/renesas,gpio-rcar.txt | 48 +++++++++++++++++ drivers/gpio/gpio-rcar.c | 63 ++++++++++++++++++---- 2 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt new file mode 100644 index 0000000..a2f4cd1 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt @@ -0,0 +1,48 @@ +* Renesas R-Car GPIO Controller + +Required Properties: + + - compatible: should be one of the following. + - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller. + - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. + - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller. + - "renesas,gpio-rcar": for generic R-Car GPIO controller. + + - reg: Base address and length of each memory resource used by the GPIO + controller hardware module. + + - interrupt-parent: phandle of the parent interrupt controller. + - interrupts: Interrupt specifier for the controllers interrupt. + + - gpio-controller: Marks the device node as a gpio controller. + - #gpio-cells: Should be 2. The first cell is the GPIO number and the second + cell is used to specify optional parameters as bit flags. Only the GPIO + active low flag (bit 0) is currently supported. + +Optional Properties: + + - #gpio-lines: Number of GPIOs handled by this controller (defaults to 32). + +Please refer to gpio.txt in this directory for details of the common GPIO +bindings used by client devices. + +Example: R8A7779 (R-Car H1) GPIO controller nodes + + gpio0: gpio@ffc40000 { + compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; + reg = <0xffc40000 0x2c>; + interrupt-parent = <&gic>; + interrupts = <0 141 0x4>; + #gpio-cells = <2>; + gpio-controller; + }; + ... + gpio6: gpio@ffc46000 { + compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; + reg = <0xffc46000 0x2c>; + interrupt-parent = <&gic>; + interrupts = <0 147 0x4>; + #gpio-cells = <2>; + gpio-controller; + #gpio-lines = <9>; + }; diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 0f3d647..a499ea6 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -50,6 +50,8 @@ struct gpio_rcar_priv { #define EDGLEVEL 0x24 #define FILONOFF 0x28 +#define RCAR_MAX_GPIO_PER_BANK 32 + static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs) { return ioread32(p->base + offs); @@ -258,9 +260,37 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = { .map = gpio_rcar_irq_domain_map, }; +static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) +{ + struct gpio_rcar_config *pdata = p->pdev->dev.platform_data; +#ifdef CONFIG_OF + struct device_node *np = p->pdev->dev.of_node; + u32 gpio_lines; + int ret; +#endif + + if (pdata) + p->config = *pdata; +#ifdef CONFIG_OF + else if (np) { + ret = of_property_read_u32(np, "#gpio-lines", &gpio_lines); + p->config.number_of_pins = ret == 0 ? gpio_lines + : RCAR_MAX_GPIO_PER_BANK; + p->config.gpio_base = -1; + } +#endif + + if (p->config.number_of_pins == 0 || + p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) { + dev_warn(&p->pdev->dev, + "Invalid number of gpio lines %u, using %u\n", + p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK); + p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK; + } +} + static int gpio_rcar_probe(struct platform_device *pdev) { - struct gpio_rcar_config *pdata = pdev->dev.platform_data; struct gpio_rcar_priv *p; struct resource *io, *irq; struct gpio_chip *gpio_chip; @@ -275,14 +305,14 @@ static int gpio_rcar_probe(struct platform_device *pdev) goto err0; } - /* deal with driver instance configuration */ - if (pdata) - p->config = *pdata; - p->pdev = pdev; - platform_set_drvdata(pdev, p); spin_lock_init(&p->lock); + /* Get device configuration from DT node or platform data. */ + gpio_rcar_parse_pdata(p); + + platform_set_drvdata(pdev, p); + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -355,10 +385,12 @@ static int gpio_rcar_probe(struct platform_device *pdev) p->config.irq_base, ret); } - ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0, - gpio_chip->base, gpio_chip->ngpio); - if (ret < 0) - dev_warn(&pdev->dev, "failed to add pin range\n"); + if (p->config.pctl_name) { + ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0, + gpio_chip->base, gpio_chip->ngpio); + if (ret < 0) + dev_warn(&pdev->dev, "failed to add pin range\n"); + } return 0; @@ -381,11 +413,22 @@ static int gpio_rcar_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id gpio_rcar_of_table[] = { + { + .compatible = "renesas,gpio-rcar", + }, +}; + +MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); +#endif + static struct platform_driver gpio_rcar_device_driver = { .probe = gpio_rcar_probe, .remove = gpio_rcar_remove, .driver = { .name = "gpio_rcar", + .of_match_table = of_match_ptr(gpio_rcar_of_table), } };