// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020 NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <media/v4l2-event.h>

#include "video.h"

static void tegra_v4l2_dev_release(struct v4l2_device *v4l2_dev)
{
	struct tegra_video_device *vid;

	vid = container_of(v4l2_dev, struct tegra_video_device, v4l2_dev);

	/* cleanup channels here as all video device nodes are released */
	tegra_channels_cleanup(vid->vi);

	v4l2_device_unregister(v4l2_dev);
	media_device_unregister(&vid->media_dev);
	media_device_cleanup(&vid->media_dev);
	kfree(vid);
}

static void tegra_v4l2_dev_notify(struct v4l2_subdev *sd,
				  unsigned int notification, void *arg)
{
	struct tegra_vi_channel *chan;
	const struct v4l2_event *ev = arg;

	if (notification != V4L2_DEVICE_NOTIFY_EVENT)
		return;

	chan = v4l2_get_subdev_hostdata(sd);
	v4l2_event_queue(&chan->video, arg);
	if (ev->type == V4L2_EVENT_SOURCE_CHANGE && vb2_is_streaming(&chan->queue))
		vb2_queue_error(&chan->queue);
}

static int host1x_video_probe(struct host1x_device *dev)
{
	struct tegra_video_device *vid;
	int ret;

	vid = kzalloc(sizeof(*vid), GFP_KERNEL);
	if (!vid)
		return -ENOMEM;

	dev_set_drvdata(&dev->dev, vid);

	vid->media_dev.dev = &dev->dev;
	strscpy(vid->media_dev.model, "NVIDIA Tegra Video Input Device",
		sizeof(vid->media_dev.model));

	media_device_init(&vid->media_dev);
	ret = media_device_register(&vid->media_dev);
	if (ret < 0) {
		dev_err(&dev->dev,
			"failed to register media device: %d\n", ret);
		goto cleanup;
	}

	vid->v4l2_dev.mdev = &vid->media_dev;
	vid->v4l2_dev.release = tegra_v4l2_dev_release;
	vid->v4l2_dev.notify = tegra_v4l2_dev_notify;
	ret = v4l2_device_register(&dev->dev, &vid->v4l2_dev);
	if (ret < 0) {
		dev_err(&dev->dev,
			"V4L2 device registration failed: %d\n", ret);
		goto unregister_media;
	}

	ret = host1x_device_init(dev);
	if (ret < 0)
		goto unregister_v4l2;

	if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)) {
		/*
		 * Both vi and csi channels are available now.
		 * Register v4l2 nodes and create media links for TPG.
		 */
		ret = tegra_v4l2_nodes_setup_tpg(vid);
		if (ret < 0) {
			dev_err(&dev->dev,
				"failed to setup tpg graph: %d\n", ret);
			goto device_exit;
		}
	}

	return 0;

device_exit:
	host1x_device_exit(dev);
	/* vi exit ops does not clean channels, so clean them here */
	tegra_channels_cleanup(vid->vi);
unregister_v4l2:
	v4l2_device_unregister(&vid->v4l2_dev);
unregister_media:
	media_device_unregister(&vid->media_dev);
cleanup:
	media_device_cleanup(&vid->media_dev);
	kfree(vid);
	return ret;
}

static int host1x_video_remove(struct host1x_device *dev)
{
	struct tegra_video_device *vid = dev_get_drvdata(&dev->dev);

	if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		tegra_v4l2_nodes_cleanup_tpg(vid);

	host1x_device_exit(dev);

	/* This calls v4l2_dev release callback on last reference */
	v4l2_device_put(&vid->v4l2_dev);

	return 0;
}

static const struct of_device_id host1x_video_subdevs[] = {
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
	{ .compatible = "nvidia,tegra20-vip", },
	{ .compatible = "nvidia,tegra20-vi", },
#endif
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
	{ .compatible = "nvidia,tegra210-csi", },
	{ .compatible = "nvidia,tegra210-vi", },
#endif
	{ }
};

static struct host1x_driver host1x_video_driver = {
	.driver = {
		.name = "tegra-video",
	},
	.probe = host1x_video_probe,
	.remove = host1x_video_remove,
	.subdevs = host1x_video_subdevs,
};

static struct platform_driver * const drivers[] = {
	&tegra_csi_driver,
	&tegra_vip_driver,
	&tegra_vi_driver,
};

static int __init host1x_video_init(void)
{
	int err;

	err = host1x_driver_register(&host1x_video_driver);
	if (err < 0)
		return err;

	err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
	if (err < 0)
		goto unregister_host1x;

	return 0;

unregister_host1x:
	host1x_driver_unregister(&host1x_video_driver);
	return err;
}
module_init(host1x_video_init);

static void __exit host1x_video_exit(void)
{
	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
	host1x_driver_unregister(&host1x_video_driver);
}
module_exit(host1x_video_exit);

MODULE_AUTHOR("Sowjanya Komatineni <skomatineni@nvidia.com>");
MODULE_DESCRIPTION("NVIDIA Tegra Host1x Video driver");
MODULE_LICENSE("GPL v2");
