Linux GPIO subsystem development
 help / color / mirror / Atom feed
From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
To: <linusw@kernel.org>
Cc: <Shyam-sundar.S-k@amd.com>, <Matt.Devillier@amd.com>,
	<Guruvendra.Punugupati@amd.com>, <linux-gpio@vger.kernel.org>,
	"Basavaraj Natikar" <Basavaraj.Natikar@amd.com>
Subject: [PATCH v2 1/3] pinctrl: amd: Centralize per-pin register access
Date: Mon, 21 Sep 2026 10:57:43 +0530	[thread overview]
Message-ID: <20260921052745.1056249-2-Basavaraj.Natikar@amd.com> (raw)
In-Reply-To: <20260921052745.1056249-1-Basavaraj.Natikar@amd.com>

Add a helper to translate a pin into its per-pin register address and
use it at every per-pin access, so a second GPIO bank added later can
be addressed from a single place. No functional change.

Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
---
 drivers/pinctrl/pinctrl-amd.c | 85 ++++++++++++++++++-----------------
 1 file changed, 44 insertions(+), 41 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 65728b590999..543733c2aae0 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -40,6 +40,11 @@
 static struct amd_gpio *pinctrl_dev;
 #endif
 
+static inline void __iomem *amd_gpio_pin_reg(struct amd_gpio *gpio_dev, unsigned int pin)
+{
+	return gpio_dev->base + pin * 4;
+}
+
 static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
 {
 	unsigned long flags;
@@ -47,7 +52,7 @@ static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + offset * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, offset));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	if (pin_reg & BIT(OUTPUT_ENABLE_OFF))
@@ -63,9 +68,9 @@ static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + offset * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, offset));
 	pin_reg &= ~BIT(OUTPUT_ENABLE_OFF);
-	writel(pin_reg, gpio_dev->base + offset * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, offset));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	return 0;
@@ -79,13 +84,13 @@ static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + offset * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, offset));
 	pin_reg |= BIT(OUTPUT_ENABLE_OFF);
 	if (value)
 		pin_reg |= BIT(OUTPUT_VALUE_OFF);
 	else
 		pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
-	writel(pin_reg, gpio_dev->base + offset * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, offset));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	return 0;
@@ -98,7 +103,7 @@ static int amd_gpio_get_value(struct gpio_chip *gc, unsigned offset)
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + offset * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, offset));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	return !!(pin_reg & BIT(PIN_STS_OFF));
@@ -112,12 +117,12 @@ static int amd_gpio_set_value(struct gpio_chip *gc, unsigned int offset,
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + offset * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, offset));
 	if (value)
 		pin_reg |= BIT(OUTPUT_VALUE_OFF);
 	else
 		pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
-	writel(pin_reg, gpio_dev->base + offset * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, offset));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	return 0;
@@ -137,7 +142,7 @@ static int amd_gpio_set_debounce(struct amd_gpio *gpio_dev, unsigned int offset,
 			debounce = 0;
 	}
 
-	pin_reg = readl(gpio_dev->base + offset * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, offset));
 
 	if (debounce) {
 		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
@@ -186,7 +191,7 @@ static int amd_gpio_set_debounce(struct amd_gpio *gpio_dev, unsigned int offset,
 		pin_reg &= ~DB_TMR_OUT_MASK;
 		pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF);
 	}
-	writel(pin_reg, gpio_dev->base + offset * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, offset));
 
 	return ret;
 }
@@ -248,7 +253,7 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
 		for (; i < pin_num; i++) {
 			seq_printf(s, "#%d\t", i);
 			raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-			pin_reg = readl(gpio_dev->base + i * 4);
+			pin_reg = readl(amd_gpio_pin_reg(gpio_dev, i));
 			raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 			if (pin_reg & BIT(INTERRUPT_ENABLE_OFF)) {
@@ -387,10 +392,10 @@ static void amd_gpio_irq_enable(struct irq_data *d)
 	gpiochip_enable_irq(gc, hwirq);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + hwirq * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, hwirq));
 	pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
 	pin_reg |= BIT(INTERRUPT_MASK_OFF);
-	writel(pin_reg, gpio_dev->base + hwirq * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, hwirq));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 }
 
@@ -403,10 +408,10 @@ static void amd_gpio_irq_disable(struct irq_data *d)
 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + hwirq * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, hwirq));
 	pin_reg &= ~BIT(INTERRUPT_ENABLE_OFF);
 	pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
