Skip to content

Commit ac2ad73

Browse files
committed
Merge tag 'exynos-drm-fixes-for-v6.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
Fixups - Fixed raw pointer leakage and unsafe behavior in printk() . Switch from %pK to %p for pointer formatting, as %p is now safer and prevents issues like raw pointer leakage and acquiring sleeping locks in atomic contexts. - Fixed kernel panic during boot . A NULL pointer dereference issue occasionally occurred when the vblank interrupt handler was called before the DRM driver was fully initialized during boot. So this patch fixes the issue by adding a check in the interrupt handler to ensure the DRM driver is properly initialized. - Fixed a lockup issue on Samsung Peach-Pit/Pi Chromebooks . The issue occurred after commit c9b1150 changed the call order of CRTC enable/disable and bridge pre_enable/post_disable methods, causing fimd_dp_clock_enable() to be called before the FIMD device was activated. To fix this, runtime PM guards were added to fimd_dp_clock_enable() to ensure proper operation even when CRTC is not enabled. Signed-off-by: Dave Airlie <[email protected]> From: Inki Dae <[email protected]> Link: https://lore.kernel.org/r/[email protected]
2 parents afd30ac + 5d91394 commit ac2ad73

File tree

4 files changed

+33
-17
lines changed

4 files changed

+33
-17
lines changed

drivers/gpu/drm/exynos/exynos7_drm_decon.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,10 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
636636
if (!ctx->drm_dev)
637637
goto out;
638638

639+
/* check if crtc and vblank have been initialized properly */
640+
if (!drm_dev_has_vblank(ctx->drm_dev))
641+
goto out;
642+
639643
if (!ctx->i80_if) {
640644
drm_crtc_handle_vblank(&ctx->crtc->base);
641645

drivers/gpu/drm/exynos/exynos_drm_fimd.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ struct fimd_context {
187187
u32 i80ifcon;
188188
bool i80_if;
189189
bool suspended;
190+
bool dp_clk_enabled;
190191
wait_queue_head_t wait_vsync_queue;
191192
atomic_t wait_vsync_event;
192193
atomic_t win_updated;
@@ -1047,7 +1048,18 @@ static void fimd_dp_clock_enable(struct exynos_drm_clk *clk, bool enable)
10471048
struct fimd_context *ctx = container_of(clk, struct fimd_context,
10481049
dp_clk);
10491050
u32 val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
1051+
1052+
if (enable == ctx->dp_clk_enabled)
1053+
return;
1054+
1055+
if (enable)
1056+
pm_runtime_resume_and_get(ctx->dev);
1057+
1058+
ctx->dp_clk_enabled = enable;
10501059
writel(val, ctx->regs + DP_MIE_CLKCON);
1060+
1061+
if (!enable)
1062+
pm_runtime_put(ctx->dev);
10511063
}
10521064

10531065
static const struct exynos_drm_crtc_ops fimd_crtc_ops = {

drivers/gpu/drm/exynos/exynos_drm_gem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
174174
return ERR_PTR(ret);
175175
}
176176

177-
DRM_DEV_DEBUG_KMS(dev->dev, "created file object = %pK\n", obj->filp);
177+
DRM_DEV_DEBUG_KMS(dev->dev, "created file object = %p\n", obj->filp);
178178

179179
return exynos_gem;
180180
}

drivers/gpu/drm/exynos/exynos_drm_ipp.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static inline struct exynos_drm_ipp_task *
271271
task->src.rect.h = task->dst.rect.h = UINT_MAX;
272272
task->transform.rotation = DRM_MODE_ROTATE_0;
273273

274-
DRM_DEV_DEBUG_DRIVER(task->dev, "Allocated task %pK\n", task);
274+
DRM_DEV_DEBUG_DRIVER(task->dev, "Allocated task %p\n", task);
275275

276276
return task;
277277
}
@@ -339,7 +339,7 @@ static int exynos_drm_ipp_task_set(struct exynos_drm_ipp_task *task,
339339
}
340340

341341
DRM_DEV_DEBUG_DRIVER(task->dev,
342-
"Got task %pK configuration from userspace\n",
342+
"Got task %p configuration from userspace\n",
343343
task);
344344
return 0;
345345
}
@@ -394,7 +394,7 @@ static void exynos_drm_ipp_task_release_buf(struct exynos_drm_ipp_buffer *buf)
394394
static void exynos_drm_ipp_task_free(struct exynos_drm_ipp *ipp,
395395
struct exynos_drm_ipp_task *task)
396396
{
397-
DRM_DEV_DEBUG_DRIVER(task->dev, "Freeing task %pK\n", task);
397+
DRM_DEV_DEBUG_DRIVER(task->dev, "Freeing task %p\n", task);
398398

399399
exynos_drm_ipp_task_release_buf(&task->src);
400400
exynos_drm_ipp_task_release_buf(&task->dst);
@@ -559,7 +559,7 @@ static int exynos_drm_ipp_check_format(struct exynos_drm_ipp_task *task,
559559
DRM_EXYNOS_IPP_FORMAT_DESTINATION);
560560
if (!fmt) {
561561
DRM_DEV_DEBUG_DRIVER(task->dev,
562-
"Task %pK: %s format not supported\n",
562+
"Task %p: %s format not supported\n",
563563
task, buf == src ? "src" : "dst");
564564
return -EINVAL;
565565
}
@@ -609,7 +609,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task)
609609
bool rotate = (rotation != DRM_MODE_ROTATE_0);
610610
bool scale = false;
611611

