aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
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 /arch/blackfin/mach-common
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>
Diffstat (limited to 'arch/blackfin/mach-common')
-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
3 files changed, 168 insertions, 34 deletions
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/*