1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
6 * Copyright (C) 2013-2021 Texas Instruments Incorporated - https://www.ti.com
8 * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
9 * Suman Anna <s-anna@ti.com>
12 #include <linux/interrupt.h>
13 #include <linux/spinlock.h>
14 #include <linux/mutex.h>
15 #include <linux/slab.h>
16 #include <linux/kfifo.h>
17 #include <linux/err.h>
19 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/mailbox_controller.h>
24 #include <linux/mailbox_client.h>
28 #define MAILBOX_REVISION 0x000
29 #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
30 #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
31 #define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
33 #define OMAP2_MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
34 #define OMAP2_MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
36 #define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 0x10 * (u))
37 #define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u))
38 #define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 0x10 * (u))
40 #define MAILBOX_IRQSTATUS(type, u) (type ? OMAP4_MAILBOX_IRQSTATUS(u) : \
41 OMAP2_MAILBOX_IRQSTATUS(u))
42 #define MAILBOX_IRQENABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE(u) : \
43 OMAP2_MAILBOX_IRQENABLE(u))
44 #define MAILBOX_IRQDISABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE_CLR(u) \
45 : OMAP2_MAILBOX_IRQENABLE(u))
47 #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m)))
48 #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1))
50 /* Interrupt register configuration types */
51 #define MBOX_INTR_CFG_TYPE1 0
52 #define MBOX_INTR_CFG_TYPE2 1
59 struct omap_mbox_fifo
{
61 unsigned long fifo_stat
;
62 unsigned long msg_stat
;
63 unsigned long irqenable
;
64 unsigned long irqstatus
;
65 unsigned long irqdisable
;
69 struct omap_mbox_match_data
{
73 struct omap_mbox_device
{
75 struct mutex cfg_lock
;
76 void __iomem
*mbox_base
;
86 struct omap_mbox_device
*parent
;
87 struct omap_mbox_fifo tx_fifo
;
88 struct omap_mbox_fifo rx_fifo
;
90 struct mbox_chan
*chan
;
95 unsigned int mbox_read_reg(struct omap_mbox_device
*mdev
, size_t ofs
)
97 return __raw_readl(mdev
->mbox_base
+ ofs
);
101 void mbox_write_reg(struct omap_mbox_device
*mdev
, u32 val
, size_t ofs
)
103 __raw_writel(val
, mdev
->mbox_base
+ ofs
);
106 /* Mailbox FIFO handle functions */
107 static u32
mbox_fifo_read(struct omap_mbox
*mbox
)
109 struct omap_mbox_fifo
*fifo
= &mbox
->rx_fifo
;
111 return mbox_read_reg(mbox
->parent
, fifo
->msg
);
114 static void mbox_fifo_write(struct omap_mbox
*mbox
, u32 msg
)
116 struct omap_mbox_fifo
*fifo
= &mbox
->tx_fifo
;
118 mbox_write_reg(mbox
->parent
, msg
, fifo
->msg
);
121 static int mbox_fifo_empty(struct omap_mbox
*mbox
)
123 struct omap_mbox_fifo
*fifo
= &mbox
->rx_fifo
;
125 return (mbox_read_reg(mbox
->parent
, fifo
->msg_stat
) == 0);
128 static int mbox_fifo_full(struct omap_mbox
*mbox
)
130 struct omap_mbox_fifo
*fifo
= &mbox
->tx_fifo
;
132 return mbox_read_reg(mbox
->parent
, fifo
->fifo_stat
);
135 /* Mailbox IRQ handle functions */
136 static void ack_mbox_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
138 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
139 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
140 u32 bit
= fifo
->intr_bit
;
141 u32 irqstatus
= fifo
->irqstatus
;
143 mbox_write_reg(mbox
->parent
, bit
, irqstatus
);
145 /* Flush posted write for irq status to avoid spurious interrupts */
146 mbox_read_reg(mbox
->parent
, irqstatus
);
149 static int is_mbox_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
151 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
152 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
153 u32 bit
= fifo
->intr_bit
;
154 u32 irqenable
= fifo
->irqenable
;
155 u32 irqstatus
= fifo
->irqstatus
;
157 u32 enable
= mbox_read_reg(mbox
->parent
, irqenable
);
158 u32 status
= mbox_read_reg(mbox
->parent
, irqstatus
);
160 return (int)(enable
& status
& bit
);
163 static void omap_mbox_enable_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
166 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
167 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
168 u32 bit
= fifo
->intr_bit
;
169 u32 irqenable
= fifo
->irqenable
;
171 l
= mbox_read_reg(mbox
->parent
, irqenable
);
173 mbox_write_reg(mbox
->parent
, l
, irqenable
);
176 static void omap_mbox_disable_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
178 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
179 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
180 u32 bit
= fifo
->intr_bit
;
181 u32 irqdisable
= fifo
->irqdisable
;
184 * Read and update the interrupt configuration register for pre-OMAP4.
185 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
187 if (!mbox
->intr_type
)
188 bit
= mbox_read_reg(mbox
->parent
, irqdisable
) & ~bit
;
190 mbox_write_reg(mbox
->parent
, bit
, irqdisable
);
194 * Mailbox interrupt handler
196 static void __mbox_tx_interrupt(struct omap_mbox
*mbox
)
198 omap_mbox_disable_irq(mbox
, IRQ_TX
);
199 ack_mbox_irq(mbox
, IRQ_TX
);
200 mbox_chan_txdone(mbox
->chan
, 0);
203 static void __mbox_rx_interrupt(struct omap_mbox
*mbox
)
207 while (!mbox_fifo_empty(mbox
)) {
208 msg
= mbox_fifo_read(mbox
);
209 mbox_chan_received_data(mbox
->chan
, (void *)(uintptr_t)msg
);
212 /* clear IRQ source. */
213 ack_mbox_irq(mbox
, IRQ_RX
);
216 static irqreturn_t
mbox_interrupt(int irq
, void *p
)
218 struct omap_mbox
*mbox
= p
;
220 if (is_mbox_irq(mbox
, IRQ_TX
))
221 __mbox_tx_interrupt(mbox
);
223 if (is_mbox_irq(mbox
, IRQ_RX
))
224 __mbox_rx_interrupt(mbox
);
229 static int omap_mbox_startup(struct omap_mbox
*mbox
)
233 ret
= request_threaded_irq(mbox
->irq
, NULL
, mbox_interrupt
,
234 IRQF_SHARED
| IRQF_ONESHOT
, mbox
->name
,
237 pr_err("failed to register mailbox interrupt:%d\n", ret
);
241 if (mbox
->send_no_irq
)
242 mbox
->chan
->txdone_method
= TXDONE_BY_ACK
;
244 omap_mbox_enable_irq(mbox
, IRQ_RX
);
249 static void omap_mbox_fini(struct omap_mbox
*mbox
)
251 omap_mbox_disable_irq(mbox
, IRQ_RX
);
252 free_irq(mbox
->irq
, mbox
);
255 static int omap_mbox_chan_startup(struct mbox_chan
*chan
)
257 struct omap_mbox
*mbox
= chan
->con_priv
;
258 struct omap_mbox_device
*mdev
= mbox
->parent
;
261 mutex_lock(&mdev
->cfg_lock
);
262 pm_runtime_get_sync(mdev
->dev
);
263 ret
= omap_mbox_startup(mbox
);
265 pm_runtime_put_sync(mdev
->dev
);
266 mutex_unlock(&mdev
->cfg_lock
);
270 static void omap_mbox_chan_shutdown(struct mbox_chan
*chan
)
272 struct omap_mbox
*mbox
= chan
->con_priv
;
273 struct omap_mbox_device
*mdev
= mbox
->parent
;
275 mutex_lock(&mdev
->cfg_lock
);
276 omap_mbox_fini(mbox
);
277 pm_runtime_put_sync(mdev
->dev
);
278 mutex_unlock(&mdev
->cfg_lock
);
281 static int omap_mbox_chan_send_noirq(struct omap_mbox
*mbox
, u32 msg
)
283 if (mbox_fifo_full(mbox
))
286 omap_mbox_enable_irq(mbox
, IRQ_RX
);
287 mbox_fifo_write(mbox
, msg
);
288 omap_mbox_disable_irq(mbox
, IRQ_RX
);
290 /* we must read and ack the interrupt directly from here */
291 mbox_fifo_read(mbox
);
292 ack_mbox_irq(mbox
, IRQ_RX
);
297 static int omap_mbox_chan_send(struct omap_mbox
*mbox
, u32 msg
)
299 if (mbox_fifo_full(mbox
)) {
300 /* always enable the interrupt */
301 omap_mbox_enable_irq(mbox
, IRQ_TX
);
305 mbox_fifo_write(mbox
, msg
);
307 /* always enable the interrupt */
308 omap_mbox_enable_irq(mbox
, IRQ_TX
);
312 static int omap_mbox_chan_send_data(struct mbox_chan
*chan
, void *data
)
314 struct omap_mbox
*mbox
= chan
->con_priv
;
316 u32 msg
= (u32
)(uintptr_t)(data
);
321 if (mbox
->send_no_irq
)
322 ret
= omap_mbox_chan_send_noirq(mbox
, msg
);
324 ret
= omap_mbox_chan_send(mbox
, msg
);
329 static const struct mbox_chan_ops omap_mbox_chan_ops
= {
330 .startup
= omap_mbox_chan_startup
,
331 .send_data
= omap_mbox_chan_send_data
,
332 .shutdown
= omap_mbox_chan_shutdown
,
335 #ifdef CONFIG_PM_SLEEP
336 static int omap_mbox_suspend(struct device
*dev
)
338 struct omap_mbox_device
*mdev
= dev_get_drvdata(dev
);
341 if (pm_runtime_status_suspended(dev
))
344 for (fifo
= 0; fifo
< mdev
->num_fifos
; fifo
++) {
345 if (mbox_read_reg(mdev
, MAILBOX_MSGSTATUS(fifo
))) {
346 dev_err(mdev
->dev
, "fifo %d has unexpected unread messages\n",
352 for (usr
= 0; usr
< mdev
->num_users
; usr
++) {
353 reg
= MAILBOX_IRQENABLE(mdev
->intr_type
, usr
);
354 mdev
->irq_ctx
[usr
] = mbox_read_reg(mdev
, reg
);
360 static int omap_mbox_resume(struct device
*dev
)
362 struct omap_mbox_device
*mdev
= dev_get_drvdata(dev
);
365 if (pm_runtime_status_suspended(dev
))
368 for (usr
= 0; usr
< mdev
->num_users
; usr
++) {
369 reg
= MAILBOX_IRQENABLE(mdev
->intr_type
, usr
);
370 mbox_write_reg(mdev
, mdev
->irq_ctx
[usr
], reg
);
377 static const struct dev_pm_ops omap_mbox_pm_ops
= {
378 SET_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend
, omap_mbox_resume
)
381 static const struct omap_mbox_match_data omap2_data
= { MBOX_INTR_CFG_TYPE1
};
382 static const struct omap_mbox_match_data omap4_data
= { MBOX_INTR_CFG_TYPE2
};
384 static const struct of_device_id omap_mailbox_of_match
[] = {
386 .compatible
= "ti,omap2-mailbox",
390 .compatible
= "ti,omap3-mailbox",
394 .compatible
= "ti,omap4-mailbox",
398 .compatible
= "ti,am654-mailbox",
402 .compatible
= "ti,am64-mailbox",
409 MODULE_DEVICE_TABLE(of
, omap_mailbox_of_match
);
411 static struct mbox_chan
*omap_mbox_of_xlate(struct mbox_controller
*controller
,
412 const struct of_phandle_args
*sp
)
414 phandle phandle
= sp
->args
[0];
415 struct device_node
*node
;
416 struct omap_mbox_device
*mdev
;
417 struct omap_mbox
*mbox
;
420 mdev
= dev_get_drvdata(controller
->dev
);
422 return ERR_PTR(-EINVAL
);
424 node
= of_find_node_by_phandle(phandle
);
426 pr_err("%s: could not find node phandle 0x%x\n",
428 return ERR_PTR(-ENODEV
);
431 for (i
= 0; i
< controller
->num_chans
; i
++) {
432 mbox
= controller
->chans
[i
].con_priv
;
433 if (!strcmp(mbox
->name
, node
->name
)) {
435 return &controller
->chans
[i
];
440 return ERR_PTR(-ENOENT
);
443 static int omap_mbox_probe(struct platform_device
*pdev
)
446 struct mbox_chan
*chnls
;
447 struct omap_mbox
*mbox
;
448 struct omap_mbox_device
*mdev
;
449 struct omap_mbox_fifo
*fifo
;
450 struct device_node
*node
= pdev
->dev
.of_node
;
451 struct device_node
*child
;
452 const struct omap_mbox_match_data
*match_data
;
453 struct mbox_controller
*controller
;
454 u32 intr_type
, info_count
;
455 u32 num_users
, num_fifos
;
461 pr_err("%s: only DT-based devices are supported\n", __func__
);
465 match_data
= of_device_get_match_data(&pdev
->dev
);
468 intr_type
= match_data
->intr_type
;
470 if (of_property_read_u32(node
, "ti,mbox-num-users", &num_users
))
473 if (of_property_read_u32(node
, "ti,mbox-num-fifos", &num_fifos
))
476 info_count
= of_get_available_child_count(node
);
478 dev_err(&pdev
->dev
, "no available mbox devices found\n");
482 mdev
= devm_kzalloc(&pdev
->dev
, sizeof(*mdev
), GFP_KERNEL
);
486 mdev
->mbox_base
= devm_platform_ioremap_resource(pdev
, 0);
487 if (IS_ERR(mdev
->mbox_base
))
488 return PTR_ERR(mdev
->mbox_base
);
490 mdev
->irq_ctx
= devm_kcalloc(&pdev
->dev
, num_users
, sizeof(u32
),
495 chnls
= devm_kcalloc(&pdev
->dev
, info_count
+ 1, sizeof(*chnls
),
501 for (i
= 0; i
< info_count
; i
++) {
502 int tx_id
, tx_irq
, tx_usr
;
505 mbox
= devm_kzalloc(&pdev
->dev
, sizeof(*mbox
), GFP_KERNEL
);
509 child
= of_get_next_available_child(node
, child
);
510 ret
= of_property_read_u32_array(child
, "ti,mbox-tx", tmp
,
518 ret
= of_property_read_u32_array(child
, "ti,mbox-rx", tmp
,
523 /* rx_irq = tmp[1]; */
526 if (tx_id
>= num_fifos
|| rx_id
>= num_fifos
||
527 tx_usr
>= num_users
|| rx_usr
>= num_users
)
530 fifo
= &mbox
->tx_fifo
;
531 fifo
->msg
= MAILBOX_MESSAGE(tx_id
);
532 fifo
->fifo_stat
= MAILBOX_FIFOSTATUS(tx_id
);
533 fifo
->intr_bit
= MAILBOX_IRQ_NOTFULL(tx_id
);
534 fifo
->irqenable
= MAILBOX_IRQENABLE(intr_type
, tx_usr
);
535 fifo
->irqstatus
= MAILBOX_IRQSTATUS(intr_type
, tx_usr
);
536 fifo
->irqdisable
= MAILBOX_IRQDISABLE(intr_type
, tx_usr
);
538 fifo
= &mbox
->rx_fifo
;
539 fifo
->msg
= MAILBOX_MESSAGE(rx_id
);
540 fifo
->msg_stat
= MAILBOX_MSGSTATUS(rx_id
);
541 fifo
->intr_bit
= MAILBOX_IRQ_NEWMSG(rx_id
);
542 fifo
->irqenable
= MAILBOX_IRQENABLE(intr_type
, rx_usr
);
543 fifo
->irqstatus
= MAILBOX_IRQSTATUS(intr_type
, rx_usr
);
544 fifo
->irqdisable
= MAILBOX_IRQDISABLE(intr_type
, rx_usr
);
546 mbox
->send_no_irq
= of_property_read_bool(child
, "ti,mbox-send-noirq");
547 mbox
->intr_type
= intr_type
;
550 mbox
->name
= child
->name
;
551 mbox
->irq
= platform_get_irq(pdev
, tx_irq
);
554 mbox
->chan
= &chnls
[i
];
555 chnls
[i
].con_priv
= mbox
;
558 mutex_init(&mdev
->cfg_lock
);
559 mdev
->dev
= &pdev
->dev
;
560 mdev
->num_users
= num_users
;
561 mdev
->num_fifos
= num_fifos
;
562 mdev
->intr_type
= intr_type
;
564 controller
= devm_kzalloc(&pdev
->dev
, sizeof(*controller
), GFP_KERNEL
);
568 * OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready
569 * IRQ and is needed to run the Tx state machine
571 controller
->txdone_irq
= true;
572 controller
->dev
= mdev
->dev
;
573 controller
->ops
= &omap_mbox_chan_ops
;
574 controller
->chans
= chnls
;
575 controller
->num_chans
= info_count
;
576 controller
->of_xlate
= omap_mbox_of_xlate
;
577 ret
= devm_mbox_controller_register(mdev
->dev
, controller
);
581 platform_set_drvdata(pdev
, mdev
);
582 devm_pm_runtime_enable(mdev
->dev
);
584 ret
= pm_runtime_resume_and_get(mdev
->dev
);
589 * just print the raw revision register, the format is not
590 * uniform across all SoCs
592 l
= mbox_read_reg(mdev
, MAILBOX_REVISION
);
593 dev_info(mdev
->dev
, "omap mailbox rev 0x%x\n", l
);
595 ret
= pm_runtime_put_sync(mdev
->dev
);
596 if (ret
< 0 && ret
!= -ENOSYS
)
602 static struct platform_driver omap_mbox_driver
= {
603 .probe
= omap_mbox_probe
,
605 .name
= "omap-mailbox",
606 .pm
= &omap_mbox_pm_ops
,
607 .of_match_table
= omap_mailbox_of_match
,
610 module_platform_driver(omap_mbox_driver
);
612 MODULE_LICENSE("GPL v2");
613 MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
614 MODULE_AUTHOR("Toshihiro Kobayashi");
615 MODULE_AUTHOR("Hiroshi DOYU");