diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 2a32f26ead0b8e..047c27087b103f 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -184,7 +184,8 @@ config MDIO_MSCC_MIIM depends on HAS_IOMEM help This driver supports the MIIM (MDIO) interface found in the network - switches of the Microsemi SoCs + switches of the Microsemi SoCs; it is recommended to switch on + CONFIG_HIGH_RES_TIMERS config MDIO_MVUSB tristate "Marvell USB to MDIO Adapter" diff --git a/drivers/net/phy/mdio-mscc-miim.c b/drivers/net/phy/mdio-mscc-miim.c index aed9afa1e8f11c..11f583fd4611fe 100644 --- a/drivers/net/phy/mdio-mscc-miim.c +++ b/drivers/net/phy/mdio-mscc-miim.c @@ -39,13 +39,25 @@ struct mscc_miim_dev { void __iomem *phy_regs; }; +/* When high resolution timers aren't built-in: we can't use usleep_range() as + * we would sleep way too long. Use udelay() instead. + */ +#define mscc_readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \ +({ \ + if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \ + readl_poll_timeout_atomic(addr, val, cond, delay_us, \ + timeout_us); \ + readl_poll_timeout(addr, val, cond, delay_us, timeout_us); \ +}) + static int mscc_miim_wait_ready(struct mii_bus *bus) { struct mscc_miim_dev *miim = bus->priv; u32 val; - return readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, - !(val & MSCC_MIIM_STATUS_STAT_BUSY), 50, 10000); + return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, + !(val & MSCC_MIIM_STATUS_STAT_BUSY), 50, + 10000); } static int mscc_miim_wait_pending(struct mii_bus *bus) @@ -53,9 +65,9 @@ static int mscc_miim_wait_pending(struct mii_bus *bus) struct mscc_miim_dev *miim = bus->priv; u32 val; - return readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, - !(val & MSCC_MIIM_STATUS_STAT_PENDING), - 50, 10000); + return mscc_readl_poll_timeout(miim->regs + MSCC_MIIM_REG_STATUS, val, + !(val & MSCC_MIIM_STATUS_STAT_PENDING), + 50, 10000); } static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)