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(>h->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(>h->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;