diff options
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/Kconfig | 26 | ||||
-rw-r--r-- | arch/blackfin/include/asm/gpio.h | 22 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 131 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 9 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 24 |
5 files changed, 24 insertions, 188 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c078849df7f9..405bdaa17333 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -1187,32 +1187,6 @@ config PM_BFIN_SLEEP | |||
1187 | If unsure, select "Sleep Deeper". | 1187 | If unsure, select "Sleep Deeper". |
1188 | endchoice | 1188 | endchoice |
1189 | 1189 | ||
1190 | config PM_WAKEUP_BY_GPIO | ||
1191 | bool "Allow Wakeup from Standby by GPIO" | ||
1192 | depends on PM && !BF54x | ||
1193 | |||
1194 | config PM_WAKEUP_GPIO_NUMBER | ||
1195 | int "GPIO number" | ||
1196 | range 0 47 | ||
1197 | depends on PM_WAKEUP_BY_GPIO | ||
1198 | default 2 | ||
1199 | |||
1200 | choice | ||
1201 | prompt "GPIO Polarity" | ||
1202 | depends on PM_WAKEUP_BY_GPIO | ||
1203 | default PM_WAKEUP_GPIO_POLAR_H | ||
1204 | config PM_WAKEUP_GPIO_POLAR_H | ||
1205 | bool "Active High" | ||
1206 | config PM_WAKEUP_GPIO_POLAR_L | ||
1207 | bool "Active Low" | ||
1208 | config PM_WAKEUP_GPIO_POLAR_EDGE_F | ||
1209 | bool "Falling EDGE" | ||
1210 | config PM_WAKEUP_GPIO_POLAR_EDGE_R | ||
1211 | bool "Rising EDGE" | ||
1212 | config PM_WAKEUP_GPIO_POLAR_EDGE_B | ||
1213 | bool "Both EDGE" | ||
1214 | endchoice | ||
1215 | |||
1216 | comment "Possible Suspend Mem / Hibernate Wake-Up Sources" | 1190 | comment "Possible Suspend Mem / Hibernate Wake-Up Sources" |
1217 | depends on PM | 1191 | depends on PM |
1218 | 1192 | ||
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 91bd2d7b9d55..01b19d0cf509 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h | |||
@@ -167,23 +167,23 @@ int bfin_special_gpio_request(unsigned gpio, const char *label); | |||
167 | #endif | 167 | #endif |
168 | 168 | ||
169 | #ifdef CONFIG_PM | 169 | #ifdef CONFIG_PM |
170 | int bfin_pm_standby_ctrl(unsigned ctrl); | ||
170 | 171 | ||
171 | unsigned int bfin_pm_standby_setup(void); | 172 | static inline int bfin_pm_standby_setup(void) |
172 | void bfin_pm_standby_restore(void); | 173 | { |
174 | return bfin_pm_standby_ctrl(1); | ||
175 | } | ||
176 | |||
177 | static inline void bfin_pm_standby_restore(void) | ||
178 | { | ||
179 | bfin_pm_standby_ctrl(0); | ||
180 | } | ||
173 | 181 | ||
174 | void bfin_gpio_pm_hibernate_restore(void); | 182 | void bfin_gpio_pm_hibernate_restore(void); |
175 | void bfin_gpio_pm_hibernate_suspend(void); | 183 | void bfin_gpio_pm_hibernate_suspend(void); |
176 | 184 | ||
177 | #ifndef CONFIG_BF54x | 185 | #ifndef CONFIG_BF54x |
178 | #define PM_WAKE_RISING 0x1 | 186 | int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); |
179 | #define PM_WAKE_FALLING 0x2 | ||
180 | #define PM_WAKE_HIGH 0x4 | ||
181 | #define PM_WAKE_LOW 0x8 | ||
182 | #define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING) | ||
183 | #define PM_WAKE_IGNORE 0xF0 | ||
184 | |||
185 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type); | ||
186 | void gpio_pm_wakeup_free(unsigned gpio); | ||
187 | 187 | ||
188 | struct gpio_port_s { | 188 | struct gpio_port_s { |
189 | unsigned short data; | 189 | unsigned short data; |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index e35e20f00d9b..42833ee2b308 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -475,9 +475,7 @@ GET_GPIO_P(maskb) | |||
475 | 475 | ||
476 | 476 | ||
477 | #ifdef CONFIG_PM | 477 | #ifdef CONFIG_PM |
478 | |||
479 | static unsigned short wakeup_map[GPIO_BANK_NUM]; | 478 | static unsigned short wakeup_map[GPIO_BANK_NUM]; |
480 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | ||
481 | 479 | ||
482 | static const unsigned int sic_iwr_irqs[] = { | 480 | static const unsigned int sic_iwr_irqs[] = { |
483 | #if defined(BF533_FAMILY) | 481 | #if defined(BF533_FAMILY) |
@@ -514,112 +512,26 @@ static const unsigned int sic_iwr_irqs[] = { | |||
514 | ************************************************************* | 512 | ************************************************************* |
515 | * MODIFICATION HISTORY : | 513 | * MODIFICATION HISTORY : |
516 | **************************************************************/ | 514 | **************************************************************/ |
517 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type) | 515 | int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) |
518 | { | ||
519 | unsigned long flags; | ||
520 | |||
521 | if ((check_gpio(gpio) < 0) || !type) | ||
522 | return -EINVAL; | ||
523 | |||
524 | local_irq_save_hw(flags); | ||
525 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); | ||
526 | wakeup_flags_map[gpio] = type; | ||
527 | local_irq_restore_hw(flags); | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | EXPORT_SYMBOL(gpio_pm_wakeup_request); | ||
532 | |||
533 | void gpio_pm_wakeup_free(unsigned gpio) | ||
534 | { | 516 | { |
535 | unsigned long flags; | 517 | unsigned long flags; |
536 | 518 | ||
537 | if (check_gpio(gpio) < 0) | 519 | if (check_gpio(gpio) < 0) |
538 | return; | 520 | return -EINVAL; |
539 | 521 | ||
540 | local_irq_save_hw(flags); | 522 | local_irq_save_hw(flags); |
541 | 523 | if (ctrl) | |
542 | wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); | 524 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); |
543 | |||
544 | local_irq_restore_hw(flags); | ||
545 | } | ||
546 | EXPORT_SYMBOL(gpio_pm_wakeup_free); | ||
547 | |||
548 | static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) | ||
549 | { | ||
550 | port_setup(gpio, GPIO_USAGE); | ||
551 | set_gpio_dir(gpio, 0); | ||
552 | set_gpio_inen(gpio, 1); | ||
553 | |||
554 | if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) | ||
555 | set_gpio_edge(gpio, 1); | ||
556 | else | ||
557 | set_gpio_edge(gpio, 0); | ||
558 | |||
559 | if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) | ||
560 | set_gpio_both(gpio, 1); | ||
561 | else | 525 | else |
562 | set_gpio_both(gpio, 0); | 526 | wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); |
563 | |||
564 | if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) | ||
565 | set_gpio_polar(gpio, 1); | ||
566 | else | ||
567 | set_gpio_polar(gpio, 0); | ||
568 | 527 | ||
569 | SSYNC(); | 528 | set_gpio_maskb(gpio, ctrl); |
570 | 529 | local_irq_restore_hw(flags); | |
571 | return 0; | ||
572 | } | ||
573 | |||
574 | u32 bfin_pm_standby_setup(void) | ||
575 | { | ||
576 | u16 bank, mask, i, gpio; | ||
577 | |||
578 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
579 | mask = wakeup_map[gpio_bank(i)]; | ||
580 | bank = gpio_bank(i); | ||
581 | |||
582 | gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; | ||
583 | gpio_array[bank]->maskb = 0; | ||
584 | |||
585 | if (mask) { | ||
586 | #if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) | ||
587 | gpio_bank_saved[bank].fer = *port_fer[bank]; | ||
588 | #endif | ||
589 | gpio_bank_saved[bank].inen = gpio_array[bank]->inen; | ||
590 | gpio_bank_saved[bank].polar = gpio_array[bank]->polar; | ||
591 | gpio_bank_saved[bank].dir = gpio_array[bank]->dir; | ||
592 | gpio_bank_saved[bank].edge = gpio_array[bank]->edge; | ||
593 | gpio_bank_saved[bank].both = gpio_array[bank]->both; | ||
594 | gpio_bank_saved[bank].reserved = | ||
595 | reserved_gpio_map[bank]; | ||
596 | |||
597 | gpio = i; | ||
598 | |||
599 | while (mask) { | ||
600 | if ((mask & 1) && (wakeup_flags_map[gpio] != | ||
601 | PM_WAKE_IGNORE)) { | ||
602 | reserved_gpio_map[gpio_bank(gpio)] |= | ||
603 | gpio_bit(gpio); | ||
604 | bfin_gpio_wakeup_type(gpio, | ||
605 | wakeup_flags_map[gpio]); | ||
606 | set_gpio_data(gpio, 0); /*Clear*/ | ||
607 | } | ||
608 | gpio++; | ||
609 | mask >>= 1; | ||
610 | } | ||
611 | |||
612 | bfin_internal_set_wake(sic_iwr_irqs[bank], 1); | ||
613 | gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; | ||
614 | } | ||
615 | } | ||
616 | |||
617 | AWA_DUMMY_READ(maskb_set); | ||
618 | 530 | ||
619 | return 0; | 531 | return 0; |
620 | } | 532 | } |
621 | 533 | ||
622 | void bfin_pm_standby_restore(void) | 534 | int bfin_pm_standby_ctrl(unsigned ctrl) |
623 | { | 535 | { |
624 | u16 bank, mask, i; | 536 | u16 bank, mask, i; |
625 | 537 | ||
@@ -627,24 +539,10 @@ void bfin_pm_standby_restore(void) | |||
627 | mask = wakeup_map[gpio_bank(i)]; | 539 | mask = wakeup_map[gpio_bank(i)]; |
628 | bank = gpio_bank(i); | 540 | bank = gpio_bank(i); |
629 | 541 | ||
630 | if (mask) { | 542 | if (mask) |
631 | #if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) | 543 | bfin_internal_set_wake(sic_iwr_irqs[bank], ctrl); |
632 | *port_fer[bank] = gpio_bank_saved[bank].fer; | ||
633 | #endif | ||
634 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; | ||
635 | gpio_array[bank]->dir = gpio_bank_saved[bank].dir; | ||
636 | gpio_array[bank]->polar = gpio_bank_saved[bank].polar; | ||
637 | gpio_array[bank]->edge = gpio_bank_saved[bank].edge; | ||
638 | gpio_array[bank]->both = gpio_bank_saved[bank].both; | ||
639 | |||
640 | reserved_gpio_map[bank] = | ||
641 | gpio_bank_saved[bank].reserved; | ||
642 | bfin_internal_set_wake(sic_iwr_irqs[bank], 0); | ||
643 | } | ||
644 | |||
645 | gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; | ||
646 | } | 544 | } |
647 | AWA_DUMMY_READ(maskb); | 545 | return 0; |
648 | } | 546 | } |
649 | 547 | ||
650 | void bfin_gpio_pm_hibernate_suspend(void) | 548 | void bfin_gpio_pm_hibernate_suspend(void) |
@@ -708,16 +606,11 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
708 | #else /* CONFIG_BF54x */ | 606 | #else /* CONFIG_BF54x */ |
709 | #ifdef CONFIG_PM | 607 | #ifdef CONFIG_PM |
710 | 608 | ||
711 | u32 bfin_pm_standby_setup(void) | 609 | int bfin_pm_standby_ctrl(unsigned ctrl) |
712 | { | 610 | { |
713 | return 0; | 611 | return 0; |
714 | } | 612 | } |
715 | 613 | ||
716 | void bfin_pm_standby_restore(void) | ||
717 | { | ||
718 | |||
719 | } | ||
720 | |||
721 | void bfin_gpio_pm_hibernate_suspend(void) | 614 | void bfin_gpio_pm_hibernate_suspend(void) |
722 | { | 615 | { |
723 | int i, bank; | 616 | int i, bank; |
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 7ad8878bfa18..ce988713445d 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -662,14 +662,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
662 | #ifdef CONFIG_PM | 662 | #ifdef CONFIG_PM |
663 | int bfin_gpio_set_wake(unsigned int irq, unsigned int state) | 663 | int bfin_gpio_set_wake(unsigned int irq, unsigned int state) |
664 | { | 664 | { |
665 | unsigned gpio = irq_to_gpio(irq); | 665 | return gpio_pm_wakeup_ctrl(irq_to_gpio(irq), state); |
666 | |||
667 | if (state) | ||
668 | gpio_pm_wakeup_request(gpio, PM_WAKE_IGNORE); | ||
669 | else | ||
670 | gpio_pm_wakeup_free(gpio); | ||
671 | |||
672 | return 0; | ||
673 | } | 666 | } |
674 | #endif | 667 | #endif |
675 | 668 | ||
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index c1f1ccc846f0..ea7f95f6bb4c 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -20,35 +20,11 @@ | |||
20 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
21 | #include <asm/dpmc.h> | 21 | #include <asm/dpmc.h> |
22 | 22 | ||
23 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H | ||
24 | #define WAKEUP_TYPE PM_WAKE_HIGH | ||
25 | #endif | ||
26 | |||
27 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_L | ||
28 | #define WAKEUP_TYPE PM_WAKE_LOW | ||
29 | #endif | ||
30 | |||
31 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_F | ||
32 | #define WAKEUP_TYPE PM_WAKE_FALLING | ||
33 | #endif | ||
34 | |||
35 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_R | ||
36 | #define WAKEUP_TYPE PM_WAKE_RISING | ||
37 | #endif | ||
38 | |||
39 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_B | ||
40 | #define WAKEUP_TYPE PM_WAKE_BOTH_EDGES | ||
41 | #endif | ||
42 | |||
43 | 23 | ||
44 | void bfin_pm_suspend_standby_enter(void) | 24 | void bfin_pm_suspend_standby_enter(void) |
45 | { | 25 | { |
46 | unsigned long flags; | 26 | unsigned long flags; |
47 | 27 | ||
48 | #ifdef CONFIG_PM_WAKEUP_BY_GPIO | ||
49 | gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); | ||
50 | #endif | ||
51 | |||
52 | local_irq_save_hw(flags); | 28 | local_irq_save_hw(flags); |
53 | bfin_pm_standby_setup(); | 29 | bfin_pm_standby_setup(); |
54 | 30 | ||