aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-rcar.c
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 /drivers/gpio/gpio-rcar.c
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>
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
-rw-r--r--drivers/gpio/gpio-rcar.c66
1 files changed, 56 insertions, 10 deletions
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