diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-07-09 22:56:54 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-07-09 22:56:54 -0400 |
commit | 9349b44a459677e270ae19a373c58e5c3edbff04 (patch) | |
tree | 630d4e337691b959b663b79060360fb725a8396a /drivers/pci/quirks.c | |
parent | a7711ba1090a5fa1caa6e07182ac4e8e1c0da695 (diff) | |
parent | 735bff10c157fdbba2291e10ca3e28a59c7acc1c (diff) |
Merge branch 'pci/myron-final-fixups-v2' into next
* pci/myron-final-fixups-v2:
PCI: call final fixups hot-added devices
PCI: move final fixups from __init to __devinit
x86/PCI: move final fixups from __init to __devinit
MIPS/PCI: move final fixups from __init to __devinit
PCI: never discard enable/suspend/resume_early/resume fixups
PCI: release temporary reference in __nv_msi_ht_cap_quirk()
PCI: restructure 'pci_do_fixups()'
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 99 |
1 files changed, 67 insertions, 32 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a2d9d330a01e..17741d3cabca 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1039,7 +1039,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev) | |||
1039 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); | 1039 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); |
1040 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); | 1040 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); |
1041 | 1041 | ||
1042 | static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) | 1042 | static void quirk_amd_ide_mode(struct pci_dev *pdev) |
1043 | { | 1043 | { |
1044 | /* set SBX00/Hudson-2 SATA in IDE mode to AHCI mode */ | 1044 | /* set SBX00/Hudson-2 SATA in IDE mode to AHCI mode */ |
1045 | u8 tmp; | 1045 | u8 tmp; |
@@ -2104,7 +2104,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | |||
2104 | PCI_DEVICE_ID_NX2_5709S, | 2104 | PCI_DEVICE_ID_NX2_5709S, |
2105 | quirk_brcm_570x_limit_vpd); | 2105 | quirk_brcm_570x_limit_vpd); |
2106 | 2106 | ||
2107 | static void __devinit quirk_brcm_5719_limit_mrrs(struct pci_dev *dev) | 2107 | static void quirk_brcm_5719_limit_mrrs(struct pci_dev *dev) |
2108 | { | 2108 | { |
2109 | u32 rev; | 2109 | u32 rev; |
2110 | 2110 | ||
@@ -2217,7 +2217,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi); | |||
2217 | 2217 | ||
2218 | /* Go through the list of Hypertransport capabilities and | 2218 | /* Go through the list of Hypertransport capabilities and |
2219 | * return 1 if a HT MSI capability is found and enabled */ | 2219 | * return 1 if a HT MSI capability is found and enabled */ |
2220 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | 2220 | static int msi_ht_cap_enabled(struct pci_dev *dev) |
2221 | { | 2221 | { |
2222 | int pos, ttl = 48; | 2222 | int pos, ttl = 48; |
2223 | 2223 | ||
@@ -2241,7 +2241,7 @@ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | |||
2241 | } | 2241 | } |
2242 | 2242 | ||
2243 | /* Check the hypertransport MSI mapping to know whether MSI is enabled or not */ | 2243 | /* Check the hypertransport MSI mapping to know whether MSI is enabled or not */ |
2244 | static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) | 2244 | static void quirk_msi_ht_cap(struct pci_dev *dev) |
2245 | { | 2245 | { |
2246 | if (dev->subordinate && !msi_ht_cap_enabled(dev)) { | 2246 | if (dev->subordinate && !msi_ht_cap_enabled(dev)) { |
2247 | dev_warn(&dev->dev, "MSI quirk detected; " | 2247 | dev_warn(&dev->dev, "MSI quirk detected; " |
@@ -2255,7 +2255,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2 | |||
2255 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. | 2255 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. |
2256 | * MSI are supported if the MSI capability set in any of these mappings. | 2256 | * MSI are supported if the MSI capability set in any of these mappings. |
2257 | */ | 2257 | */ |
2258 | static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | 2258 | static void quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) |
2259 | { | 2259 | { |
2260 | struct pci_dev *pdev; | 2260 | struct pci_dev *pdev; |
2261 | 2261 | ||
@@ -2279,7 +2279,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | |||
2279 | quirk_nvidia_ck804_msi_ht_cap); | 2279 | quirk_nvidia_ck804_msi_ht_cap); |
2280 | 2280 | ||
2281 | /* Force enable MSI mapping capability on HT bridges */ | 2281 | /* Force enable MSI mapping capability on HT bridges */ |
2282 | static void __devinit ht_enable_msi_mapping(struct pci_dev *dev) | 2282 | static void ht_enable_msi_mapping(struct pci_dev *dev) |
2283 | { | 2283 | { |
2284 | int pos, ttl = 48; | 2284 | int pos, ttl = 48; |
2285 | 2285 | ||
@@ -2359,7 +2359,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, | |||
2359 | PCI_DEVICE_ID_NVIDIA_MCP55_BRIDGE_V4, | 2359 | PCI_DEVICE_ID_NVIDIA_MCP55_BRIDGE_V4, |
2360 | nvbridge_check_legacy_irq_routing); | 2360 | nvbridge_check_legacy_irq_routing); |
2361 | 2361 | ||
2362 | static int __devinit ht_check_msi_mapping(struct pci_dev *dev) | 2362 | static int ht_check_msi_mapping(struct pci_dev *dev) |
2363 | { | 2363 | { |
2364 | int pos, ttl = 48; | 2364 | int pos, ttl = 48; |
2365 | int found = 0; | 2365 | int found = 0; |
@@ -2387,7 +2387,7 @@ static int __devinit ht_check_msi_mapping(struct pci_dev *dev) | |||
2387 | return found; | 2387 | return found; |
2388 | } | 2388 | } |
2389 | 2389 | ||
2390 | static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge) | 2390 | static int host_bridge_with_leaf(struct pci_dev *host_bridge) |
2391 | { | 2391 | { |
2392 | struct pci_dev *dev; | 2392 | struct pci_dev *dev; |
2393 | int pos; | 2393 | int pos; |
@@ -2421,7 +2421,7 @@ static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge) | |||
2421 | #define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */ | 2421 | #define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */ |
2422 | #define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */ | 2422 | #define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */ |
2423 | 2423 | ||
2424 | static int __devinit is_end_of_ht_chain(struct pci_dev *dev) | 2424 | static int is_end_of_ht_chain(struct pci_dev *dev) |
2425 | { | 2425 | { |
2426 | int pos, ctrl_off; | 2426 | int pos, ctrl_off; |
2427 | int end = 0; | 2427 | int end = 0; |
@@ -2445,7 +2445,7 @@ out: | |||
2445 | return end; | 2445 | return end; |
2446 | } | 2446 | } |
2447 | 2447 | ||
2448 | static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) | 2448 | static void nv_ht_enable_msi_mapping(struct pci_dev *dev) |
2449 | { | 2449 | { |
2450 | struct pci_dev *host_bridge; | 2450 | struct pci_dev *host_bridge; |
2451 | int pos; | 2451 | int pos; |
@@ -2484,7 +2484,7 @@ out: | |||
2484 | pci_dev_put(host_bridge); | 2484 | pci_dev_put(host_bridge); |
2485 | } | 2485 | } |
2486 | 2486 | ||
2487 | static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) | 2487 | static void ht_disable_msi_mapping(struct pci_dev *dev) |
2488 | { | 2488 | { |
2489 | int pos, ttl = 48; | 2489 | int pos, ttl = 48; |
2490 | 2490 | ||
@@ -2504,7 +2504,7 @@ static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) | |||
2504 | } | 2504 | } |
2505 | } | 2505 | } |
2506 | 2506 | ||
2507 | static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) | 2507 | static void __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) |
2508 | { | 2508 | { |
2509 | struct pci_dev *host_bridge; | 2509 | struct pci_dev *host_bridge; |
2510 | int pos; | 2510 | int pos; |
@@ -2541,23 +2541,26 @@ static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) | |||
2541 | else | 2541 | else |
2542 | nv_ht_enable_msi_mapping(dev); | 2542 | nv_ht_enable_msi_mapping(dev); |
2543 | } | 2543 | } |
2544 | return; | 2544 | goto out; |
2545 | } | 2545 | } |
2546 | 2546 | ||
2547 | /* HT MSI is not enabled */ | 2547 | /* HT MSI is not enabled */ |
2548 | if (found == 1) | 2548 | if (found == 1) |
2549 | return; | 2549 | goto out; |
2550 | 2550 | ||
2551 | /* Host bridge is not to HT, disable HT MSI mapping on this device */ | 2551 | /* Host bridge is not to HT, disable HT MSI mapping on this device */ |
2552 | ht_disable_msi_mapping(dev); | 2552 | ht_disable_msi_mapping(dev); |
2553 | |||
2554 | out: | ||
2555 | pci_dev_put(host_bridge); | ||
2553 | } | 2556 | } |
2554 | 2557 | ||
2555 | static void __devinit nv_msi_ht_cap_quirk_all(struct pci_dev *dev) | 2558 | static void nv_msi_ht_cap_quirk_all(struct pci_dev *dev) |
2556 | { | 2559 | { |
2557 | return __nv_msi_ht_cap_quirk(dev, 1); | 2560 | return __nv_msi_ht_cap_quirk(dev, 1); |
2558 | } | 2561 | } |
2559 | 2562 | ||
2560 | static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev) | 2563 | static void nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev) |
2561 | { | 2564 | { |
2562 | return __nv_msi_ht_cap_quirk(dev, 0); | 2565 | return __nv_msi_ht_cap_quirk(dev, 0); |
2563 | } | 2566 | } |
@@ -2879,20 +2882,34 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); | |||
2879 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); | 2882 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); |
2880 | 2883 | ||
2881 | 2884 | ||
2882 | static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *dev) | 2885 | static ktime_t fixup_debug_start(struct pci_dev *dev, |
2886 | void (*fn)(struct pci_dev *dev)) | ||
2883 | { | 2887 | { |
2884 | ktime_t calltime, delta, rettime; | 2888 | ktime_t calltime = ktime_set(0, 0); |
2889 | |||
2890 | dev_dbg(&dev->dev, "calling %pF\n", fn); | ||
2891 | if (initcall_debug) { | ||
2892 | pr_debug("calling %pF @ %i for %s\n", | ||
2893 | fn, task_pid_nr(current), dev_name(&dev->dev)); | ||
2894 | calltime = ktime_get(); | ||
2895 | } | ||
2896 | |||
2897 | return calltime; | ||
2898 | } | ||
2899 | |||
2900 | static void fixup_debug_report(struct pci_dev *dev, ktime_t calltime, | ||
2901 | void (*fn)(struct pci_dev *dev)) | ||
2902 | { | ||
2903 | ktime_t delta, rettime; | ||
2885 | unsigned long long duration; | 2904 | unsigned long long duration; |
2886 | 2905 | ||
2887 | printk(KERN_DEBUG "calling %pF @ %i for %s\n", | 2906 | if (initcall_debug) { |
2888 | fn, task_pid_nr(current), dev_name(&dev->dev)); | 2907 | rettime = ktime_get(); |
2889 | calltime = ktime_get(); | 2908 | delta = ktime_sub(rettime, calltime); |
2890 | fn(dev); | 2909 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
2891 | rettime = ktime_get(); | 2910 | pr_debug("pci fixup %pF returned after %lld usecs for %s\n", |
2892 | delta = ktime_sub(rettime, calltime); | 2911 | fn, duration, dev_name(&dev->dev)); |
2893 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | 2912 | } |
2894 | printk(KERN_DEBUG "pci fixup %pF returned after %lld usecs for %s\n", | ||
2895 | fn, duration, dev_name(&dev->dev)); | ||
2896 | } | 2913 | } |
2897 | 2914 | ||
2898 | /* | 2915 | /* |
@@ -2946,6 +2963,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */ | |||
2946 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2963 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2947 | struct pci_fixup *end) | 2964 | struct pci_fixup *end) |
2948 | { | 2965 | { |
2966 | ktime_t calltime; | ||
2967 | |||
2949 | for (; f < end; f++) | 2968 | for (; f < end; f++) |
2950 | if ((f->class == (u32) (dev->class >> f->class_shift) || | 2969 | if ((f->class == (u32) (dev->class >> f->class_shift) || |
2951 | f->class == (u32) PCI_ANY_ID) && | 2970 | f->class == (u32) PCI_ANY_ID) && |
@@ -2953,11 +2972,9 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | |||
2953 | f->vendor == (u16) PCI_ANY_ID) && | 2972 | f->vendor == (u16) PCI_ANY_ID) && |
2954 | (f->device == dev->device || | 2973 | (f->device == dev->device || |
2955 | f->device == (u16) PCI_ANY_ID)) { | 2974 | f->device == (u16) PCI_ANY_ID)) { |
2956 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); | 2975 | calltime = fixup_debug_start(dev, f->hook); |
2957 | if (initcall_debug) | 2976 | f->hook(dev); |
2958 | do_one_fixup_debug(f->hook, dev); | 2977 | fixup_debug_report(dev, calltime, f->hook); |
2959 | else | ||
2960 | f->hook(dev); | ||
2961 | } | 2978 | } |
2962 | } | 2979 | } |
2963 | 2980 | ||
@@ -3025,6 +3042,22 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
3025 | } | 3042 | } |
3026 | EXPORT_SYMBOL(pci_fixup_device); | 3043 | EXPORT_SYMBOL(pci_fixup_device); |
3027 | 3044 | ||
3045 | |||
3046 | /* | ||
3047 | * The global variable 'pci_fixup_final_inited' is being used as a interim | ||
3048 | * solution for calling the final quirks only during hot-plug events (not | ||
3049 | * during boot processing). | ||
3050 | * | ||
3051 | * When the boot path's PCI device setup sequencing is addressed, we can | ||
3052 | * remove the instance, and usages of, 'pci_fixup_final_inited' along with | ||
3053 | * removing 'fs_initcall_sync(pci_apply_final_quirks);' and end up with a | ||
3054 | * single, uniform, solution that satisfies both the boot path and the | ||
3055 | * various hot-plug event paths. | ||
3056 | * | ||
3057 | * ToDo: Remove 'pci_fixup_final_inited' | ||
3058 | */ | ||
3059 | bool pci_fixup_final_inited; | ||
3060 | |||
3028 | static int __init pci_apply_final_quirks(void) | 3061 | static int __init pci_apply_final_quirks(void) |
3029 | { | 3062 | { |
3030 | struct pci_dev *dev = NULL; | 3063 | struct pci_dev *dev = NULL; |
@@ -3055,6 +3088,8 @@ static int __init pci_apply_final_quirks(void) | |||
3055 | pci_cache_line_size = pci_dfl_cache_line_size; | 3088 | pci_cache_line_size = pci_dfl_cache_line_size; |
3056 | } | 3089 | } |
3057 | } | 3090 | } |
3091 | pci_fixup_final_inited = 1; | ||
3092 | |||
3058 | if (!pci_cache_line_size) { | 3093 | if (!pci_cache_line_size) { |
3059 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | 3094 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", |
3060 | cls << 2, pci_dfl_cache_line_size << 2); | 3095 | cls << 2, pci_dfl_cache_line_size << 2); |