/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 */

#include <linux/spmi.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_spmi.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>

struct of_spmi_dev_info {
	struct spmi_controller *ctrl;
	struct spmi_boardinfo b_info;
};

struct of_spmi_res_info {
	struct device_node *node;
	uint32_t num_reg;
	uint32_t num_irq;
};

/*
 * Initialize r_info structure for safe usage
 */
static inline void of_spmi_init_resource(struct of_spmi_res_info *r_info,
					 struct device_node *node)
{
	r_info->node = node;
	r_info->num_reg = 0;
	r_info->num_irq = 0;
}

/*
 * Calculate the number of resources to allocate
 *
 * The caller is responsible for initializing the of_spmi_res_info structure.
 */
static void of_spmi_sum_resources(struct of_spmi_res_info *r_info,
				  bool has_reg)
{
	struct of_irq oirq;
	uint64_t size;
	uint32_t flags;
	int i = 0;

	while (of_irq_map_one(r_info->node, i, &oirq) == 0)
		i++;

	r_info->num_irq += i;

	if (!has_reg)
		return;

	/*
	 * We can't use of_address_to_resource here since it includes
	 * address translation; and address translation assumes that no
	 * parent buses have a size-cell of 0. But SPMI does have a
	 * size-cell of 0.
	 */
	i = 0;
	while (of_get_address(r_info->node, i, &size, &flags) != NULL)
		i++;

	r_info->num_reg += i;
}

/*
 * Allocate dev_node array for spmi_device - used with spmi-dev-container
 */
static inline int of_spmi_alloc_devnode_store(struct of_spmi_dev_info *d_info,
					      uint32_t num_dev_node)
{
	d_info->b_info.num_dev_node = num_dev_node;
	d_info->b_info.dev_node = kzalloc(sizeof(struct spmi_resource) *
						num_dev_node, GFP_KERNEL);
	if (!d_info->b_info.dev_node)
		return -ENOMEM;

	return 0;
}

/*
 * Allocate enough memory to handle the resources associated with the
 * primary node.
 */
static int of_spmi_allocate_node_resources(struct of_spmi_dev_info *d_info,
					   struct of_spmi_res_info *r_info)
{
	uint32_t num_irq = r_info->num_irq, num_reg = r_info->num_reg;
	struct resource *res = NULL;

	if (num_irq || num_reg) {
		res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
		if (!res)
			return -ENOMEM;
	}
	d_info->b_info.res.num_resources = num_reg + num_irq;
	d_info->b_info.res.resource = res;

	return 0;
}

/*
 * Allocate enough memory to handle the resources associated with the
 * spmi-dev-container nodes.
 */
static int of_spmi_allocate_devnode_resources(struct of_spmi_dev_info *d_info,
					      struct of_spmi_res_info *r_info,
					      uint32_t idx)
{
	uint32_t num_irq = r_info->num_irq, num_reg = r_info->num_reg;
	struct resource *res = NULL;

	if (num_irq || num_reg) {
		res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
		if (!res)
			return -ENOMEM;
	}
	d_info->b_info.dev_node[idx].num_resources = num_reg + num_irq;
	d_info->b_info.dev_node[idx].resource = res;

	return 0;
}

/*
 * free node resources - used with primary node
 */
static void of_spmi_free_node_resources(struct of_spmi_dev_info *d_info)
{
	kfree(d_info->b_info.res.resource);
}

/*
 * free devnode resources - used with spmi-dev-container
 */
static void of_spmi_free_devnode_resources(struct of_spmi_dev_info *d_info)
{
	int i;

	for (i = 0; i < d_info->b_info.num_dev_node; i++)
		kfree(d_info->b_info.dev_node[i].resource);

	kfree(d_info->b_info.dev_node);
}

static void of_spmi_populate_resources(struct of_spmi_dev_info *d_info,
				       struct of_spmi_res_info *r_info,
				       struct resource *res)

{
	uint32_t num_irq = r_info->num_irq, num_reg = r_info->num_reg;
	int i;
	const  __be32 *addrp;
	uint64_t size;
	uint32_t flags;

	if ((num_irq || num_reg) && (res != NULL)) {
		for (i = 0; i < num_reg; i++, res++) {
			/* Addresses are always 16 bits */
			addrp = of_get_address(r_info->node, i, &size, &flags);
			BUG_ON(!addrp);
			res->start = be32_to_cpup(addrp);
			res->end = res->start + size - 1;
			res->flags = flags;
			of_property_read_string_index(r_info->node, "reg-names",
								i, &res->name);
		}
		WARN_ON(of_irq_to_resource_table(r_info->node, res, num_irq) !=
								num_irq);
	}
}

