omap-mailbox.c 21.7 KB
Newer Older
1 2 3
/*
 * OMAP mailbox driver
 *
4
 * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
5
 * Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com
6
 *
7
 * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
8
 *          Suman Anna <s-anna@ti.com>
9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#include <linux/interrupt.h>
21 22
#include <linux/spinlock.h>
#include <linux/mutex.h>
23
#include <linux/slab.h>
24 25
#include <linux/kfifo.h>
#include <linux/err.h>
26
#include <linux/module.h>
27
#include <linux/of_device.h>
28 29 30
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/omap-mailbox.h>
31 32
#include <linux/mailbox_controller.h>
#include <linux/mailbox_client.h>
33

34 35
#include "mailbox.h"

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#define MAILBOX_REVISION		0x000
#define MAILBOX_MESSAGE(m)		(0x040 + 4 * (m))
#define MAILBOX_FIFOSTATUS(m)		(0x080 + 4 * (m))
#define MAILBOX_MSGSTATUS(m)		(0x0c0 + 4 * (m))

#define OMAP2_MAILBOX_IRQSTATUS(u)	(0x100 + 8 * (u))
#define OMAP2_MAILBOX_IRQENABLE(u)	(0x104 + 8 * (u))

#define OMAP4_MAILBOX_IRQSTATUS(u)	(0x104 + 0x10 * (u))
#define OMAP4_MAILBOX_IRQENABLE(u)	(0x108 + 0x10 * (u))
#define OMAP4_MAILBOX_IRQENABLE_CLR(u)	(0x10c + 0x10 * (u))

#define MAILBOX_IRQSTATUS(type, u)	(type ? OMAP4_MAILBOX_IRQSTATUS(u) : \
						OMAP2_MAILBOX_IRQSTATUS(u))
#define MAILBOX_IRQENABLE(type, u)	(type ? OMAP4_MAILBOX_IRQENABLE(u) : \
						OMAP2_MAILBOX_IRQENABLE(u))
#define MAILBOX_IRQDISABLE(type, u)	(type ? OMAP4_MAILBOX_IRQENABLE_CLR(u) \
						: OMAP2_MAILBOX_IRQENABLE(u))

#define MAILBOX_IRQ_NEWMSG(m)		(1 << (2 * (m)))
#define MAILBOX_IRQ_NOTFULL(m)		(1 << (2 * (m) + 1))

58 59 60 61
/* Interrupt register configuration types */
#define MBOX_INTR_CFG_TYPE1		0
#define MBOX_INTR_CFG_TYPE2		1

62 63 64 65 66 67 68
struct omap_mbox_fifo {
	unsigned long msg;
	unsigned long fifo_stat;
	unsigned long msg_stat;
	unsigned long irqenable;
	unsigned long irqstatus;
	unsigned long irqdisable;
69
	u32 intr_bit;
70 71 72 73 74 75 76 77 78 79
};

struct omap_mbox_queue {
	spinlock_t		lock;
	struct kfifo		fifo;
	struct work_struct	work;
	struct omap_mbox	*mbox;
	bool full;
};

80 81 82 83
struct omap_mbox_device {
	struct device *dev;
	struct mutex cfg_lock;
	void __iomem *mbox_base;
84
	u32 *irq_ctx;
85 86
	u32 num_users;
	u32 num_fifos;
87
	u32 intr_type;
88
	struct omap_mbox **mboxes;
89
	struct mbox_controller controller;
90 91 92
	struct list_head elem;
};

93 94 95 96 97 98 99 100 101 102
struct omap_mbox_fifo_info {
	int tx_id;
	int tx_usr;
	int tx_irq;

	int rx_id;
	int rx_usr;
	int rx_irq;

	const char *name;
103
	bool send_no_irq;
104 105
};

106 107 108
struct omap_mbox {
	const char		*name;
	int			irq;
109
	struct omap_mbox_queue	*rxq;
110
	struct device		*dev;
111
	struct omap_mbox_device *parent;
112 113 114
	struct omap_mbox_fifo	tx_fifo;
	struct omap_mbox_fifo	rx_fifo;
	u32			intr_type;
115
	struct mbox_chan	*chan;
116
	bool			send_no_irq;
117 118
};

119 120 121
/* global variables for the mailbox devices */
static DEFINE_MUTEX(omap_mbox_devices_lock);
static LIST_HEAD(omap_mbox_devices);
122

