Blackfin: bf538: pull gpio/port logic out of core hibernate paths
authorMike Frysinger <vapier@gentoo.org>
Mon, 27 Jun 2011 18:46:14 +0000 (14:46 -0400)
committerMike Frysinger <vapier@gentoo.org>
Sat, 23 Jul 2011 05:18:30 +0000 (01:18 -0400)
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>
arch/blackfin/include/asm/gpio.h
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/mach-bf538/ext-gpio.c
arch/blackfin/mach-bf538/include/mach/gpio.h
arch/blackfin/mach-common/dpmc_modes.S

index d06162029c694089a9ebdc8180e8b631c51cb08b..5a25856381fff3257fbeba2e52aa85a0e4e21b1a 100644 (file)
@@ -119,6 +119,10 @@ struct gpio_port_t {
 #ifdef BFIN_SPECIAL_GPIO_BANKS
 void bfin_special_gpio_free(unsigned gpio);
 int bfin_special_gpio_request(unsigned gpio, const char *label);
+# ifdef CONFIG_PM
+void bfin_special_gpio_pm_hibernate_restore(void);
+void bfin_special_gpio_pm_hibernate_suspend(void);
+# endif
 #endif
 
 #ifdef CONFIG_PM
index bcf8cf6fe4126d6608a560b39e2b92ade8b89a7a..16d7ebfa0db1213b108c97196e51662d85ece0ff 100644 (file)
@@ -118,6 +118,9 @@ static struct str_ident {
 
 #if defined(CONFIG_PM)
 static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
+# ifdef BF538_FAMILY
+static unsigned short port_fer_saved[3];
+# endif
 #endif
 
 static void gpio_error(unsigned gpio)
@@ -604,6 +607,11 @@ void bfin_gpio_pm_hibernate_suspend(void)
 {
        int i, bank;
 
+#ifdef BF538_FAMILY
+       for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i)
+               port_fer_saved[i] = *port_fer[i];
+#endif
+
        for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
                bank = gpio_bank(i);
 
@@ -625,6 +633,10 @@ void bfin_gpio_pm_hibernate_suspend(void)
                gpio_bank_saved[bank].maska = gpio_array[bank]->maska;
        }
 
+#ifdef BFIN_SPECIAL_GPIO_BANKS
+       bfin_special_gpio_pm_hibernate_suspend();
+#endif
+
        AWA_DUMMY_READ(maska);
 }
 
@@ -632,6 +644,11 @@ void bfin_gpio_pm_hibernate_restore(void)
 {
        int i, bank;
 
+#ifdef BF538_FAMILY
+       for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i)
+               *port_fer[i] = port_fer_saved[i];
+#endif
+
        for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
                bank = gpio_bank(i);
 
@@ -653,6 +670,11 @@ void bfin_gpio_pm_hibernate_restore(void)
                gpio_array[bank]->both  = gpio_bank_saved[bank].both;
                gpio_array[bank]->maska = gpio_bank_saved[bank].maska;
        }
+
+#ifdef BFIN_SPECIAL_GPIO_BANKS
+       bfin_special_gpio_pm_hibernate_restore();
+#endif
+
        AWA_DUMMY_READ(maska);
 }
 
index 180b1252679ff7e227a9490fad7c5a6d91a4c5d5..471a9b184d5b293ff9253c8d448dd16c8c0f7609 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs
  *
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -121,3 +121,38 @@ static int __init bf538_extgpio_setup(void)
                gpiochip_add(&bf538_porte_chip);
 }
 arch_initcall(bf538_extgpio_setup);
