linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Théo Lebrun" <theo.lebrun@bootlin.com>
To: Linus Walleij <linus.walleij@linaro.org>,
	 Bartosz Golaszewski <brgl@bgdev.pl>,
	Rob Herring <robh+dt@kernel.org>,
	 Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	 Conor Dooley <conor+dt@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-mips@vger.kernel.org,
	"Gregory CLEMENT" <gregory.clement@bootlin.com>,
	"Vladimir Kondratiev" <vladimir.kondratiev@mobileye.com>,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
	"Tawfik Bayouk" <tawfik.bayouk@mobileye.com>,
	"Théo Lebrun" <theo.lebrun@bootlin.com>
Subject: [PATCH 12/23] gpio: nomadik: request dynamic ID allocation
Date: Wed, 14 Feb 2024 17:24:05 +0100	[thread overview]
Message-ID: <20240214-mbly-gpio-v1-12-f88c0ccf372b@bootlin.com> (raw)
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>

Move away from statically allocated GPIO IDs. Switch to dynamic ID
allocation. Static IDs are deprecated because they cause issues when
multiple GPIO controllers are to be found on the same platform.

Add a bit of complexity to do pin number -> GPIO chip + offset.
Previously, bank number and offsets were retrieved using division and
remainder (bank size being constant 32). Now, to get the pin number
matching a bank base, we must know the sum of ngpios of previous banks.
This is done in find_nmk_gpio_from_pin() which also exposes the offset
inside the bank.

Also remove the assumption that bank sizes are constant. Instead of
using NMK_GPIO_PER_CHIP as bank size, use nmk_gpio_chips[i]->ngpio.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 drivers/gpio/gpio-nomadik.c               |  2 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 55 +++++++++++++++++++++----------
 2 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index e39477e1a58f..8d47aef8d2c4 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -516,7 +516,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 
 	nmk_chip->bank = id;
 	chip = &nmk_chip->chip;
-	chip->base = id * NMK_GPIO_PER_CHIP;
+	chip->base = -1;
 	chip->ngpio = NMK_GPIO_PER_CHIP;
 	chip->label = dev_name(&gpio_pdev->dev);
 	chip->parent = &gpio_pdev->dev;
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 8099dd947701..c7693fbc0484 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -530,25 +530,33 @@ static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector
 	return 0;
 }
 
-static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin)
+/* This makes the mapping from pin number to a GPIO chip. We also return the pin
+ * offset in the GPIO chip for convenience (and to avoid a second loop).
+ */
+static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin,
+						    unsigned int *offset)
 {
-	int i;
+	int i, j = 0;
 	struct nmk_gpio_chip *nmk_gpio;
 
+	/* We assume that pins are allocated in bank order. */
 	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		nmk_gpio = nmk_gpio_chips[i];
 		if (!nmk_gpio)
 			continue;
-		if (pin >= nmk_gpio->chip.base &&
-		    pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio)
+		if (pin >= j && pin < j + nmk_gpio->chip.ngpio) {
+			if (offset)
+				*offset = pin - j;
 			return nmk_gpio;
+		}
+		j += nmk_gpio->chip.ngpio;
 	}
 	return NULL;
 }
 
 static struct gpio_chip *find_gc_from_pin(unsigned int pin)
 {
-	struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin);
+	struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin, NULL);
 
 	if (nmk_gpio)
 		return &nmk_gpio->chip;
@@ -903,8 +911,19 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		 * Then mask the pins that need to be sleeping now when we're
 		 * switching to the ALT C function.
 		 */
-		for (i = 0; i < g->grp.npins; i++)
-			slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]);
+		for (i = 0; i < g->grp.npins; i++) {
+			struct nmk_gpio_chip *nmk_chip;
+
+			nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], NULL);
+			if (!nmk_chip) {
+				dev_err(npct->dev,
+					"invalid pin offset %d in group %s at index %d\n",
+					g->grp.pins[i], g->grp.name, i);
+				goto out_pre_slpm_init;
+			}
+
+			slpm[nmk_chip->bank] &= ~BIT(g->grp.pins[i]);
+		}
 		nmk_gpio_glitch_slpm_init(slpm);
 	}
 
