]>
Commit | Line | Data |
---|---|---|
8fece351 GKH |
1 | From 310944d148e3600dcff8b346bee7fa01d34903b1 Mon Sep 17 00:00:00 2001 |
2 | From: Philipp Zabel <p.zabel@pengutronix.de> | |
3 | Date: Thu, 12 May 2016 15:00:44 +0200 | |
4 | Subject: drm/imx: Match imx-ipuv3-crtc components using device node in platform data | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Philipp Zabel <p.zabel@pengutronix.de> | |
10 | ||
11 | commit 310944d148e3600dcff8b346bee7fa01d34903b1 upstream. | |
12 | ||
13 | The component master driver imx-drm-core matches component devices using | |
14 | their of_node. Since commit 950b410dd1ab ("gpu: ipu-v3: Fix imx-ipuv3-crtc | |
15 | module autoloading"), the imx-ipuv3-crtc dev->of_node is not set during | |
16 | probing. Before that, of_node was set and caused an of: modalias to be | |
17 | used instead of the platform: modalias, which broke module autoloading. | |
18 | ||
19 | On the other hand, if dev->of_node is not set yet when the imx-ipuv3-crtc | |
20 | probe function calls component_add, component matching in imx-drm-core | |
21 | fails. While dev->of_node will be set once the next component tries to | |
22 | bring up the component master, imx-drm-core component binding will never | |
23 | succeed if one of the crtc devices is probed last. | |
24 | ||
25 | Add of_node to the component platform data and match against the | |
26 | pdata->of_node instead of dev->of_node in imx-drm-core to work around | |
27 | this problem. | |
28 | ||
29 | Fixes: 950b410dd1ab ("gpu: ipu-v3: Fix imx-ipuv3-crtc module autoloading") | |
30 | Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> | |
31 | Tested-by: Fabio Estevam <fabio.estevam@nxp.com> | |
32 | Tested-by: Lothar Waßmann <LW@KARO-electronics.de> | |
33 | Tested-by: Heiko Schocher <hs@denx.de> | |
34 | Tested-by: Chris Ruehl <chris.ruehl@gtsys.com.hk> | |
35 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
36 | ||
37 | --- | |
38 | drivers/gpu/drm/imx/imx-drm-core.c | 8 ++++++++ | |
39 | drivers/gpu/drm/imx/ipuv3-crtc.c | 2 +- | |
40 | drivers/gpu/ipu-v3/ipu-common.c | 5 +++-- | |
41 | include/video/imx-ipu-v3.h | 2 ++ | |
42 | 4 files changed, 14 insertions(+), 3 deletions(-) | |
43 | ||
44 | --- a/drivers/gpu/drm/imx/imx-drm-core.c | |
45 | +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |
46 | @@ -26,6 +26,7 @@ | |
47 | #include <drm/drm_fb_cma_helper.h> | |
48 | #include <drm/drm_plane_helper.h> | |
49 | #include <drm/drm_of.h> | |
50 | +#include <video/imx-ipu-v3.h> | |
51 | ||
52 | #include "imx-drm.h" | |
53 | ||
54 | @@ -498,6 +499,13 @@ static int compare_of(struct device *dev | |
55 | { | |
56 | struct device_node *np = data; | |
57 | ||
58 | + /* Special case for DI, dev->of_node may not be set yet */ | |
59 | + if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) { | |
60 | + struct ipu_client_platformdata *pdata = dev->platform_data; | |
61 | + | |
62 | + return pdata->of_node == np; | |
63 | + } | |
64 | + | |
65 | /* Special case for LDB, one device for two channels */ | |
66 | if (of_node_cmp(np->name, "lvds-channel") == 0) { | |
67 | np = of_get_parent(np); | |
68 | --- a/drivers/gpu/drm/imx/ipuv3-crtc.c | |
69 | +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c | |
70 | @@ -371,7 +371,7 @@ static int ipu_crtc_init(struct ipu_crtc | |
71 | ||
72 | ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, | |
73 | &ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs, | |
74 | - ipu_crtc->dev->of_node); | |
75 | + pdata->of_node); | |
76 | if (ret) { | |
77 | dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); | |
78 | goto err_put_resources; | |
79 | --- a/drivers/gpu/ipu-v3/ipu-common.c | |
80 | +++ b/drivers/gpu/ipu-v3/ipu-common.c | |
81 | @@ -997,7 +997,7 @@ struct ipu_platform_reg { | |
82 | }; | |
83 | ||
84 | /* These must be in the order of the corresponding device tree port nodes */ | |
85 | -static const struct ipu_platform_reg client_reg[] = { | |
86 | +static struct ipu_platform_reg client_reg[] = { | |
87 | { | |
88 | .pdata = { | |
89 | .csi = 0, | |
90 | @@ -1048,7 +1048,7 @@ static int ipu_add_client_devices(struct | |
91 | mutex_unlock(&ipu_client_id_mutex); | |
92 | ||
93 | for (i = 0; i < ARRAY_SIZE(client_reg); i++) { | |
94 | - const struct ipu_platform_reg *reg = &client_reg[i]; | |
95 | + struct ipu_platform_reg *reg = &client_reg[i]; | |
96 | struct platform_device *pdev; | |
97 | struct device_node *of_node; | |
98 | ||
99 | @@ -1070,6 +1070,7 @@ static int ipu_add_client_devices(struct | |
100 | ||
101 | pdev->dev.parent = dev; | |
102 | ||
103 | + reg->pdata.of_node = of_node; | |
104 | ret = platform_device_add_data(pdev, ®->pdata, | |
105 | sizeof(reg->pdata)); | |
106 | if (!ret) | |
107 | --- a/include/video/imx-ipu-v3.h | |
108 | +++ b/include/video/imx-ipu-v3.h | |
109 | @@ -16,6 +16,7 @@ | |
110 | #include <linux/videodev2.h> | |
111 | #include <linux/bitmap.h> | |
112 | #include <linux/fb.h> | |
113 | +#include <linux/of.h> | |
114 | #include <media/v4l2-mediabus.h> | |
115 | #include <video/videomode.h> | |
116 | ||
117 | @@ -344,6 +345,7 @@ struct ipu_client_platformdata { | |
118 | int dc; | |
119 | int dp; | |
120 | int dma[2]; | |
121 | + struct device_node *of_node; | |
122 | }; | |
123 | ||
124 | #endif /* __DRM_IPU_H__ */ |