[RFC] Inter-processor Mailboxes Drivers
Hiroshi DOYU
Hiroshi.DOYU at nokia.com
Mon Feb 14 02:32:57 EST 2011
From: ext Linus Walleij <linus.walleij at linaro.org>
Subject: Re: [RFC] Inter-processor Mailboxes Drivers
Date: Sun, 13 Feb 2011 22:16:12 +0100
> 2011/2/12 Sundar <sunder.svit at gmail.com>:
>
>> At least I would like this; I wanted to generalize such mailbox IPCs
>> right from the day when I was working on one, but coudnt really
>> work on that.
>>
>>> 2. Does something like this already exist?
>>
>> Not generic as you say; but apart from the OMAP platforms,
>> you could refer to arch/arm/mach-ux500/prcmu for a mailbox based
>> IPC on the U8500 platform.
>
> We also have this thing:
> arch/arm/mach-ux500/mbox-db5500.c
>
> It's another mailbox driver, this one talks to the modem in the
> U5500 (basically a physical transport for the CAIF protocol).
> (For the U8500 I think modem IPC is instead handled with
> a high-speed hardware FIFO, a bit different.)
>
>>> 3. Is someone else already working on this?
>>
>> Not sure of that too :), but I am CCing Linus W, the maintainer
>> of U8500 if he thinks it is a good idea to come up with a mailbox IPC
>> framework
>
> I don't know too much about the subject actually, I've not been
> deeply into any such code. I don't think anyone is working
> on something general from ST-Ericsson or Linaro.
>
> Recently I saw that Texas Instruments are posting a "hardware
> spinlock" framework though, this would be on a related tone,
> but I think it's for shared data structures (control path) rather
> than buffer passing (data path). I'm guessing this works like
> that one CPU gets to spin waiting for another one to release
> the lock.
>
> Given that we may have a framework for hardware spinlock
> and that we don't want to stockpile drivers into arch/*
> or drivers/misc/* I would say it's intuitively a good idea,
> but the question is what data types you would pass in?
> In arch/arm/mach-ux500/include/mach/mbox-db5500.h
> we have a struct like this:
>
> /**
> * struct mbox - Mailbox instance struct
> * @list: Linked list head.
> * @pdev: Pointer to device struct.
> * @cb: Callback function. Will be called
> * when new data is received.
> * @client_data: Clients private data. Will be sent back
> * in the callback function.
> * @virtbase_peer: Virtual address for outgoing mailbox.
> * @virtbase_local: Virtual address for incoming mailbox.
> * @buffer: Then internal queue for outgoing messages.
> * @name: Name of this mailbox.
> * @buffer_available: Completion variable to achieve "blocking send".
> * This variable will be signaled when there is
> * internal buffer space available.
> * @client_blocked: To keep track if any client is currently
> * blocked.
> * @lock: Spinlock to protect this mailbox instance.
> * @write_index: Index in internal buffer to write to.
> * @read_index: Index in internal buffer to read from.
> * @allocated: Indicates whether this particular mailbox
> * id has been allocated by someone.
> */
> struct mbox {
> struct list_head list;
> struct platform_device *pdev;
> mbox_recv_cb_t *cb;
> void *client_data;
> void __iomem *virtbase_peer;
> void __iomem *virtbase_local;
> u32 buffer[MBOX_BUF_SIZE];
> char name[MBOX_NAME_SIZE];
> struct completion buffer_available;
> u8 client_blocked;
> spinlock_t lock;
> u8 write_index;
> u8 read_index;
> bool allocated;
> };
>
> Compare OMAPs mailboxes in
> arch/arm/plat-omap/include/plat/mailbox.h:
>
> typedef u32 mbox_msg_t;
>
> truct omap_mbox_ops {
> omap_mbox_type_t type;
> int (*startup)(struct omap_mbox *mbox);
> void (*shutdown)(struct omap_mbox *mbox);
> /* fifo */
> mbox_msg_t (*fifo_read)(struct omap_mbox *mbox);
> void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
> int (*fifo_empty)(struct omap_mbox *mbox);
> int (*fifo_full)(struct omap_mbox *mbox);
> /* irq */
> void (*enable_irq)(struct omap_mbox *mbox,
> omap_mbox_irq_t irq);
> void (*disable_irq)(struct omap_mbox *mbox,
> omap_mbox_irq_t irq);
> void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
> int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
> /* ctx */
> void (*save_ctx)(struct omap_mbox *mbox);
> void (*restore_ctx)(struct omap_mbox *mbox);
> };
>
> struct omap_mbox_queue {
> spinlock_t lock;
> struct kfifo fifo;
> struct work_struct work;
> struct tasklet_struct tasklet;
> struct omap_mbox *mbox;
> bool full;
> };
>
> struct omap_mbox {
> char *name;
> unsigned int irq;
> struct omap_mbox_queue *txq, *rxq;
> struct omap_mbox_ops *ops;
> struct device *dev;
> void *priv;
> int use_count;
> struct blocking_notifier_head notifier;
> };
>
> Some of this may be generalized? I dunno, they look quite
> different but maybe queueing etc can actually be made general
> enough to form a framework.
OMAP mailbox is the interrupt driven 32bit unit H/W FIFO to other
cores.
"struct omap_mbox_ops" was provided mainly to absorb the difference
between OMAP1 and OMAP2+ from H/W POV. So generally the layer could
be:
-----------------------
character device driver
-----------------------
generic mailbox driver
-----------------------
H/W registration
-----------------------
In OMAP case, in addition to the above, it could be exceptionally:
-----------------------
character device driver
-----------------------
generic mailbox driver
-----------------------
H/W registration
-----------------------
OMAP 1 | OMAP2+
-----------------------
So "character device driver"(interface) and "generic mailbox
driver"(queuing) may be able to abstructed/generalized.
More information about the linux-arm-kernel
mailing list