All of lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL 00/15] stm class/intel_th: Updates for 4.14
@ 2017-08-25 16:15 Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 01/15] stm: Potential read overflow in stm_char_policy_set_ioctl() Alexander Shishkin
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

Hi Greg,

These are the changes I have queued for 4.14. These are mostly updates for
intel_th: added support for a new output type, Cannon Lake PCH PCI IDs, a
rework for the subdevice management code, and better support for IOMMU.
STM side has one fix and one documentation update.

As usual, these are checkpatch/sparse/smatch/cppcheck/coccinelle clean.
Please consider pulling. Thanks!

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git tags/stm-for-greg-20170825

for you to fetch changes up to a0e7df335afd2a8a8a688251ffee375b58b6517c:

  intel_th: Perform time resync on capture start (2017-08-25 18:48:00 +0300)

----------------------------------------------------------------
stm class / intel_th: Updates for 4.14

Intel TH:
 * Updated subdevice management code to better fit host mode
 * Added support for Low Power Path (LPP) output type
 * Fixed memory allocation with IOMMU enabled (DMAR tables)
 * Added Cannon Lake PCH PCI IDs
 * Added a quirk to force time sync on devices that need it

STM:
 * Fixed potential read overflow in ioctl()
 * Documented stm_ftrace source.

----------------------------------------------------------------
Alexander Shishkin (13):
      intel_th: pci: Enable bus mastering
      intel_th: Output devices without ports don't need assigning
      intel_th: Streamline the subdevice tree accessors
      intel_th: Make SOURCE devices children of the root device
      intel_th: Make the switch allocate its subdevices
      intel_th: msu: Use the real device in case of IOMMU domain allocation
      intel_th: Enumerate Low Power Path output port type
      intel_th: pti: Support Low Power Path output port type
      intel_th: pci: Add Cannon Lake PCH-H support
      intel_th: pci: Add Cannon Lake PCH-LP support
      intel_th: pci: Use drvdata for quirks
      intel_th: Add global activate/deactivate callbacks for the glue layers
      intel_th: Perform time resync on capture start

Chunyan Zhang (1):
      stm class: Document the stm_ftrace

Dan Carpenter (1):
      stm: Potential read overflow in stm_char_policy_set_ioctl()

 Documentation/trace/stm.txt           |  13 +-
 drivers/hwtracing/intel_th/core.c     | 359 ++++++++++++++++++++++++----------
 drivers/hwtracing/intel_th/gth.c      |  40 +++-
 drivers/hwtracing/intel_th/gth.h      |   5 +
 drivers/hwtracing/intel_th/intel_th.h | 104 ++++++++--
 drivers/hwtracing/intel_th/msu.c      |  12 +-
 drivers/hwtracing/intel_th/pci.c      |  67 ++++++-
 drivers/hwtracing/intel_th/pti.c      | 115 ++++++++++-
 drivers/hwtracing/intel_th/pti.h      |   8 +
 drivers/hwtracing/stm/core.c          |   2 +-
 10 files changed, 573 insertions(+), 152 deletions(-)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [GIT PULL 01/15] stm: Potential read overflow in stm_char_policy_set_ioctl()
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 02/15] stm class: Document the stm_ftrace Alexander Shishkin
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH
  Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Dan Carpenter,
	Alexander Shishkin

From: Dan Carpenter <dan.carpenter@oracle.com>

The "size" variable comes from the user so we need to verify that it's
large enough to hold an stp_policy_id struct.

Fixes: 7bd1d4093c2f ("stm class: Introduce an abstraction for System Trace Module devices")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/stm/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index 0e731143f6..9414900575 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -566,7 +566,7 @@ static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg)
 	if (copy_from_user(&size, arg, sizeof(size)))
 		return -EFAULT;
 
