linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] thermal: processor_thermal: Suport workload hint
@ 2023-06-20 23:01 Srinivas Pandruvada
  2023-06-20 23:01 ` [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module Srinivas Pandruvada
                   ` (7 more replies)
  0 siblings, 8 replies; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Add support for Meteor Lake workload hints. Before adding this support,
some reorganization and clean up is required.
First four changes are for clean up and to reorganize code to add
support for workload hint. The last patch adds a test program as part
of self tests.

Srinivas Pandruvada (7):
  thermal: int340x: processor_thermal: Move mailbox code to common
    module
  thermal: int340x: processor_thermal: Add interrupt configuration
  thermal: int340x: processor_thermal: Use non MSI interrupts
  thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for
    Meteor Lake
  thermal: int340x: processor_thermal: Add workload type hint
  thermal/drivers/int340x: Support workload hint interrupts
  selftests/thermel/intel: Add test to read workload hint

 .../driver-api/thermal/intel_dptf.rst         |  38 +++
 .../thermal/intel/int340x_thermal/Makefile    |   2 +
 .../processor_thermal_device.c                |  17 +-
 .../processor_thermal_device.h                |  21 +-
 .../processor_thermal_device_pci.c            |  76 ++++--
 .../processor_thermal_device_pci_legacy.c     |   3 +-
 .../int340x_thermal/processor_thermal_mbox.c  | 179 ++++---------
 .../processor_thermal_wlt_hint.c              | 239 ++++++++++++++++++
 .../processor_thermal_wlt_req.c               | 137 ++++++++++
 .../testing/selftests/thermal/intel/Makefile  |  16 ++
 .../thermal/intel/workload_hint_test.c        | 114 +++++++++
 11 files changed, 680 insertions(+), 162 deletions(-)
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
 create mode 100644 tools/testing/selftests/thermal/intel/Makefile
 create mode 100644 tools/testing/selftests/thermal/intel/workload_hint_test.c

-- 
2.38.1


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

* [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-21 14:35   ` Zhang, Rui
  2023-06-20 23:01 ` [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration Srinivas Pandruvada
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

The processor thermal mailbox is used for workload type request and
also in the processor thermal RFIM module. So, move the workload type
request code to its own module from the current processor thermal
mailbox module.

processor_thermal_mailbox.c contains only mailbox read/write related
source code. The source related to workload_types requests is moved to
a module processor_thermal_wlt_req.c.

In addition
-Rename PROC_THERMAL_FEATURE_MBOX to PROC_THERMAL_FEATURE_WLT_REQ.
- proc_thermal_mbox_add(), which adds workload type sysfs attribute group
is renamed to proc_thermal_wlt_req_add().
-proc_thermal_mbox_remove() is renamed to proc_thermal_wlt_req_remove().

While here, resolve check patch warnings for 100 columns for only modified
lines.

No functional changes are expected.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../thermal/intel/int340x_thermal/Makefile    |   1 +
 .../processor_thermal_device.c                |   8 +-
 .../processor_thermal_device.h                |  12 +-
 .../processor_thermal_device_pci.c            |  10 +-
 .../processor_thermal_device_pci_legacy.c     |   3 +-
 .../int340x_thermal/processor_thermal_mbox.c  | 130 -----------------
 .../processor_thermal_wlt_req.c               | 137 ++++++++++++++++++
 7 files changed, 160 insertions(+), 141 deletions(-)
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c

diff --git a/drivers/thermal/intel/int340x_thermal/Makefile b/drivers/thermal/intel/int340x_thermal/Makefile
index 4e852ce4a5d5..76e053e541f0 100644
--- a/drivers/thermal/intel/int340x_thermal/Makefile
+++ b/drivers/thermal/intel/int340x_thermal/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_device_pci.o
 obj-$(CONFIG_PROC_THERMAL_MMIO_RAPL) += processor_thermal_rapl.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_rfim.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_mbox.o
+obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_wlt_req.o
 obj-$(CONFIG_INT3406_THERMAL)	+= int3406_thermal.o
 obj-$(CONFIG_ACPI_THERMAL_REL)	+= acpi_thermal_rel.o
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index 3ca0a2f5937f..48f6c72b05f6 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -346,8 +346,8 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
 		}
 	}
 
-	if (feature_mask & PROC_THERMAL_FEATURE_MBOX) {
-		ret = proc_thermal_mbox_add(pdev, proc_priv);
+	if (feature_mask & PROC_THERMAL_FEATURE_WLT_REQ) {
+		ret = proc_thermal_wlt_req_add(pdev, proc_priv);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to add MBOX interface\n");
 			goto err_rem_rfim;
@@ -374,8 +374,8 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *
 	    proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS)
 		proc_thermal_rfim_remove(pdev);
 
-	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MBOX)
-		proc_thermal_mbox_remove(pdev);
+	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WLT_REQ)
+		proc_thermal_wlt_req_remove(pdev);
 }
 EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove);
 
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
index 7acaa8f1b896..7cdeca2edc21 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
@@ -59,7 +59,7 @@ struct rapl_mmio_regs {
 #define PROC_THERMAL_FEATURE_RAPL	0x01
 #define PROC_THERMAL_FEATURE_FIVR	0x02
 #define PROC_THERMAL_FEATURE_DVFS	0x04
-#define PROC_THERMAL_FEATURE_MBOX	0x08
+#define PROC_THERMAL_FEATURE_WLT_REQ	0x08
 #define PROC_THERMAL_FEATURE_DLVR	0x10
 
 #if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
@@ -80,8 +80,14 @@ static void __maybe_unused proc_thermal_rapl_remove(void)
 int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
 void proc_thermal_rfim_remove(struct pci_dev *pdev);
 
-int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
-void proc_thermal_mbox_remove(struct pci_dev *pdev);
+int proc_thermal_wlt_req_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
+void proc_thermal_wlt_req_remove(struct pci_dev *pdev);
+
+#define MBOX_CMD_WORKLOAD_TYPE_READ	0x0E
+#define MBOX_CMD_WORKLOAD_TYPE_WRITE	0x0F
+
+#define MBOX_DATA_BIT_AC_DC		30
+#define MBOX_DATA_BIT_VALID		31
 
 int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp);
 int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data);
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
index 0d1e98007270..5a2bcfff0a68 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -350,9 +350,13 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
 			 proc_thermal_pci_resume);
 
 static const struct pci_device_id proc_thermal_pci_ids[] = {
-	{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
-	{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX | PROC_THERMAL_FEATURE_DLVR) },
-	{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
+	{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
+	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ) },
+	{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL |
+	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ |
+	  PROC_THERMAL_FEATURE_DLVR) },
+	{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
+	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ) },
 	{ },
 };
 
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
index 09e032f822f3..b8c58a44fb93 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
@@ -137,7 +137,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
 	{ PCI_DEVICE_DATA(INTEL, ICL_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
 	{ PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) },
 	{ PCI_DEVICE_DATA(INTEL, SKL_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
-	{ PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_MBOX) },
+	{ PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
+	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_WLT_REQ) },
 	{ },
 };
 
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
index 0b89a4340ff4..ec766c5615b7 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
@@ -10,18 +10,12 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include "processor_thermal_device.h"
 
-#define MBOX_CMD_WORKLOAD_TYPE_READ	0x0E
-#define MBOX_CMD_WORKLOAD_TYPE_WRITE	0x0F
-
 #define MBOX_OFFSET_DATA		0x5810
 #define MBOX_OFFSET_INTERFACE		0x5818
 
 #define MBOX_BUSY_BIT			31
 #define MBOX_RETRY_COUNT		100
 
-#define MBOX_DATA_BIT_VALID		31
-#define MBOX_DATA_BIT_AC_DC		30
-
 static DEFINE_MUTEX(mbox_lock);
 
 static int wait_for_mbox_ready(struct proc_thermal_device *proc_priv)
@@ -114,128 +108,4 @@ int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data
 }
 EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd, INT340X_THERMAL);
 
-/* List of workload types */
-static const char * const workload_types[] = {
-	"none",
-	"idle",
-	"semi_active",
-	"bursty",
-	"sustained",
-	"battery_life",
-	NULL
-};
-
-static ssize_t workload_available_types_show(struct device *dev,
-					       struct device_attribute *attr,
-					       char *buf)
-{
-	int i = 0;
-	int ret = 0;
-
-	while (workload_types[i] != NULL)
-		ret += sprintf(&buf[ret], "%s ", workload_types[i++]);
-
-	ret += sprintf(&buf[ret], "\n");
-
-	return ret;
-}
-
-static DEVICE_ATTR_RO(workload_available_types);
-
-static ssize_t workload_type_store(struct device *dev,
-				    struct device_attribute *attr,
-				    const char *buf, size_t count)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	char str_preference[15];
-	u32 data = 0;
-	ssize_t ret;
-
-	ret = sscanf(buf, "%14s", str_preference);
-	if (ret != 1)
-		return -EINVAL;
-
-	ret = match_string(workload_types, -1, str_preference);
-	if (ret < 0)
-		return ret;
-
-	ret &= 0xff;
-
-	if (ret)
-		data = BIT(MBOX_DATA_BIT_VALID) | BIT(MBOX_DATA_BIT_AC_DC);
-
-	data |= ret;
-
-	ret = send_mbox_write_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_WRITE, data);
-	if (ret)
-		return false;
-
-	return count;
-}
-
-static ssize_t workload_type_show(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	u64 cmd_resp;
-	int ret;
-
-	ret = send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp);
-	if (ret)
-		return false;
-
-	cmd_resp &= 0xff;
-
-	if (cmd_resp > ARRAY_SIZE(workload_types) - 1)
-		return -EINVAL;
-
-	return sprintf(buf, "%s\n", workload_types[cmd_resp]);
-}
-
-static DEVICE_ATTR_RW(workload_type);
-
-static struct attribute *workload_req_attrs[] = {
-	&dev_attr_workload_available_types.attr,
-	&dev_attr_workload_type.attr,
-	NULL
-};
-
-static const struct attribute_group workload_req_attribute_group = {
-	.attrs = workload_req_attrs,
-	.name = "workload_request"
-};
-
-static bool workload_req_created;
-
-int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
-{
-	u64 cmd_resp;
-	int ret;
-
-	/* Check if there is a mailbox support, if fails return success */
-	ret = send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp);
-	if (ret)
-		return 0;
-
-	ret = sysfs_create_group(&pdev->dev.kobj, &workload_req_attribute_group);
-	if (ret)
-		return ret;
-
-	workload_req_created = true;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(proc_thermal_mbox_add);
-
-void proc_thermal_mbox_remove(struct pci_dev *pdev)
-{
-	if (workload_req_created)
-		sysfs_remove_group(&pdev->dev.kobj, &workload_req_attribute_group);
-
-	workload_req_created = false;
-
-}
-EXPORT_SYMBOL_GPL(proc_thermal_mbox_remove);
-
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
new file mode 100644
index 000000000000..d22c86fad231
--- /dev/null
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * processor thermal device for Workload type hints
+ * update from user space
+ *
+ * Copyright (c) 2020-2023, Intel Corporation.
+ */
+
+#include <linux/pci.h>
+#include "processor_thermal_device.h"
+
+/* List of workload types */
+static const char * const workload_types[] = {
+	"none",
+	"idle",
+	"semi_active",
+	"bursty",
+	"sustained",
+	"battery_life",
+	NULL
+};
+
+static ssize_t workload_available_types_show(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf)
+{
+	int i = 0;
+	int ret = 0;
+
+	while (workload_types[i] != NULL)
+		ret += sprintf(&buf[ret], "%s ", workload_types[i++]);
+
+	ret += sprintf(&buf[ret], "\n");
+
+	return ret;
+}
+
+static DEVICE_ATTR_RO(workload_available_types);
+
+static ssize_t workload_type_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	char str_preference[15];
+	u32 data = 0;
+	ssize_t ret;
+
+	ret = sscanf(buf, "%14s", str_preference);
+	if (ret != 1)
+		return -EINVAL;
+
+	ret = match_string(workload_types, -1, str_preference);
+	if (ret < 0)
+		return ret;
+
+	ret &= 0xff;
+
+	if (ret)
+		data = BIT(MBOX_DATA_BIT_VALID) | BIT(MBOX_DATA_BIT_AC_DC);
+
+	data |= ret;
+
+	ret = processor_thermal_send_mbox_write_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_WRITE, data);
+	if (ret)
+		return false;
+
+	return count;
+}
+
+static ssize_t workload_type_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	u64 cmd_resp;
+	int ret;
+
+	ret = processor_thermal_send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp);
+	if (ret)
+		return false;
+
+	cmd_resp &= 0xff;
+
+	if (cmd_resp > ARRAY_SIZE(workload_types) - 1)
+		return -EINVAL;
+
+	return sprintf(buf, "%s\n", workload_types[cmd_resp]);
+}
+
+static DEVICE_ATTR_RW(workload_type);
+
+static struct attribute *workload_req_attrs[] = {
+	&dev_attr_workload_available_types.attr,
+	&dev_attr_workload_type.attr,
+	NULL
+};
+
+static const struct attribute_group workload_req_attribute_group = {
+	.attrs = workload_req_attrs,
+	.name = "workload_request"
+};
+
+static bool workload_req_created;
+
+int proc_thermal_wlt_req_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
+{
+	u64 cmd_resp;
+	int ret;
+
+	/* Check if there is a mailbox support, if fails return success */
+	ret = processor_thermal_send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp);
+	if (ret)
+		return 0;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &workload_req_attribute_group);
+	if (ret)
+		return ret;
+
+	workload_req_created = true;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(proc_thermal_wlt_req_add);
+
+void proc_thermal_wlt_req_remove(struct pci_dev *pdev)
+{
+	if (workload_req_created)
+		sysfs_remove_group(&pdev->dev.kobj, &workload_req_attribute_group);
+
+	workload_req_created = false;
+
+}
+EXPORT_SYMBOL_GPL(proc_thermal_wlt_req_remove);
+
+MODULE_IMPORT_NS(INT340X_THERMAL);
+MODULE_LICENSE("GPL");
-- 
2.38.1


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

