[PATCH V2 2/2] mailbox: Introduce TI message manager driver

Jassi Brar jassisinghbrar at gmail.com
Thu Mar 3 21:18:22 PST 2016


On Sat, Feb 27, 2016 at 3:54 AM, Nishanth Menon <nm at ti.com> wrote:
> Support for TI Message Manager Module. This hardware block manages a
> bunch of hardware queues meant for communication between processor
> entities.
>
> Clients sitting on top of this would manage the required protocol
> for communicating with the counterpart entities.
>
> For more details on TI Message Manager hardware block, see documentation
> that will is available here: http://www.ti.com/lit/ug/spruhy8/spruhy8.pdf
> Chapter 8.1(Message Manager)
>
> Signed-off-by: Nishanth Menon <nm at ti.com>
> ---
> V2: Changes since V1:
>         - Major refactoring of code for binding changes
>         - moved list of valid K2G queueus into driver
>         - split up probe into sub functions for easier maintenance
>
> V1: https://patchwork.kernel.org/patch/8237171/
>
>  drivers/mailbox/Kconfig     |  11 +
>  drivers/mailbox/Makefile    |   2 +
>  drivers/mailbox/ti-msgmgr.c | 657
Do you want to call it something more specific than 'msgmgr from TI'?
Maybe its about Keystone, like mailbox-keystone.c ?


> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/ti-msgmgr.h>
>
This seems a bit bold. I think  include/linux/soc/ti/ is the right place.


> +       /* Do I actually have messages to read? */
> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
> +       if (!msg_count) {
> +               /* Shared IRQ? */
> +               dev_dbg(dev, "Spurious event - 0 pending data!\n");
> +               return IRQ_NONE;
> +       }
> +
> +       /*
> +        * I have no idea about the protocol being used to communicate with the
> +        * remote producer - 0 could be valid data, so I wont make a judgement
> +        * of how many bytes I should be reading. Let the client figure this
> +        * out.. I just read the full message and pass it on..
> +        */
Exactly. And similarly when you send data, you should not have more
than one message in transit. Now please see my note in
ti_msgmgr_send_data()


> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
> +{
> +       struct device *dev = chan->mbox->dev;
> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
> +       const struct ti_msgmgr_desc *desc;
> +       struct ti_queue_inst *qinst = chan->con_priv;
> +       int msg_count, num_words, trail_bytes;
> +       struct ti_msgmgr_message *message = data;
> +       void __iomem *data_reg;
> +       u32 *word_data;
> +
> +       if (WARN_ON(!inst)) {
> +               dev_err(dev, "no platform drv data??\n");
> +               return -EINVAL;
> +       }
> +       desc = inst->desc;
> +
> +       if (desc->max_message_size < message->len) {
> +               dev_err(dev, "Queue %s message length %d > max %d\n",
> +                       qinst->name, message->len, desc->max_message_size);
> +               return -EINVAL;
> +       }
> +
> +       /* Are we able to send this or not? */
> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
> +       if (msg_count >= desc->max_messages) {
> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
> +                        msg_count);
> +               return -EBUSY;
> +       }
This seems fishy. mailbox api always submit 1 'complete' message to be
sent and checks for completion by last_tx_done() before calling
send_data() again. Controller drivers are not supposed to queue
messages - mailbox core does. So you should never be unable to send a
message.


> +       /*
> +        * NOTE about register access involved here:
> +        * the hardware block is implemented with 32bit access operations and no
> +        * support for data splitting.  We don't want the hardware to misbehave
> +        * with sub 32bit access - For example: if the last register write is
> +        * split into byte wise access, it can result in the queue getting
> +        * stuck or dummy messages being transmitted or indeterminate behavior.
> +        * The same can occur if out of order operations take place.
> +        * Hence, we do not use memcpy_toio or ___iowrite32_copy here, instead
> +        * we use writel which ensures the sequencing we need.
> +        */
.... deja-vu ?


> +
> +/* Keystone K2G SoC integration details */
> +static const struct ti_msgmgr_valid_queue_desc k2g_valid_queues[] = {
> +       {.queue_id = 0, .proxy_id = 0, .is_tx = true,},
> +       {.queue_id = 1, .proxy_id = 0, .is_tx = true,},
> +       {.queue_id = 2, .proxy_id = 0, .is_tx = true,},
> +       {.queue_id = 3, .proxy_id = 0, .is_tx = true,},
> +       {.queue_id = 5, .proxy_id = 2, .is_tx = false,},
> +       {.queue_id = 56, .proxy_id = 1, .is_tx = true,},
> +       {.queue_id = 57, .proxy_id = 2, .is_tx = false,},
> +       {.queue_id = 58, .proxy_id = 3, .is_tx = true,},
> +       {.queue_id = 59, .proxy_id = 4, .is_tx = true,},
> +       {.queue_id = 60, .proxy_id = 5, .is_tx = true,},
> +       {.queue_id = 61, .proxy_id = 6, .is_tx = true,},
> +};
> +
> +static const struct ti_msgmgr_desc k2g_desc = {
> +       .queue_count = 64,
> +       .max_message_size = 64,
> +       .max_messages = 128,
> +       .q_slices = 1,
> +       .q_proxies = 1,
> +       .data_first_reg = 16,
> +       .data_last_reg = 31,
> +       .tx_polled = false,
> +       .valid_queues = k2g_valid_queues,
> +       .num_valid_queues = ARRAY_SIZE(k2g_valid_queues),
> +};
If these parameters are very configurable, maybe they should be in DT?

Thanks.



More information about the linux-arm-kernel mailing list