mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
drm/rockchip: dw_hdmi: avoid direct dereference of phy->dev.of_node
The dw_hdmi-rockchip driver validates pixel clock rates against the HDMI PHY's internal clock provider on certain SoCs like RK3328. This is currently achieved by dereferencing hdmi->phy->dev.of_node to obtain the provider node, which violates the Generic PHY API's encapsulation (the goal is for struct phy to be an opaque pointer with a hidden definition, to be interacted with only using API functions or NULL pointer checks, for the case where optional variants of phy_get() did not find a PHY). Refactor dw_hdmi_rockchip_bind() to perform a manual phandle lookup on the "hdmi" PHY index within the controller's DT node. This provides a parallel path to the clock provider's OF node without relying on the internal structure of the struct phy handle. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patch.msgid.link/20260505100523.1922388-16-vladimir.oltean@nxp.com
This commit is contained in:
parent
a48bbcc7ac
commit
9392e7340b
|
|
@ -537,21 +537,22 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|||
void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct device_node *np = dev_of_node(dev);
|
||||
struct dw_hdmi_plat_data *plat_data;
|
||||
const struct of_device_id *match;
|
||||
struct drm_device *drm = data;
|
||||
struct drm_encoder *encoder;
|
||||
struct rockchip_hdmi *hdmi;
|
||||
int ret;
|
||||
int ret, index;
|
||||
|
||||
if (!pdev->dev.of_node)
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
|
||||
if (!hdmi)
|
||||
return -ENOMEM;
|
||||
|
||||
match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
|
||||
match = of_match_node(dw_hdmi_rockchip_dt_ids, np);
|
||||
plat_data = devm_kmemdup(&pdev->dev, match->data,
|
||||
sizeof(*plat_data), GFP_KERNEL);
|
||||
if (!plat_data)
|
||||
|
|
@ -564,9 +565,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|||
plat_data->priv_data = hdmi;
|
||||
encoder = &hdmi->encoder.encoder;
|
||||
|
||||
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
|
||||
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, np);
|
||||
rockchip_drm_encoder_set_crtc_endpoint_id(&hdmi->encoder,
|
||||
dev->of_node, 0, 0);
|
||||
np, 0, 0);
|
||||
|
||||
/*
|
||||
* If we failed to find the CRTC(s) which this encoder is
|
||||
|
|
@ -588,13 +589,17 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|||
return dev_err_probe(hdmi->dev, ret, "failed to get phy\n");
|
||||
}
|
||||
|
||||
if (hdmi->phy) {
|
||||
index = of_property_match_string(np, "phy-names", "hdmi");
|
||||
if (index >= 0) {
|
||||
struct of_phandle_args clkspec;
|
||||
|
||||
clkspec.np = hdmi->phy->dev.of_node;
|
||||
hdmi->hdmiphy_clk = of_clk_get_from_provider(&clkspec);
|
||||
if (IS_ERR(hdmi->hdmiphy_clk))
|
||||
hdmi->hdmiphy_clk = NULL;
|
||||
if (!of_parse_phandle_with_args(np, "phys", "#phy-cells", index,
|
||||
&clkspec)) {
|
||||
hdmi->hdmiphy_clk = of_clk_get_from_provider(&clkspec);
|
||||
of_node_put(clkspec.np);
|
||||
if (IS_ERR(hdmi->hdmiphy_clk))
|
||||
hdmi->hdmiphy_clk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (hdmi->chip_data == &rk3568_chip_data) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user