linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver
@ 2021-05-25 20:48 Srinivas Pandruvada
  2021-05-25 20:48 ` [PATCH 1/2] thermal: int340x: processor_thermal: Split enumeration and processing part Srinivas Pandruvada
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Srinivas Pandruvada @ 2021-05-25 20:48 UTC (permalink / raw)
  To: daniel.lezcano, rui.zhang, amitk
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

This series adds a new thermal driver, which uses PCI MMIO for temperature and trips. To reuse
the code the first patch just reorganizes the existing code.

This series needs the following patch to cleanly apply:
[PATCH 1/2] thermal: int340x: processor_thermal: Export mailbox interface
sent on 16th May, 21.

Srinivas Pandruvada (2):
  thermal: int340x: processor_thermal: Split enumeration and processing
    part
  thermal: int340x: processor_thermal: Add PCI MMIO based thermal driver

 .../thermal/intel/int340x_thermal/Makefile    |   3 +
 .../intel/int340x_thermal/int3401_thermal.c   |  82 ++++
 .../processor_thermal_device.c                | 289 ++------------
 .../processor_thermal_device.h                |   9 +-
 .../processor_thermal_device_pci.c            | 371 ++++++++++++++++++
 .../processor_thermal_device_pci_legacy.c     | 163 ++++++++
 6 files changed, 658 insertions(+), 259 deletions(-)
 create mode 100644 drivers/thermal/intel/int340x_thermal/int3401_thermal.c
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c

-- 
2.27.0


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

* [PATCH 1/2] thermal: int340x: processor_thermal: Split enumeration and processing part
  2021-05-25 20:48 [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver Srinivas Pandruvada
@ 2021-05-25 20:48 ` Srinivas Pandruvada
  2021-05-25 20:48 ` [PATCH 2/2] thermal: int340x: processor_thermal: Add PCI MMIO based thermal driver Srinivas Pandruvada
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Srinivas Pandruvada @ 2021-05-25 20:48 UTC (permalink / raw)
  To: daniel.lezcano, rui.zhang, amitk
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Remove enumeration part from the processor_thermal_device to two
different modules. One for ACPI and one for PCI:
	ACPI enumeration: int3401_thermal
	PCI part: processor_thermal_device_pci_legacy

The current processor_thermal_device now just implements interface
functions to be used by the ACPI and PCI enumeration module. This is
done by:
1. Make functions proc_thermal_add() and proc_thermal_remove() non static
and export them for usage in other processor_thermal_device_pci_legacy.c
and in int3401_thermal.c.

2. Move the sysfs file creation for TCC offset and power limit attribute
group to the proc_thermal_add() from the individual enumeration callbacks
for PCI and ACPI.

3. Create new interface functions proc_thermal_mmio_add() and
proc_thermal_mmio_remove() which will be called from the
processor_thermal_device_pci_legacy module.

4. Export proc_thermal_resume(), so that it can be used by power
management callbacks.

5. Remove special check for double enumeration as it never happens.

While here, fix some cleanup on error conditions in proc_thermal_add().

No functional changes are expected with this change.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../thermal/intel/int340x_thermal/Makefile    |   2 +
 .../intel/int340x_thermal/int3401_thermal.c   |  82 +++++
 .../processor_thermal_device.c                | 289 ++----------------
 .../processor_thermal_device.h                |   8 +-
 .../processor_thermal_device_pci_legacy.c     | 164 ++++++++++
 5 files changed, 286 insertions(+), 259 deletions(-)
 create mode 100644 drivers/thermal/intel/int340x_thermal/int3401_thermal.c
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c

diff --git a/drivers/thermal/intel/int340x_thermal/Makefile b/drivers/thermal/intel/int340x_thermal/Makefile
index 38a2731e503c..aaf02d5deed5 100644
--- a/drivers/thermal/intel/int340x_thermal/Makefile
+++ b/drivers/thermal/intel/int340x_thermal/Makefile
@@ -4,6 +4,8 @@ obj-$(CONFIG_INT340X_THERMAL)	+= int340x_thermal_zone.o
 obj-$(CONFIG_INT340X_THERMAL)	+= int3402_thermal.o
 obj-$(CONFIG_INT340X_THERMAL)	+= int3403_thermal.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_device.o
+obj-$(CONFIG_INT340X_THERMAL)	+= int3401_thermal.o
+obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_device_pci_legacy.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
diff --git a/drivers/thermal/intel/int340x_thermal/int3401_thermal.c b/drivers/thermal/intel/int340x_thermal/int3401_thermal.c
new file mode 100644
index 000000000000..acebc8ba94e2
--- /dev/null
+++ b/drivers/thermal/intel/int340x_thermal/int3401_thermal.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * INT3401 processor thermal device
+ * Copyright (c) 2020, Intel Corporation.
+ */
+#include <linux/acpi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#include "int340x_thermal_zone.h"
+#include "processor_thermal_device.h"
+
+static const struct acpi_device_id int3401_device_ids[] = {
+	{"INT3401", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, int3401_device_ids);
+
+static int int3401_add(struct platform_device *pdev)
+{
+	struct proc_thermal_device *proc_priv;
+	int ret;
+
+	proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
+	if (!proc_priv)
+		return -ENOMEM;
+
+	ret = proc_thermal_add(&pdev->dev, proc_priv);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, proc_priv);
+
+	return ret;
+}
+
+static int int3401_remove(struct platform_device *pdev)
+{
+	proc_thermal_remove(platform_get_drvdata(pdev));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int int3401_thermal_resume(struct device *dev)
+{
+	return proc_thermal_resume(dev);
+}
+#else
+#define int3401_thermal_resume NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(int3401_proc_thermal_pm, NULL, int3401_thermal_resume);
+
+static struct platform_driver int3401_driver = {
+	.probe = int3401_add,
+	.remove = int3401_remove,
+	.driver = {
+		.name = "int3401 thermal",
+		.acpi_match_table = int3401_device_ids,
+		.pm = &int3401_proc_thermal_pm,
+	},
+};
+
+static int __init proc_thermal_init(void)
+{
+	return platform_driver_register(&int3401_driver);
+}
+
+static void __exit proc_thermal_exit(void)
+{
+	platform_driver_unregister(&int3401_driver);
+}
+
+module_init(proc_thermal_init);
+module_exit(proc_thermal_exit);
+
+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.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index 9e6f2a895a23..de4fc640deb0 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -3,34 +3,17 @@
  * processor_thermal_device.c
  * Copyright (c) 2014, Intel Corporation.
  */
+#include <linux/acpi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/acpi.h>
 #include <linux/thermal.h>
-#include <linux/cpuhotplug.h>
 #include "int340x_thermal_zone.h"
 #include "processor_thermal_device.h"
 #include "../intel_soc_dts_iosf.h"
 
 #define DRV_NAME "proc_thermal"
 
-enum proc_thermal_emum_mode_type {
-	PROC_THERMAL_NONE,
-	PROC_THERMAL_PCI,
-	PROC_THERMAL_PLATFORM_DEV
-};
-
-/*
- * We can have only one type of enumeration, PCI or Platform,
- * not both. So we don't need instance specific data.
- */
-static enum proc_thermal_emum_mode_type proc_thermal_emum_mode =
-							PROC_THERMAL_NONE;
-
 #define POWER_LIMIT_SHOW(index, suffix) \
 static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \
 					struct device_attribute *attr, \
@@ -38,11 +21,6 @@ static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \
 { \
 	struct proc_thermal_device *proc_dev = dev_get_drvdata(dev); \
 	\
-	if (proc_thermal_emum_mode == PROC_THERMAL_NONE) { \
-		dev_warn(dev, "Attempted to get power limit before device was initialized!\n"); \
-		return 0; \
-	} \
-	\
 	return sprintf(buf, "%lu\n",\
 	(unsigned long)proc_dev->power_limits[index].suffix * 1000); \
 }
@@ -291,11 +269,8 @@ static void proc_thermal_notify(acpi_handle handle, u32 event, void *data)
 	}
 }
 
-
-static int proc_thermal_add(struct device *dev,
-			    struct proc_thermal_device **priv)
+int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
 {
-	struct proc_thermal_device *proc_priv;
 	struct acpi_device *adev;
 	acpi_status status;
 	unsigned long long tmp;
@@ -306,13 +281,8 @@ static int proc_thermal_add(struct device *dev,
 	if (!adev)
 		return -ENODEV;
 
-	proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL);
-	if (!proc_priv)
-		return -ENOMEM;
-
 	proc_priv->dev = dev;
 	proc_priv->adev = adev;
-	*priv = proc_priv;
 
 	ret = proc_thermal_read_ppcc(proc_priv);
 	if (ret)
@@ -338,15 +308,29 @@ static int proc_thermal_add(struct device *dev,
 	if (ret)
 		goto remove_zone;
 
+	ret = sysfs_create_file(&dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+	if (ret)
+		goto remove_notify;
+
+	ret = sysfs_create_group(&dev->kobj, &power_limit_attribute_group);
+	if (ret) {
+		sysfs_remove_file(&dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+		goto remove_notify;
+	}
+
 	return 0;
 
+remove_notify:
+	acpi_remove_notify_handler(adev->handle,
+				    ACPI_DEVICE_NOTIFY, proc_thermal_notify);
 remove_zone:
 	int340x_thermal_zone_remove(proc_priv->int340x_zone);
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(proc_thermal_add);
 
-static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
+void proc_thermal_remove(struct proc_thermal_device *proc_priv)
 {
 	acpi_remove_notify_handler(proc_priv->adev->handle,
 				   ACPI_DEVICE_NOTIFY, proc_thermal_notify);
@@ -355,60 +339,24 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
 	sysfs_remove_group(&proc_priv->dev->kobj,
 			   &power_limit_attribute_group);
 }
+EXPORT_SYMBOL_GPL(proc_thermal_remove);
 
-static int int3401_add(struct platform_device *pdev)
+int proc_thermal_resume(struct device *dev)
 {
-	struct proc_thermal_device *proc_priv;
-	int ret;
-
-	if (proc_thermal_emum_mode == PROC_THERMAL_PCI) {
-		dev_err(&pdev->dev, "error: enumerated as PCI dev\n");
-		return -ENODEV;
-	}
-
-	ret = proc_thermal_add(&pdev->dev, &proc_priv);
-	if (ret)
-		return ret;
-
-	platform_set_drvdata(pdev, proc_priv);
-	proc_thermal_emum_mode = PROC_THERMAL_PLATFORM_DEV;
-
-	dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
-
-	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
-	if (ret)
-		return ret;
-
-	ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
-	if (ret)
-		sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+	struct proc_thermal_device *proc_dev;
 
-	return ret;
-}
+	proc_dev = dev_get_drvdata(dev);
+	proc_thermal_read_ppcc(proc_dev);
 
-static int int3401_remove(struct platform_device *pdev)
-{
-	proc_thermal_remove(platform_get_drvdata(pdev));
+	tcc_offset_update(tcc_offset_save);
 
 	return 0;
 }
-
-static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid)
-{
-	struct proc_thermal_device *proc_priv;
-	struct pci_dev *pdev = devid;
-
-	proc_priv = pci_get_drvdata(pdev);
-
-	intel_soc_dts_iosf_interrupt_handler(proc_priv->soc_dts);
-
-	return IRQ_HANDLED;
-}
+EXPORT_SYMBOL_GPL(proc_thermal_resume);
 
 #define MCHBAR 0
 
-static int proc_thermal_set_mmio_base(struct pci_dev *pdev,
-				      struct proc_thermal_device *proc_priv)
+static int proc_thermal_set_mmio_base(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
 {
 	int ret;
 
@@ -423,9 +371,9 @@ static int proc_thermal_set_mmio_base(struct pci_dev *pdev,
 	return 0;
 }
 
-static int proc_thermal_mmio_add(struct pci_dev *pdev,
-				 struct proc_thermal_device *proc_priv,
-				 kernel_ulong_t feature_mask)
+int proc_thermal_mmio_add(struct pci_dev *pdev,
+			  struct proc_thermal_device *proc_priv,
+			  kernel_ulong_t feature_mask)
 {
 	int ret;
 
@@ -471,11 +419,10 @@ static int proc_thermal_mmio_add(struct pci_dev *pdev,
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(proc_thermal_mmio_add);
 
-static void proc_thermal_mmio_remove(struct pci_dev *pdev)
+void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
 {
-	struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
-
 	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_RAPL)
 		proc_thermal_rapl_remove();
 
@@ -486,181 +433,7 @@ static void proc_thermal_mmio_remove(struct pci_dev *pdev)
 	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MBOX)
 		proc_thermal_mbox_remove(pdev);
 }
-
-static int  proc_thermal_pci_probe(struct pci_dev *pdev,
-				   const struct pci_device_id *id)
-{
-	struct proc_thermal_device *proc_priv;
-	int ret;
-
-	if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) {
-		dev_err(&pdev->dev, "error: enumerated as platform dev\n");
-		return -ENODEV;
-	}
-
-	ret = pcim_enable_device(pdev);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "error: could not enable device\n");
-		return ret;
-	}
-
-	ret = proc_thermal_add(&pdev->dev, &proc_priv);
-	if (ret)
-		return ret;
-
-	pci_set_drvdata(pdev, proc_priv);
-	proc_thermal_emum_mode = PROC_THERMAL_PCI;
-
-	if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) {
-		/*
-		 * Enumerate additional DTS sensors available via IOSF.
-		 * But we are not treating as a failure condition, if
-		 * there are no aux DTSs enabled or fails. This driver
-		 * already exposes sensors, which can be accessed via
-		 * ACPI/MSR. So we don't want to fail for auxiliary DTSs.
-		 */
-		proc_priv->soc_dts = intel_soc_dts_iosf_init(
-					INTEL_SOC_DTS_INTERRUPT_MSI, 2, 0);
-
-		if (!IS_ERR(proc_priv->soc_dts) && pdev->irq) {
-			ret = pci_enable_msi(pdev);
-			if (!ret) {
-				ret = request_threaded_irq(pdev->irq, NULL,
-						proc_thermal_pci_msi_irq,
-						IRQF_ONESHOT, "proc_thermal",
-						pdev);
-				if (ret) {
-					intel_soc_dts_iosf_exit(
-							proc_priv->soc_dts);
-					pci_disable_msi(pdev);
-					proc_priv->soc_dts = NULL;
-				}
-			}
-		} else
-			dev_err(&pdev->dev, "No auxiliary DTSs enabled\n");
-	}
-
-	dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
-
-	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
-	if (ret)
-		return ret;
-
-	ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
-	if (ret) {
-		sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
-		return ret;
-	}
-
-	ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data);
-	if (ret) {
-		proc_thermal_remove(proc_priv);
-		return ret;
-	}
-
-	return 0;
-}
-
-static void  proc_thermal_pci_remove(struct pci_dev *pdev)
-{
-	struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
-
-	if (proc_priv->soc_dts) {
-		intel_soc_dts_iosf_exit(proc_priv->soc_dts);
-		if (pdev->irq) {
-			free_irq(pdev->irq, pdev);
-			pci_disable_msi(pdev);
-		}
-	}
-
-	proc_thermal_mmio_remove(pdev);
-	proc_thermal_remove(proc_priv);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int proc_thermal_resume(struct device *dev)
-{
-	struct proc_thermal_device *proc_dev;
-
-	proc_dev = dev_get_drvdata(dev);
-	proc_thermal_read_ppcc(proc_dev);
-
-	tcc_offset_update(tcc_offset_save);
-
-	return 0;
-}
-#else
-#define proc_thermal_resume NULL
-#endif
-
-static SIMPLE_DEV_PM_OPS(proc_thermal_pm, NULL, proc_thermal_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, BDW_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) },
-	{ PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) },
-	{ 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) },
-	{ },
-};
-
-MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
-
-static struct pci_driver proc_thermal_pci_driver = {
-	.name		= DRV_NAME,
-	.probe		= proc_thermal_pci_probe,
-	.remove		= proc_thermal_pci_remove,
-	.id_table	= proc_thermal_pci_ids,
-	.driver.pm	= &proc_thermal_pm,
-};
-
-static const struct acpi_device_id int3401_device_ids[] = {
-	{"INT3401", 0},
-	{"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, int3401_device_ids);
-
-static struct platform_driver int3401_driver = {
-	.probe = int3401_add,
-	.remove = int3401_remove,
-	.driver = {
-		.name = "int3401 thermal",
-		.acpi_match_table = int3401_device_ids,
-		.pm = &proc_thermal_pm,
-	},
-};
-
-static int __init proc_thermal_init(void)
-{
-	int ret;
-
-	ret = platform_driver_register(&int3401_driver);
-	if (ret)
-		return ret;
-
-	ret = pci_register_driver(&proc_thermal_pci_driver);
-
-	return ret;
-}
-
-static void __exit proc_thermal_exit(void)
-{
-	platform_driver_unregister(&int3401_driver);
-	pci_unregister_driver(&proc_thermal_pci_driver);
-}
-
-module_init(proc_thermal_init);
-module_exit(proc_thermal_exit);
+EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove);
 
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
index 3161607424f5..5e51f1173d00 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
@@ -80,5 +80,11 @@ int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc
 void proc_thermal_mbox_remove(struct pci_dev *pdev);
 
 int processor_thermal_send_mbox_cmd(struct pci_dev *pdev, u16 cmd_id, u32 cmd_data, u32 *cmd_resp);
-
+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_resume(struct device *dev);
+int proc_thermal_mmio_add(struct pci_dev *pdev,
+			  struct proc_thermal_device *proc_priv,
+			  kernel_ulong_t feature_mask);
+void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
 #endif
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
new file mode 100644
index 000000000000..21cf7511d376
--- /dev/null
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * B0D4 processor thermal device
+ * Copyright (c) 2020, Intel Corporation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/thermal.h>
+
+#include "int340x_thermal_zone.h"
+#include "processor_thermal_device.h"
+#include "../intel_soc_dts_iosf.h"
+
+#define DRV_NAME "proc_thermal"
+
+static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid)
+{
+	struct proc_thermal_device *proc_priv;
+	struct pci_dev *pdev = devid;
+
+	proc_priv = pci_get_drvdata(pdev);
+
+	intel_soc_dts_iosf_interrupt_handler(proc_priv->soc_dts);
+
+	return IRQ_HANDLED;
+}
+
+static int proc_thermal_pci_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *id)
+{
+	struct proc_thermal_device *proc_priv;
+	int ret;
+
+	ret = pcim_enable_device(pdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "error: could not enable device\n");
+		return ret;
+	}
+
+	proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
+	if (!proc_priv)
+		return -ENOMEM;
+
+	ret = proc_thermal_add(&pdev->dev, proc_priv);
+	if (ret)
+		return ret;
+
+	pci_set_drvdata(pdev, proc_priv);
+
+	if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) {
+		/*
+		 * Enumerate additional DTS sensors available via IOSF.
+		 * But we are not treating as a failure condition, if
+		 * there are no aux DTSs enabled or fails. This driver
+		 * already exposes sensors, which can be accessed via
+		 * ACPI/MSR. So we don't want to fail for auxiliary DTSs.
+		 */
+		proc_priv->soc_dts = intel_soc_dts_iosf_init(
+					INTEL_SOC_DTS_INTERRUPT_MSI, 2, 0);
+
+		if (!IS_ERR(proc_priv->soc_dts) && pdev->irq) {
+			ret = pci_enable_msi(pdev);
+			if (!ret) {
+				ret = request_threaded_irq(pdev->irq, NULL,
+						proc_thermal_pci_msi_irq,
+						IRQF_ONESHOT, "proc_thermal",
+						pdev);
+				if (ret) {
+					intel_soc_dts_iosf_exit(
+							proc_priv->soc_dts);
+					pci_disable_msi(pdev);
+					proc_priv->soc_dts = NULL;
+				}
+			}
+		} else
+			dev_err(&pdev->dev, "No auxiliary DTSs enabled\n");
+	} else {
+
+	}
+
+	ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data);
+	if (ret) {
+		proc_thermal_remove(proc_priv);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void proc_thermal_pci_remove(struct pci_dev *pdev)
+{
+	struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
+
+	if (proc_priv->soc_dts) {
+		intel_soc_dts_iosf_exit(proc_priv->soc_dts);
+		if (pdev->irq) {
+			free_irq(pdev->irq, pdev);
+			pci_disable_msi(pdev);
+		}
+	}
+
+	proc_thermal_mmio_remove(pdev, proc_priv);
+	proc_thermal_remove(proc_priv);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int proc_thermal_pci_resume(struct device *dev)
+{
+	return proc_thermal_resume(dev);
+}
+#else
+#define proc_thermal_pci_resume NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, NULL, 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, BDW_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) },
+	{ PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) },
+	{ 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) },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
+
+static struct pci_driver proc_thermal_pci_driver = {
+	.name		= DRV_NAME,
+	.probe		= proc_thermal_pci_probe,
+	.remove		= proc_thermal_pci_remove,
+	.id_table	= proc_thermal_pci_ids,
+	.driver.pm	= &proc_thermal_pci_pm,
+};
+
+static int __init proc_thermal_init(void)
+{
+	return pci_register_driver(&proc_thermal_pci_driver);
+}
+
+static void __exit proc_thermal_exit(void)
+{
+	pci_unregister_driver(&proc_thermal_pci_driver);
+}
+
+module_init(proc_thermal_init);
+module_exit(proc_thermal_exit);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.27.0


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

* [PATCH 2/2] thermal: int340x: processor_thermal: Add PCI MMIO based thermal driver
  2021-05-25 20:48 [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver Srinivas Pandruvada
  2021-05-25 20:48 ` [PATCH 1/2] thermal: int340x: processor_thermal: Split enumeration and processing part Srinivas Pandruvada
@ 2021-05-25 20:48 ` Srinivas Pandruvada
  2021-06-24 16:19 ` [PATCH 0/2] thermal: int340x: processor_thermal: Add new " Srinivas Pandruvada
  2021-07-06  8:28 ` You-Sheng Yang
  3 siblings, 0 replies; 7+ messages in thread
From: Srinivas Pandruvada @ 2021-05-25 20:48 UTC (permalink / raw)
  To: daniel.lezcano, rui.zhang, amitk
  Cc: linux-pm, linux-kernel, Srinivas Pandruvada

Add a new PCI driver which register a thermal zone and allows to get
notification for threshold violation by a RW trip point. These
notifications are delivered from the device using MSI based
interrupt.

The main difference between this new PCI driver and the existing
one is that the temperature and trip points directly use PCI
MMIO instead of using ACPI methods.

This driver registers a thermal zone "TCPU_PCI" in addition to the
legacy processor thermal device, which uses ACPI companion device
to set name, temperature and trips.

This driver is anabled for AlderLake.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../thermal/intel/int340x_thermal/Makefile    |   1 +
 .../processor_thermal_device.h                |   1 +
 .../processor_thermal_device_pci.c            | 371 ++++++++++++++++++
 .../processor_thermal_device_pci_legacy.c     |   1 -
 4 files changed, 373 insertions(+), 1 deletion(-)
 create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c

diff --git a/drivers/thermal/intel/int340x_thermal/Makefile b/drivers/thermal/intel/int340x_thermal/Makefile
index aaf02d5deed5..4e852ce4a5d5 100644
--- a/drivers/thermal/intel/int340x_thermal/Makefile
+++ b/drivers/thermal/intel/int340x_thermal/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_INT340X_THERMAL)	+= int3403_thermal.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_device.o
 obj-$(CONFIG_INT340X_THERMAL)	+= int3401_thermal.o
 obj-$(CONFIG_INT340X_THERMAL)	+= processor_thermal_device_pci_legacy.o
+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
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
index 5e51f1173d00..5a1cfe4864f1 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h
@@ -44,6 +44,7 @@ struct proc_thermal_device {
 	struct intel_soc_dts_sensors *soc_dts;
 	u32 mmio_feature_mask;
 	void __iomem *mmio_base;
+	void *priv_data;
 };
 
 struct rapl_mmio_regs {
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
new file mode 100644
index 000000000000..ad7e2e305abf
--- /dev/null
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
@@ -0,0 +1,371 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Processor thermal device for newer processors
+ * Copyright (c) 2020, Intel Corporation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/thermal.h>
+
+#include "int340x_thermal_zone.h"
+#include "processor_thermal_device.h"
+
+#define DRV_NAME "proc_thermal_pci"
+
+struct proc_thermal_pci {
+	struct pci_dev *pdev;
+	struct proc_thermal_device *proc_priv;
+	struct thermal_zone_device *tzone;
+	struct delayed_work work;
+	int stored_thres;
+	int no_legacy;
+};
+
+enum proc_thermal_mmio_type {
+	PROC_THERMAL_MMIO_TJMAX,
+	PROC_THERMAL_MMIO_PP0_TEMP,
+	PROC_THERMAL_MMIO_PP1_TEMP,
+	PROC_THERMAL_MMIO_PKG_TEMP,
+	PROC_THERMAL_MMIO_THRES_0,
+	PROC_THERMAL_MMIO_THRES_1,
+	PROC_THERMAL_MMIO_INT_ENABLE_0,
+	PROC_THERMAL_MMIO_INT_ENABLE_1,
+	PROC_THERMAL_MMIO_INT_STATUS_0,
+	PROC_THERMAL_MMIO_INT_STATUS_1,
+	PROC_THERMAL_MMIO_MAX
+};
+
+struct proc_thermal_mmio_info {
+	enum proc_thermal_mmio_type mmio_type;
+	u64	mmio_addr;
+	u64	shift;
+	u64	mask;
+};
+
+static struct proc_thermal_mmio_info proc_thermal_mmio_info[] = {
+	{ PROC_THERMAL_MMIO_TJMAX, 0x599c, 16, 0xff },
+	{ PROC_THERMAL_MMIO_PP0_TEMP, 0x597c, 0, 0xff },
+	{ PROC_THERMAL_MMIO_PP1_TEMP, 0x5980, 0, 0xff },
+	{ PROC_THERMAL_MMIO_PKG_TEMP, 0x5978, 0, 0xff },
+	{ PROC_THERMAL_MMIO_THRES_0, 0x5820, 8, 0x7F },
+	{ PROC_THERMAL_MMIO_THRES_1, 0x5820, 16, 0x7F },
+	{ PROC_THERMAL_MMIO_INT_ENABLE_0, 0x5820, 15, 0x01 },
+	{ PROC_THERMAL_MMIO_INT_ENABLE_1, 0x5820, 23, 0x01 },
+	{ PROC_THERMAL_MMIO_INT_STATUS_0, 0x7200, 6, 0x01 },
+	{ PROC_THERMAL_MMIO_INT_STATUS_1, 0x7200, 8, 0x01 },
+};
+
+#define B0D4_THERMAL_NOTIFY_DELAY	1000
+static int notify_delay_ms = B0D4_THERMAL_NOTIFY_DELAY;
+
+static void proc_thermal_mmio_read(struct proc_thermal_pci *pci_info,
+				    enum proc_thermal_mmio_type type,
+				    u32 *value)
+{
+	*value = ioread32(((u8 __iomem *)pci_info->proc_priv->mmio_base +
+				proc_thermal_mmio_info[type].mmio_addr));
+	*value >>= proc_thermal_mmio_info[type].shift;
+	*value &= proc_thermal_mmio_info[type].mask;
+}
+
+static void proc_thermal_mmio_write(struct proc_thermal_pci *pci_info,
+				     enum proc_thermal_mmio_type type,
+				     u32 value)
+{
+	u32 current_val;
+	u32 mask;
+
+	current_val = ioread32(((u8 __iomem *)pci_info->proc_priv->mmio_base +
+				proc_thermal_mmio_info[type].mmio_addr));
+	mask = proc_thermal_mmio_info[type].mask << proc_thermal_mmio_info[type].shift;
+	current_val &= ~mask;
+
+	value &= proc_thermal_mmio_info[type].mask;
+	value <<= proc_thermal_mmio_info[type].shift;
+
+	current_val |= value;
+	iowrite32(current_val, ((u8 __iomem *)pci_info->proc_priv->mmio_base +
+				proc_thermal_mmio_info[type].mmio_addr));
+}
+
+/*
+ * To avoid sending two many messages to user space, we have 1 second delay.
+ * On interrupt we are disabling interrupt and enabling after 1 second.
+ * This workload function is delayed by 1 second.
+ */
+static void proc_thermal_threshold_work_fn(struct work_struct *work)
+{
+	struct delayed_work *delayed_work = to_delayed_work(work);
+	struct proc_thermal_pci *pci_info = container_of(delayed_work,
+						struct proc_thermal_pci, work);
+	struct thermal_zone_device *tzone = pci_info->tzone;
+
+	if (tzone)
+		thermal_zone_device_update(tzone, THERMAL_TRIP_VIOLATED);
+
+	/* Enable interrupt flag */
+	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
+}
+
+static void pkg_thermal_schedule_work(struct delayed_work *work)
+{
+	unsigned long ms = msecs_to_jiffies(notify_delay_ms);
+
+	schedule_delayed_work(work, ms);
+}
+
+static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
+{
+	struct proc_thermal_pci *pci_info = devid;
+	u32 status;
+
+	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_INT_STATUS_0, &status);
+
+	/* Disable enable interrupt flag */
+	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
+	pci_write_config_byte(pci_info->pdev, 0xdc, 0x01);
+
+	pkg_thermal_schedule_work(&pci_info->work);
+
+	return IRQ_HANDLED;
+}
+
+static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
+{
+	struct proc_thermal_pci *pci_info = tzd->devdata;
+	u32 _temp;
+
+	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_PKG_TEMP, &_temp);
+	*temp = (unsigned long)_temp * 1000;
+
+	return 0;
+}
+
+static int sys_get_trip_temp(struct thermal_zone_device *tzd,
+			     int trip, int *temp)
+{
+	struct proc_thermal_pci *pci_info = tzd->devdata;
+	u32 _temp;
+
+	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_THRES_0, &_temp);
+	if (!_temp) {
+		*temp = THERMAL_TEMP_INVALID;
+	} else {
+		int tjmax;
+
+		proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax);
+		_temp = tjmax - _temp;
+		*temp = (unsigned long)_temp * 1000;
+	}
+
+	return 0;
+}
+
+static int sys_get_trip_type(struct thermal_zone_device *tzd, int trip,
+			      enum thermal_trip_type *type)
+{
+	*type = THERMAL_TRIP_PASSIVE;
+
+	return 0;
+}
+
+static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
+{
+	struct proc_thermal_pci *pci_info = tzd->devdata;
+	int tjmax, _temp;
+
+	if (temp <= 0) {
+		cancel_delayed_work_sync(&pci_info->work);
+		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
+		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0);
+		thermal_zone_device_disable(tzd);
+		pci_info->stored_thres = 0;
+		return 0;
+	}
+
+	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax);
+	_temp = tjmax - (temp / 1000);
+	if (_temp < 0)
+		return -EINVAL;
+
+	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, _temp);
+	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
+
+	thermal_zone_device_enable(tzd);
+	pci_info->stored_thres = temp;
+
+	return 0;
+}
+
+static struct thermal_zone_device_ops tzone_ops = {
+	.get_temp = sys_get_curr_temp,
+	.get_trip_temp = sys_get_trip_temp,
+	.get_trip_type = sys_get_trip_type,
+	.set_trip_temp	= sys_set_trip_temp,
+};
+
+static struct thermal_zone_params tzone_params = {
+	.governor_name = "user_space",
+	.no_hwmon = true,
+};
+
+static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct proc_thermal_device *proc_priv;
+	struct proc_thermal_pci *pci_info;
+	int irq_flag = 0, irq, ret;
+
+	proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
+	if (!proc_priv)
+		return -ENOMEM;
+
+	pci_info = devm_kzalloc(&pdev->dev, sizeof(*pci_info), GFP_KERNEL);
+	if (!pci_info)
+		return -ENOMEM;
+
+	pci_info->pdev = pdev;
+	ret = pcim_enable_device(pdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "error: could not enable device\n");
+		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);
+	if (ret) {
+		dev_err(&pdev->dev, "error: proc_thermal_add, will continue\n");
+		pci_info->no_legacy = 1;
+	}
+
+	proc_priv->priv_data = pci_info;
+	pci_info->proc_priv = proc_priv;
+	pci_set_drvdata(pdev, proc_priv);
+
+	ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data);
+	if (ret)
+		goto err_ret_thermal;
+
+	pci_info->tzone = thermal_zone_device_register("TCPU_PCI", 1, 1, pci_info,
+							&tzone_ops,
+							&tzone_params, 0, 0);
+	if (IS_ERR(pci_info->tzone))
+		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)
+		irq_flag = IRQF_SHARED;
+
+	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);
+	if (ret) {
+		dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq);
+		goto err_free_vectors;
+	}
+
+	return 0;
+
+err_free_vectors:
+	pci_free_irq_vectors(pdev);
+err_ret_tzone:
+	thermal_zone_device_unregister(pci_info->tzone);
+err_ret_mmio:
+	proc_thermal_mmio_remove(pdev, proc_priv);
+err_ret_thermal:
+	if (!pci_info->no_legacy)
+		proc_thermal_remove(proc_priv);
+	pci_disable_device(pdev);
+
+	return ret;
+}
+
+static void proc_thermal_pci_remove(struct pci_dev *pdev)
+{
+	struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
+	struct proc_thermal_pci *pci_info = proc_priv->priv_data;
+
+	cancel_delayed_work_sync(&pci_info->work);
+
+	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0);
+	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
+
+	devm_free_irq(&pdev->dev, pdev->irq, pci_info);
+	pci_free_irq_vectors(pdev);
+
+	thermal_zone_device_unregister(pci_info->tzone);
+	proc_thermal_mmio_remove(pdev, pci_info->proc_priv);
+	if (!pci_info->no_legacy)
+		proc_thermal_remove(proc_priv);
+	pci_disable_device(pdev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int proc_thermal_pci_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct proc_thermal_device *proc_priv;
+	struct proc_thermal_pci *pci_info;
+
+	proc_priv = pci_get_drvdata(pdev);
+	pci_info = proc_priv->priv_data;
+
+	if (pci_info->stored_thres) {
+		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0,
+					 pci_info->stored_thres / 1000);
+		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
+	}
+
+	if (!pci_info->no_legacy)
+		return proc_thermal_resume(dev);
+
+	return 0;
+}
+#else
+#define proc_thermal_pci_resume NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, NULL, 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) },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
+
+static struct pci_driver proc_thermal_pci_driver = {
+	.name		= DRV_NAME,
+	.probe		= proc_thermal_pci_probe,
+	.remove	= proc_thermal_pci_remove,
+	.id_table	= proc_thermal_pci_ids,
+	.driver.pm	= &proc_thermal_pci_pm,
+};
+
+static int __init proc_thermal_init(void)
+{
+	return pci_register_driver(&proc_thermal_pci_driver);
+}
+
+static void __exit proc_thermal_exit(void)
+{
+	pci_unregister_driver(&proc_thermal_pci_driver);
+}
+
+module_init(proc_thermal_init);
+module_exit(proc_thermal_exit);
+
+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_pci_legacy.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
index 21cf7511d376..f5fc1791b11e 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
@@ -118,7 +118,6 @@ static int proc_thermal_pci_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, NULL, 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, BDW_THERMAL, 0) },
 	{ PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) },
 	{ PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) },
-- 
2.27.0


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

* Re: [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver
  2021-05-25 20:48 [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver Srinivas Pandruvada
  2021-05-25 20:48 ` [PATCH 1/2] thermal: int340x: processor_thermal: Split enumeration and processing part Srinivas Pandruvada
  2021-05-25 20:48 ` [PATCH 2/2] thermal: int340x: processor_thermal: Add PCI MMIO based thermal driver Srinivas Pandruvada
@ 2021-06-24 16:19 ` Srinivas Pandruvada
  2021-06-24 17:04   ` Daniel Lezcano
  2021-07-06  8:28 ` You-Sheng Yang
  3 siblings, 1 reply; 7+ messages in thread