123 124 125 126
static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
module_param(mbox_kfifo_size, uint, S_IRUGO);
MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");

127 128 129 130 131 132 133 134
static struct omap_mbox *mbox_chan_to_omap_mbox(struct mbox_chan *chan)
{
	if (!chan || !chan->con_priv)
		return NULL;

	return (struct omap_mbox *)chan->con_priv;
}

135 136
static inline
unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
137
{
138
	return __raw_readl(mdev->mbox_base + ofs);
139 140
}

141 142
static inline
void mbox_write_reg(struct omap_mbox_device *mdev, u32 val, size_t ofs)
143
{
144
	__raw_writel(val, mdev->mbox_base + ofs);
145 146
}

147
/* Mailbox FIFO handle functions */
148
static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
149
{
150
	struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
151 152

	return (mbox_msg_t)mbox_read_reg(mbox->parent, fifo->msg);
153
}
154 155

static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
156
{
157
	struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
158

159
	mbox_write_reg(mbox->parent, msg, fifo->msg);
160
}
161 162

static int mbox_fifo_empty(struct omap_mbox *mbox)
163
{
164
	struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
165

166
	return (mbox_read_reg(mbox->parent, fifo->msg_stat) == 0);
167
}
168 169

static int mbox_fifo_full(struct omap_mbox *mbox)
170
{
171
	struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
172

173
	return mbox_read_reg(mbox->parent, fifo->fifo_stat);
174 175 176
}

/* Mailbox IRQ handle functions */
177
static void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
178
{
179 180 181 182
	struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
				&mbox->tx_fifo : &mbox->rx_fifo;
	u32 bit = fifo->intr_bit;
	u32 irqstatus = fifo->irqstatus;
183

184
	mbox_write_reg(mbox->parent, bit, irqstatus);
185 186

	/* Flush posted write for irq status to avoid spurious interrupts */
187
	mbox_read_reg(mbox->parent, irqstatus);
188
}
189 190

static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
191
{
192 193 194 195 196 197
	struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
				&mbox->tx_fifo : &mbox->rx_fifo;
	u32 bit = fifo->intr_bit;
	u32 irqenable = fifo->irqenable;
	u32 irqstatus = fifo->irqstatus;

198 199
	u32 enable = mbox_read_reg(mbox->parent, irqenable);
	u32 status = mbox_read_reg(mbox->parent, irqstatus);
200 201

	return (int)(enable & status & bit);
202 203
}

204
static void _omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
205
{
206 207 208 209 210
	u32 l;
	struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
				&mbox->tx_fifo : &mbox->rx_fifo;
	u32 bit = fifo->intr_bit;
	u32 irqenable = fifo->irqenable;
211

212
	l = mbox_read_reg(mbox->parent, irqenable);
213
	l |= bit;
214
	mbox_write_reg(mbox->parent, l, irqenable);
215 216
}

217
static void _omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
218
{
219 220 221 222
	struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
				&mbox->tx_fifo : &mbox->rx_fifo;
	u32 bit = fifo->intr_bit;
	u32 irqdisable = fifo->irqdisable;
223 224 225 226 227

	/*
	 * Read and update the interrupt configuration register for pre-OMAP4.
	 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
	 */
228
	if (!mbox->intr_type)
229
		bit = mbox_read_reg(mbox->parent, irqdisable) & ~bit;
230

231
	mbox_write_reg(mbox->parent, bit, irqdisable);
232 233
}

234
void omap_mbox_enable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
235
{
236
	struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
237

238 239
	if (WARN_ON(!mbox))
		return;
240

241 242 243
	_omap_mbox_enable_irq(mbox, irq);
}
EXPORT_SYMBOL(omap_mbox_enable_irq);
244

245 246 247 248 249 250 251 252
void omap_mbox_disable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
{
	struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);

	if (WARN_ON(!mbox))
		return;

	_omap_mbox_disable_irq(mbox, irq);
253
}
254
EXPORT_SYMBOL(omap_mbox_disable_irq);
255 256 257 258 259 260 261 262 263

/*
 * Message receiver(workqueue)
 */