* [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
  2023-06-20 23:01 ` [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-21 14:50   ` Zhang, Rui
  2023-06-20 23:01 ` [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts Srinivas Pandruvada
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Some features on this PCI devices require interrupt support. Here
interrupts are enabled/disabled via sending mailbox commands. The
mailbox command ID is 0x1E for read and 0x1F for write.

The interrupt configuration will require mutex protection as it
involved read-modify-write operation. Since mutex are already used
in the mailbox read/write functions: send_mbox_write_cmd() and
send_mbox_read_cmd(), there will be double locking. But, this can
be avoided by moving mutexes from mailbox read/write processing
functions to the calling (exported) functions.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../processor_thermal_device.h                |  2 +
 .../int340x_thermal/processor_thermal_mbox.c  | 85 ++++++++++++++-----
 2 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
index 7cdeca2edc21..defc919cb020 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
@@ -91,6 +91,8 @@ void proc_thermal_wlt_req_remove(struct pci_dev *pdev);
 
 int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp);
 int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data);
+int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev, bool enable, int enable_bit,
+					    int time_window);
 int proc_thermal_add(struct device *dev, struct proc_thermal_device *priv);
 void proc_thermal_remove(struct proc_thermal_device *proc_priv);
 int proc_thermal_suspend(struct device *dev);
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
index ec766c5615b7..7ef0af3f5bef 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
@@ -45,23 +45,16 @@ static int send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data)
 	int ret;
 
 	proc_priv = pci_get_drvdata(pdev);
-
-	mutex_lock(&mbox_lock);
-
 	ret = wait_for_mbox_ready(proc_priv);
 	if (ret)
-		goto unlock_mbox;
+		return ret;
 
 	writel(data, (proc_priv->mmio_base + MBOX_OFFSET_DATA));
 	/* Write command register */
 	reg_data = BIT_ULL(MBOX_BUSY_BIT) | id;
 	writel(reg_data, (proc_priv->mmio_base + MBOX_OFFSET_INTERFACE));
 
-	ret = wait_for_mbox_ready(proc_priv);
-
-unlock_mbox:
-	mutex_unlock(&mbox_lock);
-	return ret;
+	return wait_for_mbox_ready(proc_priv);
 }
 
 static int send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp)
@@ -71,12 +64,9 @@ static int send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp)
 	int ret;
 
 	proc_priv = pci_get_drvdata(pdev);
-
-	mutex_lock(&mbox_lock);
-
 	ret = wait_for_mbox_ready(proc_priv);
 	if (ret)
-		goto unlock_mbox;
+		return ret;
 
 	/* Write command register */
 	reg_data = BIT_ULL(MBOX_BUSY_BIT) | id;
@@ -84,28 +74,85 @@ static int send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp)
 
 	ret = wait_for_mbox_ready(proc_priv);
 	if (ret)
-		goto unlock_mbox;
+		return ret;
 
 	if (id == MBOX_CMD_WORKLOAD_TYPE_READ)
 		*resp = readl(proc_priv->mmio_base + MBOX_OFFSET_DATA);
 	else
 		*resp = readq(proc_priv->mmio_base + MBOX_OFFSET_DATA);
 
-unlock_mbox:
-	mutex_unlock(&mbox_lock);
-	return ret;
+	return 0;
 }
 
 int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp)
 {
-	return send_mbox_read_cmd(pdev, id, resp);
+	int ret;
+
+	mutex_lock(&mbox_lock);
+	ret = send_mbox_read_cmd(pdev, id, resp);
+	mutex_unlock(&mbox_lock);
+
+	return ret;
 }
 EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_read_cmd, INT340X_THERMAL);
 
 int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data)
 {
-	return send_mbox_write_cmd(pdev, id, data);
+	int ret;
+
+	mutex_lock(&mbox_lock);
+	ret = send_mbox_write_cmd(pdev, id, data);
+	mutex_unlock(&mbox_lock);
+
+	return ret;
 }
 EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd, INT340X_THERMAL);
 
+#define MBOX_CAMARILLO_RD_INTR_CONFIG	0x1E
+#define MBOX_CAMARILLO_WR_INTR_CONFIG	0x1F
+#define WLT_TW_MASK			GENMASK_ULL(30, 24)
+#define SOC_PREDICTION_TW_SHIFT		24
+
+int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev, bool enable,
+					    int enable_bit, int time_window)
+{
+	u64 data;
+	int ret;
+
+	if (!pdev)
+		return -ENODEV;
+
+	mutex_lock(&mbox_lock);
+
+	/* Do read modify write for MBOX_CAMARILLO_RD_INTR_CONFIG */
+
+	ret = send_mbox_read_cmd(pdev, MBOX_CAMARILLO_RD_INTR_CONFIG,  &data);
+	if (ret) {
+		dev_err(&pdev->dev, "MBOX_CAMARILLO_RD_INTR_CONFIG failed\n");
+		goto unlock;
+	}
+
+	if (time_window >= 0) {
+		data &= ~WLT_TW_MASK;
+
+		/* Program notification delay */
+		data |= (time_window << SOC_PREDICTION_TW_SHIFT);
+	}
+
+	if (enable)
+		data |= BIT(enable_bit);
+	else
+		data &= ~BIT(enable_bit);
+
+	ret = send_mbox_write_cmd(pdev, MBOX_CAMARILLO_WR_INTR_CONFIG, data);
+	if (ret)
+		dev_err(&pdev->dev, "MBOX_CAMARILLO_WR_INTR_CONFIG failed\n");
+
+unlock:
+	mutex_unlock(&mbox_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(processor_thermal_mbox_interrupt_config, INT340X_THERMAL);
+
 MODULE_LICENSE("GPL v2");
-- 
2.38.1


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

* [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
  2023-06-20 23:01 ` [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module Srinivas Pandruvada
  2023-06-20 23:01 ` [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-21 14:53   ` Zhang, Rui
  2023-06-20 23:01 ` [PATCH 4/7] thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for Meteor Lake Srinivas Pandruvada
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

There are issues in using MSI interrupts for processor thermal device.
The support is not consistent, across generations. Even in the same
generation, there are issue in getting interrupts via MSI.

Hence always use legacy PCI interrupts by default, instead of MSI.
Add a module param to use of MSI, so that MSI can be still used.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../processor_thermal_device_pci.c            | 33 ++++++++++++-------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
index 5a2bcfff0a68..057778f7bece 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -15,6 +15,11 @@
 
 #define DRV_NAME "proc_thermal_pci"
 
+static int msi_enabled;
+module_param(msi_enabled, int, 0644);
+MODULE_PARM_DESC(msi_enabled,
+	"Use PCI MSI based interrupts for processor thermal device.");
+
 struct proc_thermal_pci {
 	struct pci_dev *pdev;
 	struct proc_thermal_device *proc_priv;
@@ -219,8 +224,6 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
 		return ret;
 	}
 
-	pci_set_master(pdev);
-
 	INIT_DELAYED_WORK(&pci_info->work, proc_thermal_threshold_work_fn);
 
 	ret = proc_thermal_add(&pdev->dev, proc_priv);
@@ -248,16 +251,23 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
 		goto err_ret_mmio;
 	}
 
-	/* request and enable interrupt */
-	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to allocate vectors!\n");
-		goto err_ret_tzone;
-	}
-	if (!pdev->msi_enabled && !pdev->msix_enabled)
+	if (msi_enabled) {
+		pci_set_master(pdev);
+		/* request and enable interrupt */
+		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Failed to allocate vectors!\n");
+			goto err_ret_tzone;
+		}
+		if (!pdev->msi_enabled && !pdev->msix_enabled)
+			irq_flag = IRQF_SHARED;
+
+		irq =  pci_irq_vector(pdev, 0);
+	} else {
 		irq_flag = IRQF_SHARED;
+		irq = pdev->irq;
+	}
 
-	irq =  pci_irq_vector(pdev, 0);
 	ret = devm_request_threaded_irq(&pdev->dev, irq,
 					proc_thermal_irq_handler, NULL,
 					irq_flag, KBUILD_MODNAME, pci_info);
@@ -273,7 +283,8 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
 	return 0;
 
 err_free_vectors:
-	pci_free_irq_vectors(pdev);
+	if (msi_enabled)
+		pci_free_irq_vectors(pdev);
 err_ret_tzone:
 	thermal_zone_device_unregister(pci_info->tzone);
 err_ret_mmio:
-- 
2.38.1


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

* [PATCH 4/7] thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for Meteor Lake
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
                   ` (2 preceding siblings ...)
  2023-06-20 23:01 ` [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-21 14:54   ` Zhang, Rui
  2023-06-20 23:01 ` [PATCH 5/7] thermal: int340x: processor_thermal: Add workload type hint Srinivas Pandruvada
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Meteor Lake processor supports firmware hints for predicting workload
type. So, remove support for passing workload hints to the firmware.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../intel/int340x_thermal/processor_thermal_device_pci.c       | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
index 057778f7bece..3dab3dbdbbc6 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -364,8 +364,7 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
 	{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ) },
 	{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL |
-	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ |
-	  PROC_THERMAL_FEATURE_DLVR) },
+	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR) },
 	{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ) },
 	{ },
-- 
2.38.1


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

* [PATCH 5/7] thermal: int340x: processor_thermal: Add workload type hint
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
                   ` (3 preceding siblings ...)
  2023-06-20 23:01 ` [PATCH 4/7] thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for Meteor Lake Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-21 14:12   ` Zhang, Rui
  2023-06-20 23:01 ` [PATCH 6/7] thermal/drivers/int340x: Support workload hint interrupts Srinivas Pandruvada
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Prior to Meteor Lake processor generation, user space can pass workload
type request to the firmware. Then firmware can optimize power based on
workload type. User space also uses workload type request to implement
its own heuristics.

The firmware in Meteor Lake processor generation is capable of predicting
workload type without user space. To avoid duplicate processing, the user
space can read the same workload type hint from the firmware instead of
implementing its own prediction.

This workload hint is passed from the firmware via a MMIO offset 0x5B18.
Before receiving the hint, firmware needs to be configured via a mailbox
command. This mailbox command enables interrupt and notification delay.
This notification delay can be changed from user space.

This workload hint is passed via sysfs attribute group "workload_hint".

This attribute group contains following attributes:

workload_type_enable: Enables/disables workload type hints from the
firmware.

notification_delay_ms: Notification delay in milli seconds.

workload_type_index: The current workload type index predicted by the
firmware. Refer to the documentation for meaning of each index value.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../driver-api/thermal/intel_dptf.rst         |  38 +++
 .../thermal/intel/int340x_thermal/Makefile    |   1 +
 .../processor_thermal_device.c                |   9 +
 .../processor_thermal_device.h                |   7 +
 .../processor_thermal_device_pci.c            |   3 +-
 .../processor_thermal_wlt_hint.c              | 239 ++++++++++++++++++
 6 files changed, 296 insertions(+), 1 deletion(-)
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c

diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
index 9ab4316322a1..5cba02c4c308 100644
--- a/Documentation/driver-api/thermal/intel_dptf.rst
+++ b/Documentation/driver-api/thermal/intel_dptf.rst
@@ -315,3 +315,41 @@ DPTF Fan Control
 ----------------------------------------
 
 Refer to Documentation/admin-guide/acpi/fan_performance_states.rst
+
+Workload Type Hints
+----------------------------------------
+
+The firmware in Meteor Lake processor generation is capable of predicting
+workload type and pass hints to OS. These hints can be enabled and read
+from user space. User space can poll attribute "workload_type_index" for
+the current hint or can get notification when this attribute is changed.
+
+file:`/sys/bus/pci/devices/0000:00:04.0/workload_hint/`
+
+``workload_hint_enable`` (RW)
+	Enable firmware to send workload type hints from user space.
+
+``notification_delay_ms`` (RW)
+	Minimum delay in milli seconds before firmware will notify OS.
+
+``workload_type_index`` (RO)
+	Predicted workload type index.
+	The index and description on Meteor Lake processor:
+
+	0 -  Idle: System performs no tasks, power and residency are consistently
+		low for long periods of time.
+
+	1 – Battery Life: Power is relatively low, but the processor may still be
+		actively performing a task, such as video playback for a long period of
+		time.
+
+	2 – Sustained: Power level that is relatively high for a long period
+		of time, with very few to no periods of idleness, which will eventually
+		exhaust RAPL Power Limit 1 and 2.
+
+	3 – Bursty: Consumes a relatively constant average amount of power,
+		however, bursts of activity interrupt periods of relative idleness.
+		The bursts are relatively short and spaced with relative idleness
+		which typically do not exhaust RAPL Power Limit 1.
+
+	4 – Unknown: Can't classify.
diff --git a/drivers/thermal/intel/int340x_thermal/Makefile b/drivers/thermal/intel/int340x_thermal/Makefile
index 76e053e541f0..ccd0fdd23161 100644
--- a/drivers/thermal/intel/int340x_thermal/Makefile
+++ b/drivers/thermal/intel/int340x_thermal/Makefile
@@ -11,5 +11,6 @@ obj-$(CONFIG_PROC_THERMAL_MMIO_RAPL) += processor_thermal_rapl.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_rfim.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_mbox.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_wlt_req.o
+obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_wlt_hint.o
 obj-$(CONFIG_INT3406_THERMAL)	+= int3406_thermal.o
 obj-$(CONFIG_ACPI_THERMAL_REL)	+= acpi_thermal_rel.o
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index 48f6c72b05f6..127deefbb633 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -352,6 +352,12 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
 			dev_err(&pdev->dev, "failed to add MBOX interface\n");
 			goto err_rem_rfim;
 		}
+	} else if (feature_mask & PROC_THERMAL_FEATURE_WLT_HINT) {
+		ret = proc_thermal_wlt_hint_add(pdev, proc_priv);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to add WLT Hint\n");
+			goto err_rem_rfim;
+		}
 	}
 
 	return 0;
@@ -376,10 +382,13 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *
 
 	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WLT_REQ)
 		proc_thermal_wlt_req_remove(pdev);
+	else if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WLT_HINT)
+		proc_thermal_wlt_hint_remove(pdev);
 }
 EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove);
 
 MODULE_IMPORT_NS(INTEL_TCC);
+MODULE_IMPORT_NS(INT340X_THERMAL);
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
index defc919cb020..bc056712f728 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
@@ -61,6 +61,7 @@ struct rapl_mmio_regs {
 #define PROC_THERMAL_FEATURE_DVFS	0x04
 #define PROC_THERMAL_FEATURE_WLT_REQ	0x08
 #define PROC_THERMAL_FEATURE_DLVR	0x10
+#define PROC_THERMAL_FEATURE_WLT_HINT	0x20
 
 #if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
 int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
@@ -95,6 +96,12 @@ int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev, bool enable, i
 					    int time_window);
 int proc_thermal_add(struct device *dev, struct proc_thermal_device *priv);
 void proc_thermal_remove(struct proc_thermal_device *proc_priv);
+
+int proc_thermal_wlt_hint_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
+void proc_thermal_wlt_hint_remove(struct pci_dev *pdev);
+void proc_thermal_wlt_intr_callback(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
+bool proc_thermal_check_wlt_intr(struct proc_thermal_device *proc_priv);
+
 int proc_thermal_suspend(struct device *dev);
 int proc_thermal_resume(struct device *dev);
 int proc_thermal_mmio_add(struct pci_dev *pdev,
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
index 3dab3dbdbbc6..edddebedf42e 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -364,7 +364,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
 	{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ) },
 	{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL |
-	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR) },
+	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
+	  PROC_THERMAL_FEATURE_WLT_HINT) },
 	{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WLT_REQ) },
 	{ },
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
new file mode 100644
index 000000000000..6b72ba665167
--- /dev/null
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * processor thermal device for reading Workload type hints
+ * from the user space. The hints are provided by the firmware.
+ *
+ * Operation:
+ * When user space enables workload type prediction:
+ * - Use mailbox to configure:
+ *	Configure notification delay
+ *	Enable processor thermal device interrupt
+ * - The predicted workload type can be read from MMIO:
+ *	Offset 0x5B18 shows if there was an interrupt
+ *	active for change in workload type and also
+ *	predicted workload type.
+ *
+ * Two interface function are provided to call when there is a
+ * thermal device interrupt:
+ * - proc_thermal_check_wlt_intr(): Check if the is interrupt for
+ * change in workload type.
+ * - proc_thermal_wlt_intr_callback(): Callback for interrupt
+ * under thread context to process. This involves sending
+ * notification to user space that there is a change in workload
+ * type.
+ *
+ * Copyright (c) 2020-2023, Intel Corporation.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/pci.h>
+#include "processor_thermal_device.h"
+
+#define SOC_WLT_RES_INT_STATUS_OFF	0x5B18
+#define SOC_WLT_MASK			GENMASK_ULL(47, 40)
+
+#define SOC_WLT_PREDICTION_INT_ENABLE_BIT	23
+
+#define SOC_WLT_PREDICTION_INT_ACTIVE	BIT(2)
+
+/*
+ * Closest possible to 1 Second is 1024 ms with programmed time delay
+ * of 0x0A.
+ */
+static u8 notify_delay = 0x0A;
+static u16 notify_delay_ms = 1024;
+
+/* Show current predicted workload type index */
+static ssize_t workload_type_index_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct proc_thermal_device *proc_priv;
+	struct pci_dev *pdev = to_pci_dev(dev);
+	u64 status = 0;
+	int wlt;
+
+	proc_priv = pci_get_drvdata(pdev);
+
+	status = readq(proc_priv->mmio_base + SOC_WLT_RES_INT_STATUS_OFF);
+	wlt = FIELD_GET(SOC_WLT_MASK, status);
+
+	return sysfs_emit(buf, "%d\n", wlt);
+}
+
+static DEVICE_ATTR_RO(workload_type_index);
+
+static u8 wlt_enable;
+
+static ssize_t workload_hint_enable_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	return sysfs_emit(buf, "%d\n", wlt_enable);
+}
+
+/*
+ * Enable workload type prediction by writing 1 to enable, 0 to
+ * disable
+ */
+static ssize_t workload_hint_enable_store(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t size)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	u8 mode;
+
+	if (kstrtou8(buf, 10, &mode) || mode > 1)
+		return -EINVAL;
+
+	if (mode) {
+		int ret;
+
+		ret = processor_thermal_mbox_interrupt_config(pdev, true,
+							      SOC_WLT_PREDICTION_INT_ENABLE_BIT,
+							      notify_delay);
+		if (ret)
+			return ret;
+	} else {
+		processor_thermal_mbox_interrupt_config(pdev, false,
+							SOC_WLT_PREDICTION_INT_ENABLE_BIT, 0);
+	}
+
+	wlt_enable = mode;
+
+	return size;
+}
+
+static DEVICE_ATTR_RW(workload_hint_enable);
+
+static ssize_t notification_delay_ms_show(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	return sysfs_emit(buf, "%u\n", notify_delay_ms);
+}
+
+static ssize_t notification_delay_ms_store(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t size)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	u16 new_tw;
+	int ret;
+
+	/*
+	 * Time window register value:
+	 * Formula: (1 + x/4) * power(2,y)
+	 * x = 2 msbs, that is [30:29] y = 5 [28:24]
+	 * in INTR_CONFIG register.
+	 * The result will be in milli seconds.
+	 * Here, just keep x = 0, and just change y.
+	 * First round up the user value to power of 2 and
+	 * then take log2, to get "y" value to program.
+	 */
+	ret = kstrtou16(buf, 10, &new_tw);
+	if (ret)
+		return ret;
+
+	if (new_tw) {
+		u8 tm;
+
+		new_tw = roundup_pow_of_two(new_tw);
+		tm = ilog2(new_tw);
+		if (tm > 31)
+			return -EINVAL;
+
+		ret = processor_thermal_mbox_interrupt_config(pdev, true,
+							      SOC_WLT_PREDICTION_INT_ENABLE_BIT,
+							      tm);
+		if (ret)
+			return ret;
+
+		notify_delay = tm;
+		notify_delay_ms = new_tw;
+	} else {
+		ret = processor_thermal_mbox_interrupt_config(pdev, false,
+							      SOC_WLT_PREDICTION_INT_ENABLE_BIT,
+							      notify_delay);
+		if (ret)
+			return ret;
+	}
+
+	return size;
+}
+
+static DEVICE_ATTR_RW(notification_delay_ms);
+
+static struct attribute *workload_hint_attrs[] = {
+	&dev_attr_workload_type_index.attr,
+	&dev_attr_workload_hint_enable.attr,
+	&dev_attr_notification_delay_ms.attr,
+	NULL
+};
+
+static const struct attribute_group workload_hint_attribute_group = {
+	.attrs = workload_hint_attrs,
+	.name = "workload_hint"
+};
+
+/*
+ * Callback to check if interrupt for prediction is active.
+ * Caution: Called from interrupt context.
+ */
+bool proc_thermal_check_wlt_intr(struct proc_thermal_device *proc_priv)
+{
+	u64 int_status;
+
+	int_status = readq(proc_priv->mmio_base + SOC_WLT_RES_INT_STATUS_OFF);
+	if (int_status & SOC_WLT_PREDICTION_INT_ACTIVE)
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL_NS_GPL(proc_thermal_check_wlt_intr, INT340X_THERMAL);
+
+/* Callback to notify user space */
+void proc_thermal_wlt_intr_callback(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
+{
+	u64 status;
+
+	status = readq(proc_priv->mmio_base + SOC_WLT_RES_INT_STATUS_OFF);
+	if (status & SOC_WLT_PREDICTION_INT_ACTIVE) {
+		writeq(status & ~SOC_WLT_PREDICTION_INT_ACTIVE,
+		       proc_priv->mmio_base + SOC_WLT_RES_INT_STATUS_OFF);
+		sysfs_notify(&pdev->dev.kobj, "workload_hint", "workload_type_index");
+	}
+}
+EXPORT_SYMBOL_NS_GPL(proc_thermal_wlt_intr_callback, INT340X_THERMAL);
+
+static bool workload_hint_created;
+
+int proc_thermal_wlt_hint_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
+{
+	int ret;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &workload_hint_attribute_group);
+	if (ret)
+		return ret;
+
+	workload_hint_created = true;
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(proc_thermal_wlt_hint_add, INT340X_THERMAL);
+
+void proc_thermal_wlt_hint_remove(struct pci_dev *pdev)
+{
+	processor_thermal_mbox_interrupt_config(pdev, false,
+						SOC_WLT_PREDICTION_INT_ENABLE_BIT,
+						notify_delay);
+
+	if (workload_hint_created)
+		sysfs_remove_group(&pdev->dev.kobj, &workload_hint_attribute_group);
+
+	workload_hint_created = false;
+}
+EXPORT_SYMBOL_NS_GPL(proc_thermal_wlt_hint_remove, INT340X_THERMAL);
+
+MODULE_IMPORT_NS(INT340X_THERMAL);
+MODULE_LICENSE("GPL");
-- 
2.38.1


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

* [PATCH 6/7] thermal/drivers/int340x: Support workload hint interrupts
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
                   ` (4 preceding siblings ...)
  2023-06-20 23:01 ` [PATCH 5/7] thermal: int340x: processor_thermal: Add workload type hint Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-20 23:01 ` [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint Srinivas Pandruvada
  2023-06-21 14:58 ` [PATCH 0/7] thermal: processor_thermal: Suport " Rafael J. Wysocki
  7 siblings, 0 replies; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

On thermal device interrupt, if the interrupt is generated for passing
workload hint, call the callback to pass notification to the user
space.

First call proc_thermal_check_wlt_intr() to check interrupt, if this
callback returns true, wake IRQ thread. Call
proc_thermal_wlt_intr_callback() to notify user space.

While here remove function pkg_thermal_schedule_work() and move the
processing to the caller. The function pkg_thermal_schedule_work() just
called schedule_delayed_work().

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../processor_thermal_device_pci.c            | 33 ++++++++++++++-----
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
index edddebedf42e..7fa5c3d459bd 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -115,27 +115,40 @@ static void proc_thermal_threshold_work_fn(struct work_struct *work)
 	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
 }
 
-static void pkg_thermal_schedule_work(struct delayed_work *work)
+static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid)
 {
-	unsigned long ms = msecs_to_jiffies(notify_delay_ms);
+	struct proc_thermal_pci *pci_info = devid;
+
+	proc_thermal_wlt_intr_callback(pci_info->pdev, pci_info->proc_priv);
 
-	schedule_delayed_work(work, ms);
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
 {
 	struct proc_thermal_pci *pci_info = devid;
+	struct proc_thermal_device *proc_priv;
+	int ret = IRQ_HANDLED;
 	u32 status;
 
+	proc_priv = pci_info->proc_priv;
+
+	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WLT_HINT) {
+		if (proc_thermal_check_wlt_intr(pci_info->proc_priv))
+			ret = IRQ_WAKE_THREAD;
+	}
+
 	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_INT_STATUS_0, &status);
+	if (status) {
+		unsigned long ms = msecs_to_jiffies(notify_delay_ms);
 
-	/* Disable enable interrupt flag */
-	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
+		/* Disable enable interrupt flag */
+		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
+		schedule_delayed_work(&pci_info->work, ms);
+	}
 	pci_write_config_byte(pci_info->pdev, 0xdc, 0x01);
 
-	pkg_thermal_schedule_work(&pci_info->work);
-
-	return IRQ_HANDLED;
+	return ret;
 }
 
 static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
@@ -269,7 +282,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
 	}
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq,
-					proc_thermal_irq_handler, NULL,
+					proc_thermal_irq_handler, proc_thermal_irq_thread_handler,
 					irq_flag, KBUILD_MODNAME, pci_info);
 	if (ret) {
 		dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq);
@@ -383,6 +396,8 @@ static struct pci_driver proc_thermal_pci_driver = {
 
 module_pci_driver(proc_thermal_pci_driver);
 
+MODULE_IMPORT_NS(INT340X_THERMAL);
+
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
 MODULE_LICENSE("GPL v2");
-- 
2.38.1


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

* [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
                   ` (5 preceding siblings ...)
  2023-06-20 23:01 ` [PATCH 6/7] thermal/drivers/int340x: Support workload hint interrupts Srinivas Pandruvada
@ 2023-06-20 23:01 ` Srinivas Pandruvada
  2023-06-21 14:30   ` Zhang, Rui
  2023-06-21 14:58 ` [PATCH 0/7] thermal: processor_thermal: Suport " Rafael J. Wysocki
  7 siblings, 1 reply; 20+ messages in thread
From: Srinivas Pandruvada @ 2023-06-20 23:01 UTC (permalink / raw)
  To: rafael, rui.zhang, daniel.lezcano
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Some SoCs have in built firmware support to classify current running
workload and pass to OS for making power management decisions.

This test program waits for notification of workload type change
and prints. This program can be used to test this feature and also
allows other user space programs to use as a reference.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../testing/selftests/thermal/intel/Makefile  |  16 +++
 .../thermal/intel/workload_hint_test.c        | 114 ++++++++++++++++++
 2 files changed, 130 insertions(+)
 create mode 100644 tools/testing/selftests/thermal/intel/Makefile
 create mode 100644 tools/testing/selftests/thermal/intel/workload_hint_test.c

diff --git a/tools/testing/selftests/thermal/intel/Makefile b/tools/testing/selftests/thermal/intel/Makefile
new file mode 100644
index 000000000000..02459e271ef7
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/Makefile
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+ifndef CROSS_COMPILE
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+TEST_PROGS := workload_hint_test
+
+all: $(TEST_PROGS)
+
+include ../../lib.mk
+
+clean:
+	rm -fr $(TEST_PROGS)
+endif
+endif
diff --git a/tools/testing/selftests/thermal/intel/workload_hint_test.c b/tools/testing/selftests/thermal/intel/workload_hint_test.c
new file mode 100644
index 000000000000..69a48a8ccbb4
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/workload_hint_test.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+
+#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay_ms"
+#define WORKLOAD_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enable"
+#define WORKLOAD_TYPE_INDEX_ATTRIBUTE  "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_index"
+
+static const char * const workload_types[] = {
+	"idle",
+	"battery_life",
+	"sustained",
+	"bursty",
+	NULL
+};
+
+#define WORKLOAD_TYPE_MAX_INDEX	3
+
+int main(int argc, char **argv) {
+	struct pollfd ufd;
+	char index_str[4];
+	int fd, ret, index;
+	int delay = 0;
+
+	if (argc > 1) {
+		char delay_str[64];
+
+		sscanf(argv[1], "%d", &delay);
+		printf("Setting notification delay to %d ms\n", delay);
+
+		if (delay < 0)
+			exit(1);
+
+		sprintf(delay_str, "%s\n", argv[1]);
+
+		if ((fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE, O_RDWR)) < 0) {
+			perror("Unable to open workload notification delay\n");
+			exit(1);
+		}
+
+		if (write(fd, delay_str, strlen(delay_str)) < 0) {
+			perror("Can't set delay\n");
+			exit(1);
+		}
+
+		close(fd);
+
+	}
+
+	/* Enable feature via sysfs knob */
+	if ((fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR)) < 0) {
+		perror("Unable to open workload type feature enable file\n");
+		exit(1);
+	}
+
+	if (write(fd, "1\n", 2) < 0) {
+		perror("Can' enable workload hints\n");
+		exit(1);
+	}
+
+	close(fd);
+
+	while (1) {
+		if ((fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE, O_RDONLY)) < 0) {
+			perror("Unable to open workload type file\n");
+			exit(1);
+		}
+
+		if ((lseek(fd, 0L, SEEK_SET)) < 0) {
+			fprintf(stderr, "Failed to set pointer to beginning\n");
+			exit(1);
+		}
+
+		if (read(fd, index_str, sizeof(index_str)) < 0) {
+			fprintf(stderr, "Failed to read from:%s\n",
+			WORKLOAD_TYPE_INDEX_ATTRIBUTE);
+			exit(1);
+		}
+
+		ufd.fd = fd;
+		ufd.events = POLLPRI;
+
+		if ((ret = poll(&ufd, 1, -1)) < 0) {
+			perror("poll error");
+			exit(1);
+		} else if (ret == 0) {
+			printf("Poll Timeout\n");
+		} else {
+			if ((lseek(fd, 0L, SEEK_SET)) < 0) {
+				fprintf(stderr, "Failed to set pointer to beginning\n");
+				exit(1);
+			}
+
+			if (read(fd, index_str, sizeof(index_str)) < 0) {
+				exit(0);
+			}
+
+			sscanf(index_str, "%d", &index);
+			if (index > WORKLOAD_TYPE_MAX_INDEX)
+				printf("Invalid workload type index\n");
+			else
+				printf("workload type:%s\n", workload_types[index]);
+		}
+
+		close(fd);
+	}
+}
-- 
2.38.1


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

* Re: [PATCH 5/7] thermal: int340x: processor_thermal: Add workload type hint
  2023-06-20 23:01 ` [PATCH 5/7] thermal: int340x: processor_thermal: Add workload type hint Srinivas Pandruvada
@ 2023-06-21 14:12   ` Zhang, Rui
  0 siblings, 0 replies; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:12 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> 
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
> new file mode 100644
> index 000000000000..6b72ba665167
> --- /dev/null
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
> @@ -0,0 +1,239 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * processor thermal device for reading Workload type hints
> + * from the user space. The hints are provided by the firmware.
> + *
> + * Operation:
> + * When user space enables workload type prediction:
> + * - Use mailbox to configure:
> + *     Configure notification delay
> + *     Enable processor thermal device interrupt
> + * - The predicted workload type can be read from MMIO:
> + *     Offset 0x5B18 shows if there was an interrupt
> + *     active for change in workload type and also
> + *     predicted workload type.
> + *
> + * Two interface function

s/function/functions

>  are provided to call when there is a
> + * thermal device interrupt:
> + * - proc_thermal_check_wlt_intr(): Check if the is interrupt for
> + * change in workload type.

s/is interrupt/ interrupt is ?

> + * - proc_thermal_wlt_intr_callback(): Callback for interrupt
> + * under thread context to process. This involves sending
> + * notification to user space that there is a change in workload
> + * type.
> + *
> + * Copyright (c) 2020-2023, Intel Corporation.

