FILE
pcie_cooling.c
File preview with syntax highlighting.
linux-6.19.14/drivers/thermal/pcie_cooling.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * PCIe cooling device 4 * 5 * Copyright (C) 2023-2024 Intel Corporation 6 */ 7 8#include <linux/build_bug.h> 9#include <linux/cleanup.h> 10#include <linux/err.h> 11#include <linux/module.h> 12#include <linux/pci.h> 13#include <linux/pci-bwctrl.h> 14#include <linux/slab.h> 15#include <linux/sprintf.h> 16#include <linux/thermal.h> 17 18#define COOLING_DEV_TYPE_PREFIX "PCIe_Port_Link_Speed_" 19 20static int pcie_cooling_get_max_level(struct thermal_cooling_device *cdev, unsigned long *state) 21{ 22 struct pci_dev *port = cdev->devdata; 23 24 /* cooling state 0 is same as the maximum PCIe speed */ 25 *state = port->subordinate->max_bus_speed - PCIE_SPEED_2_5GT; 26 27 return 0; 28} 29 30static int pcie_cooling_get_cur_level(struct thermal_cooling_device *cdev, unsigned long *state) 31{ 32 struct pci_dev *port = cdev->devdata; 33 34 /* cooling state 0 is same as the maximum PCIe speed */ 35 *state = cdev->max_state - (port->subordinate->cur_bus_speed - PCIE_SPEED_2_5GT); 36 37 return 0; 38} 39 40static int pcie_cooling_set_cur_level(struct thermal_cooling_device *cdev, unsigned long state) 41{ 42 struct pci_dev *port = cdev->devdata; 43 enum pci_bus_speed speed; 44 45 /* cooling state 0 is same as the maximum PCIe speed */ 46 speed = (cdev->max_state - state) + PCIE_SPEED_2_5GT; 47 48 return pcie_set_target_speed(port, speed, true); 49} 50 51static struct thermal_cooling_device_ops pcie_cooling_ops = { 52 .get_max_state = pcie_cooling_get_max_level, 53 .get_cur_state = pcie_cooling_get_cur_level, 54 .set_cur_state = pcie_cooling_set_cur_level, 55}; 56 57struct thermal_cooling_device *pcie_cooling_device_register(struct pci_dev *port) 58{ 59 char *name __free(kfree) = 60 kasprintf(GFP_KERNEL, COOLING_DEV_TYPE_PREFIX "%s", pci_name(port)); 61 if (!name) 62 return ERR_PTR(-ENOMEM); 63 64 return thermal_cooling_device_register(name, port, &pcie_cooling_ops); 65} 66 67void pcie_cooling_device_unregister(struct thermal_cooling_device *cdev) 68{ 69 thermal_cooling_device_unregister(cdev); 70} 71 72/* For bus_speed <-> state arithmetic */ 73static_assert(PCIE_SPEED_2_5GT + 1 == PCIE_SPEED_5_0GT); 74static_assert(PCIE_SPEED_5_0GT + 1 == PCIE_SPEED_8_0GT); 75static_assert(PCIE_SPEED_8_0GT + 1 == PCIE_SPEED_16_0GT); 76static_assert(PCIE_SPEED_16_0GT + 1 == PCIE_SPEED_32_0GT); 77static_assert(PCIE_SPEED_32_0GT + 1 == PCIE_SPEED_64_0GT); 78 79MODULE_AUTHOR("Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>"); 80MODULE_DESCRIPTION("PCIe cooling driver");
~/
Read-only file preview.