-	if (size >= PATH_MAX + sizeof(*id))
+	if (size < sizeof(*id) || size >= PATH_MAX + sizeof(*id))
 		return -EINVAL;
 
 	/*
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 02/15] stm class: Document the stm_ftrace
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 01/15] stm: Potential read overflow in stm_char_policy_set_ioctl() Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 03/15] intel_th: pci: Enable bus mastering Alexander Shishkin
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH
  Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Chunyan Zhang,
	Alexander Shishkin

From: Chunyan Zhang <chunyan.zhang@spreadtrum.com>

This patch adds a description to the stm_ftrace device source, an
interface for collecting Ftrace's function trace information via
STM devices.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 Documentation/trace/stm.txt | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/trace/stm.txt b/Documentation/trace/stm.txt
index 11cff47eec..0376575010 100644
--- a/Documentation/trace/stm.txt
+++ b/Documentation/trace/stm.txt
@@ -83,7 +83,7 @@ by writing the name of the desired stm device there, for example:
 $ echo dummy_stm.0 > /sys/class/stm_source/console/stm_source_link
 
 For examples on how to use stm_source interface in the kernel, refer
-to stm_console or stm_heartbeat drivers.
+to stm_console, stm_heartbeat or stm_ftrace drivers.
 
 Each stm_source device will need to assume a master and a range of
 channels, depending on how many channels it requires. These are
@@ -107,5 +107,16 @@ console in the STP stream, create a "console" policy entry (see the
 beginning of this text on how to do that). When initialized, it will
 consume one channel.
 
+stm_ftrace
+==========
+
+This is another "stm_source" device, once the stm_ftrace has been
+linked with an stm device, and if "function" tracer is enabled,
+function address and parent function address which Ftrace subsystem
+would store into ring buffer will be exported via the stm device at
+the same time.
+
+Currently only Ftrace "function" tracer is supported.
+
 [1] https://software.intel.com/sites/default/files/managed/d3/3c/intel-th-developer-manual.pdf
 [2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0444b/index.html
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 03/15] intel_th: pci: Enable bus mastering
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 01/15] stm: Potential read overflow in stm_char_policy_set_ioctl() Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 02/15] stm class: Document the stm_ftrace Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 04/15] intel_th: Output devices without ports don't need assigning Alexander Shishkin
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

The driver forgets to enable bus mastering for the PCI device.
Fix this.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
index 590cf90dd2..aac7d66d6a 100644
--- a/drivers/hwtracing/intel_th/pci.c
+++ b/drivers/hwtracing/intel_th/pci.c
@@ -46,6 +46,8 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
 	if (IS_ERR(th))
 		return PTR_ERR(th);
 
+	pci_set_master(pdev);
+
 	return 0;
 }
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 04/15] intel_th: Output devices without ports don't need assigning
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (2 preceding siblings ...)
  2017-08-25 16:15 ` [GIT PULL 03/15] intel_th: pci: Enable bus mastering Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 05/15] intel_th: Streamline the subdevice tree accessors Alexander Shishkin
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

Output subdevices that rely on other output subdevices (or otherwise
don't directly talk to an output port on the switch) don't need to be
assigned an output port either.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/intel_th.h | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 3096e7054f..c03f28ef64 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -96,6 +96,16 @@ intel_th_device_get_resource(struct intel_th_device *thdev, unsigned int type,
 	return NULL;
 }
 
+/*
+ * GTH, output ports configuration
+ */
+enum {
+	GTH_NONE = 0,
+	GTH_MSU,	/* memory/usb */
+	GTH_CTP,	/* Common Trace Port */
+	GTH_PTI = 4,	/* MIPI-PTI */
+};
+
 /**
  * intel_th_output_assigned() - if an output device is assigned to a switch port
  * @thdev:	the output device
@@ -106,7 +116,8 @@ static inline bool
 intel_th_output_assigned(struct intel_th_device *thdev)
 {
 	return thdev->type == INTEL_TH_OUTPUT &&
-		thdev->output.port >= 0;
+		(thdev->output.port >= 0 ||
+		 thdev->output.type == GTH_NONE);
 }
 
 /**
@@ -249,16 +260,6 @@ enum {
 	REG_DCIH_LENGTH		= REG_MSU_LENGTH,
 };
 
-/*
- * GTH, output ports configuration
- */
-enum {
-	GTH_NONE = 0,
-	GTH_MSU,	/* memory/usb */
-	GTH_CTP,	/* Common Trace Port */
-	GTH_PTI = 4,	/* MIPI-PTI */
-};
-
 /*
  * Scratchpad bits: tell firmware and external debuggers
  * what we are up to.
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 05/15] intel_th: Streamline the subdevice tree accessors
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (3 preceding siblings ...)
  2017-08-25 16:15 ` [GIT PULL 04/15] intel_th: Output devices without ports don't need assigning Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 06/15] intel_th: Make SOURCE devices children of the root device Alexander Shishkin
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

Make to_intel_th*() accessors available from the main header file.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     | 15 ---------------
 drivers/hwtracing/intel_th/intel_th.h | 25 ++++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 8da567abc0..e6d302ba17 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -156,21 +156,6 @@ static struct device_type intel_th_source_device_type = {
 	.release	= intel_th_device_release,
 };
 
-static struct intel_th *to_intel_th(struct intel_th_device *thdev)
-{
-	/*
-	 * subdevice tree is flat: if this one is not a switch, its
-	 * parent must be
-	 */
-	if (thdev->type != INTEL_TH_SWITCH)
-		thdev = to_intel_th_hub(thdev);
-
-	if (WARN_ON_ONCE(!thdev || thdev->type != INTEL_TH_SWITCH))
-		return NULL;
-
-	return dev_get_drvdata(thdev->dev.parent);
-}
-
 static char *intel_th_output_devnode(struct device *dev, umode_t *mode,
 				     kuid_t *uid, kgid_t *gid)
 {
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index c03f28ef64..496286ce79 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -173,7 +173,7 @@ struct intel_th_driver {
 	((_d) ? to_intel_th_driver(_d) : NULL)
 
 static inline struct intel_th_device *
-to_intel_th_hub(struct intel_th_device *thdev)
+to_intel_th_parent(struct intel_th_device *thdev)
 {
 	struct device *parent = thdev->dev.parent;
 
@@ -183,6 +183,29 @@ to_intel_th_hub(struct intel_th_device *thdev)
 	return to_intel_th_device(parent);
 }
 
+static inline struct intel_th_device *
+to_intel_th_hub(struct intel_th_device *thdev)
+{
+	/*
+	 * subdevice tree is flat: if this one is not a switch, its
+	 * parent must be
+	 */
+	if (thdev->type == INTEL_TH_SWITCH)
+		return thdev;
+
+	return to_intel_th_parent(thdev);
+}
+
+static inline struct intel_th *to_intel_th(struct intel_th_device *thdev)
+{
+	thdev = to_intel_th_hub(thdev);
+
+	if (WARN_ON_ONCE(!thdev || thdev->type != INTEL_TH_SWITCH))
+		return NULL;
+
+	return dev_get_drvdata(thdev->dev.parent);
+}
+
 struct intel_th *
 intel_th_alloc(struct device *dev, struct resource *devres,
 	       unsigned int ndevres, int irq);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 06/15] intel_th: Make SOURCE devices children of the root device
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (4 preceding siblings ...)
  2017-08-25 16:15 ` [GIT PULL 05/15] intel_th: Streamline the subdevice tree accessors Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 07/15] intel_th: Make the switch allocate its subdevices Alexander Shishkin
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

The switch (GTH) does not directly interact with SOURCE type devices and
may not even be present (in host mode). To reflect this and avoid
inconsistencies between target and host mode, make SOURCE devices
descendant directly from the root (i.e. PCI) device. Their symlinks
will no longer appear under the switch device, but they can still
be found under intel_th bus.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     |  6 +++---
 drivers/hwtracing/intel_th/intel_th.h | 39 +++++++++++++++++++++--------------
 2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index e6d302ba17..323d3ac8d4 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -311,10 +311,10 @@ intel_th_device_alloc(struct intel_th *th, unsigned int type, const char *name,
 	struct device *parent;
 	struct intel_th_device *thdev;
 
-	if (type == INTEL_TH_SWITCH)
-		parent = th->dev;
-	else
+	if (type == INTEL_TH_OUTPUT)
 		parent = &th->hub->dev;
+	else
+		parent = th->dev;
 
 	thdev = kzalloc(sizeof(*thdev) + strlen(name) + 1, GFP_KERNEL);
 	if (!thdev)
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 496286ce79..6243ac1b8b 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -172,6 +172,16 @@ struct intel_th_driver {
 #define to_intel_th_driver_or_null(_d)		\
 	((_d) ? to_intel_th_driver(_d) : NULL)
 
+/*
+ * Subdevice tree structure is as follows:
+ * + struct intel_th device (pci; dev_{get,set}_drvdata()
+ *   + struct intel_th_device INTEL_TH_SWITCH (GTH)
+ *     + struct intel_th_device INTEL_TH_OUTPUT (MSU, PTI)
+ *   + struct intel_th_device INTEL_TH_SOURCE (STH)
+ *
+ * In other words, INTEL_TH_OUTPUT devices are children of INTEL_TH_SWITCH;
+ * INTEL_TH_SWITCH and INTEL_TH_SOURCE are children of the intel_th device.
+ */
 static inline struct intel_th_device *
 to_intel_th_parent(struct intel_th_device *thdev)
 {
@@ -183,24 +193,12 @@ to_intel_th_parent(struct intel_th_device *thdev)
 	return to_intel_th_device(parent);
 }
 
-static inline struct intel_th_device *
-to_intel_th_hub(struct intel_th_device *thdev)
-{
-	/*
-	 * subdevice tree is flat: if this one is not a switch, its
-	 * parent must be
-	 */
-	if (thdev->type == INTEL_TH_SWITCH)
-		return thdev;
-
-	return to_intel_th_parent(thdev);
-}
-
 static inline struct intel_th *to_intel_th(struct intel_th_device *thdev)
 {
-	thdev = to_intel_th_hub(thdev);
+	if (thdev->type == INTEL_TH_OUTPUT)
+		thdev = to_intel_th_parent(thdev);
 
-	if (WARN_ON_ONCE(!thdev || thdev->type != INTEL_TH_SWITCH))
+	if (WARN_ON_ONCE(!thdev || thdev->type == INTEL_TH_OUTPUT))
 		return NULL;
 
 	return dev_get_drvdata(thdev->dev.parent);
@@ -254,6 +252,17 @@ struct intel_th {
 #endif
 };
 
+static inline struct intel_th_device *
+to_intel_th_hub(struct intel_th_device *thdev)
+{
+	if (thdev->type == INTEL_TH_SWITCH)
+		return thdev;
+	else if (thdev->type == INTEL_TH_OUTPUT)
+		return to_intel_th_parent(thdev);
+
+	return to_intel_th(thdev)->hub;
+}
+
 /*
  * Register windows
  */
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 07/15] intel_th: Make the switch allocate its subdevices
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (5 preceding siblings ...)
  2017-08-25 16:15 ` [GIT PULL 06/15] intel_th: Make SOURCE devices children of the root device Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:15 ` [GIT PULL 08/15] intel_th: msu: Use the real device in case of IOMMU domain allocation Alexander Shishkin
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

Instead of allocating devices for every possible output subdevice,
allow the switch to allocate only the ones that it knows about.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     | 288 ++++++++++++++++++++++++----------
 drivers/hwtracing/intel_th/gth.c      |  17 +-
 drivers/hwtracing/intel_th/intel_th.h |  13 +-
 3 files changed, 230 insertions(+), 88 deletions(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 323d3ac8d4..4f569593db 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -101,17 +101,53 @@ static int intel_th_probe(struct device *dev)
 	return ret;
 }
 
+static void intel_th_device_remove(struct intel_th_device *thdev);
+
 static int intel_th_remove(struct device *dev)
 {
 	struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver);
 	struct intel_th_device *thdev = to_intel_th_device(dev);
-	struct intel_th_device *hub = to_intel_th_device(dev->parent);
+	struct intel_th_device *hub = to_intel_th_hub(thdev);
 	int err;
 
 	if (thdev->type == INTEL_TH_SWITCH) {
+		struct intel_th *th = to_intel_th(hub);
+		int i, lowest;
+
+		/* disconnect outputs */
 		err = device_for_each_child(dev, thdev, intel_th_child_remove);
 		if (err)
 			return err;
+
+		/*
+		 * Remove outputs, that is, hub's children: they are created
+		 * at hub's probe time by having the hub call
+		 * intel_th_output_enable() for each of them.
+		 */
+		for (i = 0, lowest = -1; i < th->num_thdevs; i++) {
+			/*
+			 * Move the non-output devices from higher up the
+			 * th->thdev[] array to lower positions to maintain
+			 * a contiguous array.
+			 */
+			if (th->thdev[i]->type != INTEL_TH_OUTPUT) {
+				if (lowest >= 0) {
+					th->thdev[lowest] = th->thdev[i];
+					th->thdev[i] = NULL;
+					++lowest;
+				}
+
+				continue;
+			}
+
+			if (lowest == -1)
+				lowest = i;
+
+			intel_th_device_remove(th->thdev[i]);
+			th->thdev[i] = NULL;
+		}
+
+		th->num_thdevs = lowest;
 	}
 
 	if (thdrv->attr_group)
@@ -377,7 +413,7 @@ static const struct intel_th_subdevice {
 	unsigned		otype;
 	unsigned		scrpd;
 	int			id;
-} intel_th_subdevices[TH_SUBDEVICE_MAX] = {
+} intel_th_subdevices[] = {
 	{
 		.nres	= 1,
 		.res	= {
@@ -511,98 +547,181 @@ static inline void intel_th_request_hub_module_flush(struct intel_th *th)
 }
 #endif /* CONFIG_MODULES */
 
-static int intel_th_populate(struct intel_th *th, struct resource *devres,
-			     unsigned int ndevres, int irq)
+static struct intel_th_device *
+intel_th_subdevice_alloc(struct intel_th *th,
+			 const struct intel_th_subdevice *subdev)
 {
+	struct intel_th_device *thdev;
 	struct resource res[3];
 	unsigned int req = 0;
-	int src, dst, err;
+	int r, err;
 
-	/* create devices for each intel_th_subdevice */
-	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;
+	thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
+				      subdev->id);
+	if (!thdev)
+		return ERR_PTR(-ENOMEM);
 
-		/* 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) {
-			err = -ENOMEM;
-			goto kill_subdevs;
+	memcpy(res, subdev->res,
+	       sizeof(struct resource) * subdev->nres);
+
+	for (r = 0; r < subdev->nres; r++) {
+		struct resource *devres = th->resource;
+		int bar = TH_MMIO_CONFIG;
+
+		/*
+		 * Take .end == 0 to mean 'take the whole bar',
+		 * .start then tells us which bar it is. Default to
+		 * TH_MMIO_CONFIG.
+		 */
+		if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
+			bar = res[r].start;
+			res[r].start = 0;
+			res[r].end = resource_size(&devres[bar]) - 1;
 		}
 
-		memcpy(res, subdev->res,
-		       sizeof(struct resource) * subdev->nres);
+		if (res[r].flags & IORESOURCE_MEM) {
+			res[r].start	+= devres[bar].start;
+			res[r].end	+= devres[bar].start;
 
-		for (r = 0; r < subdev->nres; r++) {
-			int bar = TH_MMIO_CONFIG;
+			dev_dbg(th->dev, "%s:%d @ %pR\n",
+				subdev->name, r, &res[r]);
+		} else if (res[r].flags & IORESOURCE_IRQ) {
+			res[r].start	= th->irq;
+		}
+	}
 
-			/*
-			 * Take .end == 0 to mean 'take the whole bar',
-			 * .start then tells us which bar it is. Default to
-			 * TH_MMIO_CONFIG.
-			 */
-			if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
-				bar = res[r].start;
-				res[r].start = 0;
-				res[r].end = resource_size(&devres[bar]) - 1;
-			}
+	err = intel_th_device_add_resources(thdev, res, subdev->nres);
+	if (err) {
+		put_device(&thdev->dev);
+		goto fail_put_device;
+	}
 
-			if (res[r].flags & IORESOURCE_MEM) {
-				res[r].start	+= devres[bar].start;
-				res[r].end	+= devres[bar].start;
+	if (subdev->type == INTEL_TH_OUTPUT) {
+		thdev->dev.devt = MKDEV(th->major, th->num_thdevs);
+		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;
+		th->hub = thdev;
+	}
 
-				dev_dbg(th->dev, "%s:%d @ %pR\n",
-					subdev->name, r, &res[r]);
-			} else if (res[r].flags & IORESOURCE_IRQ) {
-				res[r].start	= irq;
-			}
-		}
+	err = device_add(&thdev->dev);
+	if (err) {
+		put_device(&thdev->dev);
+		goto fail_free_res;
+	}
 
-		err = intel_th_device_add_resources(thdev, res, subdev->nres);
-		if (err) {
-			put_device(&thdev->dev);
-			goto kill_subdevs;
-		}
+	/* need switch driver to be loaded to enumerate the rest */
+	if (subdev->type == INTEL_TH_SWITCH && !req) {
+		err = intel_th_request_hub_module(th);
+		if (!err)
+			req++;
+	}
 
-		if (subdev->type == INTEL_TH_OUTPUT) {
-			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;
-		}
+	return thdev;
+
+fail_free_res:
+	kfree(thdev->resource);
+
+fail_put_device:
+	put_device(&thdev->dev);
+
+	return ERR_PTR(err);
+}
 
-		err = device_add(&thdev->dev);
-		if (err) {
-			put_device(&thdev->dev);
-			goto kill_subdevs;
+/**
+ * intel_th_output_enable() - find and enable a device for a given output type
+ * @th:		Intel TH instance
+ * @otype:	output type
+ *
+ * Go through the unallocated output devices, find the first one whos type
+ * matches @otype and instantiate it. These devices are removed when the hub
+ * device is removed, see intel_th_remove().
+ */
+int intel_th_output_enable(struct intel_th *th, unsigned int otype)
+{
+	struct intel_th_device *thdev;
+	int src = 0, dst = 0;
+
+	for (src = 0, dst = 0; dst <= th->num_thdevs; src++, dst++) {
+		for (; src < ARRAY_SIZE(intel_th_subdevices); src++) {
+			if (intel_th_subdevices[src].type != INTEL_TH_OUTPUT)
+				continue;
+
+			if (intel_th_subdevices[src].otype != otype)
+				continue;
+
+			break;
 		}
 
-		/* need switch driver to be loaded to enumerate the rest */
-		if (subdev->type == INTEL_TH_SWITCH && !req) {
-			th->hub = thdev;
-			err = intel_th_request_hub_module(th);
-			if (!err)
-				req++;
+		/* no unallocated matching subdevices */
+		if (src == ARRAY_SIZE(intel_th_subdevices))
+			return -ENODEV;
+
+		for (; dst < th->num_thdevs; dst++) {
+			if (th->thdev[dst]->type != INTEL_TH_OUTPUT)
+				continue;
+
+			if (th->thdev[dst]->output.type != otype)
+				continue;
+
+			break;
 		}
 
-		th->thdev[dst++] = thdev;
+		/*
+		 * intel_th_subdevices[src] matches our requirements and is
+		 * not matched in th::thdev[]
+		 */
+		if (dst == th->num_thdevs)
+			goto found;
 	}
 
+	return -ENODEV;
+
+found:
+	thdev = intel_th_subdevice_alloc(th, &intel_th_subdevices[src]);
+	if (IS_ERR(thdev))
+		return PTR_ERR(thdev);
+
+	th->thdev[th->num_thdevs++] = thdev;
+
 	return 0;
+}
+EXPORT_SYMBOL_GPL(intel_th_output_enable);
 
-kill_subdevs:
-	for (; dst >= 0; dst--)
-		intel_th_device_remove(th->thdev[dst]);
+static int intel_th_populate(struct intel_th *th)
+{
+	int src;
 
-	return err;
+	/* create devices for each intel_th_subdevice */
+	for (src = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) {
+		const struct intel_th_subdevice *subdev =
+			&intel_th_subdevices[src];
+		struct intel_th_device *thdev;
+
+		/* only allow SOURCE and SWITCH devices in host mode */
+		if (host_mode && subdev->type == INTEL_TH_OUTPUT)
+			continue;
+
+		/*
+		 * don't enable port OUTPUTs in this path; SWITCH enables them
+		 * via intel_th_output_enable()
+		 */
+		if (subdev->type == INTEL_TH_OUTPUT &&
+		    subdev->otype != GTH_NONE)
+			continue;
+
+		thdev = intel_th_subdevice_alloc(th, subdev);
+		/* note: caller should free subdevices from th::thdev[] */
+		if (IS_ERR(thdev))
+			return PTR_ERR(thdev);
+
+		th->thdev[th->num_thdevs++] = thdev;
+	}
+
+	return 0;
 }
 
 static int match_devt(struct device *dev, void *data)
@@ -679,24 +798,25 @@ intel_th_alloc(struct device *dev, struct resource *devres,
 	}
 	th->dev = dev;
 
+	th->resource = devres;
+	th->num_resources = ndevres;
+	th->irq = irq;
+
 	dev_set_drvdata(dev, th);
 
 	pm_runtime_no_callbacks(dev);
 	pm_runtime_put(dev);
 	pm_runtime_allow(dev);
 
-	err = intel_th_populate(th, devres, ndevres, irq);
-	if (err)
-		goto err_chrdev;
+	err = intel_th_populate(th);
+	if (err) {
+		/* free the subdevices and undo everything */
+		intel_th_free(th);
+		return ERR_PTR(err);
+	}
 
 	return th;
 
-err_chrdev:
-	pm_runtime_forbid(dev);
-
-	__unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS,
-			    "intel_th/output");
-
 err_ida:
 	ida_simple_remove(&intel_th_ida, th->id);
 
@@ -712,11 +832,15 @@ void intel_th_free(struct intel_th *th)
 	int i;
 
 	intel_th_request_hub_module_flush(th);
-	for (i = 0; i < TH_SUBDEVICE_MAX; i++)
-		if (th->thdev[i] && th->thdev[i] != th->hub)
-			intel_th_device_remove(th->thdev[i]);
 
 	intel_th_device_remove(th->hub);
+	for (i = 0; i < th->num_thdevs; i++) {
+		if (th->thdev[i] != th->hub)
+			intel_th_device_remove(th->thdev[i]);
+		th->thdev[i] = NULL;
+	}
+
+	th->num_thdevs = 0;
 
 	pm_runtime_get_sync(th->dev);
 	pm_runtime_forbid(th->dev);
diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c
index dd32d0bad6..7d9d667fe0 100644
--- a/drivers/hwtracing/intel_th/gth.c
+++ b/drivers/hwtracing/intel_th/gth.c
@@ -639,6 +639,7 @@ intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master)
 static int intel_th_gth_probe(struct intel_th_device *thdev)
 {
 	struct device *dev = &thdev->dev;
+	struct intel_th *th = dev_get_drvdata(dev->parent);
 	struct gth_device *gth;
 	struct resource *res;
 	void __iomem *base;
@@ -660,6 +661,8 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
 	gth->base = base;
 	spin_lock_init(&gth->gth_lock);
 
+	dev_set_drvdata(dev, gth);
+
 	/*
 	 * 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
@@ -667,7 +670,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
 	 * drivers to ports, see intel_th_gth_assign().
 	 */
 	if (thdev->host_mode)
-		goto done;
+		return 0;
 
 	ret = intel_th_gth_reset(gth);
 	if (ret) {
@@ -676,7 +679,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
 
 		thdev->host_mode = true;
 
-		goto done;
+		return 0;
 	}
 
 	for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++)
@@ -687,6 +690,13 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
 		gth->output[i].index = i;
 		gth->output[i].port_type =
 			gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port));
+		if (gth->output[i].port_type == GTH_NONE)
+			continue;
+
+		ret = intel_th_output_enable(th, gth->output[i].port_type);
+		/* -ENODEV is ok, we just won't have that device enumerated */
+		if (ret && ret != -ENODEV)
+			return ret;
 	}
 
 	if (intel_th_output_attributes(gth) ||
@@ -698,9 +708,6 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
 		return -ENOMEM;
 	}
 
-done:
-	dev_set_drvdata(dev, gth);
-
 	return 0;
 }
 
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 6243ac1b8b..d44da50be3 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -216,6 +216,7 @@ int intel_th_trace_enable(struct intel_th_device *thdev);
 int intel_th_trace_disable(struct intel_th_device *thdev);
 int intel_th_set_output(struct intel_th_device *thdev,
 			unsigned int master);
+int intel_th_output_enable(struct intel_th *th, unsigned int otype);
 
 enum {
 	TH_MMIO_CONFIG = 0,
@@ -223,8 +224,9 @@ enum {
 	TH_MMIO_END,
 };
 
-#define TH_SUBDEVICE_MAX	6
 #define TH_POSSIBLE_OUTPUTS	8
+/* Total number of possible subdevices: outputs + GTH + STH */
+#define TH_SUBDEVICE_MAX	(TH_POSSIBLE_OUTPUTS + 2)
 #define TH_CONFIGURABLE_MASTERS 256
 #define TH_MSC_MAX		2
 
@@ -233,6 +235,10 @@ enum {
  * @dev:	driver core's device
  * @thdev:	subdevices
  * @hub:	"switch" subdevice (GTH)
+ * @resource:	resources of the entire controller
+ * @num_thdevs:	number of devices in the @thdev array
+ * @num_resources:	number or resources in the @resource array
+ * @irq:	irq number
  * @id:		this Intel TH controller's device ID in the system
  * @major:	device node major for output devices
  */
@@ -242,6 +248,11 @@ struct intel_th {
 	struct intel_th_device	*thdev[TH_SUBDEVICE_MAX];
 	struct intel_th_device	*hub;
 
+	struct resource		*resource;
+	unsigned int		num_thdevs;
+	unsigned int		num_resources;
+	int			irq;
+
 	int			id;
 	int			major;
 #ifdef CONFIG_MODULES
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 08/15] intel_th: msu: Use the real device in case of IOMMU domain allocation
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (6 preceding siblings ...)
  2017-08-25 16:15 ` [GIT PULL 07/15] intel_th: Make the switch allocate its subdevices Alexander Shishkin
@ 2017-08-25 16:15 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 09/15] intel_th: Enumerate Low Power Path output port type Alexander Shishkin
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

