// SPDX-License-Identifier: GPL-2.0
/*
 * Intel(R) Trace Hub driver core
 *
 * Copyright (C) 2014-2015 Intel Corporation.
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/kdev_t.h>
#include <linux/debugfs.h>
#include <linux/idr.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <linux/dma-mapping.h>

#include "intel_th.h"
#include "debug.h"

static bool host_mode __read_mostly;
module_param(host_mode, bool, 0444);

static DEFINE_IDA(intel_th_ida);

static int intel_th_match(struct device *dev, struct device_driver *driver)
{
	struct intel_th_driver *thdrv = to_intel_th_driver(driver);
	struct intel_th_device *thdev = to_intel_th_device(dev);

	if (thdev->type == INTEL_TH_SWITCH &&
	    (!thdrv->enable || !thdrv->disable))
		return 0;

	return !strcmp(thdev->name, driver->name);
}

static int intel_th_child_remove(struct device *dev, void *data)
{
	device_release_driver(dev);

	return 0;
}

static int intel_th_probe(struct device *dev)
{
	struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver);
	struct intel_th_device *thdev = to_intel_th_device(dev);
	struct intel_th_driver *hubdrv;
	struct intel_th_device *hub = NULL;
	int ret;

	if (thdev->type == INTEL_TH_SWITCH)
		hub = thdev;
	else if (dev->parent)
		hub = to_intel_th_device(dev->parent);

	if (!hub || !hub->dev.driver)
		return -EPROBE_DEFER;

	hubdrv = to_intel_th_driver(hub->dev.driver);

	pm_runtime_set_active(dev);
	pm_runtime_no_callbacks(dev);
	pm_runtime_enable(dev);

	ret = thdrv->probe(to_intel_th_device(dev));
	if (ret)
		goto out_pm;

	if (thdrv->attr_group) {
		ret = sysfs_create_group(&thdev->dev.kobj, thdrv->attr_group);
		if (ret)
			goto out;
	}

	if (thdev->type == INTEL_TH_OUTPUT &&
	    !intel_th_output_assigned(thdev))
		/* does not talk to hardware */
		ret = hubdrv->assign(hub, thdev);

out:
	if (ret)
		thdrv->remove(thdev);

out_pm:
	if (ret)
		pm_runtime_disable(dev);

	return ret;
}

static void intel_th_device_remove(struct intel_th_device *thdev);

static int intel_th_remove(struct device *dev)
{
	struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver);
	struct intel_th_device *thdev = to_intel_th_device(dev);
	struct intel_th_device *hub = to_intel_th_hub(thdev);
	int err;

	if (thdev->type == INTEL_TH_SWITCH) {
		struct intel_th *th = to_intel_th(hub);
		int i, lowest;

		/* disconnect outputs */
		err = device_for_each_child(dev, thdev, intel_th_child_remove);
		if (err)
			return err;

		/*
		 * Remove outputs, that is, hub's children: they are created
		 * at hub's probe time by having the hub call
		 * intel_th_output_enable() for each of them.
		 */
		for (i = 0, lowest = -1; i < th->num_thdevs; i++) {
			/*
			 * Move the non-output devices from higher up the
			 * th->thdev[] array to lower positions to maintain
			 * a contiguous array.
			 */
			if (th->thdev[i]->type != INTEL_TH_OUTPUT) {
				if (lowest >= 0) {
					th->thdev[lowest] = th->thdev[i];
					th->thdev[i] = NULL;
					++lowest;
				}

				continue;
			}

			if (lowest == -1)
				lowest = i;

			intel_th_device_remove(th->thdev[i]);
			th->thdev[i] = NULL;
		}

		if (lowest >= 0)
			th->num_thdevs = lowest;
	}

	if (thdrv->attr_group)
		sysfs_remove_group(&thdev->dev.kobj, thdrv->attr_group);

	pm_runtime_get_sync(dev);

	thdrv->remove(thdev);

	if (intel_th_output_assigned(thdev)) {
		struct intel_th_driver *hubdrv =
			to_intel_th_driver(dev->parent->driver);

		if (hub->dev.driver)
			/* does not talk to hardware */
			hubdrv->unassign(hub, thdev);
	}

	pm_runtime_disable(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	return 0;
}

