2 * Copyright (C) ST-Ericsson SA 2010
5 * License terms: GNU General Public License (GPL), version 2.
9 * Mailbox nomenclature:
13 * ..........................
26 * .........................
29 #include <linux/init.h>
30 #include <linux/module.h>
31 #include <linux/device.h>
32 #include <linux/interrupt.h>
33 #include <linux/spinlock.h>
34 #include <linux/errno.h>
36 #include <linux/irq.h>
37 #include <linux/platform_device.h>
38 #include <linux/debugfs.h>
39 #include <linux/seq_file.h>
40 #include <linux/completion.h>
41 #include <mach/mbox-db5500.h>
43 #define MBOX_NAME "mbox"
45 #define MBOX_FIFO_DATA 0x000
46 #define MBOX_FIFO_ADD 0x004
47 #define MBOX_FIFO_REMOVE 0x008
48 #define MBOX_FIFO_THRES_FREE 0x00C
49 #define MBOX_FIFO_THRES_OCCUP 0x010
50 #define MBOX_FIFO_STATUS 0x014
52 #define MBOX_DISABLE_IRQ 0x4
53 #define MBOX_ENABLE_IRQ 0x0
56 /* Global list of all mailboxes */
57 static struct list_head mboxs = LIST_HEAD_INIT(mboxs);
59 static struct mbox *get_mbox_with_id(u8 id)
62 struct list_head *pos = &mboxs;
63 for (i = 0; i <= id; i++)
66 return (struct mbox *) list_entry(pos, struct mbox, list);
69 int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block)
73 spin_lock(&mbox->lock);
75 dev_dbg(&(mbox->pdev->dev),
76 "About to buffer 0x%X to mailbox 0x%X."
77 " ri = %d, wi = %d\n",
78 mbox_msg, (u32)mbox, mbox->read_index,
81 /* Check if write buffer is full */
82 while (((mbox->write_index + 1) % MBOX_BUF_SIZE) == mbox->read_index) {
84 dev_dbg(&(mbox->pdev->dev),
85 "Buffer full in non-blocking call! "
86 "Returning -ENOMEM!\n");
90 spin_unlock(&mbox->lock);
91 dev_dbg(&(mbox->pdev->dev),
92 "Buffer full in blocking call! Sleeping...\n");
93 mbox->client_blocked = 1;
94 wait_for_completion(&mbox->buffer_available);
95 dev_dbg(&(mbox->pdev->dev),
96 "Blocking send was woken up! Trying again...\n");
97 spin_lock(&mbox->lock);
100 mbox->buffer[mbox->write_index] = mbox_msg;
101 mbox->write_index = (mbox->write_index + 1) % MBOX_BUF_SIZE;
104 * Indicate that we want an IRQ as soon as there is a slot
107 writel(MBOX_ENABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
110 spin_unlock(&mbox->lock);
113 EXPORT_SYMBOL(mbox_send);
115 #if defined(CONFIG_DEBUG_FS)
117 * Expected input: <value> <nbr sends>
118 * Example: "echo 0xdeadbeef 4 > mbox-node" sends 0xdeadbeef 4 times
120 static ssize_t mbox_write_fifo(struct device *dev,
121 struct device_attribute *attr,
125 unsigned long mbox_mess;
126 unsigned long nbr_sends;
132 struct mbox *mbox = (struct mbox *) dev->platform_data;
134 strncpy((char *) &int_buf, buf, sizeof(int_buf));
135 token = (char *) &int_buf;
138 val = strsep(&token, " ");
139 if ((val == NULL) || (strict_strtoul(val, 16, &mbox_mess) != 0))
140 mbox_mess = 0xDEADBEEF;
142 val = strsep(&token, " ");
143 if ((val == NULL) || (strict_strtoul(val, 10, &nbr_sends) != 0))
146 dev_dbg(dev, "Will write 0x%lX %ld times using data struct at 0x%X\n",
147 mbox_mess, nbr_sends, (u32) mbox);
149 for (i = 0; i < nbr_sends; i++)
150 mbox_send(mbox, mbox_mess, true);
155 static ssize_t mbox_read_fifo(struct device *dev,
156 struct device_attribute *attr,
160 struct mbox *mbox = (struct mbox *) dev->platform_data;
162 if ((readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7) <= 0)
163 return sprintf(buf, "Mailbox is empty\n");
165 mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA);
166 writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE));
168 return sprintf(buf, "0x%X\n", mbox_value);
171 static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
173 static int mbox_show(struct seq_file *s, void *data)
175 struct list_head *pos;
178 list_for_each(pos, &mboxs) {
180 (struct mbox *) list_entry(pos, struct mbox, list);
183 "Unable to retrieve mailbox %d\n",
189 if ((m->virtbase_peer == NULL) || (m->virtbase_local == NULL)) {
190 seq_printf(s, "MAILBOX %d not setup or corrupt\n",
192 spin_unlock(&m->lock);
197 "===========================\n"
199 " PEER MAILBOX DUMP\n"
200 "---------------------------\n"
202 "Free Threshold: 0x%.2X (%d)\n"
203 "Occupied Threshold: 0x%.2X (%d)\n"
204 "Status: 0x%.2X (%d)\n"
205 " Free spaces (ot): %d (%d)\n"
206 " Occup spaces (ot): %d (%d)\n"
207 "===========================\n"
208 " LOCAL MAILBOX DUMP\n"
209 "---------------------------\n"
211 "Free Threshold: 0x%.2X (%d)\n"
212 "Occupied Threshold: 0x%.2X (%d)\n"
213 "Status: 0x%.2X (%d)\n"
214 " Free spaces (ot): %d (%d)\n"
215 " Occup spaces (ot): %d (%d)\n"
216 "===========================\n"
219 "===========================\n"
222 readl(m->virtbase_peer + MBOX_FIFO_DATA),
223 readl(m->virtbase_peer + MBOX_FIFO_DATA),
224 readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE),
225 readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE),
226 readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP),
227 readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP),
228 readl(m->virtbase_peer + MBOX_FIFO_STATUS),
229 readl(m->virtbase_peer + MBOX_FIFO_STATUS),
230 (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 4) & 0x7,
231 (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 7) & 0x1,
232 (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 0) & 0x7,
233 (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 3) & 0x1,
234 readl(m->virtbase_local + MBOX_FIFO_DATA),
235 readl(m->virtbase_local + MBOX_FIFO_DATA),
236 readl(m->virtbase_local + MBOX_FIFO_THRES_FREE),
237 readl(m->virtbase_local + MBOX_FIFO_THRES_FREE),
238 readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP),
239 readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP),
240 readl(m->virtbase_local + MBOX_FIFO_STATUS),
241 readl(m->virtbase_local + MBOX_FIFO_STATUS),
242 (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 4) & 0x7,
243 (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 7) & 0x1,
244 (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 0) & 0x7,
245 (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 3) & 0x1,
246 m->write_index, m->read_index);
248 spin_unlock(&m->lock);
254 static int mbox_open(struct inode *inode, struct file *file)
256 return single_open(file, mbox_show, NULL);
259 static const struct file_operations mbox_operations = {
260 .owner = THIS_MODULE,
264 .release = single_release,
268 static irqreturn_t mbox_irq(int irq, void *arg)
273 struct mbox *mbox = (struct mbox *) arg;
275 spin_lock(&mbox->lock);
277 dev_dbg(&(mbox->pdev->dev),
278 "mbox IRQ [%d] received. ri = %d, wi = %d\n",
279 irq, mbox->read_index, mbox->write_index);
282 * Check if we have any outgoing messages, and if there is space for
285 if (mbox->read_index != mbox->write_index) {
287 * Check by reading FREE for LOCAL since that indicates
290 nbr_free = (readl(mbox->virtbase_local + MBOX_FIFO_STATUS)
292 dev_dbg(&(mbox->pdev->dev),
293 "Status indicates %d empty spaces in the FIFO!\n",
296 while ((nbr_free > 0) &&
297 (mbox->read_index != mbox->write_index)) {
298 /* Write the message and latch it into the FIFO */
299 writel(mbox->buffer[mbox->read_index],
300 (mbox->virtbase_peer + MBOX_FIFO_DATA));
302 (mbox->virtbase_peer + MBOX_FIFO_ADD));
303 dev_dbg(&(mbox->pdev->dev),
304 "Wrote message 0x%X to addr 0x%X\n",
305 mbox->buffer[mbox->read_index],
306 (u32) (mbox->virtbase_peer + MBOX_FIFO_DATA));
310 (mbox->read_index + 1) % MBOX_BUF_SIZE;
314 * Check if we still want IRQ:s when there is free
317 if (mbox->read_index != mbox->write_index) {
318 dev_dbg(&(mbox->pdev->dev),
319 "Still have messages to send, but FIFO full. "
320 "Request IRQ again!\n");
321 writel(MBOX_ENABLE_IRQ,
322 mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
324 dev_dbg(&(mbox->pdev->dev),
325 "No more messages to send. "
326 "Do not request IRQ again!\n");
327 writel(MBOX_DISABLE_IRQ,
328 mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
332 * Check if we can signal any blocked clients that it is OK to
333 * start buffering again
335 if (mbox->client_blocked &&
336 (((mbox->write_index + 1) % MBOX_BUF_SIZE)
337 != mbox->read_index)) {
338 dev_dbg(&(mbox->pdev->dev),
339 "Waking up blocked client\n");
340 complete(&mbox->buffer_available);
341 mbox->client_blocked = 0;
345 /* Check if we have any incoming messages */
346 nbr_occup = readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7;
350 if (mbox->cb == NULL) {
351 dev_dbg(&(mbox->pdev->dev), "No receive callback registered, "
352 "leaving %d incoming messages in fifo!\n", nbr_occup);
356 /* Read and acknowledge the message */
357 mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA);
358 writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE));
360 /* Notify consumer of new mailbox message */
361 dev_dbg(&(mbox->pdev->dev), "Calling callback for message 0x%X!\n",
363 mbox->cb(mbox_value, mbox->client_data);
366 dev_dbg(&(mbox->pdev->dev), "Exit mbox IRQ. ri = %d, wi = %d\n",
367 mbox->read_index, mbox->write_index);
368 spin_unlock(&mbox->lock);
373 /* Setup is executed once for each mbox pair */
374 struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv)
376 struct resource *resource;
381 mbox = get_mbox_with_id(mbox_id);
383 dev_err(&(mbox->pdev->dev), "Incorrect mailbox id: %d!\n",
389 * Check if mailbox has been allocated to someone else,
390 * otherwise allocate it
392 if (mbox->allocated) {
393 dev_err(&(mbox->pdev->dev), "Mailbox number %d is busy!\n",
398 mbox->allocated = true;
400 dev_dbg(&(mbox->pdev->dev), "Initiating mailbox number %d: 0x%X...\n",
403 mbox->client_data = priv;
406 /* Get addr for peer mailbox and ioremap it */
407 resource = platform_get_resource_byname(mbox->pdev,
410 if (resource == NULL) {
411 dev_err(&(mbox->pdev->dev),
412 "Unable to retrieve mbox peer resource\n");
416 dev_dbg(&(mbox->pdev->dev),
417 "Resource name: %s start: 0x%X, end: 0x%X\n",
418 resource->name, resource->start, resource->end);
419 mbox->virtbase_peer =
420 ioremap(resource->start, resource->end - resource->start);
421 if (!mbox->virtbase_peer) {
422 dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n");
426 dev_dbg(&(mbox->pdev->dev),
427 "ioremapped peer physical: (0x%X-0x%X) to virtual: 0x%X\n",
428 resource->start, resource->end, (u32) mbox->virtbase_peer);
430 /* Get addr for local mailbox and ioremap it */
431 resource = platform_get_resource_byname(mbox->pdev,
434 if (resource == NULL) {
435 dev_err(&(mbox->pdev->dev),
436 "Unable to retrieve mbox local resource\n");
440 dev_dbg(&(mbox->pdev->dev),
441 "Resource name: %s start: 0x%X, end: 0x%X\n",
442 resource->name, resource->start, resource->end);
443 mbox->virtbase_local =
444 ioremap(resource->start, resource->end - resource->start);
445 if (!mbox->virtbase_local) {
446 dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n");
450 dev_dbg(&(mbox->pdev->dev),
451 "ioremapped local physical: (0x%X-0x%X) to virtual: 0x%X\n",
452 resource->start, resource->end, (u32) mbox->virtbase_peer);
454 init_completion(&mbox->buffer_available);
455 mbox->client_blocked = 0;
457 /* Get IRQ for mailbox and allocate it */
458 irq = platform_get_irq_byname(mbox->pdev, "mbox_irq");
460 dev_err(&(mbox->pdev->dev),
461 "Unable to retrieve mbox irq resource\n");
466 dev_dbg(&(mbox->pdev->dev), "Allocating irq %d...\n", irq);
467 res = request_irq(irq, mbox_irq, 0, mbox->name, (void *) mbox);
469 dev_err(&(mbox->pdev->dev),
470 "Unable to allocate mbox irq %d\n", irq);
475 /* Set up mailbox to not launch IRQ on free space in mailbox */
476 writel(MBOX_DISABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
479 * Set up mailbox to launch IRQ on new message if we have
480 * a callback set. If not, do not raise IRQ, but keep message
481 * in FIFO for manual retrieval
484 writel(MBOX_ENABLE_IRQ,
485 mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP);
487 writel(MBOX_DISABLE_IRQ,
488 mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP);
490 #if defined(CONFIG_DEBUG_FS)
491 res = device_create_file(&(mbox->pdev->dev), &dev_attr_fifo);
493 dev_warn(&(mbox->pdev->dev),
494 "Unable to create mbox sysfs entry");
496 (void) debugfs_create_file("mbox", S_IFREG | S_IRUGO, NULL,
497 NULL, &mbox_operations);
500 dev_info(&(mbox->pdev->dev),
501 "Mailbox driver with index %d initiated!\n", mbox_id);
506 EXPORT_SYMBOL(mbox_setup);
509 int __init mbox_probe(struct platform_device *pdev)
511 struct mbox local_mbox;
514 dev_dbg(&(pdev->dev), "Probing mailbox (pdev = 0x%X)...\n", (u32) pdev);
516 memset(&local_mbox, 0x0, sizeof(struct mbox));
518 /* Associate our mbox data with the platform device */
519 res = platform_device_add_data(pdev,
520 (void *) &local_mbox,
521 sizeof(struct mbox));
523 dev_err(&(pdev->dev),
524 "Unable to allocate driver platform data!\n");
528 mbox = (struct mbox *) pdev->dev.platform_data;
530 mbox->write_index = 0;
531 mbox->read_index = 0;
533 INIT_LIST_HEAD(&(mbox->list));
534 list_add_tail(&(mbox->list), &mboxs);
536 sprintf(mbox->name, "%s", MBOX_NAME);
537 spin_lock_init(&mbox->lock);
539 dev_info(&(pdev->dev), "Mailbox driver loaded\n");
545 static struct platform_driver mbox_driver = {
548 .owner = THIS_MODULE,
552 static int __init mbox_init(void)
554 return platform_driver_probe(&mbox_driver, mbox_probe);
557 module_init(mbox_init);
559 void __exit mbox_exit(void)
561 platform_driver_unregister(&mbox_driver);
564 module_exit(mbox_exit);
566 MODULE_LICENSE("GPL");
567 MODULE_DESCRIPTION("MBOX driver");