/*
 * drivers/amlogic/media/common/firmware/firmware.c
 *
 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/slab.h>

#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/cpu_version.h>
#include "../../stream_input/amports/amports_priv.h"
#include "../../frame_provider/decoder/utils/vdec.h"
#include "firmware_priv.h"
#include "../chips/chips.h"
#include <linux/string.h>
#include <linux/amlogic/media/utils/log.h>
#include <linux/firmware.h>
#include <linux/amlogic/tee.h>
#include <linux/amlogic/major.h>
#include <linux/cdev.h>
#include <linux/crc32.h>
#include "../chips/decoder_cpu_ver_info.h"

/* major.minor */
#define PACK_VERS "v0.2"

#define CLASS_NAME	"firmware_codec"
#define DEV_NAME	"firmware_vdec"
#define DIR		"video"
#define FRIMWARE_SIZE	(64 * 1024) /*64k*/
#define BUFF_SIZE	(1024 * 1024 * 2)

#define FW_LOAD_FORCE	(0x1)
#define FW_LOAD_TRY	(0X2)

/*the first 256 bytes are signature data*/
#define SEC_OFFSET	(256)

#define TRY_PARSE_MAX	(256)

#define PACK ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K')
#define CODE ('C' << 24 | 'O' << 16 | 'D' << 8 | 'E')

#ifndef FIRMWARE_MAJOR
#define FIRMWARE_MAJOR AMSTREAM_MAJOR
#endif

static DEFINE_MUTEX(mutex);

static  struct ucode_file_info_s ucode_info[] = {
#include "firmware_cfg.h"
};

static const struct file_operations fw_fops = {
	.owner = THIS_MODULE
};

struct fw_mgr_s *g_mgr;
struct fw_dev_s *g_dev;

static u32 debug;
static u32 detail;

int get_firmware_data(unsigned int format, char *buf)
{
	int data_len, ret = -1;
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_info_s *info;

	pr_info("[%s], the fw (%s) will be loaded.\n",
		tee_enabled() ? "TEE" : "LOCAL",
		get_fw_format_name(format));

	if (tee_enabled())
		return 0;

	mutex_lock(&mutex);

	if (list_empty(&mgr->fw_head)) {
		pr_info("the info list is empty.\n");
		goto out;
	}

	list_for_each_entry(info, &mgr->fw_head, node) {
		if (format != info->format)
			continue;

		data_len = info->data->head.data_size;
		memcpy(buf, info->data->data, data_len);
		ret = data_len;

		break;
	}
out:
	mutex_unlock(&mutex);

	return ret;
}
EXPORT_SYMBOL(get_firmware_data);

int get_data_from_name(const char *name, char *buf)
{
	int data_len, ret = -1;
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_info_s *info;
	char *fw_name = __getname();
	int len;

	if (fw_name == NULL)
		return -ENOMEM;

	len = snprintf(fw_name, PATH_MAX, "%s.bin", name);
	if (len >= PATH_MAX) {
		__putname(fw_name);
		return -ENAMETOOLONG;
	}

	mutex_lock(&mutex);

	if (list_empty(&mgr->fw_head)) {
		pr_info("the info list is empty.\n");
		goto out;
	}

	list_for_each_entry(info, &mgr->fw_head, node) {
		if (strcmp(fw_name, info->name))
			continue;

		data_len = info->data->head.data_size;
		memcpy(buf, info->data->data, data_len);
		ret = data_len;

		break;
	}
out:
	mutex_unlock(&mutex);

	__putname(fw_name);

	return ret;
}
EXPORT_SYMBOL(get_data_from_name);

static int fw_probe(char *buf)
{
	int magic = 0;

	memcpy(&magic, buf, sizeof(int));
	return magic;
}

static int request_firmware_from_sys(const char *file_name,
		char *buf, int size)
{
	int ret = -1;
	const struct firmware *fw;
	int magic, offset = 0;

	pr_info("Try to load %s  ...\n", file_name);

	ret = request_firmware(&fw, file_name, g_dev->dev);
	if (ret < 0) {
		pr_info("Error : %d can't load the %s.\n", ret, file_name);
		goto err;
	}

	if (fw->size > size) {
		pr_info("Not enough memory size for ucode.\n");
		ret = -ENOMEM;
		goto release;
	}

	magic = fw_probe((char *)fw->data);
	if (magic != PACK && magic != CODE) {
		if (fw->size < SEC_OFFSET) {
			pr_info("This is an invalid firmware file.\n");
			goto release;
		}

		magic = fw_probe((char *)fw->data + SEC_OFFSET);
		if (magic != PACK) {
			pr_info("The firmware file is not packet.\n");
			goto release;
		}

		offset = SEC_OFFSET;
	}

	memcpy(buf, (char *)fw->data + offset, fw->size - offset);

	pr_info("load firmware size : %zd, Name : %s.\n",
		fw->size, file_name);
	ret = fw->size;
release:
	release_firmware(fw);
err:
	return ret;
}

