@@ -35,6 +35,7 @@ struct gpio_rcar_bank_info {
struct gpio_rcar_info {
bool has_outdtsel;
bool has_both_edge_trigger;
+ bool has_always_in;
};
struct gpio_rcar_priv {
@@ -302,9 +303,11 @@ static int gpio_rcar_get(struct gpio_chip *chip, unsigned offset)
struct gpio_rcar_priv *p = gpiochip_get_data(chip);
u32 bit = BIT(offset);
- /* testing on r8a7790 shows that INDT does not show correct pin state
- * when configured as output, so use OUTDT in case of output pins */
- if (gpio_rcar_read(p, INOUTSEL) & bit)
+ /*
+ * Before R-Car Gen3, INDT does not show correct pin state when
+ * configured as output, so use OUTDT in case of output pins
+ */
+ if (!p->info.has_always_in && (gpio_rcar_read(p, INOUTSEL) & bit))
return !!(gpio_rcar_read(p, OUTDT) & bit);
else
return !!(gpio_rcar_read(p, INDT) & bit);
@@ -324,6 +327,11 @@ static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask,
if (!bankmask)
return 0;
+ if (p->info.has_always_in) {
+ bits[0] = gpio_rcar_read(p, INDT) & bankmask;
+ return 0;
+ }
+
spin_lock_irqsave(&p->lock, flags);
outputs = gpio_rcar_read(p, INOUTSEL);
m = outputs & bankmask;
@@ -383,11 +391,19 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,
static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
.has_outdtsel = false,
.has_both_edge_trigger = false,
+ .has_always_in = false,
};
static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
.has_outdtsel = true,
.has_both_edge_trigger = true,
+ .has_always_in = false,
+};
+
+static const struct gpio_rcar_info gpio_rcar_info_gen3 = {
+ .has_outdtsel = true,
+ .has_both_edge_trigger = true,
+ .has_always_in = true,
};
static const struct of_device_id gpio_rcar_of_table[] = {
@@ -399,8 +415,7 @@ static const struct of_device_id gpio_rcar_of_table[] = {
.data = &gpio_rcar_info_gen2,
}, {
.compatible = "renesas,rcar-gen3-gpio",
- /* Gen3 GPIO is identical to Gen2. */
- .data = &gpio_rcar_info_gen2,
+ .data = &gpio_rcar_info_gen3,
}, {
.compatible = "renesas,gpio-rcar",
.data = &gpio_rcar_info_gen1,