612-
DRM_DEV_DEBUG_DRIVER(task->dev, "Checking task %pK\n", task);
612+
DRM_DEV_DEBUG_DRIVER(task->dev, "Checking task %p\n", task);
613613

614614
if (src->rect.w == UINT_MAX)
615615
src->rect.w = src->buf.width;
@@ -625,7 +625,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task)
625625
dst->rect.x + dst->rect.w > (dst->buf.width) ||
626626
dst->rect.y + dst->rect.h > (dst->buf.height)) {
627627
DRM_DEV_DEBUG_DRIVER(task->dev,
628-
"Task %pK: defined area is outside provided buffers\n",
628+
"Task %p: defined area is outside provided buffers\n",
629629
task);
630630
return -EINVAL;
631631
}
@@ -642,7 +642,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task)
642642
(!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_SCALE) && scale) ||
643643
(!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_CONVERT) &&
644644
src->buf.fourcc != dst->buf.fourcc)) {
645-
DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: hw capabilities exceeded\n",
645+
DRM_DEV_DEBUG_DRIVER(task->dev, "Task %p: hw capabilities exceeded\n",
646646
task);
647647
return -EINVAL;
648648
}
@@ -655,7 +655,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task)
655655
if (ret)
656656
return ret;
657657

658-
DRM_DEV_DEBUG_DRIVER(ipp->dev, "Task %pK: all checks done.\n",
658+
DRM_DEV_DEBUG_DRIVER(ipp->dev, "Task %p: all checks done.\n",
659659
task);
660660

661661
return ret;
@@ -667,25 +667,25 @@ static int exynos_drm_ipp_task_setup_buffers(struct exynos_drm_ipp_task *task,
667667
struct exynos_drm_ipp_buffer *src = &task->src, *dst = &task->dst;
668668
int ret = 0;
669669

670-
DRM_DEV_DEBUG_DRIVER(task->dev, "Setting buffer for task %pK\n",
670+
DRM_DEV_DEBUG_DRIVER(task->dev, "Setting buffer for task %p\n",
671671
task);
672672

673673
ret = exynos_drm_ipp_task_setup_buffer(src, filp);
674674
if (ret) {
675675
DRM_DEV_DEBUG_DRIVER(task->dev,
676-
"Task %pK: src buffer setup failed\n",
676+
"Task %p: src buffer setup failed\n",
677677
task);
678678
return ret;
679679
}
680680
ret = exynos_drm_ipp_task_setup_buffer(dst, filp);
681681
if (ret) {
682682
DRM_DEV_DEBUG_DRIVER(task->dev,
683-
"Task %pK: dst buffer setup failed\n",
683+
"Task %p: dst buffer setup failed\n",
684684
task);
685685
return ret;
686686
}
687687

688-
DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: buffers prepared.\n",
688+
DRM_DEV_DEBUG_DRIVER(task->dev, "Task %p: buffers prepared.\n",
689689
task);
690690

691691
return ret;
@@ -764,7 +764,7 @@ void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret)
764764
struct exynos_drm_ipp *ipp = task->ipp;
765765
unsigned long flags;
766766

767-
DRM_DEV_DEBUG_DRIVER(task->dev, "ipp: %d, task %pK done: %d\n",
767+
DRM_DEV_DEBUG_DRIVER(task->dev, "ipp: %d, task %p done: %d\n",
768768
ipp->id, task, ret);
769769

770770
spin_lock_irqsave(&ipp->lock, flags);
@@ -807,7 +807,7 @@ static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp)
807807
spin_unlock_irqrestore(&ipp->lock, flags);
808808

809809
DRM_DEV_DEBUG_DRIVER(ipp->dev,
810-
"ipp: %d, selected task %pK to run\n", ipp->id,
810+
"ipp: %d, selected task %p to run\n", ipp->id,
811811
task);
812812

813813
ret = ipp->funcs->commit(ipp, task);
@@ -917,14 +917,14 @@ int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, void *data,
917917
*/
918918
if (arg->flags & DRM_EXYNOS_IPP_FLAG_NONBLOCK) {
919919
DRM_DEV_DEBUG_DRIVER(ipp->dev,
920-
"ipp: %d, nonblocking processing task %pK\n",
920+
"ipp: %d, nonblocking processing task %p\n",
921921
ipp->id, task);
922922

923923
task->flags |= DRM_EXYNOS_IPP_TASK_ASYNC;
924924
exynos_drm_ipp_schedule_task(task->ipp, task);
925925
ret = 0;
926926
} else {
927-
DRM_DEV_DEBUG_DRIVER(ipp->dev, "ipp: %d, processing task %pK\n",
927+
DRM_DEV_DEBUG_DRIVER(ipp->dev, "ipp: %d, processing task %p\n",
928928
ipp->id, task);
929929
exynos_drm_ipp_schedule_task(ipp, task);
930930
ret = wait_event_interruptible(ipp->done_wq,

0 commit comments

Comments
 (0)