ti-msgmgr.c (cb62b8f7346338eeefa6d46160200879dc345246) ti-msgmgr.c (df227dc8a68d81b7fe3416eca16d1f21d0b537f0)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Texas Instruments' Message Manager Driver
4 *
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Texas Instruments' Message Manager Driver
4 *
5 * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
5 * Copyright (C) 2015-2022 Texas Instruments Incorporated - https://www.ti.com/
6 * Nishanth Menon
7 */
8
9#define pr_fmt(fmt) "%s: " fmt, __func__
10
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
6 * Nishanth Menon
7 */
8
9#define pr_fmt(fmt) "%s: " fmt, __func__
10
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/iopoll.h>
14#include <linux/kernel.h>
15#include <linux/mailbox_controller.h>
16#include <linux/module.h>
17#include <linux/of_device.h>
18#include <linux/of.h>
19#include <linux/of_irq.h>
20#include <linux/platform_device.h>
21#include <linux/soc/ti/ti-msgmgr.h>

--- 73 unchanged lines hidden (view full) ---

95 * @irq: IRQ for Rx Queue
96 * @is_tx: 'true' if transmit queue, else, 'false'
97 * @queue_buff_start: First register of Data Buffer
98 * @queue_buff_end: Last (or confirmation) register of Data buffer
99 * @queue_state: Queue status register
100 * @queue_ctrl: Queue Control register
101 * @chan: Mailbox channel
102 * @rx_buff: Receive buffer pointer allocated at probe, max_message_size
15#include <linux/kernel.h>
16#include <linux/mailbox_controller.h>
17#include <linux/module.h>
18#include <linux/of_device.h>
19#include <linux/of.h>
20#include <linux/of_irq.h>
21#include <linux/platform_device.h>
22#include <linux/soc/ti/ti-msgmgr.h>

--- 73 unchanged lines hidden (view full) ---

