All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Oleksij Rempel" <o.rempel@pengutronix.de>
Cc: devicetree@vger.kernel.org, robh@kernel.org,
	linux-hwmon@vger.kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v5 5/7] pinctrl: add NXP MC33978/MC34978 pinctrl driver
Date: Thu, 13 Aug 2026 21:55:22 +0000	[thread overview]
Message-ID: <20260813215522.C81C71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260316140514.1406588-6-o.rempel@pengutronix.de>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Output emulation and open-drain semantics are broken for Programmable (SP) pins due to logic flaws in `mc33978_set()` and `mc33978_set_multiple()`.
- [High] `mc33978_set_multiple()` can return an uninitialized variable and silently masks regmap error codes.
- [Medium] Missing `mpc->lock` acquisition in `mc33978_pinconf_get()` and `mc33978_pinconf_set()` breaks hardware sequence atomicity.
- [Medium] Silent omission of SPI read failures in `mc33978_get()` leads to incorrect physical state interpretation.
- [Medium] Unconditional invocation of optional parent irq_chip callbacks `irq_bus_lock` and `irq_bus_sync_unlock`.
--

--- Patch [5]: [PATCH v5 5/7] pinctrl: add NXP MC33978/MC34978 pinctrl driver ---
commit 98645888889b3328cc6079ef5439da9e7d2a7837
Author: David Jander <david@protonic.nl>

pinctrl: add NXP MC33978/MC34978 pinctrl driver

Add pin control and GPIO driver for the NXP MC33978/MC34978 Multiple
Switch Detection Interface (MSDI) devices.

> diff --git a/drivers/pinctrl/pinctrl-mc33978.c b/drivers/pinctrl/pinctrl-mc33978.c
> new file mode 100644
> index 0000000000000..31065d6333173
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-mc33978.c

[ ... ]

