Patch "net: mdio: don't defer probe forever if PHY IRQ provider is missing" has been added to the 5.17-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: mdio: don't defer probe forever if PHY IRQ provider is missing

to the 5.17-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-mdio-don-t-defer-probe-forever-if-phy-irq-provid.patch
and it can be found in the queue-5.17 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 5f641b3a04d17485f8bd930a8c1333ecdcf46024
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Thu Apr 7 19:55:38 2022 +0300

    net: mdio: don't defer probe forever if PHY IRQ provider is missing
    
    [ Upstream commit 74befa447e6839cdd90ed541159ec783726946f9 ]
    
    When a driver for an interrupt controller is missing, of_irq_get()
    returns -EPROBE_DEFER ad infinitum, causing
    fwnode_mdiobus_phy_device_register(), and ultimately, the entire
    of_mdiobus_register() call, to fail. In turn, any phy_connect() call
    towards a PHY on this MDIO bus will also fail.
    
    This is not what is expected to happen, because the PHY library falls
    back to poll mode when of_irq_get() returns a hard error code, and the
    MDIO bus, PHY and attached Ethernet controller work fine, albeit
    suboptimally, when the PHY library polls for link status. However,
    -EPROBE_DEFER has special handling given the assumption that at some
    point probe deferral will stop, and the driver for the supplier will
    kick in and create the IRQ domain.
    
    Reasons for which the interrupt controller may be missing:
    
    - It is not yet written. This may happen if a more recent DT blob (with
      an interrupt-parent for the PHY) is used to boot an old kernel where
      the driver didn't exist, and that kernel worked with the
      vintage-correct DT blob using poll mode.
    
    - It is compiled out. Behavior is the same as above.
    
    - It is compiled as a module. The kernel will wait for a number of
      seconds specified in the "deferred_probe_timeout" boot parameter for
      user space to load the required module. The current default is 0,
      which times out at the end of initcalls. It is possible that this
      might cause regressions unless users adjust this boot parameter.
    
    The proposed solution is to use the driver_deferred_probe_check_state()
    helper function provided by the driver core, which gives up after some
    -EPROBE_DEFER attempts, taking "deferred_probe_timeout" into consideration.
    The return code is changed from -EPROBE_DEFER into -ENODEV or
    -ETIMEDOUT, depending on whether the kernel is compiled with support for
    modules or not.
    
    Fixes: 66bdede495c7 ("of_mdio: Fix broken PHY IRQ in case of probe deferral")
    Suggested-by: Robin Murphy <robin.murphy@xxxxxxx>
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Acked-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Reviewed-by: Florian Fainelli <f.fainelli@xxxxxxxxx>
    Link: https://lore.kernel.org/r/20220407165538.4084809-1-vladimir.oltean@xxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 752a11d16e26..7e079fa3795b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -296,6 +296,7 @@ int driver_deferred_probe_check_state(struct device *dev)
 
 	return -EPROBE_DEFER;
 }
+EXPORT_SYMBOL_GPL(driver_deferred_probe_check_state);
 
 static void deferred_probe_timeout_work_func(struct work_struct *work)
 {
diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index 1becb1a731f6..1c1584fca632 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -43,6 +43,11 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
 	int rc;
 
 	rc = fwnode_irq_get(child, 0);
+	/* Don't wait forever if the IRQ provider doesn't become available,
+	 * just fall back to poll mode
+	 */
+	if (rc == -EPROBE_DEFER)
+		rc = driver_deferred_probe_check_state(&phy->mdio.dev);
 	if (rc == -EPROBE_DEFER)
 		return rc;
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux