Hi, Question for Heiko cs. See below. Let me know if there's a need for V6? On 3/19/19 12:44 PM, Heiko Stübner wrote: > Am Mittwoch, 6. März 2019, 23:41:10 CET schrieb Johan Jonker: >> +static int rk3066_hdmi_connector_get_modes(struct drm_connector *connector) >> +{ >> + struct rk3066_hdmi *hdmi = to_rk3066_hdmi(connector); >> + struct edid *edid; >> + int ret = 0; >> + Is this OK or drop it? hdmi->hdmi_data.sink_is_hdmi = false; >> + if (!hdmi->ddc) >> + return 0; >> + >> + edid = drm_get_edid(connector, hdmi->ddc); >> + if (edid) { >> + hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid); >> + drm_connector_update_edid_property(connector, edid); >> + ret = drm_add_edid_modes(connector, edid); >> + kfree(edid); >> + } >> + >> + >> + return ret; >> +} >> +static int rk3066_hdmi_bind(struct device *dev, struct device *master, >> + void *data) >> +{ >> + struct platform_device *pdev = to_platform_device(dev); >> + struct drm_device *drm = data; >> + struct rk3066_hdmi *hdmi; >> + struct resource *iores; >> + int irq; >> + int ret; >> + >> + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); >> + if (!hdmi) >> + return -ENOMEM; >> + >> + hdmi->dev = dev; >> + hdmi->drm_dev = drm; >> + >> + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> + if (!iores) >> + return -ENXIO; >> + >> + hdmi->regs = devm_ioremap_resource(dev, iores); >> + if (IS_ERR(hdmi->regs)) >> + return PTR_ERR(hdmi->regs); >> + >> + irq = platform_get_irq(pdev, 0); >> + if (irq < 0) >> + return irq; >> + >> + hdmi->hclk = devm_clk_get(dev, "hclk"); >> + if (IS_ERR(hdmi->hclk)) { >> + dev_err(dev, "unable to get HDMI hclk clock\n"); >> + return PTR_ERR(hdmi->hclk); >> + } >> + >> + ret = clk_prepare_enable(hdmi->hclk); >> + if (ret) { >> + dev_err(dev, "cannot enable HDMI hclk clock: %d\n", ret); >> + return ret; >> + } >> + >> + hdmi->grf = syscon_regmap_lookup_by_phandle(dev->of_node, >> + "rockchip,grf"); >> + if (IS_ERR(hdmi->grf)) { >> + dev_err(dev, "unable to get rockchip,grf\n"); >> + ret = PTR_ERR(hdmi->grf); >> + goto err_disable_hclk; >> + } >> + >> + /* internal hclk = hdmi_hclk / 25 */ >> + hdmi_writeb(hdmi, HDMI_INTERNAL_CLK_DIVIDER, 25); >> + >> + hdmi->ddc = rk3066_hdmi_i2c_adapter(hdmi); >> + if (IS_ERR(hdmi->ddc)) { >> + ret = PTR_ERR(hdmi->ddc); >> + hdmi->ddc = NULL; >> + goto err_disable_hclk; >> + } >> + >> + rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_B); >> + usleep_range(999, 1000); >> + hdmi_writeb(hdmi, HDMI_INTR_MASK1, HDMI_INTR_HOTPLUG); >> + hdmi_writeb(hdmi, HDMI_INTR_MASK2, 0); >> + hdmi_writeb(hdmi, HDMI_INTR_MASK3, 0); >> + hdmi_writeb(hdmi, HDMI_INTR_MASK4, 0); >> + rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_A); >> + The function rk3066_hdmi_register() inits an encoder and connector. >> + ret = rk3066_hdmi_register(drm, hdmi); >> + if (ret) >> + goto err_disable_hclk; > > goto err_disable_i2c; > > So that the i2c-adapter also gets disabled on error. > >> + dev_set_drvdata(dev, hdmi); >> + >> + ret = devm_request_threaded_irq(dev, irq, rk3066_hdmi_hardirq, >> + rk3066_hdmi_irq, IRQF_SHARED, >> + dev_name(dev), hdmi); >> + if (ret) { >> + dev_err(dev, "failed to request hdmi irq: %d\n", ret); >> + goto err_disable_hclk; > If an error happens here the encoder and connector also have to be removed like in the inno driver. Is that correct? Change this to: goto err_cleanup_hdmi; > goto err_disable_i2c; > >> + } >> + >> + return 0; >> + > What goto name would you like to have here? err_cleanup_hdmi: hdmi->connector.funcs->destroy(&hdmi->connector); hdmi->encoder.funcs->destroy(&hdmi->encoder); > err_disable_i2c: > i2c_put_adapter(hdmi->ddc); > >> +err_disable_hclk: >> + clk_disable_unprepare(hdmi->hclk); >> + >> + return ret; >> +} >> +