// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for onboard USB devices
 *
 * Copyright (c) 2022, Google LLC
 */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/sysfs.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/onboard_dev.h>
#include <linux/workqueue.h>

#include "onboard_usb_dev.h"

static void onboard_dev_attach_usb_driver(struct work_struct *work);

static struct usb_device_driver onboard_dev_usbdev_driver;
static DECLARE_WORK(attach_usb_driver_work, onboard_dev_attach_usb_driver);

/************************** Platform driver **************************/

struct usbdev_node {
	struct usb_device *udev;
	struct list_head list;
};

struct onboard_dev {
	struct regulator_bulk_data supplies[MAX_SUPPLIES];
	struct device *dev;
	const struct onboard_dev_pdata *pdata;
	struct gpio_desc *reset_gpio;
	bool always_powered_in_suspend;
	bool is_powered_on;
	bool going_away;
	struct list_head udev_list;
	struct mutex lock;
	struct clk *clk;
};

static int onboard_dev_get_regulators(struct onboard_dev *onboard_dev)
{
	const char * const *supply_names = onboard_dev->pdata->supply_names;
	unsigned int num_supplies = onboard_dev->pdata->num_supplies;
	struct device *dev = onboard_dev->dev;
	unsigned int i;
	int err;

	if (num_supplies > MAX_SUPPLIES)
		return dev_err_probe(dev, -EINVAL, "max %d supplies supported!\n",
				     MAX_SUPPLIES);

	for (i = 0; i < num_supplies; i++)
		onboard_dev->supplies[i].supply = supply_names[i];

	err = devm_regulator_bulk_get(dev, num_supplies, onboard_dev->supplies);
	if (err)
		dev_err(dev, "Failed to get regulator supplies: %pe\n",
			ERR_PTR(err));

	return err;
}

static int onboard_dev_power_on(struct onboard_dev *onboard_dev)
{
	int err;

	err = clk_prepare_enable(onboard_dev->clk);
	if (err) {
		dev_err(onboard_dev->dev, "failed to enable clock: %pe\n",
			ERR_PTR(err));
		return err;
	}

	err = regulator_bulk_enable(onboard_dev->pdata->num_supplies,
				    onboard_dev->supplies);
	if (err) {
		dev_err(onboard_dev->dev, "failed to enable supplies: %pe\n",
			ERR_PTR(err));
		goto disable_clk;
	}

	fsleep(onboard_dev->pdata->reset_us);
	gpiod_set_value_cansleep(onboard_dev->reset_gpio, 0);

	onboard_dev->is_powered_on = true;

	return 0;

disable_clk:
	clk_disable_unprepare(onboard_dev->clk);
	return err;
}

static int onboard_dev_power_off(struct onboard_dev *onboard_dev)
{
	int err;

	gpiod_set_value_cansleep(onboard_dev->reset_gpio, 1);

	err = regulator_bulk_disable(onboard_dev->pdata->num_supplies,
				     onboard_dev->supplies);
	if (err) {
		dev_err(onboard_dev->dev, "failed to disable supplies: %pe\n",
			ERR_PTR(err));
		return err;
	}

	clk_disable_unprepare(onboard_dev->clk);

	onboard_dev->is_powered_on = false;

	return 0;
}

static int __maybe_unused onboard_dev_suspend(struct device *dev)
{
	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
	struct usbdev_node *node;
	bool power_off = true;

	if (onboard_dev->always_powered_in_suspend)
		return 0;

	mutex_lock(&onboard_dev->lock);

	list_for_each_entry(node, &onboard_dev->udev_list, list) {
		if (!device_may_wakeup(node->udev->bus->controller))
			continue;

		if (usb_wakeup_enabled_descendants(node->udev)) {
			power_off = false;
			break;
		}
	}

	mutex_unlock(&onboard_dev->lock);

	if (!power_off)
		return 0;

	return onboard_dev_power_off(onboard_dev);
}

static int __maybe_unused onboard_dev_resume(struct device *dev)
{
	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);

	if (onboard_dev->is_powered_on)
		return 0;

	return onboard_dev_power_on(onboard_dev);
}

static inline void get_udev_link_name(const struct usb_device *udev, char *buf,
				      size_t size)
{
	snprintf(buf, size, "usb_dev.%s", dev_name(&udev->dev));
}

static int onboard_dev_add_usbdev(struct onboard_dev *onboard_dev,
				  struct usb_device *udev)
{
	struct usbdev_node *node;
	char link_name[64];
	int err;

	mutex_lock(&onboard_dev->lock);

	if (onboard_dev->going_away) {
		err = -EINVAL;
		goto error;
	}

	node = kzalloc(sizeof(*node), GFP_KERNEL);
	if (!node) {
		err = -ENOMEM;
		goto error;
	}

	node->udev = udev;

	list_add(&node->list, &onboard_dev->udev_list);

	mutex_unlock(&onboard_dev->lock);

	get_udev_link_name(udev, link_name, sizeof(link_name));
	WARN_ON(sysfs_create_link(&onboard_dev->dev->kobj, &udev->dev.kobj,
				  link_name));

	return 0;

error:
	mutex_unlock(&onboard_dev->lock);

	return err;
}

static void onboard_dev_remove_usbdev(struct onboard_dev *onboard_dev,
				      const struct usb_device *udev)
{
	struct usbdev_node *node;
	char link_name[64];

	get_udev_link_name(udev, link_name, sizeof(link_name));
	sysfs_remove_link(&onboard_dev->dev->kobj, link_name);

	mutex_lock(&onboard_dev->lock);

	list_for_each_entry(node, &onboard_dev->udev_list, list) {
		if (node->udev == udev) {
			list_del(&node->list);
			kfree(node);
			break;
		}
	}

	mutex_unlock(&onboard_dev->lock);
}

static ssize_t always_powered_in_suspend_show(struct device *dev,
					      struct device_attribute *attr,
					      char *buf)
{
	const struct onboard_dev *onboard_dev = dev_get_drvdata(dev);

	return sysfs_emit(buf, "%d\n", onboard_dev->always_powered_in_suspend);
}

static ssize_t always_powered_in_suspend_store(struct device *dev,
					       struct device_attribute *attr,
					       const char *buf, size_t count)
{
	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
	bool val;
	int ret;

	ret = kstrtobool(buf, &val);
	if (ret < 0)
		return ret;

	onboard_dev->always_powered_in_suspend = val;

	return count;
}
static DEVICE_ATTR_RW(always_powered_in_suspend);

static struct attribute *onboard_dev_attrs[] = {
	&dev_attr_always_powered_in_suspend.attr,
	NULL,
};

static umode_t onboard_dev_attrs_are_visible(struct kobject *kobj,
					     struct attribute *attr,
					     int n)
{
	struct device *dev = kobj_to_dev(kobj);
	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);

	if (attr == &dev_attr_always_powered_in_suspend.attr &&
	    !onboard_dev->pdata->is_hub)
		return 0;

	return attr->mode;
}

static const struct attribute_group onboard_dev_group = {
	.is_visible = onboard_dev_attrs_are_visible,
	.attrs = onboard_dev_attrs,
};
__ATTRIBUTE_GROUPS(onboard_dev);


static void onboard_dev_attach_usb_driver(struct work_struct *work)
{
	int err;

	err = driver_attach(&onboard_dev_usbdev_driver.driver);
	if (err)
		pr_err("Failed to attach USB driver: %pe\n", ERR_PTR(err));
}

static int onboard_dev_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct onboard_dev *onboard_dev;
	int err;

	onboard_dev = devm_kzalloc(dev, sizeof(*onboard_dev), GFP_KERNEL);
	if (!onboard_dev)
		return -ENOMEM;

	onboard_dev->pdata = device_get_match_data(dev);
	if (!onboard_dev->pdata)
		return -EINVAL;

	if (!onboard_dev->pdata->is_hub)
		onboard_dev->always_powered_in_suspend = true;

	onboard_dev->dev = dev;

	err = onboard_dev_get_regulators(onboard_dev);
	if (err)
		return err;

	onboard_dev->clk = devm_clk_get_optional(dev, NULL);
	if (IS_ERR(onboard_dev->clk))
		return dev_err_probe(dev, PTR_ERR(onboard_dev->clk),
				     "failed to get clock\n");

	onboard_dev->reset_gpio = devm_gpiod_get_optional(dev, "reset",
							  GPIOD_OUT_HIGH);
	if (IS_ERR(onboard_dev->reset_gpio))
		return dev_err_probe(dev, PTR_ERR(onboard_dev->reset_gpio),
				     "failed to get reset GPIO\n");

	mutex_init(&onboard_dev->lock);
	INIT_LIST_HEAD(&onboard_dev->udev_list);

	dev_set_drvdata(dev, onboard_dev);

	err = onboard_dev_power_on(onboard_dev);
	if (err)
		return err;

	/*
	 * The USB driver might have been detached from the USB devices by
	 * onboard_dev_remove() (e.g. through an 'unbind' by userspace),
	 * make sure to re-attach it if needed.
	 *
	 * This needs to be done deferred to avoid self-deadlocks on systems
	 * with nested onboard hubs.
	 */
	schedule_work(&attach_usb_driver_work);

	return 0;
}

static void onboard_dev_remove(struct platform_device *pdev)
{
	struct onboard_dev *onboard_dev = dev_get_drvdata(&pdev->dev);
	struct usbdev_node *node;
	struct usb_device *udev;

	onboard_dev->going_away = true;

	mutex_lock(&onboard_dev->lock);

	/* unbind the USB devices to avoid dangling references to this device */
	while (!list_empty(&onboard_dev->udev_list)) {
		node = list_first_entry(&onboard_dev->udev_list,
					struct usbdev_node, list);
		udev = node->udev;

		/*
		 * Unbinding the driver will call onboard_dev_remove_usbdev(),
		 * which acquires onboard_dev->lock. We must release the lock
		 * first.
		 */
		get_device(&udev->dev);
		mutex_unlock(&onboard_dev->lock);
		device_release_driver(&udev->dev);
		put_device(&udev->dev);
		mutex_lock(&onboard_dev->lock);
	}

	mutex_unlock(&onboard_dev->lock);

	onboard_dev_power_off(onboard_dev);
}

MODULE_DEVICE_TABLE(of, onboard_dev_match);

static const struct dev_pm_ops __maybe_unused onboard_dev_pm_ops = {
	SET_LATE_SYSTEM_SLEEP_PM_OPS(onboard_dev_suspend, onboard_dev_resume)
};

static struct platform_driver onboard_dev_driver = {
	.probe = onboard_dev_probe,
	.remove_new = onboard_dev_remove,

	.driver = {
		.name = "onboard-usb-dev",
		.of_match_table = onboard_dev_match,
		.pm = pm_ptr(&onboard_dev_pm_ops),
		.dev_groups = onboard_dev_groups,
	},
};

/************************** USB driver **************************/

#define VENDOR_ID_CYPRESS	0x04b4
#define VENDOR_ID_GENESYS	0x05e3
#define VENDOR_ID_MICROCHIP	0x0424
#define VENDOR_ID_REALTEK	0x0bda
#define VENDOR_ID_TI		0x0451
#define VENDOR_ID_VIA		0x2109
#define VENDOR_ID_XMOS		0x20B1

/*
 * Returns the onboard_dev platform device that is associated with the USB
 * device passed as parameter.
 */
static struct onboard_dev *_find_onboard_dev(struct device *dev)
{
	struct platform_device *pdev;
	struct device_node *np;
	struct onboard_dev *onboard_dev;

	pdev = of_find_device_by_node(dev->of_node);
	if (!pdev) {
		np = of_parse_phandle(dev->of_node, "peer-hub", 0);
		if (!np) {
			dev_err(dev, "failed to find device node for peer hub\n");
			return ERR_PTR(-EINVAL);
		}

		pdev = of_find_device_by_node(np);
		of_node_put(np);

		if (!pdev)
			return ERR_PTR(-ENODEV);
	}

