1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright Altera Corporation (C) 2013-2014. All rights reserved
6 #include <linux/device.h>
7 #include <linux/interrupt.h>
9 #include <linux/kernel.h>
10 #include <linux/mailbox_controller.h>
11 #include <linux/module.h>
13 #include <linux/platform_device.h>
15 #define DRIVER_NAME "altera-mailbox"
17 #define MAILBOX_CMD_REG 0x00
18 #define MAILBOX_PTR_REG 0x04
19 #define MAILBOX_STS_REG 0x08
20 #define MAILBOX_INTMASK_REG 0x0C
22 #define INT_PENDING_MSK 0x1
23 #define INT_SPACE_MSK 0x2
25 #define STS_PENDING_MSK 0x1
26 #define STS_FULL_MSK 0x2
27 #define STS_FULL_OFT 0x1
29 #define MBOX_PENDING(status) (((status) & STS_PENDING_MSK))
30 #define MBOX_FULL(status) (((status) & STS_FULL_MSK) >> STS_FULL_OFT)
32 enum altera_mbox_msg
{
37 #define MBOX_POLLING_MS 5 /* polling interval 5ms */
40 bool is_sender
; /* 1-sender, 0-receiver */
43 void __iomem
*mbox_base
;
45 struct mbox_controller controller
;
47 /* If the controller supports only RX polling mode */
48 struct timer_list rxpoll_timer
;
49 struct mbox_chan
*chan
;
52 static struct altera_mbox
*mbox_chan_to_altera_mbox(struct mbox_chan
*chan
)
54 if (!chan
|| !chan
->con_priv
)
57 return (struct altera_mbox
*)chan
->con_priv
;
60 static inline int altera_mbox_full(struct altera_mbox
*mbox
)
64 status
= readl_relaxed(mbox
->mbox_base
+ MAILBOX_STS_REG
);
65 return MBOX_FULL(status
);
68 static inline int altera_mbox_pending(struct altera_mbox
*mbox
)
72 status
= readl_relaxed(mbox
->mbox_base
+ MAILBOX_STS_REG
);
73 return MBOX_PENDING(status
);
76 static void altera_mbox_rx_intmask(struct altera_mbox
*mbox
, bool enable
)
80 mask
= readl_relaxed(mbox
->mbox_base
+ MAILBOX_INTMASK_REG
);
82 mask
|= INT_PENDING_MSK
;
84 mask
&= ~INT_PENDING_MSK
;
85 writel_relaxed(mask
, mbox
->mbox_base
+ MAILBOX_INTMASK_REG
);
88 static void altera_mbox_tx_intmask(struct altera_mbox
*mbox
, bool enable
)
92 mask
= readl_relaxed(mbox
->mbox_base
+ MAILBOX_INTMASK_REG
);
94 mask
|= INT_SPACE_MSK
;
96 mask
&= ~INT_SPACE_MSK
;
97 writel_relaxed(mask
, mbox
->mbox_base
+ MAILBOX_INTMASK_REG
);
100 static bool altera_mbox_is_sender(struct altera_mbox
*mbox
)
103 /* Write a magic number to PTR register and read back this register.
104 * This register is read-write if it is a sender.
106 #define MBOX_MAGIC 0xA5A5AA55
107 writel_relaxed(MBOX_MAGIC
, mbox
->mbox_base
+ MAILBOX_PTR_REG
);
108 reg
= readl_relaxed(mbox
->mbox_base
+ MAILBOX_PTR_REG
);
109 if (reg
== MBOX_MAGIC
) {
111 writel_relaxed(0, mbox
->mbox_base
+ MAILBOX_PTR_REG
);
117 static void altera_mbox_rx_data(struct mbox_chan
*chan
)
119 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
122 if (altera_mbox_pending(mbox
)) {
124 readl_relaxed(mbox
->mbox_base
+ MAILBOX_PTR_REG
);
126 readl_relaxed(mbox
->mbox_base
+ MAILBOX_CMD_REG
);
127 mbox_chan_received_data(chan
, (void *)data
);
131 static void altera_mbox_poll_rx(struct timer_list
*t
)
133 struct altera_mbox
*mbox
= from_timer(mbox
, t
, rxpoll_timer
);
135 altera_mbox_rx_data(mbox
->chan
);
137 mod_timer(&mbox
->rxpoll_timer
,
138 jiffies
+ msecs_to_jiffies(MBOX_POLLING_MS
));
141 static irqreturn_t
altera_mbox_tx_interrupt(int irq
, void *p
)
143 struct mbox_chan
*chan
= (struct mbox_chan
*)p
;
144 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
146 altera_mbox_tx_intmask(mbox
, false);
147 mbox_chan_txdone(chan
, 0);
152 static irqreturn_t
altera_mbox_rx_interrupt(int irq
, void *p
)
154 struct mbox_chan
*chan
= (struct mbox_chan
*)p
;
156 altera_mbox_rx_data(chan
);
160 static int altera_mbox_startup_sender(struct mbox_chan
*chan
)
163 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
165 if (mbox
->intr_mode
) {
166 ret
= request_irq(mbox
->irq
, altera_mbox_tx_interrupt
, 0,
170 "failed to register mailbox interrupt:%d\n",
179 static int altera_mbox_startup_receiver(struct mbox_chan
*chan
)
182 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
184 if (mbox
->intr_mode
) {
185 ret
= request_irq(mbox
->irq
, altera_mbox_rx_interrupt
, 0,
188 mbox
->intr_mode
= false;
189 goto polling
; /* use polling if failed */
192 altera_mbox_rx_intmask(mbox
, true);
197 /* Setup polling timer */
199 timer_setup(&mbox
->rxpoll_timer
, altera_mbox_poll_rx
, 0);
200 mod_timer(&mbox
->rxpoll_timer
,
201 jiffies
+ msecs_to_jiffies(MBOX_POLLING_MS
));
206 static int altera_mbox_send_data(struct mbox_chan
*chan
, void *data
)
208 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
209 u32
*udata
= (u32
*)data
;
213 if (!mbox
->is_sender
) {
215 "failed to send. This is receiver mailbox.\n");
219 if (altera_mbox_full(mbox
))
222 /* Enable interrupt before send */
224 altera_mbox_tx_intmask(mbox
, true);
226 /* Pointer register must write before command register */
227 writel_relaxed(udata
[MBOX_PTR
], mbox
->mbox_base
+ MAILBOX_PTR_REG
);
228 writel_relaxed(udata
[MBOX_CMD
], mbox
->mbox_base
+ MAILBOX_CMD_REG
);
233 static bool altera_mbox_last_tx_done(struct mbox_chan
*chan
)
235 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
237 /* Return false if mailbox is full */
238 return altera_mbox_full(mbox
) ? false : true;
241 static bool altera_mbox_peek_data(struct mbox_chan
*chan
)
243 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
245 return altera_mbox_pending(mbox
) ? true : false;
248 static int altera_mbox_startup(struct mbox_chan
*chan
)
250 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
257 ret
= altera_mbox_startup_sender(chan
);
259 ret
= altera_mbox_startup_receiver(chan
);
264 static void altera_mbox_shutdown(struct mbox_chan
*chan
)
266 struct altera_mbox
*mbox
= mbox_chan_to_altera_mbox(chan
);
268 if (mbox
->intr_mode
) {
269 /* Unmask all interrupt masks */
270 writel_relaxed(~0, mbox
->mbox_base
+ MAILBOX_INTMASK_REG
);
271 free_irq(mbox
->irq
, chan
);
272 } else if (!mbox
->is_sender
) {
273 del_timer_sync(&mbox
->rxpoll_timer
);
277 static const struct mbox_chan_ops altera_mbox_ops
= {
278 .send_data
= altera_mbox_send_data
,
279 .startup
= altera_mbox_startup
,
280 .shutdown
= altera_mbox_shutdown
,
281 .last_tx_done
= altera_mbox_last_tx_done
,
282 .peek_data
= altera_mbox_peek_data
,
285 static int altera_mbox_probe(struct platform_device
*pdev
)
287 struct altera_mbox
*mbox
;
288 struct resource
*regs
;
289 struct mbox_chan
*chans
;
292 mbox
= devm_kzalloc(&pdev
->dev
, sizeof(*mbox
),
297 /* Allocated one channel */
298 chans
= devm_kzalloc(&pdev
->dev
, sizeof(*chans
), GFP_KERNEL
);
302 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
304 mbox
->mbox_base
= devm_ioremap_resource(&pdev
->dev
, regs
);
305 if (IS_ERR(mbox
->mbox_base
))
306 return PTR_ERR(mbox
->mbox_base
);
308 /* Check is it a sender or receiver? */
309 mbox
->is_sender
= altera_mbox_is_sender(mbox
);
311 mbox
->irq
= platform_get_irq(pdev
, 0);
313 mbox
->intr_mode
= true;
315 mbox
->dev
= &pdev
->dev
;
317 /* Hardware supports only one channel. */
318 chans
[0].con_priv
= mbox
;
319 mbox
->controller
.dev
= mbox
->dev
;
320 mbox
->controller
.num_chans
= 1;
321 mbox
->controller
.chans
= chans
;
322 mbox
->controller
.ops
= &altera_mbox_ops
;
324 if (mbox
->is_sender
) {
325 if (mbox
->intr_mode
) {
326 mbox
->controller
.txdone_irq
= true;
328 mbox
->controller
.txdone_poll
= true;
329 mbox
->controller
.txpoll_period
= MBOX_POLLING_MS
;
333 ret
= devm_mbox_controller_register(&pdev
->dev
, &mbox
->controller
);
335 dev_err(&pdev
->dev
, "Register mailbox failed\n");
339 platform_set_drvdata(pdev
, mbox
);
344 static const struct of_device_id altera_mbox_match
[] = {
345 { .compatible
= "altr,mailbox-1.0" },
349 MODULE_DEVICE_TABLE(of
, altera_mbox_match
);
351 static struct platform_driver altera_mbox_driver
= {
352 .probe
= altera_mbox_probe
,
355 .of_match_table
= altera_mbox_match
,
359 module_platform_driver(altera_mbox_driver
);
361 MODULE_LICENSE("GPL v2");
362 MODULE_DESCRIPTION("Altera mailbox specific functions");
363 MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
364 MODULE_ALIAS("platform:altera-mailbox");