Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d295a86e authored by Russell King's avatar Russell King Committed by Wolfram Sang
Browse files

i2c: mv64xxx: work around signals causing I2C transactions to be aborted



Do not use interruptible waits in an I2C driver; if a process uses
signals (eg, Xorg uses SIGALRM and SIGPIPE) then these signals can
cause the I2C driver to abort a transaction in progress by another
driver, which can cause that driver to fail.  I2C drivers are not
expected to abort transactions on signals.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 53229345
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -252,7 +252,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
		writel(drv_data->cntl_bits,
		writel(drv_data->cntl_bits,
			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
		drv_data->block = 0;
		drv_data->block = 0;
		wake_up_interruptible(&drv_data->waitq);
		wake_up(&drv_data->waitq);
		break;
		break;


	case MV64XXX_I2C_ACTION_CONTINUE:
	case MV64XXX_I2C_ACTION_CONTINUE:
@@ -300,7 +300,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
		drv_data->block = 0;
		drv_data->block = 0;
		wake_up_interruptible(&drv_data->waitq);
		wake_up(&drv_data->waitq);
		break;
		break;


	case MV64XXX_I2C_ACTION_INVALID:
	case MV64XXX_I2C_ACTION_INVALID:
@@ -315,7 +315,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
		drv_data->block = 0;
		drv_data->block = 0;
		wake_up_interruptible(&drv_data->waitq);
		wake_up(&drv_data->waitq);
		break;
		break;
	}
	}
}
}
@@ -381,7 +381,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
	unsigned long	flags;
	unsigned long	flags;
	char		abort = 0;
	char		abort = 0;


	time_left = wait_event_interruptible_timeout(drv_data->waitq,
	time_left = wait_event_timeout(drv_data->waitq,
		!drv_data->block, drv_data->adapter.timeout);
		!drv_data->block, drv_data->adapter.timeout);


	spin_lock_irqsave(&drv_data->lock, flags);
	spin_lock_irqsave(&drv_data->lock, flags);