// SPDX-License-Identifier: GPL-2.0
/*
 * Greybus CPort control protocol.
 *
 * Copyright 2015 Google Inc.
 * Copyright 2015 Linaro Ltd.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/greybus.h>

/* Highest control-protocol version supported */
#define GB_CONTROL_VERSION_MAJOR	0
#define GB_CONTROL_VERSION_MINOR	1

static int gb_control_get_version(struct gb_control *control)
{
	struct gb_interface *intf = control->connection->intf;
	struct gb_control_version_request request;
	struct gb_control_version_response response;
	int ret;

	request.major = GB_CONTROL_VERSION_MAJOR;
	request.minor = GB_CONTROL_VERSION_MINOR;

	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_VERSION,
				&request, sizeof(request), &response,
				sizeof(response));
	if (ret) {
		dev_err(&intf->dev,
			"failed to get control-protocol version: %d\n",
			ret);
		return ret;
	}

	if (response.major > request.major) {
		dev_err(&intf->dev,
			"unsupported major control-protocol version (%u > %u)\n",
			response.major, request.major);
		return -ENOTSUPP;
	}

	control->protocol_major = response.major;
	control->protocol_minor = response.minor;

	dev_dbg(&intf->dev, "%s - %u.%u\n", __func__, response.major,
		response.minor);

	return 0;
}

static int gb_control_get_bundle_version(struct gb_control *control,
					 struct gb_bundle *bundle)
{
	struct gb_interface *intf = control->connection->intf;
	struct gb_control_bundle_version_request request;
	struct gb_control_bundle_version_response response;
	int ret;

	request.bundle_id = bundle->id;

	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_BUNDLE_VERSION,
				&request, sizeof(request),
				&response, sizeof(response));
	if (ret) {
		dev_err(&intf->dev,
			"failed to get bundle %u class version: %d\n",
			bundle->id, ret);
		return ret;
	}

	bundle->class_major = response.major;
	bundle->class_minor = response.minor;

	dev_dbg(&intf->dev, "%s - %u: %u.%u\n", __func__, bundle->id,
		response.major, response.minor);

	return 0;
}

int gb_control_get_bundle_versions(struct gb_control *control)
{
	struct gb_interface *intf = control->connection->intf;
	struct gb_bundle *bundle;
	int ret;

	if (!control->has_bundle_version)
		return 0;

	list_for_each_entry(bundle, &intf->bundles, links) {
		ret = gb_control_get_bundle_version(control, bundle);
		if (ret)
			return ret;
	}

	return 0;
}

/* Get Manifest's size from the interface */
int gb_control_get_manifest_size_operation(struct gb_interface *intf)
{
	struct gb_control_get_manifest_size_response response;
	struct gb_connection *connection = intf->control->connection;
	int ret;

	ret = gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST_SIZE,
				NULL, 0, &response, sizeof(response));
	if (ret) {
		dev_err(&connection->intf->dev,
			"failed to get manifest size: %d\n", ret);
		return ret;
	}

	return le16_to_cpu(response.size);
}

/* Reads Manifest from the interface */
int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
				      size_t size)
{
	struct gb_connection *connection = intf->control->connection;

	return gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST,
				NULL, 0, manifest, size);
}

int gb_control_connected_operation(struct gb_control *control, u16 cport_id)
{
	struct gb_control_connected_request request;

	request.cport_id = cpu_to_le16(cport_id);
	return gb_operation_sync(control->connection, GB_CONTROL_TYPE_CONNECTED,
				 &request, sizeof(request), NULL, 0);
}

int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id)
{
	struct gb_control_disconnected_request request;

	request.cport_id = cpu_to_le16(cport_id);
	return gb_operation_sync(control->connection,
				 GB_CONTROL_TYPE_DISCONNECTED, &request,
				 sizeof(request), NULL, 0);
}

int gb_control_disconnecting_operation(struct gb_control *control,
				       u16 cport_id)
{
	struct gb_control_disconnecting_request *request;
	struct gb_operation *operation;
	int ret;

	operation = gb_operation_create_core(control->connection,
					     GB_CONTROL_TYPE_DISCONNECTING,
					     sizeof(*request), 0, 0,
					     GFP_KERNEL);
	if (!operation)
		return -ENOMEM;

	request = operation->request->payload;
	request->cport_id = cpu_to_le16(cport_id);

	ret = gb_operation_request_send_sync(operation);
	if (ret) {
		dev_err(&control->dev, "failed to send disconnecting: %d\n",
			ret);
	}

	gb_operation_put(operation);

	return ret;
}