static struct bus_type intel_th_bus = {
	.name		= "intel_th",
	.match		= intel_th_match,
	.probe		= intel_th_probe,
	.remove		= intel_th_remove,
};

static void intel_th_device_free(struct intel_th_device *thdev);

static void intel_th_device_release(struct device *dev)
{
	intel_th_device_free(to_intel_th_device(dev));
}

static struct device_type intel_th_source_device_type = {
	.name		= "intel_th_source_device",
	.release	= intel_th_device_release,
};

static char *intel_th_output_devnode(struct device *dev, umode_t *mode,
				     kuid_t *uid, kgid_t *gid)
{
	struct intel_th_device *thdev = to_intel_th_device(dev);
	struct intel_th *th = to_intel_th(thdev);
	char *node;

	if (thdev->id >= 0)
		node = kasprintf(GFP_KERNEL, "intel_th%d/%s%d", th->id,
				 thdev->name, thdev->id);
	else
		node = kasprintf(GFP_KERNEL, "intel_th%d/%s", th->id,
				 thdev->name);

	return node;
}

static ssize_t port_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct intel_th_device *thdev = to_intel_th_device(dev);

	if (thdev->output.port >= 0)
		return scnprintf(buf, PAGE_SIZE, "%u\n", thdev->output.port);

	return scnprintf(buf, PAGE_SIZE, "unassigned\n");
}

static DEVICE_ATTR_RO(port);

static int intel_th_output_activate(struct intel_th_device *thdev)
{
	struct intel_th_driver *thdrv =
		to_intel_th_driver_or_null(thdev->dev.driver);
	struct intel_th *th = to_intel_th(thdev);
	int ret = 0;

	if (!thdrv)
		return -ENODEV;

	if (!try_module_get(thdrv->driver.owner))
		return -ENODEV;

	pm_runtime_get_sync(&thdev->dev);

	if (th->activate)
		ret = th->activate(th);
	if (ret)
		goto fail_put;

	if (thdrv->activate)
		ret = thdrv->activate(thdev);
	else
		intel_th_trace_enable(thdev);

	if (ret)
		goto fail_deactivate;

	return 0;

fail_deactivate:
	if (th->deactivate)
		th->deactivate(th);

fail_put:
	pm_runtime_put(&thdev->dev);
	module_put(thdrv->driver.owner);

	return ret;
}

static void intel_th_output_deactivate(struct intel_th_device *thdev)
{
	struct intel_th_driver *thdrv =
		to_intel_th_driver_or_null(thdev->dev.driver);
	struct intel_th *th = to_intel_th(thdev);

	if (!thdrv)
		return;

	if (thdrv->deactivate)
		thdrv->deactivate(thdev);
	else
		intel_th_trace_disable(thdev);

	if (th->deactivate)
		th->deactivate(th);

	pm_runtime_put(&thdev->dev);
	module_put(thdrv->driver.owner);
}

static ssize_t active_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct intel_th_device *thdev = to_intel_th_device(dev);

	return scnprintf(buf, PAGE_SIZE, "%d\n", thdev->output.active);
}

static ssize_t active_store(struct device *dev, struct device_attribute *attr,
			    const char *buf, size_t size)
{
	struct intel_th_device *thdev = to_intel_th_device(dev);
	unsigned long val;
	int ret;

	ret = kstrtoul(buf, 10, &val);
	if (ret)
		return ret;

	if (!!val != thdev->output.active) {
		if (val)
			ret = intel_th_output_activate(thdev);
		else
			intel_th_output_deactivate(thdev);
	}

	return ret ? ret : size;
}

static DEVICE_ATTR_RW(active);

static struct attribute *intel_th_output_attrs[] = {
	&dev_attr_port.attr,
	&dev_attr_active.attr,
	NULL,
};

ATTRIBUTE_GROUPS(intel_th_output);

static struct device_type intel_th_output_device_type = {
	.name		= "intel_th_output_device",
	.groups		= intel_th_output_groups,
	.release	= intel_th_device_release,
	.devnode	= intel_th_output_devnode,
};

static struct device_type intel_th_switch_device_type = {
	.name		= "intel_th_switch_device",
	.release	= intel_th_device_release,
};

