aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/mux.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-06 22:13:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-06 22:13:58 -0500
commit01539ba2a706ab7d35fc0667dff919ade7f87d63 (patch)
tree5a4bd0cf78007d06690fe4ac06bbd49a5a70bc47 /arch/arm/mach-omap2/mux.c
parent9e9bc9736756f25d6c47b4eba0ebf25b20a6f153 (diff)
parentdc69d1af9e8d9cbbabff88bb35a6782187a22229 (diff)
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6
* 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6: (243 commits) omap2: Make OMAP2PLUS select OMAP_DM_TIMER OMAP4: hwmod data: Fix alignment and end of line in structurefields OMAP4: hwmod data: Move the DMA structures OMAP4: hwmod data: Move the smartreflex structures OMAP4: hwmod data: Fix missing SIDLE_SMART_WKUP in smartreflexsysc arm: omap: tusb6010: add name for MUSB IRQ arm: omap: craneboard: Add USB EHCI support omap2+: Initialize serial port for dynamic remuxing for n8x0 omap2+: Add struct omap_board_data and use it for platform level serial init omap2+: Allow hwmod state changes to mux pads based on the state changes omap2+: Add support for hwmod specific muxing of devices omap2+: Add omap_mux_get_by_name OMAP2: PM: fix compile error when !CONFIG_SUSPEND MAINTAINERS: OMAP: hwmod: update hwmod code, data maintainership OMAP4: Smartreflex framework extensions OMAP4: hwmod: Add inital data for smartreflex modules. OMAP4: PM: Program correct init voltages for scalable VDDs OMAP4: Adding voltage driver support OMAP4: Register voltage PMIC parameters with the voltage layer OMAP3: PM: Program correct init voltages for VDD1 and VDD2 ... Fix up trivial conflict in arch/arm/plat-omap/Kconfig
Diffstat (limited to 'arch/arm/mach-omap2/mux.c')
-rw-r--r--arch/arm/mach-omap2/mux.c525
1 files changed, 395 insertions, 130 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 074536ae401f..17bd6394d224 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
@@ -35,65 +35,79 @@
35 35
36#include <asm/system.h> 36#include <asm/system.h>
37 37
38#include <plat/omap_hwmod.h>
39
38#include "control.h" 40#include "control.h"
39#include "mux.h" 41#include "mux.h"
40 42
41#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ 43#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
42#define OMAP_MUX_BASE_SZ 0x5ca 44#define OMAP_MUX_BASE_SZ 0x5ca
43#define MUXABLE_GPIO_MODE3 BIT(0)
44 45
45struct omap_mux_entry { 46struct omap_mux_entry {
46 struct omap_mux mux; 47 struct omap_mux mux;
47 struct list_head node; 48 struct list_head node;
48}; 49};
49 50
50static unsigned long mux_phys; 51static LIST_HEAD(mux_partitions);
51static void __iomem *mux_base; 52static DEFINE_MUTEX(muxmode_mutex);
52static u8 omap_mux_flags; 53
54struct 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}
53 65
54u16 omap_mux_read(u16 reg) 66u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
55{ 67{
56 if (cpu_is_omap24xx()) 68 if (partition->flags & OMAP_MUX_REG_8BIT)
57 return __raw_readb(mux_base + reg); 69 return __raw_readb(partition->base + reg);
58 else 70 else
59 return __raw_readw(mux_base + reg); 71 return __raw_readw(partition->base + reg);
60} 72}
61 73
62void omap_mux_write(u16 val, u16 reg) 74void omap_mux_write(struct omap_mux_partition *partition, u16 val,
75 u16 reg)
63{ 76{
64 if (cpu_is_omap24xx()) 77 if (partition->flags & OMAP_MUX_REG_8BIT)
65 __raw_writeb(val, mux_base + reg); 78 __raw_writeb(val, partition->base + reg);
66 else 79 else
67 __raw_writew(val, mux_base + reg); 80 __raw_writew(val, partition->base + reg);
68} 81}
69 82
70void omap_mux_write_array(struct omap_board_mux *board_mux) 83void omap_mux_write_array(struct omap_mux_partition *partition,
84 struct omap_board_mux *board_mux)
71{ 85{
72 while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { 86 while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
73 omap_mux_write(board_mux->value, board_mux->reg_offset); 87 omap_mux_write(partition, board_mux->value,
88 board_mux->reg_offset);
74 board_mux++; 89 board_mux++;
75 } 90 }
76} 91}
77 92
78static LIST_HEAD(muxmodes);
79static DEFINE_MUTEX(muxmode_mutex);
80
81#ifdef CONFIG_OMAP_MUX 93#ifdef CONFIG_OMAP_MUX
82 94
83static char *omap_mux_options; 95static char *omap_mux_options;
84 96
85int __init omap_mux_init_gpio(int gpio, int val) 97static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
98 int gpio, int val)
86{ 99{
87 struct omap_mux_entry *e; 100 struct omap_mux_entry *e;
88 struct omap_mux *gpio_mux = NULL; 101 struct omap_mux *gpio_mux = NULL;
89 u16 old_mode; 102 u16 old_mode;
90 u16 mux_mode; 103 u16 mux_mode;
91 int found = 0; 104 int found = 0;
105 struct list_head *muxmodes = &partition->muxmodes;
92 106
93 if (!gpio) 107 if (!gpio)
94 return -EINVAL; 108 return -EINVAL;
95 109
96 list_for_each_entry(e, &muxmodes, node) { 110 list_for_each_entry(e, muxmodes, node) {
97 struct omap_mux *m = &e->mux; 111 struct omap_mux *m = &e->mux;
98 if (gpio == m->gpio) { 112 if (gpio == m->gpio) {
99 gpio_mux = m; 113 gpio_mux = m;
@@ -102,34 +116,52 @@ int __init omap_mux_init_gpio(int gpio, int val)
102 } 116 }
103 117
104 if (found == 0) { 118 if (found == 0) {
105 printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); 119 pr_err("%s: Could not set gpio%i\n", __func__, gpio);
106 return -ENODEV; 120 return -ENODEV;
107 } 121 }
108 122
109 if (found > 1) { 123 if (found > 1) {
110 printk(KERN_INFO "mux: Multiple gpio paths (%d) for gpio%i\n", 124 pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
111 found, gpio); 125 found, gpio);
112 return -EINVAL; 126 return -EINVAL;
113 } 127 }
114 128
115 old_mode = omap_mux_read(gpio_mux->reg_offset); 129 old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
116 mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); 130 mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
117 if (omap_mux_flags & MUXABLE_GPIO_MODE3) 131 if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
118 mux_mode |= OMAP_MUX_MODE3; 132 mux_mode |= OMAP_MUX_MODE3;
119 else 133 else
120 mux_mode |= OMAP_MUX_MODE4; 134 mux_mode |= OMAP_MUX_MODE4;
121 printk(KERN_DEBUG "mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", 135 pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
122 gpio_mux->muxnames[0], gpio, old_mode, mux_mode); 136 gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
123 omap_mux_write(mux_mode, gpio_mux->reg_offset); 137 omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
124 138
125 return 0; 139 return 0;
126} 140}
127 141
128int __init omap_mux_init_signal(const char *muxname, int val) 142int __init omap_mux_init_gpio(int gpio, int val)
143{
144 struct omap_mux_partition *partition;
145 int ret;
146
147 list_for_each_entry(partition, &mux_partitions, node) {
148 ret = _omap_mux_init_gpio(partition, gpio, val);
149 if (!ret)
150 return ret;
151 }
152
153 return -ENODEV;
154}
155
156static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
157 const char *muxname,
158 struct omap_mux **found_mux)
129{ 159{
160 struct omap_mux *mux = NULL;
130 struct omap_mux_entry *e; 161 struct omap_mux_entry *e;
131 const char *mode_name; 162 const char *mode_name;
132 int found = 0, mode0_len = 0; 163 int found = 0, found_mode, mode0_len = 0;
164 struct list_head *muxmodes = &partition->muxmodes;
133 165
134 mode_name = strchr(muxname, '.'); 166 mode_name = strchr(muxname, '.');
135 if (mode_name) { 167 if (mode_name) {
@@ -139,51 +171,200 @@ int __init omap_mux_init_signal(const char *muxname, int val)
139 mode_name = muxname; 171 mode_name = muxname;
140 } 172 }
141 173
142 list_for_each_entry(e, &muxmodes, node) { 174 list_for_each_entry(e, muxmodes, node) {
143 struct omap_mux *m = &e->mux; 175 char *m0_entry;
144 char *m0_entry = m->muxnames[0];
145 int i; 176 int i;
146 177
178 mux = &e->mux;
179 m0_entry = mux->muxnames[0];
180
147 /* First check for full name in mode0.muxmode format */ 181 /* First check for full name in mode0.muxmode format */
148 if (mode0_len && strncmp(muxname, m0_entry, mode0_len)) 182 if (mode0_len && strncmp(muxname, m0_entry, mode0_len))
149 continue; 183 continue;
150 184
151 /* Then check for muxmode only */ 185 /* Then check for muxmode only */
152 for (i = 0; i < OMAP_MUX_NR_MODES; i++) { 186 for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
153 char *mode_cur = m->muxnames[i]; 187 char *mode_cur = mux->muxnames[i];
154 188
155 if (!mode_cur) 189 if (!mode_cur)
156 continue; 190 continue;
157 191
158 if (!strcmp(mode_name, mode_cur)) { 192 if (!strcmp(mode_name, mode_cur)) {
159 u16 old_mode; 193 *found_mux = mux;
160 u16 mux_mode;
161
162 old_mode = omap_mux_read(m->reg_offset);
163 mux_mode = val | i;
164 printk(KERN_DEBUG "mux: Setting signal "
165 "%s.%s 0x%04x -> 0x%04x\n",
166 m0_entry, muxname, old_mode, mux_mode);
167 omap_mux_write(mux_mode, m->reg_offset);
168 found++; 194 found++;
195 found_mode = i;
169 } 196 }
170 } 197 }
171 } 198 }
172 199
173 if (found == 1) 200 if (found == 1) {
174 return 0; 201 return found_mode;
202 }
175 203
176 if (found > 1) { 204 if (found > 1) {
177 printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n", 205 pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
178 found, muxname); 206 found, muxname);
179 return -EINVAL; 207 return -EINVAL;
180 } 208 }
181 209
182 printk(KERN_ERR "mux: Could not set signal %s\n", muxname); 210 pr_err("%s: Could not find signal %s\n", __func__, muxname);
183 211
184 return -ENODEV; 212 return -ENODEV;
185} 213}
186 214
215static int __init
216omap_mux_get_by_name(const char *muxname,
217 struct omap_mux_partition **found_partition,
218 struct omap_mux **found_mux)
219{
220 struct omap_mux_partition *partition;
221
222 list_for_each_entry(partition, &mux_partitions, node) {
223 struct omap_mux *mux = NULL;
224 int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux);
225 if (mux_mode < 0)
226 continue;
227
228 *found_partition = partition;
229 *found_mux = mux;
230
231 return mux_mode;
232 }
233
234 return -ENODEV;
235}
236
237int __init omap_mux_init_signal(const char *muxname, int val)
238{
239 struct omap_mux_partition *partition = NULL;
240 struct omap_mux *mux = NULL;
241 u16 old_mode;
242 int mux_mode;
243
244 mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
245 if (mux_mode < 0)
246 return mux_mode;
247
248 old_mode = omap_mux_read(partition, mux->reg_offset);
249 mux_mode |= val;
250 pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
251 __func__, muxname, old_mode, mux_mode);
252 omap_mux_write(partition, mux_mode, mux->reg_offset);
253
254 return 0;
255}
256
257struct omap_hwmod_mux_info * __init
258omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
259{
260 struct omap_hwmod_mux_info *hmux;
261 int i;
262
263 if (!bpads || nr_pads < 1)
264 return NULL;
265
266 hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
267 if (!hmux)
268 goto err1;
269
270 hmux->nr_pads = nr_pads;
271
272 hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
273 nr_pads, GFP_KERNEL);
274 if (!hmux->pads)
275 goto err2;
276
277 for (i = 0; i < hmux->nr_pads; i++) {
278 struct omap_mux_partition *partition;
279 struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
280 struct omap_mux *mux;
281 int mux_mode;
282
283 mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
284 if (mux_mode < 0)
285 goto err3;
286 if (!pad->partition)
287 pad->partition = partition;
288 if (!pad->mux)
289 pad->mux = mux;
290
291 pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
292 if (!pad->name) {
293 int j;
294
295 for (j = i - 1; j >= 0; j--)
296 kfree(hmux->pads[j].name);
297 goto err3;
298 }
299 strcpy(pad->name, bpad->name);
300
301 pad->flags = bpad->flags;
302 pad->enable = bpad->enable;
303 pad->idle = bpad->idle;
304 pad->off = bpad->off;
305 pr_debug("%s: Initialized %s\n", __func__, pad->name);
306 }
307
308 return hmux;
309
310err3:
311 kfree(hmux->pads);
312err2:
313 kfree(hmux);
314err1:
315 pr_err("%s: Could not allocate device mux entry\n", __func__);
316
317 return NULL;
318}
319
320/* Assumes the calling function takes care of locking */
321void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
322{
323 int i;
324
325 for (i = 0; i < hmux->nr_pads; i++) {
326 struct omap_device_pad *pad = &hmux->pads[i];
327 int flags, val = -EINVAL;
328
329 flags = pad->flags;
330
331 switch (state) {
332 case _HWMOD_STATE_ENABLED:
333 if (flags & OMAP_DEVICE_PAD_ENABLED)
334 break;
335 flags |= OMAP_DEVICE_PAD_ENABLED;
336 val = pad->enable;
337 pr_debug("%s: Enabling %s %x\n", __func__,
338 pad->name, val);
339 break;
340 case _HWMOD_STATE_IDLE:
341 if (!(flags & OMAP_DEVICE_PAD_REMUX))
342 break;
343 flags &= ~OMAP_DEVICE_PAD_ENABLED;
344 val = pad->idle;
345 pr_debug("%s: Idling %s %x\n", __func__,
346 pad->name, val);
347 break;
348 case _HWMOD_STATE_DISABLED:
349 default:
350 /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */
351 if (flags & OMAP_DEVICE_PAD_REMUX)
352 val = pad->off;
353 else
354 val = OMAP_MUX_MODE7;
355 flags &= ~OMAP_DEVICE_PAD_ENABLED;
356 pr_debug("%s: Disabling %s %x\n", __func__,
357 pad->name, val);
358 };
359
360 if (val >= 0) {
361 omap_mux_write(pad->partition, val,
362 pad->mux->reg_offset);
363 pad->flags = flags;
364 }
365 }
366}
367
187#ifdef CONFIG_DEBUG_FS 368#ifdef CONFIG_DEBUG_FS
188 369
189#define OMAP_MUX_MAX_NR_FLAGS 10 370#define OMAP_MUX_MAX_NR_FLAGS 10
@@ -248,13 +429,15 @@ static inline void omap_mux_decode(struct seq_file *s, u16 val)
248 } while (i-- > 0); 429 } while (i-- > 0);
249} 430}
250 431
251#define OMAP_MUX_DEFNAME_LEN 16 432#define OMAP_MUX_DEFNAME_LEN 32
252 433
253static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) 434static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
254{ 435{
436 struct omap_mux_partition *partition = s->private;
255 struct omap_mux_entry *e; 437 struct omap_mux_entry *e;
438 u8 omap_gen = omap_rev() >> 28;
256 439
257 list_for_each_entry(e, &muxmodes, node) { 440 list_for_each_entry(e, &partition->muxmodes, node) {
258 struct omap_mux *m = &e->mux; 441 struct omap_mux *m = &e->mux;
259 char m0_def[OMAP_MUX_DEFNAME_LEN]; 442 char m0_def[OMAP_MUX_DEFNAME_LEN];
260 char *m0_name = m->muxnames[0]; 443 char *m0_name = m->muxnames[0];
@@ -272,11 +455,16 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
272 } 455 }
273 m0_def[i] = toupper(m0_name[i]); 456 m0_def[i] = toupper(m0_name[i]);
274 } 457 }
275 val = omap_mux_read(m->reg_offset); 458 val = omap_mux_read(partition, m->reg_offset);
276 mode = val & OMAP_MUX_MODE7; 459 mode = val & OMAP_MUX_MODE7;
277 460 if (mode != 0)
278 seq_printf(s, "OMAP%i_MUX(%s, ", 461 seq_printf(s, "/* %s */\n", m->muxnames[mode]);
279 cpu_is_omap34xx() ? 3 : 0, m0_def); 462
463 /*
464 * XXX: Might be revisited to support differences accross
465 * same OMAP generation.
466 */
467 seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
280 omap_mux_decode(s, val); 468 omap_mux_decode(s, val);
281 seq_printf(s, "),\n"); 469 seq_printf(s, "),\n");
282 } 470 }
@@ -286,7 +474,7 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
286 474
287static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) 475static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
288{ 476{
289 return single_open(file, omap_mux_dbg_board_show, &inode->i_private); 477 return single_open(file, omap_mux_dbg_board_show, inode->i_private);
290} 478}
291 479
292static const struct file_operations omap_mux_dbg_board_fops = { 480static const struct file_operations omap_mux_dbg_board_fops = {
@@ -296,19 +484,43 @@ static const struct file_operations omap_mux_dbg_board_fops = {
296 .release = single_release, 484 .release = single_release,
297}; 485};
298 486
487static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
488{
489 struct omap_mux_partition *partition;
490
491 list_for_each_entry(partition, &mux_partitions, node) {
492 struct list_head *muxmodes = &partition->muxmodes;
493 struct omap_mux_entry *e;
494
495 list_for_each_entry(e, muxmodes, node) {
496 struct omap_mux *m = &e->mux;
497
498 if (m == mux)
499 return partition;
500 }
501 }
502
503 return NULL;
504}
505
299static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) 506static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
300{ 507{
301 struct omap_mux *m = s->private; 508 struct omap_mux *m = s->private;
509 struct omap_mux_partition *partition;
302 const char *none = "NA"; 510 const char *none = "NA";
303 u16 val; 511 u16 val;
304 int mode; 512 int mode;
305 513
306 val = omap_mux_read(m->reg_offset); 514 partition = omap_mux_get_partition(m);
515 if (!partition)
516 return 0;
517
518 val = omap_mux_read(partition, m->reg_offset);
307 mode = val & OMAP_MUX_MODE7; 519 mode = val & OMAP_MUX_MODE7;
308 520
309 seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n", 521 seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
310 m->muxnames[0], m->muxnames[mode], 522 m->muxnames[0], m->muxnames[mode],
311 mux_phys + m->reg_offset, m->reg_offset, val, 523 partition->phys + m->reg_offset, m->reg_offset, val,
312 m->balls[0] ? m->balls[0] : none, 524 m->balls[0] ? m->balls[0] : none,
313 m->balls[1] ? m->balls[1] : none); 525 m->balls[1] ? m->balls[1] : none);
314 seq_printf(s, "mode: "); 526 seq_printf(s, "mode: ");
@@ -330,14 +542,15 @@ static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
330#define OMAP_MUX_MAX_ARG_CHAR 7 542#define OMAP_MUX_MAX_ARG_CHAR 7
331 543
332static ssize_t omap_mux_dbg_signal_write(struct file *file, 544static ssize_t omap_mux_dbg_signal_write(struct file *file,
333 const char __user *user_buf, 545 const char __user *user_buf,
334 size_t count, loff_t *ppos) 546 size_t count, loff_t *ppos)
335{ 547{
336 char buf[OMAP_MUX_MAX_ARG_CHAR]; 548 char buf[OMAP_MUX_MAX_ARG_CHAR];
337 struct seq_file *seqf; 549 struct seq_file *seqf;
338 struct omap_mux *m; 550 struct omap_mux *m;
339 unsigned long val; 551 unsigned long val;
340 int buf_size, ret; 552 int buf_size, ret;
553 struct omap_mux_partition *partition;
341 554
342 if (count > OMAP_MUX_MAX_ARG_CHAR) 555 if (count > OMAP_MUX_MAX_ARG_CHAR)
343 return -EINVAL; 556 return -EINVAL;
@@ -358,7 +571,11 @@ static ssize_t omap_mux_dbg_signal_write(struct file *file,
358 seqf = file->private_data; 571 seqf = file->private_data;
359 m = seqf->private; 572 m = seqf->private;
360 573
361 omap_mux_write((u16)val, m->reg_offset); 574 partition = omap_mux_get_partition(m);
575 if (!partition)
576 return -ENODEV;
577
578 omap_mux_write(partition, (u16)val, m->reg_offset);
362 *ppos += count; 579 *ppos += count;
363 580
364 return count; 581 return count;
@@ -379,22 +596,38 @@ static const struct file_operations omap_mux_dbg_signal_fops = {
379 596
380static struct dentry *mux_dbg_dir; 597static struct dentry *mux_dbg_dir;
381 598
382static void __init omap_mux_dbg_init(void) 599static void __init omap_mux_dbg_create_entry(
600 struct omap_mux_partition *partition,
601 struct dentry *mux_dbg_dir)
383{ 602{
384 struct omap_mux_entry *e; 603 struct omap_mux_entry *e;
385 604
605 list_for_each_entry(e, &partition->muxmodes, node) {
606 struct omap_mux *m = &e->mux;
607
608 (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
609 m, &omap_mux_dbg_signal_fops);
610 }
611}
612
613static void __init omap_mux_dbg_init(void)
614{
615 struct omap_mux_partition *partition;
616 static struct dentry *mux_dbg_board_dir;
617
386 mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); 618 mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
387 if (!mux_dbg_dir) 619 if (!mux_dbg_dir)
388 return; 620 return;
389 621
390 (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir, 622 mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
391 NULL, &omap_mux_dbg_board_fops); 623 if (!mux_dbg_board_dir)
392 624 return;
393 list_for_each_entry(e, &muxmodes, node) {
394 struct omap_mux *m = &e->mux;
395 625
396 (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir, 626 list_for_each_entry(partition, &mux_partitions, node) {
397 m, &omap_mux_dbg_signal_fops); 627 omap_mux_dbg_create_entry(partition, mux_dbg_dir);
628 (void)debugfs_create_file(partition->name, S_IRUGO,
629 mux_dbg_board_dir, partition,
630 &omap_mux_dbg_board_fops);
398 } 631 }
399} 632}
400 633
@@ -421,23 +654,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 */ 654/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
422static int __init omap_mux_late_init(void) 655static int __init omap_mux_late_init(void)
423{ 656{
424 struct omap_mux_entry *e, *tmp; 657 struct omap_mux_partition *partition;
425 658
426 list_for_each_entry_safe(e, tmp, &muxmodes, node) { 659 list_for_each_entry(partition, &mux_partitions, node) {
427 struct omap_mux *m = &e->mux; 660 struct omap_mux_entry *e, *tmp;
428 u16 mode = omap_mux_read(m->reg_offset); 661 list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
662 struct omap_mux *m = &e->mux;
663 u16 mode = omap_mux_read(partition, m->reg_offset);
429 664
430 if (OMAP_MODE_GPIO(mode)) 665 if (OMAP_MODE_GPIO(mode))
431 continue; 666 continue;
432 667
433#ifndef CONFIG_DEBUG_FS 668#ifndef CONFIG_DEBUG_FS
434 mutex_lock(&muxmode_mutex); 669 mutex_lock(&muxmode_mutex);
435 list_del(&e->node); 670 list_del(&e->node);
436 mutex_unlock(&muxmode_mutex); 671 mutex_unlock(&muxmode_mutex);
437 omap_mux_free_names(m); 672 omap_mux_free_names(m);
438 kfree(m); 673 kfree(m);
439#endif 674#endif
440 675 }
441 } 676 }
442 677
443 omap_mux_dbg_init(); 678 omap_mux_dbg_init();
@@ -462,8 +697,8 @@ static void __init omap_mux_package_fixup(struct omap_mux *p,
462 s++; 697 s++;
463 } 698 }
464 if (!found) 699 if (!found)
465 printk(KERN_ERR "mux: Unknown entry offset 0x%x\n", 700 pr_err("%s: Unknown entry offset 0x%x\n", __func__,
466 p->reg_offset); 701 p->reg_offset);
467 p++; 702 p++;
468 } 703 }
469} 704}
@@ -487,8 +722,8 @@ static void __init omap_mux_package_init_balls(struct omap_ball *b,
487 s++; 722 s++;
488 } 723 }
489 if (!found) 724 if (!found)
490 printk(KERN_ERR "mux: Unknown ball offset 0x%x\n", 725 pr_err("%s: Unknown ball offset 0x%x\n", __func__,
491 b->reg_offset); 726 b->reg_offset);
492 b++; 727 b++;
493 } 728 }
494} 729}
@@ -554,7 +789,7 @@ static void __init omap_mux_set_cmdline_signals(void)
554} 789}
555 790
556static int __init omap_mux_copy_names(struct omap_mux *src, 791static int __init omap_mux_copy_names(struct omap_mux *src,
557 struct omap_mux *dst) 792 struct omap_mux *dst)
558{ 793{
559 int i; 794 int i;
560 795
@@ -592,51 +827,63 @@ free:
592 827
593#endif /* CONFIG_OMAP_MUX */ 828#endif /* CONFIG_OMAP_MUX */
594 829
595static u16 omap_mux_get_by_gpio(int gpio) 830static struct omap_mux *omap_mux_get_by_gpio(
831 struct omap_mux_partition *partition,
832 int gpio)
596{ 833{
597 struct omap_mux_entry *e; 834 struct omap_mux_entry *e;
598 u16 offset = OMAP_MUX_TERMINATOR; 835 struct omap_mux *ret = NULL;
599 836
600 list_for_each_entry(e, &muxmodes, node) { 837 list_for_each_entry(e, &partition->muxmodes, node) {
601 struct omap_mux *m = &e->mux; 838 struct omap_mux *m = &e->mux;
602 if (m->gpio == gpio) { 839 if (m->gpio == gpio) {
603 offset = m->reg_offset; 840 ret = m;
604 break; 841 break;
605 } 842 }
606 } 843 }
607 844
608 return offset; 845 return ret;
609} 846}
610 847
611/* Needed for dynamic muxing of GPIO pins for off-idle */ 848/* Needed for dynamic muxing of GPIO pins for off-idle */
612u16 omap_mux_get_gpio(int gpio) 849u16 omap_mux_get_gpio(int gpio)
613{ 850{
614 u16 offset; 851 struct omap_mux_partition *partition;
852 struct omap_mux *m;
615 853
616 offset = omap_mux_get_by_gpio(gpio); 854 list_for_each_entry(partition, &mux_partitions, node) {
617 if (offset == OMAP_MUX_TERMINATOR) { 855 m = omap_mux_get_by_gpio(partition, gpio);
618 printk(KERN_ERR "mux: Could not get gpio%i\n", gpio); 856 if (m)
619 return offset; 857 return omap_mux_read(partition, m->reg_offset);
620 } 858 }
621 859
622 return omap_mux_read(offset); 860 if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
861 pr_err("%s: Could not get gpio%i\n", __func__, gpio);
862
863 return OMAP_MUX_TERMINATOR;
623} 864}
624 865
625/* Needed for dynamic muxing of GPIO pins for off-idle */ 866/* Needed for dynamic muxing of GPIO pins for off-idle */
626void omap_mux_set_gpio(u16 val, int gpio) 867void omap_mux_set_gpio(u16 val, int gpio)
627{ 868{
628 u16 offset; 869 struct omap_mux_partition *partition;
870 struct omap_mux *m = NULL;
629 871
630 offset = omap_mux_get_by_gpio(gpio); 872 list_for_each_entry(partition, &mux_partitions, node) {
631 if (offset == OMAP_MUX_TERMINATOR) { 873 m = omap_mux_get_by_gpio(partition, gpio);
632 printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); 874 if (m) {
633 return; 875 omap_mux_write(partition, val, m->reg_offset);
876 return;
877 }
634 } 878 }
635 879
636 omap_mux_write(val, offset); 880 if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
881 pr_err("%s: Could not set gpio%i\n", __func__, gpio);
637} 882}
638 883
639static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) 884static struct omap_mux * __init omap_mux_list_add(
885 struct omap_mux_partition *partition,
886 struct omap_mux *src)
640{ 887{
641 struct omap_mux_entry *entry; 888 struct omap_mux_entry *entry;
642 struct omap_mux *m; 889 struct omap_mux *m;
@@ -656,7 +903,7 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
656#endif 903#endif
657 904
658 mutex_lock(&muxmode_mutex); 905 mutex_lock(&muxmode_mutex);
659 list_add_tail(&entry->node, &muxmodes); 906 list_add_tail(&entry->node, &partition->muxmodes);
660 mutex_unlock(&muxmode_mutex); 907 mutex_unlock(&muxmode_mutex);
661 908
662 return m; 909 return m;
@@ -667,7 +914,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 914 * the GPIO to mux offset mapping that is needed for dynamic muxing
668 * of GPIO pins for off-idle. 915 * of GPIO pins for off-idle.
669 */ 916 */
670static void __init omap_mux_init_list(struct omap_mux *superset) 917static void __init omap_mux_init_list(struct omap_mux_partition *partition,
918 struct omap_mux *superset)
671{ 919{
672 while (superset->reg_offset != OMAP_MUX_TERMINATOR) { 920 while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
673 struct omap_mux *entry; 921 struct omap_mux *entry;
@@ -679,15 +927,16 @@ static void __init omap_mux_init_list(struct omap_mux *superset)
679 } 927 }
680#else 928#else
681 /* Skip pins that are not muxed as GPIO by bootloader */ 929 /* Skip pins that are not muxed as GPIO by bootloader */
682 if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { 930 if (!OMAP_MODE_GPIO(omap_mux_read(partition,
931 superset->reg_offset))) {
683 superset++; 932 superset++;
684 continue; 933 continue;
685 } 934 }
686#endif 935#endif
687 936
688 entry = omap_mux_list_add(superset); 937 entry = omap_mux_list_add(partition, superset);
689 if (!entry) { 938 if (!entry) {
690 printk(KERN_ERR "mux: Could not add entry\n"); 939 pr_err("%s: Could not add entry\n", __func__);
691 return; 940 return;
692 } 941 }
693 superset++; 942 superset++;
@@ -706,10 +955,11 @@ static void omap_mux_init_package(struct omap_mux *superset,
706 omap_mux_package_init_balls(package_balls, superset); 955 omap_mux_package_init_balls(package_balls, superset);
707} 956}
708 957
709static void omap_mux_init_signals(struct omap_board_mux *board_mux) 958static void omap_mux_init_signals(struct omap_mux_partition *partition,
959 struct omap_board_mux *board_mux)
710{ 960{
711 omap_mux_set_cmdline_signals(); 961 omap_mux_set_cmdline_signals();
712 omap_mux_write_array(board_mux); 962 omap_mux_write_array(partition, board_mux);
713} 963}
714 964
715#else 965#else
@@ -720,34 +970,49 @@ static void omap_mux_init_package(struct omap_mux *superset,
720{ 970{
721} 971}
722 972
723static void omap_mux_init_signals(struct omap_board_mux *board_mux) 973static void omap_mux_init_signals(struct omap_mux_partition *partition,
974 struct omap_board_mux *board_mux)
724{ 975{
725} 976}
726 977
727#endif 978#endif
728 979
729int __init omap_mux_init(u32 mux_pbase, u32 mux_size, 980static 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 981
738 mux_phys = mux_pbase; 982int __init omap_mux_init(const char *name, u32 flags,
739 mux_base = ioremap(mux_pbase, mux_size); 983 u32 mux_pbase, u32 mux_size,
740 if (!mux_base) { 984 struct omap_mux *superset,
741 printk(KERN_ERR "mux: Could not ioremap\n"); 985 struct omap_mux *package_subset,
986 struct omap_board_mux *board_mux,
987 struct omap_ball *package_balls)
988{
989 struct omap_mux_partition *partition;
990
991 partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
992 if (!partition)
993 return -ENOMEM;
994
995 partition->name = name;
996 partition->flags = flags;
997 partition->size = mux_size;
998 partition->phys = mux_pbase;
999 partition->base = ioremap(mux_pbase, mux_size);
1000 if (!partition->base) {
1001 pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
1002 __func__, partition->phys);
742 return -ENODEV; 1003 return -ENODEV;
743 } 1004 }
744 1005
745 if (cpu_is_omap24xx()) 1006 INIT_LIST_HEAD(&partition->muxmodes);
746 omap_mux_flags = MUXABLE_GPIO_MODE3; 1007
1008 list_add_tail(&partition->node, &mux_partitions);
1009 mux_partitions_cnt++;
1010 pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
1011 mux_partitions_cnt, partition->name, partition->flags);
747 1012
748 omap_mux_init_package(superset, package_subset, package_balls); 1013 omap_mux_init_package(superset, package_subset, package_balls);
749 omap_mux_init_list(superset); 1014 omap_mux_init_list(partition, superset);
750 omap_mux_init_signals(board_mux); 1015 omap_mux_init_signals(partition, board_mux);
751 1016
752 return 0; 1017 return 0;
753} 1018}