// 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/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);
	}
}
