Skip to content

Commit 9ac79ba

Browse files
geertulinusw
authored andcommitted
gpio: rcar: Use wakeup_path i.s.o. explicit clock handling
Since commit ab82fa7 ("gpio: rcar: Prevent module clock disable when wake-up is enabled"), when a GPIO is used for wakeup, the GPIO block's module clock (if exists) is manually kept running during system suspend, to make sure the device stays active. However, this explicit clock handling is merely a workaround for a failure to properly communicate wakeup information to the device core. Instead, set the device's power.wakeup_path field, to indicate this device is part of the wakeup path. Depending on the PM Domain's active_wakeup configuration, the genpd core code will keep the device enabled (and the clock running) during system suspend when needed. This allows for the removal of all explicit clock handling code from the driver. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 661e50b commit 9ac79ba

File tree

1 file changed

+16
-22
lines changed

1 file changed

+16
-22
lines changed

drivers/gpio/gpio-rcar.c

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* GNU General Public License for more details.
1515
*/
1616

17-
#include <linux/clk.h>
1817
#include <linux/err.h>
1918
#include <linux/gpio.h>
2019
#include <linux/init.h>
@@ -37,10 +36,9 @@ struct gpio_rcar_priv {
3736
struct platform_device *pdev;
3837
struct gpio_chip gpio_chip;
3938
struct irq_chip irq_chip;
40-
struct clk *clk;
4139
unsigned int irq_parent;
40+
atomic_t wakeup_path;
4241
bool has_both_edge_trigger;
43-
bool needs_clk;
4442
};
4543

4644
#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)
186184
}
187185
}
188186

189-
if (!p->clk)
190-
return 0;
191-
192187
if (on)
193-
clk_enable(p->clk);
188+
atomic_inc(&p->wakeup_path);
194189
else
195-
clk_disable(p->clk);
190+
atomic_dec(&p->wakeup_path);
196191

197192
return 0;
198193
}
@@ -330,17 +325,14 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,
330325

331326
struct gpio_rcar_info {
332327
bool has_both_edge_trigger;
333-
bool needs_clk;
334328
};
335329

336330
static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
337331
.has_both_edge_trigger = false,
338-
.needs_clk = false,
339332
};
340333

341334
static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
342335
.has_both_edge_trigger = true,
343-
.needs_clk = true,
344336
};
345337

346338
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)
403395
ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args);
404396
*npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;
405397
p->has_both_edge_trigger = info->has_both_edge_trigger;
406-
p->needs_clk = info->needs_clk;
407398

408399
if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {
409400
dev_warn(&p->pdev->dev,
@@ -440,16 +431,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
440431

441432
platform_set_drvdata(pdev, p);
442433

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-
453434
pm_runtime_enable(dev);
454435

455436
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -531,11 +512,24 @@ static int gpio_rcar_remove(struct platform_device *pdev)
531512
return 0;
532513
}
533514

515+
static 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+
525+
static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL);
526+
534527
static struct platform_driver gpio_rcar_device_driver = {
535528
.probe = gpio_rcar_probe,
536529
.remove = gpio_rcar_remove,
537530
.driver = {
538531
.name = "gpio_rcar",
532+
.pm = &gpio_rcar_pm_ops,
539533
.of_match_table = of_match_ptr(gpio_rcar_of_table),
540534
}
541535
};

0 commit comments

Comments
 (0)