diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 19:24:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 19:24:54 -0400 |
commit | 3bb07f1b73ea6313b843807063e183e168c9182a (patch) | |
tree | f0e2ab77b8bc993a843a0edede00668c589863cc /drivers/pci/quirks.c | |
parent | 6326c71fd2fb3bef5fa33951479298b683da35fe (diff) | |
parent | 5420e46d4d79bcd5d5952df98d022c8412385d32 (diff) |
Merge tag 'pci-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
- Host bridge cleanups from Yinghai
- Disable Bus Master bit on PCI device shutdown (kexec-related)
- Stratus ftServer fix
- pci_dev_reset() locking fix
- IvyBridge graphics erratum workaround
* tag 'pci-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (21 commits)
microblaze/PCI: fix "io_offset undeclared" error
x86/PCI: only check for spinlock being held in SMP kernels
resources: add resource_overlaps()
PCI: fix uninitialized variable 'cap_mask'
MAINTAINERS: update PCI git tree and patchwork
PCI: disable Bus Master on PCI device shutdown
PCI: work around IvyBridge internal graphics FLR erratum
x86/PCI: fix unused variable warning in amd_bus.c
PCI: move mutex locking out of pci_dev_reset function
PCI: work around Stratus ftServer broken PCIe hierarchy
x86/PCI: merge pcibios_scan_root() and pci_scan_bus_on_node()
x86/PCI: dynamically allocate pci_root_info for native host bridge drivers
x86/PCI: embed pci_sysdata into pci_root_info on ACPI path
x86/PCI: embed name into pci_root_info struct
x86/PCI: add host bridge resource release for _CRS path
x86/PCI: refactor get_current_resources()
PCI: add host bridge release support
PCI: add generic device into pci_host_bridge struct
PCI: rename pci_host_bridge() to find_pci_root_bridge()
x86/PCI: fix memleak with get_current_resources()
...
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 953ec3f08470..2a7521677541 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3097,16 +3097,74 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) | |||
3097 | return 0; | 3097 | return 0; |
3098 | } | 3098 | } |
3099 | 3099 | ||
3100 | #include "../gpu/drm/i915/i915_reg.h" | ||
3101 | #define MSG_CTL 0x45010 | ||
3102 | #define NSDE_PWR_STATE 0xd0100 | ||
3103 | #define IGD_OPERATION_TIMEOUT 10000 /* set timeout 10 seconds */ | ||
3104 | |||
3105 | static int reset_ivb_igd(struct pci_dev *dev, int probe) | ||
3106 | { | ||
3107 | void __iomem *mmio_base; | ||
3108 | unsigned long timeout; | ||
3109 | u32 val; | ||
3110 | |||
3111 | if (probe) | ||
3112 | return 0; | ||
3113 | |||
3114 | mmio_base = pci_iomap(dev, 0, 0); | ||
3115 | if (!mmio_base) | ||
3116 | return -ENOMEM; | ||
3117 | |||
3118 | iowrite32(0x00000002, mmio_base + MSG_CTL); | ||
3119 | |||
3120 | /* | ||
3121 | * Clobbering SOUTH_CHICKEN2 register is fine only if the next | ||
3122 | * driver loaded sets the right bits. However, this's a reset and | ||
3123 | * the bits have been set by i915 previously, so we clobber | ||
3124 | * SOUTH_CHICKEN2 register directly here. | ||
3125 | */ | ||
3126 | iowrite32(0x00000005, mmio_base + SOUTH_CHICKEN2); | ||
3127 | |||
3128 | val = ioread32(mmio_base + PCH_PP_CONTROL) & 0xfffffffe; | ||
3129 | iowrite32(val, mmio_base + PCH_PP_CONTROL); | ||
3130 | |||
3131 | timeout = jiffies + msecs_to_jiffies(IGD_OPERATION_TIMEOUT); | ||
3132 | do { | ||
3133 | val = ioread32(mmio_base + PCH_PP_STATUS); | ||
3134 | if ((val & 0xb0000000) == 0) | ||
3135 | goto reset_complete; | ||
3136 | msleep(10); | ||
3137 | } while (time_before(jiffies, timeout)); | ||
3138 | dev_warn(&dev->dev, "timeout during reset\n"); | ||
3139 | |||
3140 | reset_complete: | ||
3141 | iowrite32(0x00000002, mmio_base + NSDE_PWR_STATE); | ||
3142 | |||
3143 | pci_iounmap(dev, mmio_base); | ||
3144 | return 0; | ||
3145 | } | ||
3146 | |||
3100 | #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed | 3147 | #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed |
3148 | #define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156 | ||
3149 | #define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166 | ||
3101 | 3150 | ||
3102 | static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { | 3151 | static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { |
3103 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, | 3152 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, |
3104 | reset_intel_82599_sfp_virtfn }, | 3153 | reset_intel_82599_sfp_virtfn }, |
3154 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M_VGA, | ||
3155 | reset_ivb_igd }, | ||
3156 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA, | ||
3157 | reset_ivb_igd }, | ||
3105 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | 3158 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, |
3106 | reset_intel_generic_dev }, | 3159 | reset_intel_generic_dev }, |
3107 | { 0 } | 3160 | { 0 } |
3108 | }; | 3161 | }; |
3109 | 3162 | ||
3163 | /* | ||
3164 | * These device-specific reset methods are here rather than in a driver | ||
3165 | * because when a host assigns a device to a guest VM, the host may need | ||
3166 | * to reset the device but probably doesn't have a driver for it. | ||
3167 | */ | ||
3110 | int pci_dev_specific_reset(struct pci_dev *dev, int probe) | 3168 | int pci_dev_specific_reset(struct pci_dev *dev, int probe) |
3111 | { | 3169 | { |
3112 | const struct pci_dev_reset_methods *i; | 3170 | const struct pci_dev_reset_methods *i; |