Skip to content

Commit

Permalink
Merge tag 'gpio-v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linusw/linux-gpio

Pull GPIO fix from Linus Walleij:
 "This is a single GPIO fix for the v4.16 series affecting the Renesas
  driver, and fixes wakeup from external stuff"

* tag 'gpio-v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpio: rcar: Use wakeup_path i.s.o. explicit clock handling
  • Loading branch information
torvalds committed Mar 11, 2018
2 parents 3266b5b + 9ac79ba commit d43be80
Showing 1 changed file with 16 additions and 22 deletions.
38 changes: 16 additions & 22 deletions drivers/gpio/gpio-rcar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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),
}
};
Expand Down

0 comments on commit d43be80

Please sign in to comment.