> +static int mc33978_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
> +			       unsigned long *config)
> +{
> +	struct mc33978_pinctrl *mpc = pinctrl_dev_get_drvdata(pctldev);
> +	enum pin_config_param param = pinconf_to_config_param(*config);
> +	unsigned int data, status;
> +	int ret;
> +
> +	switch (param) {
> +	case PIN_CONFIG_BIAS_PULL_UP:
> +		ret = mc33978_get_pull(mpc, pin, &data);

[Severity: Medium]
The mpc->lock is documented as protecting atomic reads and multi-register
hardware sequences. Does the lack of this lock in mc33978_pinconf_get() and
mc33978_pinconf_set() expose the hardware state reads and updates to race
conditions with concurrent GPIO operations?

[ ... ]

> +static int mc33978_get(struct gpio_chip *chip, unsigned int offset)
> +{

[ ... ]

> +	/* Determine current topology for SP pins */
> +	if (mc33978_is_sp(offset)) {
> +		int config_reg;
> +
> +		ret = mc33978_read(mpc, MC33978_REG_CONFIG, &config_reg);
> +		if (ret == 0) {
> +			/* CONFIG: 0 = Switch-to-Ground (PU), 1 = Switch-to-Battery (PD) */
> +			if (config_reg & MC33978_PINMASK(offset))
> +				is_switch_to_ground = false;
> +		}
> +	}

[Severity: Medium]
If the SPI read in mc33978_read() fails, the code ignores the error code in
ret and proceeds with is_switch_to_ground remaining true. 

Should the error code in ret be propagated back to the caller instead of
falling back to a default topology guess that might misinterpret the physical
state?

[ ... ]

> +static int mc33978_set(struct gpio_chip *chip, unsigned int offset, int value)
> +{
> +	struct mc33978_pinctrl *mpc = gpiochip_get_data(chip);
> +	int pull;
> +	int ret;
> +
> +	/*
> +	 * We emulate open-drain/-source outputs by routing or isolating the
> +	 * active wetting current sources.
> +	 * To drive the line, we apply the current source.
> +	 * To turn the line OFF (achieve High-Impedance), we MUST use the
> +	 * hardware TRI_SP / TRI_SG tri-state registers to physically isolate
> +	 * it.
> +	 */
> +	if (mc33978_is_sp(offset)) {
> +		pull = value ? MC33978_PU : MC33978_PD;
> +		value = 1;
> +	} else {
> +		pull = MC33978_PU;
> +	}

[Severity: High]
For SP pins, value is unconditionally forced to 1. Will this prevent the 
turn OFF branch (value == 0) below from ever being executed for these pins?

> +
> +	guard(mutex)(&mpc->lock);
> +
> +	/*
> +	 * Break-before-make sequencing to prevent hardware glitches (spikes).
> +	 * Since SPI transfers take time, writing the pull and tri-state
> +	 * registers in the wrong order causes a brief moment where current
> +	 * flows to the pin before it is masked, causing a visible LED flash.
> +	 */
> +	if (value) {
> +		/*
> +		 * Turn ON: Configure the underlying current source (pull) first,
> +		 * then route it to the pin by disabling tri-state.
> +		 */
> +		ret = mc33978_set_pull(mpc, offset, pull);

[ ... ]

> +static int mc33978_set_multiple(struct gpio_chip *chip,
> +				unsigned long *mask, unsigned long *bits)
> +{
> +	unsigned int sgmask = (*mask & MC33978_SG_MASK) >> MC33978_SG_SHIFT;
> +	unsigned int sgbits = (*bits & MC33978_SG_MASK) >> MC33978_SG_SHIFT;
> +	unsigned int spmask = (*mask & MC33978_SP_MASK) >> MC33978_SP_SHIFT;
> +	unsigned int spbits = (*bits & MC33978_SP_MASK) >> MC33978_SP_SHIFT;
> +	struct mc33978_pinctrl *mpc = gpiochip_get_data(chip);
> +	int ret;
> +
> +	guard(mutex)(&mpc->lock);
> +	if (spmask)
> +		ret = mc33978_update_bits(mpc, MC33978_REG_TRI_SP, spmask,
> +					  ~spbits);

[Severity: High]
Does this direct update to MC33978_REG_TRI_SP contradict the expected state
setup in mc33978_set(), since the required pull direction is not being
configured here?

Also, if both spmask and sgmask evaluate to zero, will this function return
an uninitialized ret?

If both spmask and sgmask are non-zero, will the second call to
mc33978_update_bits() silently overwrite an error code returned by the first
call?

> +	if (sgmask)
> +		ret = mc33978_update_bits(mpc, MC33978_REG_TRI_SG, sgmask,
> +					  ~sgbits);
> +
> +	return ret;
> +}

[ ... ]

> +static void mc33978_gpio_irq_bus_lock(struct irq_data *data)
> +{
> +	struct irq_data *parent = data->parent_data;
> +
> +	parent->chip->irq_bus_lock(parent);
> +}

[Severity: Medium]
Since irq_bus_lock is an optional callback in struct irq_chip, is it possible
for parent->chip->irq_bus_lock to be NULL here?

Could this cause a NULL pointer dereference panic if the parent domain does
not implement it?

> +
> +static void mc33978_gpio_irq_bus_sync_unlock(struct irq_data *data)
> +{
> +	struct irq_data *parent = data->parent_data;
> +
> +	parent->chip->irq_bus_sync_unlock(parent);
> +}

[Severity: Medium]
Similarly, could parent->chip->irq_bus_sync_unlock be NULL and lead to a 
NULL pointer dereference?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260316140514.1406588-1-o.rempel@pengutronix.de?part=5

  reply	other threads:[~2026-08-13 21:55 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-16 14:05 [PATCH v5 0/7] mfd: Add support for NXP MC33978/MC34978 MSDI Oleksij Rempel
2026-03-16 14:05 ` [PATCH v5 1/7] dt-bindings: pinctrl: add " Oleksij Rempel
2026-03-16 16:08   ` Rob Herring (Arm)
2026-03-16 17:18   ` Rob Herring (Arm)
2026-03-16 20:49   ` Linus Walleij
2026-03-16 14:05 ` [PATCH v5 2/7] mfd: add NXP MC33978/MC34978 core driver Oleksij Rempel
2026-08-13 21:45   ` sashiko-bot
2026-03-16 14:05 ` [PATCH v5 3/7] pinctrl: core: Make pin group callbacks optional Oleksij Rempel
2026-03-16 14:05 ` [PATCH v5 4/7] gpio: gpiolib: fix allocation order in hierarchical IRQ domains Oleksij Rempel
2026-03-16 14:05 ` [PATCH v5 5/7] pinctrl: add NXP MC33978/MC34978 pinctrl driver Oleksij Rempel
2026-08-13 21:55   ` sashiko-bot [this message]
2026-03-16 14:05 ` [PATCH v5 6/7] hwmon: add NXP MC33978/MC34978 driver Oleksij Rempel
2026-03-16 14:05 ` [PATCH v5 7/7] mux: add NXP MC33978/MC34978 AMUX driver Oleksij Rempel
2026-03-17 22:12 ` [PATCH v5 0/7] mfd: Add support for NXP MC33978/MC34978 MSDI Guenter Roeck
2026-03-18  8:13   ` Oleksij Rempel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260813215522.C81C71F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=o.rempel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.