aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-05-21 07:40:06 -0400
committerSimon Horman <horms+renesas@verge.net.au>2013-06-12 08:48:09 -0400
commit159f8a0209aff155af7f6fcdedd4a4484dd19c23 (patch)
tree2c3081a053077cceffb1c1651b977846043d1e5f
parent5fcf4a3c3a5bc08bf72a50ef1332501a3c1b96bb (diff)
gpio-rcar: Add DT support
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 <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r--Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt52
-rw-r--r--drivers/gpio/gpio-rcar.c66
2 files changed, 108 insertions, 10 deletions
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 000000000000..46d76a004246
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
@@ -0,0 +1,52 @@
1* Renesas R-Car GPIO Controller
2
3Required Properties:
4
5 - compatible: should be one of the following.
6 - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller.
7 - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller.
8 - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller.
9 - "renesas,gpio-rcar": for generic R-Car GPIO controller.
10
11 - reg: Base address and length of each memory resource used by the GPIO
12 controller hardware module.
13
14 - interrupt-parent: phandle of the parent interrupt controller.
15 - interrupts: Interrupt specifier for the controllers interrupt.
16
17 - gpio-controller: Marks the device node as a gpio controller.
18 - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
19 cell is used to specify optional parameters as bit flags. Only the GPIO
20 active low flag (bit 0) is currently supported.
21 - gpio-ranges: Range of pins managed by the GPIO controller as a 4-cells
22 tuple using the following syntax.
23
24 <[phandle of the pin controller node]
25 0
26 [index of the first pin]
27 [number of pins]>
28
29Please refer to gpio.txt in this directory for details of the common GPIO
30bindings used by client devices.
31
32Example: R8A7779 (R-Car H1) GPIO controller nodes
33
34 gpio0: gpio@ffc40000 {
35 compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
36 reg = <0xffc40000 0x2c>;
37 interrupt-parent = <&gic>;
38 interrupts = <0 141 0x4>;
39 #gpio-cells = <2>;
40 gpio-controller;
41 gpio-ranges = <&pfc 0 0 32>;
42 };
43 ...
44 gpio6: gpio@ffc46000 {
45 compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
46 reg = <0xffc46000 0x2c>;
47 interrupt-parent = <&gic>;
48 interrupts = <0 147 0x4>;
49 #gpio-cells = <2>;
50 gpio-controller;
51 gpio-ranges = <&pfc 0 192 9>;
52 };
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index d173d56dbb8c..5a693dd0ac7a 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -51,6 +51,8 @@ struct gpio_rcar_priv {
51#define FILONOFF 0x28 51#define FILONOFF 0x28
52#define BOTHEDGE 0x4c 52#define BOTHEDGE 0x4c
53 53
54#define RCAR_MAX_GPIO_PER_BANK 32
55
54static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs) 56static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)
55{ 57{
56 return ioread32(p->base + offs); 58 return ioread32(p->base + offs);
@@ -274,9 +276,39 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = {
274 .map = gpio_rcar_irq_domain_map, 276 .map = gpio_rcar_irq_domain_map,
275}; 277};
276 278
279static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p)
280{
281 struct gpio_rcar_config *pdata = p->pdev->dev.platform_data;
282#ifdef CONFIG_OF
283 struct device_node *np = p->pdev->dev.of_node;
284 struct of_phandle_args args;
285 int ret;
286#endif
287
288 if (pdata)
289 p->config = *pdata;
290#ifdef CONFIG_OF
291 else if (np) {
292 ret = of_parse_phandle_with_args(np, "gpio-ranges",
293 "#gpio-range-cells", 0, &args);
294 p->config.number_of_pins = ret == 0 && args.args_count == 3
295 ? args.args[2]
296 : RCAR_MAX_GPIO_PER_BANK;
297 p->config.gpio_base = -1;
298 }
299#endif
300
301 if (p->config.number_of_pins == 0 ||
302 p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) {
303 dev_warn(&p->pdev->dev,
304 "Invalid number of gpio lines %u, using %u\n",
305 p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK);
306 p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK;
307 }
308}
309
277static int gpio_rcar_probe(struct platform_device *pdev) 310static int gpio_rcar_probe(struct platform_device *pdev)
278{ 311{
279 struct gpio_rcar_config *pdata = pdev->dev.platform_data;
280 struct gpio_rcar_priv *p; 312 struct gpio_rcar_priv *p;
281 struct resource *io, *irq; 313 struct resource *io, *irq;
282 struct gpio_chip *gpio_chip; 314 struct gpio_chip *gpio_chip;
@@ -291,14 +323,14 @@ static int gpio_rcar_probe(struct platform_device *pdev)
291 goto err0; 323 goto err0;
292 } 324 }
293 325
294 /* deal with driver instance configuration */
295 if (pdata)
296 p->config = *pdata;
297
298 p->pdev = pdev; 326 p->pdev = pdev;
299 platform_set_drvdata(pdev, p);
300 spin_lock_init(&p->lock); 327 spin_lock_init(&p->lock);
301 328
329 /* Get device configuration from DT node or platform data. */
330 gpio_rcar_parse_pdata(p);
331
332 platform_set_drvdata(pdev, p);
333
302 io = platform_get_resource(pdev, IORESOURCE_MEM, 0); 334 io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
303 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 335 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
304 336
@@ -325,6 +357,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
325 gpio_chip->set = gpio_rcar_set; 357 gpio_chip->set = gpio_rcar_set;
326 gpio_chip->to_irq = gpio_rcar_to_irq; 358 gpio_chip->to_irq = gpio_rcar_to_irq;
327 gpio_chip->label = name; 359 gpio_chip->label = name;
360 gpio_chip->dev = &pdev->dev;
328 gpio_chip->owner = THIS_MODULE; 361 gpio_chip->owner = THIS_MODULE;
329 gpio_chip->base = p->config.gpio_base; 362 gpio_chip->base = p->config.gpio_base;
330 gpio_chip->ngpio = p->config.number_of_pins; 363 gpio_chip->ngpio = p->config.number_of_pins;
@@ -371,10 +404,12 @@ static int gpio_rcar_probe(struct platform_device *pdev)
371 p->config.irq_base, ret); 404 p->config.irq_base, ret);
372 } 405 }
373 406
374 ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0, 407 if (p->config.pctl_name) {
375 gpio_chip->base, gpio_chip->ngpio); 408 ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0,
376 if (ret < 0) 409 gpio_chip->base, gpio_chip->ngpio);
377 dev_warn(&pdev->dev, "failed to add pin range\n"); 410 if (ret < 0)
411 dev_warn(&pdev->dev, "failed to add pin range\n");
412 }
378 413
379 return 0; 414 return 0;
380 415
@@ -397,11 +432,22 @@ static int gpio_rcar_remove(struct platform_device *pdev)
397 return 0; 432 return 0;
398} 433}
399 434
435#ifdef CONFIG_OF
436static const struct of_device_id gpio_rcar_of_table[] = {
437 {
438 .compatible = "renesas,gpio-rcar",
439 },
440};
441
442MODULE_DEVICE_TABLE(of, gpio_rcar_of_table);
443#endif
444
400static struct platform_driver gpio_rcar_device_driver = { 445static struct platform_driver gpio_rcar_device_driver = {
401 .probe = gpio_rcar_probe, 446 .probe = gpio_rcar_probe,
402 .remove = gpio_rcar_remove, 447 .remove = gpio_rcar_remove,
403 .driver = { 448 .driver = {
404 .name = "gpio_rcar", 449 .name = "gpio_rcar",
450 .of_match_table = of_match_ptr(gpio_rcar_of_table),
405 } 451 }
406}; 452};
407 453