-	writel(pin_reg, gpio_dev->base + hwirq * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, hwirq));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	gpiochip_disable_irq(gc, hwirq);
@@ -421,9 +426,9 @@ static void amd_gpio_irq_mask(struct irq_data *d)
 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + hwirq * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, hwirq));
 	pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
-	writel(pin_reg, gpio_dev->base + hwirq * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, hwirq));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 }
 
@@ -436,9 +441,9 @@ static void amd_gpio_irq_unmask(struct irq_data *d)
 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + hwirq * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, hwirq));
 	pin_reg |= BIT(INTERRUPT_MASK_OFF);
-	writel(pin_reg, gpio_dev->base + hwirq * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, hwirq));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 }
 
@@ -456,14 +461,14 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 		   hwirq, str_enable_disable(on));
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + hwirq * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, hwirq));
 
 	if (on)
 		pin_reg |= wake_mask;
 	else
 		pin_reg &= ~wake_mask;
 
-	writel(pin_reg, gpio_dev->base + hwirq * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, hwirq));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	if (on)
@@ -502,7 +507,7 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + hwirq * 4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, hwirq));
 
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -568,11 +573,11 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 	pin_reg_irq_en = pin_reg;
 	pin_reg_irq_en |= mask;
 	pin_reg_irq_en &= ~BIT(INTERRUPT_MASK_OFF);
