PATCH 2.3.41.2: Replace Via support for ACPI

Jeff Garzik jgarzik en mandrakesoft.com
Lun Ene 24 02:59:53 CST 2000


Andy,

Attached is a patch against 2.3.41-pre2 which adds back Via support.  It
does so using the new PCI table-driven device matching code, which
should make it easy to add other chipsets.

NOTE that I was not able to get it to compile without #if-0'ing the
__setup function.  I got a section type conflict error which broke the
build.

Nevertheless, once the _unrelated_ setup function was commented out,
everything built just fine.

	Jeff




-- 
Jeff Garzik         | Andre the Giant has a posse.
Building 1024       |
MandrakeSoft, Inc.  |
------------ próxima parte ------------
diff -urN /spare/vanilla/linux-2.3.41-pre2/arch/i386/kernel/acpi.c linux/arch/i386/kernel/acpi.c
--- /spare/vanilla/linux-2.3.41-pre2/arch/i386/kernel/acpi.c	Thu Jan 20 12:51:42 2000
+++ linux/arch/i386/kernel/acpi.c	Sun Jan 23 19:19:12 2000
@@ -519,22 +519,16 @@
 	acpi_unmap_table((struct acpi_table*) acpi_facs);
 }
 
+
 /*
- * Locate PIIX4 device and create a fake FACP
+ * Init PIIX4 device, create a fake FACP
  */
-static int __init acpi_find_piix4(void)
+static int __init acpi_init_piix4 (struct pci_dev *dev)
 {
-	struct pci_dev *dev;
 	u32 base;
 	u16 cmd;
 	u8 pmregmisc;
 
-	dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82371AB_3,
-			      NULL);
-	if (!dev)
-		return -ENODEV;
-	
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	if (!(cmd & PCI_COMMAND_IO))
 		return -ENODEV;
@@ -586,6 +580,111 @@
 	return 0;
 }
 
+
+/*
+ * Init VIA ACPI device and create a fake FACP
+ */
+static int __init acpi_init_via686a (struct pci_dev *dev)
+{
+       u32 base;
+       u8 tmp, irq;
+
+       pci_read_config_byte(dev, 0x41, &tmp);
+       if (!(tmp & 0x80))
+               return -ENODEV;
+
+       pci_read_config_byte(dev, 8, &tmp);
+       tmp = (tmp & 0x10 ? 0x48 : 0x20);
+
+       pci_read_config_dword(dev, tmp, &base);
+       if (!(base & PCI_BASE_ADDRESS_SPACE_IO))
+               return -ENODEV;
+
+       base &= PCI_BASE_ADDRESS_IO_MASK;
+       if (!base)
+               return -ENODEV;
+
+       pci_read_config_byte(dev, 0x42, &irq);
+
+       printk(KERN_INFO "ACPI: found %s at 0x%04x\n", dev->name, base);
+
+       acpi_facp = kmalloc(sizeof(struct acpi_facp), GFP_KERNEL);
+       if (!acpi_facp)
+               return -ENOMEM;
+
+       acpi_fake_facp = 1;
+       memset(acpi_facp, 0, sizeof(struct acpi_facp));
+
+       acpi_facp->int_model = ACPI_VIA_INT_MODEL;
+       acpi_facp->sci_int = irq;
+       acpi_facp->smi_cmd = base + ACPI_VIA_SMI_CMD;
+       acpi_facp->acpi_enable = ACPI_VIA_ACPI_ENABLE;
+       acpi_facp->acpi_disable = ACPI_VIA_ACPI_DISABLE;
+       acpi_facp->pm1a_evt = base + ACPI_PIIX4_PM1_EVT;
+       acpi_facp->pm1a_cnt = base + ACPI_PIIX4_PM1_CNT;
+       acpi_facp->pm_tmr = base + ACPI_VIA_PM_TMR;
+       acpi_facp->gpe0 = base + ACPI_VIA_GPE0;
+
+       acpi_facp->pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
+       acpi_facp->pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
+       acpi_facp->pm_tm_len = ACPI_VIA_PM_TM_LEN;
+       acpi_facp->gpe0_len = ACPI_VIA_GPE0_LEN;
+       acpi_facp->p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+       acpi_facp->p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+       acpi_facp->duty_offset = ACPI_VIA_DUTY_OFFSET;
+       acpi_facp->duty_width = ACPI_VIA_DUTY_WIDTH;
+
+       acpi_facp->day_alarm = ACPI_VIA_DAY_ALARM;
+       acpi_facp->mon_alarm = ACPI_VIA_MON_ALARM;
+       acpi_facp->century = ACPI_VIA_CENTURY;
+
+       acpi_facp_addr = virt_to_phys(acpi_facp);
+       acpi_dsdt_addr = 0;
+
+       acpi_p_blk = base + ACPI_VIA_P_BLK;
+
+       return 0;
+}
+
+
+typedef enum {
+	CH_UNKNOWN = 0,
+	CH_INTEL_PIIX4,
+	CH_VIA_686A,
+} acpi_chip_t;
+
+/* indexed by value of each enum in acpi_chip_t */
+const static struct {
+	acpi_chip_t chip;
+	int (*chip_init) (struct pci_dev *dev);
+} acpi_chip_info[] __initdata = {
+	{ CH_UNKNOWN, },
+	{ CH_INTEL_PIIX4, acpi_init_piix4 },
+	{ CH_VIA_686A, acpi_init_via686a },
+};
+	
+const static struct pci_device_id acpi_pci_tbl[] __initdata = {
+	{ 0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4 },
+	{ 0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A },
+	{ 0,}, /* terminate list */
+};
+
+static int __init acpi_find_pcidev (void)
+{
+	struct pci_dev *pdev;
+	const struct pci_device_id *ent;
+
+	pci_for_each_dev (pdev) {
+		ent = pci_match_device (acpi_pci_tbl, pdev);
+		if (ent)
+			return acpi_chip_info[ent->driver_data].chip_init (pdev);
+	}
+	
+	return -ENODEV;
+}
+
+
 /*
  * Handle an ACPI SCI (fixed or general purpose event)
  */
@@ -1208,6 +1307,7 @@
 	return 0;
 }
 
+
 /*
  * Initialize and enable ACPI
  */
@@ -1218,8 +1318,8 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (acpi_find_tables() && acpi_find_piix4()) {
-		// no ACPI tables and not PIIX4
+	if (acpi_find_tables() && acpi_find_pcidev()) {
+		// no ACPI tables and no supported ACPI devices
 		return -ENODEV;
 	}
 
@@ -1298,6 +1398,7 @@
 	acpi_destroy_tables();
 }
 
+#if 0
 static int __init acpi_setup(char *str)
 {
 	while (str && *str) {
@@ -1313,6 +1414,7 @@
 }
 
 __setup("acpi=", acpi_setup);
+#endif
 
 /*
  * Register a device with the ACPI subsystem


Más información sobre la lista de distribución Ayuda