// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
 * Copyright 2013-2016 Freescale Semiconductor Inc.
 * Copyright 2019 NXP
 */

#include <linux/vfio.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/eventfd.h>
#include <linux/msi.h>

#include "linux/fsl/mc.h"
#include "vfio_fsl_mc_private.h"

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)
		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, u32 flags,
				       void *data)
{
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
	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 (!count && (flags & VFIO_IRQ_SET_DATA_NONE))
		return vfio_set_trigger(vdev, index, -1);

	if (start != 0 || count != 1)
		return -EINVAL;

	mutex_lock(&vdev->reflck->lock);
	ret = fsl_mc_populate_irq_pool(mc_cont,
			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 (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
		s32 fd = *(s32 *)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) {
		u8 trigger = *(u8 *)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,
			       u32 flags, unsigned int index,
			       unsigned int start, unsigned int count,
			       void *data)
{
	if (flags & VFIO_IRQ_SET_ACTION_TRIGGER)
		return  vfio_fsl_mc_set_irq_trigger(vdev, index, start,
			  count, flags, data);
	else
		return -EINVAL;
}

/* 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 (!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;
}
