/*
 * Intel(R) Trace Hub driver core
 *
 * Copyright (C) 2014-2015 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#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	= TH_MMIO_SW,
				.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;
	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;

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

	for (r = 0; r < subdev->nres; r++) {
		struct resource *devres = th->resource;
		int bar = TH_MMIO_CONFIG;

		/*
		 * 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;
			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) {
		put_device(&thdev->dev);
		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 = host_mode;
		th->hub = thdev;
	}

	err = device_add(&thdev->dev);
	if (err) {
		put_device(&thdev->dev);
		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 (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;

	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);

	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>");