@@ -912,7 +931,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		struct nmk_gpio_chip *nmk_chip;
 		unsigned int bit;
 
-		nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i]);
+		nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit);
 		if (!nmk_chip) {
 			dev_err(npct->dev,
 				"invalid pin offset %d in group %s at index %d\n",
@@ -923,7 +942,6 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 			g->grp.pins[i], g->altsetting);
 
 		clk_enable(nmk_chip->clk);
-		bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP;
 		/*
 		 * If the pin is switching to altfunc, and there was an
 		 * interrupt installed on it which has been lazy disabled,
@@ -954,17 +972,18 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 	ret = 0;
 
 out_glitch:
-	if (glitch) {
+	if (glitch)
 		nmk_gpio_glitch_slpm_restore(slpm);
+out_pre_slpm_init:
+	if (glitch)
 		spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-	}
 
 	return ret;
 }
 
 static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 				   struct pinctrl_gpio_range *range,
-				   unsigned int offset)
+				   unsigned int pin)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 	struct nmk_gpio_chip *nmk_chip;
@@ -982,10 +1001,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 	chip = range->gc;
 	nmk_chip = gpiochip_get_data(chip);
 
-	dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
+	dev_dbg(npct->dev, "enable pin %u as GPIO\n", pin);
+
+	find_nmk_gpio_from_pin(pin, &bit);
 
 	clk_enable(nmk_chip->clk);
-	bit = offset % NMK_GPIO_PER_CHIP;
 	/* There is no glitch when converting any pin to GPIO */
 	__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
 	clk_disable(nmk_chip->clk);
@@ -995,11 +1015,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
 				  struct pinctrl_gpio_range *range,
-				  unsigned int offset)
+				  unsigned int pin)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
-	dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
+	dev_dbg(npct->dev, "disable pin %u as GPIO\n", pin);
 	/* Set the pin to some default state, GPIO is usually default */
 }
 
@@ -1040,7 +1060,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	int pull, slpm, output, val, i;
 	bool lowemi, gpiomode, sleep;
 
-	nmk_chip = find_nmk_gpio_from_pin(pin);
+	nmk_chip = find_nmk_gpio_from_pin(pin, &bit);
 	if (!nmk_chip) {
 		dev_err(npct->dev,
 			"invalid pin offset %d\n", pin);
@@ -1098,7 +1118,6 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 			lowemi ? "on" : "off");
 
 		clk_enable(nmk_chip->clk);
-		bit = pin % NMK_GPIO_PER_CHIP;
 		if (gpiomode)
 			/* No glitch when going to GPIO mode */
 			__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);