This is new code, should the copyright starts from 2020?

thanks,
rui

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

* Re: [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint
  2023-06-20 23:01 ` [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint Srinivas Pandruvada
@ 2023-06-21 14:30   ` Zhang, Rui
  2023-06-21 14:40     ` srinivas pandruvada
  2023-06-21 14:58     ` Zhang, Rui
  0 siblings, 2 replies; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:30 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> Some SoCs have in built firmware support to classify current running
> workload and pass to OS for making power management decisions.
> 
> This test program waits for notification of workload type change
> and prints. This program can be used to test this feature and also
> allows other user space programs to use as a reference.
> 
> Signed-off-by: Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com>
> ---
>  .../testing/selftests/thermal/intel/Makefile  |  16 +++
>  .../thermal/intel/workload_hint_test.c        | 114
> ++++++++++++++++++
>  2 files changed, 130 insertions(+)
>  create mode 100644 tools/testing/selftests/thermal/intel/Makefile
>  create mode 100644
> tools/testing/selftests/thermal/intel/workload_hint_test.c
> 
> diff --git a/tools/testing/selftests/thermal/intel/Makefile
> b/tools/testing/selftests/thermal/intel/Makefile
> new file mode 100644
> index 000000000000..02459e271ef7
> --- /dev/null
> +++ b/tools/testing/selftests/thermal/intel/Makefile
> @@ -0,0 +1,16 @@
> +# SPDX-License-Identifier: GPL-2.0
> +ifndef CROSS_COMPILE
> +uname_M := $(shell uname -m 2>/dev/null || echo not)
> +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e
> s/x86_64/x86/)
> +
> +ifeq ($(ARCH),x86)
> +TEST_PROGS := workload_hint_test
> +
> +all: $(TEST_PROGS)
> +
> +include ../../lib.mk
> +
> +clean:
> +       rm -fr $(TEST_PROGS)
> +endif
> +endif
> diff --git
> a/tools/testing/selftests/thermal/intel/workload_hint_test.c
> b/tools/testing/selftests/thermal/intel/workload_hint_test.c
> new file mode 100644
> index 000000000000..69a48a8ccbb4
> --- /dev/null
> +++ b/tools/testing/selftests/thermal/intel/workload_hint_test.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#define _GNU_SOURCE
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <poll.h>
> +
> +#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE
> "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay_m
> s"
> +#define WORKLOAD_ENABLE_ATTRIBUTE
> "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enable
> "
> +#define WORKLOAD_TYPE_INDEX_ATTRIBUTE 
> "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_index"
> +
> +static const char * const workload_types[] = {
> +       "idle",
> +       "battery_life",
> +       "sustained",
> +       "bursty",
> +       NULL
> +};
> +
> +#define WORKLOAD_TYPE_MAX_INDEX        3
> +
> +int main(int argc, char **argv) {
> +       struct pollfd ufd;
> +       char index_str[4];
> +       int fd, ret, index;
> +       int delay = 0;
> +
> +       if (argc > 1) {
> +               char delay_str[64];
> +
> +               sscanf(argv[1], "%d", &delay);
> +               printf("Setting notification delay to %d ms\n",
> delay);
> +
> +               if (delay < 0)
> +                       exit(1);
> +
> +               sprintf(delay_str, "%s\n", argv[1]);
> +
> +               if ((fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE,
> O_RDWR)) < 0) {
> +                       perror("Unable to open workload notification
> delay\n");
> +                       exit(1);
> +               }
> +
> +               if (write(fd, delay_str, strlen(delay_str)) < 0) {
> +                       perror("Can't set delay\n");
> +                       exit(1);
> +               }
> +
> +               close(fd);
> +
> +       }
> +
> +       /* Enable feature via sysfs knob */
> +       if ((fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR)) < 0) {
> +               perror("Unable to open workload type feature enable
> file\n");
> +               exit(1);
> +       }
> +
> +       if (write(fd, "1\n", 2) < 0) {
> +               perror("Can' enable workload hints\n");
> +               exit(1);
> +       }
> +
> +       close(fd);

This enables WORKLOAD_ENABLE_ATTRIBUTE without disabling it again.
As a test program, maybe we can add a timeout, and stop polling &
disable the WORKLOAD_ENABLE_ATTRIBUTE after the timeout?

thanks,
rui
> +
> +       while (1) {
> +               if ((fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE,
> O_RDONLY)) < 0) {
> +                       perror("Unable to open workload type
> file\n");
> +                       exit(1);
> +               }
> +
> +               if ((lseek(fd, 0L, SEEK_SET)) < 0) {
> +                       fprintf(stderr, "Failed to set pointer to
> beginning\n");
> +                       exit(1);
> +               }
> +
> +               if (read(fd, index_str, sizeof(index_str)) < 0) {
> +                       fprintf(stderr, "Failed to read from:%s\n",
> +                       WORKLOAD_TYPE_INDEX_ATTRIBUTE);
> +                       exit(1);
> +               }
> +
> +               ufd.fd = fd;
> +               ufd.events = POLLPRI;
> +
> +               if ((ret = poll(&ufd, 1, -1)) < 0) {
> +                       perror("poll error");
> +                       exit(1);
> +               } else if (ret == 0) {
> +                       printf("Poll Timeout\n");
> +               } else {
> +                       if ((lseek(fd, 0L, SEEK_SET)) < 0) {
> +                               fprintf(stderr, "Failed to set
> pointer to beginning\n");
> +                               exit(1);
> +                       }
> +
> +                       if (read(fd, index_str, sizeof(index_str)) <
> 0) {
> +                               exit(0);
> +                       }
> +
> +                       sscanf(index_str, "%d", &index);
> +                       if (index > WORKLOAD_TYPE_MAX_INDEX)
> +                               printf("Invalid workload type
> index\n");
> +                       else
> +                               printf("workload type:%s\n",
> workload_types[index]);
> +               }
> +
> +               close(fd);
> +       }
> +}


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

* Re: [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module
  2023-06-20 23:01 ` [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module Srinivas Pandruvada
@ 2023-06-21 14:35   ` Zhang, Rui
  0 siblings, 0 replies; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:35 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> The processor thermal mailbox is used for workload type request and
> also in the processor thermal RFIM module. So, move the workload type
> request code to its own module from the current processor thermal
> mailbox module.
> 
> processor_thermal_mailbox.c contains only mailbox read/write related
> source code. The source related to workload_types requests is moved
> to
> a module processor_thermal_wlt_req.c.
> 
> In addition
> -Rename PROC_THERMAL_FEATURE_MBOX to PROC_THERMAL_FEATURE_WLT_REQ.
> - proc_thermal_mbox_add(), which adds workload type sysfs attribute
> group
> is renamed to proc_thermal_wlt_req_add().
> -proc_thermal_mbox_remove() is renamed to
> proc_thermal_wlt_req_remove().
> 
> While here, resolve check patch warnings for 100 columns for only
> modified
> lines.
> 
> No functional changes are expected.
> 
> Signed-off-by: Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com>
> ---
>  .../thermal/intel/int340x_thermal/Makefile    |   1 +
>  .../processor_thermal_device.c                |   8 +-
>  .../processor_thermal_device.h                |  12 +-
>  .../processor_thermal_device_pci.c            |  10 +-
>  .../processor_thermal_device_pci_legacy.c     |   3 +-
>  .../int340x_thermal/processor_thermal_mbox.c  | 130 ----------------
> -
>  .../processor_thermal_wlt_req.c               | 137
> ++++++++++++++++++
>  7 files changed, 160 insertions(+), 141 deletions(-)
>  create mode 100644
> drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
> 
> diff --git a/drivers/thermal/intel/int340x_thermal/Makefile
> b/drivers/thermal/intel/int340x_thermal/Makefile
> index 4e852ce4a5d5..76e053e541f0 100644
> --- a/drivers/thermal/intel/int340x_thermal/Makefile
> +++ b/drivers/thermal/intel/int340x_thermal/Makefile
> @@ -10,5 +10,6 @@ obj-$(CONFIG_INT340X_THERMAL) +=
> processor_thermal_device_pci.o
>  obj-$(CONFIG_PROC_THERMAL_MMIO_RAPL) += processor_thermal_rapl.o
>  obj-$(CONFIG_INT340X_THERMAL)  += processor_thermal_rfim.o
>  obj-$(CONFIG_INT340X_THERMAL)  += processor_thermal_mbox.o
> +obj-$(CONFIG_INT340X_THERMAL)  += processor_thermal_wlt_req.o
>  obj-$(CONFIG_INT3406_THERMAL)  += int3406_thermal.o
>  obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> index 3ca0a2f5937f..48f6c72b05f6 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
> @@ -346,8 +346,8 @@ int proc_thermal_mmio_add(struct pci_dev *pdev,
>                 }
>         }
>  
> -       if (feature_mask & PROC_THERMAL_FEATURE_MBOX) {
> -               ret = proc_thermal_mbox_add(pdev, proc_priv);
> +       if (feature_mask & PROC_THERMAL_FEATURE_WLT_REQ) {
> +               ret = proc_thermal_wlt_req_add(pdev, proc_priv);
>                 if (ret) {
>                         dev_err(&pdev->dev, "failed to add MBOX
> interface\n");
>                         goto err_rem_rfim;
> @@ -374,8 +374,8 @@ void proc_thermal_mmio_remove(struct pci_dev
> *pdev, struct proc_thermal_device *
>             proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS)
>                 proc_thermal_rfim_remove(pdev);
>  
> -       if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MBOX)
> -               proc_thermal_mbox_remove(pdev);
> +       if (proc_priv->mmio_feature_mask &
> PROC_THERMAL_FEATURE_WLT_REQ)
> +               proc_thermal_wlt_req_remove(pdev);
>  }
>  EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove);
>  
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> index 7acaa8f1b896..7cdeca2edc21 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> @@ -59,7 +59,7 @@ struct rapl_mmio_regs {
>  #define PROC_THERMAL_FEATURE_RAPL      0x01
>  #define PROC_THERMAL_FEATURE_FIVR      0x02
>  #define PROC_THERMAL_FEATURE_DVFS      0x04
> -#define PROC_THERMAL_FEATURE_MBOX      0x08
> +#define PROC_THERMAL_FEATURE_WLT_REQ   0x08
>  #define PROC_THERMAL_FEATURE_DLVR      0x10
>  
>  #if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
> @@ -80,8 +80,14 @@ static void __maybe_unused
> proc_thermal_rapl_remove(void)
>  int proc_thermal_rfim_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv);
>  void proc_thermal_rfim_remove(struct pci_dev *pdev);
>  
> -int proc_thermal_mbox_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv);
> -void proc_thermal_mbox_remove(struct pci_dev *pdev);
> +int proc_thermal_wlt_req_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv);
> +void proc_thermal_wlt_req_remove(struct pci_dev *pdev);
> +
> +#define MBOX_CMD_WORKLOAD_TYPE_READ    0x0E
> +#define MBOX_CMD_WORKLOAD_TYPE_WRITE   0x0F
> +
> +#define MBOX_DATA_BIT_AC_DC            30
> +#define MBOX_DATA_BIT_VALID            31
>  
>  int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16
> id, u64 *resp);
>  int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16
> id, u32 data);
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> index 0d1e98007270..5a2bcfff0a68 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> @@ -350,9 +350,13 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm,
> proc_thermal_pci_suspend,
>                          proc_thermal_pci_resume);
>  
>  static const struct pci_device_id proc_thermal_pci_ids[] = {
> -       { PCI_DEVICE_DATA(INTEL, ADL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR |
> PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
> -       { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL,
> PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR |
> PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX |
> PROC_THERMAL_FEATURE_DLVR) },
> -       { PCI_DEVICE_DATA(INTEL, RPL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR |
> PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) },
> +       { PCI_DEVICE_DATA(INTEL, ADL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
> +         PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_WLT_REQ) },
> +       { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
> +         PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_WLT_REQ |
> +         PROC_THERMAL_FEATURE_DLVR) },
> +       { PCI_DEVICE_DATA(INTEL, RPL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
> +         PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_WLT_REQ) },
>         { },
>  };
>  
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_
> legacy.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_
> legacy.c
> index 09e032f822f3..b8c58a44fb93 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_
> legacy.c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_
> legacy.c
> @@ -137,7 +137,8 @@ static const struct pci_device_id
> proc_thermal_pci_ids[] = {
>         { PCI_DEVICE_DATA(INTEL, ICL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL) },
>         { PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) },
>         { PCI_DEVICE_DATA(INTEL, SKL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL) },
> -       { PCI_DEVICE_DATA(INTEL, TGL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR |
> PROC_THERMAL_FEATURE_MBOX) },
> +       { PCI_DEVICE_DATA(INTEL, TGL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
> +         PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_WLT_REQ)
> },
>         { },
>  };
>  
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> index 0b89a4340ff4..ec766c5615b7 100644
> --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> @@ -10,18 +10,12 @@
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include "processor_thermal_device.h"
>  
> -#define MBOX_CMD_WORKLOAD_TYPE_READ    0x0E
> -#define MBOX_CMD_WORKLOAD_TYPE_WRITE   0x0F
> -
>  #define MBOX_OFFSET_DATA               0x5810
>  #define MBOX_OFFSET_INTERFACE          0x5818
>  
>  #define MBOX_BUSY_BIT                  31
>  #define MBOX_RETRY_COUNT               100
>  
> -#define MBOX_DATA_BIT_VALID            31
> -#define MBOX_DATA_BIT_AC_DC            30
> -
>  static DEFINE_MUTEX(mbox_lock);
>  
>  static int wait_for_mbox_ready(struct proc_thermal_device
> *proc_priv)
> @@ -114,128 +108,4 @@ int
> processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id,
> u32 data
>  }
>  EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd,
> INT340X_THERMAL);
>  
> -/* List of workload types */
> -static const char * const workload_types[] = {
> -       "none",
> -       "idle",
> -       "semi_active",
> -       "bursty",
> -       "sustained",
> -       "battery_life",
> -       NULL
> -};
> -
> -static ssize_t workload_available_types_show(struct device *dev,
> -                                              struct
> device_attribute *attr,
> -                                              char *buf)
> -{
> -       int i = 0;
> -       int ret = 0;
> -
> -       while (workload_types[i] != NULL)
> -               ret += sprintf(&buf[ret], "%s ",
> workload_types[i++]);
> -
> -       ret += sprintf(&buf[ret], "\n");
> -
> -       return ret;
> -}
> -
> -static DEVICE_ATTR_RO(workload_available_types);
> -
> -static ssize_t workload_type_store(struct device *dev,
> -                                   struct device_attribute *attr,
> -                                   const char *buf, size_t count)
> -{
> -       struct pci_dev *pdev = to_pci_dev(dev);
> -       char str_preference[15];
> -       u32 data = 0;
> -       ssize_t ret;
> -
> -       ret = sscanf(buf, "%14s", str_preference);
> -       if (ret != 1)
> -               return -EINVAL;
> -
> -       ret = match_string(workload_types, -1, str_preference);
> -       if (ret < 0)
> -               return ret;
> -
> -       ret &= 0xff;
> -
> -       if (ret)
> -               data = BIT(MBOX_DATA_BIT_VALID) |
> BIT(MBOX_DATA_BIT_AC_DC);
> -
> -       data |= ret;
> -
> -       ret = send_mbox_write_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_WRITE,
> data);
> -       if (ret)
> -               return false;
> -
> -       return count;
> -}
> -
> -static ssize_t workload_type_show(struct device *dev,
> -                                  struct device_attribute *attr,
> -                                  char *buf)
> -{
> -       struct pci_dev *pdev = to_pci_dev(dev);
> -       u64 cmd_resp;
> -       int ret;
> -
> -       ret = send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ,
> &cmd_resp);
> -       if (ret)
> -               return false;
> -
> -       cmd_resp &= 0xff;
> -
> -       if (cmd_resp > ARRAY_SIZE(workload_types) - 1)
> -               return -EINVAL;
> -
> -       return sprintf(buf, "%s\n", workload_types[cmd_resp]);
> -}
> -
> -static DEVICE_ATTR_RW(workload_type);
> -
> -static struct attribute *workload_req_attrs[] = {
> -       &dev_attr_workload_available_types.attr,
> -       &dev_attr_workload_type.attr,
> -       NULL
> -};
> -
> -static const struct attribute_group workload_req_attribute_group = {
> -       .attrs = workload_req_attrs,
> -       .name = "workload_request"
> -};
> -
> -static bool workload_req_created;
> -
> -int proc_thermal_mbox_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv)
> -{
> -       u64 cmd_resp;
> -       int ret;
> -
> -       /* Check if there is a mailbox support, if fails return
> success */
> -       ret = send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ,
> &cmd_resp);
> -       if (ret)
> -               return 0;
> -
> -       ret = sysfs_create_group(&pdev->dev.kobj,
> &workload_req_attribute_group);
> -       if (ret)
> -               return ret;
> -
> -       workload_req_created = true;
> -
> -       return 0;
> -}
> -EXPORT_SYMBOL_GPL(proc_thermal_mbox_add);
> -
> -void proc_thermal_mbox_remove(struct pci_dev *pdev)
> -{
> -       if (workload_req_created)
> -               sysfs_remove_group(&pdev->dev.kobj,
> &workload_req_attribute_group);
> -
> -       workload_req_created = false;
> -
> -}
> -EXPORT_SYMBOL_GPL(proc_thermal_mbox_remove);
> -
>  MODULE_LICENSE("GPL v2");
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
> new file mode 100644
> index 000000000000..d22c86fad231
> --- /dev/null
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
> @@ -0,0 +1,137 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * processor thermal device for Workload type hints
> + * update from user space
> + *
> + * Copyright (c) 2020-2023, Intel Corporation.

