blob: 26de067a62070ecd1e9c0f359e986faf722492e2 [file] [log] [blame]
developer394d5eb2023-04-14 16:46:45 +08001From patchwork Mon Mar 23 15:05:51 2020
2Content-Type: text/plain; charset="utf-8"
3MIME-Version: 1.0
4Content-Transfer-Encoding: 7bit
5X-Patchwork-Submitter: Dejin Zheng <zhengdejin5@gmail.com>
6X-Patchwork-Id: 1260097
7X-Patchwork-Delegate: davem@davemloft.net
8Return-Path: <netdev-owner@vger.kernel.org>
9X-Original-To: patchwork-incoming-netdev@ozlabs.org
10Delivered-To: patchwork-incoming-netdev@ozlabs.org
11Authentication-Results: ozlabs.org; spf=none (no SPF record)
12 smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
13 helo=vger.kernel.org;
14 envelope-from=netdev-owner@vger.kernel.org;
15 receiver=<UNKNOWN>)
16Authentication-Results: ozlabs.org;
17 dmarc=pass (p=none dis=none) header.from=gmail.com
18Authentication-Results: ozlabs.org; dkim=pass (2048-bit key;
19 unprotected) header.d=gmail.com header.i=@gmail.com
20 header.a=rsa-sha256 header.s=20161025 header.b=N1ACwCYl;
21 dkim-atps=neutral
22Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
23 by ozlabs.org (Postfix) with ESMTP id 48mHlP3Hzhz9sSs
24 for <patchwork-incoming-netdev@ozlabs.org>;
25 Tue, 24 Mar 2020 02:06:25 +1100 (AEDT)
26Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
27 id S1727267AbgCWPGW (ORCPT
28 <rfc822;patchwork-incoming-netdev@ozlabs.org>);
29 Mon, 23 Mar 2020 11:06:22 -0400
30Received: from mail-pj1-f68.google.com ([209.85.216.68]:50286 "EHLO
31 mail-pj1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
32 with ESMTP id S1727024AbgCWPGV (ORCPT
33 <rfc822;netdev@vger.kernel.org>); Mon, 23 Mar 2020 11:06:21 -0400
34Received: by mail-pj1-f68.google.com with SMTP id v13so6312358pjb.0;
35 Mon, 23 Mar 2020 08:06:20 -0700 (PDT)
36DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
37 d=gmail.com; s=20161025;
38 h=from:to:cc:subject:date:message-id:in-reply-to:references
39 :mime-version:content-transfer-encoding;
40 bh=GmXKgcJDZee4jC3cNKHKWCJhJ0kS9L2vONq2fIA+AaY=;
41 b=N1ACwCYlon7WkTCOGFsGWeQq6lNeUjbuQa8UGIBK7O82wFqYoTVzGY8MUnU/tEjer9
42 AtZt9996i6pDsvhpbunlFffuKPui1YOisSe6Xcn6Ur2AiFvfJr1DMpWE2PdmlLGH2bkH
43 /Oiqbikpi9dSUfgFJ7JfIyISqKyP15jsdhhl8xtA30gWb6CuhlhBuWuLV5CqTAZKGWab
44 LMFipg2GDKlx0udJoUoNAPi/hcypdWJW8DtamDxwH/OmZk2evJsfhm2MwG/1qAb95nJ0
45 rU/60e4BhqadPHfO9cyvgdbR+xcCJkuSIqKWH6utfd9RamZDS2djU3XDWhFW2blmcVLb
46 Ue5w==
47X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
48 d=1e100.net; s=20161025;
49 h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
50 :references:mime-version:content-transfer-encoding;
51 bh=GmXKgcJDZee4jC3cNKHKWCJhJ0kS9L2vONq2fIA+AaY=;
52 b=AwMmzIpdEKD6duSw3Dl9aQkzxRMmPOysumBp0nIE9FvhZJ+67auGBvMa7G80/DyF4x
53 BbrwsUrYoDLXs7fuLEjjZgxKwSCtYfWyPDdM/ezShIx9KZIfPiXhn6uH3eXP+g4feJN4
54 IlWVwvJMDzRJOhdZVzg934FJeMs4bW7XNm07jKxjsqksHGcw5JoHsP53xNegPbIpNb8X
55 h7+AwHXYAKzVC9aGYTA8bgxSD0d+SlO7CJ4nY+lHXcBR266/rt7rDFOwCdv9TUUAMCkY
56 rXrgSb8vThpKY/wZ8rK3SyJcPdvDt6TnmdZO7LqTbbzAHjzJml7s+5vYhk3CSOvjGTHt
57 KcMA==
58X-Gm-Message-State: ANhLgQ1lOBl50y5dc6fz/BIFJrpgXnM0GF/1DvoZm8oJbZIt2H9n38WA
59 pBi6LVse2n2Ed5tvz68N8x8=
60X-Google-Smtp-Source:
61 ADFU+vtPoQt/0UFiy7Bq0L9uIMvQbBOJzH8+jTojBCcjj2V26XqJvxqSMSsy9g8ZZ96F/Q8I4cpXYw==
62X-Received: by 2002:a17:902:9a09:: with SMTP id
63 v9mr21358610plp.341.1584975980336;
64 Mon, 23 Mar 2020 08:06:20 -0700 (PDT)
65Received: from localhost (176.122.158.203.16clouds.com. [176.122.158.203])
66 by smtp.gmail.com with ESMTPSA id
67 j19sm13485589pfe.102.2020.03.23.08.06.19
68 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
69 Mon, 23 Mar 2020 08:06:19 -0700 (PDT)
70From: Dejin Zheng <zhengdejin5@gmail.com>
71To: andrew@lunn.ch, f.fainelli@gmail.com, hkallweit1@gmail.com,
72 linux@armlinux.org.uk, davem@davemloft.net, corbet@lwn.net,
73 tglx@linutronix.de, gregkh@linuxfoundation.org,
74 allison@lohutok.net, mchehab+samsung@kernel.org, netdev@vger.kernel.org
75Cc: linux-kernel@vger.kernel.org, Dejin Zheng <zhengdejin5@gmail.com>
76Subject: [PATCH net-next v7 01/10] iopoll: introduce read_poll_timeout macro
77Date: Mon, 23 Mar 2020 23:05:51 +0800
78Message-Id: <20200323150600.21382-2-zhengdejin5@gmail.com>
79X-Mailer: git-send-email 2.25.0
80In-Reply-To: <20200323150600.21382-1-zhengdejin5@gmail.com>
81References: <20200323150600.21382-1-zhengdejin5@gmail.com>
82MIME-Version: 1.0
83Sender: netdev-owner@vger.kernel.org
84Precedence: bulk
85List-ID: <netdev.vger.kernel.org>
86X-Mailing-List: netdev@vger.kernel.org
87
88this macro is an extension of readx_poll_timeout macro. the accessor
89function op just supports only one parameter in the readx_poll_timeout
90macro, but this macro can supports multiple variable parameters for
91it. so functions like phy_read(struct phy_device *phydev, u32 regnum)
92and phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) can
93also use this poll timeout core. and also expand it can sleep some time
94before read operation.
95
96Signed-off-by: Dejin Zheng <zhengdejin5@gmail.com>
97---
98v6 -> v7:
99 - add a parameter sleep_before_read to support that it can sleep
100 some time before read operation in read_poll_timeout macro.
101v5 -> v6:
102 - no changed
103v4 -> v5:
104 - no changed
105v3 -> v4:
106 - no changed
107v2 -> v3:
108 - no changed
109v1 -> v2:
110 - no changed
111
112 include/linux/iopoll.h | 44 ++++++++++++++++++++++++++++++++++++++++++
113 1 file changed, 44 insertions(+)
114
115--- a/include/linux/iopoll.h
116+++ b/include/linux/iopoll.h
117@@ -14,36 +14,41 @@
118 #include <linux/io.h>
119
120 /**
121- * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
122- * @op: accessor function (takes @addr as its only argument)
123- * @addr: Address to poll
124+ * read_poll_timeout - Periodically poll an address until a condition is
125+ * met or a timeout occurs
126+ * @op: accessor function (takes @args as its arguments)
127 * @val: Variable to read the value into
128 * @cond: Break condition (usually involving @val)
129 * @sleep_us: Maximum time to sleep between reads in us (0
130 * tight-loops). Should be less than ~20ms since usleep_range
131 * is used (see Documentation/timers/timers-howto.rst).
132 * @timeout_us: Timeout in us, 0 means never timeout
133+ * @sleep_before_read: if it is true, sleep @sleep_us before read.
134+ * @args: arguments for @op poll
135 *
136 * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
137- * case, the last read value at @addr is stored in @val. Must not
138+ * case, the last read value at @args is stored in @val. Must not
139 * be called from atomic context if sleep_us or timeout_us are used.
140 *
141 * When available, you'll probably want to use one of the specialized
142 * macros defined below rather than this macro directly.
143 */
144-#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
145+#define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \
146+ sleep_before_read, args...) \
147 ({ \
148 u64 __timeout_us = (timeout_us); \
149 unsigned long __sleep_us = (sleep_us); \
150 ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
151 might_sleep_if((__sleep_us) != 0); \
152+ if (sleep_before_read && __sleep_us) \
153+ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
154 for (;;) { \
155- (val) = op(addr); \
156+ (val) = op(args); \
157 if (cond) \
158 break; \
159 if (__timeout_us && \
160 ktime_compare(ktime_get(), __timeout) > 0) { \
161- (val) = op(addr); \
162+ (val) = op(args); \
163 break; \
164 } \
165 if (__sleep_us) \
166@@ -53,6 +58,27 @@
167 })
168
169 /**
170+ * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
171+ * @op: accessor function (takes @addr as its only argument)
172+ * @addr: Address to poll
173+ * @val: Variable to read the value into
174+ * @cond: Break condition (usually involving @val)
175+ * @sleep_us: Maximum time to sleep between reads in us (0
176+ * tight-loops). Should be less than ~20ms since usleep_range
177+ * is used (see Documentation/timers/timers-howto.rst).
178+ * @timeout_us: Timeout in us, 0 means never timeout
179+ *
180+ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
181+ * case, the last read value at @addr is stored in @val. Must not
182+ * be called from atomic context if sleep_us or timeout_us are used.
183+ *
184+ * When available, you'll probably want to use one of the specialized
185+ * macros defined below rather than this macro directly.
186+ */
187+#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
188+ read_poll_timeout(op, val, cond, sleep_us, timeout_us, false, addr)
189+
190+/**
191 * readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs
192 * @op: accessor function (takes @addr as its only argument)
193 * @addr: Address to poll
194--- a/include/linux/phy.h
195+++ b/include/linux/phy.h
196@@ -21,6 +21,7 @@
197 #include <linux/timer.h>
198 #include <linux/workqueue.h>
199 #include <linux/mod_devicetable.h>
200+#include <linux/iopoll.h>
201
202 #include <linux/atomic.h>
203
204@@ -714,6 +715,19 @@ static inline int phy_read(struct phy_de
205 return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
206 }
207
208+#define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \
209+ timeout_us, sleep_before_read) \
210+({ \
211+ int __ret = read_poll_timeout(phy_read, val, (cond) || val < 0, \
212+ sleep_us, timeout_us, sleep_before_read, phydev, regnum); \
213+ if (val < 0) \
214+ __ret = val; \
215+ if (__ret) \
216+ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
217+ __ret; \
218+})
219+
220+
221 /**
222 * __phy_read - convenience function for reading a given PHY register
223 * @phydev: the phy_device struct
224@@ -766,6 +780,19 @@ static inline int __phy_write(struct phy
225 */
226 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
227
228+#define phy_read_mmd_poll_timeout(phydev, devaddr, regnum, val, cond, \
229+ sleep_us, timeout_us, sleep_before_read) \
230+({ \
231+ int __ret = read_poll_timeout(phy_read_mmd, val, (cond) || val < 0, \
232+ sleep_us, timeout_us, sleep_before_read, \
233+ phydev, devaddr, regnum); \
234+ if (val < 0) \
235+ __ret = val; \
236+ if (__ret) \
237+ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
238+ __ret; \
239+})
240+
241 /**
242 * __phy_read_mmd - Convenience function for reading a register
243 * from an MMD on a given PHY.
244--- a/drivers/net/phy/phy_device.c
245+++ b/drivers/net/phy/phy_device.c
246@@ -1056,18 +1056,12 @@ EXPORT_SYMBOL(phy_disconnect);
247 static int phy_poll_reset(struct phy_device *phydev)
248 {
249 /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
250- unsigned int retries = 12;
251- int ret;
252-
253- do {
254- msleep(50);
255- ret = phy_read(phydev, MII_BMCR);
256- if (ret < 0)
257- return ret;
258- } while (ret & BMCR_RESET && --retries);
259- if (ret & BMCR_RESET)
260- return -ETIMEDOUT;
261+ int ret, val;
262
263+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
264+ 50000, 600000, true);
265+ if (ret)
266+ return ret;
267 /* Some chips (smsc911x) may still need up to another 1ms after the
268 * BMCR_RESET bit is cleared before they are usable.
269 */