* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 21:09 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-10-30 21:09 UTC (permalink / raw)
To: linux-arm-kernel
In multi-master environment, this driver's master cannot know
exactly when a peer master sends data to this driver's slave so a
case can be happened that this master tries to send data through
the master_xfer function but slave data from peer master is still
being processed by this driver.
To prevent any state corruption in the case, this patch adds
checking code if any slave operation is ongoing and it waits up to
the bus timeout duration before starting a master_xfer operation.
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
---
drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 833b6b6a4c7e..30c3ab3a4844 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/completion.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
@@ -115,6 +116,9 @@
/* 0x18 : I2CD Slave Device Address Register */
#define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
+/* Busy checking */
+#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
+
enum aspeed_i2c_master_state {
ASPEED_I2C_MASTER_INACTIVE,
ASPEED_I2C_MASTER_START,
@@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
int cmd_err;
/* Protected only by i2c_lock_bus */
int master_xfer_result;
+ /* Multi-master */
+ bool multi_master;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
struct i2c_client *slave;
enum aspeed_i2c_slave_state slave_state;
@@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
}
+static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
+{
+ unsigned long timeout;
+
+ if (bus->multi_master) {
+ might_sleep();
+ /* Initialize it only when multi_master is set */
+ timeout = jiffies + bus->adap.timeout;
+ }
+
+ for (;;) {
+ if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
+ ASPEED_I2CD_BUS_BUSY_STS))
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
+#endif
+ return 0;
+ if (!bus->multi_master)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
+ ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
+ }
+
+ return aspeed_i2c_recover_bus(bus);
+}
+
static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
unsigned long time_left, flags;
- int ret = 0;
- spin_lock_irqsave(&bus->lock, flags);
- bus->cmd_err = 0;
-
- /* If bus is busy, attempt recovery. We assume a single master
- * environment.
- */
- if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
- spin_unlock_irqrestore(&bus->lock, flags);
- ret = aspeed_i2c_recover_bus(bus);
- if (ret)
- return ret;
- spin_lock_irqsave(&bus->lock, flags);
- }
+ if (aspeed_i2c_check_bus_busy(bus))
+ return -EAGAIN;
+ spin_lock_irqsave(&bus->lock, flags);
bus->cmd_err = 0;
bus->msgs = msgs;
bus->msgs_index = 0;
@@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
if (ret < 0)
return ret;
- if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
+ if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
+ bus->multi_master = true;
+ else
fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
/* Enable Master Mode */
--
2.19.1
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 21:09 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-10-30 21:09 UTC (permalink / raw)
To: Wolfram Sang, Brendan Higgins, Rob Herring, Joel Stanley,
Benjamin Herrenschmidt, Mark Rutland, Andrew Jeffery, linux-i2c,
openbmc, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
Cc: Jarkko Nikula, James Feist, Vernon Mauery, Jae Hyun Yoo
In multi-master environment, this driver's master cannot know
exactly when a peer master sends data to this driver's slave so a
case can be happened that this master tries to send data through
the master_xfer function but slave data from peer master is still
being processed by this driver.
To prevent any state corruption in the case, this patch adds
checking code if any slave operation is ongoing and it waits up to
the bus timeout duration before starting a master_xfer operation.
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
---
drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 833b6b6a4c7e..30c3ab3a4844 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/completion.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
@@ -115,6 +116,9 @@
/* 0x18 : I2CD Slave Device Address Register */
#define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
+/* Busy checking */
+#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
+
enum aspeed_i2c_master_state {
ASPEED_I2C_MASTER_INACTIVE,
ASPEED_I2C_MASTER_START,
@@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
int cmd_err;
/* Protected only by i2c_lock_bus */
int master_xfer_result;
+ /* Multi-master */
+ bool multi_master;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
struct i2c_client *slave;
enum aspeed_i2c_slave_state slave_state;
@@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
}
+static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
+{
+ unsigned long timeout;
+
+ if (bus->multi_master) {
+ might_sleep();
+ /* Initialize it only when multi_master is set */
+ timeout = jiffies + bus->adap.timeout;
+ }
+
+ for (;;) {
+ if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
+ ASPEED_I2CD_BUS_BUSY_STS))
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
+#endif
+ return 0;
+ if (!bus->multi_master)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
+ ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
+ }
+
+ return aspeed_i2c_recover_bus(bus);
+}
+
static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
unsigned long time_left, flags;
- int ret = 0;
- spin_lock_irqsave(&bus->lock, flags);
- bus->cmd_err = 0;
-
- /* If bus is busy, attempt recovery. We assume a single master
- * environment.
- */
- if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
- spin_unlock_irqrestore(&bus->lock, flags);
- ret = aspeed_i2c_recover_bus(bus);
- if (ret)
- return ret;
- spin_lock_irqsave(&bus->lock, flags);
- }
+ if (aspeed_i2c_check_bus_busy(bus))
+ return -EAGAIN;
+ spin_lock_irqsave(&bus->lock, flags);
bus->cmd_err = 0;
bus->msgs = msgs;
bus->msgs_index = 0;
@@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
if (ret < 0)
return ret;
- if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
+ if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
+ bus->multi_master = true;
+ else
fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
/* Enable Master Mode */
--
2.19.1
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
2018-10-30 21:09 ` Jae Hyun Yoo
(?)
(?)
@ 2018-10-30 22:22 ` kbuild test robot
-1 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-10-30 22:22 UTC (permalink / raw)
To: linux-aspeed
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181030]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c/busses/i2c-aspeed.c:13:
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
--
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c//busses/i2c-aspeed.c:13:
drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +108 include/linux/jiffies.h
^1da177e Linus Torvalds 2005-04-16 91
^1da177e Linus Torvalds 2005-04-16 92 /*
^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
^1da177e Linus Torvalds 2005-04-16 98 *
^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
^1da177e Linus Torvalds 2005-04-16 100 *
^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
^1da177e Linus Torvalds 2005-04-16 104 */
^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
^1da177e Linus Torvalds 2005-04-16 110
:::::: The code at line 108 was first introduced by commit
:::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
:::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
:::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 55213 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/linux-aspeed/attachments/20181031/ce27fe2c/attachment-0001.gz>
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 22:22 ` kbuild test robot
0 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-10-30 22:22 UTC (permalink / raw)
To: linux-arm-kernel
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181030]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c/busses/i2c-aspeed.c:13:
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
--
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c//busses/i2c-aspeed.c:13:
drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +108 include/linux/jiffies.h
^1da177e Linus Torvalds 2005-04-16 91
^1da177e Linus Torvalds 2005-04-16 92 /*
^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
^1da177e Linus Torvalds 2005-04-16 98 *
^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
^1da177e Linus Torvalds 2005-04-16 100 *
^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
^1da177e Linus Torvalds 2005-04-16 104 */
^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
^1da177e Linus Torvalds 2005-04-16 110
:::::: The code at line 108 was first introduced by commit
:::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
:::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
:::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 55213 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20181031/ce27fe2c/attachment-0001.gz>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 22:22 ` kbuild test robot
0 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-10-30 22:22 UTC (permalink / raw)
To: Jae Hyun Yoo
Cc: kbuild-all, Wolfram Sang, Brendan Higgins, Rob Herring,
Joel Stanley, Benjamin Herrenschmidt, Mark Rutland,
Andrew Jeffery, linux-i2c, openbmc, devicetree, linux-arm-kernel,
linux-aspeed, linux-kernel, Jarkko Nikula, James Feist,
Vernon Mauery, Jae Hyun Yoo
[-- Attachment #1: Type: text/plain, Size: 4533 bytes --]
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181030]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c/busses/i2c-aspeed.c:13:
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
--
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c//busses/i2c-aspeed.c:13:
drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +108 include/linux/jiffies.h
^1da177e Linus Torvalds 2005-04-16 91
^1da177e Linus Torvalds 2005-04-16 92 /*
^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
^1da177e Linus Torvalds 2005-04-16 98 *
^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
^1da177e Linus Torvalds 2005-04-16 100 *
^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
^1da177e Linus Torvalds 2005-04-16 104 */
^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
^1da177e Linus Torvalds 2005-04-16 110
:::::: The code at line 108 was first introduced by commit
:::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
:::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
:::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 55213 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 22:22 ` kbuild test robot
0 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-10-30 22:22 UTC (permalink / raw)
Cc: Mark Rutland, devicetree, Jae Hyun Yoo, linux-aspeed,
Wolfram Sang, Andrew Jeffery, Benjamin Herrenschmidt, openbmc,
Brendan Higgins, linux-kernel, James Feist, linux-i2c,
Rob Herring, Jarkko Nikula, Joel Stanley, Vernon Mauery,
linux-arm-kernel, kbuild-all
[-- Attachment #1: Type: text/plain, Size: 4533 bytes --]
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181030]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c/busses/i2c-aspeed.c:13:
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
--
In file included from include/linux/ktime.h:25,
from include/linux/rcutiny.h:28,
from include/linux/rcupdate.h:209,
from include/linux/srcu.h:33,
from include/linux/notifier.h:16,
from include/linux/clk.h:17,
from drivers/i2c//busses/i2c-aspeed.c:13:
drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
((long)((b) - (a)) < 0))
^
drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +108 include/linux/jiffies.h
^1da177e Linus Torvalds 2005-04-16 91
^1da177e Linus Torvalds 2005-04-16 92 /*
^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
^1da177e Linus Torvalds 2005-04-16 98 *
^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
^1da177e Linus Torvalds 2005-04-16 100 *
^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
^1da177e Linus Torvalds 2005-04-16 104 */
^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
^1da177e Linus Torvalds 2005-04-16 110
:::::: The code at line 108 was first introduced by commit
:::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
:::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
:::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 55213 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
2018-10-30 22:22 ` kbuild test robot
(?)
@ 2018-10-30 23:04 ` Jae Hyun Yoo
-1 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-10-30 23:04 UTC (permalink / raw)
To: linux-aspeed
On 10/30/2018 3:22 PM, kbuild test robot wrote:
> Hi Jae,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on wsa/i2c/for-next]
> [also build test WARNING on v4.19 next-20181030]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
> base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
> config: xtensa-allyesconfig (attached as .config)
> compiler: xtensa-linux-gcc (GCC) 8.1.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=8.1.0 make.cross ARCH=xtensa
>
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>
> All warnings (new ones prefixed by >>):
>
> In file included from include/linux/ktime.h:25,
> from include/linux/rcutiny.h:28,
> from include/linux/rcupdate.h:209,
> from include/linux/srcu.h:33,
> from include/linux/notifier.h:16,
> from include/linux/clk.h:17,
> from drivers/i2c/busses/i2c-aspeed.c:13:
> drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ((long)((b) - (a)) < 0))
> ^
> drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
> --
> In file included from include/linux/ktime.h:25,
> from include/linux/rcutiny.h:28,
> from include/linux/rcupdate.h:209,
> from include/linux/srcu.h:33,
> from include/linux/notifier.h:16,
> from include/linux/clk.h:17,
> from drivers/i2c//busses/i2c-aspeed.c:13:
> drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ((long)((b) - (a)) < 0))
> ^
> drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
>
> vim +/timeout +108 include/linux/jiffies.h
>
> ^1da177e Linus Torvalds 2005-04-16 91
> ^1da177e Linus Torvalds 2005-04-16 92 /*
> ^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
> ^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
> ^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
> ^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
> ^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
> ^1da177e Linus Torvalds 2005-04-16 98 *
> ^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
> ^1da177e Linus Torvalds 2005-04-16 100 *
> ^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
> ^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
> ^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
> ^1da177e Linus Torvalds 2005-04-16 104 */
> ^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
> ^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
> ^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
> 5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
> ^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
> ^1da177e Linus Torvalds 2005-04-16 110
>
> :::::: The code at line 108 was first introduced by commit
> :::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
>
> :::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> :::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
This is a false warning.
The 'timeout' local variable will be initialized properly if it's gonna
be used when the multi-master property is set.
-Jae
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 23:04 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-10-30 23:04 UTC (permalink / raw)
To: linux-arm-kernel
On 10/30/2018 3:22 PM, kbuild test robot wrote:
> Hi Jae,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on wsa/i2c/for-next]
> [also build test WARNING on v4.19 next-20181030]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
> base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
> config: xtensa-allyesconfig (attached as .config)
> compiler: xtensa-linux-gcc (GCC) 8.1.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=8.1.0 make.cross ARCH=xtensa
>
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>
> All warnings (new ones prefixed by >>):
>
> In file included from include/linux/ktime.h:25,
> from include/linux/rcutiny.h:28,
> from include/linux/rcupdate.h:209,
> from include/linux/srcu.h:33,
> from include/linux/notifier.h:16,
> from include/linux/clk.h:17,
> from drivers/i2c/busses/i2c-aspeed.c:13:
> drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ((long)((b) - (a)) < 0))
> ^
> drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
> --
> In file included from include/linux/ktime.h:25,
> from include/linux/rcutiny.h:28,
> from include/linux/rcupdate.h:209,
> from include/linux/srcu.h:33,
> from include/linux/notifier.h:16,
> from include/linux/clk.h:17,
> from drivers/i2c//busses/i2c-aspeed.c:13:
> drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ((long)((b) - (a)) < 0))
> ^
> drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
>
> vim +/timeout +108 include/linux/jiffies.h
>
> ^1da177e Linus Torvalds 2005-04-16 91
> ^1da177e Linus Torvalds 2005-04-16 92 /*
> ^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
> ^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
> ^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
> ^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
> ^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
> ^1da177e Linus Torvalds 2005-04-16 98 *
> ^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
> ^1da177e Linus Torvalds 2005-04-16 100 *
> ^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
> ^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
> ^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
> ^1da177e Linus Torvalds 2005-04-16 104 */
> ^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
> ^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
> ^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
> 5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
> ^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
> ^1da177e Linus Torvalds 2005-04-16 110
>
> :::::: The code at line 108 was first introduced by commit
> :::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
>
> :::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> :::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
This is a false warning.
The 'timeout' local variable will be initialized properly if it's gonna
be used when the multi-master property is set.
-Jae
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-10-30 23:04 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-10-30 23:04 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, Wolfram Sang, Brendan Higgins, Rob Herring,
Joel Stanley, Benjamin Herrenschmidt, Mark Rutland,
Andrew Jeffery, linux-i2c, openbmc, devicetree, linux-arm-kernel,
linux-aspeed, linux-kernel, Jarkko Nikula, James Feist,
Vernon Mauery
On 10/30/2018 3:22 PM, kbuild test robot wrote:
> Hi Jae,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on wsa/i2c/for-next]
> [also build test WARNING on v4.19 next-20181030]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
> base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
> config: xtensa-allyesconfig (attached as .config)
> compiler: xtensa-linux-gcc (GCC) 8.1.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=8.1.0 make.cross ARCH=xtensa
>
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>
> All warnings (new ones prefixed by >>):
>
> In file included from include/linux/ktime.h:25,
> from include/linux/rcutiny.h:28,
> from include/linux/rcupdate.h:209,
> from include/linux/srcu.h:33,
> from include/linux/notifier.h:16,
> from include/linux/clk.h:17,
> from drivers/i2c/busses/i2c-aspeed.c:13:
> drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ((long)((b) - (a)) < 0))
> ^
> drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
> --
> In file included from include/linux/ktime.h:25,
> from include/linux/rcutiny.h:28,
> from include/linux/rcupdate.h:209,
> from include/linux/srcu.h:33,
> from include/linux/notifier.h:16,
> from include/linux/clk.h:17,
> from drivers/i2c//busses/i2c-aspeed.c:13:
> drivers/i2c//busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> include/linux/jiffies.h:108:15: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ((long)((b) - (a)) < 0))
> ^
> drivers/i2c//busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
>
> vim +/timeout +108 include/linux/jiffies.h
>
> ^1da177e Linus Torvalds 2005-04-16 91
> ^1da177e Linus Torvalds 2005-04-16 92 /*
> ^1da177e Linus Torvalds 2005-04-16 93 * These inlines deal with timer wrapping correctly. You are
> ^1da177e Linus Torvalds 2005-04-16 94 * strongly encouraged to use them
> ^1da177e Linus Torvalds 2005-04-16 95 * 1. Because people otherwise forget
> ^1da177e Linus Torvalds 2005-04-16 96 * 2. Because if the timer wrap changes in future you won't have to
> ^1da177e Linus Torvalds 2005-04-16 97 * alter your driver code.
> ^1da177e Linus Torvalds 2005-04-16 98 *
> ^1da177e Linus Torvalds 2005-04-16 99 * time_after(a,b) returns true if the time a is after time b.
> ^1da177e Linus Torvalds 2005-04-16 100 *
> ^1da177e Linus Torvalds 2005-04-16 101 * Do this with "<0" and ">=0" to only test the sign of the result. A
> ^1da177e Linus Torvalds 2005-04-16 102 * good compiler would generate better code (and a really good compiler
> ^1da177e Linus Torvalds 2005-04-16 103 * wouldn't care). Gcc is currently neither.
> ^1da177e Linus Torvalds 2005-04-16 104 */
> ^1da177e Linus Torvalds 2005-04-16 105 #define time_after(a,b) \
> ^1da177e Linus Torvalds 2005-04-16 106 (typecheck(unsigned long, a) && \
> ^1da177e Linus Torvalds 2005-04-16 107 typecheck(unsigned long, b) && \
> 5a581b36 Paul E. McKenney 2013-07-27 @108 ((long)((b) - (a)) < 0))
> ^1da177e Linus Torvalds 2005-04-16 109 #define time_before(a,b) time_after(b,a)
> ^1da177e Linus Torvalds 2005-04-16 110
>
> :::::: The code at line 108 was first introduced by commit
> :::::: 5a581b367b5df0531265311fc681c2abd377e5e6 jiffies: Avoid undefined behavior from signed overflow
>
> :::::: TO: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> :::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
This is a false warning.
The 'timeout' local variable will be initialized properly if it's gonna
be used when the multi-master property is set.
-Jae
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
2018-10-30 21:09 ` Jae Hyun Yoo
(?)
(?)
@ 2018-11-01 17:44 ` kbuild test robot
-1 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-11-01 17:44 UTC (permalink / raw)
To: linux-aspeed
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181101]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (time_after(jiffies, timeout))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
604
605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
606 {
607 unsigned long timeout;
608
609 if (bus->multi_master) {
610 might_sleep();
611 /* Initialize it only when multi_master is set */
612 timeout = jiffies + bus->adap.timeout;
613 }
614
615 for (;;) {
616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
617 ASPEED_I2CD_BUS_BUSY_STS))
618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
620 #endif
621 return 0;
622 if (!bus->multi_master)
623 break;
> 624 if (time_after(jiffies, timeout))
625 break;
626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
628 }
629
630 return aspeed_i2c_recover_bus(bus);
631 }
632
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 64563 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/linux-aspeed/attachments/20181102/9bc6f6c4/attachment-0001.gz>
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-01 17:44 ` kbuild test robot
0 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-11-01 17:44 UTC (permalink / raw)
To: linux-arm-kernel
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181101]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (time_after(jiffies, timeout))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
604
605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
606 {
607 unsigned long timeout;
608
609 if (bus->multi_master) {
610 might_sleep();
611 /* Initialize it only when multi_master is set */
612 timeout = jiffies + bus->adap.timeout;
613 }
614
615 for (;;) {
616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
617 ASPEED_I2CD_BUS_BUSY_STS))
618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
620 #endif
621 return 0;
622 if (!bus->multi_master)
623 break;
> 624 if (time_after(jiffies, timeout))
625 break;
626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
628 }
629
630 return aspeed_i2c_recover_bus(bus);
631 }
632
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 64563 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20181102/9bc6f6c4/attachment-0001.gz>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-01 17:44 ` kbuild test robot
0 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-11-01 17:44 UTC (permalink / raw)
To: Jae Hyun Yoo
Cc: kbuild-all, Wolfram Sang, Brendan Higgins, Rob Herring,
Joel Stanley, Benjamin Herrenschmidt, Mark Rutland,
Andrew Jeffery, linux-i2c, openbmc, devicetree, linux-arm-kernel,
linux-aspeed, linux-kernel, Jarkko Nikula, James Feist,
Vernon Mauery, Jae Hyun Yoo
[-- Attachment #1: Type: text/plain, Size: 2540 bytes --]
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181101]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (time_after(jiffies, timeout))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
604
605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
606 {
607 unsigned long timeout;
608
609 if (bus->multi_master) {
610 might_sleep();
611 /* Initialize it only when multi_master is set */
612 timeout = jiffies + bus->adap.timeout;
613 }
614
615 for (;;) {
616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
617 ASPEED_I2CD_BUS_BUSY_STS))
618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
620 #endif
621 return 0;
622 if (!bus->multi_master)
623 break;
> 624 if (time_after(jiffies, timeout))
625 break;
626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
628 }
629
630 return aspeed_i2c_recover_bus(bus);
631 }
632
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 64563 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-01 17:44 ` kbuild test robot
0 siblings, 0 replies; 50+ messages in thread
From: kbuild test robot @ 2018-11-01 17:44 UTC (permalink / raw)
Cc: kbuild-all, Wolfram Sang, Brendan Higgins, Rob Herring,
Joel Stanley, Benjamin Herrenschmidt, Mark Rutland,
Andrew Jeffery, linux-i2c, openbmc, devicetree, linux-arm-kernel,
linux-aspeed, linux-kernel, Jarkko Nikula, James Feist,
Vernon Mauery, Jae Hyun Yoo
[-- Attachment #1: Type: text/plain, Size: 2540 bytes --]
Hi Jae,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.19 next-20181101]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (time_after(jiffies, timeout))
^
drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
unsigned long timeout;
^~~~~~~
vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
604
605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
606 {
607 unsigned long timeout;
608
609 if (bus->multi_master) {
610 might_sleep();
611 /* Initialize it only when multi_master is set */
612 timeout = jiffies + bus->adap.timeout;
613 }
614
615 for (;;) {
616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
617 ASPEED_I2CD_BUS_BUSY_STS))
618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
620 #endif
621 return 0;
622 if (!bus->multi_master)
623 break;
> 624 if (time_after(jiffies, timeout))
625 break;
626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
628 }
629
630 return aspeed_i2c_recover_bus(bus);
631 }
632
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 64563 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
2018-11-01 17:44 ` kbuild test robot
(?)
@ 2018-11-01 18:09 ` Jae Hyun Yoo
-1 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-11-01 18:09 UTC (permalink / raw)
To: linux-aspeed
On 11/1/2018 10:44 AM, kbuild test robot wrote:
> Hi Jae,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on wsa/i2c/for-next]
> [also build test WARNING on v4.19 next-20181101]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
> base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
> config: i386-allyesconfig (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>
> All warnings (new ones prefixed by >>):
>
> drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (time_after(jiffies, timeout))
> ^
> drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
>
> vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
>
> 604
> 605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
> 606 {
> 607 unsigned long timeout;
> 608
> 609 if (bus->multi_master) {
> 610 might_sleep();
> 611 /* Initialize it only when multi_master is set */
> 612 timeout = jiffies + bus->adap.timeout;
The 'timeout' variable will be initialized only when bus->multi_master
is true to save some OPs in case this variable isn't used. The saved OPs
are not expensive but it makes a meaning because this function is called
very frequently on every master transfer.
> 613 }
> 614
> 615 for (;;) {
> 616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
> 617 ASPEED_I2CD_BUS_BUSY_STS))
> 618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
> 619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
> 620 #endif
> 621 return 0;
> 622 if (!bus->multi_master)
> 623 break;
If bus->multi_master is false then it doesn't fall through so the
'timeout' variable in below will not be used when itself is
uninitialized. Also, bus->multi_master is fixed at probing time and it
doesn't change at runtime so the warning case never happens.
-Jae
> > 624 if (time_after(jiffies, timeout))
> 625 break;
> 626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
> 627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
> 628 }
> 629
> 630 return aspeed_i2c_recover_bus(bus);
> 631 }
> 632
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-01 18:09 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-11-01 18:09 UTC (permalink / raw)
To: linux-arm-kernel
On 11/1/2018 10:44 AM, kbuild test robot wrote:
> Hi Jae,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on wsa/i2c/for-next]
> [also build test WARNING on v4.19 next-20181101]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
> base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
> config: i386-allyesconfig (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>
> All warnings (new ones prefixed by >>):
>
> drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (time_after(jiffies, timeout))
> ^
> drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
>
> vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
>
> 604
> 605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
> 606 {
> 607 unsigned long timeout;
> 608
> 609 if (bus->multi_master) {
> 610 might_sleep();
> 611 /* Initialize it only when multi_master is set */
> 612 timeout = jiffies + bus->adap.timeout;
The 'timeout' variable will be initialized only when bus->multi_master
is true to save some OPs in case this variable isn't used. The saved OPs
are not expensive but it makes a meaning because this function is called
very frequently on every master transfer.
> 613 }
> 614
> 615 for (;;) {
> 616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
> 617 ASPEED_I2CD_BUS_BUSY_STS))
> 618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
> 619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
> 620 #endif
> 621 return 0;
> 622 if (!bus->multi_master)
> 623 break;
If bus->multi_master is false then it doesn't fall through so the
'timeout' variable in below will not be used when itself is
uninitialized. Also, bus->multi_master is fixed at probing time and it
doesn't change at runtime so the warning case never happens.
-Jae
> > 624 if (time_after(jiffies, timeout))
> 625 break;
> 626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
> 627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
> 628 }
> 629
> 630 return aspeed_i2c_recover_bus(bus);
> 631 }
> 632
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-01 18:09 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-11-01 18:09 UTC (permalink / raw)
To: kbuild test robot
Cc: Mark Rutland, devicetree, linux-aspeed, Wolfram Sang,
Andrew Jeffery, openbmc, Brendan Higgins, linux-kernel,
James Feist, linux-i2c, Rob Herring, Jarkko Nikula, Vernon Mauery,
linux-arm-kernel, kbuild-all
On 11/1/2018 10:44 AM, kbuild test robot wrote:
> Hi Jae,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on wsa/i2c/for-next]
> [also build test WARNING on v4.19 next-20181101]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Jae-Hyun-Yoo/dt-bindings-i2c-Add-bus-timeout-ms-and-retries-properties-as-common-optional/20181031-051152
> base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
> config: i386-allyesconfig (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>
> All warnings (new ones prefixed by >>):
>
> drivers/i2c/busses/i2c-aspeed.c: In function 'aspeed_i2c_master_xfer':
>>> drivers/i2c/busses/i2c-aspeed.c:624:210: warning: 'timeout' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (time_after(jiffies, timeout))
> ^
> drivers/i2c/busses/i2c-aspeed.c:607:16: note: 'timeout' was declared here
> unsigned long timeout;
> ^~~~~~~
>
> vim +/timeout +624 drivers/i2c/busses/i2c-aspeed.c
>
> 604
> 605 static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
> 606 {
> 607 unsigned long timeout;
> 608
> 609 if (bus->multi_master) {
> 610 might_sleep();
> 611 /* Initialize it only when multi_master is set */
> 612 timeout = jiffies + bus->adap.timeout;
The 'timeout' variable will be initialized only when bus->multi_master
is true to save some OPs in case this variable isn't used. The saved OPs
are not expensive but it makes a meaning because this function is called
very frequently on every master transfer.
> 613 }
> 614
> 615 for (;;) {
> 616 if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
> 617 ASPEED_I2CD_BUS_BUSY_STS))
> 618 #if IS_ENABLED(CONFIG_I2C_SLAVE)
> 619 if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
> 620 #endif
> 621 return 0;
> 622 if (!bus->multi_master)
> 623 break;
If bus->multi_master is false then it doesn't fall through so the
'timeout' variable in below will not be used when itself is
uninitialized. Also, bus->multi_master is fixed at probing time and it
doesn't change at runtime so the warning case never happens.
-Jae
> > 624 if (time_after(jiffies, timeout))
> 625 break;
> 626 usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
> 627 ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
> 628 }
> 629
> 630 return aspeed_i2c_recover_bus(bus);
> 631 }
> 632
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
2018-10-30 21:09 ` Jae Hyun Yoo
(?)
@ 2018-11-28 21:54 ` Wolfram Sang
-1 siblings, 0 replies; 50+ messages in thread
From: Wolfram Sang @ 2018-11-28 21:54 UTC (permalink / raw)
To: linux-aspeed
On Tue, Oct 30, 2018 at 02:09:16PM -0700, Jae Hyun Yoo wrote:
> In multi-master environment, this driver's master cannot know
> exactly when a peer master sends data to this driver's slave so a
> case can be happened that this master tries to send data through
> the master_xfer function but slave data from peer master is still
> being processed by this driver.
So, that I get this correct: your IP core cannot detect a bus busy state
when its own slave address is acessed? Well, I know HW can have bugs,
but I still wonder because a bus is busy as soon as another START has
been detected, independent of which device is going to be accessed.
Even if so, why can't you use a mutex to prevent any master_xfer while
slave_xfer is ongoing?
Shouldn't that be enough according to the above description? Why do you
need the delay? I might be missing something...
> To prevent any state corruption in the case, this patch adds
> checking code if any slave operation is ongoing and it waits up to
> the bus timeout duration before starting a master_xfer operation.
>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
> ---
> drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
> 1 file changed, 40 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index 833b6b6a4c7e..30c3ab3a4844 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -12,6 +12,7 @@
>
> #include <linux/clk.h>
> #include <linux/completion.h>
> +#include <linux/delay.h>
> #include <linux/err.h>
> #include <linux/errno.h>
> #include <linux/i2c.h>
> @@ -115,6 +116,9 @@
> /* 0x18 : I2CD Slave Device Address Register */
> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>
> +/* Busy checking */
> +#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
> +
> enum aspeed_i2c_master_state {
> ASPEED_I2C_MASTER_INACTIVE,
> ASPEED_I2C_MASTER_START,
> @@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
> int cmd_err;
> /* Protected only by i2c_lock_bus */
> int master_xfer_result;
> + /* Multi-master */
> + bool multi_master;
> #if IS_ENABLED(CONFIG_I2C_SLAVE)
> struct i2c_client *slave;
> enum aspeed_i2c_slave_state slave_state;
> @@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
> return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
> }
>
> +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
> +{
> + unsigned long timeout;
> +
> + if (bus->multi_master) {
> + might_sleep();
> + /* Initialize it only when multi_master is set */
> + timeout = jiffies + bus->adap.timeout;
> + }
> +
> + for (;;) {
> + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
> + ASPEED_I2CD_BUS_BUSY_STS))
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
> +#endif
> + return 0;
> + if (!bus->multi_master)
> + break;
> + if (time_after(jiffies, timeout))
> + break;
> + usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
> + ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
> + }
> +
> + return aspeed_i2c_recover_bus(bus);
> +}
> +
> static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
> struct i2c_msg *msgs, int num)
> {
> struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
> unsigned long time_left, flags;
> - int ret = 0;
>
> - spin_lock_irqsave(&bus->lock, flags);
> - bus->cmd_err = 0;
> -
> - /* If bus is busy, attempt recovery. We assume a single master
> - * environment.
> - */
> - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
> - spin_unlock_irqrestore(&bus->lock, flags);
> - ret = aspeed_i2c_recover_bus(bus);
> - if (ret)
> - return ret;
> - spin_lock_irqsave(&bus->lock, flags);
> - }
> + if (aspeed_i2c_check_bus_busy(bus))
> + return -EAGAIN;
>
> + spin_lock_irqsave(&bus->lock, flags);
> bus->cmd_err = 0;
> bus->msgs = msgs;
> bus->msgs_index = 0;
> @@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
> if (ret < 0)
> return ret;
>
> - if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
> + if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
> + bus->multi_master = true;
> + else
> fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
>
> /* Enable Master Mode */
> --
> 2.19.1
>
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-28 21:54 ` Wolfram Sang
0 siblings, 0 replies; 50+ messages in thread
From: Wolfram Sang @ 2018-11-28 21:54 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Oct 30, 2018 at 02:09:16PM -0700, Jae Hyun Yoo wrote:
> In multi-master environment, this driver's master cannot know
> exactly when a peer master sends data to this driver's slave so a
> case can be happened that this master tries to send data through
> the master_xfer function but slave data from peer master is still
> being processed by this driver.
So, that I get this correct: your IP core cannot detect a bus busy state
when its own slave address is acessed? Well, I know HW can have bugs,
but I still wonder because a bus is busy as soon as another START has
been detected, independent of which device is going to be accessed.
Even if so, why can't you use a mutex to prevent any master_xfer while
slave_xfer is ongoing?
Shouldn't that be enough according to the above description? Why do you
need the delay? I might be missing something...
> To prevent any state corruption in the case, this patch adds
> checking code if any slave operation is ongoing and it waits up to
> the bus timeout duration before starting a master_xfer operation.
>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
> ---
> drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
> 1 file changed, 40 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index 833b6b6a4c7e..30c3ab3a4844 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -12,6 +12,7 @@
>
> #include <linux/clk.h>
> #include <linux/completion.h>
> +#include <linux/delay.h>
> #include <linux/err.h>
> #include <linux/errno.h>
> #include <linux/i2c.h>
> @@ -115,6 +116,9 @@
> /* 0x18 : I2CD Slave Device Address Register */
> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>
> +/* Busy checking */
> +#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
> +
> enum aspeed_i2c_master_state {
> ASPEED_I2C_MASTER_INACTIVE,
> ASPEED_I2C_MASTER_START,
> @@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
> int cmd_err;
> /* Protected only by i2c_lock_bus */
> int master_xfer_result;
> + /* Multi-master */
> + bool multi_master;
> #if IS_ENABLED(CONFIG_I2C_SLAVE)
> struct i2c_client *slave;
> enum aspeed_i2c_slave_state slave_state;
> @@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
> return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
> }
>
> +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
> +{
> + unsigned long timeout;
> +
> + if (bus->multi_master) {
> + might_sleep();
> + /* Initialize it only when multi_master is set */
> + timeout = jiffies + bus->adap.timeout;
> + }
> +
> + for (;;) {
> + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
> + ASPEED_I2CD_BUS_BUSY_STS))
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
> +#endif
> + return 0;
> + if (!bus->multi_master)
> + break;
> + if (time_after(jiffies, timeout))
> + break;
> + usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
> + ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
> + }
> +
> + return aspeed_i2c_recover_bus(bus);
> +}
> +
> static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
> struct i2c_msg *msgs, int num)
> {
> struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
> unsigned long time_left, flags;
> - int ret = 0;
>
> - spin_lock_irqsave(&bus->lock, flags);
> - bus->cmd_err = 0;
> -
> - /* If bus is busy, attempt recovery. We assume a single master
> - * environment.
> - */
> - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
> - spin_unlock_irqrestore(&bus->lock, flags);
> - ret = aspeed_i2c_recover_bus(bus);
> - if (ret)
> - return ret;
> - spin_lock_irqsave(&bus->lock, flags);
> - }
> + if (aspeed_i2c_check_bus_busy(bus))
> + return -EAGAIN;
>
> + spin_lock_irqsave(&bus->lock, flags);
> bus->cmd_err = 0;
> bus->msgs = msgs;
> bus->msgs_index = 0;
> @@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
> if (ret < 0)
> return ret;
>
> - if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
> + if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
> + bus->multi_master = true;
> + else
> fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
>
> /* Enable Master Mode */
> --
> 2.19.1
>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-28 21:54 ` Wolfram Sang
0 siblings, 0 replies; 50+ messages in thread
From: Wolfram Sang @ 2018-11-28 21:54 UTC (permalink / raw)
To: Jae Hyun Yoo
Cc: Brendan Higgins, Rob Herring, Joel Stanley,
Benjamin Herrenschmidt, Mark Rutland, Andrew Jeffery, linux-i2c,
openbmc, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
Jarkko Nikula, James Feist, Vernon Mauery
On Tue, Oct 30, 2018 at 02:09:16PM -0700, Jae Hyun Yoo wrote:
> In multi-master environment, this driver's master cannot know
> exactly when a peer master sends data to this driver's slave so a
> case can be happened that this master tries to send data through
> the master_xfer function but slave data from peer master is still
> being processed by this driver.
So, that I get this correct: your IP core cannot detect a bus busy state
when its own slave address is acessed? Well, I know HW can have bugs,
but I still wonder because a bus is busy as soon as another START has
been detected, independent of which device is going to be accessed.
Even if so, why can't you use a mutex to prevent any master_xfer while
slave_xfer is ongoing?
Shouldn't that be enough according to the above description? Why do you
need the delay? I might be missing something...
> To prevent any state corruption in the case, this patch adds
> checking code if any slave operation is ongoing and it waits up to
> the bus timeout duration before starting a master_xfer operation.
>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
> ---
> drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
> 1 file changed, 40 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index 833b6b6a4c7e..30c3ab3a4844 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -12,6 +12,7 @@
>
> #include <linux/clk.h>
> #include <linux/completion.h>
> +#include <linux/delay.h>
> #include <linux/err.h>
> #include <linux/errno.h>
> #include <linux/i2c.h>
> @@ -115,6 +116,9 @@
> /* 0x18 : I2CD Slave Device Address Register */
> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>
> +/* Busy checking */
> +#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
> +
> enum aspeed_i2c_master_state {
> ASPEED_I2C_MASTER_INACTIVE,
> ASPEED_I2C_MASTER_START,
> @@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
> int cmd_err;
> /* Protected only by i2c_lock_bus */
> int master_xfer_result;
> + /* Multi-master */
> + bool multi_master;
> #if IS_ENABLED(CONFIG_I2C_SLAVE)
> struct i2c_client *slave;
> enum aspeed_i2c_slave_state slave_state;
> @@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
> return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
> }
>
> +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
> +{
> + unsigned long timeout;
> +
> + if (bus->multi_master) {
> + might_sleep();
> + /* Initialize it only when multi_master is set */
> + timeout = jiffies + bus->adap.timeout;
> + }
> +
> + for (;;) {
> + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
> + ASPEED_I2CD_BUS_BUSY_STS))
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
> +#endif
> + return 0;
> + if (!bus->multi_master)
> + break;
> + if (time_after(jiffies, timeout))
> + break;
> + usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
> + ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
> + }
> +
> + return aspeed_i2c_recover_bus(bus);
> +}
> +
> static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
> struct i2c_msg *msgs, int num)
> {
> struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
> unsigned long time_left, flags;
> - int ret = 0;
>
> - spin_lock_irqsave(&bus->lock, flags);
> - bus->cmd_err = 0;
> -
> - /* If bus is busy, attempt recovery. We assume a single master
> - * environment.
> - */
> - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
> - spin_unlock_irqrestore(&bus->lock, flags);
> - ret = aspeed_i2c_recover_bus(bus);
> - if (ret)
> - return ret;
> - spin_lock_irqsave(&bus->lock, flags);
> - }
> + if (aspeed_i2c_check_bus_busy(bus))
> + return -EAGAIN;
>
> + spin_lock_irqsave(&bus->lock, flags);
> bus->cmd_err = 0;
> bus->msgs = msgs;
> bus->msgs_index = 0;
> @@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
> if (ret < 0)
> return ret;
>
> - if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
> + if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
> + bus->multi_master = true;
> + else
> fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
>
> /* Enable Master Mode */
> --
> 2.19.1
>
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
2018-11-28 21:54 ` Wolfram Sang
(?)
@ 2018-11-28 22:30 ` Jae Hyun Yoo
-1 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-11-28 22:30 UTC (permalink / raw)
To: linux-aspeed
On 11/28/2018 3:54 PM, Wolfram Sang wrote:
> On Tue, Oct 30, 2018 at 02:09:16PM -0700, Jae Hyun Yoo wrote:
>> In multi-master environment, this driver's master cannot know
>> exactly when a peer master sends data to this driver's slave so a
>> case can be happened that this master tries to send data through
>> the master_xfer function but slave data from peer master is still
>> being processed by this driver.
>
> So, that I get this correct: your IP core cannot detect a bus busy state
> when its own slave address is acessed? Well, I know HW can have bugs,
> but I still wonder because a bus is busy as soon as another START has
> been detected, independent of which device is going to be accessed.
>
> Even if so, why can't you use a mutex to prevent any master_xfer while
> slave_xfer is ongoing?
>
> Shouldn't that be enough according to the above description? Why do you
> need the delay? I might be missing something...
>
This IP has a bus busy state bit which can cover master and slave
operations but in case of slave operation, the bit is cleared little
bit earlier than its actual completion so it's the reason why I made
this patch. I agree with you that it still has a weak point since
the bus can be changed to busy state immediately just after finishing
the busy waiting delay.
As you suggested, I'll try to implement it using a mutex instead of
using delay. Thanks a lot for your comment.
Jae
>> To prevent any state corruption in the case, this patch adds
>> checking code if any slave operation is ongoing and it waits up to
>> the bus timeout duration before starting a master_xfer operation.
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
>> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
>> ---
>> drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
>> 1 file changed, 40 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>> index 833b6b6a4c7e..30c3ab3a4844 100644
>> --- a/drivers/i2c/busses/i2c-aspeed.c
>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>> @@ -12,6 +12,7 @@
>>
>> #include <linux/clk.h>
>> #include <linux/completion.h>
>> +#include <linux/delay.h>
>> #include <linux/err.h>
>> #include <linux/errno.h>
>> #include <linux/i2c.h>
>> @@ -115,6 +116,9 @@
>> /* 0x18 : I2CD Slave Device Address Register */
>> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>>
>> +/* Busy checking */
>> +#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
>> +
>> enum aspeed_i2c_master_state {
>> ASPEED_I2C_MASTER_INACTIVE,
>> ASPEED_I2C_MASTER_START,
>> @@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
>> int cmd_err;
>> /* Protected only by i2c_lock_bus */
>> int master_xfer_result;
>> + /* Multi-master */
>> + bool multi_master;
>> #if IS_ENABLED(CONFIG_I2C_SLAVE)
>> struct i2c_client *slave;
>> enum aspeed_i2c_slave_state slave_state;
>> @@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>> return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
>> }
>>
>> +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
>> +{
>> + unsigned long timeout;
>> +
>> + if (bus->multi_master) {
>> + might_sleep();
>> + /* Initialize it only when multi_master is set */
>> + timeout = jiffies + bus->adap.timeout;
>> + }
>> +
>> + for (;;) {
>> + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
>> + ASPEED_I2CD_BUS_BUSY_STS))
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
>> +#endif
>> + return 0;
>> + if (!bus->multi_master)
>> + break;
>> + if (time_after(jiffies, timeout))
>> + break;
>> + usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
>> + ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
>> + }
>> +
>> + return aspeed_i2c_recover_bus(bus);
>> +}
>> +
>> static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>> struct i2c_msg *msgs, int num)
>> {
>> struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
>> unsigned long time_left, flags;
>> - int ret = 0;
>>
>> - spin_lock_irqsave(&bus->lock, flags);
>> - bus->cmd_err = 0;
>> -
>> - /* If bus is busy, attempt recovery. We assume a single master
>> - * environment.
>> - */
>> - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
>> - spin_unlock_irqrestore(&bus->lock, flags);
>> - ret = aspeed_i2c_recover_bus(bus);
>> - if (ret)
>> - return ret;
>> - spin_lock_irqsave(&bus->lock, flags);
>> - }
>> + if (aspeed_i2c_check_bus_busy(bus))
>> + return -EAGAIN;
>>
>> + spin_lock_irqsave(&bus->lock, flags);
>> bus->cmd_err = 0;
>> bus->msgs = msgs;
>> bus->msgs_index = 0;
>> @@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
>> if (ret < 0)
>> return ret;
>>
>> - if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> + if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> + bus->multi_master = true;
>> + else
>> fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
>>
>> /* Enable Master Mode */
>> --
>> 2.19.1
>>
^ permalink raw reply [flat|nested] 50+ messages in thread* [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-28 22:30 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-11-28 22:30 UTC (permalink / raw)
To: linux-arm-kernel
On 11/28/2018 3:54 PM, Wolfram Sang wrote:
> On Tue, Oct 30, 2018 at 02:09:16PM -0700, Jae Hyun Yoo wrote:
>> In multi-master environment, this driver's master cannot know
>> exactly when a peer master sends data to this driver's slave so a
>> case can be happened that this master tries to send data through
>> the master_xfer function but slave data from peer master is still
>> being processed by this driver.
>
> So, that I get this correct: your IP core cannot detect a bus busy state
> when its own slave address is acessed? Well, I know HW can have bugs,
> but I still wonder because a bus is busy as soon as another START has
> been detected, independent of which device is going to be accessed.
>
> Even if so, why can't you use a mutex to prevent any master_xfer while
> slave_xfer is ongoing?
>
> Shouldn't that be enough according to the above description? Why do you
> need the delay? I might be missing something...
>
This IP has a bus busy state bit which can cover master and slave
operations but in case of slave operation, the bit is cleared little
bit earlier than its actual completion so it's the reason why I made
this patch. I agree with you that it still has a weak point since
the bus can be changed to busy state immediately just after finishing
the busy waiting delay.
As you suggested, I'll try to implement it using a mutex instead of
using delay. Thanks a lot for your comment.
Jae
>> To prevent any state corruption in the case, this patch adds
>> checking code if any slave operation is ongoing and it waits up to
>> the bus timeout duration before starting a master_xfer operation.
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
>> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
>> ---
>> drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
>> 1 file changed, 40 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>> index 833b6b6a4c7e..30c3ab3a4844 100644
>> --- a/drivers/i2c/busses/i2c-aspeed.c
>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>> @@ -12,6 +12,7 @@
>>
>> #include <linux/clk.h>
>> #include <linux/completion.h>
>> +#include <linux/delay.h>
>> #include <linux/err.h>
>> #include <linux/errno.h>
>> #include <linux/i2c.h>
>> @@ -115,6 +116,9 @@
>> /* 0x18 : I2CD Slave Device Address Register */
>> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>>
>> +/* Busy checking */
>> +#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
>> +
>> enum aspeed_i2c_master_state {
>> ASPEED_I2C_MASTER_INACTIVE,
>> ASPEED_I2C_MASTER_START,
>> @@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
>> int cmd_err;
>> /* Protected only by i2c_lock_bus */
>> int master_xfer_result;
>> + /* Multi-master */
>> + bool multi_master;
>> #if IS_ENABLED(CONFIG_I2C_SLAVE)
>> struct i2c_client *slave;
>> enum aspeed_i2c_slave_state slave_state;
>> @@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>> return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
>> }
>>
>> +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
>> +{
>> + unsigned long timeout;
>> +
>> + if (bus->multi_master) {
>> + might_sleep();
>> + /* Initialize it only when multi_master is set */
>> + timeout = jiffies + bus->adap.timeout;
>> + }
>> +
>> + for (;;) {
>> + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
>> + ASPEED_I2CD_BUS_BUSY_STS))
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
>> +#endif
>> + return 0;
>> + if (!bus->multi_master)
>> + break;
>> + if (time_after(jiffies, timeout))
>> + break;
>> + usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
>> + ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
>> + }
>> +
>> + return aspeed_i2c_recover_bus(bus);
>> +}
>> +
>> static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>> struct i2c_msg *msgs, int num)
>> {
>> struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
>> unsigned long time_left, flags;
>> - int ret = 0;
>>
>> - spin_lock_irqsave(&bus->lock, flags);
>> - bus->cmd_err = 0;
>> -
>> - /* If bus is busy, attempt recovery. We assume a single master
>> - * environment.
>> - */
>> - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
>> - spin_unlock_irqrestore(&bus->lock, flags);
>> - ret = aspeed_i2c_recover_bus(bus);
>> - if (ret)
>> - return ret;
>> - spin_lock_irqsave(&bus->lock, flags);
>> - }
>> + if (aspeed_i2c_check_bus_busy(bus))
>> + return -EAGAIN;
>>
>> + spin_lock_irqsave(&bus->lock, flags);
>> bus->cmd_err = 0;
>> bus->msgs = msgs;
>> bus->msgs_index = 0;
>> @@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
>> if (ret < 0)
>> return ret;
>>
>> - if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> + if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> + bus->multi_master = true;
>> + else
>> fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
>>
>> /* Enable Master Mode */
>> --
>> 2.19.1
>>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH i2c-next v9 5/5] i2c: aspeed: Add bus idle waiting logic for multi-master use cases
@ 2018-11-28 22:30 ` Jae Hyun Yoo
0 siblings, 0 replies; 50+ messages in thread
From: Jae Hyun Yoo @ 2018-11-28 22:30 UTC (permalink / raw)
To: Wolfram Sang
Cc: Brendan Higgins, Rob Herring, Joel Stanley,
Benjamin Herrenschmidt, Mark Rutland, Andrew Jeffery, linux-i2c,
openbmc, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
Jarkko Nikula, James Feist, Vernon Mauery
On 11/28/2018 3:54 PM, Wolfram Sang wrote:
> On Tue, Oct 30, 2018 at 02:09:16PM -0700, Jae Hyun Yoo wrote:
>> In multi-master environment, this driver's master cannot know
>> exactly when a peer master sends data to this driver's slave so a
>> case can be happened that this master tries to send data through
>> the master_xfer function but slave data from peer master is still
>> being processed by this driver.
>
> So, that I get this correct: your IP core cannot detect a bus busy state
> when its own slave address is acessed? Well, I know HW can have bugs,
> but I still wonder because a bus is busy as soon as another START has
> been detected, independent of which device is going to be accessed.
>
> Even if so, why can't you use a mutex to prevent any master_xfer while
> slave_xfer is ongoing?
>
> Shouldn't that be enough according to the above description? Why do you
> need the delay? I might be missing something...
>
This IP has a bus busy state bit which can cover master and slave
operations but in case of slave operation, the bit is cleared little
bit earlier than its actual completion so it's the reason why I made
this patch. I agree with you that it still has a weak point since
the bus can be changed to busy state immediately just after finishing
the busy waiting delay.
As you suggested, I'll try to implement it using a mutex instead of
using delay. Thanks a lot for your comment.
Jae
>> To prevent any state corruption in the case, this patch adds
>> checking code if any slave operation is ongoing and it waits up to
>> the bus timeout duration before starting a master_xfer operation.
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
>> Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
>> ---
>> drivers/i2c/busses/i2c-aspeed.c | 55 ++++++++++++++++++++++++---------
>> 1 file changed, 40 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>> index 833b6b6a4c7e..30c3ab3a4844 100644
>> --- a/drivers/i2c/busses/i2c-aspeed.c
>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>> @@ -12,6 +12,7 @@
>>
>> #include <linux/clk.h>
>> #include <linux/completion.h>
>> +#include <linux/delay.h>
>> #include <linux/err.h>
>> #include <linux/errno.h>
>> #include <linux/i2c.h>
>> @@ -115,6 +116,9 @@
>> /* 0x18 : I2CD Slave Device Address Register */
>> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>>
>> +/* Busy checking */
>> +#define ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US (10 * 1000)
>> +
>> enum aspeed_i2c_master_state {
>> ASPEED_I2C_MASTER_INACTIVE,
>> ASPEED_I2C_MASTER_START,
>> @@ -156,6 +160,8 @@ struct aspeed_i2c_bus {
>> int cmd_err;
>> /* Protected only by i2c_lock_bus */
>> int master_xfer_result;
>> + /* Multi-master */
>> + bool multi_master;
>> #if IS_ENABLED(CONFIG_I2C_SLAVE)
>> struct i2c_client *slave;
>> enum aspeed_i2c_slave_state slave_state;
>> @@ -596,27 +602,44 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>> return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
>> }
>>
>> +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus)
>> +{
>> + unsigned long timeout;
>> +
>> + if (bus->multi_master) {
>> + might_sleep();
>> + /* Initialize it only when multi_master is set */
>> + timeout = jiffies + bus->adap.timeout;
>> + }
>> +
>> + for (;;) {
>> + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) &
>> + ASPEED_I2CD_BUS_BUSY_STS))
>> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
>> +#endif
>> + return 0;
>> + if (!bus->multi_master)
>> + break;
>> + if (time_after(jiffies, timeout))
>> + break;
>> + usleep_range((ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1,
>> + ASPEED_I2C_BUS_BUSY_CHECK_INTERVAL_US);
>> + }
>> +
>> + return aspeed_i2c_recover_bus(bus);
>> +}
>> +
>> static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>> struct i2c_msg *msgs, int num)
>> {
>> struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
>> unsigned long time_left, flags;
>> - int ret = 0;
>>
>> - spin_lock_irqsave(&bus->lock, flags);
>> - bus->cmd_err = 0;
>> -
>> - /* If bus is busy, attempt recovery. We assume a single master
>> - * environment.
>> - */
>> - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) {
>> - spin_unlock_irqrestore(&bus->lock, flags);
>> - ret = aspeed_i2c_recover_bus(bus);
>> - if (ret)
>> - return ret;
>> - spin_lock_irqsave(&bus->lock, flags);
>> - }
>> + if (aspeed_i2c_check_bus_busy(bus))
>> + return -EAGAIN;
>>
>> + spin_lock_irqsave(&bus->lock, flags);
>> bus->cmd_err = 0;
>> bus->msgs = msgs;
>> bus->msgs_index = 0;
>> @@ -827,7 +850,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus,
>> if (ret < 0)
>> return ret;
>>
>> - if (!of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> + if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> + bus->multi_master = true;
>> + else
>> fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS;
>>
>> /* Enable Master Mode */
>> --
>> 2.19.1
>>
^ permalink raw reply [flat|nested] 50+ messages in thread