// SPDX-License-Identifier: GPL-2.0
/*
 * System Control and Management Interface (SCMI) Message Protocol bus layer
 *
 * Copyright (C) 2018-2021 ARM Ltd.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/atomic.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/device.h>

#include "common.h"

BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);

static DEFINE_IDA(scmi_bus_id);

static DEFINE_IDR(scmi_requested_devices);
/* Protect access to scmi_requested_devices */
static DEFINE_MUTEX(scmi_requested_devices_mtx);

struct scmi_requested_dev {
	const struct scmi_device_id *id_table;
	struct list_head node;
};

/* Track globally the creation of SCMI SystemPower related devices */
static atomic_t scmi_syspower_registered = ATOMIC_INIT(0);

/**
 * scmi_protocol_device_request  - Helper to request a device
 *
 * @id_table: A protocol/name pair descriptor for the device to be created.
 *
 * This helper let an SCMI driver request specific devices identified by the
 * @id_table to be created for each active SCMI instance.
 *
 * The requested device name MUST NOT be already existent for any protocol;
 * at first the freshly requested @id_table is annotated in the IDR table
 * @scmi_requested_devices and then the requested device is advertised to any
 * registered party via the @scmi_requested_devices_nh notification chain.
 *
 * Return: 0 on Success
 */
static int scmi_protocol_device_request(const struct scmi_device_id *id_table)
{
	int ret = 0;
	unsigned int id = 0;
	struct list_head *head, *phead = NULL;
	struct scmi_requested_dev *rdev;

	pr_debug("Requesting SCMI device (%s) for protocol %x\n",
		 id_table->name, id_table->protocol_id);

	if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) &&
	    !IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX)) {
		pr_warn("SCMI Raw mode active. Rejecting '%s'/0x%02X\n",
			id_table->name, id_table->protocol_id);
		return -EINVAL;
	}

	/*
	 * Search for the matching protocol rdev list and then search
	 * of any existent equally named device...fails if any duplicate found.
	 */
	mutex_lock(&scmi_requested_devices_mtx);
	idr_for_each_entry(&scmi_requested_devices, head, id) {
		if (!phead) {
			/* A list found registered in the IDR is never empty */
			rdev = list_first_entry(head, struct scmi_requested_dev,
						node);
			if (rdev->id_table->protocol_id ==
			    id_table->protocol_id)
				phead = head;
		}
		list_for_each_entry(rdev, head, node) {
			if (!strcmp(rdev->id_table->name, id_table->name)) {
				pr_err("Ignoring duplicate request [%d] %s\n",
				       rdev->id_table->protocol_id,
				       rdev->id_table->name);
				ret = -EINVAL;
				goto out;
			}
		}
	}

	/*
	 * No duplicate found for requested id_table, so let's create a new
	 * requested device entry for this new valid request.
	 */
	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
	if (!rdev) {
		ret = -ENOMEM;
		goto out;
	}
	rdev->id_table = id_table;

	/*
	 * Append the new requested device table descriptor to the head of the
	 * related protocol list, eventually creating such head if not already
	 * there.
	 */
	if (!phead) {
		phead = kzalloc(sizeof(*phead), GFP_KERNEL);
		if (!phead) {
			kfree(rdev);
			ret = -ENOMEM;
			goto out;
		}
		INIT_LIST_HEAD(phead);

		ret = idr_alloc(&scmi_requested_devices, (void *)phead,
				id_table->protocol_id,
				id_table->protocol_id + 1, GFP_KERNEL);
		if (ret != id_table->protocol_id) {
			pr_err("Failed to save SCMI device - ret:%d\n", ret);
			kfree(rdev);
			kfree(phead);
			ret = -EINVAL;
			goto out;
		}
		ret = 0;
	}
	list_add(&rdev->node, phead);

out:
	mutex_unlock(&scmi_requested_devices_mtx);

	if (!ret)
		blocking_notifier_call_chain(&scmi_requested_devices_nh,
					     SCMI_BUS_NOTIFY_DEVICE_REQUEST,
					     (void *)rdev->id_table);

	return ret;
}

