X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fthermal%2Fint340x_thermal%2Fprocessor_thermal_device.c;h=ccc0ad02d06698108ec486d11f7b0dc69c7c734a;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hp=5e8d8e91ea6d9d6056c714b16a3eafd9d09f835e;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/kernel/drivers/thermal/int340x_thermal/processor_thermal_device.c b/kernel/drivers/thermal/int340x_thermal/processor_thermal_device.c index 5e8d8e91e..ccc0ad02d 100644 --- a/kernel/drivers/thermal/int340x_thermal/processor_thermal_device.c +++ b/kernel/drivers/thermal/int340x_thermal/processor_thermal_device.c @@ -16,15 +16,20 @@ #include #include #include +#include #include #include #include #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 #define PCI_DEVICE_ID_PROC_HSB_THERMAL 0x0A03 +/* Skylake thermal reporting device */ +#define PCI_DEVICE_ID_PROC_SKL_THERMAL 0x1903 + /* Braswell thermal reporting device */ #define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC @@ -42,6 +47,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 { @@ -139,7 +145,7 @@ static int get_tjmax(void) return -EINVAL; } -static int read_temp_msr(unsigned long *temp) +static int read_temp_msr(int *temp) { int cpu; u32 eax, edx; @@ -171,7 +177,7 @@ err_ret: } static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, - unsigned long *temp) + int *temp) { int ret; @@ -308,6 +314,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,18 +352,57 @@ 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); } static const struct pci_device_id proc_thermal_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BDW_THERMAL)}, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_HSB_THERMAL)}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_SKL_THERMAL)}, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BSW_THERMAL)}, { 0, }, };