aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-06-27 14:46:14 -0400
committerMike Frysinger <vapier@gentoo.org>2011-07-23 01:18:30 -0400
commit9466a0510a5445d81eaf33affc20e2f7e2e718fb (patch)
treeecbecd217aedca3575d27444efeadf1fee1c8f38 /arch
parenteed7b8365807549c67613ea7d9a451262050ba3e (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.h4
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c22
-rw-r--r--arch/blackfin/mach-bf538/ext-gpio.c37
-rw-r--r--arch/blackfin/mach-bf538/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-common/dpmc_modes.S35
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
120void bfin_special_gpio_free(unsigned gpio); 120void bfin_special_gpio_free(unsigned gpio);
121int bfin_special_gpio_request(unsigned gpio, const char *label); 121int bfin_special_gpio_request(unsigned gpio, const char *label);
122# ifdef CONFIG_PM
123void bfin_special_gpio_pm_hibernate_restore(void);
124void 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)
120static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; 120static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
121# ifdef BF538_FAMILY
122static unsigned short port_fer_saved[3];
123# endif
121#endif 124#endif
122 125
123static void gpio_error(unsigned gpio) 126static 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}
123arch_initcall(bf538_extgpio_setup); 123arch_initcall(bf538_extgpio_setup);
124
125#ifdef CONFIG_PM
126static struct {
127 u16 data, dir, inen;
128} gpio_bank_saved[3];
129
130static void __iomem * const port_bases[3] = {
131 (void *)PORTCIO,
132 (void *)PORTDIO,
133 (void *)PORTEIO,
134};
135
136void 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
147void 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)