/*
 * 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;
	}

	of_node_set_flag(overlay, OF_DETACHED);
	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);
