PATCH 2.3.41.2: Replace Via support for ACPI

From: Jeff Garzik (jgarzik@mandrakesoft.com)
Date: Sun Jan 23 2000 - 20:32:31 EST


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.  |

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

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jan 31 2000 - 21:00:11 EST