diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-fsi.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c index 45a6ebdeaa13..27d74a944c72 100644 --- a/drivers/i2c/busses/i2c-fsi.c +++ b/drivers/i2c/busses/i2c-fsi.c @@ -21,6 +21,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/mutex.h> #include <linux/of.h> #include <linux/slab.h> @@ -148,6 +149,7 @@ struct fsi_i2c_master { struct fsi_device *fsi; u8 fifo_size; struct list_head ports; + struct mutex lock; }; struct fsi_i2c_port { @@ -486,11 +488,14 @@ static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int i, rc; unsigned long start_time; struct fsi_i2c_port *port = adap->algo_data; + struct fsi_i2c_master *master = port->master; struct i2c_msg *msg; + mutex_lock(&master->lock); + rc = fsi_i2c_set_port(port); if (rc) - return rc; + goto unlock; for (i = 0; i < num; i++) { msg = msgs + i; @@ -498,15 +503,17 @@ static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, rc = fsi_i2c_start(port, msg, i == num - 1); if (rc) - return rc; + goto unlock; rc = fsi_i2c_wait(port, msg, adap->timeout - (jiffies - start_time)); if (rc) - return rc; + goto unlock; } - return num; +unlock: + mutex_unlock(&master->lock); + return rc ? : num; } static u32 fsi_i2c_functionality(struct i2c_adapter *adap) @@ -532,6 +539,7 @@ static int fsi_i2c_probe(struct device *dev) if (!i2c) return -ENOMEM; + mutex_init(&i2c->lock); i2c->fsi = to_fsi_dev(dev); INIT_LIST_HEAD(&i2c->ports); |