Just curious, is this the proper change when re-locating the code?

> + */
> +
> +#include <linux/pci.h>
> +#include "processor_thermal_device.h"
> +
> +/* List of workload types */
> +static const char * const workload_types[] = {
> +       "none",
> +       "idle",
> +       "semi_active",
> +       "bursty",
> +       "sustained",
> +       "battery_life",
> +       NULL
> +};
> +
> +static ssize_t workload_available_types_show(struct device *dev,
> +                                              struct
> device_attribute *attr,
> +                                              char *buf)
> +{
> +       int i = 0;
> +       int ret = 0;
> +
> +       while (workload_types[i] != NULL)
> +               ret += sprintf(&buf[ret], "%s ",
> workload_types[i++]);
> +
> +       ret += sprintf(&buf[ret], "\n");
> +
> +       return ret;
> +}
> +
> +static DEVICE_ATTR_RO(workload_available_types);
> +
> +static ssize_t workload_type_store(struct device *dev,
> +                                   struct device_attribute *attr,
> +                                   const char *buf, size_t count)
> +{
> +       struct pci_dev *pdev = to_pci_dev(dev);
> +       char str_preference[15];
> +       u32 data = 0;
> +       ssize_t ret;
> +
> +       ret = sscanf(buf, "%14s", str_preference);
> +       if (ret != 1)
> +               return -EINVAL;
> +
> +       ret = match_string(workload_types, -1, str_preference);
> +       if (ret < 0)
> +               return ret;
> +
> +       ret &= 0xff;
> +
> +       if (ret)
> +               data = BIT(MBOX_DATA_BIT_VALID) |
> BIT(MBOX_DATA_BIT_AC_DC);
> +
> +       data |= ret;
> +
> +       ret = processor_thermal_send_mbox_write_cmd(pdev,
> MBOX_CMD_WORKLOAD_TYPE_WRITE, data);
> +       if (ret)
> +               return false;
> +
> +       return count;
> +}
> +
> +static ssize_t workload_type_show(struct device *dev,
> +                                  struct device_attribute *attr,
> +                                  char *buf)
> +{
> +       struct pci_dev *pdev = to_pci_dev(dev);
> +       u64 cmd_resp;
> +       int ret;
> +
> +       ret = processor_thermal_send_mbox_read_cmd(pdev,
> MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp);
> +       if (ret)
> +               return false;
> +
> +       cmd_resp &= 0xff;
> +
> +       if (cmd_resp > ARRAY_SIZE(workload_types) - 1)
> +               return -EINVAL;
> +
> +       return sprintf(buf, "%s\n", workload_types[cmd_resp]);
> +}
> +
> +static DEVICE_ATTR_RW(workload_type);
> +
> +static struct attribute *workload_req_attrs[] = {
> +       &dev_attr_workload_available_types.attr,
> +       &dev_attr_workload_type.attr,
> +       NULL
> +};
> +
> +static const struct attribute_group workload_req_attribute_group = {
> +       .attrs = workload_req_attrs,
> +       .name = "workload_request"
> +};
> +
> +static bool workload_req_created;
> +
> +int proc_thermal_wlt_req_add(struct pci_dev *pdev, struct
> proc_thermal_device *proc_priv)
> +{
> +       u64 cmd_resp;
> +       int ret;
> +
> +       /* Check if there is a mailbox support, if fails return
> success */
> +       ret = processor_thermal_send_mbox_read_cmd(pdev,
> MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp);
> +       if (ret)
> +               return 0;
> +
> +       ret = sysfs_create_group(&pdev->dev.kobj,
> &workload_req_attribute_group);
> +       if (ret)
> +               return ret;
> +
> +       workload_req_created = true;
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(proc_thermal_wlt_req_add);
> +
> +void proc_thermal_wlt_req_remove(struct pci_dev *pdev)
> +{
> +       if (workload_req_created)
> +               sysfs_remove_group(&pdev->dev.kobj,
> &workload_req_attribute_group);
> +
> +       workload_req_created = false;
> +
> +}

extra blank line.
This is already there in the previous code, but still better to clean
it up.

Other than that,

Reviewed-by: Zhang Rui <rui.zhang@intel.com>

thanks,
rui


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

* Re: [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint
  2023-06-21 14:30   ` Zhang, Rui
@ 2023-06-21 14:40     ` srinivas pandruvada
  2023-06-21 14:58     ` Zhang, Rui
  1 sibling, 0 replies; 20+ messages in thread
From: srinivas pandruvada @ 2023-06-21 14:40 UTC (permalink / raw)
  To: Zhang, Rui, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Wed, 2023-06-21 at 14:30 +0000, Zhang, Rui wrote:
> On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> > Some SoCs have in built firmware support to classify current
> > running
> > workload and pass to OS for making power management decisions.
> > 
> > This test program waits for notification of workload type change
> > and prints. This program can be used to test this feature and also
> > allows other user space programs to use as a reference.
> > 
> > Signed-off-by: Srinivas Pandruvada
> > <srinivas.pandruvada@linux.intel.com>
> > ---
> >  .../testing/selftests/thermal/intel/Makefile  |  16 +++
> >  .../thermal/intel/workload_hint_test.c        | 114
> > ++++++++++++++++++
> >  2 files changed, 130 insertions(+)
> >  create mode 100644 tools/testing/selftests/thermal/intel/Makefile
> >  create mode 100644
> > tools/testing/selftests/thermal/intel/workload_hint_test.c
> > 
> > diff --git a/tools/testing/selftests/thermal/intel/Makefile
> > b/tools/testing/selftests/thermal/intel/Makefile
> > new file mode 100644
> > index 000000000000..02459e271ef7
> > --- /dev/null
> > +++ b/tools/testing/selftests/thermal/intel/Makefile
> > @@ -0,0 +1,16 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +ifndef CROSS_COMPILE
> > +uname_M := $(shell uname -m 2>/dev/null || echo not)
> > +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e
> > s/x86_64/x86/)
> > +
> > +ifeq ($(ARCH),x86)
> > +TEST_PROGS := workload_hint_test
> > +
> > +all: $(TEST_PROGS)
> > +
> > +include ../../lib.mk
> > +
> > +clean:
> > +       rm -fr $(TEST_PROGS)
> > +endif
> > +endif
> > diff --git
> > a/tools/testing/selftests/thermal/intel/workload_hint_test.c
> > b/tools/testing/selftests/thermal/intel/workload_hint_test.c
> > new file mode 100644
> > index 000000000000..69a48a8ccbb4
> > --- /dev/null
> > +++ b/tools/testing/selftests/thermal/intel/workload_hint_test.c
> > @@ -0,0 +1,114 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#define _GNU_SOURCE
> > +
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <fcntl.h>
> > +#include <poll.h>
> > +
> > +#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE
> > "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay
> > _m
> > s"
> > +#define WORKLOAD_ENABLE_ATTRIBUTE
> > "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enab
> > le
> > "
> > +#define WORKLOAD_TYPE_INDEX_ATTRIBUTE 
> > "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_inde
> > x"
> > +
> > +static const char * const workload_types[] = {
> > +       "idle",
> > +       "battery_life",
> > +       "sustained",
> > +       "bursty",
> > +       NULL
> > +};
> > +
> > +#define WORKLOAD_TYPE_MAX_INDEX        3
> > +
> > +int main(int argc, char **argv) {
> > +       struct pollfd ufd;
> > +       char index_str[4];
> > +       int fd, ret, index;
> > +       int delay = 0;
> > +
> > +       if (argc > 1) {
> > +               char delay_str[64];
> > +
> > +               sscanf(argv[1], "%d", &delay);
> > +               printf("Setting notification delay to %d ms\n",
> > delay);
> > +
> > +               if (delay < 0)
> > +                       exit(1);
> > +
> > +               sprintf(delay_str, "%s\n", argv[1]);
> > +
> > +               if ((fd =
> > open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE,
> > O_RDWR)) < 0) {
> > +                       perror("Unable to open workload
> > notification
> > delay\n");
> > +                       exit(1);
> > +               }
> > +
> > +               if (write(fd, delay_str, strlen(delay_str)) < 0) {
> > +                       perror("Can't set delay\n");
> > +                       exit(1);
> > +               }
> > +
> > +               close(fd);
> > +
> > +       }
> > +
> > +       /* Enable feature via sysfs knob */
> > +       if ((fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR)) < 0) {
> > +               perror("Unable to open workload type feature enable
> > file\n");
> > +               exit(1);
> > +       }
> > +
> > +       if (write(fd, "1\n", 2) < 0) {
> > +               perror("Can' enable workload hints\n");
> > +               exit(1);
> > +       }
> > +
> > +       close(fd);
> 
> This enables WORKLOAD_ENABLE_ATTRIBUTE without disabling it again.
> As a test program, maybe we can add a timeout, and stop polling &
> disable the WORKLOAD_ENABLE_ATTRIBUTE after the timeout?
> 
We can or use signal to catch ctrl-c and do disable.

Thanks,
Srinivas

> thanks,
> rui
> > +
> > +       while (1) {
> > +               if ((fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE,
> > O_RDONLY)) < 0) {
> > +                       perror("Unable to open workload type
> > file\n");
> > +                       exit(1);
> > +               }
> > +
> > +               if ((lseek(fd, 0L, SEEK_SET)) < 0) {
> > +                       fprintf(stderr, "Failed to set pointer to
> > beginning\n");
> > +                       exit(1);
> > +               }
> > +
> > +               if (read(fd, index_str, sizeof(index_str)) < 0) {
> > +                       fprintf(stderr, "Failed to read from:%s\n",
> > +                       WORKLOAD_TYPE_INDEX_ATTRIBUTE);
> > +                       exit(1);
> > +               }
> > +
> > +               ufd.fd = fd;
> > +               ufd.events = POLLPRI;
> > +
> > +               if ((ret = poll(&ufd, 1, -1)) < 0) {
> > +                       perror("poll error");
> > +                       exit(1);
> > +               } else if (ret == 0) {
> > +                       printf("Poll Timeout\n");
> > +               } else {
> > +                       if ((lseek(fd, 0L, SEEK_SET)) < 0) {
> > +                               fprintf(stderr, "Failed to set
> > pointer to beginning\n");
> > +                               exit(1);
> > +                       }
> > +
> > +                       if (read(fd, index_str, sizeof(index_str))
> > <
> > 0) {
> > +                               exit(0);
> > +                       }
> > +
> > +                       sscanf(index_str, "%d", &index);
> > +                       if (index > WORKLOAD_TYPE_MAX_INDEX)
> > +                               printf("Invalid workload type
> > index\n");
> > +                       else
> > +                               printf("workload type:%s\n",
> > workload_types[index]);
> > +               }
> > +
> > +               close(fd);
> > +       }
> > +}
> 


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

* Re: [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration
  2023-06-20 23:01 ` [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration Srinivas Pandruvada
@ 2023-06-21 14:50   ` Zhang, Rui
  2023-06-21 15:02     ` srinivas pandruvada
  0 siblings, 1 reply; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:50 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> Some features on this PCI devices require interrupt support. Here
> interrupts are enabled/disabled via sending mailbox commands. The
> mailbox command ID is 0x1E for read and 0x1F for write.
> 
> The interrupt configuration will require mutex protection as it
> involved read-modify-write operation. Since mutex are already used
> in the mailbox read/write functions: send_mbox_write_cmd() and
> send_mbox_read_cmd(), there will be double locking. But, this can
> be avoided by moving mutexes from mailbox read/write processing
> functions to the calling (exported) functions.
> 
> Signed-off-by: Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com>
> ---
>  .../processor_thermal_device.h                |  2 +
>  .../int340x_thermal/processor_thermal_mbox.c  | 85 ++++++++++++++---
> --
>  2 files changed, 68 insertions(+), 19 deletions(-)
> 
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> index 7cdeca2edc21..defc919cb020 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> @@ -91,6 +91,8 @@ void proc_thermal_wlt_req_remove(struct pci_dev
> *pdev);
>  
>  int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16
> id, u64 *resp);
>  int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16
> id, u32 data);
> +int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev,
> bool enable, int enable_bit,
> +                                           int time_window);
>  int proc_thermal_add(struct device *dev, struct proc_thermal_device
> *priv);
>  void proc_thermal_remove(struct proc_thermal_device *proc_priv);
>  int proc_thermal_suspend(struct device *dev);
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> index ec766c5615b7..7ef0af3f5bef 100644
> --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> @@ -45,23 +45,16 @@ static int send_mbox_write_cmd(struct pci_dev
> *pdev, u16 id, u32 data)
>         int ret;
>  
>         proc_priv = pci_get_drvdata(pdev);
> -
> -       mutex_lock(&mbox_lock);
> -
>         ret = wait_for_mbox_ready(proc_priv);
>         if (ret)
> -               goto unlock_mbox;
> +               return ret;
>  
>         writel(data, (proc_priv->mmio_base + MBOX_OFFSET_DATA));
>         /* Write command register */
>         reg_data = BIT_ULL(MBOX_BUSY_BIT) | id;
>         writel(reg_data, (proc_priv->mmio_base +
> MBOX_OFFSET_INTERFACE));
>  
> -       ret = wait_for_mbox_ready(proc_priv);
> -
> -unlock_mbox:
> -       mutex_unlock(&mbox_lock);
> -       return ret;
> +       return wait_for_mbox_ready(proc_priv);
>  }
>  
>  static int send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64
> *resp)
> @@ -71,12 +64,9 @@ static int send_mbox_read_cmd(struct pci_dev
> *pdev, u16 id, u64 *resp)
>         int ret;
>  
>         proc_priv = pci_get_drvdata(pdev);
> -
> -       mutex_lock(&mbox_lock);
> -
>         ret = wait_for_mbox_ready(proc_priv);
>         if (ret)
> -               goto unlock_mbox;
> +               return ret;
>  
>         /* Write command register */
>         reg_data = BIT_ULL(MBOX_BUSY_BIT) | id;
> @@ -84,28 +74,85 @@ static int send_mbox_read_cmd(struct pci_dev
> *pdev, u16 id, u64 *resp)
>  
>         ret = wait_for_mbox_ready(proc_priv);
>         if (ret)
> -               goto unlock_mbox;
> +               return ret;
>  
>         if (id == MBOX_CMD_WORKLOAD_TYPE_READ)
>                 *resp = readl(proc_priv->mmio_base +
> MBOX_OFFSET_DATA);
>         else
>                 *resp = readq(proc_priv->mmio_base +
> MBOX_OFFSET_DATA);
>  
> -unlock_mbox:
> -       mutex_unlock(&mbox_lock);
> -       return ret;
> +       return 0;
>  }
>  
>  int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16
> id, u64 *resp)
>  {
> -       return send_mbox_read_cmd(pdev, id, resp);
> +       int ret;
> +
> +       mutex_lock(&mbox_lock);
> +       ret = send_mbox_read_cmd(pdev, id, resp);
> +       mutex_unlock(&mbox_lock);
> +
> +       return ret;
>  }
>  EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_read_cmd,
> INT340X_THERMAL);
>  
>  int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16
> id, u32 data)
>  {
> -       return send_mbox_write_cmd(pdev, id, data);
> +       int ret;
> +
> +       mutex_lock(&mbox_lock);
> +       ret = send_mbox_write_cmd(pdev, id, data);
> +       mutex_unlock(&mbox_lock);
> +
> +       return ret;
>  }
>  EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd,
> INT340X_THERMAL);
>  
> +#define MBOX_CAMARILLO_RD_INTR_CONFIG  0x1E
> +#define MBOX_CAMARILLO_WR_INTR_CONFIG  0x1F
> +#define WLT_TW_MASK                    GENMASK_ULL(30, 24)
> +#define SOC_PREDICTION_TW_SHIFT                24
> +
> +int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev,
> bool enable,
> +                                           int enable_bit, int
> time_window)

