]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Thermal/int340x/processor_thermal: Enable auxiliary DTS for Braswell
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Mon, 2 Mar 2015 21:13:00 +0000 (13:13 -0800)
committerZhang Rui <rui.zhang@intel.com>
Fri, 1 May 2015 03:20:42 +0000 (11:20 +0800)
Support two auxiliary DTS present on Braswell platform using side band
IOSF interface. This supports two read write trips, which can be used
to get notification on trip violation.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
drivers/thermal/Kconfig
drivers/thermal/int340x_thermal/processor_thermal_device.c

index 210e1707f31d681695defceab85f849ce55d71b8..56922373806edaa9d04b4cb2fb244ee88db2ce78 100644 (file)
@@ -278,6 +278,7 @@ config INT340X_THERMAL
        select THERMAL_GOV_USER_SPACE
        select ACPI_THERMAL_REL
        select ACPI_FAN
+       select INTEL_SOC_DTS_IOSF_CORE
        help
          Newer laptops and tablets that use ACPI may have thermal sensors and
          other devices with thermal control capabilities outside the core
index 5e8d8e91ea6d9d6056c714b16a3eafd9d09f835e..e9f1b729fe9c27b1a9ce19210c1429314edc6e5d 100644 (file)
 #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 "int340x_thermal_zone.h"
+#include "../intel_soc_dts_iosf.h"
 
 /* Broadwell-U/HSB thermal reporting device */
 #define PCI_DEVICE_ID_PROC_BDW_THERMAL 0x1603
@@ -42,6 +44,7 @@ struct proc_thermal_device {
        struct acpi_device *adev;
        struct power_config power_limits[2];
        struct int34x_thermal_zone *int340x_zone;
+       struct intel_soc_dts_sensors *soc_dts;
 };
 
 enum proc_thermal_emum_mode_type {
@@ -308,6 +311,18 @@ static int int3401_remove(struct platform_device *pdev)
        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;
+}
+
 static int  proc_thermal_pci_probe(struct pci_dev *pdev,
                                   const struct pci_device_id *unused)
 {
@@ -334,12 +349,50 @@ static int  proc_thermal_pci_probe(struct pci_dev *pdev,
        pci_set_drvdata(pdev, proc_priv);
        proc_thermal_emum_mode = PROC_THERMAL_PCI;
 
+       if (pdev->device == PCI_DEVICE_ID_PROC_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 (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");
+       }
+
        return 0;
 }
 
 static void  proc_thermal_pci_remove(struct pci_dev *pdev)
 {
-       proc_thermal_remove(pci_get_drvdata(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_remove(proc_priv);
        pci_disable_device(pdev);
 }