summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-09-19 17:27:45 +0300
committerAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-11-18 18:11:35 +0300
commitd4f5f545da12d876f5c49cef40a4a2922c75dd1e (patch)
tree6d9f57777c5f73f3735b896ea1ec0717f49950f6
parentc49a75910c5ea9bbeb60a86350f232f6fcb13cc2 (diff)
downloadlinux-d4f5f545da12d876f5c49cef40a4a2922c75dd1e.tar.xz
intel_th: gth: Handle host mode correctly
When detecting host debugger mode either though a module option or via the scratchpad register, do not export any configuration or capture related attributes to userspace and refuse attempts by the output drivers to configure output ports. This way, GTH can still act as a hub and ensure that the other components that rely on its presence continue to function properly, namely the source devices. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
-rw-r--r--drivers/hwtracing/intel_th/gth.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c
index 33e09369a491..dd32d0bad687 100644
--- a/drivers/hwtracing/intel_th/gth.c
+++ b/drivers/hwtracing/intel_th/gth.c
@@ -564,6 +564,9 @@ static int intel_th_gth_assign(struct intel_th_device *thdev,
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;
@@ -600,6 +603,9 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev,
struct gth_device *gth = dev_get_drvdata(&thdev->dev);
int port = othdev->output.port;
+ if (thdev->host_mode)
+ return;
+
spin_lock(&gth->gth_lock);
othdev->output.port = -1;
othdev->output.active = false;
@@ -654,9 +660,24 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
gth->base = base;
spin_lock_init(&gth->gth_lock);
+ /*
+ * 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)
+ goto done;
+
ret = intel_th_gth_reset(gth);
- if (ret)
- return ret;
+ if (ret) {
+ if (ret != -EBUSY)
+ return ret;
+
+ thdev->host_mode = true;
+
+ goto done;
+ }
for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++)
gth->master[i] = -1;
@@ -677,6 +698,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
return -ENOMEM;
}
+done:
dev_set_drvdata(dev, gth);
return 0;