diff options
Diffstat (limited to 'drivers/acpi/table.c')
-rw-r--r-- | drivers/acpi/table.c | 264 |
1 files changed, 24 insertions, 240 deletions
diff --git a/drivers/acpi/table.c b/drivers/acpi/table.c index 5123b94ff..8379b4204 100644 --- a/drivers/acpi/table.c +++ b/drivers/acpi/table.c @@ -1,5 +1,5 @@ /* - * tables.c - ACPI tables, chipset, and errata handling + * table.c - ACPI tables, chipset, and errata handling * * Copyright (C) 2000 Andrew Henroid * @@ -27,250 +27,39 @@ #include "driver.h" #define _COMPONENT OS_DEPENDENT - MODULE_NAME ("tables") + MODULE_NAME ("table") -struct acpi_facp acpi_facp; - -#define ACPI_DUMMY_CHECKSUM 9 -#define ACPI_DUMMY_PBLK 51 - -static u8 acpi_dummy_dsdt[] = -{ - 0x44, 0x53, 0x44, 0x54, // "DSDT" - 0x38, 0x00, 0x00, 0x00, // length - 0x01, // revision - 0x00, // checksum - 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX" - 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY" - 0x01, 0x00, 0x00, 0x00, // OEM rev - 0x4c, 0x4e, 0x55, 0x58, // "LNUX" - 0x01, 0x00, 0x00, 0x00, // creator rev - 0x10, // Scope - 0x13, // PkgLength - 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_ - 0x5b, 0x83, // Processor - 0x0b, // PkgLength - 0x43, 0x50, 0x55, 0x30, // CPU0 - 0x00, // ID - 0x00, 0x00, 0x00, 0x00, // PBLK - 0x06 // PBLK size -}; - -/* - * Calculate and set ACPI table checksum - */ -static void -acpi_set_checksum(u8 *table, int size) -{ - int i, sum = 0; - for (i = 0; i < size; i++) - sum += (int) table[i]; - sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff)); - table[ACPI_DUMMY_CHECKSUM] = sum; -} - -/* - * Init PIIX4 device, create a fake FACP - */ -static int -acpi_init_piix4(struct pci_dev *dev) -{ - u32 base, pblk; - u16 cmd; - u8 pmregmisc; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (!(cmd & PCI_COMMAND_IO)) - return -ENODEV; - - pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc); - if (!(pmregmisc & ACPI_PIIX4_PMIOSE)) - return -ENODEV; - - base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES); - if (!base) - return -ENODEV; - - printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); - - memset(&acpi_facp, 0, sizeof(acpi_facp)); - acpi_facp.hdr.signature = ACPI_FACP_SIG; - acpi_facp.hdr.length = sizeof(acpi_facp); - acpi_facp.int_model = ACPI_PIIX4_INT_MODEL; - acpi_facp.sci_int = ACPI_PIIX4_SCI_INT; - acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD; - acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE; - acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE; - acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ; - acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT; - acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT; - acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT; - acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR; - acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0; - acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN; - acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN; - acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN; - acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN; - acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN; - acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; - acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; - - acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); - acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); - - pblk = base + ACPI_PIIX4_P_BLK; - memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); - acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); - acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); - - return 0; -} +FADT_DESCRIPTOR acpi_fadt; /* - * Init VIA ACPI device and create a fake FACP + * Fetch the fadt information */ static int -acpi_init_via(struct pci_dev *dev) -{ - u32 base, pblk; - u8 tmp, irq; - - pci_read_config_byte(dev, 0x41, &tmp); - if (!(tmp & 0x80)) - return -ENODEV; - - base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES); - if (!base) { - base = pci_resource_start(dev, PCI_BASE_ADDRESS_4); - if (!base) - return -ENODEV; - } - - pci_read_config_byte(dev, 0x42, &irq); - - printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); - - memset(&acpi_facp, 0, sizeof(acpi_facp)); - acpi_facp.hdr.signature = ACPI_FACP_SIG; - acpi_facp.hdr.length = sizeof(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_VIA_PM1_EVT; - acpi_facp.pm1a_cnt = base + ACPI_VIA_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_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); - acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); - - pblk = base + ACPI_VIA_P_BLK; - memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); - acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); - acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); - - return 0; -} - -typedef enum -{ - CH_UNKNOWN = 0, - CH_INTEL_PIIX4, - CH_VIA_586, - CH_VIA_686A, -} acpi_chip_t; - -/* indexed by value of each enum in acpi_chip_t */ -const static struct -{ - int (*chip_init)(struct pci_dev *dev); -} acpi_chip_info[] = -{ - {NULL,}, - {acpi_init_piix4}, - {acpi_init_via}, - {acpi_init_via}, -}; - -static struct pci_device_id acpi_pci_tbl[] = -{ - {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, - {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586}, - {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A}, - {0,} /* terminate list */ -}; - -static int -acpi_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - return acpi_chip_info[id->driver_data].chip_init(dev); -} - -static struct pci_driver acpi_driver = -{ - name: "acpi", - id_table: acpi_pci_tbl, - probe: acpi_probe, -}; -static int acpi_driver_registered = 0; - -/* - * Locate a known ACPI chipset - */ -static int -acpi_find_chipset(void) -{ - if (pci_register_driver(&acpi_driver) < 1) - return -ENODEV; - acpi_driver_registered = 1; - return 0; -} - -/* - * Fetch the FACP information - */ -static int -acpi_fetch_facp(void) +acpi_fetch_fadt(void) { ACPI_BUFFER buffer; - memset(&acpi_facp, 0, sizeof(acpi_facp)); - buffer.pointer = &acpi_facp; - buffer.length = sizeof(acpi_facp); - if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) { - printk(KERN_ERR "ACPI: missing FACP\n"); + memset(&acpi_fadt, 0, sizeof(acpi_fadt)); + buffer.pointer = &acpi_fadt; + buffer.length = sizeof(acpi_fadt); + if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) { + printk(KERN_ERR "ACPI: missing fadt\n"); return -ENODEV; } - if (acpi_facp.p_lvl2_lat - && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) { + if (acpi_fadt.plvl2_lat + && acpi_fadt.plvl2_lat <= ACPI_MAX_P_LVL2_LAT) { acpi_c2_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat); acpi_c2_enter_latency - = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); + = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); } - if (acpi_facp.p_lvl3_lat - && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) { + if (acpi_fadt.plvl3_lat + && acpi_fadt.plvl3_lat <= ACPI_MAX_P_LVL3_LAT) { acpi_c3_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat); acpi_c3_enter_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5); } return 0; @@ -280,24 +69,19 @@ acpi_fetch_facp(void) * Find and load ACPI tables */ int -acpi_load_tables(void) +acpi_find_and_load_tables(u64 rsdp) { - if (ACPI_SUCCESS(acpi_load_firmware_tables())) + if (ACPI_SUCCESS(acpi_load_tables(rsdp))) { - printk(KERN_INFO "ACPI: support found\n"); + printk(KERN_INFO "ACPI: System description tables loaded\n"); } - else if (acpi_find_chipset()) { - acpi_terminate(); - return -1; - } - - if (acpi_fetch_facp()) { + else { + printk(KERN_INFO "ACPI: System description table load failed\n"); acpi_terminate(); return -1; } - if (!ACPI_SUCCESS(acpi_load_namespace())) { - printk(KERN_ERR "ACPI: namespace load failed\n"); + if (acpi_fetch_fadt()) { acpi_terminate(); return -1; } |