diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-core.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 10fbd6d841e0..99b54be6ba73 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -634,7 +634,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); - mutex_lock(&dev->lock); pm_runtime_get_sync(dev->dev); reinit_completion(&dev->cmd_complete); @@ -673,11 +672,12 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } /* - * We must disable the adapter before unlocking the &dev->lock mutex - * below. Otherwise the hardware might continue generating interrupts - * which in turn causes a race condition with the following transfer. - * Needs some more investigation if the additional interrupts are - * a hardware bug or this driver doesn't handle them correctly yet. + * We must disable the adapter before returning and signaling the end + * of the current transfer. Otherwise the hardware might continue + * generating interrupts which in turn causes a race condition with + * the following transfer. Needs some more investigation if the + * additional interrupts are a hardware bug or this driver doesn't + * handle them correctly yet. */ __i2c_dw_enable(dev, false); @@ -706,7 +706,6 @@ done: done_nolock: pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); - mutex_unlock(&dev->lock); return ret; } @@ -860,7 +859,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) int r; init_completion(&dev->cmd_complete); - mutex_init(&dev->lock); r = i2c_dw_init(dev); if (r) @@ -883,9 +881,17 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) return r; } + /* + * Increment PM usage count during adapter registration in order to + * avoid possible spurious runtime suspend when adapter device is + * registered to the device core and immediate resume in case bus has + * registered I2C slaves that do I2C transfers in their probe. + */ + pm_runtime_get_noresume(dev->dev); r = i2c_add_numbered_adapter(adap); if (r) dev_err(dev->dev, "failure adding adapter: %d\n", r); + pm_runtime_put_noidle(dev->dev); return r; } |