All the callers of this API in this patch series uses
SOC_WLT_PREDICTION_INT_ENABLE_BIT as the enable_bit, so this parameter
is redundant?
or do we expect a different enable_bit on other/future platforms?

thanks,
rui

> +{
> +       u64 data;
> +       int ret;
> +
> +       if (!pdev)
> +               return -ENODEV;
> +
> +       mutex_lock(&mbox_lock);
> +
> +       /* Do read modify write for MBOX_CAMARILLO_RD_INTR_CONFIG */
> +
> +       ret = send_mbox_read_cmd(pdev,
> MBOX_CAMARILLO_RD_INTR_CONFIG,  &data);
> +       if (ret) {
> +               dev_err(&pdev->dev, "MBOX_CAMARILLO_RD_INTR_CONFIG
> failed\n");
> +               goto unlock;
> +       }
> +
> +       if (time_window >= 0) {
> +               data &= ~WLT_TW_MASK;
> +
> +               /* Program notification delay */
> +               data |= (time_window << SOC_PREDICTION_TW_SHIFT);
> +       }
> +
> +       if (enable)
> +               data |= BIT(enable_bit);
> +       else
> +               data &= ~BIT(enable_bit);
> +
> +       ret = send_mbox_write_cmd(pdev,
> MBOX_CAMARILLO_WR_INTR_CONFIG, data);
> +       if (ret)
> +               dev_err(&pdev->dev, "MBOX_CAMARILLO_WR_INTR_CONFIG
> failed\n");
> +
> +unlock:
> +       mutex_unlock(&mbox_lock);
> +
> +       return ret;
> +}
> +EXPORT_SYMBOL_NS_GPL(processor_thermal_mbox_interrupt_config,
> INT340X_THERMAL);
> +
>  MODULE_LICENSE("GPL v2");


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

* Re: [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts
  2023-06-20 23:01 ` [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts Srinivas Pandruvada
@ 2023-06-21 14:53   ` Zhang, Rui
  2023-06-21 15:02     ` srinivas pandruvada
  0 siblings, 1 reply; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:53 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> There are issues in using MSI interrupts for processor thermal
> device.
> The support is not consistent, across generations. Even in the same
> generation, there are issue in getting interrupts via MSI.
> 
> Hence always use legacy PCI interrupts by default, instead of MSI.
> Add a module param to use of MSI, so that MSI can be still used.
> 
> Signed-off-by: Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com>
> ---
>  .../processor_thermal_device_pci.c            | 33 ++++++++++++-----
> --
>  1 file changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> index 5a2bcfff0a68..057778f7bece 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> @@ -15,6 +15,11 @@
>  
>  #define DRV_NAME "proc_thermal_pci"
>  
> +static int msi_enabled;
> +module_param(msi_enabled, int, 0644);

why not use

static bool msi_enabled;
module_params(msi_enabled, bool, 0644);

thanks,
rui

> +MODULE_PARM_DESC(msi_enabled,
> +       "Use PCI MSI based interrupts for processor thermal
> device.");
> +
>  struct proc_thermal_pci {
>         struct pci_dev *pdev;
>         struct proc_thermal_device *proc_priv;
> @@ -219,8 +224,6 @@ static int proc_thermal_pci_probe(struct pci_dev
> *pdev, const struct pci_device_
>                 return ret;
>         }
>  
> -       pci_set_master(pdev);
> -
>         INIT_DELAYED_WORK(&pci_info->work,
> proc_thermal_threshold_work_fn);
>  
>         ret = proc_thermal_add(&pdev->dev, proc_priv);
> @@ -248,16 +251,23 @@ static int proc_thermal_pci_probe(struct
> pci_dev *pdev, const struct pci_device_
>                 goto err_ret_mmio;
>         }
>  
> -       /* request and enable interrupt */
> -       ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
> -       if (ret < 0) {
> -               dev_err(&pdev->dev, "Failed to allocate vectors!\n");
> -               goto err_ret_tzone;
> -       }
> -       if (!pdev->msi_enabled && !pdev->msix_enabled)
> +       if (msi_enabled) {
> +               pci_set_master(pdev);
> +               /* request and enable interrupt */
> +               ret = pci_alloc_irq_vectors(pdev, 1, 1,
> PCI_IRQ_ALL_TYPES);
> +               if (ret < 0) {
> +                       dev_err(&pdev->dev, "Failed to allocate
> vectors!\n");
> +                       goto err_ret_tzone;
> +               }
> +               if (!pdev->msi_enabled && !pdev->msix_enabled)
> +                       irq_flag = IRQF_SHARED;
> +
> +               irq =  pci_irq_vector(pdev, 0);
> +       } else {
>                 irq_flag = IRQF_SHARED;
> +               irq = pdev->irq;
> +       }
>  
> -       irq =  pci_irq_vector(pdev, 0);
>         ret = devm_request_threaded_irq(&pdev->dev, irq,
>                                         proc_thermal_irq_handler,
> NULL,
>                                         irq_flag, KBUILD_MODNAME,
> pci_info);
> @@ -273,7 +283,8 @@ static int proc_thermal_pci_probe(struct pci_dev
> *pdev, const struct pci_device_
>         return 0;
>  
>  err_free_vectors:
> -       pci_free_irq_vectors(pdev);
> +       if (msi_enabled)
> +               pci_free_irq_vectors(pdev);
>  err_ret_tzone:
>         thermal_zone_device_unregister(pci_info->tzone);
>  err_ret_mmio:


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

* Re: [PATCH 4/7] thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for Meteor Lake
  2023-06-20 23:01 ` [PATCH 4/7] thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for Meteor Lake Srinivas Pandruvada
@ 2023-06-21 14:54   ` Zhang, Rui
  0 siblings, 0 replies; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:54 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> Meteor Lake processor supports firmware hints for predicting workload
> type. So, remove support for passing workload hints to the firmware.
> 
> Signed-off-by: Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com>

Reviewed-by: Zhang Rui <rui.zhang@intel.com>

thanks,
rui

> ---
>  .../intel/int340x_thermal/processor_thermal_device_pci.c       | 3
> +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> index 057778f7bece..3dab3dbdbbc6 100644
> ---
> a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> +++
> b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.
> c
> @@ -364,8 +364,7 @@ static const struct pci_device_id
> proc_thermal_pci_ids[] = {
>         { PCI_DEVICE_DATA(INTEL, ADL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
>           PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_WLT_REQ) },
>         { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
> -         PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_WLT_REQ |
> -         PROC_THERMAL_FEATURE_DLVR) },
> +         PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_DLVR) },
>         { PCI_DEVICE_DATA(INTEL, RPL_THERMAL,
> PROC_THERMAL_FEATURE_RAPL |
>           PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS |
> PROC_THERMAL_FEATURE_WLT_REQ) },
>         { },


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

* Re: [PATCH 0/7] thermal: processor_thermal: Suport workload hint
  2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
                   ` (6 preceding siblings ...)
  2023-06-20 23:01 ` [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint Srinivas Pandruvada
@ 2023-06-21 14:58 ` Rafael J. Wysocki
  2023-06-21 15:45   ` srinivas pandruvada
  7 siblings, 1 reply; 20+ messages in thread
From: Rafael J. Wysocki @ 2023-06-21 14:58 UTC (permalink / raw)
  To: Srinivas Pandruvada
  Cc: rafael, rui.zhang, daniel.lezcano, linux-pm, linux-kernel

On Wed, Jun 21, 2023 at 1:01 AM Srinivas Pandruvada
<srinivas.pandruvada@linux.intel.com> wrote:
>
> Add support for Meteor Lake workload hints. Before adding this support,
> some reorganization and clean up is required.
> First four changes are for clean up and to reorganize code to add
> support for workload hint. The last patch adds a test program as part
> of self tests.
>
> Srinivas Pandruvada (7):
>   thermal: int340x: processor_thermal: Move mailbox code to common
>     module
>   thermal: int340x: processor_thermal: Add interrupt configuration
>   thermal: int340x: processor_thermal: Use non MSI interrupts
>   thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for
>     Meteor Lake
>   thermal: int340x: processor_thermal: Add workload type hint
>   thermal/drivers/int340x: Support workload hint interrupts
>   selftests/thermel/intel: Add test to read workload hint
>
>  .../driver-api/thermal/intel_dptf.rst         |  38 +++
>  .../thermal/intel/int340x_thermal/Makefile    |   2 +
>  .../processor_thermal_device.c                |  17 +-
>  .../processor_thermal_device.h                |  21 +-
>  .../processor_thermal_device_pci.c            |  76 ++++--
>  .../processor_thermal_device_pci_legacy.c     |   3 +-
>  .../int340x_thermal/processor_thermal_mbox.c  | 179 ++++---------
>  .../processor_thermal_wlt_hint.c              | 239 ++++++++++++++++++
>  .../processor_thermal_wlt_req.c               | 137 ++++++++++
>  .../testing/selftests/thermal/intel/Makefile  |  16 ++
>  .../thermal/intel/workload_hint_test.c        | 114 +++++++++
>  11 files changed, 680 insertions(+), 162 deletions(-)
>  create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
>  create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
>  create mode 100644 tools/testing/selftests/thermal/intel/Makefile
>  create mode 100644 tools/testing/selftests/thermal/intel/workload_hint_test.c
>
> --

Because of the timing of the first posting, I'm going to treat this
series as 6.6 material.

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

* Re: [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint
  2023-06-21 14:30   ` Zhang, Rui
  2023-06-21 14:40     ` srinivas pandruvada
@ 2023-06-21 14:58     ` Zhang, Rui
  1 sibling, 0 replies; 20+ messages in thread
From: Zhang, Rui @ 2023-06-21 14:58 UTC (permalink / raw)
  To: srinivas.pandruvada, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Wed, 2023-06-21 at 14:30 +0000, Zhang, Rui wrote:
> On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> > Some SoCs have in built firmware support to classify current
> > running
> > workload and pass to OS for making power management decisions.
> > 
> > This test program waits for notification of workload type change
> > and prints. This program can be used to test this feature and also
> > allows other user space programs to use as a reference.
> > 
> > Signed-off-by: Srinivas Pandruvada
> > <srinivas.pandruvada@linux.intel.com>
> > ---
> >  .../testing/selftests/thermal/intel/Makefile  |  16 +++
> >  .../thermal/intel/workload_hint_test.c        | 114
> > ++++++++++++++++++
> >  2 files changed, 130 insertions(+)
> >  create mode 100644 tools/testing/selftests/thermal/intel/Makefile
> >  create mode 100644
> > tools/testing/selftests/thermal/intel/workload_hint_test.c
> > 
> > diff --git a/tools/testing/selftests/thermal/intel/Makefile
> > b/tools/testing/selftests/thermal/intel/Makefile
> > new file mode 100644
> > index 000000000000..02459e271ef7
> > --- /dev/null
> > +++ b/tools/testing/selftests/thermal/intel/Makefile
> > @@ -0,0 +1,16 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +ifndef CROSS_COMPILE
> > +uname_M := $(shell uname -m 2>/dev/null || echo not)
> > +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e
> > s/x86_64/x86/)
> > +
> > +ifeq ($(ARCH),x86)
> > +TEST_PROGS := workload_hint_test
> > +
> > +all: $(TEST_PROGS)
> > +
> > +include ../../lib.mk
> > +
> > +clean:
> > +       rm -fr $(TEST_PROGS)
> > +endif
> > +endif
> > diff --git
> > a/tools/testing/selftests/thermal/intel/workload_hint_test.c
> > b/tools/testing/selftests/thermal/intel/workload_hint_test.c
> > new file mode 100644
> > index 000000000000..69a48a8ccbb4
> > --- /dev/null
> > +++ b/tools/testing/selftests/thermal/intel/workload_hint_test.c
> > @@ -0,0 +1,114 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#define _GNU_SOURCE
> > +
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <fcntl.h>
> > +#include <poll.h>
> > +
> > +#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE
> > "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay
> > _m
> > s"
> > +#define WORKLOAD_ENABLE_ATTRIBUTE
> > "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enab
> > le
> > "
> > +#define WORKLOAD_TYPE_INDEX_ATTRIBUTE 
> > "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_inde
> > x"
> > +
> > +static const char * const workload_types[] = {
> > +       "idle",
> > +       "battery_life",
> > +       "sustained",
> > +       "bursty",
> > +       NULL
> > +};
> > +
> > +#define WORKLOAD_TYPE_MAX_INDEX        3
> > +
> > +int main(int argc, char **argv) {
> > +       struct pollfd ufd;
> > +       char index_str[4];
> > +       int fd, ret, index;
> > +       int delay = 0;
> > +
> > +       if (argc > 1) {
> > +               char delay_str[64];
> > +
> > +               sscanf(argv[1], "%d", &delay);
> > +               printf("Setting notification delay to %d ms\n",
> > delay);
> > +
> > +               if (delay < 0)
> > +                       exit(1);
> > +
> > +               sprintf(delay_str, "%s\n", argv[1]);
> > +
> > +               if ((fd =
> > open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE,
> > O_RDWR)) < 0) {
> > +                       perror("Unable to open workload
> > notification
> > delay\n");
> > +                       exit(1);
> > +               }
> > +
> > +               if (write(fd, delay_str, strlen(delay_str)) < 0) {
> > +                       perror("Can't set delay\n");
> > +                       exit(1);
> > +               }
> > +
> > +               close(fd);
> > +
> > +       }
> > +
> > +       /* Enable feature via sysfs knob */
> > +       if ((fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR)) < 0) {
> > +               perror("Unable to open workload type feature enable
> > file\n");
> > +               exit(1);
> > +       }
> > +
> > +       if (write(fd, "1\n", 2) < 0) {
> > +               perror("Can' enable workload hints\n");
> > +               exit(1);
> > +       }
> > +
> > +       close(fd);
> 
> This enables WORKLOAD_ENABLE_ATTRIBUTE without disabling it again.
> As a test program, maybe we can add a timeout, and stop polling &
> disable the WORKLOAD_ENABLE_ATTRIBUTE after the timeout?

to be more accurate, restore WORKLOAD_ENABLE_ATTRIBUTE to its original
state.

thanks,
rui
> 
> thanks,
> rui
> > +
> > +       while (1) {
> > +               if ((fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE,
> > O_RDONLY)) < 0) {
> > +                       perror("Unable to open workload type
> > file\n");
> > +                       exit(1);
> > +               }
> > +
> > +               if ((lseek(fd, 0L, SEEK_SET)) < 0) {
> > +                       fprintf(stderr, "Failed to set pointer to
> > beginning\n");
> > +                       exit(1);
> > +               }
> > +
> > +               if (read(fd, index_str, sizeof(index_str)) < 0) {
> > +                       fprintf(stderr, "Failed to read from:%s\n",
> > +                       WORKLOAD_TYPE_INDEX_ATTRIBUTE);
> > +                       exit(1);
> > +               }
> > +
> > +               ufd.fd = fd;
> > +               ufd.events = POLLPRI;
> > +
> > +               if ((ret = poll(&ufd, 1, -1)) < 0) {
> > +                       perror("poll error");
> > +                       exit(1);
> > +               } else if (ret == 0) {
> > +                       printf("Poll Timeout\n");
> > +               } else {
> > +                       if ((lseek(fd, 0L, SEEK_SET)) < 0) {
> > +                               fprintf(stderr, "Failed to set
> > pointer to beginning\n");
> > +                               exit(1);
> > +                       }
> > +
> > +                       if (read(fd, index_str, sizeof(index_str))
> > <
> > 0) {
> > +                               exit(0);
> > +                       }
> > +
> > +                       sscanf(index_str, "%d", &index);
> > +                       if (index > WORKLOAD_TYPE_MAX_INDEX)
> > +                               printf("Invalid workload type
> > index\n");
> > +                       else
> > +                               printf("workload type:%s\n",
> > workload_types[index]);
> > +               }
> > +
> > +               close(fd);
> > +       }
> > +}
> 


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

* Re: [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration
  2023-06-21 14:50   ` Zhang, Rui
@ 2023-06-21 15:02     ` srinivas pandruvada
  0 siblings, 0 replies; 20+ messages in thread
From: srinivas pandruvada @ 2023-06-21 15:02 UTC (permalink / raw)
  To: Zhang, Rui, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Wed, 2023-06-21 at 14:50 +0000, Zhang, Rui wrote:
> On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> > Some features on this PCI devices require interrupt support. Here
> > interrupts are enabled/disabled via sending mailbox commands. The
> > mailbox command ID is 0x1E for read and 0x1F for write.
> > 
> > The interrupt configuration will require mutex protection as it
> > involved read-modify-write operation. Since mutex are already used
> > in the mailbox read/write functions: send_mbox_write_cmd() and
> > send_mbox_read_cmd(), there will be double locking. But, this can
> > be avoided by moving mutexes from mailbox read/write processing
> > functions to the calling (exported) functions.
> > 
> > Signed-off-by: Srinivas Pandruvada
> > <srinivas.pandruvada@linux.intel.com>
> > ---
> >  .../processor_thermal_device.h                |  2 +
> >  .../int340x_thermal/processor_thermal_mbox.c  | 85 ++++++++++++++-
> > --
> > --
> >  2 files changed, 68 insertions(+), 19 deletions(-)
> > 
> > diff --git
> > a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> > b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> > index 7cdeca2edc21..defc919cb020 100644
> > ---
> > a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> > +++
> > b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
> > @@ -91,6 +91,8 @@ void proc_thermal_wlt_req_remove(struct pci_dev
> > *pdev);
> >  
> >  int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16
> > id, u64 *resp);
> >  int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev,
> > u16
> > id, u32 data);
> > +int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev,
> > bool enable, int enable_bit,
> > +                                           int time_window);
> >  int proc_thermal_add(struct device *dev, struct
> > proc_thermal_device
> > *priv);
> >  void proc_thermal_remove(struct proc_thermal_device *proc_priv);
> >  int proc_thermal_suspend(struct device *dev);
> > diff --git
> > a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> > b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> > index ec766c5615b7..7ef0af3f5bef 100644
> > ---
> > a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> > +++
> > b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c
> > @@ -45,23 +45,16 @@ static int send_mbox_write_cmd(struct pci_dev
> > *pdev, u16 id, u32 data)
> >         int ret;
> >  
> >         proc_priv = pci_get_drvdata(pdev);
> > -
> > -       mutex_lock(&mbox_lock);
> > -
> >         ret = wait_for_mbox_ready(proc_priv);
> >         if (ret)
> > -               goto unlock_mbox;
> > +               return ret;
> >  
> >         writel(data, (proc_priv->mmio_base + MBOX_OFFSET_DATA));
> >         /* Write command register */
> >         reg_data = BIT_ULL(MBOX_BUSY_BIT) | id;
> >         writel(reg_data, (proc_priv->mmio_base +
> > MBOX_OFFSET_INTERFACE));
> >  
> > -       ret = wait_for_mbox_ready(proc_priv);
> > -
> > -unlock_mbox:
> > -       mutex_unlock(&mbox_lock);
> > -       return ret;
> > +       return wait_for_mbox_ready(proc_priv);
> >  }
> >  
> >  static int send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64
> > *resp)
> > @@ -71,12 +64,9 @@ static int send_mbox_read_cmd(struct pci_dev
> > *pdev, u16 id, u64 *resp)
> >         int ret;
> >  
> >         proc_priv = pci_get_drvdata(pdev);
> > -
> > -       mutex_lock(&mbox_lock);
> > -
> >         ret = wait_for_mbox_ready(proc_priv);
> >         if (ret)
> > -               goto unlock_mbox;
> > +               return ret;
> >  
> >         /* Write command register */
> >         reg_data = BIT_ULL(MBOX_BUSY_BIT) | id;
> > @@ -84,28 +74,85 @@ static int send_mbox_read_cmd(struct pci_dev
> > *pdev, u16 id, u64 *resp)
> >  
> >         ret = wait_for_mbox_ready(proc_priv);
> >         if (ret)
> > -               goto unlock_mbox;
> > +               return ret;
> >  
> >         if (id == MBOX_CMD_WORKLOAD_TYPE_READ)
> >                 *resp = readl(proc_priv->mmio_base +
> > MBOX_OFFSET_DATA);
> >         else
> >                 *resp = readq(proc_priv->mmio_base +
> > MBOX_OFFSET_DATA);
> >  
> > -unlock_mbox:
> > -       mutex_unlock(&mbox_lock);
> > -       return ret;
> > +       return 0;
> >  }
> >  
> >  int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16
> > id, u64 *resp)
> >  {
> > -       return send_mbox_read_cmd(pdev, id, resp);
> > +       int ret;
> > +
> > +       mutex_lock(&mbox_lock);
> > +       ret = send_mbox_read_cmd(pdev, id, resp);
> > +       mutex_unlock(&mbox_lock);
> > +
> > +       return ret;
> >  }
> >  EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_read_cmd,
> > INT340X_THERMAL);
> >  
> >  int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev,
> > u16
> > id, u32 data)
> >  {
> > -       return send_mbox_write_cmd(pdev, id, data);
> > +       int ret;
> > +
> > +       mutex_lock(&mbox_lock);
> > +       ret = send_mbox_write_cmd(pdev, id, data);
> > +       mutex_unlock(&mbox_lock);
> > +
> > +       return ret;
> >  }
> >  EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd,
> > INT340X_THERMAL);
> >  
> > +#define MBOX_CAMARILLO_RD_INTR_CONFIG  0x1E
> > +#define MBOX_CAMARILLO_WR_INTR_CONFIG  0x1F
> > +#define WLT_TW_MASK                    GENMASK_ULL(30, 24)
> > +#define SOC_PREDICTION_TW_SHIFT                24
> > +
> > +int processor_thermal_mbox_interrupt_config(struct pci_dev *pdev,
> > bool enable,
> > +                                           int enable_bit, int
> > time_window)
> 
> All the callers of this API in this patch series uses
> SOC_WLT_PREDICTION_INT_ENABLE_BIT as the enable_bit, so this
> parameter
> is redundant?
> or do we expect a different enable_bit on other/future platforms?
> 
I will submit another patch for enabling interrupt for "power floor",
that is another bit.