When allocating DMA buffers for the MSU, use the real device instead
of GTH.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/msu.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
index dbbe31df74..dfb57eaa9f 100644
--- a/drivers/hwtracing/intel_th/msu.c
+++ b/drivers/hwtracing/intel_th/msu.c
@@ -709,17 +709,17 @@ static int msc_buffer_win_alloc(struct msc *msc, unsigned int nr_blocks)
 	}
 
 	for (i = 0; i < nr_blocks; i++) {
-		win->block[i].bdesc = dma_alloc_coherent(msc_dev(msc), size,
-							 &win->block[i].addr,
-							 GFP_KERNEL);
+		win->block[i].bdesc =
+			dma_alloc_coherent(msc_dev(msc)->parent->parent, size,
+					   &win->block[i].addr, GFP_KERNEL);
+
+		if (!win->block[i].bdesc)
+			goto err_nomem;
 
 #ifdef CONFIG_X86
 		/* Set the page as uncached */
 		set_memory_uc((unsigned long)win->block[i].bdesc, 1);
 #endif
-
-		if (!win->block[i].bdesc)
-			goto err_nomem;
 	}
 
 	win->msc = msc;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 09/15] intel_th: Enumerate Low Power Path output port type
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (7 preceding siblings ...)
  2017-08-25 16:15 ` [GIT PULL 08/15] intel_th: msu: Use the real device in case of IOMMU domain allocation Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 10/15] intel_th: pti: Support " Alexander Shishkin
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

Trace Hub 2.x adds Low Power Path (LPP) output port type, which provides
a low power mode trace path from sources to PTI or BSSB.

This adds an output subdevice for the LPP port.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     | 15 +++++++++++++++
 drivers/hwtracing/intel_th/intel_th.h |  3 ++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 4f569593db..d1760003b4 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -500,6 +500,21 @@ static const struct intel_th_subdevice {
 		.otype	= GTH_PTI,
 		.scrpd	= SCRPD_PTI_IS_PRIM_DEST,
 	},
+	{
+		.nres	= 1,
+		.res	= {
+			{
+				.start	= REG_PTI_OFFSET,
+				.end	= REG_PTI_OFFSET + REG_PTI_LENGTH - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+		},
+		.id	= -1,
+		.name	= "lpp",
+		.type	= INTEL_TH_OUTPUT,
+		.otype	= GTH_LPP,
+		.scrpd	= SCRPD_PTI_IS_PRIM_DEST,
+	},
 	{
 		.nres	= 1,
 		.res	= {
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index d44da50be3..3f4558404d 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -103,7 +103,8 @@ enum {
 	GTH_NONE = 0,
 	GTH_MSU,	/* memory/usb */
 	GTH_CTP,	/* Common Trace Port */
-	GTH_PTI = 4,	/* MIPI-PTI */
+	GTH_LPP,	/* Low Power Path */
+	GTH_PTI,	/* MIPI-PTI */
 };
 
 /**
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 10/15] intel_th: pti: Support Low Power Path output port type
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (8 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 09/15] intel_th: Enumerate Low Power Path output port type Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 11/15] intel_th: pci: Add Cannon Lake PCH-H support Alexander Shishkin
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

The Low Power Path (LPP) output port type, looks mostly like PTI to
the software, with a few additional bits in the control register.

This extends the PTI driver to support LPP ports as well.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/pti.c | 115 +++++++++++++++++++++++++++++++++++++--
 drivers/hwtracing/intel_th/pti.h |   8 +++
 2 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/intel_th/pti.c b/drivers/hwtracing/intel_th/pti.c
index 35738b5bfc..e96a1fcb57 100644
--- a/drivers/hwtracing/intel_th/pti.c
+++ b/drivers/hwtracing/intel_th/pti.c
@@ -1,7 +1,7 @@
 /*
  * Intel(R) Trace Hub PTI output driver
  *
- * Copyright (C) 2014-2015 Intel Corporation.
+ * Copyright (C) 2014-2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -34,6 +34,8 @@ struct pti_device {
 	unsigned int		freeclk;
 	unsigned int		clkdiv;
 	unsigned int		patgen;
+	unsigned int		lpp_dest_mask;
+	unsigned int		lpp_dest;
 };
 
 /* map PTI widths to MODE settings of PTI_CTL register */
@@ -163,6 +165,7 @@ static int intel_th_pti_activate(struct intel_th_device *thdev)
 		ctl |= PTI_FCEN;
 	ctl |= pti->mode << __ffs(PTI_MODE);
 	ctl |= pti->clkdiv << __ffs(PTI_CLKDIV);
+	ctl |= pti->lpp_dest << __ffs(LPP_DEST);
 
 	iowrite32(ctl, pti->base + REG_PTI_CTL);
 
@@ -192,6 +195,15 @@ static void read_hw_config(struct pti_device *pti)
 		pti->mode = pti_width_mode(4);
 	if (!pti->clkdiv)
 		pti->clkdiv = 1;
+
+	if (pti->thdev->output.type == GTH_LPP) {
+		if (ctl & LPP_PTIPRESENT)
+			pti->lpp_dest_mask |= LPP_DEST_PTI;
+		if (ctl & LPP_BSSBPRESENT)
+			pti->lpp_dest_mask |= LPP_DEST_EXI;
+		if (ctl & LPP_DEST)
+			pti->lpp_dest = 1;
+	}
 }
 
 static int intel_th_pti_probe(struct intel_th_device *thdev)
@@ -239,10 +251,103 @@ static struct intel_th_driver intel_th_pti_driver = {
 	},
 };
 
-module_driver(intel_th_pti_driver,
-	      intel_th_driver_register,
-	      intel_th_driver_unregister);
+static const char * const lpp_dest_str[] = { "pti", "exi" };
+
+static ssize_t lpp_dest_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct pti_device *pti = dev_get_drvdata(dev);
+	ssize_t ret = 0;
+	int i;
+
+	for (i = ARRAY_SIZE(lpp_dest_str) - 1; i >= 0; i--) {
+		const char *fmt = pti->lpp_dest == i ? "[%s] " : "%s ";
+
+		if (!(pti->lpp_dest_mask & BIT(i)))
+			continue;
+
+		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
+				 fmt, lpp_dest_str[i]);
+	}
+
+	if (ret)
+		buf[ret - 1] = '\n';
+
+	return ret;
+}
+
+static ssize_t lpp_dest_store(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t size)
+{
+	struct pti_device *pti = dev_get_drvdata(dev);
+	ssize_t ret = -EINVAL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(lpp_dest_str); i++)
+		if (sysfs_streq(buf, lpp_dest_str[i]))
+			break;
+
+	if (i < ARRAY_SIZE(lpp_dest_str) && pti->lpp_dest_mask & BIT(i)) {
+		pti->lpp_dest = i;
+		ret = size;
+	}
+
+	return ret;
+}
+
+static DEVICE_ATTR_RW(lpp_dest);
+
+static struct attribute *lpp_output_attrs[] = {
+	&dev_attr_mode.attr,
+	&dev_attr_freerunning_clock.attr,
+	&dev_attr_clock_divider.attr,
+	&dev_attr_lpp_dest.attr,
+	NULL,
+};
+
+static struct attribute_group lpp_output_group = {
+	.attrs	= lpp_output_attrs,
+};
+
+static struct intel_th_driver intel_th_lpp_driver = {
+	.probe		= intel_th_pti_probe,
+	.remove		= intel_th_pti_remove,
+	.activate	= intel_th_pti_activate,
+	.deactivate	= intel_th_pti_deactivate,
+	.attr_group	= &lpp_output_group,
+	.driver	= {
+		.name	= "lpp",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init intel_th_pti_lpp_init(void)
+{
+	int err;
+
+	err = intel_th_driver_register(&intel_th_pti_driver);
+	if (err)
+		return err;
+
+	err = intel_th_driver_register(&intel_th_lpp_driver);
+	if (err) {
+		intel_th_driver_unregister(&intel_th_pti_driver);
+		return err;
+	}
+
+	return 0;
+}
+
+module_init(intel_th_pti_lpp_init);
+
+static void __exit intel_th_pti_lpp_exit(void)
+{
+	intel_th_driver_unregister(&intel_th_pti_driver);
+	intel_th_driver_unregister(&intel_th_lpp_driver);
+}
+
+module_exit(intel_th_pti_lpp_exit);
 
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Intel(R) Trace Hub PTI output driver");
+MODULE_DESCRIPTION("Intel(R) Trace Hub PTI/LPP output driver");
 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");
diff --git a/drivers/hwtracing/intel_th/pti.h b/drivers/hwtracing/intel_th/pti.h
index 20883f5628..30827be67b 100644
--- a/drivers/hwtracing/intel_th/pti.h
+++ b/drivers/hwtracing/intel_th/pti.h
@@ -23,7 +23,15 @@ enum {
 #define PTI_EN		BIT(0)
 #define PTI_FCEN	BIT(1)
 #define PTI_MODE	0xf0
+#define LPP_PTIPRESENT	BIT(8)
+#define LPP_BSSBPRESENT	BIT(9)
 #define PTI_CLKDIV	0x000f0000
 #define PTI_PATGENMODE	0x00f00000
+#define LPP_DEST	BIT(25)
+#define LPP_BSSBACT	BIT(30)
+#define LPP_LPPBUSY	BIT(31)
+
+#define LPP_DEST_PTI	BIT(0)
+#define LPP_DEST_EXI	BIT(1)
 
 #endif /* __INTEL_TH_STH_H__ */
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 11/15] intel_th: pci: Add Cannon Lake PCH-H support
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (9 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 10/15] intel_th: pti: Support " Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 12/15] intel_th: pci: Add Cannon Lake PCH-LP support Alexander Shishkin
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH
  Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin, stable

This adds Intel(R) Trace Hub PCI ID for Cannon Lake PCH-H.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: <stable@vger.kernel.org>
---
 drivers/hwtracing/intel_th/pci.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
index aac7d66d6a..507db47665 100644
--- a/drivers/hwtracing/intel_th/pci.c
+++ b/drivers/hwtracing/intel_th/pci.c
@@ -97,6 +97,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
 		.driver_data = (kernel_ulong_t)0,
 	},
+	{
+		/* Cannon Lake H */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
+		.driver_data = (kernel_ulong_t)0,
+	},
 	{ 0 },
 };
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 12/15] intel_th: pci: Add Cannon Lake PCH-LP support
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (10 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 11/15] intel_th: pci: Add Cannon Lake PCH-H support Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 13/15] intel_th: pci: Use drvdata for quirks Alexander Shishkin
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH
  Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin, stable

This adds Intel(R) Trace Hub PCI ID for Cannon Lake PCH-LP.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: <stable@vger.kernel.org>
---
 drivers/hwtracing/intel_th/pci.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
index 507db47665..5a9a9e8072 100644
--- a/drivers/hwtracing/intel_th/pci.c
+++ b/drivers/hwtracing/intel_th/pci.c
@@ -102,6 +102,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
 		.driver_data = (kernel_ulong_t)0,
 	},
+	{
+		/* Cannon Lake LP */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
+		.driver_data = (kernel_ulong_t)0,
+	},
 	{ 0 },
 };
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 13/15] intel_th: pci: Use drvdata for quirks
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (11 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 12/15] intel_th: pci: Add Cannon Lake PCH-LP support Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 14/15] intel_th: Add global activate/deactivate callbacks for the glue layers Alexander Shishkin
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

Allow attaching miscellaneous quirk information to devices as drvdata.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     |  6 ++++--
 drivers/hwtracing/intel_th/intel_th.h | 27 ++++++++++++++++++++-------
 drivers/hwtracing/intel_th/pci.c      |  3 ++-
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index d1760003b4..e915ab24f4 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -576,6 +576,7 @@ intel_th_subdevice_alloc(struct intel_th *th,
 	if (!thdev)
 		return ERR_PTR(-ENOMEM);
 
+	thdev->drvdata = th->drvdata;
 
 	memcpy(res, subdev->res,
 	       sizeof(struct resource) * subdev->nres);
@@ -789,8 +790,8 @@ static const struct file_operations intel_th_output_fops = {
  * @irq:	irq number
  */
 struct intel_th *
-intel_th_alloc(struct device *dev, struct resource *devres,
-	       unsigned int ndevres, int irq)
+intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
+	       struct resource *devres, unsigned int ndevres, int irq)
 {
 	struct intel_th *th;
 	int err;
@@ -812,6 +813,7 @@ intel_th_alloc(struct device *dev, struct resource *devres,
 		goto err_ida;
 	}
 	th->dev = dev;
+	th->drvdata = drvdata;
 
 	th->resource = devres;
 	th->num_resources = ndevres;
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 3f4558404d..68244602ca 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -47,9 +47,20 @@ struct intel_th_output {
 	bool		active;
 };
 
+/**
+ * struct intel_th_drvdata - describes hardware capabilities and quirks
+ * @tscu_enable:	device needs SW to enable time stamping unit
+ */
+struct intel_th_drvdata {
+	unsigned int	tscu_enable        : 1;
+};
+
+#define INTEL_TH_CAP(_th, _cap) ((_th)->drvdata ? (_th)->drvdata->_cap : 0)
+
 /**
  * struct intel_th_device - device on the intel_th bus
  * @dev:		device
+ * @drvdata:		hardware capabilities/quirks
  * @resource:		array of resources available to this device
  * @num_resources:	number of resources in @resource array
  * @type:		INTEL_TH_{SOURCE,OUTPUT,SWITCH}
@@ -59,11 +70,12 @@ struct intel_th_output {
  * @name:		device name to match the driver
  */
 struct intel_th_device {
-	struct device	dev;
-	struct resource	*resource;
-	unsigned int	num_resources;
-	unsigned int	type;
-	int		id;
+	struct device		dev;
+	struct intel_th_drvdata *drvdata;
+	struct resource		*resource;
+	unsigned int		num_resources;
+	unsigned int		type;
+	int			id;
 
 	/* INTEL_TH_SWITCH specific */
 	bool			host_mode;
@@ -206,8 +218,8 @@ static inline struct intel_th *to_intel_th(struct intel_th_device *thdev)
 }
 
 struct intel_th *
-intel_th_alloc(struct device *dev, struct resource *devres,
-	       unsigned int ndevres, int irq);
+intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
+	       struct resource *devres, unsigned int ndevres, int irq);
 void intel_th_free(struct intel_th *th);
 
 int intel_th_driver_register(struct intel_th_driver *thdrv);
@@ -248,6 +260,7 @@ struct intel_th {
 
 	struct intel_th_device	*thdev[TH_SUBDEVICE_MAX];
 	struct intel_th_device	*hub;
+	struct intel_th_drvdata	*drvdata;
 
 	struct resource		*resource;
 	unsigned int		num_thdevs;
diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
index 5a9a9e8072..aed6d59499 100644
--- a/drivers/hwtracing/intel_th/pci.c
+++ b/drivers/hwtracing/intel_th/pci.c
@@ -30,6 +30,7 @@
 static int intel_th_pci_probe(struct pci_dev *pdev,
 			      const struct pci_device_id *id)
 {
+	struct intel_th_drvdata *drvdata = (void *)id->driver_data;
 	struct intel_th *th;
 	int err;
 
@@ -41,7 +42,7 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
 	if (err)
 		return err;
 
-	th = intel_th_alloc(&pdev->dev, pdev->resource,
+	th = intel_th_alloc(&pdev->dev, drvdata, pdev->resource,
 			    DEVICE_COUNT_RESOURCE, pdev->irq);
 	if (IS_ERR(th))
 		return PTR_ERR(th);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 14/15] intel_th: Add global activate/deactivate callbacks for the glue layers
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (12 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 13/15] intel_th: pci: Use drvdata for quirks Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-25 16:16 ` [GIT PULL 15/15] intel_th: Perform time resync on capture start Alexander Shishkin
  2017-08-28 14:59 ` [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Greg KH
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

A glue layer may want to install its own hooks into trace capture start
and stop paths to apply workarounds. This adds optional callbacks.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     | 26 ++++++++++++++++++++++----
 drivers/hwtracing/intel_th/intel_th.h |  2 ++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index e915ab24f4..998e3e5507 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -226,6 +226,7 @@ static int intel_th_output_activate(struct intel_th_device *thdev)
 {
 	struct intel_th_driver *thdrv =
 		to_intel_th_driver_or_null(thdev->dev.driver);
+	struct intel_th *th = to_intel_th(thdev);
 	int ret = 0;
 
 	if (!thdrv)
@@ -236,15 +237,28 @@ static int intel_th_output_activate(struct intel_th_device *thdev)
 
 	pm_runtime_get_sync(&thdev->dev);
 
+	if (th->activate)
+		ret = th->activate(th);
+	if (ret)
+		goto fail_put;
+
 	if (thdrv->activate)
 		ret = thdrv->activate(thdev);
 	else
 		intel_th_trace_enable(thdev);
 
-	if (ret) {
-		pm_runtime_put(&thdev->dev);
-		module_put(thdrv->driver.owner);
-	}
+	if (ret)
+		goto fail_deactivate;
+
+	return 0;
+
+fail_deactivate:
+	if (th->deactivate)
+		th->deactivate(th);
+
+fail_put:
+	pm_runtime_put(&thdev->dev);
+	module_put(thdrv->driver.owner);
 
 	return ret;
 }
@@ -253,6 +267,7 @@ static void intel_th_output_deactivate(struct intel_th_device *thdev)
 {
 	struct intel_th_driver *thdrv =
 		to_intel_th_driver_or_null(thdev->dev.driver);
+	struct intel_th *th = to_intel_th(thdev);
 
 	if (!thdrv)
 		return;
@@ -262,6 +277,9 @@ static void intel_th_output_deactivate(struct intel_th_device *thdev)
 	else
 		intel_th_trace_disable(thdev);
 
+	if (th->deactivate)
+		th->deactivate(th);
+
 	pm_runtime_put(&thdev->dev);
 	module_put(thdrv->driver.owner);
 }
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 68244602ca..78a4fb28b1 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -263,6 +263,8 @@ struct intel_th {
 	struct intel_th_drvdata	*drvdata;
 
 	struct resource		*resource;
+	int			(*activate)(struct intel_th *);
+	void			(*deactivate)(struct intel_th *);
 	unsigned int		num_thdevs;
 	unsigned int		num_resources;
 	int			irq;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [GIT PULL 15/15] intel_th: Perform time resync on capture start
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (13 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 14/15] intel_th: Add global activate/deactivate callbacks for the glue layers Alexander Shishkin
@ 2017-08-25 16:16 ` Alexander Shishkin
  2017-08-28 14:59 ` [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Greg KH
  15 siblings, 0 replies; 17+ messages in thread
From: Alexander Shishkin @ 2017-08-25 16:16 UTC (permalink / raw)
  To: Greg KH; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel, Alexander Shishkin

On some devices (TH 2.x devices at the moment), the internal time counter
is initially not synchronized to the global crystal clock, so the time
stamps it produces will not be useful. In this case, the driver needs
to force the time counter resync.

This applies the workaround to relevant devices.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 drivers/hwtracing/intel_th/core.c     |  3 +-
 drivers/hwtracing/intel_th/gth.c      | 23 ++++++++++----
 drivers/hwtracing/intel_th/gth.h      |  5 ++++
 drivers/hwtracing/intel_th/intel_th.h |  4 +++
 drivers/hwtracing/intel_th/pci.c      | 56 +++++++++++++++++++++++++++++++++--
 5 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 998e3e5507..1a023e3048 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -436,8 +436,9 @@ static const struct intel_th_subdevice {
 		.nres	= 1,
 		.res	= {
 			{
+				/* Handle TSCU from GTH driver */
 				.start	= REG_GTH_OFFSET,
-				.end	= REG_GTH_OFFSET + REG_GTH_LENGTH - 1,
+				.end	= REG_TSCU_OFFSET + REG_TSCU_LENGTH - 1,
 				.flags	= IORESOURCE_MEM,
 			},
 		},
diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c
index 7d9d667fe0..018678ec3c 100644
--- a/drivers/hwtracing/intel_th/gth.c
+++ b/drivers/hwtracing/intel_th/gth.c
@@ -285,16 +285,16 @@ gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm)
  */
 static int intel_th_gth_reset(struct gth_device *gth)
 {
-	u32 scratchpad;
+	u32 reg;
 	int port, i;
 
-	scratchpad = ioread32(gth->base + REG_GTH_SCRPD0);
-	if (scratchpad & SCRPD_DEBUGGER_IN_USE)
+	reg = ioread32(gth->base + REG_GTH_SCRPD0);
+	if (reg & SCRPD_DEBUGGER_IN_USE)
 		return -EBUSY;
 
 	/* Always save/restore STH and TU registers in S0ix entry/exit */
-	scratchpad |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED;
-	iowrite32(scratchpad, gth->base + REG_GTH_SCRPD0);
+	reg |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED;
+	iowrite32(reg, gth->base + REG_GTH_SCRPD0);
 
 	/* output ports */
 	for (port = 0; port < 8; port++) {
@@ -512,6 +512,15 @@ static void intel_th_gth_disable(struct intel_th_device *thdev,
 	iowrite32(reg, gth->base + REG_GTH_SCRPD0);
 }
 
+static void gth_tscu_resync(struct gth_device *gth)
+{
+	u32 reg;
+
+	reg = ioread32(gth->base + REG_TSCU_TSUCTRL);
+	reg &= ~TSUCTRL_CTCRESYNC;
+	iowrite32(reg, gth->base + REG_TSCU_TSUCTRL);
+}
+
 /**
  * intel_th_gth_enable() - enable tracing to an output device
  * @thdev:	GTH device
@@ -524,6 +533,7 @@ static void intel_th_gth_enable(struct intel_th_device *thdev,
 				struct intel_th_output *output)
 {
 	struct gth_device *gth = dev_get_drvdata(&thdev->dev);
+	struct intel_th *th = to_intel_th(thdev);
 	u32 scr = 0xfc0000, scrpd;
 	int master;
 
@@ -539,6 +549,9 @@ static void intel_th_gth_enable(struct intel_th_device *thdev,
 	output->active = true;
 	spin_unlock(&gth->gth_lock);
 
+	if (INTEL_TH_CAP(th, tscu_enable))
+		gth_tscu_resync(gth);
+
 	scrpd = ioread32(gth->base + REG_GTH_SCRPD0);
 	scrpd |= output->scratchpad;
 	iowrite32(scrpd, gth->base + REG_GTH_SCRPD0);
diff --git a/drivers/hwtracing/intel_th/gth.h b/drivers/hwtracing/intel_th/gth.h
index 56f0d26205..f3d234251a 100644
--- a/drivers/hwtracing/intel_th/gth.h
+++ b/drivers/hwtracing/intel_th/gth.h
@@ -55,9 +55,14 @@ enum {
 	REG_GTH_SCRPD1		= 0xe4, /* ScratchPad[1] */
 	REG_GTH_SCRPD2		= 0xe8, /* ScratchPad[2] */
 	REG_GTH_SCRPD3		= 0xec, /* ScratchPad[3] */
+	REG_TSCU_TSUCTRL	= 0x2000, /* TSCU control register */
+	REG_TSCU_TSCUSTAT	= 0x2004, /* TSCU status register */
 };
 
 /* waiting for Pipeline Empty bit(s) to assert for GTH */
 #define GTH_PLE_WAITLOOP_DEPTH	10000
 
+#define TSUCTRL_CTCRESYNC	BIT(0)
+#define TSCUSTAT_CTCSYNCING	BIT(1)
+
 #endif /* __INTEL_TH_GTH_H__ */
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 78a4fb28b1..99ad563fc4 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -298,6 +298,10 @@ enum {
 	REG_GTH_OFFSET		= 0x0000,
 	REG_GTH_LENGTH		= 0x2000,
 
+	/* Timestamp counter unit (TSCU) */
+	REG_TSCU_OFFSET		= 0x2000,
+	REG_TSCU_LENGTH		= 0x1000,
+
 	/* Software Trace Hub (STH) [0x4000..0x4fff] */
 	REG_STH_OFFSET		= 0x4000,
 	REG_STH_LENGTH		= 0x2000,
diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
index aed6d59499..bc9cebc305 100644
--- a/drivers/hwtracing/intel_th/pci.c
+++ b/drivers/hwtracing/intel_th/pci.c
@@ -27,6 +27,49 @@
 
 #define BAR_MASK (BIT(TH_MMIO_CONFIG) | BIT(TH_MMIO_SW))
 
+#define PCI_REG_NPKDSC	0x80
+#define NPKDSC_TSACT	BIT(5)
+
+static int intel_th_pci_activate(struct intel_th *th)
+{
+	struct pci_dev *pdev = to_pci_dev(th->dev);
+	u32 npkdsc;
+	int err;
+
+	if (!INTEL_TH_CAP(th, tscu_enable))
+		return 0;
+
+	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
+	if (!err) {
+		npkdsc |= NPKDSC_TSACT;
+		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
+	}
+
+	if (err)
+		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
+
+	return err;
+}
+
+static void intel_th_pci_deactivate(struct intel_th *th)
+{
+	struct pci_dev *pdev = to_pci_dev(th->dev);
+	u32 npkdsc;
+	int err;
+
+	if (!INTEL_TH_CAP(th, tscu_enable))
+		return;
+
+	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
+	if (!err) {
+		npkdsc |= NPKDSC_TSACT;
+		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
+	}
+
+	if (err)
+		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
+}
+
 static int intel_th_pci_probe(struct pci_dev *pdev,
 			      const struct pci_device_id *id)
 {
@@ -47,6 +90,9 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
 	if (IS_ERR(th))
 		return PTR_ERR(th);
 
+	th->activate   = intel_th_pci_activate;
+	th->deactivate = intel_th_pci_deactivate;
+
 	pci_set_master(pdev);
 
 	return 0;
@@ -59,6 +105,10 @@ static void intel_th_pci_remove(struct pci_dev *pdev)
 	intel_th_free(th);
 }
 
+static const struct intel_th_drvdata intel_th_2x = {
+	.tscu_enable	= 1,
+};
+
 static const struct pci_device_id intel_th_pci_id_table[] = {
 	{
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),
@@ -96,17 +146,17 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
 	{
 		/* Gemini Lake */
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
-		.driver_data = (kernel_ulong_t)0,
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
 	},
 	{
 		/* Cannon Lake H */
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
-		.driver_data = (kernel_ulong_t)0,
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
 	},
 	{
 		/* Cannon Lake LP */
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
-		.driver_data = (kernel_ulong_t)0,
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
 	},
 	{ 0 },
 };
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [GIT PULL 00/15] stm class/intel_th: Updates for 4.14
  2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
                   ` (14 preceding siblings ...)
  2017-08-25 16:16 ` [GIT PULL 15/15] intel_th: Perform time resync on capture start Alexander Shishkin
@ 2017-08-28 14:59 ` Greg KH
  15 siblings, 0 replies; 17+ messages in thread
