aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc/iomux-v1.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-02-15 03:47:55 -0500
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-02-24 04:07:16 -0500
commitbac3fcfad565c9bbceeed8b607f140c29df97355 (patch)
tree63e89451b3c411416de61f5ed557cf50236ec616 /arch/arm/plat-mxc/iomux-v1.c
parente835d88e71f54c048a8cc907cc34084f1dd5846b (diff)
arm/imx/iomux-v1: check for invalid modes in mxc_gpio_mode
mxc_gpio_mode checks for invalid pins and so it returns zero for success, -EINVAL for invalid pins. While at it, remove definitions of GPIO_PORT_MAX removed as they are unused now. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'arch/arm/plat-mxc/iomux-v1.c')
-rw-r--r--arch/arm/plat-mxc/iomux-v1.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c
index 5798b35b6cb9..960a02cbcbaf 100644
--- a/arch/arm/plat-mxc/iomux-v1.c
+++ b/arch/arm/plat-mxc/iomux-v1.c
@@ -33,6 +33,7 @@
33#include <mach/iomux-v1.h> 33#include <mach/iomux-v1.h>
34 34
35static void __iomem *imx_iomuxv1_baseaddr; 35static void __iomem *imx_iomuxv1_baseaddr;
36static unsigned imx_iomuxv1_numports;
36 37
37static inline unsigned long imx_iomuxv1_readl(unsigned offset) 38static inline unsigned long imx_iomuxv1_readl(unsigned offset)
38{ 39{
@@ -120,7 +121,7 @@ static inline void imx_iomuxv1_set_iconfb(
120 imx_iomuxv1_rmwl(offset, mask, value); 121 imx_iomuxv1_rmwl(offset, mask, value);
121} 122}
122 123
123void mxc_gpio_mode(int gpio_mode) 124int mxc_gpio_mode(int gpio_mode)
124{ 125{
125 unsigned int pin = gpio_mode & GPIO_PIN_MASK; 126 unsigned int pin = gpio_mode & GPIO_PIN_MASK;
126 unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; 127 unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
@@ -128,6 +129,9 @@ void mxc_gpio_mode(int gpio_mode)
128 unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3; 129 unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3;
129 unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3; 130 unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3;
130 131
132 if (port >= imx_iomuxv1_numports)
133 return -EINVAL;
134
131 /* Pullup enable */ 135 /* Pullup enable */
132 imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN); 136 imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN);
133 137
@@ -145,50 +149,64 @@ void mxc_gpio_mode(int gpio_mode)
145 imx_iomuxv1_set_iconfa(port, pin, aout); 149 imx_iomuxv1_set_iconfa(port, pin, aout);
146 150
147 imx_iomuxv1_set_iconfb(port, pin, bout); 151 imx_iomuxv1_set_iconfb(port, pin, bout);
152
153 return 0;
148} 154}
149EXPORT_SYMBOL(mxc_gpio_mode); 155EXPORT_SYMBOL(mxc_gpio_mode);
150 156
157static int imx_iomuxv1_setup_multiple(const int *list, unsigned count)
158{
159 size_t i;
160 int ret;
161
162 for (i = 0; i < count; ++i) {
163 ret = mxc_gpio_mode(list[i]);
164
165 if (ret)
166 return ret;
167 }
168
169 return ret;
170}
171
151int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, 172int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
152 const char *label) 173 const char *label)
153{ 174{
154 const int *p = pin_list; 175 size_t i;
155 int i; 176 int ret;
156 unsigned gpio;
157 unsigned mode;
158 int ret = -EINVAL;
159 177
160 for (i = 0; i < count; i++) { 178 for (i = 0; i < count; ++i) {
161 gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); 179 unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
162 mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
163
164 if (gpio >= (GPIO_PORT_MAX + 1) * 32)
165 goto setup_error;
166 180
167 ret = gpio_request(gpio, label); 181 ret = gpio_request(gpio, label);
168 if (ret) 182 if (ret)
169 goto setup_error; 183 goto err_gpio_request;
184 }
170 185
171 mxc_gpio_mode(gpio | mode); 186 ret = imx_iomuxv1_setup_multiple(pin_list, count);
187 if (ret)
188 goto err_setup;
172 189
173 p++;
174 }
175 return 0; 190 return 0;
176 191
177setup_error: 192err_setup:
193 BUG_ON(i != count);
194
195err_gpio_request:
178 mxc_gpio_release_multiple_pins(pin_list, i); 196 mxc_gpio_release_multiple_pins(pin_list, i);
197
179 return ret; 198 return ret;
180} 199}
181EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins); 200EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins);
182 201
183void mxc_gpio_release_multiple_pins(const int *pin_list, int count) 202void mxc_gpio_release_multiple_pins(const int *pin_list, int count)
184{ 203{
185 const int *p = pin_list; 204 size_t i;
186 int i; 205
206 for (i = 0; i < count; ++i) {
207 unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
187 208
188 for (i = 0; i < count; i++) {
189 unsigned gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
190 gpio_free(gpio); 209 gpio_free(gpio);
191 p++;
192 } 210 }
193} 211}
194EXPORT_SYMBOL(mxc_gpio_release_multiple_pins); 212EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
@@ -196,19 +214,22 @@ EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
196static int imx_iomuxv1_init(void) 214static int imx_iomuxv1_init(void)
197{ 215{
198#ifdef CONFIG_ARCH_MX1 216#ifdef CONFIG_ARCH_MX1
199 if (cpu_is_mx1()) 217 if (cpu_is_mx1()) {
200 imx_iomuxv1_baseaddr = MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR); 218 imx_iomuxv1_baseaddr = MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR);
201 else 219 imx_iomuxv1_numports = MX1_NUM_GPIO_PORT;
220 } else
202#endif 221#endif
203#ifdef CONFIG_MACH_MX21 222#ifdef CONFIG_MACH_MX21
204 if (cpu_is_mx21()) 223 if (cpu_is_mx21()) {
205 imx_iomuxv1_baseaddr = MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR); 224 imx_iomuxv1_baseaddr = MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR);
206 else 225 imx_iomuxv1_numports = MX21_NUM_GPIO_PORT;
226 } else
207#endif 227#endif
208#ifdef CONFIG_MACH_MX27 228#ifdef CONFIG_MACH_MX27
209 if (cpu_is_mx27()) 229 if (cpu_is_mx27()) {
210 imx_iomuxv1_baseaddr = MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR); 230 imx_iomuxv1_baseaddr = MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR);
211 else 231 imx_iomuxv1_numports = MX27_NUM_GPIO_PORT;
232 } else
212#endif 233#endif
213 return -ENODEV; 234 return -ENODEV;
214 235