kernel: delete Linux 5.4 config and patches
[openwrt/staging/chunkeey.git] / target / linux / layerscape / patches-5.4 / 821-vfio-0008-vfio-fsl-mc-trigger-an-interrupt-via-eventfd.patch
diff --git a/target/linux/layerscape/patches-5.4/821-vfio-0008-vfio-fsl-mc-trigger-an-interrupt-via-eventfd.patch b/target/linux/layerscape/patches-5.4/821-vfio-0008-vfio-fsl-mc-trigger-an-interrupt-via-eventfd.patch
deleted file mode 100644 (file)
index 4f1e099..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-From 8f0239c9385028a0c15306966c66a56315b11dbc Mon Sep 17 00:00:00 2001
-From: Diana Craciun <diana.craciun@nxp.com>
-Date: Tue, 1 Oct 2019 16:44:04 +0300
-Subject: [PATCH] vfio/fsl-mc: trigger an interrupt via eventfd
-
-This patch allows to set an eventfd for fsl-mc device interrupt
-and also to trigger the interrupt eventfd from userspace for testing.
-
-All fsl-mc device interrupts are MSI type. This does not yet handle
-correctly DPRC container interrupt where re-scanning on container is
-required.
-
-Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
-Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
----
- drivers/vfio/fsl-mc/vfio_fsl_mc.c         |  20 +++-
- drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c    | 165 +++++++++++++++++++++++++++++-
- drivers/vfio/fsl-mc/vfio_fsl_mc_private.h |  10 ++
- 3 files changed, 193 insertions(+), 2 deletions(-)
-
---- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
-+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
-@@ -144,12 +144,30 @@ err_reg_init:
- static void vfio_fsl_mc_release(void *device_data)
- {
-       struct vfio_fsl_mc_device *vdev = device_data;
-+      int ret;
-       mutex_lock(&vdev->reflck->lock);
--      if (!(--vdev->refcnt))
-+      if (!(--vdev->refcnt)) {
-+              struct fsl_mc_device *mc_dev = vdev->mc_dev;
-+              struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
-+              struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
-+              struct fsl_mc_bus *mc_bus;
-+
-+              mc_bus = to_fsl_mc_bus(mc_cont);
-+
-               vfio_fsl_mc_regions_cleanup(vdev);
-+              /* reset the device before cleaning up the interrupts */
-+              ret = dprc_reset_container(mc_dev->mc_io, 0,
-+                    mc_dev->mc_handle,
-+                        mc_dev->obj_desc.id);
-+
-+              vfio_fsl_mc_irqs_cleanup(vdev);
-+
-+              fsl_mc_cleanup_irq_pool(mc_bus);
-+      }
-+
-       mutex_unlock(&vdev->reflck->lock);
-       module_put(THIS_MODULE);
---- a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
-+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
-@@ -29,12 +29,154 @@ static int vfio_fsl_mc_irq_unmask(struct
-       return -EINVAL;
- }
-+int vfio_fsl_mc_irqs_allocate(struct vfio_fsl_mc_device *vdev)
-+{
-+      struct fsl_mc_device *mc_dev = vdev->mc_dev;
-+      struct vfio_fsl_mc_irq *mc_irq;
-+      int irq_count;
-+      int ret, i;
-+
-+    /* Device does not support any interrupt */
-+      if (mc_dev->obj_desc.irq_count == 0)
-+              return 0;
-+
-+      /* interrupts were already allocated for this device */
-+      if (vdev->mc_irqs)
-+              return 0;
-+
-+      irq_count = mc_dev->obj_desc.irq_count;
-+
-+      mc_irq = kcalloc(irq_count, sizeof(*mc_irq), GFP_KERNEL);
-+      if (mc_irq == NULL)
-+              return -ENOMEM;
-+
-+      /* Allocate IRQs */
-+      ret = fsl_mc_allocate_irqs(mc_dev);
-+      if (ret) {
-+              kfree(mc_irq);
-+              return ret;
-+      }
-+
-+      for (i = 0; i < irq_count; i++) {
-+              mc_irq[i].count = 1;
-+              mc_irq[i].flags = VFIO_IRQ_INFO_EVENTFD;
-+      }
-+
-+      vdev->mc_irqs = mc_irq;
-+
-+      return 0;
-+}
-+static irqreturn_t vfio_fsl_mc_irq_handler(int irq_num, void *arg)
-+{
-+      struct vfio_fsl_mc_irq *mc_irq = (struct vfio_fsl_mc_irq *)arg;
-+
-+      eventfd_signal(mc_irq->trigger, 1);
-+      return IRQ_HANDLED;
-+}
-+
-+static int vfio_set_trigger(struct vfio_fsl_mc_device *vdev,
-+                                                 int index, int fd)
-+{
-+      struct vfio_fsl_mc_irq *irq = &vdev->mc_irqs[index];
-+      struct eventfd_ctx *trigger;
-+      int hwirq;
-+      int ret;
-+
-+      hwirq = vdev->mc_dev->irqs[index]->msi_desc->irq;
-+      if (irq->trigger) {
-+              free_irq(hwirq, irq);
-+              kfree(irq->name);
-+              eventfd_ctx_put(irq->trigger);
-+              irq->trigger = NULL;
-+      }
-+
-+      if (fd < 0) /* Disable only */
-+              return 0;
-+
-+      irq->name = kasprintf(GFP_KERNEL, "vfio-irq[%d](%s)",
-+                          hwirq, dev_name(&vdev->mc_dev->dev));
-+      if (!irq->name)
-+              return -ENOMEM;
-+
-+      trigger = eventfd_ctx_fdget(fd);
-+      if (IS_ERR(trigger)) {
-+              kfree(irq->name);
-+              return PTR_ERR(trigger);
-+      }
-+
-+      irq->trigger = trigger;
-+
-+      ret = request_irq(hwirq, vfio_fsl_mc_irq_handler, 0,
-+                irq->name, irq);
-+      if (ret) {
-+              kfree(irq->name);
-+              eventfd_ctx_put(trigger);
-+              irq->trigger = NULL;
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
- static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev,
-                                      unsigned int index, unsigned int start,
-                                      unsigned int count, uint32_t flags,
-                                      void *data)
- {
--      return -EINVAL;
-+      struct fsl_mc_device *mc_dev = vdev->mc_dev;
-+      struct fsl_mc_bus *mc_bus;
-+      int ret, hwirq;
-+      struct vfio_fsl_mc_irq *irq;
-+      struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
-+      struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
-+
-+      if (start != 0 || count != 1)
-+              return -EINVAL;
-+
-+      mc_bus = to_fsl_mc_bus(mc_cont);
-+
-+      mutex_lock(&vdev->reflck->lock);
-+      if (!mc_bus->irq_resources) {
-+
-+              ret = fsl_mc_populate_irq_pool(mc_bus,
-+                      FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
-+              if (ret)
-+                      goto unlock;
-+      }
-+
-+      ret = vfio_fsl_mc_irqs_allocate(vdev);
-+      if (ret)
-+              goto unlock;
-+      mutex_unlock(&vdev->reflck->lock);
-+
-+      if (!count && (flags & VFIO_IRQ_SET_DATA_NONE))
-+              return vfio_set_trigger(vdev, index, -1);
-+
-+      if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
-+              int32_t fd = *(int32_t *)data;
-+
-+              return vfio_set_trigger(vdev, index, fd);
-+      }
-+
-+      hwirq = vdev->mc_dev->irqs[index]->msi_desc->irq;
-+
-+      irq = &vdev->mc_irqs[index];
-+
-+      if (flags & VFIO_IRQ_SET_DATA_NONE) {
-+              vfio_fsl_mc_irq_handler(hwirq, irq);
-+
-+      } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
-+              uint8_t trigger = *(uint8_t *)data;
-+
-+              if (trigger)
-+                      vfio_fsl_mc_irq_handler(hwirq, irq);
-+      }
-+
-+      return 0;
-+
-+unlock:
-+      mutex_unlock(&vdev->reflck->lock);
-+      return ret;
- }
- int vfio_fsl_mc_set_irqs_ioctl(struct vfio_fsl_mc_device *vdev,
-                              uint32_t flags, unsigned int index,
-@@ -60,3 +202,24 @@ int vfio_fsl_mc_set_irqs_ioctl(struct vf
-       return ret;
- }
-+
-+/* Free All IRQs for the given MC object */
-+void vfio_fsl_mc_irqs_cleanup(struct vfio_fsl_mc_device *vdev)
-+{
-+      struct fsl_mc_device *mc_dev = vdev->mc_dev;
-+      int irq_count = mc_dev->obj_desc.irq_count;
-+      int i;
-+
-+      /* Device does not support any interrupt or the interrupts
-+       * were not configured
-+       */
-+      if (mc_dev->obj_desc.irq_count == 0 || !vdev->mc_irqs)
-+              return;
-+
-+      for (i = 0; i < irq_count; i++)
-+              vfio_set_trigger(vdev, i, -1);
-+
-+      fsl_mc_free_irqs(mc_dev);
-+      kfree(vdev->mc_irqs);
-+      vdev->mc_irqs = NULL;
-+}
---- a/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
-+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
-@@ -15,6 +15,13 @@
- #define VFIO_FSL_MC_INDEX_TO_OFFSET(index)    \
-       ((u64)(index) << VFIO_FSL_MC_OFFSET_SHIFT)
-+struct vfio_fsl_mc_irq {
-+      u32         flags;
-+      u32         count;
-+      struct eventfd_ctx  *trigger;
-+      char            *name;
-+};
-+
- struct vfio_fsl_mc_reflck {
-       struct kref             kref;
-       struct mutex            lock;
-@@ -33,6 +40,7 @@ struct vfio_fsl_mc_device {
-       u32                             num_regions;
-       struct vfio_fsl_mc_region       *regions;
-       struct vfio_fsl_mc_reflck   *reflck;
-+      struct vfio_fsl_mc_irq      *mc_irqs;
- };
- int vfio_fsl_mc_set_irqs_ioctl(struct vfio_fsl_mc_device *vdev,
-@@ -40,4 +48,6 @@ int vfio_fsl_mc_set_irqs_ioctl(struct vf
-                              unsigned int start, unsigned int count,
-                              void *data);
-+void vfio_fsl_mc_irqs_cleanup(struct vfio_fsl_mc_device *vdev);
-+
- #endif /* VFIO_PCI_PRIVATE_H */