// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//

#include <linux/firmware.h>
#include <linux/kfifo.h>
#include <linux/slab.h>
#include "avs.h"
#include "messages.h"

/* Caller responsible for holding adev->modres_mutex. */
static int avs_module_entry_index(struct avs_dev *adev, const guid_t *uuid)
{
	int i;

	for (i = 0; i < adev->mods_info->count; i++) {
		struct avs_module_entry *module;

		module = &adev->mods_info->entries[i];
		if (guid_equal(&module->uuid, uuid))
			return i;
	}

	return -ENOENT;
}

/* Caller responsible for holding adev->modres_mutex. */
static int avs_module_id_entry_index(struct avs_dev *adev, u32 module_id)
{
	int i;

	for (i = 0; i < adev->mods_info->count; i++) {
		struct avs_module_entry *module;

		module = &adev->mods_info->entries[i];
		if (module->module_id == module_id)
			return i;
	}

	return -ENOENT;
}

int avs_get_module_entry(struct avs_dev *adev, const guid_t *uuid, struct avs_module_entry *entry)
{
	int idx;

	mutex_lock(&adev->modres_mutex);

	idx = avs_module_entry_index(adev, uuid);
	if (idx >= 0)
		memcpy(entry, &adev->mods_info->entries[idx], sizeof(*entry));

	mutex_unlock(&adev->modres_mutex);
	return (idx < 0) ? idx : 0;
}

int avs_get_module_id_entry(struct avs_dev *adev, u32 module_id, struct avs_module_entry *entry)
{
	int idx;

	mutex_lock(&adev->modres_mutex);

	idx = avs_module_id_entry_index(adev, module_id);
	if (idx >= 0)
		memcpy(entry, &adev->mods_info->entries[idx], sizeof(*entry));

	mutex_unlock(&adev->modres_mutex);
	return (idx < 0) ? idx : 0;
}

int avs_get_module_id(struct avs_dev *adev, const guid_t *uuid)
{
	struct avs_module_entry module;
	int ret;

	ret = avs_get_module_entry(adev, uuid, &module);
	return !ret ? module.module_id : -ENOENT;
}

bool avs_is_module_ida_empty(struct avs_dev *adev, u32 module_id)
{
	bool ret = false;
	int idx;

	mutex_lock(&adev->modres_mutex);

	idx = avs_module_id_entry_index(adev, module_id);
	if (idx >= 0)
		ret = ida_is_empty(adev->mod_idas[idx]);

	mutex_unlock(&adev->modres_mutex);
	return ret;
}

/* Caller responsible for holding adev->modres_mutex. */
static void avs_module_ida_destroy(struct avs_dev *adev)
{
	int i = adev->mods_info ? adev->mods_info->count : 0;

	while (i--) {
		ida_destroy(adev->mod_idas[i]);
		kfree(adev->mod_idas[i]);
	}
	kfree(adev->mod_idas);
}

/* Caller responsible for holding adev->modres_mutex. */
static int
avs_module_ida_alloc(struct avs_dev *adev, struct avs_mods_info *newinfo, bool purge)
{
	struct avs_mods_info *oldinfo = adev->mods_info;
	struct ida **ida_ptrs;
	u32 tocopy_count = 0;
	int i;

	if (!purge && oldinfo) {
		if (oldinfo->count >= newinfo->count)
			dev_warn(adev->dev, "refreshing %d modules info with %d\n",
				 oldinfo->count, newinfo->count);
		tocopy_count = oldinfo->count;
	}

	ida_ptrs = kcalloc(newinfo->count, sizeof(*ida_ptrs), GFP_KERNEL);
	if (!ida_ptrs)
		return -ENOMEM;

	if (tocopy_count)
		memcpy(ida_ptrs, adev->mod_idas, tocopy_count * sizeof(*ida_ptrs));

	for (i = tocopy_count; i < newinfo->count; i++) {
		ida_ptrs[i] = kzalloc(sizeof(**ida_ptrs), GFP_KERNEL);
		if (!ida_ptrs[i]) {
			while (i--)
				kfree(ida_ptrs[i]);

			kfree(ida_ptrs);
			return -ENOMEM;
		}

		ida_init(ida_ptrs[i]);
	}

	/* If old elements have been reused, don't wipe them. */
	if (tocopy_count)
		kfree(adev->mod_idas);
	else
		avs_module_ida_destroy(adev);

	adev->mod_idas = ida_ptrs;
	return 0;
}

