/*
 * Copyright 2012 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
 */
#include <core/subdev.h>
#include <core/device.h>
#include <core/option.h>
#include <subdev/mc.h>

const char *
nvkm_subdev_type[NVKM_SUBDEV_NR] = {
#define NVKM_LAYOUT_ONCE(type,data,ptr,...) [type] = #ptr,
#define NVKM_LAYOUT_INST(A...) NVKM_LAYOUT_ONCE(A)
#include <core/layout.h>
#undef NVKM_LAYOUT_ONCE
#undef NVKM_LAYOUT_INST
};

void
nvkm_subdev_intr(struct nvkm_subdev *subdev)
{
	if (subdev->func->intr)
		subdev->func->intr(subdev);
}

int
nvkm_subdev_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data)
{
	if (subdev->func->info)
		return subdev->func->info(subdev, mthd, data);
	return -ENOSYS;
}

int
nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
{
	struct nvkm_device *device = subdev->device;
	const char *action = suspend ? "suspend" : subdev->use.enabled ? "fini" : "reset";
	s64 time;

	nvkm_trace(subdev, "%s running...\n", action);
	time = ktime_to_us(ktime_get());

	if (subdev->func->fini) {
		int ret = subdev->func->fini(subdev, suspend);
		if (ret) {
			nvkm_error(subdev, "%s failed, %d\n", action, ret);
			if (suspend)
				return ret;
		}
	}
	subdev->use.enabled = false;

	nvkm_mc_reset(device, subdev->type, subdev->inst);

	time = ktime_to_us(ktime_get()) - time;
	nvkm_trace(subdev, "%s completed in %lldus\n", action, time);
	return 0;
}

int
nvkm_subdev_preinit(struct nvkm_subdev *subdev)
{
	s64 time;

	nvkm_trace(subdev, "preinit running...\n");
	time = ktime_to_us(ktime_get());

	if (subdev->func->preinit) {
		int ret = subdev->func->preinit(subdev);
		if (ret) {
			nvkm_error(subdev, "preinit failed, %d\n", ret);
			return ret;
		}
	}

	time = ktime_to_us(ktime_get()) - time;
	nvkm_trace(subdev, "preinit completed in %lldus\n", time);
	return 0;
}

static int
nvkm_subdev_oneinit_(struct nvkm_subdev *subdev)
{
	s64 time;
	int ret;

	if (!subdev->func->oneinit || subdev->oneinit)
		return 0;

	nvkm_trace(subdev, "one-time init running...\n");
	time = ktime_to_us(ktime_get());
	ret = subdev->func->oneinit(subdev);
	if (ret) {
		nvkm_error(subdev, "one-time init failed, %d\n", ret);
		return ret;
	}

	subdev->oneinit = true;
	time = ktime_to_us(ktime_get()) - time;
	nvkm_trace(subdev, "one-time init completed in %lldus\n", time);
	return 0;
}

static int
nvkm_subdev_init_(struct nvkm_subdev *subdev)
{
	s64 time;
	int ret;

	if (subdev->use.enabled) {
		nvkm_trace(subdev, "init skipped, already running\n");
		return 0;
	}

	nvkm_trace(subdev, "init running...\n");
	time = ktime_to_us(ktime_get());

	ret = nvkm_subdev_oneinit_(subdev);
	if (ret)
		return ret;

	subdev->use.enabled = true;

	if (subdev->func->init) {
		ret = subdev->func->init(subdev);
		if (ret) {
			nvkm_error(subdev, "init failed, %d\n", ret);
			return ret;
		}
	}

	time = ktime_to_us(ktime_get()) - time;
	nvkm_trace(subdev, "init completed in %lldus\n", time);
	return 0;
}

int
nvkm_subdev_init(struct nvkm_subdev *subdev)
{
	int ret;

	mutex_lock(&subdev->use.mutex);
	if (refcount_read(&subdev->use.refcount) == 0) {
		nvkm_trace(subdev, "init skipped, no users\n");
		mutex_unlock(&subdev->use.mutex);
		return 0;
	}

	ret = nvkm_subdev_init_(subdev);
	mutex_unlock(&subdev->use.mutex);
	return ret;
}

int
nvkm_subdev_oneinit(struct nvkm_subdev *subdev)
{
	int ret;

	mutex_lock(&subdev->use.mutex);
	ret = nvkm_subdev_oneinit_(subdev);
	mutex_unlock(&subdev->use.mutex);
	return ret;
}

void
nvkm_subdev_unref(struct nvkm_subdev *subdev)
{
	if (refcount_dec_and_mutex_lock(&subdev->use.refcount, &subdev->use.mutex)) {
		nvkm_subdev_fini(subdev, false);
		mutex_unlock(&subdev->use.mutex);
	}
}

int
nvkm_subdev_ref(struct nvkm_subdev *subdev)
{
	int ret;

	if (subdev && !refcount_inc_not_zero(&subdev->use.refcount)) {
		mutex_lock(&subdev->use.mutex);
		if (!refcount_inc_not_zero(&subdev->use.refcount)) {
			if ((ret = nvkm_subdev_init_(subdev))) {
				mutex_unlock(&subdev->use.mutex);
				return ret;
			}

			refcount_set(&subdev->use.refcount, 1);
		}
		mutex_unlock(&subdev->use.mutex);
	}

	return 0;
}

void
nvkm_subdev_del(struct nvkm_subdev **psubdev)
{
	struct nvkm_subdev *subdev = *psubdev;
	s64 time;

	if (subdev && !WARN_ON(!subdev->func)) {
		nvkm_trace(subdev, "destroy running...\n");
		time = ktime_to_us(ktime_get());
		list_del(&subdev->head);
		if (subdev->func->dtor)
			*psubdev = subdev->func->dtor(subdev);
		mutex_destroy(&subdev->use.mutex);
		time = ktime_to_us(ktime_get()) - time;
		nvkm_trace(subdev, "destroy completed in %lldus\n", time);
		kfree(*psubdev);
		*psubdev = NULL;
	}
}

void
nvkm_subdev_disable(struct nvkm_device *device, enum nvkm_subdev_type type, int inst)
{
	struct nvkm_subdev *subdev;
	list_for_each_entry(subdev, &device->subdev, head) {
		if (subdev->type == type && subdev->inst == inst) {
			*subdev->pself = NULL;
			nvkm_subdev_del(&subdev);
			break;
		}
	}
}

void
__nvkm_subdev_ctor(const struct nvkm_subdev_func *func, struct nvkm_device *device,
		   enum nvkm_subdev_type type, int inst, struct nvkm_subdev *subdev)
{
	subdev->func = func;
	subdev->device = device;
	subdev->type = type;
	subdev->inst = inst < 0 ? 0 : inst;

	if (inst >= 0)
		snprintf(subdev->name, sizeof(subdev->name), "%s%d", nvkm_subdev_type[type], inst);
	else
		strscpy(subdev->name, nvkm_subdev_type[type], sizeof(subdev->name));
	subdev->debug = nvkm_dbgopt(device->dbgopt, subdev->name);

	refcount_set(&subdev->use.refcount, 1);
	list_add_tail(&subdev->head, &device->subdev);
}

int
nvkm_subdev_new_(const struct nvkm_subdev_func *func, struct nvkm_device *device,
		 enum nvkm_subdev_type type, int inst, struct nvkm_subdev **psubdev)
{
	if (!(*psubdev = kzalloc(sizeof(**psubdev), GFP_KERNEL)))
		return -ENOMEM;
	nvkm_subdev_ctor(func, device, type, inst, *psubdev);
	return 0;
}
