diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 40c13569600760d5a7e196d83a47e3b16f45d020..54d49ddb9b81c9ad8680d7a111995bc3190f0b5e 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -327,7 +327,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name, curr_dss_hwmod[0].id, curr_dss_hwmod[0].oh_name, - NULL, 0, + board_data, sizeof(*board_data), NULL); if (IS_ERR(dss_pdev)) { @@ -341,7 +341,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name, curr_dss_hwmod[i].id, curr_dss_hwmod[i].oh_name, - NULL, 0, + board_data, sizeof(*board_data), dss_pdev); if (IS_ERR(pdev)) { @@ -354,15 +354,16 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) /* Create devices for DPI and SDI */ - pdev = create_simple_dss_pdev("omapdss_dpi", -1, NULL, 0, dss_pdev); + pdev = create_simple_dss_pdev("omapdss_dpi", -1, + board_data, sizeof(*board_data), dss_pdev); if (IS_ERR(pdev)) { pr_err("Could not build platform_device for omapdss_dpi\n"); return PTR_ERR(pdev); } if (cpu_is_omap34xx()) { - pdev = create_simple_dss_pdev("omapdss_sdi", -1, NULL, 0, - dss_pdev); + pdev = create_simple_dss_pdev("omapdss_sdi", -1, + board_data, sizeof(*board_data), dss_pdev); if (IS_ERR(pdev)) { pr_err("Could not build platform_device for omapdss_sdi\n"); return PTR_ERR(pdev); diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index c3566a05d168c2a82aa37830375420845acdd846..72ded9cd2cb0fa0e0540eeb19721ae8a602d72ef 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -56,9 +56,6 @@ bool dss_debug; module_param_named(debug, dss_debug, bool, 0644); #endif -static int omap_dss_register_device(struct omap_dss_device *); -static void omap_dss_unregister_device(struct omap_dss_device *); - /* REGULATORS */ struct regulator *dss_get_vdds_dsi(void) @@ -209,7 +206,6 @@ static int __init omap_dss_probe(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; int r; - int i; core.pdev = pdev; @@ -229,25 +225,8 @@ static int __init omap_dss_probe(struct platform_device *pdev) else if (pdata->default_device) core.default_display_name = pdata->default_device->name; - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - r = omap_dss_register_device(dssdev); - if (r) { - DSSERR("device %d %s register failed %d\n", i, - dssdev->name ?: "unnamed", r); - - while (--i >= 0) - omap_dss_unregister_device(pdata->devices[i]); - - goto err_register; - } - } - return 0; -err_register: - dss_uninitialize_debugfs(); err_debugfs: return r; @@ -255,17 +234,11 @@ static int __init omap_dss_probe(struct platform_device *pdev) static int omap_dss_remove(struct platform_device *pdev) { - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - int i; - dss_uninitialize_debugfs(); dss_uninit_overlays(pdev); dss_uninit_overlay_managers(pdev); - for (i = 0; i < pdata->num_devices; ++i) - omap_dss_unregister_device(pdata->devices[i]); - return 0; } @@ -467,25 +440,36 @@ static void omap_dss_dev_release(struct device *dev) reset_device(dev, 0); } -static int omap_dss_register_device(struct omap_dss_device *dssdev) +int omap_dss_register_device(struct omap_dss_device *dssdev, + struct device *parent, int disp_num) { - static int dev_num; - WARN_ON(!dssdev->driver_name); reset_device(&dssdev->dev, 1); dssdev->dev.bus = &dss_bus_type; - dssdev->dev.parent = &dss_bus; + dssdev->dev.parent = parent; dssdev->dev.release = omap_dss_dev_release; - dev_set_name(&dssdev->dev, "display%d", dev_num++); + dev_set_name(&dssdev->dev, "display%d", disp_num); return device_register(&dssdev->dev); } -static void omap_dss_unregister_device(struct omap_dss_device *dssdev) +void omap_dss_unregister_device(struct omap_dss_device *dssdev) { device_unregister(&dssdev->dev); } +static int dss_unregister_dss_dev(struct device *dev, void *data) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + omap_dss_unregister_device(dssdev); + return 0; +} + +void omap_dss_unregister_child_devices(struct device *parent) +{ + device_for_each_child(parent, NULL, dss_unregister_dss_dev); +} + /* BUS */ static int __init omap_dss_bus_register(void) { diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 6061379559c31be332e43a11f93d0d13292a9d8c..35eb29706934825ad7f5abc7bb58bb3cdd9fa8d1 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -367,11 +367,28 @@ int dpi_init_display(struct omap_dss_device *dssdev) static int __init omap_dpi_probe(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; + int i, r; + + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) + continue; + + r = omap_dss_register_device(dssdev, &pdev->dev, i); + if (r) + DSSERR("device %s register failed: %d\n", + dssdev->name, r); + } + return 0; } static int __exit omap_dpi_remove(struct platform_device *pdev) { + omap_dss_unregister_child_devices(&pdev->dev); + return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index ddea71ea2a0f210b52441bb0267e3d451fefd631..78b962308a02f79d26d0f17ade978ad584d3b79b 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4614,6 +4614,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev) int r, i, dsi_module = dsi_get_dsidev_id(dsidev); struct resource *dsi_mem; struct dsi_data *dsi; + struct omap_dss_board_info *pdata = dsidev->dev.platform_data; dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL); if (!dsi) @@ -4700,6 +4701,21 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev) else dsi->num_lanes_supported = 3; + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) + continue; + + if (dssdev->phy.dsi.module != dsi_module) + continue; + + r = omap_dss_register_device(dssdev, &dsidev->dev, i); + if (r) + DSSERR("device %s register failed: %d\n", + dssdev->name, r); + } + dsi_runtime_put(dsidev); if (dsi_module == 0) @@ -4727,6 +4743,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) WARN_ON(dsi->scp_clk_refcount > 0); + omap_dss_unregister_child_devices(&dsidev->dev); + pm_runtime_disable(&dsidev->dev); dsi_put_clocks(dsidev); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 7bc24ed8de8ea89356ae629532012468ec2ac9cc..972b22d27972e5e100372c6e6f56d4139c039967 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -165,6 +165,11 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); int dss_set_min_bus_tput(struct device *dev, unsigned long tput); int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); +int omap_dss_register_device(struct omap_dss_device *dssdev, + struct device *parent, int disp_num); +void omap_dss_unregister_device(struct omap_dss_device *dssdev); +void omap_dss_unregister_child_devices(struct device *parent); + /* apply */ void dss_apply_init(void); int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr); diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 09ede7fa19832bcff1de88c86d29b139277eb43d..faa91441a6b04e6b516a8b858d0b46c8ea04b16b 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -774,8 +774,9 @@ static void hdmi_put_clocks(void) /* HDMI HW IP initialisation */ static int __init omapdss_hdmihw_probe(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; struct resource *hdmi_mem; - int r; + int r, i; hdmi.pdev = pdev; @@ -812,6 +813,18 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev) dss_debugfs_create_file("hdmi", hdmi_dump_regs); + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) + continue; + + r = omap_dss_register_device(dssdev, &pdev->dev, i); + if (r) + DSSERR("device %s register failed: %d\n", + dssdev->name, r); + } + #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) @@ -828,6 +841,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev) static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) { + omap_dss_unregister_child_devices(&pdev->dev); + hdmi_panel_exit(); #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 58da146254ee924cf5f3979431b64adf2ec437b1..4c0a6c97d62bab7ff134c33db7b0438a413d67da 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -930,10 +930,11 @@ int rfbi_init_display(struct omap_dss_device *dssdev) /* RFBI HW IP initialisation */ static int __init omap_rfbihw_probe(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; u32 rev; struct resource *rfbi_mem; struct clk *clk; - int r; + int r, i; rfbi.pdev = pdev; @@ -978,6 +979,18 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev) dss_debugfs_create_file("rfbi", rfbi_dump_regs); + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) + continue; + + r = omap_dss_register_device(dssdev, &pdev->dev, i); + if (r) + DSSERR("device %s register failed: %d\n", + dssdev->name, r); + } + return 0; err_runtime_get: @@ -987,6 +1000,7 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev) static int __exit omap_rfbihw_remove(struct platform_device *pdev) { + omap_dss_unregister_child_devices(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; } diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 661b594225a21b370900865726ee817f60514182..3be8134ec2d96f86ce408b9d0075290910d4482f 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -178,11 +178,28 @@ int sdi_init_display(struct omap_dss_device *dssdev) static int __init omap_sdi_probe(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; + int i, r; + + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) + continue; + + r = omap_dss_register_device(dssdev, &pdev->dev, i); + if (r) + DSSERR("device %s register failed: %d\n", + dssdev->name, r); + } + return 0; } static int __exit omap_sdi_remove(struct platform_device *pdev) { + omap_dss_unregister_child_devices(&pdev->dev); + return 0; } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 7322ac8a3bcc1792422baf1364f877c4e3f45fe8..c194dfab63568d0f04c2963573d26017f3c0120f 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -832,9 +832,10 @@ static void venc_put_clocks(void) /* VENC HW IP initialisation */ static int __init omap_venchw_probe(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; u8 rev_id; struct resource *venc_mem; - int r; + int r, i; venc.pdev = pdev; @@ -876,6 +877,18 @@ static int __init omap_venchw_probe(struct platform_device *pdev) dss_debugfs_create_file("venc", venc_dump_regs); + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) + continue; + + r = omap_dss_register_device(dssdev, &pdev->dev, i); + if (r) + DSSERR("device %s register failed: %d\n", + dssdev->name, r); + } + return 0; err_reg_panel_driver: @@ -887,10 +900,13 @@ static int __init omap_venchw_probe(struct platform_device *pdev) static int __exit omap_venchw_remove(struct platform_device *pdev) { + omap_dss_unregister_child_devices(&pdev->dev); + if (venc.vdda_dac_reg != NULL) { regulator_put(venc.vdda_dac_reg); venc.vdda_dac_reg = NULL; } + omap_dss_unregister_driver(&venc_driver); pm_runtime_disable(&pdev->dev);