	onboard_dev = dev_get_drvdata(&pdev->dev);
	put_device(&pdev->dev);

	/*
	 * The presence of drvdata indicates that the platform driver finished
	 * probing. This handles the case where (conceivably) we could be
	 * running at the exact same time as the platform driver's probe. If
	 * we detect the race we request probe deferral and we'll come back and
	 * try again.
	 */
	if (!onboard_dev)
		return ERR_PTR(-EPROBE_DEFER);

	return onboard_dev;
}

static int onboard_dev_usbdev_probe(struct usb_device *udev)
{
	struct device *dev = &udev->dev;
	struct onboard_dev *onboard_dev;
	int err;

	/* ignore supported devices without device tree node */
	if (!dev->of_node)
		return -ENODEV;

	onboard_dev = _find_onboard_dev(dev);
	if (IS_ERR(onboard_dev))
		return PTR_ERR(onboard_dev);

	dev_set_drvdata(dev, onboard_dev);

	err = onboard_dev_add_usbdev(onboard_dev, udev);
	if (err)
		return err;

	return 0;
}

static void onboard_dev_usbdev_disconnect(struct usb_device *udev)
{
	struct onboard_dev *onboard_dev = dev_get_drvdata(&udev->dev);

	onboard_dev_remove_usbdev(onboard_dev, udev);
}

static const struct usb_device_id onboard_dev_id_table[] = {
	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6504) }, /* CYUSB33{0,1,2}x/CYUSB230x 3.0 HUB */
	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6506) }, /* CYUSB33{0,1,2}x/CYUSB230x 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6570) }, /* CY7C6563x 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 HUB */
	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2744) }, /* USB5744 USB 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x5744) }, /* USB5744 USB 3.0 HUB */
	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 HUB */
	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 HUB */
	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 HUB */
	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x5414) }, /* RTS5414 USB 2.1 HUB */
	{ USB_DEVICE(VENDOR_ID_TI, 0x8025) }, /* TI USB8020B 3.0 HUB */
	{ USB_DEVICE(VENDOR_ID_TI, 0x8027) }, /* TI USB8020B 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_TI, 0x8140) }, /* TI USB8041 3.0 HUB */
	{ USB_DEVICE(VENDOR_ID_TI, 0x8142) }, /* TI USB8041 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_VIA, 0x0817) }, /* VIA VL817 3.1 HUB */
	{ USB_DEVICE(VENDOR_ID_VIA, 0x2817) }, /* VIA VL817 2.0 HUB */
	{ USB_DEVICE(VENDOR_ID_XMOS, 0x0013) }, /* XMOS XVF3500 Voice Processor */
	{}
};
MODULE_DEVICE_TABLE(usb, onboard_dev_id_table);

static struct usb_device_driver onboard_dev_usbdev_driver = {
	.name = "onboard-usb-dev",
	.probe = onboard_dev_usbdev_probe,
	.disconnect = onboard_dev_usbdev_disconnect,
	.generic_subclass = 1,
	.supports_autosuspend =	1,
	.id_table = onboard_dev_id_table,
};

static int __init onboard_dev_init(void)
{
	int ret;

	ret = usb_register_device_driver(&onboard_dev_usbdev_driver, THIS_MODULE);
	if (ret)
		return ret;

	ret = platform_driver_register(&onboard_dev_driver);
	if (ret)
		usb_deregister_device_driver(&onboard_dev_usbdev_driver);

	return ret;
}
module_init(onboard_dev_init);

static void __exit onboard_dev_exit(void)
{
	usb_deregister_device_driver(&onboard_dev_usbdev_driver);
	platform_driver_unregister(&onboard_dev_driver);

	cancel_work_sync(&attach_usb_driver_work);
}
module_exit(onboard_dev_exit);

MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
MODULE_DESCRIPTION("Driver for discrete onboard USB devices");
MODULE_LICENSE("GPL v2");