static int scmi_protocol_table_register(const struct scmi_device_id *id_table)
{
	int ret = 0;
	const struct scmi_device_id *entry;

	for (entry = id_table; entry->name && ret == 0; entry++)
		ret = scmi_protocol_device_request(entry);

	return ret;
}

/**
 * scmi_protocol_device_unrequest  - Helper to unrequest a device
 *
 * @id_table: A protocol/name pair descriptor for the device to be unrequested.
 *
 * The unrequested device, described by the provided id_table, is at first
 * removed from the IDR @scmi_requested_devices and then the removal is
 * advertised to any registered party via the @scmi_requested_devices_nh
 * notification chain.
 */
static void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table)
{
	struct list_head *phead;

	pr_debug("Unrequesting SCMI device (%s) for protocol %x\n",
		 id_table->name, id_table->protocol_id);

	mutex_lock(&scmi_requested_devices_mtx);
	phead = idr_find(&scmi_requested_devices, id_table->protocol_id);
	if (phead) {
		struct scmi_requested_dev *victim, *tmp;

		list_for_each_entry_safe(victim, tmp, phead, node) {
			if (!strcmp(victim->id_table->name, id_table->name)) {
				list_del(&victim->node);

				mutex_unlock(&scmi_requested_devices_mtx);
				blocking_notifier_call_chain(&scmi_requested_devices_nh,
							     SCMI_BUS_NOTIFY_DEVICE_UNREQUEST,
							     (void *)victim->id_table);
				kfree(victim);
				mutex_lock(&scmi_requested_devices_mtx);
				break;
			}
		}

		if (list_empty(phead)) {
			idr_remove(&scmi_requested_devices,
				   id_table->protocol_id);
			kfree(phead);
		}
	}
	mutex_unlock(&scmi_requested_devices_mtx);
}

static void
scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
{
	const struct scmi_device_id *entry;

	for (entry = id_table; entry->name; entry++)
		scmi_protocol_device_unrequest(entry);
}

static const struct scmi_device_id *
scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
{
	const struct scmi_device_id *id = scmi_drv->id_table;

	if (!id)
		return NULL;

	for (; id->protocol_id; id++)
		if (id->protocol_id == scmi_dev->protocol_id) {
			if (!id->name)
				return id;
			else if (!strcmp(id->name, scmi_dev->name))
				return id;
		}

	return NULL;
}

static int scmi_dev_match(struct device *dev, struct device_driver *drv)
{
	struct scmi_driver *scmi_drv = to_scmi_driver(drv);
	struct scmi_device *scmi_dev = to_scmi_dev(dev);
	const struct scmi_device_id *id;

	id = scmi_dev_match_id(scmi_dev, scmi_drv);
	if (id)
		return 1;

	return 0;
}

static int scmi_match_by_id_table(struct device *dev, void *data)
{
	struct scmi_device *sdev = to_scmi_dev(dev);
	struct scmi_device_id *id_table = data;

	return sdev->protocol_id == id_table->protocol_id &&
		(id_table->name && !strcmp(sdev->name, id_table->name));
}

static struct scmi_device *scmi_child_dev_find(struct device *parent,
					       int prot_id, const char *name)
{
	struct scmi_device_id id_table;
	struct device *dev;

	id_table.protocol_id = prot_id;
	id_table.name = name;

	dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
	if (!dev)
		return NULL;

	return to_scmi_dev(dev);
}

static int scmi_dev_probe(struct device *dev)
{
	struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
	struct scmi_device *scmi_dev = to_scmi_dev(dev);

	if (!scmi_dev->handle)
		return -EPROBE_DEFER;

	return scmi_drv->probe(scmi_dev);
}

static void scmi_dev_remove(struct device *dev)
{
	struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
	struct scmi_device *scmi_dev = to_scmi_dev(dev);

	if (scmi_drv->remove)
		scmi_drv->remove(scmi_dev);
}

const struct bus_type scmi_bus_type = {
	.name =	"scmi_protocol",
	.match = scmi_dev_match,
	.probe = scmi_dev_probe,
	.remove = scmi_dev_remove,
};
EXPORT_SYMBOL_GPL(scmi_bus_type);

int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
			 const char *mod_name)
{
	int retval;

	if (!driver->probe)
		return -EINVAL;

	retval = scmi_protocol_table_register(driver->id_table);
	if (retval)
		return retval;

	driver->driver.bus = &scmi_bus_type;
	driver->driver.name = driver->name;
	driver->driver.owner = owner;
	driver->driver.mod_name = mod_name;

	retval = driver_register(&driver->driver);
	if (!retval)
		pr_debug("Registered new scmi driver %s\n", driver->name);

	return retval;
}
EXPORT_SYMBOL_GPL(scmi_driver_register);

void scmi_driver_unregister(struct scmi_driver *driver)
{
	driver_unregister(&driver->driver);
	scmi_protocol_table_unregister(driver->id_table);
}
EXPORT_SYMBOL_GPL(scmi_driver_unregister);

static void scmi_device_release(struct device *dev)
{
	kfree(to_scmi_dev(dev));
}

static void __scmi_device_destroy(struct scmi_device *scmi_dev)
{
	pr_debug("(%s) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
		 of_node_full_name(scmi_dev->dev.parent->of_node),
		 dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
		 scmi_dev->name);

	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
		atomic_set(&scmi_syspower_registered, 0);

	kfree_const(scmi_dev->name);
	ida_free(&scmi_bus_id, scmi_dev->id);
	device_unregister(&scmi_dev->dev);
}

static struct scmi_device *
__scmi_device_create(struct device_node *np, struct device *parent,
		     int protocol, const char *name)
{
	int id, retval;
	struct scmi_device *scmi_dev;

	/*
	 * If the same protocol/name device already exist under the same parent
	 * (i.e. SCMI instance) just return the existent device.
	 * This avoids any race between the SCMI driver, creating devices for
	 * each DT defined protocol at probe time, and the concurrent
	 * registration of SCMI drivers.
	 */
	scmi_dev = scmi_child_dev_find(parent, protocol, name);
	if (scmi_dev)
		return scmi_dev;

	/*
	 * Ignore any possible subsequent failures while creating the device
	 * since we are doomed anyway at that point; not using a mutex which
	 * spans across this whole function to keep things simple and to avoid
	 * to serialize all the __scmi_device_create calls across possibly
	 * different SCMI server instances (parent)
	 */
	if (protocol == SCMI_PROTOCOL_SYSTEM &&
	    atomic_cmpxchg(&scmi_syspower_registered, 0, 1)) {
		dev_warn(parent,
			 "SCMI SystemPower protocol device must be unique !\n");
		return NULL;
	}

	scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL);
	if (!scmi_dev)
		return NULL;

	scmi_dev->name = kstrdup_const(name ?: "unknown", GFP_KERNEL);
	if (!scmi_dev->name) {
		kfree(scmi_dev);
		return NULL;
	}

	id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
	if (id < 0) {
		kfree_const(scmi_dev->name);
		kfree(scmi_dev);
		return NULL;
	}

	scmi_dev->id = id;
	scmi_dev->protocol_id = protocol;
	scmi_dev->dev.parent = parent;
	device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
	scmi_dev->dev.bus = &scmi_bus_type;
	scmi_dev->dev.release = scmi_device_release;
	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);

	retval = device_register(&scmi_dev->dev);
	if (retval)
		goto put_dev;

	pr_debug("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n",
		 of_node_full_name(parent->of_node),
		 dev_name(&scmi_dev->dev), protocol, name);

	return scmi_dev;
put_dev:
	kfree_const(scmi_dev->name);
	put_device(&scmi_dev->dev);
	ida_free(&scmi_bus_id, id);
	return NULL;
}

