// SPDX-License-Identifier: GPL-2.0+
/*
 *  Software partition device (UCLASS_PARTITION)
 *
 *  Copyright (c) 2021 Linaro Limited
 *			Author: AKASHI Takahiro
 */

#define LOG_CATEGORY UCLASS_PARTITION

#include <blk.h>
#include <dm.h>
#include <log.h>
#include <part.h>
#include <vsprintf.h>
#include <dm/device-internal.h>
#include <dm/lists.h>

int part_create_block_devices(struct udevice *blk_dev)
{
	int part, count;
	struct blk_desc *desc = dev_get_uclass_plat(blk_dev);
	struct disk_partition info;
	struct disk_part *part_data;
	char devname[32];
	struct udevice *dev;
	int ret;

	if (!CONFIG_IS_ENABLED(PARTITIONS) ||
	    !CONFIG_IS_ENABLED(HAVE_BLOCK_DEVICE))
		return 0;

	if (device_get_uclass_id(blk_dev) != UCLASS_BLK)
		return 0;

	/* Add devices for each partition */
	for (count = 0, part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
		if (part_get_info(desc, part, &info))
			continue;
		snprintf(devname, sizeof(devname), "%s:%d", blk_dev->name,
			 part);

		ret = device_bind_driver(blk_dev, "blk_partition",
					 strdup(devname), &dev);
		if (ret)
			return ret;

		part_data = dev_get_uclass_plat(dev);
		part_data->partnum = part;
		part_data->gpt_part_info = info;
		count++;

		ret = device_probe(dev);
		if (ret) {
			debug("Can't probe\n");
			count--;
			device_unbind(dev);

			continue;
		}
	}
	debug("%s: %d partitions found in %s\n", __func__, count,
	      blk_dev->name);

	return 0;
}

static ulong blk_part_read(struct udevice *dev, lbaint_t start,
			   lbaint_t blkcnt, void *buffer)
{
	struct udevice *parent;
	struct disk_part *part;
	const struct blk_ops *ops;

	parent = dev_get_parent(dev);
	ops = blk_get_ops(parent);
	if (!ops->read)
		return -ENOSYS;

	part = dev_get_uclass_plat(dev);
	if (start >= part->gpt_part_info.size)
		return 0;

	if ((start + blkcnt) > part->gpt_part_info.size)
		blkcnt = part->gpt_part_info.size - start;
	start += part->gpt_part_info.start;

	return ops->read(parent, start, blkcnt, buffer);
}

static ulong blk_part_write(struct udevice *dev, lbaint_t start,
			    lbaint_t blkcnt, const void *buffer)
{
	struct udevice *parent;
	struct disk_part *part;
	const struct blk_ops *ops;

	parent = dev_get_parent(dev);
	ops = blk_get_ops(parent);
	if (!ops->write)
		return -ENOSYS;

	part = dev_get_uclass_plat(dev);
	if (start >= part->gpt_part_info.size)
		return 0;

	if ((start + blkcnt) > part->gpt_part_info.size)
		blkcnt = part->gpt_part_info.size - start;
	start += part->gpt_part_info.start;

	return ops->write(parent, start, blkcnt, buffer);
}

static ulong blk_part_erase(struct udevice *dev, lbaint_t start,
			    lbaint_t blkcnt)
{
	struct udevice *parent;
	struct disk_part *part;
	const struct blk_ops *ops;

	parent = dev_get_parent(dev);
	ops = blk_get_ops(parent);
	if (!ops->erase)
		return -ENOSYS;

	part = dev_get_uclass_plat(dev);
	if (start >= part->gpt_part_info.size)
		return 0;

	if ((start + blkcnt) > part->gpt_part_info.size)
		blkcnt = part->gpt_part_info.size - start;
	start += part->gpt_part_info.start;

	return ops->erase(parent, start, blkcnt);
}

static const struct blk_ops blk_part_ops = {
	.read	= blk_part_read,
	.write	= blk_part_write,
	.erase	= blk_part_erase,
};

U_BOOT_DRIVER(blk_partition) = {
	.name		= "blk_partition",
	.id		= UCLASS_PARTITION,
	.ops		= &blk_part_ops,
};

/*
 * BLOCK IO APIs
 */
static struct blk_desc *dev_get_blk(struct udevice *dev)
{
	struct blk_desc *block_dev;

	switch (device_get_uclass_id(dev)) {
	/*
	 * We won't support UCLASS_BLK with dev_* interfaces.
	 */
	case UCLASS_PARTITION:
		block_dev = dev_get_uclass_plat(dev_get_parent(dev));
		break;
	default:
		block_dev = NULL;
		break;
	}

	return block_dev;
}

unsigned long dev_read(struct udevice *dev, lbaint_t start,
		       lbaint_t blkcnt, void *buffer)
{
	struct blk_desc *block_dev;
	const struct blk_ops *ops;
	struct disk_part *part;
	lbaint_t start_in_disk;
	ulong blks_read;

	block_dev = dev_get_blk(dev);
	if (!block_dev)
		return -ENOSYS;

	ops = blk_get_ops(dev);
	if (!ops->read)
		return -ENOSYS;

	start_in_disk = start;
	if (device_get_uclass_id(dev) == UCLASS_PARTITION) {
		part = dev_get_uclass_plat(dev);
		start_in_disk += part->gpt_part_info.start;
	}

	if (blkcache_read(block_dev->if_type, block_dev->devnum,
			  start_in_disk, blkcnt, block_dev->blksz, buffer))
		return blkcnt;
	blks_read = ops->read(dev, start, blkcnt, buffer);
	if (blks_read == blkcnt)
		blkcache_fill(block_dev->if_type, block_dev->devnum,
			      start_in_disk, blkcnt, block_dev->blksz, buffer);

	return blks_read;
}

unsigned long dev_write(struct udevice *dev, lbaint_t start,
			lbaint_t blkcnt, const void *buffer)
{
	struct blk_desc *block_dev;
	const struct blk_ops *ops;

	block_dev = dev_get_blk(dev);
	if (!block_dev)
		return -ENOSYS;

	ops = blk_get_ops(dev);
	if (!ops->write)
		return -ENOSYS;

	blkcache_invalidate(block_dev->if_type, block_dev->devnum);

	return ops->write(dev, start, blkcnt, buffer);
}

unsigned long dev_erase(struct udevice *dev, lbaint_t start,
			lbaint_t blkcnt)
{
	struct blk_desc *block_dev;
	const struct blk_ops *ops;

	block_dev = dev_get_blk(dev);
	if (!block_dev)
		return -ENOSYS;

	ops = blk_get_ops(dev);
	if (!ops->erase)
		return -ENOSYS;

	blkcache_invalidate(block_dev->if_type, block_dev->devnum);

	return ops->erase(dev, start, blkcnt);
}

UCLASS_DRIVER(partition) = {
	.id		= UCLASS_PARTITION,
	.per_device_plat_auto	= sizeof(struct disk_part),
	.name		= "partition",
};
