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 /arch/blackfin/mach-common/ints-priority.c | |
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>
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 126 |
1 files changed, 121 insertions, 5 deletions
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, |