// SPDX-License-Identifier: GPL-2.0
/*
 * Intel(R) Trace Hub Global Trace Hub
 *
 * 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/io.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/bitmap.h>
#include <linux/pm_runtime.h>

#include "intel_th.h"
#include "gth.h"

struct gth_device;

/**
 * struct gth_output - GTH view on an output port
 * @gth:	backlink to the GTH device
 * @output:	link to output device's output descriptor
 * @index:	output port number
 * @port_type:	one of GTH_* port type values
 * @master:	bitmap of masters configured for this output
 */
struct gth_output {
	struct gth_device	*gth;
	struct intel_th_output	*output;
	unsigned int		index;
	unsigned int		port_type;
	DECLARE_BITMAP(master, TH_CONFIGURABLE_MASTERS + 1);
};

/**
 * struct gth_device - GTH device
 * @dev:	driver core's device
 * @base:	register window base address
 * @output_group:	attributes describing output ports
 * @master_group:	attributes describing master assignments
 * @output:		output ports
 * @master:		master/output port assignments
 * @gth_lock:		serializes accesses to GTH bits
 */
struct gth_device {
	struct device		*dev;
	void __iomem		*base;

	struct attribute_group	output_group;
	struct attribute_group	master_group;
	struct gth_output	output[TH_POSSIBLE_OUTPUTS];
	signed char		master[TH_CONFIGURABLE_MASTERS + 1];
	spinlock_t		gth_lock;
};

static void gth_output_set(struct gth_device *gth, int port,
			   unsigned int config)
{
	unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0;
	u32 val;
	int shift = (port & 3) * 8;

	val = ioread32(gth->base + reg);
	val &= ~(0xff << shift);
	val |= config << shift;
	iowrite32(val, gth->base + reg);
}

static unsigned int gth_output_get(struct gth_device *gth, int port)
{
	unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0;
	u32 val;
	int shift = (port & 3) * 8;

	val = ioread32(gth->base + reg);
	val &= 0xff << shift;
	val >>= shift;

	return val;
}

static void gth_smcfreq_set(struct gth_device *gth, int port,
			    unsigned int freq)
{
	unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4);
	int shift = (port & 1) * 16;
	u32 val;

	val = ioread32(gth->base + reg);
	val &= ~(0xffff << shift);
	val |= freq << shift;
	iowrite32(val, gth->base + reg);
}

static unsigned int gth_smcfreq_get(struct gth_device *gth, int port)
{
	unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4);
	int shift = (port & 1) * 16;
	u32 val;

	val = ioread32(gth->base + reg);
	val &= 0xffff << shift;
	val >>= shift;

	return val;
}

/*
 * "masters" attribute group
 */

struct master_attribute {
	struct device_attribute	attr;
	struct gth_device	*gth;
	unsigned int		master;
};

static void
gth_master_set(struct gth_device *gth, unsigned int master, int port)
{
	unsigned int reg = REG_GTH_SWDEST0 + ((master >> 1) & ~3u);
	unsigned int shift = (master & 0x7) * 4;
	u32 val;

	if (master >= 256) {
		reg = REG_GTH_GSWTDEST;
		shift = 0;
	}

	val = ioread32(gth->base + reg);
	val &= ~(0xf << shift);
	if (port >= 0)
		val |= (0x8 | port) << shift;
	iowrite32(val, gth->base + reg);
}

static ssize_t master_attr_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct master_attribute *ma =
		container_of(attr, struct master_attribute, attr);
	struct gth_device *gth = ma->gth;
	size_t count;
	int port;

	spin_lock(&gth->gth_lock);
	port = gth->master[ma->master];
	spin_unlock(&gth->gth_lock);

	if (port >= 0)
		count = sysfs_emit(buf, "%x\n", port);
	else
		count = sysfs_emit(buf, "disabled\n");

	return count;
}

