drm/imx: Match imx-ipuv3-crtc components using device node in platform data
The component master driver imx-drm-core matches component devices using
their of_node. Since commit 950b410dd1ab ("gpu: ipu-v3: Fix imx-ipuv3-crtc
module autoloading"), the imx-ipuv3-crtc dev->of_node is not set during
probing. Before that, of_node was set and caused an of: modalias to be
used instead of the platform: modalias, which broke module autoloading.
On the other hand, if dev->of_node is not set yet when the imx-ipuv3-crtc
probe function calls component_add, component matching in imx-drm-core
fails. While dev->of_node will be set once the next component tries to
bring up the component master, imx-drm-core component binding will never
succeed if one of the crtc devices is probed last.
Add of_node to the component platform data and match against the
pdata->of_node instead of dev->of_node in imx-drm-core to work around
this problem.
Cc: <stable@vger.kernel.org> # 4.4.x
Fixes: 950b410dd1ab ("gpu: ipu-v3: Fix imx-ipuv3-crtc module autoloading")
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Lothar Waßmann <LW@KARO-electronics.de>
Tested-by: Heiko Schocher <hs@denx.de>
Tested-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
			
			
This commit is contained in:
		
							parent
							
								
									2dcd0af568
								
							
						
					
					
						commit
						310944d148
					
				| @ -25,6 +25,7 @@ | ||||
| #include <drm/drm_fb_cma_helper.h> | ||||
| #include <drm/drm_plane_helper.h> | ||||
| #include <drm/drm_of.h> | ||||
| #include <video/imx-ipu-v3.h> | ||||
| 
 | ||||
| #include "imx-drm.h" | ||||
| 
 | ||||
| @ -444,6 +445,13 @@ static int compare_of(struct device *dev, void *data) | ||||
| { | ||||
| 	struct device_node *np = data; | ||||
| 
 | ||||
| 	/* Special case for DI, dev->of_node may not be set yet */ | ||||
| 	if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) { | ||||
| 		struct ipu_client_platformdata *pdata = dev->platform_data; | ||||
| 
 | ||||
| 		return pdata->of_node == np; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Special case for LDB, one device for two channels */ | ||||
| 	if (of_node_cmp(np->name, "lvds-channel") == 0) { | ||||
| 		np = of_get_parent(np); | ||||
|  | ||||
| @ -473,7 +473,7 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, | ||||
| 
 | ||||
| 	ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, | ||||
| 			&ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs, | ||||
| 			ipu_crtc->dev->of_node); | ||||
| 			pdata->of_node); | ||||
| 	if (ret) { | ||||
| 		dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); | ||||
| 		goto err_put_resources; | ||||
|  | ||||
| @ -997,7 +997,7 @@ struct ipu_platform_reg { | ||||
| }; | ||||
| 
 | ||||
| /* These must be in the order of the corresponding device tree port nodes */ | ||||
| static const struct ipu_platform_reg client_reg[] = { | ||||
| static struct ipu_platform_reg client_reg[] = { | ||||
| 	{ | ||||
| 		.pdata = { | ||||
| 			.csi = 0, | ||||
| @ -1048,7 +1048,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) | ||||
| 	mutex_unlock(&ipu_client_id_mutex); | ||||
| 
 | ||||
| 	for (i = 0; i < ARRAY_SIZE(client_reg); i++) { | ||||
| 		const struct ipu_platform_reg *reg = &client_reg[i]; | ||||
| 		struct ipu_platform_reg *reg = &client_reg[i]; | ||||
| 		struct platform_device *pdev; | ||||
| 		struct device_node *of_node; | ||||
| 
 | ||||
| @ -1070,6 +1070,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) | ||||
| 
 | ||||
| 		pdev->dev.parent = dev; | ||||
| 
 | ||||
| 		reg->pdata.of_node = of_node; | ||||
| 		ret = platform_device_add_data(pdev, ®->pdata, | ||||
| 					       sizeof(reg->pdata)); | ||||
| 		if (!ret) | ||||
|  | ||||
| @ -16,6 +16,7 @@ | ||||
| #include <linux/videodev2.h> | ||||
| #include <linux/bitmap.h> | ||||
| #include <linux/fb.h> | ||||
| #include <linux/of.h> | ||||
| #include <media/v4l2-mediabus.h> | ||||
| #include <video/videomode.h> | ||||
| 
 | ||||
| @ -345,6 +346,7 @@ struct ipu_client_platformdata { | ||||
| 	int dc; | ||||
| 	int dp; | ||||
| 	int dma[2]; | ||||
| 	struct device_node *of_node; | ||||
| }; | ||||
| 
 | ||||
| #endif /* __DRM_IPU_H__ */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user