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 | |
| 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>
| -rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 3 | ||||
| -rw-r--r-- | drivers/remoteproc/remoteproc_virtio.c | 79 | ||||
| -rw-r--r-- | include/linux/remoteproc.h | 4 |
3 files changed, 64 insertions, 22 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 | /* |
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index b4cef16460f8..9e7e745dac55 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h | |||
| @@ -469,8 +469,6 @@ struct rproc_vring { | |||
| 469 | * @rproc: the rproc handle | 469 | * @rproc: the rproc handle |
| 470 | * @vdev: the virio device | 470 | * @vdev: the virio device |
| 471 | * @vring: the vrings for this vdev | 471 | * @vring: the vrings for this vdev |
| 472 | * @dfeatures: virtio device features | ||
| 473 | * @gfeatures: virtio guest features | ||
| 474 | * @rsc_offset: offset of the vdev's resource entry | 472 | * @rsc_offset: offset of the vdev's resource entry |
| 475 | */ | 473 | */ |
| 476 | struct rproc_vdev { | 474 | struct rproc_vdev { |
| @@ -478,8 +476,6 @@ struct rproc_vdev { | |||
| 478 | struct rproc *rproc; | 476 | struct rproc *rproc; |
| 479 | struct virtio_device vdev; | 477 | struct virtio_device vdev; |
| 480 | struct rproc_vring vring[RVDEV_NUM_VRINGS]; | 478 | struct rproc_vring vring[RVDEV_NUM_VRINGS]; |
| 481 | unsigned long dfeatures; | ||
| 482 | unsigned long gfeatures; | ||
| 483 | u32 rsc_offset; | 479 | u32 rsc_offset; |
| 484 | }; | 480 | }; |
| 485 | 481 | ||