static ssize_t master_attr_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct master_attribute *ma =
		container_of(attr, struct master_attribute, attr);
	struct gth_device *gth = ma->gth;
	int old_port, port;

	if (kstrtoint(buf, 10, &port) < 0)
		return -EINVAL;

	if (port >= TH_POSSIBLE_OUTPUTS || port < -1)
		return -EINVAL;

	spin_lock(&gth->gth_lock);

	/* disconnect from the previous output port, if any */
	old_port = gth->master[ma->master];
	if (old_port >= 0) {
		gth->master[ma->master] = -1;
		clear_bit(ma->master, gth->output[old_port].master);

		/*
		 * if the port is active, program this setting,
		 * implies that runtime PM is on
		 */
		if (gth->output[old_port].output->active)
			gth_master_set(gth, ma->master, -1);
	}

	/* connect to the new output port, if any */
	if (port >= 0) {
		/* check if there's a driver for this port */
		if (!gth->output[port].output) {
			count = -ENODEV;
			goto unlock;
		}

		set_bit(ma->master, gth->output[port].master);

		/* if the port is active, program this setting, see above */
		if (gth->output[port].output->active)
			gth_master_set(gth, ma->master, port);
	}

	gth->master[ma->master] = port;

unlock:
	spin_unlock(&gth->gth_lock);

	return count;
}

struct output_attribute {
	struct device_attribute attr;
	struct gth_device	*gth;
	unsigned int		port;
	unsigned int		parm;
};

#define OUTPUT_PARM(_name, _mask, _r, _w, _what)			\
	[TH_OUTPUT_PARM(_name)] = { .name = __stringify(_name),		\
				    .get = gth_ ## _what ## _get,	\
				    .set = gth_ ## _what ## _set,	\
				    .mask = (_mask),			\
				    .readable = (_r),			\
				    .writable = (_w) }

static const struct output_parm {
	const char	*name;
	unsigned int	(*get)(struct gth_device *gth, int port);
	void		(*set)(struct gth_device *gth, int port,
			       unsigned int val);
	unsigned int	mask;
	unsigned int	readable : 1,
			writable : 1;
} output_parms[] = {
	OUTPUT_PARM(port,	0x7,	1, 0, output),
	OUTPUT_PARM(null,	BIT(3),	1, 1, output),
	OUTPUT_PARM(drop,	BIT(4),	1, 1, output),
	OUTPUT_PARM(reset,	BIT(5),	1, 0, output),
	OUTPUT_PARM(flush,	BIT(7),	0, 1, output),
	OUTPUT_PARM(smcfreq,	0xffff,	1, 1, smcfreq),
};

static void
gth_output_parm_set(struct gth_device *gth, int port, unsigned int parm,
		    unsigned int val)
{
	unsigned int config = output_parms[parm].get(gth, port);
	unsigned int mask = output_parms[parm].mask;
	unsigned int shift = __ffs(mask);

	config &= ~mask;
	config |= (val << shift) & mask;
	output_parms[parm].set(gth, port, config);
}

static unsigned int
gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm)
{
	unsigned int config = output_parms[parm].get(gth, port);
	unsigned int mask = output_parms[parm].mask;
	unsigned int shift = __ffs(mask);

	config &= mask;
	config >>= shift;
	return config;
}

/*
 * Reset outputs and sources
 */
static int intel_th_gth_reset(struct gth_device *gth)
{
	u32 reg;
	int port, i;

	reg = ioread32(gth->base + REG_GTH_SCRPD0);
	if (reg & SCRPD_DEBUGGER_IN_USE)
		return -EBUSY;

	/* Always save/restore STH and TU registers in S0ix entry/exit */
	reg |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED;
	iowrite32(reg, gth->base + REG_GTH_SCRPD0);

	/* output ports */
	for (port = 0; port < 8; port++) {
		if (gth_output_parm_get(gth, port, TH_OUTPUT_PARM(port)) ==
		    GTH_NONE)
			continue;

		gth_output_set(gth, port, 0);
		gth_smcfreq_set(gth, port, 16);
	}
	/* disable overrides */
	iowrite32(0, gth->base + REG_GTH_DESTOVR);

	/* masters swdest_0~31 and gswdest */
	for (i = 0; i < 33; i++)
		iowrite32(0, gth->base + REG_GTH_SWDEST0 + i * 4);

	/* sources */
	iowrite32(0, gth->base + REG_GTH_SCR);
	iowrite32(0xfc, gth->base + REG_GTH_SCR2);

	/* setup CTS for single trigger */
	iowrite32(CTS_EVENT_ENABLE_IF_ANYTHING, gth->base + REG_CTS_C0S0_EN);
	iowrite32(CTS_ACTION_CONTROL_SET_STATE(CTS_STATE_IDLE) |
		  CTS_ACTION_CONTROL_TRIGGER, gth->base + REG_CTS_C0S0_ACT);

	return 0;
}

