// SPDX-License-Identifier: GPL-2.0
/*
 * fsl-mc object allocator driver
 *
 * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
 *
 */

#include <linux/module.h>
#include <linux/msi.h>
#include <linux/fsl/mc.h>

#include "fsl-mc-private.h"

static bool __must_check fsl_mc_is_allocatable(struct fsl_mc_device *mc_dev)
{
	return is_fsl_mc_bus_dpbp(mc_dev) ||
	       is_fsl_mc_bus_dpmcp(mc_dev) ||
	       is_fsl_mc_bus_dpcon(mc_dev);
}

/**
 * fsl_mc_resource_pool_add_device - add allocatable object to a resource
 * pool of a given fsl-mc bus
 *
 * @mc_bus: pointer to the fsl-mc bus
 * @pool_type: pool type
 * @mc_dev: pointer to allocatable fsl-mc device
 */
static int __must_check fsl_mc_resource_pool_add_device(struct fsl_mc_bus
								*mc_bus,
							enum fsl_mc_pool_type
								pool_type,
							struct fsl_mc_device
								*mc_dev)
{
	struct fsl_mc_resource_pool *res_pool;
	struct fsl_mc_resource *resource;
	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
	int error = -EINVAL;

	if (pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)
		goto out;
	if (!fsl_mc_is_allocatable(mc_dev))
		goto out;
	if (mc_dev->resource)
		goto out;

	res_pool = &mc_bus->resource_pools[pool_type];
	if (res_pool->type != pool_type)
		goto out;
	if (res_pool->mc_bus != mc_bus)
		goto out;

	mutex_lock(&res_pool->mutex);

	if (res_pool->max_count < 0)
		goto out_unlock;
	if (res_pool->free_count < 0 ||
	    res_pool->free_count > res_pool->max_count)
		goto out_unlock;

	resource = devm_kzalloc(&mc_bus_dev->dev, sizeof(*resource),
				GFP_KERNEL);
	if (!resource) {
		error = -ENOMEM;
		dev_err(&mc_bus_dev->dev,
			"Failed to allocate memory for fsl_mc_resource\n");
		goto out_unlock;
	}

	resource->type = pool_type;
	resource->id = mc_dev->obj_desc.id;
	resource->data = mc_dev;
	resource->parent_pool = res_pool;
	INIT_LIST_HEAD(&resource->node);
	list_add_tail(&resource->node, &res_pool->free_list);
	mc_dev->resource = resource;
	res_pool->free_count++;
	res_pool->max_count++;
	error = 0;
out_unlock:
	mutex_unlock(&res_pool->mutex);
out:
	return error;
}

/**
 * fsl_mc_resource_pool_remove_device - remove an allocatable device from a
 * resource pool
 *
 * @mc_dev: pointer to allocatable fsl-mc device
 *
 * It permanently removes an allocatable fsl-mc device from the resource
 * pool. It's an error if the device is in use.
 */
static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device
								   *mc_dev)
{
	struct fsl_mc_device *mc_bus_dev;
	struct fsl_mc_bus *mc_bus;
	struct fsl_mc_resource_pool *res_pool;
	struct fsl_mc_resource *resource;
	int error = -EINVAL;

	if (!fsl_mc_is_allocatable(mc_dev))
		goto out;

	resource = mc_dev->resource;
	if (!resource || resource->data != mc_dev)
		goto out;

	mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
	mc_bus = to_fsl_mc_bus(mc_bus_dev);
	res_pool = resource->parent_pool;
	if (res_pool != &mc_bus->resource_pools[resource->type])
		goto out;

	mutex_lock(&res_pool->mutex);

	if (res_pool->max_count <= 0)
		goto out_unlock;
	if (res_pool->free_count <= 0 ||
	    res_pool->free_count > res_pool->max_count)
		goto out_unlock;

	/*
	 * If the device is currently allocated, its resource is not
	 * in the free list and thus, the device cannot be removed.
	 */
	if (list_empty(&resource->node)) {
		error = -EBUSY;
		dev_err(&mc_bus_dev->dev,
			"Device %s cannot be removed from resource pool\n",
			dev_name(&mc_dev->dev));
		goto out_unlock;
	}

	list_del_init(&resource->node);
	res_pool->free_count--;
	res_pool->max_count--;

	devm_kfree(&mc_bus_dev->dev, resource);
	mc_dev->resource = NULL;
	error = 0;
out_unlock:
	mutex_unlock(&res_pool->mutex);
out:
	return error;
}

static const char *const fsl_mc_pool_type_strings[] = {
	[FSL_MC_POOL_DPMCP] = "dpmcp",
	[FSL_MC_POOL_DPBP] = "dpbp",
	[FSL_MC_POOL_DPCON] = "dpcon",
	[FSL_MC_POOL_IRQ] = "irq",
};

