aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/Kconfig26
-rw-r--r--arch/blackfin/include/asm/gpio.h22
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c131
-rw-r--r--arch/blackfin/mach-common/ints-priority.c9
-rw-r--r--arch/blackfin/mach-common/pm.c24
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".
1188endchoice 1188endchoice
1189 1189
1190config PM_WAKEUP_BY_GPIO
1191 bool "Allow Wakeup from Standby by GPIO"
1192 depends on PM && !BF54x
1193
1194config PM_WAKEUP_GPIO_NUMBER
1195 int "GPIO number"
1196 range 0 47
1197 depends on PM_WAKEUP_BY_GPIO
1198 default 2
1199
1200choice
1201 prompt "GPIO Polarity"
1202 depends on PM_WAKEUP_BY_GPIO
1203 default PM_WAKEUP_GPIO_POLAR_H
1204config PM_WAKEUP_GPIO_POLAR_H
1205 bool "Active High"
1206config PM_WAKEUP_GPIO_POLAR_L
1207 bool "Active Low"
1208config PM_WAKEUP_GPIO_POLAR_EDGE_F
1209 bool "Falling EDGE"
1210config PM_WAKEUP_GPIO_POLAR_EDGE_R
1211 bool "Rising EDGE"
1212config PM_WAKEUP_GPIO_POLAR_EDGE_B
1213 bool "Both EDGE"
1214endchoice
1215
1216comment "Possible Suspend Mem / Hibernate Wake-Up Sources" 1190comment "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
170int bfin_pm_standby_ctrl(unsigned ctrl);
170 171
171unsigned int bfin_pm_standby_setup(void); 172static inline int bfin_pm_standby_setup(void)
172void bfin_pm_standby_restore(void); 173{
174 return bfin_pm_standby_ctrl(1);
175}
176
177static inline void bfin_pm_standby_restore(void)
178{
179 bfin_pm_standby_ctrl(0);
180}
173 181
174void bfin_gpio_pm_hibernate_restore(void); 182void bfin_gpio_pm_hibernate_restore(void);
175void bfin_gpio_pm_hibernate_suspend(void); 183void bfin_gpio_pm_hibernate_suspend(void);
176 184
177#ifndef CONFIG_BF54x 185#ifndef CONFIG_BF54x
178#define PM_WAKE_RISING 0x1 186int 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
185int gpio_pm_wakeup_request(unsigned gpio, unsigned char type);
186void gpio_pm_wakeup_free(unsigned gpio);
187 187
188struct gpio_port_s { 188struct 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
479static unsigned short wakeup_map[GPIO_BANK_NUM]; 478static unsigned short wakeup_map[GPIO_BANK_NUM];
480static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
481 479
482static const unsigned int sic_iwr_irqs[] = { 480static 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**************************************************************/
517int gpio_pm_wakeup_request(unsigned gpio, unsigned char type) 515int 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}
531EXPORT_SYMBOL(gpio_pm_wakeup_request);
532
533void 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}
546EXPORT_SYMBOL(gpio_pm_wakeup_free);
547
548static 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
574u32 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
622void bfin_pm_standby_restore(void) 534int 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
650void bfin_gpio_pm_hibernate_suspend(void) 548void 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
711u32 bfin_pm_standby_setup(void) 609int bfin_pm_standby_ctrl(unsigned ctrl)
712{ 610{
713 return 0; 611 return 0;
714} 612}
715 613
716void bfin_pm_standby_restore(void)
717{
718
719}
720
721void bfin_gpio_pm_hibernate_suspend(void) 614void 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
663int bfin_gpio_set_wake(unsigned int irq, unsigned int state) 663int 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
44void bfin_pm_suspend_standby_enter(void) 24void 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