-- 
2.43.1


  parent reply	other threads:[~2024-02-14 16:24 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-14 16:23 [PATCH 00/23] Rework Nomadik GPIO to add Mobileye EyeQ5 support Théo Lebrun
2024-02-14 16:23 ` [PATCH 01/23] dt-bindings: gpio: nomadik: convert into yaml format Théo Lebrun
2024-02-15  9:11   ` Krzysztof Kozlowski
2024-02-15  9:47     ` Théo Lebrun
2024-02-19 14:50   ` Linus Walleij
2024-02-14 16:23 ` [PATCH 02/23] dt-bindings: gpio: nomadik: add optional ngpios property Théo Lebrun
2024-02-15  9:12   ` Krzysztof Kozlowski
2024-02-19 14:50   ` Linus Walleij
2024-02-19 14:55     ` Théo Lebrun
2024-02-14 16:23 ` [PATCH 03/23] dt-bindings: gpio: nomadik: add mobileye,eyeq5-gpio compatible Théo Lebrun
2024-02-15  9:13   ` Krzysztof Kozlowski
2024-02-15  9:52     ` Théo Lebrun
2024-02-14 16:23 ` [PATCH 04/23] dt-bindings: gpio: nomadik: add optional reset property Théo Lebrun
2024-02-15  9:13   ` Krzysztof Kozlowski
2024-02-19 14:55   ` Linus Walleij
2024-02-14 16:23 ` [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/ Théo Lebrun
2024-02-15 10:03   ` Philipp Zabel
2024-02-16 10:43     ` Théo Lebrun
2024-02-19 15:33     ` Bartosz Golaszewski
2024-02-21 11:41       ` Philipp Zabel
2024-02-19 16:08   ` Bartosz Golaszewski
2024-02-21 16:02     ` Théo Lebrun
2024-02-21 14:37   ` Linus Walleij
2024-02-21 16:20     ` Théo Lebrun
2024-02-21 19:31       ` Linus Walleij
2024-02-14 16:23 ` [PATCH 06/23] pinctrl: nomadik: fix build warning (-Wformat) Théo Lebrun
2024-02-14 16:24 ` [PATCH 07/23] pinctrl: nomadik: fix build warning (-Wpointer-to-int-cast) Théo Lebrun
2024-02-14 16:24 ` [PATCH 08/23] pinctrl: nomadik: minimise indentation in probe Théo Lebrun
2024-02-14 16:24 ` [PATCH 09/23] pinctrl: nomadik: follow type-system kernel coding conventions Théo Lebrun
2024-02-14 16:24 ` [PATCH 10/23] pinctrl: nomadik: follow whitespace " Théo Lebrun
2024-02-14 16:24 ` [PATCH 11/23] pinctrl: nomadik: follow conditional " Théo Lebrun
2024-02-14 16:24 ` Théo Lebrun [this message]
2024-02-14 16:24 ` [PATCH 13/23] gpio: nomadik: fix offset bug in nmk_pmx_set() Théo Lebrun
2024-02-19 15:54   ` Bartosz Golaszewski
2024-02-21 15:57     ` Théo Lebrun
2024-02-19 21:56   ` Linus Walleij
2024-02-21 16:05     ` Théo Lebrun
2024-02-14 16:24 ` [PATCH 14/23] gpio: nomadik: make clock optional Théo Lebrun
2024-02-14 16:24 ` [PATCH 15/23] gpio: nomadik: change driver name from gpio to gpio-nomadik Théo Lebrun
2024-02-14 16:24 ` [PATCH 16/23] gpio: nomadik: support shared GPIO IRQs Théo Lebrun
2024-02-19 15:48   ` Bartosz Golaszewski
2024-02-19 15:54     ` Théo Lebrun
2024-02-19 16:17       ` Bartosz Golaszewski
2024-02-20  8:07     ` Linus Walleij
2024-02-14 16:24 ` [PATCH 17/23] gpio: nomadik: handle variadic GPIO count Théo Lebrun
2024-02-19 16:17   ` Bartosz Golaszewski
2024-02-20  8:08   ` Linus Walleij
2024-02-14 16:24 ` [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio Théo Lebrun
2024-02-21 13:45   ` Linus Walleij
2024-02-21 16:22     ` Théo Lebrun
2024-02-21 14:31   ` Linus Walleij
2024-02-21 16:16     ` Théo Lebrun
2024-02-21 19:36       ` Linus Walleij
2024-02-22  9:37         ` Théo Lebrun
2024-02-14 16:24 ` [PATCH 19/23] gpio: nomadik: grab optional reset control and deassert it at probe Théo Lebrun
2024-02-15 10:19   ` Philipp Zabel
2024-02-16 10:46     ` Théo Lebrun
2024-02-14 16:24 ` [PATCH 20/23] MIPS: eyeq5_defconfig: enable GPIO by default Théo Lebrun
2024-02-14 16:24 ` [PATCH 21/23] MIPS: mobileye: eyeq5: add two GPIO bank nodes Théo Lebrun
2024-02-14 16:24 ` [PATCH 22/23] MIPS: mobileye: eyeq5: add resets to GPIO banks Théo Lebrun
2024-02-14 16:24 ` [PATCH 23/23] MIPS: mobileye: eyeq5: map GPIOs to pins using gpio-ranges Théo Lebrun
2024-02-19 15:44 ` [PATCH 00/23] Rework Nomadik GPIO to add Mobileye EyeQ5 support Bartosz Golaszewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240214-mbly-gpio-v1-12-f88c0ccf372b@bootlin.com \
    --to=theo.lebrun@bootlin.com \
    --cc=brgl@bgdev.pl \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregory.clement@bootlin.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=robh+dt@kernel.org \
    --cc=tawfik.bayouk@mobileye.com \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=tsbogend@alpha.franken.de \
    --cc=vladimir.kondratiev@mobileye.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).