summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/hwtracing/intel_th/core.c26
-rw-r--r--drivers/hwtracing/intel_th/intel_th.h4
2 files changed, 22 insertions, 8 deletions
diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 79e19627b99f..cdd9b3b26195 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -29,6 +29,9 @@
#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)
@@ -527,14 +530,19 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres,
{
struct resource res[3];
unsigned int req = 0;
- int i, err;
+ int src, dst, err;
/* create devices for each intel_th_subdevice */
- for (i = 0; i < ARRAY_SIZE(intel_th_subdevices); i++) {
- struct intel_th_subdevice *subdev = &intel_th_subdevices[i];
+ for (src = 0, dst = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) {
+ const struct intel_th_subdevice *subdev =
+ &intel_th_subdevices[src];
struct intel_th_device *thdev;
int r;
+ /* only allow SOURCE and SWITCH devices in host mode */
+ if (host_mode && subdev->type == INTEL_TH_OUTPUT)
+ continue;
+
thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
subdev->id);
if (!thdev) {
@@ -577,10 +585,12 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres,
}
if (subdev->type == INTEL_TH_OUTPUT) {
- thdev->dev.devt = MKDEV(th->major, i);
+ thdev->dev.devt = MKDEV(th->major, dst);
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;
}
err = device_add(&thdev->dev);
@@ -597,14 +607,14 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres,
req++;
}
- th->thdev[i] = thdev;
+ th->thdev[dst++] = thdev;
}
return 0;
kill_subdevs:
- for (i-- ; i >= 0; i--)
- intel_th_device_remove(th->thdev[i]);
+ for (; dst >= 0; dst--)
+ intel_th_device_remove(th->thdev[dst]);
return err;
}
@@ -717,7 +727,7 @@ void intel_th_free(struct intel_th *th)
intel_th_request_hub_module_flush(th);
for (i = 0; i < TH_SUBDEVICE_MAX; i++)
- if (th->thdev[i] != th->hub)
+ if (th->thdev[i] && th->thdev[i] != th->hub)
intel_th_device_remove(th->thdev[i]);
intel_th_device_remove(th->hub);
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 4c195786bf1f..3096e7054f6d 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -54,6 +54,7 @@ struct intel_th_output {
* @num_resources: number of resources in @resource array
* @type: INTEL_TH_{SOURCE,OUTPUT,SWITCH}
* @id: device instance or -1
+ * @host_mode: Intel TH is controlled by an external debug host
* @output: output descriptor for INTEL_TH_OUTPUT devices
* @name: device name to match the driver
*/
@@ -64,6 +65,9 @@ struct intel_th_device {
unsigned int type;
int id;
+ /* INTEL_TH_SWITCH specific */
+ bool host_mode;
+
/* INTEL_TH_OUTPUT specific */
struct intel_th_output output;