Linux GPIO subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH] gpio: tegra: do not call pinctrl for GPIO direction
From: Bartosz Golaszewski @ 2026-06-23  8:45 UTC (permalink / raw)
  To: Bartosz Golaszewski, Linus Walleij, Runyu Xiao
  Cc: Bartosz Golaszewski, Thierry Reding, Jonathan Hunter, linux-gpio,
	linux-tegra, linux-kernel, stable
In-Reply-To: <20260619152439.1239561-1-runyu.xiao@seu.edu.cn>


On Fri, 19 Jun 2026 23:24:39 +0800, Runyu Xiao wrote:
> tegra_gpio_direction_input() and tegra_gpio_direction_output() already
> program the GPIO controller direction registers directly. The additional
> pinctrl_gpio_direction_input/output() calls do not add a Tegra pinctrl
> operation, because the Tegra pinmux ops provide GPIO request/free
> handling but no gpio_set_direction hook.
> 
> The extra call still enters the pinctrl core and takes pctldev->mutex.
> Shared GPIO users can call the direction path while holding their
> per-line spinlock, so this otherwise redundant pinctrl direction call can
> sleep in an atomic context.
> 
> [...]

Applied, thanks!

[1/1] gpio: tegra: do not call pinctrl for GPIO direction
      https://git.kernel.org/brgl/c/d3e91a95b2b0fc6336dbf3ec90d831a1654d2720

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH 1/1] gpio: davinci: fix IRQ domain leak on devm_kzalloc failure
From: Bartosz Golaszewski @ 2026-06-23  8:45 UTC (permalink / raw)
  To: Keerthy, Linus Walleij, Bartosz Golaszewski, fffsqian
  Cc: Bartosz Golaszewski, linux-kernel, linux-gpio, Qingshuang Fu
In-Reply-To: <20260623023106.117229-1-fffsqian@163.com>


On Tue, 23 Jun 2026 10:31:06 +0800, fffsqian@163.com wrote:
> In davinci_gpio_irq_setup(), after successfully creating an IRQ domain
> with irq_domain_create_legacy(), a subsequent devm_kzalloc() failure
> in the bank loop causes the function to return -ENOMEM without
> removing the IRQ domain.
> 
> Unlike devm-managed resources, irq_domain_create_legacy() does not
> auto-clean up on probe failure, so the domain is leaked.
> 
> [...]

Applied, thanks!

[1/1] gpio: davinci: fix IRQ domain leak on devm_kzalloc failure
      https://git.kernel.org/brgl/c/4e8eb6952aa6749726c6c3763ae0032a6332c24f

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH v1 1/2] dt-bindings: sound: add qcom,wsa885x-i2c
From: Prasad Kumpatla @ 2026-06-23  8:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
	Bartosz Golaszewski, Srinivas Kandagatla, linux-arm-msm,
	linux-sound, devicetree, linux-kernel, linux-gpio
In-Reply-To: <CAD++jLkFPb4CZqTsAh_qX1Jt9pWxhwhgbhREe9uybL_S7-t60Q@mail.gmail.com>


On 6/11/2026 2:50 AM, Linus Walleij wrote:
> Hi Prasad,
>
> thanks for your patch!

Hi Linus Walleij,

Thanks for reviewing the patch and for the feedback.

>
> On Wed, Jun 10, 2026 at 5:57 PM Prasad Kumpatla
> <prasad.kumpatla@oss.qualcomm.com> wrote:
>
>> Document the Qualcomm WSA885X I2C smart amplifier binding.
> Skip I2C? We don't need to tell e.g. "PCI" in some device on PCI and
> there is no reason to mention I2C for this device, the fact that it sits
> on an I2C bus will be apparent later.

Ack, Will rename the file name.

>
>> Describe the required supplies, powerdown and interrupt GPIOs, the
>> optional battery configuration, and the optional init-table property
>> used to program the device during codec initialization.
>>
>> This matches the driver programming model and documents the DT data
>> needed to use the codec on platforms with Audio IF playback.
>>
>> Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
> Perhaps add
> Link: https://www.qualcomm.com/audio/applications/compute-and-mobile-audio/products/wsa8815
>
> (...)
Checking internal to get product Doc to publish.
>> ---
>>   .../bindings/sound/qcom,wsa885x-i2c.yaml      | 89 +++++++++++++++++++
>>   1 file changed, 89 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml b/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml
> Drop the -i2c suffix on the files.
Ack, Will update.
>
>> new file mode 100644
>> index 000000000..1069f470d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml
>> @@ -0,0 +1,89 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/sound/qcom,wsa885x-i2c.yaml#
> Drop the -i2c suffix.
Ack, Will update.
>
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm WSA885x I2C smart speaker amplifier
> Drop I2C.
Ack, Will update.
>
>> +maintainers:
>> +  - Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> +  - Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
>> +
>> +description: |
>> +  WSA885x is a Qualcomm Aqstic smart speaker amplifier with an I2C control
>> +  interface and a digital audio interface exposed through ASoC DAI callbacks.
>> +
>> +allOf:
>> +  - $ref: dai-common.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    const: qcom,wsa885x-i2c
> Drop -i2c
Ack, Will update.
>
>> +  reg:
>> +    maxItems: 1
>> +
>> +  '#sound-dai-cells':
>> +    const: 0
>> +
>> +  powerdown-gpios:
>> +    description: GPIO controlling the SD_N powerdown pin.
>> +    maxItems: 1
>> +
>> +  interrupt-gpios:
>> +    description: GPIO used for the codec interrupt output.
>> +    maxItems: 1
>> +
>> +  vdd-1p8-supply: true
>> +
>> +  vdd-io-supply: true
>> +
>> +  qcom,battery-config:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description: Speaker battery configuration, 1 for 1S and 2 for 2S.
> What is a "1S" and a "2S"? Include description here.
Ack, Will Update more details for 1s and 2s in next version.
>
>> +    default: 1
>> +    enum: [1, 2]
>> +
>> +  qcom,wsa885x-init-table:
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +    minItems: 2
>> +    maxItems: 256
>> +    description: |
>> +      Sequence of register/value pairs applied during codec hardware
>> +      initialization. Entries are encoded as alternating register address and
>> +      register value cells. The number of entries must be even (register/value
>> +      pairs); maxItems is 256 (128 pairs).
> Can this just be a table inside the driver, if it will be the same
> array for every user? If this is board-unique then it needs to describe
> what each value is actually doing well enough so engineers can use this
> documentation right here to configure their board without looking through
> register maps and what not.
>
> Something more abstract using SI units etc is probably needed here.

These values are part of a fixed hardware initialization sequence and 
are not board-specific.

I'll move them into the driver as a register table, making them easier 
to maintain and

avoiding opaque DT data.

Thanks,

Prasad

>
> Yours,
> Linus Walleij

^ permalink raw reply

* Re: [PATCH v1 1/2] dt-bindings: sound: add qcom,wsa885x-i2c
From: Prasad Kumpatla @ 2026-06-23  9:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
	Linus Walleij, Bartosz Golaszewski, Srinivas Kandagatla,
	linux-arm-msm, linux-sound, devicetree, linux-kernel, linux-gpio
In-Reply-To: <20260611-debonair-barnacle-of-action-ee9d22@quoll>


On 6/11/2026 3:04 PM, Krzysztof Kozlowski wrote:
> On Wed, Jun 10, 2026 at 09:27:07PM +0530, Prasad Kumpatla wrote:
>> Document the Qualcomm WSA885X I2C smart amplifier binding.
>>
>> Describe the required supplies, powerdown and interrupt GPIOs, the
>> optional battery configuration, and the optional init-table property
>> used to program the device during codec initialization.
>>
>> This matches the driver programming model and documents the DT data
> Binding matches hardware, not driver. Please describe the hardware.

Hi Krzysztof,

Thanks for reviewing the patch and for the feedback.

Ack, Will add more HW details in next version.

>
>> needed to use the codec on platforms with Audio IF playback.
>>
>> Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
>> ---
>>   .../bindings/sound/qcom,wsa885x-i2c.yaml      | 89 +++++++++++++++++++
>>   1 file changed, 89 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml b/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml
>> new file mode 100644
>> index 000000000..1069f470d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml
> There is no I2C in device name.

Ack, Will remove.

>
>> @@ -0,0 +1,89 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/sound/qcom,wsa885x-i2c.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm WSA885x I2C smart speaker amplifier
>> +
>> +maintainers:
>> +  - Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> +  - Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
>> +
>> +description: |
> Do not need '|' unless you need to preserve formatting.
Ack, Will Update.
>
>> +  WSA885x is a Qualcomm Aqstic smart speaker amplifier with an I2C control
>> +  interface and a digital audio interface exposed through ASoC DAI callbacks.
>> +
>> +allOf:
>> +  - $ref: dai-common.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    const: qcom,wsa885x-i2c
> Same here
>
> Also, incorrect usage of wildcard. Look at other bindings how this is
> written, so you will not repeat the same comments:
> https://lore.kernel.org/all/20250522-rb2_audio_v3-v3-3-9eeb08cab9dc@linaro.org/
>
> Read writing bindings before posting next version.
>
> I also cannot find traces of internal review of this. Did it happen? Did
> you receive toolset comments?

Ack, Thanks for the reference link, will cross check and update the 
bindings.

No, there is o internal review done for this patch due to timelines.

>
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  '#sound-dai-cells':
>> +    const: 0
>> +
>> +  powerdown-gpios:
>> +    description: GPIO controlling the SD_N powerdown pin.
>> +    maxItems: 1
>> +
>> +  interrupt-gpios:
> No, interrupts are never written as GPIOs.
>
> Where is this binding coming from?


Agree, Will remove this and come up standard interrupt bindings in next 
version.

>
>> +    description: GPIO used for the codec interrupt output.
>> +    maxItems: 1
>> +
>> +  vdd-1p8-supply: true
>> +
>> +  vdd-io-supply: true
>> +
>> +  qcom,battery-config:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description: Speaker battery configuration, 1 for 1S and 2 for 2S.
> Use string
Ack.
>
>> +    default: 1
>> +    enum: [1, 2]
>> +
>> +  qcom,wsa885x-init-table:
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +    minItems: 2
>> +    maxItems: 256
>> +    description: |
>> +      Sequence of register/value pairs applied during codec hardware
> No, we don't store register values usually.


Ack,I'll move them into the driver as a register table,

making them easier to maintain and avoiding opaque DT data.

>> +      initialization. Entries are encoded as alternating register address and
>> +      register value cells. The number of entries must be even (register/value
>> +      pairs); maxItems is 256 (128 pairs).
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - '#sound-dai-cells'
>> +  - powerdown-gpios
>> +  - interrupt-gpios
>> +  - vdd-1p8-supply
>> +  - vdd-io-supply
>> +
>> +additionalProperties: false
> unevaluated instead. Again, OPEN other existing bindings. Why doing
> something completely different? Is there any WSA88xx binding with
> additionalProperties? No.