static void mbox_rx_work(struct work_struct *work)
{
	struct omap_mbox_queue *mq =
			container_of(work, struct omap_mbox_queue, work);
	mbox_msg_t msg;
264 265 266 267 268
	int len;

	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
		WARN_ON(len != sizeof(msg));
269

270
		mbox_chan_received_data(mq->mbox->chan, (void *)msg);
271 272 273
		spin_lock_irq(&mq->lock);
		if (mq->full) {
			mq->full = false;
274
			_omap_mbox_enable_irq(mq->mbox, IRQ_RX);
275 276
		}
		spin_unlock_irq(&mq->lock);
277 278 279 280 281 282 283 284
	}
}

/*
 * Mailbox interrupt handler
 */
static void __mbox_tx_interrupt(struct omap_mbox *mbox)
{
285
	_omap_mbox_disable_irq(mbox, IRQ_TX);
286
	ack_mbox_irq(mbox, IRQ_TX);
287
	mbox_chan_txdone(mbox->chan, 0);
288 289 290 291
}

static void __mbox_rx_interrupt(struct omap_mbox *mbox)
{
292
	struct omap_mbox_queue *mq = mbox->rxq;
293
	mbox_msg_t msg;
294
	int len;
295 296

	while (!mbox_fifo_empty(mbox)) {
297
		if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
298
			_omap_mbox_disable_irq(mbox, IRQ_RX);
299
			mq->full = true;
300
			goto nomem;
301
		}
302 303 304

		msg = mbox_fifo_read(mbox);

305 306
		len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
		WARN_ON(len != sizeof(msg));
307 308 309 310
	}

	/* no more messages in the fifo. clear IRQ source. */
	ack_mbox_irq(mbox, IRQ_RX);
311
nomem:
Tejun Heo's avatar
Tejun Heo committed
312
	schedule_work(&mbox->rxq->work);
313 314 315 316
}

static irqreturn_t mbox_interrupt(int irq, void *p)
{
317
	struct omap_mbox *mbox = p;
318 319 320 321 322 323 324 325 326 327 328

	if (is_mbox_irq(mbox, IRQ_TX))
		__mbox_tx_interrupt(mbox);

	if (is_mbox_irq(mbox, IRQ_RX))
		__mbox_rx_interrupt(mbox);

	return IRQ_HANDLED;
}

static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
329
					void (*work)(struct work_struct *))
330 331 332
{
	struct omap_mbox_queue *mq;

333 334 335
	if (!work)
		return NULL;

336
	mq = kzalloc(sizeof(*mq), GFP_KERNEL);
337 338 339 340 341
	if (!mq)
		return NULL;

	spin_lock_init(&mq->lock);

342
	if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
343 344
		goto error;

345
	INIT_WORK(&mq->work, work);
346
	return mq;
347

348 349 350 351 352 353 354
error:
	kfree(mq);
	return NULL;
}

static void mbox_queue_free(struct omap_mbox_queue *q)
{
355
	kfifo_free(&q->fifo);
356 357 358
	kfree(q);
}

359
static int omap_mbox_startup(struct omap_mbox *mbox)
360
{
361
	int ret = 0;
362 363
	struct omap_mbox_queue *mq;

364 365 366 367 368 369 370 371 372 373 374 375
	mq = mbox_queue_alloc(mbox, mbox_rx_work);
	if (!mq)
		return -ENOMEM;
	mbox->rxq = mq;
	mq->mbox = mbox;

	ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
			  mbox->name, mbox);
	if (unlikely(ret)) {
		pr_err("failed to register mailbox interrupt:%d\n", ret);
		goto fail_request_irq;
	}
376

377 378 379
	if (mbox->send_no_irq)
		mbox->chan->txdone_method = TXDONE_BY_ACK;

380
	_omap_mbox_enable_irq(mbox, IRQ_RX);
381

382 383
	return 0;

384 385
fail_request_irq:
	mbox_queue_free(mbox->rxq);
386 387 388 389 390
	return ret;
}

static void omap_mbox_fini(struct omap_mbox *mbox)
{
391 392 393 394
	_omap_mbox_disable_irq(mbox, IRQ_RX);
	free_irq(mbox->irq, mbox);
	flush_work(&mbox->rxq->work);
	mbox_queue_free(mbox->rxq);
395 396
}

397 398
static struct omap_mbox *omap_mbox_device_find(struct omap_mbox_device *mdev,
					       const char *mbox_name)
399
{
400
	struct omap_mbox *_mbox, *mbox = NULL;
401 402
	struct omap_mbox **mboxes = mdev->mboxes;
	int i;
403

404
	if (!mboxes)
405
		return NULL;
406

407
	for (i = 0; (_mbox = mboxes[i]); i++) {
408
		if (!strcmp(_mbox->name, mbox_name)) {
409
			mbox = _mbox;
410
			break;
411 412
		}
	}
413 414 415
	return mbox;
}