-	writel(pin_reg_irq_en, gpio_dev->base + hwirq * 4);
-	if (readl_poll_timeout_atomic(gpio_dev->base + hwirq * 4, reg,
+	writel(pin_reg_irq_en, amd_gpio_pin_reg(gpio_dev, hwirq));
+	if (readl_poll_timeout_atomic(amd_gpio_pin_reg(gpio_dev, hwirq), reg,
 				      (reg & mask) == mask, 1, 1000))
 		ret = -ETIMEDOUT;
-	writel(pin_reg, gpio_dev->base + hwirq * 4);
+	writel(pin_reg, amd_gpio_pin_reg(gpio_dev, hwirq));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
 	return ret;
@@ -615,7 +620,6 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
 	struct gpio_chip *gc = &gpio_dev->gc;
 	unsigned int i, irqnr;
 	unsigned long flags;
-	u32 __iomem *regs;
 	bool ret = false;
 	u32  regval;
 	u64 status, mask;
@@ -629,15 +633,14 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
 
 	/* Bit 0-45 contain the relevant status bits */
 	status &= (1ULL << 46) - 1;
-	regs = gpio_dev->base;
-	for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
+	for (mask = 1, irqnr = 0; status; mask <<= 1, irqnr += 4) {
 		if (!(status & mask))
 			continue;
 		status &= ~mask;
 
 		/* Each status bit covers four pins */
 		for (i = 0; i < 4; i++) {
-			regval = readl(regs + i);
+			regval = readl(amd_gpio_pin_reg(gpio_dev, irqnr + i));
 
 			if (regval & PIN_IRQ_PENDING)
 				pm_pr_dbg("GPIO %d is active: 0x%x",
@@ -660,7 +663,7 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
 			 * avoid a system hang caused by an interrupt storm.
 			 */
 			raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-			regval = readl(regs + i);
+			regval = readl(amd_gpio_pin_reg(gpio_dev, irqnr + i));
 			if (!gpiochip_line_is_irq(gc, irqnr + i)) {
 				regval &= ~BIT(INTERRUPT_MASK_OFF);
 				dev_dbg(&gpio_dev->pdev->dev,
@@ -669,7 +672,7 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
 			} else {
 				ret = true;
 			}
-			writel(regval, regs + i);
+			writel(regval, amd_gpio_pin_reg(gpio_dev, irqnr + i));
 			raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 		}
 	}
@@ -745,7 +748,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev,
 	enum pin_config_param param = pinconf_to_config_param(*config);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-	pin_reg = readl(gpio_dev->base + pin*4);
+	pin_reg = readl(amd_gpio_pin_reg(gpio_dev, pin));
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 	switch (param) {
 	case PIN_CONFIG_INPUT_DEBOUNCE:
@@ -790,7 +793,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	for (i = 0; i < num_configs; i++) {
 		param = pinconf_to_config_param(configs[i]);
 		arg = pinconf_to_config_argument(configs[i]);
-		pin_reg = readl(gpio_dev->base + pin*4);
+		pin_reg = readl(amd_gpio_pin_reg(gpio_dev, pin));
 
 		switch (param) {
 		case PIN_CONFIG_INPUT_DEBOUNCE:
@@ -820,7 +823,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 			ret = -ENOTSUPP;
 		}
 
-		writel(pin_reg, gpio_dev->base + pin*4);
+		writel(pin_reg, amd_gpio_pin_reg(gpio_dev, pin));
 	}
 out_unlock:
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
@@ -897,9 +900,9 @@ static void amd_gpio_irq_init(struct amd_gpio *gpio_dev)
 
 		raw_spin_lock_irqsave(&gpio_dev->lock, flags);
 
-		pin_reg = readl(gpio_dev->base + pin * 4);
+		pin_reg = readl(amd_gpio_pin_reg(gpio_dev, pin));
 		pin_reg &= ~mask;
-		writel(pin_reg, gpio_dev->base + pin * 4);
+		writel(pin_reg, amd_gpio_pin_reg(gpio_dev, pin));
 
 		raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 	}
@@ -919,7 +922,7 @@ static void amd_gpio_check_pending(void)
 		int pin = desc->pins[i].number;
 		u32 tmp;
 
-		tmp = readl(gpio_dev->base + pin * 4);
+		tmp = readl(amd_gpio_pin_reg(gpio_dev, pin));
 		if (tmp & PIN_IRQ_PENDING)
 			pm_pr_dbg("%s: GPIO %d is active: 0x%x.\n", __func__, pin, tmp);
 	}
@@ -977,12 +980,12 @@ static int amd_gpio_suspend_hibernate_common(struct device *dev, bool is_suspend
 			continue;
 
 		raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-		gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin * 4) & ~PIN_IRQ_PENDING;
+		gpio_dev->saved_regs[i] = readl(amd_gpio_pin_reg(gpio_dev, pin)) & ~PIN_IRQ_PENDING;
 
 		/* mask any interrupts not intended to be a wake source */
 		if (!(gpio_dev->saved_regs[i] & wake_mask)) {
 			writel(gpio_dev->saved_regs[i] & ~BIT(INTERRUPT_MASK_OFF),
-			       gpio_dev->base + pin * 4);
+			       amd_gpio_pin_reg(gpio_dev, pin));
 			pm_pr_dbg("Disabling GPIO #%d interrupt for %s.\n",
 				  pin, is_suspend ? "suspend" : "hibernate");
 		}
@@ -1031,8 +1034,8 @@ static int amd_gpio_resume(struct device *dev)
 			continue;
 
 		raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-		gpio_dev->saved_regs[i] |= readl(gpio_dev->base + pin * 4) & PIN_IRQ_PENDING;
-		writel(gpio_dev->saved_regs[i], gpio_dev->base + pin * 4);
+		gpio_dev->saved_regs[i] |= readl(amd_gpio_pin_reg(gpio_dev, pin)) & PIN_IRQ_PENDING;
+		writel(gpio_dev->saved_regs[i], amd_gpio_pin_reg(gpio_dev, pin));
 		raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 	}
 
-- 
2.34.1


  reply	other threads:[~2026-09-21  5:28 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-21  5:27 [PATCH v2 0/3] pinctrl: amd: Add Remote GPIO (RGPIO) bank support Basavaraj Natikar
2026-09-21  5:27 ` Basavaraj Natikar [this message]
2026-09-21  5:27 ` [PATCH v2 2/3] pinctrl: amd: Factor out optional named resource lookup Basavaraj Natikar
2026-09-21  5:27 ` [PATCH v2 3/3] pinctrl: amd: Add support for the Remote GPIO (RGPIO) bank Basavaraj Natikar
2026-10-01  6:48 ` [PATCH v2 0/3] pinctrl: amd: Add Remote GPIO (RGPIO) bank support Linus Walleij
2026-10-01 13:32   ` Mario Limonciello

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=20260921052745.1056249-2-Basavaraj.Natikar@amd.com \
    --to=basavaraj.natikar@amd.com \
    --cc=Guruvendra.Punugupati@amd.com \
    --cc=Matt.Devillier@amd.com \
    --cc=Shyam-sundar.S-k@amd.com \
    --cc=linusw@kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    /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