Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * B0D4 processor thermal device
0004  * Copyright (c) 2020, Intel Corporation.
0005  */
0006 
0007 #include <linux/acpi.h>
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/pci.h>
0011 #include <linux/thermal.h>
0012 
0013 #include "int340x_thermal_zone.h"
0014 #include "processor_thermal_device.h"
0015 #include "../intel_soc_dts_iosf.h"
0016 
0017 #define DRV_NAME "proc_thermal"
0018 
0019 static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid)
0020 {
0021     struct proc_thermal_device *proc_priv;
0022     struct pci_dev *pdev = devid;
0023 
0024     proc_priv = pci_get_drvdata(pdev);
0025 
0026     intel_soc_dts_iosf_interrupt_handler(proc_priv->soc_dts);
0027 
0028     return IRQ_HANDLED;
0029 }
0030 
0031 static int proc_thermal_pci_probe(struct pci_dev *pdev,
0032                   const struct pci_device_id *id)
0033 {
0034     struct proc_thermal_device *proc_priv;
0035     int ret;
0036 
0037     ret = pcim_enable_device(pdev);
0038     if (ret < 0) {
0039         dev_err(&pdev->dev, "error: could not enable device\n");
0040         return ret;
0041     }
0042 
0043     proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
0044     if (!proc_priv)
0045         return -ENOMEM;
0046 
0047     ret = proc_thermal_add(&pdev->dev, proc_priv);
0048     if (ret)
0049         return ret;
0050 
0051     pci_set_drvdata(pdev, proc_priv);
0052 
0053     if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) {
0054         /*
0055          * Enumerate additional DTS sensors available via IOSF.
0056          * But we are not treating as a failure condition, if
0057          * there are no aux DTSs enabled or fails. This driver
0058          * already exposes sensors, which can be accessed via
0059          * ACPI/MSR. So we don't want to fail for auxiliary DTSs.
0060          */
0061         proc_priv->soc_dts = intel_soc_dts_iosf_init(
0062                     INTEL_SOC_DTS_INTERRUPT_MSI, 2, 0);
0063 
0064         if (!IS_ERR(proc_priv->soc_dts) && pdev->irq) {
0065             ret = pci_enable_msi(pdev);
0066             if (!ret) {
0067                 ret = request_threaded_irq(pdev->irq, NULL,
0068                         proc_thermal_pci_msi_irq,
0069                         IRQF_ONESHOT, "proc_thermal",
0070                         pdev);
0071                 if (ret) {
0072                     intel_soc_dts_iosf_exit(
0073                             proc_priv->soc_dts);
0074                     pci_disable_msi(pdev);
0075                     proc_priv->soc_dts = NULL;
0076                 }
0077             }
0078         } else
0079             dev_err(&pdev->dev, "No auxiliary DTSs enabled\n");
0080     } else {
0081 
0082     }
0083 
0084     ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data);
0085     if (ret) {
0086         proc_thermal_remove(proc_priv);
0087         return ret;
0088     }
0089 
0090     return 0;
0091 }
0092 
0093 static void proc_thermal_pci_remove(struct pci_dev *pdev)
0094 {
0095     struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
0096 
0097     if (proc_priv->soc_dts) {
0098         intel_soc_dts_iosf_exit(proc_priv->soc_dts);
0099         if (pdev->irq) {
0100             free_irq(pdev->irq, pdev);
0101             pci_disable_msi(pdev);
0102         }
0103     }
0104 
0105     proc_thermal_mmio_remove(pdev, proc_priv);
0106     proc_thermal_remove(proc_priv);
0107 }
0108 
0109 #ifdef CONFIG_PM_SLEEP
0110 static int proc_thermal_pci_suspend(struct device *dev)
0111 {
0112     return proc_thermal_suspend(dev);
0113 }
0114 static int proc_thermal_pci_resume(struct device *dev)
0115 {
0116     return proc_thermal_resume(dev);
0117 }
0118 #else
0119 #define proc_thermal_pci_suspend NULL
0120 #define proc_thermal_pci_resume NULL
0121 #endif
0122 
0123 static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
0124              proc_thermal_pci_resume);
0125 
0126 static const struct pci_device_id proc_thermal_pci_ids[] = {
0127     { PCI_DEVICE_DATA(INTEL, BDW_THERMAL, 0) },
0128     { PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) },
0129     { PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) },
0130     { PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) },
0131     { PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) },
0132     { PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) },
0133     { PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) },
0134     { PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) },
0135     { PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) },
0136     { PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) },
0137     { PCI_DEVICE_DATA(INTEL, ICL_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
0138     { PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) },
0139     { PCI_DEVICE_DATA(INTEL, SKL_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
0140     { PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_MBOX) },
0141     { },
0142 };
0143 
0144 MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
0145 
0146 static struct pci_driver proc_thermal_pci_driver = {
0147     .name       = DRV_NAME,
0148     .probe      = proc_thermal_pci_probe,
0149     .remove     = proc_thermal_pci_remove,
0150     .id_table   = proc_thermal_pci_ids,
0151     .driver.pm  = &proc_thermal_pci_pm,
0152 };
0153 
0154 static int __init proc_thermal_init(void)
0155 {
0156     return pci_register_driver(&proc_thermal_pci_driver);
0157 }
0158 
0159 static void __exit proc_thermal_exit(void)
0160 {
0161     pci_unregister_driver(&proc_thermal_pci_driver);
0162 }
0163 
0164 module_init(proc_thermal_init);
0165 module_exit(proc_thermal_exit);
0166 
0167 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
0168 MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
0169 MODULE_LICENSE("GPL v2");