int request_decoder_firmware_on_sys(enum vformat_e format,
	const char *file_name, char *buf, int size)
{
	int ret;

	ret = get_data_from_name(file_name, buf);
	if (ret < 0)
		pr_info("Get firmware fail.\n");

	if (ret > size) {
		pr_info("Not enough memory.\n");
		return -ENOMEM;
	}

	return ret;
}
int get_decoder_firmware_data(enum vformat_e format,
	const char *file_name, char *buf, int size)
{
	int ret;

	ret = request_decoder_firmware_on_sys(format, file_name, buf, size);
	if (ret < 0)
		pr_info("get_decoder_firmware_data %s for format %d failed!\n",
				file_name, format);

	return ret;
}
EXPORT_SYMBOL(get_decoder_firmware_data);

static unsigned long fw_mgr_lock(struct fw_mgr_s *mgr)
{
	unsigned long flags;

	spin_lock_irqsave(&mgr->lock, flags);
	return flags;
}

static void fw_mgr_unlock(struct fw_mgr_s *mgr, unsigned long flags)
{
	spin_unlock_irqrestore(&mgr->lock, flags);
}

static void fw_add_info(struct fw_info_s *info)
{
	unsigned long flags;
	struct fw_mgr_s *mgr = g_mgr;

	flags = fw_mgr_lock(mgr);
	list_add(&info->node, &mgr->fw_head);
	fw_mgr_unlock(mgr, flags);
}

static void fw_del_info(struct fw_info_s *info)
{
	unsigned long flags;
	struct fw_mgr_s *mgr = g_mgr;

	flags = fw_mgr_lock(mgr);
	list_del(&info->node);
	kfree(info);
	fw_mgr_unlock(mgr, flags);
}

static void fw_info_walk(void)
{
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_info_s *info;

	if (list_empty(&mgr->fw_head)) {
		pr_info("the info list is empty.\n");
		return;
	}

	list_for_each_entry(info, &mgr->fw_head, node) {
		if (IS_ERR_OR_NULL(info->data))
			continue;

		pr_info("name : %s.\n", info->name);
		pr_info("ver  : %s.\n",
			info->data->head.version);
		pr_info("crc  : 0x%x.\n",
			info->data->head.checksum);
		pr_info("size : %d.\n",
			info->data->head.data_size);
		pr_info("maker: %s.\n",
			info->data->head.maker);
		pr_info("from : %s.\n", info->src_from);
		pr_info("date : %s.\n",
			info->data->head.date);
		if (info->data->head.duplicate)
			pr_info("NOTE : Dup from %s.\n",
				info->data->head.dup_from);
		pr_info("\n");
	}
}

static void fw_files_info_walk(void)
{
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_files_s *files;

	if (list_empty(&mgr->files_head)) {
		pr_info("the file list is empty.\n");
		return;
	}

	list_for_each_entry(files, &mgr->files_head, node) {
		pr_info("type : %s.\n", !files->fw_type ?
			"VIDEO_DECODE" : files->fw_type == 1 ?
			"VIDEO_ENCODE" : "VIDEO_MISC");
		pr_info("from : %s.\n", !files->file_type ?
			"VIDEO_PACKAGE" : "VIDEO_FW_FILE");
		pr_info("path : %s.\n", files->path);
		pr_info("name : %s.\n\n", files->name);
	}
}

static ssize_t info_show(struct class *class,
			struct class_attribute *attr, char *buf)
{
	char *pbuf = buf;
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_info_s *info;
	unsigned int secs = 0;
	struct tm tm;

	mutex_lock(&mutex);

	if (list_empty(&mgr->fw_head)) {
		pbuf += sprintf(pbuf, "No firmware.\n");
		goto out;
	}

	/* shows version of driver. */
	pr_info("The driver version is %s\n", PACK_VERS);

	list_for_each_entry(info, &mgr->fw_head, node) {
		if (IS_ERR_OR_NULL(info->data))
			continue;

		if (detail) {
			pr_info("%-5s: %s\n", "name", info->name);
			pr_info("%-5s: %s\n", "ver",
				info->data->head.version);
			pr_info("%-5s: 0x%x\n", "sum",
				info->data->head.checksum);
			pr_info("%-5s: %d\n", "size",
				info->data->head.data_size);
			pr_info("%-5s: %s\n", "maker",
				info->data->head.maker);
			pr_info("%-5s: %s\n", "from",
				info->src_from);
			pr_info("%-5s: %s\n\n", "date",
				info->data->head.date);
			continue;
		}

		secs = info->data->head.time
			- sys_tz.tz_minuteswest * 60;
		time_to_tm(secs, 0, &tm);

		pr_info("%s %-16s, %02d:%02d:%02d %d/%d/%ld, %s %-8s, %s %-8s, %s %s\n",
			"fmt:", info->data->head.format,
			tm.tm_hour, tm.tm_min, tm.tm_sec,
			tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900,
			"cmtid:", info->data->head.commit,
			"chgid:", info->data->head.change_id,
			"mk:", info->data->head.maker);
	}
out:
	mutex_unlock(&mutex);

	return pbuf - buf;
}

static ssize_t info_store(struct class *cls,
	struct class_attribute *attr, const char *buf, size_t count)
{
	if (kstrtoint(buf, 0, &detail) < 0)
		return -EINVAL;

	return count;
}

static int fw_info_fill(void)
{
	int ret = 0, i, len;
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_files_s *files;
	int info_size = ARRAY_SIZE(ucode_info);
	char *path = __getname();
	const char *name;

	if (path == NULL)
		return -ENOMEM;

	for (i = 0; i < info_size; i++) {
		name = ucode_info[i].name;
		if (IS_ERR_OR_NULL(name))
			break;

		len = snprintf(path, PATH_MAX, "%s/%s", DIR,
			ucode_info[i].name);
		if (len >= PATH_MAX)
			continue;

		files = kzalloc(sizeof(struct fw_files_s), GFP_KERNEL);
		if (files == NULL) {
			__putname(path);
			return -ENOMEM;
		}

		files->file_type = ucode_info[i].file_type;
		files->fw_type = ucode_info[i].fw_type;
		strncpy(files->path, path, sizeof(files->path));
		files->path[sizeof(files->path) - 1] = '\0';
		strncpy(files->name, name, sizeof(files->name));
		files->name[sizeof(files->name) - 1] = '\0';

		list_add(&files->node, &mgr->files_head);
	}

	__putname(path);

	if (debug)
		fw_files_info_walk();

	return ret;
}

static int fw_data_check_sum(struct firmware_s *fw)
{
	unsigned int crc;

	crc = crc32_le(~0U, fw->data, fw->head.data_size);

	/*pr_info("firmware crc result : 0x%x\n", crc ^ ~0U);*/

	return fw->head.checksum != (crc ^ ~0U) ? 0 : 1;
}

static int fw_data_filter(struct firmware_s *fw,
	struct fw_info_s *fw_info)
{
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_info_s *info, *tmp;
	int cpu = fw_get_cpu(fw->head.cpu);

	if (mgr->cur_cpu < cpu) {
		kfree(fw_info);
		kfree(fw);
		return -1;
	}

	/* the encode fw need to ignoring filtering rules. */
	if (fw_info->format == FIRMWARE_MAX)
		return 0;

	list_for_each_entry_safe(info, tmp, &mgr->fw_head, node) {
		if (info->format != fw_info->format)
			continue;

		if (IS_ERR_OR_NULL(info->data)) {
			fw_del_info(info);
			return 0;
		}

		/* high priority of VIDEO_FW_FILE */
		if (info->file_type == VIDEO_FW_FILE) {
			pr_info("the %s need to priority proc.\n",info->name);
			kfree(fw_info);
			kfree(fw);
			return 1;
		}

		/* the cpu ver is lower and needs to be filtered */
		if (cpu < fw_get_cpu(info->data->head.cpu)) {
			if (debug)
				pr_info("keep the newer fw (%s) and ignore the older fw (%s).\n",
					info->name, fw_info->name);
			kfree(fw_info);
			kfree(fw);
			return 1;
		}

		/* removes not match fw from info list */
		if (debug)
			pr_info("drop the old fw (%s) will be load the newer fw (%s).\n",
					info->name, fw_info->name);
		kfree(info->data);
		fw_del_info(info);
	}

	return 0;
}

static int fw_replace_dup_data(char *buf)
{
	int ret = 0;
	struct fw_mgr_s *mgr = g_mgr;
	struct package_s *pkg =
		(struct package_s *) buf;
	struct package_info_s *pinfo =
		(struct package_info_s *) pkg->data;
	struct fw_info_s *info = NULL;
	char *pdata = pkg->data;
	int try_cnt = TRY_PARSE_MAX;

	do {
		if (!pinfo->head.length)
			break;
		list_for_each_entry(info, &mgr->fw_head, node) {
			struct firmware_s *comp = NULL;
			struct firmware_s *data = NULL;
			int len = 0;

			comp = (struct firmware_s *)pinfo->data;
			if (comp->head.duplicate)
				break;

			if (!info->data->head.duplicate ||
				comp->head.checksum !=
				info->data->head.checksum)
				continue;

			len = pinfo->head.length;
			data = kzalloc(len, GFP_KERNEL);
			if (data == NULL) {
				ret = -ENOMEM;
				goto out;
			}

			memcpy(data, pinfo->data, len);

			/* update header information. */
			memcpy(data, info->data, sizeof(*data));

			/* if replaced success need to update real size. */
			data->head.data_size = comp->head.data_size;

			kfree(info->data);
			info->data = data;
		}
		pdata += (pinfo->head.length + sizeof(*pinfo));
		pinfo = (struct package_info_s *)pdata;
	} while (try_cnt--);
out:
	return ret;
}

static int fw_check_pack_version(char *buf)
{
	struct package_s *pack = NULL;
	int major, minor, major_fw, minor_fw;
	int ret;

	pack = (struct package_s *) buf;
	ret = sscanf(PACK_VERS, "v%x.%x", &major, &minor);
	if (ret != 2)
		return -1;

	major_fw = (pack->head.version >> 16) & 0xff;
	minor_fw = pack->head.version & 0xff;

	if (major < major_fw) {
		pr_info("the pack ver v%d.%d too higher to unsupport.\n",
			major_fw, minor_fw);
		return -1;
	}

	if (minor < minor_fw) {
		pr_info("The fw driver version (v%d.%d) is lower than the pkg version (v%d.%d).\n",
			major, minor, major_fw, minor_fw);
		pr_info("The driver version is too low that may affect the work please update asap.\n");
	}

	if (debug) {
		pr_info("The package has %d fws totally.\n", pack->head.total);
		pr_info("The driver ver is v%d.%d\n", major, minor);
		pr_info("The firmware ver is v%d.%d\n", major_fw, minor_fw);
	}

	return 0;
}

static int fw_package_parse(struct fw_files_s *files,
	char *buf, int size)
{
	int ret = 0;
	struct package_info_s *pack_info;
	struct fw_info_s *info;
	struct firmware_s *data;
	char *pack_data;
	int info_len, len;
	int try_cnt = TRY_PARSE_MAX;
	char *path = __getname();

	if (path == NULL)
		return -ENOMEM;

	pack_data = ((struct package_s *)buf)->data;
	pack_info = (struct package_info_s *)pack_data;
	info_len = sizeof(struct package_info_s);

	do {
		if (!pack_info->head.length)
			break;

		len = snprintf(path, PATH_MAX, "%s/%s", DIR,
			pack_info->head.name);
		if (len >= PATH_MAX)
			continue;

		info = kzalloc(sizeof(struct fw_info_s), GFP_KERNEL);
		if (info == NULL) {
			ret = -ENOMEM;
			goto out;
		}

		data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
		if (data == NULL) {
			kfree(info);
			ret = -ENOMEM;
			goto out;
		}

		info->file_type = files->file_type;
		strncpy(info->src_from, files->name,
			sizeof(info->src_from));
		info->src_from[sizeof(info->src_from) - 1] = '\0';
		strncpy(info->name, pack_info->head.name,
			sizeof(info->name));
		info->name[sizeof(info->name) - 1] = '\0';
		info->format = get_fw_format(pack_info->head.format);

		len = pack_info->head.length;
		memcpy(data, pack_info->data, len);

		pack_data += (pack_info->head.length + info_len);
		pack_info = (struct package_info_s *)pack_data;

		if (!data->head.duplicate &&
			!fw_data_check_sum(data)) {
			pr_info("check sum fail !\n");
			kfree(data);
			kfree(info);
			goto out;
		}

		if (fw_data_filter(data, info))
			continue;

		if (debug)
			pr_info("adds %s to the fw list.\n", info->name);

		info->data = data;
		fw_add_info(info);
	} while (try_cnt--);

	/* process the fw of dup attribute. */
	ret = fw_replace_dup_data(buf);
	if (ret)
		pr_err("replace dup fw failed.\n");
out:
	__putname(path);

	return ret;
}

static int fw_code_parse(struct fw_files_s *files,
	char *buf, int size)
{
	struct fw_info_s *info;

	info = kzalloc(sizeof(struct fw_info_s), GFP_KERNEL);
	if (info == NULL)
		return -ENOMEM;

	info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
	if (info->data == NULL) {
		kfree(info);
		return -ENOMEM;
	}

	info->file_type = files->file_type;
	strncpy(info->src_from, files->name,
		sizeof(info->src_from));
	info->src_from[sizeof(info->src_from) - 1] = '\0';
	memcpy(info->data, buf, size);

	if (!fw_data_check_sum(info->data)) {
		pr_info("check sum fail !\n");
		kfree(info->data);
		kfree(info);
		return -1;
	}

	if (debug)
		pr_info("adds %s to the fw list.\n", info->name);

	fw_add_info(info);

	return 0;
}

static int get_firmware_from_sys(const char *path,
	char *buf, int size)
{
	int len = 0;

	len = request_firmware_from_sys(path, buf, size);
	if (len < 0)
		pr_info("get data from fsys fail.\n");

	return len;
}

static int fw_data_binding(void)
{
	int ret = 0, magic = 0;
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_files_s *files, *tmp;
	char *buf = NULL;
	int size;

	if (list_empty(&mgr->files_head)) {
		pr_info("the file list is empty.\n");
		return 0;
	}

	buf = vmalloc(BUFF_SIZE);
	if (IS_ERR_OR_NULL(buf))
		return -ENOMEM;

	memset(buf, 0, BUFF_SIZE);

	list_for_each_entry_safe(files, tmp, &mgr->files_head, node) {
		size = get_firmware_from_sys(files->path, buf, BUFF_SIZE);
		magic = fw_probe(buf);

		if (files->file_type == VIDEO_PACKAGE && magic == PACK) {
			if (!fw_check_pack_version(buf))
				ret = fw_package_parse(files, buf, size);
		} else if (files->file_type == VIDEO_FW_FILE && magic == CODE) {
			ret = fw_code_parse(files, buf, size);
		} else {
			list_del(&files->node);
			kfree(files);
			pr_info("invaild file type.\n");
		}

		memset(buf, 0, BUFF_SIZE);
	}

	if (debug)
		fw_info_walk();

	vfree(buf);

	return ret;
}

static int fw_pre_load(void)
{
	if (fw_info_fill() < 0) {
		pr_info("Get path fail.\n");
		return -1;
	}

	if (fw_data_binding() < 0) {
		pr_info("Set data fail.\n");
		return -1;
	}

	return 0;
}

static int fw_mgr_init(void)
{
	g_mgr = kzalloc(sizeof(struct fw_mgr_s), GFP_KERNEL);
	if (IS_ERR_OR_NULL(g_mgr))
		return -ENOMEM;

	g_mgr->cur_cpu = get_cpu_major_id();
	INIT_LIST_HEAD(&g_mgr->files_head);
	INIT_LIST_HEAD(&g_mgr->fw_head);
	spin_lock_init(&g_mgr->lock);

	return 0;
}

static void fw_ctx_clean(void)
{
	struct fw_mgr_s *mgr = g_mgr;
	struct fw_files_s *files;
	struct fw_info_s *info;
	unsigned long flags;

	flags = fw_mgr_lock(mgr);
	while (!list_empty(&mgr->files_head)) {
		files = list_entry(mgr->files_head.next,
			struct fw_files_s, node);
		list_del(&files->node);
		kfree(files);
	}

	while (!list_empty(&mgr->fw_head)) {
		info = list_entry(mgr->fw_head.next,
			struct fw_info_s, node);
		list_del(&info->node);
		kfree(info->data);
		kfree(info);
	}
	fw_mgr_unlock(mgr, flags);
}

int video_fw_reload(int mode)
{
	int ret = 0;
	struct fw_mgr_s *mgr = g_mgr;

	if (tee_enabled())
		return 0;

	mutex_lock(&mutex);

	if (mode & FW_LOAD_FORCE) {
		fw_ctx_clean();

		ret = fw_pre_load();
		if (ret < 0)
			pr_err("The fw reload fail.\n");
	} else if (mode & FW_LOAD_TRY) {
		if (!list_empty(&mgr->fw_head)) {
			pr_info("The fw has been loaded.\n");
			goto out;
		}

		ret = fw_pre_load();
		if (ret < 0)
			pr_err("The fw try to reload fail.\n");
	}
out:
	mutex_unlock(&mutex);

	return ret;
}
EXPORT_SYMBOL(video_fw_reload);

static ssize_t reload_show(struct class *class,
			struct class_attribute *attr, char *buf)
{
	char *pbuf = buf;

	pbuf += sprintf(pbuf, "The fw reload usage.\n");
	pbuf += sprintf(pbuf, "> set 1 means that the fw is forced to update\n");
	pbuf += sprintf(pbuf, "> set 2 means that the fw is try to reload\n");

	return pbuf - buf;
}

static ssize_t reload_store(struct class *class,
		struct class_attribute *attr,
		const char *buf, size_t size)
{
	int ret = -1;
	unsigned int val;

	ret = kstrtoint(buf, 0, &val);
	if (ret != 0)
		return -EINVAL;

	ret = video_fw_reload(val);
	if (ret < 0)
		pr_err("fw reload fail.\n");

	return size;
}

static ssize_t debug_show(struct class *cls,
	struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%x\n", debug);
}

static ssize_t debug_store(struct class *cls,
	struct class_attribute *attr, const char *buf, size_t count)
{
	if (kstrtoint(buf, 0, &debug) < 0)
		return -EINVAL;

	return count;
}

static struct class_attribute fw_class_attrs[] = {
	__ATTR(info, 0664, info_show, info_store),
	__ATTR(reload, 0664, reload_show, reload_store),
	__ATTR(debug, 0664, debug_show, debug_store),
	__ATTR_NULL
};

static struct class fw_class = {
	.name = CLASS_NAME,
	.class_attrs = fw_class_attrs,
};

static int fw_driver_init(void)
{
	int ret = -1;

	g_dev = kzalloc(sizeof(struct fw_dev_s), GFP_KERNEL);
	if (IS_ERR_OR_NULL(g_dev))
		return -ENOMEM;

	g_dev->dev_no = MKDEV(FIRMWARE_MAJOR, 100);

	ret = register_chrdev_region(g_dev->dev_no, 1, DEV_NAME);
	if (ret < 0) {
		pr_info("Can't get major number %d.\n", FIRMWARE_MAJOR);
		goto err;
	}

	cdev_init(&g_dev->cdev, &fw_fops);
	g_dev->cdev.owner = THIS_MODULE;

	ret = cdev_add(&g_dev->cdev, g_dev->dev_no, 1);
	if (ret) {
		pr_info("Error %d adding cdev fail.\n", ret);
		goto err;
	}

	ret = class_register(&fw_class);
	if (ret < 0) {
		pr_info("Failed in creating class.\n");
		goto err;
	}

	g_dev->dev = device_create(&fw_class, NULL,
		g_dev->dev_no, NULL, DEV_NAME);
	if (IS_ERR_OR_NULL(g_dev->dev)) {
		pr_info("Create device failed.\n");
		ret = -ENODEV;
		goto err;
	}

	pr_info("Registered firmware driver success.\n");
err:
	return ret;
}

static void fw_driver_exit(void)
{
	cdev_del(&g_dev->cdev);
	device_destroy(&fw_class, g_dev->dev_no);
	class_unregister(&fw_class);
	unregister_chrdev_region(g_dev->dev_no, 1);
	kfree(g_dev);
	kfree(g_mgr);
}

static int __init fw_module_init(void)
{
	int ret = -1;

	ret = fw_driver_init();
	if (ret) {
		pr_info("Error %d firmware driver init fail.\n", ret);
		goto err;
	}

	ret = fw_mgr_init();
	if (ret) {
		pr_info("Error %d firmware mgr init fail.\n", ret);
		goto err;
	}

	ret = fw_pre_load();
	if (ret) {
		pr_info("Error %d firmware pre load fail.\n", ret);
		goto err;
	}
err:
	return ret;
}

static void __exit fw_module_exit(void)
{
	fw_ctx_clean();
	fw_driver_exit();
	pr_info("Firmware driver cleaned up.\n");
}

module_init(fw_module_init);
module_exit(fw_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>");
