|
@@ -179,7 +179,7 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
|
|
|
{
|
|
|
struct drm_dp_aux_msg msg;
|
|
|
unsigned int retry;
|
|
|
- int err;
|
|
|
+ int err = 0;
|
|
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
|
msg.address = offset;
|
|
@@ -187,6 +187,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
|
|
|
msg.buffer = buffer;
|
|
|
msg.size = size;
|
|
|
|
|
|
+ mutex_lock(&aux->hw_mutex);
|
|
|
+
|
|
|
/*
|
|
|
* The specification doesn't give any recommendation on how often to
|
|
|
* retry native transactions. We used to retry 7 times like for
|
|
@@ -195,25 +197,24 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
|
|
|
*/
|
|
|
for (retry = 0; retry < 32; retry++) {
|
|
|
|
|
|
- mutex_lock(&aux->hw_mutex);
|
|
|
err = aux->transfer(aux, &msg);
|
|
|
- mutex_unlock(&aux->hw_mutex);
|
|
|
if (err < 0) {
|
|
|
if (err == -EBUSY)
|
|
|
continue;
|
|
|
|
|
|
- return err;
|
|
|
+ goto unlock;
|
|
|
}
|
|
|
|
|
|
|
|
|
switch (msg.reply & DP_AUX_NATIVE_REPLY_MASK) {
|
|
|
case DP_AUX_NATIVE_REPLY_ACK:
|
|
|
if (err < size)
|
|
|
- return -EPROTO;
|
|
|
- return err;
|
|
|
+ err = -EPROTO;
|
|
|
+ goto unlock;
|
|
|
|
|
|
case DP_AUX_NATIVE_REPLY_NACK:
|
|
|
- return -EIO;
|
|
|
+ err = -EIO;
|
|
|
+ goto unlock;
|
|
|
|
|
|
case DP_AUX_NATIVE_REPLY_DEFER:
|
|
|
usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
|
|
@@ -222,7 +223,11 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
|
|
|
}
|
|
|
|
|
|
DRM_DEBUG_KMS("too many retries, giving up\n");
|
|
|
- return -EIO;
|
|
|
+ err = -EIO;
|
|
|
+
|
|
|
+unlock:
|
|
|
+ mutex_unlock(&aux->hw_mutex);
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -544,9 +549,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
|
|
|
int max_retries = max(7, drm_dp_i2c_retry_count(msg, dp_aux_i2c_speed_khz));
|
|
|
|
|
|
for (retry = 0, defer_i2c = 0; retry < (max_retries + defer_i2c); retry++) {
|
|
|
- mutex_lock(&aux->hw_mutex);
|
|
|
ret = aux->transfer(aux, msg);
|
|
|
- mutex_unlock(&aux->hw_mutex);
|
|
|
if (ret < 0) {
|
|
|
if (ret == -EBUSY)
|
|
|
continue;
|
|
@@ -685,6 +688,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
|
|
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
|
|
|
|
+ mutex_lock(&aux->hw_mutex);
|
|
|
+
|
|
|
for (i = 0; i < num; i++) {
|
|
|
msg.address = msgs[i].addr;
|
|
|
drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
|
|
@@ -739,6 +744,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
|
|
|
msg.size = 0;
|
|
|
(void)drm_dp_i2c_do_msg(aux, &msg);
|
|
|
|
|
|
+ mutex_unlock(&aux->hw_mutex);
|
|
|
+
|
|
|
return err;
|
|
|
}
|
|
|
|