// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2025 Linaro Ltd.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/auxiliary_bus.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/idr.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/overflow.h>
#include <linux/printk.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/string.h>

#include "gpiolib.h"
#include "gpiolib-shared.h"

/* Represents a single reference to a GPIO pin. */
struct gpio_shared_ref {
	struct list_head list;
	/* Firmware node associated with this GPIO's consumer. */
	struct fwnode_handle *fwnode;
	/* GPIO flags this consumer uses for the request. */
	enum gpiod_flags flags;
	char *con_id;
	int dev_id;
	/* Protects the auxiliary device struct and the lookup table. */
	struct mutex lock;
	struct lock_class_key lock_key;
	struct auxiliary_device adev;
	struct gpiod_lookup_table *lookup;
	bool is_reset_gpio;
};

/* Represents a single GPIO pin. */
struct gpio_shared_entry {
	struct list_head list;
	/* Firmware node associated with the GPIO controller. */
	struct fwnode_handle *fwnode;
	/* Hardware offset of the GPIO within its chip. */
	unsigned int offset;
	/* Index in the property value array. */
	size_t index;
	/* Synchronizes the modification of shared_desc and offset. */
	struct mutex lock;
	struct gpio_shared_desc *shared_desc;
	struct kref ref;
	struct list_head refs;
};

static LIST_HEAD(gpio_shared_list);
static DEFINE_IDA(gpio_shared_ida);

#if IS_ENABLED(CONFIG_OF)
static struct gpio_shared_entry *
gpio_shared_find_entry(struct fwnode_handle *controller_node,
		       unsigned int offset)
{
	struct gpio_shared_entry *entry;

	list_for_each_entry(entry, &gpio_shared_list, list) {
		if (entry->fwnode == controller_node && entry->offset == offset)
			return entry;
	}

	return NULL;
}

static struct gpio_shared_ref *gpio_shared_make_ref(struct fwnode_handle *fwnode,
						    const char *con_id,
						    enum gpiod_flags flags)
{
	char *con_id_cpy __free(kfree) = NULL;

	struct gpio_shared_ref *ref __free(kfree) = kzalloc_obj(*ref);
	if (!ref)
		return NULL;

	if (con_id) {
		con_id_cpy = kstrdup(con_id, GFP_KERNEL);
		if (!con_id_cpy)
			return NULL;
	}

	ref->dev_id = ida_alloc(&gpio_shared_ida, GFP_KERNEL);
	if (ref->dev_id < 0)
		return NULL;

	ref->flags = flags;
	ref->con_id = no_free_ptr(con_id_cpy);
	ref->fwnode = fwnode;
	lockdep_register_key(&ref->lock_key);
	mutex_init_with_key(&ref->lock, &ref->lock_key);

	return no_free_ptr(ref);
}

static int gpio_shared_setup_reset_proxy(struct gpio_shared_entry *entry,
					 enum gpiod_flags flags)
{
	struct gpio_shared_ref *ref;

	list_for_each_entry(ref, &entry->refs, list) {
		if (ref->is_reset_gpio)
			/* Already set-up. */
			return 0;
	}

	ref = gpio_shared_make_ref(NULL, "reset", flags);
	if (!ref)
		return -ENOMEM;

	ref->is_reset_gpio = true;

	list_add_tail(&ref->list, &entry->refs);

	pr_debug("Created a secondary shared GPIO reference for potential reset-gpio device for GPIO %u at %s\n",
		 entry->offset, fwnode_get_name(entry->fwnode));

	return 0;
}

/* Handle all special nodes that we should ignore. */
static bool gpio_shared_of_node_ignore(struct device_node *node)
{
	/* Ignore disabled devices. */
	if (!of_device_is_available(node))
		return true;

	/*
	 * __symbols__ is a special, internal node and should not be considered
	 * when scanning for shared GPIOs.
	 */
	if (of_node_name_eq(node, "__symbols__"))
		return true;

	/*
	 * GPIO hogs have a "gpios" property which is not a phandle and can't
	 * possibly refer to a shared GPIO.
	 */
	if (of_property_present(node, "gpio-hog"))
		return true;

	return false;
}

static int gpio_shared_of_traverse(struct device_node *curr)
{
	struct gpio_shared_entry *entry;
	size_t con_id_len, suffix_len;
	struct fwnode_handle *fwnode;
	struct of_phandle_args args;
	struct gpio_shared_ref *ref;
	struct property *prop;
	unsigned int offset;
	const char *suffix;
	int ret, count, i;

	if (gpio_shared_of_node_ignore(curr))
		return 0;

	for_each_property_of_node(curr, prop) {
		/*
		 * The standard name for a GPIO property is "foo-gpios"
		 * or "foo-gpio". Some bindings also use "gpios" or "gpio".
		 * There are some legacy device-trees which have a different
		 * naming convention and for which we have rename quirks in
		 * place in gpiolib-of.c. I don't think any of them require
		 * support for shared GPIOs so for now let's just ignore
		 * them. We can always just export the quirk list and
		 * iterate over it here.
		 */
		if (!strends(prop->name, "-gpios") &&
		    !strends(prop->name, "-gpio") &&
		    strcmp(prop->name, "gpios") != 0 &&
		    strcmp(prop->name, "gpio") != 0)
			continue;

		count = of_count_phandle_with_args(curr, prop->name,
						   "#gpio-cells");
		if (count <= 0)
			continue;

		for (i = 0; i < count; i++) {
			struct device_node *np __free(device_node) = NULL;
			char *con_id __free(kfree) = NULL;

			ret = of_parse_phandle_with_args(curr, prop->name,
							 "#gpio-cells", i,
							 &args);
			if (ret)
				continue;

			np = args.np;

			if (!of_property_present(np, "gpio-controller"))
				continue;

			/*
			 * We support 1, 2 and 3 cell GPIO bindings in the
			 * kernel currently. There's only one old MIPS dts that
			 * has a one-cell binding but there's no associated
			 * consumer so it may as well be an error. There don't
			 * seem to be any 3-cell users of non-exclusive GPIOs,
			 * so we can skip this as well. Let's occupy ourselves
			 * with the predominant 2-cell binding with the first
			 * cell indicating the hardware offset of the GPIO and
			 * the second defining the GPIO flags of the request.
			 */
			if (args.args_count != 2)
				continue;

			fwnode = of_fwnode_handle(args.np);
			offset = args.args[0];

			entry = gpio_shared_find_entry(fwnode, offset);
			if (!entry) {
				entry = kzalloc_obj(*entry);
				if (!entry)
					return -ENOMEM;

				entry->fwnode = fwnode_handle_get(fwnode);
				entry->offset = offset;
				entry->index = count;
				INIT_LIST_HEAD(&entry->refs);
				mutex_init(&entry->lock);

				list_add_tail(&entry->list, &gpio_shared_list);
			}

			if (strends(prop->name, "gpios"))
				suffix = "-gpios";
			else if (strends(prop->name, "gpio"))
				suffix = "-gpio";
			else
				suffix = NULL;
			if (!suffix)
				continue;

			/* We only set con_id if there's actually one. */
			if (strcmp(prop->name, "gpios") && strcmp(prop->name, "gpio")) {
				con_id = kstrdup(prop->name, GFP_KERNEL);
				if (!con_id)
					return -ENOMEM;

				con_id_len = strlen(con_id);
				suffix_len = strlen(suffix);

				con_id[con_id_len - suffix_len] = '\0';
			}

			struct fwnode_handle *curr_fwnode =
				fwnode_handle_get(of_fwnode_handle(curr));
			ref = gpio_shared_make_ref(curr_fwnode, con_id, args.args[1]);
			if (!ref) {
				fwnode_handle_put(curr_fwnode);
				return -ENOMEM;
			}

			if (!list_empty(&entry->refs))
				pr_debug("GPIO %u at %s is shared by multiple firmware nodes\n",
					 entry->offset, fwnode_get_name(entry->fwnode));

			list_add_tail(&ref->list, &entry->refs);

			if (strcmp(prop->name, "reset-gpios") == 0) {
				ret = gpio_shared_setup_reset_proxy(entry, args.args[1]);
				if (ret)
					return ret;
			}
		}
	}

	for_each_child_of_node_scoped(curr, child) {
		ret = gpio_shared_of_traverse(child);
		if (ret)
			return ret;
	}

	return 0;
}

static int gpio_shared_of_scan(void)
{
	if (of_root)
		return gpio_shared_of_traverse(of_root);

	return 0;
}
#else
static int gpio_shared_of_scan(void)
{
	return 0;
}
#endif /* CONFIG_OF */

static void gpio_shared_adev_release(struct device *dev)
{

}

static int gpio_shared_make_adev(struct gpio_device *gdev,
				 struct gpio_shared_entry *entry,
				 struct gpio_shared_ref *ref)
{
	struct auxiliary_device *adev = &ref->adev;
	int ret;

	guard(mutex)(&ref->lock);

	memset(adev, 0, sizeof(*adev));

	adev->id = ref->dev_id;
	adev->name = "proxy";
	adev->dev.parent = gdev->dev.parent;
	adev->dev.platform_data = entry;
	adev->dev.release = gpio_shared_adev_release;

	ret = auxiliary_device_init(adev);
	if (ret)
		return ret;

	ret = auxiliary_device_add(adev);
	if (ret) {
		auxiliary_device_uninit(adev);
		return ret;
	}

	pr_debug("Created an auxiliary GPIO proxy %s for GPIO device %s\n",
		 dev_name(&adev->dev), gpio_device_get_label(gdev));

	return 0;
}

#if IS_ENABLED(CONFIG_RESET_GPIO)
/*
 * Special case: reset-gpio is an auxiliary device that's created dynamically
 * and put in between the GPIO controller and consumers of shared GPIOs
 * referred to by the "reset-gpios" property.
 *
 * If the supposed consumer of a shared GPIO didn't match any of the mappings
 * we created when scanning the firmware nodes, it's still possible that it's
 * the reset-gpio device which didn't exist at the time of the scan.
 *
 * This function verifies it an return true if it's the case.
 */
static bool gpio_shared_dev_is_reset_gpio(struct device *consumer,
					  struct gpio_shared_entry *entry,
					  struct gpio_shared_ref *ref)
{
	struct fwnode_handle *reset_fwnode = dev_fwnode(consumer);
	struct fwnode_reference_args ref_args, aux_args;
	struct device *parent = consumer->parent;
	struct gpio_shared_ref *real_ref;
	bool match;
	int ret;

	lockdep_assert_held(&ref->lock);

	/* The reset-gpio device must have a parent AND a firmware node. */
	if (!parent || !reset_fwnode)
		return false;

	/*
	 * Parent of the reset-gpio auxiliary device is the GPIO chip whose
	 * fwnode we stored in the entry structure.
	 */
	if (!device_match_fwnode(parent, entry->fwnode))
		return false;

