/*
 * Copyright 2016 Red Hat 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.
 *
 * Authors: Ben Skeggs <bskeggs@redhat.com>
 */
#include "priv.h"

struct nvkm_top_device *
nvkm_top_device_new(struct nvkm_top *top)
{
	struct nvkm_top_device *info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (info) {
		info->index = NVKM_SUBDEV_NR;
		info->addr = 0;
		info->fault = -1;
		info->engine = -1;
		info->runlist = -1;
		info->reset = -1;
		info->intr = -1;
		list_add_tail(&info->head, &top->device);
	}
	return info;
}

u32
nvkm_top_reset(struct nvkm_device *device, enum nvkm_devidx index)
{
	struct nvkm_top *top = device->top;
	struct nvkm_top_device *info;

	if (top) {
		list_for_each_entry(info, &top->device, head) {
			if (info->index == index && info->reset >= 0)
				return BIT(info->reset);
		}
	}

	return 0;
}

u32
nvkm_top_intr_mask(struct nvkm_device *device, enum nvkm_devidx devidx)
{
	struct nvkm_top *top = device->top;
	struct nvkm_top_device *info;

	if (top) {
		list_for_each_entry(info, &top->device, head) {
			if (info->index == devidx && info->intr >= 0)
				return BIT(info->intr);
		}
	}

	return 0;
}

u32
nvkm_top_intr(struct nvkm_device *device, u32 intr, u64 *psubdevs)
{
	struct nvkm_top *top = device->top;
	struct nvkm_top_device *info;
	u64 subdevs = 0;
	u32 handled = 0;

	if (top) {
		list_for_each_entry(info, &top->device, head) {
			if (info->index != NVKM_SUBDEV_NR && info->intr >= 0) {
				if (intr & BIT(info->intr)) {
					subdevs |= BIT_ULL(info->index);
					handled |= BIT(info->intr);
				}
			}
		}
	}

	*psubdevs = subdevs;
	return intr & ~handled;
}

enum nvkm_devidx
nvkm_top_fault(struct nvkm_device *device, int fault)
{
	struct nvkm_top *top = device->top;
	struct nvkm_top_device *info;

	list_for_each_entry(info, &top->device, head) {
		if (info->fault == fault)
			return info->index;
	}

	return NVKM_SUBDEV_NR;
}

enum nvkm_devidx
nvkm_top_engine(struct nvkm_device *device, int index, int *runl, int *engn)
{
	struct nvkm_top *top = device->top;
	struct nvkm_top_device *info;
	int n = 0;

	list_for_each_entry(info, &top->device, head) {
		if (info->engine >= 0 && info->runlist >= 0 && n++ == index) {
			*runl = info->runlist;
			*engn = info->engine;
			return info->index;
		}
	}

	return -ENODEV;
}

static int
nvkm_top_oneinit(struct nvkm_subdev *subdev)
{
	struct nvkm_top *top = nvkm_top(subdev);
	return top->func->oneinit(top);
}

static void *
nvkm_top_dtor(struct nvkm_subdev *subdev)
{
	struct nvkm_top *top = nvkm_top(subdev);
	struct nvkm_top_device *info, *temp;

	list_for_each_entry_safe(info, temp, &top->device, head) {
		list_del(&info->head);
		kfree(info);
	}

	return top;
}

static const struct nvkm_subdev_func
nvkm_top = {
	.dtor = nvkm_top_dtor,
	.oneinit = nvkm_top_oneinit,
};

int
nvkm_top_new_(const struct nvkm_top_func *func, struct nvkm_device *device,
	      int index, struct nvkm_top **ptop)
{
	struct nvkm_top *top;
	if (!(top = *ptop = kzalloc(sizeof(*top), GFP_KERNEL)))
		return -ENOMEM;
	nvkm_subdev_ctor(&nvkm_top, device, index, &top->subdev);
	top->func = func;
	INIT_LIST_HEAD(&top->device);
	return 0;
}
