aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2008-02-08 15:12:37 -0500
committerBryan Wu <bryan.wu@analog.com>2008-02-08 15:12:37 -0500
commitcfefe3c683e0d14c9ce3aeb883c55c7f30c20183 (patch)
tree77434010fc64f64606e893ce7b6f73243073ebb0
parent2c4f829b0ce3d2fb447acca823e141094a50daa5 (diff)
[Blackfin] arch: hook up set_irq_wake in Blackfin's irq code
- Add support for irq_wake on system and gpio interrupts - Remove outdated kernel options - Add option to select default PM mode - Fix various places where SIC_IWRx was only handled partially Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
-rw-r--r--arch/blackfin/Kconfig49
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c20
-rw-r--r--arch/blackfin/mach-common/dpmc.S32
-rw-r--r--arch/blackfin/mach-common/ints-priority.c126
-rw-r--r--arch/blackfin/mach-common/pm.c44
-rw-r--r--include/asm-blackfin/bfin-global.h2
-rw-r--r--include/asm-blackfin/dpmc.h8
-rw-r--r--include/asm-blackfin/gpio.h8
8 files changed, 217 insertions, 72 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index ba21e33b8b1f..368bc7fe167e 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -544,7 +544,7 @@ config EXCPT_IRQ_SYSC_L1
544 default y 544 default y
545 help 545 help
546 If enabled, the entire ASM lowlevel exception and interrupt entry code 546 If enabled, the entire ASM lowlevel exception and interrupt entry code
547 (STORE/RESTORE CONTEXT) is linked into L1 instruction memory. 547 (STORE/RESTORE CONTEXT) is linked into L1 instruction memory.
548 (less latency) 548 (less latency)
549 549
550config DO_IRQ_L1 550config DO_IRQ_L1
@@ -904,29 +904,38 @@ config ARCH_SUSPEND_POSSIBLE
904 depends on !SMP 904 depends on !SMP
905 905
906choice 906choice
907 prompt "Select PM Wakeup Event Source" 907 prompt "Default Power Saving Mode"
908 default PM_WAKEUP_GPIO_BY_SIC_IWR
909 depends on PM 908 depends on PM
910 help 909 default PM_BFIN_SLEEP_DEEPER
911 If you have a GPIO already configured as input with the corresponding PORTx_MASK 910config PM_BFIN_SLEEP_DEEPER
912 bit set - "Specify Wakeup Event by SIC_IWR value" 911 bool "Sleep Deeper"
912 help
913 Sleep "Deeper" Mode (High Power Savings) - This mode reduces dynamic
914 power dissipation by disabling the clock to the processor core (CCLK).
915 Furthermore, Standby sets the internal power supply voltage (VDDINT)
916 to 0.85 V to provide the greatest power savings, while preserving the
917 processor state.
918 The PLL and system clock (SCLK) continue to operate at a very low
919 frequency of about 3.3 MHz. To preserve data integrity in the SDRAM,
920 the SDRAM is put into Self Refresh Mode. Typically an external event
921 such as GPIO interrupt or RTC activity wakes up the processor.
922 Various Peripherals such as UART, SPORT, PPI may not function as
923 normal during Sleep Deeper, due to the reduced SCLK frequency.
924 When in the sleep mode, system DMA access to L1 memory is not supported.
925
926config PM_BFIN_SLEEP
927 bool "Sleep"
928 help
929 Sleep Mode (High Power Savings) - The sleep mode reduces power
930 dissipation by disabling the clock to the processor core (CCLK).
931 The PLL and system clock (SCLK), however, continue to operate in
932 this mode. Typically an external event or RTC activity will wake
933 up the processor. When in the sleep mode,
934 system DMA access to L1 memory is not supported.
935endchoice
913 936
914config PM_WAKEUP_GPIO_BY_SIC_IWR
915 bool "Specify Wakeup Event by SIC_IWR value"
916config PM_WAKEUP_BY_GPIO 937config PM_WAKEUP_BY_GPIO
917 bool "Cause Wakeup Event by GPIO" 938 bool "Cause Wakeup Event by GPIO"
918config PM_WAKEUP_GPIO_API
919 bool "Configure Wakeup Event by PM GPIO API"
920
921endchoice
922
923config PM_WAKEUP_SIC_IWR
924 hex "Wakeup Events (SIC_IWR)"
925 depends on PM_WAKEUP_GPIO_BY_SIC_IWR
926 default 0x8 if (BF537 || BF536 || BF534)
927 default 0x80 if (BF533 || BF532 || BF531)
928 default 0x80 if (BF54x)
929 default 0x80 if (BF52x)
930 939
931config PM_WAKEUP_GPIO_NUMBER 940config PM_WAKEUP_GPIO_NUMBER
932 int "Wakeup GPIO number" 941 int "Wakeup GPIO number"
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 6bbe0a2fccb8..08788f7bbfba 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -186,7 +186,7 @@ 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#ifdef CONFIG_PM 189#if defined(CONFIG_PM) && !defined(CONFIG_BF54x)
190static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 190static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
191static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; 191static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
192static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; 192static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -696,9 +696,8 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type)
696 return 0; 696 return 0;
697} 697}
698 698
699u32 gpio_pm_setup(void) 699u32 bfin_pm_setup(void)
700{ 700{
701 u32 sic_iwr = 0;
702 u16 bank, mask, i, gpio; 701 u16 bank, mask, i, gpio;
703 702
704 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { 703 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
@@ -723,7 +722,8 @@ u32 gpio_pm_setup(void)
723 gpio = i; 722 gpio = i;
724 723
725 while (mask) { 724 while (mask) {
726 if (mask & 1) { 725 if ((mask & 1) && (wakeup_flags_map[gpio] !=
726 PM_WAKE_IGNORE)) {
727 reserved_gpio_map[gpio_bank(gpio)] |= 727 reserved_gpio_map[gpio_bank(gpio)] |=
728 gpio_bit(gpio); 728 gpio_bit(gpio);
729 bfin_gpio_wakeup_type(gpio, 729 bfin_gpio_wakeup_type(gpio,
@@ -734,21 +734,17 @@ u32 gpio_pm_setup(void)
734 mask >>= 1; 734 mask >>= 1;
735 } 735 }
736 736
737 sic_iwr |= 1 << 737 bfin_internal_set_wake(sic_iwr_irqs[bank], 1);
738 (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1));
739 gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; 738 gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
740 } 739 }
741 } 740 }
742 741
743 AWA_DUMMY_READ(maskb_set); 742 AWA_DUMMY_READ(maskb_set);
744 743
745 if (sic_iwr) 744 return 0;
746 return sic_iwr;
747 else
748 return IWR_ENABLE_ALL;
749} 745}
750 746
751void gpio_pm_restore(void) 747void bfin_pm_restore(void)
752{ 748{
753 u16 bank, mask, i; 749 u16 bank, mask, i;
754 750
@@ -768,7 +764,7 @@ void gpio_pm_restore(void)
768 764
769 reserved_gpio_map[bank] = 765 reserved_gpio_map[bank] =
770 gpio_bank_saved[bank].reserved; 766 gpio_bank_saved[bank].reserved;
771 767 bfin_internal_set_wake(sic_iwr_irqs[bank], 0);
772 } 768 }
773 769
774 gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; 770 gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S
index b82c096e1980..b80ddd8b232d 100644
--- a/arch/blackfin/mach-common/dpmc.S
+++ b/arch/blackfin/mach-common/dpmc.S
@@ -191,6 +191,9 @@ ENTRY(_sleep_mode)
191 call _test_pll_locked; 191 call _test_pll_locked;
192 192
193 R0 = IWR_ENABLE(0); 193 R0 = IWR_ENABLE(0);
194 R1 = IWR_DISABLE_ALL;
195 R2 = IWR_DISABLE_ALL;
196
194 call _set_sic_iwr; 197 call _set_sic_iwr;
195 198
196 P0.H = hi(PLL_CTL); 199 P0.H = hi(PLL_CTL);
@@ -237,6 +240,10 @@ ENTRY(_deep_sleep)
237 240
238 CLI R4; 241 CLI R4;
239 242
243 R0 = IWR_ENABLE(0);
244 R1 = IWR_DISABLE_ALL;
245 R2 = IWR_DISABLE_ALL;
246
240 call _set_sic_iwr; 247 call _set_sic_iwr;
241 248
242 call _set_dram_srfs; 249 call _set_dram_srfs;
@@ -261,6 +268,9 @@ ENTRY(_deep_sleep)
261 call _test_pll_locked; 268 call _test_pll_locked;
262 269
263 R0 = IWR_ENABLE(0); 270 R0 = IWR_ENABLE(0);
271 R1 = IWR_DISABLE_ALL;
272 R2 = IWR_DISABLE_ALL;
273
264 call _set_sic_iwr; 274 call _set_sic_iwr;
265 275
266 P0.H = hi(PLL_CTL); 276 P0.H = hi(PLL_CTL);
@@ -286,7 +296,13 @@ ENTRY(_sleep_deeper)
286 CLI R4; 296 CLI R4;
287 297
288 P3 = R0; 298 P3 = R0;
299 P4 = R1;
300 P5 = R2;
301
289 R0 = IWR_ENABLE(0); 302 R0 = IWR_ENABLE(0);
303 R1 = IWR_DISABLE_ALL;
304 R2 = IWR_DISABLE_ALL;
305
290 call _set_sic_iwr; 306 call _set_sic_iwr;
291 call _set_dram_srfs; /* Set SDRAM Self Refresh */ 307 call _set_dram_srfs; /* Set SDRAM Self Refresh */
292 308
@@ -327,6 +343,8 @@ ENTRY(_sleep_deeper)
327 call _test_pll_locked; 343 call _test_pll_locked;
328 344
329 R0 = P3; 345 R0 = P3;
346 R1 = P4;
347 R3 = P5;
330 call _set_sic_iwr; /* Set Awake from IDLE */ 348 call _set_sic_iwr; /* Set Awake from IDLE */
331 349
332 P0.H = hi(PLL_CTL); 350 P0.H = hi(PLL_CTL);
@@ -340,6 +358,9 @@ ENTRY(_sleep_deeper)
340 call _test_pll_locked; 358 call _test_pll_locked;
341 359
342 R0 = IWR_ENABLE(0); 360 R0 = IWR_ENABLE(0);
361 R1 = IWR_DISABLE_ALL;
362 R2 = IWR_DISABLE_ALL;
363
343 call _set_sic_iwr; /* Set Awake from IDLE PLL */ 364 call _set_sic_iwr; /* Set Awake from IDLE PLL */
344 365
345 P0.H = hi(VR_CTL); 366 P0.H = hi(VR_CTL);
@@ -417,14 +438,23 @@ ENTRY(_unset_dram_srfs)
417 RTS; 438 RTS;
418 439
419ENTRY(_set_sic_iwr) 440ENTRY(_set_sic_iwr)
420#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) 441#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
421 P0.H = hi(SIC_IWR0); 442 P0.H = hi(SIC_IWR0);
422 P0.L = lo(SIC_IWR0); 443 P0.L = lo(SIC_IWR0);
444 P1.H = hi(SIC_IWR1);
445 P1.L = lo(SIC_IWR1);
446 [P1] = R1;
447#if defined(CONFIG_BF54x)
448 P1.H = hi(SIC_IWR2);
449 P1.L = lo(SIC_IWR2);
450 [P1] = R2;
451#endif
423#else 452#else
424 P0.H = hi(SIC_IWR); 453 P0.H = hi(SIC_IWR);
425 P0.L = lo(SIC_IWR); 454 P0.L = lo(SIC_IWR);
426#endif 455#endif
427 [P0] = R0; 456 [P0] = R0;
457
428 SSYNC; 458 SSYNC;
429 RTS; 459 RTS;
430 460
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 166dbba0c396..81d00183ae91 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/ints-priority-sc.c 2 * File: arch/blackfin/mach-common/ints-priority.c
3 * Based on: 3 * Based on:
4 * Author: 4 * Author:
5 * 5 *
@@ -13,7 +13,7 @@
13 * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> 13 * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
14 * 2003 Metrowerks/Motorola 14 * 2003 Metrowerks/Motorola
15 * 2003 Bas Vermeulen <bas@buyways.nl> 15 * 2003 Bas Vermeulen <bas@buyways.nl>
16 * Copyright 2004-2007 Analog Devices Inc. 16 * Copyright 2004-2008 Analog Devices Inc.
17 * 17 *
18 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 18 * Bugs: Enter bugs at http://blackfin.uclinux.org/
19 * 19 *
@@ -69,6 +69,10 @@ unsigned long irq_flags = 0x1f;
69/* The number of spurious interrupts */ 69/* The number of spurious interrupts */
70atomic_t num_spurious; 70atomic_t num_spurious;
71 71
72#ifdef CONFIG_PM
73unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
74#endif
75
72struct ivgx { 76struct ivgx {
73 /* irq number for request_irq, available in mach-bf533/irq.h */ 77 /* irq number for request_irq, available in mach-bf533/irq.h */
74 unsigned int irqno; 78 unsigned int irqno;
@@ -178,6 +182,27 @@ static void bfin_internal_unmask_irq(unsigned int irq)
178 SSYNC(); 182 SSYNC();
179} 183}
180 184
185#ifdef CONFIG_PM
186int bfin_internal_set_wake(unsigned int irq, unsigned int state)
187{
188 unsigned bank, bit;
189 unsigned long flags;
190 bank = (irq - (IRQ_CORETMR + 1)) / 32;
191 bit = (irq - (IRQ_CORETMR + 1)) % 32;
192
193 local_irq_save(flags);
194
195 if (state)
196 bfin_sic_iwr[bank] |= (1 << bit);
197 else
198 bfin_sic_iwr[bank] &= ~(1 << bit);
199
200 local_irq_restore(flags);
201
202 return 0;
203}
204#endif
205
181static struct irq_chip bfin_core_irqchip = { 206static struct irq_chip bfin_core_irqchip = {
182 .ack = ack_noop, 207 .ack = ack_noop,
183 .mask = bfin_core_mask_irq, 208 .mask = bfin_core_mask_irq,
@@ -188,6 +213,9 @@ static struct irq_chip bfin_internal_irqchip = {
188 .ack = ack_noop, 213 .ack = ack_noop,
189 .mask = bfin_internal_mask_irq, 214 .mask = bfin_internal_mask_irq,
190 .unmask = bfin_internal_unmask_irq, 215 .unmask = bfin_internal_unmask_irq,
216#ifdef CONFIG_PM
217 .set_wake = bfin_internal_set_wake,
218#endif
191}; 219};
192 220
193#ifdef BF537_GENERIC_ERROR_INT_DEMUX 221#ifdef BF537_GENERIC_ERROR_INT_DEMUX
@@ -434,6 +462,20 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
434 return 0; 462 return 0;
435} 463}
436 464
465#ifdef CONFIG_PM
466int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
467{
468 unsigned gpio = irq_to_gpio(irq);
469
470 if (state)
471 gpio_pm_wakeup_request(gpio, PM_WAKE_IGNORE);
472 else
473 gpio_pm_wakeup_free(gpio);
474
475 return 0;
476}
477#endif
478
437static struct irq_chip bfin_gpio_irqchip = { 479static struct irq_chip bfin_gpio_irqchip = {
438 .ack = bfin_gpio_ack_irq, 480 .ack = bfin_gpio_ack_irq,
439 .mask = bfin_gpio_mask_irq, 481 .mask = bfin_gpio_mask_irq,
@@ -441,7 +483,10 @@ static struct irq_chip bfin_gpio_irqchip = {
441 .unmask = bfin_gpio_unmask_irq, 483 .unmask = bfin_gpio_unmask_irq,
442 .set_type = bfin_gpio_irq_type, 484 .set_type = bfin_gpio_irq_type,
443 .startup = bfin_gpio_irq_startup, 485 .startup = bfin_gpio_irq_startup,
444 .shutdown = bfin_gpio_irq_shutdown 486 .shutdown = bfin_gpio_irq_shutdown,
487#ifdef CONFIG_PM
488 .set_wake = bfin_gpio_set_wake,
489#endif
445}; 490};
446 491
447static void bfin_demux_gpio_irq(unsigned int inta_irq, 492static void bfin_demux_gpio_irq(unsigned int inta_irq,
@@ -487,7 +532,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq,
487 } 532 }
488 533
489 if (search) { 534 if (search) {
490 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) { 535 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
491 irq += i; 536 irq += i;
492 537
493 mask = get_gpiop_data(i) & 538 mask = get_gpiop_data(i) &
@@ -763,6 +808,74 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
763 return 0; 808 return 0;
764} 809}
765 810
811#ifdef CONFIG_PM
812u32 pint_saved_masks[NR_PINT_SYS_IRQS];
813u32 pint_wakeup_masks[NR_PINT_SYS_IRQS];
814
815int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
816{
817 u32 pint_irq;
818 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
819 u32 bank = PINT_2_BANK(pint_val);
820 u32 pintbit = PINT_BIT(pint_val);
821
822 switch (bank) {
823 case 0:
824 pint_irq = IRQ_PINT0;
825 break;
826 case 2:
827 pint_irq = IRQ_PINT2;
828 break;
829 case 3:
830 pint_irq = IRQ_PINT3;
831 break;
832 case 1:
833 pint_irq = IRQ_PINT1;
834 break;
835 default:
836 return -EINVAL;
837 }
838
839 bfin_internal_set_wake(pint_irq, state);
840
841 if (state)
842 pint_wakeup_masks[bank] |= pintbit;
843 else
844 pint_wakeup_masks[bank] &= ~pintbit;
845
846 return 0;
847}
848
849u32 bfin_pm_setup(void)
850{
851 u32 val, i;
852
853 for (i = 0; i < NR_PINT_SYS_IRQS; i++) {
854 val = pint[i]->mask_clear;
855 pint_saved_masks[i] = val;
856 if (val ^ pint_wakeup_masks[i]) {
857 pint[i]->mask_clear = val;
858 pint[i]->mask_set = pint_wakeup_masks[i];
859 }
860 }
861
862 return 0;
863}
864
865void bfin_pm_restore(void)
866{
867 u32 i, val;
868
869 for (i = 0; i < NR_PINT_SYS_IRQS; i++) {
870 val = pint_saved_masks[i];
871 if (val ^ pint_wakeup_masks[i]) {
872 pint[i]->mask_clear = pint[i]->mask_clear;
873 pint[i]->mask_set = val;
874 }
875 }
876}
877#endif
878
766static struct irq_chip bfin_gpio_irqchip = { 879static struct irq_chip bfin_gpio_irqchip = {
767 .ack = bfin_gpio_ack_irq, 880 .ack = bfin_gpio_ack_irq,
768 .mask = bfin_gpio_mask_irq, 881 .mask = bfin_gpio_mask_irq,
@@ -770,7 +883,10 @@ static struct irq_chip bfin_gpio_irqchip = {
770 .unmask = bfin_gpio_unmask_irq, 883 .unmask = bfin_gpio_unmask_irq,
771 .set_type = bfin_gpio_irq_type, 884 .set_type = bfin_gpio_irq_type,
772 .startup = bfin_gpio_irq_startup, 885 .startup = bfin_gpio_irq_startup,
773 .shutdown = bfin_gpio_irq_shutdown 886 .shutdown = bfin_gpio_irq_shutdown,
887#ifdef CONFIG_PM
888 .set_wake = bfin_gpio_set_wake,
889#endif
774}; 890};
775 891
776static void bfin_demux_gpio_irq(unsigned int inta_irq, 892static void bfin_demux_gpio_irq(unsigned int inta_irq,
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 81930f7d06f1..0be805ca423f 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -4,7 +4,7 @@
4 * Author: Cliff Brake <cbrake@accelent.com> Copyright (c) 2001 4 * Author: Cliff Brake <cbrake@accelent.com> Copyright (c) 2001
5 * 5 *
6 * Created: 2001 6 * Created: 2001
7 * Description: Power management for the bfin 7 * Description: Blackfin power management
8 * 8 *
9 * Modified: Nicolas Pitre - PXA250 support 9 * Modified: Nicolas Pitre - PXA250 support
10 * Copyright (c) 2002 Monta Vista Software, Inc. 10 * Copyright (c) 2002 Monta Vista Software, Inc.
@@ -12,7 +12,7 @@
12 * Copyright (c) 2002 Monta Vista Software, Inc. 12 * Copyright (c) 2002 Monta Vista Software, Inc.
13 * Dirk Behme <dirk.behme@de.bosch.com> - OMAP1510/1610 13 * Dirk Behme <dirk.behme@de.bosch.com> - OMAP1510/1610
14 * Copyright 2004 14 * Copyright 2004
15 * Copyright 2004-2006 Analog Devices Inc. 15 * Copyright 2004-2008 Analog Devices Inc.
16 * 16 *
17 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 17 * Bugs: Enter bugs at http://blackfin.uclinux.org/
18 * 18 *
@@ -67,42 +67,30 @@ void bfin_pm_suspend_standby_enter(void)
67 gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); 67 gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE);
68#endif 68#endif
69 69
70#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API) 70 u32 flags;
71 {
72 u32 flags;
73 71
74 local_irq_save(flags); 72 local_irq_save(flags);
73 bfin_pm_setup();
75 74
76 sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/ 75#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
77 76 sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
78 gpio_pm_restore();
79
80#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
81 bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
82 bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
83# ifdef CONFIG_BF54x
84 bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
85# endif
86#else 77#else
87 bfin_write_SIC_IWR(IWR_ENABLE_ALL); 78 sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
88#endif 79#endif
89 80
90 local_irq_restore(flags); 81 bfin_pm_restore();
91 }
92#endif
93 82
94#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR) 83#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
95 sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
96# if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
97 bfin_write_SIC_IWR0(IWR_ENABLE_ALL); 84 bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
98 bfin_write_SIC_IWR1(IWR_ENABLE_ALL); 85 bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
99# ifdef CONFIG_BF54x 86# ifdef CONFIG_BF54x
100 bfin_write_SIC_IWR2(IWR_ENABLE_ALL); 87 bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
101# endif
102# else
103 bfin_write_SIC_IWR(IWR_ENABLE_ALL);
104# endif 88# endif
105#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ 89#else
90 bfin_write_SIC_IWR(IWR_ENABLE_ALL);
91#endif
92
93 local_irq_restore(flags);
106} 94}
107 95
108/* 96/*
diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h
index 6ae0619d7696..5dba3a735596 100644
--- a/include/asm-blackfin/bfin-global.h
+++ b/include/asm-blackfin/bfin-global.h
@@ -70,6 +70,7 @@ extern void program_IAR(void);
70extern void evt14_softirq(void); 70extern void evt14_softirq(void);
71extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); 71extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
72extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type); 72extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type);
73extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
73 74
74extern asmlinkage void finish_atomic_sections (struct pt_regs *regs); 75extern asmlinkage void finish_atomic_sections (struct pt_regs *regs);
75extern char fixed_code_start; 76extern char fixed_code_start;
@@ -121,6 +122,7 @@ extern unsigned long dpdt_swapcount_table[];
121 122
122extern unsigned long table_start, table_end; 123extern unsigned long table_start, table_end;
123 124
125extern unsigned long bfin_sic_iwr[];
124extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */ 126extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */
125extern struct file_operations dpmc_fops; 127extern struct file_operations dpmc_fops;
126extern char _start; 128extern char _start;
diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h
index f162edb23033..686cf83a5269 100644
--- a/include/asm-blackfin/dpmc.h
+++ b/include/asm-blackfin/dpmc.h
@@ -53,10 +53,10 @@ unsigned long get_pll_status(void);
53void change_baud(int baud); 53void change_baud(int baud);
54void fullon_mode(void); 54void fullon_mode(void);
55void active_mode(void); 55void active_mode(void);
56void sleep_mode(u32 sic_iwr); 56void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
57void deep_sleep(u32 sic_iwr); 57void deep_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
58void hibernate_mode(u32 sic_iwr); 58void hibernate_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
59void sleep_deeper(u32 sic_iwr); 59void sleep_deeper(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
60void program_wdog_timer(unsigned long); 60void program_wdog_timer(unsigned long);
61void unmask_wdog_wakeup_evt(void); 61void unmask_wdog_wakeup_evt(void);
62void clear_wdog_wakeup_evt(void); 62void clear_wdog_wakeup_evt(void);
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
index d0426c108262..27ff532a806c 100644
--- a/include/asm-blackfin/gpio.h
+++ b/include/asm-blackfin/gpio.h
@@ -376,16 +376,19 @@ struct gpio_port_t {
376#endif 376#endif
377 377
378#ifdef CONFIG_PM 378#ifdef CONFIG_PM
379unsigned int bfin_pm_setup(void);
380void bfin_pm_restore(void);
381
382#ifndef CONFIG_BF54x
379#define PM_WAKE_RISING 0x1 383#define PM_WAKE_RISING 0x1
380#define PM_WAKE_FALLING 0x2 384#define PM_WAKE_FALLING 0x2
381#define PM_WAKE_HIGH 0x4 385#define PM_WAKE_HIGH 0x4
382#define PM_WAKE_LOW 0x8 386#define PM_WAKE_LOW 0x8
383#define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING) 387#define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING)
388#define PM_WAKE_IGNORE 0xF0
384 389
385int gpio_pm_wakeup_request(unsigned gpio, unsigned char type); 390int gpio_pm_wakeup_request(unsigned gpio, unsigned char type);
386void gpio_pm_wakeup_free(unsigned gpio); 391void gpio_pm_wakeup_free(unsigned gpio);
387unsigned int gpio_pm_setup(void);
388void gpio_pm_restore(void);
389 392
390struct gpio_port_s { 393struct gpio_port_s {
391 unsigned short data; 394 unsigned short data;
@@ -409,6 +412,7 @@ struct gpio_port_s {
409 unsigned short fer; 412 unsigned short fer;
410 unsigned short reserved; 413 unsigned short reserved;
411}; 414};
415#endif /*CONFIG_BF54x*/
412#endif /*CONFIG_PM*/ 416#endif /*CONFIG_PM*/
413 417
414/*********************************************************** 418/***********************************************************