/*
 * HSI core.
 *
 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
 *
 * Contact: Carlos Chinea <carlos.chinea@nokia.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */
#include <linux/hsi/hsi.h>
#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/kobject.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include "hsi_core.h"

static ssize_t modalias_show(struct device *dev,
			struct device_attribute *a __maybe_unused, char *buf)
{
	return sprintf(buf, "hsi:%s\n", dev_name(dev));
}
static DEVICE_ATTR_RO(modalias);

static struct attribute *hsi_bus_dev_attrs[] = {
	&dev_attr_modalias.attr,
	NULL,
};
ATTRIBUTE_GROUPS(hsi_bus_dev);

static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));

	return 0;
}

static int hsi_bus_match(struct device *dev, struct device_driver *driver)
{
	if (of_driver_match_device(dev, driver))
		return true;

	if (strcmp(dev_name(dev), driver->name) == 0)
		return true;

	return false;
}

static struct bus_type hsi_bus_type = {
	.name		= "hsi",
	.dev_groups	= hsi_bus_dev_groups,
	.match		= hsi_bus_match,
	.uevent		= hsi_bus_uevent,
};

static void hsi_client_release(struct device *dev)
{
	struct hsi_client *cl = to_hsi_client(dev);

	kfree(cl->tx_cfg.channels);
	kfree(cl->rx_cfg.channels);
	kfree(cl);
}

struct hsi_client *hsi_new_client(struct hsi_port *port,
						struct hsi_board_info *info)
{
	struct hsi_client *cl;
	size_t size;

	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
	if (!cl)
		return NULL;

	cl->tx_cfg = info->tx_cfg;
	if (cl->tx_cfg.channels) {
		size = cl->tx_cfg.num_channels * sizeof(*cl->tx_cfg.channels);
		cl->tx_cfg.channels = kzalloc(size , GFP_KERNEL);
		memcpy(cl->tx_cfg.channels, info->tx_cfg.channels, size);
	}

	cl->rx_cfg = info->rx_cfg;
	if (cl->rx_cfg.channels) {
		size = cl->rx_cfg.num_channels * sizeof(*cl->rx_cfg.channels);
		cl->rx_cfg.channels = kzalloc(size , GFP_KERNEL);
		memcpy(cl->rx_cfg.channels, info->rx_cfg.channels, size);
	}

	cl->device.bus = &hsi_bus_type;
	cl->device.parent = &port->device;
	cl->device.release = hsi_client_release;
	dev_set_name(&cl->device, "%s", info->name);
	cl->device.platform_data = info->platform_data;
	if (info->archdata)
		cl->device.archdata = *info->archdata;
	if (device_register(&cl->device) < 0) {
		pr_err("hsi: failed to register client: %s\n", info->name);
		put_device(&cl->device);
	}

	return cl;
}
EXPORT_SYMBOL_GPL(hsi_new_client);

static void hsi_scan_board_info(struct hsi_controller *hsi)
{
	struct hsi_cl_info *cl_info;
	struct hsi_port	*p;

	list_for_each_entry(cl_info, &hsi_board_list, list)
		if (cl_info->info.hsi_id == hsi->id) {
			p = hsi_find_port_num(hsi, cl_info->info.port);
			if (!p)
				continue;
			hsi_new_client(p, &cl_info->info);
		}
}

#ifdef CONFIG_OF
static struct hsi_board_info hsi_char_dev_info = {
	.name = "hsi_char",
};

static int hsi_of_property_parse_mode(struct device_node *client, char *name,
				      unsigned int *result)
{
	const char *mode;
	int err;

	err = of_property_read_string(client, name, &mode);
	if (err < 0)
		return err;

	if (strcmp(mode, "stream") == 0)
		*result = HSI_MODE_STREAM;
	else if (strcmp(mode, "frame") == 0)
		*result = HSI_MODE_FRAME;
	else
		return -EINVAL;

	return 0;
}

static int hsi_of_property_parse_flow(struct device_node *client, char *name,
				      unsigned int *result)
{
	const char *flow;
	int err;

	err = of_property_read_string(client, name, &flow);
	if (err < 0)
		return err;

	if (strcmp(flow, "synchronized") == 0)
		*result = HSI_FLOW_SYNC;
	else if (strcmp(flow, "pipeline") == 0)
		*result = HSI_FLOW_PIPE;
	else
		return -EINVAL;

	return 0;
}

