Message ID | 20210525111222.241131-1-inki.dae@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/exynos: use pm_runtime_resume_and_get() | expand |
Hi Inki, I love your patch! Yet something to improve: [auto build test ERROR on drm-exynos/exynos-drm-next] [also build test ERROR on drm-intel/for-linux-next drm-tip/drm-tip tegra-drm/drm/tegra/for-next v5.13-rc3 next-20210525] [cannot apply to drm/drm-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Inki-Dae/drm-exynos-use-pm_runtime_resume_and_get/20210525-190630 base: https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next config: arm64-randconfig-r014-20210526 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 99155e913e9bad5f7f8a247f8bb3a3ff3da74af1) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/e9c82df302b53764b0fac4c14d48efe2595a296e git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Inki-Dae/drm-exynos-use-pm_runtime_resume_and_get/20210525-190630 git checkout e9c82df302b53764b0fac4c14d48efe2595a296e # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/gpu/drm/exynos/exynos_drm_gsc.c:1123:47: error: too few arguments provided to function-like macro invocation dev_err("failed to enable GScaler device.\n"); ^ include/linux/dev_printk.h:111:9: note: macro 'dev_err' defined here #define dev_err(dev, fmt, ...) \ ^ >> drivers/gpu/drm/exynos/exynos_drm_gsc.c:1123:3: error: use of undeclared identifier 'dev_err'; did you mean '_dev_err'? dev_err("failed to enable GScaler device.\n"); ^~~~~~~ _dev_err include/linux/dev_printk.h:50:6: note: '_dev_err' declared here void _dev_err(const struct device *dev, const char *fmt, ...); ^ drivers/gpu/drm/exynos/exynos_drm_gsc.c:1123:3: warning: expression result unused [-Wunused-value] dev_err("failed to enable GScaler device.\n"); ^~~~~~~ 1 warning and 2 errors generated. vim +1123 drivers/gpu/drm/exynos/exynos_drm_gsc.c 1114 1115 static int gsc_commit(struct exynos_drm_ipp *ipp, 1116 struct exynos_drm_ipp_task *task) 1117 { 1118 struct gsc_context *ctx = container_of(ipp, struct gsc_context, ipp); 1119 int ret; 1120 1121 ret = pm_runtime_resume_and_get(ctx->dev); 1122 if (ret < 0) { > 1123 dev_err("failed to enable GScaler device.\n"); 1124 return ret; 1125 } 1126 1127 ctx->task = task; 1128 1129 ret = gsc_reset(ctx); 1130 if (ret) { 1131 pm_runtime_put_autosuspend(ctx->dev); 1132 ctx->task = NULL; 1133 return ret; 1134 } 1135 1136 gsc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier); 1137 gsc_src_set_transf(ctx, task->transform.rotation); 1138 gsc_src_set_size(ctx, &task->src); 1139 gsc_src_set_addr(ctx, 0, &task->src); 1140 gsc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier); 1141 gsc_dst_set_size(ctx, &task->dst); 1142 gsc_dst_set_addr(ctx, 0, &task->dst); 1143 gsc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect); 1144 gsc_start(ctx); 1145 1146 return 0; 1147 } 1148 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index b9a4b7670a89..63dd85af13f2 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -513,8 +513,13 @@ static void decon_swreset(struct decon_context *ctx) static void decon_atomic_enable(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx; + int ret; - pm_runtime_get_sync(ctx->dev); + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + DRM_DEV_ERROR(ctx->dev, "failed to enable DECON device.\n"); + return; + } exynos_drm_pipe_clk_enable(crtc, true); diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 431c5d32f9a4..b61edc54e66f 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -531,11 +531,16 @@ static void decon_init(struct decon_context *ctx) static void decon_atomic_enable(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx; + int ret; if (!ctx->suspended) return; - pm_runtime_get_sync(ctx->dev); + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + DRM_DEV_ERROR(ctx->dev, "failed to enable DECON device.\n"); + return; + } decon_init(ctx); diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 44e402b7cdfb..5bb1388a8b18 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1383,7 +1383,12 @@ static void exynos_dsi_enable(struct drm_encoder *encoder) if (dsi->state & DSIM_STATE_ENABLED) return; - pm_runtime_get_sync(dsi->dev); + ret = pm_runtime_resume_and_get(dsi->dev); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable DSI device.\n"); + return; + } + dsi->state |= DSIM_STATE_ENABLED; if (dsi->panel) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 29ab8be8604c..a3c718148c45 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1085,8 +1085,14 @@ static int fimc_commit(struct exynos_drm_ipp *ipp, { struct fimc_context *ctx = container_of(ipp, struct fimc_context, ipp); + int ret; + + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + dev_err(ctx->dev, "failed to enable FIMC device.\n"); + return ret; + } - pm_runtime_get_sync(ctx->dev); ctx->task = task; fimc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 49a2e0c53918..5955bd90accb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -343,13 +343,18 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, writel(val, ctx->regs + SHADOWCON); } -static void fimd_clear_channels(struct exynos_drm_crtc *crtc) +static int fimd_clear_channels(struct exynos_drm_crtc *crtc) { struct fimd_context *ctx = crtc->ctx; unsigned int win, ch_enabled = 0; + int ret; /* Hardware is in unknown state, so ensure it gets enabled properly */ - pm_runtime_get_sync(ctx->dev); + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + dev_err(ctx->dev, "failed to enable FIMD device.\n"); + return ret; + } clk_prepare_enable(ctx->bus_clk); clk_prepare_enable(ctx->lcd_clk); @@ -384,6 +389,8 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc) clk_disable_unprepare(ctx->bus_clk); pm_runtime_put(ctx->dev); + + return 0; } @@ -905,7 +912,10 @@ static void fimd_atomic_enable(struct exynos_drm_crtc *crtc) ctx->suspended = false; - pm_runtime_get_sync(ctx->dev); + if (pm_runtime_resume_and_get(ctx->dev) < 0) { + dev_warn(ctx->dev, "failed to enable FIMD device.\n"); + return; + } /* if vblank was enabled status, enable it again. */ if (test_and_clear_bit(0, &ctx->irq_flags)) @@ -1089,8 +1099,13 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) if (ctx->encoder) exynos_dpi_bind(drm_dev, ctx->encoder); - if (is_drm_iommu_supported(drm_dev)) - fimd_clear_channels(ctx->crtc); + if (is_drm_iommu_supported(drm_dev)) { + int ret; + + ret = fimd_clear_channels(ctx->crtc); + if (ret < 0) + return ret; + } return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 1e0c5a7f206e..cab4d2c370a7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -892,7 +892,14 @@ static void g2d_runqueue_worker(struct work_struct *work) g2d->runqueue_node = g2d_get_runqueue_node(g2d); if (g2d->runqueue_node) { - pm_runtime_get_sync(g2d->dev); + int ret; + + ret = pm_runtime_resume_and_get(g2d->dev); + if (ret < 0) { + dev_err(g2d->dev, "failed to enable G2D device.\n"); + return; + } + g2d_dma_start(g2d, g2d->runqueue_node); } } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index b01f36e76eaf..e4cd413f1c26 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1118,7 +1118,12 @@ static int gsc_commit(struct exynos_drm_ipp *ipp, struct gsc_context *ctx = container_of(ipp, struct gsc_context, ipp); int ret; - pm_runtime_get_sync(ctx->dev); + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + dev_err("failed to enable GScaler device.\n"); + return ret; + } + ctx->task = task; ret = gsc_reset(ctx); diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index 2d94afba031e..ee61be4cf152 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -219,8 +219,13 @@ static int rotator_commit(struct exynos_drm_ipp *ipp, { struct rot_context *rot = container_of(ipp, struct rot_context, ipp); + int ret; - pm_runtime_get_sync(rot->dev); + ret = pm_runtime_resume_and_get(rot->dev); + if (ret < 0) { + dev_err(rot->dev, "failed to enable ROTATOR device.\n"); + return ret; + } rot->task = task; rotator_src_set_fmt(rot, task->src.buf.fourcc); diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c index ce1857138f89..f9ae5b038d59 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_scaler.c +++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c @@ -362,15 +362,17 @@ static int scaler_commit(struct exynos_drm_ipp *ipp, struct drm_exynos_ipp_task_rect *src_pos = &task->src.rect; struct drm_exynos_ipp_task_rect *dst_pos = &task->dst.rect; const struct scaler_format *src_fmt, *dst_fmt; + int ret = 0; src_fmt = scaler_get_format(task->src.buf.fourcc); dst_fmt = scaler_get_format(task->dst.buf.fourcc); - pm_runtime_get_sync(scaler->dev); - if (scaler_reset(scaler)) { - pm_runtime_put(scaler->dev); + ret = pm_runtime_resume_and_get(scaler->dev); + if (ret < 0) + return ret; + + if (scaler_reset(scaler)) return -EIO; - } scaler->task = task; diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 39fa5d3b01ef..f893731d6021 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1483,10 +1483,16 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) /* Should be called with hdata->mutex mutex held. */ static void hdmiphy_enable(struct hdmi_context *hdata) { + int ret; + if (hdata->powered) return; - pm_runtime_get_sync(hdata->dev); + ret = pm_runtime_resume_and_get(hdata->dev); + if (ret < 0) { + dev_err(hdata->dev, "failed to enable HDMIPHY device.\n"); + return; + } if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk)) DRM_DEV_DEBUG_KMS(hdata->dev, diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index af192e5a16ef..41c54f1f60bc 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -992,11 +992,16 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) static void mixer_atomic_enable(struct exynos_drm_crtc *crtc) { struct mixer_context *ctx = crtc->ctx; + int ret; if (test_bit(MXR_BIT_POWERED, &ctx->flags)) return; - pm_runtime_get_sync(ctx->dev); + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + dev_err(ctx->dev, "failed to enable MIXER device.\n"); + return; + } exynos_drm_pipe_clk_enable(crtc, true);
Use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() to deal with usage counter. pm_runtime_get_sync() increases the usage counter even when it failed, which makes callers to forget to decrease the usage counter and resulted in reference leak. pm_runtime_resume_and_get() function decreases the usage counter when it failed internally so it can avoid the reference leak. Signed-off-by: Inki Dae <inki.dae@samsung.com> --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 7 +++++- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 7 +++++- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 7 +++++- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 8 +++++- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 25 +++++++++++++++---- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 9 ++++++- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 7 +++++- drivers/gpu/drm/exynos/exynos_drm_rotator.c | 7 +++++- drivers/gpu/drm/exynos/exynos_drm_scaler.c | 10 +++++--- drivers/gpu/drm/exynos/exynos_hdmi.c | 8 +++++- drivers/gpu/drm/exynos/exynos_mixer.c | 7 +++++- 11 files changed, 84 insertions(+), 18 deletions(-)