[PATCH 1/4] gpio: kempld: Simplify the bit level register accesses

From: Alban Bedel

Date: Wed Mar 11 2026 - 10:38:17 EST


The hardware uses 8 bit registers but supports configurations with up
to 16 GPIO, so all GPIO registers come in pairs. Most accesses to
single bits is done using the kempld_gpio_bitop() and
kempld_gpio_get_bit() functions, which take a register index and bit
offset as parameter. These functions apply a modulo on the bit offset
but leave the register index as is, so callers have to use an
additional macro to fix the register index before the call.

Simplify things by also handling the register index offsetting in the
bitop functions.

Signed-off-by: Alban Bedel <alban.bedel@xxxxxxxxxx>
---
drivers/gpio/gpio-kempld.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c
index 923aad3ab4d45..532e4000879ab 100644
--- a/drivers/gpio/gpio-kempld.c
+++ b/drivers/gpio/gpio-kempld.c
@@ -17,8 +17,8 @@

#define KEMPLD_GPIO_MAX_NUM 16
#define KEMPLD_GPIO_MASK(x) (BIT((x) % 8))
-#define KEMPLD_GPIO_DIR_NUM(x) (0x40 + (x) / 8)
-#define KEMPLD_GPIO_LVL_NUM(x) (0x42 + (x) / 8)
+#define KEMPLD_GPIO_DIR 0x40
+#define KEMPLD_GPIO_LVL 0x42
#define KEMPLD_GPIO_EVT_LVL_EDGE 0x46
#define KEMPLD_GPIO_IEN 0x4A

@@ -32,24 +32,25 @@ struct kempld_gpio_data {
* kempld_get_mutex must be called prior to calling this function.
*/
static void kempld_gpio_bitop(struct kempld_device_data *pld,
- u8 reg, u8 bit, u8 val)
+ u8 reg, unsigned int bit, bool val)
{
u8 status;

- status = kempld_read8(pld, reg);
+ status = kempld_read8(pld, reg + (bit / 8));
if (val)
status |= KEMPLD_GPIO_MASK(bit);
else
status &= ~KEMPLD_GPIO_MASK(bit);
- kempld_write8(pld, reg, status);
+ kempld_write8(pld, reg + (bit / 8), status);
}

-static int kempld_gpio_get_bit(struct kempld_device_data *pld, u8 reg, u8 bit)
+static int kempld_gpio_get_bit(struct kempld_device_data *pld,
+ u8 reg, unsigned int bit)
{
u8 status;

kempld_get_mutex(pld);
- status = kempld_read8(pld, reg);
+ status = kempld_read8(pld, reg + (bit / 8));
kempld_release_mutex(pld);

return !!(status & KEMPLD_GPIO_MASK(bit));
@@ -60,7 +61,7 @@ static int kempld_gpio_get(struct gpio_chip *chip, unsigned offset)
struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
struct kempld_device_data *pld = gpio->pld;

- return !!kempld_gpio_get_bit(pld, KEMPLD_GPIO_LVL_NUM(offset), offset);
+ return !!kempld_gpio_get_bit(pld, KEMPLD_GPIO_LVL, offset);
}

static int kempld_gpio_set(struct gpio_chip *chip, unsigned int offset,
@@ -70,7 +71,7 @@ static int kempld_gpio_set(struct gpio_chip *chip, unsigned int offset,
struct kempld_device_data *pld = gpio->pld;

kempld_get_mutex(pld);
- kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL_NUM(offset), offset, value);
+ kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL, offset, value);
kempld_release_mutex(pld);

return 0;
@@ -82,7 +83,7 @@ static int kempld_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
struct kempld_device_data *pld = gpio->pld;

kempld_get_mutex(pld);
- kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR_NUM(offset), offset, 0);
+ kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR, offset, 0);
kempld_release_mutex(pld);

return 0;
@@ -95,8 +96,8 @@ static int kempld_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
struct kempld_device_data *pld = gpio->pld;

kempld_get_mutex(pld);
- kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL_NUM(offset), offset, value);
- kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR_NUM(offset), offset, 1);
+ kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL, offset, value);
+ kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR, offset, 1);
kempld_release_mutex(pld);

return 0;
@@ -107,7 +108,7 @@ static int kempld_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
struct kempld_device_data *pld = gpio->pld;

- if (kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset))
+ if (kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR, offset))
return GPIO_LINE_DIRECTION_OUT;

return GPIO_LINE_DIRECTION_IN;
--
2.39.5