// SPDX-License-Identifier: GPL-2.0 or MIT
/*
 * Copyright 2018 Noralf Trønnes
 */

#include <linux/export.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/seq_file.h>

#include <drm/drm_client.h>
#include <drm/drm_client_event.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_print.h>

#include "drm_internal.h"

/**
 * drm_client_dev_unregister - Unregister clients
 * @dev: DRM device
 *
 * This function releases all clients by calling each client's
 * &drm_client_funcs.unregister callback. The callback function
 * is responsibe for releaseing all resources including the client
 * itself.
 *
 * The helper drm_dev_unregister() calls this function. Drivers
 * that use it don't need to call this function themselves.
 */
void drm_client_dev_unregister(struct drm_device *dev)
{
	struct drm_client_dev *client, *tmp;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return;

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry_safe(client, tmp, &dev->clientlist, list) {
		list_del(&client->list);
		if (client->funcs && client->funcs->unregister) {
			client->funcs->unregister(client);
		} else {
			drm_client_release(client);
			kfree(client);
		}
	}
	mutex_unlock(&dev->clientlist_mutex);
}
EXPORT_SYMBOL(drm_client_dev_unregister);

static void drm_client_hotplug(struct drm_client_dev *client)
{
	struct drm_device *dev = client->dev;
	int ret;

	if (!client->funcs || !client->funcs->hotplug)
		return;

	if (client->hotplug_failed)
		return;

	if (client->suspended) {
		client->hotplug_pending = true;
		return;
	}

	client->hotplug_pending = false;
	ret = client->funcs->hotplug(client);
	drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
	if (ret)
		client->hotplug_failed = true;
}

/**
 * drm_client_dev_hotplug - Send hotplug event to clients
 * @dev: DRM device
 *
 * This function calls the &drm_client_funcs.hotplug callback on the attached clients.
 *
 * drm_kms_helper_hotplug_event() calls this function, so drivers that use it
 * don't need to call this function themselves.
 */
void drm_client_dev_hotplug(struct drm_device *dev)
{
	struct drm_client_dev *client;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return;

	if (!dev->mode_config.num_connector) {
		drm_dbg_kms(dev, "No connectors found, will not send hotplug events!\n");
		return;
	}

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry(client, &dev->clientlist, list)
		drm_client_hotplug(client);
	mutex_unlock(&dev->clientlist_mutex);
}
EXPORT_SYMBOL(drm_client_dev_hotplug);

void drm_client_dev_restore(struct drm_device *dev)
{
	struct drm_client_dev *client;
	int ret;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return;

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry(client, &dev->clientlist, list) {
		if (!client->funcs || !client->funcs->restore)
			continue;

		ret = client->funcs->restore(client);
		drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
		if (!ret) /* The first one to return zero gets the privilege to restore */
			break;
	}
	mutex_unlock(&dev->clientlist_mutex);
}

static int drm_client_suspend(struct drm_client_dev *client, bool holds_console_lock)
{
	struct drm_device *dev = client->dev;
	int ret = 0;

	if (drm_WARN_ON_ONCE(dev, client->suspended))
		return 0;

	if (client->funcs && client->funcs->suspend)
		ret = client->funcs->suspend(client, holds_console_lock);
	drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);

	client->suspended = true;

	return ret;
}

void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock)
{
	struct drm_client_dev *client;

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry(client, &dev->clientlist, list) {
		if (!client->suspended)
			drm_client_suspend(client, holds_console_lock);
	}
	mutex_unlock(&dev->clientlist_mutex);
}
EXPORT_SYMBOL(drm_client_dev_suspend);

static int drm_client_resume(struct drm_client_dev *client, bool holds_console_lock)
{
	struct drm_device *dev = client->dev;
	int ret = 0;

	if (drm_WARN_ON_ONCE(dev, !client->suspended))
		return 0;

	if (client->funcs && client->funcs->resume)
		ret = client->funcs->resume(client, holds_console_lock);
	drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);

	client->suspended = false;

	if (client->hotplug_pending)
		drm_client_hotplug(client);

	return ret;
}

void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock)
{
	struct drm_client_dev *client;

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry(client, &dev->clientlist, list) {
		if  (client->suspended)
			drm_client_resume(client, holds_console_lock);
	}
	mutex_unlock(&dev->clientlist_mutex);
}
EXPORT_SYMBOL(drm_client_dev_resume);

#ifdef CONFIG_DEBUG_FS
static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data)
{
	struct drm_debugfs_entry *entry = m->private;
	struct drm_device *dev = entry->dev;
	struct drm_printer p = drm_seq_file_printer(m);
	struct drm_client_dev *client;

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry(client, &dev->clientlist, list)
		drm_printf(&p, "%s\n", client->name);
	mutex_unlock(&dev->clientlist_mutex);

	return 0;
}

static const struct drm_debugfs_info drm_client_debugfs_list[] = {
	{ "internal_clients", drm_client_debugfs_internal_clients, 0 },
};

void drm_client_debugfs_init(struct drm_device *dev)
{
	drm_debugfs_add_files(dev, drm_client_debugfs_list,
			      ARRAY_SIZE(drm_client_debugfs_list));
}
#endif
