diff options
author | Diana Craciun <diana.craciun@oss.nxp.com> | 2021-08-17 14:46:02 +0300 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2021-11-02 17:20:05 +0800 |
commit | 11a971b0b70c824d6b47f98d48846970d93422f8 (patch) | |
tree | b221287c27b20416bd379aea13afe640406f8bf7 /drivers/vfio | |
parent | 053c79cd5d897b39d3659d46370e3b8917f92806 (diff) |
vfio/fsl-mc: Add per device reset support
Currently when a fsl-mc device is reset, the entire DPRC container
is reset which is very inefficient because the devices within a
container will be reset multiple times.
Add support for individually resetting a device.
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r-- | drivers/vfio/fsl-mc/vfio_fsl_mc.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index b69d26b18d0f..f516579bd5f1 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -56,6 +56,33 @@ static int vfio_fsl_mc_open_device(struct vfio_device *core_vdev) return 0; } +static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev) +{ + struct fsl_mc_device *mc_dev = vdev->mc_dev; + int ret = 0; + + if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { + return dprc_reset_container(mc_dev->mc_io, 0, + mc_dev->mc_handle, + mc_dev->obj_desc.id, + DPRC_RESET_OPTION_NON_RECURSIVE); + } else { + int err; + u16 token; + + err = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, + mc_dev->obj_desc.type, + &token); + if (err) + return err; + ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token); + err = fsl_mc_obj_close(mc_dev->mc_io, 0, token); + if (err) + return err; + } + return ret; +} + static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) { struct fsl_mc_device *mc_dev = vdev->mc_dev; @@ -79,9 +106,7 @@ static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) vfio_fsl_mc_regions_cleanup(vdev); /* reset the device before cleaning up the interrupts */ - ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle, - mc_cont->obj_desc.id, - DPRC_RESET_OPTION_NON_RECURSIVE); + ret = vfio_fsl_mc_reset_device(vdev); if (WARN_ON(ret)) dev_warn(&mc_cont->dev, @@ -204,18 +229,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, } case VFIO_DEVICE_RESET: { - int ret; - struct fsl_mc_device *mc_dev = vdev->mc_dev; - - /* reset is supported only for the DPRC */ - if (!is_fsl_mc_bus_dprc(mc_dev)) - return -ENOTTY; - - ret = dprc_reset_container(mc_dev->mc_io, 0, - mc_dev->mc_handle, - mc_dev->obj_desc.id, - DPRC_RESET_OPTION_NON_RECURSIVE); - return ret; + return vfio_fsl_mc_reset_device(vdev); } default: |