Hi Hsin-Yi, thanks for your patch, it looks good to me. Reviewed-by: Xin Ji <xji@xxxxxxxxxxxxxxxx> Thanks, Xin On Thu, Jun 30, 2022 at 12:05:50AM +0800, Hsin-Yi Wang wrote: > Move hpd polling check into wait_hpd_asserted() callback. For the cases > that aux transfer function wasn't used, do hpd polling check after pm > runtime resume, which will power on the bridge. > > Signed-off-by: Hsin-Yi Wang <hsinyi@xxxxxxxxxxxx> > --- > drivers/gpu/drm/bridge/analogix/anx7625.c | 33 ++++++++++++++++++----- > 1 file changed, 27 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c > index 59ddeba33652b..ea5a0b86fe52a 100644 > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > @@ -1443,23 +1443,24 @@ static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) > return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); > } > > -static void anx7625_hpd_polling(struct anx7625_data *ctx) > +static int _anx7625_hpd_polling(struct anx7625_data *ctx, > + unsigned long wait_us) > { > int ret, val; > struct device *dev = &ctx->client->dev; > > /* Interrupt mode, no need poll HPD status, just return */ > if (ctx->pdata.intp_irq) > - return; > + return 0; > > ret = readx_poll_timeout(anx7625_read_hpd_status_p0, > ctx, val, > ((val & HPD_STATUS) || (val < 0)), > - 5000, > - 5000 * 100); > + wait_us / 100, > + wait_us); > if (ret) { > DRM_DEV_ERROR(dev, "no hpd.\n"); > - return; > + return ret; > } > > DRM_DEV_DEBUG_DRIVER(dev, "system status: 0x%x. HPD raise up.\n", val); > @@ -1472,6 +1473,23 @@ static void anx7625_hpd_polling(struct anx7625_data *ctx) > > if (!ctx->pdata.panel_bridge && ctx->bridge_attached) > drm_helper_hpd_irq_event(ctx->bridge.dev); > + > + return 0; > +} > + > +static int anx7625_wait_hpd_asserted(struct drm_dp_aux *aux, > + unsigned long wait_us) > +{ > + struct anx7625_data *ctx = container_of(aux, struct anx7625_data, aux); > + struct device *dev = &ctx->client->dev; > + int ret; > + > + pm_runtime_get_sync(dev); > + ret = _anx7625_hpd_polling(ctx, wait_us); > + pm_runtime_mark_last_busy(dev); > + pm_runtime_put_autosuspend(dev); > + > + return ret; > } > > static void anx7625_remove_edid(struct anx7625_data *ctx) > @@ -1741,6 +1759,7 @@ static struct edid *anx7625_get_edid(struct anx7625_data *ctx) > } > > pm_runtime_get_sync(dev); > + _anx7625_hpd_polling(ctx, 5000 * 100); > edid_num = sp_tx_edid_read(ctx, p_edid->edid_raw_data); > pm_runtime_put_sync(dev); > > @@ -2378,6 +2397,7 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, > ctx->connector = connector; > > pm_runtime_get_sync(dev); > + _anx7625_hpd_polling(ctx, 5000 * 100); > > anx7625_dp_start(ctx); > } > @@ -2497,7 +2517,6 @@ static int __maybe_unused anx7625_runtime_pm_resume(struct device *dev) > mutex_lock(&ctx->lock); > > anx7625_power_on_init(ctx); > - anx7625_hpd_polling(ctx); > > mutex_unlock(&ctx->lock); > > @@ -2589,6 +2608,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, > platform->aux.name = "anx7625-aux"; > platform->aux.dev = dev; > platform->aux.transfer = anx7625_aux_transfer; > + platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted; > drm_dp_aux_init(&platform->aux); > > if (anx7625_register_i2c_dummy_clients(platform, client) != 0) { > @@ -2617,6 +2637,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, > if (!platform->pdata.low_power_mode) { > anx7625_disable_pd_protocol(platform); > pm_runtime_get_sync(dev); > + _anx7625_hpd_polling(platform, 5000 * 100); > } > > /* Add work function */ > -- > 2.37.0.rc0.161.g10f37bed90-goog