diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2008-11-18 04:48:22 -0500 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-11-18 04:48:22 -0500 |
commit | 8d0223744f531168d4ae87f33354d12a50402779 (patch) | |
tree | ac8c565acd08f03b41259a80444239085103e07a /arch/blackfin/mach-common/ints-priority.c | |
parent | 4989dbc17f085031885c3d898d95ce951fbd20aa (diff) |
Blackfin arch: Cleanup and unify Blackfin IRQ and GPIO IRQ handling
- Remove SSYNC()
- Use irq_to_gpio where applicable
- Remove gpio_edge_triggered bitfield, check irq_desc fields instead.
- Remove gpio_both_edge_triggeredb bitfield, check irq_desc fields
instead.
- Use BITMAP and bitops on gpio_enabled
- Preferably use 32-bit
- Looking at the disassembly this indeed saves quite a few instructions.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 191 |
1 files changed, 66 insertions, 125 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 25ad25ed9783..d45d0c59fac7 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -1,9 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File: arch/blackfin/mach-common/ints-priority.c | 2 | * File: arch/blackfin/mach-common/ints-priority.c |
3 | * Based on: | ||
4 | * Author: | ||
5 | * | 3 | * |
6 | * Created: ? | ||
7 | * Description: Set up the interrupt priorities | 4 | * Description: Set up the interrupt priorities |
8 | * | 5 | * |
9 | * Modified: | 6 | * Modified: |
@@ -186,7 +183,7 @@ static void bfin_internal_unmask_irq(unsigned int irq) | |||
186 | #ifdef CONFIG_PM | 183 | #ifdef CONFIG_PM |
187 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) | 184 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) |
188 | { | 185 | { |
189 | unsigned bank, bit, wakeup = 0; | 186 | u32 bank, bit, wakeup = 0; |
190 | unsigned long flags; | 187 | unsigned long flags; |
191 | bank = SIC_SYSIRQ(irq) / 32; | 188 | bank = SIC_SYSIRQ(irq) / 32; |
192 | bit = SIC_SYSIRQ(irq) % 32; | 189 | bit = SIC_SYSIRQ(irq) % 32; |
@@ -293,8 +290,6 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
293 | { | 290 | { |
294 | int irq = 0; | 291 | int irq = 0; |
295 | 292 | ||
296 | SSYNC(); | ||
297 | |||
298 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) | 293 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) |
299 | if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) | 294 | if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) |
300 | irq = IRQ_MAC_ERROR; | 295 | irq = IRQ_MAC_ERROR; |
@@ -373,56 +368,47 @@ static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) | |||
373 | desc->handle_irq = handle; | 368 | desc->handle_irq = handle; |
374 | } | 369 | } |
375 | 370 | ||
376 | #if !defined(CONFIG_BF54x) | 371 | static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS); |
377 | |||
378 | static unsigned short gpio_enabled[GPIO_BANK_NUM]; | ||
379 | static unsigned short gpio_edge_triggered[GPIO_BANK_NUM]; | ||
380 | |||
381 | extern void bfin_gpio_irq_prepare(unsigned gpio); | 372 | extern void bfin_gpio_irq_prepare(unsigned gpio); |
382 | 373 | ||
374 | #if !defined(CONFIG_BF54x) | ||
375 | |||
383 | static void bfin_gpio_ack_irq(unsigned int irq) | 376 | static void bfin_gpio_ack_irq(unsigned int irq) |
384 | { | 377 | { |
385 | u16 gpionr = irq - IRQ_PF0; | 378 | /* AFAIK ack_irq in case mask_ack is provided |
386 | 379 | * get's only called for edge sense irqs | |
387 | if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { | 380 | */ |
388 | set_gpio_data(gpionr, 0); | 381 | set_gpio_data(irq_to_gpio(irq), 0); |
389 | SSYNC(); | ||
390 | } | ||
391 | } | 382 | } |
392 | 383 | ||
393 | static void bfin_gpio_mask_ack_irq(unsigned int irq) | 384 | static void bfin_gpio_mask_ack_irq(unsigned int irq) |
394 | { | 385 | { |
395 | u16 gpionr = irq - IRQ_PF0; | 386 | struct irq_desc *desc = irq_desc + irq; |
387 | u32 gpionr = irq_to_gpio(irq); | ||
396 | 388 | ||
397 | if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { | 389 | if (desc->handle_irq == handle_edge_irq) |
398 | set_gpio_data(gpionr, 0); | 390 | set_gpio_data(gpionr, 0); |
399 | SSYNC(); | ||
400 | } | ||
401 | 391 | ||
402 | set_gpio_maska(gpionr, 0); | 392 | set_gpio_maska(gpionr, 0); |
403 | SSYNC(); | ||
404 | } | 393 | } |
405 | 394 | ||
406 | static void bfin_gpio_mask_irq(unsigned int irq) | 395 | static void bfin_gpio_mask_irq(unsigned int irq) |
407 | { | 396 | { |
408 | set_gpio_maska(irq - IRQ_PF0, 0); | 397 | set_gpio_maska(irq_to_gpio(irq), 0); |
409 | SSYNC(); | ||
410 | } | 398 | } |
411 | 399 | ||
412 | static void bfin_gpio_unmask_irq(unsigned int irq) | 400 | static void bfin_gpio_unmask_irq(unsigned int irq) |
413 | { | 401 | { |
414 | set_gpio_maska(irq - IRQ_PF0, 1); | 402 | set_gpio_maska(irq_to_gpio(irq), 1); |
415 | SSYNC(); | ||
416 | } | 403 | } |
417 | 404 | ||
418 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 405 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
419 | { | 406 | { |
420 | u16 gpionr = irq - IRQ_PF0; | 407 | u32 gpionr = irq_to_gpio(irq); |
421 | 408 | ||
422 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 409 | if (__test_and_set_bit(gpionr, gpio_enabled)) |
423 | bfin_gpio_irq_prepare(gpionr); | 410 | bfin_gpio_irq_prepare(gpionr); |
424 | 411 | ||
425 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
426 | bfin_gpio_unmask_irq(irq); | 412 | bfin_gpio_unmask_irq(irq); |
427 | 413 | ||
428 | return 0; | 414 | return 0; |
@@ -431,28 +417,28 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
431 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 417 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
432 | { | 418 | { |
433 | bfin_gpio_mask_irq(irq); | 419 | bfin_gpio_mask_irq(irq); |
434 | gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); | 420 | __clear_bit(irq_to_gpio(irq), gpio_enabled); |
435 | } | 421 | } |
436 | 422 | ||
437 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 423 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
438 | { | 424 | { |
439 | u16 gpionr = irq - IRQ_PF0; | 425 | u32 gpionr = irq_to_gpio(irq); |
440 | 426 | ||
441 | if (type == IRQ_TYPE_PROBE) { | 427 | if (type == IRQ_TYPE_PROBE) { |
442 | /* only probe unenabled GPIO interrupt lines */ | 428 | /* only probe unenabled GPIO interrupt lines */ |
443 | if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) | 429 | if (__test_bit(gpionr, gpio_enabled)) |
444 | return 0; | 430 | return 0; |
445 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 431 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
446 | } | 432 | } |
447 | 433 | ||
448 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 434 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
449 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 435 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
450 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 436 | |
437 | if (__test_and_set_bit(gpionr, gpio_enabled)) | ||
451 | bfin_gpio_irq_prepare(gpionr); | 438 | bfin_gpio_irq_prepare(gpionr); |
452 | 439 | ||
453 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
454 | } else { | 440 | } else { |
455 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 441 | __clear_bit(gpionr, gpio_enabled); |
456 | return 0; | 442 | return 0; |
457 | } | 443 | } |
458 | 444 | ||
@@ -473,17 +459,13 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
473 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | 459 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
474 | set_gpio_edge(gpionr, 1); | 460 | set_gpio_edge(gpionr, 1); |
475 | set_gpio_inen(gpionr, 1); | 461 | set_gpio_inen(gpionr, 1); |
476 | gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
477 | set_gpio_data(gpionr, 0); | 462 | set_gpio_data(gpionr, 0); |
478 | 463 | ||
479 | } else { | 464 | } else { |
480 | set_gpio_edge(gpionr, 0); | 465 | set_gpio_edge(gpionr, 0); |
481 | gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | ||
482 | set_gpio_inen(gpionr, 1); | 466 | set_gpio_inen(gpionr, 1); |
483 | } | 467 | } |
484 | 468 | ||
485 | SSYNC(); | ||
486 | |||
487 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 469 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
488 | bfin_set_irq_handler(irq, handle_edge_irq); | 470 | bfin_set_irq_handler(irq, handle_edge_irq); |
489 | else | 471 | else |
@@ -506,22 +488,6 @@ int bfin_gpio_set_wake(unsigned int irq, unsigned int state) | |||
506 | } | 488 | } |
507 | #endif | 489 | #endif |
508 | 490 | ||
509 | static struct irq_chip bfin_gpio_irqchip = { | ||
510 | .name = "GPIO", | ||
511 | .ack = bfin_gpio_ack_irq, | ||
512 | .mask = bfin_gpio_mask_irq, | ||
513 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
514 | .unmask = bfin_gpio_unmask_irq, | ||
515 | .disable = bfin_gpio_mask_irq, | ||
516 | .enable = bfin_gpio_unmask_irq, | ||
517 | .set_type = bfin_gpio_irq_type, | ||
518 | .startup = bfin_gpio_irq_startup, | ||
519 | .shutdown = bfin_gpio_irq_shutdown, | ||
520 | #ifdef CONFIG_PM | ||
521 | .set_wake = bfin_gpio_set_wake, | ||
522 | #endif | ||
523 | }; | ||
524 | |||
525 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 491 | static void bfin_demux_gpio_irq(unsigned int inta_irq, |
526 | struct irq_desc *desc) | 492 | struct irq_desc *desc) |
527 | { | 493 | { |
@@ -572,9 +538,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
572 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 538 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
573 | irq += i; | 539 | irq += i; |
574 | 540 | ||
575 | mask = get_gpiop_data(i) & | 541 | mask = get_gpiop_data(i) & get_gpiop_maska(i); |
576 | (gpio_enabled[gpio_bank(i)] & | ||
577 | get_gpiop_maska(i)); | ||
578 | 542 | ||
579 | while (mask) { | 543 | while (mask) { |
580 | if (mask & 1) { | 544 | if (mask & 1) { |
@@ -587,9 +551,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
587 | } | 551 | } |
588 | } else { | 552 | } else { |
589 | gpio = irq_to_gpio(irq); | 553 | gpio = irq_to_gpio(irq); |
590 | mask = get_gpiop_data(gpio) & | 554 | mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio); |
591 | (gpio_enabled[gpio_bank(gpio)] & | ||
592 | get_gpiop_maska(gpio)); | ||
593 | 555 | ||
594 | do { | 556 | do { |
595 | if (mask & 1) { | 557 | if (mask & 1) { |
@@ -617,10 +579,6 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
617 | static unsigned char irq2pint_lut[NR_PINTS]; | 579 | static unsigned char irq2pint_lut[NR_PINTS]; |
618 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | 580 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; |
619 | 581 | ||
620 | static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS]; | ||
621 | static unsigned short gpio_enabled[GPIO_BANK_NUM]; | ||
622 | |||
623 | |||
624 | struct pin_int_t { | 582 | struct pin_int_t { |
625 | unsigned int mask_set; | 583 | unsigned int mask_set; |
626 | unsigned int mask_clear; | 584 | unsigned int mask_clear; |
@@ -641,12 +599,9 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { | |||
641 | (struct pin_int_t *)PINT3_MASK_SET, | 599 | (struct pin_int_t *)PINT3_MASK_SET, |
642 | }; | 600 | }; |
643 | 601 | ||
644 | extern void bfin_gpio_irq_prepare(unsigned gpio); | 602 | inline unsigned int get_irq_base(u32 bank, u8 bmap) |
645 | |||
646 | inline unsigned short get_irq_base(u8 bank, u8 bmap) | ||
647 | { | 603 | { |
648 | 604 | unsigned int irq_base; | |
649 | u16 irq_base; | ||
650 | 605 | ||
651 | if (bank < 2) { /*PA-PB */ | 606 | if (bank < 2) { /*PA-PB */ |
652 | irq_base = IRQ_PA0 + bmap * 16; | 607 | irq_base = IRQ_PA0 + bmap * 16; |
@@ -655,7 +610,6 @@ inline unsigned short get_irq_base(u8 bank, u8 bmap) | |||
655 | } | 610 | } |
656 | 611 | ||
657 | return irq_base; | 612 | return irq_base; |
658 | |||
659 | } | 613 | } |
660 | 614 | ||
661 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | 615 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ |
@@ -682,20 +636,18 @@ void init_pint_lut(void) | |||
682 | 636 | ||
683 | pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; | 637 | pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; |
684 | irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; | 638 | irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; |
685 | |||
686 | } | 639 | } |
687 | |||
688 | } | 640 | } |
689 | |||
690 | } | 641 | } |
691 | 642 | ||
692 | static void bfin_gpio_ack_irq(unsigned int irq) | 643 | static void bfin_gpio_ack_irq(unsigned int irq) |
693 | { | 644 | { |
694 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 645 | struct irq_desc *desc = irq_desc + irq; |
646 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
695 | u32 pintbit = PINT_BIT(pint_val); | 647 | u32 pintbit = PINT_BIT(pint_val); |
696 | u8 bank = PINT_2_BANK(pint_val); | 648 | u32 bank = PINT_2_BANK(pint_val); |
697 | 649 | ||
698 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | 650 | if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { |
699 | if (pint[bank]->invert_set & pintbit) | 651 | if (pint[bank]->invert_set & pintbit) |
700 | pint[bank]->invert_clear = pintbit; | 652 | pint[bank]->invert_clear = pintbit; |
701 | else | 653 | else |
@@ -703,16 +655,16 @@ static void bfin_gpio_ack_irq(unsigned int irq) | |||
703 | } | 655 | } |
704 | pint[bank]->request = pintbit; | 656 | pint[bank]->request = pintbit; |
705 | 657 | ||
706 | SSYNC(); | ||
707 | } | 658 | } |
708 | 659 | ||
709 | static void bfin_gpio_mask_ack_irq(unsigned int irq) | 660 | static void bfin_gpio_mask_ack_irq(unsigned int irq) |
710 | { | 661 | { |
711 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 662 | struct irq_desc *desc = irq_desc + irq; |
663 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
712 | u32 pintbit = PINT_BIT(pint_val); | 664 | u32 pintbit = PINT_BIT(pint_val); |
713 | u8 bank = PINT_2_BANK(pint_val); | 665 | u32 bank = PINT_2_BANK(pint_val); |
714 | 666 | ||
715 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | 667 | if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { |
716 | if (pint[bank]->invert_set & pintbit) | 668 | if (pint[bank]->invert_set & pintbit) |
717 | pint[bank]->invert_clear = pintbit; | 669 | pint[bank]->invert_clear = pintbit; |
718 | else | 670 | else |
@@ -721,32 +673,29 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq) | |||
721 | 673 | ||
722 | pint[bank]->request = pintbit; | 674 | pint[bank]->request = pintbit; |
723 | pint[bank]->mask_clear = pintbit; | 675 | pint[bank]->mask_clear = pintbit; |
724 | SSYNC(); | ||
725 | } | 676 | } |
726 | 677 | ||
727 | static void bfin_gpio_mask_irq(unsigned int irq) | 678 | static void bfin_gpio_mask_irq(unsigned int irq) |
728 | { | 679 | { |
729 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 680 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
730 | 681 | ||
731 | pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); | 682 | pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); |
732 | SSYNC(); | ||
733 | } | 683 | } |
734 | 684 | ||
735 | static void bfin_gpio_unmask_irq(unsigned int irq) | 685 | static void bfin_gpio_unmask_irq(unsigned int irq) |
736 | { | 686 | { |
737 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 687 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
738 | u32 pintbit = PINT_BIT(pint_val); | 688 | u32 pintbit = PINT_BIT(pint_val); |
739 | u8 bank = PINT_2_BANK(pint_val); | 689 | u32 bank = PINT_2_BANK(pint_val); |
740 | 690 | ||
741 | pint[bank]->request = pintbit; | 691 | pint[bank]->request = pintbit; |
742 | pint[bank]->mask_set = pintbit; | 692 | pint[bank]->mask_set = pintbit; |
743 | SSYNC(); | ||
744 | } | 693 | } |
745 | 694 | ||
746 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 695 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
747 | { | 696 | { |
748 | u16 gpionr = irq_to_gpio(irq); | 697 | u32 gpionr = irq_to_gpio(irq); |
749 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 698 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
750 | 699 | ||
751 | if (pint_val == IRQ_NOT_AVAIL) { | 700 | if (pint_val == IRQ_NOT_AVAIL) { |
752 | printk(KERN_ERR | 701 | printk(KERN_ERR |
@@ -755,10 +704,9 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
755 | return -ENODEV; | 704 | return -ENODEV; |
756 | } | 705 | } |
757 | 706 | ||
758 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 707 | if (__test_and_set_bit(gpionr, gpio_enabled)) |
759 | bfin_gpio_irq_prepare(gpionr); | 708 | bfin_gpio_irq_prepare(gpionr); |
760 | 709 | ||
761 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
762 | bfin_gpio_unmask_irq(irq); | 710 | bfin_gpio_unmask_irq(irq); |
763 | 711 | ||
764 | return 0; | 712 | return 0; |
@@ -766,38 +714,37 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
766 | 714 | ||
767 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 715 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
768 | { | 716 | { |
769 | u16 gpionr = irq_to_gpio(irq); | 717 | u32 gpionr = irq_to_gpio(irq); |
770 | 718 | ||
771 | bfin_gpio_mask_irq(irq); | 719 | bfin_gpio_mask_irq(irq); |
772 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 720 | __clear_bit(gpionr, gpio_enabled); |
773 | } | 721 | } |
774 | 722 | ||
775 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 723 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
776 | { | 724 | { |
777 | 725 | ||
778 | u16 gpionr = irq_to_gpio(irq); | 726 | u32 gpionr = irq_to_gpio(irq); |
779 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 727 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
780 | u32 pintbit = PINT_BIT(pint_val); | 728 | u32 pintbit = PINT_BIT(pint_val); |
781 | u8 bank = PINT_2_BANK(pint_val); | 729 | u32 bank = PINT_2_BANK(pint_val); |
782 | 730 | ||
783 | if (pint_val == IRQ_NOT_AVAIL) | 731 | if (pint_val == IRQ_NOT_AVAIL) |
784 | return -ENODEV; | 732 | return -ENODEV; |
785 | 733 | ||
786 | if (type == IRQ_TYPE_PROBE) { | 734 | if (type == IRQ_TYPE_PROBE) { |
787 | /* only probe unenabled GPIO interrupt lines */ | 735 | /* only probe unenabled GPIO interrupt lines */ |
788 | if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) | 736 | if (__test_bit(gpionr, gpio_enabled)) |
789 | return 0; | 737 | return 0; |
790 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 738 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
791 | } | 739 | } |
792 | 740 | ||
793 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 741 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
794 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 742 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
795 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) | 743 | if (__test_and_set_bit(gpionr, gpio_enabled)) |
796 | bfin_gpio_irq_prepare(gpionr); | 744 | bfin_gpio_irq_prepare(gpionr); |
797 | 745 | ||
798 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
799 | } else { | 746 | } else { |
800 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | 747 | __clear_bit(gpionr, gpio_enabled); |
801 | return 0; | 748 | return 0; |
802 | } | 749 | } |
803 | 750 | ||
@@ -808,15 +755,10 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
808 | 755 | ||
809 | if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 756 | if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
810 | == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | 757 | == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
811 | |||
812 | gpio_both_edge_triggered[bank] |= pintbit; | ||
813 | |||
814 | if (gpio_get_value(gpionr)) | 758 | if (gpio_get_value(gpionr)) |
815 | pint[bank]->invert_set = pintbit; | 759 | pint[bank]->invert_set = pintbit; |
816 | else | 760 | else |
817 | pint[bank]->invert_clear = pintbit; | 761 | pint[bank]->invert_clear = pintbit; |
818 | } else { | ||
819 | gpio_both_edge_triggered[bank] &= ~pintbit; | ||
820 | } | 762 | } |
821 | 763 | ||
822 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | 764 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
@@ -827,8 +769,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
827 | bfin_set_irq_handler(irq, handle_level_irq); | 769 | bfin_set_irq_handler(irq, handle_level_irq); |
828 | } | 770 | } |
829 | 771 | ||
830 | SSYNC(); | ||
831 | |||
832 | return 0; | 772 | return 0; |
833 | } | 773 | } |
834 | 774 | ||
@@ -839,7 +779,7 @@ u32 pint_wakeup_masks[NR_PINT_SYS_IRQS]; | |||
839 | int bfin_gpio_set_wake(unsigned int irq, unsigned int state) | 779 | int bfin_gpio_set_wake(unsigned int irq, unsigned int state) |
840 | { | 780 | { |
841 | u32 pint_irq; | 781 | u32 pint_irq; |
842 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 782 | u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
843 | u32 bank = PINT_2_BANK(pint_val); | 783 | u32 bank = PINT_2_BANK(pint_val); |
844 | u32 pintbit = PINT_BIT(pint_val); | 784 | u32 pintbit = PINT_BIT(pint_val); |
845 | 785 | ||
@@ -900,26 +840,10 @@ void bfin_pm_restore(void) | |||
900 | } | 840 | } |
901 | #endif | 841 | #endif |
902 | 842 | ||
903 | static struct irq_chip bfin_gpio_irqchip = { | ||
904 | .name = "GPIO", | ||
905 | .ack = bfin_gpio_ack_irq, | ||
906 | .mask = bfin_gpio_mask_irq, | ||
907 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
908 | .unmask = bfin_gpio_unmask_irq, | ||
909 | .disable = bfin_gpio_mask_irq, | ||
910 | .enable = bfin_gpio_unmask_irq, | ||
911 | .set_type = bfin_gpio_irq_type, | ||
912 | .startup = bfin_gpio_irq_startup, | ||
913 | .shutdown = bfin_gpio_irq_shutdown, | ||
914 | #ifdef CONFIG_PM | ||
915 | .set_wake = bfin_gpio_set_wake, | ||
916 | #endif | ||
917 | }; | ||
918 | |||
919 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 843 | static void bfin_demux_gpio_irq(unsigned int inta_irq, |
920 | struct irq_desc *desc) | 844 | struct irq_desc *desc) |
921 | { | 845 | { |
922 | u8 bank, pint_val; | 846 | u32 bank, pint_val; |
923 | u32 request, irq; | 847 | u32 request, irq; |
924 | 848 | ||
925 | switch (inta_irq) { | 849 | switch (inta_irq) { |
@@ -956,6 +880,22 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
956 | } | 880 | } |
957 | #endif | 881 | #endif |
958 | 882 | ||
883 | static struct irq_chip bfin_gpio_irqchip = { | ||
884 | .name = "GPIO", | ||
885 | .ack = bfin_gpio_ack_irq, | ||
886 | .mask = bfin_gpio_mask_irq, | ||
887 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
888 | .unmask = bfin_gpio_unmask_irq, | ||
889 | .disable = bfin_gpio_mask_irq, | ||
890 | .enable = bfin_gpio_unmask_irq, | ||
891 | .set_type = bfin_gpio_irq_type, | ||
892 | .startup = bfin_gpio_irq_startup, | ||
893 | .shutdown = bfin_gpio_irq_shutdown, | ||
894 | #ifdef CONFIG_PM | ||
895 | .set_wake = bfin_gpio_set_wake, | ||
896 | #endif | ||
897 | }; | ||
898 | |||
959 | void __init init_exception_vectors(void) | 899 | void __init init_exception_vectors(void) |
960 | { | 900 | { |
961 | /* cannot program in software: | 901 | /* cannot program in software: |
@@ -982,6 +922,7 @@ void __init init_exception_vectors(void) | |||
982 | * This function should be called during kernel startup to initialize | 922 | * This function should be called during kernel startup to initialize |
983 | * the BFin IRQ handling routines. | 923 | * the BFin IRQ handling routines. |
984 | */ | 924 | */ |
925 | |||
985 | int __init init_arch_irq(void) | 926 | int __init init_arch_irq(void) |
986 | { | 927 | { |
987 | int irq; | 928 | int irq; |