Skip to content

Commit 3bce3fd

Browse files
Laurent Pincharttomba
authored andcommitted
drm: rcar-du: Don't leak device_link to CMM
The DU driver creates device_link instances between the DU and CMMs, but never deletes them. Fix it by introducing a rcar_du_cmm structure to group the CMM device and device_link, and deleting the links at cleanup time. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Link: https://patch.msgid.link/20260323164526.2292491-5-laurent.pinchart+renesas@ideasonboard.com Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
1 parent a93b873 commit 3bce3fd

4 files changed

Lines changed: 35 additions & 21 deletions

File tree

drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -513,13 +513,13 @@ static void rcar_du_cmm_setup(struct drm_crtc *crtc)
513513
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
514514
struct rcar_cmm_config cmm_config = {};
515515

516-
if (!rcrtc->cmm)
516+
if (!rcrtc->cmm->dev)
517517
return;
518518

519519
if (drm_lut)
520520
cmm_config.lut.table = (struct drm_color_lut *)drm_lut->data;
521521

522-
rcar_cmm_setup(rcrtc->cmm, &cmm_config);
522+
rcar_cmm_setup(rcrtc->cmm->dev, &cmm_config);
523523
}
524524

525525
/* -----------------------------------------------------------------------------
@@ -667,8 +667,8 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
667667
if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
668668
rcar_du_vsp_disable(rcrtc);
669669

670-
if (rcrtc->cmm)
671-
rcar_cmm_disable(rcrtc->cmm);
670+
if (rcrtc->cmm->dev)
671+
rcar_cmm_disable(rcrtc->cmm->dev);
672672

673673
/*
674674
* Select switch sync mode. This stops display operation and configures
@@ -726,8 +726,8 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
726726
struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state);
727727
struct rcar_du_device *rcdu = rcrtc->dev;
728728

729-
if (rcrtc->cmm)
730-
rcar_cmm_enable(rcrtc->cmm);
729+
if (rcrtc->cmm->dev)
730+
rcar_cmm_enable(rcrtc->cmm->dev);
731731
rcar_du_crtc_get(rcrtc);
732732

733733
/*
@@ -1300,8 +1300,8 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
13001300
return ret;
13011301

13021302
/* CMM might be disabled for this CRTC. */
1303-
if (rcdu->cmms[swindex]) {
1304-
rcrtc->cmm = rcdu->cmms[swindex];
1303+
if (rcdu->cmms[swindex].dev) {
1304+
rcrtc->cmm = &rcdu->cmms[swindex];
13051305
rgrp->cmms_mask |= BIT(hwindex % 2);
13061306

13071307
drm_mode_crtc_set_gamma_size(crtc, CM2_LUT_SIZE);

drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <media/vsp1.h>
2121

22+
struct rcar_du_cmm;
2223
struct rcar_du_group;
2324
struct rcar_du_vsp;
2425

@@ -65,7 +66,7 @@ struct rcar_du_crtc {
6566
unsigned int vblank_count;
6667

6768
struct rcar_du_group *group;
68-
struct device *cmm;
69+
struct rcar_du_cmm *cmm;
6970
struct rcar_du_vsp *vsp;
7071
unsigned int vsp_pipe;
7172

drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
struct clk;
2424
struct device;
25+
struct device_link;
2526
struct drm_bridge;
2627
struct drm_property;
2728
struct rcar_du_device;
@@ -88,6 +89,11 @@ struct rcar_du_device_info {
8889
unsigned int lvds_clk_mask;
8990
};
9091

92+
struct rcar_du_cmm {
93+
struct device *dev;
94+
struct device_link *link;
95+
};
96+
9197
#define RCAR_DU_MAX_CRTCS 4
9298
#define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
9399
#define RCAR_DU_MAX_VSPS 4
@@ -106,7 +112,7 @@ struct rcar_du_device {
106112
unsigned int num_crtcs;
107113

108114
struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
109-
struct device *cmms[RCAR_DU_MAX_CRTCS];
115+
struct rcar_du_cmm cmms[RCAR_DU_MAX_CRTCS];
110116
struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
111117
struct drm_bridge *lvds[RCAR_DU_MAX_LVDS];
112118
struct drm_bridge *dsi[RCAR_DU_MAX_DSI];

drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -769,23 +769,23 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
769769
}
770770

771771
for (i = 0; i < cells; ++i) {
772-
struct device_node *cmm __free(device_node) = NULL;
772+
struct device_node *cmm_node __free(device_node) = NULL;
773+
struct rcar_du_cmm *cmm = &rcdu->cmms[i];
773774
struct platform_device *pdev;
774-
struct device_link *link;
775775
int ret;
776776

777-
cmm = of_parse_phandle(np, "renesas,cmms", i);
778-
if (!cmm) {
777+
cmm_node = of_parse_phandle(np, "renesas,cmms", i);
778+
if (!cmm_node) {
779779
dev_err(rcdu->dev,
780780
"Failed to parse 'renesas,cmms' property\n");
781781
return -EINVAL;
782782
}
783783

784-
if (!of_device_is_available(cmm))
784+
if (!of_device_is_available(cmm_node))
785785
/* It's fine to have a phandle to a non-enabled CMM. */
786786
continue;
787787

788-
pdev = of_find_device_by_node(cmm);
788+
pdev = of_find_device_by_node(cmm_node);
789789
if (!pdev) {
790790
dev_err(rcdu->dev, "No device found for CMM%u\n", i);
791791
return -EINVAL;
@@ -801,14 +801,15 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
801801
return ret == -ENODEV ? 0 : ret;
802802
}
803803

804-
rcdu->cmms[i] = &pdev->dev;
804+
cmm->dev = &pdev->dev;
805805

806806
/*
807807
* Enforce suspend/resume ordering by making the CMM a provider
808808
* of the DU: CMM is suspended after and resumed before the DU.
809809
*/
810-
link = device_link_add(rcdu->dev, &pdev->dev, DL_FLAG_STATELESS);
811-
if (!link) {
810+
cmm->link = device_link_add(rcdu->dev, cmm->dev,
811+
DL_FLAG_STATELESS);
812+
if (!cmm->link) {
812813
dev_err(rcdu->dev,
813814
"Failed to create device link to CMM%u\n", i);
814815
return -EINVAL;
@@ -823,8 +824,14 @@ static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res)
823824
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
824825
unsigned int i;
825826

826-
for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i)
827-
put_device(rcdu->cmms[i]);
827+
for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i) {
828+
struct rcar_du_cmm *cmm = &rcdu->cmms[i];
829+
830+
if (cmm->link)
831+
device_link_del(cmm->link);
832+
833+
put_device(cmm->dev);
834+
}
828835
}
829836

830837
int rcar_du_modeset_init(struct rcar_du_device *rcdu)

0 commit comments

Comments
 (0)