// SPDX-License-Identifier: GPL-2.0-only /* * PCIe cooling device * * Copyright (C) 2023-2024 Intel Corporation */ #include #include #include #include #include #include #include #include #include #define COOLING_DEV_TYPE_PREFIX "PCIe_Port_Link_Speed_" static int pcie_cooling_get_max_level(struct thermal_cooling_device *cdev, unsigned long *state) { struct pci_dev *port = cdev->devdata; /* cooling state 0 is same as the maximum PCIe speed */ *state = port->subordinate->max_bus_speed - PCIE_SPEED_2_5GT; return 0; } static int pcie_cooling_get_cur_level(struct thermal_cooling_device *cdev, unsigned long *state) { struct pci_dev *port = cdev->devdata; /* cooling state 0 is same as the maximum PCIe speed */ *state = cdev->max_state - (port->subordinate->cur_bus_speed - PCIE_SPEED_2_5GT); return 0; } static int pcie_cooling_set_cur_level(struct thermal_cooling_device *cdev, unsigned long state) { struct pci_dev *port = cdev->devdata; enum pci_bus_speed speed; /* cooling state 0 is same as the maximum PCIe speed */ speed = (cdev->max_state - state) + PCIE_SPEED_2_5GT; return pcie_set_target_speed(port, speed, true); } static struct thermal_cooling_device_ops pcie_cooling_ops = { .get_max_state = pcie_cooling_get_max_level, .get_cur_state = pcie_cooling_get_cur_level, .set_cur_state = pcie_cooling_set_cur_level, }; struct thermal_cooling_device *pcie_cooling_device_register(struct pci_dev *port) { char *name __free(kfree) = kasprintf(GFP_KERNEL, COOLING_DEV_TYPE_PREFIX "%s", pci_name(port)); if (!name) return ERR_PTR(-ENOMEM); return thermal_cooling_device_register(name, port, &pcie_cooling_ops); } void pcie_cooling_device_unregister(struct thermal_cooling_device *cdev) { thermal_cooling_device_unregister(cdev); } /* For bus_speed <-> state arithmetic */ static_assert(PCIE_SPEED_2_5GT + 1 == PCIE_SPEED_5_0GT); static_assert(PCIE_SPEED_5_0GT + 1 == PCIE_SPEED_8_0GT); static_assert(PCIE_SPEED_8_0GT + 1 == PCIE_SPEED_16_0GT); static_assert(PCIE_SPEED_16_0GT + 1 == PCIE_SPEED_32_0GT); static_assert(PCIE_SPEED_32_0GT + 1 == PCIE_SPEED_64_0GT); MODULE_AUTHOR("Ilpo Järvinen "); MODULE_DESCRIPTION("PCIe cooling driver");