static struct device_type *intel_th_device_type[] = {
	[INTEL_TH_SOURCE]	= &intel_th_source_device_type,
	[INTEL_TH_OUTPUT]	= &intel_th_output_device_type,
	[INTEL_TH_SWITCH]	= &intel_th_switch_device_type,
};

int intel_th_driver_register(struct intel_th_driver *thdrv)
{
	if (!thdrv->probe || !thdrv->remove)
		return -EINVAL;

	thdrv->driver.bus = &intel_th_bus;

	return driver_register(&thdrv->driver);
}
EXPORT_SYMBOL_GPL(intel_th_driver_register);

void intel_th_driver_unregister(struct intel_th_driver *thdrv)
{
	driver_unregister(&thdrv->driver);
}
EXPORT_SYMBOL_GPL(intel_th_driver_unregister);

static struct intel_th_device *
intel_th_device_alloc(struct intel_th *th, unsigned int type, const char *name,
		      int id)
{
	struct device *parent;
	struct intel_th_device *thdev;

	if (type == INTEL_TH_OUTPUT)
		parent = &th->hub->dev;
	else
		parent = th->dev;

	thdev = kzalloc(sizeof(*thdev) + strlen(name) + 1, GFP_KERNEL);
	if (!thdev)
		return NULL;

	thdev->id = id;
	thdev->type = type;

	strcpy(thdev->name, name);
	device_initialize(&thdev->dev);
	thdev->dev.bus = &intel_th_bus;
	thdev->dev.type = intel_th_device_type[type];
	thdev->dev.parent = parent;
	thdev->dev.dma_mask = parent->dma_mask;
	thdev->dev.dma_parms = parent->dma_parms;
	dma_set_coherent_mask(&thdev->dev, parent->coherent_dma_mask);
	if (id >= 0)
		dev_set_name(&thdev->dev, "%d-%s%d", th->id, name, id);
	else
		dev_set_name(&thdev->dev, "%d-%s", th->id, name);

	return thdev;
}

static int intel_th_device_add_resources(struct intel_th_device *thdev,
					 struct resource *res, int nres)
{
	struct resource *r;

	r = kmemdup(res, sizeof(*res) * nres, GFP_KERNEL);
	if (!r)
		return -ENOMEM;

	thdev->resource = r;
	thdev->num_resources = nres;

	return 0;
}

static void intel_th_device_remove(struct intel_th_device *thdev)
{
	device_del(&thdev->dev);
	put_device(&thdev->dev);
}

static void intel_th_device_free(struct intel_th_device *thdev)
{
	kfree(thdev->resource);
	kfree(thdev);
}

/*
 * Intel(R) Trace Hub subdevices
 */