Thanks for pointing this out. I'll align the schema with the existing 
WSA88xx

bindings and replace additionalProperties: false with 
unevaluatedProperties: false

in the next revision.

Thanks,

Prasad

>
> Best regards,
> Krzysztof
>

^ permalink raw reply

* Re: [PATCH v1 2/2] ASoC: codecs: add Qualcomm WSA885X I2C codec driver
From: Prasad Kumpatla @ 2026-06-23  9:13 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
	Linus Walleij, Bartosz Golaszewski, Srinivas Kandagatla,
	linux-arm-msm, linux-sound, devicetree, linux-kernel, linux-gpio
In-Reply-To: <20260611-straight-refined-beetle-e2c934@quoll>


On 6/11/2026 3:09 PM, Krzysztof Kozlowski wrote:
> On Wed, Jun 10, 2026 at 09:27:08PM +0530, Prasad Kumpatla wrote:
>> +};
>> +
>> +static void wsa885x_gpio_set(struct wsa885x_i2c_priv *wsa885x, bool val)
>> +{
>> +	if (!wsa885x || !wsa885x->sd_n)
> How wsa885x can be NULL?
>
> This wrapper is pointless. Avoid creating abstraction layers over single
> call to standard kernel interfaces.

Hi Krzysztof,

Thanks for reviewing and comments on patch.

Agree. The NULL check is unnecessary, and the helper does not add any 
meaningful abstraction.

I'll remove the wrapper and use the GPIO API directly in the next revision.

>
>> +		return;
>> +
>> +	gpiod_set_value_cansleep(wsa885x->sd_n, val);
>> +}
>> +
> ...
>
>> +
>> +static void wsa885x_gpio_powerdown(void *data)
>> +{
>> +	struct wsa885x_i2c_priv *wsa885x = data;
>> +
>> +	if (!wsa885x)
>> +		return;
> How is this possible?

No, I will remove all the unnecessary checks in the next version of patch.


>
>> +
>> +	wsa885x_gpio_set(wsa885x, true);
>> +}
>> +
> ...
>
>> +	if (count > 0) {
>> +		if (count % 2) {
>> +			dev_err(dev, "%s: Invalid number of elements in %s (%d)\n",
>> +				__func__, init_table_prop, count);
>> +			return -EINVAL;
>> +		}
>> +		if (count > WSA885X_INIT_TABLE_MAX_ITEMS) {
>> +			dev_err(dev, "%s: %s has too many elements (%d > %u)\n",
>> +				__func__, init_table_prop, count,
>> +				WSA885X_INIT_TABLE_MAX_ITEMS);
>> +			return -EINVAL;
>> +		}
>> +		wsa885x->init_table_size = count;
>> +
>> +		wsa885x->init_table = devm_kcalloc(dev, wsa885x->init_table_size,
>> +						   sizeof(*wsa885x->init_table), GFP_KERNEL);
>> +		if (!wsa885x->init_table)
>> +			return -ENOMEM;
>> +
>> +		if (device_property_read_u32_array(dev, init_table_prop,
>> +						   wsa885x->init_table,
>> +						   wsa885x->init_table_size)) {
>> +			dev_err(dev, "%s: Failed to read %s\n",
>> +				__func__, init_table_prop);
>> +			return -EINVAL;
>> +		}
>> +	}
>> +
>> +	ret = device_property_read_u32(dev, "qcom,battery-config",
>> +				       &wsa885x->batt_conf);
>> +	if (ret) {
>> +		wsa885x->batt_conf = WSA885X_BATT_1S;
>> +	} else if (wsa885x->batt_conf != WSA885X_BATT_1S &&
>> +		   wsa885x->batt_conf != WSA885X_BATT_2S) {
>> +		return dev_err_probe(dev, -EINVAL,
>> +				     "Invalid battery config %u (expected 1S or 2S)\n",
>> +				     wsa885x->batt_conf);
>> +	}
>> +
>> +	for (i = 0; i < WSA885X_SUPPLIES_NUM; i++)
>> +		wsa885x->supplies[i].supply = wsa885x_supply_name[i];
>> +
>> +	ret = devm_regulator_bulk_get(dev, WSA885X_SUPPLIES_NUM, wsa885x->supplies);
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "Failed to get regulators\n");
>> +
>> +	ret = regulator_bulk_enable(WSA885X_SUPPLIES_NUM, wsa885x->supplies);
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "Failed to enable regulators\n");
>> +
>> +	ret = devm_add_action_or_reset(dev, wsa885x_regulator_disable, wsa885x);
> Why you cannot simply use devm_regulator_get_enable?
Ack, will use.
>
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "devm_add_action_or_reset failed\n");
>> +
>> +	wsa885x->sd_n = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_HIGH);
>> +	if (IS_ERR(wsa885x->sd_n))
>> +		return dev_err_probe(dev, PTR_ERR(wsa885x->sd_n),
>> +							 "Shutdown Control GPIO not found\n");
> Messed/misaligned indentation.
Ack, Will update
>
>> +
>> +	wsa885x_gpio_set(wsa885x, false);
>> +
>> +	ret = devm_add_action_or_reset(dev, wsa885x_gpio_powerdown, wsa885x);
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "devm_add_action_or_reset failed\n");
>> +
>> +	i2c_set_clientdata(client, wsa885x);
>> +
>> +	wsa885x->intr_pin = devm_gpiod_get(dev, "interrupt", GPIOD_IN);
>> +	if (IS_ERR(wsa885x->intr_pin))
>> +		return dev_err_probe(dev, PTR_ERR(wsa885x->intr_pin),
>> +							 "Interrupt GPIO not found\n");
>> +
>> +	ret = wsa885x_register_irq(wsa885x);
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "wsa885x irq registration failed\n");
>> +
>> +	ret = devm_snd_soc_register_component(dev, component_driver,
>> +					      wsa885x_i2c_dai,
>> +					      ARRAY_SIZE(wsa885x_i2c_dai));
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "Codec component registration failed\n");
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id wsa885x_i2c_dt_match[] = {
>> +	{
>> +		.compatible = "qcom,wsa885x-i2c",
>> +	},
>> +	{}
>> +};
>> +
>> +static const struct i2c_device_id wsa885x_id_i2c[] = {
>> +	{"wsa885x_i2c", 0},
> Used named initializers.
Ack, Will update
>
>> +	{}
>> +};
>> +
>> +MODULE_DEVICE_TABLE(i2c, wsa885x_id_i2c);
>> +MODULE_DEVICE_TABLE(of, wsa885x_i2c_dt_match);
> Don't come with own coding style. Each above goes IMMEDIATELY after the table.

Agreed. I'll place each MODULE_DEVICE_TABLE() immediately after its 
associated table to match the existing kernel style.

Thanks,

Prasad


>
> Best regards,
> Krzysztof
>

^ permalink raw reply

* Re: [PATCH v1 2/2] ASoC: codecs: add Qualcomm WSA885X I2C codec driver
From: Prasad Kumpatla @ 2026-06-23  9:20 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Srinivas Kandagatla, linux-arm-msm, linux-sound, devicetree,
	linux-kernel, linux-gpio, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jaroslav Kysela, Takashi Iwai, Linus Walleij
In-Reply-To: <CAMRc=Mf2oujn6MstGqKg1JCu3hbPD5zHhCB-Zke_hu8LYCz-Xg@mail.gmail.com>


On 6/11/2026 3:19 PM, Bartosz Golaszewski wrote:
> On Wed, 10 Jun 2026 17:57:08 +0200, Prasad Kumpatla
> <prasad.kumpatla@oss.qualcomm.com> said:
>> Add an ASoC codec driver for the Qualcomm WSA885X smart speaker
>> amplifier accessed over I2C.
>>
>> The driver provides the control-side support needed for playback
>> bring-up, including register programming, serial interface setup, clock
>> handling, mute and gain control, reset handling and interrupt support.
>>
>> Program the init table during codec initialization and reapply it only
>> after an explicit device reset so the static device configuration is
>> not rewritten on every playback start. Also program the TDM control
>> slot-count field from the runtime slot configuration so the same codec
>> path can be used with 2-slot, 4-slot, or 8-slot Audio IF backends.
>>
>> Keep the stream-time power-state sequencing in the DAI callbacks and
>> use normal regmap access for the control path.
>>
>> Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
>> ---
> ...
>
>> diff --git a/sound/soc/codecs/wsa885x-i2c.c b/sound/soc/codecs/wsa885x-i2c.c
>> new file mode 100644
>> index 000000000..a7d8f8d48
>> --- /dev/null
>> +++ b/sound/soc/codecs/wsa885x-i2c.c
>> @@ -0,0 +1,1643 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +
>> +/* WSA885X I2C codec driver */
>> +
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/i2c.h>
>> +#include <linux/module.h>
>> +#include <linux/regmap.h>
>> +#include <linux/property.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/slab.h>
>> +#include <sound/core.h>
>> +#include <sound/pcm.h>
>> +#include <sound/pcm_params.h>
>> +#include <sound/soc-dapm.h>
>> +#include <sound/soc.h>
>> +#include <sound/tlv.h>
>> +#include <linux/interrupt.h>
> Can you keep the headers in alphabetical order?

Hi Bart,

Thanks for review the patch and the feedback.

Ack, Will update

