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

	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_OR_NULL(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 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,
	.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");
