// SPDX-License-Identifier: GPL-2.0-only
/*
 * Qualcomm SMEM NAND flash partition parser
 *
 * Copyright (C) 2020, Linaro Ltd.
 */

#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/slab.h>
#include <linux/soc/qcom/smem.h>

#define SMEM_AARM_PARTITION_TABLE	9
#define SMEM_APPS			0

#define SMEM_FLASH_PART_MAGIC1		0x55ee73aa
#define SMEM_FLASH_PART_MAGIC2		0xe35ebddb
#define SMEM_FLASH_PTABLE_V3		3
#define SMEM_FLASH_PTABLE_V4		4
#define SMEM_FLASH_PTABLE_MAX_PARTS_V3	16
#define SMEM_FLASH_PTABLE_MAX_PARTS_V4	48
#define SMEM_FLASH_PTABLE_HDR_LEN	(4 * sizeof(u32))
#define SMEM_FLASH_PTABLE_NAME_SIZE	16

/**
 * struct smem_flash_pentry - SMEM Flash partition entry
 * @name: Name of the partition
 * @offset: Offset in blocks
 * @length: Length of the partition in blocks
 * @attr: Flags for this partition
 */
struct smem_flash_pentry {
	char name[SMEM_FLASH_PTABLE_NAME_SIZE];
	__le32 offset;
	__le32 length;
	u8 attr;
} __packed __aligned(4);

/**
 * struct smem_flash_ptable - SMEM Flash partition table
 * @magic1: Partition table Magic 1
 * @magic2: Partition table Magic 2
 * @version: Partition table version
 * @numparts: Number of partitions in this ptable
 * @pentry: Flash partition entries belonging to this ptable
 */
struct smem_flash_ptable {
	__le32 magic1;
	__le32 magic2;
	__le32 version;
	__le32 numparts;
	struct smem_flash_pentry pentry[SMEM_FLASH_PTABLE_MAX_PARTS_V4];
} __packed __aligned(4);

static int parse_qcomsmem_part(struct mtd_info *mtd,
			       const struct mtd_partition **pparts,
			       struct mtd_part_parser_data *data)
{
	struct smem_flash_pentry *pentry;
	struct smem_flash_ptable *ptable;
	size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
	struct mtd_partition *parts;
	int ret, i, numparts;
	char *name, *c;

	if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS)
			&& mtd->type == MTD_NORFLASH) {
		pr_err("%s: SMEM partition parser is incompatible with 4K sectors\n",
				mtd->name);
		return -EINVAL;
	}

	pr_debug("Parsing partition table info from SMEM\n");
	ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len);
	if (IS_ERR(ptable)) {
		pr_err("Error reading partition table header\n");
		return PTR_ERR(ptable);
	}

	/* Verify ptable magic */
	if (le32_to_cpu(ptable->magic1) != SMEM_FLASH_PART_MAGIC1 ||
	    le32_to_cpu(ptable->magic2) != SMEM_FLASH_PART_MAGIC2) {
		pr_err("Partition table magic verification failed\n");
		return -EINVAL;
	}

	/* Ensure that # of partitions is less than the max we have allocated */
	numparts = le32_to_cpu(ptable->numparts);
	if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
		pr_err("Partition numbers exceed the max limit\n");
		return -EINVAL;
	}

	/* Find out length of partition data based on table version */
	if (le32_to_cpu(ptable->version) <= SMEM_FLASH_PTABLE_V3) {
		len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V3 *
			sizeof(struct smem_flash_pentry);
	} else if (le32_to_cpu(ptable->version) == SMEM_FLASH_PTABLE_V4) {
		len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V4 *
			sizeof(struct smem_flash_pentry);
	} else {
		pr_err("Unknown ptable version (%d)", le32_to_cpu(ptable->version));
		return -EINVAL;
	}

	/*
	 * Now that the partition table header has been parsed, verified
	 * and the length of the partition table calculated, read the
	 * complete partition table
	 */
	ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len);
	if (IS_ERR(ptable)) {
		pr_err("Error reading partition table\n");
		return PTR_ERR(ptable);
	}

	parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL);
	if (!parts)
		return -ENOMEM;

	for (i = 0; i < numparts; i++) {
		pentry = &ptable->pentry[i];
		if (pentry->name[0] == '\0')
			continue;

		name = kstrdup(pentry->name, GFP_KERNEL);
		if (!name) {
			ret = -ENOMEM;
			goto out_free_parts;
		}

		/* Convert name to lower case */
		for (c = name; *c != '\0'; c++)
			*c = tolower(*c);

		parts[i].name = name;
		parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
		parts[i].mask_flags = pentry->attr;
		parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize;
		pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
			 i, pentry->name, le32_to_cpu(pentry->offset),
			 le32_to_cpu(pentry->length), pentry->attr);
	}

	pr_debug("SMEM partition table found: ver: %d len: %d\n",
		 le32_to_cpu(ptable->version), numparts);
	*pparts = parts;

	return numparts;

out_free_parts:
	while (--i >= 0)
		kfree(parts[i].name);
	kfree(parts);
	*pparts = NULL;

	return ret;
}

static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts,
				   int nr_parts)
{
	int i;

	for (i = 0; i < nr_parts; i++)
		kfree(pparts[i].name);
}

static const struct of_device_id qcomsmem_of_match_table[] = {
	{ .compatible = "qcom,smem-part" },
	{},
};
MODULE_DEVICE_TABLE(of, qcomsmem_of_match_table);

static struct mtd_part_parser mtd_parser_qcomsmem = {
	.parse_fn = parse_qcomsmem_part,
	.cleanup = parse_qcomsmem_cleanup,
	.name = "qcomsmem",
	.of_match_table = qcomsmem_of_match_table,
};
module_mtd_part_parser(mtd_parser_qcomsmem);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
MODULE_DESCRIPTION("Qualcomm SMEM NAND flash partition parser");
