// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Red Hat
 * Copyright (c) 2015 - 2020 DisplayLink (UK) Ltd.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License v2. See the file COPYING in the main directory of this archive for
 * more details.
 */

#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_probe_helper.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/usb.h>

#include "evdi_drv.h"
#include <uapi/drm/evdi_drm.h>
#include "evdi_debug.h"
#include "evdi_cursor.h"

MODULE_AUTHOR("DisplayLink (UK) Ltd.");
MODULE_DESCRIPTION("Extensible Virtual Display Interface");
MODULE_LICENSE("GPL");

#define EVDI_DEVICE_COUNT_MAX 16
#define MAX_EVDI_USB_ADDR 10

static struct evdi_context {
	struct device *root_dev;
	unsigned int dev_count;
	struct platform_device *devices[EVDI_DEVICE_COUNT_MAX];
	struct notifier_block usb_notifier;
	struct mutex lock;
} evdi_context;

#define evdi_context_lock(ctx) \
		mutex_lock(&ctx->lock)

#define evdi_context_unlock(ctx) \
		mutex_unlock(&ctx->lock)


struct evdi_platform_device_data {
	struct drm_device *drm_dev;
	struct device *parent;
	bool symlinked;
};

static void
evdi_platform_device_unlink_if_linked_with(struct platform_device *pdev,
					   struct device *parent);

static int evdi_platform_drv_usb(__always_unused struct notifier_block *nb,
		unsigned long action,
		void *data)
{
	struct usb_device *usb_dev = (struct usb_device *)(data);
	struct platform_device *pdev;
	int i = 0;

	if (!usb_dev)
		return 0;
	if (action != BUS_NOTIFY_DEL_DEVICE)
		return 0;

	evdi_context_lock((&evdi_context));
	for (i = 0; i < EVDI_DEVICE_COUNT_MAX; ++i) {
		pdev = evdi_context.devices[i];
		if (!pdev)
			continue;
		evdi_platform_device_unlink_if_linked_with(pdev, &usb_dev->dev);
		if (pdev->dev.parent == &usb_dev->dev) {
			EVDI_INFO("Parent USB removed. Removing evdi.%d\n", i);
			platform_device_unregister(pdev);
			evdi_context.dev_count--;
			evdi_context.devices[i] = NULL;
		}
	}
	evdi_context_unlock((&evdi_context));

	return 0;
}

static int evdi_context_get_free_idx(struct evdi_context *ctx)
{
	int i;

	for (i = 0; i < EVDI_DEVICE_COUNT_MAX; ++i) {
		if (ctx->devices[i] == NULL)
			return i;
	}
	return -ENOMEM;
}

static bool evdi_platform_device_is_free(struct platform_device *pdev)
{
	struct evdi_platform_device_data *data =
		(struct evdi_platform_device_data *)platform_get_drvdata(pdev);
	struct evdi_device *evdi = data->drm_dev->dev_private;

	if (evdi && !evdi_painter_is_connected(evdi) &&
	    !data->symlinked)
		return true;
	return false;
}

static void evdi_platform_device_link(struct platform_device *pdev,
				      struct device *parent)
{
	struct evdi_platform_device_data *data = NULL;
	int ret = 0;

	if (!parent || !pdev)
		return;

	data = (struct evdi_platform_device_data *)platform_get_drvdata(pdev);
	if (!evdi_platform_device_is_free(pdev)) {
		EVDI_FATAL("Device is already attached can't symlink again\n");
		return;
	}

	ret = sysfs_create_link(&pdev->dev.kobj, &parent->kobj, "device");
	if (ret) {
		EVDI_FATAL("Failed to create sysfs link to parent device\n");
	} else {
		data->symlinked = true;
		data->parent = parent;
	}
}

static void evdi_platform_device_unlink_if_linked_with(struct platform_device *pdev,
				struct device *parent)
{
	struct evdi_platform_device_data *data =
		(struct evdi_platform_device_data *)platform_get_drvdata(pdev);