96 * @irq: IRQ for Rx Queue
97 * @is_tx: 'true' if transmit queue, else, 'false'
98 * @queue_buff_start: First register of Data Buffer
99 * @queue_buff_end: Last (or confirmation) register of Data buffer
100 * @queue_state: Queue status register
101 * @queue_ctrl: Queue Control register
102 * @chan: Mailbox channel
103 * @rx_buff: Receive buffer pointer allocated at probe, max_message_size
104 * @polled_rx_mode: Use polling for rx instead of interrupts
103 */
104struct ti_queue_inst {
105 char name[30];
106 u8 queue_id;
107 u8 proxy_id;
108 int irq;
109 bool is_tx;
110 void __iomem *queue_buff_start;
111 void __iomem *queue_buff_end;
112 void __iomem *queue_state;
113 void __iomem *queue_ctrl;
114 struct mbox_chan *chan;
115 u32 *rx_buff;
105 */
106struct ti_queue_inst {
107 char name[30];
108 u8 queue_id;
109 u8 proxy_id;
110 int irq;
111 bool is_tx;
112 void __iomem *queue_buff_start;
113 void __iomem *queue_buff_end;
114 void __iomem *queue_state;
115 void __iomem *queue_ctrl;
116 struct mbox_chan *chan;
117 u32 *rx_buff;
118 bool polled_rx_mode;
116};
117
118/**
119 * struct ti_msgmgr_inst - Description of a Message Manager Instance
120 * @dev: device pointer corresponding to the Message Manager instance
121 * @desc: Description of the SoC integration
122 * @queue_proxy_region: Queue proxy region where queue buffers are located
123 * @queue_state_debug_region: Queue status register regions

--- 108 unchanged lines hidden (view full) ---

232 * NOTE: Client is expected to be as optimal as possible, since
233 * we invoke the handler in IRQ context.
234 */
235 mbox_chan_received_data(chan, (void *)&message);
236
237 return 0;
238}
239
119};
120
121/**
122 * struct ti_msgmgr_inst - Description of a Message Manager Instance
123 * @dev: device pointer corresponding to the Message Manager instance
124 * @desc: Description of the SoC integration
125 * @queue_proxy_region: Queue proxy region where queue buffers are located
126 * @queue_state_debug_region: Queue status register regions

--- 108 unchanged lines hidden (view full) ---

235 * NOTE: Client is expected to be as optimal as possible, since
236 * we invoke the handler in IRQ context.
237 */
238 mbox_chan_received_data(chan, (void *)&message);
239
240 return 0;
241}
242
243static int ti_msgmgr_queue_rx_poll_timeout(struct mbox_chan *chan, int timeout_us)
244{
245 struct device *dev = chan->mbox->dev;
246 struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
247 struct ti_queue_inst *qinst = chan->con_priv;
248 const struct ti_msgmgr_desc *desc = inst->desc;
249 int msg_count;
250 int ret;
251
252 ret = readl_poll_timeout_atomic(qinst->queue_state, msg_count,
253 (msg_count & desc->status_cnt_mask),
254 10, timeout_us);
255 if (ret != 0)
256 return ret;
257
258 ti_msgmgr_queue_rx_data(chan, qinst, desc);
259
260 return 0;
261}
262
240/**
241 * ti_msgmgr_queue_rx_interrupt() - Interrupt handler for receive Queue
242 * @irq: Interrupt number
243 * @p: Channel Pointer
244 *
245 * Return: -EINVAL if there is no instance
246 * IRQ_NONE if the interrupt is not ours.
247 * IRQ_HANDLED if the rx interrupt was successfully handled.

--- 93 unchanged lines hidden (view full) ---

341 /* In secure proxy, msg_count indicates how many we can send */
342 return msg_count ? true : false;
343 }
344
345 /* if we have any messages pending.. */
346 return msg_count ? false : true;
347}
348
263/**
264 * ti_msgmgr_queue_rx_interrupt() - Interrupt handler for receive Queue
265 * @irq: Interrupt number
266 * @p: Channel Pointer
267 *
268 * Return: -EINVAL if there is no instance
269 * IRQ_NONE if the interrupt is not ours.
270 * IRQ_HANDLED if the rx interrupt was successfully handled.

--- 93 unchanged lines hidden (view full) ---

364 /* In secure proxy, msg_count indicates how many we can send */
365 return msg_count ? true : false;
366 }
367
368 /* if we have any messages pending.. */
369 return msg_count ? false : true;
370}
371
372static bool ti_msgmgr_chan_has_polled_queue_rx(struct mbox_chan *chan)
373{
374 struct ti_queue_inst *qinst;
375
376 if (!chan)
377 return false;
378
379 qinst = chan->con_priv;
380 return qinst->polled_rx_mode;
381}
382
349/**
350 * ti_msgmgr_send_data() - Send data
351 * @chan: Channel Pointer
352 * @data: ti_msgmgr_message * Message Pointer
353 *
354 * Return: 0 if all goes good, else appropriate error messages.
355 */
356static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
357{
358 struct device *dev = chan->mbox->dev;
359 struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
360 const struct ti_msgmgr_desc *desc;
361 struct ti_queue_inst *qinst = chan->con_priv;
362 int num_words, trail_bytes;
363 struct ti_msgmgr_message *message = data;
364 void __iomem *data_reg;
365 u32 *word_data;
383/**
384 * ti_msgmgr_send_data() - Send data
385 * @chan: Channel Pointer
386 * @data: ti_msgmgr_message * Message Pointer
387 *
388 * Return: 0 if all goes good, else appropriate error messages.
389 */
390static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
391{
392 struct device *dev = chan->mbox->dev;
393 struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
394 const struct ti_msgmgr_desc *desc;
395 struct ti_queue_inst *qinst = chan->con_priv;
396 int num_words, trail_bytes;
397 struct ti_msgmgr_message *message = data;
398 void __iomem *data_reg;
399 u32 *word_data;
400 int ret = 0;
366
367 if (WARN_ON(!inst)) {
368 dev_err(dev, "no platform drv data??\n");
369 return -EINVAL;
370 }
371 desc = inst->desc;
372
373 if (ti_msgmgr_queue_is_error(desc, qinst)) {

--- 25 unchanged lines hidden (view full) ---

399 }
400 /*
401 * 'data_reg' indicates next register to write. If we did not already
402 * write on tx complete reg(last reg), we must do so for transmit
403 */
404 if (data_reg <= qinst->queue_buff_end)
405 writel(0, qinst->queue_buff_end);
406
401
402 if (WARN_ON(!inst)) {
403 dev_err(dev, "no platform drv data??\n");
404 return -EINVAL;
405 }
406 desc = inst->desc;
407
408 if (ti_msgmgr_queue_is_error(desc, qinst)) {

--- 25 unchanged lines hidden (view full) ---

434 }
435 /*
436 * 'data_reg' indicates next register to write. If we did not already
437 * write on tx complete reg(last reg), we must do so for transmit
438 */
439 if (data_reg <= qinst->queue_buff_end)
440 writel(0, qinst->queue_buff_end);
441
407 return 0;
442 /* If we are in polled mode, wait for a response before proceeding */
443 if (ti_msgmgr_chan_has_polled_queue_rx(message->chan_rx))
444 ret = ti_msgmgr_queue_rx_poll_timeout(message->chan_rx,
445 message->timeout_rx_ms * 1000);
446
447 return ret;
408}
409
410/**
411 * ti_msgmgr_queue_rx_irq_req() - RX IRQ request
412 * @dev: device pointer
413 * @d: descriptor for ti_msgmgr
414 * @qinst: Queue instance
415 * @chan: Channel pointer

--- 231 unchanged lines hidden (view full) ---

647 chan->con_priv = qinst;
648
649 dev_dbg(dev, "[%d] qidx=%d pidx=%d irq=%d q_s=%p q_e = %p\n",
650 idx, qinst->queue_id, qinst->proxy_id, qinst->irq,
651 qinst->queue_buff_start, qinst->queue_buff_end);
652 return 0;
653}
654
448}
449
450/**
451 * ti_msgmgr_queue_rx_irq_req() - RX IRQ request
452 * @dev: device pointer
453 * @d: descriptor for ti_msgmgr
454 * @qinst: Queue instance
455 * @chan: Channel pointer

--- 231 unchanged lines hidden (view full) ---

687 chan->con_priv = qinst;
688
689 dev_dbg(dev, "[%d] qidx=%d pidx=%d irq=%d q_s=%p q_e = %p\n",
690 idx, qinst->queue_id, qinst->proxy_id, qinst->irq,
691 qinst->queue_buff_start, qinst->queue_buff_end);
692 return 0;
693}
694
695static int ti_msgmgr_queue_rx_set_polled_mode(struct ti_queue_inst *qinst, bool enable)
696{
697 if (enable) {
698 disable_irq(qinst->irq);
699 qinst->polled_rx_mode = true;
700 } else {
701 enable_irq(qinst->irq);
702 qinst->polled_rx_mode = false;
703 }
704
705 return 0;
706}
707
708static int ti_msgmgr_suspend(struct device *dev)
709{
710 struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
711 struct ti_queue_inst *qinst;
712 int i;
713
714 /*
715 * We must switch operation to polled mode now as drivers and the genpd
716 * layer may make late TI SCI calls to change clock and device states
717 * from the noirq phase of suspend.
718 */
719 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; qinst++, i++) {
720 if (!qinst->is_tx)
721 ti_msgmgr_queue_rx_set_polled_mode(qinst, true);
722 }
723
724 return 0;
725}
726
727static int ti_msgmgr_resume(struct device *dev)
728{
729 struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
730 struct ti_queue_inst *qinst;
731 int i;
732
733 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; qinst++, i++) {
734 if (!qinst->is_tx)
735 ti_msgmgr_queue_rx_set_polled_mode(qinst, false);
736 }
737
738 return 0;
739}
740
741static DEFINE_SIMPLE_DEV_PM_OPS(ti_msgmgr_pm_ops, ti_msgmgr_suspend, ti_msgmgr_resume);
742
655/* Queue operations */
656static const struct mbox_chan_ops ti_msgmgr_chan_ops = {
657 .startup = ti_msgmgr_queue_startup,
658 .shutdown = ti_msgmgr_queue_shutdown,
659 .peek_data = ti_msgmgr_queue_peek_data,
660 .last_tx_done = ti_msgmgr_last_tx_done,
661 .send_data = ti_msgmgr_send_data,
662};