From: Srinivas Pandruvada @ 2021-06-24 16:19 UTC (permalink / raw)
  To: daniel.lezcano, rui.zhang, amitk; +Cc: linux-pm, linux-kernel

On Tue, 2021-05-25 at 13:48 -0700, Srinivas Pandruvada wrote:
> This series adds a new thermal driver, which uses PCI MMIO for
> temperature and trips. To reuse
> the code the first patch just reorganizes the existing code.
> 
Any comments on this series?

Thanks,
Srinivas

> This series needs the following patch to cleanly apply:
> [PATCH 1/2] thermal: int340x: processor_thermal: Export mailbox
> interface
> sent on 16th May, 21.
> 
> Srinivas Pandruvada (2):
>   thermal: int340x: processor_thermal: Split enumeration and
> processing
>     part
>   thermal: int340x: processor_thermal: Add PCI MMIO based thermal
> driver
> 
>  .../thermal/intel/int340x_thermal/Makefile    |   3 +
>  .../intel/int340x_thermal/int3401_thermal.c   |  82 ++++
>  .../processor_thermal_device.c                | 289 ++------------
>  .../processor_thermal_device.h                |   9 +-
>  .../processor_thermal_device_pci.c            | 371
> ++++++++++++++++++
>  .../processor_thermal_device_pci_legacy.c     | 163 ++++++++
>  6 files changed, 658 insertions(+), 259 deletions(-)
>  create mode 100644
> drivers/thermal/intel/int340x_thermal/int3401_thermal.c
>  create mode 100644
> drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
>  create mode 100644
> drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_le
> gacy.c
> 


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