/*
 * "outputs" attribute group
 */

static ssize_t output_attr_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct output_attribute *oa =
		container_of(attr, struct output_attribute, attr);
	struct gth_device *gth = oa->gth;
	size_t count;

	pm_runtime_get_sync(dev);

	spin_lock(&gth->gth_lock);
	count = sysfs_emit(buf, "%x\n",
			   gth_output_parm_get(gth, oa->port, oa->parm));
	spin_unlock(&gth->gth_lock);

	pm_runtime_put(dev);

	return count;
}

static ssize_t output_attr_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct output_attribute *oa =
		container_of(attr, struct output_attribute, attr);
	struct gth_device *gth = oa->gth;
	unsigned int config;

	if (kstrtouint(buf, 16, &config) < 0)
		return -EINVAL;

	pm_runtime_get_sync(dev);

	spin_lock(&gth->gth_lock);
	gth_output_parm_set(gth, oa->port, oa->parm, config);
	spin_unlock(&gth->gth_lock);

	pm_runtime_put(dev);

	return count;
}

static int intel_th_master_attributes(struct gth_device *gth)
{
	struct master_attribute *master_attrs;
	struct attribute **attrs;
	int i, nattrs = TH_CONFIGURABLE_MASTERS + 2;

	attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL);
	if (!attrs)
		return -ENOMEM;

	master_attrs = devm_kcalloc(gth->dev, nattrs,
				    sizeof(struct master_attribute),
				    GFP_KERNEL);
	if (!master_attrs)
		return -ENOMEM;

	for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++) {
		char *name;

		name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d%s", i,
				      i == TH_CONFIGURABLE_MASTERS ? "+" : "");
		if (!name)
			return -ENOMEM;

		master_attrs[i].attr.attr.name = name;
		master_attrs[i].attr.attr.mode = S_IRUGO | S_IWUSR;
		master_attrs[i].attr.show = master_attr_show;
		master_attrs[i].attr.store = master_attr_store;

		sysfs_attr_init(&master_attrs[i].attr.attr);
		attrs[i] = &master_attrs[i].attr.attr;

		master_attrs[i].gth = gth;
		master_attrs[i].master = i;
	}

	gth->master_group.name	= "masters";
	gth->master_group.attrs = attrs;

	return sysfs_create_group(&gth->dev->kobj, &gth->master_group);
}

static int intel_th_output_attributes(struct gth_device *gth)
{
	struct output_attribute *out_attrs;
	struct attribute **attrs;
	int i, j, nouts = TH_POSSIBLE_OUTPUTS;
	int nparms = ARRAY_SIZE(output_parms);
	int nattrs = nouts * nparms + 1;

	attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL);
	if (!attrs)
		return -ENOMEM;

	out_attrs = devm_kcalloc(gth->dev, nattrs,
				 sizeof(struct output_attribute),
				 GFP_KERNEL);
	if (!out_attrs)
		return -ENOMEM;

	for (i = 0; i < nouts; i++) {
		for (j = 0; j < nparms; j++) {
			unsigned int idx = i * nparms + j;
			char *name;

			name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d_%s", i,
					      output_parms[j].name);
			if (!name)
				return -ENOMEM;

			out_attrs[idx].attr.attr.name = name;

			if (output_parms[j].readable) {
				out_attrs[idx].attr.attr.mode |= S_IRUGO;
				out_attrs[idx].attr.show = output_attr_show;
			}

			if (output_parms[j].writable) {
				out_attrs[idx].attr.attr.mode |= S_IWUSR;
				out_attrs[idx].attr.store = output_attr_store;
			}

			sysfs_attr_init(&out_attrs[idx].attr.attr);
			attrs[idx] = &out_attrs[idx].attr.attr;

			out_attrs[idx].gth = gth;
			out_attrs[idx].port = i;
			out_attrs[idx].parm = j;
		}
	}

	gth->output_group.name	= "outputs";
	gth->output_group.attrs = attrs;

	return sysfs_create_group(&gth->dev->kobj, &gth->output_group);
}

