Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Ivaylo Dimitrov" <ivo.g.dimitrov.75@gmail.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org,
	vkoul@kernel.org, olteanv@gmail.com, neil.armstrong@linaro.org,
	linux-phy@lists.infradead.org
Subject: Re: [PATCH v4 3/6] phy: cpcap-usb: add DCP detection and make UART idle mode optional
Date: Sat, 11 Jul 2026 17:06:42 +0000	[thread overview]
Message-ID: <20260711170642.BA9A61F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260711164754.185565-4-ivo.g.dimitrov.75@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] `cpcap_usb_set_idle_mode()` unconditionally sets `CPCAP_BIT_DMPD_SPI` and `CPCAP_BIT_DPPD_SPI`, overriding hardware pulldowns and breaking subsequent charger detection.
- [Medium] The `cpcap_usb_set_dcp_mode` function fails to fully configure the PHY registers, leaving them in a non-deterministic state.

Pre-existing issues:
- [High] A TOCTOU race condition exists between the IRQ handler thread and `cpcap_usb_phy_remove`, leading to a use-after-free of the `ddata` structure.
--

--- Patch [3]: [PATCH v4 3/6] phy: cpcap-usb: add DCP detection and make UART idle mode optional ---
commit ccdf9470fbb5fbd414c5546a329d78f69ecf50b7
Author: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>

phy: cpcap-usb: add DCP detection and make UART idle mode optional

Handle DCP separately from USB host connections using CPCAP charger
detection status. Make the existing idle UART mode optional via the
enable_uart module parameter. Also initialize the PHY into the baseline
configuration required for reliable charger detection during probe.

> diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
> index 7cb020dd3423c..d4eb8086b6000 100644
> --- a/drivers/phy/motorola/phy-cpcap-usb.c
> +++ b/drivers/phy/motorola/phy-cpcap-usb.c
[ ... ]
> @@ -411,43 +446,84 @@ static int cpcap_usb_gpio_set_mode(struct cpcap_phy_ddata *ddata,
[ ... ]
> +static int cpcap_usb_set_idle_mode(struct cpcap_phy_ddata *ddata)
> +{
> +	int error;
> +	unsigned int val;
> +	bool enable_uart = cpcap_enable_uart;
> +
> +	error = cpcap_usb_set_safe_mode(ddata);
> +	if (error)
> +		return error;
> +
>  	error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
> +				   CPCAP_BIT_DP150KPU |
> +				   CPCAP_BIT_DP1K5PU |
> +				   CPCAP_BIT_DM1K5PU |
> +				   CPCAP_BIT_DPPD |
> +				   CPCAP_BIT_DMPD |
>  				   CPCAP_BIT_VBUSPD,
> +				   CPCAP_BIT_DP150KPU |
>  				   CPCAP_BIT_VBUSPD);
>  	if (error)
>  		goto out_err;
>  
> -	error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
> -				   0xffff, CPCAP_BIT_UARTMUX0 |
> -				   CPCAP_BIT_EMUMODE0);
> +	val = CPCAP_BIT_USBSUSPEND;
> +
> +	if (enable_uart)
> +		val |= (CPCAP_BIT_UARTMUX0 | CPCAP_BIT_EMUMODE0);
> +
> +	error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2, 0xffff, val);
>  	if (error)
>  		goto out_err;
>  
> -	error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff,
> -				   CPCAP_BIT_IDPU_SPI);
> +	val = CPCAP_BIT_VBUSSTBY_EN |
> +	      CPCAP_BIT_VBUSPD_SPI |
> +	      CPCAP_BIT_DMPD_SPI |
> +	      CPCAP_BIT_DPPD_SPI |
> +	      CPCAP_BIT_PU_SPI |
> +	      CPCAP_BIT_IDPU_SPI |
> +	      CPCAP_BIT_ULPI_SPI_SEL;
> +
> +	if (!enable_uart)
> +		val |= CPCAP_BIT_SUSPEND_SPI;
> +
> +	error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff, val);

[Severity: High]
Does setting CPCAP_BIT_DMPD_SPI and CPCAP_BIT_DPPD_SPI here break charger
detection?

Writing this value to USBC3 unconditionally sets both DMPD_SPI and DPPD_SPI to
1. This overrides the hardware pulldowns and forces them off. The original
code correctly cleared these bits, and as noted in cpcap_usb_init_usb(),
disabling these pulldowns can break subsequent charger detection when the
cable is disconnected.

