diff mbox series

[2/2] i2c: Ensure ordering between i2c_request_send() and completion

Message ID 2f79194719d79c71b905be26c4537292649312b2.camel@kernel.crashing.org
State Accepted
Headers show
Series [1/2] i2c: Fix multiple-enqueue of the same request on NACK | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied
snowpatch_ozlabs/make_check success Test make_check on branch master

Commit Message

Benjamin Herrenschmidt Aug. 14, 2018, 6:45 a.m. UTC
i2c_request_send loops waiting for a flag "uc.done" set by
the completion routine, and then look for a result code
also set by that same completion.

There is no synchronization, the completion can happen on another
processor, so we need to order the stores to uc and the reads
from uc so that uc.done is stored last and tested first using
memory barriers.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 core/i2c.c | 3 +++
 1 file changed, 3 insertions(+)
diff mbox series

Patch

diff --git a/core/i2c.c b/core/i2c.c
index 070a0f6f..e8333105 100644
--- a/core/i2c.c
+++ b/core/i2c.c
@@ -20,6 +20,7 @@ 
 #include <device.h>
 #include <opal-msg.h>
 #include <timebase.h>
+#include <processor.h>
 
 static LIST_HEAD(i2c_bus_list);
 
@@ -148,6 +149,7 @@  static void i2c_sync_request_complete(int rc, struct i2c_request *req)
 {
 	struct i2c_sync_userdata *ud = req->user_data;
 	ud->rc = rc;
+	lwsync();
 	ud->done = true;
 }
 
@@ -222,6 +224,7 @@  int i2c_request_send(int bus_id, int dev_addr, int read_write,
 			waited += time_to_wait;
 		} while (!ud.done);
 
+		lwsync();
 		rc = ud.rc;
 
 		/* error or success */