diff options
author | Ohad Ben-Cohen <ohad@wizery.com> | 2012-05-30 15:01:25 -0400 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2012-07-05 17:53:03 -0400 |
commit | b5ab5e24e960b9f780a4cc96815cfd4b0d412720 (patch) | |
tree | d07fbf490e03e9e2706c14a9bc24ae4f47b05111 /drivers/remoteproc/omap_remoteproc.c | |
parent | 6db20ea8d85064175c7ef594c433c6c2e6bbab83 (diff) |
remoteproc: maintain a generic child device for each rproc
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 <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/remoteproc/omap_remoteproc.c')
-rw-r--r-- | drivers/remoteproc/omap_remoteproc.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 69425c4e86f3..b5e6d2981741 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c | |||
@@ -66,7 +66,7 @@ static int omap_rproc_mbox_callback(struct notifier_block *this, | |||
66 | { | 66 | { |
67 | mbox_msg_t msg = (mbox_msg_t) data; | 67 | mbox_msg_t msg = (mbox_msg_t) data; |
68 | struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb); | 68 | struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb); |
69 | struct device *dev = oproc->rproc->dev; | 69 | struct device *dev = oproc->rproc->dev.parent; |
70 | const char *name = oproc->rproc->name; | 70 | const char *name = oproc->rproc->name; |
71 | 71 | ||
72 | dev_dbg(dev, "mbox msg: 0x%x\n", msg); | 72 | dev_dbg(dev, "mbox msg: 0x%x\n", msg); |
@@ -92,12 +92,13 @@ static int omap_rproc_mbox_callback(struct notifier_block *this, | |||
92 | static void omap_rproc_kick(struct rproc *rproc, int vqid) | 92 | static void omap_rproc_kick(struct rproc *rproc, int vqid) |
93 | { | 93 | { |
94 | struct omap_rproc *oproc = rproc->priv; | 94 | struct omap_rproc *oproc = rproc->priv; |
95 | struct device *dev = rproc->dev.parent; | ||
95 | int ret; | 96 | int ret; |
96 | 97 | ||
97 | /* send the index of the triggered virtqueue in the mailbox payload */ | 98 | /* send the index of the triggered virtqueue in the mailbox payload */ |
98 | ret = omap_mbox_msg_send(oproc->mbox, vqid); | 99 | ret = omap_mbox_msg_send(oproc->mbox, vqid); |
99 | if (ret) | 100 | if (ret) |
100 | dev_err(rproc->dev, "omap_mbox_msg_send failed: %d\n", ret); | 101 | dev_err(dev, "omap_mbox_msg_send failed: %d\n", ret); |
101 | } | 102 | } |
102 | 103 | ||
103 | /* | 104 | /* |
@@ -110,7 +111,8 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid) | |||
110 | static int omap_rproc_start(struct rproc *rproc) | 111 | static int omap_rproc_start(struct rproc *rproc) |
111 | { | 112 | { |
112 | struct omap_rproc *oproc = rproc->priv; | 113 | struct omap_rproc *oproc = rproc->priv; |
113 | struct platform_device *pdev = to_platform_device(rproc->dev); | 114 | struct device *dev = rproc->dev.parent; |
115 | struct platform_device *pdev = to_platform_device(dev); | ||
114 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | 116 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; |
115 | int ret; | 117 | int ret; |
116 | 118 | ||
@@ -120,7 +122,7 @@ static int omap_rproc_start(struct rproc *rproc) | |||
120 | oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb); | 122 | oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb); |
121 | if (IS_ERR(oproc->mbox)) { | 123 | if (IS_ERR(oproc->mbox)) { |
122 | ret = PTR_ERR(oproc->mbox); | 124 | ret = PTR_ERR(oproc->mbox); |
123 | dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret); | 125 | dev_err(dev, "omap_mbox_get failed: %d\n", ret); |
124 | return ret; | 126 | return ret; |
125 | } | 127 | } |
126 | 128 | ||
@@ -133,13 +135,13 @@ static int omap_rproc_start(struct rproc *rproc) | |||
133 | */ | 135 | */ |
134 | ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST); | 136 | ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST); |
135 | if (ret) { | 137 | if (ret) { |
136 | dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret); | 138 | dev_err(dev, "omap_mbox_get failed: %d\n", ret); |
137 | goto put_mbox; | 139 | goto put_mbox; |
138 | } | 140 | } |
139 | 141 | ||
140 | ret = pdata->device_enable(pdev); | 142 | ret = pdata->device_enable(pdev); |
141 | if (ret) { | 143 | if (ret) { |
142 | dev_err(rproc->dev, "omap_device_enable failed: %d\n", ret); | 144 | dev_err(dev, "omap_device_enable failed: %d\n", ret); |
143 | goto put_mbox; | 145 | goto put_mbox; |
144 | } | 146 | } |
145 | 147 | ||
@@ -153,7 +155,8 @@ put_mbox: | |||
153 | /* power off the remote processor */ | 155 | /* power off the remote processor */ |
154 | static int omap_rproc_stop(struct rproc *rproc) | 156 | static int omap_rproc_stop(struct rproc *rproc) |
155 | { | 157 | { |
156 | struct platform_device *pdev = to_platform_device(rproc->dev); | 158 | struct device *dev = rproc->dev.parent; |
159 | struct platform_device *pdev = to_platform_device(dev); | ||
157 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; | 160 | struct omap_rproc_pdata *pdata = pdev->dev.platform_data; |
158 | struct omap_rproc *oproc = rproc->priv; | 161 | struct omap_rproc *oproc = rproc->priv; |
159 | int ret; | 162 | int ret; |