mux.c 26.0 KB
Newer Older
1 2 3
/*
 * linux/arch/arm/mach-omap2/mux.c
 *
4
 * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
5
 *
6
 * Copyright (C) 2004 - 2010 Texas Instruments Inc.
T
Tony Lindgren 已提交
7
 * Copyright (C) 2003 - 2008 Nokia Corporation
8
 *
T
Tony Lindgren 已提交
9
 * Written by Tony Lindgren
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
26
#include <linux/kernel.h>
27
#include <linux/init.h>
28
#include <linux/io.h>
29
#include <linux/list.h>
30
#include <linux/slab.h>
31 32 33 34
#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
35 36
#include <linux/irq.h>
#include <linux/interrupt.h>
37

38

39 40
#include <plat/omap_hwmod.h>

41
#include "control.h"
42
#include "mux.h"
43
#include "prm.h"
44

45 46 47
#define OMAP_MUX_BASE_OFFSET		0x30	/* Offset from CTRL_BASE */
#define OMAP_MUX_BASE_SZ		0x5ca

48 49 50 51 52
struct omap_mux_entry {
	struct omap_mux		mux;
	struct list_head	node;
};

53 54 55 56 57 58 59 60 61 62 63
static LIST_HEAD(mux_partitions);
static DEFINE_MUTEX(muxmode_mutex);

struct omap_mux_partition *omap_mux_get(const char *name)
{
	struct omap_mux_partition *partition;

	list_for_each_entry(partition, &mux_partitions, node) {
		if (!strcmp(name, partition->name))
			return partition;
	}
64

65 66 67 68
	return NULL;
}

u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
69
{
70 71
	if (partition->flags & OMAP_MUX_REG_8BIT)
		return __raw_readb(partition->base + reg);
72
	else
73
		return __raw_readw(partition->base + reg);
74 75
}

76 77
void omap_mux_write(struct omap_mux_partition *partition, u16 val,
			   u16 reg)
78
{
79 80
	if (partition->flags & OMAP_MUX_REG_8BIT)
		__raw_writeb(val, partition->base + reg);
81
	else
82
		__raw_writew(val, partition->base + reg);
83
}
84

85 86
void omap_mux_write_array(struct omap_mux_partition *partition,
				 struct omap_board_mux *board_mux)
87
{
88 89 90
	if (!board_mux)
		return;

91 92 93
	while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
		omap_mux_write(partition, board_mux->value,
			       board_mux->reg_offset);
94 95 96 97
		board_mux++;
	}
}

98 99 100 101
#ifdef CONFIG_OMAP_MUX

static char *omap_mux_options;

102 103
static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
				      int gpio, int val)
104 105
{
	struct omap_mux_entry *e;
106
	struct omap_mux *gpio_mux = NULL;
107 108
	u16 old_mode;
	u16 mux_mode;
109
	int found = 0;
110
	struct list_head *muxmodes = &partition->muxmodes;
111 112 113 114

	if (!gpio)
		return -EINVAL;

115
	list_for_each_entry(e, muxmodes, node) {
116 117
		struct omap_mux *m = &e->mux;
		if (gpio == m->gpio) {
118
			gpio_mux = m;
119 120 121 122
			found++;
		}
	}

123
	if (found == 0) {
124
		pr_err("%s: Could not set gpio%i\n", __func__, gpio);
125 126
		return -ENODEV;
	}
127 128

	if (found > 1) {
129
		pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
130
			found, gpio);
131 132 133
		return -EINVAL;
	}

134
	old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
135
	mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
136
	if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
137 138 139
		mux_mode |= OMAP_MUX_MODE3;
	else
		mux_mode |= OMAP_MUX_MODE4;
140
	pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
141
		 gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
142
	omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
143

144
	return 0;
145 146
}

147
int __init omap_mux_init_gpio(int gpio, int val)
148 149 150 151 152 153 154 155 156 157 158 159 160
{
	struct omap_mux_partition *partition;
	int ret;

	list_for_each_entry(partition, &mux_partitions, node) {
		ret = _omap_mux_init_gpio(partition, gpio, val);
		if (!ret)
			return ret;
	}

	return -ENODEV;
}

