2015-04-04 02:47:13

by Nicholas Mc Guire

[permalink] [raw]
Subject: [PATCH 1/3] drm/msm: fixup wait_for_completion_timeout handling

wait_for_completion_timeout return >= 0 but never negative so the check
logic looks inconsistent. Further the return value of
wait_for_completion_timeout was being passed up the call chain but the
x call sites as drm_dp_i2c_do_msg()/drm_dp_dpcd_access() check for < 0
thus timeout was being treated as success case.

<snip> drivers/gpu/drm/drm_dp_helper.c:drm_dp_i2c_do_msg()
mutex_lock(&aux->hw_mutex);
ret = aux->transfer(aux, msg);
mutex_unlock(&aux->hw_mutex);
if (ret < 0) {
<snip>
logic in edp_aux_transfer() seems incorrect as it could return 0 (timeout)
but checks of <= 0 to indicate error so the return probably should be
-ETIMEDOUT in case wait_for_completion_timeout returns 0 (timeout
occurred).

Signed-off-by: Nicholas Mc Guire <[email protected]>
---

This was compile tested with qcom_defconfig +
CONFIG_DRM=m (implies CONFIG_DRM_MSM=m)

Patch is against 4.0-rc6 (localversion-next is -next-20150402)

drivers/gpu/drm/msm/edp/edp_aux.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c
index 5f5a84f..1d2ccdf 100644
--- a/drivers/gpu/drm/msm/edp/edp_aux.c
+++ b/drivers/gpu/drm/msm/edp/edp_aux.c
@@ -119,6 +119,7 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
{
struct edp_aux *aux = to_edp_aux(drm_aux);
ssize_t ret;
+ unsigned long time_left;
bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);

@@ -147,15 +148,16 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
goto unlock_exit;

DBG("wait_for_completion");
- ret = wait_for_completion_timeout(&aux->msg_comp, 300);
- if (ret <= 0) {
+ time_left = wait_for_completion_timeout(&aux->msg_comp, 300);
+ if (!time_left) {
/*
* Clear GO and reset AUX channel
* to cancel the current transaction.
*/
edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
msm_edp_aux_ctrl(aux, 1);
- pr_err("%s: aux timeout, %d\n", __func__, ret);
+ pr_err("%s: aux timeout, %lu\n", __func__, time_left);
+ ret = -ETIMEDOUT;
goto unlock_exit;
}
DBG("completion");
--
1.7.10.4


2015-04-04 02:47:27

by Nicholas Mc Guire

[permalink] [raw]
Subject: [PATCH 2/3] drm/msm: fix HZ dependency of timeout

The timeout is passed as a constant which makes it HZ dependent because
jiffies are expected so it should be converted to jiffies. The actual
value is not clear from the code - my best guess is that this should be
300 milliseconds given that other timeouts are in milliseconds based on
looking at other drm drivers (e.g. exynos_drm_dsi.c:356 300ms,
tegra/dpaux.c:188 250ms) - this needs to be confirmed by someone who
knows the details of the driver.

Signed-off-by: Nicholas Mc Guire <[email protected]>
---

This was compile tested with qcom_defconfig +
CONFIG_DRM=m (implies CONFIG_DRM_MSM=m)

Patch is against 4.0-rc6 (localversion-next is -next-20150402)

drivers/gpu/drm/msm/edp/edp_aux.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c
index 91a1a67..d1b6833 100644
--- a/drivers/gpu/drm/msm/edp/edp_aux.c
+++ b/drivers/gpu/drm/msm/edp/edp_aux.c
@@ -148,7 +148,8 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
goto unlock_exit;

DBG("wait_for_completion");
- time_left = wait_for_completion_timeout(&aux->msg_comp, 300);
+ time_left = wait_for_completion_timeout(&aux->msg_comp,
+ msecs_to_jiffies(300));
if (!time_left) {
/*
* Clear GO and reset AUX channel
--
1.7.10.4

2015-04-04 02:47:31

by Nicholas Mc Guire

[permalink] [raw]
Subject: [PATCH 3/3] drm/msm: drop redundant output in debug message

wait_for_completion_timeout returns 0 in case of timeout so printing the
return value here will always yield 0 and is therefor redundant - dropped.

Signed-off-by: Nicholas Mc Guire <[email protected]>
---

This was compile tested with qcom_defconfig +
CONFIG_DRM=m (implies CONFIG_DRM_MSM=m)

Patch is against 4.0-rc6 (localversion-next is -next-20150402)

drivers/gpu/drm/msm/edp/edp_aux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c
index d1b6833..645ea07 100644
--- a/drivers/gpu/drm/msm/edp/edp_aux.c
+++ b/drivers/gpu/drm/msm/edp/edp_aux.c
@@ -157,7 +157,7 @@ ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
*/
edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
msm_edp_aux_ctrl(aux, 1);
- pr_err("%s: aux timeout, %lu\n", __func__, time_left);
+ pr_err("%s: aux timeout,\n", __func__);
ret = -ETIMEDOUT;
goto unlock_exit;
}
--
1.7.10.4