diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-06-27 14:46:14 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2011-07-23 01:18:30 -0400 |
commit | 9466a0510a5445d81eaf33affc20e2f7e2e718fb (patch) | |
tree | ecbecd217aedca3575d27444efeadf1fee1c8f38 /arch | |
parent | eed7b8365807549c67613ea7d9a451262050ba3e (diff) |
Blackfin: bf538: pull gpio/port logic out of core hibernate paths
Re-architect how we save/restore the gpio/port logic that only pertains
to bf538/bf539 parts by pulling it out of the core code paths and pushing
it out to bf538-specific locations.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/include/asm/gpio.h | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 22 | ||||
-rw-r--r-- | arch/blackfin/mach-bf538/ext-gpio.c | 37 | ||||
-rw-r--r-- | arch/blackfin/mach-bf538/include/mach/gpio.h | 3 | ||||
-rw-r--r-- | arch/blackfin/mach-common/dpmc_modes.S | 35 |
5 files changed, 65 insertions, 36 deletions
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index d06162029c69..5a25856381ff 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h | |||
@@ -119,6 +119,10 @@ struct gpio_port_t { | |||
119 | #ifdef BFIN_SPECIAL_GPIO_BANKS | 119 | #ifdef BFIN_SPECIAL_GPIO_BANKS |
120 | void bfin_special_gpio_free(unsigned gpio); | 120 | void bfin_special_gpio_free(unsigned gpio); |
121 | int bfin_special_gpio_request(unsigned gpio, const char *label); | 121 | int bfin_special_gpio_request(unsigned gpio, const char *label); |
122 | # ifdef CONFIG_PM | ||
123 | void bfin_special_gpio_pm_hibernate_restore(void); | ||
124 | void bfin_special_gpio_pm_hibernate_suspend(void); | ||
125 | # endif | ||
122 | #endif | 126 | #endif |
123 | 127 | ||
124 | #ifdef CONFIG_PM | 128 | #ifdef CONFIG_PM |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index bcf8cf6fe412..16d7ebfa0db1 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -118,6 +118,9 @@ static struct str_ident { | |||
118 | 118 | ||
119 | #if defined(CONFIG_PM) | 119 | #if defined(CONFIG_PM) |
120 | static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; | 120 | static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; |
121 | # ifdef BF538_FAMILY | ||
122 | static unsigned short port_fer_saved[3]; | ||
123 | # endif | ||
121 | #endif | 124 | #endif |
122 | 125 | ||
123 | static void gpio_error(unsigned gpio) | 126 | static void gpio_error(unsigned gpio) |
@@ -604,6 +607,11 @@ void bfin_gpio_pm_hibernate_suspend(void) | |||
604 | { | 607 | { |
605 | int i, bank; | 608 | int i, bank; |
606 | 609 | ||
610 | #ifdef BF538_FAMILY | ||
611 | for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i) | ||
612 | port_fer_saved[i] = *port_fer[i]; | ||
613 | #endif | ||
614 | |||
607 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 615 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
608 | bank = gpio_bank(i); | 616 | bank = gpio_bank(i); |
609 | 617 | ||
@@ -625,6 +633,10 @@ void bfin_gpio_pm_hibernate_suspend(void) | |||
625 | gpio_bank_saved[bank].maska = gpio_array[bank]->maska; | 633 | gpio_bank_saved[bank].maska = gpio_array[bank]->maska; |
626 | } | 634 | } |
627 | 635 | ||
636 | #ifdef BFIN_SPECIAL_GPIO_BANKS | ||
637 | bfin_special_gpio_pm_hibernate_suspend(); | ||
638 | #endif | ||
639 | |||
628 | AWA_DUMMY_READ(maska); | 640 | AWA_DUMMY_READ(maska); |
629 | } | 641 | } |
630 | 642 | ||
@@ -632,6 +644,11 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
632 | { | 644 | { |
633 | int i, bank; | 645 | int i, bank; |
634 | 646 | ||
647 | #ifdef BF538_FAMILY | ||
648 | for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i) | ||
649 | *port_fer[i] = port_fer_saved[i]; | ||
650 | #endif | ||
651 | |||
635 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 652 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
636 | bank = gpio_bank(i); | 653 | bank = gpio_bank(i); |
637 | 654 | ||
@@ -653,6 +670,11 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
653 | gpio_array[bank]->both = gpio_bank_saved[bank].both; | 670 | gpio_array[bank]->both = gpio_bank_saved[bank].both; |
654 | gpio_array[bank]->maska = gpio_bank_saved[bank].maska; | 671 | gpio_array[bank]->maska = gpio_bank_saved[bank].maska; |
655 | } | 672 | } |
673 | |||
674 | #ifdef BFIN_SPECIAL_GPIO_BANKS | ||
675 | bfin_special_gpio_pm_hibernate_restore(); | ||
676 | #endif | ||
677 | |||
656 | AWA_DUMMY_READ(maska); | 678 | AWA_DUMMY_READ(maska); |
657 | } | 679 | } |
658 | 680 | ||
diff --git a/arch/blackfin/mach-bf538/ext-gpio.c b/arch/blackfin/mach-bf538/ext-gpio.c index 180b1252679f..471a9b184d5b 100644 --- a/arch/blackfin/mach-bf538/ext-gpio.c +++ b/arch/blackfin/mach-bf538/ext-gpio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs | 2 | * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs |
3 | * | 3 | * |
4 | * Copyright 2009 Analog Devices Inc. | 4 | * Copyright 2009-2011 Analog Devices Inc. |
5 | * | 5 | * |
6 | * Licensed under the GPL-2 or later. | 6 | * Licensed under the GPL-2 or later. |
7 | */ | 7 | */ |
@@ -121,3 +121,38 @@ static int __init bf538_extgpio_setup(void) | |||
121 | gpiochip_add(&bf538_porte_chip); | 121 | gpiochip_add(&bf538_porte_chip); |
122 | } | 122 | } |
123 | arch_initcall(bf538_extgpio_setup); | 123 | arch_initcall(bf538_extgpio_setup); |
124 | |||
125 | #ifdef CONFIG_PM | ||
126 | static struct { | ||
127 | u16 data, dir, inen; | ||
128 | } gpio_bank_saved[3]; | ||
129 | |||
130 | static void __iomem * const port_bases[3] = { | ||
131 | (void *)PORTCIO, | ||
132 | (void *)PORTDIO, | ||
133 | (void *)PORTEIO, | ||
134 | }; | ||
135 | |||
136 | void bfin_special_gpio_pm_hibernate_suspend(void) | ||
137 | { | ||
138 | int i; | ||
139 | |||
140 | for (i = 0; i < ARRAY_SIZE(port_bases); ++i) { | ||
141 | gpio_bank_saved[i].data = read_PORTIO(port_bases[i]); | ||
142 | gpio_bank_saved[i].inen = read_PORTIO_INEN(port_bases[i]); | ||
143 | gpio_bank_saved[i].dir = read_PORTIO_DIR(port_bases[i]); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | void bfin_special_gpio_pm_hibernate_restore(void) | ||
148 | { | ||
149 | int i; | ||
150 | |||
151 | for (i = 0; i < ARRAY_SIZE(port_bases); ++i) { | ||
152 | write_PORTIO_INEN(port_bases[i], gpio_bank_saved[i].inen); | ||
153 | write_PORTIO_SET(port_bases[i], | ||
154 | gpio_bank_saved[i].data & gpio_bank_saved[i].dir); | ||
155 | write_PORTIO_DIR(port_bases[i], gpio_bank_saved[i].dir); | ||
156 | } | ||
157 | } | ||
158 | #endif | ||
diff --git a/arch/blackfin/mach-bf538/include/mach/gpio.h b/arch/blackfin/mach-bf538/include/mach/gpio.h index 8a5beeece996..3561c7d8935b 100644 --- a/arch/blackfin/mach-bf538/include/mach/gpio.h +++ b/arch/blackfin/mach-bf538/include/mach/gpio.h | |||
@@ -8,7 +8,10 @@ | |||
8 | #define _MACH_GPIO_H_ | 8 | #define _MACH_GPIO_H_ |
9 | 9 | ||
10 | #define MAX_BLACKFIN_GPIOS 16 | 10 | #define MAX_BLACKFIN_GPIOS 16 |
11 | #ifdef CONFIG_GPIOLIB | ||
12 | /* We only use the special logic with GPIOLIB devices */ | ||
11 | #define BFIN_SPECIAL_GPIO_BANKS 3 | 13 | #define BFIN_SPECIAL_GPIO_BANKS 3 |
14 | #endif | ||
12 | 15 | ||
13 | #define GPIO_PF0 0 /* PF */ | 16 | #define GPIO_PF0 0 /* PF */ |
14 | #define GPIO_PF1 1 | 17 | #define GPIO_PF1 1 |
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 1a1c09287222..fa0df0ac3aea 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S | |||
@@ -459,24 +459,6 @@ ENTRY(_do_hibernate) | |||
459 | PM_PUSH_SYNC(9) | 459 | PM_PUSH_SYNC(9) |
460 | #endif | 460 | #endif |
461 | 461 | ||
462 | #ifdef PORTCIO_FER | ||
463 | /* 16bit loads can only be done with dregs */ | ||
464 | PM_SYS_PUSH16(0, PORTCIO_DIR) | ||
465 | PM_SYS_PUSH16(1, PORTCIO_INEN) | ||
466 | PM_SYS_PUSH16(2, PORTCIO) | ||
467 | PM_SYS_PUSH16(3, PORTCIO_FER) | ||
468 | PM_SYS_PUSH16(4, PORTDIO_DIR) | ||
469 | PM_SYS_PUSH16(5, PORTDIO_INEN) | ||
470 | PM_SYS_PUSH16(6, PORTDIO) | ||
471 | PM_SYS_PUSH16(7, PORTDIO_FER) | ||
472 | PM_PUSH_SYNC(7) | ||
473 | PM_SYS_PUSH16(0, PORTEIO_DIR) | ||
474 | PM_SYS_PUSH16(1, PORTEIO_INEN) | ||
475 | PM_SYS_PUSH16(2, PORTEIO) | ||
476 | PM_SYS_PUSH16(3, PORTEIO_FER) | ||
477 | PM_PUSH_SYNC(3) | ||
478 | #endif | ||
479 | |||
480 | /* Save Core MMRs */ | 462 | /* Save Core MMRs */ |
481 | I0.H = hi(COREMMR_BASE); | 463 | I0.H = hi(COREMMR_BASE); |
482 | I0.L = lo(COREMMR_BASE); | 464 | I0.L = lo(COREMMR_BASE); |
@@ -777,23 +759,6 @@ ENTRY(_do_hibernate) | |||
777 | FP.H = hi(SYSMMR_BASE); | 759 | FP.H = hi(SYSMMR_BASE); |
778 | FP.L = lo(SYSMMR_BASE); | 760 | FP.L = lo(SYSMMR_BASE); |
779 | 761 | ||
780 | #ifdef PORTCIO_FER | ||
781 | PM_POP_SYNC(3) | ||
782 | PM_SYS_POP16(3, PORTEIO_FER) | ||
783 | PM_SYS_POP16(2, PORTEIO) | ||
784 | PM_SYS_POP16(1, PORTEIO_INEN) | ||
785 | PM_SYS_POP16(0, PORTEIO_DIR) | ||
786 | PM_POP_SYNC(7) | ||
787 | PM_SYS_POP16(7, PORTDIO_FER) | ||
788 | PM_SYS_POP16(6, PORTDIO) | ||
789 | PM_SYS_POP16(5, PORTDIO_INEN) | ||
790 | PM_SYS_POP16(4, PORTDIO_DIR) | ||
791 | PM_SYS_POP16(3, PORTCIO_FER) | ||
792 | PM_SYS_POP16(2, PORTCIO) | ||
793 | PM_SYS_POP16(1, PORTCIO_INEN) | ||
794 | PM_SYS_POP16(0, PORTCIO_DIR) | ||
795 | #endif | ||
796 | |||
797 | #ifdef EBIU_FCTL | 762 | #ifdef EBIU_FCTL |
798 | PM_POP_SYNC(12) | 763 | PM_POP_SYNC(12) |
799 | PM_SYS_POP(12, EBIU_FCTL) | 764 | PM_SYS_POP(12, EBIU_FCTL) |