Commit 8841a66a authored by Suman Anna's avatar Suman Anna Committed by Jassi Brar

mailbox/omap: adapt to the new mailbox framework

The OMAP mailbox driver and its existing clients (remoteproc
for OMAP4+) are adapted to use the generic mailbox framework.

The main changes for the adaptation are:
  - The tasklet used for Tx is replaced with the state machine from
    the generic mailbox framework. The workqueue used for processing
    the received messages stays intact for minimizing the effects on
    the OMAP mailbox clients.
  - The existing exported client API, omap_mbox_get, omap_mbox_put and
    omap_mbox_send_msg are deleted, as the framework provides equivalent
    functionality. A OMAP-specific omap_mbox_request_channel is added
    though to support non-DT way of requesting mailboxes.
  - The OMAP mailbox driver is integrated with the mailbox framework
    through the proper implementations of mbox_chan_ops, except for
    .last_tx_done and .peek_data. The OMAP mailbox driver does not need
    these ops, as it is completely interrupt driven.
  - The OMAP mailbox driver uses a custom of_xlate controller ops that
    allows phandles for the pargs specifier instead of indexing to avoid
    any channel registration order dependencies.
  - The new framework does not support multiple clients operating on a
    single channel, so the reference counting logic is simplified.
  - The remoteproc driver (current client) is adapted to use the new API.
    The notifier callbacks used within this client is replaced with the
    regular callbacks from the newer framework.
  - The exported OMAP mailbox API are limited to omap_mbox_save_ctx,
    omap_mbox_restore_ctx, omap_mbox_enable_irq & omap_mbox_disable_irq,
    with the signature modified to take in the new mbox_chan handle instead
    of the OMAP specific omap_mbox handle. The first 2 will be removed when
    the OMAP mailbox driver is adapted to runtime_pm. The other exported
    API omap_mbox_request_channel will be removed once existing legacy
    users are converted to DT.