416 417
struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
					    const char *chan_name)
418
{
419
	struct device *dev = cl->dev;
420 421
	struct omap_mbox *mbox = NULL;
	struct omap_mbox_device *mdev;
422 423
	struct mbox_chan *chan;
	unsigned long flags;
424 425
	int ret;

426 427 428 429 430 431 432 433 434
	if (!dev)
		return ERR_PTR(-ENODEV);

	if (dev->of_node) {
		pr_err("%s: please use mbox_request_channel(), this API is supported only for OMAP non-DT usage\n",
		       __func__);
		return ERR_PTR(-ENODEV);
	}

435 436
	mutex_lock(&omap_mbox_devices_lock);
	list_for_each_entry(mdev, &omap_mbox_devices, elem) {
437
		mbox = omap_mbox_device_find(mdev, chan_name);
438 439 440 441
		if (mbox)
			break;
	}
	mutex_unlock(&omap_mbox_devices_lock);
442

443
	if (!mbox || !mbox->chan)
444
		return ERR_PTR(-ENOENT);
445

446 447 448 449 450 451 452 453
	chan = mbox->chan;
	spin_lock_irqsave(&chan->lock, flags);
	chan->msg_free = 0;
	chan->msg_count = 0;
	chan->active_req = NULL;
	chan->cl = cl;
	init_completion(&chan->tx_complete);
	spin_unlock_irqrestore(&chan->lock, flags);
454

455
	ret = chan->mbox->ops->startup(chan);
456
	if (ret) {
457 458 459
		pr_err("Unable to startup the chan (%d)\n", ret);
		mbox_free_channel(chan);
		chan = ERR_PTR(ret);
460 461
	}

462
	return chan;
463
}
464
EXPORT_SYMBOL(omap_mbox_request_channel);
465

466 467
static struct class omap_mbox_class = { .name = "mbox", };

468
static int omap_mbox_register(struct omap_mbox_device *mdev)
469
{
470 471
	int ret;
	int i;
472
	struct omap_mbox **mboxes;
473

474
	if (!mdev || !mdev->mboxes)
475 476
		return -EINVAL;

477
	mboxes = mdev->mboxes;
478 479
	for (i = 0; mboxes[i]; i++) {
		struct omap_mbox *mbox = mboxes[i];
480

481 482
		mbox->dev = device_create(&omap_mbox_class, mdev->dev,
					0, mbox, "%s", mbox->name);
483 484 485 486 487
		if (IS_ERR(mbox->dev)) {
			ret = PTR_ERR(mbox->dev);
			goto err_out;
		}
	}
488 489 490 491 492

	mutex_lock(&omap_mbox_devices_lock);
	list_add(&mdev->elem, &omap_mbox_devices);
	mutex_unlock(&omap_mbox_devices_lock);

493
	ret = mbox_controller_register(&mdev->controller);
494

495
err_out:
496 497 498 499
	if (ret) {
		while (i--)
			device_unregister(mboxes[i]->dev);
	}
500 501 502
	return ret;
}

503
static int omap_mbox_unregister(struct omap_mbox_device *mdev)
504
{
505
	int i;
506
	struct omap_mbox **mboxes;
507

508
	if (!mdev || !mdev->mboxes)
509 510
		return -EINVAL;

511 512 513 514
	mutex_lock(&omap_mbox_devices_lock);
	list_del(&mdev->elem);
	mutex_unlock(&omap_mbox_devices_lock);

515 516
	mbox_controller_unregister(&mdev->controller);

517
	mboxes = mdev->mboxes;
518 519 520
	for (i = 0; mboxes[i]; i++)
		device_unregister(mboxes[i]->dev);
	return 0;
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
static int omap_mbox_chan_startup(struct mbox_chan *chan)
{
	struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
	struct omap_mbox_device *mdev = mbox->parent;
	int ret = 0;

	mutex_lock(&mdev->cfg_lock);
	pm_runtime_get_sync(mdev->dev);
	ret = omap_mbox_startup(mbox);
	if (ret)
		pm_runtime_put_sync(mdev->dev);
	mutex_unlock(&mdev->cfg_lock);
	return ret;
}

static void omap_mbox_chan_shutdown(struct mbox_chan *chan)
{
	struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
	struct omap_mbox_device *mdev = mbox->parent;

	mutex_lock(&mdev->cfg_lock);
	omap_mbox_fini(mbox);
	pm_runtime_put_sync(mdev->dev);
	mutex_unlock(&mdev->cfg_lock);
}

549
static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, void *data)
550 551 552
{
	int ret = -EBUSY;

553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569
	if (!mbox_fifo_full(mbox)) {
		_omap_mbox_enable_irq(mbox, IRQ_RX);
		mbox_fifo_write(mbox, (mbox_msg_t)data);
		ret = 0;
		_omap_mbox_disable_irq(mbox, IRQ_RX);

		/* we must read and ack the interrupt directly from here */
		mbox_fifo_read(mbox);
		ack_mbox_irq(mbox, IRQ_RX);
	}

	return ret;
}

