|
@@ -43,15 +43,19 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
|
|
int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction);
|
|
int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction);
|
|
unsigned char *base;
|
|
unsigned char *base;
|
|
u16 out = cpu_to_le16(0);
|
|
u16 out = cpu_to_le16(0);
|
|
|
|
+ int r = 0;
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
|
|
|
+ mutex_lock(&chan->mutex);
|
|
|
|
+
|
|
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
|
|
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
|
|
|
|
|
|
if (flags & HW_I2C_WRITE) {
|
|
if (flags & HW_I2C_WRITE) {
|
|
if (num > ATOM_MAX_HW_I2C_WRITE) {
|
|
if (num > ATOM_MAX_HW_I2C_WRITE) {
|
|
DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num);
|
|
DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num);
|
|
- return -EINVAL;
|
|
|
|
|
|
+ r = -EINVAL;
|
|
|
|
+ goto done;
|
|
}
|
|
}
|
|
if (buf == NULL)
|
|
if (buf == NULL)
|
|
args.ucRegIndex = 0;
|
|
args.ucRegIndex = 0;
|
|
@@ -65,7 +69,8 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
|
|
} else {
|
|
} else {
|
|
if (num > ATOM_MAX_HW_I2C_READ) {
|
|
if (num > ATOM_MAX_HW_I2C_READ) {
|
|
DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num);
|
|
DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num);
|
|
- return -EINVAL;
|
|
|
|
|
|
+ r = -EINVAL;
|
|
|
|
+ goto done;
|
|
}
|
|
}
|
|
args.ucRegIndex = 0;
|
|
args.ucRegIndex = 0;
|
|
args.lpI2CDataOut = 0;
|
|
args.lpI2CDataOut = 0;
|
|
@@ -82,13 +87,17 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
|
|
/* error */
|
|
/* error */
|
|
if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
|
|
if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
|
|
DRM_DEBUG_KMS("hw_i2c error\n");
|
|
DRM_DEBUG_KMS("hw_i2c error\n");
|
|
- return -EIO;
|
|
|
|
|
|
+ r = -EIO;
|
|
|
|
+ goto done;
|
|
}
|
|
}
|
|
|
|
|
|
if (!(flags & HW_I2C_WRITE))
|
|
if (!(flags & HW_I2C_WRITE))
|
|
radeon_atom_copy_swap(buf, base, num, false);
|
|
radeon_atom_copy_swap(buf, base, num, false);
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+done:
|
|
|
|
+ mutex_unlock(&chan->mutex);
|
|
|
|
+
|
|
|
|
+ return r;
|
|
}
|
|
}
|
|
|
|
|
|
int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
|
|
int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
|