static const struct intel_th_subdevice {
	const char		*name;
	struct resource		res[3];
	unsigned		nres;
	unsigned		type;
	unsigned		otype;
	unsigned		scrpd;
	int			id;
} intel_th_subdevices[] = {
	{
		.nres	= 1,
		.res	= {
			{
				/* Handle TSCU from GTH driver */
				.start	= REG_GTH_OFFSET,
				.end	= REG_TSCU_OFFSET + REG_TSCU_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
		},
		.name	= "gth",
		.type	= INTEL_TH_SWITCH,
		.id	= -1,
	},
	{
		.nres	= 2,
		.res	= {
			{
				.start	= REG_MSU_OFFSET,
				.end	= REG_MSU_OFFSET + REG_MSU_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
			{
				.start	= BUF_MSU_OFFSET,
				.end	= BUF_MSU_OFFSET + BUF_MSU_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
		},
		.name	= "msc",
		.id	= 0,
		.type	= INTEL_TH_OUTPUT,
		.otype	= GTH_MSU,
		.scrpd	= SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC0_IS_ENABLED,
	},
	{
		.nres	= 2,
		.res	= {
			{
				.start	= REG_MSU_OFFSET,
				.end	= REG_MSU_OFFSET + REG_MSU_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
			{
				.start	= BUF_MSU_OFFSET,
				.end	= BUF_MSU_OFFSET + BUF_MSU_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
		},
		.name	= "msc",
		.id	= 1,
		.type	= INTEL_TH_OUTPUT,
		.otype	= GTH_MSU,
		.scrpd	= SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC1_IS_ENABLED,
	},
	{
		.nres	= 2,
		.res	= {
			{
				.start	= REG_STH_OFFSET,
				.end	= REG_STH_OFFSET + REG_STH_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
			{
				.start	= 1, /* use resource[1] */
				.end	= 0,
				.flags	= IORESOURCE_MEM,
			},
		},
		.id	= -1,
		.name	= "sth",
		.type	= INTEL_TH_SOURCE,
	},
	{
		.nres	= 1,
		.res	= {
			{
				.start	= REG_PTI_OFFSET,
				.end	= REG_PTI_OFFSET + REG_PTI_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
		},
		.id	= -1,
		.name	= "pti",
		.type	= INTEL_TH_OUTPUT,
		.otype	= GTH_PTI,
		.scrpd	= SCRPD_PTI_IS_PRIM_DEST,
	},
	{
		.nres	= 1,
		.res	= {
			{
				.start	= REG_PTI_OFFSET,
				.end	= REG_PTI_OFFSET + REG_PTI_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
		},
		.id	= -1,
		.name	= "lpp",
		.type	= INTEL_TH_OUTPUT,
		.otype	= GTH_LPP,
		.scrpd	= SCRPD_PTI_IS_PRIM_DEST,
	},
	{
		.nres	= 1,
		.res	= {
			{
				.start	= REG_DCIH_OFFSET,
				.end	= REG_DCIH_OFFSET + REG_DCIH_LENGTH - 1,
				.flags	= IORESOURCE_MEM,
			},
		},
		.id	= -1,
		.name	= "dcih",
		.type	= INTEL_TH_OUTPUT,
	},
};

#ifdef CONFIG_MODULES
static void __intel_th_request_hub_module(struct work_struct *work)
{
	struct intel_th *th = container_of(work, struct intel_th,
					   request_module_work);

	request_module("intel_th_%s", th->hub->name);
}

static int intel_th_request_hub_module(struct intel_th *th)
{
	INIT_WORK(&th->request_module_work, __intel_th_request_hub_module);
	schedule_work(&th->request_module_work);

	return 0;
}

static void intel_th_request_hub_module_flush(struct intel_th *th)
{
	flush_work(&th->request_module_work);
}
#else
static inline int intel_th_request_hub_module(struct intel_th *th)
{
	return -EINVAL;
}

static inline void intel_th_request_hub_module_flush(struct intel_th *th)
{
}
#endif /* CONFIG_MODULES */

static struct intel_th_device *
intel_th_subdevice_alloc(struct intel_th *th,
			 const struct intel_th_subdevice *subdev)
{
	struct intel_th_device *thdev;
	struct resource res[3];
	unsigned int req = 0;
	bool is64bit = false;
	int r, err;

	thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
				      subdev->id);
	if (!thdev)
		return ERR_PTR(-ENOMEM);

	thdev->drvdata = th->drvdata;

	for (r = 0; r < th->num_resources; r++)
		if (th->resource[r].flags & IORESOURCE_MEM_64) {
			is64bit = true;
			break;
		}

	memcpy(res, subdev->res,
	       sizeof(struct resource) * subdev->nres);

	for (r = 0; r < subdev->nres; r++) {
		struct resource *devres = th->resource;
		int bar = 0; /* cut subdevices' MMIO from resource[0] */

		/*
		 * Take .end == 0 to mean 'take the whole bar',
		 * .start then tells us which bar it is. Default to
		 * TH_MMIO_CONFIG.
		 */
		if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
			bar = res[r].start;
			if (is64bit)
				bar *= 2;
			res[r].start = 0;
			res[r].end = resource_size(&devres[bar]) - 1;
		}

		if (res[r].flags & IORESOURCE_MEM) {
			res[r].start	+= devres[bar].start;
			res[r].end	+= devres[bar].start;

			dev_dbg(th->dev, "%s:%d @ %pR\n",
				subdev->name, r, &res[r]);
		} else if (res[r].flags & IORESOURCE_IRQ) {
			res[r].start	= th->irq;
		}
	}

	err = intel_th_device_add_resources(thdev, res, subdev->nres);
	if (err)
		goto fail_put_device;

	if (subdev->type == INTEL_TH_OUTPUT) {
		thdev->dev.devt = MKDEV(th->major, th->num_thdevs);
		thdev->output.type = subdev->otype;
		thdev->output.port = -1;
		thdev->output.scratchpad = subdev->scrpd;
	} else if (subdev->type == INTEL_TH_SWITCH) {
		thdev->host_mode =
			INTEL_TH_CAP(th, host_mode_only) ? true : host_mode;
		th->hub = thdev;
	}

	err = device_add(&thdev->dev);
	if (err)
		goto fail_free_res;

	/* need switch driver to be loaded to enumerate the rest */
	if (subdev->type == INTEL_TH_SWITCH && !req) {
		err = intel_th_request_hub_module(th);
		if (!err)
			req++;
	}

	return thdev;

fail_free_res:
	kfree(thdev->resource);

fail_put_device:
	put_device(&thdev->dev);

	return ERR_PTR(err);
}

/**
 * intel_th_output_enable() - find and enable a device for a given output type
 * @th:		Intel TH instance
 * @otype:	output type
 *
 * Go through the unallocated output devices, find the first one whos type
 * matches @otype and instantiate it. These devices are removed when the hub
 * device is removed, see intel_th_remove().
 */
int intel_th_output_enable(struct intel_th *th, unsigned int otype)
{
	struct intel_th_device *thdev;
	int src = 0, dst = 0;

	for (src = 0, dst = 0; dst <= th->num_thdevs; src++, dst++) {
		for (; src < ARRAY_SIZE(intel_th_subdevices); src++) {
			if (intel_th_subdevices[src].type != INTEL_TH_OUTPUT)
				continue;

			if (intel_th_subdevices[src].otype != otype)
				continue;

			break;
		}

		/* no unallocated matching subdevices */
		if (src == ARRAY_SIZE(intel_th_subdevices))
			return -ENODEV;

		for (; dst < th->num_thdevs; dst++) {
			if (th->thdev[dst]->type != INTEL_TH_OUTPUT)
				continue;

			if (th->thdev[dst]->output.type != otype)
				continue;

			break;
		}

		/*
		 * intel_th_subdevices[src] matches our requirements and is
		 * not matched in th::thdev[]
		 */
		if (dst == th->num_thdevs)
			goto found;
	}

	return -ENODEV;

found:
	thdev = intel_th_subdevice_alloc(th, &intel_th_subdevices[src]);
	if (IS_ERR(thdev))
		return PTR_ERR(thdev);

	th->thdev[th->num_thdevs++] = thdev;

	return 0;
}
EXPORT_SYMBOL_GPL(intel_th_output_enable);

static int intel_th_populate(struct intel_th *th)
{
	int src;

	/* create devices for each intel_th_subdevice */
	for (src = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) {
		const struct intel_th_subdevice *subdev =
			&intel_th_subdevices[src];
		struct intel_th_device *thdev;

		/* only allow SOURCE and SWITCH devices in host mode */
		if ((INTEL_TH_CAP(th, host_mode_only) || host_mode) &&
		    subdev->type == INTEL_TH_OUTPUT)
			continue;

		/*
		 * don't enable port OUTPUTs in this path; SWITCH enables them
		 * via intel_th_output_enable()
		 */
		if (subdev->type == INTEL_TH_OUTPUT &&
		    subdev->otype != GTH_NONE)
			continue;

		thdev = intel_th_subdevice_alloc(th, subdev);
		/* note: caller should free subdevices from th::thdev[] */
		if (IS_ERR(thdev))
			return PTR_ERR(thdev);

		th->thdev[th->num_thdevs++] = thdev;
	}

	return 0;
}

static int match_devt(struct device *dev, void *data)
{
	dev_t devt = (dev_t)(unsigned long)data;

	return dev->devt == devt;
}

static int intel_th_output_open(struct inode *inode, struct file *file)
{
	const struct file_operations *fops;
	struct intel_th_driver *thdrv;
	struct device *dev;
	int err;

	dev = bus_find_device(&intel_th_bus, NULL,
			      (void *)(unsigned long)inode->i_rdev,
			      match_devt);
	if (!dev || !dev->driver)
		return -ENODEV;

	thdrv = to_intel_th_driver(dev->driver);
	fops = fops_get(thdrv->fops);
	if (!fops)
		return -ENODEV;

	replace_fops(file, fops);

	file->private_data = to_intel_th_device(dev);

	if (file->f_op->open) {
		err = file->f_op->open(inode, file);
		return err;
	}

	return 0;
}

static const struct file_operations intel_th_output_fops = {
	.open	= intel_th_output_open,
	.llseek	= noop_llseek,
};

/**
 * intel_th_alloc() - allocate a new Intel TH device and its subdevices
 * @dev:	parent device
 * @devres:	parent's resources
 * @ndevres:	number of resources
 * @irq:	irq number
 */
struct intel_th *
intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
	       struct resource *devres, unsigned int ndevres, int irq)
{
	struct intel_th *th;
	int err, r;

	if (irq == -1)
		for (r = 0; r < ndevres; r++)
			if (devres[r].flags & IORESOURCE_IRQ) {
				irq = devres[r].start;
				break;
			}

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

	th->id = ida_simple_get(&intel_th_ida, 0, 0, GFP_KERNEL);
	if (th->id < 0) {
		err = th->id;
		goto err_alloc;
	}

	th->major = __register_chrdev(0, 0, TH_POSSIBLE_OUTPUTS,
				      "intel_th/output", &intel_th_output_fops);
	if (th->major < 0) {
		err = th->major;
		goto err_ida;
	}
	th->dev = dev;
	th->drvdata = drvdata;

	th->resource = devres;
	th->num_resources = ndevres;
	th->irq = irq;

	dev_set_drvdata(dev, th);

	pm_runtime_no_callbacks(dev);
	pm_runtime_put(dev);
	pm_runtime_allow(dev);

	err = intel_th_populate(th);
	if (err) {
		/* free the subdevices and undo everything */
		intel_th_free(th);
		return ERR_PTR(err);
	}

	return th;

err_ida:
	ida_simple_remove(&intel_th_ida, th->id);

err_alloc:
	kfree(th);

	return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(intel_th_alloc);

void intel_th_free(struct intel_th *th)
{
	int i;

	intel_th_request_hub_module_flush(th);

	intel_th_device_remove(th->hub);
	for (i = 0; i < th->num_thdevs; i++) {
		if (th->thdev[i] != th->hub)
			intel_th_device_remove(th->thdev[i]);
		th->thdev[i] = NULL;
	}

	th->num_thdevs = 0;

	pm_runtime_get_sync(th->dev);
	pm_runtime_forbid(th->dev);

	__unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS,
			    "intel_th/output");

	ida_simple_remove(&intel_th_ida, th->id);

	kfree(th);
}
EXPORT_SYMBOL_GPL(intel_th_free);

/**
 * intel_th_trace_enable() - enable tracing for an output device
 * @thdev:	output device that requests tracing be enabled
 */
int intel_th_trace_enable(struct intel_th_device *thdev)
{
	struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent);
	struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);

	if (WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH))
		return -EINVAL;

	if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT))
		return -EINVAL;

	pm_runtime_get_sync(&thdev->dev);
	hubdrv->enable(hub, &thdev->output);

	return 0;
}
EXPORT_SYMBOL_GPL(intel_th_trace_enable);

