Lines Matching +full:pcie +full:- +full:root +full:- +full:port +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe Native PME support
5 * Copyright (C) 2007 - 2009 Intel Corp
6 * Copyright (C) 2007 - 2009 Shaohua Li <[email protected]>
26 * If this switch is set, MSI will not be used for PCIe PME signaling. This
27 * causes the PCIe port driver to use INTx interrupts only, but it turns out
28 * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based
29 * wake-up from system sleep states.
38 return 1; in pcie_pme_setup()
50 * pcie_pme_interrupt_enable - Enable/disable PCIe PME interrupt generation.
51 * @dev: PCIe root port or event collector.
65 * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#.
75 list_for_each_entry(dev, &bus->devices, bus_list) { in pcie_pme_walk_bus()
76 /* Skip PCIe devices in case we started from a root port. */ in pcie_pme_walk_bus()
78 if (dev->pme_poll) in pcie_pme_walk_bus()
79 dev->pme_poll = false; in pcie_pme_walk_bus()
82 pm_request_resume(&dev->dev); in pcie_pme_walk_bus()
86 if (dev->subordinate && pcie_pme_walk_bus(dev->subordinate)) in pcie_pme_walk_bus()
94 * pcie_pme_from_pci_bridge - Check if PCIe-PCI bridge generated a PME.
98 * PME from PCI devices under a PCIe-PCI bridge may be converted to an in-band
99 * PCIe PME message. In such that case the bridge should use the Requester ID
110 dev = pci_dev_get(bus->self); in pcie_pme_from_pci_bridge()
126 * pcie_pme_handle_request - Find device that generated PME and handle it.
127 * @port: Root port or event collector that generated the PME interrupt.
128 * @req_id: PCIe Requester ID of the device that generated the PME.
130 static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) in pcie_pme_handle_request() argument
137 /* First, check if the PME is from the root port itself. */ in pcie_pme_handle_request()
138 if (port->devfn == devfn && port->bus->number == busnr) { in pcie_pme_handle_request()
139 if (port->pme_poll) in pcie_pme_handle_request()
140 port->pme_poll = false; in pcie_pme_handle_request()
142 if (pci_check_pme_status(port)) { in pcie_pme_handle_request()
143 pm_request_resume(&port->dev); in pcie_pme_handle_request()
147 * Apparently, the root port generated the PME on behalf in pcie_pme_handle_request()
148 * of a non-PCIe device downstream. If this is done by in pcie_pme_handle_request()
149 * a root port, the Requester ID field in its status in pcie_pme_handle_request()
150 * register may contain either the root port's, or the in pcie_pme_handle_request()
155 found = pcie_pme_walk_bus(port->subordinate); in pcie_pme_handle_request()
162 bus = pci_find_bus(pci_domain_nr(port->bus), busnr); in pcie_pme_handle_request()
166 /* Next, check if the PME is from a PCIe-PCI bridge. */ in pcie_pme_handle_request()
173 list_for_each_entry(dev, &bus->devices, bus_list) { in pcie_pme_handle_request()
175 if (dev->devfn == devfn) { in pcie_pme_handle_request()
187 if (dev->pme_poll) in pcie_pme_handle_request()
188 dev->pme_poll = false; in pcie_pme_handle_request()
191 pm_request_resume(&dev->dev); in pcie_pme_handle_request()
197 * assuming that the PME was reported by a PCIe-PCI bridge that in pcie_pme_handle_request()
200 pci_info(port, "interrupt generated for non-existent device %02x:%02x.%d\n", in pcie_pme_handle_request()
207 pci_info(port, "Spurious native interrupt!\n"); in pcie_pme_handle_request()
211 * pcie_pme_work_fn - Work handler for PCIe PME interrupt.
218 struct pci_dev *port = data->srv->port; in pcie_pme_work_fn() local
221 spin_lock_irq(&data->lock); in pcie_pme_work_fn()
224 if (data->noirq) in pcie_pme_work_fn()
227 pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); in pcie_pme_work_fn()
233 * Clear PME status of the port. If there are other in pcie_pme_work_fn()
236 pcie_clear_root_pme_status(port); in pcie_pme_work_fn()
238 spin_unlock_irq(&data->lock); in pcie_pme_work_fn()
239 pcie_pme_handle_request(port, in pcie_pme_work_fn()
241 spin_lock_irq(&data->lock); in pcie_pme_work_fn()
250 spin_unlock_irq(&data->lock); in pcie_pme_work_fn()
252 spin_lock_irq(&data->lock); in pcie_pme_work_fn()
255 if (!data->noirq) in pcie_pme_work_fn()
256 pcie_pme_interrupt_enable(port, true); in pcie_pme_work_fn()
258 spin_unlock_irq(&data->lock); in pcie_pme_work_fn()
262 * pcie_pme_irq - Interrupt handler for PCIe root port PME interrupt.
268 struct pci_dev *port; in pcie_pme_irq() local
273 port = ((struct pcie_device *)context)->port; in pcie_pme_irq()
276 spin_lock_irqsave(&data->lock, flags); in pcie_pme_irq()
277 pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); in pcie_pme_irq()
280 spin_unlock_irqrestore(&data->lock, flags); in pcie_pme_irq()
284 pcie_pme_interrupt_enable(port, false); in pcie_pme_irq()
285 spin_unlock_irqrestore(&data->lock, flags); in pcie_pme_irq()
288 schedule_work(&data->work); in pcie_pme_irq()
294 * pcie_pme_can_wakeup - Set the wakeup capability flag.
300 device_set_wakeup_capable(&dev->dev, true); in pcie_pme_can_wakeup()
305 * pcie_pme_mark_devices - Set the wakeup flag for devices below a port.
306 * @port: PCIe root port or event collector to handle.
308 * For each device below given root port, including the port itself (or for each
309 * root complex integrated endpoint if @port is a root complex event collector)
310 * set the flag indicating that it can signal run-time wake-up events.
312 static void pcie_pme_mark_devices(struct pci_dev *port) in pcie_pme_mark_devices() argument
314 pcie_pme_can_wakeup(port, NULL); in pcie_pme_mark_devices()
316 if (pci_pcie_type(port) == PCI_EXP_TYPE_RC_EC) in pcie_pme_mark_devices()
317 pcie_walk_rcec(port, pcie_pme_can_wakeup, NULL); in pcie_pme_mark_devices()
318 else if (port->subordinate) in pcie_pme_mark_devices()
319 pci_walk_bus(port->subordinate, pcie_pme_can_wakeup, NULL); in pcie_pme_mark_devices()
323 * pcie_pme_probe - Initialize PCIe PME service for given root port.
324 * @srv: PCIe service to initialize.
328 struct pci_dev *port = srv->port; in pcie_pme_probe() local
330 int type = pci_pcie_type(port); in pcie_pme_probe()
333 /* Limit to Root Ports or Root Complex Event Collectors */ in pcie_pme_probe()
336 return -ENODEV; in pcie_pme_probe()
340 return -ENOMEM; in pcie_pme_probe()
342 spin_lock_init(&data->lock); in pcie_pme_probe()
343 INIT_WORK(&data->work, pcie_pme_work_fn); in pcie_pme_probe()
344 data->srv = srv; in pcie_pme_probe()
347 pcie_pme_interrupt_enable(port, false); in pcie_pme_probe()
348 pcie_clear_root_pme_status(port); in pcie_pme_probe()
350 ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); in pcie_pme_probe()
356 pci_info(port, "Signaling with IRQ %d\n", srv->irq); in pcie_pme_probe()
358 pcie_pme_mark_devices(port); in pcie_pme_probe()
359 pcie_pme_interrupt_enable(port, true); in pcie_pme_probe()
370 list_for_each_entry(dev, &bus->devices, bus_list) in pcie_pme_check_wakeup()
371 if (device_may_wakeup(&dev->dev) in pcie_pme_check_wakeup()
372 || pcie_pme_check_wakeup(dev->subordinate)) in pcie_pme_check_wakeup()
378 static void pcie_pme_disable_interrupt(struct pci_dev *port, in pcie_pme_disable_interrupt() argument
381 spin_lock_irq(&data->lock); in pcie_pme_disable_interrupt()
382 pcie_pme_interrupt_enable(port, false); in pcie_pme_disable_interrupt()
383 pcie_clear_root_pme_status(port); in pcie_pme_disable_interrupt()
384 data->noirq = true; in pcie_pme_disable_interrupt()
385 spin_unlock_irq(&data->lock); in pcie_pme_disable_interrupt()
389 * pcie_pme_suspend - Suspend PCIe PME service device.
390 * @srv: PCIe service device to suspend.
395 struct pci_dev *port = srv->port; in pcie_pme_suspend() local
399 if (device_may_wakeup(&port->dev)) { in pcie_pme_suspend()
403 wakeup = pcie_pme_check_wakeup(port->subordinate); in pcie_pme_suspend()
407 ret = enable_irq_wake(srv->irq); in pcie_pme_suspend()
412 pcie_pme_disable_interrupt(port, data); in pcie_pme_suspend()
414 synchronize_irq(srv->irq); in pcie_pme_suspend()
420 * pcie_pme_resume - Resume PCIe PME service device.
421 * @srv: PCIe service device to resume.
427 spin_lock_irq(&data->lock); in pcie_pme_resume()
428 if (data->noirq) { in pcie_pme_resume()
429 struct pci_dev *port = srv->port; in pcie_pme_resume() local
431 pcie_clear_root_pme_status(port); in pcie_pme_resume()
432 pcie_pme_interrupt_enable(port, true); in pcie_pme_resume()
433 data->noirq = false; in pcie_pme_resume()
435 disable_irq_wake(srv->irq); in pcie_pme_resume()
437 spin_unlock_irq(&data->lock); in pcie_pme_resume()
443 * pcie_pme_remove - Prepare PCIe PME service device for removal.
444 * @srv: PCIe service device to remove.
450 pcie_pme_disable_interrupt(srv->port, data); in pcie_pme_remove()
451 free_irq(srv->irq, srv); in pcie_pme_remove()
452 cancel_work_sync(&data->work); in pcie_pme_remove()
468 * pcie_pme_init - Register the PCIe PME service driver.