* Re: [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver
  2021-06-24 16:19 ` [PATCH 0/2] thermal: int340x: processor_thermal: Add new " Srinivas Pandruvada
@ 2021-06-24 17:04   ` Daniel Lezcano
  2021-06-24 18:04     ` Srinivas Pandruvada
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Lezcano @ 2021-06-24 17:04 UTC (permalink / raw)
  To: Srinivas Pandruvada, rui.zhang, amitk; +Cc: linux-pm, linux-kernel

On 24/06/2021 18:19, Srinivas Pandruvada wrote:
> On Tue, 2021-05-25 at 13:48 -0700, Srinivas Pandruvada wrote:
>> This series adds a new thermal driver, which uses PCI MMIO for
>> temperature and trips. To reuse
>> the code the first patch just reorganizes the existing code.
>>
> Any comments on this series?

I've been through the series and it looks fine for me. Except a typo in
the log 'anabled' but I fixed it.



-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver
  2021-06-24 17:04   ` Daniel Lezcano
@ 2021-06-24 18:04     ` Srinivas Pandruvada
  0 siblings, 0 replies; 7+ messages in thread
From: Srinivas Pandruvada @ 2021-06-24 18:04 UTC (permalink / raw)
  To: Daniel Lezcano, rui.zhang, amitk; +Cc: linux-pm, linux-kernel

On Thu, 2021-06-24 at 19:04 +0200, Daniel Lezcano wrote:
> On 24/06/2021 18:19, Srinivas Pandruvada wrote:
> > On Tue, 2021-05-25 at 13:48 -0700, Srinivas Pandruvada wrote:
> > > This series adds a new thermal driver, which uses PCI MMIO for
> > > temperature and trips. To reuse
> > > the code the first patch just reorganizes the existing code.
> > > 
> > Any comments on this series?
> 
> I've been through the series and it looks fine for me. Except a typo
> in
> the log 'anabled' but I fixed it.
Thanks Daniel.

-Srinivas

> 
> 
> 


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

* Re: [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver
  2021-05-25 20:48 [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver Srinivas Pandruvada
                   ` (2 preceding siblings ...)
  2021-06-24 16:19 ` [PATCH 0/2] thermal: int340x: processor_thermal: Add new " Srinivas Pandruvada
@ 2021-07-06  8:28 ` You-Sheng Yang
  3 siblings, 0 replies; 7+ messages in thread
From: You-Sheng Yang @ 2021-07-06  8:28 UTC (permalink / raw)
  To: Srinivas Pandruvada
  Cc: linux-pm, linux-kernel, daniel.lezcano, rui.zhang, amitk

Verified this initialize [8086:461d] correctly. An additional thermal
zone TCPU_PCI added.

Tested-by: You-Sheng Yang <vicamo.yang@canonical.com>

On 5/26/21 4:48 AM, Srinivas Pandruvada wrote:
> This series adds a new thermal driver, which uses PCI MMIO for temperature and trips. To reuse
> the code the first patch just reorganizes the existing code.
> 
> This series needs the following patch to cleanly apply:
> [PATCH 1/2] thermal: int340x: processor_thermal: Export mailbox interface
> sent on 16th May, 21.
> 
> Srinivas Pandruvada (2):
>   thermal: int340x: processor_thermal: Split enumeration and processing
>     part
>   thermal: int340x: processor_thermal: Add PCI MMIO based thermal driver
> 
>  .../thermal/intel/int340x_thermal/Makefile    |   3 +
>  .../intel/int340x_thermal/int3401_thermal.c   |  82 ++++
>  .../processor_thermal_device.c                | 289 ++------------
>  .../processor_thermal_device.h                |   9 +-
>  .../processor_thermal_device_pci.c            | 371 ++++++++++++++++++
>  .../processor_thermal_device_pci_legacy.c     | 163 ++++++++
>  6 files changed, 658 insertions(+), 259 deletions(-)
>  create mode 100644 drivers/thermal/intel/int340x_thermal/int3401_thermal.c
>  create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
>  create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c
> 

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

end of thread, other threads:[~2021-07-06  8:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-25 20:48 [PATCH 0/2] thermal: int340x: processor_thermal: Add new PCI MMIO based thermal driver Srinivas Pandruvada
2021-05-25 20:48 ` [PATCH 1/2] thermal: int340x: processor_thermal: Split enumeration and processing part Srinivas Pandruvada
2021-05-25 20:48 ` [PATCH 2/2] thermal: int340x: processor_thermal: Add PCI MMIO based thermal driver Srinivas Pandruvada
2021-06-24 16:19 ` [PATCH 0/2] thermal: int340x: processor_thermal: Add new " Srinivas Pandruvada
2021-06-24 17:04   ` Daniel Lezcano
2021-06-24 18:04     ` Srinivas Pandruvada
2021-07-06  8:28 ` You-Sheng Yang

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).