static int hsi_of_property_parse_arb_mode(struct device_node *client,
					  char *name, unsigned int *result)
{
	const char *arb_mode;
	int err;

	err = of_property_read_string(client, name, &arb_mode);
	if (err < 0)
		return err;

	if (strcmp(arb_mode, "round-robin") == 0)
		*result = HSI_ARB_RR;
	else if (strcmp(arb_mode, "priority") == 0)
		*result = HSI_ARB_PRIO;
	else
		return -EINVAL;

	return 0;
}

static void hsi_add_client_from_dt(struct hsi_port *port,
						struct device_node *client)
{
	struct hsi_client *cl;
	struct hsi_channel channel;
	struct property *prop;
	char name[32];
	int length, cells, err, i, max_chan, mode;

	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
	if (!cl)
		return;

	err = of_modalias_node(client, name, sizeof(name));
	if (err)
		goto err;

	err = hsi_of_property_parse_mode(client, "hsi-mode", &mode);
	if (err) {
		err = hsi_of_property_parse_mode(client, "hsi-rx-mode",
						 &cl->rx_cfg.mode);
		if (err)
			goto err;

		err = hsi_of_property_parse_mode(client, "hsi-tx-mode",
						 &cl->tx_cfg.mode);
		if (err)
			goto err;
	} else {
		cl->rx_cfg.mode = mode;
		cl->tx_cfg.mode = mode;
	}

	err = of_property_read_u32(client, "hsi-speed-kbps",
				   &cl->tx_cfg.speed);
	if (err)
		goto err;
	cl->rx_cfg.speed = cl->tx_cfg.speed;

	err = hsi_of_property_parse_flow(client, "hsi-flow",
					 &cl->rx_cfg.flow);
	if (err)
		goto err;

	err = hsi_of_property_parse_arb_mode(client, "hsi-arb-mode",
					     &cl->rx_cfg.arb_mode);
	if (err)
		goto err;

	prop = of_find_property(client, "hsi-channel-ids", &length);
	if (!prop) {
		err = -EINVAL;
		goto err;
	}

	cells = length / sizeof(u32);

	cl->rx_cfg.num_channels = cells;
	cl->tx_cfg.num_channels = cells;

	cl->rx_cfg.channels = kzalloc(cells * sizeof(channel), GFP_KERNEL);
	if (!cl->rx_cfg.channels) {
		err = -ENOMEM;
		goto err;
	}

	cl->tx_cfg.channels = kzalloc(cells * sizeof(channel), GFP_KERNEL);
	if (!cl->tx_cfg.channels) {
		err = -ENOMEM;
		goto err2;
	}

	max_chan = 0;
	for (i = 0; i < cells; i++) {
		err = of_property_read_u32_index(client, "hsi-channel-ids", i,
						 &channel.id);
		if (err)
			goto err3;

		err = of_property_read_string_index(client, "hsi-channel-names",
						    i, &channel.name);
		if (err)
			channel.name = NULL;

		if (channel.id > max_chan)
			max_chan = channel.id;

		cl->rx_cfg.channels[i] = channel;
		cl->tx_cfg.channels[i] = channel;
	}

	cl->rx_cfg.num_hw_channels = max_chan + 1;
	cl->tx_cfg.num_hw_channels = max_chan + 1;

	cl->device.bus = &hsi_bus_type;
	cl->device.parent = &port->device;
	cl->device.release = hsi_client_release;
	cl->device.of_node = client;

	dev_set_name(&cl->device, "%s", name);
	if (device_register(&cl->device) < 0) {
		pr_err("hsi: failed to register client: %s\n", name);
		put_device(&cl->device);
		goto err3;
	}

	return;

err3:
	kfree(cl->tx_cfg.channels);
err2:
	kfree(cl->rx_cfg.channels);
err:
	kfree(cl);
	pr_err("hsi client: missing or incorrect of property: err=%d\n", err);
}

void hsi_add_clients_from_dt(struct hsi_port *port, struct device_node *clients)
{
	struct device_node *child;

	/* register hsi-char device */
	hsi_new_client(port, &hsi_char_dev_info);

	for_each_available_child_of_node(clients, child)
		hsi_add_client_from_dt(port, child);
}
EXPORT_SYMBOL_GPL(hsi_add_clients_from_dt);
#endif