static int __must_check object_type_to_pool_type(const char *object_type,
						 enum fsl_mc_pool_type
								*pool_type)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(fsl_mc_pool_type_strings); i++) {
		if (strcmp(object_type, fsl_mc_pool_type_strings[i]) == 0) {
			*pool_type = i;
			return 0;
		}
	}

	return -EINVAL;
}

int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus,
					  enum fsl_mc_pool_type pool_type,
					  struct fsl_mc_resource **new_resource)
{
	struct fsl_mc_resource_pool *res_pool;
	struct fsl_mc_resource *resource;
	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
	int error = -EINVAL;

	BUILD_BUG_ON(ARRAY_SIZE(fsl_mc_pool_type_strings) !=
		     FSL_MC_NUM_POOL_TYPES);

	*new_resource = NULL;
	if (pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)
		goto out;

	res_pool = &mc_bus->resource_pools[pool_type];
	if (res_pool->mc_bus != mc_bus)
		goto out;

	mutex_lock(&res_pool->mutex);
	resource = list_first_entry_or_null(&res_pool->free_list,
					    struct fsl_mc_resource, node);

	if (!resource) {
		error = -ENXIO;
		dev_err(&mc_bus_dev->dev,
			"No more resources of type %s left\n",
			fsl_mc_pool_type_strings[pool_type]);
		goto out_unlock;
	}

	if (resource->type != pool_type)
		goto out_unlock;
	if (resource->parent_pool != res_pool)
		goto out_unlock;
	if (res_pool->free_count <= 0 ||
	    res_pool->free_count > res_pool->max_count)
		goto out_unlock;

	list_del_init(&resource->node);

	res_pool->free_count--;
	error = 0;
out_unlock:
	mutex_unlock(&res_pool->mutex);
	*new_resource = resource;
out:
	return error;
}
EXPORT_SYMBOL_GPL(fsl_mc_resource_allocate);

void fsl_mc_resource_free(struct fsl_mc_resource *resource)
{
	struct fsl_mc_resource_pool *res_pool;

	res_pool = resource->parent_pool;
	if (resource->type != res_pool->type)
		return;

	mutex_lock(&res_pool->mutex);
	if (res_pool->free_count < 0 ||
	    res_pool->free_count >= res_pool->max_count)
		goto out_unlock;

	if (!list_empty(&resource->node))
		goto out_unlock;

	list_add_tail(&resource->node, &res_pool->free_list);
	res_pool->free_count++;
out_unlock:
	mutex_unlock(&res_pool->mutex);
}
EXPORT_SYMBOL_GPL(fsl_mc_resource_free);

/**
 * fsl_mc_object_allocate - Allocates an fsl-mc object of the given
 * pool type from a given fsl-mc bus instance
 *
 * @mc_dev: fsl-mc device which is used in conjunction with the
 * allocated object
 * @pool_type: pool type
 * @new_mc_dev: pointer to area where the pointer to the allocated device
 * is to be returned
 *
 * Allocatable objects are always used in conjunction with some functional
 * device.  This function allocates an object of the specified type from
 * the DPRC containing the functional device.
 *
 * NOTE: pool_type must be different from FSL_MC_POOL_MCP, since MC
 * portals are allocated using fsl_mc_portal_allocate(), instead of
 * this function.
 */
int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev,
					enum fsl_mc_pool_type pool_type,
					struct fsl_mc_device **new_mc_adev)
{
	struct fsl_mc_device *mc_bus_dev;
	struct fsl_mc_bus *mc_bus;
	struct fsl_mc_device *mc_adev;
	int error = -EINVAL;
	struct fsl_mc_resource *resource = NULL;

	*new_mc_adev = NULL;
	if (mc_dev->flags & FSL_MC_IS_DPRC)
		goto error;

	if (!dev_is_fsl_mc(mc_dev->dev.parent))
		goto error;

	if (pool_type == FSL_MC_POOL_DPMCP)
		goto error;

	mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
	mc_bus = to_fsl_mc_bus(mc_bus_dev);
	error = fsl_mc_resource_allocate(mc_bus, pool_type, &resource);
	if (error < 0)
		goto error;

	mc_adev = resource->data;
	if (!mc_adev)
		goto error;

	*new_mc_adev = mc_adev;
	return 0;
error:
	if (resource)
		fsl_mc_resource_free(resource);

	return error;
}
EXPORT_SYMBOL_GPL(fsl_mc_object_allocate);

/**
 * fsl_mc_object_free - Returns an fsl-mc object to the resource
 * pool where it came from.
 * @mc_adev: Pointer to the fsl-mc device
 */