From: Greg KH @ 2017-08-28 14:59 UTC (permalink / raw)
  To: Alexander Shishkin; +Cc: Mathieu Poirier, Chunyan Zhang, linux-kernel

On Fri, Aug 25, 2017 at 07:15:51PM +0300, Alexander Shishkin wrote:
> Hi Greg,
> 
> These are the changes I have queued for 4.14. These are mostly updates for
> intel_th: added support for a new output type, Cannon Lake PCH PCI IDs, a
> rework for the subdevice management code, and better support for IOMMU.
> STM side has one fix and one documentation update.
> 
> As usual, these are checkpatch/sparse/smatch/cppcheck/coccinelle clean.
> Please consider pulling. Thanks!
> 
> The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:
> 
>   Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git tags/stm-for-greg-20170825

Pulled and pushed out, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-08-28 14:59 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-25 16:15 [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 01/15] stm: Potential read overflow in stm_char_policy_set_ioctl() Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 02/15] stm class: Document the stm_ftrace Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 03/15] intel_th: pci: Enable bus mastering Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 04/15] intel_th: Output devices without ports don't need assigning Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 05/15] intel_th: Streamline the subdevice tree accessors Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 06/15] intel_th: Make SOURCE devices children of the root device Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 07/15] intel_th: Make the switch allocate its subdevices Alexander Shishkin
2017-08-25 16:15 ` [GIT PULL 08/15] intel_th: msu: Use the real device in case of IOMMU domain allocation Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 09/15] intel_th: Enumerate Low Power Path output port type Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 10/15] intel_th: pti: Support " Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 11/15] intel_th: pci: Add Cannon Lake PCH-H support Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 12/15] intel_th: pci: Add Cannon Lake PCH-LP support Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 13/15] intel_th: pci: Use drvdata for quirks Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 14/15] intel_th: Add global activate/deactivate callbacks for the glue layers Alexander Shishkin
2017-08-25 16:16 ` [GIT PULL 15/15] intel_th: Perform time resync on capture start Alexander Shishkin
2017-08-28 14:59 ` [GIT PULL 00/15] stm class/intel_th: Updates for 4.14 Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.