drivers/usb/typec/mux.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
The fwnode_typec_switch_get() sporadically returns NULL instead of an
-EPROBE_DEFER for orientation-switch described in DT. This makes it
impossible to discern whether the DT does describe an orientation-switch
which did not probe yet, or whether the DT does not describe the switch.
This happens with gpio-sbu-mux connected to an I2C GPIO expander.
The class_find_device() on typec_switch_match() may return NULL in case
the mux did not probe just yet early on boot. The sw_devs[] array can be
empty on boot as well. If these two conditions occur, then the conditional
if (to_typec_switch_dev(dev) == sw_devs[i]) evaluates to true and the match
function returns NULL, which propagates to fwnode_typec_switch_get() which
makes it look as if the orientation-switch was not described in DT.
This is incorrect, because the mux driver will probe a bit later on, but
at that point, the caller of fwnode_typec_switch_get() already got the
NULL return value. The NULL return value also does not trigger IS_ERR(),
therefore the caller driver interprets this as if the orientation-switch
is not described in DT, and does not return -EPROBE_DEFER to try again,
even if it should.
Fix this by checking the class_find_device() return value, and return
-EPROBE_DEFER if it is NULL right away. If the return value is not NULL,
perform the deduplication test, and if that test passes, consider the
return value to be already non-NULL.
Fixes: a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
Cc: stable@vger.kernel.org
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: kernel@dh-electronics.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-usb@vger.kernel.org
---
NOTE: A similar change was reverted in
f576c75f95a5 ("Revert "usb: typec: mux: avoid duplicated mux switches"")
Maybe the orientation switch commit also needs a revert ?
Or the mux switch revert can be undone and fixed using this NULL check ?
---
drivers/usb/typec/mux.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 9b908c46bd7df..2bc7e8edb3cbd 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -56,17 +56,19 @@ static void *typec_switch_match(const struct fwnode_handle *fwnode,
* function "defers probe" for now.
*/
dev = class_find_device(&typec_mux_class, NULL, fwnode,
switch_fwnode_match);
+ if (!dev)
+ return ERR_PTR(-EPROBE_DEFER);
/* Skip duplicates */
for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
if (to_typec_switch_dev(dev) == sw_devs[i]) {
put_device(dev);
return NULL;
}
- return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
+ return to_typec_switch_dev(dev);
}
/**
* fwnode_typec_switch_get - Find USB Type-C orientation switch
--
2.53.0
On Mon, Aug 17, 2026 at 08:22:39PM +0200, Marek Vasut wrote:
> The fwnode_typec_switch_get() sporadically returns NULL instead of an
> -EPROBE_DEFER for orientation-switch described in DT. This makes it
> impossible to discern whether the DT does describe an orientation-switch
> which did not probe yet, or whether the DT does not describe the switch.
> This happens with gpio-sbu-mux connected to an I2C GPIO expander.
>
> The class_find_device() on typec_switch_match() may return NULL in case
> the mux did not probe just yet early on boot. The sw_devs[] array can be
> empty on boot as well. If these two conditions occur, then the conditional
> if (to_typec_switch_dev(dev) == sw_devs[i]) evaluates to true and the match
> function returns NULL, which propagates to fwnode_typec_switch_get() which
> makes it look as if the orientation-switch was not described in DT.
>
> This is incorrect, because the mux driver will probe a bit later on, but
> at that point, the caller of fwnode_typec_switch_get() already got the
> NULL return value. The NULL return value also does not trigger IS_ERR(),
> therefore the caller driver interprets this as if the orientation-switch
> is not described in DT, and does not return -EPROBE_DEFER to try again,
> even if it should.
>
> Fix this by checking the class_find_device() return value, and return
> -EPROBE_DEFER if it is NULL right away. If the return value is not NULL,
> perform the deduplication test, and if that test passes, consider the
> return value to be already non-NULL.
>
> Fixes: a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marex@nabladev.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
> Cc: kernel@dh-electronics.com
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> ---
> NOTE: A similar change was reverted in
> f576c75f95a5 ("Revert "usb: typec: mux: avoid duplicated mux switches"")
> Maybe the orientation switch commit also needs a revert ?
> Or the mux switch revert can be undone and fixed using this NULL check ?
> ---
> drivers/usb/typec/mux.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
> index 9b908c46bd7df..2bc7e8edb3cbd 100644
> --- a/drivers/usb/typec/mux.c
> +++ b/drivers/usb/typec/mux.c
> @@ -56,17 +56,19 @@ static void *typec_switch_match(const struct fwnode_handle *fwnode,
> * function "defers probe" for now.
> */
> dev = class_find_device(&typec_mux_class, NULL, fwnode,
> switch_fwnode_match);
> + if (!dev)
> + return ERR_PTR(-EPROBE_DEFER);
>
> /* Skip duplicates */
> for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
> if (to_typec_switch_dev(dev) == sw_devs[i]) {
> put_device(dev);
> return NULL;
> }
>
> - return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
> + return to_typec_switch_dev(dev);
> }
>
> /**
> * fwnode_typec_switch_get - Find USB Type-C orientation switch
> --
> 2.53.0
--
heikki
Hi,
On Mon, Aug 17, 2026 at 08:22:39PM +0200, Marek Vasut wrote:
> The fwnode_typec_switch_get() sporadically returns NULL instead of an
> -EPROBE_DEFER for orientation-switch described in DT. This makes it
> impossible to discern whether the DT does describe an orientation-switch
> which did not probe yet, or whether the DT does not describe the switch.
> This happens with gpio-sbu-mux connected to an I2C GPIO expander.
>
> The class_find_device() on typec_switch_match() may return NULL in case
> the mux did not probe just yet early on boot. The sw_devs[] array can be
> empty on boot as well. If these two conditions occur, then the conditional
> if (to_typec_switch_dev(dev) == sw_devs[i]) evaluates to true and the match
> function returns NULL, which propagates to fwnode_typec_switch_get() which
> makes it look as if the orientation-switch was not described in DT.
>
> This is incorrect, because the mux driver will probe a bit later on, but
> at that point, the caller of fwnode_typec_switch_get() already got the
> NULL return value. The NULL return value also does not trigger IS_ERR(),
> therefore the caller driver interprets this as if the orientation-switch
> is not described in DT, and does not return -EPROBE_DEFER to try again,
> even if it should.
>
> Fix this by checking the class_find_device() return value, and return
> -EPROBE_DEFER if it is NULL right away. If the return value is not NULL,
> perform the deduplication test, and if that test passes, consider the
> return value to be already non-NULL.
>
> Fixes: a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
> Cc: kernel@dh-electronics.com
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> ---
> NOTE: A similar change was reverted in
> f576c75f95a5 ("Revert "usb: typec: mux: avoid duplicated mux switches"")
> Maybe the orientation switch commit also needs a revert ?
> Or the mux switch revert can be undone and fixed using this NULL check ?
> ---
This revert negatively affects Rockchip once my USB-C rework for
USB-DP lands and I undid it locally. I've just not yet found the
time to investigate why it regresses the X1E platform to reintroduce
the feature. Maybe you found the root cause and fix already, but
investigating with my T14s Gen6 Snapdragon is on my TODO list.
FWIW this patch is
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Greetings,
-- Sebastian
> drivers/usb/typec/mux.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
> index 9b908c46bd7df..2bc7e8edb3cbd 100644
> --- a/drivers/usb/typec/mux.c
> +++ b/drivers/usb/typec/mux.c
> @@ -56,17 +56,19 @@ static void *typec_switch_match(const struct fwnode_handle *fwnode,
> * function "defers probe" for now.
> */
> dev = class_find_device(&typec_mux_class, NULL, fwnode,
> switch_fwnode_match);
> + if (!dev)
> + return ERR_PTR(-EPROBE_DEFER);
>
> /* Skip duplicates */
> for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
> if (to_typec_switch_dev(dev) == sw_devs[i]) {
> put_device(dev);
> return NULL;
> }
>
> - return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
> + return to_typec_switch_dev(dev);
> }
>
> /**
> * fwnode_typec_switch_get - Find USB Type-C orientation switch
> --
> 2.53.0
>
Hi, Sebastian, On 8/18/26 18:24, Sebastian Reichel wrote: [...] > This revert negatively affects Rockchip once my USB-C rework for > USB-DP lands and I undid it locally. I've just not yet found the > time to investigate why it regresses the X1E platform to reintroduce > the feature. Maybe you found the root cause and fix already, but > investigating with my T14s Gen6 Snapdragon is on my TODO list. The T14s Gen6 Snapdragon has ps8830 redrivers, your patch works with them. Probably because they register as retimer-switch which takes a different path then mode-switch. I observed the issues with models that don't have the redriver chip, like Ideapad 5 14Q8X9 and Thinkbook 16 G7 QOY. They have a separate gpio-sbu-mux which don't get the mode-switch call when the patch is in. I could test on sc8280xp which also has separate gpio-sbu-mux switches if that brings some light to the issue. with best regards Jens
On 8/18/26 6:24 PM, Sebastian Reichel wrote:
Hello Sebastian,
> On Mon, Aug 17, 2026 at 08:22:39PM +0200, Marek Vasut wrote:
>> The fwnode_typec_switch_get() sporadically returns NULL instead of an
>> -EPROBE_DEFER for orientation-switch described in DT. This makes it
>> impossible to discern whether the DT does describe an orientation-switch
>> which did not probe yet, or whether the DT does not describe the switch.
>> This happens with gpio-sbu-mux connected to an I2C GPIO expander.
>>
>> The class_find_device() on typec_switch_match() may return NULL in case
>> the mux did not probe just yet early on boot. The sw_devs[] array can be
>> empty on boot as well. If these two conditions occur, then the conditional
>> if (to_typec_switch_dev(dev) == sw_devs[i]) evaluates to true and the match
>> function returns NULL, which propagates to fwnode_typec_switch_get() which
>> makes it look as if the orientation-switch was not described in DT.
>>
>> This is incorrect, because the mux driver will probe a bit later on, but
>> at that point, the caller of fwnode_typec_switch_get() already got the
>> NULL return value. The NULL return value also does not trigger IS_ERR(),
>> therefore the caller driver interprets this as if the orientation-switch
>> is not described in DT, and does not return -EPROBE_DEFER to try again,
>> even if it should.
>>
>> Fix this by checking the class_find_device() return value, and return
>> -EPROBE_DEFER if it is NULL right away. If the return value is not NULL,
>> perform the deduplication test, and if that test passes, consider the
>> return value to be already non-NULL.
>>
>> Fixes: a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Marek Vasut <marex@nabladev.com>
>> ---
>>
>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
>> Cc: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
>> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
>> Cc: kernel@dh-electronics.com
>> Cc: linux-kernel@vger.kernel.org
>> Cc: linux-usb@vger.kernel.org
>> ---
>> NOTE: A similar change was reverted in
>> f576c75f95a5 ("Revert "usb: typec: mux: avoid duplicated mux switches"")
>> Maybe the orientation switch commit also needs a revert ?
>> Or the mux switch revert can be undone and fixed using this NULL check ?
>> ---
>
> This revert negatively affects Rockchip once my USB-C rework for
> USB-DP lands and I undid it locally. I've just not yet found the
> time to investigate why it regresses the X1E platform to reintroduce
> the feature. Maybe you found the root cause and fix already, but
> investigating with my T14s Gen6 Snapdragon is on my TODO list.
>
> FWIW this patch is
>
> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Could you revert f576c75f95a5 ("Revert "usb: typec: mux: avoid
duplicated mux switches"") and apply the following patch (equivalent to
this patch, applies to mux instead of switch) and see if that fixes the
T14s for you too then ? If yes, than, I think this might be the proper
fix rather than the revert:
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 4a4297f15aad3..afa6fc1813978 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -294,6 +294,8 @@ static void *typec_mux_match(const struct
fwnode_handle *fwnode,
dev = class_find_device(&typec_mux_class, NULL, fwnode,
mux_fwnode_match);
+ if (!dev)
+ return ERR_PTR(-EPROBE_DEFER);
/* Skip duplicates */
for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
@@ -303,7 +305,7 @@ static void *typec_mux_match(const struct
fwnode_handle *fwnode,
}
- return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
+ return to_typec_mux_dev(dev);
}
/**
Hi Marek,
On 8/18/26 18:56, Marek Vasut wrote:
> Hello Sebastian,
[...]
> Could you revert f576c75f95a5 ("Revert "usb: typec: mux: avoid
> duplicated mux switches"") and apply the following patch (equivalent
> to this patch, applies to mux instead of switch) and see if that fixes
> the T14s for you too then ? If yes, than, I think this might be the
> proper fix rather than the revert:
>
> diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
> index 4a4297f15aad3..afa6fc1813978 100644
> --- a/drivers/usb/typec/mux.c
> +++ b/drivers/usb/typec/mux.c
> @@ -294,6 +294,8 @@ static void *typec_mux_match(const struct
> fwnode_handle *fwnode,
>
> dev = class_find_device(&typec_mux_class, NULL, fwnode,
> mux_fwnode_match);
> + if (!dev)
> + return ERR_PTR(-EPROBE_DEFER);
>
> /* Skip duplicates */
> for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
> @@ -303,7 +305,7 @@ static void *typec_mux_match(const struct
> fwnode_handle *fwnode,
> }
>
>
> - return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
> + return to_typec_mux_dev(dev);
> }
>
> /**
I will test that one with the f576c75f95a5 reverted on the x1p and
sc8280xp boxes I have here, let's see. T14s G6 shouldn't be affected
either way.
with best regards
Jens
On 8/18/26 7:05 PM, Jens Glathe wrote:
> Hi Marek,
>
> On 8/18/26 18:56, Marek Vasut wrote:
>> Hello Sebastian,
> [...]
>> Could you revert f576c75f95a5 ("Revert "usb: typec: mux: avoid
>> duplicated mux switches"") and apply the following patch (equivalent
>> to this patch, applies to mux instead of switch) and see if that fixes
>> the T14s for you too then ? If yes, than, I think this might be the
>> proper fix rather than the revert:
>>
>> diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
>> index 4a4297f15aad3..afa6fc1813978 100644
>> --- a/drivers/usb/typec/mux.c
>> +++ b/drivers/usb/typec/mux.c
>> @@ -294,6 +294,8 @@ static void *typec_mux_match(const struct
>> fwnode_handle *fwnode,
>>
>> dev = class_find_device(&typec_mux_class, NULL, fwnode,
>> mux_fwnode_match);
>> + if (!dev)
>> + return ERR_PTR(-EPROBE_DEFER);
>>
>> /* Skip duplicates */
>> for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
>> @@ -303,7 +305,7 @@ static void *typec_mux_match(const struct
>> fwnode_handle *fwnode,
>> }
>>
>>
>> - return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
>> + return to_typec_mux_dev(dev);
>> }
>>
>> /**
>
> I will test that one with the f576c75f95a5 reverted on the x1p and
> sc8280xp boxes I have here, let's see. T14s G6 shouldn't be affected
> either way.
>
> with best regards
Thank you
Hi Marek,
On 8/18/26 19:43, Marek Vasut wrote:
> On 8/18/26 7:05 PM, Jens Glathe wrote:
>> Hi Marek,
>>
>> On 8/18/26 18:56, Marek Vasut wrote:
>>> Hello Sebastian,
>> [...]
>>> Could you revert f576c75f95a5 ("Revert "usb: typec: mux: avoid
>>> duplicated mux switches"") and apply the following patch (equivalent
>>> to this patch, applies to mux instead of switch) and see if that
>>> fixes the T14s for you too then ? If yes, than, I think this might
>>> be the proper fix rather than the revert:
>>>
>>> diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
>>> index 4a4297f15aad3..afa6fc1813978 100644
>>> --- a/drivers/usb/typec/mux.c
>>> +++ b/drivers/usb/typec/mux.c
>>> @@ -294,6 +294,8 @@ static void *typec_mux_match(const struct
>>> fwnode_handle *fwnode,
>>>
>>> dev = class_find_device(&typec_mux_class, NULL, fwnode,
>>> mux_fwnode_match);
>>> + if (!dev)
>>> + return ERR_PTR(-EPROBE_DEFER);
>>>
>>> /* Skip duplicates */
>>> for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
>>> @@ -303,7 +305,7 @@ static void *typec_mux_match(const struct
>>> fwnode_handle *fwnode,
>>> }
>>>
>>>
>>> - return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
>>> + return to_typec_mux_dev(dev);
>>> }
>>>
>>> /**
>>
>> I will test that one with the f576c75f95a5 reverted on the x1p and
>> sc8280xp boxes I have here, let's see. T14s G6 shouldn't be affected
>> either way.
>>
>> with best regards
> Thank you
I did the test: switch patch, revert f576c75f95a5, mux patch. Afterwards
let it run on the zoo here... ps883x devices are unaffected and work
well, and your proposed mux patch appears to fix the problem with the
gpio-sbu-mux, too. So it would be a good idea to do this instead of
f576c75f95a5.
Tested on:
Lenovo IdeaCeentre mini 01q8x10 (ps8833)
Lenovo Thinkpad T14s G6 21N1 (ps8830)
Lenovo Ideapad Slim5 14q8x9 (gpio mux)
Lenovo Ideapad 5 2in1 14q8x9 (gpio mux)
Microsoft Windows Dev Kit 2023 (sc8280xp, gpio mux)
Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
with best regards
Jens
On 8/21/26 9:20 PM, Jens Glathe wrote: Hello Jens, >>> I will test that one with the f576c75f95a5 reverted on the x1p and >>> sc8280xp boxes I have here, let's see. T14s G6 shouldn't be affected >>> either way. >>> >>> with best regards >> Thank you > > I did the test: switch patch, revert f576c75f95a5, mux patch. Afterwards > let it run on the zoo here... ps883x devices are unaffected and work > well, and your proposed mux patch appears to fix the problem with the > gpio-sbu-mux, too. So it would be a good idea to do this instead of > f576c75f95a5. > > Tested on: > > Lenovo IdeaCeentre mini 01q8x10 (ps8833) > > Lenovo Thinkpad T14s G6 21N1 (ps8830) > > Lenovo Ideapad Slim5 14q8x9 (gpio mux) > > Lenovo Ideapad 5 2in1 14q8x9 (gpio mux) > > Microsoft Windows Dev Kit 2023 (sc8280xp, gpio mux) > > Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz> Thank you for testing , I have submitted: https://lore.kernel.org/linux-usb/20260822072556.490594-1-marex@nabladev.com/
On 8/17/26 20:22, Marek Vasut wrote:
> The fwnode_typec_switch_get() sporadically returns NULL instead of an
> -EPROBE_DEFER for orientation-switch described in DT.
Hi Marek! Just to make sure, have you seen the patch submission
"usb: typec: mux: initialize orientation switch array"?
https://lore.kernel.org/all/20260804083434.20885-1-i@4t.pw/
It has a fixes tag for the commit you mention and reads: ""Commit
a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
started using the orientation switch result array as state for duplicate
detection, but left the array uninitialized.
The first match therefore scans indeterminate stack contents before any
result has been stored. [...]""
Not my area of expertise, but it sounds related, that's why I wanted to
ensure you are aware of it. If it's something else: sorry!
Ciao, Thorsten
> This makes it
> impossible to discern whether the DT does describe an orientation-switch
> which did not probe yet, or whether the DT does not describe the switch.
> This happens with gpio-sbu-mux connected to an I2C GPIO expander.
>
> The class_find_device() on typec_switch_match() may return NULL in case
> the mux did not probe just yet early on boot. The sw_devs[] array can be
> empty on boot as well. If these two conditions occur, then the conditional
> if (to_typec_switch_dev(dev) == sw_devs[i]) evaluates to true and the match
> function returns NULL, which propagates to fwnode_typec_switch_get() which
> makes it look as if the orientation-switch was not described in DT.
>
> This is incorrect, because the mux driver will probe a bit later on, but
> at that point, the caller of fwnode_typec_switch_get() already got the
> NULL return value. The NULL return value also does not trigger IS_ERR(),
> therefore the caller driver interprets this as if the orientation-switch
> is not described in DT, and does not return -EPROBE_DEFER to try again,
> even if it should.
>
> Fix this by checking the class_find_device() return value, and return
> -EPROBE_DEFER if it is NULL right away. If the return value is not NULL,
> perform the deduplication test, and if that test passes, consider the
> return value to be already non-NULL.
>
> Fixes: a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
> Cc: kernel@dh-electronics.com
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> ---
> NOTE: A similar change was reverted in
> f576c75f95a5 ("Revert "usb: typec: mux: avoid duplicated mux switches"")
> Maybe the orientation switch commit also needs a revert ?
> Or the mux switch revert can be undone and fixed using this NULL check ?
> ---
> drivers/usb/typec/mux.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
> index 9b908c46bd7df..2bc7e8edb3cbd 100644
> --- a/drivers/usb/typec/mux.c
> +++ b/drivers/usb/typec/mux.c
> @@ -56,17 +56,19 @@ static void *typec_switch_match(const struct fwnode_handle *fwnode,
> * function "defers probe" for now.
> */
> dev = class_find_device(&typec_mux_class, NULL, fwnode,
> switch_fwnode_match);
> + if (!dev)
> + return ERR_PTR(-EPROBE_DEFER);
>
> /* Skip duplicates */
> for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++)
> if (to_typec_switch_dev(dev) == sw_devs[i]) {
> put_device(dev);
> return NULL;
> }
>
> - return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
> + return to_typec_switch_dev(dev);
> }
>
> /**
> * fwnode_typec_switch_get - Find USB Type-C orientation switch
On 8/18/26 10:32 AM, Thorsten Leemhuis wrote:
> On 8/17/26 20:22, Marek Vasut wrote:
>> The fwnode_typec_switch_get() sporadically returns NULL instead of an
>> -EPROBE_DEFER for orientation-switch described in DT.
>
> Hi Marek! Just to make sure, have you seen the patch submission
> "usb: typec: mux: initialize orientation switch array"?
> https://lore.kernel.org/all/20260804083434.20885-1-i@4t.pw/
>
> It has a fixes tag for the commit you mention and reads: ""Commit
> a53b4f9c51a9 ("usb: typec: mux: avoid duplicated orientation switches")
> started using the orientation switch result array as state for duplicate
> detection, but left the array uninitialized.
>
> The first match therefore scans indeterminate stack contents before any
> result has been stored. [...]""
That seems like a different issue -- even if the sw_devs[] array is
NULL-initialized, if to_typec_switch_dev() returns NULL, then the
comparison between to_typec_switch_dev() and sw_devs[] would still be
true and the match callback would return NULL instead of EPROBE_DEFER.
© 2016 - 2026 Red Hat, Inc.