aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorarchit taneja <archit@ti.com>2011-02-23 03:41:03 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-03-11 08:46:24 -0500
commitaffe360d13e54b415cde2f11cee02369b4ed54bd (patch)
tree5c3b0382ac358351c86e73bb16004cc90aa930ab /drivers
parent371e2081447ce2bc6a25c20b513b9ba33cf5769e (diff)
OMAP: DSS2: Have separate irq handlers for DISPC and DSI
Currently, the core DSS platform device requests for an irq line for OMAP2 and OMAP3. Make DISPC and DSI platform devices request for a shared IRQ line. On OMAP3, the logical OR of DSI and DISPC interrupt lines goes to the MPU. There is a register DSS_IRQSTATUS which tells if the interrupt came from DISPC or DSI. On OMAP2, there is no DSI, only DISPC interrupts goto the MPU. There is no DSS_IRQSTATUS register. Hence, it makes more sense to have separate irq handlers corresponding to the DSS sub modules instead of having a common handler. Since on OMAP3 the logical OR of the lines goes to MPU, the irq line is shared among the IRQ handlers. The hwmod irq info has been removed for DSS to DISPC and DSI for OMAP2 and OMAP3 hwmod databases. The Probes of DISPC and DSI now request for irq handlers. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/omap2/dss/dispc.c40
-rw-r--r--drivers/video/omap2/dss/dsi.c25
-rw-r--r--drivers/video/omap2/dss/dss.c51
3 files changed, 60 insertions, 56 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index dc4518c4b0e..43f7091c71c 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/interrupt.h>
35 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -178,6 +179,7 @@ struct dispc_irq_stats {
178static struct { 179static struct {
179 struct platform_device *pdev; 180 struct platform_device *pdev;
180 void __iomem *base; 181 void __iomem *base;
182 int irq;
181 183
182 u32 fifo_size[3]; 184 u32 fifo_size[3];
183 185
@@ -2865,10 +2867,10 @@ static void print_irq_status(u32 status)
2865 * but we presume they are on because we got an IRQ. However, 2867 * but we presume they are on because we got an IRQ. However,
2866 * an irq handler may turn the clocks off, so we may not have 2868 * an irq handler may turn the clocks off, so we may not have
2867 * clock later in the function. */ 2869 * clock later in the function. */
2868void dispc_irq_handler(void) 2870static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2869{ 2871{
2870 int i; 2872 int i;
2871 u32 irqstatus; 2873 u32 irqstatus, irqenable;
2872 u32 handledirqs = 0; 2874 u32 handledirqs = 0;
2873 u32 unhandled_errors; 2875 u32 unhandled_errors;
2874 struct omap_dispc_isr_data *isr_data; 2876 struct omap_dispc_isr_data *isr_data;
@@ -2877,6 +2879,13 @@ void dispc_irq_handler(void)
2877 spin_lock(&dispc.irq_lock); 2879 spin_lock(&dispc.irq_lock);
2878 2880
2879 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 2881 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
2882 irqenable = dispc_read_reg(DISPC_IRQENABLE);
2883
2884 /* IRQ is not for us */
2885 if (!(irqstatus & irqenable)) {
2886 spin_unlock(&dispc.irq_lock);
2887 return IRQ_NONE;
2888 }
2880 2889
2881#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2890#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2882 spin_lock(&dispc.irq_stats_lock); 2891 spin_lock(&dispc.irq_stats_lock);
@@ -2928,6 +2937,8 @@ void dispc_irq_handler(void)
2928 } 2937 }
2929 2938
2930 spin_unlock(&dispc.irq_lock); 2939 spin_unlock(&dispc.irq_lock);
2940
2941 return IRQ_HANDLED;
2931} 2942}
2932 2943
2933static void dispc_error_worker(struct work_struct *work) 2944static void dispc_error_worker(struct work_struct *work)
@@ -3322,6 +3333,7 @@ int dispc_setup_plane(enum omap_plane plane,
3322static int omap_dispchw_probe(struct platform_device *pdev) 3333static int omap_dispchw_probe(struct platform_device *pdev)
3323{ 3334{
3324 u32 rev; 3335 u32 rev;
3336 int r = 0;
3325 struct resource *dispc_mem; 3337 struct resource *dispc_mem;
3326 3338
3327 dispc.pdev = pdev; 3339 dispc.pdev = pdev;
@@ -3338,12 +3350,27 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3338 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 3350 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3339 if (!dispc_mem) { 3351 if (!dispc_mem) {
3340 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3352 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3341 return -EINVAL; 3353 r = -EINVAL;
3354 goto fail0;
3342 } 3355 }
3343 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); 3356 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3344 if (!dispc.base) { 3357 if (!dispc.base) {
3345 DSSERR("can't ioremap DISPC\n"); 3358 DSSERR("can't ioremap DISPC\n");
3346 return -ENOMEM; 3359 r = -ENOMEM;
3360 goto fail0;
3361 }
3362 dispc.irq = platform_get_irq(dispc.pdev, 0);
3363 if (dispc.irq < 0) {
3364 DSSERR("platform_get_irq failed\n");
3365 r = -ENODEV;
3366 goto fail1;
3367 }
3368
3369 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3370 "OMAP DISPC", dispc.pdev);
3371 if (r < 0) {
3372 DSSERR("request_irq failed\n");
3373 goto fail1;
3347 } 3374 }
3348 3375
3349 enable_clocks(1); 3376 enable_clocks(1);
@@ -3361,10 +3388,15 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3361 enable_clocks(0); 3388 enable_clocks(0);
3362 3389
3363 return 0; 3390 return 0;
3391fail1:
3392 iounmap(dispc.base);
3393fail0:
3394 return r;
3364} 3395}
3365 3396
3366static int omap_dispchw_remove(struct platform_device *pdev) 3397static int omap_dispchw_remove(struct platform_device *pdev)
3367{ 3398{
3399 free_irq(dispc.irq, dispc.pdev);
3368 iounmap(dispc.base); 3400 iounmap(dispc.base);
3369 return 0; 3401 return 0;
3370} 3402}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 2928cddeb3f..2f7d9491cd0 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -222,6 +222,7 @@ static struct
222{ 222{
223 struct platform_device *pdev; 223 struct platform_device *pdev;
224 void __iomem *base; 224 void __iomem *base;
225 int irq;
225 226
226 struct dsi_clock_info current_cinfo; 227 struct dsi_clock_info current_cinfo;
227 228
@@ -480,13 +481,17 @@ static void print_irq_status_cio(u32 status)
480static int debug_irq; 481static int debug_irq;
481 482
482/* called from dss */ 483/* called from dss */
483void dsi_irq_handler(void) 484static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
484{ 485{
485 u32 irqstatus, vcstatus, ciostatus; 486 u32 irqstatus, vcstatus, ciostatus;
486 int i; 487 int i;
487 488
488 irqstatus = dsi_read_reg(DSI_IRQSTATUS); 489 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
489 490
491 /* IRQ is not for us */
492 if (!irqstatus)
493 return IRQ_NONE;
494
490#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 495#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
491 spin_lock(&dsi.irq_stats_lock); 496 spin_lock(&dsi.irq_stats_lock);
492 dsi.irq_stats.irq_count++; 497 dsi.irq_stats.irq_count++;
@@ -564,9 +569,9 @@ void dsi_irq_handler(void)
564#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 569#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
565 spin_unlock(&dsi.irq_stats_lock); 570 spin_unlock(&dsi.irq_stats_lock);
566#endif 571#endif
572 return IRQ_HANDLED;
567} 573}
568 574
569
570static void _dsi_initialize_irq(void) 575static void _dsi_initialize_irq(void)
571{ 576{
572 u32 l; 577 u32 l;
@@ -3293,6 +3298,19 @@ static int dsi_init(struct platform_device *pdev)
3293 r = -ENOMEM; 3298 r = -ENOMEM;
3294 goto err1; 3299 goto err1;
3295 } 3300 }
3301 dsi.irq = platform_get_irq(dsi.pdev, 0);
3302 if (dsi.irq < 0) {
3303 DSSERR("platform_get_irq failed\n");
3304 r = -ENODEV;
3305 goto err2;
3306 }
3307
3308 r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED,
3309 "OMAP DSI1", dsi.pdev);
3310 if (r < 0) {
3311 DSSERR("request_irq failed\n");
3312 goto err2;
3313 }
3296 3314
3297 enable_clocks(1); 3315 enable_clocks(1);
3298 3316
@@ -3303,6 +3321,8 @@ static int dsi_init(struct platform_device *pdev)
3303 enable_clocks(0); 3321 enable_clocks(0);
3304 3322
3305 return 0; 3323 return 0;
3324err2:
3325 iounmap(dsi.base);
3306err1: 3326err1:
3307 destroy_workqueue(dsi.workqueue); 3327 destroy_workqueue(dsi.workqueue);
3308 return r; 3328 return r;
@@ -3315,6 +3335,7 @@ static void dsi_exit(void)
3315 dsi.vdds_dsi_reg = NULL; 3335 dsi.vdds_dsi_reg = NULL;
3316 } 3336 }
3317 3337
3338 free_irq(dsi.irq, dsi.pdev);
3318 iounmap(dsi.base); 3339 iounmap(dsi.base);
3319 3340
3320 destroy_workqueue(dsi.workqueue); 3341 destroy_workqueue(dsi.workqueue);
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index ab82f793767..dc57100cc43 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -26,7 +26,6 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/seq_file.h> 29#include <linux/seq_file.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32 31
@@ -79,7 +78,6 @@ static struct {
79 enum dss_clk_source dispc_clk_source; 78 enum dss_clk_source dispc_clk_source;
80 79
81 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 80 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
82 int dss_irq;
83} dss; 81} dss;
84 82
85static void dss_clk_enable_all_no_ctx(void); 83static void dss_clk_enable_all_no_ctx(void);
@@ -495,31 +493,6 @@ found:
495 return 0; 493 return 0;
496} 494}
497 495
498
499
500static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
501{
502 dispc_irq_handler();
503
504 return IRQ_HANDLED;
505}
506
507static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
508{
509 u32 irqstatus;
510
511 irqstatus = dss_read_reg(DSS_IRQSTATUS);
512
513 if (irqstatus & (1<<0)) /* DISPC_IRQ */
514 dispc_irq_handler();
515#ifdef CONFIG_OMAP2_DSS_DSI
516 if (irqstatus & (1<<1)) /* DSI_IRQ */
517 dsi_irq_handler();
518#endif
519
520 return IRQ_HANDLED;
521}
522
523static int _omap_dss_wait_reset(void) 496static int _omap_dss_wait_reset(void)
524{ 497{
525 int t = 0; 498 int t = 0;
@@ -610,30 +583,12 @@ static int dss_init(bool skip_init)
610 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 583 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
611#endif 584#endif
612 585
613 dss.dss_irq = platform_get_irq(dss.pdev, 0);
614 if (dss.dss_irq < 0) {
615 DSSERR("omap2 dss: platform_get_irq failed\n");
616 r = -ENODEV;
617 goto fail1;
618 }
619
620 r = request_irq(dss.dss_irq,
621 cpu_is_omap24xx()
622 ? dss_irq_handler_omap2
623 : dss_irq_handler_omap3,
624 0, "OMAP DSS", NULL);
625
626 if (r < 0) {
627 DSSERR("omap2 dss: request_irq failed\n");
628 goto fail1;
629 }
630
631 if (cpu_is_omap34xx()) { 586 if (cpu_is_omap34xx()) {
632 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 587 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
633 if (IS_ERR(dss.dpll4_m4_ck)) { 588 if (IS_ERR(dss.dpll4_m4_ck)) {
634 DSSERR("Failed to get dpll4_m4_ck\n"); 589 DSSERR("Failed to get dpll4_m4_ck\n");
635 r = PTR_ERR(dss.dpll4_m4_ck); 590 r = PTR_ERR(dss.dpll4_m4_ck);
636 goto fail2; 591 goto fail1;
637 } 592 }
638 } 593 }
639 594
@@ -648,8 +603,6 @@ static int dss_init(bool skip_init)
648 603
649 return 0; 604 return 0;
650 605
651fail2:
652 free_irq(dss.dss_irq, NULL);
653fail1: 606fail1:
654 iounmap(dss.base); 607 iounmap(dss.base);
655fail0: 608fail0:
@@ -661,8 +614,6 @@ static void dss_exit(void)
661 if (cpu_is_omap34xx()) 614 if (cpu_is_omap34xx())
662 clk_put(dss.dpll4_m4_ck); 615 clk_put(dss.dpll4_m4_ck);
663 616
664 free_irq(dss.dss_irq, NULL);
665
666 iounmap(dss.base); 617 iounmap(dss.base);
667} 618}
668 619