void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
{
	struct fsl_mc_resource *resource;

	resource = mc_adev->resource;
	if (resource->type == FSL_MC_POOL_DPMCP)
		return;
	if (resource->data != mc_adev)
		return;

	fsl_mc_resource_free(resource);
}
EXPORT_SYMBOL_GPL(fsl_mc_object_free);

/*
 * A DPRC and the devices in the DPRC all share the same GIC-ITS device
 * ID.  A block of IRQs is pre-allocated and maintained in a pool
 * from which devices can allocate them when needed.
 */

/*
 * Initialize the interrupt pool associated with an fsl-mc bus.
 * It allocates a block of IRQs from the GIC-ITS.
 */
int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
			     unsigned int irq_count)
{
	unsigned int i;
	struct msi_desc *msi_desc;
	struct fsl_mc_device_irq *irq_resources;
	struct fsl_mc_device_irq *mc_dev_irq;
	int error;
	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
	struct fsl_mc_resource_pool *res_pool =
			&mc_bus->resource_pools[FSL_MC_POOL_IRQ];

	if (irq_count == 0 ||
	    irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS)
		return -EINVAL;

	error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
	if (error < 0)
		return error;

	irq_resources = devm_kcalloc(&mc_bus_dev->dev,
				     irq_count, sizeof(*irq_resources),
				     GFP_KERNEL);
	if (!irq_resources) {
		error = -ENOMEM;
		goto cleanup_msi_irqs;
	}

	for (i = 0; i < irq_count; i++) {
		mc_dev_irq = &irq_resources[i];

		/*
		 * NOTE: This mc_dev_irq's MSI addr/value pair will be set
		 * by the fsl_mc_msi_write_msg() callback
		 */
		mc_dev_irq->resource.type = res_pool->type;
		mc_dev_irq->resource.data = mc_dev_irq;
		mc_dev_irq->resource.parent_pool = res_pool;
		INIT_LIST_HEAD(&mc_dev_irq->resource.node);
		list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
	}

	for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
		mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
		mc_dev_irq->msi_desc = msi_desc;
		mc_dev_irq->resource.id = msi_desc->irq;
	}

	res_pool->max_count = irq_count;
	res_pool->free_count = irq_count;
	mc_bus->irq_resources = irq_resources;
	return 0;

cleanup_msi_irqs:
	fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
	return error;
}
EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);

/**
 * Teardown the interrupt pool associated with an fsl-mc bus.
 * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
 */
void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
{
	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
	struct fsl_mc_resource_pool *res_pool =
			&mc_bus->resource_pools[FSL_MC_POOL_IRQ];

	if (!mc_bus->irq_resources)
		return;

	if (res_pool->max_count == 0)
		return;

	if (res_pool->free_count != res_pool->max_count)
		return;

	INIT_LIST_HEAD(&res_pool->free_list);
	res_pool->max_count = 0;
	res_pool->free_count = 0;
	mc_bus->irq_resources = NULL;
	fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
}
EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);

/**
 * Allocate the IRQs required by a given fsl-mc device.
 */
int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev)
{
	int i;
	int irq_count;
	int res_allocated_count = 0;
	int error = -EINVAL;
	struct fsl_mc_device_irq **irqs = NULL;
	struct fsl_mc_bus *mc_bus;
	struct fsl_mc_resource_pool *res_pool;

	if (mc_dev->irqs)
		return -EINVAL;

	irq_count = mc_dev->obj_desc.irq_count;
	if (irq_count == 0)
		return -EINVAL;

	if (is_fsl_mc_bus_dprc(mc_dev))
		mc_bus = to_fsl_mc_bus(mc_dev);
	else
		mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));

	if (!mc_bus->irq_resources)
		return -EINVAL;

	res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
	if (res_pool->free_count < irq_count) {
		dev_err(&mc_dev->dev,
			"Not able to allocate %u irqs for device\n", irq_count);
		return -ENOSPC;
	}

	irqs = devm_kcalloc(&mc_dev->dev, irq_count, sizeof(irqs[0]),
			    GFP_KERNEL);
	if (!irqs)
		return -ENOMEM;

	for (i = 0; i < irq_count; i++) {
		struct fsl_mc_resource *resource;

		error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_IRQ,
						 &resource);
		if (error < 0)
			goto error_resource_alloc;

		irqs[i] = to_fsl_mc_irq(resource);
		res_allocated_count++;

		irqs[i]->mc_dev = mc_dev;
		irqs[i]->dev_irq_index = i;
	}

	mc_dev->irqs = irqs;
	return 0;

