From: "Michael Walle" <mwalle@kernel.org>
To: "Yu-Chun Lin" <eleanor.lin@realtek.com>
Cc: <Michael.Hennerich@analog.com>, <afaerber@suse.com>,
<andy@kernel.org>, <brgl@kernel.org>, <conor+dt@kernel.org>,
<cy.huang@realtek.com>, <devicetree@vger.kernel.org>,
<dlechner@baylibre.com>, <james.tai@realtek.com>,
<jic23@kernel.org>, <krzk+dt@kernel.org>, <lars@metafoo.de>,
<linus.walleij@linaro.org>, <linusw@kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-gpio@vger.kernel.org>, <linux-iio@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
<linux-realtek-soc@lists.infradead.org>,
<mathieu.dubois-briand@bootlin.com>, <nuno.sa@analog.com>,
<robh@kernel.org>, <stanley_chang@realtek.com>,
<tychang@realtek.com>, <wbg@kernel.org>
Subject: Re: [PATCH v3 3/7] gpio: regmap: Add gpio_regmap_operation and write-enable support
Date: Thu, 16 Jul 2026 09:15:29 +0200 [thread overview]
Message-ID: <DJZT74OCHTA2.3LLOKE9Y2SBXO@kernel.org> (raw)
In-Reply-To: <20260716062614.1507243-1-eleanor.lin@realtek.com>
Hi,
On Thu Jul 16, 2026 at 8:26 AM CEST, Yu-Chun Lin wrote:
>>> > @@ -185,7 +218,7 @@ static int gpio_regmap_set_direction(struct
>>> gpio_chip *chip,
>>> > unsigned int offset, bool output)
>>> > {
>>> > struct gpio_regmap *gpio = gpiochip_get_data(chip);
>>> > - unsigned int base, val, reg, mask;
>>> > + unsigned int base, val, reg, mask, wren_mask;
>>> > int invert, ret;
>>> >
>>> > if (gpio->reg_dir_out_base) {
>>> > @@ -198,7 +231,12 @@ static int gpio_regmap_set_direction(struct
>>> gpio_chip *chip,
>>> > return -ENOTSUPP;
>>> > }
>>> >
>>> > - ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask);
>>> > + ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_DIR_OP, base,
>>> offset, ®, &mask);
>>> > + if (ret)
>>> > + return ret;
>>> > +
>>> > + ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_DIR_WREN_OP,
>>> base, offset, ®,
>>> > + &wren_mask);
>>>
>>> What constrains these two to provide the same value back for reg?
>>> To me it seems like the write enable might well be in a different register.
>>>
>>> > if (ret)
>>> > return ret;
>>> >
>>> > @@ -207,7 +245,7 @@ static int gpio_regmap_set_direction(struct
>>> gpio_chip *chip,
>>> > else
>>> > val = output ? mask : 0;
>>> >
>>> > - return regmap_update_bits(gpio->regmap, reg, mask, val);
>>> > + return regmap_update_bits(gpio->regmap, reg, mask | wren_mask,
>>> > + val | wren_mask);
>>> > }
>>> >
>>> > static int gpio_regmap_direction_input(struct gpio_chip *chip,
>>
>> My initial design indeed assumed that the WREN mask and Data mask reside in
>> the same register.
>>
>> Regarding WREN support, especially if WREN and Data use separate registers, I
>> came up with three ideas. Which direction do you prefer?
>>
>> Approach 1: Provide Custom Callbacks in config (Let consumer driver handle it)
>> We can add '.set' and '.set_direction' function pointers in
>> 'struct gpio_regmap_config'. If a driver requires WREN, it can implement these
>> callbacks itself.
>>
>> static void gpio_regmap_set(struct gpio_chip *chip, unsigned int offset, int val)
>> {
>> struct gpio_regmap *gpio = gpiochip_get_data(chip);
>>
>> /* If the driver provides a custom set (to handle WREN), delegate to it */
>> if (gpio->set) {
>> gpio->set(chip, offset, val);
>> return;
>> }
>> /* ... existing generic regmap logic ... */
>> }
>>
>> Pros: Clean core, no need to touch existing drivers' xlate signature. The consumer
>> driver handles its own locking for different registers.
>> Cons: It feels a bit strange and inconsistent to expose only '.set' and
>> '.set_direction' overrides while keeping other operations entirely abstracted.
>>
>> Approach 2: Handle separate WREN register in the core (with locking concerns)
>> We keep the 'XX_WREN_OP' in 'xlate'. If someone needs WREN and 'wren_reg != reg',
>> we write to both.
>>
>> static int gpio_regmap_set(struct gpio_chip *chip, unsigned int offset,
>> int val)
>> {
>> /* skip */
>> ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_WREN_OP, base, offset, &wren_reg,
>> &wren_mask);
>> if (ret == -ENOTSUPP)
>> has_wren = false;
>> else if (ret)
>> return ret;
>>
>> ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_OP, base, offset, ®, &mask);
>>
>> if (has_wren && reg == wren_reg) {
>> mask |= wren_mask;
>> mask_val |= wren_mask;
>> has_wren = false;
>> }
>>
>> if (has_wren)
>> ret = regmap_set_bits(gpio->regmap, wren_reg, wren_mask);
>>
>> /* ignore input values which shadow the old output value */
>> if (gpio->reg_dat_base == gpio->reg_set_base)
>> ret = regmap_write_bits(gpio->regmap, reg, mask, mask_val);
>> else
>> ret = regmap_update_bits(gpio->regmap, reg, mask, mask_val);
>>
>> return ret;
>> }
>>
>> Pros: Keeps all WREN logic unified inside the core framework.
>> Cons: Introduces a locking issue. writing to 'wren_reg' and then 'reg' requires an
>> external lock to be atomic, which seems to defeat the purpose of relying on regmap's
>> internal lock.
>>
>> Approach 3: Assume WREN and Data always share the same register
>>
>> static int gpio_regmap_set(struct gpio_chip *chip, unsigned int offset, int val)
>> {
>> /* ... */
>> ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_WREN_OP, base, offset, ®, &wren_mask);
>> if (ret == -ENOTSUPP)
>> wren_mask = 0;
>> else if (ret)
>> return ret;
>>
>> ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_OP, base, offset, ®, &mask);
>>
>> ret = regmap_update_bits(gpio->regmap, reg, mask | wren_mask, mask_val | wren_mask);
>> return ret;
>> }
>>
>> Regarding this approach, I would like to ask from your experience: Is it
>> actually common for hardware designs to place WREN and Data bits in completely
>> different registers for GPIO operations?
I'd say that such a write enable bit by itself is pretty uncommon
for a gpio controller, regardless if it's in the same register or in
a different one.
>> If they practically always share the same register, this simpler approach might
>> suffice.
It seems, that your hardware has it in one register. Why do you need
a separate mask anyway? Why can't the xlate callback just set the
bit in addition to the gpio bit? It looks like in the end you're
doing a "mask | wren_mask" anyway. What am I missing here?
-michael
next prev parent reply other threads:[~2026-07-16 7:15 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-12 3:33 [PATCH v3 0/7] gpio: realtek: Add support for Realtek DHC RTD1625 Yu-Chun Lin
2026-05-12 3:33 ` [PATCH v3 1/7] gpio: Replace "default y" with "default ARCH_REALTEK" in Kconfig Yu-Chun Lin
2026-05-12 3:33 ` [PATCH v3 2/7] gpio: regmap: add gpio_regmap_get_gpiochip() accessor Yu-Chun Lin
2026-05-12 11:20 ` Andy Shevchenko
2026-05-25 12:04 ` Yu-Chun Lin [林祐君]
2026-06-03 0:34 ` Andy Shevchenko
2026-06-08 14:10 ` Bartosz Golaszewski
2026-06-08 14:41 ` Michael Walle
2026-06-17 8:36 ` Yu-Chun Lin [林祐君]
2026-06-17 8:44 ` Michael Walle
2026-06-17 9:54 ` Yu-Chun Lin [林祐君]
2026-06-17 11:19 ` Michael Walle
2026-06-19 21:08 ` Linus Walleij
2026-06-22 10:35 ` Andy Shevchenko
2026-06-30 13:21 ` Linus Walleij
2026-07-01 8:44 ` Michael Walle
2026-07-01 10:01 ` Andy Shevchenko
2026-07-01 10:55 ` Andy Shevchenko
2026-07-01 11:38 ` Andy Shevchenko
2026-07-01 11:42 ` Michael Walle
2026-07-01 12:03 ` Andy Shevchenko
2026-07-01 11:38 ` Michael Walle
2026-07-01 12:08 ` Andy Shevchenko
2026-05-12 3:33 ` [PATCH v3 3/7] gpio: regmap: Add gpio_regmap_operation and write-enable support Yu-Chun Lin
2026-05-12 11:26 ` Andy Shevchenko
2026-05-12 14:37 ` Jonathan Cameron
2026-07-09 17:21 ` Yu-Chun Lin [林祐君]
2026-07-16 6:26 ` Yu-Chun Lin
2026-07-16 7:15 ` Michael Walle [this message]
2026-07-16 8:27 ` Andy Shevchenko
2026-07-16 9:08 ` Michael Walle
2026-07-16 9:40 ` Andy Shevchenko
2026-07-16 10:47 ` Yu-Chun Lin [林祐君]
2026-07-16 11:03 ` Michael Walle
2026-07-16 11:21 ` Yu-Chun Lin [林祐君]
2026-07-16 11:42 ` Michael Walle
2026-07-16 12:08 ` Yu-Chun Lin [林祐君]
2026-07-16 10:55 ` Michael Walle
2026-07-16 17:56 ` Andy Shevchenko
2026-05-13 4:01 ` sashiko-bot
2026-05-13 7:40 ` Linus Walleij
2026-05-12 3:33 ` [PATCH v3 4/7] gpio: regmap: Add set_config callback Yu-Chun Lin
2026-05-12 18:12 ` Andy Shevchenko
2026-05-13 4:23 ` sashiko-bot
2026-05-12 3:33 ` [PATCH v3 5/7] dt-bindings: gpio: realtek: Add realtek,rtd1625-gpio Yu-Chun Lin
2026-05-13 4:26 ` sashiko-bot
2026-05-12 3:33 ` [PATCH v3 6/7] gpio: realtek: Add driver for Realtek DHC RTD1625 SoC Yu-Chun Lin
2026-05-12 18:50 ` Andy Shevchenko
2026-05-13 4:56 ` sashiko-bot
2026-05-12 3:33 ` [PATCH v3 7/7] arm64: dts: realtek: Add GPIO support for RTD1625 Yu-Chun Lin
2026-05-13 5:40 ` sashiko-bot
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=DJZT74OCHTA2.3LLOKE9Y2SBXO@kernel.org \
--to=mwalle@kernel.org \
--cc=Michael.Hennerich@analog.com \
--cc=afaerber@suse.com \
--cc=andy@kernel.org \
--cc=brgl@kernel.org \
--cc=conor+dt@kernel.org \
--cc=cy.huang@realtek.com \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=eleanor.lin@realtek.com \
--cc=james.tai@realtek.com \
--cc=jic23@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linus.walleij@linaro.org \
--cc=linusw@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-realtek-soc@lists.infradead.org \
--cc=mathieu.dubois-briand@bootlin.com \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
--cc=stanley_chang@realtek.com \
--cc=tychang@realtek.com \
--cc=wbg@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.