diff options
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
| -rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 131 |
1 files changed, 12 insertions, 119 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index e35e20f00d9b..42833ee2b308 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
| @@ -475,9 +475,7 @@ GET_GPIO_P(maskb) | |||
| 475 | 475 | ||
| 476 | 476 | ||
| 477 | #ifdef CONFIG_PM | 477 | #ifdef CONFIG_PM |
| 478 | |||
| 479 | static unsigned short wakeup_map[GPIO_BANK_NUM]; | 478 | static unsigned short wakeup_map[GPIO_BANK_NUM]; |
| 480 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | ||
| 481 | 479 | ||
| 482 | static const unsigned int sic_iwr_irqs[] = { | 480 | static const unsigned int sic_iwr_irqs[] = { |
| 483 | #if defined(BF533_FAMILY) | 481 | #if defined(BF533_FAMILY) |
| @@ -514,112 +512,26 @@ static const unsigned int sic_iwr_irqs[] = { | |||
| 514 | ************************************************************* | 512 | ************************************************************* |
| 515 | * MODIFICATION HISTORY : | 513 | * MODIFICATION HISTORY : |
| 516 | **************************************************************/ | 514 | **************************************************************/ |
| 517 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type) | 515 | int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) |
| 518 | { | ||
| 519 | unsigned long flags; | ||
| 520 | |||
| 521 | if ((check_gpio(gpio) < 0) || !type) | ||
| 522 | return -EINVAL; | ||
| 523 | |||
| 524 | local_irq_save_hw(flags); | ||
| 525 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); | ||
| 526 | wakeup_flags_map[gpio] = type; | ||
| 527 | local_irq_restore_hw(flags); | ||
| 528 | |||
| 529 | return 0; | ||
| 530 | } | ||
| 531 | EXPORT_SYMBOL(gpio_pm_wakeup_request); | ||
| 532 | |||
| 533 | void gpio_pm_wakeup_free(unsigned gpio) | ||
| 534 | { | 516 | { |
| 535 | unsigned long flags; | 517 | unsigned long flags; |
| 536 | 518 | ||
| 537 | if (check_gpio(gpio) < 0) | 519 | if (check_gpio(gpio) < 0) |
| 538 | return; | 520 | return -EINVAL; |
| 539 | 521 | ||
| 540 | local_irq_save_hw(flags); | 522 | local_irq_save_hw(flags); |
| 541 | 523 | if (ctrl) | |
| 542 | wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | 524 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); |
| 543 | |||
| 544 | local_irq_restore_hw(flags); | ||
| 545 | } | ||
| 546 | EXPORT_SYMBOL(gpio_pm_wakeup_free); | ||
| 547 | |||
| 548 | static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) | ||
| 549 | { | ||
| 550 | port_setup(gpio, GPIO_USAGE); | ||
| 551 | set_gpio_dir(gpio, 0); | ||
| 552 | set_gpio_inen(gpio, 1); | ||
| 553 | |||
| 554 | if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) | ||
| 555 | set_gpio_edge(gpio, 1); | ||
| 556 | else | ||
| 557 | set_gpio_edge(gpio, 0); | ||
| 558 | |||
| 559 | if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) | ||
| 560 | set_gpio_both(gpio, 1); | ||
| 561 | else | 525 | else |
| 562 | set_gpio_both(gpio, 0); | 526 | wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); |
| 563 | |||
| 564 | if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) | ||
| 565 | set_gpio_polar(gpio, 1); | ||
| 566 | else | ||
| 567 | set_gpio_polar(gpio, 0); | ||
| 568 | 527 | ||
| 569 | SSYNC(); | 528 | set_gpio_maskb(gpio, ctrl); |
| 570 | 529 | local_irq_restore_hw(flags); | |
| 571 | return 0; | ||
| 572 | } | ||
| 573 | |||
| 574 | u32 bfin_pm_standby_setup(void) | ||
| 575 | { | ||
| 576 | u16 bank, mask, i, gpio; | ||
| 577 | |||
| 578 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
| 579 | mask = wakeup_map[gpio_bank(i)]; | ||
| 580 | bank = gpio_bank(i); | ||
| 581 | |||
| 582 | gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; | ||
| 583 | gpio_array[bank]->maskb = 0; | ||
| 584 | |||
| 585 | if (mask) { | ||
| 586 | #if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) | ||
| 587 | gpio_bank_saved[bank].fer = *port_fer[bank]; | ||
| 588 | #endif | ||
| 589 | gpio_bank_saved[bank].inen = gpio_array[bank]->inen; | ||
| 590 | gpio_bank_saved[bank].polar = gpio_array[bank]->polar; | ||
| 591 | gpio_bank_saved[bank].dir = gpio_array[bank]->dir; | ||
| 592 | gpio_bank_saved[bank].edge = gpio_array[bank]->edge; | ||
| 593 | gpio_bank_saved[bank].both = gpio_array[bank]->both; | ||
| 594 | gpio_bank_saved[bank].reserved = | ||
| 595 | reserved_gpio_map[bank]; | ||
| 596 | |||
| 597 | gpio = i; | ||
| 598 | |||
| 599 | while (mask) { | ||
| 600 | if ((mask & 1) && (wakeup_flags_map[gpio] != | ||
| 601 | PM_WAKE_IGNORE)) { | ||
| 602 | reserved_gpio_map[gpio_bank(gpio)] |= | ||
| 603 | gpio_bit(gpio); | ||
| 604 | bfin_gpio_wakeup_type(gpio, | ||
| 605 | wakeup_flags_map[gpio]); | ||
| 606 | set_gpio_data(gpio, 0); /*Clear*/ | ||
| 607 | } | ||
| 608 | gpio++; | ||
| 609 | mask >>= 1; | ||
| 610 | } | ||
| 611 | |||
| 612 | bfin_internal_set_wake(sic_iwr_irqs[bank], 1); | ||
| 613 | gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | AWA_DUMMY_READ(maskb_set); | ||
| 618 | 530 | ||
| 619 | return 0; | 531 | return 0; |
| 620 | } | 532 | } |
| 621 | 533 | ||
| 622 | void bfin_pm_standby_restore(void) | 534 | int bfin_pm_standby_ctrl(unsigned ctrl) |
| 623 | { | 535 | { |
| 624 | u16 bank, mask, i; | 536 | u16 bank, mask, i; |
| 625 | 537 | ||
| @@ -627,24 +539,10 @@ void bfin_pm_standby_restore(void) | |||
| 627 | mask = wakeup_map[gpio_bank(i)]; | 539 | mask = wakeup_map[gpio_bank(i)]; |
| 628 | bank = gpio_bank(i); | 540 | bank = gpio_bank(i); |
| 629 | 541 | ||
| 630 | if (mask) { | 542 | if (mask) |
| 631 | #if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) | 543 | bfin_internal_set_wake(sic_iwr_irqs[bank], ctrl); |
| 632 | *port_fer[bank] = gpio_bank_saved[bank].fer; | ||
| 633 | #endif | ||
| 634 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; | ||
| 635 | gpio_array[bank]->dir = gpio_bank_saved[bank].dir; | ||
| 636 | gpio_array[bank]->polar = gpio_bank_saved[bank].polar; | ||
| 637 | gpio_array[bank]->edge = gpio_bank_saved[bank].edge; | ||
| 638 | gpio_array[bank]->both = gpio_bank_saved[bank].both; | ||
| 639 | |||
| 640 | reserved_gpio_map[bank] = | ||
| 641 | gpio_bank_saved[bank].reserved; | ||
| 642 | bfin_internal_set_wake(sic_iwr_irqs[bank], 0); | ||
| 643 | } | ||
| 644 | |||
| 645 | gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; | ||
| 646 | } | 544 | } |
| 647 | AWA_DUMMY_READ(maskb); | 545 | return 0; |
| 648 | } | 546 | } |
| 649 | 547 | ||
| 650 | void bfin_gpio_pm_hibernate_suspend(void) | 548 | void bfin_gpio_pm_hibernate_suspend(void) |
| @@ -708,16 +606,11 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
| 708 | #else /* CONFIG_BF54x */ | 606 | #else /* CONFIG_BF54x */ |
| 709 | #ifdef CONFIG_PM | 607 | #ifdef CONFIG_PM |
| 710 | 608 | ||
| 711 | u32 bfin_pm_standby_setup(void) | 609 | int bfin_pm_standby_ctrl(unsigned ctrl) |
| 712 | { | 610 | { |
| 713 | return 0; | 611 | return 0; |
| 714 | } | 612 | } |
| 715 | 613 | ||
| 716 | void bfin_pm_standby_restore(void) | ||
| 717 | { | ||
| 718 | |||
| 719 | } | ||
| 720 | |||
| 721 | void bfin_gpio_pm_hibernate_suspend(void) | 614 | void bfin_gpio_pm_hibernate_suspend(void) |
| 722 | { | 615 | { |
| 723 | int i, bank; | 616 | int i, bank; |