error_resource_alloc:
	for (i = 0; i < res_allocated_count; i++) {
		irqs[i]->mc_dev = NULL;
		fsl_mc_resource_free(&irqs[i]->resource);
	}

	return error;
}
EXPORT_SYMBOL_GPL(fsl_mc_allocate_irqs);

/*
 * Frees the IRQs that were allocated for an fsl-mc device.
 */
void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
{
	int i;
	int irq_count;
	struct fsl_mc_bus *mc_bus;
	struct fsl_mc_device_irq **irqs = mc_dev->irqs;

	if (!irqs)
		return;

	irq_count = mc_dev->obj_desc.irq_count;

	if (is_fsl_mc_bus_dprc(mc_dev))
		mc_bus = to_fsl_mc_bus(mc_dev);
	else
		mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));

	if (!mc_bus->irq_resources)
		return;

	for (i = 0; i < irq_count; i++) {
		irqs[i]->mc_dev = NULL;
		fsl_mc_resource_free(&irqs[i]->resource);
	}

	mc_dev->irqs = NULL;
}
EXPORT_SYMBOL_GPL(fsl_mc_free_irqs);

void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
{
	int pool_type;
	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);

	for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) {
		struct fsl_mc_resource_pool *res_pool =
		    &mc_bus->resource_pools[pool_type];

		res_pool->type = pool_type;
		res_pool->max_count = 0;
		res_pool->free_count = 0;
		res_pool->mc_bus = mc_bus;
		INIT_LIST_HEAD(&res_pool->free_list);
		mutex_init(&res_pool->mutex);
	}
}

static void fsl_mc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev,
					 enum fsl_mc_pool_type pool_type)
{
	struct fsl_mc_resource *resource;
	struct fsl_mc_resource *next;
	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
	struct fsl_mc_resource_pool *res_pool =
					&mc_bus->resource_pools[pool_type];
	int free_count = 0;

	list_for_each_entry_safe(resource, next, &res_pool->free_list, node) {
		free_count++;
		devm_kfree(&mc_bus_dev->dev, resource);
	}
}

void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
{
	int pool_type;

	for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++)
		fsl_mc_cleanup_resource_pool(mc_bus_dev, pool_type);
}

/**
 * fsl_mc_allocator_probe - callback invoked when an allocatable device is
 * being added to the system
 */
static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev)
{
	enum fsl_mc_pool_type pool_type;
	struct fsl_mc_device *mc_bus_dev;
	struct fsl_mc_bus *mc_bus;
	int error;

	if (!fsl_mc_is_allocatable(mc_dev))
		return -EINVAL;

	mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
	if (!dev_is_fsl_mc(&mc_bus_dev->dev))
		return -EINVAL;

	mc_bus = to_fsl_mc_bus(mc_bus_dev);
	error = object_type_to_pool_type(mc_dev->obj_desc.type, &pool_type);
	if (error < 0)
		return error;

	error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, mc_dev);
	if (error < 0)
		return error;

	dev_dbg(&mc_dev->dev,
		"Allocatable fsl-mc device bound to fsl_mc_allocator driver");
	return 0;
}

/**
 * fsl_mc_allocator_remove - callback invoked when an allocatable device is
 * being removed from the system
 */
static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev)
{
	int error;

	if (!fsl_mc_is_allocatable(mc_dev))
		return -EINVAL;

	if (mc_dev->resource) {
		error = fsl_mc_resource_pool_remove_device(mc_dev);
		if (error < 0)
			return error;
	}

	dev_dbg(&mc_dev->dev,
		"Allocatable fsl-mc device unbound from fsl_mc_allocator driver");
	return 0;
}

static const struct fsl_mc_device_id match_id_table[] = {
	{
	 .vendor = FSL_MC_VENDOR_FREESCALE,
	 .obj_type = "dpbp",
	},
	{
	 .vendor = FSL_MC_VENDOR_FREESCALE,
	 .obj_type = "dpmcp",
	},
	{
	 .vendor = FSL_MC_VENDOR_FREESCALE,
	 .obj_type = "dpcon",
	},
	{.vendor = 0x0},
};

static struct fsl_mc_driver fsl_mc_allocator_driver = {
	.driver = {
		   .name = "fsl_mc_allocator",
		   .pm = NULL,
		   },
	.match_id_table = match_id_table,
	.probe = fsl_mc_allocator_probe,
	.remove = fsl_mc_allocator_remove,
};

int __init fsl_mc_allocator_driver_init(void)
{
	return fsl_mc_driver_register(&fsl_mc_allocator_driver);
}

void fsl_mc_allocator_driver_exit(void)
{
	fsl_mc_driver_unregister(&fsl_mc_allocator_driver);
}