161 162 163
static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
					const char *muxname,
					struct omap_mux **found_mux)
164
{
T
Tony Lindgren 已提交
165
	struct omap_mux *mux = NULL;
166
	struct omap_mux_entry *e;
167
	const char *mode_name;
168
	int found = 0, found_mode = 0, mode0_len = 0;
169
	struct list_head *muxmodes = &partition->muxmodes;
170 171 172

	mode_name = strchr(muxname, '.');
	if (mode_name) {
173
		mode0_len = strlen(muxname) - strlen(mode_name);
174 175 176 177 178
		mode_name++;
	} else {
		mode_name = muxname;
	}

179
	list_for_each_entry(e, muxmodes, node) {
T
Tony Lindgren 已提交
180
		char *m0_entry;
181 182
		int i;

T
Tony Lindgren 已提交
183 184 185
		mux = &e->mux;
		m0_entry = mux->muxnames[0];

186 187
		/* First check for full name in mode0.muxmode format */
		if (mode0_len && strncmp(muxname, m0_entry, mode0_len))
188 189
			continue;

190
		/* Then check for muxmode only */
191
		for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
T
Tony Lindgren 已提交
192
			char *mode_cur = mux->muxnames[i];
193 194 195 196 197

			if (!mode_cur)
				continue;

			if (!strcmp(mode_name, mode_cur)) {
T
Tony Lindgren 已提交
198
				*found_mux = mux;
199
				found++;
T
Tony Lindgren 已提交
200
				found_mode = i;
201 202 203 204
			}
		}
	}

T
Tony Lindgren 已提交
205 206 207
	if (found == 1) {
		return found_mode;
	}
208 209

	if (found > 1) {
210
		pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
211
		       found, muxname);
212 213 214
		return -EINVAL;
	}

T
Tony Lindgren 已提交
215
	pr_err("%s: Could not find signal %s\n", __func__, muxname);
216 217 218 219

	return -ENODEV;
}

220
static int __init
T
Tony Lindgren 已提交
221 222 223
omap_mux_get_by_name(const char *muxname,
			struct omap_mux_partition **found_partition,
			struct omap_mux **found_mux)
224 225 226 227
{
	struct omap_mux_partition *partition;

	list_for_each_entry(partition, &mux_partitions, node) {
T
Tony Lindgren 已提交
228 229 230 231 232 233 234 235 236
		struct omap_mux *mux = NULL;
		int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux);
		if (mux_mode < 0)
			continue;

		*found_partition = partition;
		*found_mux = mux;

		return mux_mode;
237 238 239
	}

	return -ENODEV;
T
Tony Lindgren 已提交
240
}
241

242
int __init omap_mux_init_signal(const char *muxname, int val)
T
Tony Lindgren 已提交
243 244 245 246 247 248 249
{
	struct omap_mux_partition *partition = NULL;
	struct omap_mux *mux = NULL;
	u16 old_mode;
	int mux_mode;

	mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
250
	if (mux_mode < 0 || !mux)
T
Tony Lindgren 已提交
251 252 253 254 255 256 257 258 259
		return mux_mode;

	old_mode = omap_mux_read(partition, mux->reg_offset);
	mux_mode |= val;
	pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
			 __func__, muxname, old_mode, mux_mode);
	omap_mux_write(partition, mux_mode, mux->reg_offset);

	return 0;
260 261
}

262 263 264 265
struct omap_hwmod_mux_info * __init
omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
{
	struct omap_hwmod_mux_info *hmux;
266
	int i, nr_pads_dynamic = 0;
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309

	if (!bpads || nr_pads < 1)
		return NULL;

	hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
	if (!hmux)
		goto err1;

	hmux->nr_pads = nr_pads;

	hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
				nr_pads, GFP_KERNEL);
	if (!hmux->pads)
		goto err2;

	for (i = 0; i < hmux->nr_pads; i++) {
		struct omap_mux_partition *partition;
		struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
		struct omap_mux *mux;
		int mux_mode;

		mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
		if (mux_mode < 0)
			goto err3;
		if (!pad->partition)
			pad->partition = partition;
		if (!pad->mux)
			pad->mux = mux;

		pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
		if (!pad->name) {
			int j;

			for (j = i - 1; j >= 0; j--)
				kfree(hmux->pads[j].name);
			goto err3;
		}
		strcpy(pad->name, bpad->name);

		pad->flags = bpad->flags;
		pad->enable = bpad->enable;
		pad->idle = bpad->idle;
		pad->off = bpad->off;
310

311 312
		if (pad->flags &
		    (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP))
313 314
			nr_pads_dynamic++;

315 316 317
		pr_debug("%s: Initialized %s\n", __func__, pad->name);
	}