Thanks,
Srinivas

> thanks,
> rui
> 
> > +{
> > +       u64 data;
> > +       int ret;
> > +
> > +       if (!pdev)
> > +               return -ENODEV;
> > +
> > +       mutex_lock(&mbox_lock);
> > +
> > +       /* Do read modify write for MBOX_CAMARILLO_RD_INTR_CONFIG
> > */
> > +
> > +       ret = send_mbox_read_cmd(pdev,
> > MBOX_CAMARILLO_RD_INTR_CONFIG,  &data);
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "MBOX_CAMARILLO_RD_INTR_CONFIG
> > failed\n");
> > +               goto unlock;
> > +       }
> > +
> > +       if (time_window >= 0) {
> > +               data &= ~WLT_TW_MASK;
> > +
> > +               /* Program notification delay */
> > +               data |= (time_window << SOC_PREDICTION_TW_SHIFT);
> > +       }
> > +
> > +       if (enable)
> > +               data |= BIT(enable_bit);
> > +       else
> > +               data &= ~BIT(enable_bit);
> > +
> > +       ret = send_mbox_write_cmd(pdev,
> > MBOX_CAMARILLO_WR_INTR_CONFIG, data);
> > +       if (ret)
> > +               dev_err(&pdev->dev, "MBOX_CAMARILLO_WR_INTR_CONFIG
> > failed\n");
> > +
> > +unlock:
> > +       mutex_unlock(&mbox_lock);
> > +
> > +       return ret;
> > +}
> > +EXPORT_SYMBOL_NS_GPL(processor_thermal_mbox_interrupt_config,
> > INT340X_THERMAL);
> > +
> >  MODULE_LICENSE("GPL v2");
> 


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

