Skip to content

Commit

Permalink
remoteproc: maintain a generic child device for each rproc
Browse files Browse the repository at this point in the history
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).

With this in hand, the resulting device hierarchy might then look like:

omap-rproc.0
 |
 - remoteproc0  <---- new !
    |
    - virtio0
    |
    - virtio1
       |
       - rpmsg0
       |
       - rpmsg1
       |
       - rpmsg2

Where:
- omap-rproc.0 is the low level device that's bound to the
  driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
  remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
  when it realizes that they are supported by the firmware
  of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
  channels, and are registerd by the rpmsg bus when it gets notified
  about their existence

Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
  device belong to.
- adds a super simple enumeration method for the indices of the
  remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
  instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
  the platform-specific memory pools, most commonly CMA, are to be found)

Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
  new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
  instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
  refcounting (see subsequent patch)

Thanks to Stephen Boyd <[email protected]> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <[email protected]> for trying them out
with the (upcoming) runtime PM support for remoteproc.

Cc: Fernando Guzman Lugo <[email protected]>
Reviewed-by: Stephen Boyd <[email protected]>
Signed-off-by: Ohad Ben-Cohen <[email protected]>
  • Loading branch information
ohadbc committed Jul 5, 2012
1 parent 6db20ea commit b5ab5e2
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 61 deletions.
17 changes: 10 additions & 7 deletions drivers/remoteproc/omap_remoteproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static int omap_rproc_mbox_callback(struct notifier_block *this,
{
mbox_msg_t msg = (mbox_msg_t) data;
struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb);
struct device *dev = oproc->rproc->dev;
struct device *dev = oproc->rproc->dev.parent;
const char *name = oproc->rproc->name;

dev_dbg(dev, "mbox msg: 0x%x\n", msg);
Expand All @@ -92,12 +92,13 @@ static int omap_rproc_mbox_callback(struct notifier_block *this,
static void omap_rproc_kick(struct rproc *rproc, int vqid)
{
struct omap_rproc *oproc = rproc->priv;
struct device *dev = rproc->dev.parent;
int ret;

/* send the index of the triggered virtqueue in the mailbox payload */
ret = omap_mbox_msg_send(oproc->mbox, vqid);
if (ret)
dev_err(rproc->dev, "omap_mbox_msg_send failed: %d\n", ret);
dev_err(dev, "omap_mbox_msg_send failed: %d\n", ret);
}

/*
Expand All @@ -110,7 +111,8 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
static int omap_rproc_start(struct rproc *rproc)
{
struct omap_rproc *oproc = rproc->priv;
struct platform_device *pdev = to_platform_device(rproc->dev);
struct device *dev = rproc->dev.parent;
struct platform_device *pdev = to_platform_device(dev);
struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
int ret;

Expand All @@ -120,7 +122,7 @@ static int omap_rproc_start(struct rproc *rproc)
oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb);
if (IS_ERR(oproc->mbox)) {
ret = PTR_ERR(oproc->mbox);
dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret);
dev_err(dev, "omap_mbox_get failed: %d\n", ret);
return ret;
}

Expand All @@ -133,13 +135,13 @@ static int omap_rproc_start(struct rproc *rproc)
*/
ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST);
if (ret) {
dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret);
dev_err(dev, "omap_mbox_get failed: %d\n", ret);
goto put_mbox;
}

ret = pdata->device_enable(pdev);
if (ret) {
dev_err(rproc->dev, "omap_device_enable failed: %d\n", ret);
dev_err(dev, "omap_device_enable failed: %d\n", ret);
goto put_mbox;
}

Expand All @@ -153,7 +155,8 @@ static int omap_rproc_start(struct rproc *rproc)
/* power off the remote processor */
static int omap_rproc_stop(struct rproc *rproc)
{
struct platform_device *pdev = to_platform_device(rproc->dev);
struct device *dev = rproc->dev.parent;
struct platform_device *pdev = to_platform_device(dev);
struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
struct omap_rproc *oproc = rproc->priv;
int ret;
Expand Down
Loading

0 comments on commit b5ab5e2

Please sign in to comment.