* [PATCH v7 00/12] gpio: mxc: probe cleanup
@ 2026-10-27 12:09 Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code Peng Fan (OSS)
` (11 more replies)
0 siblings, 12 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan,
Andy Shevchenko
This is the cleanup portion of the gpio-mxc series, following the bug
fixes merged in [1].
For Linus's comment in [2], I will use a follow up patch set to
update pinctrl-imx and gpio-mxc.
Patches 1-2 are wakeup_pads cleanups: consolidate enable/disable_irq_wake
into irq_set_irq_wake(), and use for_each_set_bit() for the pad wakeup
iteration.
Patch 3 fixes bare 'unsigned' to 'unsigned int' per coding style.
Patches 4-5 replace runtime of_device_is_compatible() calls with static
per-compatible hwdata flags, eliminating repeated string comparisons in
the suspend/resume path.
Patch 6 introduces a local dev variable for readability.
Patch 7 uses a driver-local cleanup guard to disable runtime PM and drop
the probe-scoped pm_runtime_get_noresume() reference on error paths.
Patch 8 converts the remaining probe resources to devres.
Patch 9 switches selected probe error paths to dev_err_probe().
Patches 10-11 are cosmetic: MXC_ICR macros with icr_update_edge()/
icr_get_edge() helpers using field_prep/field_get, and BIT() macro for
single-bit shifts.
Patch 12 adds a maintainer entry for the driver.
[1] https://lore.kernel.org/all/179206687877.10309.9401675786609225009.b4-ty@oss.qualcomm.com/#r
[2] https://lore.kernel.org/all/CAD++jL=tKnT0qr5chD-fhxgTM-f9kcdFRsKVBbbqionBp9iTyw@mail.gmail.com/
Changes in v7:
- Drop the three bug-fix patches merged separately; this series contains
cleanup patches only.
- New patch 3: fix bare 'unsigned' to 'unsigned int' (Andy Shevchenko).
- Patch 7: combine pm_runtime_disable() and pm_runtime_put_noidle() into
a driver-local cleanup guard, so runtime PM is disabled before the
probe reference is dropped. Keep the cleanup helper local to gpio-mxc
instead of adding it to pm_runtime.h.
- Patch 8: convert the remaining probe resources to devres and drop the
devm_pm_runtime_set_active_enabled() conversion; runtime PM stays
non-managed.
- Patch 9: also use dev_err_probe() for the platform_irq_count() and
devm_clk_get_optional_enabled() failures, while leaving helpers that
already report errors alone.
- Patch 12: add a MAINTAINERS entry for gpio-mxc.
- Link to v6: https://lore.kernel.org/all/20261011-gpio-mxc-cleanup-v6-0-cb47ce2ad758@nxp.com/
Changes in v6:
- Patch 9: use retain_and_null_ptr() instead of no_free_ptr() to disarm
the pm_runtime cleanup guard, as the return value is unused (Frank Li).
- Minor commit message rewording for patches 10-12.
- Collect R-b from Frank Li.
- Link to v5: https://patch.msgid.link/20261010-gpio-mxc-cleanup-v5-0-1e59e6ddfa00@nxp.com
Changes in v5:
- New patch 2: fix both_edges race using atomic bitops (set_bit/
clear_bit/test_bit), prompted by review feedback on the BIT() patch.
- Patch 3 (wakeup_pads fix): split the irq_set_irq_wake()
consolidation and for_each_set_bit() conversion into separate cleanup
patches (4-5) for bisectability.
- Patch 7 (pad wakeup hwdata): renamed MXC_GPIO_IS_IMX8QM to
MXC_GPIO_FALL_EDGE_WAKEUP_BROKEN to describe the property, not the
SoC.
- Patch 9 (new): use __free cleanup guard for pm_runtime_get_noresume()
balance instead of devm_pm_runtime_get_noresume(), which would cause a
usage counter underflow on unbind due to the double put (devres +
success-path pm_runtime_put_autosuspend).
- Patch 10 (devres): dropped devm_pm_runtime_get_noresume(); the __free
guard from patch 9 handles the usage counter balance. Fixed stale
&pdev->dev references that should use the local dev variable.
- Patch 11 (dev_err_probe): fixed &pdev->dev references to use dev.
- Reordered series: moved "use local dev variable" before the devres
and dev_err_probe patches so the local variable is available.
- Link to v4: https://patch.msgid.link/20261007-gpio-mxc-cleanup-v4-0-c9f5a8b50df9@nxp.com
Changes in v4:
- Just a resend of V3 with below changes.
Add R-b from Linus for patch 10.
Update commit for patch 2 and drop empty line and separate
for_each_set_bit changes into a new patch Per Andy.
- Link to v3: https://lore.kernel.org/all/20261006-gpio-mxc-cleanup-v3-0-129f93302a90@nxp.com/
Changes in v3:
- Patch ("gpio: mxc: convert probe error handling to devres"):
Replaced pm_runtime_get_noresume() with
devm_pm_runtime_get_noresume() to fix a PM usage counter leak on
probe error paths. The non-devm pm_runtime_get_noresume() was not
balanced by any devres action, so any probe failure after the PM
block (e.g. -EPROBE_DEFER from devm_gpiochip_add_data()) would
leave usage_count permanently elevated, preventing runtime suspend
on re-probe.
Dropped the explicit pm_runtime_put_noidle() on
devm_pm_runtime_set_active_enabled() failure - the devres
registered by devm_pm_runtime_get_noresume() handles the balance
automatically during probe unwind.
- Patch ("gpio: mxc: use local dev variable"):
Keep of_device_is_compatible(), only focus on switching &pdev->dev to
dev.
- Link to v2: https://patch.msgid.link/20261005-gpio-mxc-cleanup-v2-0-bdc3afbb35e2@nxp.com
Changes in V2:
- Reworked compatible-string caching (V1 patch 3) from probe-time bools
in mxc_gpio_port to static hwdata flags with per-compatible data
instances. Split into two patches: one introducing the flags scheme
with MXC_GPIO_HW_DATA_COMMON macro for power_off (patch 3), one
extending it to pad_wakeup and imx8qm (patch 4). (Frank, bot review)
- Replaced devm_pm_runtime_get_noresume() + pm_runtime_set_active() +
devm_pm_runtime_enable() with devm_pm_runtime_set_active_enabled().
Keep plain pm_runtime_get_noresume() (non-devm) for the probe-scoped
reference to avoid usage_count underflow on unbind. (Frank, bot review)
- Replaced irq_domain_create_legacy() + devm_add_action_or_reset() with
devm_irq_domain_instantiate(). Squashed with the PM runtime devres
conversion (V1 patches 4+5) into a single patch (patch 5), since the
goto labels cannot be removed until both resources are devres-managed.
- Split dev_err_probe() conversion into its own patch (patch 6) for
bisectability — patch 5 uses bare returns with correct error values.
- Folded gpio_set_wake_irq() assign_bit simplification (V1 patch 9) into
the wakeup_pads fix (patch 2) where it belongs.
- Used 0x3U (unsigned) in MXC_ICR_MASK() to avoid implementation-defined
behavior when shifting by 30 bits.
- Replaced linux/of.h with linux/property.h to match the
of_device_is_compatible() → device_is_compatible() API change (patch 7).
- Added return-value checks for devm_pm_runtime_set_active_enabled().
- Fixed stale error code returns after devm_irq_alloc_descs() and
devm_irq_domain_instantiate() in the devres conversion patch.
- Link to v1: https://patch.msgid.link/20261003-gpio-mxc-cleanup-v1-0-dad728ce27f2@nxp.com
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Peng Fan (12):
gpio: mxc: use irq_set_irq_wake() to simplify code
gpio: mxc: use for_each_set_bit() to iterate wakeup pads
gpio: mxc: use 'unsigned int' instead of bare 'unsigned'
gpio: mxc: replace of_device_is_compatible() with hwdata flags
gpio: mxc: convert pad wakeup compatible checks to hwdata flags
gpio: mxc: use local dev variable
gpio: mxc: use __free guard for runtime PM cleanup
gpio: mxc: use devres functions to simplify probe code
gpio: mxc: add dev_err_probe() for error paths to help diagnostics
gpio: mxc: introduce MXC_ICR macros and use field_prep/field_get
gpio: mxc: use BIT() macro for single-bit operations
MAINTAINERS: Add an entry for gpio-mxc
MAINTAINERS | 8 ++
drivers/gpio/gpio-mxc.c | 295 ++++++++++++++++++++++++++++--------------------
2 files changed, 181 insertions(+), 122 deletions(-)
---
base-commit: f1ac44c32cba88ad65dcecd4a279661d14e93651
change-id: 20261027-gpio-mxc-cleanup-v7-4-f1163de27591
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 14:09 ` Frank Li
2026-10-27 12:09 ` [PATCH v7 02/12] gpio: mxc: use for_each_set_bit() to iterate wakeup pads Peng Fan (OSS)
` (10 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Simplify the logic by consolidating into a single irq_set_irq_wake()
call based on the enable parameter.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 32ded7b548fb..95dfe199409a 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -326,17 +326,10 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
u32 gpio_idx = d->hwirq;
int ret;
- if (enable) {
- if (port->irq_high && (gpio_idx >= 16))
- ret = enable_irq_wake(port->irq_high);
- else
- ret = enable_irq_wake(port->irq);
- } else {
- if (port->irq_high && (gpio_idx >= 16))
- ret = disable_irq_wake(port->irq_high);
- else
- ret = disable_irq_wake(port->irq);
- }
+ if (port->irq_high && (gpio_idx >= 16))
+ ret = irq_set_irq_wake(port->irq_high, enable);
+ else
+ ret = irq_set_irq_wake(port->irq, enable);
if (ret)
return ret;
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 02/12] gpio: mxc: use for_each_set_bit() to iterate wakeup pads
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 16:35 ` Andy Shevchenko
2026-10-27 12:09 ` [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned' Peng Fan (OSS)
` (9 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan,
Andy Shevchenko
From: Peng Fan <peng.fan@nxp.com>
Use for_each_set_bit() to iterate over the enabled wakeup pads instead
of checking every bit individually.
Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 95dfe199409a..848d7725ccfe 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -599,22 +599,20 @@ static bool mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
IMX_SCU_WAKEUP_LOW_LVL, /* IRQ_TYPE_LEVEL_LOW */
};
- for (i = 0; i < 32; i++) {
- if ((port->wakeup_pads & (1 << i))) {
- type = port->pad_type[i];
- if (enable)
- config = pad_type_map[type];
- else
- config = IMX_SCU_WAKEUP_OFF;
-
- if (is_imx8qm && config == IMX_SCU_WAKEUP_FALL_EDGE) {
- dev_warn_once(port->dev,
- "No falling-edge support for wakeup on i.MX8QM\n");
- config = IMX_SCU_WAKEUP_OFF;
- }
+ for_each_set_bit(i, &port->wakeup_pads, 32) {
+ type = port->pad_type[i];
+ if (enable)
+ config = pad_type_map[type];
+ else
+ config = IMX_SCU_WAKEUP_OFF;
- ret |= mxc_gpio_generic_config(port, i, config);
+ if (is_imx8qm && config == IMX_SCU_WAKEUP_FALL_EDGE) {
+ dev_warn_once(port->dev,
+ "No falling-edge support for wakeup on i.MX8QM\n");
+ config = IMX_SCU_WAKEUP_OFF;
}
+
+ ret |= mxc_gpio_generic_config(port, i, config);
}
return ret;
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned'
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 02/12] gpio: mxc: use for_each_set_bit() to iterate wakeup pads Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 14:10 ` Frank Li
2026-10-27 16:36 ` Andy Shevchenko
2026-10-27 12:09 ` [PATCH v7 04/12] gpio: mxc: replace of_device_is_compatible() with hwdata flags Peng Fan (OSS)
` (8 subsequent siblings)
11 siblings, 2 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan,
Andy Shevchenko
From: Peng Fan <peng.fan@nxp.com>
The kernel coding style prefers 'unsigned int' over bare 'unsigned'.
Fix all instances in struct mxc_gpio_hwdata and mxc_gpio_to_irq().
No functional change.
Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 848d7725ccfe..43868a214c17 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -36,18 +36,18 @@
/* device type dependent stuff */
struct mxc_gpio_hwdata {
- unsigned dr_reg;
- unsigned gdir_reg;
- unsigned psr_reg;
- unsigned icr1_reg;
- unsigned icr2_reg;
- unsigned imr_reg;
- unsigned isr_reg;
+ unsigned int dr_reg;
+ unsigned int gdir_reg;
+ unsigned int psr_reg;
+ unsigned int icr1_reg;
+ unsigned int icr2_reg;
+ unsigned int imr_reg;
+ unsigned int isr_reg;
int edge_sel_reg;
- unsigned low_level;
- unsigned high_level;
- unsigned rise_edge;
- unsigned fall_edge;
+ unsigned int low_level;
+ unsigned int high_level;
+ unsigned int rise_edge;
+ unsigned int fall_edge;
};
struct mxc_gpio_reg_saved {
@@ -367,7 +367,7 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
return rv;
}
-static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
{
struct mxc_gpio_port *port = gpiochip_get_data(gc);
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 04/12] gpio: mxc: replace of_device_is_compatible() with hwdata flags
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (2 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned' Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 05/12] gpio: mxc: convert pad wakeup compatible checks to " Peng Fan (OSS)
` (7 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Replace the runtime of_device_is_compatible() check for "fsl,imx7d-gpio"
with a flags field in mxc_gpio_hwdata to move the power-off capability
from a per-instance bool populated at probe time to static per-compatible
data.
Introduce MXC_GPIO_HAS_POWER_OFF and a dedicated imx7d_gpio_hwdata
instance that carries it, along with a mxc_gpio_has_power_off() helper
that replaces every former port->power_off test.
While at it, factor the register offsets shared by imx35 and imx7d into
a MXC_GPIO_HW_DATA_COMMON macro to avoid duplicating twelve identical
initializers.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 50 ++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 43868a214c17..abff07bd3840 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -34,6 +34,8 @@
#define IMX_SCU_WAKEUP_RISE_EDGE 6
#define IMX_SCU_WAKEUP_HIGH_LVL 7
+#define MXC_GPIO_HAS_POWER_OFF BIT(0)
+
/* device type dependent stuff */
struct mxc_gpio_hwdata {
unsigned int dr_reg;
@@ -48,6 +50,7 @@ struct mxc_gpio_hwdata {
unsigned int high_level;
unsigned int rise_edge;
unsigned int fall_edge;
+ unsigned int flags;
};
struct mxc_gpio_reg_saved {
@@ -71,13 +74,26 @@ struct mxc_gpio_port {
struct device *dev;
unsigned long both_edges;
struct mxc_gpio_reg_saved gpio_saved_reg;
- bool power_off;
bool is_pad_wakeup;
unsigned long wakeup_pads;
u32 pad_type[32];
const struct mxc_gpio_hwdata *hwdata;
};
+#define MXC_GPIO_HW_DATA_COMMON \
+ .dr_reg = 0x00, \
+ .gdir_reg = 0x04, \
+ .psr_reg = 0x08, \
+ .icr1_reg = 0x0c, \
+ .icr2_reg = 0x10, \
+ .imr_reg = 0x14, \
+ .isr_reg = 0x18, \
+ .edge_sel_reg = 0x1c, \
+ .low_level = 0x00, \
+ .high_level = 0x01, \
+ .rise_edge = 0x02, \
+ .fall_edge = 0x03
+
static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
.dr_reg = 0x1c,
.gdir_reg = 0x00,
@@ -109,20 +125,19 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
};
static struct mxc_gpio_hwdata imx35_gpio_hwdata = {
- .dr_reg = 0x00,
- .gdir_reg = 0x04,
- .psr_reg = 0x08,
- .icr1_reg = 0x0c,
- .icr2_reg = 0x10,
- .imr_reg = 0x14,
- .isr_reg = 0x18,
- .edge_sel_reg = 0x1c,
- .low_level = 0x00,
- .high_level = 0x01,
- .rise_edge = 0x02,
- .fall_edge = 0x03,
+ MXC_GPIO_HW_DATA_COMMON,
+};
+
+static struct mxc_gpio_hwdata imx7d_gpio_hwdata = {
+ MXC_GPIO_HW_DATA_COMMON,
+ .flags = MXC_GPIO_HAS_POWER_OFF,
};
+static inline bool mxc_gpio_has_power_off(struct mxc_gpio_port *port)
+{
+ return port->hwdata->flags & MXC_GPIO_HAS_POWER_OFF;
+}
+
#define GPIO_DR (port->hwdata->dr_reg)
#define GPIO_GDIR (port->hwdata->gdir_reg)
#define GPIO_PSR (port->hwdata->psr_reg)
@@ -143,7 +158,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
{ .compatible = "fsl,imx21-gpio", .data = &imx1_imx21_gpio_hwdata },
{ .compatible = "fsl,imx31-gpio", .data = &imx31_gpio_hwdata },
{ .compatible = "fsl,imx35-gpio", .data = &imx35_gpio_hwdata },
- { .compatible = "fsl,imx7d-gpio", .data = &imx35_gpio_hwdata },
+ { .compatible = "fsl,imx7d-gpio", .data = &imx7d_gpio_hwdata },
{ .compatible = "fsl,imx8dxl-gpio", .data = &imx35_gpio_hwdata },
{ .compatible = "fsl,imx8qm-gpio", .data = &imx35_gpio_hwdata },
{ .compatible = "fsl,imx8qxp-gpio", .data = &imx35_gpio_hwdata },
@@ -448,9 +463,6 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (IS_ERR(port->clk))
return PTR_ERR(port->clk);
- if (of_device_is_compatible(np, "fsl,imx7d-gpio"))
- port->power_off = true;
-
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
@@ -542,7 +554,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
static void mxc_gpio_save_regs(struct mxc_gpio_port *port)
{
- if (!port->power_off)
+ if (!mxc_gpio_has_power_off(port))
return;
port->gpio_saved_reg.icr1 = readl(port->base + GPIO_ICR1);
@@ -555,7 +567,7 @@ static void mxc_gpio_save_regs(struct mxc_gpio_port *port)
static void mxc_gpio_restore_regs(struct mxc_gpio_port *port)
{
- if (!port->power_off)
+ if (!mxc_gpio_has_power_off(port))
return;
writel(port->gpio_saved_reg.icr1, port->base + GPIO_ICR1);
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 05/12] gpio: mxc: convert pad wakeup compatible checks to hwdata flags
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (3 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 04/12] gpio: mxc: replace of_device_is_compatible() with hwdata flags Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 06/12] gpio: mxc: use local dev variable Peng Fan (OSS)
` (6 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
mxc_gpio_generic_config() and mxc_gpio_set_pad_wakeup() call
of_device_is_compatible() on every invocation to determine pad wakeup
capability and i.MX8QM-specific behavior. These properties are
invariant for the lifetime of the device.
Extend the hwdata flags scheme introduced in the previous commit with
MXC_GPIO_HAS_PAD_WAKEUP and MXC_GPIO_FALL_EDGE_WAKEUP_BROKEN, adding
dedicated hwdata instances for imx8qm and imx8qxp (also used by imx8dxl).
This replaces the repeated device tree string comparisons in the
suspend/resume path with simple flag tests on static per-compatible
data.
While at it, clean up mxc_gpio_generic_config() to use a local ret
variable for clarity instead of the == 0 comparison.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 46 ++++++++++++++++++++++++++++++++++------------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index abff07bd3840..e7c6fbd811a6 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -35,6 +35,8 @@
#define IMX_SCU_WAKEUP_HIGH_LVL 7
#define MXC_GPIO_HAS_POWER_OFF BIT(0)
+#define MXC_GPIO_HAS_PAD_WAKEUP BIT(1)
+#define MXC_GPIO_FALL_EDGE_WAKEUP_BROKEN BIT(2)
/* device type dependent stuff */
struct mxc_gpio_hwdata {
@@ -133,6 +135,26 @@ static struct mxc_gpio_hwdata imx7d_gpio_hwdata = {
.flags = MXC_GPIO_HAS_POWER_OFF,
};
+static struct mxc_gpio_hwdata imx8qm_gpio_hwdata = {
+ MXC_GPIO_HW_DATA_COMMON,
+ .flags = MXC_GPIO_FALL_EDGE_WAKEUP_BROKEN | MXC_GPIO_HAS_PAD_WAKEUP,
+};
+
+static struct mxc_gpio_hwdata imx8qxp_gpio_hwdata = {
+ MXC_GPIO_HW_DATA_COMMON,
+ .flags = MXC_GPIO_HAS_PAD_WAKEUP,
+};
+
+static inline bool mxc_gpio_fall_edge_wakeup_broken(struct mxc_gpio_port *port)
+{
+ return port->hwdata->flags & MXC_GPIO_FALL_EDGE_WAKEUP_BROKEN;
+}
+
+static inline bool mxc_gpio_has_pad_wakeup(struct mxc_gpio_port *port)
+{
+ return port->hwdata->flags & MXC_GPIO_HAS_PAD_WAKEUP;
+}
+
static inline bool mxc_gpio_has_power_off(struct mxc_gpio_port *port)
{
return port->hwdata->flags & MXC_GPIO_HAS_POWER_OFF;
@@ -159,9 +181,9 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
{ .compatible = "fsl,imx31-gpio", .data = &imx31_gpio_hwdata },
{ .compatible = "fsl,imx35-gpio", .data = &imx35_gpio_hwdata },
{ .compatible = "fsl,imx7d-gpio", .data = &imx7d_gpio_hwdata },
- { .compatible = "fsl,imx8dxl-gpio", .data = &imx35_gpio_hwdata },
- { .compatible = "fsl,imx8qm-gpio", .data = &imx35_gpio_hwdata },
- { .compatible = "fsl,imx8qxp-gpio", .data = &imx35_gpio_hwdata },
+ { .compatible = "fsl,imx8dxl-gpio", .data = &imx8qxp_gpio_hwdata },
+ { .compatible = "fsl,imx8qm-gpio", .data = &imx8qm_gpio_hwdata },
+ { .compatible = "fsl,imx8qxp-gpio", .data = &imx8qxp_gpio_hwdata },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxc_gpio_dt_ids);
@@ -581,15 +603,16 @@ static void mxc_gpio_restore_regs(struct mxc_gpio_port *port)
static bool mxc_gpio_generic_config(struct mxc_gpio_port *port,
unsigned int offset, unsigned long conf)
{
- struct device_node *np = port->dev->of_node;
+ int ret;
+
+ if (!mxc_gpio_has_pad_wakeup(port))
+ return false;
- if (of_device_is_compatible(np, "fsl,imx8dxl-gpio") ||
- of_device_is_compatible(np, "fsl,imx8qxp-gpio") ||
- of_device_is_compatible(np, "fsl,imx8qm-gpio"))
- return (gpiochip_generic_config(&port->gen_gc.gc,
- offset, conf) == 0);
+ ret = gpiochip_generic_config(&port->gen_gc.gc, offset, conf);
+ if (ret)
+ return false;
- return false;
+ return true;
}
static bool mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
@@ -597,7 +620,6 @@ static bool mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
unsigned long config;
bool ret = false;
int i, type;
- bool is_imx8qm = of_device_is_compatible(port->dev->of_node, "fsl,imx8qm-gpio");
static const u32 pad_type_map[] = {
IMX_SCU_WAKEUP_OFF, /* 0 */
@@ -618,7 +640,7 @@ static bool mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
else
config = IMX_SCU_WAKEUP_OFF;
- if (is_imx8qm && config == IMX_SCU_WAKEUP_FALL_EDGE) {
+ if (mxc_gpio_fall_edge_wakeup_broken(port) && config == IMX_SCU_WAKEUP_FALL_EDGE) {
dev_warn_once(port->dev,
"No falling-edge support for wakeup on i.MX8QM\n");
config = IMX_SCU_WAKEUP_OFF;
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 06/12] gpio: mxc: use local dev variable
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (4 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 05/12] gpio: mxc: convert pad wakeup compatible checks to " Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 07/12] gpio: mxc: use __free guard for runtime PM cleanup Peng Fan (OSS)
` (5 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Introduce a local 'struct device *dev' variable to replace repeated
'&pdev->dev' dereferences throughout mxc_gpio_probe(), improving
readability.
No functional change.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index e7c6fbd811a6..21c74b244c1f 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -450,17 +450,18 @@ static int mxc_gpio_probe(struct platform_device *pdev)
{
struct gpio_generic_chip_config config = { };
struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
struct mxc_gpio_port *port;
int irq_count;
int irq_base;
int err;
- port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
- port->dev = &pdev->dev;
- port->hwdata = device_get_match_data(&pdev->dev);
+ port->dev = dev;
+ port->hwdata = device_get_match_data(dev);
port->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(port->base))
@@ -481,13 +482,13 @@ static int mxc_gpio_probe(struct platform_device *pdev)
return port->irq;
/* the controller clock is optional */
- port->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
+ port->clk = devm_clk_get_optional_enabled(dev, NULL);
if (IS_ERR(port->clk))
return PTR_ERR(port->clk);
- pm_runtime_get_noresume(&pdev->dev);
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
/* disable the interrupt and clear the status */
writel(0, port->base + GPIO_IMR);
@@ -504,7 +505,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
} else
port->mx_irq_handler = mx3_gpio_irq_handler;
- config.dev = &pdev->dev;
+ config.dev = dev;
config.sz = 4;
config.dat = port->base + GPIO_PSR;
config.set = port->base + GPIO_DR;
@@ -527,20 +528,20 @@ static int mxc_gpio_probe(struct platform_device *pdev)
else /* silence boot time warning */
port->gen_gc.gc.base = -1;
- irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id());
+ irq_base = devm_irq_alloc_descs(dev, -1, 0, 32, numa_node_id());
if (irq_base < 0) {
err = irq_base;
goto out_bgio;
}
- port->domain = irq_domain_create_legacy(dev_fwnode(&pdev->dev), 32, irq_base, 0,
+ port->domain = irq_domain_create_legacy(dev_fwnode(dev), 32, irq_base, 0,
&irq_domain_simple_ops, NULL);
if (!port->domain) {
err = -ENODEV;
goto out_bgio;
}
- irq_domain_set_pm_device(port->domain, &pdev->dev);
+ irq_domain_set_pm_device(port->domain, dev);
/* gpio-mxc can be a generic irq chip */
err = mxc_gpio_init_gc(port, irq_base);
@@ -552,7 +553,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
* chip visible to consumers immediately, so the IRQ domain and
* generic irq chip must be ready before any to_irq() call.
*/
- err = devm_gpiochip_add_data(&pdev->dev, &port->gen_gc.gc, port);
+ err = devm_gpiochip_add_data(dev, &port->gen_gc.gc, port);
if (err)
goto out_irqdomain_remove;
@@ -561,16 +562,16 @@ static int mxc_gpio_probe(struct platform_device *pdev)
mxc_update_irq_chained_handler(port, true);
platform_set_drvdata(pdev, port);
- pm_runtime_put_autosuspend(&pdev->dev);
+ pm_runtime_put_autosuspend(dev);
return 0;
out_irqdomain_remove:
irq_domain_remove(port->domain);
out_bgio:
- pm_runtime_disable(&pdev->dev);
- pm_runtime_put_noidle(&pdev->dev);
- dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
+ dev_info(dev, "%s failed with errno %d\n", __func__, err);
return err;
}
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 07/12] gpio: mxc: use __free guard for runtime PM cleanup
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (5 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 06/12] gpio: mxc: use local dev variable Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 14:12 ` Frank Li
2026-10-27 12:09 ` [PATCH v7 08/12] gpio: mxc: use devres functions to simplify probe code Peng Fan (OSS)
` (4 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Use a scope-based cleanup guard to disable runtime PM and drop the
probe-scoped pm_runtime_get_noresume() reference on error paths. Disarm
it with retain_and_null_ptr() before the success-path
pm_runtime_put_autosuspend().
The guard keeps the required order: pm_runtime_disable() runs before
pm_runtime_put_noidle(), so dropping the reference cannot trigger a
runtime suspend callback while probe is still unwinding.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 21c74b244c1f..68857730b5e3 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -28,6 +28,20 @@
#include <linux/of.h>
#include <linux/bug.h>
+static void mxc_gpio_pm_release(struct device *dev)
+{
+ if (!dev)
+ return;
+
+ if (pm_runtime_enabled(dev))
+ pm_runtime_disable(dev);
+
+ pm_runtime_put_noidle(dev);
+}
+
+DEFINE_FREE(mxc_gpio_pm_cleanup, struct device *,
+ mxc_gpio_pm_release(_T))
+
#define IMX_SCU_WAKEUP_OFF 0
#define IMX_SCU_WAKEUP_LOW_LVL 4
#define IMX_SCU_WAKEUP_FALL_EDGE 5
@@ -487,6 +501,9 @@ static int mxc_gpio_probe(struct platform_device *pdev)
return PTR_ERR(port->clk);
pm_runtime_get_noresume(dev);
+
+ struct device *pm_guard __free(mxc_gpio_pm_cleanup) = dev;
+
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -562,6 +579,8 @@ static int mxc_gpio_probe(struct platform_device *pdev)
mxc_update_irq_chained_handler(port, true);
platform_set_drvdata(pdev, port);
+
+ retain_and_null_ptr(pm_guard);
pm_runtime_put_autosuspend(dev);
return 0;
@@ -569,8 +588,6 @@ static int mxc_gpio_probe(struct platform_device *pdev)
out_irqdomain_remove:
irq_domain_remove(port->domain);
out_bgio:
- pm_runtime_disable(dev);
- pm_runtime_put_noidle(dev);
dev_info(dev, "%s failed with errno %d\n", __func__, err);
return err;
}
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 08/12] gpio: mxc: use devres functions to simplify probe code
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (6 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 07/12] gpio: mxc: use __free guard for runtime PM cleanup Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 09/12] gpio: mxc: add dev_err_probe() for error paths to help diagnostics Peng Fan (OSS)
` (3 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Replace irq_domain_create_legacy() with devm_irq_domain_instantiate()
and convert the remaining manually-unwound IRQ resources in probe to
devres management.
The runtime PM cleanup guard from the previous commit disables runtime PM
and drops the probe reference on these error returns.
With every allocation after the PM block now devm-managed, the
out_irqdomain_remove and out_bgio labels are no longer needed.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 37 ++++++++++++++++++-------------------
1 file changed, 18 insertions(+), 19 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 68857730b5e3..eeb7d36e6b44 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -465,6 +465,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
struct gpio_generic_chip_config config = { };
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
+ struct irq_domain_info d_info;
struct mxc_gpio_port *port;
int irq_count;
int irq_base;
@@ -531,7 +532,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
err = gpio_generic_chip_init(&port->gen_gc, &config);
if (err)
- goto out_bgio;
+ return err;
port->gen_gc.gc.request = mxc_gpio_request;
port->gen_gc.gc.free = mxc_gpio_free;
@@ -546,24 +547,28 @@ static int mxc_gpio_probe(struct platform_device *pdev)
port->gen_gc.gc.base = -1;
irq_base = devm_irq_alloc_descs(dev, -1, 0, 32, numa_node_id());
- if (irq_base < 0) {
- err = irq_base;
- goto out_bgio;
- }
+ if (irq_base < 0)
+ return irq_base;
+
+ d_info = (struct irq_domain_info) {
+ .fwnode = dev_fwnode(dev),
+ .size = 32,
+ .hwirq_max = 32,
+ .virq_base = irq_base,
+ .ops = &irq_domain_simple_ops,
+ .dev = dev,
+ };
- port->domain = irq_domain_create_legacy(dev_fwnode(dev), 32, irq_base, 0,
- &irq_domain_simple_ops, NULL);
- if (!port->domain) {
- err = -ENODEV;
- goto out_bgio;
- }
+ port->domain = devm_irq_domain_instantiate(dev, &d_info);
+ if (IS_ERR(port->domain))
+ return PTR_ERR(port->domain);
irq_domain_set_pm_device(port->domain, dev);
/* gpio-mxc can be a generic irq chip */
err = mxc_gpio_init_gc(port, irq_base);
if (err < 0)
- goto out_irqdomain_remove;
+ return err;
/*
* Register the GPIO chip last: devm_gpiochip_add_data() makes the
@@ -572,7 +577,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
*/
err = devm_gpiochip_add_data(dev, &port->gen_gc.gc, port);
if (err)
- goto out_irqdomain_remove;
+ return err;
list_add_tail(&port->node, &mxc_gpio_ports);
@@ -584,12 +589,6 @@ static int mxc_gpio_probe(struct platform_device *pdev)
pm_runtime_put_autosuspend(dev);
return 0;
-
-out_irqdomain_remove:
- irq_domain_remove(port->domain);
-out_bgio:
- dev_info(dev, "%s failed with errno %d\n", __func__, err);
- return err;
}
static void mxc_gpio_save_regs(struct mxc_gpio_port *port)
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 09/12] gpio: mxc: add dev_err_probe() for error paths to help diagnostics
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (7 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 08/12] gpio: mxc: use devres functions to simplify probe code Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 14:13 ` Frank Li
2026-10-27 12:09 ` [PATCH v7 10/12] gpio: mxc: introduce MXC_ICR macros and use field_prep/field_get Peng Fan (OSS)
` (2 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Use dev_err_probe() on probe error paths that do not already report the
failure, so that deferred probe reasons are recorded consistently. Leave
the devm_platform_ioremap_resource() and platform_get_irq() paths alone;
those already log their errors.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index eeb7d36e6b44..f816822e36ad 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -484,7 +484,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
irq_count = platform_irq_count(pdev);
if (irq_count < 0)
- return irq_count;
+ return dev_err_probe(dev, irq_count, "Failed to count irq\n");
if (irq_count > 1) {
port->irq_high = platform_get_irq(pdev, 1);
@@ -499,7 +499,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
/* the controller clock is optional */
port->clk = devm_clk_get_optional_enabled(dev, NULL);
if (IS_ERR(port->clk))
- return PTR_ERR(port->clk);
+ return dev_err_probe(dev, PTR_ERR(port->clk), "Failed to get clk\n");
pm_runtime_get_noresume(dev);
@@ -532,7 +532,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
err = gpio_generic_chip_init(&port->gen_gc, &config);
if (err)
- return err;
+ return dev_err_probe(dev, err, "Failed to init gpio chip\n");
port->gen_gc.gc.request = mxc_gpio_request;
port->gen_gc.gc.free = mxc_gpio_free;
@@ -548,7 +548,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
irq_base = devm_irq_alloc_descs(dev, -1, 0, 32, numa_node_id());
if (irq_base < 0)
- return irq_base;
+ return dev_err_probe(dev, irq_base, "Failed to alloc irq desc\n");
d_info = (struct irq_domain_info) {
.fwnode = dev_fwnode(dev),
@@ -561,14 +561,15 @@ static int mxc_gpio_probe(struct platform_device *pdev)
port->domain = devm_irq_domain_instantiate(dev, &d_info);
if (IS_ERR(port->domain))
- return PTR_ERR(port->domain);
+ return dev_err_probe(dev, PTR_ERR(port->domain),
+ "Failed to create irq domain\n");
irq_domain_set_pm_device(port->domain, dev);
/* gpio-mxc can be a generic irq chip */
err = mxc_gpio_init_gc(port, irq_base);
if (err < 0)
- return err;
+ return dev_err_probe(dev, err, "Failed to init generic irq chip\n");
/*
* Register the GPIO chip last: devm_gpiochip_add_data() makes the
@@ -577,7 +578,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
*/
err = devm_gpiochip_add_data(dev, &port->gen_gc.gc, port);
if (err)
- return err;
+ return dev_err_probe(dev, err, "Failed to add gpiochip data\n");
list_add_tail(&port->node, &mxc_gpio_ports);
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 10/12] gpio: mxc: introduce MXC_ICR macros and use field_prep/field_get
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (8 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 09/12] gpio: mxc: add dev_err_probe() for error paths to help diagnostics Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 11/12] gpio: mxc: use BIT() macro for single-bit operations Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 12/12] MAINTAINERS: Add an entry for gpio-mxc Peng Fan (OSS)
11 siblings, 0 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Both gpio_set_irq_type() and mxc_flip_edge() open-code the same ICR
register selection and 2-bit field shift/mask arithmetic with magic
numbers (0x10, 0xf, 0x3).
Introduce two macros:
- MXC_ICR_REG(gpio): selects ICR1 (pins 0-15) or ICR2 (pins 16-31)
- MXC_ICR_MASK(gpio): 2-bit mask at the correct position
Use 0x3U in MXC_ICR_MASK() to avoid implementation-defined behavior
when shifting by 30 bits (pin 15 or 31).
Extract the read-modify-write pattern into icr_update_edge()
and the edge readback into icr_get_edge(), using field_prep() and
field_get() for the shift/extract operations.
No functional change.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index f816822e36ad..87460dab67fa 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -7,6 +7,7 @@
// Authors: Daniel Mack, Juergen Beisert.
// Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
@@ -189,6 +190,9 @@ static inline bool mxc_gpio_has_power_off(struct mxc_gpio_port *port)
#define GPIO_INT_FALL_EDGE (port->hwdata->fall_edge)
#define GPIO_INT_BOTH_EDGES 0x4
+#define MXC_ICR_REG(gpio) (GPIO_ICR1 + (((gpio) & 0x10) >> 2))
+#define MXC_ICR_MASK(gpio) (0x3U << (((gpio) & 0xf) << 1))
+
static const struct of_device_id mxc_gpio_dt_ids[] = {
{ .compatible = "fsl,imx1-gpio", .data = &imx1_imx21_gpio_hwdata },
{ .compatible = "fsl,imx21-gpio", .data = &imx1_imx21_gpio_hwdata },
@@ -211,14 +215,28 @@ static LIST_HEAD(mxc_gpio_ports);
/* Note: This driver assumes 32 GPIOs are handled in one register */
+static void icr_update_edge(struct mxc_gpio_port *port, u32 gpio, u32 edge)
+{
+ void __iomem *reg = port->base;
+ u32 val;
+
+ reg += MXC_ICR_REG(gpio);
+ val = readl(reg) & ~MXC_ICR_MASK(gpio);
+ writel(val | field_prep(MXC_ICR_MASK(gpio), edge), reg);
+}
+
+static u32 icr_get_edge(struct mxc_gpio_port *port, u32 gpio)
+{
+ return field_get(MXC_ICR_MASK(gpio), readl(port->base + MXC_ICR_REG(gpio)));
+}
+
static int gpio_set_irq_type(struct irq_data *d, u32 type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct mxc_gpio_port *port = gc->private;
- u32 bit, val;
+ u32 val;
u32 gpio_idx = d->hwirq;
int edge;
- void __iomem *reg = port->base;
clear_bit(gpio_idx, &port->both_edges);
switch (type) {
@@ -264,12 +282,8 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
port->base + GPIO_EDGE_SEL);
}
- if (edge != GPIO_INT_BOTH_EDGES) {
- reg += GPIO_ICR1 + ((gpio_idx & 0x10) >> 2); /* lower or upper register */
- bit = gpio_idx & 0xf;
- val = readl(reg) & ~(0x3 << (bit << 1));
- writel(val | (edge << (bit << 1)), reg);
- }
+ if (edge != GPIO_INT_BOTH_EDGES)
+ icr_update_edge(port, gpio_idx, edge);
writel(1 << gpio_idx, port->base + GPIO_ISR);
port->pad_type[gpio_idx] = type;
@@ -280,17 +294,11 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
{
- void __iomem *reg = port->base;
- u32 bit, val;
- int edge;
+ u32 edge;
guard(gpio_generic_lock_irqsave)(&port->gen_gc);
- reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
- bit = gpio & 0xf;
- val = readl(reg);
- edge = (val >> (bit << 1)) & 3;
- val &= ~(0x3 << (bit << 1));
+ edge = icr_get_edge(port, gpio);
if (edge == GPIO_INT_HIGH_LEV) {
edge = GPIO_INT_LOW_LEV;
pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
@@ -302,7 +310,7 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
gpio, edge);
return;
}
- writel(val | (edge << (bit << 1)), reg);
+ icr_update_edge(port, gpio, edge);
}
/* handle 32 interrupts in one status register */
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 11/12] gpio: mxc: use BIT() macro for single-bit operations
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (9 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 10/12] gpio: mxc: introduce MXC_ICR macros and use field_prep/field_get Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 12/12] MAINTAINERS: Add an entry for gpio-mxc Peng Fan (OSS)
11 siblings, 0 replies; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Replace open-coded '1 << n' shifts with the BIT() macro throughout
the driver for consistency and to avoid potential signed-shift issues
when the bit index is 31 (1 << 31 is implementation-defined for
signed int).
No functional change.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/gpio/gpio-mxc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 87460dab67fa..cef0da73b885 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -275,17 +275,17 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
if (GPIO_EDGE_SEL >= 0) {
val = readl(port->base + GPIO_EDGE_SEL);
if (edge == GPIO_INT_BOTH_EDGES)
- writel(val | (1 << gpio_idx),
+ writel(val | BIT(gpio_idx),
port->base + GPIO_EDGE_SEL);
else
- writel(val & ~(1 << gpio_idx),
+ writel(val & ~BIT(gpio_idx),
port->base + GPIO_EDGE_SEL);
}
if (edge != GPIO_INT_BOTH_EDGES)
icr_update_edge(port, gpio_idx, edge);
- writel(1 << gpio_idx, port->base + GPIO_ISR);
+ writel(BIT(gpio_idx), port->base + GPIO_ISR);
port->pad_type[gpio_idx] = type;
}
@@ -324,7 +324,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
generic_handle_domain_irq(port->domain, irqoffset);
- irq_stat &= ~(1 << irqoffset);
+ irq_stat &= ~BIT(irqoffset);
}
}
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 12/12] MAINTAINERS: Add an entry for gpio-mxc
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
` (10 preceding siblings ...)
2026-10-27 12:09 ` [PATCH v7 11/12] gpio: mxc: use BIT() macro for single-bit operations Peng Fan (OSS)
@ 2026-10-27 12:09 ` Peng Fan (OSS)
2026-10-27 14:14 ` Frank Li
11 siblings, 1 reply; 20+ messages in thread
From: Peng Fan (OSS) @ 2026-10-27 12:09 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-kernel, linux-gpio, imx, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Add myself as gpio-mxc maintainer
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index fcff12847485..a7aa9a587496 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10738,6 +10738,14 @@ F: drivers/perf/fsl_imx8_ddr_perf.c
F: drivers/perf/fsl_imx9_ddr_perf.c
F: tools/perf/pmu-events/arch/arm64/freescale/
+FREESCALE IMX GPIO DRIVER
+M: Peng Fan <peng.fan@nxp.com>
+L: linux-gpio@vger.kernel.org
+L: imx@lists.linux.dev
+S: Maintained
+F: Documentation/devicetree/bindings/gpio/fsl-imx-gpio.yaml
+F: drivers/gpio/gpio-mxc.c
+
FREESCALE IMX I2C DRIVER
M: Oleksij Rempel <o.rempel@pengutronix.de>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
--
2.51.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code
2026-10-27 12:09 ` [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code Peng Fan (OSS)
@ 2026-10-27 14:09 ` Frank Li
0 siblings, 0 replies; 20+ messages in thread
From: Frank Li @ 2026-10-27 14:09 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan
On Tue, Oct 27, 2026 at 08:09:28PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Simplify the logic by consolidating into a single irq_set_irq_wake()
> call based on the enable parameter.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/gpio/gpio-mxc.c | 15 ++++-----------
> 1 file changed, 4 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
> index 32ded7b548fb..95dfe199409a 100644
> --- a/drivers/gpio/gpio-mxc.c
> +++ b/drivers/gpio/gpio-mxc.c
> @@ -326,17 +326,10 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
> u32 gpio_idx = d->hwirq;
> int ret;
>
> - if (enable) {
> - if (port->irq_high && (gpio_idx >= 16))
> - ret = enable_irq_wake(port->irq_high);
> - else
> - ret = enable_irq_wake(port->irq);
> - } else {
> - if (port->irq_high && (gpio_idx >= 16))
> - ret = disable_irq_wake(port->irq_high);
> - else
> - ret = disable_irq_wake(port->irq);
> - }
> + if (port->irq_high && (gpio_idx >= 16))
> + ret = irq_set_irq_wake(port->irq_high, enable);
> + else
> + ret = irq_set_irq_wake(port->irq, enable);
> if (ret)
> return ret;
>
>
> --
> 2.51.0
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned'
2026-10-27 12:09 ` [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned' Peng Fan (OSS)
@ 2026-10-27 14:10 ` Frank Li
2026-10-27 16:36 ` Andy Shevchenko
1 sibling, 0 replies; 20+ messages in thread
From: Frank Li @ 2026-10-27 14:10 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan, Andy Shevchenko
On Tue, Oct 27, 2026 at 08:09:30PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> The kernel coding style prefers 'unsigned int' over bare 'unsigned'.
> Fix all instances in struct mxc_gpio_hwdata and mxc_gpio_to_irq().
>
> No functional change.
>
> Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/gpio/gpio-mxc.c | 24 ++++++++++++------------
> 1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
> index 848d7725ccfe..43868a214c17 100644
> --- a/drivers/gpio/gpio-mxc.c
> +++ b/drivers/gpio/gpio-mxc.c
> @@ -36,18 +36,18 @@
>
> /* device type dependent stuff */
> struct mxc_gpio_hwdata {
> - unsigned dr_reg;
> - unsigned gdir_reg;
> - unsigned psr_reg;
> - unsigned icr1_reg;
> - unsigned icr2_reg;
> - unsigned imr_reg;
> - unsigned isr_reg;
> + unsigned int dr_reg;
> + unsigned int gdir_reg;
> + unsigned int psr_reg;
> + unsigned int icr1_reg;
> + unsigned int icr2_reg;
> + unsigned int imr_reg;
> + unsigned int isr_reg;
> int edge_sel_reg;
> - unsigned low_level;
> - unsigned high_level;
> - unsigned rise_edge;
> - unsigned fall_edge;
> + unsigned int low_level;
> + unsigned int high_level;
> + unsigned int rise_edge;
> + unsigned int fall_edge;
> };
>
> struct mxc_gpio_reg_saved {
> @@ -367,7 +367,7 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
> return rv;
> }
>
> -static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> +static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
> {
> struct mxc_gpio_port *port = gpiochip_get_data(gc);
>
>
> --
> 2.51.0
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 07/12] gpio: mxc: use __free guard for runtime PM cleanup
2026-10-27 12:09 ` [PATCH v7 07/12] gpio: mxc: use __free guard for runtime PM cleanup Peng Fan (OSS)
@ 2026-10-27 14:12 ` Frank Li
0 siblings, 0 replies; 20+ messages in thread
From: Frank Li @ 2026-10-27 14:12 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan
On Tue, Oct 27, 2026 at 08:09:34PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Use a scope-based cleanup guard to disable runtime PM and drop the
> probe-scoped pm_runtime_get_noresume() reference on error paths. Disarm
> it with retain_and_null_ptr() before the success-path
> pm_runtime_put_autosuspend().
>
> The guard keeps the required order: pm_runtime_disable() runs before
> pm_runtime_put_noidle(), so dropping the reference cannot trigger a
> runtime suspend callback while probe is still unwinding.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/gpio/gpio-mxc.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
> index 21c74b244c1f..68857730b5e3 100644
> --- a/drivers/gpio/gpio-mxc.c
> +++ b/drivers/gpio/gpio-mxc.c
> @@ -28,6 +28,20 @@
> #include <linux/of.h>
> #include <linux/bug.h>
>
> +static void mxc_gpio_pm_release(struct device *dev)
> +{
> + if (!dev)
> + return;
> +
> + if (pm_runtime_enabled(dev))
> + pm_runtime_disable(dev);
> +
> + pm_runtime_put_noidle(dev);
> +}
> +
> +DEFINE_FREE(mxc_gpio_pm_cleanup, struct device *,
> + mxc_gpio_pm_release(_T))
> +
> #define IMX_SCU_WAKEUP_OFF 0
> #define IMX_SCU_WAKEUP_LOW_LVL 4
> #define IMX_SCU_WAKEUP_FALL_EDGE 5
> @@ -487,6 +501,9 @@ static int mxc_gpio_probe(struct platform_device *pdev)
> return PTR_ERR(port->clk);
>
> pm_runtime_get_noresume(dev);
> +
> + struct device *pm_guard __free(mxc_gpio_pm_cleanup) = dev;
> +
> pm_runtime_set_active(dev);
> pm_runtime_enable(dev);
>
> @@ -562,6 +579,8 @@ static int mxc_gpio_probe(struct platform_device *pdev)
> mxc_update_irq_chained_handler(port, true);
>
> platform_set_drvdata(pdev, port);
> +
> + retain_and_null_ptr(pm_guard);
> pm_runtime_put_autosuspend(dev);
>
> return 0;
> @@ -569,8 +588,6 @@ static int mxc_gpio_probe(struct platform_device *pdev)
> out_irqdomain_remove:
> irq_domain_remove(port->domain);
> out_bgio:
> - pm_runtime_disable(dev);
> - pm_runtime_put_noidle(dev);
> dev_info(dev, "%s failed with errno %d\n", __func__, err);
> return err;
> }
>
> --
> 2.51.0
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 09/12] gpio: mxc: add dev_err_probe() for error paths to help diagnostics
2026-10-27 12:09 ` [PATCH v7 09/12] gpio: mxc: add dev_err_probe() for error paths to help diagnostics Peng Fan (OSS)
@ 2026-10-27 14:13 ` Frank Li
0 siblings, 0 replies; 20+ messages in thread
From: Frank Li @ 2026-10-27 14:13 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan
On Tue, Oct 27, 2026 at 08:09:36PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Use dev_err_probe() on probe error paths that do not already report the
> failure, so that deferred probe reasons are recorded consistently. Leave
> the devm_platform_ioremap_resource() and platform_get_irq() paths alone;
> those already log their errors.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/gpio/gpio-mxc.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
> index eeb7d36e6b44..f816822e36ad 100644
> --- a/drivers/gpio/gpio-mxc.c
> +++ b/drivers/gpio/gpio-mxc.c
> @@ -484,7 +484,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
>
> irq_count = platform_irq_count(pdev);
> if (irq_count < 0)
> - return irq_count;
> + return dev_err_probe(dev, irq_count, "Failed to count irq\n");
>
> if (irq_count > 1) {
> port->irq_high = platform_get_irq(pdev, 1);
> @@ -499,7 +499,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
> /* the controller clock is optional */
> port->clk = devm_clk_get_optional_enabled(dev, NULL);
> if (IS_ERR(port->clk))
> - return PTR_ERR(port->clk);
> + return dev_err_probe(dev, PTR_ERR(port->clk), "Failed to get clk\n");
>
> pm_runtime_get_noresume(dev);
>
> @@ -532,7 +532,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
>
> err = gpio_generic_chip_init(&port->gen_gc, &config);
> if (err)
> - return err;
> + return dev_err_probe(dev, err, "Failed to init gpio chip\n");
>
> port->gen_gc.gc.request = mxc_gpio_request;
> port->gen_gc.gc.free = mxc_gpio_free;
> @@ -548,7 +548,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
>
> irq_base = devm_irq_alloc_descs(dev, -1, 0, 32, numa_node_id());
> if (irq_base < 0)
> - return irq_base;
> + return dev_err_probe(dev, irq_base, "Failed to alloc irq desc\n");
>
> d_info = (struct irq_domain_info) {
> .fwnode = dev_fwnode(dev),
> @@ -561,14 +561,15 @@ static int mxc_gpio_probe(struct platform_device *pdev)
>
> port->domain = devm_irq_domain_instantiate(dev, &d_info);
> if (IS_ERR(port->domain))
> - return PTR_ERR(port->domain);
> + return dev_err_probe(dev, PTR_ERR(port->domain),
> + "Failed to create irq domain\n");
>
> irq_domain_set_pm_device(port->domain, dev);
>
> /* gpio-mxc can be a generic irq chip */
> err = mxc_gpio_init_gc(port, irq_base);
> if (err < 0)
> - return err;
> + return dev_err_probe(dev, err, "Failed to init generic irq chip\n");
>
> /*
> * Register the GPIO chip last: devm_gpiochip_add_data() makes the
> @@ -577,7 +578,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
> */
> err = devm_gpiochip_add_data(dev, &port->gen_gc.gc, port);
> if (err)
> - return err;
> + return dev_err_probe(dev, err, "Failed to add gpiochip data\n");
>
> list_add_tail(&port->node, &mxc_gpio_ports);
>
>
> --
> 2.51.0
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 12/12] MAINTAINERS: Add an entry for gpio-mxc
2026-10-27 12:09 ` [PATCH v7 12/12] MAINTAINERS: Add an entry for gpio-mxc Peng Fan (OSS)
@ 2026-10-27 14:14 ` Frank Li
0 siblings, 0 replies; 20+ messages in thread
From: Frank Li @ 2026-10-27 14:14 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan
On Tue, Oct 27, 2026 at 08:09:39PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> Add myself as gpio-mxc maintainer
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> MAINTAINERS | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fcff12847485..a7aa9a587496 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10738,6 +10738,14 @@ F: drivers/perf/fsl_imx8_ddr_perf.c
> F: drivers/perf/fsl_imx9_ddr_perf.c
> F: tools/perf/pmu-events/arch/arm64/freescale/
>
> +FREESCALE IMX GPIO DRIVER
> +M: Peng Fan <peng.fan@nxp.com>
> +L: linux-gpio@vger.kernel.org
> +L: imx@lists.linux.dev
> +S: Maintained
> +F: Documentation/devicetree/bindings/gpio/fsl-imx-gpio.yaml
> +F: drivers/gpio/gpio-mxc.c
> +
> FREESCALE IMX I2C DRIVER
> M: Oleksij Rempel <o.rempel@pengutronix.de>
> R: Pengutronix Kernel Team <kernel@pengutronix.de>
>
> --
> 2.51.0
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 02/12] gpio: mxc: use for_each_set_bit() to iterate wakeup pads
2026-10-27 12:09 ` [PATCH v7 02/12] gpio: mxc: use for_each_set_bit() to iterate wakeup pads Peng Fan (OSS)
@ 2026-10-27 16:35 ` Andy Shevchenko
0 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2026-10-27 16:35 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan
On Tue, Oct 27, 2026 at 08:09:29PM +0800, Peng Fan (OSS) wrote:
>
> Use for_each_set_bit() to iterate over the enabled wakeup pads instead
> of checking every bit individually.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned'
2026-10-27 12:09 ` [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned' Peng Fan (OSS)
2026-10-27 14:10 ` Frank Li
@ 2026-10-27 16:36 ` Andy Shevchenko
1 sibling, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2026-10-27 16:36 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
imx, linux-arm-kernel, Peng Fan
On Tue, Oct 27, 2026 at 08:09:30PM +0800, Peng Fan (OSS) wrote:
>
> The kernel coding style prefers 'unsigned int' over bare 'unsigned'.
> Fix all instances in struct mxc_gpio_hwdata and mxc_gpio_to_irq().
>
> No functional change.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-10-27 16:36 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27 12:09 [PATCH v7 00/12] gpio: mxc: probe cleanup Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 01/12] gpio: mxc: use irq_set_irq_wake() to simplify code Peng Fan (OSS)
2026-10-27 14:09 ` Frank Li
2026-10-27 12:09 ` [PATCH v7 02/12] gpio: mxc: use for_each_set_bit() to iterate wakeup pads Peng Fan (OSS)
2026-10-27 16:35 ` Andy Shevchenko
2026-10-27 12:09 ` [PATCH v7 03/12] gpio: mxc: use 'unsigned int' instead of bare 'unsigned' Peng Fan (OSS)
2026-10-27 14:10 ` Frank Li
2026-10-27 16:36 ` Andy Shevchenko
2026-10-27 12:09 ` [PATCH v7 04/12] gpio: mxc: replace of_device_is_compatible() with hwdata flags Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 05/12] gpio: mxc: convert pad wakeup compatible checks to " Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 06/12] gpio: mxc: use local dev variable Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 07/12] gpio: mxc: use __free guard for runtime PM cleanup Peng Fan (OSS)
2026-10-27 14:12 ` Frank Li
2026-10-27 12:09 ` [PATCH v7 08/12] gpio: mxc: use devres functions to simplify probe code Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 09/12] gpio: mxc: add dev_err_probe() for error paths to help diagnostics Peng Fan (OSS)
2026-10-27 14:13 ` Frank Li
2026-10-27 12:09 ` [PATCH v7 10/12] gpio: mxc: introduce MXC_ICR macros and use field_prep/field_get Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 11/12] gpio: mxc: use BIT() macro for single-bit operations Peng Fan (OSS)
2026-10-27 12:09 ` [PATCH v7 12/12] MAINTAINERS: Add an entry for gpio-mxc Peng Fan (OSS)
2026-10-27 14:14 ` Frank Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®