* Re: [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts
  2023-06-21 14:53   ` Zhang, Rui
@ 2023-06-21 15:02     ` srinivas pandruvada
  0 siblings, 0 replies; 20+ messages in thread
From: srinivas pandruvada @ 2023-06-21 15:02 UTC (permalink / raw)
  To: Zhang, Rui, rafael, daniel.lezcano; +Cc: linux-pm, linux-kernel

On Wed, 2023-06-21 at 14:53 +0000, Zhang, Rui wrote:
> On Tue, 2023-06-20 at 16:01 -0700, Srinivas Pandruvada wrote:
> > There are issues in using MSI interrupts for processor thermal
> > device.
> > The support is not consistent, across generations. Even in the same
> > generation, there are issue in getting interrupts via MSI.
> > 
> > Hence always use legacy PCI interrupts by default, instead of MSI.
> > Add a module param to use of MSI, so that MSI can be still used.
> > 
> > Signed-off-by: Srinivas Pandruvada
> > <srinivas.pandruvada@linux.intel.com>
> > ---
> >  .../processor_thermal_device_pci.c            | 33 ++++++++++++---
> > --
> > --
> >  1 file changed, 22 insertions(+), 11 deletions(-)
> > 
> > diff --git
> > a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pc
> > i.
> > c
> > b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pc
> > i.
> > c
> > index 5a2bcfff0a68..057778f7bece 100644
> > ---
> > a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pc
> > i.
> > c
> > +++
> > b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pc
> > i.
> > c
> > @@ -15,6 +15,11 @@
> >  
> >  #define DRV_NAME "proc_thermal_pci"
> >  
> > +static int msi_enabled;
> > +module_param(msi_enabled, int, 0644);
> 
> why not use
> 
> static bool msi_enabled;
> module_params(msi_enabled, bool, 0644);
> 
Sure.

Thanks,
Srinivas

> thanks,
> rui
> 
> > +MODULE_PARM_DESC(msi_enabled,
> > +       "Use PCI MSI based interrupts for processor thermal
> > device.");
> > +
> >  struct proc_thermal_pci {
> >         struct pci_dev *pdev;
> >         struct proc_thermal_device *proc_priv;
> > @@ -219,8 +224,6 @@ static int proc_thermal_pci_probe(struct
> > pci_dev
> > *pdev, const struct pci_device_
> >                 return ret;
> >         }
> >  
> > -       pci_set_master(pdev);
> > -
> >         INIT_DELAYED_WORK(&pci_info->work,
> > proc_thermal_threshold_work_fn);
> >  
> >         ret = proc_thermal_add(&pdev->dev, proc_priv);
> > @@ -248,16 +251,23 @@ static int proc_thermal_pci_probe(struct
> > pci_dev *pdev, const struct pci_device_
> >                 goto err_ret_mmio;
> >         }
> >  
> > -       /* request and enable interrupt */
> > -       ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
> > -       if (ret < 0) {
> > -               dev_err(&pdev->dev, "Failed to allocate
> > vectors!\n");
> > -               goto err_ret_tzone;
> > -       }
> > -       if (!pdev->msi_enabled && !pdev->msix_enabled)
> > +       if (msi_enabled) {
> > +               pci_set_master(pdev);
> > +               /* request and enable interrupt */
> > +               ret = pci_alloc_irq_vectors(pdev, 1, 1,
> > PCI_IRQ_ALL_TYPES);
> > +               if (ret < 0) {
> > +                       dev_err(&pdev->dev, "Failed to allocate
> > vectors!\n");
> > +                       goto err_ret_tzone;
> > +               }
> > +               if (!pdev->msi_enabled && !pdev->msix_enabled)
> > +                       irq_flag = IRQF_SHARED;
> > +
> > +               irq =  pci_irq_vector(pdev, 0);
> > +       } else {
> >                 irq_flag = IRQF_SHARED;
> > +               irq = pdev->irq;
> > +       }
> >  
> > -       irq =  pci_irq_vector(pdev, 0);
> >         ret = devm_request_threaded_irq(&pdev->dev, irq,
> >                                         proc_thermal_irq_handler,
> > NULL,
> >                                         irq_flag, KBUILD_MODNAME,
> > pci_info);
> > @@ -273,7 +283,8 @@ static int proc_thermal_pci_probe(struct
> > pci_dev
> > *pdev, const struct pci_device_
> >         return 0;
> >  
> >  err_free_vectors:
> > -       pci_free_irq_vectors(pdev);
> > +       if (msi_enabled)
> > +               pci_free_irq_vectors(pdev);
> >  err_ret_tzone:
> >         thermal_zone_device_unregister(pci_info->tzone);
> >  err_ret_mmio:
> 


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

* Re: [PATCH 0/7] thermal: processor_thermal: Suport workload hint
  2023-06-21 14:58 ` [PATCH 0/7] thermal: processor_thermal: Suport " Rafael J. Wysocki
@ 2023-06-21 15:45   ` srinivas pandruvada
  0 siblings, 0 replies; 20+ messages in thread
From: srinivas pandruvada @ 2023-06-21 15:45 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: rui.zhang, daniel.lezcano, linux-pm, linux-kernel

On Wed, 2023-06-21 at 16:58 +0200, Rafael J. Wysocki wrote:
> On Wed, Jun 21, 2023 at 1:01 AM Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com> wrote:
> > 
> > Add support for Meteor Lake workload hints. Before adding this
> > support,
> > some reorganization and clean up is required.
> > First four changes are for clean up and to reorganize code to add
> > support for workload hint. The last patch adds a test program as
> > part
> > of self tests.
> > 
> > Srinivas Pandruvada (7):
> >   thermal: int340x: processor_thermal: Move mailbox code to common
> >     module
> >   thermal: int340x: processor_thermal: Add interrupt configuration
> >   thermal: int340x: processor_thermal: Use non MSI interrupts
> >   thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for
> >     Meteor Lake
> >   thermal: int340x: processor_thermal: Add workload type hint
> >   thermal/drivers/int340x: Support workload hint interrupts
> >   selftests/thermel/intel: Add test to read workload hint
> > 
> >  .../driver-api/thermal/intel_dptf.rst         |  38 +++
> >  .../thermal/intel/int340x_thermal/Makefile    |   2 +
> >  .../processor_thermal_device.c                |  17 +-
> >  .../processor_thermal_device.h                |  21 +-
> >  .../processor_thermal_device_pci.c            |  76 ++++--
> >  .../processor_thermal_device_pci_legacy.c     |   3 +-
> >  .../int340x_thermal/processor_thermal_mbox.c  | 179 ++++---------
> >  .../processor_thermal_wlt_hint.c              | 239
> > ++++++++++++++++++
> >  .../processor_thermal_wlt_req.c               | 137 ++++++++++
> >  .../testing/selftests/thermal/intel/Makefile  |  16 ++
> >  .../thermal/intel/workload_hint_test.c        | 114 +++++++++
> >  11 files changed, 680 insertions(+), 162 deletions(-)
> >  create mode 100644
> > drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_hint.c
> >  create mode 100644
> > drivers/thermal/intel/int340x_thermal/processor_thermal_wlt_req.c
> >  create mode 100644 tools/testing/selftests/thermal/intel/Makefile
> >  create mode 100644
> > tools/testing/selftests/thermal/intel/workload_hint_test.c
> > 
> > --
> 
> Because of the timing of the first posting, I'm going to treat this
> series as 6.6 material.
That is fine. Just review is important, so that it can be back ported
to Chrome kernel.

Thanks,
Srinivas


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

end of thread, other threads:[~2023-06-21 15:45 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-20 23:01 [PATCH 0/7] thermal: processor_thermal: Suport workload hint Srinivas Pandruvada
2023-06-20 23:01 ` [PATCH 1/7] thermal: int340x: processor_thermal: Move mailbox code to common module Srinivas Pandruvada
2023-06-21 14:35   ` Zhang, Rui
2023-06-20 23:01 ` [PATCH 2/7] thermal: int340x: processor_thermal: Add interrupt configuration Srinivas Pandruvada
2023-06-21 14:50   ` Zhang, Rui
2023-06-21 15:02     ` srinivas pandruvada
2023-06-20 23:01 ` [PATCH 3/7] thermal: int340x: processor_thermal: Use non MSI interrupts Srinivas Pandruvada
2023-06-21 14:53   ` Zhang, Rui
2023-06-21 15:02     ` srinivas pandruvada
2023-06-20 23:01 ` [PATCH 4/7] thermal/drivers/int340x: Remove PROC_THERMAL_FEATURE_WLT_REQ for Meteor Lake Srinivas Pandruvada
2023-06-21 14:54   ` Zhang, Rui
2023-06-20 23:01 ` [PATCH 5/7] thermal: int340x: processor_thermal: Add workload type hint Srinivas Pandruvada
2023-06-21 14:12   ` Zhang, Rui
2023-06-20 23:01 ` [PATCH 6/7] thermal/drivers/int340x: Support workload hint interrupts Srinivas Pandruvada
2023-06-20 23:01 ` [PATCH 7/7] selftests/thermel/intel: Add test to read workload hint Srinivas Pandruvada
2023-06-21 14:30   ` Zhang, Rui
2023-06-21 14:40     ` srinivas pandruvada
2023-06-21 14:58     ` Zhang, Rui
2023-06-21 14:58 ` [PATCH 0/7] thermal: processor_thermal: Suport " Rafael J. Wysocki
2023-06-21 15:45   ` srinivas pandruvada

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).