int gb_control_mode_switch_operation(struct gb_control *control)
{
	struct gb_operation *operation;
	int ret;

	operation = gb_operation_create_core(control->connection,
					     GB_CONTROL_TYPE_MODE_SWITCH,
					     0, 0,
					     GB_OPERATION_FLAG_UNIDIRECTIONAL,
					     GFP_KERNEL);
	if (!operation)
		return -ENOMEM;

	ret = gb_operation_request_send_sync(operation);
	if (ret)
		dev_err(&control->dev, "failed to send mode switch: %d\n", ret);

	gb_operation_put(operation);

	return ret;
}

static int gb_control_bundle_pm_status_map(u8 status)
{
	switch (status) {
	case GB_CONTROL_BUNDLE_PM_INVAL:
		return -EINVAL;
	case GB_CONTROL_BUNDLE_PM_BUSY:
		return -EBUSY;
	case GB_CONTROL_BUNDLE_PM_NA:
		return -ENOMSG;
	case GB_CONTROL_BUNDLE_PM_FAIL:
	default:
		return -EREMOTEIO;
	}
}

int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id)
{
	struct gb_control_bundle_pm_request request;
	struct gb_control_bundle_pm_response response;
	int ret;

	request.bundle_id = bundle_id;
	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_BUNDLE_SUSPEND, &request,
				sizeof(request), &response, sizeof(response));
	if (ret) {
		dev_err(&control->dev, "failed to send bundle %u suspend: %d\n",
			bundle_id, ret);
		return ret;
	}

	if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
		dev_err(&control->dev, "failed to suspend bundle %u: %d\n",
			bundle_id, response.status);
		return gb_control_bundle_pm_status_map(response.status);
	}

	return 0;
}

int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id)
{
	struct gb_control_bundle_pm_request request;
	struct gb_control_bundle_pm_response response;
	int ret;

	request.bundle_id = bundle_id;
	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_BUNDLE_RESUME, &request,
				sizeof(request), &response, sizeof(response));
	if (ret) {
		dev_err(&control->dev, "failed to send bundle %u resume: %d\n",
			bundle_id, ret);
		return ret;
	}

	if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
		dev_err(&control->dev, "failed to resume bundle %u: %d\n",
			bundle_id, response.status);
		return gb_control_bundle_pm_status_map(response.status);
	}

	return 0;
}

int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id)
{
	struct gb_control_bundle_pm_request request;
	struct gb_control_bundle_pm_response response;
	int ret;

	request.bundle_id = bundle_id;
	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_BUNDLE_DEACTIVATE, &request,
				sizeof(request), &response, sizeof(response));
	if (ret) {
		dev_err(&control->dev,
			"failed to send bundle %u deactivate: %d\n", bundle_id,
			ret);
		return ret;
	}

	if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
		dev_err(&control->dev, "failed to deactivate bundle %u: %d\n",
			bundle_id, response.status);
		return gb_control_bundle_pm_status_map(response.status);
	}

	return 0;
}

int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id)
{
	struct gb_control_bundle_pm_request request;
	struct gb_control_bundle_pm_response response;
	int ret;

	if (!control->has_bundle_activate)
		return 0;

	request.bundle_id = bundle_id;
	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_BUNDLE_ACTIVATE, &request,
				sizeof(request), &response, sizeof(response));
	if (ret) {
		dev_err(&control->dev,
			"failed to send bundle %u activate: %d\n", bundle_id,
			ret);
		return ret;
	}

	if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
		dev_err(&control->dev, "failed to activate bundle %u: %d\n",
			bundle_id, response.status);
		return gb_control_bundle_pm_status_map(response.status);
	}

	return 0;
}

static int gb_control_interface_pm_status_map(u8 status)
{
	switch (status) {
	case GB_CONTROL_INTF_PM_BUSY:
		return -EBUSY;
	case GB_CONTROL_INTF_PM_NA:
		return -ENOMSG;
	default:
		return -EREMOTEIO;
	}
}

int gb_control_interface_suspend_prepare(struct gb_control *control)
{
	struct gb_control_intf_pm_response response;
	int ret;

	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE, NULL, 0,
				&response, sizeof(response));
	if (ret) {
		dev_err(&control->dev,
			"failed to send interface suspend prepare: %d\n", ret);
		return ret;
	}

	if (response.status != GB_CONTROL_INTF_PM_OK) {
		dev_err(&control->dev, "interface error while preparing suspend: %d\n",
			response.status);
		return gb_control_interface_pm_status_map(response.status);
	}

	return 0;
}

int gb_control_interface_deactivate_prepare(struct gb_control *control)
{
	struct gb_control_intf_pm_response response;
	int ret;

	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_INTF_DEACTIVATE_PREPARE, NULL,
				0, &response, sizeof(response));
	if (ret) {
		dev_err(&control->dev, "failed to send interface deactivate prepare: %d\n",
			ret);
		return ret;
	}

	if (response.status != GB_CONTROL_INTF_PM_OK) {
		dev_err(&control->dev, "interface error while preparing deactivate: %d\n",
			response.status);
		return gb_control_interface_pm_status_map(response.status);
	}

	return 0;
}

