From 3f8ac6983f0e56231374fedc9fc50c81db465540 Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Wed, 14 Apr 2021 17:44:01 -0700 Subject: [PATCH] disp: msm: dsi: add check for DSI resources during display probe The change adds a check for DSI controller and PHY resources during the DSI display probe. The validation now only checks for the availabilty of the resources without increasing the refcount of the controller or PHY till an exact match is found after the device tree is parsed. Change-Id: I96a5022a8ab5f55271e0df36675037b597e1ec85 Signed-off-by: Satya Rama Aditya Pinapala --- msm/dsi/dsi_ctrl.c | 31 +++++++++++++++++++++++++ msm/dsi/dsi_ctrl.h | 10 ++++++++ msm/dsi/dsi_display.c | 53 +++++++++++++------------------------------ msm/dsi/dsi_phy.c | 32 ++++++++++++++++++++++++++ msm/dsi/dsi_phy.h | 10 ++++++++ 5 files changed, 99 insertions(+), 37 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 06859948ff..d552a53062 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -2204,6 +2204,37 @@ int dsi_ctrl_get_io_resources(struct msm_io_res *io_res) return rc; } +/** + * dsi_ctrl_check_resource() - check if DSI controller is probed + * @of_node: of_node of the DSI controller. + * + * Checks if the DSI controller has been probed and is available. + * + * Return: status of DSI controller + */ +bool dsi_ctrl_check_resource(struct device_node *of_node) +{ + struct list_head *pos, *tmp; + struct dsi_ctrl *ctrl = NULL; + + mutex_lock(&dsi_ctrl_list_lock); + list_for_each_safe(pos, tmp, &dsi_ctrl_list) { + struct dsi_ctrl_list_item *n; + + n = list_entry(pos, struct dsi_ctrl_list_item, list); + if (!n->ctrl || !n->ctrl->pdev) + break; + + if (n->ctrl->pdev->dev.of_node == of_node) { + ctrl = n->ctrl; + break; + } + } + mutex_unlock(&dsi_ctrl_list_lock); + + return ctrl ? true : false; +} + /** * dsi_ctrl_get() - get a dsi_ctrl handle from an of_node * @of_node: of_node of the DSI controller. diff --git a/msm/dsi/dsi_ctrl.h b/msm/dsi/dsi_ctrl.h index 52a99e7a55..d251d40846 100644 --- a/msm/dsi/dsi_ctrl.h +++ b/msm/dsi/dsi_ctrl.h @@ -319,6 +319,16 @@ struct dsi_ctrl { u32 cmd_success_frame; }; +/** + * dsi_ctrl_check_resource() - check if DSI controller is probed + * @of_node: of_node of the DSI controller. + * + * Checks if the DSI controller has been probed and is available. + * + * Return: status of DSI controller + */ +bool dsi_ctrl_check_resource(struct device_node *of_node); + /** * dsi_ctrl_get() - get a dsi_ctrl handle from an of_node * @of_node: of_node of the DSI controller. diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 299632cefa..d737b6e6dd 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -4008,35 +4008,27 @@ end: return rc; } -static int dsi_display_validate_res(struct dsi_display *display) +static bool dsi_display_validate_res(struct dsi_display *display) { struct device_node *of_node = display->pdev->dev.of_node; struct of_phandle_iterator it; - struct dsi_ctrl *dsi_ctrl; bool ctrl_avail = false; + bool phy_avail = false; + /* + * At least if one of the controller or PHY is present or has been probed, the + * dsi_display_dev_probe can pass this check. Exact ctrl and PHY match will be + * done after the DT is parsed. + */ of_phandle_iterator_init(&it, of_node, "qcom,dsi-ctrl", NULL, 0); - while (of_phandle_iterator_next(&it) == 0) { - dsi_ctrl = dsi_ctrl_get(it.node); - if (IS_ERR(dsi_ctrl)) { - int rc = PTR_ERR(dsi_ctrl); + while (of_phandle_iterator_next(&it) == 0) + ctrl_avail |= dsi_ctrl_check_resource(it.node); - if (rc == -EPROBE_DEFER) - return rc; - /* - * With dual display mode, the seconday display needs at least - * one ctrl to proceed through the probe. Exact ctrl match - * will be done after parsing the DT or firmware data. - */ - if (rc == -EBUSY) - ctrl_avail |= false; - } else { - dsi_ctrl_put(dsi_ctrl); - ctrl_avail = true; - } - } + of_phandle_iterator_init(&it, of_node, "qcom,dsi-phy", NULL, 0); + while (of_phandle_iterator_next(&it) == 0) + phy_avail |= dsi_phy_check_resource(it.node); - return ctrl_avail ? 0 : -EBUSY; + return (ctrl_avail & phy_avail); } static int dsi_display_get_phandle_count(struct dsi_display *display, @@ -5902,22 +5894,9 @@ int dsi_display_dev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, display); - rc = dsi_display_validate_res(display); - if (rc) { - /* - * Display's bailing out without probe deferral must register its - * components to complete MDSS binding. Scheduled to be fixed in the future - * with dynamic component binding. - */ - if (rc == -EBUSY) { - int ret = component_add(&pdev->dev, - &dsi_display_comp_ops); - if (ret) - DSI_ERR( - "component add failed for display type: %s, rc=%d\n" - , display->type, ret); - } - + if (!dsi_display_validate_res(display)) { + rc = -EPROBE_DEFER; + DSI_ERR("resources required for display probe not present: rc=%d\n", rc); goto end; } diff --git a/msm/dsi/dsi_phy.c b/msm/dsi/dsi_phy.c index 58d35f04f8..a7a5ec4560 100644 --- a/msm/dsi/dsi_phy.c +++ b/msm/dsi/dsi_phy.c @@ -579,6 +579,38 @@ static void dsi_phy_disable_hw(struct msm_dsi_phy *phy) phy->hw.ops.regulator_disable(&phy->hw); } +/** + * dsi_phy_check_resource() - check if DSI PHY is probed + * @of_node: of_node of the DSI PHY. + * + * Checks if the DSI PHY has been probed and is available. + * + * Return: status of DSI PHY + */ +bool dsi_phy_check_resource(struct device_node *of_node) +{ + struct list_head *pos, *tmp; + struct msm_dsi_phy *phy = NULL; + + mutex_lock(&dsi_phy_list_lock); + list_for_each_safe(pos, tmp, &dsi_phy_list) { + struct dsi_phy_list_item *n; + + n = list_entry(pos, struct dsi_phy_list_item, list); + + if (!n->phy || !n->phy->pdev) + break; + + if (n->phy->pdev->dev.of_node == of_node) { + phy = n->phy; + break; + } + } + mutex_unlock(&dsi_phy_list_lock); + + return phy ? true : false; +} + /** * dsi_phy_get() - get a dsi phy handle from device node * @of_node: device node for dsi phy controller diff --git a/msm/dsi/dsi_phy.h b/msm/dsi/dsi_phy.h index 590a119589..1e291033c3 100644 --- a/msm/dsi/dsi_phy.h +++ b/msm/dsi/dsi_phy.h @@ -106,6 +106,16 @@ struct msm_dsi_phy { bool dfps_trigger_mdpintf_flush; }; +/** + * dsi_phy_check_resource() - check if DSI PHY is probed + * @of_node: of_node of the DSI PHY. + * + * Checks if the DSI PHY has been probed and is available. + * + * Return: status of DSI PHY + */ +bool dsi_phy_check_resource(struct device_node *of_node); + /** * dsi_phy_get() - get a dsi phy handle from device node * @of_node: device node for dsi phy controller