From: Michael Scott <mike.scott@oss.qualcomm.com>
To: Bryan O'Donoghue <bryan.odonoghue@linaro.org>,
linux-arm-msm@vger.kernel.org
Cc: vkoul@kernel.org, neil.armstrong@linaro.org,
dmitry.baryshkov@oss.qualcomm.com, wesley.cheng@oss.qualcomm.com,
abelvesa@kernel.org, faisal.hassan@oss.qualcomm.com,
linux-phy@lists.infradead.org, andersson@kernel.org,
konradybcio@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, devicetree@vger.kernel.org,
val@packett.cool, laurentiu.tudor1@dell.com,
alex.vinarskis@gmail.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/4] phy: qcom: qmp-combo: skip USB power_off/exit after device teardown
Date: Fri, 22 May 2026 08:59:15 -0700 [thread overview]
Message-ID: <8a6af223-901e-4d1a-ab3f-7e20980cb683@oss.qualcomm.com> (raw)
In-Reply-To: <d543fe6c-88a3-40b8-a83a-ccc6fa80eee3@linaro.org>
On 5/21/26 4:58 AM, Bryan O'Donoghue wrote:
> On 21/05/2026 02:09, Michael Scott wrote:
>> qmp_combo_usb_power_off() is reachable from an external consumer
>> (notably dwc3 via phy_exit() during driver unbind) after this device's
>> backing resources have already been released along a separate teardown
>> chain. The dereference of qmp->pcs (whose ioremap mapping has been
>> freed by devm cleanup) then takes a level-3 translation fault and
>> oopses.
>>
>> Easily reproducible during testing of USB-C role-switch enablement on
>> Dell Latitude 7455 (X1E80100), by writing "none" to a USB-C DWC3's
>> usb_role_switch role attribute, e.g.
>>
>> echo none > /sys/class/usb_role/a800000.usb-role-switch/role
>>
>> which triggers the chain:
>>
>> Unable to handle kernel paging request at virtual address
>> ffff8000876c5400
>> pc : qmp_combo_usb_power_off.isra.0+0x58/0x470 [phy_qcom_qmp_combo]
>> Call trace:
>> qmp_combo_usb_power_off+0x58/0x470 [phy_qcom_qmp_combo]
>> qmp_combo_usb_exit+0x38/0x90 [phy_qcom_qmp_combo]
>> phy_exit
>> dwc3_phy_exit [dwc3]
>> dwc3_core_remove [dwc3]
>> dwc3_remove [dwc3]
>> platform_remove
>> device_release_driver_internal
>> device_driver_detach
>> unbind_store
>> sysfs_kf_write
>> vfs_write
>> ksys_write
>> __arm64_sys_write
>> el0_svc
>>
>> Two WARNs precede the oops from the same teardown chain, confirming
>> the resource ordering:
>>
>> WARNING: drivers/clk/clk.c:4494 at
>> clk_nodrv_disable_unprepare+0x8/0x18
>> WARNING: drivers/regulator/core.c:2657 at _regulator_put+0x84/0x98
>>
>> i.e. the pipe clock provider has been unregistered and the regulators
>> released before qmp_combo_usb_power_off() runs.
>>
>> The proper long-term fix is a teardown-ordering rework so the QMP
>> PHY's backing resources outlive any consumer that may still call its
>> phy_ops. Pending that, guard the power_off/exit paths with the
>> existing usb_init_count balance so re-entry after teardown does not
>> oops. usb_init_count tracks the balance of usb_power_on/off; if it
>> is zero we have either never powered on or have already powered off,
>> and there is nothing to do.
>>
>> The same guard is added to qmp_combo_usb_exit() since it is the entry
>> point used by external consumers via phy_exit().
>>
>> Signed-off-by: Michael Scott <mike.scott@oss.qualcomm.com>
>
> Something like this requires a Fixes: tag
Thanks! Noted.
>
>> ---
>> drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 22 ++++++++++++++++++++++
>> 1 file changed, 22 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
>> b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
>> index cdcfad2e86b1..0db200292642 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
>> @@ -3926,6 +3926,17 @@ static int qmp_combo_usb_power_off(struct phy
>> *phy)
>> struct qmp_combo *qmp = phy_get_drvdata(phy);
>> const struct qmp_phy_cfg *cfg = qmp->cfg;
>> + /*
>> + * Reachable as ->exit from external consumers (notably dwc3) after
>> + * this device's backing resources have already been released along
>> + * a teardown chain. Refuse to touch registers in that case.
>> + */
>> + if (!qmp->usb_init_count) {
>> + dev_dbg(qmp->dev, "%s: PHY not powered on, skipping\n",
>> + __func__);
>> + return 0;
>> + }
>> +
>> /* PHY reset */
>> qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>> @@ -3968,6 +3979,17 @@ static int qmp_combo_usb_exit(struct phy *phy)
>> struct qmp_combo *qmp = phy_get_drvdata(phy);
>> int ret;
>> + /*
>> + * See qmp_combo_usb_power_off(): an external consumer may call
>> + * phy_exit() after the QMP device's resources have been torn
>> + * down. usb_init_count tracks usb_init/usb_exit balance.
>> + */
>> + if (!qmp->usb_init_count) {
>> + dev_dbg(qmp->dev, "%s: PHY not initialised, skipping\n",
>> + __func__);
>> + return 0;
>> + }
>> +
>> mutex_lock(&qmp->phy_mutex);
>> ret = qmp_combo_usb_power_off(phy);
>
> This can't be right - you check usb_init_count before the mutex and
> then again inside the mutex @ qmp_combo_usb_power_off();
>
> It seems like an error to even get to this function with
> !usb_init_count also check if that is a signed or an unsigned value as
> usb_init_count = -1 will evaluate true.
Yep, there are a few issues with this patch (and this looks like an
extra check I accidentally left in). I'm dropping this from the
patchset and I'll revisit at a later date.
Apologies for the noise.
>
>> if (ret)
>> --
>> 2.53.0
>>
>
next prev parent reply other threads:[~2026-05-22 15:59 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-21 1:09 [PATCH v2 0/4] phy: qcom: qmp-combo fixes + x1-dell-thena DT maintenance Michael Scott
2026-05-21 1:09 ` [PATCH v2 1/4] phy: qcom: qmp-combo: skip USB power_off/exit after device teardown Michael Scott
2026-05-21 1:52 ` sashiko-bot
2026-05-21 11:58 ` Bryan O'Donoghue
2026-05-22 15:59 ` Michael Scott [this message]
2026-05-21 1:09 ` [PATCH v2 2/4] phy: qcom: qmp-combo: track whether the cached typec_mux mode was committed to hardware Michael Scott
2026-05-21 2:37 ` sashiko-bot
2026-05-21 12:00 ` Bryan O'Donoghue
2026-05-21 1:09 ` [PATCH v2 3/4] arm64: dts: qcom: x1-dell-thena: mark l12b and l15b always-on Michael Scott
2026-05-21 4:28 ` Val Packett
2026-06-16 12:22 ` Konrad Dybcio
2026-05-21 1:09 ` [PATCH v2 4/4] arm64: dts: qcom: x1-dell-thena: bump linux,cma to 256 MiB Michael Scott
2026-05-21 3:52 ` Val Packett
2026-05-22 17:42 ` Rob Clark
2026-05-21 12:04 ` Bryan O'Donoghue
2026-05-22 17:16 ` Michael Scott
2026-05-22 21:33 ` Bryan O'Donoghue
2026-05-21 4:39 ` [PATCH v2 0/4] phy: qcom: qmp-combo fixes + x1-dell-thena DT maintenance Val Packett
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=8a6af223-901e-4d1a-ab3f-7e20980cb683@oss.qualcomm.com \
--to=mike.scott@oss.qualcomm.com \
--cc=abelvesa@kernel.org \
--cc=alex.vinarskis@gmail.com \
--cc=andersson@kernel.org \
--cc=bryan.odonoghue@linaro.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=faisal.hassan@oss.qualcomm.com \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=laurentiu.tudor1@dell.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-phy@lists.infradead.org \
--cc=neil.armstrong@linaro.org \
--cc=robh@kernel.org \
--cc=val@packett.cool \
--cc=vkoul@kernel.org \
--cc=wesley.cheng@oss.qualcomm.com \
/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