>
> ...
>
>> +
>> +#define WSA885X_FU21_VOL_STEPS 124
>> +#define WSA885X_USAGE_MODE_MAX 8
>> +#define WSA885X_INIT_TABLE_MAX_ITEMS 256
> Add newline.
Ack, Will update.
>
> ...
>
>> +
>> +static int wsa885x_apply_init_table(struct wsa885x_i2c_priv *wsa885x)
>> +{
>> +	int i;
>> +	int ret;
> I'd put it on the same line (elsewhere too) but that's personal preference.
Ack, I will make them to a single line.
>
>> +
>> +	if (!wsa885x || !wsa885x->regmap)
>> +		return -EINVAL;
>
> You have a lot of these checks but this can't really happen, can it?
Ack, I will cleanup and remove the all unnecessary checks and update in 
next version
>
>> +
>> +	if (!wsa885x->init_table_size)
>> +		return 0;
>> +
>> +	if (!wsa885x->init_table)
>> +		return -EINVAL;
>> +
>> +	for (i = 0; i < wsa885x->init_table_size / 2; i++) {
>> +		u32 reg = wsa885x->init_table[2 * i];
>> +		u32 val = wsa885x->init_table[2 * i + 1];
>> +
>> +		if (wsa885x->batt_conf == WSA885X_BATT_2S && reg == WSA885X_SPK_TOP_LF_CH1_CTRL11)
>> +			continue;
>> +
>> +		if (wsa885x->batt_conf == WSA885X_BATT_2S && reg == WSA885X_SPK_TOP_LF_CH2_CTRL11)
>> +			continue;
>> +
>> +		ret = regmap_write(wsa885x->regmap, reg, val);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int wsa885x_hw_init(struct wsa885x_i2c_priv *wsa885x)
>> +{
>> +	static const struct reg_sequence regs[] = {
>> +		{ WSA885X_DIG_CTRL1_SPMI_PAD_GPIO2_CTL, 0x2e },
>> +		{ WSA885X_DIG_CTRL1_INTR_MODE, 0x01 },
>> +		{ WSA885X_DIG_CTRL1_PIN_CT, 0x04 },
>> +	};
>> +	int ret;
>> +
>> +	if (!wsa885x || !wsa885x->regmap)
>> +		return -EINVAL;
>> +
>> +	ret = wsa885x_apply_init_table(wsa885x);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (wsa885x->batt_conf == WSA885X_BATT_2S) {
>> +		ret = wsa885x_2s_conf(wsa885x);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return regmap_multi_reg_write(wsa885x->regmap, regs, ARRAY_SIZE(regs));
>> +}
>> +
>> +static int wsa885x_unmask_interrupts(struct wsa885x_i2c_priv *wsa885x)
>> +{
>> +	static const struct reg_sequence regs[] = {
>> +		{ WSA885X_INTR_MASK0, 0x00 },
>> +		{ WSA885X_INTR_MASK0 + 1, 0x00 },
>> +		{ WSA885X_INTR_MASK0 + 2, 0xf8 },
>> +	};
>> +
>> +	if (!wsa885x || !wsa885x->regmap)
>> +		return -EINVAL;
>> +
>> +	return regmap_multi_reg_write(wsa885x->regmap, regs, ARRAY_SIZE(regs));
>> +}
>> +
>> +static int wsa885x_wait_for_pde_state(struct wsa885x_i2c_priv *wsa885x, int ps)
>> +{
>> +	int act_ps = -1, cnt = 0, clock_valid = -1;
>> +	int rc = 0;
>> +
>> +	if (!wsa885x || !wsa885x->regmap)
>> +		return -EINVAL;
>> +
>> +	if (ps < 0 || ps > 3)
>> +		return -EINVAL;
>> +
>> +	do {
>> +		usleep_range(1000, 1500);
>> +		rc = regmap_read(wsa885x->regmap,
>> +				 WSA885X_SMP_AMP_CTRL_STEREO_PDE23_ACT_PS,
>> +				 &act_ps);
>> +		if (rc) {
>> +			dev_err(wsa885x->dev, "PDE state read failed: %d\n", rc);
>> +			return rc;
>> +		}
>> +		if (act_ps == ps)
>> +			return 0;
>> +	} while (++cnt < 5);
> Newline.
Ack.
>
>> +	if (regmap_read(wsa885x->regmap,
>> +			WSA885X_SMP_AMP_CTRL_STEREO_CS21_CLOCK_VALID,
>> +			&clock_valid))
>> +		dev_err(wsa885x->dev,
>> +			"PDE power state %d request failed, actual_ps %d, clock_valid read failed\n",
>> +			ps, act_ps);
>> +	else
>> +		dev_err(wsa885x->dev,
>> +			"PDE power state %d request failed, actual_ps %d, clock_valid:%d\n",
>> +			ps, act_ps, clock_valid);
>> +
>> +	return -ETIMEDOUT;
>> +}
>> +
>> +static int wsa885x_codec_hw_params(struct snd_pcm_substream *substream,
>> +				   struct snd_pcm_hw_params *params,
>> +				   struct snd_soc_dai *dai)
>> +{
>> +	struct wsa885x_i2c_priv *wsa885x;
>> +	u8 pcm_rate, cs21_sample_rate_idx, cs24_sample_rate_idx;
>> +
>> +	(void)substream;
> Do we warn about unused arguments in the kernel now?

Right, this is unnecessary. I'll drop the unused parameter cast.

Ack.

>
> ...
>
>> +
>> +static int wsa885x_stereo_gain_offset_get(struct snd_kcontrol *kcontrol,
>> +					  struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct snd_soc_component *component;
>> +	struct wsa885x_i2c_priv *wsa885x;
>> +	int val;
>> +
>> +	if (!kcontrol || !ucontrol)
>> +		return -EINVAL;
>> +
>> +	component = snd_kcontrol_chip(kcontrol);
>> +	if (!component)
>> +		return -EINVAL;
>> +
>> +	wsa885x = snd_soc_component_get_drvdata(component);
>> +	if (!wsa885x)
>> +		return -EINVAL;
>> +
>> +	val = wsa885x->stereo_vol_db + 84;
>> +	if (val < 0 || val > WSA885X_FU21_VOL_STEPS)
>> +		return -ERANGE;
>> +
>> +	ucontrol->value.integer.value[0] = val;
>> +	return 0;
>> +}
>> +
>> +static int wsa885x_stereo_gain_offset_put(struct snd_kcontrol *kcontrol,
>> +					  struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct snd_soc_component *component;
>> +	struct wsa885x_i2c_priv *wsa885x;
>> +	long val;
>> +
>> +	if (!kcontrol || !ucontrol)
>> +		return -EINVAL;
>> +
>> +	component = snd_kcontrol_chip(kcontrol);
>> +	if (!component)
>> +		return -EINVAL;
>> +
>> +	wsa885x = snd_soc_component_get_drvdata(component);
>> +	if (!wsa885x)
>> +		return -EINVAL;
>> +
>> +	val = ucontrol->value.integer.value[0];
>> +
>> +	if (val < 0 || val > WSA885X_FU21_VOL_STEPS) {
>> +		dev_err(component->dev, "%s: Invalid range, Val: %ld\n", __func__, val);
>> +		return -EINVAL;
>> +	}
>> +	wsa885x->stereo_vol_db = (int)val - 84;
>> +	return 0;
>> +}
>> +
>> +static int wsa885x_i2c_usage_modes_get(struct snd_kcontrol *kcontrol,
>> +				       struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct snd_soc_component *component;
>> +	struct wsa885x_i2c_priv *wsa885x_i2c;
>> +
>> +	if (!kcontrol || !ucontrol)
>> +		return -EINVAL;
>> +
>> +	component = snd_kcontrol_chip(kcontrol);
>> +	if (!component)
>> +		return -EINVAL;
>> +
>> +	wsa885x_i2c = snd_soc_component_get_drvdata(component);
>> +	if (!wsa885x_i2c)
>> +		return -EINVAL;
>> +
>> +	if (wsa885x_i2c->usage_mode > WSA885X_USAGE_MODE_MAX)
>> +		return -ERANGE;
>> +
>> +	ucontrol->value.integer.value[0] = wsa885x_i2c->usage_mode;
>> +
>> +	return 0;
>> +}
>> +
>> +static int wsa885x_i2c_usage_modes_put(struct snd_kcontrol *kcontrol,
>> +				       struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct snd_soc_component *component;
>> +	struct wsa885x_i2c_priv *wsa885x_i2c;
>> +	long val;
>> +
>> +	if (!kcontrol || !ucontrol)
>> +		return -EINVAL;
>> +
>> +	component = snd_kcontrol_chip(kcontrol);
>> +	if (!component)
>> +		return -EINVAL;
>> +
>> +	wsa885x_i2c = snd_soc_component_get_drvdata(component);
>> +	if (!wsa885x_i2c)
>> +		return -EINVAL;
>> +
> You seem to be repeating the same sequence in multiple functions just to get
> the address of wsa885x_i2c. Can you factor it out into a separate helper and
> save some lines?
Ack.
>
>> +	val = ucontrol->value.integer.value[0];
>> +
>> +	if (val < 0 || val > WSA885X_USAGE_MODE_MAX)
>> +		return -EINVAL;
>> +
>> +	wsa885x_i2c->usage_mode = val;
>> +
>> +	return 0;
>> +}
>> +
>> +static int wsa885x_i2c_rx_slot_mask_get(struct snd_kcontrol *kcontrol,
>> +					struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct snd_soc_component *component;
>> +	struct wsa885x_i2c_priv *wsa885x_i2c;
>> +	u32 mask;
>> +
>> +	if (!kcontrol || !ucontrol)
>> +		return -EINVAL;
>> +
>> +	component = snd_kcontrol_chip(kcontrol);
>> +	if (!component)
>> +		return -EINVAL;
>> +
>> +	wsa885x_i2c = snd_soc_component_get_drvdata(component);
>> +	if (!wsa885x_i2c)
>> +		return -EINVAL;
>> +
>> +	mask = wsa885x_i2c->rx_slot_mask;
>> +	if (!wsa885x_is_valid_rx_slot_mask(mask))
>> +		return -ERANGE;
>> +
>> +	ucontrol->value.integer.value[0] = mask;
>> +
>> +	return 0;
>> +}
>> +
>> +static int wsa885x_i2c_rx_slot_mask_put(struct snd_kcontrol *kcontrol,
>> +					struct snd_ctl_elem_value *ucontrol)
>> +{
>> +	struct snd_soc_component *component;
>> +	struct wsa885x_i2c_priv *wsa885x_i2c;
>> +	long mask;
>> +
>> +	if (!kcontrol || !ucontrol)
>> +		return -EINVAL;
>> +
>> +	component = snd_kcontrol_chip(kcontrol);
>> +	if (!component)
>> +		return -EINVAL;
>> +
>> +	wsa885x_i2c = snd_soc_component_get_drvdata(component);
>> +	if (!wsa885x_i2c)
>> +		return -EINVAL;
>> +
>> +	mask = ucontrol->value.integer.value[0];
>> +
>> +	if (!wsa885x_is_valid_rx_slot_mask(mask))
>> +		return -EINVAL;
>> +
>> +	wsa885x_i2c->rx_slot_mask = mask;
>> +
>> +	return 0;
>> +}
>> +
> ...
>
>> +				/* INTR_CLEAR registers are write-only; use regmap_write
>> +				 * instead of regmap_update_bits to avoid the read-modify-write
>> +				 * that regmap_update_bits performs on non-readable registers.
>> +				 */
> /*
>   */
>
> style comments please
Ack. will update
>
> ...
>
>> +	ret = devm_add_action_or_reset(dev, wsa885x_gpio_powerdown, wsa885x);
>> +	if (ret)
>> +		return dev_err_probe(dev, ret, "devm_add_action_or_reset failed\n");
>> +
>> +	i2c_set_clientdata(client, wsa885x);
> I don't see a corresponding i2c_get_clientdata(). Do you really need it?

It is currently not being used, so storing the client data is unnecessary.

I'll either remove it or add it together with the code that requires 
i2c_get_clientdata() in a future versions.

Thanks,

Prasad

>
> ...
>
> Bart

^ permalink raw reply

* RE: [PATCH v2 2/5] dt-binding: pinctrl: samsung: Add exynos8855-pinctrl compatible
From: Alim Akhtar @ 2026-06-23 10:44 UTC (permalink / raw)
  To: 'Krzysztof Kozlowski'
  Cc: peter.griffin, robh, conor+dt, linusw, linux-samsung-soc,
	linux-kernel, devicetree, linux-gpio, hajun.sung
In-Reply-To: <20260617-favorite-bobcat-of-ecstasy-02f62f@quoll>

Hi Krzysztof

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Wednesday, June 17, 2026 3:50 PM
> To: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: peter.griffin@linaro.org; robh@kernel.org; conor+dt@kernel.org;
> linusw@kernel.org; linux-samsung-soc@vger.kernel.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org; linux-
> gpio@vger.kernel.org; hajun.sung@samsung.com
> Subject: Re: [PATCH v2 2/5] dt-binding: pinctrl: samsung: Add exynos8855-
> pinctrl compatible
> 
> On Mon, Jun 15, 2026 at 02:22:49PM +0530, Alim Akhtar wrote:
> > Document pin controller support on Exynos8855 SoC.
> >
> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > ---
> 
> No wakeup-eint?
> 
Yes, in next version, will update samsung,pinctrl-wakeup-interrupt.yaml with wakeup-eint entry
Thanks



^ permalink raw reply

* [PATCH libgpiod] build: fix dependencies for generated files
From: Bartosz Golaszewski @ 2026-06-23 11:40 UTC (permalink / raw)
  To: Linus Walleij, Vincent Fazio, Kent Gibson, Luca Weiss
  Cc: linux-gpio, brgl, Bartosz Golaszewski

Depending on the timing, we may try to build generated files that don't
exist yet. Generated .c and .h files need to be included in the sources
of the dependencies that need them so that they get generated before we
try to build them. Fix issues observed in dbus and GLib bindings.

Reported-by: Luca Weiss <luca@lucaweiss.eu>
Fixes: 97bab4cc87dd ("build: replace autotools with meson & ninja")
Closes: https://github.com/brgl/libgpiod/issues/191
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 bindings/glib/meson.build | 1 +
 dbus/lib/meson.build      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/bindings/glib/meson.build b/bindings/glib/meson.build
index b8f8f53c2a4e564de1012ccb4979077e9813e7b5..3965314f835792b363e93df0aeaaeb38b51ecc27 100644
--- a/bindings/glib/meson.build
+++ b/bindings/glib/meson.build
@@ -88,6 +88,7 @@ pkgconfig.generate(libgpiod_glib_lib,
 libgpiod_glib_dep = declare_dependency(
   link_with: libgpiod_glib_lib,
   include_directories: glib_inc,
+  sources: [gen_enum_c, gen_enum_h],
 )
 
 if opt_introspection.allowed() and gir_dep.found()
diff --git a/dbus/lib/meson.build b/dbus/lib/meson.build
index bf49d08fe4054f191ab8be6abddceec60bb809e9..9acf5e1f1d4cb9c7c30dbfbadf49755c26abb00e 100644
--- a/dbus/lib/meson.build
+++ b/dbus/lib/meson.build
@@ -31,4 +31,5 @@ install_data('io.gpiod1.xml',
 libgpiodbus_dep = declare_dependency(
   link_with: libgpiodbus_lib,
   include_directories: dbus_lib_inc,
+  sources: generated_dbus,
 )

---
base-commit: 40538a7b48c9a6bd50d6253f86fdcb354b45073b
change-id: 20260623-dbus-meson-deps-ff2e9ba43d0f

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>


^ permalink raw reply related

* Re: [PATCH 2/2] dt-bindings: Drop incorrect usage of double '::'
From: Daniel Lezcano @ 2026-06-23 11:45 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Peter Griffin, Alim Akhtar,
	Michael Turquette, Stephen Boyd, Brian Masney, Sylwester Nawrocki,
	Chanwoo Choi, Sam Protsenko, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Inki Dae, Seung-Woo Kim, Kyungmin Park,
	Andi Shyti, Georgi Djakov, Lee Jones, Pavel Machek, Hans Verkuil,
	Mauro Carvalho Chehab, Ulf Hansson, Peter Rosin, Vinod Koul,
	Neil Armstrong, Linus Walleij, Geert Uytterhoeven, Magnus Damm,
	Sebastian Reichel, Javier Martinez Canillas, Liam Girdwood,
	Mark Brown, Greg Kroah-Hartman, Jiri Slaby, Srinivas Kandagatla,
	Bartlomiej Zolnierkiewicz, Rafael J. Wysocki, Daniel Lezcano,
	Zhang Rui, Lukasz Luba, Jonathan Marek, Taniya Das, Robert Marko,
	Christian Marangi, Stephan Gerhold, Adam Skladowski,
	Sireesh Kodali, Barnabas Czeman, Imran Shaik,
	Sricharan Ramabadhran, Anusha Rao, Luo Jie, Tomasz Figa,
	Chanho Park, Sunyeal Hong, Shin Son, Krishna Manikandan,
	Jacek Anaszewski, Jaehoon Chung, Marek Szyprowski, Alina Yu,
	Andy Gross, Niklas Söderlund, Wesley Cheng, linux-arm-msm,
	devicetree, linux-kernel, linux-arm-kernel, linux-samsung-soc,
	linux-clk, dri-devel, freedreno, linux-i2c, linux-pm, linux-leds,
	linux-media, linux-mmc, linux-phy, linux-gpio, linux-renesas-soc,
	linux-serial, linux-sound, linux-usb
In-Reply-To: <20260622101606.485961-4-krzysztof.kozlowski@oss.qualcomm.com>

On 6/22/26 12:16, Krzysztof Kozlowski wrote:
> There is no use of double colon '::' in YAML. OTOH, the literal style
> block, e.g. using '|' treats all characters as content [1] therefore
> single use of ':' in descriptions is perfectly fine, whenever '|' is
> used.
> 
> Cleanup existing code, so the confusing style won't be re-used in new
> contributions.
> 
> Link: https://yaml.org/spec/1.2.2/#literal-style [1]
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> 
> ---
> 
> Intention for this patch is to go via Rob's tree.
> ---
>   .../devicetree/bindings/arm/qcom-soc.yaml     |  4 ++--
>   .../devicetree/bindings/arm/qcom.yaml         |  4 ++--
>   .../bindings/arm/samsung/samsung-soc.yaml     |  4 ++--
>   .../display/msm/dsi-controller-main.yaml      | 20 +++++++++----------
>   .../display/samsung/samsung,fimd.yaml         |  4 ++--
>   .../bindings/i2c/samsung,s3c2410-i2c.yaml     |  2 +-
>   .../interconnect/qcom,msm8998-bwmon.yaml      |  2 +-
>   .../interconnect/samsung,exynos-bus.yaml      | 14 ++++++-------
>   .../bindings/leds/qcom,pm8058-led.yaml        |  4 ++--
>   .../bindings/leds/skyworks,aat1290.yaml       |  6 +++---
>   .../bindings/media/cec/cec-gpio.yaml          |  2 +-
>   .../bindings/mmc/samsung,exynos-dw-mshc.yaml  |  2 +-
>   .../devicetree/bindings/mux/mux-consumer.yaml |  4 ++--
>   .../bindings/phy/samsung,mipi-video-phy.yaml  |  4 ++--
>   .../bindings/phy/samsung,usb2-phy.yaml        |  2 +-
>   .../bindings/phy/samsung,usb3-drd-phy.yaml    |  2 +-
>   .../bindings/pinctrl/samsung,pinctrl.yaml     |  2 +-
>   .../bindings/power/renesas,rcar-sysc.yaml     |  2 +-
>   .../bindings/power/reset/restart-handler.yaml |  8 ++++----
>   .../bindings/regulator/maxim,max77802.yaml    |  4 ++--
>   .../bindings/regulator/richtek,rtq2208.yaml   |  2 +-
>   .../bindings/serial/qcom,msm-uartdm.yaml      |  2 +-
>   .../devicetree/bindings/slimbus/slimbus.yaml  |  4 ++--
>   .../bindings/soc/qcom/qcom,apr-services.yaml  |  2 +-
>   .../bindings/soc/qcom/qcom,rpmh-rsc.yaml      |  8 ++++----
>   .../bindings/soc/qcom/qcom,wcnss.yaml         |  2 +-
>   .../bindings/soc/renesas/renesas-soc.yaml     |  4 ++--
>   .../bindings/sound/qcom,q6asm-dais.yaml       |  2 +-
>   .../thermal/samsung,exynos-thermal.yaml       |  4 ++--

Acked-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com> # thermal


^ permalink raw reply

* [PATCH 1/2] pinctrl: qcom: Drop unnecessary bitmap_fill() call
From: Hans de Goede @ 2026-06-23 12:27 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij; +Cc: Hans de Goede, linux-arm-msm, linux-gpio

Drop an unnecessary bitmap_fill() call from msm_gpio_irq_init_valid_mask(),
this is unnecessary because gpiochip_allocate_mask() already does this.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 drivers/pinctrl/qcom/pinctrl-msm.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index c2938494c6bb..419342ab45e1 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1047,8 +1047,6 @@ static void msm_gpio_irq_init_valid_mask(struct gpio_chip *gc,
 	const struct msm_pingroup *g;
 	int i;
 
-	bitmap_fill(valid_mask, ngpios);
-
 	for (i = 0; i < ngpios; i++) {
 		g = &pctrl->soc->groups[i];
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH 2/2] pinctrl: qcom: Drop unused irq_data argument from msm_gpio_update_dual_edge_pos()
From: Hans de Goede @ 2026-06-23 12:27 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij; +Cc: Hans de Goede, linux-arm-msm, linux-gpio
In-Reply-To: <20260623122732.6439-1-johannes.goede@oss.qualcomm.com>

The "struct irq_data *d" argument to msm_gpio_update_dual_edge_pos() is
unused, drop it.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 drivers/pinctrl/qcom/pinctrl-msm.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 419342ab45e1..f780bab51d9c 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -810,8 +810,7 @@ static const struct gpio_chip msm_gpio_template = {
  * Algorithm comes from Google's msmgpio driver.
  */
 static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
-					  const struct msm_pingroup *g,
-					  struct irq_data *d)
+					  const struct msm_pingroup *g)
 {
 	int loop_limit = 100;
 	unsigned val, val2, intstat;
@@ -1015,7 +1014,7 @@ static void msm_gpio_irq_ack(struct irq_data *d)
 	msm_ack_intr_status(pctrl, g);
 
 	if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
-		msm_gpio_update_dual_edge_pos(pctrl, g, d);
+		msm_gpio_update_dual_edge_pos(pctrl, g);
 
 	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
@@ -1190,7 +1189,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 		msm_ack_intr_status(pctrl, g);
 
 	if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
-		msm_gpio_update_dual_edge_pos(pctrl, g, d);
+		msm_gpio_update_dual_edge_pos(pctrl, g);
 
 	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH 0/2] gpio: fix sleeping-in-atomic in shared-proxy; restore meson non-sleeping
From: Robin Murphy @ 2026-06-23 15:16 UTC (permalink / raw)
  To: Marek Szyprowski, Viacheslav Bocharov, Linus Walleij,
	Bartosz Golaszewski
  Cc: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
	Diederik de Haas, linux-gpio, linux-arm-kernel, linux-amlogic,
	linux-kernel, linux-rockchip, Heiko Stuebner
In-Reply-To: <184d315b-a0a1-4792-8a40-1b4967025916@samsung.com>

On 11/06/2026 9:26 am, Marek Szyprowski wrote:
> Hi Viachesla,
> 
> On 10.06.2026 17:32, Viacheslav Bocharov wrote:
>> gpio-shared-proxy chooses its descriptor lock (mutex vs spinlock) from
>> the underlying chip's can_sleep, but under that lock it calls config and
>> direction ops that reach sleeping pinctrl paths. On a controller with
>> non-sleeping MMIO value ops the lock is a spinlock, so a sleeping call
>> runs from atomic context:
>>
>>    BUG: sleeping function called from invalid context
>>      ... pinctrl_gpio_set_config <- gpiochip_generic_config
>>      <- gpio_shared_proxy_set_config (voting spinlock held)
>>      <- ... <- mmc_pwrseq_simple_probe
>>
>> This was reported on Khadas VIM3 and worked around for Amlogic by
>> commit 28f240683871 ("pinctrl: meson: mark the GPIO controller as
>> sleeping"), which marked the whole meson controller sleeping. That
>> workaround broke atomic value-path consumers: w1-gpio (1-Wire bitbang)
>> no longer detects devices, because its IRQ-disabled read slot calls the
>> non-cansleep gpiod_*_value() and now hits WARN_ON(can_sleep) per bit.
>>
>> Patch 1 fixes the proxy locking generically (always a sleeping mutex).
>> Patch 2 then restores meson can_sleep=false, fixing 1-Wire.
>>
>> Patch 1 has a trade-off: a proxied GPIO becomes sleeping, so consumers
>> gating on gpiod_cansleep() change behaviour. No current device needs
>> atomic (non-cansleep) value access on a shared GPIO -- every report
>> (Khadas VIM3, ODROID-M1, my test on JetHub D1+) is a shared reset line
>> (eMMC/SDIO pwrseq or PCIe reset) driven through the cansleep accessors,
>> which is what the proxy exists to vote on. An alternative that keeps
>> atomic value access (split locking) is possible but adds a second lock
>> and new race windows. I went with the simpler, verified approach and
>> would appreciate guidance on whether the atomic value path must be
>> preserved.
>>
>> The two are a unit: patch 2 must not be applied without patch 1,
>> otherwise the original VIM3 splat returns on boards that share a meson
>> GPIO -- please keep the order. I have not Cc'd stable; I will request
>> stable backports separately once both patches have landed.
>>
>> Viacheslav Bocharov (2):
>>    gpio: shared-proxy: always serialize with a sleeping mutex
>>    pinctrl: meson: restore non-sleeping GPIO access
> 
> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> 
> This probably also affects the similar changes in Rockchip GPIO driver done
> by the following commits:
> 20cf2aed89ac ("gpio: rockchip: mark the GPIO controller as sleeping")
> 7ca497be0016 ("gpio: rockchip: Stop calling pinctrl for set_direction")
> 
> I've checked this patchset with these two reverted and no warning was reported.

If it hadn't already been fixed, then indeed I guess this might make 
20cf2aed89ac redundant. However, 7ca497be0016 is still an objective 
improvement either way, since that driver never needed to call pinctrl 
at all (it was seemingly just an artefact of how the GPIO code was 
originally implemented within the pinctrl driver itself).

Thanks,
Robin.

^ permalink raw reply

* Re: [PATCH 1/2] pinctrl: qcom: Drop unnecessary bitmap_fill() call
From: Mukesh Ojha @ 2026-06-23 15:44 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Bjorn Andersson, Linus Walleij, linux-arm-msm, linux-gpio
In-Reply-To: <20260623122732.6439-1-johannes.goede@oss.qualcomm.com>

On Tue, Jun 23, 2026 at 02:27:31PM +0200, Hans de Goede wrote:
> Drop an unnecessary bitmap_fill() call from msm_gpio_irq_init_valid_mask(),
> this is unnecessary because gpiochip_allocate_mask() already does this.
> 
> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> ---
>  drivers/pinctrl/qcom/pinctrl-msm.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> index c2938494c6bb..419342ab45e1 100644
> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> @@ -1047,8 +1047,6 @@ static void msm_gpio_irq_init_valid_mask(struct gpio_chip *gc,
>  	const struct msm_pingroup *g;
>  	int i;
>  
> -	bitmap_fill(valid_mask, ngpios);
> -
>  	for (i = 0; i < ngpios; i++) {
>  		g = &pctrl->soc->groups[i];
>  

Reviewed-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

-- 
-Mukesh Ojha

^ permalink raw reply

* Re: [PATCH 2/2] pinctrl: qcom: Drop unused irq_data argument from msm_gpio_update_dual_edge_pos()
From: Mukesh Ojha @ 2026-06-23 15:52 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Bjorn Andersson, Linus Walleij, linux-arm-msm, linux-gpio
In-Reply-To: <20260623122732.6439-2-johannes.goede@oss.qualcomm.com>

On Tue, Jun 23, 2026 at 02:27:32PM +0200, Hans de Goede wrote:
> The "struct irq_data *d" argument to msm_gpio_update_dual_edge_pos() is
> unused, drop it.
> 
> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> ---
>  drivers/pinctrl/qcom/pinctrl-msm.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> index 419342ab45e1..f780bab51d9c 100644
> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> @@ -810,8 +810,7 @@ static const struct gpio_chip msm_gpio_template = {
>   * Algorithm comes from Google's msmgpio driver.
>   */
>  static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
> -					  const struct msm_pingroup *g,
> -					  struct irq_data *d)
> +					  const struct msm_pingroup *g)
>  {
>  	int loop_limit = 100;
>  	unsigned val, val2, intstat;
> @@ -1015,7 +1014,7 @@ static void msm_gpio_irq_ack(struct irq_data *d)
>  	msm_ack_intr_status(pctrl, g);
>  
>  	if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
> -		msm_gpio_update_dual_edge_pos(pctrl, g, d);
> +		msm_gpio_update_dual_edge_pos(pctrl, g);
>  
>  	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
>  }
> @@ -1190,7 +1189,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
>  		msm_ack_intr_status(pctrl, g);
>  
>  	if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
> -		msm_gpio_update_dual_edge_pos(pctrl, g, d);
> +		msm_gpio_update_dual_edge_pos(pctrl, g);
>  
>  	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
>  
> -- 
> 2.54.0
> 

Reviewed-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

-- 
-Mukesh Ojha

^ permalink raw reply

* Re: [PATCH 1/2] pinctrl: qcom: Drop unnecessary bitmap_fill() call
From: Mukesh Ojha @ 2026-06-23 16:04 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Bjorn Andersson, Linus Walleij, linux-arm-msm, linux-gpio
In-Reply-To: <20260623122732.6439-1-johannes.goede@oss.qualcomm.com>

On Tue, Jun 23, 2026 at 02:27:31PM +0200, Hans de Goede wrote:
> Drop an unnecessary bitmap_fill() call from msm_gpio_irq_init_valid_mask(),
> this is unnecessary because gpiochip_allocate_mask() already does this.
> 
> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> ---
>  drivers/pinctrl/qcom/pinctrl-msm.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> index c2938494c6bb..419342ab45e1 100644
> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> @@ -1047,8 +1047,6 @@ static void msm_gpio_irq_init_valid_mask(struct gpio_chip *gc,
>  	const struct msm_pingroup *g;
>  	int i;
>  
> -	bitmap_fill(valid_mask, ngpios);
> -
>  	for (i = 0; i < ngpios; i++) {
>  		g = &pctrl->soc->groups[i];
>  
> -- 
> 2.54.0
> 

Looks like you missed to add kernel mailing list to the series.

-- 
-Mukesh Ojha

^ permalink raw reply

* Re: [PATCH 1/2] pinctrl: qcom: Drop unnecessary bitmap_fill() call
From: Hans de Goede @ 2026-06-23 17:33 UTC (permalink / raw)
  To: Mukesh Ojha; +Cc: Bjorn Andersson, Linus Walleij, linux-arm-msm, linux-gpio
In-Reply-To: <20260623160457.j66dlzxfkvn3jxuj@hu-mojha-hyd.qualcomm.com>

Hi,

Thank you for the reviews.

On 23-Jun-26 18:04, Mukesh Ojha wrote:
> On Tue, Jun 23, 2026 at 02:27:31PM +0200, Hans de Goede wrote:
>> Drop an unnecessary bitmap_fill() call from msm_gpio_irq_init_valid_mask(),
>> this is unnecessary because gpiochip_allocate_mask() already does this.
>>
>> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
>> ---
>>  drivers/pinctrl/qcom/pinctrl-msm.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
>> index c2938494c6bb..419342ab45e1 100644
>> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
>> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
>> @@ -1047,8 +1047,6 @@ static void msm_gpio_irq_init_valid_mask(struct gpio_chip *gc,
>>  	const struct msm_pingroup *g;
>>  	int i;
>>  
>> -	bitmap_fill(valid_mask, ngpios);
>> -
>>  	for (i = 0; i < ngpios; i++) {
>>  		g = &pctrl->soc->groups[i];
>>  
>> -- 
>> 2.54.0
>>
> 
> Looks like you missed to add kernel mailing list to the series.

You mean lkml ? Generally speaking I don't add that to series which
are subsytem specific and not really interesting for a wider audience.

Regards,

Hans




^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: clock: Drop incorrect usage of double '::'
From: Andi Shyti @ 2026-06-23 20:26 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-clk, dri-devel, freedreno, linux-i2c,
	linux-pm, linux-leds, linux-media, linux-mmc, linux-phy,
	linux-gpio, linux-renesas-soc, linux-serial, linux-sound,
	linux-usb
In-Reply-To: <20260623054842.21831-3-krzysztof.kozlowski@oss.qualcomm.com>

Hi Krzysztof,

On Tue, Jun 23, 2026 at 07:48:43AM +0200, Krzysztof Kozlowski wrote:
> There is no use of double colon '::' in YAML. OTOH, the literal style
> block, e.g. using '|' treats all characters as content [1] therefore
> single use of ':' in descriptions is perfectly fine, whenever '|' is
> used.
> 
> Cleanup existing code, so the confusing style won't be re-used in new
> contributions.
> 
> Link: https://yaml.org/spec/1.2.2/#literal-style [1]
> Acked-by: Alim Akhtar <alim.akhtar@samsung.com>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Acked-by: Andi Shyti <andi.shyti@kernel.org>

Thanks,
Andi

^ permalink raw reply

* Re: [PATCH v2 2/2] dt-bindings: Drop incorrect usage of double '::'
From: Andi Shyti @ 2026-06-23 20:26 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, linux-clk, dri-devel, freedreno, linux-i2c,
	linux-pm, linux-leds, linux-media, linux-mmc, linux-phy,
	linux-gpio, linux-renesas-soc, linux-serial, linux-sound,
	linux-usb
In-Reply-To: <20260623054842.21831-4-krzysztof.kozlowski@oss.qualcomm.com>

Hi Krzysztof,

On Tue, Jun 23, 2026 at 07:48:44AM +0200, Krzysztof Kozlowski wrote:
> There is no use of double colon '::' in YAML. OTOH, the literal style
> block, e.g. using '|' treats all characters as content [1] therefore
> single use of ':' in descriptions is perfectly fine, whenever '|' is
> used.
> 
> Cleanup existing code, so the confusing style won't be re-used in new
> contributions.
> 
> Link: https://yaml.org/spec/1.2.2/#literal-style [1]
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> Acked-by: Alim Akhtar <alim.akhtar@samsung.com>
> Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> Acked-by: Mark Brown <broonie@kernel.org>
> Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> # renesas
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Acked-by: Andi Shyti <andi.shyti@kernel.org>

Thanks,
Andi

^ permalink raw reply

* [PATCH] gpio: pca9570: Use I2C match data
From: Pengpeng Hou @ 2026-06-24  5:37 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski; +Cc: linux-gpio, linux-kernel, Pengpeng Hou

The driver stores chip metadata in both the OF match table and the I2C
id table, but probe currently reads it with device_get_match_data().
That helper only returns firmware-node match data, so an I2C-id/modalias
match can leave chip_data NULL before the driver dereferences it to read
ngpio.

Use i2c_get_match_data() so the I2C id table driver_data is consumed
when firmware match data is not present.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/gpio/gpio-pca9570.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-pca9570.c b/drivers/gpio/gpio-pca9570.c
index 4a368803fb03..f0c2fea0f6fe 100644
--- a/drivers/gpio/gpio-pca9570.c
+++ b/drivers/gpio/gpio-pca9570.c
@@ -133,7 +133,7 @@ static int pca9570_probe(struct i2c_client *client)
 	gpio->chip.get = pca9570_get;
 	gpio->chip.set = pca9570_set;
 	gpio->chip.base = -1;
-	gpio->chip_data = device_get_match_data(&client->dev);
+	gpio->chip_data = i2c_get_match_data(client);
 	gpio->chip.ngpio = gpio->chip_data->ngpio;
 	gpio->chip.can_sleep = true;
 
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCH 0/2] gpio: fix sleeping-in-atomic in shared-proxy; restore meson non-sleeping
From: Bartosz Golaszewski @ 2026-06-24  7:25 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
	Diederik de Haas, linux-gpio, linux-arm-kernel, linux-amlogic,
	linux-kernel, linux-rockchip, Heiko Stuebner, Marek Szyprowski,
	Viacheslav Bocharov, Linus Walleij, Bartosz Golaszewski
In-Reply-To: <112d2563-e650-4881-bba0-335f6a3fcb8a@arm.com>

On Tue, 23 Jun 2026 17:16:44 +0200, Robin Murphy <robin.murphy@arm.com> said:
> On 11/06/2026 9:26 am, Marek Szyprowski wrote:
>> Hi Viachesla,
>>
>> On 10.06.2026 17:32, Viacheslav Bocharov wrote:
>>> gpio-shared-proxy chooses its descriptor lock (mutex vs spinlock) from
>>> the underlying chip's can_sleep, but under that lock it calls config and
>>> direction ops that reach sleeping pinctrl paths. On a controller with
>>> non-sleeping MMIO value ops the lock is a spinlock, so a sleeping call
>>> runs from atomic context:
>>>

...

>>
>> I've checked this patchset with these two reverted and no warning was reported.
>
> If it hadn't already been fixed (...)
>

About that - Viacheslav, do you still plan to submit v2 of this?

Bart

^ permalink raw reply

* Re: [PATCH 1/2] pinctrl: qcom: Drop unnecessary bitmap_fill() call
From: Konrad Dybcio @ 2026-06-24  7:41 UTC (permalink / raw)
  To: Hans de Goede, Bjorn Andersson, Linus Walleij; +Cc: linux-arm-msm, linux-gpio
In-Reply-To: <20260623122732.6439-1-johannes.goede@oss.qualcomm.com>

On 6/23/26 2:27 PM, Hans de Goede wrote:
> Drop an unnecessary bitmap_fill() call from msm_gpio_irq_init_valid_mask(),
> this is unnecessary because gpiochip_allocate_mask() already does this.
> 
> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

^ permalink raw reply

* Re: [PATCH 2/2] pinctrl: qcom: Drop unused irq_data argument from msm_gpio_update_dual_edge_pos()
From: Konrad Dybcio @ 2026-06-24  7:43 UTC (permalink / raw)
  To: Hans de Goede, Bjorn Andersson, Linus Walleij; +Cc: linux-arm-msm, linux-gpio
In-Reply-To: <20260623122732.6439-2-johannes.goede@oss.qualcomm.com>

On 6/23/26 2:27 PM, Hans de Goede wrote:
> The "struct irq_data *d" argument to msm_gpio_update_dual_edge_pos() is
> unused, drop it.
> 
> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

^ permalink raw reply

* [brgl:gpio/for-current] BUILD SUCCESS 4e8eb6952aa6749726c6c3763ae0032a6332c24f
From: kernel test robot @ 2026-06-24  7:49 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: 4e8eb6952aa6749726c6c3763ae0032a6332c24f  gpio: davinci: fix IRQ domain leak on devm_kzalloc failure

elapsed time: 913m

configs tested: 218
configs skipped: 4

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-20260624    gcc-15.2.0
arc                   randconfig-002-20260624    gcc-15.2.0
arm                               allnoconfig    gcc-16.1.0
arm                              allyesconfig    clang-23
arm                                 defconfig    gcc-16.1.0
arm                   randconfig-001-20260624    gcc-15.2.0
arm                   randconfig-002-20260624    gcc-15.2.0
arm                   randconfig-003-20260624    gcc-15.2.0
arm                   randconfig-004-20260624    gcc-15.2.0
arm                           sama5_defconfig    gcc-16.1.0
arm                        vexpress_defconfig    gcc-16.1.0
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-16.1.0
arm64                               defconfig    gcc-16.1.0
arm64                 randconfig-001-20260624    clang-21
arm64                 randconfig-002-20260624    clang-21
arm64                 randconfig-003-20260624    clang-21
arm64                 randconfig-004-20260624    clang-21
csky                             allmodconfig    gcc-16.1.0
csky                              allnoconfig    gcc-16.1.0
csky                                defconfig    gcc-16.1.0
csky                  randconfig-001-20260624    clang-21
csky                  randconfig-002-20260624    clang-21
hexagon                          allmodconfig    gcc-16.1.0
hexagon                           allnoconfig    gcc-16.1.0
hexagon                             defconfig    gcc-16.1.0
hexagon                        randconfig-001    gcc-11.5.0
hexagon               randconfig-001-20260624    gcc-11.5.0
hexagon               randconfig-001-20260624    gcc-9.5.0
hexagon                        randconfig-002    gcc-11.5.0
hexagon               randconfig-002-20260624    gcc-11.5.0
hexagon               randconfig-002-20260624    gcc-9.5.0
i386                             allmodconfig    clang-22
i386                              allnoconfig    gcc-16.1.0
i386                             allyesconfig    clang-22
i386                 buildonly-randconfig-001    gcc-12
i386        buildonly-randconfig-001-20260624    gcc-12
i386                 buildonly-randconfig-002    gcc-12
i386        buildonly-randconfig-002-20260624    gcc-12
i386                 buildonly-randconfig-003    gcc-12
i386        buildonly-randconfig-003-20260624    gcc-12
i386                 buildonly-randconfig-004    gcc-12
i386        buildonly-randconfig-004-20260624    gcc-12
i386                 buildonly-randconfig-005    gcc-12
i386        buildonly-randconfig-005-20260624    gcc-12
i386                 buildonly-randconfig-006    gcc-12
i386        buildonly-randconfig-006-20260624    gcc-12
i386                                defconfig    gcc-16.1.0
i386                           randconfig-001    clang-22
i386                  randconfig-001-20260624    clang-22
i386                           randconfig-002    clang-22
i386                  randconfig-002-20260624    clang-22
i386                           randconfig-003    clang-22
i386                  randconfig-003-20260624    clang-22
i386                           randconfig-004    clang-22
i386                  randconfig-004-20260624    clang-22
i386                           randconfig-005    clang-22
i386                  randconfig-005-20260624    clang-22
i386                           randconfig-006    clang-22
i386                  randconfig-006-20260624    clang-22
i386                           randconfig-007    clang-22
i386                  randconfig-007-20260624    clang-22
i386                  randconfig-011-20260624    clang-22
i386                  randconfig-012-20260624    clang-22
i386                  randconfig-013-20260624    clang-22
i386                  randconfig-014-20260624    clang-22
i386                  randconfig-015-20260624    clang-22
i386                  randconfig-016-20260624    clang-22
i386                  randconfig-017-20260624    clang-22
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    gcc-16.1.0
loongarch                           defconfig    clang-23
loongarch                      randconfig-001    gcc-11.5.0
loongarch             randconfig-001-20260624    gcc-11.5.0
loongarch             randconfig-001-20260624    gcc-9.5.0
loongarch                      randconfig-002    gcc-11.5.0
loongarch             randconfig-002-20260624    gcc-11.5.0
loongarch             randconfig-002-20260624    gcc-9.5.0
m68k                             allmodconfig    gcc-16.1.0
m68k                              allnoconfig    gcc-16.1.0
m68k                             allyesconfig    clang-23
m68k                                defconfig    clang-23
m68k                        stmark2_defconfig    gcc-16.1.0
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                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                               defconfig    clang-23
nios2                          randconfig-001    gcc-11.5.0
nios2                 randconfig-001-20260624    gcc-11.5.0
nios2                 randconfig-001-20260624    gcc-9.5.0
nios2                          randconfig-002    gcc-11.5.0
nios2                 randconfig-002-20260624    gcc-11.5.0
nios2                 randconfig-002-20260624    gcc-9.5.0
openrisc                         allmodconfig    clang-20
openrisc                         allmodconfig    gcc-16.1.0
openrisc                          allnoconfig    clang-23
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-20260624    gcc-16.1.0
parisc                randconfig-002-20260624    gcc-16.1.0
parisc64                            defconfig    clang-23
powerpc                          allmodconfig    gcc-16.1.0
powerpc                           allnoconfig    clang-23
powerpc                     asp8347_defconfig    clang-23
powerpc                        fsp2_defconfig    gcc-16.1.0
powerpc               randconfig-001-20260624    gcc-16.1.0
powerpc               randconfig-002-20260624    gcc-16.1.0
powerpc64             randconfig-001-20260624    gcc-16.1.0
powerpc64             randconfig-002-20260624    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    clang-18
riscv                 randconfig-001-20260624    clang-18
riscv                          randconfig-002    clang-18
riscv                 randconfig-002-20260624    clang-18
s390                             allmodconfig    clang-17
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-16.1.0
s390                                defconfig    gcc-16.1.0
s390                           randconfig-001    clang-18
s390                  randconfig-001-20260624    clang-18
s390                           randconfig-002    clang-18
s390                  randconfig-002-20260624    clang-18
sh                               allmodconfig    gcc-16.1.0
sh                                allnoconfig    clang-23
sh                               allyesconfig    clang-17
sh                                  defconfig    gcc-14
sh                             randconfig-001    clang-18
sh                    randconfig-001-20260624    clang-18
sh                             randconfig-002    clang-18
sh                    randconfig-002-20260624    clang-18
sparc                             allnoconfig    clang-23
sparc                               defconfig    gcc-16.1.0
sparc                 randconfig-001-20260624    gcc-14.3.0
sparc                 randconfig-002-20260624    gcc-14.3.0
sparc                       sparc32_defconfig    gcc-16.1.0
sparc64                          allmodconfig    clang-20
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260624    gcc-14.3.0
sparc64               randconfig-002-20260624    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-20260624    gcc-14.3.0
um                    randconfig-002-20260624    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-20260624    clang-22
x86_64               buildonly-randconfig-002    clang-22
x86_64      buildonly-randconfig-002-20260624    clang-22
x86_64               buildonly-randconfig-003    clang-22
x86_64      buildonly-randconfig-003-20260624    clang-22
x86_64               buildonly-randconfig-004    clang-22
x86_64      buildonly-randconfig-004-20260624    clang-22
x86_64               buildonly-randconfig-005    clang-22
x86_64      buildonly-randconfig-005-20260624    clang-22
x86_64               buildonly-randconfig-006    clang-22
x86_64      buildonly-randconfig-006-20260624    clang-22
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-22
x86_64                         randconfig-001    clang-22
x86_64                randconfig-001-20260624    clang-22
x86_64                         randconfig-002    clang-22
x86_64                randconfig-002-20260624    clang-22
x86_64                         randconfig-003    clang-22
x86_64                randconfig-003-20260624    clang-22
x86_64                         randconfig-004    clang-22
x86_64                randconfig-004-20260624    clang-22
x86_64                         randconfig-005    clang-22
x86_64                randconfig-005-20260624    clang-22
x86_64                         randconfig-006    clang-22
x86_64                randconfig-006-20260624    clang-22
x86_64                randconfig-011-20260624    gcc-14
x86_64                randconfig-012-20260624    gcc-14
x86_64                randconfig-013-20260624    gcc-14
x86_64                randconfig-014-20260624    gcc-14
x86_64                randconfig-015-20260624    gcc-14
x86_64                randconfig-016-20260624    gcc-14
x86_64                randconfig-071-20260624    gcc-14
x86_64                randconfig-072-20260624    gcc-14
x86_64                randconfig-073-20260624    gcc-14
x86_64                randconfig-074-20260624    gcc-14
x86_64                randconfig-075-20260624    gcc-14
x86_64                randconfig-076-20260624    gcc-14
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-20260624    gcc-14.3.0
xtensa                randconfig-002-20260624    gcc-14.3.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH 1/1] x86/vm86: fix vm86 struct leak on copy_from_user() failure
From: fffsqian @ 2026-06-24  9:26 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	hpa, Kees Cook, Andy Lutomirski, Brian Gerst
  Cc: linux-gpio, Qingshuang Fu

From: Qingshuang Fu <fuqingshuang@kylinos.cn>

When copy_from_user() fails during vm86 setup in do_sys_vm86(),
the newly allocated vm86 structure is not freed, leading to a
memory leak that can be exploited by users with appropriate
privileges to cause DoS through resource exhaustion.

The leak occurs in multiple error paths after kzalloc_obj()
successfully allocates the vm86 structure and assigns it to
tsk->thread.vm86. Subsequent copy_from_user() failures for
vm86_struct, int_revectored, int21_revectored, or vm86plus data
leave the allocated memory orphaned.

Fix this by introducing a 'newly_allocated' boolean to distinguish
between newly created and pre-existing vm86 contexts. Use a
centralized cleanup path via goto to properly release memory in
all error scenarios while preserving existing vm86 states.

Security impact: This memory leak can lead to system DoS via OOM if
exploited by unprivileged local users, provided the system has
mmap_min_addr set to 0. The regression was introduced in commit
9fda6a0681e0 ("x86/vm86: Move vm86 fields out of 'thread_struct'") back
in 2015, and affects all 32-bit x86 kernels built with CONFIG_VM86
enabled.

Fixes: 9fda6a0681e0 ("x86/vm86: Move vm86 fields out of 'thread_struct'")
Signed-off-by: Qingshuang Fu <fuqingshuang@kylinos.cn>
---
 arch/x86/kernel/vm86_32.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index b4c1cabc7a4b..cde077f2c97e 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -202,7 +202,8 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 	struct vm86 *vm86 = tsk->thread.vm86;
 	struct kernel_vm86_regs vm86regs;
 	struct pt_regs *regs = current_pt_regs();
-	unsigned long err = 0;
+	bool newly_allocated = false;
+	long err = 0;
 	struct vm86_struct v;
 
 	err = security_mmap_addr(0);
@@ -235,20 +236,24 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 		if (!(vm86 = kzalloc_obj(*vm86)))
 			return -ENOMEM;
 		tsk->thread.vm86 = vm86;
+		newly_allocated = true;
 	}
 	if (vm86->saved_sp0)
 		return -EPERM;
 
 	if (copy_from_user(&v, user_vm86,
-			offsetof(struct vm86_struct, int_revectored)))
-		return -EFAULT;
+			offsetof(struct vm86_struct, int_revectored))) {
+		err = -EFAULT;
+		goto cleanup;
+	}
 
 
 	/* VM86_SCREEN_BITMAP had numerous bugs and appears to have no users. */
 	if (v.flags & VM86_SCREEN_BITMAP) {
 		pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n",
 			     current->comm);
-		return -EINVAL;
+		err = -EINVAL;
+		goto cleanup;
 	}
 
 	memset(&vm86regs, 0, sizeof(vm86regs));
@@ -275,16 +280,22 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 
 	if (copy_from_user(&vm86->int_revectored,
 			   &user_vm86->int_revectored,
-			   sizeof(struct revectored_struct)))
-		return -EFAULT;
+			   sizeof(struct revectored_struct))) {
+		err = -EFAULT;
+		goto cleanup;
+	}
 	if (copy_from_user(&vm86->int21_revectored,
 			   &user_vm86->int21_revectored,
-			   sizeof(struct revectored_struct)))
-		return -EFAULT;
+			   sizeof(struct revectored_struct))) {
+		err = -EFAULT;
+		goto cleanup;
+	}
 	if (plus) {
 		if (copy_from_user(&vm86->vm86plus, &user_vm86->vm86plus,
-				   sizeof(struct vm86plus_info_struct)))
-			return -EFAULT;
+				   sizeof(struct vm86plus_info_struct))) {
+			err = -EFAULT;
+			goto cleanup;
+		}
 		vm86->vm86plus.is_vm86pus = 1;
 	} else
 		memset(&vm86->vm86plus, 0,
@@ -340,6 +351,13 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 
 	memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
 	return regs->ax;
+
+cleanup:
+	if (newly_allocated) {
+		tsk->thread.vm86 = NULL;
+		kfree(vm86);
+	}
+	return err;
 }
 
 static inline void set_IF(struct kernel_vm86_regs *regs)

base-commit: 840ef6c78e6a2f694b578ecb9063241c992aaa9e
-- 
2.25.1


^ permalink raw reply related

* [PATCH v11] PCI: Add support for PCIe WAKE# interrupt
From: Krishna Chaitanya Chundru @ 2026-06-24 11:25 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, Bjorn Helgaas, Bartosz Golaszewski,
	Linus Walleij, Bartosz Golaszewski, Rob Herring, Saravana Kannan,
	Linus Walleij
  Cc: linux-pm, linux-kernel, linux-pci, linux-gpio, quic_vbadigan,
	sherry.sun, driver-core, devicetree, Manivannan Sadhasivam,
	Krishna Chaitanya Chundru

According to the PCI Express specification (PCIe r7.0, Section 5.3.3.2),
two link wakeup mechanisms are defined: Beacon and WAKE#. Beacon is a
hardware-only mechanism and is invisible to software (PCIe r7.0,
Section 4.2.7.8.1). This change adds support for the WAKE# mechanism
in the PCI core.

According to the PCIe specification, multiple WAKE# signals can exist in
a system or each component in the hierarchy could share a single WAKE#
signal. In configurations involving a PCIe switch, each downstream port
(DSP) of the switch may be connected to a separate WAKE# line, allowing
each endpoint to signal WAKE# independently. From figure 5.4 in sec
5.3.3.2, WAKE# can also be terminated at the switch itself. Such topologies
are typically not described in Device Tree, therefore it is out of scope
for this series.

To support this, the WAKE# should be described in the device tree node of
the endpoint/bridge. If all endpoints share a single WAKE# line, then each
endpoint node shall describe the same WAKE# signal or a single WAKE# in
the Root Port node.

In pci_device_add(), PCI framework will search for the WAKE# in device
node. Once found, register for the wake IRQ through
dev_pm_set_dedicated_wake_irq() associates a wakeup IRQ with a device
and requests it, but the PM core keeps the IRQ disabled by default. The
IRQ is enabled by the PM core, only when the device is permitted to wake
the system, i.e. during system suspend and after runtime suspend, and
only when device wakeup is enabled.

If the same WAKE# GPIO is described in multiple device tree nodes, only the
first device that successfully registers the wake IRQ will succeed, while
subsequent registrations may fail. This limitation does not affect
functional correctness, since WAKE# is only used to bring the link to D0,
and endpoint-specific wakeup handling is resolved later through
PME detection (PME_EN is set in suspend path by PCI core by default).

When the wake IRQ fires, the wakeirq handler invokes pm_runtime_resume() to
bring the device back to an active power state, such as transitioning from
D3cold to D0. Once the device is active and the link is usable, the
endpoint may generate a PME, which is then handled by the PCI core through
PME polling or the PCIe PME service driver to complete the wakeup of the
endpoint.

