Loading drivers/video/fbdev/omap2/dss/core.c +27 −53 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -253,6 +245,8 @@ static struct platform_driver omap_dss_driver = { /* INIT */ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { dss_init_platform_driver, dispc_init_platform_driver, #ifdef CONFIG_OMAP2_DSS_DSI dsi_init_platform_driver, #endif Loading @@ -276,32 +270,32 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { #endif }; static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { #ifdef CONFIG_OMAP2_DSS_DSI dsi_uninit_platform_driver, static void (*dss_output_drv_unreg_funcs[])(void) = { #ifdef CONFIG_OMAP5_DSS_HDMI hdmi5_uninit_platform_driver, #endif #ifdef CONFIG_OMAP2_DSS_DPI dpi_uninit_platform_driver, #ifdef CONFIG_OMAP4_DSS_HDMI hdmi4_uninit_platform_driver, #endif #ifdef CONFIG_OMAP2_DSS_SDI sdi_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_VENC venc_uninit_platform_driver, #ifdef CONFIG_OMAP2_DSS_SDI sdi_uninit_platform_driver, #endif #ifdef CONFIG_OMAP4_DSS_HDMI hdmi4_uninit_platform_driver, #ifdef CONFIG_OMAP2_DSS_DPI dpi_uninit_platform_driver, #endif #ifdef CONFIG_OMAP5_DSS_HDMI hdmi5_uninit_platform_driver, #ifdef CONFIG_OMAP2_DSS_DSI dsi_uninit_platform_driver, #endif dispc_uninit_platform_driver, dss_uninit_platform_driver, }; static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; static int __init omap_dss_init(void) { int r; Loading @@ -311,35 +305,20 @@ static int __init omap_dss_init(void) if (r) return r; r = dss_init_platform_driver(); if (r) { DSSERR("Failed to initialize DSS platform driver\n"); goto err_dss; } r = dispc_init_platform_driver(); if (r) { DSSERR("Failed to initialize dispc platform driver\n"); goto err_dispc; } /* * It's ok if the output-driver register fails. It happens, for example, * when there is no output-device (e.g. SDI for OMAP4). */ for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) { r = dss_output_drv_reg_funcs[i](); if (r == 0) dss_output_drv_loaded[i] = true; if (r) goto err_reg; } dss_initialized = true; return 0; err_dispc: dss_uninit_platform_driver(); err_dss: err_reg: for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) dss_output_drv_unreg_funcs[i](); platform_driver_unregister(&omap_dss_driver); return r; Loading @@ -349,13 +328,8 @@ static void __exit omap_dss_exit(void) { int i; for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) { if (dss_output_drv_loaded[i]) for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) dss_output_drv_unreg_funcs[i](); } dispc_uninit_platform_driver(); dss_uninit_platform_driver(); platform_driver_unregister(&omap_dss_driver); } Loading drivers/video/fbdev/omap2/dss/dispc.c +30 −12 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include <linux/of.h> #include <linux/component.h> #include <video/omapdss.h> Loading Loading @@ -3692,7 +3693,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, Loading @@ -3711,7 +3712,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, Loading @@ -3731,7 +3732,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, Loading @@ -3751,7 +3752,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, Loading @@ -3771,7 +3772,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, Loading @@ -3792,7 +3793,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; Loading Loading @@ -3882,8 +3883,9 @@ 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 dispc_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); u32 rev; int r = 0; struct resource *dispc_mem; Loading Loading @@ -3955,12 +3957,27 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) return r; } static int __exit omap_dispchw_remove(struct platform_device *pdev) static void dispc_unbind(struct device *dev, struct device *master, void *data) { pm_runtime_disable(&pdev->dev); pm_runtime_disable(dev); dss_uninit_overlay_managers(); } static const struct component_ops dispc_component_ops = { .bind = dispc_bind, .unbind = dispc_unbind, }; static int dispc_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &dispc_component_ops); } static int dispc_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dispc_component_ops); return 0; } Loading Loading @@ -4013,7 +4030,8 @@ static const struct of_device_id dispc_of_match[] = { }; static struct platform_driver omap_dispchw_driver = { .remove = __exit_p(omap_dispchw_remove), .probe = dispc_probe, .remove = dispc_remove, .driver = { .name = "omapdss_dispc", .pm = &dispc_pm_ops, Loading @@ -4024,10 +4042,10 @@ static struct platform_driver omap_dispchw_driver = { int __init dispc_init_platform_driver(void) { return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); return platform_driver_register(&omap_dispchw_driver); } void __exit dispc_uninit_platform_driver(void) void dispc_uninit_platform_driver(void) { platform_driver_unregister(&omap_dispchw_driver); } drivers/video/fbdev/omap2/dss/dpi.c +27 −9 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <linux/string.h> #include <linux/of.h> #include <linux/clk.h> #include <linux/component.h> #include <video/omapdss.h> Loading Loading @@ -731,7 +732,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; Loading Loading @@ -775,7 +776,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; Loading @@ -783,8 +784,9 @@ static void __exit dpi_uninit_output_port(struct device_node *port) omapdss_unregister_output(out); } static int omap_dpi_probe(struct platform_device *pdev) static int dpi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct dpi_data *dpi; dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); Loading @@ -802,16 +804,32 @@ static int omap_dpi_probe(struct platform_device *pdev) return 0; } static int __exit omap_dpi_remove(struct platform_device *pdev) static void dpi_unbind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); dpi_uninit_output(pdev); } static const struct component_ops dpi_component_ops = { .bind = dpi_bind, .unbind = dpi_unbind, }; static int dpi_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &dpi_component_ops); } static int dpi_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dpi_component_ops); return 0; } static struct platform_driver omap_dpi_driver = { .probe = omap_dpi_probe, .remove = __exit_p(omap_dpi_remove), .probe = dpi_probe, .remove = dpi_remove, .driver = { .name = "omapdss_dpi", .suppress_bind_attrs = true, Loading @@ -823,12 +841,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; Loading Loading @@ -870,7 +888,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; Loading drivers/video/fbdev/omap2/dss/dsi.c +22 −5 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_platform.h> #include <linux/component.h> #include <video/omapdss.h> #include <video/mipi_display.h> Loading Loading @@ -5274,8 +5275,9 @@ static int dsi_init_pll_data(struct platform_device *dsidev) } /* DSI1 HW IP initialisation */ static int omap_dsihw_probe(struct platform_device *dsidev) static int dsi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *dsidev = to_platform_device(dev); u32 rev; int r, i; struct dsi_data *dsi; Loading Loading @@ -5484,8 +5486,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev) return r; } static int __exit omap_dsihw_remove(struct platform_device *dsidev) static void dsi_unbind(struct device *dev, struct device *master, void *data) { struct platform_device *dsidev = to_platform_device(dev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); of_platform_depopulate(&dsidev->dev); Loading @@ -5502,7 +5505,21 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) regulator_disable(dsi->vdds_dsi_reg); dsi->vdds_dsi_enabled = false; } } static const struct component_ops dsi_component_ops = { .bind = dsi_bind, .unbind = dsi_unbind, }; static int dsi_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &dsi_component_ops); } static int dsi_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dsi_component_ops); return 0; } Loading Loading @@ -5569,8 +5586,8 @@ 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), .probe = dsi_probe, .remove = dsi_remove, .driver = { .name = "omapdss_dsi", .pm = &dsi_pm_ops, Loading @@ -5584,7 +5601,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); } drivers/video/fbdev/omap2/dss/dss.c +151 −72 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <linux/of.h> #include <linux/regulator/consumer.h> #include <linux/suspend.h> #include <linux/component.h> #include <video/omapdss.h> Loading Loading @@ -111,6 +112,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); Loading Loading @@ -811,7 +820,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. Loading @@ -824,7 +833,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", Loading @@ -833,7 +842,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", Loading @@ -842,7 +851,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", Loading @@ -851,7 +860,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", Loading @@ -860,7 +869,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, Loading @@ -869,7 +878,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", Loading @@ -878,7 +887,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; Loading Loading @@ -932,7 +941,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; Loading Loading @@ -976,7 +985,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; Loading Loading @@ -1018,14 +1027,74 @@ static void __exit dss_uninit_ports(struct platform_device *pdev) } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); } static int dss_video_pll_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct regulator *pll_regulator; int r; if (!np) return 0; 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)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl regmap\n"); return PTR_ERR(dss.syscon_pll_ctrl); } if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1, &dss.syscon_pll_ctrl_offset)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl offset\n"); return -EINVAL; } } pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video"); if (IS_ERR(pll_regulator)) { r = PTR_ERR(pll_regulator); switch (r) { case -ENOENT: pll_regulator = NULL; break; case -EPROBE_DEFER: return -EPROBE_DEFER; default: DSSERR("can't get DPLL VDDA regulator\n"); return r; } } 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)) 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)) { 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) static int dss_bind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct resource *dss_mem; struct device_node *np = pdev->dev.of_node; u32 rev; int r; struct regulator *pll_regulator; dss.pdev = pdev; Loading Loading @@ -1054,6 +1123,14 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) if (r) goto err_setup_clocks; r = dss_video_pll_probe(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(); Loading @@ -1078,86 +1155,48 @@ 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); if (np && 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)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl regmap\n"); return PTR_ERR(dss.syscon_pll_ctrl); } if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1, &dss.syscon_pll_ctrl_offset)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl offset\n"); return -EINVAL; } } pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video"); if (IS_ERR(pll_regulator)) { r = PTR_ERR(pll_regulator); switch (r) { case -ENOENT: pll_regulator = NULL; break; case -EPROBE_DEFER: return -EPROBE_DEFER; default: DSSERR("can't get DPLL VDDA regulator\n"); return r; } } 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 (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; } } 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)); dss_runtime_put(); r = component_bind_all(&pdev->dev, NULL); if (r) goto err_component; dss_debugfs_create_file("dss", dss_dump_regs); pm_set_vt_switch(0); dss_initialized = true; return 0; err_pll_init: err_component: 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); 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; } static int __exit omap_dsshw_remove(struct platform_device *pdev) static void dss_unbind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); dss_initialized = false; component_unbind_all(&pdev->dev, NULL); if (dss.video1_pll) dss_video_pll_uninit(dss.video1_pll); Loading @@ -1169,7 +1208,46 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); dss_put_clocks(); } static const struct component_master_ops dss_component_ops = { .bind = dss_bind, .unbind = dss_unbind, }; static int dss_component_compare(struct device *dev, void *data) { struct device *child = data; return dev == child; } static int dss_add_child_component(struct device *dev, void *data) { struct component_match **match = data; component_match_add(dev->parent, match, dss_component_compare, dev); return 0; } static int dss_probe(struct platform_device *pdev) { struct component_match *match = NULL; int r; /* add all the child devices as components */ device_for_each_child(&pdev->dev, &match, dss_add_child_component); r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match); if (r) return r; return 0; } static int dss_remove(struct platform_device *pdev) { component_master_del(&pdev->dev, &dss_component_ops); return 0; } Loading Loading @@ -1215,7 +1293,8 @@ 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), .probe = dss_probe, .remove = dss_remove, .driver = { .name = "omapdss_dss", .pm = &dss_pm_ops, Loading @@ -1226,7 +1305,7 @@ static struct platform_driver omap_dsshw_driver = { int __init dss_init_platform_driver(void) { return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); return platform_driver_register(&omap_dsshw_driver); } void dss_uninit_platform_driver(void) Loading Loading
drivers/video/fbdev/omap2/dss/core.c +27 −53 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -253,6 +245,8 @@ static struct platform_driver omap_dss_driver = { /* INIT */ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { dss_init_platform_driver, dispc_init_platform_driver, #ifdef CONFIG_OMAP2_DSS_DSI dsi_init_platform_driver, #endif Loading @@ -276,32 +270,32 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { #endif }; static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { #ifdef CONFIG_OMAP2_DSS_DSI dsi_uninit_platform_driver, static void (*dss_output_drv_unreg_funcs[])(void) = { #ifdef CONFIG_OMAP5_DSS_HDMI hdmi5_uninit_platform_driver, #endif #ifdef CONFIG_OMAP2_DSS_DPI dpi_uninit_platform_driver, #ifdef CONFIG_OMAP4_DSS_HDMI hdmi4_uninit_platform_driver, #endif #ifdef CONFIG_OMAP2_DSS_SDI sdi_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_VENC venc_uninit_platform_driver, #ifdef CONFIG_OMAP2_DSS_SDI sdi_uninit_platform_driver, #endif #ifdef CONFIG_OMAP4_DSS_HDMI hdmi4_uninit_platform_driver, #ifdef CONFIG_OMAP2_DSS_DPI dpi_uninit_platform_driver, #endif #ifdef CONFIG_OMAP5_DSS_HDMI hdmi5_uninit_platform_driver, #ifdef CONFIG_OMAP2_DSS_DSI dsi_uninit_platform_driver, #endif dispc_uninit_platform_driver, dss_uninit_platform_driver, }; static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; static int __init omap_dss_init(void) { int r; Loading @@ -311,35 +305,20 @@ static int __init omap_dss_init(void) if (r) return r; r = dss_init_platform_driver(); if (r) { DSSERR("Failed to initialize DSS platform driver\n"); goto err_dss; } r = dispc_init_platform_driver(); if (r) { DSSERR("Failed to initialize dispc platform driver\n"); goto err_dispc; } /* * It's ok if the output-driver register fails. It happens, for example, * when there is no output-device (e.g. SDI for OMAP4). */ for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) { r = dss_output_drv_reg_funcs[i](); if (r == 0) dss_output_drv_loaded[i] = true; if (r) goto err_reg; } dss_initialized = true; return 0; err_dispc: dss_uninit_platform_driver(); err_dss: err_reg: for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) dss_output_drv_unreg_funcs[i](); platform_driver_unregister(&omap_dss_driver); return r; Loading @@ -349,13 +328,8 @@ static void __exit omap_dss_exit(void) { int i; for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) { if (dss_output_drv_loaded[i]) for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) dss_output_drv_unreg_funcs[i](); } dispc_uninit_platform_driver(); dss_uninit_platform_driver(); platform_driver_unregister(&omap_dss_driver); } Loading
drivers/video/fbdev/omap2/dss/dispc.c +30 −12 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include <linux/of.h> #include <linux/component.h> #include <video/omapdss.h> Loading Loading @@ -3692,7 +3693,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, Loading @@ -3711,7 +3712,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, Loading @@ -3731,7 +3732,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, Loading @@ -3751,7 +3752,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, Loading @@ -3771,7 +3772,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, Loading @@ -3792,7 +3793,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; Loading Loading @@ -3882,8 +3883,9 @@ 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 dispc_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); u32 rev; int r = 0; struct resource *dispc_mem; Loading Loading @@ -3955,12 +3957,27 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) return r; } static int __exit omap_dispchw_remove(struct platform_device *pdev) static void dispc_unbind(struct device *dev, struct device *master, void *data) { pm_runtime_disable(&pdev->dev); pm_runtime_disable(dev); dss_uninit_overlay_managers(); } static const struct component_ops dispc_component_ops = { .bind = dispc_bind, .unbind = dispc_unbind, }; static int dispc_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &dispc_component_ops); } static int dispc_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dispc_component_ops); return 0; } Loading Loading @@ -4013,7 +4030,8 @@ static const struct of_device_id dispc_of_match[] = { }; static struct platform_driver omap_dispchw_driver = { .remove = __exit_p(omap_dispchw_remove), .probe = dispc_probe, .remove = dispc_remove, .driver = { .name = "omapdss_dispc", .pm = &dispc_pm_ops, Loading @@ -4024,10 +4042,10 @@ static struct platform_driver omap_dispchw_driver = { int __init dispc_init_platform_driver(void) { return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); return platform_driver_register(&omap_dispchw_driver); } void __exit dispc_uninit_platform_driver(void) void dispc_uninit_platform_driver(void) { platform_driver_unregister(&omap_dispchw_driver); }
drivers/video/fbdev/omap2/dss/dpi.c +27 −9 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <linux/string.h> #include <linux/of.h> #include <linux/clk.h> #include <linux/component.h> #include <video/omapdss.h> Loading Loading @@ -731,7 +732,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; Loading Loading @@ -775,7 +776,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; Loading @@ -783,8 +784,9 @@ static void __exit dpi_uninit_output_port(struct device_node *port) omapdss_unregister_output(out); } static int omap_dpi_probe(struct platform_device *pdev) static int dpi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct dpi_data *dpi; dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); Loading @@ -802,16 +804,32 @@ static int omap_dpi_probe(struct platform_device *pdev) return 0; } static int __exit omap_dpi_remove(struct platform_device *pdev) static void dpi_unbind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); dpi_uninit_output(pdev); } static const struct component_ops dpi_component_ops = { .bind = dpi_bind, .unbind = dpi_unbind, }; static int dpi_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &dpi_component_ops); } static int dpi_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dpi_component_ops); return 0; } static struct platform_driver omap_dpi_driver = { .probe = omap_dpi_probe, .remove = __exit_p(omap_dpi_remove), .probe = dpi_probe, .remove = dpi_remove, .driver = { .name = "omapdss_dpi", .suppress_bind_attrs = true, Loading @@ -823,12 +841,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; Loading Loading @@ -870,7 +888,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; Loading
drivers/video/fbdev/omap2/dss/dsi.c +22 −5 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_platform.h> #include <linux/component.h> #include <video/omapdss.h> #include <video/mipi_display.h> Loading Loading @@ -5274,8 +5275,9 @@ static int dsi_init_pll_data(struct platform_device *dsidev) } /* DSI1 HW IP initialisation */ static int omap_dsihw_probe(struct platform_device *dsidev) static int dsi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *dsidev = to_platform_device(dev); u32 rev; int r, i; struct dsi_data *dsi; Loading Loading @@ -5484,8 +5486,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev) return r; } static int __exit omap_dsihw_remove(struct platform_device *dsidev) static void dsi_unbind(struct device *dev, struct device *master, void *data) { struct platform_device *dsidev = to_platform_device(dev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); of_platform_depopulate(&dsidev->dev); Loading @@ -5502,7 +5505,21 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) regulator_disable(dsi->vdds_dsi_reg); dsi->vdds_dsi_enabled = false; } } static const struct component_ops dsi_component_ops = { .bind = dsi_bind, .unbind = dsi_unbind, }; static int dsi_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &dsi_component_ops); } static int dsi_remove(struct platform_device *pdev) { component_del(&pdev->dev, &dsi_component_ops); return 0; } Loading Loading @@ -5569,8 +5586,8 @@ 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), .probe = dsi_probe, .remove = dsi_remove, .driver = { .name = "omapdss_dsi", .pm = &dsi_pm_ops, Loading @@ -5584,7 +5601,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); }
drivers/video/fbdev/omap2/dss/dss.c +151 −72 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <linux/of.h> #include <linux/regulator/consumer.h> #include <linux/suspend.h> #include <linux/component.h> #include <video/omapdss.h> Loading Loading @@ -111,6 +112,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); Loading Loading @@ -811,7 +820,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. Loading @@ -824,7 +833,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", Loading @@ -833,7 +842,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", Loading @@ -842,7 +851,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", Loading @@ -851,7 +860,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", Loading @@ -860,7 +869,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, Loading @@ -869,7 +878,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", Loading @@ -878,7 +887,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; Loading Loading @@ -932,7 +941,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; Loading Loading @@ -976,7 +985,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; Loading Loading @@ -1018,14 +1027,74 @@ static void __exit dss_uninit_ports(struct platform_device *pdev) } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); } static int dss_video_pll_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct regulator *pll_regulator; int r; if (!np) return 0; 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)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl regmap\n"); return PTR_ERR(dss.syscon_pll_ctrl); } if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1, &dss.syscon_pll_ctrl_offset)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl offset\n"); return -EINVAL; } } pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video"); if (IS_ERR(pll_regulator)) { r = PTR_ERR(pll_regulator); switch (r) { case -ENOENT: pll_regulator = NULL; break; case -EPROBE_DEFER: return -EPROBE_DEFER; default: DSSERR("can't get DPLL VDDA regulator\n"); return r; } } 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)) 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)) { 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) static int dss_bind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct resource *dss_mem; struct device_node *np = pdev->dev.of_node; u32 rev; int r; struct regulator *pll_regulator; dss.pdev = pdev; Loading Loading @@ -1054,6 +1123,14 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) if (r) goto err_setup_clocks; r = dss_video_pll_probe(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(); Loading @@ -1078,86 +1155,48 @@ 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); if (np && 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)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl regmap\n"); return PTR_ERR(dss.syscon_pll_ctrl); } if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1, &dss.syscon_pll_ctrl_offset)) { dev_err(&pdev->dev, "failed to get syscon-pll-ctrl offset\n"); return -EINVAL; } } pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video"); if (IS_ERR(pll_regulator)) { r = PTR_ERR(pll_regulator); switch (r) { case -ENOENT: pll_regulator = NULL; break; case -EPROBE_DEFER: return -EPROBE_DEFER; default: DSSERR("can't get DPLL VDDA regulator\n"); return r; } } 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 (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; } } 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)); dss_runtime_put(); r = component_bind_all(&pdev->dev, NULL); if (r) goto err_component; dss_debugfs_create_file("dss", dss_dump_regs); pm_set_vt_switch(0); dss_initialized = true; return 0; err_pll_init: err_component: 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); 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; } static int __exit omap_dsshw_remove(struct platform_device *pdev) static void dss_unbind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); dss_initialized = false; component_unbind_all(&pdev->dev, NULL); if (dss.video1_pll) dss_video_pll_uninit(dss.video1_pll); Loading @@ -1169,7 +1208,46 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); dss_put_clocks(); } static const struct component_master_ops dss_component_ops = { .bind = dss_bind, .unbind = dss_unbind, }; static int dss_component_compare(struct device *dev, void *data) { struct device *child = data; return dev == child; } static int dss_add_child_component(struct device *dev, void *data) { struct component_match **match = data; component_match_add(dev->parent, match, dss_component_compare, dev); return 0; } static int dss_probe(struct platform_device *pdev) { struct component_match *match = NULL; int r; /* add all the child devices as components */ device_for_each_child(&pdev->dev, &match, dss_add_child_component); r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match); if (r) return r; return 0; } static int dss_remove(struct platform_device *pdev) { component_master_del(&pdev->dev, &dss_component_ops); return 0; } Loading Loading @@ -1215,7 +1293,8 @@ 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), .probe = dss_probe, .remove = dss_remove, .driver = { .name = "omapdss_dss", .pm = &dss_pm_ops, Loading @@ -1226,7 +1305,7 @@ static struct platform_driver omap_dsshw_driver = { int __init dss_init_platform_driver(void) { return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); return platform_driver_register(&omap_dsshw_driver); } void dss_uninit_platform_driver(void) Loading