There will never be threads queueing up in the xiic_xmit(), use completion synchronization primitive to wait for the interrupt handler thread to complete instead as it is much better fit and there is no need to overload it for this purpose. Signed-off-by: Marek Vasut <marex@xxxxxxx> Cc: Michal Simek <michal.simek@xxxxxxxxxx> Cc: Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxxxxx> Cc: Wolfram Sang <wsa@xxxxxxxxxx> --- drivers/i2c/busses/i2c-xiic.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 87eca9d46afd9..e4c3427b2f3f5 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -23,7 +23,7 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/interrupt.h> -#include <linux/wait.h> +#include <linux/completion.h> #include <linux/platform_data/i2c-xiic.h> #include <linux/io.h> #include <linux/slab.h> @@ -48,7 +48,7 @@ enum xiic_endian { * struct xiic_i2c - Internal representation of the XIIC I2C bus * @dev: Pointer to device structure * @base: Memory base of the HW registers - * @wait: Wait queue for callers + * @completion: Completion for callers * @adap: Kernel adapter representation * @tx_msg: Messages from above to be sent * @lock: Mutual exclusion @@ -63,7 +63,7 @@ enum xiic_endian { struct xiic_i2c { struct device *dev; void __iomem *base; - wait_queue_head_t wait; + struct completion completion; struct i2c_adapter adap; struct i2c_msg *tx_msg; struct mutex lock; @@ -365,7 +365,7 @@ static void xiic_wakeup(struct xiic_i2c *i2c, int code) i2c->rx_msg = NULL; i2c->nmsgs = 0; i2c->state = code; - wake_up(&i2c->wait); + complete(&i2c->completion); } static irqreturn_t xiic_process(int irq, void *dev_id) @@ -677,6 +677,7 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num) i2c->tx_msg = msgs; i2c->nmsgs = num; + init_completion(&i2c->completion); ret = xiic_reinit(i2c); if (!ret) @@ -703,23 +704,24 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) err = xiic_start_xfer(i2c, msgs, num); if (err < 0) { dev_err(adap->dev.parent, "Error xiic_start_xfer\n"); - goto out; + return err; } - if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ)) { - mutex_lock(&i2c->lock); - err = (i2c->state == STATE_DONE) ? num : -EIO; - goto out; - } else { - mutex_lock(&i2c->lock); + err = wait_for_completion_interruptible_timeout(&i2c->completion, + XIIC_I2C_TIMEOUT); + mutex_lock(&i2c->lock); + if (err == 0) { /* Timeout */ i2c->tx_msg = NULL; i2c->rx_msg = NULL; i2c->nmsgs = 0; err = -ETIMEDOUT; - goto out; + } else if (err < 0) { /* Completion error */ + i2c->tx_msg = NULL; + i2c->rx_msg = NULL; + i2c->nmsgs = 0; + } else { + err = (i2c->state == STATE_DONE) ? num : -EIO; } -out: mutex_unlock(&i2c->lock); pm_runtime_mark_last_busy(i2c->dev); pm_runtime_put_autosuspend(i2c->dev); @@ -781,7 +783,6 @@ static int xiic_i2c_probe(struct platform_device *pdev) i2c->adap.dev.of_node = pdev->dev.of_node; mutex_init(&i2c->lock); - init_waitqueue_head(&i2c->wait); i2c->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(i2c->clk)) { -- 2.26.2