linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] gpio: rcar: select General Output Register to set output states
@ 2019-01-18  8:53 Vladimir Zapolskiy
  2019-01-22 18:31 ` Geert Uytterhoeven
  0 siblings, 1 reply; 2+ messages in thread
From: Vladimir Zapolskiy @ 2019-01-18  8:53 UTC (permalink / raw)
  To: Linus Walleij, Geert Uytterhoeven; +Cc: linux-gpio, linux-renesas-soc

R-Car GPIO controller provides two interfaces to set GPIO line output
signal state, and for a particular GPIO line the selected interface is
determined by OUTDTSEL bit value.

At the moment the driver supports only one of two interfaces, namely
OUTDT General Output Register is used to control the output signal.

While this selection is the default one on reset, it is not explicitly
configured on probe, thus it might be possible that kernel and userspace
consumers of a GPIO won't be able to set the wanted GPIO output signal.

Below is a simple test case to reproduce the described problem and
verify this fix in the kernel on H3 ULCB by setting non-default OUTDTSEL
configuration from a bootloader:

  u-boot    > mw.l 0xe6055440 0x3000 1
  ...
  userspace > echo default-on > /sys/devices/platform/leds/leds/led5/trigger
  userspace > echo default-on > /sys/devices/platform/leds/leds/led6/trigger

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
Link to v1: https://www.spinics.net/lists/linux-gpio/msg35018.html

Changes from v1 to v2:
* OUTDTSEL and companion OUTDTH/OUTDTL registers are found on R-Car Gen2
  and R-Car Gen3 SoCs, to avoid a possible regression don't modify
  OUTDTSEL register value at R-Car Gen1 GPIO controller,
* removed Fixes tag as too weak one.

As a note .has_outdtsel field has been selected to precede the existing
.has_both_edge_trigger struct field, because OUTDTSEL register precedes
BOTHEDGE register on the controller.

 drivers/gpio/gpio-rcar.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index 068ce25ffd28..500a3596aaf4 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -40,6 +40,7 @@ struct gpio_rcar_priv {
 	struct irq_chip irq_chip;
 	unsigned int irq_parent;
 	atomic_t wakeup_path;
+	bool has_outdtsel;
 	bool has_both_edge_trigger;
 	struct gpio_rcar_bank_info bank_info;
 };
@@ -55,6 +56,7 @@ struct gpio_rcar_priv {
 #define POSNEG 0x20	/* Positive/Negative Logic Select Register */
 #define EDGLEVEL 0x24	/* Edge/level Select Register */
 #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 RCAR_MAX_GPIO_PER_BANK		32
@@ -235,6 +237,10 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,
 	/* Select Input Mode or Output Mode in INOUTSEL */
 	gpio_rcar_modify_bit(p, INOUTSEL, gpio, output);
 
+	/* Select General Output Register to output data in OUTDTSEL */
+	if (p->has_outdtsel && output)
+		gpio_rcar_modify_bit(p, OUTDTSEL, gpio, false);
+
 	spin_unlock_irqrestore(&p->lock, flags);
 }
 
@@ -336,14 +342,17 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,
 }
 
 struct gpio_rcar_info {
+	bool has_outdtsel;
 	bool has_both_edge_trigger;
 };
 
 static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
+	.has_outdtsel = false,
 	.has_both_edge_trigger = false,
 };
 
 static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
+	.has_outdtsel = true,
 	.has_both_edge_trigger = true,
 };
 
@@ -403,10 +412,11 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins)
 	int ret;
 
 	info = of_device_get_match_data(p->dev);
+	p->has_outdtsel = info->has_outdtsel;
+	p->has_both_edge_trigger = info->has_both_edge_trigger;
 
 	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;
 
 	if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {
 		dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n",
-- 
2.19.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] gpio: rcar: select General Output Register to set output states
  2019-01-18  8:53 [PATCH v2] gpio: rcar: select General Output Register to set output states Vladimir Zapolskiy
@ 2019-01-22 18:31 ` Geert Uytterhoeven
  0 siblings, 0 replies; 2+ messages in thread
From: Geert Uytterhoeven @ 2019-01-22 18:31 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Linus Walleij, Geert Uytterhoeven, open list:GPIO SUBSYSTEM,
	Linux-Renesas

On Fri, Jan 18, 2019 at 9:54 AM Vladimir Zapolskiy
<vladimir_zapolskiy@mentor.com> wrote:
> R-Car GPIO controller provides two interfaces to set GPIO line output
> signal state, and for a particular GPIO line the selected interface is
> determined by OUTDTSEL bit value.
>
> At the moment the driver supports only one of two interfaces, namely
> OUTDT General Output Register is used to control the output signal.
>
> While this selection is the default one on reset, it is not explicitly
> configured on probe, thus it might be possible that kernel and userspace
> consumers of a GPIO won't be able to set the wanted GPIO output signal.
>
> Below is a simple test case to reproduce the described problem and
> verify this fix in the kernel on H3 ULCB by setting non-default OUTDTSEL
> configuration from a bootloader:
>
>   u-boot    > mw.l 0xe6055440 0x3000 1
>   ...
>   userspace > echo default-on > /sys/devices/platform/leds/leds/led5/trigger
>   userspace > echo default-on > /sys/devices/platform/leds/leds/led6/trigger
>
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>

FTR (already applied on gpio/for-next)
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-01-22 18:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-18  8:53 [PATCH v2] gpio: rcar: select General Output Register to set output states Vladimir Zapolskiy
2019-01-22 18:31 ` Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).