318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
	if (!nr_pads_dynamic)
		return hmux;

	/*
	 * Add pads that need dynamic muxing into a separate list
	 */

	hmux->nr_pads_dynamic = nr_pads_dynamic;
	hmux->pads_dynamic = kzalloc(sizeof(struct omap_device_pad *) *
					nr_pads_dynamic, GFP_KERNEL);
	if (!hmux->pads_dynamic) {
		pr_err("%s: Could not allocate dynamic pads\n", __func__);
		return hmux;
	}

	nr_pads_dynamic = 0;
	for (i = 0; i < hmux->nr_pads; i++) {
		struct omap_device_pad *pad = &hmux->pads[i];

337 338
		if (pad->flags &
		    (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) {
339 340 341 342 343 344 345
			pr_debug("%s: pad %s tagged dynamic\n",
					__func__, pad->name);
			hmux->pads_dynamic[nr_pads_dynamic] = pad;
			nr_pads_dynamic++;
		}
	}

346 347 348 349 350 351 352 353 354 355 356 357
	return hmux;

err3:
	kfree(hmux->pads);
err2:
	kfree(hmux);
err1:
	pr_err("%s: Could not allocate device mux entry\n", __func__);

	return NULL;
}

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
/**
 * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
 * @hmux: Pads for a hwmod
 * @mpu_irqs: MPU irq array for a hwmod
 *
 * Scans the wakeup status of pads for a single hwmod.  If an irq
 * array is defined for this mux, the parser will call the registered
 * ISRs for corresponding pads, otherwise the parser will stop at the
 * first wakeup active pad and return.  Returns true if there is a
 * pending and non-served wakeup event for the mux, otherwise false.
 */
static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
		struct omap_hwmod_irq_info *mpu_irqs)
{
	int i, irq;
	unsigned int val;
	u32 handled_irqs = 0;

	for (i = 0; i < hmux->nr_pads_dynamic; i++) {
		struct omap_device_pad *pad = hmux->pads_dynamic[i];

		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) ||
		    !(pad->idle & OMAP_WAKEUP_EN))
			continue;

		val = omap_mux_read(pad->partition, pad->mux->reg_offset);
		if (!(val & OMAP_WAKEUP_EVENT))
			continue;

		if (!hmux->irqs)
			return true;

		irq = hmux->irqs[i];
		/* make sure we only handle each irq once */
		if (handled_irqs & 1 << irq)
			continue;

		handled_irqs |= 1 << irq;

		generic_handle_irq(mpu_irqs[irq].irq);
	}

	return false;
}

/**
 * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
 *
 * Checks a single hwmod for every wakeup capable pad to see if there is an
 * active wakeup event. If this is the case, call the corresponding ISR.
 */
static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
{
	if (!oh->mux || !oh->mux->enabled)
		return 0;
	if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
		generic_handle_irq(oh->mpu_irqs[0].irq);
	return 0;
}

/**
 * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
 *
 * Calls a function for each registered omap_hwmod to check
 * pad wakeup statuses.
 */
static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
{
	omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
	return IRQ_HANDLED;
}

