diff options
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
-rw-r--r-- | drivers/gpio/gpio-rcar.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 8b7e719a68c3..ca76ce751540 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c | |||
@@ -285,7 +285,34 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = { | |||
285 | .map = gpio_rcar_irq_domain_map, | 285 | .map = gpio_rcar_irq_domain_map, |
286 | }; | 286 | }; |
287 | 287 | ||
288 | static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) | 288 | struct gpio_rcar_info { |
289 | bool has_both_edge_trigger; | ||
290 | }; | ||
291 | |||
292 | static const struct of_device_id gpio_rcar_of_table[] = { | ||
293 | { | ||
294 | .compatible = "renesas,gpio-r8a7790", | ||
295 | .data = (void *)&(const struct gpio_rcar_info) { | ||
296 | .has_both_edge_trigger = true, | ||
297 | }, | ||
298 | }, { | ||
299 | .compatible = "renesas,gpio-r8a7791", | ||
300 | .data = (void *)&(const struct gpio_rcar_info) { | ||
301 | .has_both_edge_trigger = true, | ||
302 | }, | ||
303 | }, { | ||
304 | .compatible = "renesas,gpio-rcar", | ||
305 | .data = (void *)&(const struct gpio_rcar_info) { | ||
306 | .has_both_edge_trigger = false, | ||
307 | }, | ||
308 | }, { | ||
309 | /* Terminator */ | ||
310 | }, | ||
311 | }; | ||
312 | |||
313 | MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); | ||
314 | |||
315 | static int gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) | ||
289 | { | 316 | { |
290 | struct gpio_rcar_config *pdata = dev_get_platdata(&p->pdev->dev); | 317 | struct gpio_rcar_config *pdata = dev_get_platdata(&p->pdev->dev); |
291 | struct device_node *np = p->pdev->dev.of_node; | 318 | struct device_node *np = p->pdev->dev.of_node; |
@@ -295,11 +322,21 @@ static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) | |||
295 | if (pdata) { | 322 | if (pdata) { |
296 | p->config = *pdata; | 323 | p->config = *pdata; |
297 | } else if (IS_ENABLED(CONFIG_OF) && np) { | 324 | } else if (IS_ENABLED(CONFIG_OF) && np) { |
325 | const struct of_device_id *match; | ||
326 | const struct gpio_rcar_info *info; | ||
327 | |||
328 | match = of_match_node(gpio_rcar_of_table, np); | ||
329 | if (!match) | ||
330 | return -EINVAL; | ||
331 | |||
332 | info = match->data; | ||
333 | |||
298 | ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, | 334 | ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, |
299 | &args); | 335 | &args); |
300 | p->config.number_of_pins = ret == 0 ? args.args[2] | 336 | p->config.number_of_pins = ret == 0 ? args.args[2] |
301 | : RCAR_MAX_GPIO_PER_BANK; | 337 | : RCAR_MAX_GPIO_PER_BANK; |
302 | p->config.gpio_base = -1; | 338 | p->config.gpio_base = -1; |
339 | p->config.has_both_edge_trigger = info->has_both_edge_trigger; | ||
303 | } | 340 | } |
304 | 341 | ||
305 | if (p->config.number_of_pins == 0 || | 342 | if (p->config.number_of_pins == 0 || |
@@ -309,6 +346,8 @@ static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) | |||
309 | p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK); | 346 | p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK); |
310 | p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK; | 347 | p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK; |
311 | } | 348 | } |
349 | |||
350 | return 0; | ||
312 | } | 351 | } |
313 | 352 | ||
314 | static int gpio_rcar_probe(struct platform_device *pdev) | 353 | static int gpio_rcar_probe(struct platform_device *pdev) |
@@ -331,7 +370,9 @@ static int gpio_rcar_probe(struct platform_device *pdev) | |||
331 | spin_lock_init(&p->lock); | 370 | spin_lock_init(&p->lock); |
332 | 371 | ||
333 | /* Get device configuration from DT node or platform data. */ | 372 | /* Get device configuration from DT node or platform data. */ |
334 | gpio_rcar_parse_pdata(p); | 373 | ret = gpio_rcar_parse_pdata(p); |
374 | if (ret < 0) | ||
375 | return ret; | ||
335 | 376 | ||
336 | platform_set_drvdata(pdev, p); | 377 | platform_set_drvdata(pdev, p); |
337 | 378 | ||
@@ -370,10 +411,9 @@ static int gpio_rcar_probe(struct platform_device *pdev) | |||
370 | irq_chip->name = name; | 411 | irq_chip->name = name; |
371 | irq_chip->irq_mask = gpio_rcar_irq_disable; | 412 | irq_chip->irq_mask = gpio_rcar_irq_disable; |
372 | irq_chip->irq_unmask = gpio_rcar_irq_enable; | 413 | irq_chip->irq_unmask = gpio_rcar_irq_enable; |
373 | irq_chip->irq_enable = gpio_rcar_irq_enable; | ||
374 | irq_chip->irq_disable = gpio_rcar_irq_disable; | ||
375 | irq_chip->irq_set_type = gpio_rcar_irq_set_type; | 414 | irq_chip->irq_set_type = gpio_rcar_irq_set_type; |
376 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED; | 415 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED |
416 | | IRQCHIP_MASK_ON_SUSPEND; | ||
377 | 417 | ||
378 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, | 418 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, |
379 | p->config.number_of_pins, | 419 | p->config.number_of_pins, |
@@ -436,17 +476,6 @@ static int gpio_rcar_remove(struct platform_device *pdev) | |||
436 | return 0; | 476 | return 0; |
437 | } | 477 | } |
438 | 478 | ||
439 | #ifdef CONFIG_OF | ||
440 | static const struct of_device_id gpio_rcar_of_table[] = { | ||
441 | { | ||
442 | .compatible = "renesas,gpio-rcar", | ||
443 | }, | ||
444 | { }, | ||
445 | }; | ||
446 | |||
447 | MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); | ||
448 | #endif | ||
449 | |||
450 | static struct platform_driver gpio_rcar_device_driver = { | 479 | static struct platform_driver gpio_rcar_device_driver = { |
451 | .probe = gpio_rcar_probe, | 480 | .probe = gpio_rcar_probe, |
452 | .remove = gpio_rcar_remove, | 481 | .remove = gpio_rcar_remove, |