static int omap_mbox_chan_send(struct omap_mbox *mbox, void *data)
{
	int ret = -EBUSY;
570 571 572 573 574 575 576 577 578 579 580

	if (!mbox_fifo_full(mbox)) {
		mbox_fifo_write(mbox, (mbox_msg_t)data);
		ret = 0;
	}

	/* always enable the interrupt */
	_omap_mbox_enable_irq(mbox, IRQ_TX);
	return ret;
}

581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
{
	struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
	int ret;

	if (!mbox)
		return -EINVAL;

	if (mbox->send_no_irq)
		ret = omap_mbox_chan_send_noirq(mbox, data);
	else
		ret = omap_mbox_chan_send(mbox, data);

	return ret;
}

597
static const struct mbox_chan_ops omap_mbox_chan_ops = {
598 599 600 601 602
	.startup        = omap_mbox_chan_startup,
	.send_data      = omap_mbox_chan_send_data,
	.shutdown       = omap_mbox_chan_shutdown,
};

603 604 605 606
#ifdef CONFIG_PM_SLEEP
static int omap_mbox_suspend(struct device *dev)
{
	struct omap_mbox_device *mdev = dev_get_drvdata(dev);
607
	u32 usr, fifo, reg;
608 609 610 611

	if (pm_runtime_status_suspended(dev))
		return 0;

612 613 614 615 616 617 618 619
	for (fifo = 0; fifo < mdev->num_fifos; fifo++) {
		if (mbox_read_reg(mdev, MAILBOX_MSGSTATUS(fifo))) {
			dev_err(mdev->dev, "fifo %d has unexpected unread messages\n",
				fifo);
			return -EBUSY;
		}
	}

620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
	for (usr = 0; usr < mdev->num_users; usr++) {
		reg = MAILBOX_IRQENABLE(mdev->intr_type, usr);
		mdev->irq_ctx[usr] = mbox_read_reg(mdev, reg);
	}

	return 0;
}

static int omap_mbox_resume(struct device *dev)
{
	struct omap_mbox_device *mdev = dev_get_drvdata(dev);
	u32 usr, reg;

	if (pm_runtime_status_suspended(dev))
		return 0;

	for (usr = 0; usr < mdev->num_users; usr++) {
		reg = MAILBOX_IRQENABLE(mdev->intr_type, usr);
		mbox_write_reg(mdev, mdev->irq_ctx[usr], reg);
	}

	return 0;
}
#endif

static const struct dev_pm_ops omap_mbox_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend, omap_mbox_resume)
};

649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
static const struct of_device_id omap_mailbox_of_match[] = {
	{
		.compatible	= "ti,omap2-mailbox",
		.data		= (void *)MBOX_INTR_CFG_TYPE1,
	},
	{
		.compatible	= "ti,omap3-mailbox",
		.data		= (void *)MBOX_INTR_CFG_TYPE1,
	},
	{
		.compatible	= "ti,omap4-mailbox",
		.data		= (void *)MBOX_INTR_CFG_TYPE2,
	},
	{
		/* end */
	},
};
MODULE_DEVICE_TABLE(of, omap_mailbox_of_match);

