Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: of: Add drm_of_get_dsi_bus helper function

Add helper function to find DSI host for devices where DSI panel is not
a minor of a DSI bus (such as the Samsung AMS495QA01 panel or the
official Raspberry Pi touchscreen display).

Co-developed-by: Maya Matuszczyk <maccraft123mc@gmail.com>
Signed-off-by: Maya Matuszczyk <maccraft123mc@gmail.com>
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Reviewed-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230123154603.1315112-2-macroalpha82@gmail.com

authored by

Chris Morgan and committed by
Linus Walleij
19ff997f 413ebc48

+63
+51
drivers/gpu/drm/drm_of.c
··· 10 10 #include <drm/drm_crtc.h> 11 11 #include <drm/drm_device.h> 12 12 #include <drm/drm_encoder.h> 13 + #include <drm/drm_mipi_dsi.h> 13 14 #include <drm/drm_of.h> 14 15 #include <drm/drm_panel.h> 15 16 ··· 494 493 return ret; 495 494 } 496 495 EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep); 496 + 497 + #if IS_ENABLED(CONFIG_DRM_MIPI_DSI) 498 + 499 + /** 500 + * drm_of_get_dsi_bus - find the DSI bus for a given device 501 + * @dev: parent device of display (SPI, I2C) 502 + * 503 + * Gets parent DSI bus for a DSI device controlled through a bus other 504 + * than MIPI-DCS (SPI, I2C, etc.) using the Device Tree. 505 + * 506 + * Returns pointer to mipi_dsi_host if successful, -EINVAL if the 507 + * request is unsupported, -EPROBE_DEFER if the DSI host is found but 508 + * not available, or -ENODEV otherwise. 509 + */ 510 + struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev) 511 + { 512 + struct mipi_dsi_host *dsi_host; 513 + struct device_node *endpoint, *dsi_host_node; 514 + 515 + /* 516 + * Get first endpoint child from device. 517 + */ 518 + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 519 + if (!endpoint) 520 + return ERR_PTR(-ENODEV); 521 + 522 + /* 523 + * Follow the first endpoint to get the DSI host node and then 524 + * release the endpoint since we no longer need it. 525 + */ 526 + dsi_host_node = of_graph_get_remote_port_parent(endpoint); 527 + of_node_put(endpoint); 528 + if (!dsi_host_node) 529 + return ERR_PTR(-ENODEV); 530 + 531 + /* 532 + * Get the DSI host from the DSI host node. If we get an error 533 + * or the return is null assume we're not ready to probe just 534 + * yet. Release the DSI host node since we're done with it. 535 + */ 536 + dsi_host = of_find_mipi_dsi_host_by_node(dsi_host_node); 537 + of_node_put(dsi_host_node); 538 + if (IS_ERR_OR_NULL(dsi_host)) 539 + return ERR_PTR(-EPROBE_DEFER); 540 + 541 + return dsi_host; 542 + } 543 + EXPORT_SYMBOL_GPL(drm_of_get_dsi_bus); 544 + 545 + #endif /* CONFIG_DRM_MIPI_DSI */
+12
include/drm/drm_of.h
··· 15 15 struct drm_panel; 16 16 struct drm_bridge; 17 17 struct device_node; 18 + struct mipi_dsi_device_info; 19 + struct mipi_dsi_host; 18 20 19 21 /** 20 22 * enum drm_lvds_dual_link_pixels - Pixel order of an LVDS dual-link connection ··· 130 128 return -EINVAL; 131 129 } 132 130 #endif 131 + 132 + #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_MIPI_DSI) 133 + struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev); 134 + #else 135 + static inline struct 136 + mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev) 137 + { 138 + return ERR_PTR(-EINVAL); 139 + } 140 + #endif /* CONFIG_OF && CONFIG_DRM_MIPI_DSI */ 133 141 134 142 /* 135 143 * drm_of_panel_bridge_remove - remove panel bridge