diff options
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r-- | drivers/gpu/drm/msm/hdmi/hdmi.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/hdmi/hdmi.h | 2 |
2 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 0fe5411c5c3e..043a70c17f98 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -81,12 +81,46 @@ static void hdmi_destroy(struct hdmi *hdmi) if (phy) phy->funcs->destroy(phy); + if (hdmi->phy_dev) { + put_device(hdmi->phy_dev); + hdmi->phy = NULL; + hdmi->phy_dev = NULL; + } + if (hdmi->i2c) hdmi_i2c_destroy(hdmi->i2c); platform_set_drvdata(hdmi->pdev, NULL); } +static int hdmi_get_phy(struct hdmi *hdmi) +{ + struct platform_device *pdev = hdmi->pdev; + struct platform_device *phy_pdev; + struct device_node *phy_node; + + phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); + if (!phy_node) { + dev_err(&pdev->dev, "cannot find phy device\n"); + return -ENXIO; + } + + phy_pdev = of_find_device_by_node(phy_node); + if (phy_pdev) + hdmi->phy = platform_get_drvdata(phy_pdev); + + of_node_put(phy_node); + + if (!phy_pdev || !hdmi->phy) { + dev_err(&pdev->dev, "phy driver is not ready\n"); + return -EPROBE_DEFER; + } + + hdmi->phy_dev = get_device(&phy_pdev->dev); + + return 0; +} + /* construct hdmi at bind/probe time, grab all the resources. If * we are to EPROBE_DEFER we want to do it here, rather than later * at modeset_init() time @@ -230,6 +264,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) goto fail; } + ret = hdmi_get_phy(hdmi); + if (ret) { + dev_err(&pdev->dev, "failed to get phy\n"); + goto fail; + } + hdmi->hdcp_ctrl = hdmi_hdcp_init(hdmi); if (IS_ERR(hdmi->hdcp_ctrl)) { dev_warn(&pdev->dev, "failed to init hdcp: disabled\n"); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 1beace8bcb4b..f8122cf099b1 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -70,6 +70,8 @@ struct hdmi { struct clk **pwr_clks; struct hdmi_phy *phy; + struct device *phy_dev; + struct i2c_adapter *i2c; struct drm_connector *connector; struct drm_bridge *bridge; |