* Re: [PATCH v3 5/8] irqchip/qcom-pdc: Configure PDC to pass through mode
From: Konrad Dybcio @ 2026-06-18 8:18 UTC (permalink / raw)
To: Maulik Shah, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Linus Walleij
Cc: linux-arm-msm, linux-kernel, devicetree, linux-gpio, Sneh Mankad
In-Reply-To: <20260616-hamoa_pdc_v3-v3-5-4d8e1504ea75@oss.qualcomm.com>
On 6/16/26 11:25 AM, Maulik Shah wrote:
> All PDC irqchip supports pass through mode in which both Direct SPIs and
> GPIO IRQs (as SPIs) are sent to GIC without latching at PDC.
>
> Newer PDCs (v3.0 onwards) also support additional secondary controller mode
> where PDC latches GPIO IRQs and sends to GIC as level type IRQ. Direct SPIs
> still works same as pass through mode without latching at PDC even in
> secondary controller mode.
>
> All the SoCs so far default uses pass through mode with the exception of
> x1e. x1e PDC may be set to secondary controller mode for builds on CRD
> boards whereas it may be set to pass through mode for IoT-EVK boards.
> The mode configuration is done in firmware and initially shipped windows
> firmware did not have SCM interface to read or modify the PDC mode.
> Later only write access is opened up for non secure world.
>
> Using the write access available add changes to modify the PDC mode to
> pass through mode via SCM write. When the write fails (on older firmware)
> assume to work in secondary mode.
>
> In secondary mode set the separate irqchip for the GPIOs to perform
> additional operations only for the GPIO irqs.
>
> Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
> ---
[...]
> +static int qcom_pdc_gic_secondary_set_type(struct irq_data *d, unsigned int type)
> +{
> + enum pdc_irq_config_bits pdc_type;
> + enum pdc_irq_config_bits old_pdc_type;
> + int ret;
> +
> + switch (type) {
> + case IRQ_TYPE_EDGE_RISING:
> + pdc_type = PDC_EDGE_RISING;
> + break;
> + case IRQ_TYPE_EDGE_FALLING:
> + pdc_type = PDC_EDGE_FALLING;
> + break;
> + case IRQ_TYPE_EDGE_BOTH:
> + pdc_type = PDC_EDGE_DUAL;
> + break;
> + case IRQ_TYPE_LEVEL_HIGH:
> + pdc_type = PDC_LEVEL_HIGH;
> + break;
> + case IRQ_TYPE_LEVEL_LOW:
> + pdc_type = PDC_LEVEL_LOW;
> + break;
> + default:
> + WARN_ON(1);
> + return -EINVAL;
> + }
> +
> + old_pdc_type = pdc_reg_read(pdc->regs->irq_cfg_reg, d->hwirq);
> + pdc_type |= (old_pdc_type & ~pdc->cfg_fields->irq_type);
> + pdc_reg_write(pdc->regs->irq_cfg_reg, d->hwirq, pdc_type);
> +
> + type = IRQ_TYPE_LEVEL_HIGH;
Please carry your comment from the previous revision:
/*
* PDC forwards GPIOs as level high to GIC in secondary
* mode. Update the type and clear any previously latched
* phantom interrupt at PDC.
*/
> + pdc->clear_gpio(d->hwirq);
> +
> + ret = irq_chip_set_type_parent(d, type);
> + if (ret)
> + return ret;
> +
> + /*
> + * When we change types the PDC can give a phantom interrupt.
> + * Clear it. Specifically the phantom shows up when reconfiguring
> + * polarity of interrupt without changing the state of the signal
> + * but let's be consistent and clear it always.
> + *
> + * Doing this works because we have IRQCHIP_SET_TYPE_MASKED so the
> + * interrupt will be cleared before the rest of the system sees it.
> + */
> + if (old_pdc_type != pdc_type)
> + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false);
This bit and the switch statement above are common between the two paths..
I'm debating whether we should factor them out as static inline void, but
neither solution is perfect.. so, up to you
[...]
> @@ -385,20 +547,37 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
> if (hwirq == GPIO_NO_WAKE_IRQ)
> return irq_domain_disconnect_hierarchy(domain, virq);
>
> - ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
> - &qcom_pdc_gic_chip, NULL);
> - if (ret)
> - return ret;
> + /*
> + * PDC secondary chip is only set for the GPIO interrupts as SPIs.
> + * Direct SPI interrupts are still in pass through mode (no latching
> + * at PDC).
> + */
> + if (pdc->mode == PDC_PASS_THROUGH_MODE || !pdc_pin_is_gpio(hwirq)) {
> + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
> + &qcom_pdc_gic_chip,
> + NULL);
> + if (ret)
> + return ret;
>
> - region = get_pin_region(hwirq);
> - if (!region)
> - return irq_domain_disconnect_hierarchy(domain->parent, virq);
> + if (type & IRQ_TYPE_EDGE_BOTH)
> + type = IRQ_TYPE_EDGE_RISING;
>
> - if (type & IRQ_TYPE_EDGE_BOTH)
> - type = IRQ_TYPE_EDGE_RISING;
> + if (type & IRQ_TYPE_LEVEL_MASK)
> + type = IRQ_TYPE_LEVEL_HIGH;
> + } else {
> + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
> + &qcom_pdc_gic_secondary_chip,
> + NULL);
> + if (ret)
> + return ret;
>
> - if (type & IRQ_TYPE_LEVEL_MASK)
> + /* Secondary mode converts all interrupts to LEVEL HIGH type */
> type = IRQ_TYPE_LEVEL_HIGH;
> + }
nit: (pdc->mode == PDC_SECONDARY_MODE && pdc_pin_is_gpio(hwirq))
could be the primary case to better communicate intent
Konrad
^ permalink raw reply
* Re: Question: SPEAr PLGPIO irq_enable on PREEMPT_RT and regmap updates
From: Sebastian Andrzej Siewior @ 2026-06-18 8:15 UTC (permalink / raw)
To: Runyu Xiao, Mark Brown
Cc: Viresh Kumar, Linus Walleij, Clark Williams, Steven Rostedt,
linux-arm-kernel, soc, linux-gpio, linux-rt-devel, linux-kernel,
jianhao.xu
In-Reply-To: <20260618023418.213453-1-runyu.xiao@seu.edu.cn>
On 2026-06-18 10:34:18 [+0800], Runyu Xiao wrote:
> Hi,
Hi,
…
> The repair I am considering is to keep the gpiolib resource updates in
> the fast irq_enable/irq_disable callbacks, but defer the actual PLGPIO
> IE/EIT register writes to irq_bus_sync_unlock(), after the IRQ core has
> dropped desc->lock. The driver would keep per-line shadow state for:
>
> - IRQ disabled/enabled state
> - pending IE update
> - edge direction state
> - pending EIT update
>
> and then synchronize those shadow updates from irq_bus_sync_unlock()
> under a mutex.
Not sure how this will look like, but okay. I was looking at making the
a lock a raw_spinlock_t for fast_io. Since it is just a read and write
it shouldn't be a problem. But then there is the regcache and the sync
of many registers might be painful. The actual problem is the type MAPLE
and RBTREE which have an allocation in their write callback. That is a
no but the FLAT ones should work since there is just one alloc during
init. Well, wouldn't it be for the lock that is acquired during the
callback.
I don't think this is required given that it is init time so
holding the lock shouldn't be required. This was introduced in commit
fd4ebc07b4dff ("regmap: Hold the regmap lock when allocating and freeing
the cache"). This change broke gpio-104-idio-16.c, pio-pci-idio-16.c,
pio-pcie-idio-24, gpio-ws16c48.c and pinctrl-apple-gpio.c.
So unless there is something that I miss…
> In other words, the fast callbacks would only update local shadow state
> and call gpiochip_enable_irq()/gpiochip_disable_irq(), while the sleepable
> regmap writes would be batched into the irq bus sync phase.
>
> Does that sound like an acceptable direction for SPEAr PLGPIO, or would
> you prefer a different fix, such as changing the underlying syscon regmap
> locking model or handling only the IE register path?
>
> The draft patch I have locally is roughly:
>
> pinctrl: spear: defer PLGPIO IRQ updates to bus sync
>
> and it changes only drivers/pinctrl/spear/pinctrl-plgpio.c.
>
> Thanks,
> Runyu
Sebastian
^ permalink raw reply
* Re: [PATCH 0/2] gpio: use raw spinlocks in irq startup paths
From: Bartosz Golaszewski @ 2026-06-18 8:02 UTC (permalink / raw)
To: Bartosz Golaszewski, Linus Walleij, Runyu Xiao
Cc: Bartosz Golaszewski, Orson Zhai, Baolin Wang, Chunyan Zhang,
Andy Shevchenko, Sebastian Andrzej Siewior, Clark Williams,
Steven Rostedt, Jan Kiszka, linux-gpio, linux-rt-devel,
linux-kernel, jianhao.xu
In-Reply-To: <20260617154035.1199948-1-runyu.xiao@seu.edu.cn>
On Wed, 17 Jun 2026 23:40:33 +0800, Runyu Xiao wrote:
> This 2-patch series fixes two GPIO irqchip paths where IRQ startup or
> unmask can update controller state under a regular spinlock. On
> PREEMPT_RT, that lock can sleep while irq_startup() is running in a
> non-sleepable context.
>
> Both issues were found by our static analysis tool and then manually
> reviewed against the current tree. The grounded PoCs kept the
> request_threaded_irq() -> __setup_irq() -> irq_startup() carriers and
> Lockdep reported "BUG: sleeping function called from invalid context" on
> the corresponding driver update helpers.
>
> [...]
Applied, thanks!
[1/2] gpio: sch: use raw_spinlock_t in the irq startup path
https://git.kernel.org/brgl/c/286533cb14a3c8a8bd39ff64ea2fc8e1aa0f638b
[2/2] gpio: eic-sprd: use raw_spinlock_t in the irq startup path
https://git.kernel.org/brgl/c/90f0109019e6817eb40a486671b7722d1544ae29
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v3 4/8] irqchip/qcom-pdc: Differentiate between direct SPI and GPIO as SPI
From: Konrad Dybcio @ 2026-06-18 8:02 UTC (permalink / raw)
To: Maulik Shah, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Linus Walleij
Cc: linux-arm-msm, linux-kernel, devicetree, linux-gpio, Sneh Mankad
In-Reply-To: <20260616-hamoa_pdc_v3-v3-4-4d8e1504ea75@oss.qualcomm.com>
On 6/16/26 11:25 AM, Maulik Shah wrote:
> Before commit 4dc70713dc24 ("irqchip/qcom-pdc: Kill non-wakeup irqdomain")
> there are separate domains for direct SPIs and GPIO used as SPIs. Separate
> domains can be useful in case irqchip want to differentiate both of them.
> Since commit unified both the domains there is no way to differentiate.
>
> In preparation to add the second level interrupt controller support where
> GPIO interrupts get latched at PDC (but not direct SPIs) there is a need to
> differentiate between SPIs and GPIOs as SPIs. Reverting above commit do not
> seem a good option either which leads to waste of resources.
>
> PDC HW have the IRQ_PARAM register telling number of direct SPIs and number
> of GPIOs as SPIs. Further PDC allocates direct SPIs at the beginning and
> all GPIOs as SPIs are allocated at the end. This information can be used in
> driver to differentiate them.
>
> Add the support to read this register and keep this information in
> struct pdc_desc. Later change utilizes same.
>
> Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
> ---
[...]
> + irq_param = pdc_reg_read(pdc->regs->irq_param_reg, 0);
> + pdc->num_spis = FIELD_GET(GENMASK(7, 0), irq_param);
> + pdc->num_gpios = FIELD_GET(GENMASK(15, 8), irq_param);
num_gpios is not used in this series, please either drop it or
use it to limit the index in the following patches
Konrad
^ permalink raw reply
* Re: Question: SPEAr PLGPIO irq_enable on PREEMPT_RT and regmap updates
From: Viresh Kumar @ 2026-06-18 7:40 UTC (permalink / raw)
To: Runyu Xiao, Herve Codina
Cc: Viresh Kumar, Linus Walleij, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, linux-arm-kernel, soc, linux-gpio,
linux-rt-devel, linux-kernel, jianhao.xu
In-Reply-To: <20260618023418.213453-1-runyu.xiao@seu.edu.cn>
+ Herve (the last guy to work on this driver).
On 18-06-26, 10:34, Runyu Xiao wrote:
> Hi,
>
> While auditing GPIO/pinctrl irqchip callbacks, our static analysis tool
> flagged the SPEAr PLGPIO irq_enable path, and we manually reviewed it
> against the current tree.
>
> The path is:
>
> irq_startup()
> -> plgpio_irq_enable()
> -> gpiochip_enable_irq()
> -> spin_lock_irqsave(&plgpio->lock)
> -> plgpio_reg_reset()
> -> regmap_update_bits()
>
> On PREEMPT_RT, plgpio->lock is a regular spinlock_t and can become a
> sleeping lock. Since irq_enable/irq_disable can be called from IRQ
> management paths while the IRQ descriptor raw lock is held, taking that
> regular spinlock there looks unsafe.
>
> A minimal Lockdep reproducer preserving this irq_chip::irq_enable carrier
> reports:
>
> BUG: sleeping function called from invalid context
> irqs_disabled(): 1
> plgpio_rt_spin_lock_irqsave
> plgpio_irq_enable
> request_threaded_irq_probe_path
>
> My first thought was to convert the PLGPIO register lock to
> raw_spinlock_t. However, that does not seem sufficient because the IE/EIT
> updates go through regmap_update_bits()/regmap_read()/regmap_write(). For
> the syscon/MMIO regmap used here, regmap may still take its own regular
> fast-IO lock unless the regmap was created with use_raw_spinlock. So a
> raw_spinlock_t conversion in the PLGPIO driver alone may just move the
> PREEMPT_RT problem one level down into regmap.
>
> The repair I am considering is to keep the gpiolib resource updates in
> the fast irq_enable/irq_disable callbacks, but defer the actual PLGPIO
> IE/EIT register writes to irq_bus_sync_unlock(), after the IRQ core has
> dropped desc->lock. The driver would keep per-line shadow state for:
>
> - IRQ disabled/enabled state
> - pending IE update
> - edge direction state
> - pending EIT update
>
> and then synchronize those shadow updates from irq_bus_sync_unlock()
> under a mutex.
>
> In other words, the fast callbacks would only update local shadow state
> and call gpiochip_enable_irq()/gpiochip_disable_irq(), while the sleepable
> regmap writes would be batched into the irq bus sync phase.
>
> Does that sound like an acceptable direction for SPEAr PLGPIO, or would
> you prefer a different fix, such as changing the underlying syscon regmap
> locking model or handling only the IE register path?
>
> The draft patch I have locally is roughly:
>
> pinctrl: spear: defer PLGPIO IRQ updates to bus sync
>
> and it changes only drivers/pinctrl/spear/pinctrl-plgpio.c.
I haven't worked on this for a very long time now (15 yrs). There are some
people who use this hardware, and so it is not removed until now.
Also I am not sure if RT kernel is a valid use case here for this SoC family.
--
viresh
^ permalink raw reply
* Re: [PATCH v9 2/2] i2c: designware: defer probe if child GpioInt controllers are not bound
From: Andy Shevchenko @ 2026-06-18 6:55 UTC (permalink / raw)
To: Hardik Prakash
Cc: linux-i2c, linux-gpio, wsa, mario.limonciello, brgl,
basavaraj.natikar, linusw, nathan, chaitanya.kumar.borah
In-Reply-To: <CANTFpSUSKwTj-z0E2w3C_8ue8wANE+dHtDKboZ1+rqwN98C3cA@mail.gmail.com>
On Thu, Jun 18, 2026 at 12:52:46AM +0530, Hardik Prakash wrote:
> On Wed, Jun 17, 2026 at 14:57, Andy Shevchenko wrote:
> > > + if (!agpio->resource_source.string_length ||
> > > + !agpio->resource_source.string_ptr)
> > > + return 1;
> >
> > I'm wondering if we simply can move to strncmp() instead of this check
> >
> > > + list_for_each_entry(ref, gpio_controllers, node) {
> > > + if (!strcmp(ref->path, agpio->resource_source.string_ptr))
> >
> > if (!strncmp(ref->path, agpio->resource_source.string_ptr))
>
> Could you clarify? strncmp() with n=string_length would protect the
> dedup check against a NULL or unterminated string_ptr, but we still
> need string_ptr to be non-NULL before passing it to kstrdup(). Should
> we keep a NULL/zero-length guard before kstrdup() and only replace the
> strcmp() in the dedup loop with strncmp()?
Ah, okay, you are talking about the first iteration when the list is empty and
we have to add it to the list.
So the question is, do we expect the resource_source not to be set at this point?
In other words is there any valid AML that interpreter decodes to the empty
resource_source? If so, can we ever have the following condition to be true?
string_length != 0 && string_ptr == NULL
P.S. Do not top-post! Reply under the piece in question. Also remove
the context you are not replying to.
> On Wed, 17 Jun 2026 at 14:57, Andy Shevchenko
> <andriy.shevchenko@intel.com> wrote:
> > On Wed, Jun 17, 2026 at 12:29:22PM +0530, Hardik Prakash wrote:
...
> > > +static int check_gpioint_resource(struct acpi_resource *ares, void *data)
> > > +{
> > > + struct list_head *gpio_controllers = data;
> > > + struct acpi_resource_gpio *agpio;
> > > + struct gpio_controller_ref *ref;
> > > +
> > > + if (!acpi_gpio_get_irq_resource(ares, &agpio))
> > > + return 1;
> >
> > > + if (!agpio->resource_source.string_length ||
> > > + !agpio->resource_source.string_ptr)
> > > + return 1;
> >
> > I'm wondering if we simply can move to strncmp() instead of this check
> >
> > > + /* Skip if we've already tracked this GPIO controller */
> > > + list_for_each_entry(ref, gpio_controllers, node) {
> > > + if (!strcmp(ref->path, agpio->resource_source.string_ptr))
> >
> > if (!strncmp(ref->path, agpio->resource_source.string_ptr))
> >
> >
> > > + return 1;
> > > + }
> > > +
> > > + ref = kzalloc(sizeof(*ref), GFP_KERNEL);
> > > + if (!ref)
> > > + return -ENOMEM;
> > > +
> > > + ref->path = kstrdup(agpio->resource_source.string_ptr, GFP_KERNEL);
> > > + if (!ref->path) {
> > > + kfree(ref);
> > > + return -ENOMEM;
> > > + }
> > > +
> > > + list_add_tail(&ref->node, gpio_controllers);
> > > + return 1;
> > > +}
You haven't replied to the rest, I assume you agree with all the suggestions?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: Question: GPIO direction callbacks calling pinctrl in atomic paths
From: Thierry Reding @ 2026-06-18 6:52 UTC (permalink / raw)
To: Runyu Xiao
Cc: Linus Walleij, Bartosz Golaszewski, Robert Jarzmik,
Thierry Reding, Jonathan Hunter, linux-gpio, linux-tegra,
linux-kernel, jianhao.xu
In-Reply-To: <20260618030609.958831-1-runyu.xiao@seu.edu.cn>
[-- Attachment #1: Type: text/plain, Size: 2837 bytes --]
On Thu, Jun 18, 2026 at 11:06:09AM +0800, Runyu Xiao wrote:
> Hi,
>
> While auditing GPIO direction callbacks, our static analysis tool flagged
> several drivers whose direction_input/direction_output paths call into
> the pinctrl core even though the GPIO chip is registered as non-sleeping.
> We then manually reviewed the findings against the current tree.
>
> The class of path we looked at is:
>
> gpiod_direction_output_raw_commit()
> -> <driver>_gpio_direction_output()
> -> pinctrl_gpio_direction_output()
> -> pinctrl_get_device_gpio_range()
> -> mutex_lock(&pctldev->mutex)
>
> That can be reached from shared GPIO users while a per-line spinlock is
> still held. A minimal Lockdep reproducer preserving this direction path
> reports:
>
> BUG: sleeping function called from invalid context
> #0: ... (&global_shared_desc.spinlock) ...
> pinctrl_get_device_gpio_range
> <driver>_gpio_direction_output
> [ BUG: Invalid wait context ]
>
> My first draft for this class was to mark the affected gpio_chip as
> can_sleep, but that looks like the wrong contract. gpio_chip::can_sleep
> describes whether get()/set() may sleep, while the problematic operation
> here is not MMIO value access but an extra pinctrl direction round-trip.
> Rockchip history seems to support that concern: after the controller was
> marked sleeping, a follow-up change stopped calling pinctrl for
> set_direction because whole-chip can_sleep caused atomic get/set
> warnings.
>
> For PXA and Tegra, I am considering a small series that removes the
> pinctrl_gpio_direction_input/output() calls from the GPIO direction
> callbacks and leaves direction programming on the drivers' existing MMIO
> paths.
>
> For PXA, the driver already updates GPDR directly in
> pxa_gpio_direction_input/output(). The proposed change would drop the
> additional pinctrl direction call on variants where pxa_gpio_has_pinctrl()
> currently returns true.
>
> For Tegra, the GPIO driver already programs the GPIO controller direction
> registers directly. The Tegra pinmux ops appear to provide GPIO
> request/free handling, but no gpio_set_direction hook, so the
> pinctrl_gpio_direction_input/output() call seems to enter the pinctrl core
> without adding a Tegra-specific direction operation. The proposed change
> would keep pinctrl involvement in request/free but not in GPIO direction.
I looked into this, and yes, we don't provide gpio_set_direction
callbacks for the Tegra pinctrl driver, so what you're proposing looks
fine.
However, I'm on the fence about this because I think conceptually it is
correct to call into the pinctrl subsystem to set the direction. The
GPIO driver should be oblivious to the fact that it isn't strictly
necessary.
Thierry
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] gpio: sch: use raw_spinlock_t in the irq startup path
From: Andy Shevchenko @ 2026-06-18 6:41 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Runyu Xiao, Linus Walleij, Bartosz Golaszewski, Orson Zhai,
Baolin Wang, Chunyan Zhang, Andy Shevchenko, Clark Williams,
Steven Rostedt, Jan Kiszka, linux-gpio, linux-rt-devel,
linux-kernel, jianhao.xu, stable
In-Reply-To: <ajOS2UR9pw_pUBxr@ashevche-desk.local>
On Thu, Jun 18, 2026 at 09:40:31AM +0300, Andy Shevchenko wrote:
> On Thu, Jun 18, 2026 at 08:28:39AM +0200, Sebastian Andrzej Siewior wrote:
> > On 2026-06-17 23:40:34 [+0800], Runyu Xiao wrote:
> > > sch_irq_unmask() enables the GPIO IRQ and then updates the controller
> > > state through sch_irq_mask_unmask(), which takes sch->lock with
> > > spin_lock_irqsave(). The callback can be reached from irq_startup()
> > > while setting up a requested IRQ. That path is not sleepable, but on
> > > PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
…
> > > Fixes: 7a81638485c1 ("gpio: sch: Add edge event support")
> > > Cc: stable@vger.kernel.org
> > > Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
> >
> > Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>
> There is already a v2.
Or not... I might have been confused with other patch that got two versions
in a row.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 1/2] gpio: sch: use raw_spinlock_t in the irq startup path
From: Andy Shevchenko @ 2026-06-18 6:40 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Runyu Xiao, Linus Walleij, Bartosz Golaszewski, Orson Zhai,
Baolin Wang, Chunyan Zhang, Andy Shevchenko, Clark Williams,
Steven Rostedt, Jan Kiszka, linux-gpio, linux-rt-devel,
linux-kernel, jianhao.xu, stable
In-Reply-To: <20260618062839.4o1ewdEn@linutronix.de>
On Thu, Jun 18, 2026 at 08:28:39AM +0200, Sebastian Andrzej Siewior wrote:
> On 2026-06-17 23:40:34 [+0800], Runyu Xiao wrote:
> > sch_irq_unmask() enables the GPIO IRQ and then updates the controller
> > state through sch_irq_mask_unmask(), which takes sch->lock with
> > spin_lock_irqsave(). The callback can be reached from irq_startup()
> > while setting up a requested IRQ. That path is not sleepable, but on
> > PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
> …
> > Fixes: 7a81638485c1 ("gpio: sch: Add edge event support")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
There is already a v2.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 1/4] soc: qcom: rpmh: Allow non-child devices to issue write commands
From: Fenglin Wu @ 2026-06-18 6:39 UTC (permalink / raw)
To: Dmitry Baryshkov, Konrad Dybcio
Cc: linux-arm-msm, Bjorn Andersson, Konrad Dybcio, Linus Walleij,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bartosz Golaszewski, David Collins, Subbaraman Narayanamurthy,
Kamal Wadhwa, Maulik Shah, kernel, linux-kernel, linux-gpio,
devicetree
In-Reply-To: <ao2bl4vzgb3mvqnk2kgvgqnifujbvy6oyzuj4rnvjrv6teyrel@56txzbrtwm64>
On 6/12/2026 8:27 AM, Dmitry Baryshkov wrote:
> On Thu, Jun 11, 2026 at 12:36:43PM +0200, Konrad Dybcio wrote:
>> On 6/9/26 3:28 AM, Fenglin Wu wrote:
>>> On 6/8/2026 5:21 AM, Dmitry Baryshkov wrote:
>>>> On Thu, Jun 04, 2026 at 10:02:43AM +0800, Fenglin Wu wrote:
>>>>> On 6/2/2026 3:29 PM, Fenglin Wu wrote:
>>>>>> On 6/1/2026 9:37 PM, Dmitry Baryshkov wrote:
>>>>>>> On Thu, May 28, 2026 at 06:05:35PM -0700, Fenglin Wu wrote:
>>>>>>>> Currently, the RPMH driver only allows child devices of the RPMH
>>>>>>>> controller to issue commands, as it assumes dev->parent points to the
>>>>>>>> RSC device.
>>>>>>>>
>>>>>>>> There is a possibility that certain devices which are not children of
>>>>>>>> the RPMH controller want to send commands for special control at the
>>>>>>>> RPMH side. For example, in PMH0101 PMICs, there are bidirectional
>>>>>>>> level shifter (LS) peripherals, and each LS works with a pair of PMIC
>>>>>>>> GPIOs. The control of the LS, which is combined with the GPIO
>>>>>>>> configuration, is handled by RPMH firmware for sharing the resource
>>>>>>>> between different subsystems. From a hardware point of view, the LS
>>>>>>>> functionality is tied to a pair of PMIC GPIOs, so its control is more
>>>>>>>> suitable to be added in the pinctrl-spmi-gpio driver by adding the
>>>>>>>> level-shifter function. However, the pinctrl-spmi-gpio device is a
>>>>>>>> child device of the SPMI controller, not the RPMH controller.
>>>>>>> This replicates the story of the PMIC regulators. There are two drivers,
>>>>>>> one SPMI and one RPMh. Why don't we add a separate, RPMh-based GPIO
>>>>>>> driver targeting only those paired GPIOs (and we don't even need to
>>>>>>> represent them as a pair, it might be just one pin).
>>>>>> Thanks for the suggestion.
>>>>>>
>>>>>> I agree that adding a separate, RPMh-based GPIO driver would be more
>>>>>> straightforward from RPMh control perspective. It makes the new device
>>>>>> as a child of the RSC device then it can naturally use the APIs for RPMh
>>>>>> commands. The main challenge here is, we need to make the level-shifter
>>>>>> mutually exclusive with other GPIO functions when the GPIO pairs are
>>>>>> used in level-shifter function, which means we need to write SPMI
>>>>>> commands to disable the associated GPIO modules. I am not sure if AOP
>>>>>> already handles this; as far as I know, AOP only manages the
>>>>>> BIDIR_LVL_SHIFTER module registers. Let me double check on this
>>>>>> internally, if the GPIO modules could be controlled along
>>>>>> with BIDIR_LVL_SHIFTER module registers at AOP side, and get back.
>>>>>>
>>>>> I checked on this internally, AOP only handles BIDIR_LVL_SHIFTER module
>>>>> registers, it doesn't disable the associated GPIO modules. Also, I still
>>>>> have no idea how could we make the "level-shifter" function to be mutually
>>>>> exclusive with other GPIO functions after moved it into a separate driver.
>>>>> Do you have further suggestions?
>>>> So, for my understanding, we still need to write SPMI registers to
>>>> configure the pins and only then AOP can handle the level shifter?
>>>>
>>>> I was thinking of using gpio-reserved-ranges to prevent those GPIOs from
>>>> being used by the normal SPMI driver.
>>> More background: "level-shifter" module is actually an independent hardware which is not part of the GPIO module. However, they are sharing the physical pins. Which means, from PMIC chip perspective, these pins can be configured to either a GPIO function or the "level-shifter" function. So in PMIC base dtsi file, for example, pmh0101.dtsi, these pins should not be restricted in the GPIO nodes in "gpio-reserved-ranges".
>>>
>>> Also, we need to make the GPIO modules are disabled when the "level-shifter" is enabled, to ensure that the "level-shifter" circuitry is not impacted by the GPIO modules internal circuitry. So it is supposed to write GPIO EN_CTL register (offset 0x46) to 0 through SPMI bus when the "level-shifter" is enabled.
>>>
>>> That's why we have the requirement to access both RPMh and SPMI bus in the same driver.
>> I was thinking about other ways to solve it.. maybe someting like:
>>
>> &pmh0101_gpios {
>> pmh0101_ls_pins1_2: foo-bar {
>> pins = "gpio1", "gpio2";
>> // appropriate pinctrl config
>> };
>> };
>>
>> &rpmh_rsc {
>> // should this be a gpio controller? a mux provider?
>> // is there another class that would better suit this?
>> rpmh_level_shifter: rpmh-foo-bar {
>> pinctrl-0 = <&>;
>> pinctrl-names = "default";
>> };
>> };
>>
>> // but where would it make sense to describe?
>> // fixed-regulator or something akin to that?
>> &some_consumer {
>> someclass = <&rpmh_level_shifter 1>;
>> };
>>
>> i.e. the "rpmh level shifter" driver would consume a reference to the
>> pins, configure them as necessary (just like any other pinctrl consumer)
>> upon request
> SGTM.
Thanks for the suggestion, Konrad and Dmitry!
Using the pinctrl state in the new driver to disable GPIO pairs is a
good idea. I’ve been considering which class would best support the PMIC
level-shifter, especially since we’re moving it to a new driver and it’s
no longer restricted by the pinctrl framework. Functionally, the driver
should provide following capabilities:
1. Enable and disable the level-shifter at runtime. Consumers, likely
I2C client devices, will enable it when active and disable it when not,
mainly to save power.
2. Allow sharing the level-shifter between multiple consumers, even
across different subsystems (currently managed by AOP).
I see flaws in each of the following approaches and haven’t decided
which to use:
A. Using the mux subsystem: The level-shifter acts as a switch, so it
fits the mux subsystem physically. It can be enabled/disabled via
‘mux_control_select()’ and ‘mux_control_deselect()’. However, with
multiple consumers, a second call to ‘mux_control_select()’ is blocked
until ‘mux_control_deselect()’ is called, so votes from multiple
consumers are not allowed and can’t be aggregated.
B. Using the GPIO/pinctrl subsystem: After moving to a new driver, the
level-shifter doesn’t fit the GPIO controller or pinctrl device concept.
It has only one pinmux, and each level-shifter works with two pins.
Also, both GPIO and pinctrl frameworks require exclusive control, and
couldn't shared between consumers.
C. Using the regulator framework: The level-shifter is controlled via
the RPMh XOB resource at the AOP side, which was adopted from the idea
of power rails sharing between subsystems. The regulator framework’s
APIs and reference counting fit the requirements for sharing between
multiple consumers. The problem is, the level-shifter isn’t a power rail
so it is conceptually not a regulator.
Please let me know your thoughts. If there isn’t a suitable approach for
supporting the PMIC level-shifter right now, I’ll stop chasing on this
until there is a better idea.
Thanks
>> Konrad
^ permalink raw reply
* Re: [PATCH 2/2] gpio: eic-sprd: use raw_spinlock_t in the irq startup path
From: Sebastian Andrzej Siewior @ 2026-06-18 6:32 UTC (permalink / raw)
To: Runyu Xiao
Cc: Linus Walleij, Bartosz Golaszewski, Orson Zhai, Baolin Wang,
Chunyan Zhang, Andy Shevchenko, Clark Williams, Steven Rostedt,
Jan Kiszka, linux-gpio, linux-rt-devel, linux-kernel, jianhao.xu,
stable
In-Reply-To: <20260617154035.1199948-3-runyu.xiao@seu.edu.cn>
On 2026-06-17 23:40:35 [+0800], Runyu Xiao wrote:
> sprd_eic_irq_unmask() enables the GPIO IRQ and then updates controller
> state through sprd_eic_update(), which takes sprd_eic->lock with
> spin_lock_irqsave(). The callback can be reached from irq_startup()
> while setting up a requested IRQ. That path is not sleepable, but on
> PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
…
> Fixes: 25518e024e3a ("gpio: Add Spreadtrum EIC driver support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Sebastian
^ permalink raw reply
* Re: [PATCH 1/2] gpio: sch: use raw_spinlock_t in the irq startup path
From: Sebastian Andrzej Siewior @ 2026-06-18 6:28 UTC (permalink / raw)
To: Runyu Xiao
Cc: Linus Walleij, Bartosz Golaszewski, Orson Zhai, Baolin Wang,
Chunyan Zhang, Andy Shevchenko, Clark Williams, Steven Rostedt,
Jan Kiszka, linux-gpio, linux-rt-devel, linux-kernel, jianhao.xu,
stable
In-Reply-To: <20260617154035.1199948-2-runyu.xiao@seu.edu.cn>
On 2026-06-17 23:40:34 [+0800], Runyu Xiao wrote:
> sch_irq_unmask() enables the GPIO IRQ and then updates the controller
> state through sch_irq_mask_unmask(), which takes sch->lock with
> spin_lock_irqsave(). The callback can be reached from irq_startup()
> while setting up a requested IRQ. That path is not sleepable, but on
> PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
…
> Fixes: 7a81638485c1 ("gpio: sch: Add edge event support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Sebastian
^ permalink raw reply
* Question: pinctrl-backed GPIO set_config and gpio_chip::can_sleep
From: Runyu Xiao @ 2026-06-18 5:36 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski
Cc: Ludovic Desroches, Nicolas Ferre, Alexandre Belloni,
Claudiu Beznea, Antonio Borneo, Maxime Coquelin, Alexandre Torgue,
Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, linux-arm-kernel,
linux-gpio, linux-stm32, linux-sunxi, linux-kernel, jianhao.xu,
runyu.xiao
Hi,
While auditing pinctrl-backed GPIO chips, our static analysis tool
flagged several controllers that expose gpiochip_generic_config() while
still advertising a non-sleeping gpio_chip. We then manually reviewed
the findings against the current tree.
The path we are concerned about is:
gpiod_set_config()
-> gpio_do_set_config()
-> gpiochip_generic_config()
-> pinctrl_gpio_set_config()
-> pinctrl_get_device_gpio_range()
-> mutex_lock(&pctldev->mutex)
If gpiod_cansleep() returns false, a GPIO forwarder or another consumer
can choose an atomic carrier and call gpiod_set_config() while holding a
spinlock. A minimal Lockdep reproducer preserving this carrier reports:
BUG: sleeping function called from invalid context
#0: ... (&global_shared_desc.spinlock) ...
pinctrl_get_device_gpio_range
gpiochip_generic_config
[ BUG: Invalid wait context ]
This looks similar to the Meson fix that marked the GPIO controller as
sleeping when GPIO configuration is routed through the pinctrl-backed
generic config path.
The local draft I am considering marks only these controllers as
sleeping:
pinctrl: at91-pio4: mark the GPIO controller as sleeping
pinctrl: stm32: mark the GPIO controller as sleeping
pinctrl: sunxi: mark the GPIO controller as sleeping
The reason is that all three expose gpiochip_generic_config() and can
therefore reach the pinctrl mutex from the GPIO set_config path, while
their current gpio_chip registration does not set can_sleep.
Two other candidates from the same audit, bcm2835 and keembay, are not
part of this draft. They use gpio_irq_chip::parent_handler, and gpiolib
rejects chained interrupts on a GPIO chip that may sleep. Setting
can_sleep there would therefore break registration instead of fixing the
contract; those cases need a separate irqchip design review.
Does setting gpio_chip::can_sleep for the at91-pio4, stm32 and sunxi
pinctrl-backed GPIO chips sound like the right fix for this set_config
contract mismatch? Or would you prefer this to be handled elsewhere in
gpiolib/pinctrl so that set_config sleepability can be represented more
narrowly than the whole gpio_chip?
Thanks,
Runyu
^ permalink raw reply
* Question: GPIO direction callbacks calling pinctrl in atomic paths
From: Runyu Xiao @ 2026-06-18 3:06 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski
Cc: Robert Jarzmik, Thierry Reding, Jonathan Hunter, linux-gpio,
linux-tegra, linux-kernel, jianhao.xu, runyu.xiao
Hi,
While auditing GPIO direction callbacks, our static analysis tool flagged
several drivers whose direction_input/direction_output paths call into
the pinctrl core even though the GPIO chip is registered as non-sleeping.
We then manually reviewed the findings against the current tree.
The class of path we looked at is:
gpiod_direction_output_raw_commit()
-> <driver>_gpio_direction_output()
-> pinctrl_gpio_direction_output()
-> pinctrl_get_device_gpio_range()
-> mutex_lock(&pctldev->mutex)
That can be reached from shared GPIO users while a per-line spinlock is
still held. A minimal Lockdep reproducer preserving this direction path
reports:
BUG: sleeping function called from invalid context
#0: ... (&global_shared_desc.spinlock) ...
pinctrl_get_device_gpio_range
<driver>_gpio_direction_output
[ BUG: Invalid wait context ]
My first draft for this class was to mark the affected gpio_chip as
can_sleep, but that looks like the wrong contract. gpio_chip::can_sleep
describes whether get()/set() may sleep, while the problematic operation
here is not MMIO value access but an extra pinctrl direction round-trip.
Rockchip history seems to support that concern: after the controller was
marked sleeping, a follow-up change stopped calling pinctrl for
set_direction because whole-chip can_sleep caused atomic get/set
warnings.
For PXA and Tegra, I am considering a small series that removes the
pinctrl_gpio_direction_input/output() calls from the GPIO direction
callbacks and leaves direction programming on the drivers' existing MMIO
paths.
For PXA, the driver already updates GPDR directly in
pxa_gpio_direction_input/output(). The proposed change would drop the
additional pinctrl direction call on variants where pxa_gpio_has_pinctrl()
currently returns true.
For Tegra, the GPIO driver already programs the GPIO controller direction
registers directly. The Tegra pinmux ops appear to provide GPIO
request/free handling, but no gpio_set_direction hook, so the
pinctrl_gpio_direction_input/output() call seems to enter the pinctrl core
without adding a Tegra-specific direction operation. The proposed change
would keep pinctrl involvement in request/free but not in GPIO direction.
I am not proposing the same change for MVEBU in this question. Its
pinctrl direction hook appears to enforce GPI/GPO capability checks, so
simply removing the pinctrl direction call there would remove real
driver-specific validation and needs a different design.
Does removing the pinctrl direction calls for PXA and Tegra sound like
the right direction, or would you prefer that this be handled differently
in gpiolib/pinctrl?
The local draft subjects are:
gpio: pxa: stop routing direction changes through pinctrl
gpio: tegra: do not call pinctrl for GPIO direction
Thanks,
Runyu
^ permalink raw reply
* Question: SPEAr PLGPIO irq_enable on PREEMPT_RT and regmap updates
From: Runyu Xiao @ 2026-06-18 2:34 UTC (permalink / raw)
To: Viresh Kumar, Linus Walleij
Cc: Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
linux-arm-kernel, soc, linux-gpio, linux-rt-devel, linux-kernel,
jianhao.xu, runyu.xiao
Hi,
While auditing GPIO/pinctrl irqchip callbacks, our static analysis tool
flagged the SPEAr PLGPIO irq_enable path, and we manually reviewed it
against the current tree.
The path is:
irq_startup()
-> plgpio_irq_enable()
-> gpiochip_enable_irq()
-> spin_lock_irqsave(&plgpio->lock)
-> plgpio_reg_reset()
-> regmap_update_bits()
On PREEMPT_RT, plgpio->lock is a regular spinlock_t and can become a
sleeping lock. Since irq_enable/irq_disable can be called from IRQ
management paths while the IRQ descriptor raw lock is held, taking that
regular spinlock there looks unsafe.
A minimal Lockdep reproducer preserving this irq_chip::irq_enable carrier
reports:
BUG: sleeping function called from invalid context
irqs_disabled(): 1
plgpio_rt_spin_lock_irqsave
plgpio_irq_enable
request_threaded_irq_probe_path
My first thought was to convert the PLGPIO register lock to
raw_spinlock_t. However, that does not seem sufficient because the IE/EIT
updates go through regmap_update_bits()/regmap_read()/regmap_write(). For
the syscon/MMIO regmap used here, regmap may still take its own regular
fast-IO lock unless the regmap was created with use_raw_spinlock. So a
raw_spinlock_t conversion in the PLGPIO driver alone may just move the
PREEMPT_RT problem one level down into regmap.
The repair I am considering is to keep the gpiolib resource updates in
the fast irq_enable/irq_disable callbacks, but defer the actual PLGPIO
IE/EIT register writes to irq_bus_sync_unlock(), after the IRQ core has
dropped desc->lock. The driver would keep per-line shadow state for:
- IRQ disabled/enabled state
- pending IE update
- edge direction state
- pending EIT update
and then synchronize those shadow updates from irq_bus_sync_unlock()
under a mutex.
In other words, the fast callbacks would only update local shadow state
and call gpiochip_enable_irq()/gpiochip_disable_irq(), while the sleepable
regmap writes would be batched into the irq bus sync phase.
Does that sound like an acceptable direction for SPEAr PLGPIO, or would
you prefer a different fix, such as changing the underlying syscon regmap
locking model or handling only the IE register path?
The draft patch I have locally is roughly:
pinctrl: spear: defer PLGPIO IRQ updates to bus sync
and it changes only drivers/pinctrl/spear/pinctrl-plgpio.c.
Thanks,
Runyu
^ permalink raw reply
* [brgl:gpio/for-current] BUILD SUCCESS ae9f812df3149729643d27d2af488c112f62af9a
From: kernel test robot @ 2026-06-18 0:20 UTC (permalink / raw)
To: Bartosz Golaszewski; +Cc: linux-gpio
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git gpio/for-current
branch HEAD: ae9f812df3149729643d27d2af488c112f62af9a gpiolib: acpi: Prevent out-of-bounds pin access in OperationRegion handler
elapsed time: 822m
configs tested: 270
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc defconfig gcc-16.1.0
arc randconfig-001 gcc-16.1.0
arc randconfig-001-20260617 gcc-16.1.0
arc randconfig-001-20260618 gcc-15.2.0
arc randconfig-002 gcc-16.1.0
arc randconfig-002-20260617 gcc-16.1.0
arc randconfig-002-20260618 gcc-15.2.0
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001 gcc-16.1.0
arm randconfig-001-20260617 gcc-16.1.0
arm randconfig-001-20260618 gcc-15.2.0
arm randconfig-002 gcc-16.1.0
arm randconfig-002-20260617 gcc-16.1.0
arm randconfig-002-20260618 gcc-15.2.0
arm randconfig-003 gcc-16.1.0
arm randconfig-003-20260617 gcc-16.1.0
arm randconfig-003-20260618 gcc-15.2.0
arm randconfig-004 gcc-16.1.0
arm randconfig-004-20260617 gcc-16.1.0
arm randconfig-004-20260618 gcc-15.2.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260617 gcc-12.5.0
arm64 randconfig-001-20260618 gcc-15.2.0
arm64 randconfig-002-20260617 gcc-12.5.0
arm64 randconfig-002-20260618 gcc-15.2.0
arm64 randconfig-003-20260617 gcc-12.5.0
arm64 randconfig-003-20260618 gcc-15.2.0
arm64 randconfig-004-20260617 gcc-12.5.0
arm64 randconfig-004-20260618 gcc-15.2.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260617 gcc-12.5.0
csky randconfig-001-20260618 gcc-15.2.0
csky randconfig-002-20260617 gcc-12.5.0
csky randconfig-002-20260618 gcc-15.2.0
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001-20260617 clang-17
hexagon randconfig-001-20260618 clang-23
hexagon randconfig-002-20260617 clang-17
hexagon randconfig-002-20260618 clang-23
i386 allmodconfig clang-22
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260617 gcc-14
i386 buildonly-randconfig-001-20260618 gcc-14
i386 buildonly-randconfig-002-20260617 gcc-14
i386 buildonly-randconfig-002-20260618 gcc-14
i386 buildonly-randconfig-003-20260617 gcc-14
i386 buildonly-randconfig-003-20260618 gcc-14
i386 buildonly-randconfig-004-20260617 gcc-14
i386 buildonly-randconfig-004-20260618 gcc-14
i386 buildonly-randconfig-005-20260617 gcc-14
i386 buildonly-randconfig-005-20260618 gcc-14
i386 buildonly-randconfig-006-20260617 gcc-14
i386 buildonly-randconfig-006-20260618 gcc-14
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260617 gcc-13
i386 randconfig-001-20260618 clang-22
i386 randconfig-002-20260617 gcc-13
i386 randconfig-002-20260618 clang-22
i386 randconfig-003-20260617 gcc-13
i386 randconfig-003-20260618 clang-22
i386 randconfig-004-20260617 gcc-13
i386 randconfig-004-20260618 clang-22
i386 randconfig-005-20260617 gcc-13
i386 randconfig-005-20260618 clang-22
i386 randconfig-006-20260617 gcc-13
i386 randconfig-006-20260618 clang-22
i386 randconfig-007-20260617 gcc-13
i386 randconfig-007-20260618 clang-22
i386 randconfig-011-20260617 clang-22
i386 randconfig-011-20260618 clang-22
i386 randconfig-012-20260617 clang-22
i386 randconfig-012-20260618 clang-22
i386 randconfig-013-20260617 clang-22
i386 randconfig-013-20260618 clang-22
i386 randconfig-014-20260617 clang-22
i386 randconfig-014-20260618 clang-22
i386 randconfig-015-20260617 clang-22
i386 randconfig-015-20260618 clang-22
i386 randconfig-016-20260617 clang-22
i386 randconfig-016-20260618 clang-22
i386 randconfig-017-20260617 clang-22
i386 randconfig-017-20260618 clang-22
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001-20260617 clang-17
loongarch randconfig-001-20260618 clang-23
loongarch randconfig-002-20260617 clang-17
loongarch randconfig-002-20260618 clang-23
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k defconfig clang-23
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allnoconfig clang-23
nios2 defconfig clang-23
nios2 randconfig-001-20260617 clang-17
nios2 randconfig-001-20260618 clang-23
nios2 randconfig-002-20260617 clang-17
nios2 randconfig-002-20260618 clang-23
openrisc allmodconfig clang-20
openrisc allnoconfig clang-23
openrisc de0_nano_multicore_defconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allyesconfig clang-17
parisc defconfig gcc-16.1.0
parisc randconfig-001-20260617 gcc-15.2.0
parisc randconfig-001-20260618 gcc-16.1.0
parisc randconfig-002-20260617 gcc-15.2.0
parisc randconfig-002-20260618 gcc-16.1.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc g5_defconfig gcc-16.1.0
powerpc randconfig-001-20260617 gcc-15.2.0
powerpc randconfig-001-20260618 gcc-16.1.0
powerpc randconfig-002-20260617 gcc-15.2.0
powerpc randconfig-002-20260618 gcc-16.1.0
powerpc64 randconfig-001-20260617 gcc-15.2.0
powerpc64 randconfig-001-20260618 gcc-16.1.0
powerpc64 randconfig-002-20260617 gcc-15.2.0
powerpc64 randconfig-002-20260618 gcc-16.1.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001 gcc-16.1.0
riscv randconfig-001-20260617 gcc-16.1.0
riscv randconfig-001-20260618 gcc-13.4.0
riscv randconfig-002 gcc-16.1.0
riscv randconfig-002-20260617 gcc-16.1.0
riscv randconfig-002-20260618 gcc-13.4.0
s390 allmodconfig clang-17
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001 gcc-16.1.0
s390 randconfig-001-20260617 gcc-16.1.0
s390 randconfig-001-20260618 gcc-13.4.0
s390 randconfig-002 gcc-16.1.0
s390 randconfig-002-20260617 gcc-16.1.0
s390 randconfig-002-20260618 gcc-13.4.0
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allyesconfig clang-17
sh ap325rxa_defconfig gcc-16.1.0
sh defconfig gcc-14
sh randconfig-001 gcc-16.1.0
sh randconfig-001-20260617 gcc-16.1.0
sh randconfig-001-20260618 gcc-13.4.0
sh randconfig-002 gcc-16.1.0
sh randconfig-002-20260617 gcc-16.1.0
sh randconfig-002-20260618 gcc-13.4.0
sparc allnoconfig clang-23
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260617 gcc-16.1.0
sparc randconfig-001-20260618 gcc-14.3.0
sparc randconfig-002-20260617 gcc-16.1.0
sparc randconfig-002-20260618 gcc-14.3.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260617 gcc-16.1.0
sparc64 randconfig-001-20260618 gcc-14.3.0
sparc64 randconfig-002-20260617 gcc-16.1.0
sparc64 randconfig-002-20260618 gcc-14.3.0
um allmodconfig clang-17
um allnoconfig clang-23
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260617 gcc-16.1.0
um randconfig-001-20260618 gcc-14.3.0
um randconfig-002-20260617 gcc-16.1.0
um randconfig-002-20260618 gcc-14.3.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001 clang-22
x86_64 buildonly-randconfig-001-20260617 clang-22
x86_64 buildonly-randconfig-002 clang-22
x86_64 buildonly-randconfig-002-20260617 clang-22
x86_64 buildonly-randconfig-003 clang-22
x86_64 buildonly-randconfig-003-20260617 clang-22
x86_64 buildonly-randconfig-004 clang-22
x86_64 buildonly-randconfig-004-20260617 clang-22
x86_64 buildonly-randconfig-005 clang-22
x86_64 buildonly-randconfig-005-20260617 clang-22
x86_64 buildonly-randconfig-006 clang-22
x86_64 buildonly-randconfig-006-20260617 clang-22
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001 clang-22
x86_64 randconfig-001-20260617 clang-22
x86_64 randconfig-001-20260618 clang-22
x86_64 randconfig-002 clang-22
x86_64 randconfig-002-20260617 clang-22
x86_64 randconfig-002-20260618 clang-22
x86_64 randconfig-003 clang-22
x86_64 randconfig-003-20260617 clang-22
x86_64 randconfig-003-20260618 clang-22
x86_64 randconfig-004 clang-22
x86_64 randconfig-004-20260617 clang-22
x86_64 randconfig-004-20260618 clang-22
x86_64 randconfig-005 clang-22
x86_64 randconfig-005-20260617 clang-22
x86_64 randconfig-005-20260618 clang-22
x86_64 randconfig-006 clang-22
x86_64 randconfig-006-20260617 clang-22
x86_64 randconfig-006-20260618 clang-22
x86_64 randconfig-011-20260617 clang-22
x86_64 randconfig-012-20260617 clang-22
x86_64 randconfig-013-20260617 clang-22
x86_64 randconfig-014-20260617 clang-22
x86_64 randconfig-015-20260617 clang-22
x86_64 randconfig-016-20260617 clang-22
x86_64 randconfig-071 gcc-13
x86_64 randconfig-071-20260617 gcc-13
x86_64 randconfig-071-20260618 clang-22
x86_64 randconfig-072 gcc-13
x86_64 randconfig-072-20260617 gcc-13
x86_64 randconfig-072-20260618 clang-22
x86_64 randconfig-073 gcc-13
x86_64 randconfig-073-20260617 gcc-13
x86_64 randconfig-073-20260618 clang-22
x86_64 randconfig-074 gcc-13
x86_64 randconfig-074-20260617 gcc-13
x86_64 randconfig-074-20260618 clang-22
x86_64 randconfig-075 gcc-13
x86_64 randconfig-075-20260617 gcc-13
x86_64 randconfig-075-20260618 clang-22
x86_64 randconfig-076 gcc-13
x86_64 randconfig-076-20260617 gcc-13
x86_64 randconfig-076-20260618 clang-22
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allyesconfig clang-20
xtensa randconfig-001-20260617 gcc-16.1.0
xtensa randconfig-001-20260618 gcc-14.3.0
xtensa randconfig-002-20260617 gcc-16.1.0
xtensa randconfig-002-20260618 gcc-14.3.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Marco Scardovi @ 2026-06-17 23:14 UTC (permalink / raw)
To: w_armin
Cc: andriy.shevchenko, bnatikar, brgl, linusw, linux-acpi, linux-gpio,
linux-kernel, mario.limonciello, scardracs, westeri
In-Reply-To: <0e6ea9d5-68ac-4d18-b40a-25e70216b288@gmx.de>
Hi Armin,
On Wed, Jun 17, 2026 at 10:33 PM, Armin Wolf wrote:
>
> could you share the output of "acpidump" on your device? I suspect that Asus
> uses a _DSM control method to tell Windows to invert the polarity inside the
> ActiveBoth check.
>
I have extracted and decompiled the ACPI tables (DSDT and SSDTs) from acpidump.
You can find the raw acpidump.out and the decompiled ASL tables in the
following Google Drive folder:
https://drive.google.com/drive/folders/1aTqLAnUhrTsPdpA8tfOFyRopG3P3DGnc?usp=drive_link
As far as I can see/understand there is no _DSM method defined under the
GPIO controller device (AMDI0030) or the \_SB.GPIO scope.
Under the _AEI method (defined in SSDT9 line 188-193), pin 21 (0x15) and
pin 24 (0x18) are defined as:
GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullNone, 0x0000,
"\\_SB.GPIO", 0x00, ResourceConsumer, ,
)
{
0x0015 // Pin 21 (Touchpad attention line)
}
When triggered, they evaluate the _EVT method which calls:
Case (0x15)
{
\_SB.PCI0.SBRG.HNC0 (0x15, Zero)
}
Since Arg1 is Zero, HNC0 executes the Else branch, invoking M009 and ATKM/ADTM,
which stalls synchronously for ~36 seconds when executed during the probe path at
boot time.
Thanks,
Marco
^ permalink raw reply
* [PATCH] pinctrl: bcm2835: Don't remove an unregistered GPIO chip
From: Daniel McCarthy @ 2026-06-17 22:04 UTC (permalink / raw)
To: Linus Walleij, Florian Fainelli, Ray Jui, Scott Branden
Cc: linux-gpio, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Daniel McCarthy
If the devm_pinctrl_register() function fails,
bcm2835_pinctrl_probe() calls gpiochip_remove()
before gpiochip_add_data() has registered the GPIO chip.
This means that upon failure the gpio_chip.gpiodev
is NULL resulting in a null pointer dereference
inside the gpiochip_remove() function.
Remove the unnecessary function call to gpiochip_remove().
No GPIO cleanup is required because the GPIO chip
has not yet been registered. Without this change there
is potential for a kernel panic upon registration failure
Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
Signed-off-by: Daniel McCarthy <daniel@dragonzap.com>
---
drivers/pinctrl/bcm/pinctrl-bcm2835.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index e7b35019a5a7..725e880ae086 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1350,7 +1350,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
pc->pctl_desc = *pdata->pctl_desc;
pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
if (IS_ERR(pc->pctl_dev)) {
- gpiochip_remove(&pc->gpio_chip);
return PTR_ERR(pc->pctl_dev);
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Armin Wolf @ 2026-06-17 21:23 UTC (permalink / raw)
To: Marco Scardovi, bnatikar
Cc: andriy.shevchenko, brgl, linusw, linux-acpi, linux-gpio,
linux-kernel, mario.limonciello, westeri
In-Reply-To: <20260617185318.11237-1-scardracs@disroot.org>
Am 17.06.26 um 20:50 schrieb Marco Scardovi:
> Hi Basavaraj,
>
> Thank you for your review: this is the v2 with the rewording as requested.
Hi,
could you share the output of "acpidump" on your device? I suspect that Asus
uses a _DSM control method to tell Windows to invert the polarity inside the
ActiveBoth check.
Thanks,
Armin Wolf
> Changes in v2:
> - Reworded the commit message and the code comment to explain the actual
> boot-time replay mechanism as suggested by Basavaraj.
> - Explicitly noted that the touchpad itself is driven by i2c-hid and functions
> normally, and that the ACPI event handler is preserved for post-boot events.
> - Rebased against linux-next-20260616
>
> Marco Scardovi (1):
> gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
>
> drivers/gpio/gpiolib-acpi-quirks.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
^ permalink raw reply
* Re: [PATCH v9 2/2] i2c: designware: defer probe if child GpioInt controllers are not bound
From: Hardik Prakash @ 2026-06-17 19:22 UTC (permalink / raw)
To: Andy Shevchenko
Cc: linux-i2c, linux-gpio, wsa, mario.limonciello, brgl,
basavaraj.natikar, linusw, nathan, chaitanya.kumar.borah
In-Reply-To: <ajJobvY67HKufaTs@ashevche-desk.local>
On Wed, Jun 17, 2026 at 14:57, Andy Shevchenko wrote:
> > + if (!agpio->resource_source.string_length ||
> > + !agpio->resource_source.string_ptr)
> > + return 1;
>
> I'm wondering if we simply can move to strncmp() instead of this check
>
> > + list_for_each_entry(ref, gpio_controllers, node) {
> > + if (!strcmp(ref->path, agpio->resource_source.string_ptr))
>
> if (!strncmp(ref->path, agpio->resource_source.string_ptr))
Could you clarify? strncmp() with n=string_length would protect the
dedup check against a NULL or unterminated string_ptr, but we still
need string_ptr to be non-NULL before passing it to kstrdup(). Should
we keep a NULL/zero-length guard before kstrdup() and only replace the
strcmp() in the dedup loop with strncmp()?
Thanks,
Hardik
On Wed, 17 Jun 2026 at 14:57, Andy Shevchenko
<andriy.shevchenko@intel.com> wrote:
>
> On Wed, Jun 17, 2026 at 12:29:22PM +0530, Hardik Prakash wrote:
> > I2C controllers may have child devices with GpioInt resources that
> > depend on GPIO controllers to be fully initialized. If the I2C
> > controller probes and enumerates children before the referenced GPIO
> > controller has completed probe, GPIO interrupts may not be properly
> > configured, leading to device failures.
> >
> > On Lenovo Yoga 7 14AGP11, the WACF2200 touchscreen (child of
> > AMDI0010:02) has a GpioInt resource pointing to GPIO 157 on the
> > pinctrl-amd controller (AMDI0030:00). When i2c-designware probes
> > AMDI0010:02 before pinctrl-amd finishes initializing, I2C transactions
> > fail with lost arbitration errors.
> >
> > Add a generic dependency check in i2c-designware that walks ACPI child
> > devices, identifies any GpioInt resources, resolves the referenced GPIO
> > controllers, and defers probe if those controllers are not yet bound.
> > Uses acpi_gpio_get_irq_resource() to avoid duplicating GPIO resource
> > parsing logic from gpiolib-acpi. Skips resources with no resource
> > source string (string_length == 0 or string_ptr == NULL) to avoid
> > crashes on hardware where GPIO resources have no named controller.
> >
> > The probe ordering race was confirmed via dynamic debug tracing:
> >
> > 0.285952 amd_gpio_probe: registering gpiochip <- GPIO chip visible
> > 0.287121 amd_gpio_probe: requesting parent IRQ <- probe still running
> > 0.301454 AMDI0010:02 dw_i2c_plat_probe: start <- races here
> > 2.348157 lost arbitration
>
> ...
>
> > +static int check_gpioint_resource(struct acpi_resource *ares, void *data)
> > +{
> > + struct list_head *gpio_controllers = data;
> > + struct acpi_resource_gpio *agpio;
> > + struct gpio_controller_ref *ref;
> > +
> > + if (!acpi_gpio_get_irq_resource(ares, &agpio))
> > + return 1;
>
> > + if (!agpio->resource_source.string_length ||
> > + !agpio->resource_source.string_ptr)
> > + return 1;
>
> I'm wondering if we simply can move to strncmp() instead of this check
>
> > + /* Skip if we've already tracked this GPIO controller */
> > + list_for_each_entry(ref, gpio_controllers, node) {
> > + if (!strcmp(ref->path, agpio->resource_source.string_ptr))
>
> if (!strncmp(ref->path, agpio->resource_source.string_ptr))
>
>
> > + return 1;
> > + }
> > +
> > + ref = kzalloc(sizeof(*ref), GFP_KERNEL);
> > + if (!ref)
> > + return -ENOMEM;
> > +
> > + ref->path = kstrdup(agpio->resource_source.string_ptr, GFP_KERNEL);
> > + if (!ref->path) {
> > + kfree(ref);
> > + return -ENOMEM;
> > + }
> > +
> > + list_add_tail(&ref->node, gpio_controllers);
> > + return 1;
> > +}
> > +
> > +static int check_child_gpioint(struct acpi_device *adev, void *data)
> > +{
> > + struct list_head res_list;
> > + int ret;
> > +
> > + INIT_LIST_HEAD(&res_list);
>
> > + ret = acpi_dev_get_resources(adev, &res_list,
> > + check_gpioint_resource, data);
>
> Make it a single line.
>
> > + acpi_dev_free_resource_list(&res_list);
>
> It's not critical double free (it will try to free an empty list) on error.
>
> > + return ret < 0 ? ret : 0;
>
> ret = acpi_dev_get_resources(adev, &res_list, check_gpioint_resource, data);
> if (ret < 0)
> return ret;
>
> acpi_dev_free_resource_list(&res_list);
> return 0;
>
> > +}
> > +
> > +static int i2c_dw_check_gpio_dependencies(struct device *dev)
> > +{
> > + struct acpi_device *adev;
> > + LIST_HEAD(gpio_controllers);
> > + struct gpio_controller_ref *ref;
>
> Reversed xmas tree order.
>
> > + int ret = 0;
>
> Useless assignment.
>
> > + adev = ACPI_COMPANION(dev);
> > + if (!adev)
> > + return 0;
> > +
> > + /* Walk all child devices and collect GpioInt controller references */
>
> > + ret = acpi_dev_for_each_child(adev, check_child_gpioint,
> > + &gpio_controllers);
>
> Make it a single line.
>
> > + if (ret < 0)
> > + goto cleanup;
> > +
> > + /* For each GPIO controller, check if its platform device is bound */
> > + list_for_each_entry(ref, &gpio_controllers, node) {
> > + acpi_handle handle;
> > + acpi_status status;
> > + struct acpi_device *gpio_adev;
> > + struct device *gpio_dev;
>
> Reversed xmas tree order.
>
> > + bool bound;
> > +
> > + status = acpi_get_handle(NULL, ref->path, &handle);
> > + if (ACPI_FAILURE(status))
> > + continue;
> > +
> > + gpio_adev = acpi_fetch_acpi_dev(handle);
> > + if (!gpio_adev)
> > + continue;
>
> > + gpio_dev = acpi_get_first_physical_node(gpio_adev);
> > + acpi_dev_put(gpio_adev);
> > + if (!gpio_dev) {
> > + ret = -EPROBE_DEFER;
> > + goto cleanup;
> > + }
>
> > + /*
> > + * Defer probe until the GPIO controller is fully bound,
> > + * ensuring its IRQ setup is complete before we enumerate
> > + * I2C child devices.
> > + */
> > + scoped_guard(device, gpio_dev)
> > + bound = device_is_bound(gpio_dev);
>
> > + if (!bound) {
>
> Some of the compilers might complain the use of uninitialised variable (they
> might not parse properly scoped_guard() case).
>
> > + ret = -EPROBE_DEFER;
> > + goto cleanup;
> > + }
>
> To make it sure and deduplicate above the whole stuff can be written as
>
> gpio_dev = acpi_get_first_physical_node(gpio_adev);
> acpi_dev_put(gpio_adev);
> if (gpio_dev) {
> guard(device)(gpio_dev);
>
> bound = device_is_bound(gpio_dev);
> } else {
> bound = false;
> }
> /*
> * Defer probe until the GPIO controller is fully bound,
> * ensuring its IRQ setup is complete before we enumerate
> * I2C child devices.
> */
> if (!bound) {
> ret = -EPROBE_DEFER;
> goto cleanup;
> }
>
> > + }
> > +
> > +cleanup:
> > + free_gpio_controller_list(&gpio_controllers);
> > + return ret;
> > +}
> > +#else
> > +static int i2c_dw_check_gpio_dependencies(struct device *dev)
> > +{
> > + return 0;
> > +}
> > +#endif /* CONFIG_ACPI && CONFIG_GPIOLIB */
>
> I'm not sure if it's good to have all this quirk here or simply start
> a i2c-designware-quirks.c. Theoretically the PCI counterpart might,
> but I think quite unlikely, want to have something similar in the future.
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply
* [PATCH v2 1/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Marco Scardovi @ 2026-06-17 18:50 UTC (permalink / raw)
To: bnatikar
Cc: andriy.shevchenko, brgl, linusw, linux-acpi, linux-gpio,
linux-kernel, mario.limonciello, scardracs, westeri
In-Reply-To: <20260617185318.11237-1-scardracs@disroot.org>
ASUS ROG Strix G16 G614 series laptops experience a long boot delay of
approximately 36 seconds.
On these laptops, the firmware leaves the touchpad's ActiveBoth GPIO
line asserted (logic low) at boot. Per the boot-time initial-state logic,
an ActiveBoth interrupt found low is replayed once to sync its initial state,
which calls the handler synchronously in the probe path. On these laptops
that interrupt handler is slow/hanging, so the synchronous call blocks for
~36s and stalls boot.
The touchpad itself is driven by the i2c-hid driver using a standard
GpioInt() resource defined in the touchpad device's _CRS method. The ACPI
event handler on pin 21 is distinct from this and is not required for the
touchpad's initialization or runtime operation.
Commit 3bb62e3f99a5 ("gpiolib: acpi: Only trigger ActiveBoth interrupts
on boot") restricted the boot-time replay to ActiveBoth interrupts that are
asserted (low). The pin on ASUS ROG Strix G16 G614 series laptops meets
exactly that condition, which is why it still triggers.
Fix the delay by adding a DMI quirk to set no_edge_events_on_boot to true
for the ASUS ROG Strix G16 G614 family. This prevents the boot-time
trigger of this ACPI event handler without affecting the touchpad driver
or disabling the handler for post-boot events.
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Marco Scardovi <scardracs@disroot.org>
---
drivers/gpio/gpiolib-acpi-quirks.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/gpio/gpiolib-acpi-quirks.c b/drivers/gpio/gpiolib-acpi-quirks.c
index a0116f004975..3cd4cd27808a 100644
--- a/drivers/gpio/gpiolib-acpi-quirks.c
+++ b/drivers/gpio/gpiolib-acpi-quirks.c
@@ -392,6 +392,21 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
.ignore_wake = "VEN_0488:00@355",
},
},
+ {
+ /*
+ * ASUS ROG Strix G16 G614 series laptops experience a long boot
+ * delay (approx. 36 seconds) because the touchpad's ActiveBoth
+ * GPIO interrupt handler (TP_ATTN#) stalls/hangs during boot
+ * initialization.
+ */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ROG Strix G16 G614"),
+ },
+ .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+ .no_edge_events_on_boot = true,
+ },
+ },
{} /* Terminating entry */
};
--
2.54.0
^ permalink raw reply related
* [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Marco Scardovi @ 2026-06-17 18:50 UTC (permalink / raw)
To: bnatikar
Cc: andriy.shevchenko, brgl, linusw, linux-acpi, linux-gpio,
linux-kernel, mario.limonciello, scardracs, westeri
In-Reply-To: <221cd70d-70f9-4d01-8e8c-b4a5b347b8b9@amd.com>
Hi Basavaraj,
Thank you for your review: this is the v2 with the rewording as requested.
Changes in v2:
- Reworded the commit message and the code comment to explain the actual
boot-time replay mechanism as suggested by Basavaraj.
- Explicitly noted that the touchpad itself is driven by i2c-hid and functions
normally, and that the ACPI event handler is preserved for post-boot events.
- Rebased against linux-next-20260616
Marco Scardovi (1):
gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
drivers/gpio/gpiolib-acpi-quirks.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--
2.54.0
^ permalink raw reply
* Re: [PATCH] gpiolib: acpi: Add quirk for ASUS ROG Strix G614 series
From: Basavaraj Natikar @ 2026-06-17 18:34 UTC (permalink / raw)
To: Marco Scardovi, Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski
Cc: Mario Limonciello, linux-gpio, linux-acpi, linux-kernel
In-Reply-To: <20260616090824.5967-1-scardracs@disroot.org>
hi,
On 6/16/2026 2:38 PM, Marco Scardovi wrote:
> The ASUS ROG Strix G16 G614 series laptops experience a long boot delay of
> approximately 36 seconds. This happens because the system firmware triggers
> a slow/hanging ActiveBoth GPIO interrupt handler at boot time.
>
> Even though commit 3bb62e3f99a5 ("gpiolib: acpi: Only trigger ActiveBoth
> interrupts on boot") restricted boot-time execution to ActiveBoth edge
> events, the problematic interrupt on these laptops is configured as
> ActiveBoth. Consequently, the handler is still executed at boot and
> the boot process stalls.
>
> Fix the delay by adding a DMI quirk to disable edge event execution at
> boot for the ASUS ROG Strix G16 G614 family.
Could you reword the commit message to explain the actual mechanism?
Something like:
On ASUS ROG Strix G16 G614 series laptops, the firmware leaves this
ActiveBoth GPIO line asserted (logic low) at boot. Per the boot-time
initial-state logic, an ActiveBoth interrupt found low is replayed
once to sync its initial state, which calls the handler synchronously
in the probe path. On these laptops that interrupt handler is slow/hanging,
so the synchronous call blocks for ~36 s and stalls boot.
It's also worth noting that commit 3bb62e3f99a5 already restricts the
boot-time replay to ActiveBoth interrupts that are asserted (low) — the pin
on ASUS ROG Strix G16 G614 series laptops meets exactly that condition,
which is why it still triggers. Disabling edge_events_on_boot via the
DMI quirk is therefore the right workaround for these laptops.
Thanks,
--
Basavaraj
>
> Assisted-by: Antigravity:gemini-3.5-flash
> Signed-off-by: Marco Scardovi <scardracs@disroot.org>
> ---
> drivers/gpio/gpiolib-acpi-quirks.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/drivers/gpio/gpiolib-acpi-quirks.c b/drivers/gpio/gpiolib-acpi-quirks.c
> index a0116f004975..fa0f03bd51af 100644
> --- a/drivers/gpio/gpiolib-acpi-quirks.c
> +++ b/drivers/gpio/gpiolib-acpi-quirks.c
> @@ -392,6 +392,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
> .ignore_wake = "VEN_0488:00@355",
> },
> },
> + {
> + /*
> + * ASUS ROG Strix G614 series laptops experience a long boot
> + * delay (approx. 36 seconds) due to a slow/hanging ActiveBoth
> + * GPIO interrupt handler executing at boot.
> + */
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
> + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Strix G16 G614"),
> + },
> + .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
> + .no_edge_events_on_boot = true,
> + },
> + },
> {} /* Terminating entry */
> };
>
^ permalink raw reply
* Re: (subset) [PATCH v2] mfd: si476x: Modernize GPIO handling
From: Lee Jones @ 2026-06-17 16:15 UTC (permalink / raw)
To: Andrey Smirnov, Lee Jones, Bartosz Golaszewski, Linus Walleij
Cc: linux-kernel, linux-gpio
In-Reply-To: <20260608-mfd-si476x-v2-1-da5f779c1888@kernel.org>
On Mon, 08 Jun 2026 10:57:34 +0200, Linus Walleij wrote:
> The SI476X driver depends on the legacy GPIO API. As it only
> really use a single GPIO for reset, and this can be easily converted
> to use a GPIO descriptor, modernize the driver.
>
> The "reset" GPIO is obtained from a device property, such as a
> device tree ("reset-gpios", which is standard, but this hardware has
> no DT bindings as of now) or a software node for static platforms.
>
> [...]
Applied, thanks!
[1/1] mfd: si476x: Modernize GPIO handling
commit: f3f0acd3768dfe71aa6b2618dbeaff69f25923c4
--
Lee Jones [李琼斯]
^ permalink raw reply
* Re: (subset) [PATCH] mfd: si476x: Modernize GPIO handling
From: Lee Jones @ 2026-06-17 16:15 UTC (permalink / raw)
To: Andrey Smirnov, Lee Jones, Bartosz Golaszewski, Linus Walleij
Cc: linux-kernel, linux-gpio
In-Reply-To: <20260327-mfd-si476x-v1-1-93298ca35d6d@kernel.org>
On Fri, 27 Mar 2026 09:37:26 +0100, Linus Walleij wrote:
> The SI476X driver depends on the legacy GPIO API. As it only
> really use a single GPIO for reset, and this can be easily converted
> to use a GPIO descriptor, modernize the driver.
>
> The "reset" GPIO is obtained from a device property, such as a
> device tree ("reset-gpios", which is standard, but this hardware has
> no DT bindings as of now) or a software node for static platforms.
>
> [...]
Applied, thanks!
[1/1] mfd: si476x: Modernize GPIO handling
commit: f3f0acd3768dfe71aa6b2618dbeaff69f25923c4
--
Lee Jones [李琼斯]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox