diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2008-02-08 15:12:37 -0500 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2008-02-08 15:12:37 -0500 |
commit | cfefe3c683e0d14c9ce3aeb883c55c7f30c20183 (patch) | |
tree | 77434010fc64f64606e893ce7b6f73243073ebb0 | |
parent | 2c4f829b0ce3d2fb447acca823e141094a50daa5 (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/Kconfig | 49 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 20 | ||||
-rw-r--r-- | arch/blackfin/mach-common/dpmc.S | 32 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 126 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 44 | ||||
-rw-r--r-- | include/asm-blackfin/bfin-global.h | 2 | ||||
-rw-r--r-- | include/asm-blackfin/dpmc.h | 8 | ||||
-rw-r--r-- | include/asm-blackfin/gpio.h | 8 |
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 | ||
550 | config DO_IRQ_L1 | 550 | config DO_IRQ_L1 |
@@ -904,29 +904,38 @@ config ARCH_SUSPEND_POSSIBLE | |||
904 | depends on !SMP | 904 | depends on !SMP |
905 | 905 | ||
906 | choice | 906 | choice |
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 | 910 | config 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 | |||
926 | config 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. | ||
935 | endchoice | ||
913 | 936 | ||
914 | config PM_WAKEUP_GPIO_BY_SIC_IWR | ||
915 | bool "Specify Wakeup Event by SIC_IWR value" | ||
916 | config PM_WAKEUP_BY_GPIO | 937 | config PM_WAKEUP_BY_GPIO |
917 | bool "Cause Wakeup Event by GPIO" | 938 | bool "Cause Wakeup Event by GPIO" |
918 | config PM_WAKEUP_GPIO_API | ||
919 | bool "Configure Wakeup Event by PM GPIO API" | ||
920 | |||
921 | endchoice | ||
922 | |||
923 | config 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 | ||
931 | config PM_WAKEUP_GPIO_NUMBER | 940 | config 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) |
190 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 190 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
191 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | 191 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; |
192 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 192 | static 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 | ||
699 | u32 gpio_pm_setup(void) | 699 | u32 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 | ||
751 | void gpio_pm_restore(void) | 747 | void 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 | ||
419 | ENTRY(_set_sic_iwr) | 440 | ENTRY(_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 */ |
70 | atomic_t num_spurious; | 70 | atomic_t num_spurious; |
71 | 71 | ||
72 | #ifdef CONFIG_PM | ||
73 | unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ | ||
74 | #endif | ||
75 | |||
72 | struct ivgx { | 76 | struct 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 | ||
186 | int 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 | |||
181 | static struct irq_chip bfin_core_irqchip = { | 206 | static 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 | ||
466 | int 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 | |||
437 | static struct irq_chip bfin_gpio_irqchip = { | 479 | static 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 | ||
447 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 492 | static 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 | ||
812 | u32 pint_saved_masks[NR_PINT_SYS_IRQS]; | ||
813 | u32 pint_wakeup_masks[NR_PINT_SYS_IRQS]; | ||
814 | |||
815 | int 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 | |||
849 | u32 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 | |||
865 | void 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 | |||
766 | static struct irq_chip bfin_gpio_irqchip = { | 879 | static 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 | ||
776 | static void bfin_demux_gpio_irq(unsigned int inta_irq, | 892 | static 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); | |||
70 | extern void evt14_softirq(void); | 70 | extern void evt14_softirq(void); |
71 | extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); | 71 | extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); |
72 | extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type); | 72 | extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type); |
73 | extern int bfin_internal_set_wake(unsigned int irq, unsigned int state); | ||
73 | 74 | ||
74 | extern asmlinkage void finish_atomic_sections (struct pt_regs *regs); | 75 | extern asmlinkage void finish_atomic_sections (struct pt_regs *regs); |
75 | extern char fixed_code_start; | 76 | extern char fixed_code_start; |
@@ -121,6 +122,7 @@ extern unsigned long dpdt_swapcount_table[]; | |||
121 | 122 | ||
122 | extern unsigned long table_start, table_end; | 123 | extern unsigned long table_start, table_end; |
123 | 124 | ||
125 | extern unsigned long bfin_sic_iwr[]; | ||
124 | extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */ | 126 | extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */ |
125 | extern struct file_operations dpmc_fops; | 127 | extern struct file_operations dpmc_fops; |
126 | extern char _start; | 128 | extern 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); | |||
53 | void change_baud(int baud); | 53 | void change_baud(int baud); |
54 | void fullon_mode(void); | 54 | void fullon_mode(void); |
55 | void active_mode(void); | 55 | void active_mode(void); |
56 | void sleep_mode(u32 sic_iwr); | 56 | void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); |
57 | void deep_sleep(u32 sic_iwr); | 57 | void deep_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); |
58 | void hibernate_mode(u32 sic_iwr); | 58 | void hibernate_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); |
59 | void sleep_deeper(u32 sic_iwr); | 59 | void sleep_deeper(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); |
60 | void program_wdog_timer(unsigned long); | 60 | void program_wdog_timer(unsigned long); |
61 | void unmask_wdog_wakeup_evt(void); | 61 | void unmask_wdog_wakeup_evt(void); |
62 | void clear_wdog_wakeup_evt(void); | 62 | void 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 |
379 | unsigned int bfin_pm_setup(void); | ||
380 | void 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 | ||
385 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type); | 390 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type); |
386 | void gpio_pm_wakeup_free(unsigned gpio); | 391 | void gpio_pm_wakeup_free(unsigned gpio); |
387 | unsigned int gpio_pm_setup(void); | ||
388 | void gpio_pm_restore(void); | ||
389 | 392 | ||
390 | struct gpio_port_s { | 393 | struct 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 | /*********************************************************** |