int hsi_remove_client(struct device *dev, void *data __maybe_unused)
{
	device_unregister(dev);

	return 0;
}
EXPORT_SYMBOL_GPL(hsi_remove_client);

static int hsi_remove_port(struct device *dev, void *data __maybe_unused)
{
	device_for_each_child(dev, NULL, hsi_remove_client);
	device_unregister(dev);

	return 0;
}

static void hsi_controller_release(struct device *dev)
{
	struct hsi_controller *hsi = to_hsi_controller(dev);

	kfree(hsi->port);
	kfree(hsi);
}

static void hsi_port_release(struct device *dev)
{
	kfree(to_hsi_port(dev));
}

/**
 * hsi_unregister_port - Unregister an HSI port
 * @port: The HSI port to unregister
 */
void hsi_port_unregister_clients(struct hsi_port *port)
{
	device_for_each_child(&port->device, NULL, hsi_remove_client);
}
EXPORT_SYMBOL_GPL(hsi_port_unregister_clients);

/**
 * hsi_unregister_controller - Unregister an HSI controller
 * @hsi: The HSI controller to register
 */
void hsi_unregister_controller(struct hsi_controller *hsi)
{
	device_for_each_child(&hsi->device, NULL, hsi_remove_port);
	device_unregister(&hsi->device);
}
EXPORT_SYMBOL_GPL(hsi_unregister_controller);

/**
 * hsi_register_controller - Register an HSI controller and its ports
 * @hsi: The HSI controller to register
 *
 * Returns -errno on failure, 0 on success.
 */
int hsi_register_controller(struct hsi_controller *hsi)
{
	unsigned int i;
	int err;

	err = device_add(&hsi->device);
	if (err < 0)
		return err;
	for (i = 0; i < hsi->num_ports; i++) {
		hsi->port[i]->device.parent = &hsi->device;
		err = device_add(&hsi->port[i]->device);
		if (err < 0)
			goto out;
	}
	/* Populate HSI bus with HSI clients */
	hsi_scan_board_info(hsi);

	return 0;
out:
	while (i-- > 0)
		device_del(&hsi->port[i]->device);
	device_del(&hsi->device);

	return err;
}
EXPORT_SYMBOL_GPL(hsi_register_controller);

/**
 * hsi_register_client_driver - Register an HSI client to the HSI bus
 * @drv: HSI client driver to register
 *
 * Returns -errno on failure, 0 on success.
 */
int hsi_register_client_driver(struct hsi_client_driver *drv)
{
	drv->driver.bus = &hsi_bus_type;

	return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(hsi_register_client_driver);

static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused)
{
	return 0;
}

static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)
{
	return 0;
}

/**
 * hsi_put_controller - Free an HSI controller
 *
 * @hsi: Pointer to the HSI controller to freed
 *
 * HSI controller drivers should only use this function if they need
 * to free their allocated hsi_controller structures before a successful
 * call to hsi_register_controller. Other use is not allowed.
 */
void hsi_put_controller(struct hsi_controller *hsi)
{
	unsigned int i;

	if (!hsi)
		return;

	for (i = 0; i < hsi->num_ports; i++)
		if (hsi->port && hsi->port[i])
			put_device(&hsi->port[i]->device);
	put_device(&hsi->device);
}
EXPORT_SYMBOL_GPL(hsi_put_controller);

/**
 * hsi_alloc_controller - Allocate an HSI controller and its ports
 * @n_ports: Number of ports on the HSI controller
 * @flags: Kernel allocation flags
 *
 * Return NULL on failure or a pointer to an hsi_controller on success.
 */
struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags)
{
	struct hsi_controller	*hsi;
	struct hsi_port		**port;
	unsigned int		i;

	if (!n_ports)
		return NULL;

	hsi = kzalloc(sizeof(*hsi), flags);
	if (!hsi)
		return NULL;
	port = kzalloc(sizeof(*port)*n_ports, flags);
	if (!port) {
		kfree(hsi);
		return NULL;
	}
	hsi->num_ports = n_ports;
	hsi->port = port;
	hsi->device.release = hsi_controller_release;
	device_initialize(&hsi->device);

	for (i = 0; i < n_ports; i++) {
		port[i] = kzalloc(sizeof(**port), flags);
		if (port[i] == NULL)
			goto out;
		port[i]->num = i;
		port[i]->async = hsi_dummy_msg;
		port[i]->setup = hsi_dummy_cl;
		port[i]->flush = hsi_dummy_cl;
		port[i]->start_tx = hsi_dummy_cl;
		port[i]->stop_tx = hsi_dummy_cl;
		port[i]->release = hsi_dummy_cl;
		mutex_init(&port[i]->lock);
		ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head);
		dev_set_name(&port[i]->device, "port%d", i);
		hsi->port[i]->device.release = hsi_port_release;
		device_initialize(&hsi->port[i]->device);
	}

	return hsi;
out:
	hsi_put_controller(hsi);

	return NULL;
}
EXPORT_SYMBOL_GPL(hsi_alloc_controller);

/**
 * hsi_free_msg - Free an HSI message
 * @msg: Pointer to the HSI message
 *
 * Client is responsible to free the buffers pointed by the scatterlists.
 */
void hsi_free_msg(struct hsi_msg *msg)
{
	if (!msg)
		return;
	sg_free_table(&msg->sgt);
	kfree(msg);
}
EXPORT_SYMBOL_GPL(hsi_free_msg);

/**
 * hsi_alloc_msg - Allocate an HSI message
 * @nents: Number of memory entries
 * @flags: Kernel allocation flags
 *
 * nents can be 0. This mainly makes sense for read transfer.
 * In that case, HSI drivers will call the complete callback when
 * there is data to be read without consuming it.
 *
 * Return NULL on failure or a pointer to an hsi_msg on success.
 */
struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags)
{
	struct hsi_msg *msg;
	int err;

	msg = kzalloc(sizeof(*msg), flags);
	if (!msg)
		return NULL;

	if (!nents)
		return msg;

	err = sg_alloc_table(&msg->sgt, nents, flags);
	if (unlikely(err)) {
		kfree(msg);
		msg = NULL;
	}

	return msg;
}
EXPORT_SYMBOL_GPL(hsi_alloc_msg);

/**
 * hsi_async - Submit an HSI transfer to the controller
 * @cl: HSI client sending the transfer
 * @msg: The HSI transfer passed to controller
 *
 * The HSI message must have the channel, ttype, complete and destructor
 * fields set beforehand. If nents > 0 then the client has to initialize
 * also the scatterlists to point to the buffers to write to or read from.
 *
 * HSI controllers relay on pre-allocated buffers from their clients and they
 * do not allocate buffers on their own.
 *
 * Once the HSI message transfer finishes, the HSI controller calls the
 * complete callback with the status and actual_len fields of the HSI message
 * updated. The complete callback can be called before returning from
 * hsi_async.
 *
 * Returns -errno on failure or 0 on success
 */
int hsi_async(struct hsi_client *cl, struct hsi_msg *msg)
{
	struct hsi_port *port = hsi_get_port(cl);

	if (!hsi_port_claimed(cl))
		return -EACCES;

	WARN_ON_ONCE(!msg->destructor || !msg->complete);
	msg->cl = cl;

	return port->async(msg);
}
EXPORT_SYMBOL_GPL(hsi_async);

/**
 * hsi_claim_port - Claim the HSI client's port
 * @cl: HSI client that wants to claim its port
 * @share: Flag to indicate if the client wants to share the port or not.
 *
 * Returns -errno on failure, 0 on success.
 */
int hsi_claim_port(struct hsi_client *cl, unsigned int share)
{
	struct hsi_port *port = hsi_get_port(cl);
	int err = 0;

	mutex_lock(&port->lock);
	if ((port->claimed) && (!port->shared || !share)) {
		err = -EBUSY;
		goto out;
	}
	if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) {
		err = -ENODEV;
		goto out;
	}
	port->claimed++;
	port->shared = !!share;
	cl->pclaimed = 1;
out:
	mutex_unlock(&port->lock);

	return err;
}
EXPORT_SYMBOL_GPL(hsi_claim_port);

/**
 * hsi_release_port - Release the HSI client's port
 * @cl: HSI client which previously claimed its port
 */