430 431 432 433 434
/* Assumes the calling function takes care of locking */
void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
{
	int i;

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
	/* Runtime idling of dynamic pads */
	if (state == _HWMOD_STATE_IDLE && hmux->enabled) {
		for (i = 0; i < hmux->nr_pads_dynamic; i++) {
			struct omap_device_pad *pad = hmux->pads_dynamic[i];
			int val = -EINVAL;

			val = pad->idle;
			omap_mux_write(pad->partition, val,
					pad->mux->reg_offset);
		}

		return;
	}

	/* Runtime enabling of dynamic pads */
450 451
	if ((state == _HWMOD_STATE_ENABLED) && hmux->pads_dynamic
					&& hmux->enabled) {
452 453 454 455 456 457 458 459 460
		for (i = 0; i < hmux->nr_pads_dynamic; i++) {
			struct omap_device_pad *pad = hmux->pads_dynamic[i];
			int val = -EINVAL;

			val = pad->enable;
			omap_mux_write(pad->partition, val,
					pad->mux->reg_offset);
		}

461
		return;
462 463 464
	}

	/* Enabling or disabling of all pads */
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
	for (i = 0; i < hmux->nr_pads; i++) {
		struct omap_device_pad *pad = &hmux->pads[i];
		int flags, val = -EINVAL;

		flags = pad->flags;

		switch (state) {
		case _HWMOD_STATE_ENABLED:
			val = pad->enable;
			pr_debug("%s: Enabling %s %x\n", __func__,
					pad->name, val);
			break;
		case _HWMOD_STATE_DISABLED:
			/* Use safe mode unless OMAP_DEVICE_PAD_REMUX */
			if (flags & OMAP_DEVICE_PAD_REMUX)
				val = pad->off;
			else
				val = OMAP_MUX_MODE7;
			pr_debug("%s: Disabling %s %x\n", __func__,
					pad->name, val);
485 486 487 488
			break;
		default:
			/* Nothing to be done */
			break;
489 490 491 492 493 494 495 496
		};

		if (val >= 0) {
			omap_mux_write(pad->partition, val,
					pad->mux->reg_offset);
			pad->flags = flags;
		}
	}
497 498 499 500 501

	if (state == _HWMOD_STATE_ENABLED)
		hmux->enabled = true;
	else
		hmux->enabled = false;
502 503
}

504 505 506 507 508 509 510 511 512 513 514 515 516
#ifdef CONFIG_DEBUG_FS

#define OMAP_MUX_MAX_NR_FLAGS	10
#define OMAP_MUX_TEST_FLAG(val, mask)				\
	if (((val) & (mask)) == (mask)) {			\
		i++;						\
		flags[i] =  #mask;				\
	}

/* REVISIT: Add checking for non-optimal mux settings */
static inline void omap_mux_decode(struct seq_file *s, u16 val)
{
	char *flags[OMAP_MUX_MAX_NR_FLAGS];
517
	char mode[sizeof("OMAP_MUX_MODE") + 1];
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
	int i = -1;

	sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
	i++;
	flags[i] = mode;

	OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
	if (val & OMAP_OFF_EN) {
		if (!(val & OMAP_OFFOUT_EN)) {
			if (!(val & OMAP_OFF_PULL_UP)) {
				OMAP_MUX_TEST_FLAG(val,
					OMAP_PIN_OFF_INPUT_PULLDOWN);
			} else {
				OMAP_MUX_TEST_FLAG(val,
					OMAP_PIN_OFF_INPUT_PULLUP);
			}
		} else {
			if (!(val & OMAP_OFFOUT_VAL)) {
				OMAP_MUX_TEST_FLAG(val,
					OMAP_PIN_OFF_OUTPUT_LOW);
			} else {
				OMAP_MUX_TEST_FLAG(val,
					OMAP_PIN_OFF_OUTPUT_HIGH);
			}
		}
	}

	if (val & OMAP_INPUT_EN) {
		if (val & OMAP_PULL_ENA) {
			if (!(val & OMAP_PULL_UP)) {
				OMAP_MUX_TEST_FLAG(val,
					OMAP_PIN_INPUT_PULLDOWN);
			} else {
				OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
			}
		} else {
			OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
		}
	} else {
		i++;
		flags[i] = "OMAP_PIN_OUTPUT";
	}

	do {
		seq_printf(s, "%s", flags[i]);
		if (i > 0)
			seq_printf(s, " | ");
	} while (i-- > 0);
}

568
#define OMAP_MUX_DEFNAME_LEN	32
569 570 571

