diff --git a/Documentation/devicetree/bindings/net/mdio.yaml b/Documentation/devicetree/bindings/net/mdio.yaml index d6a3bf8550eb5..26afb556dfae6 100644 --- a/Documentation/devicetree/bindings/net/mdio.yaml +++ b/Documentation/devicetree/bindings/net/mdio.yaml @@ -39,6 +39,13 @@ properties: and must therefore be appropriately determined based on all devices requirements (maximum value of all per-device RESET pulse widths). + reset-post-delay-us: + description: + Delay after reset deassert in microseconds. It applies to all MDIO + devices and it's determined by how fast all devices are ready for + communication. This delay happens just before e.g. Ethernet PHY + type ID auto detection. + clock-frequency: description: Desired MDIO bus clock frequency in Hz. Values greater than IEEE 802.3 diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 46b33701ad4b0..0af20faad69df 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -554,8 +554,10 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) bus->reset_gpiod = gpiod; gpiod_set_value_cansleep(gpiod, 1); - udelay(bus->reset_delay_us); + fsleep(bus->reset_delay_us); gpiod_set_value_cansleep(gpiod, 0); + if (bus->reset_post_delay_us > 0) + fsleep(bus->reset_post_delay_us); } if (bus->reset) { diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index 0f625a1b16447..0837319a52d75 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -132,7 +132,7 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value) d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay; if (d) - usleep_range(d, d + max_t(unsigned int, d / 10, 100)); + fsleep(d); } EXPORT_SYMBOL(mdio_device_reset); diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index eb84507de28ae..cb32d7ef49382 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -268,6 +268,8 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) /* Get bus level PHY reset GPIO details */ mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY; of_property_read_u32(np, "reset-delay-us", &mdio->reset_delay_us); + mdio->reset_post_delay_us = 0; + of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us); /* Register the MDIO bus */ rc = mdiobus_register(mdio); diff --git a/include/linux/phy.h b/include/linux/phy.h index 0403eb7999132..3a09d2bf69ea4 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -293,6 +293,8 @@ struct mii_bus { /* GPIO reset pulse width in microseconds */ int reset_delay_us; + /* GPIO reset deassert delay in microseconds */ + int reset_post_delay_us; /* RESET GPIO descriptor pointer */ struct gpio_desc *reset_gpiod;