aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/mux.c
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2010-08-16 04:55:35 -0400
committerBenoit Cousson <b-cousson@ti.com>2010-11-17 06:01:49 -0500
commit112485e9c543b17fc08daea56c7a558b415d06af (patch)
tree3bffd99e96d4c54a177ec251026a1cd5e1122af4 /arch/arm/mach-omap2/mux.c
parent1cbb3a9a132969ed1ffeaecff2f910619d4470ae (diff)
OMAP: mux: Add support for control module split in several partitions
Starting on OMAP4, the pin mux configuration is located in two different partitions of the control module (CODE_PAD and WKUP_PAD). The first one is inside the core power domain whereas the second one is inside the wakeup. - Add the capability to add any number of partition during board init time depending of Soc partitioning. - Add some init flags as well in order to avoid explicit Soc version check inside the mux core code. - Add a comment with mux0 mode on top of omap_mux/board/<partition> if the current mux mode is not the default one. Thanks to Tony Lindgren <tony@atomide.com> for the following improvements: - Add omap_mux_get for getting the partition data so platform level device code can use it. - Fix the rx51 board code to use the new API. - Do not store the partition for each mux entry. Look up the partition for debugfs instead. Thanks to Dan Murphy <dmurphy@ti.com> for testing on OMAP4 and reporting a couple of bugs. Thanks to Anand Gadiyar <gadiyar@ti.com> for testing on OMAP3 zoom and bug report. Signed-off-by: Benoit Cousson <b-cousson@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Tested-by: Murphy Dan <dmurphy@ti.com> Cc: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com> Cc: Anand Gadiyar <gadiyar@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/mux.c')
-rw-r--r--arch/arm/mach-omap2/mux.c337
1 files changed, 233 insertions, 104 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 979e9d1c4659..92215703b671 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
@@ -40,60 +40,72 @@
40 40
41#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ 41#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
42#define OMAP_MUX_BASE_SZ 0x5ca 42#define OMAP_MUX_BASE_SZ 0x5ca
43#define MUXABLE_GPIO_MODE3 BIT(0)
44 43
45struct omap_mux_entry { 44struct omap_mux_entry {
46 struct omap_mux mux; 45 struct omap_mux mux;
47 struct list_head node; 46 struct list_head node;
48}; 47};
49 48
50static unsigned long mux_phys; 49static LIST_HEAD(mux_partitions);
51static void __iomem *mux_base; 50static DEFINE_MUTEX(muxmode_mutex);
52static u8 omap_mux_flags; 51
52struct omap_mux_partition *omap_mux_get(const char *name)
53{
54 struct omap_mux_partition *partition;
55
56 list_for_each_entry(partition, &mux_partitions, node) {
57 if (!strcmp(name, partition->name))
58 return partition;
59 }
53 60
54u16 omap_mux_read(u16 reg) 61 return NULL;
62}
63
64u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
55{ 65{
56 if (cpu_is_omap24xx()) 66 if (partition->flags & OMAP_MUX_REG_8BIT)
57 return __raw_readb(mux_base + reg); 67 return __raw_readb(partition->base + reg);
58 else 68 else
59 return __raw_readw(mux_base + reg); 69 return __raw_readw(partition->base + reg);
60} 70}
61 71
62void omap_mux_write(u16 val, u16 reg) 72void omap_mux_write(struct omap_mux_partition *partition, u16 val,
73 u16 reg)
63{ 74{
64 if (cpu_is_omap24xx()) 75 if (partition->flags & OMAP_MUX_REG_8BIT)
65 __raw_writeb(val, mux_base + reg); 76 __raw_writeb(val, partition->base + reg);
66 else 77 else
67 __raw_writew(val, mux_base + reg); 78 __raw_writew(val, partition->base + reg);
68} 79}
69 80
70void omap_mux_write_array(struct omap_board_mux *board_mux) 81void omap_mux_write_array(struct omap_mux_partition *partition,
82 struct omap_board_mux *board_mux)
71{ 83{
72 while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { 84 while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
73 omap_mux_write(board_mux->value, board_mux->reg_offset); 85 omap_mux_write(partition, board_mux->value,
86 board_mux->reg_offset);
74 board_mux++; 87 board_mux++;
75 } 88 }
76} 89}
77 90
78static LIST_HEAD(muxmodes);
79static DEFINE_MUTEX(muxmode_mutex);
80
81#ifdef CONFIG_OMAP_MUX 91#ifdef CONFIG_OMAP_MUX
82 92
83static char *omap_mux_options; 93static char *omap_mux_options;
84 94
85int __init omap_mux_init_gpio(int gpio, int val) 95static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
96 int gpio, int val)
86{ 97{
87 struct omap_mux_entry *e; 98 struct omap_mux_entry *e;
88 struct omap_mux *gpio_mux = NULL; 99 struct omap_mux *gpio_mux = NULL;
89 u16 old_mode; 100 u16 old_mode;
90 u16 mux_mode; 101 u16 mux_mode;
91 int found = 0; 102 int found = 0;
103 struct list_head *muxmodes = &partition->muxmodes;
92 104
93 if (!gpio) 105 if (!gpio)
94 return -EINVAL; 106 return -EINVAL;
95 107
96 list_for_each_entry(e, &muxmodes, node) { 108 list_for_each_entry(e, muxmodes, node) {
97 struct omap_mux *m = &e->mux; 109 struct omap_mux *m = &e->mux;
98 if (gpio == m->gpio) { 110 if (gpio == m->gpio) {
99 gpio_mux = m; 111 gpio_mux = m;
@@ -112,24 +124,40 @@ int __init omap_mux_init_gpio(int gpio, int val)
112 return -EINVAL; 124 return -EINVAL;
113 } 125 }
114 126
115 old_mode = omap_mux_read(gpio_mux->reg_offset); 127 old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
116 mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); 128 mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
117 if (omap_mux_flags & MUXABLE_GPIO_MODE3) 129 if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
118 mux_mode |= OMAP_MUX_MODE3; 130 mux_mode |= OMAP_MUX_MODE3;
119 else 131 else
120 mux_mode |= OMAP_MUX_MODE4; 132 mux_mode |= OMAP_MUX_MODE4;
121 pr_debug("mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", 133 pr_debug("mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n",
122 gpio_mux->muxnames[0], gpio, old_mode, mux_mode); 134 gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
123 omap_mux_write(mux_mode, gpio_mux->reg_offset); 135 omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
124 136
125 return 0; 137 return 0;
126} 138}
127 139
128int __init omap_mux_init_signal(const char *muxname, int val) 140int __init omap_mux_init_gpio(int gpio, int val)
141{
142 struct omap_mux_partition *partition;
143 int ret;
144
145 list_for_each_entry(partition, &mux_partitions, node) {
146 ret = _omap_mux_init_gpio(partition, gpio, val);
147 if (!ret)
148 return ret;
149 }
150
151 return -ENODEV;
152}
153
154static int __init _omap_mux_init_signal(struct omap_mux_partition *partition,
155 const char *muxname, int val)
129{ 156{
130 struct omap_mux_entry *e; 157 struct omap_mux_entry *e;
131 const char *mode_name; 158 const char *mode_name;
132 int found = 0, mode0_len = 0; 159 int found = 0, mode0_len = 0;
160 struct list_head *muxmodes = &partition->muxmodes;
133 161
134 mode_name = strchr(muxname, '.'); 162 mode_name = strchr(muxname, '.');
135 if (mode_name) { 163 if (mode_name) {
@@ -139,7 +167,7 @@ int __init omap_mux_init_signal(const char *muxname, int val)
139 mode_name = muxname; 167 mode_name = muxname;
140 } 168 }
141 169
142 list_for_each_entry(e, &muxmodes, node) { 170 list_for_each_entry(e, muxmodes, node) {
143 struct omap_mux *m = &e->mux; 171 struct omap_mux *m = &e->mux;
144 char *m0_entry = m->muxnames[0]; 172 char *m0_entry = m->muxnames[0];
145 int i; 173 int i;
@@ -159,12 +187,14 @@ int __init omap_mux_init_signal(const char *muxname, int val)
159 u16 old_mode; 187 u16 old_mode;
160 u16 mux_mode; 188 u16 mux_mode;
161 189
162 old_mode = omap_mux_read(m->reg_offset); 190 old_mode = omap_mux_read(partition,
191 m->reg_offset);
163 mux_mode = val | i; 192 mux_mode = val | i;
164 pr_debug("mux: Setting signal " 193 pr_debug("mux: Setting signal "
165 "%s.%s 0x%04x -> 0x%04x\n", 194 "%s.%s 0x%04x -> 0x%04x\n",
166 m0_entry, muxname, old_mode, mux_mode); 195 m0_entry, muxname, old_mode, mux_mode);
167 omap_mux_write(mux_mode, m->reg_offset); 196 omap_mux_write(partition, mux_mode,
197 m->reg_offset);
168 found++; 198 found++;
169 } 199 }
170 } 200 }
@@ -184,6 +214,21 @@ int __init omap_mux_init_signal(const char *muxname, int val)
184 return -ENODEV; 214 return -ENODEV;
185} 215}
186 216
217int __init omap_mux_init_signal(const char *muxname, int val)
218{
219 struct omap_mux_partition *partition;
220 int ret;
221
222 list_for_each_entry(partition, &mux_partitions, node) {
223 ret = _omap_mux_init_signal(partition, muxname, val);
224 if (!ret)
225 return ret;
226 }
227
228 return -ENODEV;
229
230}
231
187#ifdef CONFIG_DEBUG_FS 232#ifdef CONFIG_DEBUG_FS
188 233
189#define OMAP_MUX_MAX_NR_FLAGS 10 234#define OMAP_MUX_MAX_NR_FLAGS 10
@@ -248,13 +293,15 @@ static inline void omap_mux_decode(struct seq_file *s, u16 val)
248 } while (i-- > 0); 293 } while (i-- > 0);
249} 294}
250 295
251#define OMAP_MUX_DEFNAME_LEN 16 296#define OMAP_MUX_DEFNAME_LEN 32
252 297
253static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) 298static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
254{ 299{
300 struct omap_mux_partition *partition = s->private;
255 struct omap_mux_entry *e; 301 struct omap_mux_entry *e;
302 u8 omap_gen = omap_rev() >> 28;
256 303
257 list_for_each_entry(e, &muxmodes, node) { 304 list_for_each_entry(e, &partition->muxmodes, node) {
258 struct omap_mux *m = &e->mux; 305 struct omap_mux *m = &e->mux;
259 char m0_def[OMAP_MUX_DEFNAME_LEN]; 306 char m0_def[OMAP_MUX_DEFNAME_LEN];
260 char *m0_name = m->muxnames[0]; 307 char *m0_name = m->muxnames[0];
@@ -272,11 +319,16 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
272 } 319 }
273 m0_def[i] = toupper(m0_name[i]); 320 m0_def[i] = toupper(m0_name[i]);
274 } 321 }
275 val = omap_mux_read(m->reg_offset); 322 val = omap_mux_read(partition, m->reg_offset);
276 mode = val & OMAP_MUX_MODE7; 323 mode = val & OMAP_MUX_MODE7;
277 324 if (mode != 0)
278 seq_printf(s, "OMAP%i_MUX(%s, ", 325 seq_printf(s, "/* %s */\n", m->muxnames[mode]);
279 cpu_is_omap34xx() ? 3 : 0, m0_def); 326
327 /*
328 * XXX: Might be revisited to support differences accross
329 * same OMAP generation.
330 */
331 seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
280 omap_mux_decode(s, val); 332 omap_mux_decode(s, val);
281 seq_printf(s, "),\n"); 333 seq_printf(s, "),\n");
282 } 334 }
@@ -286,7 +338,7 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
286 338
287static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) 339static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
288{ 340{
289 return single_open(file, omap_mux_dbg_board_show, &inode->i_private); 341 return single_open(file, omap_mux_dbg_board_show, inode->i_private);
290} 342}
291 343
292static const struct file_operations omap_mux_dbg_board_fops = { 344static const struct file_operations omap_mux_dbg_board_fops = {
@@ -296,19 +348,43 @@ static const struct file_operations omap_mux_dbg_board_fops = {
296 .release = single_release, 348 .release = single_release,
297}; 349};
298 350
351static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
352{
353 struct omap_mux_partition *partition;
354
355 list_for_each_entry(partition, &mux_partitions, node) {
356 struct list_head *muxmodes = &partition->muxmodes;
357 struct omap_mux_entry *e;
358
359 list_for_each_entry(e, muxmodes, node) {
360 struct omap_mux *m = &e->mux;
361
362 if (m == mux)
363 return partition;
364 }
365 }
366
367 return NULL;
368}
369
299static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) 370static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
300{ 371{
301 struct omap_mux *m = s->private; 372 struct omap_mux *m = s->private;
373 struct omap_mux_partition *partition;
302 const char *none = "NA"; 374 const char *none = "NA";
303 u16 val; 375 u16 val;
304 int mode; 376 int mode;
305 377
306 val = omap_mux_read(m->reg_offset); 378 partition = omap_mux_get_partition(m);
379 if (!partition)
380 return 0;
381
382 val = omap_mux_read(partition, m->reg_offset);
307 mode = val & OMAP_MUX_MODE7; 383 mode = val & OMAP_MUX_MODE7;
308 384
309 seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n", 385 seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
310 m->muxnames[0], m->muxnames[mode], 386 m->muxnames[0], m->muxnames[mode],
311 mux_phys + m->reg_offset, m->reg_offset, val, 387 partition->phys + m->reg_offset, m->reg_offset, val,
312 m->balls[0] ? m->balls[0] : none, 388 m->balls[0] ? m->balls[0] : none,
313 m->balls[1] ? m->balls[1] : none); 389 m->balls[1] ? m->balls[1] : none);
314 seq_printf(s, "mode: "); 390 seq_printf(s, "mode: ");
@@ -330,14 +406,15 @@ static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
330#define OMAP_MUX_MAX_ARG_CHAR 7 406#define OMAP_MUX_MAX_ARG_CHAR 7
331 407
332static ssize_t omap_mux_dbg_signal_write(struct file *file, 408static ssize_t omap_mux_dbg_signal_write(struct file *file,
333 const char __user *user_buf, 409 const char __user *user_buf,
334 size_t count, loff_t *ppos) 410 size_t count, loff_t *ppos)
335{ 411{
336 char buf[OMAP_MUX_MAX_ARG_CHAR]; 412 char buf[OMAP_MUX_MAX_ARG_CHAR];
337 struct seq_file *seqf; 413 struct seq_file *seqf;
338 struct omap_mux *m; 414 struct omap_mux *m;
339 unsigned long val; 415 unsigned long val;
340 int buf_size, ret; 416 int buf_size, ret;
417 struct omap_mux_partition *partition;
341 418
342 if (count > OMAP_MUX_MAX_ARG_CHAR) 419 if (count > OMAP_MUX_MAX_ARG_CHAR)
343 return -EINVAL; 420 return -EINVAL;
@@ -358,7 +435,11 @@ static ssize_t omap_mux_dbg_signal_write(struct file *file,
358 seqf = file->private_data; 435 seqf = file->private_data;
359 m = seqf->private; 436 m = seqf->private;
360 437
361 omap_mux_write((u16)val, m->reg_offset); 438 partition = omap_mux_get_partition(m);
439 if (!partition)
440 return -ENODEV;
441
442 omap_mux_write(partition, (u16)val, m->reg_offset);
362 *ppos += count; 443 *ppos += count;
363 444
364 return count; 445 return count;
@@ -379,22 +460,38 @@ static const struct file_operations omap_mux_dbg_signal_fops = {
379 460
380static struct dentry *mux_dbg_dir; 461static struct dentry *mux_dbg_dir;
381 462
382static void __init omap_mux_dbg_init(void) 463static void __init omap_mux_dbg_create_entry(
464 struct omap_mux_partition *partition,
465 struct dentry *mux_dbg_dir)
383{ 466{
384 struct omap_mux_entry *e; 467 struct omap_mux_entry *e;
385 468
469 list_for_each_entry(e, &partition->muxmodes, node) {
470 struct omap_mux *m = &e->mux;
471
472 (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
473 m, &omap_mux_dbg_signal_fops);
474 }
475}
476
477static void __init omap_mux_dbg_init(void)
478{
479 struct omap_mux_partition *partition;
480 static struct dentry *mux_dbg_board_dir;
481
386 mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); 482 mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
387 if (!mux_dbg_dir) 483 if (!mux_dbg_dir)
388 return; 484 return;
389 485
390 (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir, 486 mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
391 NULL, &omap_mux_dbg_board_fops); 487 if (!mux_dbg_board_dir)
392 488 return;
393 list_for_each_entry(e, &muxmodes, node) {
394 struct omap_mux *m = &e->mux;
395 489
396 (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir, 490 list_for_each_entry(partition, &mux_partitions, node) {
397 m, &omap_mux_dbg_signal_fops); 491 omap_mux_dbg_create_entry(partition, mux_dbg_dir);
492 (void)debugfs_create_file(partition->name, S_IRUGO,
493 mux_dbg_board_dir, partition,
494 &omap_mux_dbg_board_fops);
398 } 495 }
399} 496}
400 497
@@ -421,23 +518,25 @@ static void __init omap_mux_free_names(struct omap_mux *m)
421/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ 518/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
422static int __init omap_mux_late_init(void) 519static int __init omap_mux_late_init(void)
423{ 520{
424 struct omap_mux_entry *e, *tmp; 521 struct omap_mux_partition *partition;
425 522
426 list_for_each_entry_safe(e, tmp, &muxmodes, node) { 523 list_for_each_entry(partition, &mux_partitions, node) {
427 struct omap_mux *m = &e->mux; 524 struct omap_mux_entry *e, *tmp;
428 u16 mode = omap_mux_read(m->reg_offset); 525 list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
526 struct omap_mux *m = &e->mux;
527 u16 mode = omap_mux_read(partition, m->reg_offset);
429 528
430 if (OMAP_MODE_GPIO(mode)) 529 if (OMAP_MODE_GPIO(mode))
431 continue; 530 continue;
432 531
433#ifndef CONFIG_DEBUG_FS 532#ifndef CONFIG_DEBUG_FS
434 mutex_lock(&muxmode_mutex); 533 mutex_lock(&muxmode_mutex);
435 list_del(&e->node); 534 list_del(&e->node);
436 mutex_unlock(&muxmode_mutex); 535 mutex_unlock(&muxmode_mutex);
437 omap_mux_free_names(m); 536 omap_mux_free_names(m);
438 kfree(m); 537 kfree(m);
439#endif 538#endif
440 539 }
441 } 540 }
442 541
443 omap_mux_dbg_init(); 542 omap_mux_dbg_init();
@@ -554,7 +653,7 @@ static void __init omap_mux_set_cmdline_signals(void)
554} 653}
555 654
556static int __init omap_mux_copy_names(struct omap_mux *src, 655static int __init omap_mux_copy_names(struct omap_mux *src,
557 struct omap_mux *dst) 656 struct omap_mux *dst)
558{ 657{
559 int i; 658 int i;
560 659
@@ -592,51 +691,63 @@ free:
592 691
593#endif /* CONFIG_OMAP_MUX */ 692#endif /* CONFIG_OMAP_MUX */
594 693
595static u16 omap_mux_get_by_gpio(int gpio) 694static struct omap_mux *omap_mux_get_by_gpio(
695 struct omap_mux_partition *partition,
696 int gpio)
596{ 697{
597 struct omap_mux_entry *e; 698 struct omap_mux_entry *e;
598 u16 offset = OMAP_MUX_TERMINATOR; 699 struct omap_mux *ret = NULL;
599 700
600 list_for_each_entry(e, &muxmodes, node) { 701 list_for_each_entry(e, &partition->muxmodes, node) {
601 struct omap_mux *m = &e->mux; 702 struct omap_mux *m = &e->mux;
602 if (m->gpio == gpio) { 703 if (m->gpio == gpio) {
603 offset = m->reg_offset; 704 ret = m;
604 break; 705 break;
605 } 706 }
606 } 707 }
607 708
608 return offset; 709 return ret;
609} 710}
610 711
611/* Needed for dynamic muxing of GPIO pins for off-idle */ 712/* Needed for dynamic muxing of GPIO pins for off-idle */
612u16 omap_mux_get_gpio(int gpio) 713u16 omap_mux_get_gpio(int gpio)
613{ 714{
614 u16 offset; 715 struct omap_mux_partition *partition;
716 struct omap_mux *m;
615 717
616 offset = omap_mux_get_by_gpio(gpio); 718 list_for_each_entry(partition, &mux_partitions, node) {
617 if (offset == OMAP_MUX_TERMINATOR) { 719 m = omap_mux_get_by_gpio(partition, gpio);
618 pr_err("mux: Could not get gpio%i\n", gpio); 720 if (m)
619 return offset; 721 return omap_mux_read(partition, m->reg_offset);
620 } 722 }
621 723
622 return omap_mux_read(offset); 724 if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
725 pr_err("mux: Could not get gpio%i\n", gpio);
726
727 return OMAP_MUX_TERMINATOR;
623} 728}
624 729
625/* Needed for dynamic muxing of GPIO pins for off-idle */ 730/* Needed for dynamic muxing of GPIO pins for off-idle */
626void omap_mux_set_gpio(u16 val, int gpio) 731void omap_mux_set_gpio(u16 val, int gpio)
627{ 732{
628 u16 offset; 733 struct omap_mux_partition *partition;
734 struct omap_mux *m = NULL;
629 735
630 offset = omap_mux_get_by_gpio(gpio); 736 list_for_each_entry(partition, &mux_partitions, node) {
631 if (offset == OMAP_MUX_TERMINATOR) { 737 m = omap_mux_get_by_gpio(partition, gpio);
632 pr_err("mux: Could not set gpio%i\n", gpio); 738 if (m) {
633 return; 739 omap_mux_write(partition, val, m->reg_offset);
740 return;
741 }
634 } 742 }
635 743
636 omap_mux_write(val, offset); 744 if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
745 pr_err("mux: Could not set gpio%i\n", gpio);
637} 746}
638 747
639static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) 748static struct omap_mux * __init omap_mux_list_add(
749 struct omap_mux_partition *partition,
750 struct omap_mux *src)
640{ 751{
641 struct omap_mux_entry *entry; 752 struct omap_mux_entry *entry;
642 struct omap_mux *m; 753 struct omap_mux *m;
@@ -656,7 +767,7 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
656#endif 767#endif
657 768
658 mutex_lock(&muxmode_mutex); 769 mutex_lock(&muxmode_mutex);
659 list_add_tail(&entry->node, &muxmodes); 770 list_add_tail(&entry->node, &partition->muxmodes);
660 mutex_unlock(&muxmode_mutex); 771 mutex_unlock(&muxmode_mutex);
661 772
662 return m; 773 return m;
@@ -667,7 +778,8 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
667 * the GPIO to mux offset mapping that is needed for dynamic muxing 778 * the GPIO to mux offset mapping that is needed for dynamic muxing
668 * of GPIO pins for off-idle. 779 * of GPIO pins for off-idle.
669 */ 780 */
670static void __init omap_mux_init_list(struct omap_mux *superset) 781static void __init omap_mux_init_list(struct omap_mux_partition *partition,
782 struct omap_mux *superset)
671{ 783{
672 while (superset->reg_offset != OMAP_MUX_TERMINATOR) { 784 while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
673 struct omap_mux *entry; 785 struct omap_mux *entry;
@@ -679,13 +791,14 @@ static void __init omap_mux_init_list(struct omap_mux *superset)
679 } 791 }
680#else 792#else
681 /* Skip pins that are not muxed as GPIO by bootloader */ 793 /* Skip pins that are not muxed as GPIO by bootloader */
682 if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { 794 if (!OMAP_MODE_GPIO(omap_mux_read(partition,
795 superset->reg_offset))) {
683 superset++; 796 superset++;
684 continue; 797 continue;
685 } 798 }
686#endif 799#endif
687 800
688 entry = omap_mux_list_add(superset); 801 entry = omap_mux_list_add(partition, superset);
689 if (!entry) { 802 if (!entry) {
690 pr_err("mux: Could not add entry\n"); 803 pr_err("mux: Could not add entry\n");
691 return; 804 return;
@@ -706,10 +819,11 @@ static void omap_mux_init_package(struct omap_mux *superset,
706 omap_mux_package_init_balls(package_balls, superset); 819 omap_mux_package_init_balls(package_balls, superset);
707} 820}
708 821
709static void omap_mux_init_signals(struct omap_board_mux *board_mux) 822static void omap_mux_init_signals(struct omap_mux_partition *partition,
823 struct omap_board_mux *board_mux)
710{ 824{
711 omap_mux_set_cmdline_signals(); 825 omap_mux_set_cmdline_signals();
712 omap_mux_write_array(board_mux); 826 omap_mux_write_array(partition, board_mux);
713} 827}
714 828
715#else 829#else
@@ -720,34 +834,49 @@ static void omap_mux_init_package(struct omap_mux *superset,
720{ 834{
721} 835}
722 836
723static void omap_mux_init_signals(struct omap_board_mux *board_mux) 837static void omap_mux_init_signals(struct omap_mux_partition *partition,
838 struct omap_board_mux *board_mux)
724{ 839{
725} 840}
726 841
727#endif 842#endif
728 843
729int __init omap_mux_init(u32 mux_pbase, u32 mux_size, 844static u32 mux_partitions_cnt;
730 struct omap_mux *superset,
731 struct omap_mux *package_subset,
732 struct omap_board_mux *board_mux,
733 struct omap_ball *package_balls)
734{
735 if (mux_base)
736 return -EBUSY;
737 845
738 mux_phys = mux_pbase; 846int __init omap_mux_init(const char *name, u32 flags,
739 mux_base = ioremap(mux_pbase, mux_size); 847 u32 mux_pbase, u32 mux_size,
740 if (!mux_base) { 848 struct omap_mux *superset,
741 pr_err("mux: Could not ioremap\n"); 849 struct omap_mux *package_subset,
850 struct omap_board_mux *board_mux,
851 struct omap_ball *package_balls)
852{
853 struct omap_mux_partition *partition;
854
855 partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
856 if (!partition)
857 return -ENOMEM;
858
859 partition->name = name;
860 partition->flags = flags;
861 partition->size = mux_size;
862 partition->phys = mux_pbase;
863 partition->base = ioremap(mux_pbase, mux_size);
864 if (!partition->base) {
865 pr_err("mux: Could not ioremap mux partition at 0x%08x\n",
866 partition->phys);
742 return -ENODEV; 867 return -ENODEV;
743 } 868 }
744 869
745 if (cpu_is_omap24xx()) 870 INIT_LIST_HEAD(&partition->muxmodes);
746 omap_mux_flags = MUXABLE_GPIO_MODE3; 871
872 list_add_tail(&partition->node, &mux_partitions);
873 mux_partitions_cnt++;
874 pr_info("MUX: Add partition: #%d: %s, flags: %x\n",
875 mux_partitions_cnt, partition->name, partition->flags);
747 876
748 omap_mux_init_package(superset, package_subset, package_balls); 877 omap_mux_init_package(superset, package_subset, package_balls);
749 omap_mux_init_list(superset); 878 omap_mux_init_list(partition, superset);
750 omap_mux_init_signals(board_mux); 879 omap_mux_init_signals(partition, board_mux);
751 880
752 return 0; 881 return 0;
753} 882}