Skip to content

Commit

Permalink
i2c: Ensure ordering between i2c_request_send() and completion
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
  • Loading branch information
ozbenh authored and stewartsmith committed Aug 16, 2018
1 parent f737777 commit ef79d03
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <device.h>
#include <opal-msg.h>
#include <timebase.h>
#include <processor.h>

static LIST_HEAD(i2c_bus_list);

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit ef79d03

Please sign in to comment.