@@ -21,7 +21,6 @@
#include <linux/of.h>
#include <linux/sched.h>
#include <linux/semaphore.h>
-#include <linux/spinlock.h>
#include <linux/wait.h>
#define FSI_ENGID_I2C 0x7
@@ -148,7 +147,6 @@ struct fsi_i2c_master {
struct list_head ports;
wait_queue_head_t wait;
struct semaphore lock;
- spinlock_t reset_lock;
};
struct fsi_i2c_port {
@@ -427,71 +425,63 @@ static int fsi_i2c_reset(struct fsi_i2c_master *i2c, u16 port)
{
int rc;
u32 mode, stat, dummy = 0;
- unsigned long flags;
-
- /* disable pre-emption; bus won't get left in a bad state for long */
- spin_lock_irqsave(&i2c->reset_lock, flags);
/* reset engine */
rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_I2C, &dummy);
if (rc)
- goto done;
+ return rc;
/* re-init engine */
rc = fsi_i2c_dev_init(i2c);
if (rc)
- goto done;
+ return rc;
rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_MODE, &mode);
if (rc)
- goto done;
+ return rc;
/* set port; default after reset is 0 */
if (port) {
mode = SETFIELD(I2C_MODE_PORT, mode, port);
rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_MODE, &mode);
if (rc)
- goto done;
+ return rc;
}
/* reset busy register; hw workaround */
dummy = I2C_PORT_BUSY_RESET;
rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_PORT_BUSY, &dummy);
if (rc)
- goto done;
+ return rc;
/* force bus reset */
rc = fsi_i2c_reset_bus(i2c);
if (rc)
- goto done;
+ return rc;
/* reset errors */
dummy = 0;
rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_ERR, &dummy);
if (rc)
- goto done;
+ return rc;
/* wait for command complete; time from legacy driver */
- udelay(1000);
+ msleep(1);
rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
if (rc)
- goto done;
+ return rc;
if (stat & I2C_STAT_CMD_COMP)
- goto done;
+ return rc;
/* failed to get command complete; reset engine again */
rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_I2C, &dummy);
if (rc)
- goto done;
+ return rc;
/* re-init engine again */
- rc = fsi_i2c_dev_init(i2c);
-
-done:
- spin_unlock_irqrestore(&i2c->reset_lock, flags);
- return rc;
+ return fsi_i2c_dev_init(i2c);
}
static int fsi_i2c_abort(struct fsi_i2c_port *port, u32 status)
@@ -711,7 +701,6 @@ static int fsi_i2c_probe(struct device *dev)
init_waitqueue_head(&i2c->wait);
sema_init(&i2c->lock, 1);
- spin_lock_init(&i2c->reset_lock);
i2c->fsi = to_fsi_dev(dev);
INIT_LIST_HEAD(&i2c->ports);
That lock is incorrect as FSI can sleep and thus will trigger lockdep warnings. It is also unnecessary as it was meant to "speed up" the reset process for unspecified reasons, not to protect against anything. The the master semaphore should prevent any concurrent user from seeing the intermediate state already and the recent improvements to the FSI layer should take care of potential speed issues. Signed-off-by: Eddie James <eajames@linux.vnet.ibm.com> --- This is Benjamin Herrenschmidt's <benh@kernel.crashing.org> patch, but I also removed the reset_lock in the master structure and didn't add delay.h include; thought I would just get these in one patch set for convenience. drivers/i2c/busses/i2c-fsi.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-)