linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* apm dell I8K 2.4.18
@ 2002-05-05 12:53 Ken Van Eyndonck
  2002-05-05 13:29 ` arjan
  0 siblings, 1 reply; 2+ messages in thread
From: Ken Van Eyndonck @ 2002-05-05 12:53 UTC (permalink / raw)
  To: linux-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

hi

i'm fairly new to linux but i'm eager to learn.
i'm running suse 7.3 on a dell inspiron 8000.
i used to run suse 7.1 (2.2.??) and the apm worked "fine" as far as i could 
tell
now i cant suspend or un/plug the ac power while linux is running.
i've made several attemps by compiling new kernels. But nothing worked.
i've looked in the archive of this list and found several mails that handeld 
or discribed several problems i had but appearently didn't offer a straight 
up way the get rid of the problem.

plz
help
-----BEGIN PGP SIGNATURE-----
Version: PGP 6.5.8

iQA/AwUBPNUrPHbvQ8h/YgNnEQJDvACgixvyTcqwcwp/aB05EGkgciIeLHUAoJKo
ehsUEvmQKP4hK03YpbSH0lIi
=3XIj
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: apm dell I8K 2.4.18
  2002-05-05 12:53 apm dell I8K 2.4.18 Ken Van Eyndonck
@ 2002-05-05 13:29 ` arjan
  0 siblings, 0 replies; 2+ messages in thread
From: arjan @ 2002-05-05 13:29 UTC (permalink / raw)
  To: Ken Van Eyndonck; +Cc: linux-kernel

In article <20020505125344.01C4E36BA0@yoda.planetinternet.be> you wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> hi
> 
> i'm fairly new to linux but i'm eager to learn.
> i'm running suse 7.3 on a dell inspiron 8000.
> i used to run suse 7.1 (2.2.??) and the apm worked "fine" as far as i could 
> tell
> now i cant suspend or un/plug the ac power while linux is running.

for Dell i 8000 laptops 2 things are important:
1) Compile the kernel without IO APIC support
2) Apply the patch below 

with that it works at least for the guy next to me at work ;)



diff -urN Linux/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
--- Linux/arch/i386/kernel/dmi_scan.c	Thu Apr 11 11:14:41 2002
+++ linux/arch/i386/kernel/dmi_scan.c	Thu Apr 11 11:15:28 2002
@@ -499,6 +499,22 @@
 }
 
 /*
+ * Dell Inspiron 8000 APM BIOS fails to correctly save and restore the
+ * config space of some PCI devices.
+ */
+
+static __init int broken_apm_pci_restore(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_PCI
+	extern int pci_bridge_force_restore;
+
+	printk(KERN_WARNING "%s detected. Forcing restore of PCI configuration space on APM resume.\n", d->ident);
+	pci_bridge_force_restore = 1;
+#endif
+	return 0;
+}
+
+/*
  *	Process the DMI blacklists
  */
  
@@ -779,6 +795,16 @@
 			MATCH(DMI_SYS_VENDOR, "IBM"),
 			NO_MATCH, NO_MATCH, NO_MATCH
 			} },
+	{ broken_apm_pci_restore, "Dell Inspiron 8000", {	/* Work around broken Dell BIOS */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 8000"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ broken_apm_pci_restore, "Dell Inspiron 8100", {	/* Work around broken Dell BIOS */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 8100"),
+			NO_MATCH, NO_MATCH
+			} },
 
 	{ NULL, }
 };
diff -urN Linux/drivers/pci/Makefile linux/drivers/pci/Makefile
--- Linux/drivers/pci/Makefile	Thu Apr 11 11:14:25 2002
+++ linux/drivers/pci/Makefile	Thu Apr 11 11:15:28 2002
@@ -13,7 +13,7 @@
 
 export-objs := pci.o
 
-obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o
+obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o bridge.o 
 obj-$(CONFIG_PROC_FS) += proc.o
 
 ifndef CONFIG_SPARC64