>  	if (error)
>  		goto out_err;
>  
[ ... ]
> @@ -508,6 +583,31 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
>  	return error;
>  }
>  
> +static int cpcap_usb_set_dcp_mode(struct cpcap_phy_ddata *ddata)
> +{
> +	int error;
> +
> +	error = cpcap_usb_set_safe_mode(ddata);
> +	if (error)
> +		return error;
> +
> +	error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
> +				   CPCAP_BIT_SUSPEND_SPI, 0);
> +	if (error)
> +		goto out_err;

[Severity: Medium]
Does cpcap_usb_set_dcp_mode() need to configure USBC1 and USBC2 as well?

Because this only updates USBC3, it seems to inherit whatever state was left
by the previous mode. For example, if transitioning from USB mode, USBXCVREN
in USBC2 might remain set. If transitioning from IDLE mode with
enable_uart=1, UARTMUX0 might remain set, leaving the UART connected to the
data lines during charging.

> +
> +	error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
> +	if (error)
> +		goto out_err;
> +
> +	return 0;
> +
> +out_err:
> +	dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
> +
> +	return error;
> +}
> +
[ ... ]
> @@ -688,17 +849,13 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev)
>  static void cpcap_usb_phy_remove(struct platform_device *pdev)
>  {
>  	struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev);
> -	int error;
>  
>  	atomic_set(&ddata->active, 0);
> -	error = cpcap_usb_set_uart_mode(ddata);
> -	if (error)
> -		dev_err(ddata->dev, "could not set UART mode\n");
> -
> +	cancel_delayed_work_sync(&ddata->detect_work);
> +	cpcap_usb_set_idle_mode(ddata);
>  	cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
>  
>  	usb_remove_phy(&ddata->phy);
> -	cancel_delayed_work_sync(&ddata->detect_work);
>  	regulator_disable(ddata->vusb);
>  }

[Severity: High]
This is a pre-existing issue, but is there a TOCTOU race condition between
cpcap_phy_irq_thread() and cpcap_usb_phy_remove() that can result in a
use-after-free?

If the IRQ thread reads ddata->active as 1 in cpcap_phy_irq_thread() and gets
preempted:

cpcap_phy_irq_thread() {
    if (!atomic_read(&ddata->active))
        return IRQ_NONE;
    /* preempted here */

And cpcap_usb_phy_remove() completes, setting ddata->active = 0, canceling the
work, and allowing devres to free ddata:

cpcap_usb_phy_remove() {
    atomic_set(&ddata->active, 0);
    cancel_delayed_work_sync(&ddata->detect_work);
    ...
}
/* devres frees ddata */

Could the IRQ thread then resume and call schedule_delayed_work() on the freed
ddata?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260711164754.185565-1-ivo.g.dimitrov.75@gmail.com?part=3

  reply	other threads:[~2026-07-11 17:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-11 16:47 [PATCH v4 0/6] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
2026-07-11 16:47 ` [PATCH v4 1/6] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
2026-07-11 16:47 ` [PATCH v4 2/6] dt-bindings: phy: motorola,cpcap-usb-phy: add optional safe pinctrl state Ivaylo Dimitrov
2026-07-11 17:00   ` sashiko-bot
2026-07-11 16:47 ` [PATCH v4 3/6] phy: cpcap-usb: add DCP detection and make UART idle mode optional Ivaylo Dimitrov
2026-07-11 17:06   ` sashiko-bot [this message]
2026-07-11 16:47 ` [PATCH v4 4/6] phy: cpcap-usb: add extcon support Ivaylo Dimitrov
2026-07-11 17:14   ` sashiko-bot
2026-07-11 16:47 ` [PATCH v4 5/6] ARM: dts: ti: cpcap-mapphone: add charger detection interrupt for CPCAP USB PHY Ivaylo Dimitrov
2026-07-11 16:47 ` [PATCH v4 6/6] ARM: dts: ti: cpcap-mapphone: add USB safe pinctrl state Ivaylo Dimitrov

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=20260711170642.BA9A61F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=ivo.g.dimitrov.75@gmail.com \
    --cc=linux-phy@lists.infradead.org \
    --cc=neil.armstrong@linaro.org \
    --cc=olteanv@gmail.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox