// SPDX-License-Identifier: GPL-2.0
/*
 * USB4 port device
 *
 * Copyright (C) 2021, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/pm_runtime.h>
#include <linux/component.h>
#include <linux/property.h>

#include "tb.h"

static int connector_bind(struct device *dev, struct device *connector, void *data)
{
	int ret;

	ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector");
	if (ret)
		return ret;

	ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev));
	if (ret)
		sysfs_remove_link(&dev->kobj, "connector");

	return ret;
}

static void connector_unbind(struct device *dev, struct device *connector, void *data)
{
	sysfs_remove_link(&connector->kobj, dev_name(dev));
	sysfs_remove_link(&dev->kobj, "connector");
}

static const struct component_ops connector_ops = {
	.bind = connector_bind,
	.unbind = connector_unbind,
};

static ssize_t link_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
	struct tb_port *port = usb4->port;
	struct tb *tb = port->sw->tb;
	const char *link;

	if (mutex_lock_interruptible(&tb->lock))
		return -ERESTARTSYS;

	if (tb_is_upstream_port(port))
		link = port->sw->link_usb4 ? "usb4" : "tbt";
	else if (tb_port_has_remote(port))
		link = port->remote->sw->link_usb4 ? "usb4" : "tbt";
	else if (port->xdomain)
		link = port->xdomain->link_usb4 ? "usb4" : "tbt";
	else
		link = "none";

	mutex_unlock(&tb->lock);

	return sysfs_emit(buf, "%s\n", link);
}
static DEVICE_ATTR_RO(link);

static struct attribute *common_attrs[] = {
	&dev_attr_link.attr,
	NULL
};

static const struct attribute_group common_group = {
	.attrs = common_attrs,
};

static int usb4_port_offline(struct usb4_port *usb4)
{
	struct tb_port *port = usb4->port;
	int ret;

	ret = tb_acpi_power_on_retimers(port);
	if (ret)
		return ret;

	ret = usb4_port_router_offline(port);
	if (ret) {
		tb_acpi_power_off_retimers(port);
		return ret;
	}

	ret = tb_retimer_scan(port, false);
	if (ret) {
		usb4_port_router_online(port);
		tb_acpi_power_off_retimers(port);
	}

	return ret;
}

static void usb4_port_online(struct usb4_port *usb4)
{
	struct tb_port *port = usb4->port;

	usb4_port_router_online(port);
	tb_acpi_power_off_retimers(port);
}

static ssize_t offline_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);

	return sysfs_emit(buf, "%d\n", usb4->offline);
}

static ssize_t offline_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
	struct tb_port *port = usb4->port;
	struct tb *tb = port->sw->tb;
	bool val;
	int ret;

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

	pm_runtime_get_sync(&usb4->dev);

	if (mutex_lock_interruptible(&tb->lock)) {
		ret = -ERESTARTSYS;
		goto out_rpm;
	}

	if (val == usb4->offline)
		goto out_unlock;

	/* Offline mode works only for ports that are not connected */
	if (tb_port_has_remote(port)) {
		ret = -EBUSY;
		goto out_unlock;
	}

	if (val) {
		ret = usb4_port_offline(usb4);
		if (ret)
			goto out_unlock;
	} else {
		usb4_port_online(usb4);
		tb_retimer_remove_all(port);
	}

	usb4->offline = val;
	tb_port_dbg(port, "%s offline mode\n", val ? "enter" : "exit");

out_unlock:
	mutex_unlock(&tb->lock);
out_rpm:
	pm_runtime_mark_last_busy(&usb4->dev);
	pm_runtime_put_autosuspend(&usb4->dev);

	return ret ? ret : count;
}
static DEVICE_ATTR_RW(offline);

static ssize_t rescan_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
	struct tb_port *port = usb4->port;
	struct tb *tb = port->sw->tb;
	bool val;
	int ret;

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

	if (!val)
		return count;

	pm_runtime_get_sync(&usb4->dev);

	if (mutex_lock_interruptible(&tb->lock)) {
		ret = -ERESTARTSYS;
		goto out_rpm;
	}

	/* Must be in offline mode already */
	if (!usb4->offline) {
		ret = -EINVAL;
		goto out_unlock;
	}

	tb_retimer_remove_all(port);
	ret = tb_retimer_scan(port, true);