diff -urN Linux/drivers/pci/bridge.c linux/drivers/pci/bridge.c
--- Linux/drivers/pci/bridge.c	Thu Jan  1 01:00:00 1970
+++ linux/drivers/pci/bridge.c	Thu Apr 11 11:15:28 2002
@@ -0,0 +1,149 @@
+
+/*
+ *	Copyright (c) 2001 Red Hat, Inc. All rights reserved.
+ *
+ *	This software may be freely redistributed under the terms
+ * 	of the GNU public license.
+ * 
+ *	You should have received a copy of the GNU General Public License
+ *	along with this program; if not, write to the Free Software
+ *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 	Author: Arjan van de Ven <arjanv@redhat.com>
+ *
+ */
+
+
+/*
+ * Generic PCI driver for PCI bridges for powermanagement purposes
+ *
+ */
+
+#include <linux/config.h> 
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+static struct pci_device_id bridge_pci_table[] __devinitdata = {
+        {/* handle all PCI bridges */
+	class:          ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
+	class_mask:     ~0,
+	vendor:         PCI_ANY_ID,
+	device:         PCI_ANY_ID,
+	subvendor:      PCI_ANY_ID,
+	subdevice:      PCI_ANY_ID,
+	},
+        {0,},
+};
+
+static int bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id);
+static int pci_bridge_save_state_bus(struct pci_bus *bus, int force);
+int pci_generic_resume_compare(struct pci_dev *pdev);
+
+int pci_bridge_force_restore = 0;
+
+
+
+
+static int __init bridge_setup(char *str)
+{
+	if (!strcmp(str,"force"))
+		pci_bridge_force_restore = 1;
+	else if (!strcmp(str,"noforce"))
+		pci_bridge_force_restore = 0;
+	return 0;
+}
+
+__setup("resume=",bridge_setup);
+
+
+static int pci_bridge_save_state_bus(struct pci_bus *bus, int force)
+{
+	struct list_head *list;
+	int error = 0;
+
+	list_for_each(list, &bus->children) {
+		error = pci_bridge_save_state_bus(pci_bus_b(list),force);
+		if (error) return error;
+	}
+	list_for_each(list, &bus->devices) {
+		pci_generic_suspend_save(pci_dev_b(list),0);
+	}
+	return 0;
+}
+
+
+static int pci_bridge_restore_state_bus(struct pci_bus *bus, int force)
+{
+	struct list_head *list;
+	int error = 0;
+	static int printed_warning=0;
+
+	list_for_each(list, &bus->children) {
+		error = pci_bridge_restore_state_bus(pci_bus_b(list),force);
+		if (error) return error;
+	}
+	list_for_each(list, &bus->devices) {
+		if (force)
+			pci_generic_resume_restore(pci_dev_b(list));
+		else {
+			error = pci_generic_resume_compare(pci_dev_b(list));
+			if (error && !printed_warning++) { 
+				printk(KERN_WARNING "resume warning: bios doesn't restore PCI state properly\n");
+				printk(KERN_WARNING "resume warning: if resume failed, try booting with resume=force\n");
+			}
+			if (error)
+				return error;
+		}
+	}
+	return 0;
+}
+
+static int bridge_suspend(struct pci_dev *dev, u32 force)
+{
+	pci_generic_suspend_save(dev,force);
+	if (dev->subordinate)
+		pci_bridge_save_state_bus(dev->subordinate,force);
+	return 0;
+}
+
+static int bridge_resume(struct pci_dev *dev)
+{
+
+	pci_generic_resume_restore(dev);
+	if (dev->subordinate)
+		pci_bridge_restore_state_bus(dev->subordinate,pci_bridge_force_restore);
+	return 0;
+}
+
+
+MODULE_DEVICE_TABLE(pci, bridge_pci_table);
+static struct pci_driver bridge_ops = {
+        name:           "PCI Bridge",   
+        id_table:       bridge_pci_table,
+        probe:          bridge_probe,    
+        suspend: 	bridge_suspend,
+        resume: 	bridge_resume
+};
+
+static int __devinit bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	return 0;
+}
+
+static int __init bridge_init(void) 
+{
+        pci_register_driver(&bridge_ops);
+        return 0;
+}
+
+static void __exit bridge_exit(void)
+{
+        pci_unregister_driver(&bridge_ops);
+} 
+
+
+module_init(bridge_init)
+module_exit(bridge_exit)
+
diff -urN Linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- Linux/drivers/pci/pci.c	Thu Apr 11 11:14:40 2002
+++ linux/drivers/pci/pci.c	Thu Apr 11 11:15:28 2002
@@ -357,6 +357,48 @@
 	return 0;
 }
 
+int 
+pci_compare_state(struct pci_dev *dev, u32 *buffer)
+{
+	int i;
+	unsigned int temp;
+
+	if (buffer) {
+		for (i = 0; i < 16; i++) {
+			pci_read_config_dword(dev,i*4,&temp);
+			if (temp!=buffer[i])
+				return 1;
+		}
+	}
+	return 0;
+}
+
+int pci_generic_suspend_save(struct pci_dev *pdev, u32 state)
+{
+	if (pdev)
+		pci_save_state(pdev,pdev->saved_state);
+	return 0;
+}
+
+int pci_generic_resume_restore(struct pci_dev *pdev)
+{
+	if (pdev)
+		pci_restore_state(pdev,pdev->saved_state);
+	return 0;		
+}
+
+int pci_generic_resume_compare(struct pci_dev *pdev)
+{
+	int retval=0;
+	if (pdev)
+		retval = pci_compare_state(pdev,pdev->saved_state);
+	return retval;		
+}
+
+EXPORT_SYMBOL(pci_generic_suspend_save);
+EXPORT_SYMBOL(pci_generic_resume_restore);
+EXPORT_SYMBOL(pci_generic_resume_compare);
+
 /**
  * pci_enable_device - Initialize device before it's used by a driver.
  * @dev: PCI device to be initialized
diff -urN Linux/include/linux/pci.h linux/include/linux/pci.h
--- Linux/include/linux/pci.h	Thu Apr 11 11:14:40 2002
+++ linux/include/linux/pci.h	Thu Apr 11 11:15:28 2002
@@ -378,6 +378,7 @@
 
 	char		name[80];	/* device name */
 	char		slot_name[8];	/* slot name */
+	u32		saved_state[16]; /* for saving the config space before suspend */
 	int		active;		/* ISAPnP: device is active */
 	int		ro;		/* ISAPnP: read only */
 	unsigned short	regs;		/* ISAPnP: supported registers */
@@ -570,6 +571,8 @@
 int pci_restore_state(struct pci_dev *dev, u32 *buffer);
 int pci_set_power_state(struct pci_dev *dev, int state);
 int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
+int pci_generic_suspend_save(struct pci_dev *pdev, u32 state);
+int pci_generic_resume_restore(struct pci_dev *pdev);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-05-05 13:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-05 12:53 apm dell I8K 2.4.18 Ken Van Eyndonck
2002-05-05 13:29 ` arjan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).