/**
 * intel_th_trace_disable() - disable tracing for an output device
 * @thdev:	output device that requests tracing be disabled
 */
int intel_th_trace_disable(struct intel_th_device *thdev)
{
	struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent);
	struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);

	WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH);
	if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT))
		return -EINVAL;

	hubdrv->disable(hub, &thdev->output);
	pm_runtime_put(&thdev->dev);

	return 0;
}
EXPORT_SYMBOL_GPL(intel_th_trace_disable);

int intel_th_set_output(struct intel_th_device *thdev,
			unsigned int master)
{
	struct intel_th_device *hub = to_intel_th_hub(thdev);
	struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);

	/* In host mode, this is up to the external debugger, do nothing. */
	if (hub->host_mode)
		return 0;

	if (!hubdrv->set_output)
		return -ENOTSUPP;

	return hubdrv->set_output(hub, master);
}
EXPORT_SYMBOL_GPL(intel_th_set_output);

static int __init intel_th_init(void)
{
	intel_th_debug_init();

	return bus_register(&intel_th_bus);
}
subsys_initcall(intel_th_init);

static void __exit intel_th_exit(void)
{
	intel_th_debug_done();

	bus_unregister(&intel_th_bus);
}
module_exit(intel_th_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel(R) Trace Hub controller driver");
MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");
