]> git.karo-electronics.de Git - linux-beck.git/commitdiff
intel_th: Support Host Debugger mode of operation
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>
Mon, 19 Sep 2016 14:07:47 +0000 (17:07 +0300)
committerAlexander Shishkin <alexander.shishkin@linux.intel.com>
Fri, 18 Nov 2016 15:07:54 +0000 (17:07 +0200)
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>
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/intel_th.h

index 79e19627b99fd4505097db5199dab5f2ca8da1fd..cdd9b3b26195aa38f03a910d10e483bca61edcca 100644 (file)
@@ -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);
index 4c195786bf1f21592023fbf34b82de6b5123116f..3096e7054f6dba9388690cd022fd8730029587c8 100644 (file)
@@ -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;