summaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-09-19 10:07:47 -0400
committerAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-11-18 10:07:54 -0500
commitc49a75910c5ea9bbeb60a86350f232f6fcb13cc2 (patch)
tree34940e4cb1789aa17e9dc67b33002b27186c535c /drivers/hwtracing
parent77c98b28ee68b9e26bd1492e547cb2e5d3fcfc94 (diff)
intel_th: Support Host Debugger mode of operation
This patch adds a 'host_mode' module option to enable host-driven operational mode in the driver. In this mode, the driver does not perform trace configuration or enable trace capture, but still provides all the means necessary for software trace sources to write their data to the Trace Hub. This means that the debug host takes care of all the configuration and enabling and we do not interfere. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Diffstat (limited to 'drivers/hwtracing')
-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 @@
29#include "intel_th.h" 29#include "intel_th.h"
30#include "debug.h" 30#include "debug.h"
31 31
32static bool host_mode __read_mostly;
33module_param(host_mode, bool, 0444);
34
32static DEFINE_IDA(intel_th_ida); 35static DEFINE_IDA(intel_th_ida);
33 36
34static int intel_th_match(struct device *dev, struct device_driver *driver) 37static 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,
527{ 530{
528 struct resource res[3]; 531 struct resource res[3];
529 unsigned int req = 0; 532 unsigned int req = 0;
530 int i, err; 533 int src, dst, err;
531 534
532 /* create devices for each intel_th_subdevice */ 535 /* create devices for each intel_th_subdevice */
533 for (i = 0; i < ARRAY_SIZE(intel_th_subdevices); i++) { 536 for (src = 0, dst = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) {
534 struct intel_th_subdevice *subdev = &intel_th_subdevices[i]; 537 const struct intel_th_subdevice *subdev =
538 &intel_th_subdevices[src];
535 struct intel_th_device *thdev; 539 struct intel_th_device *thdev;
536 int r; 540 int r;
537 541
542 /* only allow SOURCE and SWITCH devices in host mode */
543 if (host_mode && subdev->type == INTEL_TH_OUTPUT)
544 continue;
545
538 thdev = intel_th_device_alloc(th, subdev->type, subdev->name, 546 thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
539 subdev->id); 547 subdev->id);
540 if (!thdev) { 548 if (!thdev) {
@@ -577,10 +585,12 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres,
577 } 585 }
578 586
579 if (subdev->type == INTEL_TH_OUTPUT) { 587 if (subdev->type == INTEL_TH_OUTPUT) {
580 thdev->dev.devt = MKDEV(th->major, i); 588 thdev->dev.devt = MKDEV(th->major, dst);
581 thdev->output.type = subdev->otype; 589 thdev->output.type = subdev->otype;
582 thdev->output.port = -1; 590 thdev->output.port = -1;
583 thdev->output.scratchpad = subdev->scrpd; 591 thdev->output.scratchpad = subdev->scrpd;
592 } else if (subdev->type == INTEL_TH_SWITCH) {
593 thdev->host_mode = host_mode;
584 } 594 }
585 595
586 err = device_add(&thdev->dev); 596 err = device_add(&thdev->dev);
@@ -597,14 +607,14 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres,
597 req++; 607 req++;
598 } 608 }
599 609
600 th->thdev[i] = thdev; 610 th->thdev[dst++] = thdev;
601 } 611 }
602 612
603 return 0; 613 return 0;
604 614
605kill_subdevs: 615kill_subdevs:
606 for (i-- ; i >= 0; i--) 616 for (; dst >= 0; dst--)
607 intel_th_device_remove(th->thdev[i]); 617 intel_th_device_remove(th->thdev[dst]);
608 618
609 return err; 619 return err;
610} 620}
@@ -717,7 +727,7 @@ void intel_th_free(struct intel_th *th)
717 727
718 intel_th_request_hub_module_flush(th); 728 intel_th_request_hub_module_flush(th);
719 for (i = 0; i < TH_SUBDEVICE_MAX; i++) 729 for (i = 0; i < TH_SUBDEVICE_MAX; i++)
720 if (th->thdev[i] != th->hub) 730 if (th->thdev[i] && th->thdev[i] != th->hub)
721 intel_th_device_remove(th->thdev[i]); 731 intel_th_device_remove(th->thdev[i]);
722 732
723 intel_th_device_remove(th->hub); 733 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 {
54 * @num_resources: number of resources in @resource array 54 * @num_resources: number of resources in @resource array
55 * @type: INTEL_TH_{SOURCE,OUTPUT,SWITCH} 55 * @type: INTEL_TH_{SOURCE,OUTPUT,SWITCH}
56 * @id: device instance or -1 56 * @id: device instance or -1
57 * @host_mode: Intel TH is controlled by an external debug host
57 * @output: output descriptor for INTEL_TH_OUTPUT devices 58 * @output: output descriptor for INTEL_TH_OUTPUT devices
58 * @name: device name to match the driver 59 * @name: device name to match the driver
59 */ 60 */
@@ -64,6 +65,9 @@ struct intel_th_device {
64 unsigned int type; 65 unsigned int type;
65 int id; 66 int id;
66 67
68 /* INTEL_TH_SWITCH specific */
69 bool host_mode;
70
67 /* INTEL_TH_OUTPUT specific */ 71 /* INTEL_TH_OUTPUT specific */
68 struct intel_th_output output; 72 struct intel_th_output output;
69 73