/**
 * scmi_device_create  - A method to create one or more SCMI devices
 *
 * @np: A reference to the device node to use for the new device(s)
 * @parent: The parent device to use identifying a specific SCMI instance
 * @protocol: The SCMI protocol to be associated with this device
 * @name: The requested-name of the device to be created; this is optional
 *	  and if no @name is provided, all the devices currently known to
 *	  be requested on the SCMI bus for @protocol will be created.
 *
 * This method can be invoked to create a single well-defined device (like
 * a transport device or a device requested by an SCMI driver loaded after
 * the core SCMI stack has been probed), or to create all the devices currently
 * known to have been requested by the loaded SCMI drivers for a specific
 * protocol (typically during SCMI core protocol enumeration at probe time).
 *
 * Return: The created device (or one of them if @name was NOT provided and
 *	   multiple devices were created) or NULL if no device was created;
 *	   note that NULL indicates an error ONLY in case a specific @name
 *	   was provided: when @name param was not provided, a number of devices
 *	   could have been potentially created for a whole protocol, unless no
 *	   device was found to have been requested for that specific protocol.
 */
struct scmi_device *scmi_device_create(struct device_node *np,
				       struct device *parent, int protocol,
				       const char *name)
{
	struct list_head *phead;
	struct scmi_requested_dev *rdev;
	struct scmi_device *scmi_dev = NULL;

	if (name)
		return __scmi_device_create(np, parent, protocol, name);

	mutex_lock(&scmi_requested_devices_mtx);
	phead = idr_find(&scmi_requested_devices, protocol);
	/* Nothing to do. */
	if (!phead) {
		mutex_unlock(&scmi_requested_devices_mtx);
		return NULL;
	}

	/* Walk the list of requested devices for protocol and create them */
	list_for_each_entry(rdev, phead, node) {
		struct scmi_device *sdev;

		sdev = __scmi_device_create(np, parent,
					    rdev->id_table->protocol_id,
					    rdev->id_table->name);
		/* Report errors and carry on... */
		if (sdev)
			scmi_dev = sdev;
		else
			pr_err("(%s) Failed to create device for protocol 0x%x (%s)\n",
			       of_node_full_name(parent->of_node),
			       rdev->id_table->protocol_id,
			       rdev->id_table->name);
	}
	mutex_unlock(&scmi_requested_devices_mtx);

	return scmi_dev;
}
EXPORT_SYMBOL_GPL(scmi_device_create);

void scmi_device_destroy(struct device *parent, int protocol, const char *name)
{
	struct scmi_device *scmi_dev;

	scmi_dev = scmi_child_dev_find(parent, protocol, name);
	if (scmi_dev)
		__scmi_device_destroy(scmi_dev);
}
EXPORT_SYMBOL_GPL(scmi_device_destroy);

static int __scmi_devices_unregister(struct device *dev, void *data)
{
	struct scmi_device *scmi_dev = to_scmi_dev(dev);

	__scmi_device_destroy(scmi_dev);
	return 0;
}

static void scmi_devices_unregister(void)
{
	bus_for_each_dev(&scmi_bus_type, NULL, NULL, __scmi_devices_unregister);
}

static int __init scmi_bus_init(void)
{
	int retval;

	retval = bus_register(&scmi_bus_type);
	if (retval)
		pr_err("SCMI protocol bus register failed (%d)\n", retval);

	pr_info("SCMI protocol bus registered\n");

	return retval;
}
subsys_initcall(scmi_bus_init);

static void __exit scmi_bus_exit(void)
{
	/*
	 * Destroy all remaining devices: just in case the drivers were
	 * manually unbound and at first and then the modules unloaded.
	 */
	scmi_devices_unregister();
	bus_unregister(&scmi_bus_type);
	ida_destroy(&scmi_bus_id);
}
module_exit(scmi_bus_exit);

MODULE_ALIAS("scmi-core");
MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
MODULE_DESCRIPTION("ARM SCMI protocol bus");
MODULE_LICENSE("GPL");
