blob: 6519716571cb442ab40384431a65108fbb8310e5 [file] [log] [blame]
Hiroshi DOYU340a6142006-12-07 15:43:59 -08001/*
Hiroshi DOYU733ecc52009-03-23 18:07:23 -07002 * Mailbox reservation modules for OMAP2/3
Hiroshi DOYU340a6142006-12-07 15:43:59 -08003 *
Hiroshi DOYU733ecc52009-03-23 18:07:23 -07004 * Copyright (C) 2006-2009 Nokia Corporation
Hiroshi DOYU340a6142006-12-07 15:43:59 -08005 * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Hiroshi DOYU733ecc52009-03-23 18:07:23 -07006 * and Paul Mundt
Hiroshi DOYU340a6142006-12-07 15:43:59 -08007 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/platform_device.h>
Russell Kingfced80c2008-09-06 12:10:45 +010017#include <linux/io.h>
Tony Lindgrence491cf2009-10-20 09:40:47 -070018#include <plat/mailbox.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010019#include <mach/irqs.h>
Hiroshi DOYU340a6142006-12-07 15:43:59 -080020
C A Subramaniam5f00ec62009-11-22 10:11:22 -080021#define DRV_NAME "omap2-mailbox"
22
Hiroshi DOYU733ecc52009-03-23 18:07:23 -070023#define MAILBOX_REVISION 0x000
24#define MAILBOX_SYSCONFIG 0x010
25#define MAILBOX_SYSSTATUS 0x014
26#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
27#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
28#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
29#define MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
30#define MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
31
C A Subramaniam5f00ec62009-11-22 10:11:22 -080032#define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 10 * (u))
33#define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 10 * (u))
34#define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 10 * (u))
35
36#define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m)))
37#define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1))
Hiroshi DOYU340a6142006-12-07 15:43:59 -080038
Hiroshi DOYU1ffe6272009-09-24 16:23:09 -070039/* SYSCONFIG: register bit definition */
40#define AUTOIDLE (1 << 0)
41#define SOFTRESET (1 << 1)
42#define SMARTIDLE (2 << 3)
Suman Annaa6a60222010-01-26 16:55:29 -060043#define OMAP4_SOFTRESET (1 << 0)
Hiroshi DOYU1ffe6272009-09-24 16:23:09 -070044
45/* SYSSTATUS: register bit definition */
46#define RESETDONE (1 << 0)
47
Hiroshi DOYUc75ee752009-03-23 18:07:26 -070048#define MBOX_REG_SIZE 0x120
C A Subramaniam5f00ec62009-11-22 10:11:22 -080049
50#define OMAP4_MBOX_REG_SIZE 0x130
51
Hiroshi DOYUc75ee752009-03-23 18:07:26 -070052#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32))
C A Subramaniam5f00ec62009-11-22 10:11:22 -080053#define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32))
Hiroshi DOYUc75ee752009-03-23 18:07:26 -070054
Hiroshi DOYU6c20a682009-03-23 18:07:23 -070055static void __iomem *mbox_base;
Hiroshi DOYU340a6142006-12-07 15:43:59 -080056
Hiroshi DOYU340a6142006-12-07 15:43:59 -080057struct omap_mbox2_fifo {
58 unsigned long msg;
59 unsigned long fifo_stat;
60 unsigned long msg_stat;
61};
62
63struct omap_mbox2_priv {
64 struct omap_mbox2_fifo tx_fifo;
65 struct omap_mbox2_fifo rx_fifo;
66 unsigned long irqenable;
67 unsigned long irqstatus;
68 u32 newmsg_bit;
69 u32 notfull_bit;
C A Subramaniam5f00ec62009-11-22 10:11:22 -080070 u32 ctx[OMAP4_MBOX_NR_REGS];
71 unsigned long irqdisable;
Hiroshi DOYU340a6142006-12-07 15:43:59 -080072};
73
74static struct clk *mbox_ick_handle;
75
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +030076static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
77 omap_mbox_type_t irq);
78
Hiroshi DOYU6c20a682009-03-23 18:07:23 -070079static inline unsigned int mbox_read_reg(size_t ofs)
Hiroshi DOYU340a6142006-12-07 15:43:59 -080080{
Hiroshi DOYU6c20a682009-03-23 18:07:23 -070081 return __raw_readl(mbox_base + ofs);
Hiroshi DOYU340a6142006-12-07 15:43:59 -080082}
83
Hiroshi DOYU6c20a682009-03-23 18:07:23 -070084static inline void mbox_write_reg(u32 val, size_t ofs)
Hiroshi DOYU340a6142006-12-07 15:43:59 -080085{
Hiroshi DOYU6c20a682009-03-23 18:07:23 -070086 __raw_writel(val, mbox_base + ofs);
Hiroshi DOYU340a6142006-12-07 15:43:59 -080087}
88
89/* Mailbox H/W preparations */
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +030090static int omap2_mbox_startup(struct omap_mbox *mbox)
Hiroshi DOYU340a6142006-12-07 15:43:59 -080091{
Hiroshi DOYU1ffe6272009-09-24 16:23:09 -070092 u32 l;
93 unsigned long timeout;
Hiroshi DOYU340a6142006-12-07 15:43:59 -080094
95 mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
96 if (IS_ERR(mbox_ick_handle)) {
Felipe Balbi0cd7e1c2010-02-15 10:03:33 -080097 printk(KERN_ERR "Could not get mailboxes_ick: %ld\n",
C A Subramaniam5f00ec62009-11-22 10:11:22 -080098 PTR_ERR(mbox_ick_handle));
99 return PTR_ERR(mbox_ick_handle);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800100 }
101 clk_enable(mbox_ick_handle);
102
Suman Annaa6a60222010-01-26 16:55:29 -0600103 if (cpu_is_omap44xx()) {
104 mbox_write_reg(OMAP4_SOFTRESET, MAILBOX_SYSCONFIG);
105 timeout = jiffies + msecs_to_jiffies(20);
106 do {
107 l = mbox_read_reg(MAILBOX_SYSCONFIG);
108 if (!(l & OMAP4_SOFTRESET))
109 break;
110 } while (!time_after(jiffies, timeout));
Hiroshi DOYU1ffe6272009-09-24 16:23:09 -0700111
Suman Annaa6a60222010-01-26 16:55:29 -0600112 if (l & OMAP4_SOFTRESET) {
113 pr_err("Can't take mailbox out of reset\n");
114 return -ENODEV;
115 }
116 } else {
117 mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG);
118 timeout = jiffies + msecs_to_jiffies(20);
119 do {
120 l = mbox_read_reg(MAILBOX_SYSSTATUS);
121 if (l & RESETDONE)
122 break;
123 } while (!time_after(jiffies, timeout));
124
125 if (!(l & RESETDONE)) {
126 pr_err("Can't take mailbox out of reset\n");
127 return -ENODEV;
128 }
Hiroshi DOYU1ffe6272009-09-24 16:23:09 -0700129 }
130
Hiroshi DOYU94fc58c2009-03-23 18:07:24 -0700131 l = mbox_read_reg(MAILBOX_REVISION);
132 pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
133
Hiroshi DOYU1ffe6272009-09-24 16:23:09 -0700134 l = SMARTIDLE | AUTOIDLE;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800135 mbox_write_reg(l, MAILBOX_SYSCONFIG);
136
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300137 omap2_mbox_enable_irq(mbox, IRQ_RX);
138
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800139 return 0;
140}
141
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300142static void omap2_mbox_shutdown(struct omap_mbox *mbox)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800143{
144 clk_disable(mbox_ick_handle);
145 clk_put(mbox_ick_handle);
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800146 mbox_ick_handle = NULL;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800147}
148
149/* Mailbox FIFO handle functions */
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300150static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800151{
152 struct omap_mbox2_fifo *fifo =
153 &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
154 return (mbox_msg_t) mbox_read_reg(fifo->msg);
155}
156
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300157static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800158{
159 struct omap_mbox2_fifo *fifo =
160 &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
161 mbox_write_reg(msg, fifo->msg);
162}
163
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300164static int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800165{
166 struct omap_mbox2_fifo *fifo =
167 &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
168 return (mbox_read_reg(fifo->msg_stat) == 0);
169}
170
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300171static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800172{
173 struct omap_mbox2_fifo *fifo =
174 &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800175 return mbox_read_reg(fifo->fifo_stat);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800176}
177
178/* Mailbox IRQ handle functions */
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300179static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800180 omap_mbox_type_t irq)
181{
182 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
183 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
184
185 l = mbox_read_reg(p->irqenable);
186 l |= bit;
187 mbox_write_reg(l, p->irqenable);
188}
189
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300190static void omap2_mbox_disable_irq(struct omap_mbox *mbox,
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800191 omap_mbox_type_t irq)
192{
193 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
194 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800195 l = mbox_read_reg(p->irqdisable);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800196 l &= ~bit;
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800197 mbox_write_reg(l, p->irqdisable);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800198}
199
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300200static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800201 omap_mbox_type_t irq)
202{
203 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
204 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
205
206 mbox_write_reg(bit, p->irqstatus);
Hiroshi DOYU88288802009-09-24 16:23:10 -0700207
208 /* Flush posted write for irq status to avoid spurious interrupts */
209 mbox_read_reg(p->irqstatus);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800210}
211
Hiroshi DOYUbfbdcf82007-07-30 14:04:04 +0300212static int omap2_mbox_is_irq(struct omap_mbox *mbox,
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800213 omap_mbox_type_t irq)
214{
215 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
216 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
217 u32 enable = mbox_read_reg(p->irqenable);
218 u32 status = mbox_read_reg(p->irqstatus);
219
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800220 return (int)(enable & status & bit);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800221}
222
Hiroshi DOYUc75ee752009-03-23 18:07:26 -0700223static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
224{
225 int i;
226 struct omap_mbox2_priv *p = mbox->priv;
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800227 int nr_regs;
228 if (cpu_is_omap44xx())
229 nr_regs = OMAP4_MBOX_NR_REGS;
230 else
231 nr_regs = MBOX_NR_REGS;
232 for (i = 0; i < nr_regs; i++) {
Hiroshi DOYUc75ee752009-03-23 18:07:26 -0700233 p->ctx[i] = mbox_read_reg(i * sizeof(u32));
234
235 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
236 i, p->ctx[i]);
237 }
238}
239
240static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
241{
242 int i;
243 struct omap_mbox2_priv *p = mbox->priv;
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800244 int nr_regs;
245 if (cpu_is_omap44xx())
246 nr_regs = OMAP4_MBOX_NR_REGS;
247 else
248 nr_regs = MBOX_NR_REGS;
249 for (i = 0; i < nr_regs; i++) {
Hiroshi DOYUc75ee752009-03-23 18:07:26 -0700250 mbox_write_reg(p->ctx[i], i * sizeof(u32));
251
252 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
253 i, p->ctx[i]);
254 }
255}
256
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800257static struct omap_mbox_ops omap2_mbox_ops = {
258 .type = OMAP_MBOX_TYPE2,
259 .startup = omap2_mbox_startup,
260 .shutdown = omap2_mbox_shutdown,
261 .fifo_read = omap2_mbox_fifo_read,
262 .fifo_write = omap2_mbox_fifo_write,
263 .fifo_empty = omap2_mbox_fifo_empty,
264 .fifo_full = omap2_mbox_fifo_full,
265 .enable_irq = omap2_mbox_enable_irq,
266 .disable_irq = omap2_mbox_disable_irq,
267 .ack_irq = omap2_mbox_ack_irq,
268 .is_irq = omap2_mbox_is_irq,
Hiroshi DOYUc75ee752009-03-23 18:07:26 -0700269 .save_ctx = omap2_mbox_save_ctx,
270 .restore_ctx = omap2_mbox_restore_ctx,
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800271};
272
273/*
274 * MAILBOX 0: ARM -> DSP,
275 * MAILBOX 1: ARM <- DSP.
276 * MAILBOX 2: ARM -> IVA,
277 * MAILBOX 3: ARM <- IVA.
278 */
279
280/* FIXME: the following structs should be filled automatically by the user id */
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800281/* DSP */
282static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
283 .tx_fifo = {
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700284 .msg = MAILBOX_MESSAGE(0),
285 .fifo_stat = MAILBOX_FIFOSTATUS(0),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800286 },
287 .rx_fifo = {
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700288 .msg = MAILBOX_MESSAGE(1),
289 .msg_stat = MAILBOX_MSGSTATUS(1),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800290 },
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700291 .irqenable = MAILBOX_IRQENABLE(0),
292 .irqstatus = MAILBOX_IRQSTATUS(0),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800293 .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
294 .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800295 .irqdisable = MAILBOX_IRQENABLE(0),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800296};
297
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800298
299
300/* OMAP4 specific data structure. Use the cpu_is_omap4xxx()
301to use this*/
302static struct omap_mbox2_priv omap2_mbox_1_priv = {
303 .tx_fifo = {
304 .msg = MAILBOX_MESSAGE(0),
305 .fifo_stat = MAILBOX_FIFOSTATUS(0),
306 },
307 .rx_fifo = {
308 .msg = MAILBOX_MESSAGE(1),
309 .msg_stat = MAILBOX_MSGSTATUS(1),
310 },
311 .irqenable = OMAP4_MAILBOX_IRQENABLE(0),
312 .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0),
313 .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
314 .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
315 .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0),
316};
317
318struct omap_mbox mbox_1_info = {
319 .name = "mailbox-1",
320 .ops = &omap2_mbox_ops,
321 .priv = &omap2_mbox_1_priv,
322};
323EXPORT_SYMBOL(mbox_1_info);
324
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800325struct omap_mbox mbox_dsp_info = {
326 .name = "dsp",
327 .ops = &omap2_mbox_ops,
328 .priv = &omap2_mbox_dsp_priv,
329};
330EXPORT_SYMBOL(mbox_dsp_info);
331
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800332static struct omap_mbox2_priv omap2_mbox_2_priv = {
333 .tx_fifo = {
334 .msg = MAILBOX_MESSAGE(3),
335 .fifo_stat = MAILBOX_FIFOSTATUS(3),
336 },
337 .rx_fifo = {
338 .msg = MAILBOX_MESSAGE(2),
339 .msg_stat = MAILBOX_MSGSTATUS(2),
340 },
341 .irqenable = OMAP4_MAILBOX_IRQENABLE(0),
342 .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0),
343 .notfull_bit = MAILBOX_IRQ_NOTFULL(3),
344 .newmsg_bit = MAILBOX_IRQ_NEWMSG(2),
345 .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0),
346};
347
348struct omap_mbox mbox_2_info = {
349 .name = "mailbox-2",
350 .ops = &omap2_mbox_ops,
351 .priv = &omap2_mbox_2_priv,
352};
353EXPORT_SYMBOL(mbox_2_info);
354
355
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700356#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800357static struct omap_mbox2_priv omap2_mbox_iva_priv = {
358 .tx_fifo = {
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700359 .msg = MAILBOX_MESSAGE(2),
360 .fifo_stat = MAILBOX_FIFOSTATUS(2),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800361 },
362 .rx_fifo = {
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700363 .msg = MAILBOX_MESSAGE(3),
364 .msg_stat = MAILBOX_MSGSTATUS(3),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800365 },
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700366 .irqenable = MAILBOX_IRQENABLE(3),
367 .irqstatus = MAILBOX_IRQSTATUS(3),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800368 .notfull_bit = MAILBOX_IRQ_NOTFULL(2),
369 .newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800370 .irqdisable = MAILBOX_IRQENABLE(3),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800371};
372
373static struct omap_mbox mbox_iva_info = {
374 .name = "iva",
375 .ops = &omap2_mbox_ops,
376 .priv = &omap2_mbox_iva_priv,
377};
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700378#endif
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800379
Hiroshi DOYUda8cfe02009-03-23 18:07:25 -0700380static int __devinit omap2_mbox_probe(struct platform_device *pdev)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800381{
382 struct resource *res;
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700383 int ret;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800384
385 /* MBOX base */
386 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
387 if (unlikely(!res)) {
388 dev_err(&pdev->dev, "invalid mem resource\n");
389 return -ENODEV;
390 }
Tobias Klauser6d135242009-11-10 18:55:19 -0800391 mbox_base = ioremap(res->start, resource_size(res));
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700392 if (!mbox_base)
393 return -ENOMEM;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800394
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700395 /* DSP or IVA2 IRQ */
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800396 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
397
398 if (unlikely(!res)) {
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800399 dev_err(&pdev->dev, "invalid irq resource\n");
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800400 ret = -ENODEV;
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700401 goto err_dsp;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800402 }
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800403 if (cpu_is_omap44xx()) {
404 mbox_1_info.irq = res->start;
405 ret = omap_mbox_register(&pdev->dev, &mbox_1_info);
406 } else {
407 mbox_dsp_info.irq = res->start;
408 ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info);
409 }
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700410 if (ret)
411 goto err_dsp;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800412
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800413 if (cpu_is_omap44xx()) {
414 mbox_2_info.irq = res->start;
415 ret = omap_mbox_register(&pdev->dev, &mbox_2_info);
416 if (ret) {
417 omap_mbox_unregister(&mbox_1_info);
418 goto err_dsp;
419 }
420 }
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700421#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
422 if (cpu_is_omap2420()) {
423 /* IVA IRQ */
424 res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
425 if (unlikely(!res)) {
426 dev_err(&pdev->dev, "invalid irq resource\n");
427 ret = -ENODEV;
428 goto err_iva1;
429 }
430 mbox_iva_info.irq = res->start;
Hiroshi DOYUda8cfe02009-03-23 18:07:25 -0700431 ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700432 if (ret)
433 goto err_iva1;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800434 }
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700435#endif
436 return 0;
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800437
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700438err_iva1:
439 omap_mbox_unregister(&mbox_dsp_info);
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800440
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700441err_dsp:
442 iounmap(mbox_base);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800443 return ret;
444}
445
Hiroshi DOYUda8cfe02009-03-23 18:07:25 -0700446static int __devexit omap2_mbox_remove(struct platform_device *pdev)
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800447{
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700448#if defined(CONFIG_ARCH_OMAP2420)
449 omap_mbox_unregister(&mbox_iva_info);
450#endif
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800451
452 if (cpu_is_omap44xx()) {
453 omap_mbox_unregister(&mbox_2_info);
454 omap_mbox_unregister(&mbox_1_info);
455 } else
456 omap_mbox_unregister(&mbox_dsp_info);
Hiroshi DOYU6c20a682009-03-23 18:07:23 -0700457 iounmap(mbox_base);
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800458 return 0;
459}
460
461static struct platform_driver omap2_mbox_driver = {
462 .probe = omap2_mbox_probe,
Hiroshi DOYUda8cfe02009-03-23 18:07:25 -0700463 .remove = __devexit_p(omap2_mbox_remove),
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800464 .driver = {
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800465 .name = DRV_NAME,
Hiroshi DOYU340a6142006-12-07 15:43:59 -0800466 },
467};
468
469static int __init omap2_mbox_init(void)
470{
471 return platform_driver_register(&omap2_mbox_driver);
472}
473
474static void __exit omap2_mbox_exit(void)
475{
476 platform_driver_unregister(&omap2_mbox_driver);
477}
478
479module_init(omap2_mbox_init);
480module_exit(omap2_mbox_exit);
481
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700482MODULE_LICENSE("GPL v2");
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800483MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions");
Hiroshi DOYU733ecc52009-03-23 18:07:23 -0700484MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>, Paul Mundt");
C A Subramaniam5f00ec62009-11-22 10:11:22 -0800485MODULE_ALIAS("platform:"DRV_NAME);