Lines Matching +full:irq +full:- +full:status +full:- +full:read +full:- +full:quirk

1 // SPDX-License-Identifier: GPL-2.0+
8 * Copyright (C) 2023-2024 Intel Corporation
30 #include <linux/pci-bwctrl.h>
39 * struct pcie_bwctrl_data - PCIe bandwidth controller
79 * pcie_bwctrl_select_speed - Select Target Link Speed
90 struct pci_bus *bus = port->subordinate; in pcie_bwctrl_select_speed()
97 supported_speeds = port->supported_speeds; in pcie_bwctrl_select_speed()
100 dev = list_first_entry_or_null(&bus->devices, struct pci_dev, bus_list); in pcie_bwctrl_select_speed()
102 supported_speeds &= dev->supported_speeds; in pcie_bwctrl_select_speed()
124 * pcie_set_target_speed - Set downstream Link Speed for PCIe Port
134 * * 0 - on success
135 * * -EINVAL - @speed_req is not a PCIe Link Speed
136 * * -ENODEV - @port is not controllable
137 * * -ETIMEDOUT - changing Link Speed took too long
138 * * -EAGAIN - Link Speed was changed but @speed_req was not achieved
143 struct pci_bus *bus = port->subordinate; in pcie_set_target_speed()
148 return -EINVAL; in pcie_set_target_speed()
150 if (bus && bus->cur_bus_speed == speed_req) in pcie_set_target_speed()
156 struct pcie_bwctrl_data *data = port->link_bwctrl; in pcie_set_target_speed()
159 * port->link_bwctrl is NULL during initial scan when called in pcie_set_target_speed()
160 * e.g. from the Target Speed quirk. in pcie_set_target_speed()
163 mutex_lock(&data->set_speed_mutex); in pcie_set_target_speed()
168 mutex_unlock(&data->set_speed_mutex); in pcie_set_target_speed()
175 if (!ret && bus && bus->cur_bus_speed != speed_req && in pcie_set_target_speed()
176 !list_empty(&bus->devices)) in pcie_set_target_speed()
177 ret = -EAGAIN; in pcie_set_target_speed()
184 struct pci_dev *port = srv->port; in pcie_bwnotif_enable()
191 set_bit(PCI_LINK_LBMS_SEEN, &port->priv_flags); in pcie_bwnotif_enable()
199 * Update after enabling notifications & clearing status bits ensures in pcie_bwnotif_enable()
202 pcie_update_link_speed(port->subordinate); in pcie_bwnotif_enable()
211 static irqreturn_t pcie_bwnotif_irq(int irq, void *context) in pcie_bwnotif_irq() argument
214 struct pci_dev *port = srv->port; in pcie_bwnotif_irq()
227 set_bit(PCI_LINK_LBMS_SEEN, &port->priv_flags); in pcie_bwnotif_irq()
233 * change until LBMS is cleared by the write. Therefore, re-read the in pcie_bwnotif_irq()
237 pcie_update_link_speed(port->subordinate); in pcie_bwnotif_irq()
244 clear_bit(PCI_LINK_LBMS_SEEN, &port->priv_flags); in pcie_reset_lbms()
250 struct pci_dev *port = srv->port; in pcie_bwnotif_probe()
254 if (!port->subordinate) in pcie_bwnotif_probe()
255 return -ENODEV; in pcie_bwnotif_probe()
257 struct pcie_bwctrl_data *data = devm_kzalloc(&srv->device, in pcie_bwnotif_probe()
260 return -ENOMEM; in pcie_bwnotif_probe()
262 ret = devm_mutex_init(&srv->device, &data->set_speed_mutex); in pcie_bwnotif_probe()
267 port->link_bwctrl = data; in pcie_bwnotif_probe()
269 ret = request_irq(srv->irq, pcie_bwnotif_irq, in pcie_bwnotif_probe()
272 port->link_bwctrl = NULL; in pcie_bwnotif_probe()
279 pci_dbg(port, "enabled with IRQ %d\n", srv->irq); in pcie_bwnotif_probe()
281 /* Don't fail on errors. Don't leave IS_ERR() "pointer" into ->cdev */ in pcie_bwnotif_probe()
282 port->link_bwctrl->cdev = pcie_cooling_device_register(port); in pcie_bwnotif_probe()
283 if (IS_ERR(port->link_bwctrl->cdev)) in pcie_bwnotif_probe()
284 port->link_bwctrl->cdev = NULL; in pcie_bwnotif_probe()
291 struct pcie_bwctrl_data *data = srv->port->link_bwctrl; in pcie_bwnotif_remove()
293 pcie_cooling_device_unregister(data->cdev); in pcie_bwnotif_remove()
296 pcie_bwnotif_disable(srv->port); in pcie_bwnotif_remove()
298 free_irq(srv->irq, srv); in pcie_bwnotif_remove()
300 srv->port->link_bwctrl = NULL; in pcie_bwnotif_remove()
306 pcie_bwnotif_disable(srv->port); in pcie_bwnotif_suspend()