From f99467b3549be1c87757e564d18eea6e541060c4 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Jun 2015 12:35:42 +0300 Subject: [PATCH 1/7] OMAPDSS: move 'dss_initialized' to dss driver We have a flag, 'dss_initialized', which tells omapfb and omapdrm if omapdss is available. At the moment it can be set even if the dss submodules are not all ready, in case something gets deferred. Move the flag to dss_core driver so that it'll signal the availability of the dss drivers move accurately. For now, it'll signal that dss_core is ready, which is not quite correct but still better than previously. The following patches will add component system to omapdss, and after those patches 'dss_initialized' will signal that all the submodules are ready. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart --- drivers/video/fbdev/omap2/dss/core.c | 10 ---------- drivers/video/fbdev/omap2/dss/dss.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c index 16751755d433..57b6a5296c87 100644 --- a/drivers/video/fbdev/omap2/dss/core.c +++ b/drivers/video/fbdev/omap2/dss/core.c @@ -50,8 +50,6 @@ static char *def_disp_name; module_param_named(def_disp, def_disp_name, charp, 0); MODULE_PARM_DESC(def_disp, "default display name"); -static bool dss_initialized; - const char *omapdss_get_default_display_name(void) { return core.default_display_name; @@ -65,12 +63,6 @@ enum omapdss_version omapdss_get_version(void) } EXPORT_SYMBOL(omapdss_get_version); -bool omapdss_is_initialized(void) -{ - return dss_initialized; -} -EXPORT_SYMBOL(omapdss_is_initialized); - struct platform_device *dss_get_core_pdev(void) { return core.pdev; @@ -333,8 +325,6 @@ static int __init omap_dss_init(void) dss_output_drv_loaded[i] = true; } - dss_initialized = true; - return 0; err_dispc: diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 7f978b6a34e8..35601ab232e3 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -111,6 +111,14 @@ static const char * const dss_generic_clk_source_names[] = { [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI", }; +static bool dss_initialized; + +bool omapdss_is_initialized(void) +{ + return dss_initialized; +} +EXPORT_SYMBOL(omapdss_is_initialized); + static inline void dss_write_reg(const struct dss_reg idx, u32 val) { __raw_writel(val, dss.base + idx.idx); @@ -1141,6 +1149,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) pm_set_vt_switch(0); + dss_initialized = true; + return 0; err_pll_init: @@ -1158,6 +1168,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) static int __exit omap_dsshw_remove(struct platform_device *pdev) { + dss_initialized = false; + if (dss.video1_pll) dss_video_pll_uninit(dss.video1_pll); From 7e328f5adcabb0b08e713f202b4a0fc388b2319e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Jun 2015 13:02:52 +0300 Subject: [PATCH 2/7] OMAPDSS: refactor dss probe function Refactor dss probe function by extracting the setup for video plls into a separate function. The call to this function is also moved to a slightly earlier phase, so that in error case we can bail out more easily. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart --- drivers/video/fbdev/omap2/dss/dss.c | 147 +++++++++++++++------------- 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 35601ab232e3..1ce47441efe3 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -1026,69 +1026,16 @@ static void __exit dss_uninit_ports(struct platform_device *pdev) } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); } -/* DSS HW IP initialisation */ -static int __init omap_dsshw_probe(struct platform_device *pdev) +static int dss_video_pll_probe(struct platform_device *pdev) { - struct resource *dss_mem; struct device_node *np = pdev->dev.of_node; - u32 rev; - int r; struct regulator *pll_regulator; + int r; - dss.pdev = pdev; + if (!np) + return 0; - r = dss_init_features(dss.pdev); - if (r) - return r; - - dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); - if (!dss_mem) { - DSSERR("can't get IORESOURCE_MEM DSS\n"); - return -EINVAL; - } - - dss.base = devm_ioremap(&pdev->dev, dss_mem->start, - resource_size(dss_mem)); - if (!dss.base) { - DSSERR("can't ioremap DSS\n"); - return -ENOMEM; - } - - r = dss_get_clocks(); - if (r) - return r; - - r = dss_setup_default_clock(); - if (r) - goto err_setup_clocks; - - pm_runtime_enable(&pdev->dev); - - r = dss_runtime_get(); - if (r) - goto err_runtime_get; - - dss.dss_clk_rate = clk_get_rate(dss.dss_clk); - - /* Select DPLL */ - REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); - - dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); - -#ifdef CONFIG_OMAP2_DSS_VENC - REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ - REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ - REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ -#endif - dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; - dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; - dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK; - dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; - dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; - - dss_init_ports(pdev); - - if (np && of_property_read_bool(np, "syscon-pll-ctrl")) { + if (of_property_read_bool(np, "syscon-pll-ctrl")) { dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np, "syscon-pll-ctrl"); if (IS_ERR(dss.syscon_pll_ctrl)) { @@ -1125,20 +1072,85 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) if (of_property_match_string(np, "reg-names", "pll1") >= 0) { dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator); - if (IS_ERR(dss.video1_pll)) { - r = PTR_ERR(dss.video1_pll); - goto err_pll_init; - } + if (IS_ERR(dss.video1_pll)) + return PTR_ERR(dss.video1_pll); } if (of_property_match_string(np, "reg-names", "pll2") >= 0) { dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator); if (IS_ERR(dss.video2_pll)) { - r = PTR_ERR(dss.video2_pll); - goto err_pll_init; + dss_video_pll_uninit(dss.video1_pll); + return PTR_ERR(dss.video2_pll); } } + return 0; +} + +/* DSS HW IP initialisation */ +static int __init omap_dsshw_probe(struct platform_device *pdev) +{ + struct resource *dss_mem; + u32 rev; + int r; + + dss.pdev = pdev; + + r = dss_init_features(dss.pdev); + if (r) + return r; + + dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); + if (!dss_mem) { + DSSERR("can't get IORESOURCE_MEM DSS\n"); + return -EINVAL; + } + + dss.base = devm_ioremap(&pdev->dev, dss_mem->start, + resource_size(dss_mem)); + if (!dss.base) { + DSSERR("can't ioremap DSS\n"); + return -ENOMEM; + } + + r = dss_get_clocks(); + if (r) + return r; + + r = dss_setup_default_clock(); + if (r) + goto err_setup_clocks; + + r = dss_video_pll_probe(pdev); + if (r) + goto err_pll_init; + + pm_runtime_enable(&pdev->dev); + + r = dss_runtime_get(); + if (r) + goto err_runtime_get; + + dss.dss_clk_rate = clk_get_rate(dss.dss_clk); + + /* Select DPLL */ + REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); + + dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); + +#ifdef CONFIG_OMAP2_DSS_VENC + REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ + REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ + REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ +#endif + dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; + dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; + dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK; + dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; + dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; + + dss_init_ports(pdev); + rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); @@ -1153,14 +1165,15 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) return 0; -err_pll_init: +err_runtime_get: + pm_runtime_disable(&pdev->dev); + if (dss.video1_pll) dss_video_pll_uninit(dss.video1_pll); if (dss.video2_pll) dss_video_pll_uninit(dss.video2_pll); -err_runtime_get: - pm_runtime_disable(&pdev->dev); +err_pll_init: err_setup_clocks: dss_put_clocks(); return r; From f5a1a1f8e41e93584935d4ae62a84280dcdbe778 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Jun 2015 13:06:37 +0300 Subject: [PATCH 3/7] OMAPDSS: fix dss_init_ports error handling The return value of dss_init_ports() is not handled at all, causing crashes later if the call failed. This patch adds the error handling, and we also move the call to a slightly earlier place to make bailing out easier. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart --- drivers/video/fbdev/omap2/dss/dss.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 1ce47441efe3..28e6ff053b47 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -1125,6 +1125,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) if (r) goto err_pll_init; + r = dss_init_ports(pdev); + if (r) + goto err_init_ports; + pm_runtime_enable(&pdev->dev); r = dss_runtime_get(); @@ -1149,8 +1153,6 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; - dss_init_ports(pdev); - rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); @@ -1167,7 +1169,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) err_runtime_get: pm_runtime_disable(&pdev->dev); - + dss_uninit_ports(pdev); +err_init_ports: if (dss.video1_pll) dss_video_pll_uninit(dss.video1_pll); From ede9269572da9206249f02ebe031ded025b84fd3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Jun 2015 14:12:16 +0300 Subject: [PATCH 4/7] OMAPDSS: remove uses of __init/__exit The following patches will add component handling to omapdss, improving the handling of deferred probing. However, at the moment we're using quite a lot of __inits and __exits in the driver, which prevent normal dynamic probing and removal. This patch removes most of the uses of __init and __exit, so that we can register drivers after module init, and so that we can unregister drivers even if the module is built-in. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart --- drivers/video/fbdev/omap2/dss/dispc.c | 20 ++++++++--------- drivers/video/fbdev/omap2/dss/dpi.c | 14 ++++++------ drivers/video/fbdev/omap2/dss/dsi.c | 6 ++--- drivers/video/fbdev/omap2/dss/dss.c | 26 +++++++++++----------- drivers/video/fbdev/omap2/dss/dss.h | 32 +++++++++++++-------------- drivers/video/fbdev/omap2/dss/hdmi4.c | 6 ++--- drivers/video/fbdev/omap2/dss/hdmi5.c | 6 ++--- drivers/video/fbdev/omap2/dss/rfbi.c | 8 +++---- drivers/video/fbdev/omap2/dss/sdi.c | 12 +++++----- drivers/video/fbdev/omap2/dss/venc.c | 8 +++---- 10 files changed, 69 insertions(+), 69 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index f4fc77d9d3bf..e3417af63451 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -3692,7 +3692,7 @@ static void _omap_dispc_initial_config(void) dispc_init_mflag(); } -static const struct dispc_features omap24xx_dispc_feats __initconst = { +static const struct dispc_features omap24xx_dispc_feats = { .sw_start = 5, .fp_start = 15, .bp_start = 27, @@ -3711,7 +3711,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = { .set_max_preload = false, }; -static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { +static const struct dispc_features omap34xx_rev1_0_dispc_feats = { .sw_start = 5, .fp_start = 15, .bp_start = 27, @@ -3731,7 +3731,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { .set_max_preload = false, }; -static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { +static const struct dispc_features omap34xx_rev3_0_dispc_feats = { .sw_start = 7, .fp_start = 19, .bp_start = 31, @@ -3751,7 +3751,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { .set_max_preload = false, }; -static const struct dispc_features omap44xx_dispc_feats __initconst = { +static const struct dispc_features omap44xx_dispc_feats = { .sw_start = 7, .fp_start = 19, .bp_start = 31, @@ -3771,7 +3771,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = { .set_max_preload = true, }; -static const struct dispc_features omap54xx_dispc_feats __initconst = { +static const struct dispc_features omap54xx_dispc_feats = { .sw_start = 7, .fp_start = 19, .bp_start = 31, @@ -3792,7 +3792,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = { .set_max_preload = true, }; -static int __init dispc_init_features(struct platform_device *pdev) +static int dispc_init_features(struct platform_device *pdev) { const struct dispc_features *src; struct dispc_features *dst; @@ -3882,7 +3882,7 @@ void dispc_free_irq(void *dev_id) EXPORT_SYMBOL(dispc_free_irq); /* DISPC HW IP initialisation */ -static int __init omap_dispchw_probe(struct platform_device *pdev) +static int omap_dispchw_probe(struct platform_device *pdev) { u32 rev; int r = 0; @@ -3955,7 +3955,7 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) return r; } -static int __exit omap_dispchw_remove(struct platform_device *pdev) +static int omap_dispchw_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); @@ -4013,7 +4013,7 @@ static const struct of_device_id dispc_of_match[] = { }; static struct platform_driver omap_dispchw_driver = { - .remove = __exit_p(omap_dispchw_remove), + .remove = omap_dispchw_remove, .driver = { .name = "omapdss_dispc", .pm = &dispc_pm_ops, @@ -4027,7 +4027,7 @@ int __init dispc_init_platform_driver(void) return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); } -void __exit dispc_uninit_platform_driver(void) +void dispc_uninit_platform_driver(void) { platform_driver_unregister(&omap_dispchw_driver); } diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index f83e7b030249..a06e7558280f 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -731,7 +731,7 @@ static void dpi_init_output(struct platform_device *pdev) omapdss_register_output(out); } -static void __exit dpi_uninit_output(struct platform_device *pdev) +static void dpi_uninit_output(struct platform_device *pdev) { struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); struct omap_dss_device *out = &dpi->output; @@ -775,7 +775,7 @@ static void dpi_init_output_port(struct platform_device *pdev, omapdss_register_output(out); } -static void __exit dpi_uninit_output_port(struct device_node *port) +static void dpi_uninit_output_port(struct device_node *port) { struct dpi_data *dpi = port->data; struct omap_dss_device *out = &dpi->output; @@ -802,7 +802,7 @@ static int omap_dpi_probe(struct platform_device *pdev) return 0; } -static int __exit omap_dpi_remove(struct platform_device *pdev) +static int omap_dpi_remove(struct platform_device *pdev) { dpi_uninit_output(pdev); @@ -811,7 +811,7 @@ static int __exit omap_dpi_remove(struct platform_device *pdev) static struct platform_driver omap_dpi_driver = { .probe = omap_dpi_probe, - .remove = __exit_p(omap_dpi_remove), + .remove = omap_dpi_remove, .driver = { .name = "omapdss_dpi", .suppress_bind_attrs = true, @@ -823,12 +823,12 @@ int __init dpi_init_platform_driver(void) return platform_driver_register(&omap_dpi_driver); } -void __exit dpi_uninit_platform_driver(void) +void dpi_uninit_platform_driver(void) { platform_driver_unregister(&omap_dpi_driver); } -int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) +int dpi_init_port(struct platform_device *pdev, struct device_node *port) { struct dpi_data *dpi; struct device_node *ep; @@ -870,7 +870,7 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) return r; } -void __exit dpi_uninit_port(struct device_node *port) +void dpi_uninit_port(struct device_node *port) { struct dpi_data *dpi = port->data; diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c index 28b0bc11669d..c4c27c09c62f 100644 --- a/drivers/video/fbdev/omap2/dss/dsi.c +++ b/drivers/video/fbdev/omap2/dss/dsi.c @@ -5484,7 +5484,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) return r; } -static int __exit omap_dsihw_remove(struct platform_device *dsidev) +static int omap_dsihw_remove(struct platform_device *dsidev) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -5570,7 +5570,7 @@ static const struct of_device_id dsi_of_match[] = { static struct platform_driver omap_dsihw_driver = { .probe = omap_dsihw_probe, - .remove = __exit_p(omap_dsihw_remove), + .remove = omap_dsihw_remove, .driver = { .name = "omapdss_dsi", .pm = &dsi_pm_ops, @@ -5584,7 +5584,7 @@ int __init dsi_init_platform_driver(void) return platform_driver_register(&omap_dsihw_driver); } -void __exit dsi_uninit_platform_driver(void) +void dsi_uninit_platform_driver(void) { platform_driver_unregister(&omap_dsihw_driver); } diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 28e6ff053b47..3397cbf484b0 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -819,7 +819,7 @@ static const enum omap_display_type dra7xx_ports[] = { OMAP_DISPLAY_TYPE_DPI, }; -static const struct dss_features omap24xx_dss_feats __initconst = { +static const struct dss_features omap24xx_dss_feats = { /* * fck div max is really 16, but the divider range has gaps. The range * from 1 to 6 has no gaps, so let's use that as a max. @@ -832,7 +832,7 @@ static const struct dss_features omap24xx_dss_feats __initconst = { .num_ports = ARRAY_SIZE(omap2plus_ports), }; -static const struct dss_features omap34xx_dss_feats __initconst = { +static const struct dss_features omap34xx_dss_feats = { .fck_div_max = 16, .dss_fck_multiplier = 2, .parent_clk_name = "dpll4_ck", @@ -841,7 +841,7 @@ static const struct dss_features omap34xx_dss_feats __initconst = { .num_ports = ARRAY_SIZE(omap34xx_ports), }; -static const struct dss_features omap3630_dss_feats __initconst = { +static const struct dss_features omap3630_dss_feats = { .fck_div_max = 32, .dss_fck_multiplier = 1, .parent_clk_name = "dpll4_ck", @@ -850,7 +850,7 @@ static const struct dss_features omap3630_dss_feats __initconst = { .num_ports = ARRAY_SIZE(omap2plus_ports), }; -static const struct dss_features omap44xx_dss_feats __initconst = { +static const struct dss_features omap44xx_dss_feats = { .fck_div_max = 32, .dss_fck_multiplier = 1, .parent_clk_name = "dpll_per_x2_ck", @@ -859,7 +859,7 @@ static const struct dss_features omap44xx_dss_feats __initconst = { .num_ports = ARRAY_SIZE(omap2plus_ports), }; -static const struct dss_features omap54xx_dss_feats __initconst = { +static const struct dss_features omap54xx_dss_feats = { .fck_div_max = 64, .dss_fck_multiplier = 1, .parent_clk_name = "dpll_per_x2_ck", @@ -868,7 +868,7 @@ static const struct dss_features omap54xx_dss_feats __initconst = { .num_ports = ARRAY_SIZE(omap2plus_ports), }; -static const struct dss_features am43xx_dss_feats __initconst = { +static const struct dss_features am43xx_dss_feats = { .fck_div_max = 0, .dss_fck_multiplier = 0, .parent_clk_name = NULL, @@ -877,7 +877,7 @@ static const struct dss_features am43xx_dss_feats __initconst = { .num_ports = ARRAY_SIZE(omap2plus_ports), }; -static const struct dss_features dra7xx_dss_feats __initconst = { +static const struct dss_features dra7xx_dss_feats = { .fck_div_max = 64, .dss_fck_multiplier = 1, .parent_clk_name = "dpll_per_x2_ck", @@ -886,7 +886,7 @@ static const struct dss_features dra7xx_dss_feats __initconst = { .num_ports = ARRAY_SIZE(dra7xx_ports), }; -static int __init dss_init_features(struct platform_device *pdev) +static int dss_init_features(struct platform_device *pdev) { const struct dss_features *src; struct dss_features *dst; @@ -940,7 +940,7 @@ static int __init dss_init_features(struct platform_device *pdev) return 0; } -static int __init dss_init_ports(struct platform_device *pdev) +static int dss_init_ports(struct platform_device *pdev) { struct device_node *parent = pdev->dev.of_node; struct device_node *port; @@ -984,7 +984,7 @@ static int __init dss_init_ports(struct platform_device *pdev) return 0; } -static void __exit dss_uninit_ports(struct platform_device *pdev) +static void dss_uninit_ports(struct platform_device *pdev) { struct device_node *parent = pdev->dev.of_node; struct device_node *port; @@ -1088,7 +1088,7 @@ static int dss_video_pll_probe(struct platform_device *pdev) } /* DSS HW IP initialisation */ -static int __init omap_dsshw_probe(struct platform_device *pdev) +static int omap_dsshw_probe(struct platform_device *pdev) { struct resource *dss_mem; u32 rev; @@ -1182,7 +1182,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) return r; } -static int __exit omap_dsshw_remove(struct platform_device *pdev) +static int omap_dsshw_remove(struct platform_device *pdev) { dss_initialized = false; @@ -1243,7 +1243,7 @@ static const struct of_device_id dss_of_match[] = { MODULE_DEVICE_TABLE(of, dss_of_match); static struct platform_driver omap_dsshw_driver = { - .remove = __exit_p(omap_dsshw_remove), + .remove = omap_dsshw_remove, .driver = { .name = "omapdss_dss", .pm = &dss_pm_ops, diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h index 4812eee2622a..2406bcdb831a 100644 --- a/drivers/video/fbdev/omap2/dss/dss.h +++ b/drivers/video/fbdev/omap2/dss/dss.h @@ -309,18 +309,18 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min, /* SDI */ int sdi_init_platform_driver(void) __init; -void sdi_uninit_platform_driver(void) __exit; +void sdi_uninit_platform_driver(void); #ifdef CONFIG_OMAP2_DSS_SDI -int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; -void sdi_uninit_port(struct device_node *port) __exit; +int sdi_init_port(struct platform_device *pdev, struct device_node *port); +void sdi_uninit_port(struct device_node *port); #else -static inline int __init sdi_init_port(struct platform_device *pdev, +static inline int sdi_init_port(struct platform_device *pdev, struct device_node *port) { return 0; } -static inline void __exit sdi_uninit_port(struct device_node *port) +static inline void sdi_uninit_port(struct device_node *port) { } #endif @@ -333,7 +333,7 @@ struct dentry; struct file_operations; int dsi_init_platform_driver(void) __init; -void dsi_uninit_platform_driver(void) __exit; +void dsi_uninit_platform_driver(void); void dsi_dump_clocks(struct seq_file *s); @@ -350,25 +350,25 @@ static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) /* DPI */ int dpi_init_platform_driver(void) __init; -void dpi_uninit_platform_driver(void) __exit; +void dpi_uninit_platform_driver(void); #ifdef CONFIG_OMAP2_DSS_DPI -int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; -void dpi_uninit_port(struct device_node *port) __exit; +int dpi_init_port(struct platform_device *pdev, struct device_node *port); +void dpi_uninit_port(struct device_node *port); #else -static inline int __init dpi_init_port(struct platform_device *pdev, +static inline int dpi_init_port(struct platform_device *pdev, struct device_node *port) { return 0; } -static inline void __exit dpi_uninit_port(struct device_node *port) +static inline void dpi_uninit_port(struct device_node *port) { } #endif /* DISPC */ int dispc_init_platform_driver(void) __init; -void dispc_uninit_platform_driver(void) __exit; +void dispc_uninit_platform_driver(void); void dispc_dump_clocks(struct seq_file *s); void dispc_enable_sidle(void); @@ -418,18 +418,18 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, /* VENC */ int venc_init_platform_driver(void) __init; -void venc_uninit_platform_driver(void) __exit; +void venc_uninit_platform_driver(void); /* HDMI */ int hdmi4_init_platform_driver(void) __init; -void hdmi4_uninit_platform_driver(void) __exit; +void hdmi4_uninit_platform_driver(void); int hdmi5_init_platform_driver(void) __init; -void hdmi5_uninit_platform_driver(void) __exit; +void hdmi5_uninit_platform_driver(void); /* RFBI */ int rfbi_init_platform_driver(void) __init; -void rfbi_uninit_platform_driver(void) __exit; +void rfbi_uninit_platform_driver(void); #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 916d47978f41..31deebbc32dc 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -713,7 +713,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) return r; } -static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) +static int omapdss_hdmihw_remove(struct platform_device *pdev) { if (hdmi.audio_pdev) platform_device_unregister(hdmi.audio_pdev); @@ -757,7 +757,7 @@ static const struct of_device_id hdmi_of_match[] = { static struct platform_driver omapdss_hdmihw_driver = { .probe = omapdss_hdmihw_probe, - .remove = __exit_p(omapdss_hdmihw_remove), + .remove = omapdss_hdmihw_remove, .driver = { .name = "omapdss_hdmi", .pm = &hdmi_pm_ops, @@ -771,7 +771,7 @@ int __init hdmi4_init_platform_driver(void) return platform_driver_register(&omapdss_hdmihw_driver); } -void __exit hdmi4_uninit_platform_driver(void) +void hdmi4_uninit_platform_driver(void) { platform_driver_unregister(&omapdss_hdmihw_driver); } diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index 3f0b34a7031a..a57f5e8f9aea 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -748,7 +748,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) return r; } -static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) +static int omapdss_hdmihw_remove(struct platform_device *pdev) { if (hdmi.audio_pdev) platform_device_unregister(hdmi.audio_pdev); @@ -793,7 +793,7 @@ static const struct of_device_id hdmi_of_match[] = { static struct platform_driver omapdss_hdmihw_driver = { .probe = omapdss_hdmihw_probe, - .remove = __exit_p(omapdss_hdmihw_remove), + .remove = omapdss_hdmihw_remove, .driver = { .name = "omapdss_hdmi5", .pm = &hdmi_pm_ops, @@ -807,7 +807,7 @@ int __init hdmi5_init_platform_driver(void) return platform_driver_register(&omapdss_hdmihw_driver); } -void __exit hdmi5_uninit_platform_driver(void) +void hdmi5_uninit_platform_driver(void) { platform_driver_unregister(&omapdss_hdmihw_driver); } diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c index 065effca9236..8ec810bce0b6 100644 --- a/drivers/video/fbdev/omap2/dss/rfbi.c +++ b/drivers/video/fbdev/omap2/dss/rfbi.c @@ -938,7 +938,7 @@ static void rfbi_init_output(struct platform_device *pdev) omapdss_register_output(out); } -static void __exit rfbi_uninit_output(struct platform_device *pdev) +static void rfbi_uninit_output(struct platform_device *pdev) { struct omap_dss_device *out = &rfbi.output; @@ -1005,7 +1005,7 @@ static int omap_rfbihw_probe(struct platform_device *pdev) return r; } -static int __exit omap_rfbihw_remove(struct platform_device *pdev) +static int omap_rfbihw_remove(struct platform_device *pdev) { rfbi_uninit_output(pdev); @@ -1039,7 +1039,7 @@ static const struct dev_pm_ops rfbi_pm_ops = { static struct platform_driver omap_rfbihw_driver = { .probe = omap_rfbihw_probe, - .remove = __exit_p(omap_rfbihw_remove), + .remove = omap_rfbihw_remove, .driver = { .name = "omapdss_rfbi", .pm = &rfbi_pm_ops, @@ -1052,7 +1052,7 @@ int __init rfbi_init_platform_driver(void) return platform_driver_register(&omap_rfbihw_driver); } -void __exit rfbi_uninit_platform_driver(void) +void rfbi_uninit_platform_driver(void) { platform_driver_unregister(&omap_rfbihw_driver); } diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index 5c2ccab5a958..a873118f1e0e 100644 --- a/drivers/video/fbdev/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c @@ -350,7 +350,7 @@ static void sdi_init_output(struct platform_device *pdev) omapdss_register_output(out); } -static void __exit sdi_uninit_output(struct platform_device *pdev) +static void sdi_uninit_output(struct platform_device *pdev) { struct omap_dss_device *out = &sdi.output; @@ -366,7 +366,7 @@ static int omap_sdi_probe(struct platform_device *pdev) return 0; } -static int __exit omap_sdi_remove(struct platform_device *pdev) +static int omap_sdi_remove(struct platform_device *pdev) { sdi_uninit_output(pdev); @@ -375,7 +375,7 @@ static int __exit omap_sdi_remove(struct platform_device *pdev) static struct platform_driver omap_sdi_driver = { .probe = omap_sdi_probe, - .remove = __exit_p(omap_sdi_remove), + .remove = omap_sdi_remove, .driver = { .name = "omapdss_sdi", .suppress_bind_attrs = true, @@ -387,12 +387,12 @@ int __init sdi_init_platform_driver(void) return platform_driver_register(&omap_sdi_driver); } -void __exit sdi_uninit_platform_driver(void) +void sdi_uninit_platform_driver(void) { platform_driver_unregister(&omap_sdi_driver); } -int __init sdi_init_port(struct platform_device *pdev, struct device_node *port) +int sdi_init_port(struct platform_device *pdev, struct device_node *port) { struct device_node *ep; u32 datapairs; @@ -426,7 +426,7 @@ int __init sdi_init_port(struct platform_device *pdev, struct device_node *port) return r; } -void __exit sdi_uninit_port(struct device_node *port) +void sdi_uninit_port(struct device_node *port) { if (!sdi.port_initialized) return; diff --git a/drivers/video/fbdev/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c index ef7fd925e7f2..e7fad0e19d43 100644 --- a/drivers/video/fbdev/omap2/dss/venc.c +++ b/drivers/video/fbdev/omap2/dss/venc.c @@ -802,7 +802,7 @@ static void venc_init_output(struct platform_device *pdev) omapdss_register_output(out); } -static void __exit venc_uninit_output(struct platform_device *pdev) +static void venc_uninit_output(struct platform_device *pdev) { struct omap_dss_device *out = &venc.output; @@ -912,7 +912,7 @@ static int omap_venchw_probe(struct platform_device *pdev) return r; } -static int __exit omap_venchw_remove(struct platform_device *pdev) +static int omap_venchw_remove(struct platform_device *pdev) { venc_uninit_output(pdev); @@ -960,7 +960,7 @@ static const struct of_device_id venc_of_match[] = { static struct platform_driver omap_venchw_driver = { .probe = omap_venchw_probe, - .remove = __exit_p(omap_venchw_remove), + .remove = omap_venchw_remove, .driver = { .name = "omapdss_venc", .pm = &venc_pm_ops, @@ -974,7 +974,7 @@ int __init venc_init_platform_driver(void) return platform_driver_register(&omap_venchw_driver); } -void __exit venc_uninit_platform_driver(void) +void venc_uninit_platform_driver(void) { platform_driver_unregister(&omap_venchw_driver); } From 606ae4865a1947c04d52b97b5109cda90aebe892 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Jun 2015 14:31:36 +0300 Subject: [PATCH 5/7] OMAPDSS: reorder uninit calls We have a list of function pointers to dss submodule uninit functions. It makes sense to do the uninit in the reverse order to init, but that is not currently the case. This patch reorders the uninit calls to be the reverse of init order. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart --- drivers/video/fbdev/omap2/dss/core.c | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c index 57b6a5296c87..5c64515de818 100644 --- a/drivers/video/fbdev/omap2/dss/core.c +++ b/drivers/video/fbdev/omap2/dss/core.c @@ -269,26 +269,26 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { }; static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { -#ifdef CONFIG_OMAP2_DSS_DSI - dsi_uninit_platform_driver, -#endif -#ifdef CONFIG_OMAP2_DSS_DPI - dpi_uninit_platform_driver, -#endif -#ifdef CONFIG_OMAP2_DSS_SDI - sdi_uninit_platform_driver, -#endif -#ifdef CONFIG_OMAP2_DSS_RFBI - rfbi_uninit_platform_driver, -#endif -#ifdef CONFIG_OMAP2_DSS_VENC - venc_uninit_platform_driver, +#ifdef CONFIG_OMAP5_DSS_HDMI + hdmi5_uninit_platform_driver, #endif #ifdef CONFIG_OMAP4_DSS_HDMI hdmi4_uninit_platform_driver, #endif -#ifdef CONFIG_OMAP5_DSS_HDMI - hdmi5_uninit_platform_driver, +#ifdef CONFIG_OMAP2_DSS_VENC + venc_uninit_platform_driver, +#endif +#ifdef CONFIG_OMAP2_DSS_RFBI + rfbi_uninit_platform_driver, +#endif +#ifdef CONFIG_OMAP2_DSS_SDI + sdi_uninit_platform_driver, +#endif +#ifdef CONFIG_OMAP2_DSS_DPI + dpi_uninit_platform_driver, +#endif +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_uninit_platform_driver, #endif }; From 736e60ddc215b85e73bbf7da26e1cde84cc9500f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Jun 2015 15:22:23 +0300 Subject: [PATCH 6/7] OMAPDSS: componentize omapdss omapdss kernel module contains drivers for multiple devices, one for each DSS submodule. The probing we have at the moment is a mess, and doesn't give us proper deferred probing nor ensure that all the devices are probed before omapfb/omapdrm start using omapdss. This patch solves the mess by using the component system for DSS submodules. The changes to all DSS submodules (dispc, dpi, dsi, hdmi4/5, rfbi, sdi, venc) are the same: probe & remove functions are changed to bind & unbind, and new probe & remove functions are added which call component_add/del. The dss_core driver (dss.c) acts as a component master. Adding and matching the components is simple: all dss device's child devices are added as components. However, we do have some dependencies between the drivers. The order in which they should be probed is reflected by the list in core.c (dss_output_drv_reg_funcs). The drivers are registered in that order, which causes the components to be added in that order, which makes the components to be bound in that order. This feels a bit fragile, and we probably should improve the code to manage binds in random order. However, for now, this works fine. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart --- drivers/video/fbdev/omap2/dss/dispc.c | 28 ++++++++++--- drivers/video/fbdev/omap2/dss/dpi.c | 28 ++++++++++--- drivers/video/fbdev/omap2/dss/dsi.c | 25 ++++++++++-- drivers/video/fbdev/omap2/dss/dss.c | 59 +++++++++++++++++++++++++-- drivers/video/fbdev/omap2/dss/hdmi4.c | 26 ++++++++++-- drivers/video/fbdev/omap2/dss/hdmi5.c | 26 ++++++++++-- drivers/video/fbdev/omap2/dss/rfbi.c | 28 +++++++++++-- drivers/video/fbdev/omap2/dss/sdi.c | 29 ++++++++++--- drivers/video/fbdev/omap2/dss/venc.c | 27 +++++++++--- 9 files changed, 236 insertions(+), 40 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index e3417af63451..c8e34163211a 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -39,6 +39,7 @@ #include #include #include +#include #include