--- 171 unchanged lines hidden (view full) ---

834 return ret;
835}
836
837static struct platform_driver ti_msgmgr_driver = {
838 .probe = ti_msgmgr_probe,
839 .driver = {
840 .name = "ti-msgmgr",
841 .of_match_table = of_match_ptr(ti_msgmgr_of_match),
743/* Queue operations */
744static const struct mbox_chan_ops ti_msgmgr_chan_ops = {
745 .startup = ti_msgmgr_queue_startup,
746 .shutdown = ti_msgmgr_queue_shutdown,
747 .peek_data = ti_msgmgr_queue_peek_data,
748 .last_tx_done = ti_msgmgr_last_tx_done,
749 .send_data = ti_msgmgr_send_data,
750};

--- 171 unchanged lines hidden (view full) ---

922 return ret;
923}
924
925static struct platform_driver ti_msgmgr_driver = {
926 .probe = ti_msgmgr_probe,
927 .driver = {
928 .name = "ti-msgmgr",
929 .of_match_table = of_match_ptr(ti_msgmgr_of_match),
930 .pm = &ti_msgmgr_pm_ops,
842 },
843};
844module_platform_driver(ti_msgmgr_driver);
845
846MODULE_LICENSE("GPL v2");
847MODULE_DESCRIPTION("TI message manager driver");
848MODULE_AUTHOR("Nishanth Menon");
849MODULE_ALIAS("platform:ti-msgmgr");
931 },
932};
933module_platform_driver(ti_msgmgr_driver);
934
935MODULE_LICENSE("GPL v2");
936MODULE_DESCRIPTION("TI message manager driver");
937MODULE_AUTHOR("Nishanth Menon");
938MODULE_ALIAS("platform:ti-msgmgr");