int gb_control_interface_hibernate_abort(struct gb_control *control)
{
	struct gb_control_intf_pm_response response;
	int ret;

	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_INTF_HIBERNATE_ABORT, NULL, 0,
				&response, sizeof(response));
	if (ret) {
		dev_err(&control->dev,
			"failed to send interface aborting hibernate: %d\n",
			ret);
		return ret;
	}

	if (response.status != GB_CONTROL_INTF_PM_OK) {
		dev_err(&control->dev, "interface error while aborting hibernate: %d\n",
			response.status);
		return gb_control_interface_pm_status_map(response.status);
	}

	return 0;
}

static ssize_t vendor_string_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	struct gb_control *control = to_gb_control(dev);

	return scnprintf(buf, PAGE_SIZE, "%s\n", control->vendor_string);
}
static DEVICE_ATTR_RO(vendor_string);

static ssize_t product_string_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct gb_control *control = to_gb_control(dev);

	return scnprintf(buf, PAGE_SIZE, "%s\n", control->product_string);
}
static DEVICE_ATTR_RO(product_string);

static struct attribute *control_attrs[] = {
	&dev_attr_vendor_string.attr,
	&dev_attr_product_string.attr,
	NULL,
};
ATTRIBUTE_GROUPS(control);

static void gb_control_release(struct device *dev)
{
	struct gb_control *control = to_gb_control(dev);

	gb_connection_destroy(control->connection);

	kfree(control->vendor_string);
	kfree(control->product_string);

	kfree(control);
}

const struct device_type greybus_control_type = {
	.name =		"greybus_control",
	.release =	gb_control_release,
};

struct gb_control *gb_control_create(struct gb_interface *intf)
{
	struct gb_connection *connection;
	struct gb_control *control;

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

	control->intf = intf;

	connection = gb_connection_create_control(intf);
	if (IS_ERR(connection)) {
		dev_err(&intf->dev,
			"failed to create control connection: %ld\n",
			PTR_ERR(connection));
		kfree(control);
		return ERR_CAST(connection);
	}

	control->connection = connection;

	control->dev.parent = &intf->dev;
	control->dev.bus = &greybus_bus_type;
	control->dev.type = &greybus_control_type;
	control->dev.groups = control_groups;
	control->dev.dma_mask = intf->dev.dma_mask;
	device_initialize(&control->dev);
	dev_set_name(&control->dev, "%s.ctrl", dev_name(&intf->dev));

	gb_connection_set_data(control->connection, control);

	return control;
}

int gb_control_enable(struct gb_control *control)
{
	int ret;

	dev_dbg(&control->connection->intf->dev, "%s\n", __func__);

	ret = gb_connection_enable_tx(control->connection);
	if (ret) {
		dev_err(&control->connection->intf->dev,
			"failed to enable control connection: %d\n",
			ret);
		return ret;
	}

	ret = gb_control_get_version(control);
	if (ret)
		goto err_disable_connection;

	if (control->protocol_major > 0 || control->protocol_minor > 1)
		control->has_bundle_version = true;

	/* FIXME: use protocol version instead */
	if (!(control->intf->quirks & GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE))
		control->has_bundle_activate = true;

	return 0;

err_disable_connection:
	gb_connection_disable(control->connection);

	return ret;
}

void gb_control_disable(struct gb_control *control)
{
	dev_dbg(&control->connection->intf->dev, "%s\n", __func__);

	if (control->intf->disconnected)
		gb_connection_disable_forced(control->connection);
	else
		gb_connection_disable(control->connection);
}

int gb_control_suspend(struct gb_control *control)
{
	gb_connection_disable(control->connection);

	return 0;
}

int gb_control_resume(struct gb_control *control)
{
	int ret;

	ret = gb_connection_enable_tx(control->connection);
	if (ret) {
		dev_err(&control->connection->intf->dev,
			"failed to enable control connection: %d\n", ret);
		return ret;
	}

	return 0;
}

int gb_control_add(struct gb_control *control)
{
	int ret;

	ret = device_add(&control->dev);
	if (ret) {
		dev_err(&control->dev,
			"failed to register control device: %d\n",
			ret);
		return ret;
	}

	return 0;
}

void gb_control_del(struct gb_control *control)
{
	if (device_is_registered(&control->dev))
		device_del(&control->dev);
}

struct gb_control *gb_control_get(struct gb_control *control)
{
	get_device(&control->dev);

	return control;
}

void gb_control_put(struct gb_control *control)
{
	put_device(&control->dev);
}

void gb_control_mode_switch_prepare(struct gb_control *control)
{
	gb_connection_mode_switch_prepare(control->connection);
}

void gb_control_mode_switch_complete(struct gb_control *control)
{
	gb_connection_mode_switch_complete(control->connection);
}
