diff options
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority-sc.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-sc.c | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c index 147f0731087a..dec42acb5de0 100644 --- a/arch/blackfin/mach-common/ints-priority-sc.c +++ b/arch/blackfin/mach-common/ints-priority-sc.c | |||
@@ -313,6 +313,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
313 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 313 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
314 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 314 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
315 | 315 | ||
316 | |||
316 | static void bfin_gpio_ack_irq(unsigned int irq) | 317 | static void bfin_gpio_ack_irq(unsigned int irq) |
317 | { | 318 | { |
318 | u16 gpionr = irq - IRQ_PF0; | 319 | u16 gpionr = irq - IRQ_PF0; |
@@ -352,9 +353,11 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
352 | { | 353 | { |
353 | unsigned int ret; | 354 | unsigned int ret; |
354 | u16 gpionr = irq - IRQ_PF0; | 355 | u16 gpionr = irq - IRQ_PF0; |
356 | char buf[8]; | ||
355 | 357 | ||
356 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 358 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
357 | ret = gpio_request(gpionr, "IRQ"); | 359 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
360 | ret = gpio_request(gpionr, buf); | ||
358 | if (ret) | 361 | if (ret) |
359 | return ret; | 362 | return ret; |
360 | } | 363 | } |
@@ -376,6 +379,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
376 | { | 379 | { |
377 | 380 | ||
378 | unsigned int ret; | 381 | unsigned int ret; |
382 | char buf[8]; | ||
379 | u16 gpionr = irq - IRQ_PF0; | 383 | u16 gpionr = irq - IRQ_PF0; |
380 | 384 | ||
381 | if (type == IRQ_TYPE_PROBE) { | 385 | if (type == IRQ_TYPE_PROBE) { |
@@ -388,7 +392,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
388 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 392 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
389 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 393 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
390 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 394 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
391 | ret = gpio_request(gpionr, "IRQ"); | 395 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
396 | ret = gpio_request(gpionr, buf); | ||
392 | if (ret) | 397 | if (ret) |
393 | return ret; | 398 | return ret; |
394 | } | 399 | } |
@@ -478,6 +483,10 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq, | |||
478 | static unsigned char irq2pint_lut[NR_PINTS]; | 483 | static unsigned char irq2pint_lut[NR_PINTS]; |
479 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | 484 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; |
480 | 485 | ||
486 | static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS]; | ||
487 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
488 | |||
489 | |||
481 | struct pin_int_t { | 490 | struct pin_int_t { |
482 | unsigned int mask_set; | 491 | unsigned int mask_set; |
483 | unsigned int mask_clear; | 492 | unsigned int mask_clear; |
@@ -544,13 +553,20 @@ void init_pint_lut(void) | |||
544 | 553 | ||
545 | } | 554 | } |
546 | 555 | ||
547 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
548 | |||
549 | static void bfin_gpio_ack_irq(unsigned int irq) | 556 | static void bfin_gpio_ack_irq(unsigned int irq) |
550 | { | 557 | { |
551 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 558 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
559 | u32 pintbit = PINT_BIT(pint_val); | ||
560 | u8 bank = PINT_2_BANK(pint_val); | ||
561 | |||
562 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | ||
563 | if (pint[bank]->invert_set & pintbit) | ||
564 | pint[bank]->invert_clear = pintbit; | ||
565 | else | ||
566 | pint[bank]->invert_set = pintbit; | ||
567 | } | ||
568 | pint[bank]->request = pintbit; | ||
552 | 569 | ||
553 | pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val); | ||
554 | SSYNC(); | 570 | SSYNC(); |
555 | } | 571 | } |
556 | 572 | ||
@@ -560,6 +576,13 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq) | |||
560 | u32 pintbit = PINT_BIT(pint_val); | 576 | u32 pintbit = PINT_BIT(pint_val); |
561 | u8 bank = PINT_2_BANK(pint_val); | 577 | u8 bank = PINT_2_BANK(pint_val); |
562 | 578 | ||
579 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | ||
580 | if (pint[bank]->invert_set & pintbit) | ||
581 | pint[bank]->invert_clear = pintbit; | ||
582 | else | ||
583 | pint[bank]->invert_set = pintbit; | ||
584 | } | ||
585 | |||
563 | pint[bank]->request = pintbit; | 586 | pint[bank]->request = pintbit; |
564 | pint[bank]->mask_clear = pintbit; | 587 | pint[bank]->mask_clear = pintbit; |
565 | SSYNC(); | 588 | SSYNC(); |
@@ -587,7 +610,8 @@ static void bfin_gpio_unmask_irq(unsigned int irq) | |||
587 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 610 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
588 | { | 611 | { |
589 | unsigned int ret; | 612 | unsigned int ret; |
590 | u16 gpionr = irq - IRQ_PA0; | 613 | char buf[8]; |
614 | u16 gpionr = irq_to_gpio(irq); | ||
591 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 615 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
592 | 616 | ||
593 | if (pint_val == IRQ_NOT_AVAIL) { | 617 | if (pint_val == IRQ_NOT_AVAIL) { |
@@ -598,7 +622,8 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
598 | } | 622 | } |
599 | 623 | ||
600 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 624 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
601 | ret = gpio_request(gpionr, "IRQ"); | 625 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
626 | ret = gpio_request(gpionr, buf); | ||
602 | if (ret) | 627 | if (ret) |
603 | return ret; | 628 | return ret; |
604 | } | 629 | } |
@@ -611,16 +636,19 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
611 | 636 | ||
612 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 637 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
613 | { | 638 | { |
639 | u16 gpionr = irq_to_gpio(irq); | ||
640 | |||
614 | bfin_gpio_mask_irq(irq); | 641 | bfin_gpio_mask_irq(irq); |
615 | gpio_free(irq - IRQ_PA0); | 642 | gpio_free(gpionr); |
616 | gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0); | 643 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); |
617 | } | 644 | } |
618 | 645 | ||
619 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 646 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
620 | { | 647 | { |
621 | 648 | ||
622 | unsigned int ret; | 649 | unsigned int ret; |
623 | u16 gpionr = irq - IRQ_PA0; | 650 | char buf[8]; |
651 | u16 gpionr = irq_to_gpio(irq); | ||
624 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 652 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
625 | u32 pintbit = PINT_BIT(pint_val); | 653 | u32 pintbit = PINT_BIT(pint_val); |
626 | u8 bank = PINT_2_BANK(pint_val); | 654 | u8 bank = PINT_2_BANK(pint_val); |
@@ -638,7 +666,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
638 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 666 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
639 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 667 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
640 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 668 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
641 | ret = gpio_request(gpionr, "IRQ"); | 669 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
670 | ret = gpio_request(gpionr, buf); | ||
642 | if (ret) | 671 | if (ret) |
643 | return ret; | 672 | return ret; |
644 | } | 673 | } |
@@ -651,28 +680,33 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
651 | 680 | ||
652 | gpio_direction_input(gpionr); | 681 | gpio_direction_input(gpionr); |
653 | 682 | ||
654 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | ||
655 | pint[bank]->edge_set = pintbit; | ||
656 | } else { | ||
657 | pint[bank]->edge_clear = pintbit; | ||
658 | } | ||
659 | |||
660 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | 683 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) |
661 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ | 684 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ |
662 | else | 685 | else |
663 | pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */ | 686 | pint[bank]->invert_clear = pintbit; /* high or rising edge denoted by zero */ |
664 | 687 | ||
665 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 688 | if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
666 | pint[bank]->invert_set = pintbit; | 689 | == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
667 | else | ||
668 | pint[bank]->invert_set = pintbit; | ||
669 | 690 | ||
670 | SSYNC(); | 691 | gpio_both_edge_triggered[bank] |= pintbit; |
671 | 692 | ||
672 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 693 | if (gpio_get_value(gpionr)) |
694 | pint[bank]->invert_set = pintbit; | ||
695 | else | ||
696 | pint[bank]->invert_clear = pintbit; | ||
697 | } else { | ||
698 | gpio_both_edge_triggered[bank] &= ~pintbit; | ||
699 | } | ||
700 | |||
701 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | ||
702 | pint[bank]->edge_set = pintbit; | ||
673 | set_irq_handler(irq, handle_edge_irq); | 703 | set_irq_handler(irq, handle_edge_irq); |
674 | else | 704 | } else { |
705 | pint[bank]->edge_clear = pintbit; | ||
675 | set_irq_handler(irq, handle_level_irq); | 706 | set_irq_handler(irq, handle_level_irq); |
707 | } | ||
708 | |||
709 | SSYNC(); | ||
676 | 710 | ||
677 | return 0; | 711 | return 0; |
678 | } | 712 | } |