/**
 * intel_th_gth_stop() - stop tracing to an output device
 * @gth:		GTH device
 * @output:		output device's descriptor
 * @capture_done:	set when no more traces will be captured
 *
 * This will stop tracing using force storeEn off signal and wait for the
 * pipelines to be empty for the corresponding output port.
 */
static void intel_th_gth_stop(struct gth_device *gth,
			      struct intel_th_output *output,
			      bool capture_done)
{
	struct intel_th_device *outdev =
		container_of(output, struct intel_th_device, output);
	struct intel_th_driver *outdrv =
		to_intel_th_driver(outdev->dev.driver);
	unsigned long count;
	u32 reg;
	u32 scr2 = 0xfc | (capture_done ? 1 : 0);

	iowrite32(0, gth->base + REG_GTH_SCR);
	iowrite32(scr2, gth->base + REG_GTH_SCR2);

	/* wait on pipeline empty for the given port */
	for (reg = 0, count = GTH_PLE_WAITLOOP_DEPTH;
	     count && !(reg & BIT(output->port)); count--) {
		reg = ioread32(gth->base + REG_GTH_STAT);
		cpu_relax();
	}

	if (!count)
		dev_dbg(gth->dev, "timeout waiting for GTH[%d] PLE\n",
			output->port);

	/* wait on output piepline empty */
	if (outdrv->wait_empty)
		outdrv->wait_empty(outdev);

	/* clear force capture done for next captures */
	iowrite32(0xfc, gth->base + REG_GTH_SCR2);
}

/**
 * intel_th_gth_start() - start tracing to an output device
 * @gth:	GTH device
 * @output:	output device's descriptor
 *
 * This will start tracing using force storeEn signal.
 */
static void intel_th_gth_start(struct gth_device *gth,
			       struct intel_th_output *output)
{
	u32 scr = 0xfc0000;

	if (output->multiblock)
		scr |= 0xff;

	iowrite32(scr, gth->base + REG_GTH_SCR);
	iowrite32(0, gth->base + REG_GTH_SCR2);
}

/**
 * intel_th_gth_disable() - disable tracing to an output device
 * @thdev:	GTH device
 * @output:	output device's descriptor
 *
 * This will deconfigure all masters set to output to this device,
 * disable tracing using force storeEn off signal and wait for the
 * "pipeline empty" bit for corresponding output port.
 */
static void intel_th_gth_disable(struct intel_th_device *thdev,
				 struct intel_th_output *output)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	int master;
	u32 reg;

	spin_lock(&gth->gth_lock);
	output->active = false;

	for_each_set_bit(master, gth->output[output->port].master,
			 TH_CONFIGURABLE_MASTERS + 1) {
		gth_master_set(gth, master, -1);
	}
	spin_unlock(&gth->gth_lock);

	intel_th_gth_stop(gth, output, true);

	reg = ioread32(gth->base + REG_GTH_SCRPD0);
	reg &= ~output->scratchpad;
	iowrite32(reg, gth->base + REG_GTH_SCRPD0);
}

static void gth_tscu_resync(struct gth_device *gth)
{
	u32 reg;

	reg = ioread32(gth->base + REG_TSCU_TSUCTRL);
	reg &= ~TSUCTRL_CTCRESYNC;
	iowrite32(reg, gth->base + REG_TSCU_TSUCTRL);
}