void hsi_release_port(struct hsi_client *cl)
{
	struct hsi_port *port = hsi_get_port(cl);

	mutex_lock(&port->lock);
	/* Allow HW driver to do some cleanup */
	port->release(cl);
	if (cl->pclaimed)
		port->claimed--;
	BUG_ON(port->claimed < 0);
	cl->pclaimed = 0;
	if (!port->claimed)
		port->shared = 0;
	module_put(to_hsi_controller(port->device.parent)->owner);
	mutex_unlock(&port->lock);
}
EXPORT_SYMBOL_GPL(hsi_release_port);

static int hsi_event_notifier_call(struct notifier_block *nb,
				unsigned long event, void *data __maybe_unused)
{
	struct hsi_client *cl = container_of(nb, struct hsi_client, nb);

	(*cl->ehandler)(cl, event);

	return 0;
}

/**
 * hsi_register_port_event - Register a client to receive port events
 * @cl: HSI client that wants to receive port events
 * @handler: Event handler callback
 *
 * Clients should register a callback to be able to receive
 * events from the ports. Registration should happen after
 * claiming the port.
 * The handler can be called in interrupt context.
 *
 * Returns -errno on error, or 0 on success.
 */
int hsi_register_port_event(struct hsi_client *cl,
			void (*handler)(struct hsi_client *, unsigned long))
{
	struct hsi_port *port = hsi_get_port(cl);

	if (!handler || cl->ehandler)
		return -EINVAL;
	if (!hsi_port_claimed(cl))
		return -EACCES;
	cl->ehandler = handler;
	cl->nb.notifier_call = hsi_event_notifier_call;

	return atomic_notifier_chain_register(&port->n_head, &cl->nb);
}
EXPORT_SYMBOL_GPL(hsi_register_port_event);

/**
 * hsi_unregister_port_event - Stop receiving port events for a client
 * @cl: HSI client that wants to stop receiving port events
 *
 * Clients should call this function before releasing their associated
 * port.
 *
 * Returns -errno on error, or 0 on success.
 */
int hsi_unregister_port_event(struct hsi_client *cl)
{
	struct hsi_port *port = hsi_get_port(cl);
	int err;

	WARN_ON(!hsi_port_claimed(cl));

	err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb);
	if (!err)
		cl->ehandler = NULL;

	return err;
}
EXPORT_SYMBOL_GPL(hsi_unregister_port_event);

/**
 * hsi_event - Notifies clients about port events
 * @port: Port where the event occurred
 * @event: The event type
 *
 * Clients should not be concerned about wake line behavior. However, due
 * to a race condition in HSI HW protocol, clients need to be notified
 * about wake line changes, so they can implement a workaround for it.
 *
 * Events:
 * HSI_EVENT_START_RX - Incoming wake line high
 * HSI_EVENT_STOP_RX - Incoming wake line down
 *
 * Returns -errno on error, or 0 on success.
 */
int hsi_event(struct hsi_port *port, unsigned long event)
{
	return atomic_notifier_call_chain(&port->n_head, event, NULL);
}
EXPORT_SYMBOL_GPL(hsi_event);

/**
 * hsi_get_channel_id_by_name - acquire channel id by channel name
 * @cl: HSI client, which uses the channel
 * @name: name the channel is known under
 *
 * Clients can call this function to get the hsi channel ids similar to
 * requesting IRQs or GPIOs by name. This function assumes the same
 * channel configuration is used for RX and TX.
 *
 * Returns -errno on error or channel id on success.
 */
int hsi_get_channel_id_by_name(struct hsi_client *cl, char *name)
{
	int i;

	if (!cl->rx_cfg.channels)
		return -ENOENT;

	for (i = 0; i < cl->rx_cfg.num_channels; i++)
		if (!strcmp(cl->rx_cfg.channels[i].name, name))
			return cl->rx_cfg.channels[i].id;

	return -ENXIO;
}
EXPORT_SYMBOL_GPL(hsi_get_channel_id_by_name);

static int __init hsi_init(void)
{
	return bus_register(&hsi_bus_type);
}
postcore_initcall(hsi_init);

static void __exit hsi_exit(void)
{
	bus_unregister(&hsi_bus_type);
}
module_exit(hsi_exit);

MODULE_AUTHOR("Carlos Chinea <carlos.chinea@nokia.com>");
MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework");
MODULE_LICENSE("GPL v2");
