diff options
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
| -rw-r--r-- | drivers/gpio/gpio-rcar.c | 38 | 
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 @@   * GNU General Public License for more details.   */ -#include <linux/clk.h>  #include <linux/err.h>  #include <linux/gpio.h>  #include <linux/init.h> @@ -37,10 +36,9 @@ struct gpio_rcar_priv {  	struct platform_device *pdev;  	struct gpio_chip gpio_chip;  	struct irq_chip irq_chip; -	struct clk *clk;  	unsigned int irq_parent; +	atomic_t wakeup_path;  	bool has_both_edge_trigger; -	bool needs_clk;  };  #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)  		}  	} -	if (!p->clk) -		return 0; -  	if (on) -		clk_enable(p->clk); +		atomic_inc(&p->wakeup_path);  	else -		clk_disable(p->clk); +		atomic_dec(&p->wakeup_path);  	return 0;  } @@ -330,17 +325,14 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,  struct gpio_rcar_info {  	bool has_both_edge_trigger; -	bool needs_clk;  };  static const struct gpio_rcar_info gpio_rcar_info_gen1 = {  	.has_both_edge_trigger = false, -	.needs_clk = false,  };  static const struct gpio_rcar_info gpio_rcar_info_gen2 = {  	.has_both_edge_trigger = true, -	.needs_clk = true,  };  static 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)  	ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args);  	*npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;  	p->has_both_edge_trigger = info->has_both_edge_trigger; -	p->needs_clk = info->needs_clk;  	if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {  		dev_warn(&p->pdev->dev, @@ -440,16 +431,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, p); -	p->clk = devm_clk_get(dev, NULL); -	if (IS_ERR(p->clk)) { -		if (p->needs_clk) { -			dev_err(dev, "unable to get clock\n"); -			ret = PTR_ERR(p->clk); -			goto err0; -		} -		p->clk = NULL; -	} -  	pm_runtime_enable(dev);  	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -531,11 +512,24 @@ static int gpio_rcar_remove(struct platform_device *pdev)  	return 0;  } +static int __maybe_unused gpio_rcar_suspend(struct device *dev) +{ +	struct gpio_rcar_priv *p = dev_get_drvdata(dev); + +	if (atomic_read(&p->wakeup_path)) +		device_set_wakeup_path(dev); + +	return 0; +} + +static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL); +  static struct platform_driver gpio_rcar_device_driver = {  	.probe		= gpio_rcar_probe,  	.remove		= gpio_rcar_remove,  	.driver		= {  		.name	= "gpio_rcar", +		.pm     = &gpio_rcar_pm_ops,  		.of_match_table = of_match_ptr(gpio_rcar_of_table),  	}  };  | 
