// SPDX-License-Identifier: GPL-2.0-only
/*
 * OMAP Display Subsystem Base
 *
 * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
 */

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>

#include "dss.h"
#include "omapdss.h"

struct dispc_device *dispc_get_dispc(struct dss_device *dss)
{
	return dss->dispc;
}

/* -----------------------------------------------------------------------------
 * OMAP DSS Devices Handling
 */

static LIST_HEAD(omapdss_devices_list);
static DEFINE_MUTEX(omapdss_devices_lock);

void omapdss_device_register(struct omap_dss_device *dssdev)
{
	mutex_lock(&omapdss_devices_lock);
	list_add_tail(&dssdev->list, &omapdss_devices_list);
	mutex_unlock(&omapdss_devices_lock);
}

void omapdss_device_unregister(struct omap_dss_device *dssdev)
{
	mutex_lock(&omapdss_devices_lock);
	list_del(&dssdev->list);
	mutex_unlock(&omapdss_devices_lock);
}

static bool omapdss_device_is_registered(struct device_node *node)
{
	struct omap_dss_device *dssdev;
	bool found = false;

	mutex_lock(&omapdss_devices_lock);

	list_for_each_entry(dssdev, &omapdss_devices_list, list) {
		if (dssdev->dev->of_node == node) {
			found = true;
			break;
		}
	}

	mutex_unlock(&omapdss_devices_lock);
	return found;
}

struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev)
{
	if (get_device(dssdev->dev) == NULL)
		return NULL;

	return dssdev;
}

void omapdss_device_put(struct omap_dss_device *dssdev)
{
	put_device(dssdev->dev);
}

struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node)
{
	struct omap_dss_device *dssdev;

	list_for_each_entry(dssdev, &omapdss_devices_list, list) {
		if (dssdev->dev->of_node == node)
			return omapdss_device_get(dssdev);
	}

	return NULL;
}

/*
 * Search for the next output device starting at @from. Release the reference to
 * the @from device, and acquire a reference to the returned device if found.
 */
struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device *from)
{
	struct omap_dss_device *dssdev;
	struct list_head *list;

	mutex_lock(&omapdss_devices_lock);

	if (list_empty(&omapdss_devices_list)) {
		dssdev = NULL;
		goto done;
	}

	/*
	 * Start from the from entry if given or from omapdss_devices_list
	 * otherwise.
	 */
	list = from ? &from->list : &omapdss_devices_list;

	list_for_each_entry(dssdev, list, list) {
		/*
		 * Stop if we reach the omapdss_devices_list, that's the end of
		 * the list.
		 */
		if (&dssdev->list == &omapdss_devices_list) {
			dssdev = NULL;
			goto done;
		}

		if (dssdev->id && dssdev->bridge)
			goto done;
	}

	dssdev = NULL;

done:
	if (from)
		omapdss_device_put(from);
	if (dssdev)
		omapdss_device_get(dssdev);

	mutex_unlock(&omapdss_devices_lock);
	return dssdev;
}

static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
{
	return dssdev->dss;
}

int omapdss_device_connect(struct dss_device *dss,
			   struct omap_dss_device *dst)
{
	dev_dbg(&dss->pdev->dev, "connect(%s)\n",
		dst ? dev_name(dst->dev) : "NULL");

	if (!dst)
		return -EINVAL;

	if (omapdss_device_is_connected(dst))
		return -EBUSY;

	dst->dss = dss;

	return 0;
}

void omapdss_device_disconnect(struct dss_device *dss,
			       struct omap_dss_device *dst)
{
	dev_dbg(&dss->pdev->dev, "disconnect(%s)\n",
		dst ? dev_name(dst->dev) : "NULL");

	if (WARN_ON(!dst))
		return;

	if (!dst->id && !omapdss_device_is_connected(dst)) {
		WARN_ON(1);
		return;
	}

	dst->dss = NULL;
}

/* -----------------------------------------------------------------------------
 * Components Handling
 */

static struct list_head omapdss_comp_list;

struct omapdss_comp_node {
	struct list_head list;
	struct device_node *node;
	bool dss_core_component;
	const char *compat;
};

static bool omapdss_list_contains(const struct device_node *node)
{
	struct omapdss_comp_node *comp;

	list_for_each_entry(comp, &omapdss_comp_list, list) {
		if (comp->node == node)
			return true;
	}

	return false;
}

static void omapdss_walk_device(struct device *dev, struct device_node *node,
				bool dss_core)
{
	struct omapdss_comp_node *comp;
	struct device_node *n;
	const char *compat;
	int ret;

	ret = of_property_read_string(node, "compatible", &compat);
	if (ret < 0)
		return;

	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
	if (comp) {
		comp->node = node;
		comp->dss_core_component = dss_core;
		comp->compat = compat;
		list_add(&comp->list, &omapdss_comp_list);
	}

	/*
	 * of_graph_get_remote_port_parent() prints an error if there is no
	 * port/ports node. To avoid that, check first that there's the node.
	 */
	n = of_get_child_by_name(node, "ports");
	if (!n)
		n = of_get_child_by_name(node, "port");
	if (!n)
		return;

	of_node_put(n);

	for_each_endpoint_of_node(node, n) {
		struct device_node *pn = of_graph_get_remote_port_parent(n);

		if (!pn)
			continue;

		if (!of_device_is_available(pn) || omapdss_list_contains(pn)) {
			of_node_put(pn);
			continue;
		}

		omapdss_walk_device(dev, pn, false);
	}
}

void omapdss_gather_components(struct device *dev)
{
	struct device_node *child;

	INIT_LIST_HEAD(&omapdss_comp_list);

	omapdss_walk_device(dev, dev->of_node, true);

	for_each_available_child_of_node(dev->of_node, child)
		omapdss_walk_device(dev, child, true);
}

static bool omapdss_component_is_loaded(struct omapdss_comp_node *comp)
{
	if (comp->dss_core_component)
		return true;
	if (!strstarts(comp->compat, "omapdss,"))
		return true;
	if (omapdss_device_is_registered(comp->node))
		return true;

	return false;
}

bool omapdss_stack_is_ready(void)
{
	struct omapdss_comp_node *comp;

	list_for_each_entry(comp, &omapdss_comp_list, list) {
		if (!omapdss_component_is_loaded(comp))
			return false;
	}

	return true;
}
