summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpio-rcar.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index edded6478792..e7092d5fe700 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -36,6 +36,7 @@ struct gpio_rcar_info {
bool has_outdtsel;
bool has_both_edge_trigger;
bool has_always_in;
+ bool has_inen;
};
struct gpio_rcar_priv {
@@ -63,6 +64,7 @@ struct gpio_rcar_priv {
#define FILONOFF 0x28 /* Chattering Prevention On/Off Register */
#define OUTDTSEL 0x40 /* Output Data Select Register */
#define BOTHEDGE 0x4c /* One Edge/Both Edge Select Register */
+#define INEN 0x50 /* General Input Enable Register */
#define RCAR_MAX_GPIO_PER_BANK 32
@@ -392,22 +394,35 @@ static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
.has_outdtsel = false,
.has_both_edge_trigger = false,
.has_always_in = false,
+ .has_inen = false,
};
static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
.has_outdtsel = true,
.has_both_edge_trigger = true,
.has_always_in = false,
+ .has_inen = false,
};
static const struct gpio_rcar_info gpio_rcar_info_gen3 = {
.has_outdtsel = true,
.has_both_edge_trigger = true,
.has_always_in = true,
+ .has_inen = false,
+};
+
+static const struct gpio_rcar_info gpio_rcar_info_v3u = {
+ .has_outdtsel = true,
+ .has_both_edge_trigger = true,
+ .has_always_in = true,
+ .has_inen = true,
};
static const struct of_device_id gpio_rcar_of_table[] = {
{
+ .compatible = "renesas,gpio-r8a779a0",
+ .data = &gpio_rcar_info_v3u,
+ }, {
.compatible = "renesas,rcar-gen1-gpio",
.data = &gpio_rcar_info_gen1,
}, {
@@ -448,6 +463,17 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins)
return 0;
}
+static void gpio_rcar_enable_inputs(struct gpio_rcar_priv *p)
+{
+ u32 mask = GENMASK(p->gpio_chip.ngpio - 1, 0);
+
+ /* Select "Input Enable" in INEN */
+ if (p->gpio_chip.valid_mask)
+ mask &= p->gpio_chip.valid_mask[0];
+ if (mask)
+ gpio_rcar_write(p, INEN, gpio_rcar_read(p, INEN) | mask);
+}
+
static int gpio_rcar_probe(struct platform_device *pdev)
{
struct gpio_rcar_priv *p;
@@ -537,6 +563,12 @@ static int gpio_rcar_probe(struct platform_device *pdev)
goto err1;
}
+ if (p->info.has_inen) {
+ pm_runtime_get_sync(p->dev);
+ gpio_rcar_enable_inputs(p);
+ pm_runtime_put(p->dev);
+ }
+
dev_info(dev, "driving %d GPIOs\n", npins);
return 0;
@@ -612,6 +644,9 @@ static int gpio_rcar_resume(struct device *dev)
}
}
+ if (p->info.has_inen)
+ gpio_rcar_enable_inputs(p);
+
return 0;
}
#endif /* CONFIG_PM_SLEEP*/