static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
{
572
	struct omap_mux_partition *partition = s->private;
573
	struct omap_mux_entry *e;
574
	u8 omap_gen = omap_rev() >> 28;
575

576
	list_for_each_entry(e, &partition->muxmodes, node) {
577 578 579 580 581 582 583 584 585
		struct omap_mux *m = &e->mux;
		char m0_def[OMAP_MUX_DEFNAME_LEN];
		char *m0_name = m->muxnames[0];
		u16 val;
		int i, mode;

		if (!m0_name)
			continue;

586
		/* REVISIT: Needs to be updated if mode0 names get longer */
587 588 589 590 591 592 593
		for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
			if (m0_name[i] == '\0') {
				m0_def[i] = m0_name[i];
				break;
			}
			m0_def[i] = toupper(m0_name[i]);
		}
594
		val = omap_mux_read(partition, m->reg_offset);
595
		mode = val & OMAP_MUX_MODE7;
596 597 598 599
		if (mode != 0)
			seq_printf(s, "/* %s */\n", m->muxnames[mode]);

		/*
L
Lucas De Marchi 已提交
600
		 * XXX: Might be revisited to support differences across
601 602 603
		 * same OMAP generation.
		 */
		seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
604 605 606 607 608 609 610 611 612
		omap_mux_decode(s, val);
		seq_printf(s, "),\n");
	}

	return 0;
}

static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
{
613
	return single_open(file, omap_mux_dbg_board_show, inode->i_private);
614 615 616 617 618 619 620 621 622
}

static const struct file_operations omap_mux_dbg_board_fops = {
	.open		= omap_mux_dbg_board_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
{
	struct omap_mux_partition *partition;

	list_for_each_entry(partition, &mux_partitions, node) {
		struct list_head *muxmodes = &partition->muxmodes;
		struct omap_mux_entry *e;

		list_for_each_entry(e, muxmodes, node) {
			struct omap_mux *m = &e->mux;

			if (m == mux)
				return partition;
		}
	}

	return NULL;
}

642 643 644
static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
{
	struct omap_mux *m = s->private;
645
	struct omap_mux_partition *partition;
646 647 648 649
	const char *none = "NA";
	u16 val;
	int mode;

650 651 652 653 654
	partition = omap_mux_get_partition(m);
	if (!partition)
		return 0;

	val = omap_mux_read(partition, m->reg_offset);
655 656
	mode = val & OMAP_MUX_MODE7;

657
	seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
658
			m->muxnames[0], m->muxnames[mode],
659
			partition->phys + m->reg_offset, m->reg_offset, val,
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
			m->balls[0] ? m->balls[0] : none,
			m->balls[1] ? m->balls[1] : none);
	seq_printf(s, "mode: ");
	omap_mux_decode(s, val);
	seq_printf(s, "\n");
	seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
			m->muxnames[0] ? m->muxnames[0] : none,
			m->muxnames[1] ? m->muxnames[1] : none,
			m->muxnames[2] ? m->muxnames[2] : none,
			m->muxnames[3] ? m->muxnames[3] : none,
			m->muxnames[4] ? m->muxnames[4] : none,
			m->muxnames[5] ? m->muxnames[5] : none,
			m->muxnames[6] ? m->muxnames[6] : none,
			m->muxnames[7] ? m->muxnames[7] : none);

	return 0;
}

#define OMAP_MUX_MAX_ARG_CHAR  7

static ssize_t omap_mux_dbg_signal_write(struct file *file,
681 682
					 const char __user *user_buf,
					 size_t count, loff_t *ppos)
683 684 685 686 687 688
{
	char buf[OMAP_MUX_MAX_ARG_CHAR];
	struct seq_file *seqf;
	struct omap_mux *m;
	unsigned long val;
	int buf_size, ret;
689
	struct omap_mux_partition *partition;
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709

	if (count > OMAP_MUX_MAX_ARG_CHAR)
		return -EINVAL;

	memset(buf, 0, sizeof(buf));
	buf_size = min(count, sizeof(buf) - 1);

	if (copy_from_user(buf, user_buf, buf_size))
		return -EFAULT;

	ret = strict_strtoul(buf, 0x10, &val);
	if (ret < 0)
		return ret;

	if (val > 0xffff)
		return -EINVAL;

	seqf = file->private_data;
	m = seqf->private;

710 711 712 713 714
	partition = omap_mux_get_partition(m);
	if (!partition)
		return -ENODEV;

	omap_mux_write(partition, (u16)val, m->reg_offset);
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
	*ppos += count;

	return count;
}

