aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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
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')
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c12
-rw-r--r--arch/arm/mach-omap2/mux.c337
-rw-r--r--arch/arm/mach-omap2/mux.h70
-rw-r--r--arch/arm/mach-omap2/mux2420.c7
-rw-r--r--arch/arm/mach-omap2/mux2430.c7
-rw-r--r--arch/arm/mach-omap2/mux34xx.c7
6 files changed, 312 insertions, 128 deletions
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 3fec4d62a91a..3fda20d73233 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -293,6 +293,8 @@ static struct omap_board_mux rx51_mmc2_off_mux[] = {
293 { .reg_offset = OMAP_MUX_TERMINATOR }, 293 { .reg_offset = OMAP_MUX_TERMINATOR },
294}; 294};
295 295
296static struct omap_mux_partition *partition;
297
296/* 298/*
297 * Current flows to eMMC when eMMC is off and the data lines are pulled up, 299 * Current flows to eMMC when eMMC is off and the data lines are pulled up,
298 * so pull them down. N.B. we pull 8 lines because we are using 8 lines. 300 * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
@@ -300,9 +302,9 @@ static struct omap_board_mux rx51_mmc2_off_mux[] = {
300static void rx51_mmc2_remux(struct device *dev, int slot, int power_on) 302static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
301{ 303{
302 if (power_on) 304 if (power_on)
303 omap_mux_write_array(rx51_mmc2_on_mux); 305 omap_mux_write_array(partition, rx51_mmc2_on_mux);
304 else 306 else
305 omap_mux_write_array(rx51_mmc2_off_mux); 307 omap_mux_write_array(partition, rx51_mmc2_off_mux);
306} 308}
307 309
308static struct omap2_hsmmc_info mmc[] __initdata = { 310static struct omap2_hsmmc_info mmc[] __initdata = {
@@ -922,7 +924,11 @@ void __init rx51_peripherals_init(void)
922 rx51_init_wl1251(); 924 rx51_init_wl1251();
923 spi_register_board_info(rx51_peripherals_spi_board_info, 925 spi_register_board_info(rx51_peripherals_spi_board_info,
924 ARRAY_SIZE(rx51_peripherals_spi_board_info)); 926 ARRAY_SIZE(rx51_peripherals_spi_board_info));
925 omap2_hsmmc_init(mmc); 927
928 partition = omap_mux_get("core");
929 if (partition)
930 omap2_hsmmc_init(mmc);
931
926 platform_device_register(&rx51_charger_device); 932 platform_device_register(&rx51_charger_device);
927} 933}
928 934
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}
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 350c04f27383..86549bedd526 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia 2 * Copyright (C) 2009 Nokia
3 * Copyright (C) 2009 Texas Instruments 3 * Copyright (C) 2009-2010 Texas Instruments
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
@@ -56,7 +56,7 @@
56 56
57#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4) 57#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
58 58
59/* Flags for omap_mux_init */ 59/* Flags for omapX_mux_init */
60#define OMAP_PACKAGE_MASK 0xffff 60#define OMAP_PACKAGE_MASK 0xffff
61#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */ 61#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */
62#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */ 62#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */
@@ -66,14 +66,47 @@
66#define OMAP_PACKAGE_ZAF 1 /* 2420 447-pin SIP */ 66#define OMAP_PACKAGE_ZAF 1 /* 2420 447-pin SIP */
67 67
68 68
69#define OMAP_MUX_NR_MODES 8 /* Available modes */ 69#define OMAP_MUX_NR_MODES 8 /* Available modes */
70#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */ 70#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */
71
72/*
73 * omap_mux_init flags definition:
74 *
75 * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
76 * The default value is 16 bits.
77 * OMAP_MUX_GPIO_IN_MODE3: The GPIO is selected in mode3.
78 * The default is mode4.
79 */
80#define OMAP_MUX_REG_8BIT (1 << 0)
81#define OMAP_MUX_GPIO_IN_MODE3 (1 << 1)
82
83/**
84 * struct mux_partition - contain partition related information
85 * @name: name of the current partition
86 * @flags: flags specific to this partition
87 * @phys: physical address
88 * @size: partition size
89 * @base: virtual address after ioremap
90 * @muxmodes: list of nodes that belong to a partition
91 * @node: list node for the partitions linked list
92 */
93struct omap_mux_partition {
94 const char *name;
95 u32 flags;
96 u32 phys;
97 u32 size;
98 void __iomem *base;
99 struct list_head muxmodes;
100 struct list_head node;
101};
71 102
72/** 103/**
73 * struct omap_mux - data for omap mux register offset and it's value 104 * struct omap_mux - data for omap mux register offset and it's value
74 * @reg_offset: mux register offset from the mux base 105 * @reg_offset: mux register offset from the mux base
75 * @gpio: GPIO number 106 * @gpio: GPIO number
76 * @muxnames: available signal modes for a ball 107 * @muxnames: available signal modes for a ball
108 * @balls: available balls on the package
109 * @partition: mux partition
77 */ 110 */
78struct omap_mux { 111struct omap_mux {
79 u16 reg_offset; 112 u16 reg_offset;
@@ -151,28 +184,39 @@ u16 omap_mux_get_gpio(int gpio);
151void omap_mux_set_gpio(u16 val, int gpio); 184void omap_mux_set_gpio(u16 val, int gpio);
152 185
153/** 186/**
187 * omap_mux_get() - get a mux partition by name
188 * @name: Name of the mux partition
189 *
190 */
191struct omap_mux_partition *omap_mux_get(const char *name);
192
193/**
154 * omap_mux_read() - read mux register 194 * omap_mux_read() - read mux register
195 * @partition: Mux partition
155 * @mux_offset: Offset of the mux register 196 * @mux_offset: Offset of the mux register
156 * 197 *
157 */ 198 */
158u16 omap_mux_read(u16 mux_offset); 199u16 omap_mux_read(struct omap_mux_partition *p, u16 mux_offset);
159 200
160/** 201/**
161 * omap_mux_write() - write mux register 202 * omap_mux_write() - write mux register
203 * @partition: Mux partition
162 * @val: New mux register value 204 * @val: New mux register value
163 * @mux_offset: Offset of the mux register 205 * @mux_offset: Offset of the mux register
164 * 206 *
165 * This should be only needed for dynamic remuxing of non-gpio signals. 207 * This should be only needed for dynamic remuxing of non-gpio signals.
166 */ 208 */
167void omap_mux_write(u16 val, u16 mux_offset); 209void omap_mux_write(struct omap_mux_partition *p, u16 val, u16 mux_offset);
168 210
169/** 211/**
170 * omap_mux_write_array() - write an array of mux registers 212 * omap_mux_write_array() - write an array of mux registers
213 * @partition: Mux partition
171 * @board_mux: Array of mux registers terminated by MAP_MUX_TERMINATOR 214 * @board_mux: Array of mux registers terminated by MAP_MUX_TERMINATOR
172 * 215 *
173 * This should be only needed for dynamic remuxing of non-gpio signals. 216 * This should be only needed for dynamic remuxing of non-gpio signals.
174 */ 217 */
175void omap_mux_write_array(struct omap_board_mux *board_mux); 218void omap_mux_write_array(struct omap_mux_partition *p,
219 struct omap_board_mux *board_mux);
176 220
177/** 221/**
178 * omap2420_mux_init() - initialize mux system with board specific set 222 * omap2420_mux_init() - initialize mux system with board specific set
@@ -198,8 +242,10 @@ int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
198/** 242/**
199 * omap_mux_init - private mux init function, do not call 243 * omap_mux_init - private mux init function, do not call
200 */ 244 */
201int omap_mux_init(u32 mux_pbase, u32 mux_size, 245int omap_mux_init(const char *name, u32 flags,
202 struct omap_mux *superset, 246 u32 mux_pbase, u32 mux_size,
203 struct omap_mux *package_subset, 247 struct omap_mux *superset,
204 struct omap_board_mux *board_mux, 248 struct omap_mux *package_subset,
205 struct omap_ball *package_balls); 249 struct omap_board_mux *board_mux,
250 struct omap_ball *package_balls);
251
diff --git a/arch/arm/mach-omap2/mux2420.c b/arch/arm/mach-omap2/mux2420.c
index 414af5434456..8231f0ae4856 100644
--- a/arch/arm/mach-omap2/mux2420.c
+++ b/arch/arm/mach-omap2/mux2420.c
@@ -681,8 +681,9 @@ int __init omap2420_mux_init(struct omap_board_mux *board_subset, int flags)
681 pr_warning("mux: No ball data available for omap2420 package\n"); 681 pr_warning("mux: No ball data available for omap2420 package\n");
682 } 682 }
683 683
684 return omap_mux_init(OMAP2420_CONTROL_PADCONF_MUX_PBASE, 684 return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
685 OMAP2420_CONTROL_PADCONF_MUX_PBASE,
685 OMAP2420_CONTROL_PADCONF_MUX_SIZE, 686 OMAP2420_CONTROL_PADCONF_MUX_SIZE,
686 omap2420_muxmodes, NULL, board_subset, 687 omap2420_muxmodes, NULL, board_subset,
687 package_balls); 688 package_balls);
688} 689}
diff --git a/arch/arm/mach-omap2/mux2430.c b/arch/arm/mach-omap2/mux2430.c
index 84d2c5a7ecd7..cb6b40436e19 100644
--- a/arch/arm/mach-omap2/mux2430.c
+++ b/arch/arm/mach-omap2/mux2430.c
@@ -784,8 +784,9 @@ int __init omap2430_mux_init(struct omap_board_mux *board_subset, int flags)
784 pr_warning("mux: No ball data available for omap2420 package\n"); 784 pr_warning("mux: No ball data available for omap2420 package\n");
785 } 785 }
786 786
787 return omap_mux_init(OMAP2430_CONTROL_PADCONF_MUX_PBASE, 787 return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
788 OMAP2430_CONTROL_PADCONF_MUX_PBASE,
788 OMAP2430_CONTROL_PADCONF_MUX_SIZE, 789 OMAP2430_CONTROL_PADCONF_MUX_SIZE,
789 omap2430_muxmodes, NULL, board_subset, 790 omap2430_muxmodes, NULL, board_subset,
790 package_balls); 791 package_balls);
791} 792}
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
index 574e54ea3ab7..4113c93d3f27 100644
--- a/arch/arm/mach-omap2/mux34xx.c
+++ b/arch/arm/mach-omap2/mux34xx.c
@@ -2053,8 +2053,9 @@ int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
2053 return -EINVAL; 2053 return -EINVAL;
2054 } 2054 }
2055 2055
2056 return omap_mux_init(OMAP3_CONTROL_PADCONF_MUX_PBASE, 2056 return omap_mux_init("core", 0,
2057 OMAP3_CONTROL_PADCONF_MUX_PBASE,
2057 OMAP3_CONTROL_PADCONF_MUX_SIZE, 2058 OMAP3_CONTROL_PADCONF_MUX_SIZE,
2058 omap3_muxmodes, package_subset, board_subset, 2059 omap3_muxmodes, package_subset, board_subset,
2059 package_balls); 2060 package_balls);
2060} 2061}