aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc
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
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')
-rw-r--r--arch/arm/plat-mxc/Makefile1
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v1.h17
-rw-r--r--arch/arm/plat-mxc/iomux-v1.c77
4 files changed, 54 insertions, 46 deletions
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 41d31762bca4..9465a01b3f50 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -8,7 +8,6 @@ obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
8obj-$(CONFIG_ARCH_MX1) += dma-mx1-mx2.o 8obj-$(CONFIG_ARCH_MX1) += dma-mx1-mx2.o
9obj-$(CONFIG_ARCH_MX2) += dma-mx1-mx2.o 9obj-$(CONFIG_ARCH_MX2) += dma-mx1-mx2.o
10obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o 10obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
11CFLAGS_iomux-v1.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
12obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o 11obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
13obj-$(CONFIG_MXC_PWM) += pwm.o 12obj-$(CONFIG_MXC_PWM) += pwm.o
14obj-$(CONFIG_USB_EHCI_MXC) += ehci.o 13obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index e5e5861cbbe1..e51465d7b224 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -165,11 +165,6 @@ int mxc_iomux_mode(unsigned int pin_mode);
165 MXC_GPIO_IRQ_START) 165 MXC_GPIO_IRQ_START)
166 166
167/* 167/*
168 * The number of gpio devices among the pads
169 */
170#define GPIO_PORT_MAX 3
171
172/*
173 * This enumeration is constructed based on the Section 168 * This enumeration is constructed based on the Section
174 * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated 169 * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
175 * value is constructed based on the rules described above. 170 * value is constructed based on the rules described above.
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h
index 54abfc051b72..884f5753f279 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v1.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h
@@ -41,16 +41,9 @@
41#define MXC_SWR(x) (0x3c + ((x) << 8)) 41#define MXC_SWR(x) (0x3c + ((x) << 8))
42#define MXC_PUEN(x) (0x40 + ((x) << 8)) 42#define MXC_PUEN(x) (0x40 + ((x) << 8))
43 43
44#ifdef CONFIG_ARCH_MX1 44#define MX1_NUM_GPIO_PORT 4
45# define GPIO_PORT_MAX 3 45#define MX21_NUM_GPIO_PORT 6
46#endif 46#define MX27_NUM_GPIO_PORT 6
47#ifdef CONFIG_ARCH_MX2
48# define GPIO_PORT_MAX 5
49#endif
50
51#ifndef GPIO_PORT_MAX
52# error "GPIO config port count unknown!"
53#endif
54 47
55#define GPIO_PIN_MASK 0x1f 48#define GPIO_PIN_MASK 0x1f
56 49
@@ -102,9 +95,9 @@
102#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) 95#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x)
103#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x) 96#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x)
104 97
105extern void mxc_gpio_mode(int gpio_mode); 98extern int mxc_gpio_mode(int gpio_mode);
106extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, 99extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
107 const char *label); 100 const char *label);
108extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count); 101extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
109 102
110#endif /* __MACH_IOMUX_V1_H__ */ 103#endif /* __MACH_IOMUX_V1_H__ */
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