Signed-off-by: default avatarSuman Anna <s-anna@ti.com>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: default avatarJassi Brar <jaswinder.singh@linaro.org>
parent 97b0c7bd
...@@ -43,6 +43,9 @@ Required properties: ...@@ -43,6 +43,9 @@ Required properties:
device. The format is dependent on which interrupt device. The format is dependent on which interrupt
controller the OMAP device uses controller the OMAP device uses
- ti,hwmods: Name of the hwmod associated with the mailbox - ti,hwmods: Name of the hwmod associated with the mailbox
- #mbox-cells: Common mailbox binding property to identify the number
of cells required for the mailbox specifier. Should be
1
- ti,mbox-num-users: Number of targets (processor devices) that the mailbox - ti,mbox-num-users: Number of targets (processor devices) that the mailbox
device can interrupt device can interrupt
- ti,mbox-num-fifos: Number of h/w fifo queues within the mailbox IP block - ti,mbox-num-fifos: Number of h/w fifo queues within the mailbox IP block
...@@ -72,6 +75,18 @@ data that represent the following: ...@@ -72,6 +75,18 @@ data that represent the following:
Cell #3 (usr_id) - mailbox user id for identifying the interrupt line Cell #3 (usr_id) - mailbox user id for identifying the interrupt line
associated with generating a tx/rx fifo interrupt. associated with generating a tx/rx fifo interrupt.
Mailbox Users:
==============
A device needing to communicate with a target processor device should specify
them using the common mailbox binding properties, "mboxes" and the optional
"mbox-names" (please see Documentation/devicetree/bindings/mailbox/mailbox.txt
for details). Each value of the mboxes property should contain a phandle to the
mailbox controller device node and an args specifier that will be the phandle to
the intended sub-mailbox child node to be used for communication. The equivalent
"mbox-names" property value can be used to give a name to the communication channel
to be used by the client user.
Example: Example:
-------- --------
...@@ -81,6 +96,7 @@ mailbox: mailbox@4a0f4000 { ...@@ -81,6 +96,7 @@ mailbox: mailbox@4a0f4000 {
reg = <0x4a0f4000 0x200>; reg = <0x4a0f4000 0x200>;
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "mailbox"; ti,hwmods = "mailbox";
#mbox-cells = <1>;
ti,mbox-num-users = <3>; ti,mbox-num-users = <3>;
ti,mbox-num-fifos = <8>; ti,mbox-num-fifos = <8>;
mbox_ipu: mbox_ipu { mbox_ipu: mbox_ipu {
...@@ -93,12 +109,19 @@ mailbox: mailbox@4a0f4000 { ...@@ -93,12 +109,19 @@ mailbox: mailbox@4a0f4000 {
}; };
}; };
dsp {
...
mboxes = <&mailbox &mbox_dsp>;
...
};
/* AM33xx */ /* AM33xx */
mailbox: mailbox@480C8000 { mailbox: mailbox@480C8000 {
compatible = "ti,omap4-mailbox"; compatible = "ti,omap4-mailbox";
reg = <0x480C8000 0x200>; reg = <0x480C8000 0x200>;
interrupts = <77>; interrupts = <77>;
ti,hwmods = "mailbox"; ti,hwmods = "mailbox";
#mbox-cells = <1>;
ti,mbox-num-users = <4>; ti,mbox-num-users = <4>;
ti,mbox-num-fifos = <8>; ti,mbox-num-fifos = <8>;
mbox_wkupm3: wkup_m3 { mbox_wkupm3: wkup_m3 {
......
This diff is collapsed.
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/remoteproc.h> #include <linux/remoteproc.h>
#include <linux/mailbox_client.h>
#include <linux/omap-mailbox.h> #include <linux/omap-mailbox.h>
#include <linux/platform_data/remoteproc-omap.h> #include <linux/platform_data/remoteproc-omap.h>
...@@ -36,20 +37,19 @@ ...@@ -36,20 +37,19 @@
/** /**
* struct omap_rproc - omap remote processor state * struct omap_rproc - omap remote processor state
* @mbox: omap mailbox handle * @mbox: mailbox channel handle
* @nb: notifier block that will be invoked on inbound mailbox messages * @client: mailbox client to request the mailbox channel
* @rproc: rproc handle * @rproc: rproc handle
*/ */
struct omap_rproc { struct omap_rproc {
struct omap_mbox *mbox; struct mbox_chan *mbox;
struct notifier_block nb; struct mbox_client client;
struct rproc *rproc; struct rproc *rproc;
}; };
/** /**
* omap_rproc_mbox_callback() - inbound mailbox message handler * omap_rproc_mbox_callback() - inbound mailbox message handler
* @this: notifier block * @client: mailbox client pointer used for requesting the mailbox channel
* @index: unused
* @data: mailbox payload * @data: mailbox payload
* *
* This handler is invoked by omap's mailbox driver whenever a mailbox * This handler is invoked by omap's mailbox driver whenever a mailbox
...@@ -61,13 +61,13 @@ struct omap_rproc { ...@@ -61,13 +61,13 @@ struct omap_rproc {
* that indicates different events. Those values are deliberately very * that indicates different events. Those values are deliberately very
* big so they don't coincide with virtqueue indices. * big so they don't coincide with virtqueue indices.
*/ */
static int omap_rproc_mbox_callback(struct notifier_block *this, static void omap_rproc_mbox_callback(struct mbox_client *client, void *data)
unsigned long index, void *data)
{ {
mbox_msg_t msg = (mbox_msg_t) data; struct omap_rproc *oproc = container_of(client, struct omap_rproc,
struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb); client);
struct device *dev = oproc->rproc->dev.parent; struct device *dev = oproc->rproc->dev.parent;
const char *name = oproc->rproc->name; const char *name = oproc->rproc->name;
u32 msg = (u32)data;
dev_dbg(dev, "mbox msg: 0x%x\n", msg); dev_dbg(dev, "mbox msg: 0x%x\n", msg);
...@@ -84,8 +84,6 @@ static int omap_rproc_mbox_callback(struct notifier_block *this, ...@@ -84,8 +84,6 @@ static int omap_rproc_mbox_callback(struct notifier_block *this,
if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE) if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE)
dev_dbg(dev, "no message was found in vqid %d\n", msg); dev_dbg(dev, "no message was found in vqid %d\n", msg);
} }
return NOTIFY_DONE;
} }
/* kick a virtqueue */ /* kick a virtqueue */
...@@ -96,8 +94,8 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid) ...@@ -96,8 +94,8 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
int ret; int ret;
/* send the index of the triggered virtqueue in the mailbox payload */ /* send the index of the triggered virtqueue in the mailbox payload */
ret = omap_mbox_msg_send(oproc->mbox, vqid); ret = mbox_send_message(oproc->mbox, (void *)vqid);
if (ret) if (ret < 0)
dev_err(dev, "omap_mbox_msg_send failed: %d\n", ret); dev_err(dev, "omap_mbox_msg_send failed: %d\n", ret);
} }
...@@ -115,17 +113,22 @@ static int omap_rproc_start(struct rproc *rproc) ...@@ -115,17 +113,22 @@ static int omap_rproc_start(struct rproc *rproc)
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct omap_rproc_pdata *pdata = pdev->dev.platform_data; struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
int ret; int ret;
struct mbox_client *client = &oproc->client;
if (pdata->set_bootaddr) if (pdata->set_bootaddr)
pdata->set_bootaddr(rproc->bootaddr); pdata->set_bootaddr(rproc->bootaddr);
oproc->nb.notifier_call = omap_rproc_mbox_callback; client->dev = dev;
client->tx_done = NULL;
client->rx_callback = omap_rproc_mbox_callback;
client->tx_block = false;
client->knows_txdone = false;
/* every omap rproc is assigned a mailbox instance for messaging */ oproc->mbox = omap_mbox_request_channel(client, pdata->mbox_name);
oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb);
if (IS_ERR(oproc->mbox)) { if (IS_ERR(oproc->mbox)) {
ret = PTR_ERR(oproc->mbox); ret = -EBUSY;
dev_err(dev, "omap_mbox_get failed: %d\n", ret); dev_err(dev, "mbox_request_channel failed: %ld\n",
PTR_ERR(oproc->mbox));
return ret; return ret;
} }
...@@ -136,9 +139,9 @@ static int omap_rproc_start(struct rproc *rproc) ...@@ -136,9 +139,9 @@ static int omap_rproc_start(struct rproc *rproc)
* Note that the reply will _not_ arrive immediately: this message * Note that the reply will _not_ arrive immediately: this message
* will wait in the mailbox fifo until the remote processor is booted. * will wait in the mailbox fifo until the remote processor is booted.
*/ */
ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST); ret = mbox_send_message(oproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
if (ret) { if (ret < 0) {
dev_err(dev, "omap_mbox_get failed: %d\n", ret); dev_err(dev, "mbox_send_message failed: %d\n", ret);
goto put_mbox; goto put_mbox;
} }
...@@ -151,7 +154,7 @@ static int omap_rproc_start(struct rproc *rproc) ...@@ -151,7 +154,7 @@ static int omap_rproc_start(struct rproc *rproc)
return 0; return 0;
put_mbox: put_mbox:
omap_mbox_put(oproc->mbox, &oproc->nb); mbox_free_channel(oproc->mbox);
return ret; return ret;
} }
...@@ -168,7 +171,7 @@ static int omap_rproc_stop(struct rproc *rproc) ...@@ -168,7 +171,7 @@ static int omap_rproc_stop(struct rproc *rproc)
if (ret) if (ret)
return ret; return ret;
omap_mbox_put(oproc->mbox, &oproc->nb); mbox_free_channel(oproc->mbox);
return 0; return 0;
} }
......
...@@ -10,20 +10,20 @@ ...@@ -10,20 +10,20 @@
#define OMAP_MAILBOX_H #define OMAP_MAILBOX_H
typedef u32 mbox_msg_t; typedef u32 mbox_msg_t;
struct omap_mbox;
typedef int __bitwise omap_mbox_irq_t; typedef int __bitwise omap_mbox_irq_t;
#define IRQ_TX ((__force omap_mbox_irq_t) 1) #define IRQ_TX ((__force omap_mbox_irq_t) 1)
#define IRQ_RX ((__force omap_mbox_irq_t) 2) #define IRQ_RX ((__force omap_mbox_irq_t) 2)
int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); struct mbox_chan;
struct mbox_client;
struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); const char *chan_name);
void omap_mbox_save_ctx(struct omap_mbox *mbox); void omap_mbox_save_ctx(struct mbox_chan *chan);
void omap_mbox_restore_ctx(struct omap_mbox *mbox); void omap_mbox_restore_ctx(struct mbox_chan *chan);
void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); void omap_mbox_enable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq);
void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); void omap_mbox_disable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq);
#endif /* OMAP_MAILBOX_H */ #endif /* OMAP_MAILBOX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment