/*
 * Copyright (c) 2015-2016, 2020, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/seq_file.h>
#include <asm/setup.h>
#include <linux/mtd/partitions.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/genhd.h>
#include <linux/major.h>
#include <linux/mtd/blktrans.h>
#include <linux/mtd/mtd.h>
#include <linux/types.h>
#include <linux/blkdev.h>
#include "bootconfig.h"

static struct proc_dir_entry *boot_info_dir;
static struct proc_dir_entry *partname_dir[CONFIG_NUM_ALT_PARTITION];

static unsigned int num_parts;
static unsigned int flash_type_emmc;

struct sbl_if_dualboot_info_type_v2 *bootconfig1;
struct sbl_if_dualboot_info_type_v2 *bootconfig2;

static int getbinary_show(struct seq_file *m, void *v)
{
	struct sbl_if_dualboot_info_type_v2 *sbl_info_v2;

	sbl_info_v2 = m->private;
	memcpy(m->buf + m->count, sbl_info_v2,
		sizeof(struct sbl_if_dualboot_info_type_v2));
	m->count += sizeof(struct sbl_if_dualboot_info_type_v2);

	return 0;
}

static int getbinary_open(struct inode *inode, struct file *file)
{
	return single_open(file, getbinary_show, PDE_DATA(inode));
}

static const struct file_operations getbinary_ops = {
	.open		= getbinary_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int part_upgradepartition_show(struct seq_file *m, void *v)
{
	struct per_part_info *part_info_t = m->private;

	/*
	 * In case of NOR\NAND, SBLs change the names of paritions in
	 * such a way that the partition to upgrade is always suffixed
	 * by _1. This is not the case in eMMC as paritions are read
	 * from GPT and we have no control on it. So for eMMC we need
	 * to check and generate the name wheres for NOR\NAND it is
	 * always _1 SBLs should be modified not to change partition
	 * names so that it is consistent with GPT. Till that is done
	 * we will take care of it here.
	 */

	if (flash_type_emmc && (part_info_t->primaryboot))
		seq_printf(m, "%s\n", part_info_t->name);
	else
		seq_printf(m, "%s_1\n", part_info_t->name);

	return 0;

}

static int part_upgradepartition_open(struct inode *inode, struct file *file)
{
	return single_open(file, part_upgradepartition_show, PDE_DATA(inode));
}

static const struct file_operations upgradepartition_ops = {
	.open		= part_upgradepartition_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};


static ssize_t part_primaryboot_write(struct file *file,
				       const char __user *user,
				       size_t count, loff_t *data)
{
	int ret;
	char optstr[64];
	struct per_part_info *part_entry;
	unsigned long val;

	part_entry = PDE_DATA(file_inode(file));

	if (count == 0 || count > sizeof(optstr))
		return -EINVAL;

	ret = copy_from_user(optstr, user, count);
	if (ret)
		return ret;

	optstr[count - 1] = '\0';

	ret = kstrtoul(optstr, 0, &val);
	if (ret)
		return ret;

	part_entry->primaryboot = val;

	return count;

}

static int part_primaryboot_show(struct seq_file *m, void *v)
{
	struct per_part_info *part_entry;

	part_entry = m->private;
	seq_printf(m, "%x\n", part_entry->primaryboot);
	return 0;
}

static int part_primaryboot_open(struct inode *inode, struct file *file)
{
	return single_open(file, part_primaryboot_show, PDE_DATA(inode));
}

static const struct file_operations primaryboot_ops = {
	.open		= part_primaryboot_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= part_primaryboot_write,
};

#ifdef CONFIG_MTD
struct sbl_if_dualboot_info_type_v2 *read_bootconfig_mtd(
						struct mtd_info *master,
						uint64_t offset)
{

	size_t retlen = 0;
	struct sbl_if_dualboot_info_type_v2 *bootconfig_mtd;
	int ret;

	while (mtd_block_isbad(master, offset)) {
		offset += master->erasesize;
		if (offset >= master->size) {
			pr_alert("Bad blocks occurred while reading from \"%s\"\n",
					master->name);
			return NULL;
		}
	}
	bootconfig_mtd = kmalloc(sizeof(struct sbl_if_dualboot_info_type_v2),
				   GFP_ATOMIC);

	if (!bootconfig_mtd)
		return NULL;

	ret = mtd_read(master, offset,
			sizeof(struct sbl_if_dualboot_info_type_v2),
			&retlen, (void *)bootconfig_mtd);
	if (ret < 0) {
		pr_alert("error occured while reading from \"%s\"\n",
				master->name);
		bootconfig_mtd = NULL;
		kfree(bootconfig_mtd);
		return NULL;
	}

	if (bootconfig_mtd->magic_start != SMEM_DUAL_BOOTINFO_MAGIC_START) {
		pr_alert("Magic not found in \"%s\"\n", master->name);
		kfree(bootconfig_mtd);
		return NULL;
	}

	return bootconfig_mtd;
}
#endif

#ifdef CONFIG_MMC
struct sbl_if_dualboot_info_type_v2 *read_bootconfig_emmc(struct gendisk *disk,
						struct hd_struct *part)
{
	sector_t n;
	Sector sect;
	int ret;
	unsigned char *data;
	struct sbl_if_dualboot_info_type_v2 *bootconfig_emmc;
	unsigned ssz;
	struct block_device *bdev = NULL;

	bdev = bdget_disk(disk, 0);
	if (!bdev)
		return NULL;

	bdev->bd_invalidated = 1;
	ret = blkdev_get(bdev, FMODE_READ , NULL);
	if (ret)
		return NULL;

	ssz = bdev_logical_block_size(bdev);
	bootconfig_emmc = kmalloc(ssz, GFP_ATOMIC);
	if (!bootconfig_emmc)
		return NULL;

	n =  part->start_sect * (bdev_logical_block_size(bdev) / 512);
	data = read_dev_sector(bdev, n, &sect);
	put_dev_sector(sect);
	blkdev_put(bdev, FMODE_READ);
	if (!data) {
		kfree(bootconfig_emmc);
		return NULL;
	}

	memcpy(bootconfig_emmc, data, 512);

	if (bootconfig_emmc->magic_start != SMEM_DUAL_BOOTINFO_MAGIC_START) {
		pr_alert("Magic not found\n");
		kfree(bootconfig_emmc);
		return NULL;
	}

	return bootconfig_emmc;
}
#endif

#define BOOTCONFIG_PARTITION	"0:BOOTCONFIG"
#define BOOTCONFIG_PARTITION1	"0:BOOTCONFIG1"
#define ROOTFS_PARTITION	"rootfs"
#define MAX_MMC_DEVICE		2
static int __init bootconfig_partition_init(void)
{
	struct per_part_info *part_info;
	int i;
#ifdef CONFIG_MMC
	struct gendisk *disk = NULL;
	struct disk_part_iter piter;
	struct hd_struct *part;
	int partno;
#endif
	struct mtd_info *mtd = NULL;

	/*
	 * In case of NOR\NAND boot, there is a chance that emmc
	 * might have bootconfig paritions. This will try to read
	 * the bootconfig partitions and create a proc entry which
	 * is not correct since it is not booting from emmc.
	 */
#ifdef CONFIG_MTD
	mtd = get_mtd_device_nm(ROOTFS_PARTITION);
	if (IS_ERR(mtd))
		flash_type_emmc = 1;
	mtd = get_mtd_device_nm(BOOTCONFIG_PARTITION);
	if (IS_ERR_OR_NULL(mtd)) {

		bootconfig1 = read_bootconfig_mtd(mtd, 0);
		mtd = get_mtd_device_nm(BOOTCONFIG_PARTITION1);
		if (IS_ERR(mtd)) {
			pr_alert("%s: " BOOTCONFIG_PARTITION1 " not found\n",
				__func__);
			return 0;
		}

		bootconfig2 = read_bootconfig_mtd(mtd, 0);
	}
#else
	flash_type_emmc = 1;
#endif
#ifdef CONFIG_MMC
	if (IS_ERR_OR_NULL(mtd) && flash_type_emmc == 1) {
		flash_type_emmc = 0;
		for (i = 0; i < MAX_MMC_DEVICE; i++) {

			disk = get_gendisk(MKDEV(MMC_BLOCK_MAJOR, i*CONFIG_MMC_BLOCK_MINORS), &partno);
			if (!disk)
				return 0;

			disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
			while ((part = disk_part_iter_next(&piter))) {

				if (part->info) {
					if (!strcmp((char *)part->info->volname,
							BOOTCONFIG_PARTITION)) {
						bootconfig1 = read_bootconfig_emmc(disk,
									part);
					}

					if (!strcmp((char *)part->info->volname,
							BOOTCONFIG_PARTITION1)) {
						bootconfig2 = read_bootconfig_emmc(disk,
									 part);
						flash_type_emmc = 1;
					}
				}
			}
			disk_part_iter_exit(&piter);

			if (bootconfig1 || bootconfig2)
			       break;
		}
	}
#endif

	if (!bootconfig1) {
		if (bootconfig2)
			bootconfig1 = bootconfig2;
		else
			return 0;
	}

	if (!bootconfig2) {
		if (bootconfig1)
			bootconfig2 = bootconfig1;
		else
			return 0;
	}
/*
 * The following check is to handle the case when an image without
 * apps upgrade support is upgraded to the image that supports APPS
 * upgrade. Earlier, the bootconfig file will be chosen based on age,
 * but now bootconfig1 only is considered and bootconfig2 is a backup.
 * When bootconfig2 is active in the older image and sysupgrade
 * is done to it, we copy the bootconfig2 to bootconfig1 so that the
 * failsafe parameters can be retained.
 */
	if (bootconfig2->age > bootconfig1->age)
		bootconfig1 = bootconfig2;

	num_parts = bootconfig1->numaltpart;
	bootconfig1->age++;
	part_info = (struct per_part_info *)bootconfig1->per_part_entry;
	boot_info_dir = proc_mkdir("boot_info", NULL);
	if (!boot_info_dir)
		return 0;

	for (i = 0; i < num_parts; i++) {
		if (!flash_type_emmc &&
				(strncmp(part_info[i].name, "kernel",
					ALT_PART_NAME_LENGTH) == 0))
			continue;

		partname_dir[i] = proc_mkdir(part_info[i].name, boot_info_dir);
		if (partname_dir != NULL) {
			proc_create_data("primaryboot", S_IRUGO,
					   partname_dir[i],
					   &primaryboot_ops,
					   part_info + i);
			proc_create_data("upgradepartition", S_IRUGO,
					   partname_dir[i],
					   &upgradepartition_ops,
					   part_info + i);
		}
	}

	proc_create_data("getbinary_bootconfig", S_IRUGO, boot_info_dir,
			&getbinary_ops, bootconfig1);
	proc_create_data("getbinary_bootconfig1", S_IRUGO, boot_info_dir,
			&getbinary_ops, bootconfig1);

	return 0;
}
module_init(bootconfig_partition_init);

static void __exit bootconfig_partition_exit(void)
{
	struct per_part_info *part_info;
	int i;

	if (!bootconfig1)
		return;

	if (!bootconfig2)
		return;

	part_info = (struct per_part_info *)bootconfig1->per_part_entry;
	for (i = 0; i < num_parts; i++) {
		if (!flash_type_emmc &&
				(strncmp(part_info[i].name, "kernel",
					ALT_PART_NAME_LENGTH) == 0))
			continue;

		remove_proc_entry("primaryboot", partname_dir[i]);
		remove_proc_entry("upgradepartition", partname_dir[i]);
		remove_proc_entry(part_info[i].name, boot_info_dir);
	}
	remove_proc_entry("getbinary_bootconfig", boot_info_dir);
	remove_proc_entry("getbinary_bootconfig1", boot_info_dir);
	remove_proc_entry("boot_info", NULL);
	kfree(bootconfig1);
	kfree(bootconfig2);
}

module_exit(bootconfig_partition_exit);

MODULE_LICENSE("Dual BSD/GPL");