/*
 * Gather primary node resources and populate.
 */
static void of_spmi_populate_node_resources(struct of_spmi_dev_info *d_info,
					    struct of_spmi_res_info *r_info)

{
	struct resource *res;

	res = d_info->b_info.res.resource;
	d_info->b_info.res.of_node = r_info->node;
	of_property_read_string(r_info->node, "label",
				&d_info->b_info.res.label);
	of_spmi_populate_resources(d_info, r_info, res);
}

/*
 * Gather node devnode resources and populate - used with spmi-dev-container.
 */
static void of_spmi_populate_devnode_resources(struct of_spmi_dev_info *d_info,
					       struct of_spmi_res_info *r_info,
					       int idx)

{
	struct resource *res;

	res = d_info->b_info.dev_node[idx].resource;
	d_info->b_info.dev_node[idx].of_node = r_info->node;
	of_property_read_string(r_info->node, "label",
				&d_info->b_info.dev_node[idx].label);
	of_spmi_populate_resources(d_info, r_info, res);
}

/*
 * create a single spmi_device
 */
static int of_spmi_create_device(struct of_spmi_dev_info *d_info,
				 struct device_node *node)
{
	struct spmi_controller *ctrl = d_info->ctrl;
	struct spmi_boardinfo *b_info = &d_info->b_info;
	void *result;
	int rc;

	rc = of_modalias_node(node, b_info->name, sizeof(b_info->name));
	if (rc < 0) {
		dev_err(&ctrl->dev, "of_spmi modalias failure on %s\n",
				node->full_name);
		return rc;
	}

	b_info->of_node = of_node_get(node);
	result = spmi_new_device(ctrl, b_info);

	if (result == NULL) {
		dev_err(&ctrl->dev, "of_spmi: Failure registering %s\n",
				node->full_name);
		of_node_put(node);
		return -ENODEV;
	}

	return 0;
}

/*
 * Walks all children of a node containing the spmi-dev-container
 * binding. This special type of spmi_device can include resources
 * from more than one device node.
 */
static void of_spmi_walk_dev_container(struct of_spmi_dev_info *d_info,
					struct device_node *container)
{
	struct of_spmi_res_info r_info = {};
	struct spmi_controller *ctrl = d_info->ctrl;
	struct device_node *node;
	int rc, i, num_dev_node = 0;

	if (!of_device_is_available(container))
		return;

	/*
	 * Count the total number of device_nodes so we know how much
	 * device_store to allocate.
	 */
	for_each_child_of_node(container, node) {
		if (!of_device_is_available(node))
			continue;
		num_dev_node++;
	}

	rc = of_spmi_alloc_devnode_store(d_info, num_dev_node);
	if (rc) {
		dev_err(&ctrl->dev, "%s: unable to allocate devnode resources\n",
								__func__);
		return;
	}

	i = 0;
	for_each_child_of_node(container, node) {
		if (!of_device_is_available(node))
			continue;
		of_spmi_init_resource(&r_info, node);
		of_spmi_sum_resources(&r_info, true);
		rc = of_spmi_allocate_devnode_resources(d_info, &r_info, i);
		if (rc) {
			dev_err(&ctrl->dev, "%s: unable to allocate"
					" resources\n", __func__);
			of_spmi_free_devnode_resources(d_info);
			return;
		}
		of_spmi_populate_devnode_resources(d_info, &r_info, i);
		i++;
	}

	of_spmi_init_resource(&r_info, container);
	of_spmi_sum_resources(&r_info, true);

	rc = of_spmi_allocate_node_resources(d_info, &r_info);
	if (rc) {
		dev_err(&ctrl->dev, "%s: unable to allocate resources\n",
								  __func__);
		of_spmi_free_node_resources(d_info);
	}

	of_spmi_populate_node_resources(d_info, &r_info);


	rc = of_spmi_create_device(d_info, container);
	if (rc) {
		dev_err(&ctrl->dev, "%s: unable to create device for"
				" node %s\n", __func__, container->full_name);
		of_spmi_free_devnode_resources(d_info);
		return;
	}
}

