mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 15:10:38 +00:00
xhci: move PCI specific MSI/MSIX cleanup away from generic xhci functions
Call the PCI specific MSI/MSIX interrupt freeing code from the xhci-pci callbacks instead of generic xhci code, decoupling PCI parts from generic xhci functions. Adds xhci_pci_stop() that overrides xhci_stop() for PCI xHC controllers. This will free MSIX interrupts a bit later in the hc_driver stop callback, but is still earlier than usb core frees "legacy" interrupts, or interrupts for other hosts. Signed-off-by: Josue David Hernandez Gutierrez <josue.d.hernandez.gutierrez@intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20230317154715.535523-12-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fabbd95cc4
commit
ed526ba2ec
@ -230,6 +230,16 @@ static int xhci_pci_run(struct usb_hcd *hcd)
|
||||
return xhci_run(hcd);
|
||||
}
|
||||
|
||||
static void xhci_pci_stop(struct usb_hcd *hcd)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
|
||||
xhci_stop(hcd);
|
||||
|
||||
if (usb_hcd_is_primary_hcd(hcd))
|
||||
xhci_cleanup_msix(xhci);
|
||||
}
|
||||
|
||||
/* called after powerup, by probe or system-pm "wakeup" */
|
||||
static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
|
||||
{
|
||||
@ -868,6 +878,7 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd)
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
|
||||
xhci_shutdown(hcd);
|
||||
xhci_cleanup_msix(xhci);
|
||||
|
||||
/* Yet another workaround for spurious wakeups at shutdown with HSW */
|
||||
if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
|
||||
@ -932,6 +943,7 @@ static int __init xhci_pci_init(void)
|
||||
xhci_pci_hc_driver.pci_poweroff_late = xhci_pci_poweroff_late;
|
||||
xhci_pci_hc_driver.shutdown = xhci_pci_shutdown;
|
||||
#endif
|
||||
xhci_pci_hc_driver.stop = xhci_pci_stop;
|
||||
return pci_register_driver(&xhci_pci_driver);
|
||||
}
|
||||
module_init(xhci_pci_init);
|
||||
|
@ -321,7 +321,7 @@ static int xhci_disable_interrupter(struct xhci_interrupter *ir)
|
||||
#ifdef CONFIG_USB_PCI
|
||||
|
||||
/* Free any IRQs and disable MSI-X */
|
||||
static void xhci_cleanup_msix(struct xhci_hcd *xhci)
|
||||
void xhci_cleanup_msix(struct xhci_hcd *xhci)
|
||||
{
|
||||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
@ -345,6 +345,7 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
|
||||
pci_free_irq_vectors(pdev);
|
||||
hcd->msix_enabled = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_cleanup_msix);
|
||||
|
||||
static void __maybe_unused xhci_msix_sync_irqs(struct xhci_hcd *xhci)
|
||||
{
|
||||
@ -617,7 +618,7 @@ EXPORT_SYMBOL_GPL(xhci_run);
|
||||
* Disable device contexts, disable IRQs, and quiesce the HC.
|
||||
* Reset the HC, finish any completed transactions, and cleanup memory.
|
||||
*/
|
||||
static void xhci_stop(struct usb_hcd *hcd)
|
||||
void xhci_stop(struct usb_hcd *hcd)
|
||||
{
|
||||
u32 temp;
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
@ -640,8 +641,6 @@ static void xhci_stop(struct usb_hcd *hcd)
|
||||
xhci_reset(xhci, XHCI_RESET_SHORT_USEC);
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
|
||||
xhci_cleanup_msix(xhci);
|
||||
|
||||
/* Deleting Compliance Mode Recovery Timer */
|
||||
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
|
||||
(!(xhci_all_ports_seen_u0(xhci)))) {
|
||||
@ -668,6 +667,7 @@ static void xhci_stop(struct usb_hcd *hcd)
|
||||
readl(&xhci->op_regs->status));
|
||||
mutex_unlock(&xhci->mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_stop);
|
||||
|
||||
/*
|
||||
* Shutdown HC (not bus-specific)
|
||||
@ -709,8 +709,6 @@ void xhci_shutdown(struct usb_hcd *hcd)
|
||||
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
|
||||
xhci_cleanup_msix(xhci);
|
||||
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
|
||||
"xhci_shutdown completed - status = %x",
|
||||
readl(&xhci->op_regs->status));
|
||||
|
@ -2125,6 +2125,7 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us);
|
||||
int xhci_run(struct usb_hcd *hcd);
|
||||
int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
|
||||
void xhci_shutdown(struct usb_hcd *hcd);
|
||||
void xhci_stop(struct usb_hcd *hcd);
|
||||
void xhci_init_driver(struct hc_driver *drv,
|
||||
const struct xhci_driver_overrides *over);
|
||||
int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
@ -2143,6 +2144,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated);
|
||||
|
||||
irqreturn_t xhci_irq(struct usb_hcd *hcd);
|
||||
irqreturn_t xhci_msi_irq(int irq, void *hcd);
|
||||
void xhci_cleanup_msix(struct xhci_hcd *xhci);
|
||||
int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
|
||||
int xhci_alloc_tt_info(struct xhci_hcd *xhci,
|
||||
struct xhci_virt_device *virt_dev,
|
||||
|
Loading…
x
Reference in New Issue
Block a user