diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2008-07-19 04:57:32 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-07-19 04:57:32 -0400 |
commit | 1efc80b53eb54770139219f99657abd92595fc86 (patch) | |
tree | 254c76b3aaf22110b116e67a8118945006cacce6 /arch/blackfin/kernel/bfin_gpio.c | |
parent | 4f13f548cef5af1717cbbc341a1a3474f3e7466e (diff) |
Blackfin arch: Functional power management support
Enable: PM_SUSPEND_MEM -> Blackfin Hibernate to SDRAM
This feature requires a special bootloader (u-boot)
supporting return from hibernate.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 118 |
1 files changed, 112 insertions, 6 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index b6d89d1644cc..ecbd141e0ef2 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -186,7 +186,10 @@ static struct str_ident { | |||
186 | char name[RESOURCE_LABEL_SIZE]; | 186 | char name[RESOURCE_LABEL_SIZE]; |
187 | } str_ident[MAX_RESOURCES]; | 187 | } str_ident[MAX_RESOURCES]; |
188 | 188 | ||
189 | #if defined(CONFIG_PM) && !defined(CONFIG_BF54x) | 189 | #if defined(CONFIG_PM) |
190 | #if defined(CONFIG_BF54x) | ||
191 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
192 | #else | ||
190 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 193 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
191 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | 194 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; |
192 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 195 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
@@ -206,7 +209,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INT | |||
206 | #ifdef BF561_FAMILY | 209 | #ifdef BF561_FAMILY |
207 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; | 210 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; |
208 | #endif | 211 | #endif |
209 | 212 | #endif | |
210 | #endif /* CONFIG_PM */ | 213 | #endif /* CONFIG_PM */ |
211 | 214 | ||
212 | #if defined(BF548_FAMILY) | 215 | #if defined(BF548_FAMILY) |
@@ -667,7 +670,7 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) | |||
667 | return 0; | 670 | return 0; |
668 | } | 671 | } |
669 | 672 | ||
670 | u32 bfin_pm_setup(void) | 673 | u32 bfin_pm_standby_setup(void) |
671 | { | 674 | { |
672 | u16 bank, mask, i, gpio; | 675 | u16 bank, mask, i, gpio; |
673 | 676 | ||
@@ -679,7 +682,7 @@ u32 bfin_pm_setup(void) | |||
679 | gpio_bankb[bank]->maskb = 0; | 682 | gpio_bankb[bank]->maskb = 0; |
680 | 683 | ||
681 | if (mask) { | 684 | if (mask) { |
682 | #ifdef BF537_FAMILY | 685 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) |
683 | gpio_bank_saved[bank].fer = *port_fer[bank]; | 686 | gpio_bank_saved[bank].fer = *port_fer[bank]; |
684 | #endif | 687 | #endif |
685 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | 688 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; |
@@ -715,7 +718,7 @@ u32 bfin_pm_setup(void) | |||
715 | return 0; | 718 | return 0; |
716 | } | 719 | } |
717 | 720 | ||
718 | void bfin_pm_restore(void) | 721 | void bfin_pm_standby_restore(void) |
719 | { | 722 | { |
720 | u16 bank, mask, i; | 723 | u16 bank, mask, i; |
721 | 724 | ||
@@ -724,7 +727,7 @@ void bfin_pm_restore(void) | |||
724 | bank = gpio_bank(i); | 727 | bank = gpio_bank(i); |
725 | 728 | ||
726 | if (mask) { | 729 | if (mask) { |
727 | #ifdef BF537_FAMILY | 730 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) |
728 | *port_fer[bank] = gpio_bank_saved[bank].fer; | 731 | *port_fer[bank] = gpio_bank_saved[bank].fer; |
729 | #endif | 732 | #endif |
730 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | 733 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; |
@@ -743,8 +746,111 @@ void bfin_pm_restore(void) | |||
743 | AWA_DUMMY_READ(maskb); | 746 | AWA_DUMMY_READ(maskb); |
744 | } | 747 | } |
745 | 748 | ||
749 | void bfin_gpio_pm_hibernate_suspend(void) | ||
750 | { | ||
751 | int i, bank; | ||
752 | |||
753 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
754 | bank = gpio_bank(i); | ||
755 | |||
756 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) | ||
757 | gpio_bank_saved[bank].fer = *port_fer[bank]; | ||
758 | #ifdef BF527_FAMILY | ||
759 | gpio_bank_saved[bank].mux = *port_mux[bank]; | ||
760 | #else | ||
761 | if (bank == 0) | ||
762 | gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); | ||
763 | #endif | ||
764 | #endif | ||
765 | gpio_bank_saved[bank].data = gpio_bankb[bank]->data; | ||
766 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | ||
767 | gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; | ||
768 | gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; | ||
769 | gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; | ||
770 | gpio_bank_saved[bank].both = gpio_bankb[bank]->both; | ||
771 | gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; | ||
772 | } | ||
773 | |||
774 | AWA_DUMMY_READ(maska); | ||
775 | } | ||
776 | |||
777 | void bfin_gpio_pm_hibernate_restore(void) | ||
778 | { | ||
779 | int i, bank; | ||
780 | |||
781 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
782 | bank = gpio_bank(i); | ||
783 | |||
784 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) | ||
785 | #ifdef BF527_FAMILY | ||
786 | *port_mux[bank] = gpio_bank_saved[bank].mux; | ||
787 | #else | ||
788 | if (bank == 0) | ||
789 | bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); | ||
790 | #endif | ||
791 | *port_fer[bank] = gpio_bank_saved[bank].fer; | ||
792 | #endif | ||
793 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | ||
794 | gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; | ||
795 | gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; | ||
796 | gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; | ||
797 | gpio_bankb[bank]->both = gpio_bank_saved[bank].both; | ||
798 | |||
799 | gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data | ||
800 | | gpio_bank_saved[bank].dir; | ||
801 | |||
802 | gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; | ||
803 | } | ||
804 | AWA_DUMMY_READ(maska); | ||
805 | } | ||
806 | |||
807 | |||
746 | #endif | 808 | #endif |
747 | #else /* BF548_FAMILY */ | 809 | #else /* BF548_FAMILY */ |
810 | #ifdef CONFIG_PM | ||
811 | |||
812 | u32 bfin_pm_standby_setup(void) | ||
813 | { | ||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | void bfin_pm_standby_restore(void) | ||
818 | { | ||
819 | |||
820 | } | ||
821 | |||
822 | void bfin_gpio_pm_hibernate_suspend(void) | ||
823 | { | ||
824 | int i, bank; | ||
825 | |||
826 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
827 | bank = gpio_bank(i); | ||
828 | |||
829 | gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; | ||
830 | gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; | ||
831 | gpio_bank_saved[bank].data = gpio_array[bank]->port_data; | ||
832 | gpio_bank_saved[bank].data = gpio_array[bank]->port_data; | ||
833 | gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; | ||
834 | gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; | ||
835 | } | ||
836 | } | ||
837 | |||
838 | void bfin_gpio_pm_hibernate_restore(void) | ||
839 | { | ||
840 | int i, bank; | ||
841 | |||
842 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
843 | bank = gpio_bank(i); | ||
844 | |||
845 | gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; | ||
846 | gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; | ||
847 | gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; | ||
848 | gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; | ||
849 | gpio_array[bank]->port_set = gpio_bank_saved[bank].data | ||
850 | | gpio_bank_saved[bank].dir; | ||
851 | } | ||
852 | } | ||
853 | #endif | ||
748 | 854 | ||
749 | unsigned short get_gpio_dir(unsigned gpio) | 855 | unsigned short get_gpio_dir(unsigned gpio) |
750 | { | 856 | { |