/*
 * Copyright (C) 2015 Texas Instruments
 * Author: Jyri Sarha <jsarha@ti.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.
 *
 */

/*
 * To support the old "ti,tilcdc,slave" binding the binding has to be
 * transformed to the new external encoder binding.
 */

#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_fdt.h>
#include <linux/slab.h>
#include <linux/list.h>

#include "tilcdc_slave_compat.h"

struct kfree_table {
	int total;
	int num;
	void **table;
};

static int __init kfree_table_init(struct kfree_table *kft)
{
	kft->total = 32;
	kft->num = 0;
	kft->table = kmalloc(kft->total * sizeof(*kft->table),
			     GFP_KERNEL);
	if (!kft->table)
		return -ENOMEM;

	return 0;
}

static int __init kfree_table_add(struct kfree_table *kft, void *p)
{
	if (kft->num == kft->total) {
		void **old = kft->table;

		kft->total *= 2;
		kft->table = krealloc(old, kft->total * sizeof(*kft->table),
				      GFP_KERNEL);
		if (!kft->table) {
			kft->table = old;
			kfree(p);
			return -ENOMEM;
		}
	}
	kft->table[kft->num++] = p;
	return 0;
}

static void __init kfree_table_free(struct kfree_table *kft)
{
	int i;

	for (i = 0; i < kft->num; i++)
		kfree(kft->table[i]);

	kfree(kft->table);
}

static
struct property * __init tilcdc_prop_dup(const struct property *prop,
					 struct kfree_table *kft)
{
	struct property *nprop;

	nprop = kzalloc(sizeof(*nprop), GFP_KERNEL);
	if (!nprop || kfree_table_add(kft, nprop))
		return NULL;

	nprop->name = kstrdup(prop->name, GFP_KERNEL);
	if (!nprop->name || kfree_table_add(kft, nprop->name))
		return NULL;

	nprop->value = kmemdup(prop->value, prop->length, GFP_KERNEL);
	if (!nprop->value || kfree_table_add(kft, nprop->value))
		return NULL;

	nprop->length = prop->length;

	return nprop;
}

static void __init tilcdc_copy_props(struct device_node *from,
				     struct device_node *to,
				     const char * const props[],
				     struct kfree_table *kft)
{
	struct property *prop;
	int i;

	for (i = 0; props[i]; i++) {
		prop = of_find_property(from, props[i], NULL);
		if (!prop)
			continue;

		prop = tilcdc_prop_dup(prop, kft);
		if (!prop)
			continue;

		prop->next = to->properties;
		to->properties = prop;
	}
}

static int __init tilcdc_prop_str_update(struct property *prop,
					  const char *str,
					  struct kfree_table *kft)
{
	prop->value = kstrdup(str, GFP_KERNEL);
	if (kfree_table_add(kft, prop->value) || !prop->value)
		return -ENOMEM;
	prop->length = strlen(str)+1;
	return 0;
}

static void __init tilcdc_node_disable(struct device_node *node)
{
	struct property *prop;

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

	prop->name = "status";
	prop->value = "disabled";
	prop->length = strlen((char *)prop->value)+1;

	of_update_property(node, prop);
}

static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft)
{
	const int size = __dtb_tilcdc_slave_compat_end -
		__dtb_tilcdc_slave_compat_begin;
	static void *overlay_data;
	struct device_node *overlay;
	int ret;

	if (!size) {
		pr_warn("%s: No overlay data\n", __func__);
		return NULL;
	}

	overlay_data = kmemdup(__dtb_tilcdc_slave_compat_begin,
			       size, GFP_KERNEL);
	if (!overlay_data || kfree_table_add(kft, overlay_data))
		return NULL;

	of_fdt_unflatten_tree(overlay_data, NULL, &overlay);
	if (!overlay) {
		pr_warn("%s: Unfattening overlay tree failed\n", __func__);
		return NULL;
	}

	ret = of_resolve_phandles(overlay);
	if (ret) {
		pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret);
		return NULL;
	}

	return overlay;
}

static const struct of_device_id tilcdc_slave_of_match[] __initconst = {
	{ .compatible = "ti,tilcdc,slave", },
	{},
};

static const struct of_device_id tilcdc_of_match[] __initconst = {
	{ .compatible = "ti,am33xx-tilcdc", },
	{},
};

static const struct of_device_id tilcdc_tda998x_of_match[] __initconst = {
	{ .compatible = "nxp,tda998x", },
	{},
};

static const char * const tilcdc_slave_props[] __initconst = {
	"pinctrl-names",
	"pinctrl-0",
	"pinctrl-1",
	NULL
};

static void __init tilcdc_convert_slave_node(void)
{
	struct device_node *slave = NULL, *lcdc = NULL;
	struct device_node *i2c = NULL, *fragment = NULL;
	struct device_node *overlay, *encoder;
	struct property *prop;
	/* For all memory needed for the overlay tree. This memory can
	   be freed after the overlay has been applied. */
	struct kfree_table kft;
	int ret;

	if (kfree_table_init(&kft))
		return;

	lcdc = of_find_matching_node(NULL, tilcdc_of_match);
	slave = of_find_matching_node(NULL, tilcdc_slave_of_match);

	if (!slave || !of_device_is_available(lcdc))
		goto out;

	i2c = of_parse_phandle(slave, "i2c", 0);
	if (!i2c) {
		pr_err("%s: Can't find i2c node trough phandle\n", __func__);
		goto out;
	}

	overlay = tilcdc_get_overlay(&kft);
	if (!overlay)
		goto out;

	encoder = of_find_matching_node(overlay, tilcdc_tda998x_of_match);
	if (!encoder) {
		pr_err("%s: Failed to find tda998x node\n", __func__);
		goto out;
	}

	tilcdc_copy_props(slave, encoder, tilcdc_slave_props, &kft);

	for_each_child_of_node(overlay, fragment) {
		prop = of_find_property(fragment, "target-path", NULL);
		if (!prop)
			continue;
		if (!strncmp("i2c", (char *)prop->value, prop->length))
			if (tilcdc_prop_str_update(prop, i2c->full_name, &kft))
				goto out;
		if (!strncmp("lcdc", (char *)prop->value, prop->length))
			if (tilcdc_prop_str_update(prop, lcdc->full_name, &kft))
				goto out;
	}

	tilcdc_node_disable(slave);

	ret = of_overlay_create(overlay);
	if (ret)
		pr_err("%s: Creating overlay failed: %d\n", __func__, ret);
	else
		pr_info("%s: ti,tilcdc,slave node successfully converted\n",
			__func__);
out:
	kfree_table_free(&kft);
	of_node_put(i2c);
	of_node_put(slave);
	of_node_put(lcdc);
	of_node_put(fragment);
}

static int __init tilcdc_slave_compat_init(void)
{
	tilcdc_convert_slave_node();
	return 0;
}

subsys_initcall(tilcdc_slave_compat_init);
