aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/bfin_gpio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 13:23:17 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 13:23:17 -0700
commit7f268a2ba7c884a239713696238dd4207a57dd9a (patch)
treefdc02fecda32f5df8de3ddc2c01c29ba68e6a42b /arch/blackfin/kernel/bfin_gpio.c
parentdsp56k: Fix BKL pushdown (diff)
parentBlackfin arch: If we double fault, rather than hang forever, reset (diff)
downloadlinux-dev-7f268a2ba7c884a239713696238dd4207a57dd9a.tar.xz
linux-dev-7f268a2ba7c884a239713696238dd4207a57dd9a.zip
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (30 commits) Blackfin arch: If we double fault, rather than hang forever, reset Blackfin arch: When icache is off, make sure people know it Blackfin arch: Fix bug - skip single step in high priority interrupt handler instead of disabling all interrupts in single step debugging. Blackfin arch: cache the values of vco/sclk/cclk as the overhead of doing so (~24 bytes) is worth avoiding the software mult/div routines Blackfin arch: fix bug - IMDMA is not type struct dma_register Blackfin arch: check the EXTBANKS field of the DDRCTL1 register to see if we are using both memory banks Blackfin arch: Apply Bluetechnix CM-BF527 board support patch Blackfin arch: Add unwinding for stack info, and a little more detail on trace buffer Blackfin arch: Add ISP1760 board resources to BF548-EZKIT Blackfin arch: fix bug - detect 0.1 silicon revision BF527-EZKIT as 0.0 version Blackfin arch: add missing IORESOURCE_MEM flags to UART3 Blackfin arch: Add return value check in bfin_sir_probe(), remove SSYNC(). Blackfin arch: Extend sram malloc to handle L2 SRAM. Blackfin arch: Remove useless config option. Blackfin arch: change L1 malloc to base on slab cache and lists. Blackfin arch: use local labels and ENDPROC() markings Blackfin arch: Do not need this dualcore test module in kernel. Blackfin arch: Allow ptrace to peek and poke application data in L1 data SRAM. Blackfin arch: Add ANOMALY_05000368 workaround Blackfin arch: Functional power management support ...
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 {
char name[RESOURCE_LABEL_SIZE];
} str_ident[MAX_RESOURCES];
-#if defined(CONFIG_PM) && !defined(CONFIG_BF54x)
+#if defined(CONFIG_PM)
+#if defined(CONFIG_BF54x)
+static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)];
+#else
static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
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
#ifdef BF561_FAMILY
static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
#endif
-
+#endif
#endif /* CONFIG_PM */
#if defined(BF548_FAMILY)
@@ -667,7 +670,7 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type)
return 0;
}
-u32 bfin_pm_setup(void)
+u32 bfin_pm_standby_setup(void)
{
u16 bank, mask, i, gpio;
@@ -679,7 +682,7 @@ u32 bfin_pm_setup(void)
gpio_bankb[bank]->maskb = 0;
if (mask) {
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
gpio_bank_saved[bank].fer = *port_fer[bank];
#endif
gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen;
@@ -715,7 +718,7 @@ u32 bfin_pm_setup(void)
return 0;
}
-void bfin_pm_restore(void)
+void bfin_pm_standby_restore(void)
{
u16 bank, mask, i;
@@ -724,7 +727,7 @@ void bfin_pm_restore(void)
bank = gpio_bank(i);
if (mask) {
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
*port_fer[bank] = gpio_bank_saved[bank].fer;
#endif
gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen;
@@ -743,8 +746,111 @@ void bfin_pm_restore(void)
AWA_DUMMY_READ(maskb);
}
+void bfin_gpio_pm_hibernate_suspend(void)
+{
+ int i, bank;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
+ bank = gpio_bank(i);
+
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+ gpio_bank_saved[bank].fer = *port_fer[bank];
+#ifdef BF527_FAMILY
+ gpio_bank_saved[bank].mux = *port_mux[bank];
+#else
+ if (bank == 0)
+ gpio_bank_saved[bank].mux = bfin_read_PORT_MUX();
+#endif
+#endif
+ gpio_bank_saved[bank].data = gpio_bankb[bank]->data;
+ gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen;
+ gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar;
+ gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir;
+ gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge;
+ gpio_bank_saved[bank].both = gpio_bankb[bank]->both;
+ gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska;
+ }
+
+ AWA_DUMMY_READ(maska);
+}
+
+void bfin_gpio_pm_hibernate_restore(void)
+{
+ int i, bank;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
+ bank = gpio_bank(i);
+
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+#ifdef BF527_FAMILY
+ *port_mux[bank] = gpio_bank_saved[bank].mux;
+#else
+ if (bank == 0)
+ bfin_write_PORT_MUX(gpio_bank_saved[bank].mux);
+#endif
+ *port_fer[bank] = gpio_bank_saved[bank].fer;
+#endif
+ gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen;
+ gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir;
+ gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar;
+ gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge;
+ gpio_bankb[bank]->both = gpio_bank_saved[bank].both;
+
+ gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data
+ | gpio_bank_saved[bank].dir;
+
+ gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska;
+ }
+ AWA_DUMMY_READ(maska);
+}
+
+
#endif
#else /* BF548_FAMILY */
+#ifdef CONFIG_PM
+
+u32 bfin_pm_standby_setup(void)
+{
+ return 0;
+}
+
+void bfin_pm_standby_restore(void)
+{
+
+}
+
+void bfin_gpio_pm_hibernate_suspend(void)
+{
+ int i, bank;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
+ bank = gpio_bank(i);
+
+ gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer;
+ gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux;
+ gpio_bank_saved[bank].data = gpio_array[bank]->port_data;
+ gpio_bank_saved[bank].data = gpio_array[bank]->port_data;
+ gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen;
+ gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set;
+ }
+}
+
+void bfin_gpio_pm_hibernate_restore(void)
+{
+ int i, bank;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
+ bank = gpio_bank(i);
+
+ gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux;
+ gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer;
+ gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen;
+ gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir;
+ gpio_array[bank]->port_set = gpio_bank_saved[bank].data
+ | gpio_bank_saved[bank].dir;
+ }
+}
+#endif
unsigned short get_gpio_dir(unsigned gpio)
{