1 diff -urNp linux-1391/arch/i386/kernel/dmi_scan.c linux-1420/arch/i386/kernel/dmi_scan.c
2 --- linux-1391/arch/i386/kernel/dmi_scan.c
3 +++ linux-1420/arch/i386/kernel/dmi_scan.c
4 @@ -546,6 +546,22 @@ static __init int print_if_true(struct d
8 + * Dell Inspiron 8000 APM BIOS fails to correctly save and restore the
9 + * config space of some PCI devices.
12 +static __init int broken_apm_pci_restore(struct dmi_blacklist *d)
15 + extern int pci_bridge_force_restore;
17 + printk(KERN_WARNING "%s detected. Forcing restore of PCI configuration space on APM resume.\n", d->ident);
18 + pci_bridge_force_restore = 1;
24 * Process the DMI blacklists
27 @@ -871,6 +887,16 @@ static __initdata struct dmi_blacklist d
28 MATCH(DMI_SYS_VENDOR, "IBM"),
29 NO_MATCH, NO_MATCH, NO_MATCH
31 + { broken_apm_pci_restore, "Dell Inspiron 8000", { /* Work around broken Dell BIOS */
32 + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
33 + MATCH(DMI_PRODUCT_NAME, "Inspiron 8000"),
36 + { broken_apm_pci_restore, "Dell Inspiron 8100", { /* Work around broken Dell BIOS */
37 + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
38 + MATCH(DMI_PRODUCT_NAME, "Inspiron 8100"),
44 diff -urNp linux-1391/drivers/pci/bridge.c linux-1420/drivers/pci/bridge.c
45 --- linux-1391/drivers/pci/bridge.c 1970-01-01 01:00:00.000000000 +0100
46 +++ linux-1420/drivers/pci/bridge.c
50 + * Copyright (c) 2001 Red Hat, Inc. All rights reserved.
52 + * This software may be freely redistributed under the terms
53 + * of the GNU public license.
55 + * You should have received a copy of the GNU General Public License
56 + * along with this program; if not, write to the Free Software
57 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
59 + * Author: Arjan van de Ven <arjanv@redhat.com>
65 + * Generic PCI driver for PCI bridges for powermanagement purposes
69 +#include <linux/config.h>
70 +#include <linux/module.h>
71 +#include <linux/kernel.h>
72 +#include <linux/pci.h>
73 +#include <linux/init.h>
75 +static struct pci_device_id bridge_pci_table[] __devinitdata = {
76 + {/* handle all PCI bridges */
77 + class: ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
81 + subvendor: PCI_ANY_ID,
82 + subdevice: PCI_ANY_ID,
87 +static int bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id);
88 +static int pci_bridge_save_state_bus(struct pci_bus *bus, int force);
89 +int pci_generic_resume_compare(struct pci_dev *pdev);
91 +int pci_bridge_force_restore = 0;
96 +static int __init bridge_setup(char *str)
98 + if (!strcmp(str,"force"))
99 + pci_bridge_force_restore = 1;
100 + else if (!strcmp(str,"noforce"))
101 + pci_bridge_force_restore = 0;
105 +__setup("resume=",bridge_setup);
108 +static int pci_bridge_save_state_bus(struct pci_bus *bus, int force)
110 + struct list_head *list;
113 + list_for_each(list, &bus->children) {
114 + error = pci_bridge_save_state_bus(pci_bus_b(list),force);
115 + if (error) return error;
117 + list_for_each(list, &bus->devices) {
118 + pci_generic_suspend_save(pci_dev_b(list),0);
124 +static int pci_bridge_restore_state_bus(struct pci_bus *bus, int force)
126 + struct list_head *list;
128 + static int printed_warning=0;
130 + list_for_each(list, &bus->children) {
131 + error = pci_bridge_restore_state_bus(pci_bus_b(list),force);
132 + if (error) return error;
134 + list_for_each(list, &bus->devices) {
136 + pci_generic_resume_restore(pci_dev_b(list));
138 + error = pci_generic_resume_compare(pci_dev_b(list));
139 + if (error && !printed_warning++) {
140 + printk(KERN_WARNING "resume warning: bios doesn't restore PCI state properly\n");
141 + printk(KERN_WARNING "resume warning: if resume failed, try booting with resume=force\n");
150 +static int bridge_suspend(struct pci_dev *dev, u32 force)
152 + pci_generic_suspend_save(dev,force);
153 + if (dev->subordinate)
154 + pci_bridge_save_state_bus(dev->subordinate,force);
158 +static int bridge_resume(struct pci_dev *dev)
161 + pci_generic_resume_restore(dev);
162 + if (dev->subordinate)
163 + pci_bridge_restore_state_bus(dev->subordinate,pci_bridge_force_restore);
168 +MODULE_DEVICE_TABLE(pci, bridge_pci_table);
169 +static struct pci_driver bridge_ops = {
170 + name: "PCI Bridge",
171 + id_table: bridge_pci_table,
172 + probe: bridge_probe,
173 + suspend: bridge_suspend,
174 + resume: bridge_resume
177 +static int __devinit bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id)
182 +static int __init bridge_init(void)
184 + pci_register_driver(&bridge_ops);
188 +static void __exit bridge_exit(void)
190 + pci_unregister_driver(&bridge_ops);
194 +module_init(bridge_init)
195 +module_exit(bridge_exit)
197 diff -urNp linux-1391/drivers/pci/Makefile linux-1420/drivers/pci/Makefile
198 --- linux-1391/drivers/pci/Makefile
199 +++ linux-1420/drivers/pci/Makefile
200 @@ -13,7 +13,7 @@ O_TARGET := driver.o
204 -obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o
205 +obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o bridge.o
206 obj-$(CONFIG_PROC_FS) += proc.o
208 ifndef CONFIG_SPARC64
209 diff -urNp linux-1391/drivers/pci/pci.c linux-1420/drivers/pci/pci.c
210 --- linux-1391/drivers/pci/pci.c
211 +++ linux-1420/drivers/pci/pci.c
212 @@ -380,6 +380,48 @@ pci_enable_device_bars(struct pci_dev *d
217 +pci_compare_state(struct pci_dev *dev, u32 *buffer)
223 + for (i = 0; i < 16; i++) {
224 + pci_read_config_dword(dev,i*4,&temp);
225 + if (temp!=buffer[i])
232 +int pci_generic_suspend_save(struct pci_dev *pdev, u32 state)
235 + pci_save_state(pdev,pdev->saved_state);
239 +int pci_generic_resume_restore(struct pci_dev *pdev)
242 + pci_restore_state(pdev,pdev->saved_state);
246 +int pci_generic_resume_compare(struct pci_dev *pdev)
250 + retval = pci_compare_state(pdev,pdev->saved_state);
254 +EXPORT_SYMBOL_GPL(pci_generic_suspend_save);
255 +EXPORT_SYMBOL_GPL(pci_generic_resume_restore);
256 +EXPORT_SYMBOL_GPL(pci_generic_resume_compare);
259 * pci_enable_device - Initialize device before it's used by a driver.
260 * @dev: PCI device to be initialized
261 diff -urNp linux-1391/include/linux/pci.h linux-1420/include/linux/pci.h
262 --- linux-1391/include/linux/pci.h
263 +++ linux-1420/include/linux/pci.h
264 @@ -410,6 +410,7 @@ struct pci_dev {
266 char name[90]; /* device name */
267 char slot_name[8]; /* slot name */
268 + u32 saved_state[16]; /* for saving the config space before suspend */
269 int active; /* ISAPnP: device is active */
270 int ro; /* ISAPnP: read only */
271 unsigned short regs; /* ISAPnP: supported registers */
272 @@ -612,6 +613,8 @@ int pci_save_state(struct pci_dev *dev,
273 int pci_restore_state(struct pci_dev *dev, u32 *buffer);
274 int pci_set_power_state(struct pci_dev *dev, int state);
275 int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
276 +int pci_generic_suspend_save(struct pci_dev *pdev, u32 state);
277 +int pci_generic_resume_restore(struct pci_dev *pdev);
279 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
281 @@ -707,6 +710,7 @@ static inline int pci_restore_state(stru
282 static inline int pci_set_power_state(struct pci_dev *dev, int state) { return 0; }
283 static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) { return 0; }
286 #define pci_for_each_dev(dev) \