static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
{
	return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
}

static const struct file_operations omap_mux_dbg_signal_fops = {
	.open		= omap_mux_dbg_signal_open,
	.read		= seq_read,
	.write		= omap_mux_dbg_signal_write,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static struct dentry *mux_dbg_dir;

735 736 737
static void __init omap_mux_dbg_create_entry(
				struct omap_mux_partition *partition,
				struct dentry *mux_dbg_dir)
738 739 740
{
	struct omap_mux_entry *e;

741 742 743
	list_for_each_entry(e, &partition->muxmodes, node) {
		struct omap_mux *m = &e->mux;

744
		(void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir,
745 746 747 748 749 750 751 752 753
					  m, &omap_mux_dbg_signal_fops);
	}
}

static void __init omap_mux_dbg_init(void)
{
	struct omap_mux_partition *partition;
	static struct dentry *mux_dbg_board_dir;

754 755 756 757
	mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
	if (!mux_dbg_dir)
		return;

758 759 760
	mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
	if (!mux_dbg_board_dir)
		return;
761

762 763 764 765 766
	list_for_each_entry(partition, &mux_partitions, node) {
		omap_mux_dbg_create_entry(partition, mux_dbg_dir);
		(void)debugfs_create_file(partition->name, S_IRUGO,
					  mux_dbg_board_dir, partition,
					  &omap_mux_dbg_board_fops);
767 768 769 770 771 772 773 774 775
	}
}

#else
static inline void omap_mux_dbg_init(void)
{
}
#endif	/* CONFIG_DEBUG_FS */

776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
static void __init omap_mux_free_names(struct omap_mux *m)
{
	int i;

	for (i = 0; i < OMAP_MUX_NR_MODES; i++)
		kfree(m->muxnames[i]);

#ifdef CONFIG_DEBUG_FS
	for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
		kfree(m->balls[i]);
#endif

}

/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
791
int __init omap_mux_late_init(void)
792
{
793
	struct omap_mux_partition *partition;
794
	int ret;
795

796 797 798 799 800
	list_for_each_entry(partition, &mux_partitions, node) {
		struct omap_mux_entry *e, *tmp;
		list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
			struct omap_mux *m = &e->mux;
			u16 mode = omap_mux_read(partition, m->reg_offset);
801

802 803
			if (OMAP_MODE_GPIO(mode))
				continue;
804 805

#ifndef CONFIG_DEBUG_FS
806 807 808 809 810
			mutex_lock(&muxmode_mutex);
			list_del(&e->node);
			mutex_unlock(&muxmode_mutex);
			omap_mux_free_names(m);
			kfree(m);
811
#endif
812
		}
813 814
	}

815 816 817 818 819 820 821
	ret = request_irq(omap_prcm_event_to_irq("io"),
		omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
			"hwmod_io", omap_mux_late_init);

	if (ret)
		pr_warning("mux: Failed to setup hwmod io irq %d\n", ret);

822 823
	omap_mux_dbg_init();

824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
	return 0;
}

static void __init omap_mux_package_fixup(struct omap_mux *p,
					struct omap_mux *superset)
{
	while (p->reg_offset !=  OMAP_MUX_TERMINATOR) {
		struct omap_mux *s = superset;
		int found = 0;

		while (s->reg_offset != OMAP_MUX_TERMINATOR) {
			if (s->reg_offset == p->reg_offset) {
				*s = *p;
				found++;
				break;
			}
			s++;
		}
		if (!found)
843
			pr_err("%s: Unknown entry offset 0x%x\n", __func__,
844
			       p->reg_offset);
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
		p++;
	}
}

#ifdef CONFIG_DEBUG_FS

static void __init omap_mux_package_init_balls(struct omap_ball *b,
				struct omap_mux *superset)
{
	while (b->reg_offset != OMAP_MUX_TERMINATOR) {
		struct omap_mux *s = superset;
		int found = 0;

		while (s->reg_offset != OMAP_MUX_TERMINATOR) {
			if (s->reg_offset == b->reg_offset) {
				s->balls[0] = b->balls[0];
				s->balls[1] = b->balls[1];
				found++;
				break;
			}
			s++;
		}
		if (!found)
868
			pr_err("%s: Unknown ball offset 0x%x\n", __func__,
869
			       b->reg_offset);
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
		b++;
	}
}

