diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2008-05-15 15:51:31 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-06-10 13:59:46 -0400 |
commit | e1a2a51e684bfe9d6165992d4a065439617a3107 (patch) | |
tree | 4d05a1b9ebadd0ab22e0e42ee3b053dddf11baf1 | |
parent | 273c11270d3715c4c06d4df1607a1a60034d887b (diff) |
Suspend/Resume bug in PCI layer wrt quirks
Some quirks should be called with interrupt disabled, we can't directly
call them in .resume_early. Also the patch introduces
pci_fixup_resume_early and pci_fixup_suspend, which matches current
device core callbacks (.suspend/.resume_early).
TBD: Somebody knows why we need quirk resume should double check if a
quirk should be called in resume or resume_early. I changed some per my
understanding, but can't make sure I fixed all.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | drivers/pci/pci-driver.c | 6 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 118 | ||||
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 6 | ||||
-rw-r--r-- | include/linux/pci.h | 10 |
4 files changed, 101 insertions, 39 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 72cf61ed8f96..677fd9d6db12 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -292,6 +292,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) | |||
292 | if (pci_dev->current_state == PCI_D0) | 292 | if (pci_dev->current_state == PCI_D0) |
293 | pci_dev->current_state = PCI_UNKNOWN; | 293 | pci_dev->current_state = PCI_UNKNOWN; |
294 | } | 294 | } |
295 | |||
296 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
297 | |||
295 | return i; | 298 | return i; |
296 | } | 299 | } |
297 | 300 | ||
@@ -337,6 +340,7 @@ static int pci_device_resume(struct device * dev) | |||
337 | error = drv->resume(pci_dev); | 340 | error = drv->resume(pci_dev); |
338 | else | 341 | else |
339 | error = pci_default_resume(pci_dev); | 342 | error = pci_default_resume(pci_dev); |
343 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
340 | return error; | 344 | return error; |
341 | } | 345 | } |
342 | 346 | ||
@@ -346,7 +350,7 @@ static int pci_device_resume_early(struct device * dev) | |||
346 | struct pci_dev * pci_dev = to_pci_dev(dev); | 350 | struct pci_dev * pci_dev = to_pci_dev(dev); |
347 | struct pci_driver * drv = pci_dev->driver; | 351 | struct pci_driver * drv = pci_dev->driver; |
348 | 352 | ||
349 | pci_fixup_device(pci_fixup_resume, pci_dev); | 353 | pci_fixup_device(pci_fixup_resume_early, pci_dev); |
350 | 354 | ||
351 | if (drv && drv->resume_early) | 355 | if (drv && drv->resume_early) |
352 | error = drv->resume_early(pci_dev); | 356 | error = drv->resume_early(pci_dev); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index dabb563f51d9..44aabb1519a9 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -556,7 +556,7 @@ static void quirk_via_ioapic(struct pci_dev *dev) | |||
556 | pci_write_config_byte (dev, 0x58, tmp); | 556 | pci_write_config_byte (dev, 0x58, tmp); |
557 | } | 557 | } |
558 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic); | 558 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic); |
559 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic); | 559 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic); |
560 | 560 | ||
561 | /* | 561 | /* |
562 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. | 562 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. |
@@ -576,7 +576,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) | |||
576 | } | 576 | } |
577 | } | 577 | } |
578 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); | 578 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); |
579 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); | 579 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); |
580 | 580 | ||
581 | /* | 581 | /* |
582 | * The AMD io apic can hang the box when an apic irq is masked. | 582 | * The AMD io apic can hang the box when an apic irq is masked. |
@@ -622,7 +622,7 @@ static void quirk_amd_8131_ioapic(struct pci_dev *dev) | |||
622 | } | 622 | } |
623 | } | 623 | } |
624 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | 624 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); |
625 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | 625 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); |
626 | #endif /* CONFIG_X86_IO_APIC */ | 626 | #endif /* CONFIG_X86_IO_APIC */ |
627 | 627 | ||
628 | /* | 628 | /* |
@@ -774,7 +774,7 @@ static void quirk_cardbus_legacy(struct pci_dev *dev) | |||
774 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); | 774 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); |
775 | } | 775 | } |
776 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 776 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); |
777 | DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 777 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); |
778 | 778 | ||
779 | /* | 779 | /* |
780 | * Following the PCI ordering rules is optional on the AMD762. I'm not | 780 | * Following the PCI ordering rules is optional on the AMD762. I'm not |
@@ -797,7 +797,7 @@ static void quirk_amd_ordering(struct pci_dev *dev) | |||
797 | } | 797 | } |
798 | } | 798 | } |
799 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering); | 799 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering); |
800 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering); | 800 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering); |
801 | 801 | ||
802 | /* | 802 | /* |
803 | * DreamWorks provided workaround for Dunord I-3000 problem | 803 | * DreamWorks provided workaround for Dunord I-3000 problem |
@@ -865,7 +865,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev) | |||
865 | } | 865 | } |
866 | } | 866 | } |
867 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); | 867 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); |
868 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); | 868 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); |
869 | 869 | ||
870 | static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) | 870 | static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) |
871 | { | 871 | { |
@@ -885,9 +885,9 @@ static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) | |||
885 | } | 885 | } |
886 | } | 886 | } |
887 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); | 887 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); |
888 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); | 888 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); |
889 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); | 889 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); |
890 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); | 890 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); |
891 | 891 | ||
892 | /* | 892 | /* |
893 | * Serverworks CSB5 IDE does not fully support native mode | 893 | * Serverworks CSB5 IDE does not fully support native mode |
@@ -1093,31 +1093,61 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu | |||
1093 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc); | 1093 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc); |
1094 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc); | 1094 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc); |
1095 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc); | 1095 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc); |
1096 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc); | 1096 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc); |
1097 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc); | 1097 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc); |
1098 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc); | 1098 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc); |
1099 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc); | 1099 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc); |
1100 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc); | 1100 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc); |
1101 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc); | 1101 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc); |
1102 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc); | 1102 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc); |
1103 | 1103 | ||
1104 | static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | 1104 | /* It appears we just have one such device. If not, we have a warning */ |
1105 | static void __iomem *asus_rcba_base; | ||
1106 | static void asus_hides_smbus_lpc_ich6_suspend(struct pci_dev *dev) | ||
1105 | { | 1107 | { |
1106 | u32 val, rcba; | 1108 | u32 rcba; |
1107 | void __iomem *base; | ||
1108 | 1109 | ||
1109 | if (likely(!asus_hides_smbus)) | 1110 | if (likely(!asus_hides_smbus)) |
1110 | return; | 1111 | return; |
1112 | WARN_ON(asus_rcba_base); | ||
1113 | |||
1111 | pci_read_config_dword(dev, 0xF0, &rcba); | 1114 | pci_read_config_dword(dev, 0xF0, &rcba); |
1112 | base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */ | 1115 | /* use bits 31:14, 16 kB aligned */ |
1113 | if (base == NULL) return; | 1116 | asus_rcba_base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); |
1114 | val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */ | 1117 | if (asus_rcba_base == NULL) |
1115 | writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */ | 1118 | return; |
1116 | iounmap(base); | 1119 | } |
1120 | |||
1121 | static void asus_hides_smbus_lpc_ich6_resume_early(struct pci_dev *dev) | ||
1122 | { | ||
1123 | u32 val; | ||
1124 | |||
1125 | if (likely(!asus_hides_smbus || !asus_rcba_base)) | ||
1126 | return; | ||
1127 | /* read the Function Disable register, dword mode only */ | ||
1128 | val = readl(asus_rcba_base + 0x3418); | ||
1129 | writel(val & 0xFFFFFFF7, asus_rcba_base + 0x3418); /* enable the SMBus device */ | ||
1130 | } | ||
1131 | |||
1132 | static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev) | ||
1133 | { | ||
1134 | if (likely(!asus_hides_smbus || !asus_rcba_base)) | ||
1135 | return; | ||
1136 | iounmap(asus_rcba_base); | ||
1137 | asus_rcba_base = NULL; | ||
1117 | dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n"); | 1138 | dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n"); |
1118 | } | 1139 | } |
1140 | |||
1141 | static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | ||
1142 | { | ||
1143 | asus_hides_smbus_lpc_ich6_suspend(dev); | ||
1144 | asus_hides_smbus_lpc_ich6_resume_early(dev); | ||
1145 | asus_hides_smbus_lpc_ich6_resume(dev); | ||
1146 | } | ||
1119 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6); | 1147 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6); |
1120 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6); | 1148 | DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_suspend); |
1149 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume); | ||
1150 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6_resume_early); | ||
1121 | 1151 | ||
1122 | /* | 1152 | /* |
1123 | * SiS 96x south bridge: BIOS typically hides SMBus device... | 1153 | * SiS 96x south bridge: BIOS typically hides SMBus device... |
@@ -1135,10 +1165,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_ | |||
1135 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus); | 1165 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus); |
1136 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus); | 1166 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus); |
1137 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus); | 1167 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus); |
1138 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus); | 1168 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus); |
1139 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus); | 1169 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus); |
1140 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus); | 1170 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus); |
1141 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus); | 1171 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus); |
1142 | 1172 | ||
1143 | /* | 1173 | /* |
1144 | * ... This is further complicated by the fact that some SiS96x south | 1174 | * ... This is further complicated by the fact that some SiS96x south |
@@ -1172,7 +1202,7 @@ static void quirk_sis_503(struct pci_dev *dev) | |||
1172 | quirk_sis_96x_smbus(dev); | 1202 | quirk_sis_96x_smbus(dev); |
1173 | } | 1203 | } |
1174 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503); | 1204 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503); |
1175 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503); | 1205 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503); |
1176 | 1206 | ||
1177 | 1207 | ||
1178 | /* | 1208 | /* |
@@ -1205,7 +1235,7 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev) | |||
1205 | } | 1235 | } |
1206 | } | 1236 | } |
1207 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc); | 1237 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc); |
1208 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc); | 1238 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc); |
1209 | 1239 | ||
1210 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) | 1240 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) |
1211 | 1241 | ||
@@ -1270,12 +1300,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, qui | |||
1270 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | 1300 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); |
1271 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | 1301 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); |
1272 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | 1302 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); |
1273 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | 1303 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); |
1274 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | 1304 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); |
1275 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | 1305 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); |
1276 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | 1306 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); |
1277 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | 1307 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); |
1278 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | 1308 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); |
1279 | 1309 | ||
1280 | #endif | 1310 | #endif |
1281 | 1311 | ||
@@ -1521,6 +1551,10 @@ extern struct pci_fixup __start_pci_fixups_enable[]; | |||
1521 | extern struct pci_fixup __end_pci_fixups_enable[]; | 1551 | extern struct pci_fixup __end_pci_fixups_enable[]; |
1522 | extern struct pci_fixup __start_pci_fixups_resume[]; | 1552 | extern struct pci_fixup __start_pci_fixups_resume[]; |
1523 | extern struct pci_fixup __end_pci_fixups_resume[]; | 1553 | extern struct pci_fixup __end_pci_fixups_resume[]; |
1554 | extern struct pci_fixup __start_pci_fixups_resume_early[]; | ||
1555 | extern struct pci_fixup __end_pci_fixups_resume_early[]; | ||
1556 | extern struct pci_fixup __start_pci_fixups_suspend[]; | ||
1557 | extern struct pci_fixup __end_pci_fixups_suspend[]; | ||
1524 | 1558 | ||
1525 | 1559 | ||
1526 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | 1560 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) |
@@ -1553,6 +1587,16 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
1553 | end = __end_pci_fixups_resume; | 1587 | end = __end_pci_fixups_resume; |
1554 | break; | 1588 | break; |
1555 | 1589 | ||
1590 | case pci_fixup_resume_early: | ||
1591 | start = __start_pci_fixups_resume_early; | ||
1592 | end = __end_pci_fixups_resume_early; | ||
1593 | break; | ||
1594 | |||
1595 | case pci_fixup_suspend: | ||
1596 | start = __start_pci_fixups_suspend; | ||
1597 | end = __end_pci_fixups_suspend; | ||
1598 | break; | ||
1599 | |||
1556 | default: | 1600 | default: |
1557 | /* stupid compiler warning, you would think with an enum... */ | 1601 | /* stupid compiler warning, you would think with an enum... */ |
1558 | return; | 1602 | return; |
@@ -1629,7 +1673,7 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) | |||
1629 | } | 1673 | } |
1630 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1674 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1631 | quirk_nvidia_ck804_pcie_aer_ext_cap); | 1675 | quirk_nvidia_ck804_pcie_aer_ext_cap); |
1632 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1676 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1633 | quirk_nvidia_ck804_pcie_aer_ext_cap); | 1677 | quirk_nvidia_ck804_pcie_aer_ext_cap); |
1634 | 1678 | ||
1635 | static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | 1679 | static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f054778e916c..cf108a3c7f59 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -84,6 +84,12 @@ | |||
84 | VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \ | 84 | VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \ |
85 | *(.pci_fixup_resume) \ | 85 | *(.pci_fixup_resume) \ |
86 | VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \ | 86 | VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \ |
87 | VMLINUX_SYMBOL(__start_pci_fixups_resume_early) = .; \ | ||
88 | *(.pci_fixup_resume_early) \ | ||
89 | VMLINUX_SYMBOL(__end_pci_fixups_resume_early) = .; \ | ||
90 | VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .; \ | ||
91 | *(.pci_fixup_suspend) \ | ||
92 | VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .; \ | ||
87 | } \ | 93 | } \ |
88 | \ | 94 | \ |
89 | /* RapidIO route ops */ \ | 95 | /* RapidIO route ops */ \ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index aaa9f333fb44..700704ef70f3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1013,7 +1013,9 @@ enum pci_fixup_pass { | |||
1013 | pci_fixup_header, /* After reading configuration header */ | 1013 | pci_fixup_header, /* After reading configuration header */ |
1014 | pci_fixup_final, /* Final phase of device fixups */ | 1014 | pci_fixup_final, /* Final phase of device fixups */ |
1015 | pci_fixup_enable, /* pci_enable_device() time */ | 1015 | pci_fixup_enable, /* pci_enable_device() time */ |
1016 | pci_fixup_resume, /* pci_enable_device() time */ | 1016 | pci_fixup_resume, /* pci_device_resume() */ |
1017 | pci_fixup_suspend, /* pci_device_suspend */ | ||
1018 | pci_fixup_resume_early, /* pci_device_resume_early() */ | ||
1017 | }; | 1019 | }; |
1018 | 1020 | ||
1019 | /* Anonymous variables would be nice... */ | 1021 | /* Anonymous variables would be nice... */ |
@@ -1035,6 +1037,12 @@ enum pci_fixup_pass { | |||
1035 | #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ | 1037 | #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ |
1036 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ | 1038 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ |
1037 | resume##vendor##device##hook, vendor, device, hook) | 1039 | resume##vendor##device##hook, vendor, device, hook) |
1040 | #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \ | ||
1041 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ | ||
1042 | resume_early##vendor##device##hook, vendor, device, hook) | ||
1043 | #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \ | ||
1044 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ | ||
1045 | suspend##vendor##device##hook, vendor, device, hook) | ||
1038 | 1046 | ||
1039 | 1047 | ||
1040 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); | 1048 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); |