WAKE# is added in dts schema and merged based on below links.

Link: https://lore.kernel.org/all/20250515090517.3506772-1-krishna.chundru@oss.qualcomm.com/
Link: https://github.com/devicetree-org/dt-schema/pull/170
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
PCIe WAKE# interrupt is needed for bringing back PCIe device state from
D3cold to D0.

This is pending from long time, there was two attempts done previously to
add WAKE# support[1], [2]. Those series tried to add support for legacy
interrupts along with WAKE#. Legacy interrupts are already available in
the latest kernel and we can ignore them. For the wake IRQ the series is
trying to use interrupts property define in the device tree.

WAKE# is added in dts schema and merged based on this patch.
https://lore.kernel.org/all/20250515090517.3506772-1-krishna.chundru@oss.qualcomm.com/

[1]: https://lore.kernel.org/all/b2b91240-95fe-145d-502c-d52225497a34@nvidia.com/T/
[2]: https://lore.kernel.org/all/20171226023646.17722-1-jeffy.chen@rock-chips.com/
---
Changes in v11:
- Add device_init_wakeup() as client driver is not expected to enable
  bridge dev wakeup capability.
- Link to v10: https://patch.msgid.link/20260511-wakeirq_support-v10-0-c10af9c9eb8c@oss.qualcomm.com

