aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-10-10 06:59:07 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-07 10:05:55 -0500
commit1550202d4a7593655a2aca99e39a58751073c92a (patch)
tree21c11abba54b61aca5f527ff0b40efb4dc76a38d /drivers/video/omap2
parent74b65ec24560ab0df0e7b789fa91cde4a442f169 (diff)
OMAPDSS: manage framedone irq with mgr ops
Some of the output drivers need to handle FRAMEDONE interrupt from DISPC. This creates a direct dependency to dispc code, and we need to avoid this to make the compat code to work. Instead of the output drivers registering for dispc interrupts, we create new mgr-ops that are used to register a framedone handler. The code implementing the mgr-ops is responsible for calling the handler when DISPC FRAMEDONE interrupt happens. The compat layer is improved accordingly to do the call to the framedone handler. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/dss/apply.c46
-rw-r--r--drivers/video/omap2/dss/dsi.c26
-rw-r--r--drivers/video/omap2/dss/dss.h8
-rw-r--r--drivers/video/omap2/dss/output.c12
-rw-r--r--drivers/video/omap2/dss/rfbi.c12
5 files changed, 82 insertions, 22 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 70eaa8f70e97..5952f149c91a 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -105,6 +105,9 @@ struct mgr_priv_data {
105 105
106 struct omap_video_timings timings; 106 struct omap_video_timings timings;
107 struct dss_lcd_mgr_config lcd_config; 107 struct dss_lcd_mgr_config lcd_config;
108
109 void (*framedone_handler)(void *);
110 void *framedone_handler_data;
108}; 111};
109 112
110static struct { 113static struct {
@@ -888,6 +891,21 @@ static void dss_apply_irq_handler(void *data, u32 mask)
888 if (!extra_updating) 891 if (!extra_updating)
889 complete_all(&extra_updated_completion); 892 complete_all(&extra_updated_completion);
890 893
894 /* call framedone handlers for manual update displays */
895 for (i = 0; i < num_mgrs; i++) {
896 struct omap_overlay_manager *mgr;
897 struct mgr_priv_data *mp;
898
899 mgr = omap_dss_get_overlay_manager(i);
900 mp = get_mgr_priv(mgr);
901
902 if (!mgr_manual_update(mgr) || !mp->framedone_handler)
903 continue;
904
905 if (mask & dispc_mgr_get_framedone_irq(i))
906 mp->framedone_handler(mp->framedone_handler_data);
907 }
908
891 if (!need_isr()) 909 if (!need_isr())
892 dss_unregister_vsync_isr(); 910 dss_unregister_vsync_isr();
893 911
@@ -1501,12 +1519,40 @@ err:
1501 return r; 1519 return r;
1502} 1520}
1503 1521
1522static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager *mgr,
1523 void (*handler)(void *), void *data)
1524{
1525 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1526
1527 if (mp->framedone_handler)
1528 return -EBUSY;
1529
1530 mp->framedone_handler = handler;
1531 mp->framedone_handler_data = data;
1532
1533 return 0;
1534}
1535
1536static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager *mgr,
1537 void (*handler)(void *), void *data)
1538{
1539 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1540
1541 WARN_ON(mp->framedone_handler != handler ||
1542 mp->framedone_handler_data != data);
1543
1544 mp->framedone_handler = NULL;
1545 mp->framedone_handler_data = NULL;
1546}
1547
1504static const struct dss_mgr_ops apply_mgr_ops = { 1548static const struct dss_mgr_ops apply_mgr_ops = {
1505 .start_update = dss_mgr_start_update_compat, 1549 .start_update = dss_mgr_start_update_compat,
1506 .enable = dss_mgr_enable_compat, 1550 .enable = dss_mgr_enable_compat,
1507 .disable = dss_mgr_disable_compat, 1551 .disable = dss_mgr_disable_compat,
1508 .set_timings = dss_mgr_set_timings_compat, 1552 .set_timings = dss_mgr_set_timings_compat,
1509 .set_lcd_config = dss_mgr_set_lcd_config_compat, 1553 .set_lcd_config = dss_mgr_set_lcd_config_compat,
1554 .register_framedone_handler = dss_mgr_register_framedone_handler_compat,
1555 .unregister_framedone_handler = dss_mgr_unregister_framedone_handler_compat,
1510}; 1556};
1511 1557
1512static int compat_refcnt; 1558static int compat_refcnt;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index db9663dcfbd0..28d41d16b7be 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4535,7 +4535,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
4535 dsi_handle_framedone(dsi->pdev, -ETIMEDOUT); 4535 dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
4536} 4536}
4537 4537
4538static void dsi_framedone_irq_callback(void *data, u32 mask) 4538static void dsi_framedone_irq_callback(void *data)
4539{ 4539{
4540 struct platform_device *dsidev = (struct platform_device *) data; 4540 struct platform_device *dsidev = (struct platform_device *) data;
4541 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4541 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4609,7 +4609,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4609 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4609 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4610 struct omap_overlay_manager *mgr = dssdev->output->manager; 4610 struct omap_overlay_manager *mgr = dssdev->output->manager;
4611 int r; 4611 int r;
4612 u32 irq = 0;
4613 4612
4614 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4613 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
4615 dsi->timings.hsw = 1; 4614 dsi->timings.hsw = 1;
@@ -4619,12 +4618,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4619 dsi->timings.vfp = 0; 4618 dsi->timings.vfp = 0;
4620 dsi->timings.vbp = 0; 4619 dsi->timings.vbp = 0;
4621 4620
4622 irq = dispc_mgr_get_framedone_irq(mgr->id); 4621 r = dss_mgr_register_framedone_handler(mgr,
4623 4622 dsi_framedone_irq_callback, dsidev);
4624 r = omap_dispc_register_isr(dsi_framedone_irq_callback,
4625 (void *) dsidev, irq);
4626 if (r) { 4623 if (r) {
4627 DSSERR("can't get FRAMEDONE irq\n"); 4624 DSSERR("can't register FRAMEDONE handler\n");
4628 goto err; 4625 goto err;
4629 } 4626 }
4630 4627
@@ -4662,8 +4659,8 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4662 return 0; 4659 return 0;
4663err1: 4660err1:
4664 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) 4661 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
4665 omap_dispc_unregister_isr(dsi_framedone_irq_callback, 4662 dss_mgr_unregister_framedone_handler(mgr,
4666 (void *) dsidev, irq); 4663 dsi_framedone_irq_callback, dsidev);
4667err: 4664err:
4668 return r; 4665 return r;
4669} 4666}
@@ -4674,14 +4671,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
4674 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4671 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4675 struct omap_overlay_manager *mgr = dssdev->output->manager; 4672 struct omap_overlay_manager *mgr = dssdev->output->manager;
4676 4673
4677 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4674 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
4678 u32 irq; 4675 dss_mgr_unregister_framedone_handler(mgr,
4679 4676 dsi_framedone_irq_callback, dsidev);
4680 irq = dispc_mgr_get_framedone_irq(mgr->id);
4681
4682 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4683 (void *) dsidev, irq);
4684 }
4685} 4677}
4686 4678
4687static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4679static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5cc13ea2b5a7..8ae73670aa37 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -185,6 +185,10 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
185 const struct omap_video_timings *timings); 185 const struct omap_video_timings *timings);
186void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 186void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
187 const struct dss_lcd_mgr_config *config); 187 const struct dss_lcd_mgr_config *config);
188int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
189 void (*handler)(void *), void *data);
190void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
191 void (*handler)(void *), void *data);
188 192
189/* output */ 193/* output */
190void dss_register_output(struct omap_dss_output *out); 194void dss_register_output(struct omap_dss_output *out);
@@ -531,6 +535,10 @@ struct dss_mgr_ops {
531 const struct omap_video_timings *timings); 535 const struct omap_video_timings *timings);
532 void (*set_lcd_config)(struct omap_overlay_manager *mgr, 536 void (*set_lcd_config)(struct omap_overlay_manager *mgr,
533 const struct dss_lcd_mgr_config *config); 537 const struct dss_lcd_mgr_config *config);
538 int (*register_framedone_handler)(struct omap_overlay_manager *mgr,
539 void (*handler)(void *), void *data);
540 void (*unregister_framedone_handler)(struct omap_overlay_manager *mgr,
541 void (*handler)(void *), void *data);
534}; 542};
535 543
536int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); 544int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 9527ee6a769e..6def0d7bbd05 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -157,3 +157,15 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
157{ 157{
158 dss_mgr_ops->start_update(mgr); 158 dss_mgr_ops->start_update(mgr);
159} 159}
160
161int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
162 void (*handler)(void *), void *data)
163{
164 return dss_mgr_ops->register_framedone_handler(mgr, handler, data);
165}
166
167void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
168 void (*handler)(void *), void *data)
169{
170 dss_mgr_ops->unregister_framedone_handler(mgr, handler, data);
171}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index ec9fde52716c..e903dd3f54d9 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -342,7 +342,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
342 return 0; 342 return 0;
343} 343}
344 344
345static void framedone_callback(void *data, u32 mask) 345static void framedone_callback(void *data)
346{ 346{
347 void (*callback)(void *data); 347 void (*callback)(void *data);
348 348
@@ -908,8 +908,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
908 goto err0; 908 goto err0;
909 } 909 }
910 910
911 r = omap_dispc_register_isr(framedone_callback, NULL, 911 r = dss_mgr_register_framedone_handler(out->manager,
912 DISPC_IRQ_FRAMEDONE); 912 framedone_callback, NULL);
913 if (r) { 913 if (r) {
914 DSSERR("can't get FRAMEDONE irq\n"); 914 DSSERR("can't get FRAMEDONE irq\n");
915 goto err1; 915 goto err1;
@@ -933,8 +933,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
933 933
934void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) 934void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
935{ 935{
936 omap_dispc_unregister_isr(framedone_callback, NULL, 936 struct omap_dss_output *out = dssdev->output;
937 DISPC_IRQ_FRAMEDONE); 937
938 dss_mgr_unregister_framedone_handler(out->manager,
939 framedone_callback, NULL);
938 omap_dss_stop_device(dssdev); 940 omap_dss_stop_device(dssdev);
939 941
940 rfbi_runtime_put(); 942 rfbi_runtime_put();