#else	/* CONFIG_DEBUG_FS */

static inline void omap_mux_package_init_balls(struct omap_ball *b,
					struct omap_mux *superset)
{
}

#endif	/* CONFIG_DEBUG_FS */

static int __init omap_mux_setup(char *options)
{
	if (!options)
		return 0;

	omap_mux_options = options;

	return 1;
}
__setup("omap_mux=", omap_mux_setup);

/*
 * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
 * cmdline options only override the bootloader values.
 * During development, please enable CONFIG_DEBUG_FS, and use the
 * signal specific entries under debugfs.
 */
static void __init omap_mux_set_cmdline_signals(void)
{
	char *options, *next_opt, *token;

	if (!omap_mux_options)
		return;

907
	options = kstrdup(omap_mux_options, GFP_KERNEL);
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
	if (!options)
		return;

	next_opt = options;

	while ((token = strsep(&next_opt, ",")) != NULL) {
		char *keyval, *name;
		unsigned long val;

		keyval = token;
		name = strsep(&keyval, "=");
		if (name) {
			int res;

			res = strict_strtoul(keyval, 0x10, &val);
			if (res < 0)
				continue;

			omap_mux_init_signal(name, (u16)val);
		}
	}

	kfree(options);
}

static int __init omap_mux_copy_names(struct omap_mux *src,
934
				      struct omap_mux *dst)
935 936 937 938 939
{
	int i;

	for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
		if (src->muxnames[i]) {
940 941
			dst->muxnames[i] = kstrdup(src->muxnames[i],
						   GFP_KERNEL);
942 943 944 945 946 947 948 949
			if (!dst->muxnames[i])
				goto free;
		}
	}

#ifdef CONFIG_DEBUG_FS
	for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
		if (src->balls[i]) {
950
			dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL);
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
			if (!dst->balls[i])
				goto free;
		}
	}
#endif

	return 0;

free:
	omap_mux_free_names(dst);
	return -ENOMEM;

}

#endif	/* CONFIG_OMAP_MUX */

967 968 969
static struct omap_mux *omap_mux_get_by_gpio(
				struct omap_mux_partition *partition,
				int gpio)
970 971
{
	struct omap_mux_entry *e;
972
	struct omap_mux *ret = NULL;
973

974
	list_for_each_entry(e, &partition->muxmodes, node) {
975 976
		struct omap_mux *m = &e->mux;
		if (m->gpio == gpio) {
977
			ret = m;
978 979 980 981
			break;
		}
	}

982
	return ret;
983 984 985 986 987
}

/* Needed for dynamic muxing of GPIO pins for off-idle */
u16 omap_mux_get_gpio(int gpio)
{
988
	struct omap_mux_partition *partition;
989
	struct omap_mux *m = NULL;
990

991 992 993 994
	list_for_each_entry(partition, &mux_partitions, node) {
		m = omap_mux_get_by_gpio(partition, gpio);
		if (m)
			return omap_mux_read(partition, m->reg_offset);
995 996
	}

997
	if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
998
		pr_err("%s: Could not get gpio%i\n", __func__, gpio);
999 1000

	return OMAP_MUX_TERMINATOR;
1001 1002 1003 1004 1005
}

/* Needed for dynamic muxing of GPIO pins for off-idle */
void omap_mux_set_gpio(u16 val, int gpio)
{
1006 1007
	struct omap_mux_partition *partition;
	struct omap_mux *m = NULL;
1008

1009 1010 1011 1012 1013 1014
	list_for_each_entry(partition, &mux_partitions, node) {
		m = omap_mux_get_by_gpio(partition, gpio);
		if (m) {
			omap_mux_write(partition, val, m->reg_offset);
			return;
		}
1015 1016
	}

1017
	if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
1018
		pr_err("%s: Could not set gpio%i\n", __func__, gpio);
1019 1020
}

