// 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(sizeof(*control), GFP_KERNEL);
	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);
}