	if (parent && data->parent == parent) {
		sysfs_remove_link(&pdev->dev.kobj, "device");
		data->symlinked = false;
		data->parent = NULL;
		EVDI_INFO("Detached from parent device\n");
	}
}

static struct drm_driver driver;

struct drm_ioctl_desc evdi_painter_ioctls[] = {
	DRM_IOCTL_DEF_DRV(EVDI_CONNECT, evdi_painter_connect_ioctl,
				DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(EVDI_REQUEST_UPDATE,
				evdi_painter_request_update_ioctl,
				DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(EVDI_GRABPIX, evdi_painter_grabpix_ioctl,
				DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(EVDI_DDCCI_RESPONSE,
				evdi_painter_ddcci_response_ioctl,
				DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(EVDI_ENABLE_CURSOR_EVENTS,
			    evdi_painter_enable_cursor_events_ioctl,
				DRM_UNLOCKED),
};

static const struct vm_operations_struct evdi_gem_vm_ops = {
	.fault = evdi_gem_fault,
	.open = drm_gem_vm_open,
	.close = drm_gem_vm_close,
};

static const struct file_operations evdi_driver_fops = {
	.owner = THIS_MODULE,
	.open = drm_open,
	.mmap = evdi_drm_gem_mmap,
	.poll = drm_poll,
	.read = drm_read,
	.unlocked_ioctl = drm_ioctl,
	.release = drm_release,
#ifdef CONFIG_COMPAT
	.compat_ioctl = evdi_compat_ioctl,
#endif
	.llseek = noop_llseek,
};

static int evdi_enable_vblank(__always_unused struct drm_device *dev,
	__always_unused unsigned int pipe)
{
	return 1;
}

static void evdi_disable_vblank(__always_unused struct drm_device *dev,
	__always_unused unsigned int pipe)
{
}

static struct drm_driver driver = {
	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
	.load = evdi_driver_load,
	.unload = evdi_driver_unload,
	.postclose = evdi_driver_postclose,

	/* gem hooks */
	.gem_free_object = evdi_gem_free_object,
	.gem_vm_ops = &evdi_gem_vm_ops,

	.dumb_create = evdi_dumb_create,
	.dumb_map_offset = evdi_gem_mmap,
	.dumb_destroy = drm_gem_dumb_destroy,

	.ioctls = evdi_painter_ioctls,
	.num_ioctls = ARRAY_SIZE(evdi_painter_ioctls),

	.fops = &evdi_driver_fops,

	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
	.gem_prime_import = evdi_gem_prime_import,
	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
	.gem_prime_export = evdi_gem_prime_export,

	.enable_vblank = evdi_enable_vblank,
	.disable_vblank = evdi_disable_vblank,

	.name = DRIVER_NAME,
	.desc = DRIVER_DESC,
	.date = DRIVER_DATE,
	.major = DRIVER_MAJOR,
	.minor = DRIVER_MINOR,
	.patchlevel = DRIVER_PATCHLEVEL,
};

static struct platform_device *evdi_platform_drv_get_free_device(
				struct evdi_context *ctx)
{
	int i;
	struct platform_device *pdev = NULL;

	for (i = 0; i < EVDI_DEVICE_COUNT_MAX; ++i) {
		pdev = ctx->devices[i];
		if (pdev && evdi_platform_device_is_free(pdev))
			return pdev;
	}
	return NULL;
}

static struct platform_device *evdi_platform_drv_create_new_device(
				struct evdi_context *ctx)
{
	struct platform_device_info pdevinfo = {
		.parent = NULL,
		.name = "evdi",
		.id = evdi_context_get_free_idx(ctx),
		.res = NULL,
		.num_res = 0,
		.data = NULL,
		.size_data = 0,
		.dma_mask = DMA_BIT_MASK(32),
	};

	if (pdevinfo.id < 0 || ctx->dev_count >= EVDI_DEVICE_COUNT_MAX) {
		EVDI_ERROR("Evdi device add failed. Too many devices.\n");
		return ERR_PTR(-EINVAL);
	}

	ctx->devices[pdevinfo.id] = platform_device_register_full(&pdevinfo);
	if (dma_set_mask(&evdi_context.devices[evdi_context.dev_count]->dev,
			 DMA_BIT_MASK(64))) {
		EVDI_DEBUG("Unable to change dma mask to 64 bit. ");
		EVDI_DEBUG("Sticking with 32 bit\n");
	}

	ctx->dev_count++;
	return ctx->devices[pdevinfo.id];
}

static int evdi_add_device(struct evdi_context *ctx, struct device *parent)
{
	struct platform_device *pdev = NULL;

	evdi_context_lock(ctx);
	if (parent)
		pdev = evdi_platform_drv_get_free_device(ctx);

	if (IS_ERR_OR_NULL(pdev))
		pdev = evdi_platform_drv_create_new_device(ctx);
	evdi_context_unlock(ctx);

	if (IS_ERR_OR_NULL(pdev))
		return -EINVAL;

	evdi_platform_device_link(pdev, parent);
	return 0;
}

static int evdi_drm_device_setup(struct drm_device *dev)
{
	struct platform_device *platdev;
	struct evdi_device *evdi;
	int ret;

	EVDI_CHECKPT();
	evdi = kzalloc(sizeof(struct evdi_device), GFP_KERNEL);
	if (!evdi)
		return -ENOMEM;

	evdi->ddev = dev;
	dev->dev_private = evdi;

	ret = evdi_cursor_init(&evdi->cursor);
	if (ret)
		goto err_free;

	EVDI_CHECKPT();
	evdi_modeset_init(dev);

#ifdef CONFIG_FB
	ret = evdi_fbdev_init(dev);
	if (ret)
		goto err_cursor;
#endif /* CONFIG_FB */

	ret = drm_vblank_init(dev, 1);
	if (ret)
		goto err_fb;

	ret = evdi_painter_init(evdi);
	if (ret)
		goto err_fb;

	drm_kms_helper_poll_init(dev);

	platdev = to_platform_device(dev->dev);
	platform_set_drvdata(platdev, dev);

	return 0;

err_fb:
#ifdef CONFIG_FB
	evdi_fbdev_cleanup(dev);
err_cursor:
#endif /* CONFIG_FB */
	evdi_cursor_free(evdi->cursor);
err_free:
	EVDI_ERROR("%d\n", ret);
	kfree(evdi);
	return ret;
}

static int evdi_platform_probe(struct platform_device *pdev)
{
	int ret;
	struct drm_device *dev;
	struct evdi_platform_device_data *data;

	EVDI_CHECKPT();

	data = kzalloc(sizeof(struct evdi_platform_device_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	dev = drm_dev_alloc(&driver, &pdev->dev);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto err_free;
	}

	ret = evdi_drm_device_setup(dev);
	if (ret)
		goto err_put_dev;

	ret = drm_dev_register(dev, 0);
	if (ret)
		goto err_put_dev;

	data->drm_dev = dev;
	data->symlinked = false;
	platform_set_drvdata(pdev, data);

	return 0;

err_put_dev:
	drm_dev_put(dev);
err_free:
	kfree(data);
	return ret;
}

static int evdi_platform_remove(struct platform_device *pdev)
{
	struct evdi_platform_device_data *data = platform_get_drvdata(pdev);

	EVDI_CHECKPT();

	drm_dev_unplug(data->drm_dev);
	kfree(data);

	return 0;
}

static void evdi_remove_all(void)
{
	int i;

	EVDI_DEBUG("removing all evdi devices\n");
	evdi_context_lock((&evdi_context));
	for (i = 0; i < EVDI_DEVICE_COUNT_MAX; ++i) {
		if (evdi_context.devices[i]) {
			EVDI_DEBUG("removing evdi %d\n", i);

			platform_device_unregister(evdi_context.devices[i]);
			evdi_context.dev_count--;
			evdi_context.devices[i] = NULL;
		}
	}
	evdi_context.dev_count = 0;
	evdi_context_unlock((&evdi_context));
}

static struct platform_driver evdi_platform_driver = {
	.probe = evdi_platform_probe,
	.remove = evdi_platform_remove,
	.driver = {
			 .name = "evdi",
			 .mod_name = KBUILD_MODNAME,
			 .owner = THIS_MODULE,
	}
};

static ssize_t version_show(__always_unused struct device *dev,
				__always_unused struct device_attribute *attr,
				char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u.%u.%u\n", DRIVER_MAJOR,
			DRIVER_MINOR, DRIVER_PATCHLEVEL);
}

static ssize_t count_show(__always_unused struct device *dev,
				__always_unused struct device_attribute *attr,
				char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n", evdi_context.dev_count);
}

struct evdi_usb_addr {
	int addr[MAX_EVDI_USB_ADDR];
	int len;
	struct usb_device *usb;
};

static int evdi_platform_device_attach(struct device *device,
		struct evdi_usb_addr *parent_addr);

static ssize_t add_device_with_usb_path(struct device *dev,
			 const char *buf, size_t count)
{
	char *usb_path = kstrdup(buf, GFP_KERNEL);
	char *temp_path = usb_path;
	char *bus_token;
	char *usb_token;
	char *usb_token_copy = NULL;
	char *token;
	char *bus;
	char *port;
	struct evdi_usb_addr usb_addr;

	if (!usb_path)
		return -ENOMEM;

	memset(&usb_addr, 0, sizeof(usb_addr));
	temp_path = strnstr(temp_path, "usb:", count);
	if (!temp_path)
		goto err_parse_usb_path;

	temp_path = strim(temp_path);

	bus_token = strsep(&temp_path, ":");
	if (!bus_token)
		goto err_parse_usb_path;

	usb_token = strsep(&temp_path, ":");
	if (!usb_token)
		goto err_parse_usb_path;

	/* Separate trailing ':*' from usb_token */
	strsep(&temp_path, ":");

	token = usb_token_copy = kstrdup(usb_token, GFP_KERNEL);
	bus = strsep(&token, "-");
	if (!bus)
		goto err_parse_usb_path;
	if (kstrtouint(bus, 10, &usb_addr.addr[usb_addr.len++]))
		goto err_parse_usb_path;

	do {
		port = strsep(&token, ".");
		if (!port)
			goto err_parse_usb_path;
		if (kstrtouint(port, 10, &usb_addr.addr[usb_addr.len++]))
			goto err_parse_usb_path;
	} while (token && port && usb_addr.len < MAX_EVDI_USB_ADDR);

	if (evdi_platform_device_attach(dev, &usb_addr) != 0) {
		EVDI_ERROR("Unable to attach to: %s\n", buf);
		kfree(usb_path);
		kfree(usb_token_copy);
		return -EINVAL;
	}

	EVDI_INFO("Attaching to %s:%s\n", bus_token, usb_token);
	kfree(usb_path);
	kfree(usb_token_copy);
	return count;

err_parse_usb_path:
	EVDI_ERROR("Unable to parse usb path: %s", buf);
	kfree(usb_path);
	kfree(usb_token_copy);
	return -EINVAL;
}

static int find_usb_device_at_path(struct usb_device *usb, void *data)
{
	struct evdi_usb_addr *find_path = (struct evdi_usb_addr *)(data);
	struct usb_device *pdev = usb;
	int port = 0;
	int i;

	i = find_path->len - 1;
	while (pdev != NULL && i >= 0 && i < MAX_EVDI_USB_ADDR) {
		port = pdev->portnum;
		if (port == 0)
			port = pdev->bus->busnum;

		if (port != find_path->addr[i])
			return 0;

		if (pdev->parent == NULL && i == 0) {
			find_path->usb = usb;
			return 1;
		}
		pdev = pdev->parent;
		i--;
	}

	return 0;
}

int evdi_platform_device_attach(struct device *device,
		struct evdi_usb_addr *parent_addr)
{
	struct device *parent = NULL;

	if (!parent_addr)
		return -EINVAL;

	if (!usb_for_each_dev(parent_addr, find_usb_device_at_path) ||
	    !parent_addr->usb)
		return -EINVAL;

	parent = &parent_addr->usb->dev;
	return evdi_add_device(&evdi_context, parent);
}

static ssize_t add_store(struct device *dev,
			 __always_unused struct device_attribute *attr,
			 const char *buf, size_t count)
{
	unsigned int val;

	if (strnstr(buf, "usb:", count))
		return add_device_with_usb_path(dev, buf, count);

	if (kstrtouint(buf, 10, &val)) {
		EVDI_ERROR("Invalid device count \"%s\"\n", buf);
		return -EINVAL;
	}
	if (val == 0) {
		EVDI_WARN("Adding 0 devices has no effect\n");
		return count;
	}
	if (val > EVDI_DEVICE_COUNT_MAX - evdi_context.dev_count) {
		EVDI_ERROR("Evdi device add failed. Too many devices.\n");
		return -EINVAL;
	}

	EVDI_DEBUG("Increasing device count to %u\n",
			evdi_context.dev_count + val);
	while (val-- && evdi_add_device(&evdi_context, NULL) == 0)
		;

	return count;
}

static ssize_t remove_all_store(__always_unused struct device *dev,
				__always_unused struct device_attribute *attr,
				__always_unused const char *buf,
				size_t count)
{
	evdi_remove_all();
	return count;
}

static ssize_t loglevel_show(__always_unused struct device *dev,
				__always_unused struct device_attribute *attr,
				char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n", evdi_loglevel);
}

static ssize_t loglevel_store(__always_unused struct device *dev,
				__always_unused struct device_attribute *attr,
				const char *buf,
				size_t count)
{
	unsigned int val;

	if (kstrtouint(buf, 10, &val)) {
		EVDI_ERROR("Unable to parse %u\n", val);
		return -EINVAL;
	}
	if (val > EVDI_LOGLEVEL_VERBOSE) {
		EVDI_ERROR("Invalid loglevel %u\n", val);
		return -EINVAL;
	}

	EVDI_INFO("Setting loglevel to %u\n", val);
	evdi_loglevel = val;
	return count;
}

static struct device_attribute evdi_device_attributes[] = {
	__ATTR_RO(count),
	__ATTR_RO(version),
	__ATTR_RW(loglevel),
	__ATTR_WO(add),
	__ATTR_WO(remove_all)
};

static int __init evdi_init(void)
{
	int i;

	EVDI_INFO("Initialising logging on level %u\n", evdi_loglevel);
	EVDI_INFO("Atomic driver:%s",
		(driver.driver_features & DRIVER_ATOMIC) ? "yes" : "no");
	evdi_context.root_dev = root_device_register("evdi");
	evdi_context.usb_notifier.notifier_call = evdi_platform_drv_usb;
	mutex_init(&evdi_context.lock);

	usb_register_notify(&evdi_context.usb_notifier);
	if (!PTR_RET(evdi_context.root_dev))
		for (i = 0; i < ARRAY_SIZE(evdi_device_attributes); i++) {
			device_create_file(evdi_context.root_dev,
						 &evdi_device_attributes[i]);
		}

	return platform_driver_register(&evdi_platform_driver);
}

static void __exit evdi_exit(void)
{
	int i;

	EVDI_CHECKPT();
	evdi_remove_all();

	usb_unregister_notify(&evdi_context.usb_notifier);
	platform_driver_unregister(&evdi_platform_driver);

	if (!PTR_RET(evdi_context.root_dev)) {
		for (i = 0; i < ARRAY_SIZE(evdi_device_attributes); i++) {
			device_remove_file(evdi_context.root_dev,
						 &evdi_device_attributes[i]);
		}
		root_device_unregister(evdi_context.root_dev);
	}
}

module_init(evdi_init);
module_exit(evdi_exit);
