aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/bfin_gpio.c
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2008-07-19 04:57:32 -0400
committerBryan Wu <cooloney@kernel.org>2008-07-19 04:57:32 -0400
commit1efc80b53eb54770139219f99657abd92595fc86 (patch)
tree254c76b3aaf22110b116e67a8118945006cacce6 /arch/blackfin/kernel/bfin_gpio.c
parent4f13f548cef5af1717cbbc341a1a3474f3e7466e (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.c118
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)
191static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)];
192#else
190static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 193static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
191static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; 194static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
192static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; 195static 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
207static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; 210static 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
670u32 bfin_pm_setup(void) 673u32 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
718void bfin_pm_restore(void) 721void 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
749void 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
777void 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
812u32 bfin_pm_standby_setup(void)
813{
814 return 0;
815}
816
817void bfin_pm_standby_restore(void)
818{
819
820}
821
822void 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
838void 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
749unsigned short get_gpio_dir(unsigned gpio) 855unsigned short get_gpio_dir(unsigned gpio)
750{ 856{