aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/mfp-pxa2xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/mfp-pxa2xx.c')
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c72
1 files changed, 52 insertions, 20 deletions
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 22097a1707cc..fd4545eab803 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -20,6 +20,7 @@
20 20
21#include <asm/arch/hardware.h> 21#include <asm/arch/hardware.h>
22#include <asm/arch/pxa-regs.h> 22#include <asm/arch/pxa-regs.h>
23#include <asm/arch/pxa2xx-regs.h>
23#include <asm/arch/mfp-pxa2xx.h> 24#include <asm/arch/mfp-pxa2xx.h>
24 25
25#include "generic.h" 26#include "generic.h"
@@ -38,6 +39,28 @@ struct gpio_desc {
38 39
39static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1]; 40static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
40 41
42static int __mfp_config_lpm(unsigned gpio, unsigned long lpm)
43{
44 unsigned mask = GPIO_bit(gpio);
45
46 /* low power state */
47 switch (lpm) {
48 case MFP_LPM_DRIVE_HIGH:
49 PGSR(gpio) |= mask;
50 break;
51 case MFP_LPM_DRIVE_LOW:
52 PGSR(gpio) &= ~mask;
53 break;
54 case MFP_LPM_INPUT:
55 break;
56 default:
57 pr_warning("%s: invalid low power state for GPIO%d\n",
58 __func__, gpio);
59 return -EINVAL;
60 }
61 return 0;
62}
63
41static int __mfp_config_gpio(unsigned gpio, unsigned long c) 64static int __mfp_config_gpio(unsigned gpio, unsigned long c)
42{ 65{
43 unsigned long gafr, mask = GPIO_bit(gpio); 66 unsigned long gafr, mask = GPIO_bit(gpio);
@@ -56,21 +79,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
56 else 79 else
57 GPDR(gpio) &= ~mask; 80 GPDR(gpio) &= ~mask;
58 81
59 /* low power state */ 82 if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
60 switch (c & MFP_LPM_STATE_MASK) {
61 case MFP_LPM_DRIVE_HIGH:
62 PGSR(gpio) |= mask;
63 break;
64 case MFP_LPM_DRIVE_LOW:
65 PGSR(gpio) &= ~mask;
66 break;
67 case MFP_LPM_INPUT:
68 break;
69 default:
70 pr_warning("%s: invalid low power state for GPIO%d\n",
71 __func__, gpio);
72 return -EINVAL; 83 return -EINVAL;
73 }
74 84
75 /* give early warning if MFP_LPM_CAN_WAKEUP is set on the 85 /* give early warning if MFP_LPM_CAN_WAKEUP is set on the
76 * configurations of those pins not able to wakeup 86 * configurations of those pins not able to wakeup
@@ -90,6 +100,18 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
90 return 0; 100 return 0;
91} 101}
92 102
103static inline int __mfp_validate(int mfp)
104{
105 int gpio = mfp_to_gpio(mfp);
106
107 if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
108 pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
109 return -1;
110 }
111
112 return gpio;
113}
114
93void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) 115void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
94{ 116{
95 unsigned long flags; 117 unsigned long flags;
@@ -98,13 +120,9 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
98 120
99 for (i = 0, c = mfp_cfgs; i < num; i++, c++) { 121 for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
100 122
101 gpio = mfp_to_gpio(MFP_PIN(*c)); 123 gpio = __mfp_validate(MFP_PIN(*c));
102 124 if (gpio < 0)
103 if (!gpio_desc[gpio].valid) {
104 pr_warning("%s: GPIO%d is invalid pin\n",
105 __func__, gpio);
106 continue; 125 continue;
107 }
108 126
109 local_irq_save(flags); 127 local_irq_save(flags);
110 128
@@ -115,6 +133,20 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
115 } 133 }
116} 134}
117 135
136void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
137{
138 unsigned long flags;
139 int gpio;
140
141 gpio = __mfp_validate(mfp);
142 if (gpio < 0)
143 return;
144
145 local_irq_save(flags);
146 __mfp_config_lpm(gpio, lpm);
147 local_irq_restore(flags);
148}
149
118int gpio_set_wake(unsigned int gpio, unsigned int on) 150int gpio_set_wake(unsigned int gpio, unsigned int on)
119{ 151{
120 struct gpio_desc *d; 152 struct gpio_desc *d;