From 958f2717b84e88bf833d996997fda8f73276f2af Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 17 Feb 2012 12:19:48 +0200 Subject: [PATCH 01/20] OMAPDSS: TFP410: pdata rewrite To ease device tree adaptation in the future, rewrite TFP410 platform data handling to be done inside probe(), so that probe() is the only place where we need to handle the DT/pdata choice. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-tfp410.c | 72 +++++++++++---------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c index 52637fa8fda8..f03964e5b6ab 100644 --- a/drivers/video/omap2/displays/panel-tfp410.c +++ b/drivers/video/omap2/displays/panel-tfp410.c @@ -47,13 +47,9 @@ struct panel_drv_data { struct mutex lock; int pd_gpio; -}; -static inline struct tfp410_platform_data -*get_pdata(const struct omap_dss_device *dssdev) -{ - return dssdev->data; -} + struct i2c_adapter *i2c_adapter; +}; static int tfp410_power_on(struct omap_dss_device *dssdev) { @@ -90,11 +86,11 @@ static void tfp410_power_off(struct omap_dss_device *dssdev) static int tfp410_probe(struct omap_dss_device *dssdev) { - struct tfp410_platform_data *pdata = get_pdata(dssdev); struct panel_drv_data *ddata; int r; + int i2c_bus_num; - ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); + ddata = devm_kzalloc(&dssdev->dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) return -ENOMEM; @@ -104,10 +100,15 @@ static int tfp410_probe(struct omap_dss_device *dssdev) ddata->dssdev = dssdev; mutex_init(&ddata->lock); - if (pdata) + if (dssdev->data) { + struct tfp410_platform_data *pdata = dssdev->data; + ddata->pd_gpio = pdata->power_down_gpio; - else + i2c_bus_num = pdata->i2c_bus_num; + } else { ddata->pd_gpio = -1; + i2c_bus_num = -1; + } if (gpio_is_valid(ddata->pd_gpio)) { r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, @@ -115,13 +116,31 @@ static int tfp410_probe(struct omap_dss_device *dssdev) if (r) { dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", ddata->pd_gpio); - ddata->pd_gpio = -1; + return r; } } + if (i2c_bus_num != -1) { + struct i2c_adapter *adapter; + + adapter = i2c_get_adapter(i2c_bus_num); + if (!adapter) { + dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", + i2c_bus_num); + r = -EINVAL; + goto err_i2c; + } + + ddata->i2c_adapter = adapter; + } + dev_set_drvdata(&dssdev->dev, ddata); return 0; +err_i2c: + if (gpio_is_valid(ddata->pd_gpio)) + gpio_free(ddata->pd_gpio); + return r; } static void __exit tfp410_remove(struct omap_dss_device *dssdev) @@ -130,14 +149,15 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev) mutex_lock(&ddata->lock); + if (ddata->i2c_adapter) + i2c_put_adapter(ddata->i2c_adapter); + if (gpio_is_valid(ddata->pd_gpio)) gpio_free(ddata->pd_gpio); dev_set_drvdata(&dssdev->dev, NULL); mutex_unlock(&ddata->lock); - - kfree(ddata); } static int tfp410_enable(struct omap_dss_device *dssdev) @@ -269,27 +289,17 @@ static int tfp410_read_edid(struct omap_dss_device *dssdev, u8 *edid, int len) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); - struct tfp410_platform_data *pdata = get_pdata(dssdev); - struct i2c_adapter *adapter; int r, l, bytes_read; mutex_lock(&ddata->lock); - if (pdata->i2c_bus_num == 0) { + if (!ddata->i2c_adapter) { r = -ENODEV; goto err; } - adapter = i2c_get_adapter(pdata->i2c_bus_num); - if (!adapter) { - dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", - pdata->i2c_bus_num); - r = -EINVAL; - goto err; - } - l = min(EDID_LENGTH, len); - r = tfp410_ddc_read(adapter, edid, l, 0); + r = tfp410_ddc_read(ddata->i2c_adapter, edid, l, 0); if (r) goto err; @@ -299,7 +309,7 @@ static int tfp410_read_edid(struct omap_dss_device *dssdev, if (len > EDID_LENGTH && edid[0x7e] > 0) { l = min(EDID_LENGTH, len - EDID_LENGTH); - r = tfp410_ddc_read(adapter, edid + EDID_LENGTH, + r = tfp410_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH, l, EDID_LENGTH); if (r) goto err; @@ -319,21 +329,15 @@ static int tfp410_read_edid(struct omap_dss_device *dssdev, static bool tfp410_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); - struct tfp410_platform_data *pdata = get_pdata(dssdev); - struct i2c_adapter *adapter; unsigned char out; int r; mutex_lock(&ddata->lock); - if (pdata->i2c_bus_num == 0) - goto out; - - adapter = i2c_get_adapter(pdata->i2c_bus_num); - if (!adapter) + if (!ddata->i2c_adapter) goto out; - r = tfp410_ddc_read(adapter, &out, 1, 0); + r = tfp410_ddc_read(ddata->i2c_adapter, &out, 1, 0); mutex_unlock(&ddata->lock); From e23d83b0c92bbe30d1fe9d5c0b972e50c6593946 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 10 Jan 2012 11:26:52 +0200 Subject: [PATCH 02/20] OMAPDSS: DSI: use dsi_get_dsidev_id(dsidev) instead of dsidev->id The DSI driver uses dsi_get_dsidev_id() to get the ID number for the DSI instance. However, there were a few places where dsidev->id was used instead of the function. Fix those places to use the function. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 446e13667471..a243e65b870f 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2306,7 +2306,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) DSSDBGF(); - r = dsi->enable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); + r = dsi->enable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); if (r) return r; @@ -2416,7 +2416,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) dsi_cio_disable_lane_override(dsidev); err_scp_clk_dom: dsi_disable_scp_clk(dsidev); - dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); + dsi->disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); return r; } @@ -2430,7 +2430,7 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev) dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); dsi_disable_scp_clk(dsidev); - dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev)); + dsi->disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); } static void dsi_config_tx_fifo(struct platform_device *dsidev, From 00928eaf52007ee4e1fb7dc860bc02a56c125bb4 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 20 Feb 2012 11:50:06 +0200 Subject: [PATCH 03/20] OMAPDSS: clean up the omapdss platform data mess The omapdss pdata handling is a mess. This is more evident when trying to use device tree for DSS, as we don't have platform data anymore in that case. This patch cleans the pdata handling by: - Remove struct omap_display_platform_data. It was used just as a wrapper for struct omap_dss_board_info. - Pass the platform data only to omapdss device. The drivers for omap dss hwmods do not need the platform data. This should also work better for DT, as we can create omapdss device programmatically in generic omap boot code, and thus we can pass the pdata to it. - Create dss functions for get_ctx_loss_count and dsi_enable/disable_pads that the dss hwmod drivers can call. Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 39 ++++++++++++++++----------------- drivers/video/omap2/dss/core.c | 35 +++++++++++++++++++++++++++++ drivers/video/omap2/dss/dispc.c | 21 ++---------------- drivers/video/omap2/dss/dsi.c | 17 +++----------- drivers/video/omap2/dss/dss.h | 3 +++ drivers/video/omap2/dss/hdmi.c | 2 -- include/video/omapdss.h | 5 ----- 7 files changed, 62 insertions(+), 60 deletions(-) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 60cded4738a0..07232fd7ab17 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -191,10 +191,24 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) struct omap_hwmod *oh; struct platform_device *pdev; int i, oh_count; - struct omap_display_platform_data pdata; const struct omap_dss_hwmod_data *curr_dss_hwmod; - memset(&pdata, 0, sizeof(pdata)); + /* create omapdss device */ + + board_data->dsi_enable_pads = omap_dsi_enable_pads; + board_data->dsi_disable_pads = omap_dsi_disable_pads; + board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count; + board_data->set_min_bus_tput = omap_dss_set_min_bus_tput; + + omap_display_device.dev.platform_data = board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) { + pr_err("Unable to register omapdss device\n"); + return r; + } + + /* create devices for dss hwmods */ if (cpu_is_omap24xx()) { curr_dss_hwmod = omap2_dss_hwmod_data; @@ -207,16 +221,6 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); } - if (board_data->dsi_enable_pads == NULL) - board_data->dsi_enable_pads = omap_dsi_enable_pads; - if (board_data->dsi_disable_pads == NULL) - board_data->dsi_disable_pads = omap_dsi_disable_pads; - - pdata.board_data = board_data; - pdata.board_data->get_context_loss_count = - omap_pm_get_dev_context_loss_count; - pdata.board_data->set_min_bus_tput = omap_dss_set_min_bus_tput; - for (i = 0; i < oh_count; i++) { oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name); if (!oh) { @@ -226,21 +230,16 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) } pdev = omap_device_build(curr_dss_hwmod[i].dev_name, - curr_dss_hwmod[i].id, oh, &pdata, - sizeof(struct omap_display_platform_data), + curr_dss_hwmod[i].id, oh, + NULL, 0, NULL, 0, 0); if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", curr_dss_hwmod[i].oh_name)) return -ENODEV; } - omap_display_device.dev.platform_data = board_data; - r = platform_device_register(&omap_display_device); - if (r < 0) - printk(KERN_ERR "Unable to register OMAP-Display device\n"); - - return r; + return 0; } static void dispc_disable_outputs(void) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 64cb8aa49b26..b37b6f484c08 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -87,6 +87,41 @@ struct regulator *dss_get_vdds_sdi(void) return reg; } +int dss_get_ctx_loss_count(struct device *dev) +{ + struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; + int cnt; + + if (!board_data->get_context_loss_count) + return -ENOENT; + + cnt = board_data->get_context_loss_count(dev); + + WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); + + return cnt; +} + +int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) +{ + struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; + + if (!board_data->dsi_enable_pads) + return -ENOENT; + + return board_data->dsi_enable_pads(dsi_id, lane_mask); +} + +void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask) +{ + struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; + + if (!board_data->dsi_enable_pads) + return; + + return board_data->dsi_disable_pads(dsi_id, lane_mask); +} + int dss_set_min_bus_tput(struct device *dev, unsigned long tput) { struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 727e15b29a14..2c43119b5ade 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -131,23 +131,6 @@ static inline u32 dispc_read_reg(const u16 idx) return __raw_readl(dispc.base + idx); } -static int dispc_get_ctx_loss_count(void) -{ - struct device *dev = &dispc.pdev->dev; - struct omap_display_platform_data *pdata = dev->platform_data; - struct omap_dss_board_info *board_data = pdata->board_data; - int cnt; - - if (!board_data->get_context_loss_count) - return -ENOENT; - - cnt = board_data->get_context_loss_count(dev); - - WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); - - return cnt; -} - #define SR(reg) \ dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) #define RR(reg) \ @@ -251,7 +234,7 @@ static void dispc_save_context(void) if (dss_has_feature(FEAT_CORE_CLK_DIV)) SR(DIVISOR); - dispc.ctx_loss_cnt = dispc_get_ctx_loss_count(); + dispc.ctx_loss_cnt = dss_get_ctx_loss_count(&dispc.pdev->dev); dispc.ctx_valid = true; DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); @@ -266,7 +249,7 @@ static void dispc_restore_context(void) if (!dispc.ctx_valid) return; - ctx = dispc_get_ctx_loss_count(); + ctx = dss_get_ctx_loss_count(&dispc.pdev->dev); if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) return; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index a243e65b870f..d18c8e290c85 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -261,9 +261,6 @@ struct dsi_data { struct clk *dss_clk; struct clk *sys_clk; - int (*enable_pads)(int dsi_id, unsigned lane_mask); - void (*disable_pads)(int dsi_id, unsigned lane_mask); - struct dsi_clock_info current_cinfo; bool vdds_dsi_enabled; @@ -2306,7 +2303,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) DSSDBGF(); - r = dsi->enable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); + r = dss_dsi_enable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); if (r) return r; @@ -2416,21 +2413,20 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) dsi_cio_disable_lane_override(dsidev); err_scp_clk_dom: dsi_disable_scp_clk(dsidev); - dsi->disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); + dss_dsi_disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); return r; } static void dsi_cio_uninit(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); /* DDR_CLK_ALWAYS_ON */ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13); dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); dsi_disable_scp_clk(dsidev); - dsi->disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); + dss_dsi_disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev)); } static void dsi_config_tx_fifo(struct platform_device *dsidev, @@ -4645,8 +4641,6 @@ static void dsi_put_clocks(struct platform_device *dsidev) /* DSI1 HW IP initialisation */ static int omap_dsihw_probe(struct platform_device *dsidev) { - struct omap_display_platform_data *dss_plat_data; - struct omap_dss_board_info *board_info; u32 rev; int r, i, dsi_module = dsi_get_dsidev_id(dsidev); struct resource *dsi_mem; @@ -4660,11 +4654,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev) dsi_pdev_map[dsi_module] = dsidev; dev_set_drvdata(&dsidev->dev, dsi); - dss_plat_data = dsidev->dev.platform_data; - board_info = dss_plat_data->board_data; - dsi->enable_pads = board_info->dsi_enable_pads; - dsi->disable_pads = board_info->dsi_disable_pads; - spin_lock_init(&dsi->irq_lock); spin_lock_init(&dsi->errors_lock); dsi->errors = 0; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8e9e9a5765fa..848fc9cd65d4 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -159,6 +159,9 @@ struct platform_device; struct bus_type *dss_get_bus(void); struct regulator *dss_get_vdds_dsi(void); struct regulator *dss_get_vdds_sdi(void); +int dss_get_ctx_loss_count(struct device *dev); +int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); +void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); int dss_set_min_bus_tput(struct device *dev, unsigned long tput); /* apply */ diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 32ad7124a952..043eac676786 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -63,7 +63,6 @@ static struct { struct mutex lock; - struct omap_display_platform_data *pdata; struct platform_device *pdev; struct hdmi_ip_data ip_data; @@ -797,7 +796,6 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) struct resource *hdmi_mem; int r; - hdmi.pdata = pdev->dev.platform_data; hdmi.pdev = pdev; mutex_init(&hdmi.lock); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 1cbb2dd5fbba..1217df40cb7e 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -317,11 +317,6 @@ extern int omap_display_init(struct omap_dss_board_info *board_data); /* HDMI mux init*/ extern int omap_hdmi_init(enum omap_hdmi_flags flags); -struct omap_display_platform_data { - struct omap_dss_board_info *board_data; - /* TODO: Additional members to be added when PM is considered */ -}; - struct omap_video_timings { /* Unit: pixels */ u16 x_res; From 04c742c3dccac296fdc52b464bd0491ffe88de23 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 23 Feb 2012 15:32:37 +0200 Subject: [PATCH 04/20] OMAPDSS: remove return from platform_driver_unreg For unknown reasons we seem to have a return in each of the omapdss's uninit functions, which is a void function. Remove the returns. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 2 +- drivers/video/omap2/dss/dsi.c | 2 +- drivers/video/omap2/dss/dss.c | 2 +- drivers/video/omap2/dss/hdmi.c | 2 +- drivers/video/omap2/dss/rfbi.c | 2 +- drivers/video/omap2/dss/venc.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 2c43119b5ade..4623bd97a1af 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3611,5 +3611,5 @@ int dispc_init_platform_driver(void) void dispc_uninit_platform_driver(void) { - return platform_driver_unregister(&omap_dispchw_driver); + platform_driver_unregister(&omap_dispchw_driver); } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d18c8e290c85..43eeb0d04d47 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4814,5 +4814,5 @@ int dsi_init_platform_driver(void) void dsi_uninit_platform_driver(void) { - return platform_driver_unregister(&omap_dsihw_driver); + platform_driver_unregister(&omap_dsihw_driver); } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index e212acb1e7d5..3a0655020252 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -874,5 +874,5 @@ int dss_init_platform_driver(void) void dss_uninit_platform_driver(void) { - return platform_driver_unregister(&omap_dsshw_driver); + platform_driver_unregister(&omap_dsshw_driver); } diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 043eac676786..1d73ee7a5367 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -916,5 +916,5 @@ int hdmi_init_platform_driver(void) void hdmi_uninit_platform_driver(void) { - return platform_driver_unregister(&omapdss_hdmihw_driver); + platform_driver_unregister(&omapdss_hdmihw_driver); } diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index feadfab27ec2..31c992662457 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -1039,5 +1039,5 @@ int rfbi_init_platform_driver(void) void rfbi_uninit_platform_driver(void) { - return platform_driver_unregister(&omap_rfbihw_driver); + platform_driver_unregister(&omap_rfbihw_driver); } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 9475e6edce68..1884e347b630 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -959,5 +959,5 @@ void venc_uninit_platform_driver(void) if (cpu_is_omap44xx()) return; - return platform_driver_unregister(&omap_venchw_driver); + platform_driver_unregister(&omap_venchw_driver); } From 11436e1dd2aab1a33f81a3737ec8641788ec8543 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 7 Mar 2012 12:53:18 +0200 Subject: [PATCH 05/20] OMAPDSS: use platform_driver_probe for core/dispc/dss The platform devices for omapdss, dss and dispc drivers are always present, so we can use platform_driver_probe instead of platform_driver_register. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 3 +-- drivers/video/omap2/dss/dispc.c | 3 +-- drivers/video/omap2/dss/dss.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index b37b6f484c08..db45e6abe311 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -296,7 +296,6 @@ static int omap_dss_resume(struct platform_device *pdev) } static struct platform_driver omap_dss_driver = { - .probe = omap_dss_probe, .remove = omap_dss_remove, .shutdown = omap_dss_shutdown, .suspend = omap_dss_suspend, @@ -521,7 +520,7 @@ static int __init omap_dss_register_drivers(void) { int r; - r = platform_driver_register(&omap_dss_driver); + r = platform_driver_probe(&omap_dss_driver, omap_dss_probe); if (r) return r; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 4623bd97a1af..242efe9f702a 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3595,7 +3595,6 @@ static const struct dev_pm_ops dispc_pm_ops = { }; static struct platform_driver omap_dispchw_driver = { - .probe = omap_dispchw_probe, .remove = omap_dispchw_remove, .driver = { .name = "omapdss_dispc", @@ -3606,7 +3605,7 @@ static struct platform_driver omap_dispchw_driver = { int dispc_init_platform_driver(void) { - return platform_driver_register(&omap_dispchw_driver); + return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); } void dispc_uninit_platform_driver(void) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 3a0655020252..c849d8bd5256 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -858,7 +858,6 @@ static const struct dev_pm_ops dss_pm_ops = { }; static struct platform_driver omap_dsshw_driver = { - .probe = omap_dsshw_probe, .remove = omap_dsshw_remove, .driver = { .name = "omapdss_dss", @@ -869,7 +868,7 @@ static struct platform_driver omap_dsshw_driver = { int dss_init_platform_driver(void) { - return platform_driver_register(&omap_dsshw_driver); + return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); } void dss_uninit_platform_driver(void) From 966eaed08c40b49de19273b2b1ad1af4bf014862 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 17 Feb 2012 17:15:58 +0200 Subject: [PATCH 06/20] OMAPDSS: create custom pdevs for DSS omap_devices Instead of using omap_device_build() to create the omap_devices for DSS hwmods, create them with a custom function. This will allow us to create a parent-child hierarchy for the devices so that the omapdss_core device is parent for the rest of the dss hwmod devices. Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 101 +++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 07232fd7ab17..5369bf13652b 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -185,13 +185,71 @@ static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput) return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput); } +static struct platform_device *create_dss_pdev(const char *pdev_name, + int pdev_id, const char *oh_name, void *pdata, int pdata_len, + struct platform_device *parent) +{ + struct platform_device *pdev; + struct omap_device *od; + struct omap_hwmod *ohs[1]; + struct omap_hwmod *oh; + int r; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + r = -ENODEV; + goto err; + } + + pdev = platform_device_alloc(pdev_name, pdev_id); + if (!pdev) { + pr_err("Could not create pdev for %s\n", pdev_name); + r = -ENOMEM; + goto err; + } + + if (parent != NULL) + pdev->dev.parent = &parent->dev; + + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); + + ohs[0] = oh; + od = omap_device_alloc(pdev, ohs, 1, NULL, 0); + if (!od) { + pr_err("Could not alloc omap_device for %s\n", pdev_name); + r = -ENOMEM; + goto err; + } + + r = platform_device_add_data(pdev, pdata, pdata_len); + if (r) { + pr_err("Could not set pdata for %s\n", pdev_name); + goto err; + } + + r = omap_device_register(pdev); + if (r) { + pr_err("Could not register omap_device for %s\n", pdev_name); + goto err; + } + + return pdev; + +err: + return ERR_PTR(r); +} + int __init omap_display_init(struct omap_dss_board_info *board_data) { int r = 0; - struct omap_hwmod *oh; struct platform_device *pdev; int i, oh_count; const struct omap_dss_hwmod_data *curr_dss_hwmod; + struct platform_device *dss_pdev; /* create omapdss device */ @@ -221,22 +279,37 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); } - for (i = 0; i < oh_count; i++) { - oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name); - if (!oh) { - pr_err("Could not look up %s\n", - curr_dss_hwmod[i].oh_name); - return -ENODEV; - } + /* + * First create the pdev for dss_core, which is used as a parent device + * by the other dss pdevs. Note: dss_core has to be the first item in + * the hwmod list. + */ + dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name, + curr_dss_hwmod[0].id, + curr_dss_hwmod[0].oh_name, + NULL, 0, + NULL); - pdev = omap_device_build(curr_dss_hwmod[i].dev_name, - curr_dss_hwmod[i].id, oh, + if (IS_ERR(dss_pdev)) { + pr_err("Could not build omap_device for %s\n", + curr_dss_hwmod[0].oh_name); + + return PTR_ERR(dss_pdev); + } + + for (i = 1; i < oh_count; i++) { + pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name, + curr_dss_hwmod[i].id, + curr_dss_hwmod[i].oh_name, NULL, 0, - NULL, 0, 0); + dss_pdev); + + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s\n", + curr_dss_hwmod[i].oh_name); - if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", - curr_dss_hwmod[i].oh_name)) - return -ENODEV; + return PTR_ERR(pdev); + } } return 0; From 53f576a8dc5729e719c862aba2ed3430867bd5cb Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 7 Mar 2012 13:09:43 +0200 Subject: [PATCH 07/20] OMAPDSS: create DPI & SDI devices We currently have separate device/driver for each DSS HW module. The DPI and SDI outputs are more or less parts of the DSS or DISPC hardware modules, but in SW it makes sense to represent them as device/driver pairs similarly to all the other outputs. This also makes sense for device tree, as each node under dss will be a platform device, and handling DPI & SDI somehow differently than the rest would just make the code more complex. This patch modifies arch/arm/mach-omap2/display.c to create platform devices for DPI and SDI, and later patches will implement driver for them. Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 5369bf13652b..40c135696007 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -243,6 +243,46 @@ static struct platform_device *create_dss_pdev(const char *pdev_name, return ERR_PTR(r); } +static struct platform_device *create_simple_dss_pdev(const char *pdev_name, + int pdev_id, void *pdata, int pdata_len, + struct platform_device *parent) +{ + struct platform_device *pdev; + int r; + + pdev = platform_device_alloc(pdev_name, pdev_id); + if (!pdev) { + pr_err("Could not create pdev for %s\n", pdev_name); + r = -ENOMEM; + goto err; + } + + if (parent != NULL) + pdev->dev.parent = &parent->dev; + + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); + + r = platform_device_add_data(pdev, pdata, pdata_len); + if (r) { + pr_err("Could not set pdata for %s\n", pdev_name); + goto err; + } + + r = omap_device_register(pdev); + if (r) { + pr_err("Could not register omap_device for %s\n", pdev_name); + goto err; + } + + return pdev; + +err: + return ERR_PTR(r); +} + int __init omap_display_init(struct omap_dss_board_info *board_data) { int r = 0; @@ -312,6 +352,23 @@ 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); + 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); + if (IS_ERR(pdev)) { + pr_err("Could not build platform_device for omapdss_sdi\n"); + return PTR_ERR(pdev); + } + } + return 0; } From a57dd4fe7bef557afaa1a6cdb77cd95b2cba094e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 20 Feb 2012 16:57:37 +0200 Subject: [PATCH 08/20] OMAPDSS: create DPI & SDI drivers We currently have separate device/driver for each DSS HW module. The DPI and SDI outputs are more or less parts of the DSS or DISPC hardware modules, but in SW it makes sense to represent them as device/driver pairs similarly to all the other outputs. This also makes sense for device tree, as each node under dss will be a platform device, and handling DPI & SDI somehow differently than the rest would just make the code more complex. This patch modifies the dpi.c and sdi.c to create drivers for the platform devices. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 18 ++++++++++++++++++ drivers/video/omap2/dss/dpi.c | 23 +++++++++++++++++++++-- drivers/video/omap2/dss/dss.c | 20 +------------------- drivers/video/omap2/dss/dss.h | 26 ++++++++------------------ drivers/video/omap2/dss/sdi.c | 25 +++++++++++++++++++++++-- 5 files changed, 71 insertions(+), 41 deletions(-) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index db45e6abe311..77fbd99295dc 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -536,6 +536,18 @@ static int __init omap_dss_register_drivers(void) goto err_dispc; } + r = dpi_init_platform_driver(); + if (r) { + DSSERR("Failed to initialize dpi platform driver\n"); + goto err_dpi; + } + + r = sdi_init_platform_driver(); + if (r) { + DSSERR("Failed to initialize sdi platform driver\n"); + goto err_sdi; + } + r = rfbi_init_platform_driver(); if (r) { DSSERR("Failed to initialize rfbi platform driver\n"); @@ -569,6 +581,10 @@ static int __init omap_dss_register_drivers(void) err_venc: rfbi_uninit_platform_driver(); err_rfbi: + sdi_uninit_platform_driver(); +err_sdi: + dpi_uninit_platform_driver(); +err_dpi: dispc_uninit_platform_driver(); err_dispc: dss_uninit_platform_driver(); @@ -584,6 +600,8 @@ static void __exit omap_dss_unregister_drivers(void) dsi_uninit_platform_driver(); venc_uninit_platform_driver(); rfbi_uninit_platform_driver(); + sdi_uninit_platform_driver(); + dpi_uninit_platform_driver(); dispc_uninit_platform_driver(); dss_uninit_platform_driver(); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index d6e8fe776152..79d242a42607 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -379,12 +379,31 @@ int dpi_init_display(struct omap_dss_device *dssdev) return 0; } -int dpi_init(void) +static int omap_dpi_probe(struct platform_device *pdev) { return 0; } -void dpi_exit(void) +static int omap_dpi_remove(struct platform_device *pdev) { + return 0; } +static struct platform_driver omap_dpi_driver = { + .probe = omap_dpi_probe, + .remove = omap_dpi_remove, + .driver = { + .name = "omapdss_dpi", + .owner = THIS_MODULE, + }, +}; + +int dpi_init_platform_driver(void) +{ + return platform_driver_register(&omap_dpi_driver); +} + +void dpi_uninit_platform_driver(void) +{ + platform_driver_unregister(&omap_dpi_driver); +} diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index c849d8bd5256..7a7ddd8fbf5e 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -786,18 +786,6 @@ static int 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; - r = dpi_init(); - if (r) { - DSSERR("Failed to initialize DPI\n"); - goto err_dpi; - } - - r = sdi_init(); - if (r) { - DSSERR("Failed to initialize SDI\n"); - goto err_sdi; - } - 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)); @@ -805,10 +793,7 @@ static int omap_dsshw_probe(struct platform_device *pdev) dss_runtime_put(); return 0; -err_sdi: - dpi_exit(); -err_dpi: - dss_runtime_put(); + err_runtime_get: pm_runtime_disable(&pdev->dev); dss_put_clocks(); @@ -817,9 +802,6 @@ static int omap_dsshw_probe(struct platform_device *pdev) static int omap_dsshw_remove(struct platform_device *pdev) { - dpi_exit(); - sdi_exit(); - pm_runtime_disable(&pdev->dev); dss_put_clocks(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 848fc9cd65d4..5496134c280b 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -272,17 +272,12 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, /* SDI */ #ifdef CONFIG_OMAP2_DSS_SDI -int sdi_init(void); -void sdi_exit(void); +int sdi_init_platform_driver(void); +void sdi_uninit_platform_driver(void); int sdi_init_display(struct omap_dss_device *display); #else -static inline int sdi_init(void) -{ - return 0; -} -static inline void sdi_exit(void) -{ -} +static inline int sdi_init_platform_driver(void) { return 0; } +static inline void sdi_uninit_platform_driver(void) { } #endif /* DSI */ @@ -384,17 +379,12 @@ static inline struct platform_device *dsi_get_dsidev_from_id(int module) /* DPI */ #ifdef CONFIG_OMAP2_DSS_DPI -int dpi_init(void); -void dpi_exit(void); +int dpi_init_platform_driver(void); +void dpi_uninit_platform_driver(void); int dpi_init_display(struct omap_dss_device *dssdev); #else -static inline int dpi_init(void) -{ - return 0; -} -static inline void dpi_exit(void) -{ -} +static inline int dpi_init_platform_driver(void) { return 0; } +static inline void dpi_uninit_platform_driver(void) { } #endif /* DISPC */ diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 67fbe7cee412..4ae2d8f55048 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include