aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-rcar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
-rw-r--r--drivers/gpio/gpio-rcar.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index e76de57dd617..ebaea8b1594b 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -14,7 +14,6 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 */ 15 */
16 16
17#include <linux/clk.h>
18#include <linux/err.h> 17#include <linux/err.h>
19#include <linux/gpio.h> 18#include <linux/gpio.h>
20#include <linux/init.h> 19#include <linux/init.h>
@@ -37,10 +36,9 @@ struct gpio_rcar_priv {
37 struct platform_device *pdev; 36 struct platform_device *pdev;
38 struct gpio_chip gpio_chip; 37 struct gpio_chip gpio_chip;
39 struct irq_chip irq_chip; 38 struct irq_chip irq_chip;
40 struct clk *clk;
41 unsigned int irq_parent; 39 unsigned int irq_parent;
40 atomic_t wakeup_path;
42 bool has_both_edge_trigger; 41 bool has_both_edge_trigger;
43 bool needs_clk;
44}; 42};
45 43
46#define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */ 44#define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */
@@ -186,13 +184,10 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)
186 } 184 }
187 } 185 }
188 186
189 if (!p->clk)
190 return 0;
191
192 if (on) 187 if (on)
193 clk_enable(p->clk); 188 atomic_inc(&p->wakeup_path);
194 else 189 else
195 clk_disable(p->clk); 190 atomic_dec(&p->wakeup_path);
196 191
197 return 0; 192 return 0;
198} 193}
@@ -330,17 +325,14 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,
330 325
331struct gpio_rcar_info { 326struct gpio_rcar_info {
332 bool has_both_edge_trigger; 327 bool has_both_edge_trigger;
333 bool needs_clk;
334}; 328};
335 329
336static const struct gpio_rcar_info gpio_rcar_info_gen1 = { 330static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
337 .has_both_edge_trigger = false, 331 .has_both_edge_trigger = false,
338 .needs_clk = false,
339}; 332};
340 333
341static const struct gpio_rcar_info gpio_rcar_info_gen2 = { 334static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
342 .has_both_edge_trigger = true, 335 .has_both_edge_trigger = true,
343 .needs_clk = true,
344}; 336};
345 337
346static const struct of_device_id gpio_rcar_of_table[] = { 338static const struct of_device_id gpio_rcar_of_table[] = {
@@ -403,7 +395,6 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins)
403 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); 395 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args);
404 *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; 396 *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;
405 p->has_both_edge_trigger = info->has_both_edge_trigger; 397 p->has_both_edge_trigger = info->has_both_edge_trigger;
406 p->needs_clk = info->needs_clk;
407 398
408 if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { 399 if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {
409 dev_warn(&p->pdev->dev, 400 dev_warn(&p->pdev->dev,
@@ -440,16 +431,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
440 431
441 platform_set_drvdata(pdev, p); 432 platform_set_drvdata(pdev, p);
442 433
443 p->clk = devm_clk_get(dev, NULL);
444 if (IS_ERR(p->clk)) {
445 if (p->needs_clk) {
446 dev_err(dev, "unable to get clock\n");
447 ret = PTR_ERR(p->clk);
448 goto err0;
449 }
450 p->clk = NULL;
451 }
452
453 pm_runtime_enable(dev); 434 pm_runtime_enable(dev);
454 435
455 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 436 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -531,11 +512,24 @@ static int gpio_rcar_remove(struct platform_device *pdev)
531 return 0; 512 return 0;
532} 513}
533 514
515static int __maybe_unused gpio_rcar_suspend(struct device *dev)
516{
517 struct gpio_rcar_priv *p = dev_get_drvdata(dev);
518
519 if (atomic_read(&p->wakeup_path))
520 device_set_wakeup_path(dev);
521
522 return 0;
523}
524
525static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL);
526
534static struct platform_driver gpio_rcar_device_driver = { 527static struct platform_driver gpio_rcar_device_driver = {
535 .probe = gpio_rcar_probe, 528 .probe = gpio_rcar_probe,
536 .remove = gpio_rcar_remove, 529 .remove = gpio_rcar_remove,
537 .driver = { 530 .driver = {
538 .name = "gpio_rcar", 531 .name = "gpio_rcar",
532 .pm = &gpio_rcar_pm_ops,
539 .of_match_table = of_match_ptr(gpio_rcar_of_table), 533 .of_match_table = of_match_ptr(gpio_rcar_of_table),
540 } 534 }
541}; 535};