Changes in v10:
- As sashiko pointed, shared irq has plenty of race conditions.
- So we are moving away from the shared IRQ patch and registering with
  dedicated wake irq only, as part of wake irq the link will come to D0
  as the parent controller driver will be runtime resume first and then
  pme service will kick in wake up correct endpoint driver.
- Removed device_init_wakeup() since it enabling wakeup explicitly,
  which is not intended as this should be set by endpoint driver only.
- Link to v9: https://lore.kernel.org/r/20260403-wakeirq_support-v9-0-1cbecf3b58d7@oss.qualcomm.com

Changes in v9:
- Call device_init_wakeup() only if
  dev_pm_set_dedicated_shared_wake_irq() succeeds (Mani).
- Change the IRQ_TYPE from IRQ_TYPE_EDGE_FALLING to IRQ_TYPE_LEVEL_LOW (Mani).
- Link to v8: https://lore.kernel.org/r/20260313-wakeirq_support-v8-0-48a0a702518a@oss.qualcomm.com

Changes in v8:
- Moved the stub functions under CONFIG_OF_IRQ(mani).
- Added the description of how dev_pm_set_dedicated_shared_wake_irq()
  works.
- Link to v7: https://lore.kernel.org/r/20260218-wakeirq_support-v7-0-0d4689830207@oss.qualcomm.com