out_unlock:
	mutex_unlock(&tb->lock);
out_rpm:
	pm_runtime_mark_last_busy(&usb4->dev);
	pm_runtime_put_autosuspend(&usb4->dev);

	return ret ? ret : count;
}
static DEVICE_ATTR_WO(rescan);

static struct attribute *service_attrs[] = {
	&dev_attr_offline.attr,
	&dev_attr_rescan.attr,
	NULL
};

static umode_t service_attr_is_visible(struct kobject *kobj,
				       struct attribute *attr, int n)
{
	struct device *dev = kobj_to_dev(kobj);
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);

	/*
	 * Always need some platform help to cycle the modes so that
	 * retimers can be accessed through the sideband.
	 */
	return usb4->can_offline ? attr->mode : 0;
}

static const struct attribute_group service_group = {
	.attrs = service_attrs,
	.is_visible = service_attr_is_visible,
};

static const struct attribute_group *usb4_port_device_groups[] = {
	&common_group,
	&service_group,
	NULL
};

static void usb4_port_device_release(struct device *dev)
{
	struct usb4_port *usb4 = container_of(dev, struct usb4_port, dev);

	kfree(usb4);
}

const struct device_type usb4_port_device_type = {
	.name = "usb4_port",
	.groups = usb4_port_device_groups,
	.release = usb4_port_device_release,
};

/**
 * usb4_port_device_add() - Add USB4 port device
 * @port: Lane 0 adapter port to add the USB4 port
 *
 * Creates and registers a USB4 port device for @port. Returns the new
 * USB4 port device pointer or ERR_PTR() in case of error.
 */
struct usb4_port *usb4_port_device_add(struct tb_port *port)
{
	struct usb4_port *usb4;
	int ret;

	usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL);
	if (!usb4)
		return ERR_PTR(-ENOMEM);

	usb4->port = port;
	usb4->dev.type = &usb4_port_device_type;
	usb4->dev.parent = &port->sw->dev;
	dev_set_name(&usb4->dev, "usb4_port%d", port->port);

	ret = device_register(&usb4->dev);
	if (ret) {
		put_device(&usb4->dev);
		return ERR_PTR(ret);
	}

	if (dev_fwnode(&usb4->dev)) {
		ret = component_add(&usb4->dev, &connector_ops);
		if (ret) {
			dev_err(&usb4->dev, "failed to add component\n");
			device_unregister(&usb4->dev);
		}
	}

	if (!tb_is_upstream_port(port))
		device_set_wakeup_capable(&usb4->dev, true);

	pm_runtime_no_callbacks(&usb4->dev);
	pm_runtime_set_active(&usb4->dev);
	pm_runtime_enable(&usb4->dev);
	pm_runtime_set_autosuspend_delay(&usb4->dev, TB_AUTOSUSPEND_DELAY);
	pm_runtime_mark_last_busy(&usb4->dev);
	pm_runtime_use_autosuspend(&usb4->dev);

	return usb4;
}

/**
 * usb4_port_device_remove() - Removes USB4 port device
 * @usb4: USB4 port device
 *
 * Unregisters the USB4 port device from the system. The device will be
 * released when the last reference is dropped.
 */
void usb4_port_device_remove(struct usb4_port *usb4)
{
	if (dev_fwnode(&usb4->dev))
		component_del(&usb4->dev, &connector_ops);
	device_unregister(&usb4->dev);
}

/**
 * usb4_port_device_resume() - Resumes USB4 port device
 * @usb4: USB4 port device
 *
 * Used to resume USB4 port device after sleep state.
 */
int usb4_port_device_resume(struct usb4_port *usb4)
{
	return usb4->offline ? usb4_port_offline(usb4) : 0;
}
