aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/dispc.c55
-rw-r--r--drivers/video/omap2/dss/dsi.c20
2 files changed, 68 insertions, 7 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 2bbdb7ff7daf..b37e3fbf60cc 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -101,6 +101,8 @@ static struct {
101 void __iomem *base; 101 void __iomem *base;
102 102
103 int irq; 103 int irq;
104 irq_handler_t user_handler;
105 void *user_data;
104 106
105 unsigned long core_clk_rate; 107 unsigned long core_clk_rate;
106 unsigned long tv_pclk_rate; 108 unsigned long tv_pclk_rate;
@@ -113,6 +115,8 @@ static struct {
113 u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; 115 u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
114 116
115 const struct dispc_features *feat; 117 const struct dispc_features *feat;
118
119 bool is_enabled;
116} dispc; 120} dispc;
117 121
118enum omap_color_component { 122enum omap_color_component {
@@ -3669,16 +3673,44 @@ static int __init dispc_init_features(struct platform_device *pdev)
3669 return 0; 3673 return 0;
3670} 3674}
3671 3675
3676static irqreturn_t dispc_irq_handler(int irq, void *arg)
3677{
3678 if (!dispc.is_enabled)
3679 return IRQ_NONE;
3680
3681 return dispc.user_handler(irq, dispc.user_data);
3682}
3683
3672int dispc_request_irq(irq_handler_t handler, void *dev_id) 3684int dispc_request_irq(irq_handler_t handler, void *dev_id)
3673{ 3685{
3674 return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler, 3686 int r;
3675 IRQF_SHARED, "OMAP DISPC", dev_id); 3687
3688 if (dispc.user_handler != NULL)
3689 return -EBUSY;
3690
3691 dispc.user_handler = handler;
3692 dispc.user_data = dev_id;
3693
3694 /* ensure the dispc_irq_handler sees the values above */
3695 smp_wmb();
3696
3697 r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
3698 IRQF_SHARED, "OMAP DISPC", &dispc);
3699 if (r) {
3700 dispc.user_handler = NULL;
3701 dispc.user_data = NULL;
3702 }
3703
3704 return r;
3676} 3705}
3677EXPORT_SYMBOL(dispc_request_irq); 3706EXPORT_SYMBOL(dispc_request_irq);
3678 3707
3679void dispc_free_irq(void *dev_id) 3708void dispc_free_irq(void *dev_id)
3680{ 3709{
3681 devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id); 3710 devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
3711
3712 dispc.user_handler = NULL;
3713 dispc.user_data = NULL;
3682} 3714}
3683EXPORT_SYMBOL(dispc_free_irq); 3715EXPORT_SYMBOL(dispc_free_irq);
3684 3716
@@ -3750,6 +3782,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
3750 3782
3751static int dispc_runtime_suspend(struct device *dev) 3783static int dispc_runtime_suspend(struct device *dev)
3752{ 3784{
3785 dispc.is_enabled = false;
3786 /* ensure the dispc_irq_handler sees the is_enabled value */
3787 smp_wmb();
3788 /* wait for current handler to finish before turning the DISPC off */
3789 synchronize_irq(dispc.irq);
3790
3753 dispc_save_context(); 3791 dispc_save_context();
3754 3792
3755 return 0; 3793 return 0;
@@ -3763,12 +3801,15 @@ static int dispc_runtime_resume(struct device *dev)
3763 * _omap_dispc_initial_config(). We can thus use it to detect if 3801 * _omap_dispc_initial_config(). We can thus use it to detect if
3764 * we have lost register context. 3802 * we have lost register context.
3765 */ 3803 */
3766 if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY) 3804 if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
3767 return 0; 3805 _omap_dispc_initial_config();
3768 3806
3769 _omap_dispc_initial_config(); 3807 dispc_restore_context();
3808 }
3770 3809
3771 dispc_restore_context(); 3810 dispc.is_enabled = true;
3811 /* ensure the dispc_irq_handler sees the is_enabled value */
3812 smp_wmb();
3772 3813
3773 return 0; 3814 return 0;
3774} 3815}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 121d1049d0bc..8be9b04d8849 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -297,6 +297,8 @@ struct dsi_data {
297 297
298 int irq; 298 int irq;
299 299
300 bool is_enabled;
301
300 struct clk *dss_clk; 302 struct clk *dss_clk;
301 struct clk *sys_clk; 303 struct clk *sys_clk;
302 304
@@ -795,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
795 dsidev = (struct platform_device *) arg; 797 dsidev = (struct platform_device *) arg;
796 dsi = dsi_get_dsidrv_data(dsidev); 798 dsi = dsi_get_dsidrv_data(dsidev);
797 799
800 if (!dsi->is_enabled)
801 return IRQ_NONE;
802
798 spin_lock(&dsi->irq_lock); 803 spin_lock(&dsi->irq_lock);
799 804
800 irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); 805 irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
@@ -5671,6 +5676,15 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5671 5676
5672static int dsi_runtime_suspend(struct device *dev) 5677static int dsi_runtime_suspend(struct device *dev)
5673{ 5678{
5679 struct platform_device *pdev = to_platform_device(dev);
5680 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5681
5682 dsi->is_enabled = false;
5683 /* ensure the irq handler sees the is_enabled value */
5684 smp_wmb();
5685 /* wait for current handler to finish before turning the DSI off */
5686 synchronize_irq(dsi->irq);
5687
5674 dispc_runtime_put(); 5688 dispc_runtime_put();
5675 5689
5676 return 0; 5690 return 0;
@@ -5678,12 +5692,18 @@ static int dsi_runtime_suspend(struct device *dev)
5678 5692
5679static int dsi_runtime_resume(struct device *dev) 5693static int dsi_runtime_resume(struct device *dev)
5680{ 5694{
5695 struct platform_device *pdev = to_platform_device(dev);
5696 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5681 int r; 5697 int r;
5682 5698
5683 r = dispc_runtime_get(); 5699 r = dispc_runtime_get();
5684 if (r) 5700 if (r)
5685 return r; 5701 return r;
5686 5702
5703 dsi->is_enabled = true;
5704 /* ensure the irq handler sees the is_enabled value */
5705 smp_wmb();
5706
5687 return 0; 5707 return 0;
5688} 5708}
5689 5709