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

#include <linux/acpi.h>
#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
		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);
}

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;
}
