processor_thermal_device_pci_legacy.c (4475B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * B0D4 processor thermal device 4 * Copyright (c) 2020, Intel Corporation. 5 */ 6 7#include <linux/acpi.h> 8#include <linux/kernel.h> 9#include <linux/module.h> 10#include <linux/pci.h> 11#include <linux/thermal.h> 12 13#include "int340x_thermal_zone.h" 14#include "processor_thermal_device.h" 15#include "../intel_soc_dts_iosf.h" 16 17#define DRV_NAME "proc_thermal" 18 19static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid) 20{ 21 struct proc_thermal_device *proc_priv; 22 struct pci_dev *pdev = devid; 23 24 proc_priv = pci_get_drvdata(pdev); 25 26 intel_soc_dts_iosf_interrupt_handler(proc_priv->soc_dts); 27 28 return IRQ_HANDLED; 29} 30 31static int proc_thermal_pci_probe(struct pci_dev *pdev, 32 const struct pci_device_id *id) 33{ 34 struct proc_thermal_device *proc_priv; 35 int ret; 36 37 ret = pcim_enable_device(pdev); 38 if (ret < 0) { 39 dev_err(&pdev->dev, "error: could not enable device\n"); 40 return ret; 41 } 42 43 proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL); 44 if (!proc_priv) 45 return -ENOMEM; 46 47 ret = proc_thermal_add(&pdev->dev, proc_priv); 48 if (ret) 49 return ret; 50 51 pci_set_drvdata(pdev, proc_priv); 52 53 if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) { 54 /* 55 * Enumerate additional DTS sensors available via IOSF. 56 * But we are not treating as a failure condition, if 57 * there are no aux DTSs enabled or fails. This driver 58 * already exposes sensors, which can be accessed via 59 * ACPI/MSR. So we don't want to fail for auxiliary DTSs. 60 */ 61 proc_priv->soc_dts = intel_soc_dts_iosf_init( 62 INTEL_SOC_DTS_INTERRUPT_MSI, 2, 0); 63 64 if (!IS_ERR(proc_priv->soc_dts) && pdev->irq) { 65 ret = pci_enable_msi(pdev); 66 if (!ret) { 67 ret = request_threaded_irq(pdev->irq, NULL, 68 proc_thermal_pci_msi_irq, 69 IRQF_ONESHOT, "proc_thermal", 70 pdev); 71 if (ret) { 72 intel_soc_dts_iosf_exit( 73 proc_priv->soc_dts); 74 pci_disable_msi(pdev); 75 proc_priv->soc_dts = NULL; 76 } 77 } 78 } else 79 dev_err(&pdev->dev, "No auxiliary DTSs enabled\n"); 80 } else { 81 82 } 83 84 ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data); 85 if (ret) { 86 proc_thermal_remove(proc_priv); 87 return ret; 88 } 89 90 return 0; 91} 92 93static void proc_thermal_pci_remove(struct pci_dev *pdev) 94{ 95 struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev); 96 97 if (proc_priv->soc_dts) { 98 intel_soc_dts_iosf_exit(proc_priv->soc_dts); 99 if (pdev->irq) { 100 free_irq(pdev->irq, pdev); 101 pci_disable_msi(pdev); 102 } 103 } 104 105 proc_thermal_mmio_remove(pdev, proc_priv); 106 proc_thermal_remove(proc_priv); 107} 108 109#ifdef CONFIG_PM_SLEEP 110static int proc_thermal_pci_suspend(struct device *dev) 111{ 112 return proc_thermal_suspend(dev); 113} 114static int proc_thermal_pci_resume(struct device *dev) 115{ 116 return proc_thermal_resume(dev); 117} 118#else 119#define proc_thermal_pci_suspend NULL 120#define proc_thermal_pci_resume NULL 121#endif 122 123static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend, 124 proc_thermal_pci_resume); 125 126static const struct pci_device_id proc_thermal_pci_ids[] = { 127 { PCI_DEVICE_DATA(INTEL, BDW_THERMAL, 0) }, 128 { PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) }, 129 { PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) }, 130 { PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) }, 131 { PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) }, 132 { PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) }, 133 { PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) }, 134 { PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) }, 135 { PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) }, 136 { PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) }, 137 { PCI_DEVICE_DATA(INTEL, ICL_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, 138 { PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) }, 139 { PCI_DEVICE_DATA(INTEL, SKL_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, 140 { PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_MBOX) }, 141 { }, 142}; 143 144MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids); 145 146static struct pci_driver proc_thermal_pci_driver = { 147 .name = DRV_NAME, 148 .probe = proc_thermal_pci_probe, 149 .remove = proc_thermal_pci_remove, 150 .id_table = proc_thermal_pci_ids, 151 .driver.pm = &proc_thermal_pci_pm, 152}; 153 154static int __init proc_thermal_init(void) 155{ 156 return pci_register_driver(&proc_thermal_pci_driver); 157} 158 159static void __exit proc_thermal_exit(void) 160{ 161 pci_unregister_driver(&proc_thermal_pci_driver); 162} 163 164module_init(proc_thermal_init); 165module_exit(proc_thermal_exit); 166 167MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 168MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); 169MODULE_LICENSE("GPL v2");