/*
 * Walks all children of a node containing the spmi-slave-container
 * binding. This indicates that all spmi_devices created from this
 * point all share the same slave_id.
 */
static void of_spmi_walk_slave_container(struct of_spmi_dev_info *d_info,
					 struct device_node *container)
{
	struct spmi_controller *ctrl = d_info->ctrl;
	struct device_node *node;
	int rc;

	for_each_child_of_node(container, node) {
		struct of_spmi_res_info r_info;

		if (!of_device_is_available(node))
			continue;

		/**
		 * Check to see if this node contains children which
		 * should be all created as the same spmi_device.
		 */
		if (of_get_property(node, "spmi-dev-container", NULL)) {
			of_spmi_walk_dev_container(d_info, node);
			continue;
		}

		of_spmi_init_resource(&r_info, node);
		of_spmi_sum_resources(&r_info, true);

		rc = of_spmi_allocate_node_resources(d_info, &r_info);
		if (rc) {
			dev_err(&ctrl->dev, "%s: unable to allocate"
						" resources\n", __func__);
			goto slave_err;
		}

		of_spmi_populate_node_resources(d_info, &r_info);

		rc = of_spmi_create_device(d_info, node);
		if (rc) {
			dev_err(&ctrl->dev, "%s: unable to create device for"
				     " node %s\n", __func__, node->full_name);
			goto slave_err;
		}
	}
	return;

slave_err:
	of_spmi_free_node_resources(d_info);
}

int of_spmi_register_devices(struct spmi_controller *ctrl)
{
	struct device_node *node = ctrl->dev.of_node;

	/* Only register child devices if the ctrl has a node pointer set */
	if (!node)
		return -ENODEV;

	if (of_get_property(node, "spmi-slave-container", NULL)) {
		dev_err(&ctrl->dev, "%s: structural error: spmi-slave-container"
			" is prohibited at the root level\n", __func__);
		return -EINVAL;
	} else if (of_get_property(node, "spmi-dev-container", NULL)) {
		dev_err(&ctrl->dev, "%s: structural error: spmi-dev-container"
			" is prohibited at the root level\n", __func__);
		return -EINVAL;
	}

	/**
	 * Make best effort to launch as many nodes as possible. If there are
	 * syntax errors, we will simply ignore that subtree and keep going.
	 */
	for_each_child_of_node(ctrl->dev.of_node, node) {
		struct of_spmi_dev_info d_info = {};
		const __be32 *slave_id;
		int len, rc, have_dev_container = 0;

		slave_id = of_get_property(node, "reg", &len);
		if (!slave_id) {
			dev_err(&ctrl->dev, "%s: invalid sid "
					"on %s\n", __func__, node->full_name);
			continue;
		}

		d_info.b_info.slave_id = be32_to_cpup(slave_id);
		d_info.ctrl = ctrl;

		if (of_get_property(node, "spmi-dev-container", NULL))
			have_dev_container = 1;
		if (of_get_property(node, "spmi-slave-container", NULL)) {
			if (have_dev_container)
				of_spmi_walk_dev_container(&d_info, node);
			else
				of_spmi_walk_slave_container(&d_info, node);
		} else {
			struct of_spmi_res_info r_info;

			/**
			 * A dev container at the second level without a slave
			 * container is considered an error.
			 */
			if (have_dev_container) {
				dev_err(&ctrl->dev, "%s: structural error,"
				     " node %s has spmi-dev-container without"
				     " specifying spmi-slave-container\n",
				     __func__, node->full_name);
				continue;
			}

			if (!of_device_is_available(node))
				continue;

			of_spmi_init_resource(&r_info, node);
			of_spmi_sum_resources(&r_info, false);
			rc = of_spmi_allocate_node_resources(&d_info, &r_info);
			if (rc) {
				dev_err(&ctrl->dev, "%s: unable to allocate"
						" resources\n", __func__);
				of_spmi_free_node_resources(&d_info);
				continue;
			}

			of_spmi_populate_node_resources(&d_info, &r_info);

			rc = of_spmi_create_device(&d_info, node);
			if (rc) {
				dev_err(&ctrl->dev, "%s: unable to create"
						" device\n", __func__);
				of_spmi_free_node_resources(&d_info);
				continue;
			}
		}
	}

	return 0;
}
EXPORT_SYMBOL(of_spmi_register_devices);

MODULE_LICENSE("GPL v2");
