/*
 * Copyright 2014 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * KFD Interrupts.
 *
 * AMD GPUs deliver interrupts by pushing an interrupt description onto the
 * interrupt ring and then sending an interrupt. KGD receives the interrupt
 * in ISR and sends us a pointer to each new entry on the interrupt ring.
 *
 * We generally can't process interrupt-signaled events from ISR, so we call
 * out to each interrupt client module (currently only the scheduler) to ask if
 * each interrupt is interesting. If they return true, then it requires further
 * processing so we copy it to an internal interrupt ring and call each
 * interrupt client again from a work-queue.
 *
 * There's no acknowledgment for the interrupts we use. The hardware simply
 * queues a new interrupt each time without waiting.
 *
 * The fixed-size internal queue means that it's possible for us to lose
 * interrupts because we have no back-pressure to the hardware.
 */

#include <linux/slab.h>
#include <linux/device.h>
#include "kfd_priv.h"

#define KFD_INTERRUPT_RING_SIZE 256

static void interrupt_wq(struct work_struct *);

int kfd_interrupt_init(struct kfd_dev *kfd)
{
	void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE,
					kfd->device_info->ih_ring_entry_size,
					GFP_KERNEL);
	if (!interrupt_ring)
		return -ENOMEM;

	kfd->interrupt_ring = interrupt_ring;
	kfd->interrupt_ring_size =
		KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size;
	atomic_set(&kfd->interrupt_ring_wptr, 0);
	atomic_set(&kfd->interrupt_ring_rptr, 0);

	spin_lock_init(&kfd->interrupt_lock);

	INIT_WORK(&kfd->interrupt_work, interrupt_wq);

	kfd->interrupts_active = true;

	/*
	 * After this function returns, the interrupt will be enabled. This
	 * barrier ensures that the interrupt running on a different processor
	 * sees all the above writes.
	 */
	smp_wmb();

	return 0;
}

void kfd_interrupt_exit(struct kfd_dev *kfd)
{
	/*
	 * Stop the interrupt handler from writing to the ring and scheduling
	 * workqueue items. The spinlock ensures that any interrupt running
	 * after we have unlocked sees interrupts_active = false.
	 */
	unsigned long flags;

	spin_lock_irqsave(&kfd->interrupt_lock, flags);
	kfd->interrupts_active = false;
	spin_unlock_irqrestore(&kfd->interrupt_lock, flags);

	/*
	 * Flush_scheduled_work ensures that there are no outstanding
	 * work-queue items that will access interrupt_ring. New work items
	 * can't be created because we stopped interrupt handling above.
	 */
	flush_scheduled_work();

	kfree(kfd->interrupt_ring);
}

/*
 * This assumes that it can't be called concurrently with itself
 * but only with dequeue_ih_ring_entry.
 */
bool enqueue_ih_ring_entry(struct kfd_dev *kfd,	const void *ih_ring_entry)
{
	unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr);
	unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr);

	if ((rptr - wptr) % kfd->interrupt_ring_size ==
					kfd->device_info->ih_ring_entry_size) {
		/* This is very bad, the system is likely to hang. */
		dev_err_ratelimited(kfd_chardev(),
			"Interrupt ring overflow, dropping interrupt.\n");
		return false;
	}

	memcpy(kfd->interrupt_ring + wptr, ih_ring_entry,
			kfd->device_info->ih_ring_entry_size);

	wptr = (wptr + kfd->device_info->ih_ring_entry_size) %
			kfd->interrupt_ring_size;
	smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */
	atomic_set(&kfd->interrupt_ring_wptr, wptr);

	return true;
}

/*
 * This assumes that it can't be called concurrently with itself
 * but only with enqueue_ih_ring_entry.
 */
static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry)
{
	/*
	 * Assume that wait queues have an implicit barrier, i.e. anything that
	 * happened in the ISR before it queued work is visible.
	 */

	unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr);
	unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr);

	if (rptr == wptr)
		return false;

	memcpy(ih_ring_entry, kfd->interrupt_ring + rptr,
			kfd->device_info->ih_ring_entry_size);

	rptr = (rptr + kfd->device_info->ih_ring_entry_size) %
			kfd->interrupt_ring_size;

	/*
	 * Ensure the rptr write update is not visible until
	 * memcpy has finished reading.
	 */
	smp_mb();
	atomic_set(&kfd->interrupt_ring_rptr, rptr);

	return true;
}

static void interrupt_wq(struct work_struct *work)
{
	struct kfd_dev *dev = container_of(work, struct kfd_dev,
						interrupt_work);

	uint32_t ih_ring_entry[DIV_ROUND_UP(
				dev->device_info->ih_ring_entry_size,
				sizeof(uint32_t))];

	while (dequeue_ih_ring_entry(dev, ih_ring_entry))
		;
}