668 669 670 671 672 673 674 675 676 677
static struct mbox_chan *omap_mbox_of_xlate(struct mbox_controller *controller,
					    const struct of_phandle_args *sp)
{
	phandle phandle = sp->args[0];
	struct device_node *node;
	struct omap_mbox_device *mdev;
	struct omap_mbox *mbox;

	mdev = container_of(controller, struct omap_mbox_device, controller);
	if (WARN_ON(!mdev))
678
		return ERR_PTR(-EINVAL);
679 680 681 682 683

	node = of_find_node_by_phandle(phandle);
	if (!node) {
		pr_err("%s: could not find node phandle 0x%x\n",
		       __func__, phandle);
684
		return ERR_PTR(-ENODEV);
685 686 687 688
	}

	mbox = omap_mbox_device_find(mdev, node->name);
	of_node_put(node);
689
	return mbox ? mbox->chan : ERR_PTR(-ENOENT);
690 691
}

692 693 694 695
static int omap_mbox_probe(struct platform_device *pdev)
{
	struct resource *mem;
	int ret;
696
	struct mbox_chan *chnls;
697
	struct omap_mbox **list, *mbox, *mboxblk;
698
	struct omap_mbox_fifo_info *finfo, *finfoblk;
699
	struct omap_mbox_device *mdev;
700
	struct omap_mbox_fifo *fifo;
701 702 703 704 705 706
	struct device_node *node = pdev->dev.of_node;
	struct device_node *child;
	const struct of_device_id *match;
	u32 intr_type, info_count;
	u32 num_users, num_fifos;
	u32 tmp[3];
707 708 709
	u32 l;
	int i;

710 711
	if (!node) {
		pr_err("%s: only DT-based devices are supported\n", __func__);
712 713 714
		return -ENODEV;
	}

715 716 717 718
	match = of_match_device(omap_mailbox_of_match, &pdev->dev);
	if (!match)
		return -ENODEV;
	intr_type = (u32)match->data;
719

720 721
	if (of_property_read_u32(node, "ti,mbox-num-users", &num_users))
		return -ENODEV;
722

723 724
	if (of_property_read_u32(node, "ti,mbox-num-fifos", &num_fifos))
		return -ENODEV;
725

726 727 728 729
	info_count = of_get_available_child_count(node);
	if (!info_count) {
		dev_err(&pdev->dev, "no available mbox devices found\n");
		return -ENODEV;
730 731 732 733 734 735 736 737 738 739
	}

	finfoblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*finfoblk),
				GFP_KERNEL);
	if (!finfoblk)
		return -ENOMEM;

	finfo = finfoblk;
	child = NULL;
	for (i = 0; i < info_count; i++, finfo++) {
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
		child = of_get_next_available_child(node, child);
		ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
						 ARRAY_SIZE(tmp));
		if (ret)
			return ret;
		finfo->tx_id = tmp[0];
		finfo->tx_irq = tmp[1];
		finfo->tx_usr = tmp[2];

		ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
						 ARRAY_SIZE(tmp));
		if (ret)
			return ret;
		finfo->rx_id = tmp[0];
		finfo->rx_irq = tmp[1];
		finfo->rx_usr = tmp[2];

		finfo->name = child->name;

		if (of_find_property(child, "ti,mbox-send-noirq", NULL))
			finfo->send_no_irq = true;

762 763 764 765 766
		if (finfo->tx_id >= num_fifos || finfo->rx_id >= num_fifos ||
		    finfo->tx_usr >= num_users || finfo->rx_usr >= num_users)
			return -EINVAL;
	}

767 768 769 770 771 772 773 774 775
	mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
	if (!mdev)
		return -ENOMEM;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mdev->mbox_base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(mdev->mbox_base))
		return PTR_ERR(mdev->mbox_base);

776 777 778 779 780
	mdev->irq_ctx = devm_kzalloc(&pdev->dev, num_users * sizeof(u32),
				     GFP_KERNEL);
	if (!mdev->irq_ctx)
		return -ENOMEM;

781
	/* allocate one extra for marking end of list */
782
	list = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*list),
783 784 785 786
			    GFP_KERNEL);
	if (!list)
		return -ENOMEM;

787 788 789 790 791
	chnls = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*chnls),
			     GFP_KERNEL);
	if (!chnls)
		return -ENOMEM;

792
	mboxblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*mbox),
793 794 795 796 797
			       GFP_KERNEL);
	if (!mboxblk)
		return -ENOMEM;

	mbox = mboxblk;
798 799
	finfo = finfoblk;
	for (i = 0; i < info_count; i++, finfo++) {
800
		fifo = &mbox->tx_fifo;
801 802 803 804 805 806
		fifo->msg = MAILBOX_MESSAGE(finfo->tx_id);
		fifo->fifo_stat = MAILBOX_FIFOSTATUS(finfo->tx_id);
		fifo->intr_bit = MAILBOX_IRQ_NOTFULL(finfo->tx_id);
		fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->tx_usr);
		fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->tx_usr);
		fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->tx_usr);