Changes in v7:
- Updated the commit text (Mani).
- Couple of nits like using pci_err instead of dev_err,
  use platform_pci_configure_wake(), platform_pci_remove_wake() instead
  of calling directly calling pci_configure_of_wake_gpio() & pci_remove_of_wake_gpio() etc (Mani).
- Add a new fwnode_gpiod_get() API that wraps fwnode_gpiod_get_index(..0..), similar to
  devm_fwnode_gpiod_get() (Mani).
- Link to v6: https://lore.kernel.org/r/20251127-wakeirq_support-v6-0-60f581f94205@oss.qualcomm.com

Changes in v6:
- Change the name to dev_pm_set_dedicated_shared_wake_irq() and make the
  changes pointed by (Rafael). 
- Link to v5: https://lore.kernel.org/r/20251107-wakeirq_support-v5-0-464e17f2c20c@oss.qualcomm.com

Changes in v5:
- Enable WAKE# irq only when there is wake -gpios defined in its device
  tree node (Bjorn).
- For legacy bindings for direct atach check in root port if we haven't
  find the wake in the endpoint node.
- Instead of hooking wake in driver bound case, do it in the framework
  irrespective of the driver state (Bjorn).
- Link to v4: https://lore.kernel.org/r/20250801-wake_irq_support-v4-0-6b6639013a1a@oss.qualcomm.com

Changes in v4:
- Move wake from portdrv to core framework to endpoint (Bjorn).
- Added support for multiple WAKE# case (Bjorn). But traverse from
  endpoint upstream port to root port till you get WAKE#. And use
  IRQF_SHARED flag for requesting interrupts.
- Link to v3: https://lore.kernel.org/r/20250605-wake_irq_support-v3-0-7ba56dc909a5@oss.qualcomm.com

Changes in v3:
- Update the commit messages, function names etc as suggested by Mani.
- return wake_irq if returns error (Neil).
- Link to v2: https://lore.kernel.org/r/20250419-wake_irq_support-v2-0-06baed9a87a1@oss.qualcomm.com

Changes in v2:
- Move the wake irq teardown after pcie_port_device_remove
  and move of_pci_setup_wake_irq before pcie_link_rcec (Lukas)
- teardown wake irq in shutdown also.
- Link to v1: https://lore.kernel.org/r/20250401-wake_irq_support-v1-0-d2e22f4a0efd@oss.qualcomm.com

To: Bjorn Helgaas <bhelgaas@google.com>
To: Rob Herring <robh@kernel.org>
To: Saravana Kannan <saravanak@kernel.org>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
 drivers/pci/of.c       | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.c      | 11 ++++++++
 drivers/pci/pci.h      |  2 ++
 drivers/pci/probe.c    |  2 ++
 drivers/pci/remove.c   |  1 +
 include/linux/of_pci.h |  6 ++++
 include/linux/pci.h    |  2 ++
 7 files changed, 100 insertions(+)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 8b18c4ba845c..0f5effe1d702 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -7,6 +7,7 @@
 #define pr_fmt(fmt)	"PCI: OF: " fmt
 
 #include <linux/cleanup.h>
+#include <linux/gpio/consumer.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -15,6 +16,7 @@
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
 #include "pci.h"
 
 #ifdef CONFIG_PCI
@@ -586,6 +588,80 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
 	return irq_create_of_mapping(&oirq);
 }
 EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
+
+static void pci_configure_wake_irq(struct pci_dev *pdev, struct gpio_desc *wake)
+{
+	int ret, wake_irq;
+
+	wake_irq = gpiod_to_irq(wake);
+	if (wake_irq < 0) {
+		pci_err(pdev, "Failed to get wake irq: %d\n", wake_irq);
+		return;
+	}
+
+	/*
+	 * dev_pm_set_dedicated_wake_irq() associates a wakeup IRQ with the
+	 * device and requests it, but the PM core keeps it disabled by default.
+	 * The IRQ is enabled only when the device is allowed to wake the system
+	 * (during system suspend and after runtime suspend), and only if device
+	 * wakeup is enabled.
+	 *
+	 * When the wake IRQ fires, the wakeirq handler invokes pm_runtime_resume()
+	 * to bring the device back to an active power state (e.g. from D3cold to D0).
+	 * Once the device is active and the link is usable, the endpoint may signal
+	 * a PME, which is then handled by the PCI core (either via PME polling or the
+	 * PCIe PME service driver) to wakeup particular endpoint.
+	 */
+	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
+	if (ret < 0) {
+		pci_err(pdev, "Failed to set WAKE# IRQ: %d\n", ret);
+		return;
+	}
+
+	ret = irq_set_irq_type(wake_irq, IRQ_TYPE_LEVEL_LOW);
+	if (ret < 0) {
+		dev_pm_clear_wake_irq(&pdev->dev);
+		pci_err(pdev, "Failed to set irq_type: %d\n", ret);
+		return;
+	}
+
+	device_init_wakeup(&pdev->dev, true);
+}
+
+void pci_configure_of_wake_gpio(struct pci_dev *dev)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+	struct gpio_desc *gpio;
+
+	if (!dn)
+		return;
+	/*
+	 * fwnode_gpiod_get() may fail with -EBUSY (e.g. shared WAKE#), but the
+	 * actual WAKE# trigger from the device would still work and the host
+	 * controller driver will enable power to the topology.
+	 *
+	 * -EPROBE_DEFER cannot be propagated here since pci_device_add() has no
+	 *  retry mechanism.
+	 */
+	gpio = fwnode_gpiod_get(of_fwnode_handle(dn), "wake", GPIOD_IN, NULL);
+	if (!IS_ERR(gpio)) {
+		dev->wake = gpio;
+		pci_configure_wake_irq(dev, gpio);
+	}
+}
+
+void pci_remove_of_wake_gpio(struct pci_dev *dev)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+
+	if (!dn)
+		return;
+
+	device_init_wakeup(&dev->dev, false);
+	dev_pm_clear_wake_irq(&dev->dev);
+	gpiod_put(dev->wake);
+	dev->wake = NULL;
+}
 #endif	/* CONFIG_OF_IRQ */
 
 static int pci_parse_request_of_pci_ranges(struct device *dev,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d34266651ad0..9d9777fe099a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -17,6 +17,7 @@
 #include <linux/lockdep.h>
 #include <linux/msi.h>
 #include <linux/of.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -1123,6 +1124,16 @@ static inline bool platform_pci_bridge_d3(struct pci_dev *dev)
 	return acpi_pci_bridge_d3(dev);
 }
 
+void platform_pci_configure_wake(struct pci_dev *dev)
+{
+	pci_configure_of_wake_gpio(dev);
+}
+
+void platform_pci_remove_wake(struct pci_dev *dev)
+{
+	pci_remove_of_wake_gpio(dev);
+}
+
 /**
  * pci_update_current_state - Read power state of given device and cache it
  * @dev: PCI device to handle.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index e8ad27abb1cf..8633c093385c 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -284,6 +284,8 @@ void pci_msix_init(struct pci_dev *dev);
 bool pci_bridge_d3_possible(struct pci_dev *dev);
 void pci_bridge_d3_update(struct pci_dev *dev);
 int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type);
+void platform_pci_configure_wake(struct pci_dev *dev);
+void platform_pci_remove_wake(struct pci_dev *dev);
 
 static inline bool pci_bus_rrs_vendor_id(u32 l)
 {
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..143b0bd35b3c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2775,6 +2775,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	/* Establish pdev->tsm for newly added (e.g. new SR-IOV VFs) */
 	pci_tsm_init(dev);
 
+	platform_pci_configure_wake(dev);
+
 	pci_npem_create(dev);
 
 	pci_doe_sysfs_init(dev);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index e9d519993853..d781b41e57c4 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -35,6 +35,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
 	if (pci_dev_test_and_set_removed(dev))
 		return;
 
+	platform_pci_remove_wake(dev);
 	pci_doe_sysfs_teardown(dev);
 	pci_npem_remove(dev);
 
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29658c0ee71f..649fe8eafcfa 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -30,12 +30,18 @@ static inline void of_pci_check_probe_only(void) { }
 
 #if IS_ENABLED(CONFIG_OF_IRQ)
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
+void pci_configure_of_wake_gpio(struct pci_dev *dev);
+void pci_remove_of_wake_gpio(struct pci_dev *dev);
 #else
 static inline int
 of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	return 0;
 }
+
+static inline void pci_configure_of_wake_gpio(struct pci_dev *dev) { }
+
+static inline void pci_remove_of_wake_gpio(struct pci_dev *dev) { }
 #endif
 
 #endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..4289b60dcc83 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -588,6 +588,8 @@ struct pci_dev {
 	/* These methods index pci_reset_fn_methods[] */
 	u8 reset_methods[PCI_NUM_RESET_METHODS]; /* In priority order */
 
+	struct gpio_desc *wake; /* Holds WAKE# gpio */
+
 #ifdef CONFIG_PCIE_TPH
 	u16		tph_cap;	/* TPH capability offset */
 	u8		tph_mode;	/* TPH mode */

---
base-commit: 840ef6c78e6a2f694b578ecb9063241c992aaa9e
change-id: 20251104-wakeirq_support-f54c4baa18c5

Best regards,
--  
Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox