|
24 | 24 | #include <linux/pm_runtime.h>
|
25 | 25 | #include <linux/module.h>
|
26 | 26 | #include <linux/of_graph.h>
|
| 27 | +#include <linux/of_platform.h> |
27 | 28 | #include <linux/component.h>
|
28 | 29 | #include <linux/console.h>
|
29 | 30 | #include <linux/iommu.h>
|
@@ -267,6 +268,53 @@ static const struct dev_pm_ops rockchip_drm_pm_ops = {
|
267 | 268 | static struct platform_driver *rockchip_sub_drivers[MAX_ROCKCHIP_SUB_DRIVERS];
|
268 | 269 | static int num_rockchip_sub_drivers;
|
269 | 270 |
|
| 271 | +/* |
| 272 | + * Check if a vop endpoint is leading to a rockchip subdriver or bridge. |
| 273 | + * Should be called from the component bind stage of the drivers |
| 274 | + * to ensure that all subdrivers are probed. |
| 275 | + * |
| 276 | + * @ep: endpoint of a rockchip vop |
| 277 | + * |
| 278 | + * returns true if subdriver, false if external bridge and -ENODEV |
| 279 | + * if remote port does not contain a device. |
| 280 | + */ |
| 281 | +int rockchip_drm_endpoint_is_subdriver(struct device_node *ep) |
| 282 | +{ |
| 283 | + struct device_node *node = of_graph_get_remote_port_parent(ep); |
| 284 | + struct platform_device *pdev; |
| 285 | + struct device_driver *drv; |
| 286 | + int i; |
| 287 | + |
| 288 | + if (!node) |
| 289 | + return -ENODEV; |
| 290 | + |
| 291 | + /* status disabled will prevent creation of platform-devices */ |
| 292 | + pdev = of_find_device_by_node(node); |
| 293 | + of_node_put(node); |
| 294 | + if (!pdev) |
| 295 | + return -ENODEV; |
| 296 | + |
| 297 | + /* |
| 298 | + * All rockchip subdrivers have probed at this point, so |
| 299 | + * any device not having a driver now is an external bridge. |
| 300 | + */ |
| 301 | + drv = pdev->dev.driver; |
| 302 | + if (!drv) { |
| 303 | + platform_device_put(pdev); |
| 304 | + return false; |
| 305 | + } |
| 306 | + |
| 307 | + for (i = 0; i < num_rockchip_sub_drivers; i++) { |
| 308 | + if (rockchip_sub_drivers[i] == to_platform_driver(drv)) { |
| 309 | + platform_device_put(pdev); |
| 310 | + return true; |
| 311 | + } |
| 312 | + } |
| 313 | + |
| 314 | + platform_device_put(pdev); |
| 315 | + return false; |
| 316 | +} |
| 317 | + |
270 | 318 | static int compare_dev(struct device *dev, void *data)
|
271 | 319 | {
|
272 | 320 | return dev == (struct device *)data;
|
|
0 commit comments