static void intel_th_gth_prepare(struct intel_th_device *thdev,
				 struct intel_th_output *output)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	int count;

	/*
	 * Wait until the output port is in reset before we start
	 * programming it.
	 */
	for (count = GTH_PLE_WAITLOOP_DEPTH;
	     count && !(gth_output_get(gth, output->port) & BIT(5)); count--)
		cpu_relax();
}

/**
 * intel_th_gth_enable() - enable tracing to an output device
 * @thdev:	GTH device
 * @output:	output device's descriptor
 *
 * This will configure all masters set to output to this device and
 * enable tracing using force storeEn signal.
 */
static void intel_th_gth_enable(struct intel_th_device *thdev,
				struct intel_th_output *output)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	struct intel_th *th = to_intel_th(thdev);
	int master;
	u32 scrpd;

	spin_lock(&gth->gth_lock);
	for_each_set_bit(master, gth->output[output->port].master,
			 TH_CONFIGURABLE_MASTERS + 1) {
		gth_master_set(gth, master, output->port);
	}

	output->active = true;
	spin_unlock(&gth->gth_lock);

	if (INTEL_TH_CAP(th, tscu_enable))
		gth_tscu_resync(gth);

	scrpd = ioread32(gth->base + REG_GTH_SCRPD0);
	scrpd |= output->scratchpad;
	iowrite32(scrpd, gth->base + REG_GTH_SCRPD0);

	intel_th_gth_start(gth, output);
}

/**
 * intel_th_gth_switch() - execute a switch sequence
 * @thdev:	GTH device
 * @output:	output device's descriptor
 *
 * This will execute a switch sequence that will trigger a switch window
 * when tracing to MSC in multi-block mode.
 */
static void intel_th_gth_switch(struct intel_th_device *thdev,
				struct intel_th_output *output)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	unsigned long count;
	u32 reg;

	/* trigger */
	iowrite32(0, gth->base + REG_CTS_CTL);
	iowrite32(CTS_CTL_SEQUENCER_ENABLE, gth->base + REG_CTS_CTL);
	/* wait on trigger status */
	for (reg = 0, count = CTS_TRIG_WAITLOOP_DEPTH;
	     count && !(reg & BIT(4)); count--) {
		reg = ioread32(gth->base + REG_CTS_STAT);
		cpu_relax();
	}
	if (!count)
		dev_dbg(&thdev->dev, "timeout waiting for CTS Trigger\n");

	/* De-assert the trigger */
	iowrite32(0, gth->base + REG_CTS_CTL);

	intel_th_gth_stop(gth, output, false);
	intel_th_gth_start(gth, output);
}

/**
 * intel_th_gth_assign() - assign output device to a GTH output port
 * @thdev:	GTH device
 * @othdev:	output device
 *
 * This will match a given output device parameters against present
 * output ports on the GTH and fill out relevant bits in output device's
 * descriptor.
 *
 * Return:	0 on success, -errno on error.
 */
static int intel_th_gth_assign(struct intel_th_device *thdev,
			       struct intel_th_device *othdev)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	int i, id;

	if (thdev->host_mode)
		return -EBUSY;

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

	for (i = 0, id = 0; i < TH_POSSIBLE_OUTPUTS; i++) {
		if (gth->output[i].port_type != othdev->output.type)
			continue;

		if (othdev->id == -1 || othdev->id == id)
			goto found;

		id++;
	}

	return -ENOENT;

found:
	spin_lock(&gth->gth_lock);
	othdev->output.port = i;
	othdev->output.active = false;
	gth->output[i].output = &othdev->output;
	spin_unlock(&gth->gth_lock);

	return 0;
}

/**
 * intel_th_gth_unassign() - deassociate an output device from its output port
 * @thdev:	GTH device
 * @othdev:	output device
 */
