X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=drivers%2Fpci%2Fpci.c;h=eaf4ffc0c27363bcde85fc4141f882fede59fcde;hb=18e5e6913b1ae5c6f60390945d4c8446f5c40c89;hp=d1a7105b92760fe2b6bc269b238cb0000ed74527;hpb=0f0836b7eb1b9d14862ee40c7856227a3ead70db;p=linux-2.6-block.git diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d1a7105b9276..eaf4ffc0c273 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include "pci.h" @@ -1417,7 +1416,7 @@ struct pci_devres { static void pcim_release(struct device *gendev, void *res) { - struct pci_dev *dev = container_of(gendev, struct pci_dev, dev); + struct pci_dev *dev = to_pci_dev(gendev); struct pci_devres *this = res; int i; @@ -1534,7 +1533,7 @@ void __weak pcibios_release_device(struct pci_dev *dev) {} * is the default implementation. Architecture implementations can * override this. */ -void __weak pcibios_disable_device (struct pci_dev *dev) {} +void __weak pcibios_disable_device(struct pci_dev *dev) {} /** * pcibios_penalize_isa_irq - penalize an ISA IRQ @@ -3386,18 +3385,6 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx); -int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) -{ - return dma_set_max_seg_size(&dev->dev, size); -} -EXPORT_SYMBOL(pci_set_dma_max_seg_size); - -int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask) -{ - return dma_set_seg_boundary(&dev->dev, mask); -} -EXPORT_SYMBOL(pci_set_dma_seg_boundary); - /** * pci_wait_for_pending_transaction - waits for pending transaction * @dev: the PCI device to operate on @@ -3414,6 +3401,29 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) } EXPORT_SYMBOL(pci_wait_for_pending_transaction); +/* + * We should only need to wait 100ms after FLR, but some devices take longer. + * Wait for up to 1000ms for config space to return something other than -1. + * Intel IGD requires this when an LCD panel is attached. We read the 2nd + * dword because VFs don't implement the 1st dword. + */ +static void pci_flr_wait(struct pci_dev *dev) +{ + int i = 0; + u32 id; + + do { + msleep(100); + pci_read_config_dword(dev, PCI_COMMAND, &id); + } while (i++ < 10 && id == ~0); + + if (id == ~0) + dev_warn(&dev->dev, "Failed to return from FLR\n"); + else if (i > 1) + dev_info(&dev->dev, "Required additional %dms to return from FLR\n", + (i - 1) * 100); +} + static int pcie_flr(struct pci_dev *dev, int probe) { u32 cap; @@ -3429,7 +3439,7 @@ static int pcie_flr(struct pci_dev *dev, int probe) dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n"); pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); - msleep(100); + pci_flr_wait(dev); return 0; } @@ -3459,7 +3469,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n"); pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); - msleep(100); + pci_flr_wait(dev); return 0; }