	/*
	 * Now we need to find the actual pin we want to assign to this
	 * reset-gpio device. To that end: iterate over the list of references
	 * of this entry and see if there's one, whose reset-gpios property's
	 * arguments match the ones from this consumer's node.
	 */
	list_for_each_entry(real_ref, &entry->refs, list) {
		if (real_ref == ref)
			continue;

		guard(mutex)(&real_ref->lock);

		if (!real_ref->fwnode)
			continue;

		/*
		 * The device associated with the shared reference's firmware
		 * node is the consumer of the reset control exposed by the
		 * reset-gpio device. It must have a "reset-gpios" property
		 * that's referencing the entry's firmware node.
		 *
		 * The reference args must agree between the real consumer and
		 * the auxiliary reset-gpio device.
		 */
		ret = fwnode_property_get_reference_args(real_ref->fwnode,
							 "reset-gpios",
							 NULL, 2, 0, &ref_args);
		if (ret)
			continue;

		ret = fwnode_property_get_reference_args(reset_fwnode, "reset-gpios",
							 NULL, 2, 0, &aux_args);
		if (ret) {
			fwnode_handle_put(ref_args.fwnode);
			continue;
		}

		match = ((ref_args.fwnode == entry->fwnode) &&
			 (aux_args.fwnode == entry->fwnode) &&
			 (ref_args.args[0] == aux_args.args[0]));

		fwnode_handle_put(ref_args.fwnode);
		fwnode_handle_put(aux_args.fwnode);

		if (!match)
			continue;

		/*
		 * Reuse the fwnode of the real device, next time we'll use it
		 * in the normal path.
		 */
		ref->fwnode = fwnode_handle_get(reset_fwnode);
		return true;
	}

	return false;
}
#else
static bool gpio_shared_dev_is_reset_gpio(struct device *consumer,
					  struct gpio_shared_entry *entry,
					  struct gpio_shared_ref *ref)
{
	return false;
}
#endif /* CONFIG_RESET_GPIO */

int gpio_shared_add_proxy_lookup(struct device *consumer, struct fwnode_handle *fwnode,
				 const char *con_id, unsigned long lflags)
{
	const char *dev_id = dev_name(consumer);
	struct gpiod_lookup_table *lookup;
	struct gpio_shared_entry *entry;
	struct gpio_shared_ref *ref;

	list_for_each_entry(entry, &gpio_shared_list, list) {
		list_for_each_entry(ref, &entry->refs, list) {
			guard(mutex)(&ref->lock);

			if (!ref->fwnode && device_is_compatible(consumer, "reset-gpio")) {
				if (!gpio_shared_dev_is_reset_gpio(consumer, entry, ref))
					continue;
			} else if (fwnode != ref->fwnode) {
				continue;
			}

			if ((!con_id && ref->con_id) || (con_id && !ref->con_id) ||
			    (con_id && ref->con_id && strcmp(con_id, ref->con_id) != 0))
				continue;

			/* We've already done that on a previous request. */
			if (ref->lookup)
				return 0;

			char *key __free(kfree) =
				kasprintf(GFP_KERNEL,
					  KBUILD_MODNAME ".proxy.%u",
					  ref->adev.id);
			if (!key)
				return -ENOMEM;

			lookup = kzalloc_flex(*lookup, table, 2);
			if (!lookup)
				return -ENOMEM;

			pr_debug("Adding machine lookup entry for a shared GPIO for consumer %s, with key '%s' and con_id '%s'\n",
				 dev_id, key, ref->con_id ?: "none");

			lookup->dev_id = dev_id;
			lookup->table[0] = GPIO_LOOKUP(no_free_ptr(key), 0,
						       ref->con_id, lflags);

			ref->lookup = lookup;
			gpiod_add_lookup_table(ref->lookup);

			return 0;
		}
	}

	/* We warn here because this can only happen if the programmer borked. */
	WARN_ON(1);
	return -ENOENT;
}

static void gpio_shared_remove_adev(struct auxiliary_device *adev)
{
	auxiliary_device_delete(adev);
	auxiliary_device_uninit(adev);
}