1021 1022 1023
static struct omap_mux * __init omap_mux_list_add(
					struct omap_mux_partition *partition,
					struct omap_mux *src)
1024 1025 1026 1027 1028 1029 1030 1031 1032
{
	struct omap_mux_entry *entry;
	struct omap_mux *m;

	entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
	if (!entry)
		return NULL;

	m = &entry->mux;
1033
	entry->mux = *src;
1034 1035 1036 1037 1038 1039 1040 1041 1042

#ifdef CONFIG_OMAP_MUX
	if (omap_mux_copy_names(src, m)) {
		kfree(entry);
		return NULL;
	}
#endif

	mutex_lock(&muxmode_mutex);
1043
	list_add_tail(&entry->node, &partition->muxmodes);
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
	mutex_unlock(&muxmode_mutex);

	return m;
}

/*
 * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
 * the GPIO to mux offset mapping that is needed for dynamic muxing
 * of GPIO pins for off-idle.
 */
1054 1055
static void __init omap_mux_init_list(struct omap_mux_partition *partition,
				      struct omap_mux *superset)
1056 1057 1058 1059
{
	while (superset->reg_offset !=  OMAP_MUX_TERMINATOR) {
		struct omap_mux *entry;

1060 1061
#ifdef CONFIG_OMAP_MUX
		if (!superset->muxnames || !superset->muxnames[0]) {
1062 1063 1064
			superset++;
			continue;
		}
1065 1066
#else
		/* Skip pins that are not muxed as GPIO by bootloader */
1067 1068
		if (!OMAP_MODE_GPIO(omap_mux_read(partition,
				    superset->reg_offset))) {
T
Tony Lindgren 已提交
1069 1070 1071 1072 1073
			superset++;
			continue;
		}
#endif

1074
		entry = omap_mux_list_add(partition, superset);
1075
		if (!entry) {
1076
			pr_err("%s: Could not add entry\n", __func__);
1077 1078 1079 1080 1081 1082
			return;
		}
		superset++;
	}
}

1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
#ifdef CONFIG_OMAP_MUX

static void omap_mux_init_package(struct omap_mux *superset,
				  struct omap_mux *package_subset,
				  struct omap_ball *package_balls)
{
	if (package_subset)
		omap_mux_package_fixup(package_subset, superset);
	if (package_balls)
		omap_mux_package_init_balls(package_balls, superset);
}

1095 1096
static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
					 struct omap_board_mux *board_mux)
1097 1098
{
	omap_mux_set_cmdline_signals();
1099
	omap_mux_write_array(partition, board_mux);
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109
}

#else

static void omap_mux_init_package(struct omap_mux *superset,
				  struct omap_mux *package_subset,
				  struct omap_ball *package_balls)
{
}

1110 1111
static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
					 struct omap_board_mux *board_mux)
1112 1113 1114 1115 1116
{
}

#endif

1117
static u32 mux_partitions_cnt;
1118

1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
int __init omap_mux_init(const char *name, u32 flags,
			 u32 mux_pbase, u32 mux_size,
			 struct omap_mux *superset,
			 struct omap_mux *package_subset,
			 struct omap_board_mux *board_mux,
			 struct omap_ball *package_balls)
{
	struct omap_mux_partition *partition;

	partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
	if (!partition)
		return -ENOMEM;

	partition->name = name;
	partition->flags = flags;
	partition->size = mux_size;
	partition->phys = mux_pbase;
	partition->base = ioremap(mux_pbase, mux_size);
	if (!partition->base) {
1138 1139
		pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
			__func__, partition->phys);
1140
		kfree(partition);
1141 1142 1143
		return -ENODEV;
	}

1144 1145 1146 1147
	INIT_LIST_HEAD(&partition->muxmodes);

	list_add_tail(&partition->node, &mux_partitions);
	mux_partitions_cnt++;
1148
	pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
1149
		mux_partitions_cnt, partition->name, partition->flags);
1150

1151
	omap_mux_init_package(superset, package_subset, package_balls);
1152 1153
	omap_mux_init_list(partition, superset);
	omap_mux_init_signals(partition, board_mux);
T
Tony Lindgren 已提交
1154

1155 1156 1157
	return 0;
}