diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2018-06-08 08:26:03 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2023-01-06 06:27:56 +0100 |
commit | 5cfc1b49a480b6425552be445f56c05dceff8b29 (patch) | |
tree | cfbbdb2c163556fe51446a4410b9cb05b0976334 | |
parent | 76dcd734eca23168cb008912c0f69ff408905235 (diff) | |
download | linux-5cfc1b49a480b6425552be445f56c05dceff8b29.tar.gz |
[debug] reset_ehci_dev
-rw-r--r-- | drivers/pci/quirks.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 285acc4aaccc..d29f61bb5680 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3894,6 +3894,38 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe) return 0; } +#define EHCI_CMD_RESET (1<<1) + +static int reset_ehci_dev(struct pci_dev *dev, int probe) +{ + void __iomem *mmio; + unsigned long timeout; + u32 opregs, cmd; + + if (probe) + return 0; + + mmio = pci_iomap(dev, 0, 0); + if (!mmio) + return -ENOMEM; + + opregs = ioread8(mmio); + cmd = EHCI_CMD_RESET; + iowrite32(cmd, mmio + opregs); + timeout = jiffies + msecs_to_jiffies(250); + do { + cmd = ioread32(mmio + opregs); + if ((cmd & EHCI_CMD_RESET) == 0) + goto reset_complete; + msleep(10); + } while (time_before(jiffies, timeout)); + pci_warn(dev, "timeout during reset\n"); + +reset_complete: + pci_iounmap(dev, mmio); + return 0; +} + #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed #define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156 #define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166 @@ -4094,6 +4126,9 @@ int pci_dev_specific_reset(struct pci_dev *dev, bool probe) return i->reset(dev, probe); } + if (dev->class == PCI_CLASS_SERIAL_USB_EHCI) + reset_ehci_dev(dev, probe); + return -ENOTTY; } |