diff options
Diffstat (limited to 'arch/arm/mach-pxa/mfp-pxa2xx.c')
-rw-r--r-- | arch/arm/mach-pxa/mfp-pxa2xx.c | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index d1cdb4ecb0b8..fd4545eab803 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c | |||
@@ -39,6 +39,28 @@ struct gpio_desc { | |||
39 | 39 | ||
40 | static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1]; | 40 | static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1]; |
41 | 41 | ||
42 | static 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 | |||
42 | static int __mfp_config_gpio(unsigned gpio, unsigned long c) | 64 | static int __mfp_config_gpio(unsigned gpio, unsigned long c) |
43 | { | 65 | { |
44 | unsigned long gafr, mask = GPIO_bit(gpio); | 66 | unsigned long gafr, mask = GPIO_bit(gpio); |
@@ -57,21 +79,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) | |||
57 | else | 79 | else |
58 | GPDR(gpio) &= ~mask; | 80 | GPDR(gpio) &= ~mask; |
59 | 81 | ||
60 | /* low power state */ | 82 | if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK)) |
61 | switch (c & MFP_LPM_STATE_MASK) { | ||
62 | case MFP_LPM_DRIVE_HIGH: | ||
63 | PGSR(gpio) |= mask; | ||
64 | break; | ||
65 | case MFP_LPM_DRIVE_LOW: | ||
66 | PGSR(gpio) &= ~mask; | ||
67 | break; | ||
68 | case MFP_LPM_INPUT: | ||
69 | break; | ||
70 | default: | ||
71 | pr_warning("%s: invalid low power state for GPIO%d\n", | ||
72 | __func__, gpio); | ||
73 | return -EINVAL; | 83 | return -EINVAL; |
74 | } | ||
75 | 84 | ||
76 | /* 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 |
77 | * configurations of those pins not able to wakeup | 86 | * configurations of those pins not able to wakeup |
@@ -91,6 +100,18 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) | |||
91 | return 0; | 100 | return 0; |
92 | } | 101 | } |
93 | 102 | ||
103 | static 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 | |||
94 | void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) | 115 | void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) |
95 | { | 116 | { |
96 | unsigned long flags; | 117 | unsigned long flags; |
@@ -99,13 +120,9 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) | |||
99 | 120 | ||
100 | for (i = 0, c = mfp_cfgs; i < num; i++, c++) { | 121 | for (i = 0, c = mfp_cfgs; i < num; i++, c++) { |
101 | 122 | ||
102 | gpio = mfp_to_gpio(MFP_PIN(*c)); | 123 | gpio = __mfp_validate(MFP_PIN(*c)); |
103 | 124 | if (gpio < 0) | |
104 | if (!gpio_desc[gpio].valid) { | ||
105 | pr_warning("%s: GPIO%d is invalid pin\n", | ||
106 | __func__, gpio); | ||
107 | continue; | 125 | continue; |
108 | } | ||
109 | 126 | ||
110 | local_irq_save(flags); | 127 | local_irq_save(flags); |
111 | 128 | ||
@@ -116,6 +133,20 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) | |||
116 | } | 133 | } |
117 | } | 134 | } |
118 | 135 | ||
136 | void 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 | |||
119 | int gpio_set_wake(unsigned int gpio, unsigned int on) | 150 | int gpio_set_wake(unsigned int gpio, unsigned int on) |
120 | { | 151 | { |
121 | struct gpio_desc *d; | 152 | struct gpio_desc *d; |