diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-03-02 07:44:27 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-03-15 04:53:29 -0400 |
commit | 69b281a61442f97e8df14babc9bb6a28624886b1 (patch) | |
tree | 069fda76ff74f01045ffe94d3adbfb4289061bf1 /drivers/video/omap2 | |
parent | 49641116392ad7522fa0efad53f7ed63f811bd88 (diff) |
OMAP: DSS2: DSI: Restructure IRQ handler
Clean up the IRQ handler a bit by separating collection of IRQ stats and
handling of IRQ errors to separate functions.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 123 |
1 files changed, 73 insertions, 50 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 7a4b4404a976..b6c08a6f2da1 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -477,26 +477,33 @@ static void print_irq_status_cio(u32 status) | |||
477 | printk("\n"); | 477 | printk("\n"); |
478 | } | 478 | } |
479 | 479 | ||
480 | static int debug_irq; | 480 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
481 | 481 | static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus) | |
482 | /* called from dss */ | ||
483 | static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) | ||
484 | { | 482 | { |
485 | u32 irqstatus, vcstatus, ciostatus; | ||
486 | int i; | 483 | int i; |
487 | 484 | ||
488 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); | ||
489 | |||
490 | /* IRQ is not for us */ | ||
491 | if (!irqstatus) | ||
492 | return IRQ_NONE; | ||
493 | |||
494 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
495 | spin_lock(&dsi.irq_stats_lock); | 485 | spin_lock(&dsi.irq_stats_lock); |
486 | |||
496 | dsi.irq_stats.irq_count++; | 487 | dsi.irq_stats.irq_count++; |
497 | dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); | 488 | dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); |
489 | |||
490 | for (i = 0; i < 4; ++i) | ||
491 | dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]); | ||
492 | |||
493 | dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); | ||
494 | |||
495 | spin_unlock(&dsi.irq_stats_lock); | ||
496 | } | ||
497 | #else | ||
498 | #define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus) | ||
498 | #endif | 499 | #endif |
499 | 500 | ||
501 | static int debug_irq; | ||
502 | |||
503 | static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus) | ||
504 | { | ||
505 | int i; | ||
506 | |||
500 | if (irqstatus & DSI_IRQ_ERROR_MASK) { | 507 | if (irqstatus & DSI_IRQ_ERROR_MASK) { |
501 | DSSERR("DSI error, irqstatus %x\n", irqstatus); | 508 | DSSERR("DSI error, irqstatus %x\n", irqstatus); |
502 | print_irq_status(irqstatus); | 509 | print_irq_status(irqstatus); |
@@ -507,37 +514,48 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) | |||
507 | print_irq_status(irqstatus); | 514 | print_irq_status(irqstatus); |
508 | } | 515 | } |
509 | 516 | ||
510 | #ifdef DSI_CATCH_MISSING_TE | ||
511 | if (irqstatus & DSI_IRQ_TE_TRIGGER) | ||
512 | del_timer(&dsi.te_timer); | ||
513 | #endif | ||
514 | |||
515 | for (i = 0; i < 4; ++i) { | 517 | for (i = 0; i < 4; ++i) { |
516 | if ((irqstatus & (1<<i)) == 0) | 518 | if (vcstatus[i] & DSI_VC_IRQ_ERROR_MASK) { |
517 | continue; | 519 | DSSERR("DSI VC(%d) error, vc irqstatus %x\n", |
520 | i, vcstatus[i]); | ||
521 | print_irq_status_vc(i, vcstatus[i]); | ||
522 | } else if (debug_irq) { | ||
523 | print_irq_status_vc(i, vcstatus[i]); | ||
524 | } | ||
525 | } | ||
518 | 526 | ||
519 | vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); | 527 | if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { |
528 | DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); | ||
529 | print_irq_status_cio(ciostatus); | ||
530 | } else if (debug_irq) { | ||
531 | print_irq_status_cio(ciostatus); | ||
532 | } | ||
533 | } | ||
520 | 534 | ||
521 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 535 | static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) |
522 | dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); | 536 | { |
523 | #endif | 537 | u32 irqstatus, vcstatus[4], ciostatus; |
538 | int i; | ||
524 | 539 | ||
525 | if (vcstatus & DSI_VC_IRQ_BTA) { | 540 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); |
526 | complete(&dsi.bta_completion); | ||
527 | 541 | ||
528 | if (dsi.bta_callback) | 542 | /* IRQ is not for us */ |
529 | dsi.bta_callback(); | 543 | if (!irqstatus) |
530 | } | 544 | return IRQ_NONE; |
531 | 545 | ||
532 | if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { | 546 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); |
533 | DSSERR("DSI VC(%d) error, vc irqstatus %x\n", | 547 | /* flush posted write */ |
534 | i, vcstatus); | 548 | dsi_read_reg(DSI_IRQSTATUS); |
535 | print_irq_status_vc(i, vcstatus); | 549 | |
536 | } else if (debug_irq) { | 550 | for (i = 0; i < 4; ++i) { |
537 | print_irq_status_vc(i, vcstatus); | 551 | if ((irqstatus & (1 << i)) == 0) { |
552 | vcstatus[i] = 0; | ||
553 | continue; | ||
538 | } | 554 | } |
539 | 555 | ||
540 | dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); | 556 | vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i)); |
557 | |||
558 | dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]); | ||
541 | /* flush posted write */ | 559 | /* flush posted write */ |
542 | dsi_read_reg(DSI_VC_IRQSTATUS(i)); | 560 | dsi_read_reg(DSI_VC_IRQSTATUS(i)); |
543 | } | 561 | } |
@@ -545,29 +563,34 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) | |||
545 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { | 563 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { |
546 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 564 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); |
547 | 565 | ||
548 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
549 | dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); | ||
550 | #endif | ||
551 | |||
552 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); | 566 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); |
553 | /* flush posted write */ | 567 | /* flush posted write */ |
554 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 568 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); |
569 | } else { | ||
570 | ciostatus = 0; | ||
571 | } | ||
555 | 572 | ||
556 | if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { | 573 | #ifdef DSI_CATCH_MISSING_TE |
557 | DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); | 574 | if (irqstatus & DSI_IRQ_TE_TRIGGER) |
558 | print_irq_status_cio(ciostatus); | 575 | del_timer(&dsi.te_timer); |
559 | } else if (debug_irq) { | 576 | #endif |
560 | print_irq_status_cio(ciostatus); | 577 | |
578 | for (i = 0; i < 4; ++i) { | ||
579 | if (vcstatus[i] == 0) | ||
580 | continue; | ||
581 | |||
582 | if (vcstatus[i] & DSI_VC_IRQ_BTA) { | ||
583 | complete(&dsi.bta_completion); | ||
584 | |||
585 | if (dsi.bta_callback) | ||
586 | dsi.bta_callback(); | ||
561 | } | 587 | } |
562 | } | 588 | } |
563 | 589 | ||
564 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); | 590 | dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus); |
565 | /* flush posted write */ | 591 | |
566 | dsi_read_reg(DSI_IRQSTATUS); | 592 | dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus); |
567 | 593 | ||
568 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
569 | spin_unlock(&dsi.irq_stats_lock); | ||
570 | #endif | ||
571 | return IRQ_HANDLED; | 594 | return IRQ_HANDLED; |
572 | } | 595 | } |
573 | 596 | ||