int avs_module_info_init(struct avs_dev *adev, bool purge)
{
	struct avs_mods_info *info;
	int ret;

	ret = avs_ipc_get_modules_info(adev, &info);
	if (ret)
		return AVS_IPC_RET(ret);

	mutex_lock(&adev->modres_mutex);

	ret = avs_module_ida_alloc(adev, info, purge);
	if (ret < 0) {
		dev_err(adev->dev, "initialize module idas failed: %d\n", ret);
		goto exit;
	}

	/* Refresh current information with newly received table. */
	kfree(adev->mods_info);
	adev->mods_info = info;

exit:
	mutex_unlock(&adev->modres_mutex);
	return ret;
}

void avs_module_info_free(struct avs_dev *adev)
{
	mutex_lock(&adev->modres_mutex);

	avs_module_ida_destroy(adev);
	kfree(adev->mods_info);
	adev->mods_info = NULL;

	mutex_unlock(&adev->modres_mutex);
}

int avs_module_id_alloc(struct avs_dev *adev, u16 module_id)
{
	int ret, idx, max_id;

	mutex_lock(&adev->modres_mutex);

	idx = avs_module_id_entry_index(adev, module_id);
	if (idx == -ENOENT) {
		dev_err(adev->dev, "invalid module id: %d", module_id);
		ret = -EINVAL;
		goto exit;
	}
	max_id = adev->mods_info->entries[idx].instance_max_count - 1;
	ret = ida_alloc_max(adev->mod_idas[idx], max_id, GFP_KERNEL);
exit:
	mutex_unlock(&adev->modres_mutex);
	return ret;
}

void avs_module_id_free(struct avs_dev *adev, u16 module_id, u8 instance_id)
{
	int idx;

	mutex_lock(&adev->modres_mutex);

	idx = avs_module_id_entry_index(adev, module_id);
	if (idx == -ENOENT) {
		dev_err(adev->dev, "invalid module id: %d", module_id);
		goto exit;
	}

	ida_free(adev->mod_idas[idx], instance_id);
exit:
	mutex_unlock(&adev->modres_mutex);
}

/*
 * Once driver loads FW it should keep it in memory, so we are not affected
 * by FW removal from filesystem or even worse by loading different FW at
 * runtime suspend/resume.
 */
int avs_request_firmware(struct avs_dev *adev, const struct firmware **fw_p, const char *name)
{
	struct avs_fw_entry *entry;
	int ret;

	/* first check in list if it is not already loaded */
	list_for_each_entry(entry, &adev->fw_list, node) {
		if (!strcmp(name, entry->name)) {
			*fw_p = entry->fw;
			return 0;
		}
	}

	/* FW is not loaded, let's load it now and add to the list */
	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
		return -ENOMEM;

	entry->name = kstrdup(name, GFP_KERNEL);
	if (!entry->name) {
		kfree(entry);
		return -ENOMEM;
	}

	ret = request_firmware(&entry->fw, name, adev->dev);
	if (ret < 0) {
		kfree(entry->name);
		kfree(entry);
		return ret;
	}

	*fw_p = entry->fw;

	list_add_tail(&entry->node, &adev->fw_list);

	return 0;
}

/*
 * Release single FW entry, used to handle errors in functions calling
 * avs_request_firmware()
 */
void avs_release_last_firmware(struct avs_dev *adev)
{
	struct avs_fw_entry *entry;

	entry = list_last_entry(&adev->fw_list, typeof(*entry), node);

	list_del(&entry->node);
	release_firmware(entry->fw);
	kfree(entry->name);
	kfree(entry);
}

/*
 * Release all FW entries, used on driver removal
 */
void avs_release_firmwares(struct avs_dev *adev)
{
	struct avs_fw_entry *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &adev->fw_list, node) {
		list_del(&entry->node);
		release_firmware(entry->fw);
		kfree(entry->name);
		kfree(entry);
	}
}
