cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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");