int gpiochip_setup_shared(struct gpio_chip *gc)
{
	struct gpio_device *gdev = gc->gpiodev;
	struct gpio_shared_entry *entry;
	struct gpio_shared_ref *ref;
	struct gpio_desc *desc;
	int ret;

	list_for_each_entry(entry, &gpio_shared_list, list) {
		list_for_each_entry(ref, &entry->refs, list) {
			if (gdev->dev.parent == &ref->adev.dev) {
				/*
				 * This is a shared GPIO proxy. Mark its
				 * descriptor as such and return here.
				 */
				__set_bit(GPIOD_FLAG_SHARED_PROXY,
					  &gdev->descs[0].flags);
				return 0;
			}
		}
	}

	/*
	 * This is not a shared GPIO proxy but it still may be the device
	 * exposing shared pins. Find them and create the proxy devices.
	 */
	list_for_each_entry(entry, &gpio_shared_list, list) {
		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
			continue;

		if (list_count_nodes(&entry->refs) <= 1)
			continue;

		scoped_guard(mutex, &entry->lock) {
#if IS_ENABLED(CONFIG_OF)
			if (is_of_node(entry->fwnode) && gc->of_xlate) {
				/*
				 * This is the earliest that we can tranlate the
				 * devicetree offset to the chip offset.
				 */
				struct of_phandle_args gpiospec = { };

				gpiospec.np = to_of_node(entry->fwnode);
				gpiospec.args_count = 2;
				gpiospec.args[0] = entry->offset;

				ret = gc->of_xlate(gc, &gpiospec, NULL);
				if (ret < 0)
					return ret;

				entry->offset = ret;
			}
#endif /* CONFIG_OF */

			desc = &gdev->descs[entry->offset];

			__set_bit(GPIOD_FLAG_SHARED, &desc->flags);
			/*
			 * Shared GPIOs are not requested via the normal path. Make
			 * them inaccessible to anyone even before we register the
			 * chip.
			 */
			ret = gpiod_request_commit(desc, "shared");
			if (ret)
				return ret;

			pr_debug("GPIO %u owned by %s is shared by multiple consumers\n",
				 entry->offset, gpio_device_get_label(gdev));
		}

		list_for_each_entry(ref, &entry->refs, list) {
			pr_debug("Setting up a shared GPIO entry for %s (con_id: '%s')\n",
				 fwnode_get_name(ref->fwnode) ?: "(no fwnode)",
				 ref->con_id ?: "(none)");

			ret = gpio_shared_make_adev(gdev, entry, ref);
			if (ret) {
				gpiod_free_commit(desc);
				return ret;
			}
		}
	}

	return 0;
}

void gpio_device_teardown_shared(struct gpio_device *gdev)
{
	struct gpio_shared_entry *entry;
	struct gpio_shared_ref *ref;

	list_for_each_entry(entry, &gpio_shared_list, list) {
		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
			continue;

		scoped_guard(mutex, &entry->lock)
			gpiod_free_commit(&gdev->descs[entry->offset]);

		list_for_each_entry(ref, &entry->refs, list) {
			if (ref->lookup) {
				gpiod_remove_lookup_table(ref->lookup);
				kfree(ref->lookup->table[0].key);
				kfree(ref->lookup);
				ref->lookup = NULL;
			}

			gpio_shared_remove_adev(&ref->adev);
		}
	}
}

static void gpio_shared_release(struct kref *kref)
{
	struct gpio_shared_entry *entry =
		container_of(kref, struct gpio_shared_entry, ref);
	struct gpio_shared_desc *shared_desc;

	guard(mutex)(&entry->lock);

	shared_desc = entry->shared_desc;
	gpio_device_put(shared_desc->desc->gdev);
	mutex_destroy(&shared_desc->mutex);
	kfree(shared_desc);
	entry->shared_desc = NULL;
}

static void gpiod_shared_put(void *data)
{
	struct gpio_shared_entry *entry = data;

	kref_put(&entry->ref, gpio_shared_release);
}

static struct gpio_shared_desc *
gpiod_shared_desc_create(struct gpio_shared_entry *entry)
{
	struct gpio_shared_desc *shared_desc;
	struct gpio_device *gdev;

	lockdep_assert_held(&entry->lock);

	shared_desc = kzalloc_obj(*shared_desc);
	if (!shared_desc)
		return ERR_PTR(-ENOMEM);

	gdev = gpio_device_find_by_fwnode(entry->fwnode);
	if (!gdev) {
		kfree(shared_desc);
		return ERR_PTR(-EPROBE_DEFER);
	}

	shared_desc->desc = &gdev->descs[entry->offset];
	mutex_init(&shared_desc->mutex);

	return shared_desc;
}

struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev)
{
	struct gpio_shared_desc *shared_desc;
	struct gpio_shared_entry *entry;
	int ret;

	entry = dev_get_platdata(dev);
	if (WARN_ON(!entry))
		/* Programmer bug */
		return ERR_PTR(-ENOENT);

	scoped_guard(mutex, &entry->lock) {
		if (entry->shared_desc) {
			kref_get(&entry->ref);
			shared_desc = entry->shared_desc;
		} else {
			shared_desc = gpiod_shared_desc_create(entry);
			if (IS_ERR(shared_desc))
				return ERR_CAST(shared_desc);

			kref_init(&entry->ref);
			entry->shared_desc = shared_desc;
		}

		pr_debug("Device %s acquired a reference to the shared GPIO %u owned by %s\n",
			 dev_name(dev), gpiod_hwgpio(shared_desc->desc),
			 gpio_device_get_label(shared_desc->desc->gdev));
	}

	ret = devm_add_action_or_reset(dev, gpiod_shared_put, entry);
	if (ret)
		return ERR_PTR(ret);

	return shared_desc;
}
EXPORT_SYMBOL_GPL(devm_gpiod_shared_get);

static void gpio_shared_drop_ref(struct gpio_shared_ref *ref)
{
	list_del(&ref->list);
	mutex_destroy(&ref->lock);
	lockdep_unregister_key(&ref->lock_key);
	kfree(ref->con_id);
	ida_free(&gpio_shared_ida, ref->dev_id);
	fwnode_handle_put(ref->fwnode);
	kfree(ref);
}

static void gpio_shared_drop_entry(struct gpio_shared_entry *entry)
{
	list_del(&entry->list);
	mutex_destroy(&entry->lock);
	fwnode_handle_put(entry->fwnode);
	kfree(entry);
}

/*
 * This is only called if gpio_shared_init() fails so it's in fact __init and
 * not __exit.
 */
static void __init gpio_shared_teardown(void)
{
	struct gpio_shared_entry *entry, *epos;
	struct gpio_shared_ref *ref, *rpos;

	list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) {
		list_for_each_entry_safe(ref, rpos, &entry->refs, list)
			gpio_shared_drop_ref(ref);

		gpio_shared_drop_entry(entry);
	}
}

static bool gpio_shared_entry_is_really_shared(struct gpio_shared_entry *entry)
{
	size_t num_nodes = list_count_nodes(&entry->refs);
	struct gpio_shared_ref *ref;

	if (num_nodes <= 1)
		return false;

	if (num_nodes > 2)
		return true;

	/* Exactly two references: */
	list_for_each_entry(ref, &entry->refs, list) {
		/*
		 * Corner-case: the second reference comes from the potential
		 * reset-gpio instance. However, this pin is not really shared
		 * as it would have three references in this case. Avoid
		 * creating unnecessary proxies.
		 */
		if (ref->is_reset_gpio)
			return false;
	}

	return true;
}

static void gpio_shared_free_exclusive(void)
{
	struct gpio_shared_entry *entry, *epos;
	struct gpio_shared_ref *ref, *rpos;

	list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) {
		if (gpio_shared_entry_is_really_shared(entry))
			continue;

		list_for_each_entry_safe(ref, rpos, &entry->refs, list)
			gpio_shared_drop_ref(ref);
		gpio_shared_drop_entry(entry);
	}
}

static int __init gpio_shared_init(void)
{
	int ret;

	/* Right now, we only support OF-based systems. */
	ret = gpio_shared_of_scan();
	if (ret) {
		gpio_shared_teardown();
		pr_err("Failed to scan OF nodes for shared GPIOs: %d\n", ret);
		return ret;
	}

	gpio_shared_free_exclusive();

	pr_debug("Finished scanning firmware nodes for shared GPIOs\n");
	return 0;
}
postcore_initcall(gpio_shared_init);