static void intel_th_gth_unassign(struct intel_th_device *thdev,
				  struct intel_th_device *othdev)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	int port = othdev->output.port;
	int master;

	if (thdev->host_mode)
		return;

	spin_lock(&gth->gth_lock);
	othdev->output.port = -1;
	othdev->output.active = false;
	gth->output[port].output = NULL;
	for (master = 0; master < TH_CONFIGURABLE_MASTERS + 1; master++)
		if (gth->master[master] == port)
			gth->master[master] = -1;
	spin_unlock(&gth->gth_lock);
}

static int
intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
	int port = 0; /* FIXME: make default output configurable */

	/*
	 * everything above TH_CONFIGURABLE_MASTERS is controlled by the
	 * same register
	 */
	if (master > TH_CONFIGURABLE_MASTERS)
		master = TH_CONFIGURABLE_MASTERS;

	spin_lock(&gth->gth_lock);
	if (gth->master[master] == -1) {
		set_bit(master, gth->output[port].master);
		gth->master[master] = port;
	}
	spin_unlock(&gth->gth_lock);

	return 0;
}

static int intel_th_gth_probe(struct intel_th_device *thdev)
{
	struct device *dev = &thdev->dev;
	struct intel_th *th = dev_get_drvdata(dev->parent);
	struct gth_device *gth;
	struct resource *res;
	void __iomem *base;
	int i, ret;

	res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	base = devm_ioremap(dev, res->start, resource_size(res));
	if (!base)
		return -ENOMEM;

	gth = devm_kzalloc(dev, sizeof(*gth), GFP_KERNEL);
	if (!gth)
		return -ENOMEM;

	gth->dev = dev;
	gth->base = base;
	spin_lock_init(&gth->gth_lock);

	dev_set_drvdata(dev, gth);

	/*
	 * Host mode can be signalled via SW means or via SCRPD_DEBUGGER_IN_USE
	 * bit. Either way, don't reset HW in this case, and don't export any
	 * capture configuration attributes. Also, refuse to assign output
	 * drivers to ports, see intel_th_gth_assign().
	 */
	if (thdev->host_mode)
		return 0;

	ret = intel_th_gth_reset(gth);
	if (ret) {
		if (ret != -EBUSY)
			return ret;

		thdev->host_mode = true;

		return 0;
	}

	for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++)
		gth->master[i] = -1;

	for (i = 0; i < TH_POSSIBLE_OUTPUTS; i++) {
		gth->output[i].gth = gth;
		gth->output[i].index = i;
		gth->output[i].port_type =
			gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port));
		if (gth->output[i].port_type == GTH_NONE)
			continue;

		ret = intel_th_output_enable(th, gth->output[i].port_type);
		/* -ENODEV is ok, we just won't have that device enumerated */
		if (ret && ret != -ENODEV)
			return ret;
	}

	if (intel_th_output_attributes(gth) ||
	    intel_th_master_attributes(gth)) {
		pr_warn("Can't initialize sysfs attributes\n");

		if (gth->output_group.attrs)
			sysfs_remove_group(&gth->dev->kobj, &gth->output_group);
		return -ENOMEM;
	}

	return 0;
}

static void intel_th_gth_remove(struct intel_th_device *thdev)
{
	struct gth_device *gth = dev_get_drvdata(&thdev->dev);

	sysfs_remove_group(&gth->dev->kobj, &gth->output_group);
	sysfs_remove_group(&gth->dev->kobj, &gth->master_group);
}

static struct intel_th_driver intel_th_gth_driver = {
	.probe		= intel_th_gth_probe,
	.remove		= intel_th_gth_remove,
	.assign		= intel_th_gth_assign,
	.unassign	= intel_th_gth_unassign,
	.set_output	= intel_th_gth_set_output,
	.prepare	= intel_th_gth_prepare,
	.enable		= intel_th_gth_enable,
	.trig_switch	= intel_th_gth_switch,
	.disable	= intel_th_gth_disable,
	.driver	= {
		.name	= "gth",
		.owner	= THIS_MODULE,
	},
};

module_driver(intel_th_gth_driver,
	      intel_th_driver_register,
	      intel_th_driver_unregister);

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