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>
18 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/mailbox_controller.h>
23 #include <linux/mailbox_client.h>
27 #define MAILBOX_REVISION 0x000
28 #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
29 #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
30 #define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
32 #define OMAP2_MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
33 #define OMAP2_MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
35 #define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 0x10 * (u))
36 #define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u))
37 #define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 0x10 * (u))
39 #define MAILBOX_IRQSTATUS(type, u) (type ? OMAP4_MAILBOX_IRQSTATUS(u) : \
40 OMAP2_MAILBOX_IRQSTATUS(u))
41 #define MAILBOX_IRQENABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE(u) : \
42 OMAP2_MAILBOX_IRQENABLE(u))
43 #define MAILBOX_IRQDISABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE_CLR(u) \
44 : OMAP2_MAILBOX_IRQENABLE(u))
46 #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m)))
47 #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1))
49 /* Interrupt register configuration types */
50 #define MBOX_INTR_CFG_TYPE1 0
51 #define MBOX_INTR_CFG_TYPE2 1
58 struct omap_mbox_fifo
{
60 unsigned long fifo_stat
;
61 unsigned long msg_stat
;
62 unsigned long irqenable
;
63 unsigned long irqstatus
;
64 unsigned long irqdisable
;
68 struct omap_mbox_match_data
{
72 struct omap_mbox_device
{
74 struct mutex cfg_lock
;
75 void __iomem
*mbox_base
;
85 struct omap_mbox_device
*parent
;
86 struct omap_mbox_fifo tx_fifo
;
87 struct omap_mbox_fifo rx_fifo
;
89 struct mbox_chan
*chan
;
94 unsigned int mbox_read_reg(struct omap_mbox_device
*mdev
, size_t ofs
)
96 return __raw_readl(mdev
->mbox_base
+ ofs
);
100 void mbox_write_reg(struct omap_mbox_device
*mdev
, u32 val
, size_t ofs
)
102 __raw_writel(val
, mdev
->mbox_base
+ ofs
);
105 /* Mailbox FIFO handle functions */
106 static u32
mbox_fifo_read(struct omap_mbox
*mbox
)
108 struct omap_mbox_fifo
*fifo
= &mbox
->rx_fifo
;
110 return mbox_read_reg(mbox
->parent
, fifo
->msg
);
113 static void mbox_fifo_write(struct omap_mbox
*mbox
, u32 msg
)
115 struct omap_mbox_fifo
*fifo
= &mbox
->tx_fifo
;
117 mbox_write_reg(mbox
->parent
, msg
, fifo
->msg
);
120 static int mbox_fifo_empty(struct omap_mbox
*mbox
)
122 struct omap_mbox_fifo
*fifo
= &mbox
->rx_fifo
;
124 return (mbox_read_reg(mbox
->parent
, fifo
->msg_stat
) == 0);
127 static int mbox_fifo_full(struct omap_mbox
*mbox
)
129 struct omap_mbox_fifo
*fifo
= &mbox
->tx_fifo
;
131 return mbox_read_reg(mbox
->parent
, fifo
->fifo_stat
);
134 /* Mailbox IRQ handle functions */
135 static void ack_mbox_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
137 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
138 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
139 u32 bit
= fifo
->intr_bit
;
140 u32 irqstatus
= fifo
->irqstatus
;
142 mbox_write_reg(mbox
->parent
, bit
, irqstatus
);
144 /* Flush posted write for irq status to avoid spurious interrupts */
145 mbox_read_reg(mbox
->parent
, irqstatus
);
148 static int is_mbox_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
150 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
151 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
152 u32 bit
= fifo
->intr_bit
;
153 u32 irqenable
= fifo
->irqenable
;
154 u32 irqstatus
= fifo
->irqstatus
;
156 u32 enable
= mbox_read_reg(mbox
->parent
, irqenable
);
157 u32 status
= mbox_read_reg(mbox
->parent
, irqstatus
);
159 return (int)(enable
& status
& bit
);
162 static void omap_mbox_enable_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
165 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
166 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
167 u32 bit
= fifo
->intr_bit
;
168 u32 irqenable
= fifo
->irqenable
;
170 l
= mbox_read_reg(mbox
->parent
, irqenable
);
172 mbox_write_reg(mbox
->parent
, l
, irqenable
);
175 static void omap_mbox_disable_irq(struct omap_mbox
*mbox
, omap_mbox_irq_t irq
)
177 struct omap_mbox_fifo
*fifo
= (irq
== IRQ_TX
) ?
178 &mbox
->tx_fifo
: &mbox
->rx_fifo
;
179 u32 bit
= fifo
->intr_bit
;
180 u32 irqdisable
= fifo
->irqdisable
;
183 * Read and update the interrupt configuration register for pre-OMAP4.
184 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
186 if (!mbox
->intr_type
)
187 bit
= mbox_read_reg(mbox
->parent
, irqdisable
) & ~bit
;
189 mbox_write_reg(mbox
->parent
, bit
, irqdisable
);
193 * Mailbox interrupt handler
195 static void __mbox_tx_interrupt(struct omap_mbox
*mbox
)
197 omap_mbox_disable_irq(mbox
, IRQ_TX
);
198 ack_mbox_irq(mbox
, IRQ_TX
);
199 mbox_chan_txdone(mbox
->chan
, 0);
202 static void __mbox_rx_interrupt(struct omap_mbox
*mbox
)
206 while (!mbox_fifo_empty(mbox
)) {
207 msg
= mbox_fifo_read(mbox
);
208 mbox_chan_received_data(mbox
->chan
, (void *)(uintptr_t)msg
);
211 /* clear IRQ source. */
212 ack_mbox_irq(mbox
, IRQ_RX
);
215 static irqreturn_t
mbox_interrupt(int irq
, void *p
)
217 struct omap_mbox
*mbox
= p
;
219 if (is_mbox_irq(mbox
, IRQ_TX
))
220 __mbox_tx_interrupt(mbox
);
222 if (is_mbox_irq(mbox
, IRQ_RX
))
223 __mbox_rx_interrupt(mbox
);
228 static int omap_mbox_startup(struct omap_mbox
*mbox
)
232 ret
= request_threaded_irq(mbox
->irq
, NULL
, mbox_interrupt
,
233 IRQF_SHARED
| IRQF_ONESHOT
, mbox
->name
,
236 pr_err("failed to register mailbox interrupt:%d\n", ret
);
240 if (mbox
->send_no_irq
)
241 mbox
->chan
->txdone_method
= TXDONE_BY_ACK
;
243 omap_mbox_enable_irq(mbox
, IRQ_RX
);
248 static void omap_mbox_fini(struct omap_mbox
*mbox
)
250 omap_mbox_disable_irq(mbox
, IRQ_RX
);
251 free_irq(mbox
->irq
, mbox
);
254 static int omap_mbox_chan_startup(struct mbox_chan
*chan
)
256 struct omap_mbox
*mbox
= chan
->con_priv
;
257 struct omap_mbox_device
*mdev
= mbox
->parent
;
260 mutex_lock(&mdev
->cfg_lock
);
261 pm_runtime_get_sync(mdev
->dev
);
262 ret
= omap_mbox_startup(mbox
);
264 pm_runtime_put_sync(mdev
->dev
);
265 mutex_unlock(&mdev
->cfg_lock
);
269 static void omap_mbox_chan_shutdown(struct mbox_chan
*chan
)
271 struct omap_mbox
*mbox
= chan
->con_priv
;
272 struct omap_mbox_device
*mdev
= mbox
->parent
;
274 mutex_lock(&mdev
->cfg_lock
);
275 omap_mbox_fini(mbox
);
276 pm_runtime_put_sync(mdev
->dev
);
277 mutex_unlock(&mdev
->cfg_lock
);
280 static int omap_mbox_chan_send_noirq(struct omap_mbox
*mbox
, u32 msg
)
282 if (mbox_fifo_full(mbox
))
285 omap_mbox_enable_irq(mbox
, IRQ_RX
);
286 mbox_fifo_write(mbox
, msg
);
287 omap_mbox_disable_irq(mbox
, IRQ_RX
);
289 /* we must read and ack the interrupt directly from here */
290 mbox_fifo_read(mbox
);
291 ack_mbox_irq(mbox
, IRQ_RX
);
296 static int omap_mbox_chan_send(struct omap_mbox
*mbox
, u32 msg
)
298 if (mbox_fifo_full(mbox
)) {
299 /* always enable the interrupt */
300 omap_mbox_enable_irq(mbox
, IRQ_TX
);
304 mbox_fifo_write(mbox
, msg
);
306 /* always enable the interrupt */
307 omap_mbox_enable_irq(mbox
, IRQ_TX
);
311 static int omap_mbox_chan_send_data(struct mbox_chan
*chan
, void *data
)
313 struct omap_mbox
*mbox
= chan
->con_priv
;
315 u32 msg
= (u32
)(uintptr_t)(data
);
320 if (mbox
->send_no_irq
)
321 ret
= omap_mbox_chan_send_noirq(mbox
, msg
);
323 ret
= omap_mbox_chan_send(mbox
, msg
);
328 static const struct mbox_chan_ops omap_mbox_chan_ops
= {
329 .startup
= omap_mbox_chan_startup
,
330 .send_data
= omap_mbox_chan_send_data
,
331 .shutdown
= omap_mbox_chan_shutdown
,
334 #ifdef CONFIG_PM_SLEEP
335 static int omap_mbox_suspend(struct device
*dev
)
337 struct omap_mbox_device
*mdev
= dev_get_drvdata(dev
);
340 if (pm_runtime_status_suspended(dev
))
343 for (fifo
= 0; fifo
< mdev
->num_fifos
; fifo
++) {
344 if (mbox_read_reg(mdev
, MAILBOX_MSGSTATUS(fifo
))) {
345 dev_err(mdev
->dev
, "fifo %d has unexpected unread messages\n",
351 for (usr
= 0; usr
< mdev
->num_users
; usr
++) {
352 reg
= MAILBOX_IRQENABLE(mdev
->intr_type
, usr
);
353 mdev
->irq_ctx
[usr
] = mbox_read_reg(mdev
, reg
);
359 static int omap_mbox_resume(struct device
*dev
)
361 struct omap_mbox_device
*mdev
= dev_get_drvdata(dev
);
364 if (pm_runtime_status_suspended(dev
))
367 for (usr
= 0; usr
< mdev
->num_users
; usr
++) {
368 reg
= MAILBOX_IRQENABLE(mdev
->intr_type
, usr
);
369 mbox_write_reg(mdev
, mdev
->irq_ctx
[usr
], reg
);
376 static const struct dev_pm_ops omap_mbox_pm_ops
= {
377 SET_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend
, omap_mbox_resume
)
380 static const struct omap_mbox_match_data omap2_data
= { MBOX_INTR_CFG_TYPE1
};
381 static const struct omap_mbox_match_data omap4_data
= { MBOX_INTR_CFG_TYPE2
};
383 static const struct of_device_id omap_mailbox_of_match
[] = {
385 .compatible
= "ti,omap2-mailbox",
389 .compatible
= "ti,omap3-mailbox",
393 .compatible
= "ti,omap4-mailbox",
397 .compatible
= "ti,am654-mailbox",
401 .compatible
= "ti,am64-mailbox",
408 MODULE_DEVICE_TABLE(of
, omap_mailbox_of_match
);
410 static struct mbox_chan
*omap_mbox_of_xlate(struct mbox_controller
*controller
,
411 const struct of_phandle_args
*sp
)
413 phandle phandle
= sp
->args
[0];
414 struct device_node
*node
;
415 struct omap_mbox_device
*mdev
;
416 struct omap_mbox
*mbox
;
419 mdev
= dev_get_drvdata(controller
->dev
);
421 return ERR_PTR(-EINVAL
);
423 node
= of_find_node_by_phandle(phandle
);
425 pr_err("%s: could not find node phandle 0x%x\n",
427 return ERR_PTR(-ENODEV
);
430 for (i
= 0; i
< controller
->num_chans
; i
++) {
431 mbox
= controller
->chans
[i
].con_priv
;
432 if (!strcmp(mbox
->name
, node
->name
)) {
434 return &controller
->chans
[i
];
439 return ERR_PTR(-ENOENT
);
442 static int omap_mbox_probe(struct platform_device
*pdev
)
445 struct mbox_chan
*chnls
;
446 struct omap_mbox
*mbox
;
447 struct omap_mbox_device
*mdev
;
448 struct omap_mbox_fifo
*fifo
;
449 struct device_node
*node
= pdev
->dev
.of_node
;
450 struct device_node
*child
;
451 const struct omap_mbox_match_data
*match_data
;
452 struct mbox_controller
*controller
;
453 u32 intr_type
, info_count
;
454 u32 num_users
, num_fifos
;
460 pr_err("%s: only DT-based devices are supported\n", __func__
);
464 match_data
= of_device_get_match_data(&pdev
->dev
);
467 intr_type
= match_data
->intr_type
;
469 if (of_property_read_u32(node
, "ti,mbox-num-users", &num_users
))
472 if (of_property_read_u32(node
, "ti,mbox-num-fifos", &num_fifos
))
475 info_count
= of_get_available_child_count(node
);
477 dev_err(&pdev
->dev
, "no available mbox devices found\n");
481 mdev
= devm_kzalloc(&pdev
->dev
, sizeof(*mdev
), GFP_KERNEL
);
485 mdev
->mbox_base
= devm_platform_ioremap_resource(pdev
, 0);
486 if (IS_ERR(mdev
->mbox_base
))
487 return PTR_ERR(mdev
->mbox_base
);
489 mdev
->irq_ctx
= devm_kcalloc(&pdev
->dev
, num_users
, sizeof(u32
),
494 chnls
= devm_kcalloc(&pdev
->dev
, info_count
+ 1, sizeof(*chnls
),
500 for (i
= 0; i
< info_count
; i
++) {
501 int tx_id
, tx_irq
, tx_usr
;
504 mbox
= devm_kzalloc(&pdev
->dev
, sizeof(*mbox
), GFP_KERNEL
);
508 child
= of_get_next_available_child(node
, child
);
509 ret
= of_property_read_u32_array(child
, "ti,mbox-tx", tmp
,
517 ret
= of_property_read_u32_array(child
, "ti,mbox-rx", tmp
,
522 /* rx_irq = tmp[1]; */
525 if (tx_id
>= num_fifos
|| rx_id
>= num_fifos
||
526 tx_usr
>= num_users
|| rx_usr
>= num_users
)
529 fifo
= &mbox
->tx_fifo
;
530 fifo
->msg
= MAILBOX_MESSAGE(tx_id
);
531 fifo
->fifo_stat
= MAILBOX_FIFOSTATUS(tx_id
);
532 fifo
->intr_bit
= MAILBOX_IRQ_NOTFULL(tx_id
);
533 fifo
->irqenable
= MAILBOX_IRQENABLE(intr_type
, tx_usr
);
534 fifo
->irqstatus
= MAILBOX_IRQSTATUS(intr_type
, tx_usr
);
535 fifo
->irqdisable
= MAILBOX_IRQDISABLE(intr_type
, tx_usr
);
537 fifo
= &mbox
->rx_fifo
;
538 fifo
->msg
= MAILBOX_MESSAGE(rx_id
);
539 fifo
->msg_stat
= MAILBOX_MSGSTATUS(rx_id
);
540 fifo
->intr_bit
= MAILBOX_IRQ_NEWMSG(rx_id
);
541 fifo
->irqenable
= MAILBOX_IRQENABLE(intr_type
, rx_usr
);
542 fifo
->irqstatus
= MAILBOX_IRQSTATUS(intr_type
, rx_usr
);
543 fifo
->irqdisable
= MAILBOX_IRQDISABLE(intr_type
, rx_usr
);
545 mbox
->send_no_irq
= of_property_read_bool(child
, "ti,mbox-send-noirq");
546 mbox
->intr_type
= intr_type
;
549 mbox
->name
= child
->name
;
550 mbox
->irq
= platform_get_irq(pdev
, tx_irq
);
553 mbox
->chan
= &chnls
[i
];
554 chnls
[i
].con_priv
= mbox
;
557 mutex_init(&mdev
->cfg_lock
);
558 mdev
->dev
= &pdev
->dev
;
559 mdev
->num_users
= num_users
;
560 mdev
->num_fifos
= num_fifos
;
561 mdev
->intr_type
= intr_type
;
563 controller
= devm_kzalloc(&pdev
->dev
, sizeof(*controller
), GFP_KERNEL
);
567 * OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready
568 * IRQ and is needed to run the Tx state machine
570 controller
->txdone_irq
= true;
571 controller
->dev
= mdev
->dev
;
572 controller
->ops
= &omap_mbox_chan_ops
;
573 controller
->chans
= chnls
;
574 controller
->num_chans
= info_count
;
575 controller
->of_xlate
= omap_mbox_of_xlate
;
576 ret
= devm_mbox_controller_register(mdev
->dev
, controller
);
580 platform_set_drvdata(pdev
, mdev
);
581 devm_pm_runtime_enable(mdev
->dev
);
583 ret
= pm_runtime_resume_and_get(mdev
->dev
);
588 * just print the raw revision register, the format is not
589 * uniform across all SoCs
591 l
= mbox_read_reg(mdev
, MAILBOX_REVISION
);
592 dev_info(mdev
->dev
, "omap mailbox rev 0x%x\n", l
);
594 ret
= pm_runtime_put_sync(mdev
->dev
);
595 if (ret
< 0 && ret
!= -ENOSYS
)
601 static struct platform_driver omap_mbox_driver
= {
602 .probe
= omap_mbox_probe
,
604 .name
= "omap-mailbox",
605 .pm
= &omap_mbox_pm_ops
,
606 .of_match_table
= omap_mailbox_of_match
,
609 module_platform_driver(omap_mbox_driver
);
611 MODULE_LICENSE("GPL v2");
612 MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
613 MODULE_AUTHOR("Toshihiro Kobayashi");
614 MODULE_AUTHOR("Hiroshi DOYU");