diff options
author | Sjur Brændeland <sjur.brandeland@stericsson.com> | 2013-02-21 12:15:39 -0500 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2013-04-07 07:06:17 -0400 |
commit | 92b38f851470f8d8ea7ed638d546f83b5268bc12 (patch) | |
tree | 2c9010584f33d5b6b9e26f6f9139e5c42b19aad0 /drivers/remoteproc | |
parent | a2b950ac7b1e6442919ee9e79c4963e134698869 (diff) |
remoteproc: support virtio config space.
Support virtio configuration space and device status. The virtio
device can now access the resource table in shared memory.
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
Acked-by: Ido Yariv <ido@wizery.com>
[rebase and style changes]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 3 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_virtio.c | 79 |
2 files changed, 64 insertions, 18 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 617b825aa553..d0251fe9e119 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -345,9 +345,6 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, | |||
345 | goto free_rvdev; | 345 | goto free_rvdev; |
346 | } | 346 | } |
347 | 347 | ||
348 | /* remember the device features */ | ||
349 | rvdev->dfeatures = rsc->dfeatures; | ||
350 | |||
351 | /* remember the resource offset*/ | 348 | /* remember the resource offset*/ |
352 | rvdev->rsc_offset = offset; | 349 | rvdev->rsc_offset = offset; |
353 | 350 | ||
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index afed9b7731c4..b09c75c21b60 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c | |||
@@ -173,25 +173,35 @@ error: | |||
173 | return ret; | 173 | return ret; |
174 | } | 174 | } |
175 | 175 | ||
176 | /* | ||
177 | * We don't support yet real virtio status semantics. | ||
178 | * | ||
179 | * The plan is to provide this via the VDEV resource entry | ||
180 | * which is part of the firmware: this way the remote processor | ||
181 | * will be able to access the status values as set by us. | ||
182 | */ | ||
183 | static u8 rproc_virtio_get_status(struct virtio_device *vdev) | 176 | static u8 rproc_virtio_get_status(struct virtio_device *vdev) |
184 | { | 177 | { |
185 | return 0; | 178 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); |
179 | struct fw_rsc_vdev *rsc; | ||
180 | |||
181 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
182 | |||
183 | return rsc->status; | ||
186 | } | 184 | } |
187 | 185 | ||
188 | static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status) | 186 | static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status) |
189 | { | 187 | { |
188 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
189 | struct fw_rsc_vdev *rsc; | ||
190 | |||
191 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
192 | |||
193 | rsc->status = status; | ||
190 | dev_dbg(&vdev->dev, "status: %d\n", status); | 194 | dev_dbg(&vdev->dev, "status: %d\n", status); |
191 | } | 195 | } |
192 | 196 | ||
193 | static void rproc_virtio_reset(struct virtio_device *vdev) | 197 | static void rproc_virtio_reset(struct virtio_device *vdev) |
194 | { | 198 | { |
199 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
200 | struct fw_rsc_vdev *rsc; | ||
201 | |||
202 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
203 | |||
204 | rsc->status = 0; | ||
195 | dev_dbg(&vdev->dev, "reset !\n"); | 205 | dev_dbg(&vdev->dev, "reset !\n"); |
196 | } | 206 | } |
197 | 207 | ||
@@ -199,13 +209,19 @@ static void rproc_virtio_reset(struct virtio_device *vdev) | |||
199 | static u32 rproc_virtio_get_features(struct virtio_device *vdev) | 209 | static u32 rproc_virtio_get_features(struct virtio_device *vdev) |
200 | { | 210 | { |
201 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | 211 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); |
212 | struct fw_rsc_vdev *rsc; | ||
213 | |||
214 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
202 | 215 | ||
203 | return rvdev->dfeatures; | 216 | return rsc->dfeatures; |
204 | } | 217 | } |
205 | 218 | ||
206 | static void rproc_virtio_finalize_features(struct virtio_device *vdev) | 219 | static void rproc_virtio_finalize_features(struct virtio_device *vdev) |
207 | { | 220 | { |
208 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | 221 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); |
222 | struct fw_rsc_vdev *rsc; | ||
223 | |||
224 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
209 | 225 | ||
210 | /* Give virtio_ring a chance to accept features */ | 226 | /* Give virtio_ring a chance to accept features */ |
211 | vring_transport_features(vdev); | 227 | vring_transport_features(vdev); |
@@ -213,13 +229,44 @@ static void rproc_virtio_finalize_features(struct virtio_device *vdev) | |||
213 | /* | 229 | /* |
214 | * Remember the finalized features of our vdev, and provide it | 230 | * Remember the finalized features of our vdev, and provide it |
215 | * to the remote processor once it is powered on. | 231 | * to the remote processor once it is powered on. |
216 | * | ||
217 | * Similarly to the status field, we don't expose yet the negotiated | ||
218 | * features to the remote processors at this point. This will be | ||
219 | * fixed as part of a small resource table overhaul and then an | ||
220 | * extension of the virtio resource entries. | ||
221 | */ | 232 | */ |
222 | rvdev->gfeatures = vdev->features[0]; | 233 | rsc->gfeatures = vdev->features[0]; |
234 | } | ||
235 | |||
236 | static void rproc_virtio_get(struct virtio_device *vdev, unsigned offset, | ||
237 | void *buf, unsigned len) | ||
238 | { | ||
239 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
240 | struct fw_rsc_vdev *rsc; | ||
241 | void *cfg; | ||
242 | |||
243 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
244 | cfg = &rsc->vring[rsc->num_of_vrings]; | ||
245 | |||
246 | if (offset + len > rsc->config_len || offset + len < len) { | ||
247 | dev_err(&vdev->dev, "rproc_virtio_get: access out of bounds\n"); | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | memcpy(buf, cfg + offset, len); | ||
252 | } | ||
253 | |||
254 | static void rproc_virtio_set(struct virtio_device *vdev, unsigned offset, | ||
255 | const void *buf, unsigned len) | ||
256 | { | ||
257 | struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); | ||
258 | struct fw_rsc_vdev *rsc; | ||
259 | void *cfg; | ||
260 | |||
261 | rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset; | ||
262 | cfg = &rsc->vring[rsc->num_of_vrings]; | ||
263 | |||
264 | if (offset + len > rsc->config_len || offset + len < len) { | ||
265 | dev_err(&vdev->dev, "rproc_virtio_set: access out of bounds\n"); | ||
266 | return; | ||
267 | } | ||
268 | |||
269 | memcpy(cfg + offset, buf, len); | ||
223 | } | 270 | } |
224 | 271 | ||
225 | static const struct virtio_config_ops rproc_virtio_config_ops = { | 272 | static const struct virtio_config_ops rproc_virtio_config_ops = { |
@@ -230,6 +277,8 @@ static const struct virtio_config_ops rproc_virtio_config_ops = { | |||
230 | .reset = rproc_virtio_reset, | 277 | .reset = rproc_virtio_reset, |
231 | .set_status = rproc_virtio_set_status, | 278 | .set_status = rproc_virtio_set_status, |
232 | .get_status = rproc_virtio_get_status, | 279 | .get_status = rproc_virtio_get_status, |
280 | .get = rproc_virtio_get, | ||
281 | .set = rproc_virtio_set, | ||
233 | }; | 282 | }; |
234 | 283 | ||
235 | /* | 284 | /* |