Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'introduce-read_poll_timeout'

Dejin Zheng says:

====================
introduce read_poll_timeout

This patch sets is introduce read_poll_timeout macro, it is an extension
of readx_poll_timeout macro. the accessor function op just supports only
one parameter in the readx_poll_timeout macro, but this macro can
supports multiple variable parameters for it. so functions like
phy_read(struct phy_device *phydev, u32 regnum) and
phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) can
use this poll timeout framework.

the first patch introduce read_poll_timeout macro, and the second patch
redefined readx_poll_timeout macro by read_poll_timeout(), and the other
patches are examples using read_poll_timeout macro.

v6 -> v7:
- add a parameter to supports that it can sleep some time
before read operation in read_poll_timeout macro.
- add prefix with double underscores for some variable to avoid
any variable re-declaration or shadowing in patch 3 and patch
7.
v5 -> v6:
- add some check to keep the code more similar in patch 8
v4 -> v5:
- add some msleep() before call phy_read_mmd_poll_timeout() to
keep the code more similar in patch 6 and patch 9.
- add a patch of drop by v4, it can add msleep before call
phy_read_poll_timeout() to keep the code more similar.
v3 -> v4:
- add 3 examples of using new functions.
- deal with precedence issues for parameter cond.
- drop a patch about phy_poll_reset() function.
v2 -> v3:
- modify the parameter order of newly added functions.
phy_read_mmd_poll_timeout(val, cond, sleep_us, timeout_us, \
phydev, devaddr, regnum)
||
\/
phy_read_mmd_poll_timeout(phydev, devaddr regnum, val, cond, \
sleep_us, timeout_us)

