diff options
Diffstat (limited to 'arch/arm/mach-omap2/mux.c')
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 605 |
1 files changed, 465 insertions, 140 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index ab403b2ed26b..c7fb22abc219 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap2/mux.c | 2 | * linux/arch/arm/mach-omap2/mux.c |
3 | * | 3 | * |
4 | * OMAP2 and OMAP3 pin multiplexing configurations | 4 | * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations |
5 | * | 5 | * |
6 | * Copyright (C) 2004 - 2008 Texas Instruments Inc. | 6 | * Copyright (C) 2004 - 2010 Texas Instruments Inc. |
7 | * Copyright (C) 2003 - 2008 Nokia Corporation | 7 | * Copyright (C) 2003 - 2008 Nokia Corporation |
8 | * | 8 | * |
9 | * Written by Tony Lindgren | 9 | * Written by Tony Lindgren |
@@ -23,12 +23,11 @@ | |||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | #include <linux/module.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <linux/slab.h> | ||
32 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
33 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
34 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
@@ -36,66 +35,82 @@ | |||
36 | 35 | ||
37 | #include <asm/system.h> | 36 | #include <asm/system.h> |
38 | 37 | ||
39 | #include <plat/control.h> | 38 | #include <plat/omap_hwmod.h> |
40 | 39 | ||
40 | #include "control.h" | ||
41 | #include "mux.h" | 41 | #include "mux.h" |
42 | 42 | ||
43 | #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ | 43 | #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ |
44 | #define OMAP_MUX_BASE_SZ 0x5ca | 44 | #define OMAP_MUX_BASE_SZ 0x5ca |
45 | #define MUXABLE_GPIO_MODE3 BIT(0) | ||
46 | 45 | ||
47 | struct omap_mux_entry { | 46 | struct omap_mux_entry { |
48 | struct omap_mux mux; | 47 | struct omap_mux mux; |
49 | struct list_head node; | 48 | struct list_head node; |
50 | }; | 49 | }; |
51 | 50 | ||
52 | static unsigned long mux_phys; | 51 | static LIST_HEAD(mux_partitions); |
53 | static void __iomem *mux_base; | 52 | static DEFINE_MUTEX(muxmode_mutex); |
54 | static u8 omap_mux_flags; | 53 | |
54 | struct omap_mux_partition *omap_mux_get(const char *name) | ||
55 | { | ||
56 | struct omap_mux_partition *partition; | ||
57 | |||
58 | list_for_each_entry(partition, &mux_partitions, node) { | ||
59 | if (!strcmp(name, partition->name)) | ||
60 | return partition; | ||
61 | } | ||
62 | |||
63 | return NULL; | ||
64 | } | ||
55 | 65 | ||
56 | u16 omap_mux_read(u16 reg) | 66 | u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg) |
57 | { | 67 | { |
58 | if (cpu_is_omap24xx()) | 68 | if (partition->flags & OMAP_MUX_REG_8BIT) |
59 | return __raw_readb(mux_base + reg); | 69 | return __raw_readb(partition->base + reg); |
60 | else | 70 | else |
61 | return __raw_readw(mux_base + reg); | 71 | return __raw_readw(partition->base + reg); |
62 | } | 72 | } |
63 | 73 | ||
64 | void omap_mux_write(u16 val, u16 reg) | 74 | void omap_mux_write(struct omap_mux_partition *partition, u16 val, |
75 | u16 reg) | ||
65 | { | 76 | { |
66 | if (cpu_is_omap24xx()) | 77 | if (partition->flags & OMAP_MUX_REG_8BIT) |
67 | __raw_writeb(val, mux_base + reg); | 78 | __raw_writeb(val, partition->base + reg); |
68 | else | 79 | else |
69 | __raw_writew(val, mux_base + reg); | 80 | __raw_writew(val, partition->base + reg); |
70 | } | 81 | } |
71 | 82 | ||
72 | void omap_mux_write_array(struct omap_board_mux *board_mux) | 83 | void omap_mux_write_array(struct omap_mux_partition *partition, |
84 | struct omap_board_mux *board_mux) | ||
73 | { | 85 | { |
74 | while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { | 86 | if (!board_mux) |
75 | omap_mux_write(board_mux->value, board_mux->reg_offset); | 87 | return; |
88 | |||
89 | while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { | ||
90 | omap_mux_write(partition, board_mux->value, | ||
91 | board_mux->reg_offset); | ||
76 | board_mux++; | 92 | board_mux++; |
77 | } | 93 | } |
78 | } | 94 | } |
79 | 95 | ||
80 | static LIST_HEAD(muxmodes); | ||
81 | static DEFINE_MUTEX(muxmode_mutex); | ||
82 | |||
83 | #ifdef CONFIG_OMAP_MUX | 96 | #ifdef CONFIG_OMAP_MUX |
84 | 97 | ||
85 | static char *omap_mux_options; | 98 | static char *omap_mux_options; |
86 | 99 | ||
87 | int __init omap_mux_init_gpio(int gpio, int val) | 100 | static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition, |
101 | int gpio, int val) | ||
88 | { | 102 | { |
89 | struct omap_mux_entry *e; | 103 | struct omap_mux_entry *e; |
90 | struct omap_mux *gpio_mux; | 104 | struct omap_mux *gpio_mux = NULL; |
91 | u16 old_mode; | 105 | u16 old_mode; |
92 | u16 mux_mode; | 106 | u16 mux_mode; |
93 | int found = 0; | 107 | int found = 0; |
108 | struct list_head *muxmodes = &partition->muxmodes; | ||
94 | 109 | ||
95 | if (!gpio) | 110 | if (!gpio) |
96 | return -EINVAL; | 111 | return -EINVAL; |
97 | 112 | ||
98 | list_for_each_entry(e, &muxmodes, node) { | 113 | list_for_each_entry(e, muxmodes, node) { |
99 | struct omap_mux *m = &e->mux; | 114 | struct omap_mux *m = &e->mux; |
100 | if (gpio == m->gpio) { | 115 | if (gpio == m->gpio) { |
101 | gpio_mux = m; | 116 | gpio_mux = m; |
@@ -104,87 +119,312 @@ int __init omap_mux_init_gpio(int gpio, int val) | |||
104 | } | 119 | } |
105 | 120 | ||
106 | if (found == 0) { | 121 | if (found == 0) { |
107 | printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); | 122 | pr_err("%s: Could not set gpio%i\n", __func__, gpio); |
108 | return -ENODEV; | 123 | return -ENODEV; |
109 | } | 124 | } |
110 | 125 | ||
111 | if (found > 1) { | 126 | if (found > 1) { |
112 | printk(KERN_INFO "mux: Multiple gpio paths (%d) for gpio%i\n", | 127 | pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__, |
113 | found, gpio); | 128 | found, gpio); |
114 | return -EINVAL; | 129 | return -EINVAL; |
115 | } | 130 | } |
116 | 131 | ||
117 | old_mode = omap_mux_read(gpio_mux->reg_offset); | 132 | old_mode = omap_mux_read(partition, gpio_mux->reg_offset); |
118 | mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); | 133 | mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); |
119 | if (omap_mux_flags & MUXABLE_GPIO_MODE3) | 134 | if (partition->flags & OMAP_MUX_GPIO_IN_MODE3) |
120 | mux_mode |= OMAP_MUX_MODE3; | 135 | mux_mode |= OMAP_MUX_MODE3; |
121 | else | 136 | else |
122 | mux_mode |= OMAP_MUX_MODE4; | 137 | mux_mode |= OMAP_MUX_MODE4; |
123 | printk(KERN_DEBUG "mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", | 138 | pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__, |
124 | gpio_mux->muxnames[0], gpio, old_mode, mux_mode); | 139 | gpio_mux->muxnames[0], gpio, old_mode, mux_mode); |
125 | omap_mux_write(mux_mode, gpio_mux->reg_offset); | 140 | omap_mux_write(partition, mux_mode, gpio_mux->reg_offset); |
126 | 141 | ||
127 | return 0; | 142 | return 0; |
128 | } | 143 | } |
129 | 144 | ||
130 | int __init omap_mux_init_signal(char *muxname, int val) | 145 | int __init omap_mux_init_gpio(int gpio, int val) |
131 | { | 146 | { |
147 | struct omap_mux_partition *partition; | ||
148 | int ret; | ||
149 | |||
150 | list_for_each_entry(partition, &mux_partitions, node) { | ||
151 | ret = _omap_mux_init_gpio(partition, gpio, val); | ||
152 | if (!ret) | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | return -ENODEV; | ||
157 | } | ||
158 | |||
159 | static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, | ||
160 | const char *muxname, | ||
161 | struct omap_mux **found_mux) | ||
162 | { | ||
163 | struct omap_mux *mux = NULL; | ||
132 | struct omap_mux_entry *e; | 164 | struct omap_mux_entry *e; |
133 | char *m0_name = NULL, *mode_name = NULL; | 165 | const char *mode_name; |
134 | int found = 0; | 166 | int found = 0, found_mode = 0, mode0_len = 0; |
167 | struct list_head *muxmodes = &partition->muxmodes; | ||
135 | 168 | ||
136 | mode_name = strchr(muxname, '.'); | 169 | mode_name = strchr(muxname, '.'); |
137 | if (mode_name) { | 170 | if (mode_name) { |
138 | *mode_name = '\0'; | 171 | mode0_len = strlen(muxname) - strlen(mode_name); |
139 | mode_name++; | 172 | mode_name++; |
140 | m0_name = muxname; | ||
141 | } else { | 173 | } else { |
142 | mode_name = muxname; | 174 | mode_name = muxname; |
143 | } | 175 | } |
144 | 176 | ||
145 | list_for_each_entry(e, &muxmodes, node) { | 177 | list_for_each_entry(e, muxmodes, node) { |
146 | struct omap_mux *m = &e->mux; | 178 | char *m0_entry; |
147 | char *m0_entry = m->muxnames[0]; | ||
148 | int i; | 179 | int i; |
149 | 180 | ||
150 | if (m0_name && strcmp(m0_name, m0_entry)) | 181 | mux = &e->mux; |
182 | m0_entry = mux->muxnames[0]; | ||
183 | |||
184 | /* First check for full name in mode0.muxmode format */ | ||
185 | if (mode0_len && strncmp(muxname, m0_entry, mode0_len)) | ||
151 | continue; | 186 | continue; |
152 | 187 | ||
188 | /* Then check for muxmode only */ | ||
153 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) { | 189 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) { |
154 | char *mode_cur = m->muxnames[i]; | 190 | char *mode_cur = mux->muxnames[i]; |
155 | 191 | ||
156 | if (!mode_cur) | 192 | if (!mode_cur) |
157 | continue; | 193 | continue; |
158 | 194 | ||
159 | if (!strcmp(mode_name, mode_cur)) { | 195 | if (!strcmp(mode_name, mode_cur)) { |
160 | u16 old_mode; | 196 | *found_mux = mux; |
161 | u16 mux_mode; | ||
162 | |||
163 | old_mode = omap_mux_read(m->reg_offset); | ||
164 | mux_mode = val | i; | ||
165 | printk(KERN_DEBUG "mux: Setting signal " | ||
166 | "%s.%s 0x%04x -> 0x%04x\n", | ||
167 | m0_entry, muxname, old_mode, mux_mode); | ||
168 | omap_mux_write(mux_mode, m->reg_offset); | ||
169 | found++; | 197 | found++; |
198 | found_mode = i; | ||
170 | } | 199 | } |
171 | } | 200 | } |
172 | } | 201 | } |
173 | 202 | ||
174 | if (found == 1) | 203 | if (found == 1) { |
175 | return 0; | 204 | return found_mode; |
205 | } | ||
176 | 206 | ||
177 | if (found > 1) { | 207 | if (found > 1) { |
178 | printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n", | 208 | pr_err("%s: Multiple signal paths (%i) for %s\n", __func__, |
179 | found, muxname); | 209 | found, muxname); |
180 | return -EINVAL; | 210 | return -EINVAL; |
181 | } | 211 | } |
182 | 212 | ||
183 | printk(KERN_ERR "mux: Could not set signal %s\n", muxname); | 213 | pr_err("%s: Could not find signal %s\n", __func__, muxname); |
214 | |||
215 | return -ENODEV; | ||
216 | } | ||
217 | |||
218 | static int __init | ||
219 | omap_mux_get_by_name(const char *muxname, | ||
220 | struct omap_mux_partition **found_partition, | ||
221 | struct omap_mux **found_mux) | ||
222 | { | ||
223 | struct omap_mux_partition *partition; | ||
224 | |||
225 | list_for_each_entry(partition, &mux_partitions, node) { | ||
226 | struct omap_mux *mux = NULL; | ||
227 | int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux); | ||
228 | if (mux_mode < 0) | ||
229 | continue; | ||
230 | |||
231 | *found_partition = partition; | ||
232 | *found_mux = mux; | ||
233 | |||
234 | return mux_mode; | ||
235 | } | ||
184 | 236 | ||
185 | return -ENODEV; | 237 | return -ENODEV; |
186 | } | 238 | } |
187 | 239 | ||
240 | int __init omap_mux_init_signal(const char *muxname, int val) | ||
241 | { | ||
242 | struct omap_mux_partition *partition = NULL; | ||
243 | struct omap_mux *mux = NULL; | ||
244 | u16 old_mode; | ||
245 | int mux_mode; | ||
246 | |||
247 | mux_mode = omap_mux_get_by_name(muxname, &partition, &mux); | ||
248 | if (mux_mode < 0) | ||
249 | return mux_mode; | ||
250 | |||
251 | old_mode = omap_mux_read(partition, mux->reg_offset); | ||
252 | mux_mode |= val; | ||
253 | pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n", | ||
254 | __func__, muxname, old_mode, mux_mode); | ||
255 | omap_mux_write(partition, mux_mode, mux->reg_offset); | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | struct omap_hwmod_mux_info * __init | ||
261 | omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads) | ||
262 | { | ||
263 | struct omap_hwmod_mux_info *hmux; | ||
264 | int i, nr_pads_dynamic = 0; | ||
265 | |||
266 | if (!bpads || nr_pads < 1) | ||
267 | return NULL; | ||
268 | |||
269 | hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL); | ||
270 | if (!hmux) | ||
271 | goto err1; | ||
272 | |||
273 | hmux->nr_pads = nr_pads; | ||
274 | |||
275 | hmux->pads = kzalloc(sizeof(struct omap_device_pad) * | ||
276 | nr_pads, GFP_KERNEL); | ||
277 | if (!hmux->pads) | ||
278 | goto err2; | ||
279 | |||
280 | for (i = 0; i < hmux->nr_pads; i++) { | ||
281 | struct omap_mux_partition *partition; | ||
282 | struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i]; | ||
283 | struct omap_mux *mux; | ||
284 | int mux_mode; | ||
285 | |||
286 | mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux); | ||
287 | if (mux_mode < 0) | ||
288 | goto err3; | ||
289 | if (!pad->partition) | ||
290 | pad->partition = partition; | ||
291 | if (!pad->mux) | ||
292 | pad->mux = mux; | ||
293 | |||
294 | pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL); | ||
295 | if (!pad->name) { | ||
296 | int j; | ||
297 | |||
298 | for (j = i - 1; j >= 0; j--) | ||
299 | kfree(hmux->pads[j].name); | ||
300 | goto err3; | ||
301 | } | ||
302 | strcpy(pad->name, bpad->name); | ||
303 | |||
304 | pad->flags = bpad->flags; | ||
305 | pad->enable = bpad->enable; | ||
306 | pad->idle = bpad->idle; | ||
307 | pad->off = bpad->off; | ||
308 | |||
309 | if (pad->flags & OMAP_DEVICE_PAD_REMUX) | ||
310 | nr_pads_dynamic++; | ||
311 | |||
312 | pr_debug("%s: Initialized %s\n", __func__, pad->name); | ||
313 | } | ||
314 | |||
315 | if (!nr_pads_dynamic) | ||
316 | return hmux; | ||
317 | |||
318 | /* | ||
319 | * Add pads that need dynamic muxing into a separate list | ||
320 | */ | ||
321 | |||
322 | hmux->nr_pads_dynamic = nr_pads_dynamic; | ||
323 | hmux->pads_dynamic = kzalloc(sizeof(struct omap_device_pad *) * | ||
324 | nr_pads_dynamic, GFP_KERNEL); | ||
325 | if (!hmux->pads_dynamic) { | ||
326 | pr_err("%s: Could not allocate dynamic pads\n", __func__); | ||
327 | return hmux; | ||
328 | } | ||
329 | |||
330 | nr_pads_dynamic = 0; | ||
331 | for (i = 0; i < hmux->nr_pads; i++) { | ||
332 | struct omap_device_pad *pad = &hmux->pads[i]; | ||
333 | |||
334 | if (pad->flags & OMAP_DEVICE_PAD_REMUX) { | ||
335 | pr_debug("%s: pad %s tagged dynamic\n", | ||
336 | __func__, pad->name); | ||
337 | hmux->pads_dynamic[nr_pads_dynamic] = pad; | ||
338 | nr_pads_dynamic++; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | return hmux; | ||
343 | |||
344 | err3: | ||
345 | kfree(hmux->pads); | ||
346 | err2: | ||
347 | kfree(hmux); | ||
348 | err1: | ||
349 | pr_err("%s: Could not allocate device mux entry\n", __func__); | ||
350 | |||
351 | return NULL; | ||
352 | } | ||
353 | |||
354 | /* Assumes the calling function takes care of locking */ | ||
355 | void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) | ||
356 | { | ||
357 | int i; | ||
358 | |||
359 | /* Runtime idling of dynamic pads */ | ||
360 | if (state == _HWMOD_STATE_IDLE && hmux->enabled) { | ||
361 | for (i = 0; i < hmux->nr_pads_dynamic; i++) { | ||
362 | struct omap_device_pad *pad = hmux->pads_dynamic[i]; | ||
363 | int val = -EINVAL; | ||
364 | |||
365 | val = pad->idle; | ||
366 | omap_mux_write(pad->partition, val, | ||
367 | pad->mux->reg_offset); | ||
368 | } | ||
369 | |||
370 | return; | ||
371 | } | ||
372 | |||
373 | /* Runtime enabling of dynamic pads */ | ||
374 | if ((state == _HWMOD_STATE_ENABLED) && hmux->pads_dynamic | ||
375 | && hmux->enabled) { | ||
376 | for (i = 0; i < hmux->nr_pads_dynamic; i++) { | ||
377 | struct omap_device_pad *pad = hmux->pads_dynamic[i]; | ||
378 | int val = -EINVAL; | ||
379 | |||
380 | val = pad->enable; | ||
381 | omap_mux_write(pad->partition, val, | ||
382 | pad->mux->reg_offset); | ||
383 | } | ||
384 | |||
385 | return; | ||
386 | } | ||
387 | |||
388 | /* Enabling or disabling of all pads */ | ||
389 | for (i = 0; i < hmux->nr_pads; i++) { | ||
390 | struct omap_device_pad *pad = &hmux->pads[i]; | ||
391 | int flags, val = -EINVAL; | ||
392 | |||
393 | flags = pad->flags; | ||
394 | |||
395 | switch (state) { | ||
396 | case _HWMOD_STATE_ENABLED: | ||
397 | val = pad->enable; | ||
398 | pr_debug("%s: Enabling %s %x\n", __func__, | ||
399 | pad->name, val); | ||
400 | break; | ||
401 | case _HWMOD_STATE_DISABLED: | ||
402 | /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */ | ||
403 | if (flags & OMAP_DEVICE_PAD_REMUX) | ||
404 | val = pad->off; | ||
405 | else | ||
406 | val = OMAP_MUX_MODE7; | ||
407 | pr_debug("%s: Disabling %s %x\n", __func__, | ||
408 | pad->name, val); | ||
409 | break; | ||
410 | default: | ||
411 | /* Nothing to be done */ | ||
412 | break; | ||
413 | }; | ||
414 | |||
415 | if (val >= 0) { | ||
416 | omap_mux_write(pad->partition, val, | ||
417 | pad->mux->reg_offset); | ||
418 | pad->flags = flags; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | if (state == _HWMOD_STATE_ENABLED) | ||
423 | hmux->enabled = true; | ||
424 | else | ||
425 | hmux->enabled = false; | ||
426 | } | ||
427 | |||
188 | #ifdef CONFIG_DEBUG_FS | 428 | #ifdef CONFIG_DEBUG_FS |
189 | 429 | ||
190 | #define OMAP_MUX_MAX_NR_FLAGS 10 | 430 | #define OMAP_MUX_MAX_NR_FLAGS 10 |
@@ -249,13 +489,15 @@ static inline void omap_mux_decode(struct seq_file *s, u16 val) | |||
249 | } while (i-- > 0); | 489 | } while (i-- > 0); |
250 | } | 490 | } |
251 | 491 | ||
252 | #define OMAP_MUX_DEFNAME_LEN 16 | 492 | #define OMAP_MUX_DEFNAME_LEN 32 |
253 | 493 | ||
254 | static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) | 494 | static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) |
255 | { | 495 | { |
496 | struct omap_mux_partition *partition = s->private; | ||
256 | struct omap_mux_entry *e; | 497 | struct omap_mux_entry *e; |
498 | u8 omap_gen = omap_rev() >> 28; | ||
257 | 499 | ||
258 | list_for_each_entry(e, &muxmodes, node) { | 500 | list_for_each_entry(e, &partition->muxmodes, node) { |
259 | struct omap_mux *m = &e->mux; | 501 | struct omap_mux *m = &e->mux; |
260 | char m0_def[OMAP_MUX_DEFNAME_LEN]; | 502 | char m0_def[OMAP_MUX_DEFNAME_LEN]; |
261 | char *m0_name = m->muxnames[0]; | 503 | char *m0_name = m->muxnames[0]; |
@@ -273,11 +515,16 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) | |||
273 | } | 515 | } |
274 | m0_def[i] = toupper(m0_name[i]); | 516 | m0_def[i] = toupper(m0_name[i]); |
275 | } | 517 | } |
276 | val = omap_mux_read(m->reg_offset); | 518 | val = omap_mux_read(partition, m->reg_offset); |
277 | mode = val & OMAP_MUX_MODE7; | 519 | mode = val & OMAP_MUX_MODE7; |
278 | 520 | if (mode != 0) | |
279 | seq_printf(s, "OMAP%i_MUX(%s, ", | 521 | seq_printf(s, "/* %s */\n", m->muxnames[mode]); |
280 | cpu_is_omap34xx() ? 3 : 0, m0_def); | 522 | |
523 | /* | ||
524 | * XXX: Might be revisited to support differences across | ||
525 | * same OMAP generation. | ||
526 | */ | ||
527 | seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def); | ||
281 | omap_mux_decode(s, val); | 528 | omap_mux_decode(s, val); |
282 | seq_printf(s, "),\n"); | 529 | seq_printf(s, "),\n"); |
283 | } | 530 | } |
@@ -287,7 +534,7 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) | |||
287 | 534 | ||
288 | static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) | 535 | static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) |
289 | { | 536 | { |
290 | return single_open(file, omap_mux_dbg_board_show, &inode->i_private); | 537 | return single_open(file, omap_mux_dbg_board_show, inode->i_private); |
291 | } | 538 | } |
292 | 539 | ||
293 | static const struct file_operations omap_mux_dbg_board_fops = { | 540 | static const struct file_operations omap_mux_dbg_board_fops = { |
@@ -297,19 +544,43 @@ static const struct file_operations omap_mux_dbg_board_fops = { | |||
297 | .release = single_release, | 544 | .release = single_release, |
298 | }; | 545 | }; |
299 | 546 | ||
547 | static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux) | ||
548 | { | ||
549 | struct omap_mux_partition *partition; | ||
550 | |||
551 | list_for_each_entry(partition, &mux_partitions, node) { | ||
552 | struct list_head *muxmodes = &partition->muxmodes; | ||
553 | struct omap_mux_entry *e; | ||
554 | |||
555 | list_for_each_entry(e, muxmodes, node) { | ||
556 | struct omap_mux *m = &e->mux; | ||
557 | |||
558 | if (m == mux) | ||
559 | return partition; | ||
560 | } | ||
561 | } | ||
562 | |||
563 | return NULL; | ||
564 | } | ||
565 | |||
300 | static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) | 566 | static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) |
301 | { | 567 | { |
302 | struct omap_mux *m = s->private; | 568 | struct omap_mux *m = s->private; |
569 | struct omap_mux_partition *partition; | ||
303 | const char *none = "NA"; | 570 | const char *none = "NA"; |
304 | u16 val; | 571 | u16 val; |
305 | int mode; | 572 | int mode; |
306 | 573 | ||
307 | val = omap_mux_read(m->reg_offset); | 574 | partition = omap_mux_get_partition(m); |
575 | if (!partition) | ||
576 | return 0; | ||
577 | |||
578 | val = omap_mux_read(partition, m->reg_offset); | ||
308 | mode = val & OMAP_MUX_MODE7; | 579 | mode = val & OMAP_MUX_MODE7; |
309 | 580 | ||
310 | seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n", | 581 | seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n", |
311 | m->muxnames[0], m->muxnames[mode], | 582 | m->muxnames[0], m->muxnames[mode], |
312 | mux_phys + m->reg_offset, m->reg_offset, val, | 583 | partition->phys + m->reg_offset, m->reg_offset, val, |
313 | m->balls[0] ? m->balls[0] : none, | 584 | m->balls[0] ? m->balls[0] : none, |
314 | m->balls[1] ? m->balls[1] : none); | 585 | m->balls[1] ? m->balls[1] : none); |
315 | seq_printf(s, "mode: "); | 586 | seq_printf(s, "mode: "); |
@@ -331,14 +602,15 @@ static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) | |||
331 | #define OMAP_MUX_MAX_ARG_CHAR 7 | 602 | #define OMAP_MUX_MAX_ARG_CHAR 7 |
332 | 603 | ||
333 | static ssize_t omap_mux_dbg_signal_write(struct file *file, | 604 | static ssize_t omap_mux_dbg_signal_write(struct file *file, |
334 | const char __user *user_buf, | 605 | const char __user *user_buf, |
335 | size_t count, loff_t *ppos) | 606 | size_t count, loff_t *ppos) |
336 | { | 607 | { |
337 | char buf[OMAP_MUX_MAX_ARG_CHAR]; | 608 | char buf[OMAP_MUX_MAX_ARG_CHAR]; |
338 | struct seq_file *seqf; | 609 | struct seq_file *seqf; |
339 | struct omap_mux *m; | 610 | struct omap_mux *m; |
340 | unsigned long val; | 611 | unsigned long val; |
341 | int buf_size, ret; | 612 | int buf_size, ret; |
613 | struct omap_mux_partition *partition; | ||
342 | 614 | ||
343 | if (count > OMAP_MUX_MAX_ARG_CHAR) | 615 | if (count > OMAP_MUX_MAX_ARG_CHAR) |
344 | return -EINVAL; | 616 | return -EINVAL; |
@@ -359,7 +631,11 @@ static ssize_t omap_mux_dbg_signal_write(struct file *file, | |||
359 | seqf = file->private_data; | 631 | seqf = file->private_data; |
360 | m = seqf->private; | 632 | m = seqf->private; |
361 | 633 | ||
362 | omap_mux_write((u16)val, m->reg_offset); | 634 | partition = omap_mux_get_partition(m); |
635 | if (!partition) | ||
636 | return -ENODEV; | ||
637 | |||
638 | omap_mux_write(partition, (u16)val, m->reg_offset); | ||
363 | *ppos += count; | 639 | *ppos += count; |
364 | 640 | ||
365 | return count; | 641 | return count; |
@@ -380,22 +656,38 @@ static const struct file_operations omap_mux_dbg_signal_fops = { | |||
380 | 656 | ||
381 | static struct dentry *mux_dbg_dir; | 657 | static struct dentry *mux_dbg_dir; |
382 | 658 | ||
383 | static void __init omap_mux_dbg_init(void) | 659 | static void __init omap_mux_dbg_create_entry( |
660 | struct omap_mux_partition *partition, | ||
661 | struct dentry *mux_dbg_dir) | ||
384 | { | 662 | { |
385 | struct omap_mux_entry *e; | 663 | struct omap_mux_entry *e; |
386 | 664 | ||
665 | list_for_each_entry(e, &partition->muxmodes, node) { | ||
666 | struct omap_mux *m = &e->mux; | ||
667 | |||
668 | (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir, | ||
669 | m, &omap_mux_dbg_signal_fops); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | static void __init omap_mux_dbg_init(void) | ||
674 | { | ||
675 | struct omap_mux_partition *partition; | ||
676 | static struct dentry *mux_dbg_board_dir; | ||
677 | |||
387 | mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); | 678 | mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); |
388 | if (!mux_dbg_dir) | 679 | if (!mux_dbg_dir) |
389 | return; | 680 | return; |
390 | 681 | ||
391 | (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir, | 682 | mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir); |
392 | NULL, &omap_mux_dbg_board_fops); | 683 | if (!mux_dbg_board_dir) |
393 | 684 | return; | |
394 | list_for_each_entry(e, &muxmodes, node) { | ||
395 | struct omap_mux *m = &e->mux; | ||
396 | 685 | ||
397 | (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir, | 686 | list_for_each_entry(partition, &mux_partitions, node) { |
398 | m, &omap_mux_dbg_signal_fops); | 687 | omap_mux_dbg_create_entry(partition, mux_dbg_dir); |
688 | (void)debugfs_create_file(partition->name, S_IRUGO, | ||
689 | mux_dbg_board_dir, partition, | ||
690 | &omap_mux_dbg_board_fops); | ||
399 | } | 691 | } |
400 | } | 692 | } |
401 | 693 | ||
@@ -422,23 +714,25 @@ static void __init omap_mux_free_names(struct omap_mux *m) | |||
422 | /* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ | 714 | /* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ |
423 | static int __init omap_mux_late_init(void) | 715 | static int __init omap_mux_late_init(void) |
424 | { | 716 | { |
425 | struct omap_mux_entry *e, *tmp; | 717 | struct omap_mux_partition *partition; |
426 | 718 | ||
427 | list_for_each_entry_safe(e, tmp, &muxmodes, node) { | 719 | list_for_each_entry(partition, &mux_partitions, node) { |
428 | struct omap_mux *m = &e->mux; | 720 | struct omap_mux_entry *e, *tmp; |
429 | u16 mode = omap_mux_read(m->reg_offset); | 721 | list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) { |
722 | struct omap_mux *m = &e->mux; | ||
723 | u16 mode = omap_mux_read(partition, m->reg_offset); | ||
430 | 724 | ||
431 | if (OMAP_MODE_GPIO(mode)) | 725 | if (OMAP_MODE_GPIO(mode)) |
432 | continue; | 726 | continue; |
433 | 727 | ||
434 | #ifndef CONFIG_DEBUG_FS | 728 | #ifndef CONFIG_DEBUG_FS |
435 | mutex_lock(&muxmode_mutex); | 729 | mutex_lock(&muxmode_mutex); |
436 | list_del(&e->node); | 730 | list_del(&e->node); |
437 | mutex_unlock(&muxmode_mutex); | 731 | mutex_unlock(&muxmode_mutex); |
438 | omap_mux_free_names(m); | 732 | omap_mux_free_names(m); |
439 | kfree(m); | 733 | kfree(m); |
440 | #endif | 734 | #endif |
441 | 735 | } | |
442 | } | 736 | } |
443 | 737 | ||
444 | omap_mux_dbg_init(); | 738 | omap_mux_dbg_init(); |
@@ -463,8 +757,8 @@ static void __init omap_mux_package_fixup(struct omap_mux *p, | |||
463 | s++; | 757 | s++; |
464 | } | 758 | } |
465 | if (!found) | 759 | if (!found) |
466 | printk(KERN_ERR "mux: Unknown entry offset 0x%x\n", | 760 | pr_err("%s: Unknown entry offset 0x%x\n", __func__, |
467 | p->reg_offset); | 761 | p->reg_offset); |
468 | p++; | 762 | p++; |
469 | } | 763 | } |
470 | } | 764 | } |
@@ -488,8 +782,8 @@ static void __init omap_mux_package_init_balls(struct omap_ball *b, | |||
488 | s++; | 782 | s++; |
489 | } | 783 | } |
490 | if (!found) | 784 | if (!found) |
491 | printk(KERN_ERR "mux: Unknown ball offset 0x%x\n", | 785 | pr_err("%s: Unknown ball offset 0x%x\n", __func__, |
492 | b->reg_offset); | 786 | b->reg_offset); |
493 | b++; | 787 | b++; |
494 | } | 788 | } |
495 | } | 789 | } |
@@ -555,7 +849,7 @@ static void __init omap_mux_set_cmdline_signals(void) | |||
555 | } | 849 | } |
556 | 850 | ||
557 | static int __init omap_mux_copy_names(struct omap_mux *src, | 851 | static int __init omap_mux_copy_names(struct omap_mux *src, |
558 | struct omap_mux *dst) | 852 | struct omap_mux *dst) |
559 | { | 853 | { |
560 | int i; | 854 | int i; |
561 | 855 | ||
@@ -593,51 +887,63 @@ free: | |||
593 | 887 | ||
594 | #endif /* CONFIG_OMAP_MUX */ | 888 | #endif /* CONFIG_OMAP_MUX */ |
595 | 889 | ||
596 | static u16 omap_mux_get_by_gpio(int gpio) | 890 | static struct omap_mux *omap_mux_get_by_gpio( |
891 | struct omap_mux_partition *partition, | ||
892 | int gpio) | ||
597 | { | 893 | { |
598 | struct omap_mux_entry *e; | 894 | struct omap_mux_entry *e; |
599 | u16 offset = OMAP_MUX_TERMINATOR; | 895 | struct omap_mux *ret = NULL; |
600 | 896 | ||
601 | list_for_each_entry(e, &muxmodes, node) { | 897 | list_for_each_entry(e, &partition->muxmodes, node) { |
602 | struct omap_mux *m = &e->mux; | 898 | struct omap_mux *m = &e->mux; |
603 | if (m->gpio == gpio) { | 899 | if (m->gpio == gpio) { |
604 | offset = m->reg_offset; | 900 | ret = m; |
605 | break; | 901 | break; |
606 | } | 902 | } |
607 | } | 903 | } |
608 | 904 | ||
609 | return offset; | 905 | return ret; |
610 | } | 906 | } |
611 | 907 | ||
612 | /* Needed for dynamic muxing of GPIO pins for off-idle */ | 908 | /* Needed for dynamic muxing of GPIO pins for off-idle */ |
613 | u16 omap_mux_get_gpio(int gpio) | 909 | u16 omap_mux_get_gpio(int gpio) |
614 | { | 910 | { |
615 | u16 offset; | 911 | struct omap_mux_partition *partition; |
912 | struct omap_mux *m = NULL; | ||
616 | 913 | ||
617 | offset = omap_mux_get_by_gpio(gpio); | 914 | list_for_each_entry(partition, &mux_partitions, node) { |
618 | if (offset == OMAP_MUX_TERMINATOR) { | 915 | m = omap_mux_get_by_gpio(partition, gpio); |
619 | printk(KERN_ERR "mux: Could not get gpio%i\n", gpio); | 916 | if (m) |
620 | return offset; | 917 | return omap_mux_read(partition, m->reg_offset); |
621 | } | 918 | } |
622 | 919 | ||
623 | return omap_mux_read(offset); | 920 | if (!m || m->reg_offset == OMAP_MUX_TERMINATOR) |
921 | pr_err("%s: Could not get gpio%i\n", __func__, gpio); | ||
922 | |||
923 | return OMAP_MUX_TERMINATOR; | ||
624 | } | 924 | } |
625 | 925 | ||
626 | /* Needed for dynamic muxing of GPIO pins for off-idle */ | 926 | /* Needed for dynamic muxing of GPIO pins for off-idle */ |
627 | void omap_mux_set_gpio(u16 val, int gpio) | 927 | void omap_mux_set_gpio(u16 val, int gpio) |
628 | { | 928 | { |
629 | u16 offset; | 929 | struct omap_mux_partition *partition; |
930 | struct omap_mux *m = NULL; | ||
630 | 931 | ||
631 | offset = omap_mux_get_by_gpio(gpio); | 932 | list_for_each_entry(partition, &mux_partitions, node) { |
632 | if (offset == OMAP_MUX_TERMINATOR) { | 933 | m = omap_mux_get_by_gpio(partition, gpio); |
633 | printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); | 934 | if (m) { |
634 | return; | 935 | omap_mux_write(partition, val, m->reg_offset); |
936 | return; | ||
937 | } | ||
635 | } | 938 | } |
636 | 939 | ||
637 | omap_mux_write(val, offset); | 940 | if (!m || m->reg_offset == OMAP_MUX_TERMINATOR) |
941 | pr_err("%s: Could not set gpio%i\n", __func__, gpio); | ||
638 | } | 942 | } |
639 | 943 | ||
640 | static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) | 944 | static struct omap_mux * __init omap_mux_list_add( |
945 | struct omap_mux_partition *partition, | ||
946 | struct omap_mux *src) | ||
641 | { | 947 | { |
642 | struct omap_mux_entry *entry; | 948 | struct omap_mux_entry *entry; |
643 | struct omap_mux *m; | 949 | struct omap_mux *m; |
@@ -647,7 +953,7 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) | |||
647 | return NULL; | 953 | return NULL; |
648 | 954 | ||
649 | m = &entry->mux; | 955 | m = &entry->mux; |
650 | memcpy(m, src, sizeof(struct omap_mux_entry)); | 956 | entry->mux = *src; |
651 | 957 | ||
652 | #ifdef CONFIG_OMAP_MUX | 958 | #ifdef CONFIG_OMAP_MUX |
653 | if (omap_mux_copy_names(src, m)) { | 959 | if (omap_mux_copy_names(src, m)) { |
@@ -657,7 +963,7 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) | |||
657 | #endif | 963 | #endif |
658 | 964 | ||
659 | mutex_lock(&muxmode_mutex); | 965 | mutex_lock(&muxmode_mutex); |
660 | list_add_tail(&entry->node, &muxmodes); | 966 | list_add_tail(&entry->node, &partition->muxmodes); |
661 | mutex_unlock(&muxmode_mutex); | 967 | mutex_unlock(&muxmode_mutex); |
662 | 968 | ||
663 | return m; | 969 | return m; |
@@ -668,7 +974,8 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) | |||
668 | * the GPIO to mux offset mapping that is needed for dynamic muxing | 974 | * the GPIO to mux offset mapping that is needed for dynamic muxing |
669 | * of GPIO pins for off-idle. | 975 | * of GPIO pins for off-idle. |
670 | */ | 976 | */ |
671 | static void __init omap_mux_init_list(struct omap_mux *superset) | 977 | static void __init omap_mux_init_list(struct omap_mux_partition *partition, |
978 | struct omap_mux *superset) | ||
672 | { | 979 | { |
673 | while (superset->reg_offset != OMAP_MUX_TERMINATOR) { | 980 | while (superset->reg_offset != OMAP_MUX_TERMINATOR) { |
674 | struct omap_mux *entry; | 981 | struct omap_mux *entry; |
@@ -680,15 +987,16 @@ static void __init omap_mux_init_list(struct omap_mux *superset) | |||
680 | } | 987 | } |
681 | #else | 988 | #else |
682 | /* Skip pins that are not muxed as GPIO by bootloader */ | 989 | /* Skip pins that are not muxed as GPIO by bootloader */ |
683 | if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { | 990 | if (!OMAP_MODE_GPIO(omap_mux_read(partition, |
991 | superset->reg_offset))) { | ||
684 | superset++; | 992 | superset++; |
685 | continue; | 993 | continue; |
686 | } | 994 | } |
687 | #endif | 995 | #endif |
688 | 996 | ||
689 | entry = omap_mux_list_add(superset); | 997 | entry = omap_mux_list_add(partition, superset); |
690 | if (!entry) { | 998 | if (!entry) { |
691 | printk(KERN_ERR "mux: Could not add entry\n"); | 999 | pr_err("%s: Could not add entry\n", __func__); |
692 | return; | 1000 | return; |
693 | } | 1001 | } |
694 | superset++; | 1002 | superset++; |
@@ -707,10 +1015,11 @@ static void omap_mux_init_package(struct omap_mux *superset, | |||
707 | omap_mux_package_init_balls(package_balls, superset); | 1015 | omap_mux_package_init_balls(package_balls, superset); |
708 | } | 1016 | } |
709 | 1017 | ||
710 | static void omap_mux_init_signals(struct omap_board_mux *board_mux) | 1018 | static void omap_mux_init_signals(struct omap_mux_partition *partition, |
1019 | struct omap_board_mux *board_mux) | ||
711 | { | 1020 | { |
712 | omap_mux_set_cmdline_signals(); | 1021 | omap_mux_set_cmdline_signals(); |
713 | omap_mux_write_array(board_mux); | 1022 | omap_mux_write_array(partition, board_mux); |
714 | } | 1023 | } |
715 | 1024 | ||
716 | #else | 1025 | #else |
@@ -721,34 +1030,50 @@ static void omap_mux_init_package(struct omap_mux *superset, | |||
721 | { | 1030 | { |
722 | } | 1031 | } |
723 | 1032 | ||
724 | static void omap_mux_init_signals(struct omap_board_mux *board_mux) | 1033 | static void omap_mux_init_signals(struct omap_mux_partition *partition, |
1034 | struct omap_board_mux *board_mux) | ||
725 | { | 1035 | { |
726 | } | 1036 | } |
727 | 1037 | ||
728 | #endif | 1038 | #endif |
729 | 1039 | ||
730 | int __init omap_mux_init(u32 mux_pbase, u32 mux_size, | 1040 | static u32 mux_partitions_cnt; |
731 | struct omap_mux *superset, | ||
732 | struct omap_mux *package_subset, | ||
733 | struct omap_board_mux *board_mux, | ||
734 | struct omap_ball *package_balls) | ||
735 | { | ||
736 | if (mux_base) | ||
737 | return -EBUSY; | ||
738 | 1041 | ||
739 | mux_phys = mux_pbase; | 1042 | int __init omap_mux_init(const char *name, u32 flags, |
740 | mux_base = ioremap(mux_pbase, mux_size); | 1043 | u32 mux_pbase, u32 mux_size, |
741 | if (!mux_base) { | 1044 | struct omap_mux *superset, |
742 | printk(KERN_ERR "mux: Could not ioremap\n"); | 1045 | struct omap_mux *package_subset, |
1046 | struct omap_board_mux *board_mux, | ||
1047 | struct omap_ball *package_balls) | ||
1048 | { | ||
1049 | struct omap_mux_partition *partition; | ||
1050 | |||
1051 | partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL); | ||
1052 | if (!partition) | ||
1053 | return -ENOMEM; | ||
1054 | |||
1055 | partition->name = name; | ||
1056 | partition->flags = flags; | ||
1057 | partition->size = mux_size; | ||
1058 | partition->phys = mux_pbase; | ||
1059 | partition->base = ioremap(mux_pbase, mux_size); | ||
1060 | if (!partition->base) { | ||
1061 | pr_err("%s: Could not ioremap mux partition at 0x%08x\n", | ||
1062 | __func__, partition->phys); | ||
1063 | kfree(partition); | ||
743 | return -ENODEV; | 1064 | return -ENODEV; |
744 | } | 1065 | } |
745 | 1066 | ||
746 | if (cpu_is_omap24xx()) | 1067 | INIT_LIST_HEAD(&partition->muxmodes); |
747 | omap_mux_flags = MUXABLE_GPIO_MODE3; | 1068 | |
1069 | list_add_tail(&partition->node, &mux_partitions); | ||
1070 | mux_partitions_cnt++; | ||
1071 | pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__, | ||
1072 | mux_partitions_cnt, partition->name, partition->flags); | ||
748 | 1073 | ||
749 | omap_mux_init_package(superset, package_subset, package_balls); | 1074 | omap_mux_init_package(superset, package_subset, package_balls); |
750 | omap_mux_init_list(superset); | 1075 | omap_mux_init_list(partition, superset); |
751 | omap_mux_init_signals(board_mux); | 1076 | omap_mux_init_signals(partition, board_mux); |
752 | 1077 | ||
753 | return 0; | 1078 | return 0; |
754 | } | 1079 | } |