+
+#ifdef CONFIG_PM
+static struct {
+       u16 data, dir, inen;
+} gpio_bank_saved[3];
+
+static void __iomem * const port_bases[3] = {
+       (void *)PORTCIO,
+       (void *)PORTDIO,
+       (void *)PORTEIO,
+};
+
+void bfin_special_gpio_pm_hibernate_suspend(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(port_bases); ++i) {
+               gpio_bank_saved[i].data = read_PORTIO(port_bases[i]);
+               gpio_bank_saved[i].inen = read_PORTIO_INEN(port_bases[i]);
+               gpio_bank_saved[i].dir = read_PORTIO_DIR(port_bases[i]);
+       }
+}
+
+void bfin_special_gpio_pm_hibernate_restore(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(port_bases); ++i) {
+               write_PORTIO_INEN(port_bases[i], gpio_bank_saved[i].inen);
+               write_PORTIO_SET(port_bases[i],
+                       gpio_bank_saved[i].data & gpio_bank_saved[i].dir);
+               write_PORTIO_DIR(port_bases[i], gpio_bank_saved[i].dir);
+       }
+}
+#endif
index 8a5beeece9969d10ddda6286016cf57f92af72e1..3561c7d8935b39228fa665f7624f5cfc558abbf7 100644 (file)
@@ -8,7 +8,10 @@
 #define _MACH_GPIO_H_
 
 #define MAX_BLACKFIN_GPIOS 16
+#ifdef CONFIG_GPIOLIB
+/* We only use the special logic with GPIOLIB devices */
 #define BFIN_SPECIAL_GPIO_BANKS 3
+#endif
 
 #define GPIO_PF0       0       /* PF */
 #define GPIO_PF1       1
index 1a1c09287222fdbcba5edfc489b5a647079bae5e..fa0df0ac3aeab83055a55646ab250715f5114bf3 100644 (file)
@@ -459,24 +459,6 @@ ENTRY(_do_hibernate)
        PM_PUSH_SYNC(9)
 #endif
 
-#ifdef PORTCIO_FER
-       /* 16bit loads can only be done with dregs */
-       PM_SYS_PUSH16(0, PORTCIO_DIR)
-       PM_SYS_PUSH16(1, PORTCIO_INEN)
-       PM_SYS_PUSH16(2, PORTCIO)
-       PM_SYS_PUSH16(3, PORTCIO_FER)
-       PM_SYS_PUSH16(4, PORTDIO_DIR)
-       PM_SYS_PUSH16(5, PORTDIO_INEN)
-       PM_SYS_PUSH16(6, PORTDIO)
-       PM_SYS_PUSH16(7, PORTDIO_FER)
-       PM_PUSH_SYNC(7)
-       PM_SYS_PUSH16(0, PORTEIO_DIR)
-       PM_SYS_PUSH16(1, PORTEIO_INEN)
-       PM_SYS_PUSH16(2, PORTEIO)
-       PM_SYS_PUSH16(3, PORTEIO_FER)
-       PM_PUSH_SYNC(3)
-#endif
-
        /* Save Core MMRs */
        I0.H = hi(COREMMR_BASE);
        I0.L = lo(COREMMR_BASE);
@@ -777,23 +759,6 @@ ENTRY(_do_hibernate)
        FP.H = hi(SYSMMR_BASE);
        FP.L = lo(SYSMMR_BASE);
 
-#ifdef PORTCIO_FER
-       PM_POP_SYNC(3)
-       PM_SYS_POP16(3, PORTEIO_FER)
-       PM_SYS_POP16(2, PORTEIO)
-       PM_SYS_POP16(1, PORTEIO_INEN)
-       PM_SYS_POP16(0, PORTEIO_DIR)
-       PM_POP_SYNC(7)
-       PM_SYS_POP16(7, PORTDIO_FER)
-       PM_SYS_POP16(6, PORTDIO)
-       PM_SYS_POP16(5, PORTDIO_INEN)
-       PM_SYS_POP16(4, PORTDIO_DIR)
-       PM_SYS_POP16(3, PORTCIO_FER)
-       PM_SYS_POP16(2, PORTCIO)
-       PM_SYS_POP16(1, PORTCIO_INEN)
-       PM_SYS_POP16(0, PORTCIO_DIR)
-#endif
-
 #ifdef EBIU_FCTL
        PM_POP_SYNC(12)
        PM_SYS_POP(12, EBIU_FCTL)