aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/remoteproc/remoteproc_core.c3
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c79
-rw-r--r--include/linux/remoteproc.h4
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 */
183static u8 rproc_virtio_get_status(struct virtio_device *vdev) 176static 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
188static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status) 186static 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
193static void rproc_virtio_reset(struct virtio_device *vdev) 197static 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)
199static u32 rproc_virtio_get_features(struct virtio_device *vdev) 209static 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
206static void rproc_virtio_finalize_features(struct virtio_device *vdev) 219static 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
236static 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
254static 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
225static const struct virtio_config_ops rproc_virtio_config_ops = { 272static 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 */
476struct rproc_vdev { 474struct 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