807 808

		fifo = &mbox->rx_fifo;
809 810 811 812 813 814
		fifo->msg = MAILBOX_MESSAGE(finfo->rx_id);
		fifo->msg_stat =  MAILBOX_MSGSTATUS(finfo->rx_id);
		fifo->intr_bit = MAILBOX_IRQ_NEWMSG(finfo->rx_id);
		fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->rx_usr);
		fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->rx_usr);
		fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->rx_usr);
815

816
		mbox->send_no_irq = finfo->send_no_irq;
817 818
		mbox->intr_type = intr_type;

819
		mbox->parent = mdev;
820 821
		mbox->name = finfo->name;
		mbox->irq = platform_get_irq(pdev, finfo->tx_irq);
822 823
		if (mbox->irq < 0)
			return mbox->irq;
824 825
		mbox->chan = &chnls[i];
		chnls[i].con_priv = mbox;
826 827 828
		list[i] = mbox++;
	}

829 830
	mutex_init(&mdev->cfg_lock);
	mdev->dev = &pdev->dev;
831 832
	mdev->num_users = num_users;
	mdev->num_fifos = num_fifos;
833
	mdev->intr_type = intr_type;
834
	mdev->mboxes = list;
835 836 837 838 839 840 841 842

	/* OMAP does not have a Tx-Done IRQ, but rather a Tx-Ready IRQ */
	mdev->controller.txdone_irq = true;
	mdev->controller.dev = mdev->dev;
	mdev->controller.ops = &omap_mbox_chan_ops;
	mdev->controller.chans = chnls;
	mdev->controller.num_chans = info_count;
	mdev->controller.of_xlate = omap_mbox_of_xlate;
843
	ret = omap_mbox_register(mdev);
844 845 846
	if (ret)
		return ret;

847 848
	platform_set_drvdata(pdev, mdev);
	pm_runtime_enable(mdev->dev);
849

850
	ret = pm_runtime_get_sync(mdev->dev);
851
	if (ret < 0) {
852
		pm_runtime_put_noidle(mdev->dev);
853 854 855 856 857 858 859
		goto unregister;
	}

	/*
	 * just print the raw revision register, the format is not
	 * uniform across all SoCs
	 */
860 861
	l = mbox_read_reg(mdev, MAILBOX_REVISION);
	dev_info(mdev->dev, "omap mailbox rev 0x%x\n", l);
862

863
	ret = pm_runtime_put_sync(mdev->dev);
864 865 866
	if (ret < 0)
		goto unregister;

867
	devm_kfree(&pdev->dev, finfoblk);
868 869 870
	return 0;

unregister:
871 872
	pm_runtime_disable(mdev->dev);
	omap_mbox_unregister(mdev);
873 874 875 876 877
	return ret;
}

static int omap_mbox_remove(struct platform_device *pdev)
{
878 879 880 881
	struct omap_mbox_device *mdev = platform_get_drvdata(pdev);

	pm_runtime_disable(mdev->dev);
	omap_mbox_unregister(mdev);
882 883 884 885 886 887 888 889 890

	return 0;
}

static struct platform_driver omap_mbox_driver = {
	.probe	= omap_mbox_probe,
	.remove	= omap_mbox_remove,
	.driver	= {
		.name = "omap-mailbox",
891
		.pm = &omap_mbox_pm_ops,
892
		.of_match_table = of_match_ptr(omap_mailbox_of_match),
893 894
	},
};
895

896
static int __init omap_mbox_init(void)
897
{
898 899 900 901 902 903
	int err;

	err = class_register(&omap_mbox_class);
	if (err)
		return err;

904 905
	/* kfifo size sanity check: alignment and minimal size */
	mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
906 907
	mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
							sizeof(mbox_msg_t));
908

909
	return platform_driver_register(&omap_mbox_driver);
910
}
911
subsys_initcall(omap_mbox_init);
912

913
static void __exit omap_mbox_exit(void)
914
{
915
	platform_driver_unregister(&omap_mbox_driver);
916
	class_unregister(&omap_mbox_class);
917
}
918
module_exit(omap_mbox_exit);
919

920 921
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
922 923
MODULE_AUTHOR("Toshihiro Kobayashi");
MODULE_AUTHOR("Hiroshi DOYU");