From: Lorenzo Bianconi <lorenzo@kernel.org>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: "Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Sean Wang" <sean.wang@kernel.org>,
"Matthias Brugger" <matthias.bgg@gmail.com>,
"AngeloGioacchino Del Regno"
<angelogioacchino.delregno@collabora.com>,
"Lee Jones" <lee@kernel.org>,
"Uwe Kleine-König" <ukleinek@kernel.org>,
linux-mediatek@lists.infradead.org, linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
upstream@airoha.com, benjamin.larsson@genexis.eu,
ansuelsmth@gmail.com, linux-pwm@vger.kernel.org
Subject: Re: [PATCH v4 4/5] pinctrl: airoha: Add support for EN7581 SoC
Date: Tue, 24 Sep 2024 23:22:28 +0200 [thread overview]
Message-ID: <ZvMtlJN1xAMHoW-E@lore-desk> (raw)
In-Reply-To: <ZvKQe73ZKIFy4fny@lore-desk>
[-- Attachment #1: Type: text/plain, Size: 10267 bytes --]
[...]
>
> I am fine to switch to regmap but I guess we need to enable fast_io
> since it can run even in interrupt context. Btw, I figured out even
> airoha_pinctrl_rmw needs to grab a spin_lock since we can exec a led
> trigger (like timer) where we run airoha_pinctrl_rmw in interrupt context
> (so it should be fine to use a single regmap for it).
> However, I guess we need to keep the spin_lock in airoha_pinctrl_gpiochip
> since we need to grab it in airoha_pinctrl_gpio_irq_unmask() and
> airoha_pinctrl_gpio_irq_type() (we access irq_type array there).
> A possible solution would be to keep the local spin_lock and set
> disable_locking. What do you think? Do you prefer to switch to regmap or
> keep the current implementation using 'guard(spinlock_irqsave)' instead?
I reworked the code using regmap APIs and setting disable_locking flag
in order to keep the spinlock local (I switch to guard(spinlock) as
well). Thx for pointing this out, the code is simpler and more readable,
I will add it in v5.
>
> >
> > > +static int airoha_pinctrl_get_gpio_from_pin(struct pinctrl_dev *pctrl_dev,
> > > + int pin)
> > > +{
> > > + struct pinctrl_gpio_range *range;
> > > + int gpio;
> > > +
> > > + range = pinctrl_find_gpio_range_from_pin_nolock(pctrl_dev, pin);
> > > + if (!range)
> > > + return -EINVAL;
> > > +
> > > + gpio = pin - range->pin_base;
> > > + if (gpio < 0)
> > > + return -EINVAL;
> > > +
> > > + return gpio;
> > > +}
> >
> > This function is just used here:
>
> it is used in airoha_pinconf_get()/airoha_pinconf_set()
>
> >
[...]
> > > + case PIN_CONFIG_OUTPUT_ENABLE:
> > > + case PIN_CONFIG_INPUT_ENABLE: {
> > > + int gpio = airoha_pinctrl_get_gpio_from_pin(pctrl_dev, pin);
> > > +
> > > + if (gpio < 0)
> > > + return gpio;
> > > +
> > > + arg = airoha_pinctrl_gpio_get_direction(pinctrl, gpio);
> >
> > I don't see why a pin would have to exist in a GPIO range in order to
> > be set as output or input?
> >
> > Can't you just set up the pin as requested and not care whether
> > it has a corresponding GPIO range?
> >
> > Is it over-reuse of the GPIO code? I'd say just set up the pin instead.
>
> Do you mean to get rid of PIN_CONFIG_OUTPUT_ENABLE, PIN_CONFIG_INPUT_ENABLE
> (and even PIN_CONFIG_OUTPUT in airoha_pinconf_set()) here?
> E.g. we need PIN_CONFIG_OUTPUT_ENABLE to enable pwm for pwm-leds:
>
> &mfd {
> ...
> pio: pinctrl {
> ...
> pwm_gpio18_idx10_pins: pwm-gpio18-idx10-pins {
> function = "pwm";
> pins = "gpio18";
> output-enable;
> };
> };
> };
I reworked the code here in order to not explicitly use gpio value in
airoha_pinconf_get/airoha_pinconf_set routines. However, we need to switch
from pin to gpio configuring data/direction/out hw registers since:
- not all pins can be used as gpio (actually we can configure just pins in the
range [13, 59])
- data, dir and out hw register are indexed using gpio id and not pin one.
(e.g BIT(0) in data[0] refers to GPIO0 and not to PIN0).
Regards,
Lorenzo
>
> >
> > > +static int airoha_pinconf_set(struct pinctrl_dev *pctrl_dev,
> > > + unsigned int pin, unsigned long *configs,
> > > + unsigned int num_configs)
> > > +{
> > > + struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> > > + int i;
> > > +
> > > + for (i = 0; i < num_configs; i++) {
> > > + u32 param = pinconf_to_config_param(configs[i]);
> > > + u32 arg = pinconf_to_config_argument(configs[i]);
> > > +
> > > + switch (param) {
> > > + case PIN_CONFIG_BIAS_DISABLE:
> > > + airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
> > > + airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
> > > + break;
> > > + case PIN_CONFIG_BIAS_PULL_UP:
> > > + airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
> > > + airoha_pinctrl_set_pullup_conf(pinctrl, pin, 1);
> > > + break;
> > > + case PIN_CONFIG_BIAS_PULL_DOWN:
> > > + airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1);
> > > + airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
> > > + break;
> > > + case PIN_CONFIG_DRIVE_STRENGTH: {
> > > + u32 e2 = 0, e4 = 0;
> > > +
> > > + switch (arg) {
> > > + case MTK_DRIVE_2mA:
> > > + break;
> > > + case MTK_DRIVE_4mA:
> > > + e2 = 1;
> > > + break;
> > > + case MTK_DRIVE_6mA:
> > > + e4 = 1;
> > > + break;
> > > + case MTK_DRIVE_8mA:
> > > + e2 = 1;
> > > + e4 = 1;
> > > + break;
> > > + default:
> > > + return -EINVAL;
> > > + }
> > > +
> > > + airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, e2);
> > > + airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, e4);
> > > + break;
> > > + }
> > > + case PIN_CONFIG_DRIVE_OPEN_DRAIN:
> > > + airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, !!arg);
> > > + break;
> > > + case PIN_CONFIG_OUTPUT_ENABLE:
> > > + case PIN_CONFIG_INPUT_ENABLE:
> > > + case PIN_CONFIG_OUTPUT: {
> > > + int gpio = airoha_pinctrl_get_gpio_from_pin(pctrl_dev, pin);
> > > + bool input = param == PIN_CONFIG_INPUT_ENABLE;
> > > +
> > > + if (gpio < 0)
> > > + return gpio;
> > > +
> > > + airoha_pinctrl_gpio_set_direction(pinctrl, gpio, input);
> > > + if (param == PIN_CONFIG_OUTPUT)
> > > + airoha_pinctrl_gpio_set_value(pinctrl, gpio, !!arg);
> > > + break;
> >
> > Dito. No need to reuse the GPIO set direction function. Make a helper
> > that just work on the pin instead, and perhaps the GPIO set direction
> > can use that instead.
>
> ack, I will fix it in v5.
>
> >
> > > +static int airoha_pinctrl_gpio_direction_output(struct gpio_chip *chip,
> > > + unsigned int gpio, int value)
> > > +{
> > > + int err;
> > > +
> > > + err = pinctrl_gpio_direction_output(chip, gpio);
> > > + if (err)
> > > + return err;
> > > +
> > > + airoha_pinctrl_gpio_set(chip, gpio, value);
> >
> > Hm I get a bit confused by the similarly named helpers I guess...
>
> Naming is always hard, I will try to improve :)
>
> >
> > > +static void airoha_pinctrl_gpio_irq_unmask(struct irq_data *data)
> > > +{
> > > + u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_GPIO;
> > > + u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_GPIO;
> > > + u32 mask = GENMASK(2 * offset + 1, 2 * offset);
> > > + struct airoha_pinctrl_gpiochip *gpiochip;
> > > + u32 val = BIT(2 * offset);
> > > + unsigned long flags;
> > > +
> > > + gpiochip = irq_data_get_irq_chip_data(data);
> > > + if (WARN_ON_ONCE(data->hwirq >= ARRAY_SIZE(gpiochip->irq_type)))
> > > + return;
> > > +
> > > + spin_lock_irqsave(&gpiochip->lock, flags);
> >
> > Use a scoped guard here
> >
> > guard(spinlock_irqsave)(&gpiochip->lock);
> >
> > > +static void airoha_pinctrl_gpio_irq_mask(struct irq_data *data)
> > > +{
> > > + u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_GPIO;
> > > + u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_GPIO;
> > > + u32 mask = GENMASK(2 * offset + 1, 2 * offset);
> > > + struct airoha_pinctrl_gpiochip *gpiochip;
> > > + unsigned long flags;
> > > +
> > > + gpiochip = irq_data_get_irq_chip_data(data);
> > > +
> > > + spin_lock_irqsave(&gpiochip->lock, flags);
> >
> > Dito
> >
> > > +static int airoha_pinctrl_gpio_irq_type(struct irq_data *data,
> > > + unsigned int type)
> > > +{
> > > + struct airoha_pinctrl_gpiochip *gpiochip;
> > > + unsigned long flags;
> > > +
> > > + gpiochip = irq_data_get_irq_chip_data(data);
> > > + if (data->hwirq >= ARRAY_SIZE(gpiochip->irq_type))
> > > + return -EINVAL;
> > > +
> > > + spin_lock_irqsave(&gpiochip->lock, flags);
> >
> > Dito
> >
> > > + girq->chip = devm_kzalloc(dev, sizeof(*girq->chip), GFP_KERNEL);
> > > + if (!girq->chip)
> > > + return -ENOMEM;
> > > +
> > > + girq->chip->name = dev_name(dev);
> > > + girq->chip->irq_unmask = airoha_pinctrl_gpio_irq_unmask;
> > > + girq->chip->irq_mask = airoha_pinctrl_gpio_irq_mask;
> > > + girq->chip->irq_mask_ack = airoha_pinctrl_gpio_irq_mask;
> > > + girq->chip->irq_set_type = airoha_pinctrl_gpio_irq_type;
> > > + girq->chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE;
> > > + girq->default_type = IRQ_TYPE_NONE;
> > > + girq->handler = handle_simple_irq;
> >
> > If the irqchip is immutable it is const and there is no point to malloc it.
> >
> > Just
> >
> > static const struct irq_chip airoha_gpio_irq_chip = {...
> >
> > And assign it:
> >
> > girq = &g->gc.irq;
> > gpio_irq_chip_set_chip(girq, &airoha_gpio_irq_chip);
>
> ack, I will fix it in v5.
>
> Regards,
> Lorenzo
>
> >
> > Yours,
> > Linus Walleij
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next prev parent reply other threads:[~2024-09-24 21:22 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-11 19:50 [PATCH v4 0/5] Add mfd, pinctrl and pwm support to EN7581 SoC Lorenzo Bianconi
2024-09-11 19:50 ` [PATCH v4 1/5] dt-bindings: arm: airoha: Add the chip-scu node for " Lorenzo Bianconi
2024-09-11 21:12 ` Rob Herring (Arm)
2024-09-11 21:46 ` Lorenzo Bianconi
2024-09-12 16:43 ` Rob Herring
2024-09-11 19:50 ` [PATCH v4 2/5] dt-bindings: mfd: Add support for Airoha EN7581 GPIO System Controller Lorenzo Bianconi
2024-09-11 21:12 ` Rob Herring (Arm)
2024-09-11 21:48 ` Lorenzo Bianconi
2024-09-12 16:44 ` Rob Herring (Arm)
2024-09-11 19:50 ` [PATCH v4 3/5] mfd: airoha: Add support for Airoha EN7581 MFD Lorenzo Bianconi
2024-09-11 19:50 ` [PATCH v4 4/5] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
2024-09-24 7:34 ` Linus Walleij
2024-09-24 10:12 ` Lorenzo Bianconi
2024-09-24 21:22 ` Lorenzo Bianconi [this message]
2024-10-02 12:58 ` Linus Walleij
2024-10-02 15:36 ` Lorenzo Bianconi
2024-09-11 19:50 ` [PATCH v4 5/5] pwm: " Lorenzo Bianconi
2024-09-23 9:53 ` [PATCH v4 0/5] Add mfd, pinctrl and pwm support to " Christian Marangi
2024-09-25 9:47 ` Lee Jones
2024-09-25 9:51 ` Christian Marangi
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=ZvMtlJN1xAMHoW-E@lore-desk \
--to=lorenzo@kernel.org \
--cc=angelogioacchino.delregno@collabora.com \
--cc=ansuelsmth@gmail.com \
--cc=benjamin.larsson@genexis.eu \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-pwm@vger.kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=robh@kernel.org \
--cc=sean.wang@kernel.org \
--cc=ukleinek@kernel.org \
--cc=upstream@airoha.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 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.