phy_read_poll_timeout(val, cond, sleep_us, timeout_us, \
phydev, regnum)
||
\/
phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \
timeout_us)
v1 -> v2:
- passed a phydev, device address and a reg to replace args...
parameter in phy_read_mmd_poll_timeout() by Andrew Lunn 's
suggestion in patch 3. Andrew Lunn <andrew@lunn.ch>, Thanks
very much for your help!
- also in patch 3, handle phy_read_mmd return an error(the return
value < 0) in phy_read_mmd_poll_timeout(). Thanks Andrew
again.
- in patch 6, pass a phydev and a reg to replace args...
parameter in phy_read_poll_timeout(), and also handle the
phy_read() function's return error.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+98 -96
+4 -9
drivers/net/phy/aquantia_main.c
··· 434 434 */ 435 435 static int aqr107_wait_reset_complete(struct phy_device *phydev) 436 436 { 437 - int val, retries = 100; 437 + int val; 438 438 439 - do { 440 - val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); 441 - if (val < 0) 442 - return val; 443 - msleep(20); 444 - } while (!val && --retries); 445 - 446 - return val ? 0 : -ETIMEDOUT; 439 + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 440 + VEND1_GLOBAL_FW_ID, val, val != 0, 441 + 20000, 2000000, false); 447 442 } 448 443 449 444 static void aqr107_chip_info(struct phy_device *phydev)
+4 -23
drivers/net/phy/bcm84881.c
··· 22 22 23 23 static int bcm84881_wait_init(struct phy_device *phydev) 24 24 { 25 - unsigned int tries = 20; 26 - int ret, val; 25 + int val; 27 26 28 - do { 29 - val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1); 30 - if (val < 0) { 31 - ret = val; 32 - break; 33 - } 34 - if (!(val & MDIO_CTRL1_RESET)) { 35 - ret = 0; 36 - break; 37 - } 38 - if (!--tries) { 39 - ret = -ETIMEDOUT; 40 - break; 41 - } 42 - msleep(100); 43 - } while (1); 44 - 45 - if (ret) 46 - phydev_err(phydev, "%s failed: %d\n", __func__, ret); 47 - 48 - return ret; 27 + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, 28 + val, !(val & MDIO_CTRL1_RESET), 29 + 100000, 2000000, false); 49 30 } 50 31 51 32 static int bcm84881_config_init(struct phy_device *phydev)
+5 -10
drivers/net/phy/marvell10g.c
··· 241 241 242 242 static int mv3310_reset(struct phy_device *phydev, u32 unit) 243 243 { 244 - int retries, val, err; 244 + int val, err; 245 245 246 246 err = phy_modify_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1, 247 247 MDIO_CTRL1_RESET, MDIO_CTRL1_RESET); 248 248 if (err < 0) 249 249 return err; 250 250 251 - retries = 20; 252 - do { 253 - msleep(5); 254 - val = phy_read_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1); 255 - if (val < 0) 256 - return val; 257 - } while (val & MDIO_CTRL1_RESET && --retries); 258 - 259 - return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0; 251 + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS, 252 + unit + MDIO_CTRL1, val, 253 + !(val & MDIO_CTRL1_RESET), 254 + 5000, 100000, true); 260 255 } 261 256 262 257 static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd)
+3 -13
drivers/net/phy/nxp-tja11xx.c
··· 72 72 73 73 static int tja11xx_check(struct phy_device *phydev, u8 reg, u16 mask, u16 set) 74 74 { 75 - int i, ret; 75 + int val; 76 76 77 - for (i = 0; i < 200; i++) { 78 - ret = phy_read(phydev, reg); 79 - if (ret < 0) 80 - return ret; 81 - 82 - if ((ret & mask) == set) 83 - return 0; 84 - 85 - usleep_range(100, 150); 86 - } 87 - 88 - return -ETIMEDOUT; 77 + return phy_read_poll_timeout(phydev, reg, val, (val & mask) == set, 78 + 150, 30000, false); 89 79 } 90 80 91 81 static int phy_modify_check(struct phy_device *phydev, u8 reg,
+5 -11
drivers/net/phy/phy_device.c
··· 1059 1059 static int phy_poll_reset(struct phy_device *phydev) 1060 1060 { 1061 1061 /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ 1062 - unsigned int retries = 12; 1063 - int ret; 1062 + int ret, val; 1064 1063 1065 - do { 1066 - msleep(50); 1067 - ret = phy_read(phydev, MII_BMCR); 1068 - if (ret < 0) 1069 - return ret; 1070 - } while (ret & BMCR_RESET && --retries); 1071 - if (ret & BMCR_RESET) 1072 - return -ETIMEDOUT; 1073 - 1064 + ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), 1065 + 50000, 600000, true); 1066 + if (ret) 1067 + return ret; 1074 1068 /* Some chips (smsc911x) may still need up to another 1ms after the 1075 1069 * BMCR_RESET bit is cleared before they are usable. 1076 1070 */
+5 -11
drivers/net/phy/smsc.c
··· 112 112 int err = genphy_read_status(phydev); 113 113 114 114 if (!phydev->link && priv->energy_enable) { 115 - int i; 116 - 117 115 /* Disable EDPD to wake up PHY */ 118 116 int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); 119 117 if (rc < 0) ··· 123 125 return rc; 124 126 125 127 /* Wait max 640 ms to detect energy */ 126 - for (i = 0; i < 64; i++) { 127 - /* Sleep to allow link test pulses to be sent */ 128 - msleep(10); 129 - rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); 130 - if (rc < 0) 131 - return rc; 132 - if (rc & MII_LAN83C185_ENERGYON) 133 - break; 134 - } 128 + phy_read_poll_timeout(phydev, MII_LAN83C185_CTRL_STATUS, rc, 129 + rc & MII_LAN83C185_ENERGYON, 10000, 130 + 640000, true); 131 + if (rc < 0) 132 + return rc; 135 133 136 134 /* Re-enable EDPD */ 137 135 rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
+45 -19
include/linux/iopoll.h
··· 14 14 #include <linux/io.h> 15 15 16 16 /** 17 + * read_poll_timeout - Periodically poll an address until a condition is 18 + * met or a timeout occurs 19 + * @op: accessor function (takes @args as its arguments) 20 + * @val: Variable to read the value into 21 + * @cond: Break condition (usually involving @val) 22 + * @sleep_us: Maximum time to sleep between reads in us (0 23 + * tight-loops). Should be less than ~20ms since usleep_range 24 + * is used (see Documentation/timers/timers-howto.rst). 25 + * @timeout_us: Timeout in us, 0 means never timeout 26 + * @sleep_before_read: if it is true, sleep @sleep_us before read. 27 + * @args: arguments for @op poll 28 + * 29 + * Returns 0 on success and -ETIMEDOUT upon a timeout. In either 30 + * case, the last read value at @args is stored in @val. Must not 31 + * be called from atomic context if sleep_us or timeout_us are used. 32 + * 33 + * When available, you'll probably want to use one of the specialized 34 + * macros defined below rather than this macro directly. 35 + */ 36 + #define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \ 37 + sleep_before_read, args...) \ 38 + ({ \ 39 + u64 __timeout_us = (timeout_us); \ 40 + unsigned long __sleep_us = (sleep_us); \ 41 + ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ 42 + might_sleep_if((__sleep_us) != 0); \ 43 + if (sleep_before_read && __sleep_us) \ 44 + usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ 45 + for (;;) { \ 46 + (val) = op(args); \ 47 + if (cond) \ 48 + break; \ 49 + if (__timeout_us && \ 50 + ktime_compare(ktime_get(), __timeout) > 0) { \ 51 + (val) = op(args); \ 52 + break; \ 53 + } \ 54 + if (__sleep_us) \ 55 + usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ 56 + } \ 57 + (cond) ? 0 : -ETIMEDOUT; \ 58 + }) 59 + 60 + /** 17 61 * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs 18 62 * @op: accessor function (takes @addr as its only argument) 19 63 * @addr: Address to poll ··· 76 32 * macros defined below rather than this macro directly. 77 33 */ 78 34 #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \ 79 - ({ \ 80 - u64 __timeout_us = (timeout_us); \ 81 - unsigned long __sleep_us = (sleep_us); \ 82 - ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ 83 - might_sleep_if((__sleep_us) != 0); \ 84 - for (;;) { \ 85 - (val) = op(addr); \ 86 - if (cond) \ 87 - break; \ 88 - if (__timeout_us && \ 89 - ktime_compare(ktime_get(), __timeout) > 0) { \ 90 - (val) = op(addr); \ 91 - break; \ 92 - } \ 93 - if (__sleep_us) \ 94 - usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ 95 - } \ 96 - (cond) ? 0 : -ETIMEDOUT; \ 97 - }) 35 + read_poll_timeout(op, val, cond, sleep_us, timeout_us, false, addr) 98 36 99 37 /** 100 38 * readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs
+27
include/linux/phy.h
··· 24 24 #include <linux/mod_devicetable.h> 25 25 #include <linux/u64_stats_sync.h> 26 26 #include <linux/irqreturn.h> 27 + #include <linux/iopoll.h> 27 28 28 29 #include <linux/atomic.h> 29 30 ··· 717 716 return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum); 718 717 } 719 718 719 + #define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \ 720 + timeout_us, sleep_before_read) \ 721 + ({ \ 722 + int __ret = read_poll_timeout(phy_read, val, (cond) || val < 0, \ 723 + sleep_us, timeout_us, sleep_before_read, phydev, regnum); \ 724 + if (val < 0) \ 725 + __ret = val; \ 726 + if (__ret) \ 727 + phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \ 728 + __ret; \ 729 + }) 730 + 731 + 720 732 /** 721 733 * __phy_read - convenience function for reading a given PHY register 722 734 * @phydev: the phy_device struct ··· 800 786 * Same rules as for phy_read(); 801 787 */ 802 788 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum); 789 + 790 + #define phy_read_mmd_poll_timeout(phydev, devaddr, regnum, val, cond, \ 791 + sleep_us, timeout_us, sleep_before_read) \ 792 + ({ \ 793 + int __ret = read_poll_timeout(phy_read_mmd, val, (cond) || val < 0, \ 794 + sleep_us, timeout_us, sleep_before_read, \ 795 + phydev, devaddr, regnum); \ 796 + if (val < 0) \ 797 + __ret = val; \ 798 + if (__ret) \ 799 + phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \ 800 + __ret; \ 801 + }) 803 802 804 803 /** 805 804 * __phy_read_mmd - Convenience function for reading a register