From: Linus Torvalds Date: Fri, 9 Jan 2009 19:55:14 +0000 (-0800) Subject: Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux... X-Git-Tag: v2.6.29-rc1~34 X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=a3a798c88a14b35e5d4ca30716dbc9eb9a1ddfe2;hp=efcb3cf7f00c3c424db012380a8a974c2676a3c8;p=linux-2.6-omap-h63xx.git Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 * 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (94 commits) ACPICA: hide private headers ACPICA: create acpica/ directory ACPI: fix build warning ACPI : Use RSDT instead of XSDT by adding boot option of "acpi=rsdt" ACPI: Avoid array address overflow when _CST MWAIT hint bits are set fujitsu-laptop: Simplify SBLL/SBL2 backlight handling fujitsu-laptop: Add BL power, LED control and radio state information ACPICA: delete utcache.c ACPICA: delete acdisasm.h ACPICA: Update version to 20081204. ACPICA: FADT: Update error msgs for consistency ACPICA: FADT: set acpi_gbl_use_default_register_widths to TRUE by default ACPICA: FADT parsing changes and fixes ACPICA: Add ACPI_MUTEX_TYPE configuration option ACPICA: Fixes for various ACPI data tables ACPICA: Restructure includes into public/private ACPI: remove private acpica headers from driver files ACPI: reboot.c: use new acpi_reset interface ACPICA: New: acpi_reset interface - write to reset register ACPICA: Move all public H/W interfaces to new hwxface ... --- diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fb849020aea..fcc48bf722a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -141,6 +141,7 @@ and is between 256 and 4096 characters. It is defined in the file ht -- run only enough ACPI to enable Hyper Threading strict -- Be less tolerant of platforms that are not strictly ACPI specification compliant. + rsdt -- prefer RSDT over (default) XSDT See also Documentation/power/pm.txt, pci=noacpi @@ -151,16 +152,20 @@ and is between 256 and 4096 characters. It is defined in the file default: 0 acpi_sleep= [HW,ACPI] Sleep options - Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering } - See Documentation/power/video.txt for s3_bios and s3_mode. + Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, + old_ordering, s4_nonvs } + See Documentation/power/video.txt for information on + s3_bios and s3_mode. s3_beep is for debugging; it makes the PC's speaker beep as soon as the kernel's real-mode entry point is called. s4_nohwsig prevents ACPI hardware signature from being used during resume from hibernation. old_ordering causes the ACPI 1.0 ordering of the _PTS - control method, wrt putting devices into low power - states, to be enforced (the ACPI 2.0 ordering of _PTS is - used by default). + control method, with respect to putting devices into + low power states, to be enforced (the ACPI 2.0 ordering + of _PTS is used by default). + s4_nonvs prevents the kernel from saving/restoring the + ACPI NVS memory during hibernation. acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode Format: { level | edge | high | low } @@ -195,7 +200,7 @@ and is between 256 and 4096 characters. It is defined in the file acpi_skip_timer_override [HW,ACPI] Recognize and ignore IRQ0/pin2 Interrupt Override. For broken nForce2 BIOS resulting in XT-PIC timer. - acpi_use_timer_override [HW,ACPI} + acpi_use_timer_override [HW,ACPI] Use timer override. For some broken Nvidia NF5 boards that require a timer override, but don't have HPET @@ -878,17 +883,19 @@ and is between 256 and 4096 characters. It is defined in the file See Documentation/ide/ide.txt. idle= [X86] - Format: idle=poll or idle=mwait, idle=halt, idle=nomwait - Poll forces a polling idle loop that can slightly improves the performance - of waking up a idle CPU, but will use a lot of power and make the system - run hot. Not recommended. - idle=mwait. On systems which support MONITOR/MWAIT but the kernel chose - to not use it because it doesn't save as much power as a normal idle - loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same - as idle=poll. - idle=halt. Halt is forced to be used for CPU idle. + Format: idle=poll, idle=mwait, idle=halt, idle=nomwait + Poll forces a polling idle loop that can slightly + improve the performance of waking up a idle CPU, but + will use a lot of power and make the system run hot. + Not recommended. + idle=mwait: On systems which support MONITOR/MWAIT but + the kernel chose to not use it because it doesn't save + as much power as a normal idle loop, use the + MONITOR/MWAIT idle loop anyways. Performance should be + the same as idle=poll. + idle=halt: Halt is forced to be used for CPU idle. In such case C2/C3 won't be used again. - idle=nomwait. Disable mwait for CPU C-states + idle=nomwait: Disable mwait for CPU C-states ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem Claim all unknown PCI IDE storage controllers. @@ -1074,8 +1081,8 @@ and is between 256 and 4096 characters. It is defined in the file lapic [X86-32,APIC] Enable the local APIC even if BIOS disabled it. - lapic_timer_c2_ok [X86-32,x86-64,APIC] trust the local apic timer in - C2 power state. + lapic_timer_c2_ok [X86-32,x86-64,APIC] trust the local apic timer + in C2 power state. libata.dma= [LIBATA] DMA control libata.dma=0 Disable all PATA and SATA DMA @@ -2303,7 +2310,8 @@ and is between 256 and 4096 characters. It is defined in the file thermal.psv= [HW,ACPI] -1: disable all passive trip points - : override all passive trip points to this value + : override all passive trip points to this + value thermal.tzp= [HW,ACPI] Specify global default ACPI thermal zone polling rate diff --git a/arch/ia64/include/asm/acpi-ext.h b/arch/ia64/include/asm/acpi-ext.h index 734d137dda6..7f8362b379e 100644 --- a/arch/ia64/include/asm/acpi-ext.h +++ b/arch/ia64/include/asm/acpi-ext.h @@ -14,7 +14,6 @@ #define _ASM_IA64_ACPI_EXT_H #include -#include extern acpi_status hp_acpi_csr_space (acpi_handle, u64 *base, u64 *length); diff --git a/arch/ia64/include/asm/sn/acpi.h b/arch/ia64/include/asm/sn/acpi.h index 9ce2801cbd5..fd480db2556 100644 --- a/arch/ia64/include/asm/sn/acpi.h +++ b/arch/ia64/include/asm/sn/acpi.h @@ -9,8 +9,6 @@ #ifndef _ASM_IA64_SN_ACPI_H #define _ASM_IA64_SN_ACPI_H -#include "acpi/acglobal.h" - extern int sn_acpi_rev; #define SN_ACPI_BASE_SUPPORT() (sn_acpi_rev >= 0x20101) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 0553648b759..d541671caf4 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -65,6 +65,7 @@ EXPORT_SYMBOL(pm_idle); void (*pm_power_off) (void); EXPORT_SYMBOL(pm_power_off); +u32 acpi_rsdt_forced; unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index bc610a6c785..c5a214026a7 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -13,7 +13,6 @@ #include #include "xtalk/hubdev.h" #include -#include /* @@ -64,6 +63,7 @@ static acpi_status __init sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; u64 addr; struct hubdev_info *hubdev; struct hubdev_info *hubdev_ptr; @@ -77,11 +77,12 @@ sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret) status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR "sn_acpi_hubdev_init: acpi_get_vendor_resource() " - "(0x%x) failed for: ", status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "(0x%x) failed for: %s\n", status, + (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return AE_OK; /* Continue walking namespace */ } @@ -89,11 +90,12 @@ sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret) vendor = &resource->data.vendor_typed; if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != sizeof(struct hubdev_info *)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR - "sn_acpi_hubdev_init: Invalid vendor data length: %d for: ", - vendor->byte_length); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "sn_acpi_hubdev_init: Invalid vendor data length: " + "%d for: %s\n", + vendor->byte_length, (char *)name_buffer.pointer); + kfree(name_buffer.pointer); goto exit; } @@ -120,6 +122,7 @@ sn_get_bussoft_ptr(struct pci_bus *bus) { u64 addr; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle; struct pcibus_bussoft *prom_bussoft_ptr; struct acpi_resource *resource; @@ -131,11 +134,11 @@ sn_get_bussoft_ptr(struct pci_bus *bus) status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR "%s: " - "acpi_get_vendor_resource() failed (0x%x) for: ", - __func__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "acpi_get_vendor_resource() failed (0x%x) for: %s\n", + __func__, status, (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return NULL; } resource = buffer.pointer; @@ -168,6 +171,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, { u64 addr; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct sn_irq_info *irq_info, *irq_info_prom; struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr; struct acpi_resource *resource; @@ -182,11 +186,11 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR - "%s: acpi_get_vendor_resource() failed (0x%x) for: ", - __func__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "%s: acpi_get_vendor_resource() failed (0x%x) for: %s\n", + __func__, status, (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return 1; } @@ -194,11 +198,12 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, vendor = &resource->data.vendor_typed; if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != sizeof(struct pci_devdev_info *)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR - "%s: Invalid vendor data length: %d for: ", - __func__, vendor->byte_length); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "%s: Invalid vendor data length: %d for: %s\n", + __func__, vendor->byte_length, + (char *)name_buffer.pointer); + kfree(name_buffer.pointer); ret = 1; goto exit; } @@ -239,6 +244,9 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) acpi_handle parent; int slot; acpi_status status; + struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + acpi_get_name(device_handle, ACPI_FULL_PATHNAME, &name_buffer); /* * Do an upward search to find the root bus device, and @@ -249,9 +257,8 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) status = acpi_get_parent(child, &parent); if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: acpi_get_parent() failed " - "(0x%x) for: ", __func__, status); - acpi_ns_print_node_pathname(child, NULL); - printk("\n"); + "(0x%x) for: %s\n", __func__, status, + (char *)name_buffer.pointer); panic("%s: Unable to find host devfn\n", __func__); } if (parent == rootbus_handle) @@ -259,22 +266,20 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) child = parent; } if (!child) { - printk(KERN_ERR "%s: Unable to find root bus for: ", - __func__); - acpi_ns_print_node_pathname(device_handle, NULL); - printk("\n"); + printk(KERN_ERR "%s: Unable to find root bus for: %s\n", + __func__, (char *)name_buffer.pointer); BUG(); } status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr); if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: ", - __func__, status); - acpi_ns_print_node_pathname(child, NULL); - printk("\n"); + printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: %s\n", + __func__, status, (char *)name_buffer.pointer); panic("%s: Unable to find host devfn\n", __func__); } + kfree(name_buffer.pointer); + slot = (adr >> 16) & 0xffff; function = adr & 0xffff; devfn = PCI_DEVFN(slot, function); @@ -300,27 +305,28 @@ find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv) int function; int slot; struct sn_pcidev_match *info = context; + struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr); if (ACPI_SUCCESS(status)) { status = acpi_get_parent(handle, &parent); if (ACPI_FAILURE(status)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR - "%s: acpi_get_parent() failed (0x%x) for: ", - __func__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "%s: acpi_get_parent() failed (0x%x) for: %s\n", + __func__, status, (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return AE_OK; } status = acpi_evaluate_integer(parent, METHOD_NAME__BBN, NULL, &bbn); if (ACPI_FAILURE(status)) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); printk(KERN_ERR - "%s: Failed to find _BBN in parent of: ", - __func__); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + "%s: Failed to find _BBN in parent of: %s\n", + __func__, (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return AE_OK; } @@ -350,24 +356,27 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, acpi_handle rootbus_handle; unsigned long long segment; acpi_status status; + struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; rootbus_handle = PCI_CONTROLLER(dev)->acpi_handle; status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL, &segment); if (ACPI_SUCCESS(status)) { if (segment != pci_domain_nr(dev)) { + acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME, + &name_buffer); printk(KERN_ERR - "%s: Segment number mismatch, 0x%llx vs 0x%x for: ", - __func__, segment, pci_domain_nr(dev)); - acpi_ns_print_node_pathname(rootbus_handle, NULL); - printk("\n"); + "%s: Segment number mismatch, 0x%llx vs 0x%x for: %s\n", + __func__, segment, pci_domain_nr(dev), + (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return 1; } } else { - printk(KERN_ERR "%s: Unable to get __SEG from: ", - __func__); - acpi_ns_print_node_pathname(rootbus_handle, NULL); - printk("\n"); + acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME, &name_buffer); + printk(KERN_ERR "%s: Unable to get __SEG from: %s\n", + __func__, (char *)name_buffer.pointer); + kfree(name_buffer.pointer); return 1; } diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 8a924a5661d..0d4ffa4da1d 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -26,7 +26,6 @@ #include #include #include -#include "acpi/acglobal.h" extern void sn_init_cpei_timer(void); extern void register_sn_procfs(void); @@ -473,7 +472,7 @@ sn_io_early_init(void) { struct acpi_table_header *header = NULL; - acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); + acpi_get_table(ACPI_SIG_DSDT, 1, &header); BUG_ON(header == NULL); sn_acpi_rev = header->oem_revision; } @@ -505,7 +504,7 @@ sn_io_early_init(void) { struct acpi_table_header *header; - (void)acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); + (void)acpi_get_table(ACPI_SIG_DSDT, 1, &header); printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", header->oem_revision); } diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 29dc0c89d4a..d37593c2f43 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -47,7 +47,7 @@ #endif static int __initdata acpi_force = 0; - +u32 acpi_rsdt_forced; #ifdef CONFIG_ACPI int acpi_disabled = 0; #else @@ -1374,6 +1374,17 @@ static void __init acpi_process_madt(void) "Invalid BIOS MADT, disabling ACPI\n"); disable_acpi(); } + } else { + /* + * ACPI found no MADT, and so ACPI wants UP PIC mode. + * In the event an MPS table was found, forget it. + * Boot with "acpi=off" to use MPS on such a system. + */ + if (smp_found_config) { + printk(KERN_WARNING PREFIX + "No APIC-table, disabling MPS\n"); + smp_found_config = 0; + } } /* @@ -1809,6 +1820,10 @@ static int __init parse_acpi(char *arg) disable_acpi(); acpi_ht = 1; } + /* acpi=rsdt use RSDT instead of XSDT */ + else if (strcmp(arg, "rsdt") == 0) { + acpi_rsdt_forced = 1; + } /* "acpi=noirq" disables ACPI interrupt routing */ else if (strcmp(arg, "noirq") == 0) { acpi_noirq_set(); diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index c2502eb9aa8..a4805b3b409 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -56,6 +56,7 @@ static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; #define MWAIT_SUBSTATE_MASK (0xf) +#define MWAIT_CSTATE_MASK (0xf) #define MWAIT_SUBSTATE_SIZE (4) #define CPUID_MWAIT_LEAF (5) @@ -98,7 +99,8 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); /* Check whether this particular cx_type (in CST) is supported or not */ - cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1; + cstate_type = ((cx->address >> MWAIT_SUBSTATE_SIZE) & + MWAIT_CSTATE_MASK) + 1; edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE); num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK; diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 806b4e9051b..707c1f6f95f 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -159,6 +159,8 @@ static int __init acpi_sleep_setup(char *str) #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); + if (strncmp(str, "s4_nonvs", 8) == 0) + acpi_s4_no_nvs(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 65a13943e09..e85826829cf 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -665,6 +665,27 @@ void __init e820_mark_nosave_regions(unsigned long limit_pfn) } #endif +#ifdef CONFIG_HIBERNATION +/** + * Mark ACPI NVS memory region, so that we can save/restore it during + * hibernation and the subsequent resume. + */ +static int __init e820_mark_nvs_memory(void) +{ + int i; + + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + + if (ei->type == E820_NVS) + hibernate_nvs_register(ei->addr, ei->size); + } + + return 0; +} +core_initcall(e820_mark_nvs_memory); +#endif + /* * Early reserved memory areas. */ diff --git a/drivers/Kconfig b/drivers/Kconfig index 2f557f570ad..00cf9553f74 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -107,4 +107,6 @@ source "drivers/uio/Kconfig" source "drivers/xen/Kconfig" source "drivers/staging/Kconfig" + +source "drivers/platform/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 6326f4dbbda..c1bf4173793 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -105,3 +105,4 @@ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_STAGING) += staging/ +obj-y += platform/ diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b0243fd55ac..d7f9839ba26 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -196,90 +196,6 @@ config ACPI_NUMA depends on (X86 || IA64) default y if IA64_GENERIC || IA64_SGI_SN2 -config ACPI_WMI - tristate "WMI (EXPERIMENTAL)" - depends on X86 - depends on EXPERIMENTAL - help - This driver adds support for the ACPI-WMI (Windows Management - Instrumentation) mapper device (PNP0C14) found on some systems. - - ACPI-WMI is a proprietary extension to ACPI to expose parts of the - ACPI firmware to userspace - this is done through various vendor - defined methods and data blocks in a PNP0C14 device, which are then - made available for userspace to call. - - The implementation of this in Linux currently only exposes this to - other kernel space drivers. - - This driver is a required dependency to build the firmware specific - drivers needed on many machines, including Acer and HP laptops. - - It is safe to enable this driver even if your DSDT doesn't define - any ACPI-WMI devices. - -config ACPI_ASUS - tristate "ASUS/Medion Laptop Extras" - depends on X86 - select BACKLIGHT_CLASS_DEVICE - ---help--- - This driver provides support for extra features of ACPI-compatible - ASUS laptops. As some of Medion laptops are made by ASUS, it may also - support some Medion laptops (such as 9675 for example). It makes all - the extra buttons generate standard ACPI events that go through - /proc/acpi/events, and (on some models) adds support for changing the - display brightness and output, switching the LCD backlight on and off, - and most importantly, allows you to blink those fancy LEDs intended - for reporting mail and wireless status. - - Note: display switching code is currently considered EXPERIMENTAL, - toying with these values may even lock your machine. - - All settings are changed via /proc/acpi/asus directory entries. Owner - and group for these entries can be set with asus_uid and asus_gid - parameters. - - More information and a userspace daemon for handling the extra buttons - at . - - If you have an ACPI-compatible ASUS laptop, say Y or M here. This - driver is still under development, so if your laptop is unsupported or - something works not quite as expected, please use the mailing list - available on the above page (acpi4asus-user@lists.sourceforge.net). - - NOTE: This driver is deprecated and will probably be removed soon, - use asus-laptop instead. - -config ACPI_TOSHIBA - tristate "Toshiba Laptop Extras" - depends on X86 && INPUT - select INPUT_POLLDEV - select NET - select RFKILL - select BACKLIGHT_CLASS_DEVICE - ---help--- - This driver adds support for access to certain system settings - on "legacy free" Toshiba laptops. These laptops can be recognized by - their lack of a BIOS setup menu and APM support. - - On these machines, all system configuration is handled through the - ACPI. This driver is required for access to controls not covered - by the general ACPI drivers, such as LCD brightness, video output, - etc. - - This driver differs from the non-ACPI Toshiba laptop driver (located - under "Processor type and features") in several aspects. - Configuration is accessed by reading and writing text files in the - /proc tree instead of by program interface to /dev. Furthermore, no - power management functions are exposed, as those are handled by the - general ACPI drivers. - - More information about this driver is available at - . - - If you have a legacy free Toshiba laptop (such as the Libretto L1 - series), say Y. - config ACPI_CUSTOM_DSDT_FILE string "Custom DSDT Table file to include" default "" diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 3c0c93300f1..d80f4cc2e0d 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -2,15 +2,8 @@ # Makefile for the Linux ACPI interpreter # -export ACPI_CFLAGS - -ACPI_CFLAGS := -Os - -ifdef CONFIG_ACPI_DEBUG - ACPI_CFLAGS += -DACPI_DEBUG_OUTPUT -endif - -EXTRA_CFLAGS += $(ACPI_CFLAGS) +ccflags-y := -Os +ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # # ACPI Boot-Time Table Parsing @@ -22,9 +15,13 @@ obj-$(CONFIG_X86) += blacklist.o # ACPI Core Subsystem (Interpreter) # obj-y += osl.o utils.o reboot.o\ - dispatcher/ events/ executer/ hardware/ \ - namespace/ parser/ resources/ tables/ \ - utilities/ + acpica/ + +# sleep related files +obj-y += wakeup.o +obj-y += main.o +obj-$(CONFIG_ACPI_SLEEP) += proc.o + # # ACPI Bus and Device Drivers @@ -35,7 +32,6 @@ ifdef CONFIG_CPU_FREQ processor-objs += processor_perflib.o endif -obj-y += sleep/ obj-y += bus.o glue.o obj-y += scan.o # Keep EC driver first. Initialization of others depend on it. @@ -59,9 +55,6 @@ obj-y += power.o obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o obj-$(CONFIG_ACPI_DEBUG) += debug.o obj-$(CONFIG_ACPI_NUMA) += numa.o -obj-$(CONFIG_ACPI_WMI) += wmi.o -obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o -obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += sbshc.o diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile new file mode 100644 index 00000000000..3f23298ee3f --- /dev/null +++ b/drivers/acpi/acpica/Makefile @@ -0,0 +1,44 @@ +# +# Makefile for ACPICA Core interpreter +# + +ccflags-y := -Os +ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT + +obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ + dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ + dsinit.o + +obj-y += evevent.o evregion.o evsci.o evxfevnt.o \ + evmisc.o evrgnini.o evxface.o evxfregn.o \ + evgpe.o evgpeblk.o + +obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ + exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ + excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ + exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o + +obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o + +obj-$(ACPI_FUTURE_USAGE) += hwtimer.o + +obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ + nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ + nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ + nsparse.o nspredef.o + +obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o + +obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ + psopcode.o psscope.o psutils.o psxface.o + +obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ + rscalc.o rsirq.o rsmemory.o rsutils.o + +obj-$(ACPI_FUTURE_USAGE) += rsdump.o + +obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o + +obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ + utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ + utstate.o utmutex.o utobject.o utresrc.o diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h new file mode 100644 index 00000000000..3b20786cbb0 --- /dev/null +++ b/drivers/acpi/acpica/accommon.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Name: accommon.h - Common include files for generation of ACPICA source + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef __ACCOMMON_H__ +#define __ACCOMMON_H__ + +/* + * Common set of includes for all ACPICA source files. + * We put them here because we don't want to duplicate them + * in the the source code again and again. + * + * Note: The order of these include files is important. + */ +#include "acconfig.h" /* Global configuration constants */ +#include "acmacros.h" /* C macros */ +#include "aclocal.h" /* Internal data types */ +#include "acobject.h" /* ACPI internal object */ +#include "acstruct.h" /* Common structures */ +#include "acglobal.h" /* All global variables */ +#include "achware.h" /* Hardware defines and interfaces */ +#include "acutils.h" /* Utility interfaces */ + +#endif /* __ACCOMMON_H__ */ diff --git a/include/acpi/acconfig.h b/drivers/acpi/acpica/acconfig.h similarity index 98% rename from include/acpi/acconfig.h rename to drivers/acpi/acpica/acconfig.h index 29feee27f0e..e6777fb883d 100644 --- a/include/acpi/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -61,10 +61,6 @@ * */ -/* Current ACPICA subsystem version in YYYYMMDD format */ - -#define ACPI_CA_VERSION 0x20080926 - /* * OS name, used for the _OS object. The _OS object is essentially obsolete, * but there is a large base of ASL/AML code in existing machines that check @@ -119,6 +115,10 @@ #define ACPI_ROOT_TABLE_SIZE_INCREMENT 4 +/* Maximum number of While() loop iterations before forced abort */ + +#define ACPI_MAX_LOOP_ITERATIONS 0xFFFF + /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) diff --git a/include/acpi/acdebug.h b/drivers/acpi/acpica/acdebug.h similarity index 100% rename from include/acpi/acdebug.h rename to drivers/acpi/acpica/acdebug.h diff --git a/include/acpi/acdispat.h b/drivers/acpi/acpica/acdispat.h similarity index 100% rename from include/acpi/acdispat.h rename to drivers/acpi/acpica/acdispat.h diff --git a/include/acpi/acevents.h b/drivers/acpi/acpica/acevents.h similarity index 97% rename from include/acpi/acevents.h rename to drivers/acpi/acpica/acevents.h index d5d099bf349..07e20135f01 100644 --- a/include/acpi/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -93,11 +93,13 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, */ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); -acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback); +acpi_status +acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context); acpi_status acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block); + struct acpi_gpe_block_info *gpe_block, + void *context); acpi_status acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, diff --git a/include/acpi/acglobal.h b/drivers/acpi/acpica/acglobal.h similarity index 97% rename from include/acpi/acglobal.h rename to drivers/acpi/acpica/acglobal.h index 15dda46b70d..ddb40f5c68f 100644 --- a/include/acpi/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -102,6 +102,12 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); */ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); +/* + * Optionally use default values for the ACPI register widths. Set this to + * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. + */ +ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); + /***************************************************************************** * * Debug support @@ -140,7 +146,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; */ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; -extern u8 acpi_gbl_permanent_mmap; +ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; /* These addresses are calculated from FADT address values */ @@ -326,6 +332,7 @@ ACPI_EXTERN struct acpi_fixed_event_handler ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; +ACPI_EXTERN u32 acpi_current_gpe_count; /***************************************************************************** * diff --git a/include/acpi/achware.h b/drivers/acpi/acpica/achware.h similarity index 89% rename from include/acpi/achware.h rename to drivers/acpi/acpica/achware.h index 97a72b19327..58c69dc49ab 100644 --- a/include/acpi/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -44,11 +44,7 @@ #ifndef __ACHWARE_H__ #define __ACHWARE_H__ -/* PM Timer ticks per second (HZ) */ - -#define PM_TIMER_FREQUENCY 3579545 - -/* Values for the _SST reserved method */ +/* Values for the _SST predefined method */ #define ACPI_SST_INDICATOR_OFF 0 #define ACPI_SST_WORKING 1 @@ -56,8 +52,6 @@ #define ACPI_SST_SLEEPING 3 #define ACPI_SST_SLEEP_CONTEXT 4 -/* Prototypes */ - /* * hwacpi - high level functions */ @@ -75,13 +69,6 @@ acpi_hw_register_read(u32 register_id, u32 * return_value); acpi_status acpi_hw_register_write(u32 register_id, u32 value); -acpi_status -acpi_hw_low_level_read(u32 width, - u32 * value, struct acpi_generic_address *reg); - -acpi_status -acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address *reg); - acpi_status acpi_hw_clear_acpi_status(void); /* @@ -94,13 +81,13 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); acpi_status acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block); + struct acpi_gpe_block_info *gpe_block, void *context); acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info); acpi_status acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block); + struct acpi_gpe_block_info *gpe_block, void *context); acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, @@ -114,7 +101,8 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void); acpi_status acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block); + struct acpi_gpe_block_info *gpe_block, + void *context); #ifdef ACPI_FUTURE_USAGE /* diff --git a/include/acpi/acinterp.h b/drivers/acpi/acpica/acinterp.h similarity index 100% rename from include/acpi/acinterp.h rename to drivers/acpi/acpica/acinterp.h diff --git a/include/acpi/aclocal.h b/drivers/acpi/acpica/aclocal.h similarity index 95% rename from include/acpi/aclocal.h rename to drivers/acpi/acpica/aclocal.h index ecab527cf78..492d02761bb 100644 --- a/include/acpi/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -46,8 +46,6 @@ /* acpisrc:struct_defs -- for acpisrc conversion */ -#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */ -#define ACPI_DO_NOT_WAIT 0 #define ACPI_SERIALIZED 0xFF typedef u32 acpi_mutex_handle; @@ -120,11 +118,6 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { #define ACPI_MAX_LOCK 1 #define ACPI_NUM_LOCK ACPI_MAX_LOCK+1 -/* Owner IDs are used to track namespace nodes for selective deletion */ - -typedef u8 acpi_owner_id; -#define ACPI_OWNER_ID_MAX 0xFF - /* This Thread ID means that the mutex is not in use (unlocked) */ #define ACPI_MUTEX_NOT_ACQUIRED (acpi_thread_id) 0 @@ -165,11 +158,6 @@ typedef enum { ACPI_IMODE_EXECUTE = 0x03 } acpi_interpreter_mode; -union acpi_name_union { - u32 integer; - char ascii[4]; -}; - /* * The Namespace Node describes a named object that appears in the AML. * descriptor_type is used to differentiate between internal descriptors. @@ -216,26 +204,6 @@ struct acpi_namespace_node { #define ANOBJ_IS_BIT_OFFSET 0x40 /* i_aSL only: Reference is a bit offset */ #define ANOBJ_IS_REFERENCED 0x80 /* i_aSL only: Object was referenced */ -/* - * ACPI Table Descriptor. One per ACPI table - */ -struct acpi_table_desc { - acpi_physical_address address; - struct acpi_table_header *pointer; - u32 length; /* Length fixed at 32 bits */ - union acpi_name_union signature; - acpi_owner_id owner_id; - u8 flags; -}; - -/* Flags for above */ - -#define ACPI_TABLE_ORIGIN_UNKNOWN (0) -#define ACPI_TABLE_ORIGIN_MAPPED (1) -#define ACPI_TABLE_ORIGIN_ALLOCATED (2) -#define ACPI_TABLE_ORIGIN_MASK (3) -#define ACPI_TABLE_IS_LOADED (4) - /* One internal RSDT for table management */ struct acpi_internal_rsdt { @@ -266,15 +234,6 @@ struct acpi_ns_search_data { struct acpi_namespace_node *node; }; -/* - * Predefined Namespace items - */ -struct acpi_predefined_names { - char *name; - u8 type; - char *val; -}; - /* Object types used during package copies */ #define ACPI_COPY_TYPE_SIMPLE 0 @@ -487,10 +446,15 @@ struct acpi_gpe_walk_info { struct acpi_gpe_block_info *gpe_block; }; -typedef acpi_status(*acpi_gpe_callback) (struct acpi_gpe_xrupt_info * - gpe_xrupt_info, - struct acpi_gpe_block_info * - gpe_block); +struct acpi_gpe_device_info { + u32 index; + u32 next_block_base_index; + acpi_status status; + struct acpi_namespace_node *gpe_device; +}; + +typedef acpi_status(*acpi_gpe_callback) (struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, void *context); /* Information about each particular fixed event */ @@ -566,6 +530,7 @@ struct acpi_control_state { union acpi_parse_object *predicate_op; u8 *aml_predicate_start; /* Start of if/while predicate */ u8 *package_end; /* End of if/while block */ + u32 loop_count; /* While() loop counter */ }; /* @@ -671,6 +636,12 @@ union acpi_parse_value { union acpi_parse_object *arg; /* arguments and contained ops */ }; +#ifdef ACPI_DISASSEMBLER +#define ACPI_DISASM_ONLY_MEMBERS(a) a; +#else +#define ACPI_DISASM_ONLY_MEMBERS(a) +#endif + #define ACPI_PARSE_COMMON \ union acpi_parse_object *parent; /* Parent op */\ u8 descriptor_type; /* To differentiate various internal objs */\ @@ -790,9 +761,6 @@ struct acpi_parse_state { * ****************************************************************************/ -#define PCI_ROOT_HID_STRING "PNP0A03" -#define PCI_EXPRESS_ROOT_HID_STRING "PNP0A08" - struct acpi_bit_register_info { u8 parent_register; u8 bit_position; @@ -1019,26 +987,4 @@ struct acpi_debug_mem_block { #define ACPI_MEM_LIST_MAX 1 #define ACPI_NUM_MEM_LISTS 2 -struct acpi_memory_list { - char *list_name; - void *list_head; - u16 object_size; - u16 max_depth; - u16 current_depth; - u16 link_offset; - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - - /* Statistics for debug memory tracking only */ - - u32 total_allocated; - u32 total_freed; - u32 max_occupied; - u32 total_size; - u32 current_total_size; - u32 requests; - u32 hits; -#endif -}; - #endif /* __ACLOCAL_H__ */ diff --git a/include/acpi/acmacros.h b/drivers/acpi/acpica/acmacros.h similarity index 83% rename from include/acpi/acmacros.h rename to drivers/acpi/acpica/acmacros.h index 1954c9d1d01..9c127e8e2d6 100644 --- a/include/acpi/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -44,23 +44,6 @@ #ifndef __ACMACROS_H__ #define __ACMACROS_H__ -/* - * Data manipulation macros - */ -#define ACPI_LOWORD(l) ((u16)(u32)(l)) -#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) -#define ACPI_LOBYTE(l) ((u8)(u16)(l)) -#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) - -#define ACPI_SET_BIT(target,bit) ((target) |= (bit)) -#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) -#define ACPI_MIN(a,b) (((a)<(b))?(a):(b)) -#define ACPI_MAX(a,b) (((a)>(b))?(a):(b)) - -/* Size calculation */ - -#define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) - /* * Extract data using a pointer. Any more than a byte and we * get into potential aligment issues -- see the STORE macros below. @@ -75,39 +58,6 @@ #define ACPI_SET32(ptr) *ACPI_CAST_PTR (u32, ptr) #define ACPI_SET64(ptr) *ACPI_CAST_PTR (u64, ptr) -/* - * Pointer manipulation - */ -#define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p)) -#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p)) -#define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_size)(b))) -#define ACPI_PTR_DIFF(a, b) (acpi_size) (ACPI_CAST_PTR (u8, (a)) - ACPI_CAST_PTR (u8, (b))) - -/* Pointer/Integer type conversions */ - -#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL, (acpi_size) i) -#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p, (void *) NULL) -#define ACPI_OFFSET(d, f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f), (void *) NULL) -#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) -#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) - -#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED -#define ACPI_COMPARE_NAME(a, b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b))) -#else -#define ACPI_COMPARE_NAME(a, b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE)) -#endif - -/* - * Full 64-bit integer must be available on both 32-bit and 64-bit platforms - */ -struct acpi_integer_overlay { - u32 lo_dword; - u32 hi_dword; -}; - -#define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword) -#define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword) - /* * printf() format helpers */ @@ -209,7 +159,7 @@ struct acpi_integer_overlay { /* * The hardware does not support unaligned transfers. We must move the * data one byte at a time. These macros work whether the source or - * the destination (or both) is/are unaligned. (Little-endian move) + * the destination (or both) is/are unaligned. (Little-endian move) */ /* 16-bit source, 16/32/64 destination */ @@ -357,12 +307,6 @@ struct acpi_integer_overlay { {(u32)(Pargs), (u32)(Iargs), (u32)(flags), obj_type, class, type} #endif -#ifdef ACPI_DISASSEMBLER -#define ACPI_DISASM_ONLY_MEMBERS(a) a; -#else -#define ACPI_DISASM_ONLY_MEMBERS(a) -#endif - #define ARG_TYPE_WIDTH 5 #define ARG_1(x) ((u32)(x)) #define ARG_2(x) ((u32)(x) << (1 * ARG_TYPE_WIDTH)) @@ -388,32 +332,16 @@ struct acpi_integer_overlay { #define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) #define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) -#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) -/* - * Module name is include in both debug and non-debug versions primarily for - * error messages. The __FILE__ macro is not very useful for this, because it - * often includes the entire pathname to the module - */ -#define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name; -#else -#define ACPI_MODULE_NAME(name) -#endif - /* * Ascii error messages can be configured out */ #ifndef ACPI_NO_ERROR_MESSAGES -#define AE_INFO _acpi_module_name, __LINE__ /* * Error reporting. Callers module and line number are inserted by AE_INFO, * the plist contains a set of parens to allow variable-length lists. * These macros are used for both the debug and non-debug versions of the code. */ -#define ACPI_INFO(plist) acpi_ut_info plist -#define ACPI_WARNING(plist) acpi_ut_warning plist -#define ACPI_EXCEPTION(plist) acpi_ut_exception plist -#define ACPI_ERROR(plist) acpi_ut_error plist #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); @@ -421,50 +349,18 @@ struct acpi_integer_overlay { /* No error messages */ -#define ACPI_INFO(plist) -#define ACPI_WARNING(plist) -#define ACPI_EXCEPTION(plist) -#define ACPI_ERROR(plist) #define ACPI_ERROR_NAMESPACE(s, e) #define ACPI_ERROR_METHOD(s, n, p, e) -#endif +#endif /* ACPI_NO_ERROR_MESSAGES */ /* * Debug macros that are conditionally compiled */ #ifdef ACPI_DEBUG_OUTPUT -/* - * Common parameters used for debug output functions: - * line number, function name, module(file) name, component ID - */ -#define ACPI_DEBUG_PARAMETERS __LINE__, ACPI_GET_FUNCTION_NAME, _acpi_module_name, _COMPONENT - /* * Function entry tracing */ - -/* - * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header, - * define it now. This is the case where there the compiler does not support - * a __func__ macro or equivalent. - */ -#ifndef ACPI_GET_FUNCTION_NAME -#define ACPI_GET_FUNCTION_NAME _acpi_function_name -/* - * The Name parameter should be the procedure name as a quoted string. - * The function name is also used by the function exit macros below. - * Note: (const char) is used to be compatible with the debug interfaces - * and macros such as __func__. - */ -#define ACPI_FUNCTION_NAME(name) static const char _acpi_function_name[] = #name; - -#else -/* Compiler supports __func__ (or equivalent) -- Ignore this macro */ - -#define ACPI_FUNCTION_NAME(name) -#endif - #ifdef CONFIG_ACPI_DEBUG_FUNC_TRACE #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ @@ -584,15 +480,6 @@ struct acpi_integer_overlay { #define ACPI_DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a) #define ACPI_DUMP_BUFFER(a, b) acpi_ut_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT) -/* - * Master debug print macros - * Print iff: - * 1) Debug print for the current component is enabled - * 2) Debug error level or trace level for the print statement is enabled - */ -#define ACPI_DEBUG_PRINT(plist) acpi_ut_debug_print plist -#define ACPI_DEBUG_PRINT_RAW(plist) acpi_ut_debug_print_raw plist - #else /* * This is the non-debug case -- make everything go away, @@ -603,7 +490,6 @@ struct acpi_integer_overlay { #define ACPI_DEBUG_DEFINE(a) do { } while(0) #define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0) -#define ACPI_FUNCTION_NAME(a) do { } while(0) #define ACPI_FUNCTION_TRACE(a) do { } while(0) #define ACPI_FUNCTION_TRACE_PTR(a, b) do { } while(0) #define ACPI_FUNCTION_TRACE_U32(a, b) do { } while(0) @@ -619,8 +505,6 @@ struct acpi_integer_overlay { #define ACPI_DUMP_PATHNAME(a, b, c, d) do { } while(0) #define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0) #define ACPI_DUMP_BUFFER(a, b) do { } while(0) -#define ACPI_DEBUG_PRINT(pl) do { } while(0) -#define ACPI_DEBUG_PRINT_RAW(pl) do { } while(0) #define return_VOID return #define return_ACPI_STATUS(s) return(s) @@ -629,7 +513,7 @@ struct acpi_integer_overlay { #define return_UINT32(s) return(s) #define return_PTR(s) return(s) -#endif +#endif /* ACPI_DEBUG_OUTPUT */ /* * Some code only gets executed when the debugger is built in. diff --git a/include/acpi/acnamesp.h b/drivers/acpi/acpica/acnamesp.h similarity index 98% rename from include/acpi/acnamesp.h rename to drivers/acpi/acpica/acnamesp.h index db4e6f67785..46cb5b46d28 100644 --- a/include/acpi/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -182,7 +182,9 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); */ acpi_status acpi_ns_check_predefined_names(struct acpi_namespace_node *node, - union acpi_operand_object *return_object); + u32 user_param_count, + acpi_status return_status, + union acpi_operand_object **return_object); const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct acpi_namespace_node @@ -191,6 +193,7 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct void acpi_ns_check_parameter_count(char *pathname, struct acpi_namespace_node *node, + u32 user_param_count, const union acpi_predefined_info *info); /* diff --git a/include/acpi/acobject.h b/drivers/acpi/acpica/acobject.h similarity index 100% rename from include/acpi/acobject.h rename to drivers/acpi/acpica/acobject.h diff --git a/include/acpi/acopcode.h b/drivers/acpi/acpica/acopcode.h similarity index 100% rename from include/acpi/acopcode.h rename to drivers/acpi/acpica/acopcode.h diff --git a/include/acpi/acparser.h b/drivers/acpi/acpica/acparser.h similarity index 100% rename from include/acpi/acparser.h rename to drivers/acpi/acpica/acparser.h diff --git a/include/acpi/acpredef.h b/drivers/acpi/acpica/acpredef.h similarity index 100% rename from include/acpi/acpredef.h rename to drivers/acpi/acpica/acpredef.h diff --git a/include/acpi/acresrc.h b/drivers/acpi/acpica/acresrc.h similarity index 100% rename from include/acpi/acresrc.h rename to drivers/acpi/acpica/acresrc.h diff --git a/include/acpi/acstruct.h b/drivers/acpi/acpica/acstruct.h similarity index 100% rename from include/acpi/acstruct.h rename to drivers/acpi/acpica/acstruct.h diff --git a/include/acpi/actables.h b/drivers/acpi/acpica/actables.h similarity index 98% rename from include/acpi/actables.h rename to drivers/acpi/acpica/actables.h index 0cbe1b9ab52..7ce6e33c7f7 100644 --- a/include/acpi/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -94,6 +94,8 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); /* * tbutils - table manager utilities */ +acpi_status acpi_tb_initialize_facs(void); + u8 acpi_tb_tables_loaded(void); void diff --git a/include/acpi/acutils.h b/drivers/acpi/acpica/acutils.h similarity index 93% rename from include/acpi/acutils.h rename to drivers/acpi/acpica/acutils.h index d8307b2987e..80d8813484f 100644 --- a/include/acpi/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -297,42 +297,6 @@ void acpi_ut_report_info(char *module_name, u32 line_number); void acpi_ut_report_warning(char *module_name, u32 line_number); -/* Error and message reporting interfaces */ - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_debug_print(u32 requested_debug_level, - u32 line_number, - const char *function_name, - const char *module_name, - u32 component_id, - const char *format, ...) ACPI_PRINTF_LIKE(6); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_debug_print_raw(u32 requested_debug_level, - u32 line_number, - const char *function_name, - const char *module_name, - u32 component_id, - const char *format, ...) ACPI_PRINTF_LIKE(6); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_error(const char *module_name, - u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_exception(const char *module_name, - u32 line_number, - acpi_status status, - const char *format, ...) ACPI_PRINTF_LIKE(4); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_warning(const char *module_name, - u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_info(const char *module_name, - u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); - /* * utdelete - Object deletion and reference counts */ diff --git a/include/acpi/amlcode.h b/drivers/acpi/acpica/amlcode.h similarity index 100% rename from include/acpi/amlcode.h rename to drivers/acpi/acpica/amlcode.h diff --git a/include/acpi/amlresrc.h b/drivers/acpi/acpica/amlresrc.h similarity index 100% rename from include/acpi/amlresrc.h rename to drivers/acpi/acpica/amlresrc.h diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/acpica/dsfield.c similarity index 99% rename from drivers/acpi/dispatcher/dsfield.c rename to drivers/acpi/acpica/dsfield.c index f988a5e7d2b..53e27bc5a73 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -42,11 +42,12 @@ */ #include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "acparser.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsfield") diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/acpica/dsinit.c similarity index 98% rename from drivers/acpi/dispatcher/dsinit.c rename to drivers/acpi/acpica/dsinit.c index 949f7c75029..eb144b13d8f 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acdispat.h" +#include "acnamesp.h" +#include "actables.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsinit") diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/acpica/dsmethod.c similarity index 98% rename from drivers/acpi/dispatcher/dsmethod.c rename to drivers/acpi/acpica/dsmethod.c index 279a5a60a0d..14b8b8ed802 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -42,11 +42,14 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" +#ifdef ACPI_DISASSEMBLER #include +#endif #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsmethod") @@ -412,6 +415,9 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { status = obj_desc->method.implementation(next_walk_state); + if (status == AE_OK) { + status = AE_CTRL_TERMINATE; + } } return_ACPI_STATUS(status); diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c similarity index 99% rename from drivers/acpi/dispatcher/dsmthdat.c rename to drivers/acpi/acpica/dsmthdat.c index d03f81bd1bc..da0f5468184 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acdispat.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsmthdat") diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/acpica/dsobject.c similarity index 99% rename from drivers/acpi/dispatcher/dsobject.c rename to drivers/acpi/acpica/dsobject.c index 4f08e599d07..15c628e6aa0 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -42,11 +42,12 @@ */ #include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsobject") diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/acpica/dsopcode.c similarity index 96% rename from drivers/acpi/dispatcher/dsopcode.c rename to drivers/acpi/acpica/dsopcode.c index 69fae5905bb..0c3b4dd60e8 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -43,13 +43,14 @@ */ #include -#include -#include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "acevents.h" +#include "actables.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsopcode") @@ -1140,9 +1141,28 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, op->common.aml_opcode, walk_state)); switch (op->common.aml_opcode) { - case AML_IF_OP: case AML_WHILE_OP: + /* + * If this is an additional iteration of a while loop, continue. + * There is no need to allocate a new control state. + */ + if (walk_state->control_state) { + if (walk_state->control_state->control.aml_predicate_start + == (walk_state->parser_state.aml - 1)) { + + /* Reset the state to start-of-loop */ + + walk_state->control_state->common.state = + ACPI_CONTROL_CONDITIONAL_EXECUTING; + break; + } + } + + /*lint -fallthrough */ + + case AML_IF_OP: + /* * IF/WHILE: Create a new control state to manage these * constructs. We need to manage these as a stack, in order @@ -1243,13 +1263,36 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); - if (walk_state->control_state->common.value) { + control_state = walk_state->control_state; + if (control_state->common.value) { - /* Predicate was true, go back and evaluate it again! */ + /* Predicate was true, the body of the loop was just executed */ + /* + * This loop counter mechanism allows the interpreter to escape + * possibly infinite loops. This can occur in poorly written AML + * when the hardware does not respond within a while loop and the + * loop does not implement a timeout. + */ + control_state->control.loop_count++; + if (control_state->control.loop_count > + ACPI_MAX_LOOP_ITERATIONS) { + status = AE_AML_INFINITE_LOOP; + break; + } + + /* + * Go back and evaluate the predicate and maybe execute the loop + * another time + */ status = AE_CTRL_PENDING; + walk_state->aml_last_while = + control_state->control.aml_predicate_start; + break; } + /* Predicate was false, terminate this while loop */ + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op)); @@ -1257,9 +1300,6 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, control_state = acpi_ut_pop_generic_state(&walk_state->control_state); - - walk_state->aml_last_while = - control_state->control.aml_predicate_start; acpi_ut_delete_generic_state(control_state); break; diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/acpica/dsutils.c similarity index 99% rename from drivers/acpi/dispatcher/dsutils.c rename to drivers/acpi/acpica/dsutils.c index b398982f0d8..dabc23a4617 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -42,12 +42,13 @@ */ #include -#include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "acdebug.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsutils") diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/acpica/dswexec.c similarity index 99% rename from drivers/acpi/dispatcher/dswexec.c rename to drivers/acpi/acpica/dswexec.c index 396fe12078c..350e6656bc8 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -43,12 +43,13 @@ */ #include -#include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "acdebug.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswexec") diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/acpica/dswload.c similarity index 99% rename from drivers/acpi/dispatcher/dswload.c rename to drivers/acpi/acpica/dswload.c index dff7a3e445a..3023ceaa8d5 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -42,12 +42,13 @@ */ #include -#include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "acevents.h" #ifdef ACPI_ASL_COMPILER #include diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/acpica/dswscope.c similarity index 99% rename from drivers/acpi/dispatcher/dswscope.c rename to drivers/acpi/acpica/dswscope.c index 9e607326587..908645e72f0 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acdispat.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswscope") diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/acpica/dswstate.c similarity index 99% rename from drivers/acpi/dispatcher/dswstate.c rename to drivers/acpi/acpica/dswstate.c index b00d4af791a..40f92bf7dce 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acdispat.h" +#include "acnamesp.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswstate") diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/acpica/evevent.c similarity index 96% rename from drivers/acpi/events/evevent.c rename to drivers/acpi/acpica/evevent.c index c56c5c6ea77..803edd9e3f6 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acevents.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evevent") @@ -72,8 +73,8 @@ acpi_status acpi_ev_initialize_events(void) /* * Initialize the Fixed and General Purpose Events. This is done prior to - * enabling SCIs to prevent interrupts from occurring before the handlers are - * installed. + * enabling SCIs to prevent interrupts from occurring before the handlers + * are installed. */ status = acpi_ev_fixed_event_initialize(); if (ACPI_FAILURE(status)) { @@ -192,8 +193,8 @@ static acpi_status acpi_ev_fixed_event_initialize(void) acpi_status status; /* - * Initialize the structure that keeps track of fixed event handlers - * and enable the fixed events. + * Initialize the structure that keeps track of fixed event handlers and + * enable the fixed events. */ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { acpi_gbl_fixed_event_handlers[i].handler = NULL; @@ -237,7 +238,7 @@ u32 acpi_ev_fixed_event_detect(void) /* * Read the fixed feature status and enable registers, as all the cases - * depend on their values. Ignore errors here. + * depend on their values. Ignore errors here. */ (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status); (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable); @@ -291,8 +292,8 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) status_register_id, 1); /* - * Make sure we've got a handler. If not, report an error. - * The event is disabled to prevent further interrupts. + * Make sure we've got a handler. If not, report an error. The event is + * disabled to prevent further interrupts. */ if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/acpica/evgpe.c similarity index 94% rename from drivers/acpi/events/evgpe.c rename to drivers/acpi/acpica/evgpe.c index f45c74fe745..f345ced3647 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evgpe") @@ -125,7 +126,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, (1 << (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); - /* 1) Disable case. Simply clear all enable bits */ + /* 1) Disable case. Simply clear all enable bits */ if (type == ACPI_GPE_DISABLE) { ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, @@ -134,7 +135,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, return_ACPI_STATUS(AE_OK); } - /* 2) Enable case. Set/Clear the appropriate enable bits */ + /* 2) Enable case. Set/Clear the appropriate enable bits */ switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { case ACPI_GPE_TYPE_WAKE: @@ -295,7 +296,7 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) * * FUNCTION: acpi_ev_get_gpe_event_info * - * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 + * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 * gpe_number - Raw GPE number * * RETURN: A GPE event_info struct. NULL if not a valid GPE @@ -372,7 +373,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, * * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * - * DESCRIPTION: Detect if any GP events have occurred. This function is + * DESCRIPTION: Detect if any GP events have occurred. This function is * executed at interrupt level. * ******************************************************************************/ @@ -400,8 +401,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* * We need to obtain the GPE lock for both the data structs and registers - * Note: Not necessary to obtain the hardware lock, since the GPE registers - * are owned by the gpe_lock. + * Note: Not necessary to obtain the hardware lock, since the GPE + * registers are owned by the gpe_lock. */ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); @@ -410,9 +411,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) gpe_block = gpe_xrupt_list->gpe_block_list_head; while (gpe_block) { /* - * Read all of the 8-bit GPE status and enable registers - * in this GPE block, saving all of them. - * Find all currently active GP events. + * Read all of the 8-bit GPE status and enable registers in this GPE + * block, saving all of them. Find all currently active GP events. */ for (i = 0; i < gpe_block->register_count; i++) { @@ -423,10 +423,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Read the Status Register */ status = - acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH, - &status_reg, - &gpe_register_info-> - status_address); + acpi_read(&status_reg, + &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -434,10 +432,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Read the Enable Register */ status = - acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH, - &enable_reg, - &gpe_register_info-> - enable_address); + acpi_read(&enable_reg, + &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -527,8 +523,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) (void)acpi_ev_enable_gpe(gpe_event_info, FALSE); /* - * Take a snapshot of the GPE info for this level - we copy the - * info to prevent a race condition with remove_handler/remove_block. + * Take a snapshot of the GPE info for this level - we copy the info to + * prevent a race condition with remove_handler/remove_block. */ ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, sizeof(struct acpi_gpe_event_info)); @@ -539,8 +535,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) } /* - * Must check for control method type dispatch one more - * time to avoid race with ev_gpe_install_handler + * Must check for control method type dispatch one more time to avoid a + * race with ev_gpe_install_handler */ if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) { @@ -584,8 +580,8 @@ static void acpi_ev_asynch_enable_gpe(void *context) if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) { /* - * GPE is level-triggered, we clear the GPE status bit after - * handling the event. + * GPE is level-triggered, we clear the GPE status bit after handling + * the event. */ status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { @@ -624,7 +620,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) acpi_os_gpe_count(gpe_number); /* - * If edge-triggered, clear the GPE status bit now. Note that + * If edge-triggered, clear the GPE status bit now. Note that * level-triggered events are cleared after the GPE is serviced. */ if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == @@ -650,7 +646,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) /* * Invoke the installed handler (at interrupt level) - * Ignore return status for now. TBD: leave GPE disabled on error? + * Ignore return status for now. + * TBD: leave GPE disabled on error? */ (void)gpe_event_info->dispatch.handler->address(gpe_event_info-> dispatch. @@ -708,7 +705,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) gpe_number)); /* - * Disable the GPE. The GPE will remain disabled until the ACPI + * Disable the GPE. The GPE will remain disabled until the ACPICA * Core Subsystem is restarted, or a handler is installed. */ status = acpi_ev_disable_gpe(gpe_event_info); diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c similarity index 94% rename from drivers/acpi/events/evgpeblk.c rename to drivers/acpi/acpica/evgpeblk.c index 73c058e2f5c..484cc0565d5 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evgpeblk") @@ -124,6 +125,7 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) * FUNCTION: acpi_ev_walk_gpe_list * * PARAMETERS: gpe_walk_callback - Routine called for each GPE block + * Context - Value passed to callback * * RETURN: Status * @@ -131,7 +133,8 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) * ******************************************************************************/ -acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) +acpi_status +acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context) { struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_info; @@ -154,8 +157,13 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) /* One callback per GPE block */ - status = gpe_walk_callback(gpe_xrupt_info, gpe_block); + status = + gpe_walk_callback(gpe_xrupt_info, gpe_block, + context); if (ACPI_FAILURE(status)) { + if (status == AE_CTRL_END) { /* Callback abort */ + status = AE_OK; + } goto unlock_and_exit; } @@ -186,7 +194,8 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) acpi_status acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block) + struct acpi_gpe_block_info *gpe_block, + void *context) { struct acpi_gpe_event_info *gpe_event_info; u32 i; @@ -309,17 +318,17 @@ acpi_ev_save_method_info(acpi_handle obj_handle, (gpe_block->block_base_number + (gpe_block->register_count * 8)))) { /* - * Not valid for this GPE block, just ignore it - * However, it may be valid for a different GPE block, since GPE0 and GPE1 - * methods both appear under \_GPE. + * Not valid for this GPE block, just ignore it. However, it may be + * valid for a different GPE block, since GPE0 and GPE1 methods both + * appear under \_GPE. */ return_ACPI_STATUS(AE_OK); } /* - * Now we can add this information to the gpe_event_info block - * for use during dispatch of this GPE. Default type is RUNTIME, although - * this may change when the _PRW methods are executed later. + * Now we can add this information to the gpe_event_info block for use + * during dispatch of this GPE. Default type is RUNTIME, although this may + * change when the _PRW methods are executed later. */ gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; @@ -394,8 +403,8 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, gpe_block = gpe_info->gpe_block; /* - * The _PRW object must return a package, we are only interested - * in the first element + * The _PRW object must return a package, we are only interested in the + * first element */ obj_desc = pkg_desc->package.elements[0]; @@ -434,7 +443,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, /* * Is this GPE within this block? * - * TRUE iff these conditions are true: + * TRUE if and only if these conditions are true: * 1) The GPE devices match. * 2) The GPE index(number) is within the range of the Gpe Block * associated with the GPE device. @@ -457,6 +466,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, if (ACPI_FAILURE(status)) { goto cleanup; } + status = acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_DISABLE); @@ -476,9 +486,9 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, * RETURN: A GPE interrupt block * * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt - * block per unique interrupt level used for GPEs. - * Should be called only when the GPE lists are semaphore locked - * and not subject to change. + * block per unique interrupt level used for GPEs. Should be + * called only when the GPE lists are semaphore locked and not + * subject to change. * ******************************************************************************/ @@ -608,8 +618,9 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) * * FUNCTION: acpi_ev_install_gpe_block * - * PARAMETERS: gpe_block - New GPE block - * interrupt_number - Xrupt to be associated with this GPE block + * PARAMETERS: gpe_block - New GPE block + * interrupt_number - Xrupt to be associated with this + * GPE block * * RETURN: Status * @@ -666,7 +677,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, * * FUNCTION: acpi_ev_delete_gpe_block * - * PARAMETERS: gpe_block - Existing GPE block + * PARAMETERS: gpe_block - Existing GPE block * * RETURN: Status * @@ -688,7 +699,8 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) /* Disable all GPEs in this block */ - status = acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block); + status = + acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL); if (!gpe_block->previous && !gpe_block->next) { @@ -715,6 +727,9 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) acpi_os_release_lock(acpi_gbl_gpe_lock, flags); } + acpi_current_gpe_count -= + gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH; + /* Free the gpe_block */ ACPI_FREE(gpe_block->register_info); @@ -786,9 +801,9 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) /* * Initialize the GPE Register and Event structures. A goal of these - * tables is to hide the fact that there are two separate GPE register sets - * in a given GPE hardware block, the status registers occupy the first half, - * and the enable registers occupy the second half. + * tables is to hide the fact that there are two separate GPE register + * sets in a given GPE hardware block, the status registers occupy the + * first half, and the enable registers occupy the second half. */ this_register = gpe_register_info; this_event = gpe_event_info; @@ -816,10 +831,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) ACPI_GPE_REGISTER_WIDTH; this_register->enable_address.bit_width = ACPI_GPE_REGISTER_WIDTH; - this_register->status_address.bit_offset = - ACPI_GPE_REGISTER_WIDTH; - this_register->enable_address.bit_offset = - ACPI_GPE_REGISTER_WIDTH; + this_register->status_address.bit_offset = 0; + this_register->enable_address.bit_offset = 0; /* Init the event_info for each GPE within this register */ @@ -832,18 +845,14 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) /* Disable all GPEs within this register */ - status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0x00, - &this_register-> - enable_address); + status = acpi_write(0x00, &this_register->enable_address); if (ACPI_FAILURE(status)) { goto error_exit; } /* Clear any pending GPE events within this register */ - status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0xFF, - &this_register-> - status_address); + status = acpi_write(0xFF, &this_register->status_address); if (ACPI_FAILURE(status)) { goto error_exit; } @@ -956,6 +965,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, gpe_device->name.ascii, gpe_block->register_count, interrupt_number)); + /* Update global count of currently available GPEs */ + + acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH; return_ACPI_STATUS(AE_OK); } @@ -1055,7 +1067,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, /* Enable all valid runtime GPEs found above */ - status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); + status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block, NULL); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p", gpe_block)); diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/acpica/evmisc.c similarity index 93% rename from drivers/acpi/events/evmisc.c rename to drivers/acpi/acpica/evmisc.c index 1d5670be729..5f893057bcc 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -42,18 +42,15 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evmisc") -/* Pointer to FACS needed for the Global Lock */ -static struct acpi_table_facs *facs = NULL; - /* Local prototypes */ - static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); static u32 acpi_ev_global_lock_handler(void *context); @@ -152,7 +149,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, break; default: + /* All other types are not supported */ + return (AE_TYPE); } } @@ -193,9 +192,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, acpi_ut_delete_generic_state(notify_info); } } else { - /* - * There is no notify handler (per-device or system) for this device. - */ + /* There is no notify handler (per-device or system) for this device */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No notify handler for Notify (%4.4s, %X) node %p\n", acpi_ut_get_node_name(node), notify_value, @@ -229,9 +227,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) ACPI_FUNCTION_ENTRY(); /* - * We will invoke a global notify handler if installed. - * This is done _before_ we invoke the per-device handler attached - * to the device. + * We will invoke a global notify handler if installed. This is done + * _before_ we invoke the per-device handler attached to the device. */ if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) { @@ -299,7 +296,7 @@ static u32 acpi_ev_global_lock_handler(void *context) * If we don't get it now, it will be marked pending and we will * take another interrupt when it becomes free. */ - ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { /* Got the lock, now wake all threads waiting for it */ @@ -336,34 +333,27 @@ acpi_status acpi_ev_init_global_lock_handler(void) ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); - status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - ACPI_CAST_INDIRECT_PTR(struct - acpi_table_header, - &facs)); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } + /* Attempt installation of the global lock handler */ - acpi_gbl_global_lock_present = TRUE; status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, acpi_ev_global_lock_handler, NULL); /* - * If the global lock does not exist on this platform, the attempt - * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) - * Map to AE_OK, but mark global lock as not present. - * Any attempt to actually use the global lock will be flagged - * with an error. + * If the global lock does not exist on this platform, the attempt to + * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). + * Map to AE_OK, but mark global lock as not present. Any attempt to + * actually use the global lock will be flagged with an error. */ if (status == AE_NO_HARDWARE_RESPONSE) { ACPI_ERROR((AE_INFO, "No response from Global Lock hardware, disabling lock")); acpi_gbl_global_lock_present = FALSE; - status = AE_OK; + return_ACPI_STATUS(AE_OK); } + acpi_gbl_global_lock_present = TRUE; return_ACPI_STATUS(status); } @@ -462,8 +452,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) } /* - * Make sure that a global lock actually exists. If not, just treat - * the lock as a standard mutex. + * Make sure that a global lock actually exists. If not, just treat the + * lock as a standard mutex. */ if (!acpi_gbl_global_lock_present) { acpi_gbl_global_lock_acquired = TRUE; @@ -472,7 +462,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) /* Attempt to acquire the actual hardware lock */ - ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { /* We got the lock */ @@ -536,7 +526,7 @@ acpi_status acpi_ev_release_global_lock(void) /* Allow any thread to release the lock */ - ACPI_RELEASE_GLOBAL_LOCK(facs, pending); + ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending); /* * If the pending bit was set, we must write GBL_RLS to the control @@ -582,8 +572,8 @@ void acpi_ev_terminate(void) if (acpi_gbl_events_initialized) { /* - * Disable all event-related functionality. - * In all cases, on error, print a message but obviously we don't abort. + * Disable all event-related functionality. In all cases, on error, + * print a message but obviously we don't abort. */ /* Disable all fixed events */ @@ -599,7 +589,7 @@ void acpi_ev_terminate(void) /* Disable all GPEs in all GPE blocks */ - status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); + status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); /* Remove SCI handler */ @@ -617,7 +607,7 @@ void acpi_ev_terminate(void) /* Deallocate all handler objects installed within GPE info structs */ - status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers); + status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL); /* Return to original mode if necessary */ diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/acpica/evregion.c similarity index 91% rename from drivers/acpi/events/evregion.c rename to drivers/acpi/acpica/evregion.c index 236fbd1ca43..665c0887ab4 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -42,22 +42,15 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evregion") -#define ACPI_NUM_DEFAULT_SPACES 4 -static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { - ACPI_ADR_SPACE_SYSTEM_MEMORY, - ACPI_ADR_SPACE_SYSTEM_IO, - ACPI_ADR_SPACE_PCI_CONFIG, - ACPI_ADR_SPACE_DATA_TABLE -}; /* Local prototypes */ - static acpi_status acpi_ev_reg_run(acpi_handle obj_handle, u32 level, void *context, void **return_value); @@ -66,6 +59,17 @@ static acpi_status acpi_ev_install_handler(acpi_handle obj_handle, u32 level, void *context, void **return_value); +/* These are the address spaces that will get default handlers */ + +#define ACPI_NUM_DEFAULT_SPACES 4 + +static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { + ACPI_ADR_SPACE_SYSTEM_MEMORY, + ACPI_ADR_SPACE_SYSTEM_IO, + ACPI_ADR_SPACE_PCI_CONFIG, + ACPI_ADR_SPACE_DATA_TABLE +}; + /******************************************************************************* * * FUNCTION: acpi_ev_install_region_handlers @@ -91,18 +95,19 @@ acpi_status acpi_ev_install_region_handlers(void) } /* - * All address spaces (PCI Config, EC, SMBus) are scope dependent - * and registration must occur for a specific device. + * All address spaces (PCI Config, EC, SMBus) are scope dependent and + * registration must occur for a specific device. * - * In the case of the system memory and IO address spaces there is currently - * no device associated with the address space. For these we use the root. + * In the case of the system memory and IO address spaces there is + * currently no device associated with the address space. For these we + * use the root. * - * We install the default PCI config space handler at the root so - * that this space is immediately available even though the we have - * not enumerated all the PCI Root Buses yet. This is to conform - * to the ACPI specification which states that the PCI config - * space must be always available -- even though we are nowhere - * near ready to find the PCI root buses at this point. + * We install the default PCI config space handler at the root so that + * this space is immediately available even though the we have not + * enumerated all the PCI Root Buses yet. This is to conform to the ACPI + * specification which states that the PCI config space must be always + * available -- even though we are nowhere near ready to find the PCI root + * buses at this point. * * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler * has already been installed (via acpi_install_address_space_handler). @@ -160,12 +165,11 @@ acpi_status acpi_ev_initialize_op_regions(void) return_ACPI_STATUS(status); } - /* - * Run the _REG methods for op_regions in each default address space - */ - for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { + /* Run the _REG methods for op_regions in each default address space */ - /* TBD: Make sure handler is the DEFAULT handler, otherwise + for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { + /* + * TBD: Make sure handler is the DEFAULT handler, otherwise * _REG will have already been run. */ status = acpi_ev_execute_reg_methods(acpi_gbl_root_node, @@ -318,13 +322,13 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } /* - * It may be the case that the region has never been initialized + * It may be the case that the region has never been initialized. * Some types of regions require special init code */ if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { - /* - * This region has not been initialized yet, do it - */ + + /* This region has not been initialized yet, do it */ + region_setup = handler_desc->address_space.setup; if (!region_setup) { @@ -339,9 +343,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } /* - * We must exit the interpreter because the region - * setup will potentially execute control methods - * (e.g., _REG method for this region) + * We must exit the interpreter because the region setup will + * potentially execute control methods (for example, the _REG method + * for this region) */ acpi_ex_exit_interpreter(); @@ -364,9 +368,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, return_ACPI_STATUS(status); } - /* - * Region initialization may have been completed by region_setup - */ + /* Region initialization may have been completed by region_setup */ + if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; @@ -521,8 +524,8 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, } /* - * If the region has been activated, call the setup handler - * with the deactivate notification + * If the region has been activated, call the setup handler with + * the deactivate notification */ if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { region_setup = handler_obj->address_space.setup; @@ -668,8 +671,8 @@ acpi_ev_install_handler(acpi_handle obj_handle, } /* - * We only care about regions.and objects - * that are allowed to have address space handlers + * We only care about regions and objects that are allowed to have + * address space handlers */ if ((node->type != ACPI_TYPE_DEVICE) && (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) { @@ -710,9 +713,9 @@ acpi_ev_install_handler(acpi_handle obj_handle, /* * Since the object we found it on was a device, then it * means that someone has already installed a handler for - * the branch of the namespace from this device on. Just + * the branch of the namespace from this device on. Just * bail out telling the walk routine to not traverse this - * branch. This preserves the scoping rule for handlers. + * branch. This preserves the scoping rule for handlers. */ return (AE_CTRL_DEPTH); } @@ -723,9 +726,8 @@ acpi_ev_install_handler(acpi_handle obj_handle, } /* - * As long as the device didn't have a handler for this - * space we don't care about it. We just ignore it and - * proceed. + * As long as the device didn't have a handler for this space we + * don't care about it. We just ignore it and proceed. */ return (AE_OK); } @@ -733,16 +735,14 @@ acpi_ev_install_handler(acpi_handle obj_handle, /* Object is a Region */ if (obj_desc->region.space_id != handler_obj->address_space.space_id) { - /* - * This region is for a different address space - * -- just ignore it - */ + + /* This region is for a different address space, just ignore it */ + return (AE_OK); } /* - * Now we have a region and it is for the handler's address - * space type. + * Now we have a region and it is for the handler's address space type. * * First disconnect region for any previous handler (if any) */ @@ -786,9 +786,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, ACPI_FUNCTION_TRACE(ev_install_space_handler); /* - * This registration is valid for only the types below - * and the root. This is where the default handlers - * get placed. + * This registration is valid for only the types below and the root. This + * is where the default handlers get placed. */ if ((node->type != ACPI_TYPE_DEVICE) && (node->type != ACPI_TYPE_PROCESSOR) && @@ -848,8 +847,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { /* - * The attached device object already exists. - * Make sure the handler is not already installed. + * The attached device object already exists. Make sure the handler + * is not already installed. */ handler_obj = obj_desc->device.handler; @@ -864,8 +863,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, handler) { /* * It is (relatively) OK to attempt to install the SAME - * handler twice. This can easily happen - * with PCI_Config space. + * handler twice. This can easily happen with the + * PCI_Config space. */ status = AE_SAME_HANDLER; goto unlock_and_exit; @@ -925,9 +924,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, /* * Install the handler * - * At this point there is no existing handler. - * Just allocate the object for the handler and link it - * into the list. + * At this point there is no existing handler. Just allocate the object + * for the handler and link it into the list. */ handler_obj = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER); @@ -1000,11 +998,10 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, ACPI_FUNCTION_TRACE(ev_execute_reg_methods); /* - * Run all _REG methods for all Operation Regions for this - * space ID. This is a separate walk in order to handle any - * interdependencies between regions and _REG methods. (i.e. handlers - * must be installed for all regions of this Space ID before we - * can run any _REG methods) + * Run all _REG methods for all Operation Regions for this space ID. This + * is a separate walk in order to handle any interdependencies between + * regions and _REG methods. (i.e. handlers must be installed for all + * regions of this Space ID before we can run any _REG methods) */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, @@ -1042,8 +1039,8 @@ acpi_ev_reg_run(acpi_handle obj_handle, } /* - * We only care about regions.and objects - * that are allowed to have address space handlers + * We only care about regions.and objects that are allowed to have address + * space handlers */ if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) { return (AE_OK); @@ -1062,10 +1059,9 @@ acpi_ev_reg_run(acpi_handle obj_handle, /* Object is a Region */ if (obj_desc->region.space_id != space_id) { - /* - * This region is for a different address space - * -- just ignore it - */ + + /* This region is for a different address space, just ignore it */ + return (AE_OK); } diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/acpica/evrgnini.c similarity index 95% rename from drivers/acpi/events/evrgnini.c rename to drivers/acpi/acpica/evrgnini.c index 6b94b38df07..f3f1fb45c3d 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evrgnini") @@ -233,9 +234,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, if (ACPI_FAILURE(status)) { if (status == AE_SAME_HANDLER) { /* - * It is OK if the handler is already installed on the root - * bridge. Still need to return a context object for the - * new PCI_Config operation region, however. + * It is OK if the handler is already installed on the + * root bridge. Still need to return a context object + * for the new PCI_Config operation region, however. */ status = AE_OK; } else { @@ -272,8 +273,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, } /* - * For PCI_Config space access, we need the segment, bus, - * device and function numbers. Acquire them here. + * For PCI_Config space access, we need the segment, bus, device and + * function numbers. Acquire them here. * * Find the parent device object. (This allows the operation region to be * within a subscope under the device, such as a control method.) @@ -289,16 +290,16 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, } /* - * Get the PCI device and function numbers from the _ADR object - * contained in the parent's scope. + * Get the PCI device and function numbers from the _ADR object contained + * in the parent's scope. */ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, &pci_value); /* - * The default is zero, and since the allocation above zeroed - * the data, just do nothing on failure. + * The default is zero, and since the allocation above zeroed the data, + * just do nothing on failure. */ if (ACPI_SUCCESS(status)) { pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value)); @@ -382,9 +383,8 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) struct acpi_compatible_id_list *cid; u32 i; - /* - * Get the _HID and check for a PCI Root Bridge - */ + /* Get the _HID and check for a PCI Root Bridge */ + status = acpi_ut_execute_HID(node, &hid); if (ACPI_FAILURE(status)) { return (FALSE); @@ -394,10 +394,8 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) return (TRUE); } - /* - * The _HID did not match. - * Get the _CID and check for a PCI Root Bridge - */ + /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */ + status = acpi_ut_execute_CID(node, &cid); if (ACPI_FAILURE(status)) { return (FALSE); @@ -516,9 +514,9 @@ acpi_ev_default_region_setup(acpi_handle handle, * Get the appropriate address space handler for a newly * created region. * - * This also performs address space specific initialization. For + * This also performs address space specific initialization. For * example, PCI regions must have an _ADR object that contains - * a PCI address in the scope of the definition. This address is + * a PCI address in the scope of the definition. This address is * required to perform an access to PCI config space. * * MUTEX: Interpreter should be unlocked, because we may run the _REG @@ -572,7 +570,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, if (ACPI_SUCCESS(status)) { /* * The _REG method is optional and there can be only one per region - * definition. This will be executed when the handler is attached + * definition. This will be executed when the handler is attached * or removed */ region_obj2->extra.method_REG = method_node; @@ -670,10 +668,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, } } - /* - * This node does not have the handler we need; - * Pop up one level - */ + /* This node does not have the handler we need; Pop up one level */ + node = acpi_ns_get_parent_node(node); } diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/acpica/evsci.c similarity index 95% rename from drivers/acpi/events/evsci.c rename to drivers/acpi/acpica/evsci.c index 2a8b7787761..567b356c85a 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acevents.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evsci") @@ -115,10 +116,8 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) * if this interrupt handler is installed, ACPI is enabled. */ - /* - * GPEs: - * Check for and dispatch any GPEs that have occurred - */ + /* GPEs: Check for and dispatch any GPEs that have occurred */ + interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); return_UINT32(interrupt_handled); @@ -158,11 +157,11 @@ u32 acpi_ev_install_sci_handler(void) * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not * installed to begin with * - * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be + * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be * taken. * * Note: It doesn't seem important to disable all events or set the event - * enable registers to their original values. The OS should disable + * enable registers to their original values. The OS should disable * the SCI interrupt level when the handler is removed, so no more * events will come in. * diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/acpica/evxface.c similarity index 99% rename from drivers/acpi/events/evxface.c rename to drivers/acpi/acpica/evxface.c index 94a6efe020b..3aca9010a11 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acevents.h" +#include "acinterp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxface") @@ -267,7 +268,7 @@ acpi_install_notify_handler(acpi_handle device, /* * Root Object: * Registering a notify handler on the root object indicates that the - * caller wishes to receive notifications for all objects. Note that + * caller wishes to receive notifications for all objects. Note that * only one global handler can be regsitered (per notify type). */ if (device == ACPI_ROOT_OBJECT) { diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c similarity index 81% rename from drivers/acpi/events/evxfevnt.c rename to drivers/acpi/acpica/evxfevnt.c index 41554f736b6..35485e4b60a 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -42,13 +42,19 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" +#include "actables.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxfevnt") +/* Local prototypes */ +acpi_status +acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, void *context); + /******************************************************************************* * * FUNCTION: acpi_enable @@ -60,6 +66,7 @@ ACPI_MODULE_NAME("evxfevnt") * DESCRIPTION: Transfers the system into ACPI mode. * ******************************************************************************/ + acpi_status acpi_enable(void) { acpi_status status = AE_OK; @@ -161,8 +168,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags) } /* - * Enable the requested fixed event (by writing a one to the - * enable register bit) + * Enable the requested fixed event (by writing a one to the enable + * register bit) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. @@ -343,8 +350,8 @@ acpi_status acpi_disable_event(u32 event, u32 flags) } /* - * Disable the requested fixed event (by writing a zero to the - * enable register bit) + * Disable the requested fixed event (by writing a zero to the enable + * register bit) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. @@ -396,8 +403,8 @@ acpi_status acpi_clear_event(u32 event) } /* - * Clear the requested fixed event (By writing a one to the - * status register bit) + * Clear the requested fixed event (By writing a one to the status + * register bit) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. @@ -717,3 +724,148 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) } ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) + +/******************************************************************************* + * + * FUNCTION: acpi_get_gpe_device + * + * PARAMETERS: Index - System GPE index (0-current_gpe_count) + * gpe_device - Where the parent GPE Device is returned + * + * RETURN: Status + * + * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL + * gpe device indicates that the gpe number is contained in one of + * the FADT-defined gpe blocks. Otherwise, the GPE block device. + * + ******************************************************************************/ +acpi_status +acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) +{ + struct acpi_gpe_device_info info; + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_get_gpe_device); + + if (!gpe_device) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + if (index >= acpi_current_gpe_count) { + return_ACPI_STATUS(AE_NOT_EXIST); + } + + /* Setup and walk the GPE list */ + + info.index = index; + info.status = AE_NOT_EXIST; + info.gpe_device = NULL; + info.next_block_base_index = 0; + + status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + *gpe_device = info.gpe_device; + return_ACPI_STATUS(info.status); +} + +ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) + +/******************************************************************************* + * + * FUNCTION: acpi_ev_get_gpe_device + * + * PARAMETERS: GPE_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE + * block device. NULL if the GPE is one of the FADT-defined GPEs. + * + ******************************************************************************/ +acpi_status +acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, void *context) +{ + struct acpi_gpe_device_info *info = context; + + /* Increment Index by the number of GPEs in this block */ + + info->next_block_base_index += + (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH); + + if (info->index < info->next_block_base_index) { + /* + * The GPE index is within this block, get the node. Leave the node + * NULL for the FADT-defined GPEs + */ + if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { + info->gpe_device = gpe_block->node; + } + + info->status = AE_OK; + return (AE_CTRL_END); + } + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_disable_all_gpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Disable and clear all GPEs in all GPE blocks + * + ******************************************************************************/ + +acpi_status acpi_disable_all_gpes(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + status = acpi_hw_disable_all_gpes(); + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + + return_ACPI_STATUS(status); +} + +/****************************************************************************** + * + * FUNCTION: acpi_enable_all_runtime_gpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks + * + ******************************************************************************/ + +acpi_status acpi_enable_all_runtime_gpes(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + status = acpi_hw_enable_all_runtime_gpes(); + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + + return_ACPI_STATUS(status); +} diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/acpica/evxfregn.c similarity index 99% rename from drivers/acpi/events/evxfregn.c rename to drivers/acpi/acpica/evxfregn.c index e8750807e57..479e7a3721b 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -43,8 +43,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acevents.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxfregn") diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/acpica/exconfig.c similarity index 99% rename from drivers/acpi/executer/exconfig.c rename to drivers/acpi/acpica/exconfig.c index 74da6fa52ef..932bbc26aa0 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -42,10 +42,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "actables.h" +#include "acdispat.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exconfig") diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/acpica/exconvrt.c similarity index 99% rename from drivers/acpi/executer/exconvrt.c rename to drivers/acpi/acpica/exconvrt.c index 1d1f35adddd..0be10188316 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exconvrt") diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/acpica/excreate.c similarity index 99% rename from drivers/acpi/executer/excreate.c rename to drivers/acpi/acpica/excreate.c index ad09696d506..a57ad2564ab 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("excreate") diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/acpica/exdump.c similarity index 99% rename from drivers/acpi/executer/exdump.c rename to drivers/acpi/acpica/exdump.c index d087a7d28aa..aa313574b0d 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exdump") diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/acpica/exfield.c similarity index 99% rename from drivers/acpi/executer/exfield.c rename to drivers/acpi/acpica/exfield.c index 3e440d84226..a352d023385 100644 --- a/drivers/acpi/executer/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acdispat.h" +#include "acinterp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exfield") diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/acpica/exfldio.c similarity index 98% rename from drivers/acpi/executer/exfldio.c rename to drivers/acpi/acpica/exfldio.c index 9ff9d1f4615..ef58ac4e687 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -42,10 +42,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acevents.h" +#include "acdispat.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exfldio") @@ -498,14 +499,13 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, return_ACPI_STATUS(status); } - ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "I/O to Data Register: ValuePtr %p\n", - value)); - if (read_write == ACPI_READ) { /* Read the datum from the data_register */ + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, + "Read from Data Register\n")); + status = acpi_ex_extract_from_field(obj_desc->index_field. data_obj, value, @@ -513,6 +513,10 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, } else { /* Write the datum to the data_register */ + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, + "Write to Data Register: Value %8.8X%8.8X\n", + ACPI_FORMAT_UINT64(*value))); + status = acpi_ex_insert_into_field(obj_desc->index_field. data_obj, value, diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/acpica/exmisc.c similarity index 99% rename from drivers/acpi/executer/exmisc.c rename to drivers/acpi/acpica/exmisc.c index efb19134005..6b0747ac683 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -43,9 +43,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" +#include "amlresrc.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmisc") diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/acpica/exmutex.c similarity index 99% rename from drivers/acpi/executer/exmutex.c rename to drivers/acpi/acpica/exmutex.c index a8bf3d713e2..d301c1f363e 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -43,8 +43,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "acevents.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmutex") diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/acpica/exnames.c similarity index 99% rename from drivers/acpi/executer/exnames.c rename to drivers/acpi/acpica/exnames.c index 817e67be369..ffdae122d94 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -43,8 +43,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exnames") diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/acpica/exoparg1.c similarity index 99% rename from drivers/acpi/executer/exoparg1.c rename to drivers/acpi/acpica/exoparg1.c index f622f9eac8a..b530480cc7d 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -43,11 +43,12 @@ */ #include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acdispat.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exoparg1") diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/acpica/exoparg2.c similarity index 99% rename from drivers/acpi/executer/exoparg2.c rename to drivers/acpi/acpica/exoparg2.c index 368def5dffc..0b4f513ca88 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -42,10 +42,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acinterp.h" +#include "acevents.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exoparg2") diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/acpica/exoparg3.c similarity index 98% rename from drivers/acpi/executer/exoparg3.c rename to drivers/acpi/acpica/exoparg3.c index 9cb4197681a..c6520bbf882 100644 --- a/drivers/acpi/executer/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -43,9 +43,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exoparg3") diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/acpica/exoparg6.c similarity index 99% rename from drivers/acpi/executer/exoparg6.c rename to drivers/acpi/acpica/exoparg6.c index 67d48737af5..ae43f7670a6 100644 --- a/drivers/acpi/executer/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -43,9 +43,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exoparg6") diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/acpica/exprep.c similarity index 99% rename from drivers/acpi/executer/exprep.c rename to drivers/acpi/acpica/exprep.c index a7dc87ecee3..a226f74d4a5 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -43,9 +43,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exprep") diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/acpica/exregion.c similarity index 99% rename from drivers/acpi/executer/exregion.c rename to drivers/acpi/acpica/exregion.c index 7a41c409ae4..76ec8ff903b 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acinterp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exregion") diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/acpica/exresnte.c similarity index 98% rename from drivers/acpi/executer/exresnte.c rename to drivers/acpi/acpica/exresnte.c index 423ad3635f3..a063a74006f 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -43,9 +43,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exresnte") diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/acpica/exresolv.c similarity index 99% rename from drivers/acpi/executer/exresolv.c rename to drivers/acpi/acpica/exresolv.c index 60e8c47128e..f6105a6d612 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -43,10 +43,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "amlcode.h" +#include "acdispat.h" +#include "acinterp.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exresolv") diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/acpica/exresop.c similarity index 99% rename from drivers/acpi/executer/exresop.c rename to drivers/acpi/acpica/exresop.c index 0bb82593da7..3c3802764bf 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -43,10 +43,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "amlcode.h" +#include "acparser.h" +#include "acinterp.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exresop") diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/acpica/exstore.c similarity index 99% rename from drivers/acpi/executer/exstore.c rename to drivers/acpi/acpica/exstore.c index 1c118ba78ad..e35e9b4f6a4 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -43,10 +43,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "acdispat.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exstore") diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/acpica/exstoren.c similarity index 99% rename from drivers/acpi/executer/exstoren.c rename to drivers/acpi/acpica/exstoren.c index eef61a00803..145d15305f7 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -44,8 +44,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exstoren") diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/acpica/exstorob.c similarity index 99% rename from drivers/acpi/executer/exstorob.c rename to drivers/acpi/acpica/exstorob.c index 9a75ff09fb0..67340cc7014 100644 --- a/drivers/acpi/executer/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acinterp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exstorob") diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/acpica/exsystem.c similarity index 99% rename from drivers/acpi/executer/exsystem.c rename to drivers/acpi/acpica/exsystem.c index 68990f1df37..3d00b935723 100644 --- a/drivers/acpi/executer/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acinterp.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exsystem") diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/acpica/exutils.c similarity index 99% rename from drivers/acpi/executer/exutils.c rename to drivers/acpi/acpica/exutils.c index 86c03880b52..32b85d68e75 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -59,8 +59,9 @@ #define DEFINE_AML_GLOBALS #include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exutils") diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/acpica/hwacpi.c similarity index 99% rename from drivers/acpi/hardware/hwacpi.c rename to drivers/acpi/acpica/hwacpi.c index 816894ea839..a9d4fea4167 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -43,6 +43,7 @@ */ #include +#include "accommon.h" #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwacpi") diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/acpica/hwgpe.c similarity index 86% rename from drivers/acpi/hardware/hwgpe.c rename to drivers/acpi/acpica/hwgpe.c index 0b80db9d919..2013b66745d 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acevents.h" #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwgpe") @@ -51,7 +52,8 @@ ACPI_MODULE_NAME("hwgpe") /* Local prototypes */ static acpi_status acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block); + struct acpi_gpe_block_info *gpe_block, + void *context); /****************************************************************************** * @@ -80,8 +82,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) /* Get current value of the enable register that contains this GPE */ - status = acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH, &enable_mask, - &gpe_register_info->enable_address); + status = acpi_read(&enable_mask, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -95,9 +96,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) /* Write the updated enable mask */ - status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, enable_mask, - &gpe_register_info->enable_address); - + status = acpi_write(enable_mask, &gpe_register_info->enable_address); return (status); } @@ -132,8 +131,8 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) /* Write the entire GPE (runtime) enable register */ - status = acpi_hw_low_level_write(8, gpe_register_info->enable_for_run, - &gpe_register_info->enable_address); + status = acpi_write(gpe_register_info->enable_for_run, + &gpe_register_info->enable_address); return (status); } @@ -166,9 +165,8 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) * Write a one to the appropriate bit in the status register to * clear this GPE. */ - status = acpi_hw_low_level_write(8, register_bit, - &gpe_event_info->register_info-> - status_address); + status = acpi_write(register_bit, + &gpe_event_info->register_info->status_address); return (status); } @@ -227,9 +225,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* GPE currently active (status bit == 1)? */ - status = - acpi_hw_low_level_read(8, &in_byte, - &gpe_register_info->status_address); + status = acpi_read(&in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -260,8 +256,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, ******************************************************************************/ acpi_status -acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, - struct acpi_gpe_block_info * gpe_block) +acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, void *context) { u32 i; acpi_status status; @@ -272,9 +268,9 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, /* Disable all GPEs in this register */ - status = acpi_hw_low_level_write(8, 0x00, - &gpe_block->register_info[i]. - enable_address); + status = + acpi_write(0x00, + &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -297,8 +293,8 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, ******************************************************************************/ acpi_status -acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, - struct acpi_gpe_block_info * gpe_block) +acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, void *context) { u32 i; acpi_status status; @@ -309,9 +305,9 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, /* Clear status on all GPEs in this register */ - status = acpi_hw_low_level_write(8, 0xFF, - &gpe_block->register_info[i]. - status_address); + status = + acpi_write(0xFF, + &gpe_block->register_info[i].status_address); if (ACPI_FAILURE(status)) { return (status); } @@ -335,8 +331,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, ******************************************************************************/ acpi_status -acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, - struct acpi_gpe_block_info * gpe_block) +acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, void *context) { u32 i; acpi_status status; @@ -352,12 +348,9 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, /* Enable all "runtime" GPEs in this register */ - status = - acpi_hw_low_level_write(8, - gpe_block->register_info[i]. - enable_for_run, - &gpe_block->register_info[i]. - enable_address); + status = acpi_write(gpe_block->register_info[i].enable_for_run, + &gpe_block->register_info[i]. + enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -382,7 +375,8 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, static acpi_status acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block) + struct acpi_gpe_block_info *gpe_block, + void *context) { u32 i; acpi_status status; @@ -396,11 +390,9 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /* Enable all "wake" GPEs in this register */ - status = acpi_hw_low_level_write(8, - gpe_block->register_info[i]. - enable_for_wake, - &gpe_block->register_info[i]. - enable_address); + status = acpi_write(gpe_block->register_info[i].enable_for_wake, + &gpe_block->register_info[i]. + enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -427,8 +419,8 @@ acpi_status acpi_hw_disable_all_gpes(void) ACPI_FUNCTION_TRACE(hw_disable_all_gpes); - status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); - status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); + status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); + status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); return_ACPI_STATUS(status); } @@ -450,7 +442,7 @@ acpi_status acpi_hw_enable_all_runtime_gpes(void) ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes); - status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block); + status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL); return_ACPI_STATUS(status); } @@ -472,6 +464,6 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void) ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes); - status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block); + status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c new file mode 100644 index 00000000000..4dc43b01851 --- /dev/null +++ b/drivers/acpi/acpica/hwregs.c @@ -0,0 +1,353 @@ + +/******************************************************************************* + * + * Module Name: hwregs - Read/write access functions for the various ACPI + * control and status registers. + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" +#include "acnamesp.h" +#include "acevents.h" + +#define _COMPONENT ACPI_HARDWARE +ACPI_MODULE_NAME("hwregs") + +/******************************************************************************* + * + * FUNCTION: acpi_hw_clear_acpi_status + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Clears all fixed and general purpose status bits + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * + ******************************************************************************/ +acpi_status acpi_hw_clear_acpi_status(void) +{ + acpi_status status; + acpi_cpu_flags lock_flags = 0; + + ACPI_FUNCTION_TRACE(hw_clear_acpi_status); + + ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", + ACPI_BITMASK_ALL_FIXED_STATUS, + (u16) acpi_gbl_FADT.xpm1a_event_block.address)); + + lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + + status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, + ACPI_BITMASK_ALL_FIXED_STATUS); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + + /* Clear the fixed events */ + + if (acpi_gbl_FADT.xpm1b_event_block.address) { + status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS, + &acpi_gbl_FADT.xpm1b_event_block); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + } + + /* Clear the GPE Bits in all GPE registers in all GPE blocks */ + + status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); + + unlock_and_exit: + acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_hw_get_register_bit_mask + * + * PARAMETERS: register_id - Index of ACPI Register to access + * + * RETURN: The bitmask to be used when accessing the register + * + * DESCRIPTION: Map register_id into a register bitmask. + * + ******************************************************************************/ + +struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) +{ + ACPI_FUNCTION_ENTRY(); + + if (register_id > ACPI_BITREG_MAX) { + ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", + register_id)); + return (NULL); + } + + return (&acpi_gbl_bit_register_info[register_id]); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_register_read + * + * PARAMETERS: register_id - ACPI Register ID + * return_value - Where the register value is returned + * + * RETURN: Status and the value read. + * + * DESCRIPTION: Read from the specified ACPI register + * + ******************************************************************************/ +acpi_status +acpi_hw_register_read(u32 register_id, u32 * return_value) +{ + u32 value1 = 0; + u32 value2 = 0; + acpi_status status; + + ACPI_FUNCTION_TRACE(hw_register_read); + + switch (register_id) { + case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ + + status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* PM1B is optional */ + + status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block); + value1 |= value2; + break; + + case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ + + status = acpi_read(&value1, &acpi_gbl_xpm1a_enable); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* PM1B is optional */ + + status = acpi_read(&value2, &acpi_gbl_xpm1b_enable); + value1 |= value2; + break; + + case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ + + status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block); + if (ACPI_FAILURE(status)) { + goto exit; + } + + status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block); + value1 |= value2; + break; + + case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ + + status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block); + break; + + case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ + + status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block); + break; + + case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ + + status = + acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); + break; + + default: + ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); + status = AE_BAD_PARAMETER; + break; + } + + exit: + + if (ACPI_SUCCESS(status)) { + *return_value = value1; + } + + return_ACPI_STATUS(status); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_register_write + * + * PARAMETERS: register_id - ACPI Register ID + * Value - The value to write + * + * RETURN: Status + * + * DESCRIPTION: Write to the specified ACPI register + * + * NOTE: In accordance with the ACPI specification, this function automatically + * preserves the value of the following bits, meaning that these bits cannot be + * changed via this interface: + * + * PM1_CONTROL[0] = SCI_EN + * PM1_CONTROL[9] + * PM1_STATUS[11] + * + * ACPI References: + * 1) Hardware Ignored Bits: When software writes to a register with ignored + * bit fields, it preserves the ignored bit fields + * 2) SCI_EN: OSPM always preserves this bit position + * + ******************************************************************************/ + +acpi_status acpi_hw_register_write(u32 register_id, u32 value) +{ + acpi_status status; + u32 read_value; + + ACPI_FUNCTION_TRACE(hw_register_write); + + switch (register_id) { + case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ + + /* Perform a read first to preserve certain bits (per ACPI spec) */ + + status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, + &read_value); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* Insert the bits to be preserved */ + + ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, + read_value); + + /* Now we can write the data */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* PM1B is optional */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block); + break; + + case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ + + status = acpi_write(value, &acpi_gbl_xpm1a_enable); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* PM1B is optional */ + + status = acpi_write(value, &acpi_gbl_xpm1b_enable); + break; + + case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ + + /* + * Perform a read first to preserve certain bits (per ACPI spec) + */ + status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, + &read_value); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* Insert the bits to be preserved */ + + ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, + read_value); + + /* Now we can write the data */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block); + if (ACPI_FAILURE(status)) { + goto exit; + } + + status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block); + break; + + case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block); + break; + + case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block); + break; + + case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); + break; + + case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ + + status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block); + break; + + case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ + + /* SMI_CMD is currently always in IO space */ + + status = + acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); + break; + + default: + status = AE_BAD_PARAMETER; + break; + } + + exit: + return_ACPI_STATUS(status); +} diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/acpica/hwsleep.c similarity index 91% rename from drivers/acpi/hardware/hwsleep.c rename to drivers/acpi/acpica/hwsleep.c index 25dccdf179b..a2af2a4f2f2 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "actables.h" #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwsleep") @@ -52,31 +53,19 @@ ACPI_MODULE_NAME("hwsleep") * * FUNCTION: acpi_set_firmware_waking_vector * - * PARAMETERS: physical_address - Physical address of ACPI real mode + * PARAMETERS: physical_address - 32-bit physical address of ACPI real mode * entry point. * * RETURN: Status * - * DESCRIPTION: Access function for the firmware_waking_vector field in FACS + * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS * ******************************************************************************/ acpi_status -acpi_set_firmware_waking_vector(acpi_physical_address physical_address) +acpi_set_firmware_waking_vector(u32 physical_address) { - struct acpi_table_facs *facs; - acpi_status status; - ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); - /* Get the FACS */ - - status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - ACPI_CAST_INDIRECT_PTR(struct - acpi_table_header, - &facs)); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } /* * According to the ACPI specification 2.0c and later, the 64-bit @@ -85,10 +74,16 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address) * Protected Mode. Some systems (for example HP dv5-1004nr) are known * to fail to resume if the 64-bit vector is used. */ - if (facs->version >= 1) - facs->xfirmware_waking_vector = 0; - facs->firmware_waking_vector = (u32)physical_address; + /* Set the 32-bit vector */ + + acpi_gbl_FACS->firmware_waking_vector = physical_address; + + /* Clear the 64-bit vector if it exists */ + + if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) { + acpi_gbl_FACS->xfirmware_waking_vector = 0; + } return_ACPI_STATUS(AE_OK); } @@ -97,48 +92,39 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) /******************************************************************************* * - * FUNCTION: acpi_get_firmware_waking_vector + * FUNCTION: acpi_set_firmware_waking_vector64 * - * PARAMETERS: *physical_address - Where the contents of - * the firmware_waking_vector field of - * the FACS will be returned. + * PARAMETERS: physical_address - 64-bit physical address of ACPI protected + * mode entry point. * - * RETURN: Status, vector + * RETURN: Status * - * DESCRIPTION: Access function for the firmware_waking_vector field in FACS + * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if + * it exists in the table. * ******************************************************************************/ -#ifdef ACPI_FUTURE_USAGE acpi_status -acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) +acpi_set_firmware_waking_vector64(u64 physical_address) { - struct acpi_table_facs *facs; - acpi_status status; + ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64); - ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); - - if (!physical_address) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - /* Get the FACS */ + /* Determine if the 64-bit vector actually exists */ - status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - ACPI_CAST_INDIRECT_PTR(struct - acpi_table_header, - &facs)); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) { + return_ACPI_STATUS(AE_NOT_EXIST); } - /* Get the vector */ - *physical_address = (acpi_physical_address)facs->firmware_waking_vector; + /* Clear 32-bit vector, set the 64-bit X_ vector */ + + acpi_gbl_FACS->firmware_waking_vector = 0; + acpi_gbl_FACS->xfirmware_waking_vector = physical_address; return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_get_firmware_waking_vector) -#endif +ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) + /******************************************************************************* * * FUNCTION: acpi_enter_sleep_state_prep diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/acpica/hwtimer.c similarity index 99% rename from drivers/acpi/hardware/hwtimer.c rename to drivers/acpi/acpica/hwtimer.c index b53d575491b..b7f522c8f02 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -43,6 +43,7 @@ */ #include +#include "accommon.h" #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwtimer") diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/acpica/hwxface.c similarity index 62% rename from drivers/acpi/hardware/hwregs.c rename to drivers/acpi/acpica/hwxface.c index ddf792adcf9..ae597c0ab53 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/acpica/hwxface.c @@ -1,10 +1,9 @@ -/******************************************************************************* +/****************************************************************************** * - * Module Name: hwregs - Read/write access functions for the various ACPI - * control and status registers. + * Module Name: hwxface - Public ACPICA hardware interfaces * - ******************************************************************************/ + *****************************************************************************/ /* * Copyright (C) 2000 - 2008, Intel Corp. @@ -44,209 +43,208 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_HARDWARE -ACPI_MODULE_NAME("hwregs") +ACPI_MODULE_NAME("hwxface") -/******************************************************************************* +/****************************************************************************** * - * FUNCTION: acpi_hw_clear_acpi_status + * FUNCTION: acpi_reset * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Clears all fixed and general purpose status bits - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * DESCRIPTION: Set reset register in memory or IO space. Note: Does not + * support reset register in PCI config space, this must be + * handled separately. * ******************************************************************************/ -acpi_status acpi_hw_clear_acpi_status(void) +acpi_status acpi_reset(void) { + struct acpi_generic_address *reset_reg; acpi_status status; - acpi_cpu_flags lock_flags = 0; - - ACPI_FUNCTION_TRACE(hw_clear_acpi_status); - - ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", - ACPI_BITMASK_ALL_FIXED_STATUS, - (u16) acpi_gbl_FADT.xpm1a_event_block.address)); - lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + ACPI_FUNCTION_TRACE(acpi_reset); - status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, - ACPI_BITMASK_ALL_FIXED_STATUS); - if (ACPI_FAILURE(status)) { - goto unlock_and_exit; - } + reset_reg = &acpi_gbl_FADT.reset_register; - /* Clear the fixed events */ + /* Check if the reset register is supported */ - if (acpi_gbl_FADT.xpm1b_event_block.address) { - status = - acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, - &acpi_gbl_FADT.xpm1b_event_block); - if (ACPI_FAILURE(status)) { - goto unlock_and_exit; - } + if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || + !reset_reg->address) { + return_ACPI_STATUS(AE_NOT_EXIST); } - /* Clear the GPE Bits in all GPE registers in all GPE blocks */ + /* Write the reset value to the reset register */ - status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); - - unlock_and_exit: - acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + status = acpi_write(acpi_gbl_FADT.reset_value, reset_reg); return_ACPI_STATUS(status); } -/******************************************************************************* +ACPI_EXPORT_SYMBOL(acpi_reset) + +/****************************************************************************** * - * FUNCTION: acpi_get_sleep_type_data + * FUNCTION: acpi_read * - * PARAMETERS: sleep_state - Numeric sleep state - * *sleep_type_a - Where SLP_TYPa is returned - * *sleep_type_b - Where SLP_TYPb is returned + * PARAMETERS: Value - Where the value is returned + * Reg - GAS register structure * - * RETURN: Status - ACPI status + * RETURN: Status * - * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep - * state. + * DESCRIPTION: Read from either memory or IO space. * ******************************************************************************/ - -acpi_status -acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) +acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) { - acpi_status status = AE_OK; - struct acpi_evaluate_info *info; - - ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); - - /* Validate parameters */ - - if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } + u32 width; + u64 address; + acpi_status status; - /* Allocate the evaluation information block */ + ACPI_FUNCTION_NAME(acpi_read); - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); + /* + * Must have a valid pointer to a GAS structure, and + * a non-zero address within. However, don't return an error + * because the PM1A/B code must not fail if B isn't present. + */ + if (!reg) { + return (AE_OK); } - info->pathname = - ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); - - /* Evaluate the namespace object containing the values for this state */ - - status = acpi_ns_evaluate(info); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "%s while evaluating SleepState [%s]\n", - acpi_format_exception(status), - info->pathname)); + /* Get a local copy of the address. Handles possible alignment issues */ - goto cleanup; + ACPI_MOVE_64_TO_64(&address, ®->address); + if (!address) { + return (AE_OK); } - /* Must have a return object */ + /* Supported widths are 8/16/32 */ - if (!info->return_object) { - ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", - info->pathname)); - status = AE_NOT_EXIST; + width = reg->bit_width; + if ((width != 8) && (width != 16) && (width != 32)) { + return (AE_SUPPORT); } - /* It must be of type Package */ + /* Initialize entire 32-bit return value to zero */ - else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { - ACPI_ERROR((AE_INFO, - "Sleep State return object is not a Package")); - status = AE_AML_OPERAND_TYPE; - } + *value = 0; /* - * The package must have at least two elements. NOTE (March 2005): This - * goes against the current ACPI spec which defines this object as a - * package with one encoded DWORD element. However, existing practice - * by BIOS vendors seems to be to have 2 or more elements, at least - * one per sleep type (A/B). + * Two address spaces supported: Memory or IO. + * PCI_Config is not supported here because the GAS struct is insufficient */ - else if (info->return_object->package.count < 2) { - ACPI_ERROR((AE_INFO, - "Sleep State return package does not have at least two elements")); - status = AE_AML_NO_OPERAND; - } + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: - /* The first two elements must both be of type Integer */ + status = acpi_os_read_memory((acpi_physical_address) address, + value, width); + break; - else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) - != ACPI_TYPE_INTEGER) || - (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) - != ACPI_TYPE_INTEGER)) { - ACPI_ERROR((AE_INFO, - "Sleep State return package elements are not both Integers (%s, %s)", - acpi_ut_get_object_type_name(info->return_object-> - package.elements[0]), - acpi_ut_get_object_type_name(info->return_object-> - package.elements[1]))); - status = AE_AML_OPERAND_TYPE; - } else { - /* Valid _Sx_ package size, type, and value */ + case ACPI_ADR_SPACE_SYSTEM_IO: - *sleep_type_a = (u8) - (info->return_object->package.elements[0])->integer.value; - *sleep_type_b = (u8) - (info->return_object->package.elements[1])->integer.value; - } + status = + acpi_os_read_port((acpi_io_address) address, value, width); + break; - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While evaluating SleepState [%s], bad Sleep object %p type %s", - info->pathname, info->return_object, - acpi_ut_get_object_type_name(info-> - return_object))); + default: + ACPI_ERROR((AE_INFO, + "Unsupported address space: %X", reg->space_id)); + return (AE_BAD_PARAMETER); } - acpi_ut_remove_reference(info->return_object); + ACPI_DEBUG_PRINT((ACPI_DB_IO, + "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", + *value, width, ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->space_id))); - cleanup: - ACPI_FREE(info); - return_ACPI_STATUS(status); + return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) +ACPI_EXPORT_SYMBOL(acpi_read) -/******************************************************************************* +/****************************************************************************** * - * FUNCTION: acpi_hw_get_register_bit_mask + * FUNCTION: acpi_write * - * PARAMETERS: register_id - Index of ACPI Register to access + * PARAMETERS: Value - To be written + * Reg - GAS register structure * - * RETURN: The bitmask to be used when accessing the register + * RETURN: Status * - * DESCRIPTION: Map register_id into a register bitmask. + * DESCRIPTION: Write to either memory or IO space. * ******************************************************************************/ -struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) +acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) { - ACPI_FUNCTION_ENTRY(); + u32 width; + u64 address; + acpi_status status; - if (register_id > ACPI_BITREG_MAX) { - ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", - register_id)); - return (NULL); + ACPI_FUNCTION_NAME(acpi_write); + + /* + * Must have a valid pointer to a GAS structure, and + * a non-zero address within. However, don't return an error + * because the PM1A/B code must not fail if B isn't present. + */ + if (!reg) { + return (AE_OK); + } + + /* Get a local copy of the address. Handles possible alignment issues */ + + ACPI_MOVE_64_TO_64(&address, ®->address); + if (!address) { + return (AE_OK); + } + + /* Supported widths are 8/16/32 */ + + width = reg->bit_width; + if ((width != 8) && (width != 16) && (width != 32)) { + return (AE_SUPPORT); + } + + /* + * Two address spaces supported: Memory or IO. + * PCI_Config is not supported here because the GAS struct is insufficient + */ + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + + status = acpi_os_write_memory((acpi_physical_address) address, + value, width); + break; + + case ACPI_ADR_SPACE_SYSTEM_IO: + + status = acpi_os_write_port((acpi_io_address) address, value, + width); + break; + + default: + ACPI_ERROR((AE_INFO, + "Unsupported address space: %X", reg->space_id)); + return (AE_BAD_PARAMETER); } - return (&acpi_gbl_bit_register_info[register_id]); + ACPI_DEBUG_PRINT((ACPI_DB_IO, + "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", + value, width, ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->space_id))); + + return (status); } +ACPI_EXPORT_SYMBOL(acpi_write) + /******************************************************************************* * - * FUNCTION: acpi_get_register + * FUNCTION: acpi_get_register_unlocked * * PARAMETERS: register_id - ID of ACPI bit_register to access * return_value - Value that was read from the register @@ -254,17 +252,16 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) * RETURN: Status and the value read from specified Register. Value * returned is normalized to bit0 (is shifted all the way right) * - * DESCRIPTION: ACPI bit_register read function. + * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock. * ******************************************************************************/ - -acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) +acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_get_register); + ACPI_FUNCTION_TRACE(acpi_get_register_unlocked); /* Get the info structure corresponding to the requested ACPI Register */ @@ -296,14 +293,31 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) return_ACPI_STATUS(status); } -acpi_status acpi_get_register(u32 register_id, u32 * return_value) +ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked) + +/******************************************************************************* + * + * FUNCTION: acpi_get_register + * + * PARAMETERS: register_id - ID of ACPI bit_register to access + * return_value - Value that was read from the register + * + * RETURN: Status and the value read from specified Register. Value + * returned is normalized to bit0 (is shifted all the way right) + * + * DESCRIPTION: ACPI bit_register read function. + * + ******************************************************************************/ +acpi_status acpi_get_register(u32 register_id, u32 *return_value) { acpi_status status; acpi_cpu_flags flags; + flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); status = acpi_get_register_unlocked(register_id, return_value); acpi_os_release_lock(acpi_gbl_hardware_lock, flags); - return status; + + return (status); } ACPI_EXPORT_SYMBOL(acpi_get_register) @@ -370,8 +384,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value) bit_reg_info-> access_bit_mask); if (value) { - status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, - (u16) value); + status = + acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, + (u16) value); register_value = 0; } break; @@ -459,399 +474,120 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ACPI_EXPORT_SYMBOL(acpi_set_register) -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: acpi_hw_register_read + * FUNCTION: acpi_get_sleep_type_data * - * PARAMETERS: register_id - ACPI Register ID - * return_value - Where the register value is returned + * PARAMETERS: sleep_state - Numeric sleep state + * *sleep_type_a - Where SLP_TYPa is returned + * *sleep_type_b - Where SLP_TYPb is returned * - * RETURN: Status and the value read. + * RETURN: Status - ACPI status * - * DESCRIPTION: Read from the specified ACPI register + * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep + * state. * ******************************************************************************/ acpi_status -acpi_hw_register_read(u32 register_id, u32 * return_value) +acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) { - u32 value1 = 0; - u32 value2 = 0; - acpi_status status; - - ACPI_FUNCTION_TRACE(hw_register_read); + acpi_status status = AE_OK; + struct acpi_evaluate_info *info; - switch (register_id) { - case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ + ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); - status = - acpi_hw_low_level_read(16, &value1, - &acpi_gbl_FADT.xpm1a_event_block); - if (ACPI_FAILURE(status)) { - goto exit; - } + /* Validate parameters */ - /* PM1B is optional */ + if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - status = - acpi_hw_low_level_read(16, &value2, - &acpi_gbl_FADT.xpm1b_event_block); - value1 |= value2; - break; + /* Allocate the evaluation information block */ - case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ + info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); + if (!info) { + return_ACPI_STATUS(AE_NO_MEMORY); + } - status = - acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); - if (ACPI_FAILURE(status)) { - goto exit; - } + info->pathname = + ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); - /* PM1B is optional */ + /* Evaluate the namespace object containing the values for this state */ - status = - acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable); - value1 |= value2; - break; - - case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ - - status = - acpi_hw_low_level_read(16, &value1, - &acpi_gbl_FADT.xpm1a_control_block); - if (ACPI_FAILURE(status)) { - goto exit; - } - - status = - acpi_hw_low_level_read(16, &value2, - &acpi_gbl_FADT.xpm1b_control_block); - value1 |= value2; - break; - - case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - - status = - acpi_hw_low_level_read(8, &value1, - &acpi_gbl_FADT.xpm2_control_block); - break; - - case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - - status = - acpi_hw_low_level_read(32, &value1, - &acpi_gbl_FADT.xpm_timer_block); - break; - - case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ - - status = - acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); - break; - - default: - ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); - status = AE_BAD_PARAMETER; - break; - } - - exit: - - if (ACPI_SUCCESS(status)) { - *return_value = value1; - } - - return_ACPI_STATUS(status); -} - -/****************************************************************************** - * - * FUNCTION: acpi_hw_register_write - * - * PARAMETERS: register_id - ACPI Register ID - * Value - The value to write - * - * RETURN: Status - * - * DESCRIPTION: Write to the specified ACPI register - * - * NOTE: In accordance with the ACPI specification, this function automatically - * preserves the value of the following bits, meaning that these bits cannot be - * changed via this interface: - * - * PM1_CONTROL[0] = SCI_EN - * PM1_CONTROL[9] - * PM1_STATUS[11] - * - * ACPI References: - * 1) Hardware Ignored Bits: When software writes to a register with ignored - * bit fields, it preserves the ignored bit fields - * 2) SCI_EN: OSPM always preserves this bit position - * - ******************************************************************************/ - -acpi_status acpi_hw_register_write(u32 register_id, u32 value) -{ - acpi_status status; - u32 read_value; - - ACPI_FUNCTION_TRACE(hw_register_write); - - switch (register_id) { - case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ - - /* Perform a read first to preserve certain bits (per ACPI spec) */ - - status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, - &read_value); - if (ACPI_FAILURE(status)) { - goto exit; - } - - /* Insert the bits to be preserved */ - - ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, - read_value); - - /* Now we can write the data */ - - status = - acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_event_block); - if (ACPI_FAILURE(status)) { - goto exit; - } - - /* PM1B is optional */ - - status = - acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_event_block); - break; - - case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ - - status = - acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); - if (ACPI_FAILURE(status)) { - goto exit; - } - - /* PM1B is optional */ - - status = - acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable); - break; - - case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ - - /* - * Perform a read first to preserve certain bits (per ACPI spec) - */ - status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, - &read_value); - if (ACPI_FAILURE(status)) { - goto exit; - } - - /* Insert the bits to be preserved */ - - ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, - read_value); - - /* Now we can write the data */ - - status = - acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_control_block); - if (ACPI_FAILURE(status)) { - goto exit; - } - - status = - acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_control_block); - break; - - case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ - - status = - acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_control_block); - break; - - case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ - - status = - acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_control_block); - break; - - case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - - status = - acpi_hw_low_level_write(8, value, - &acpi_gbl_FADT.xpm2_control_block); - break; - - case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - - status = - acpi_hw_low_level_write(32, value, - &acpi_gbl_FADT.xpm_timer_block); - break; - - case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ - - /* SMI_CMD is currently always in IO space */ - - status = - acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); - break; + status = acpi_ns_evaluate(info); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "%s while evaluating SleepState [%s]\n", + acpi_format_exception(status), + info->pathname)); - default: - status = AE_BAD_PARAMETER; - break; + goto cleanup; } - exit: - return_ACPI_STATUS(status); -} - -/****************************************************************************** - * - * FUNCTION: acpi_hw_low_level_read - * - * PARAMETERS: Width - 8, 16, or 32 - * Value - Where the value is returned - * Reg - GAS register structure - * - * RETURN: Status - * - * DESCRIPTION: Read from either memory or IO space. - * - ******************************************************************************/ - -acpi_status -acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) -{ - u64 address; - acpi_status status; - - ACPI_FUNCTION_NAME(hw_low_level_read); + /* Must have a return object */ - /* - * Must have a valid pointer to a GAS structure, and - * a non-zero address within. However, don't return an error - * because the PM1A/B code must not fail if B isn't present. - */ - if (!reg) { - return (AE_OK); + if (!info->return_object) { + ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", + info->pathname)); + status = AE_NOT_EXIST; } - /* Get a local copy of the address. Handles possible alignment issues */ + /* It must be of type Package */ - ACPI_MOVE_64_TO_64(&address, ®->address); - if (!address) { - return (AE_OK); + else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { + ACPI_ERROR((AE_INFO, + "Sleep State return object is not a Package")); + status = AE_AML_OPERAND_TYPE; } - *value = 0; /* - * Two address spaces supported: Memory or IO. - * PCI_Config is not supported here because the GAS struct is insufficient + * The package must have at least two elements. NOTE (March 2005): This + * goes against the current ACPI spec which defines this object as a + * package with one encoded DWORD element. However, existing practice + * by BIOS vendors seems to be to have 2 or more elements, at least + * one per sleep type (A/B). */ - switch (reg->space_id) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: - - status = acpi_os_read_memory((acpi_physical_address) address, - value, width); - break; - - case ACPI_ADR_SPACE_SYSTEM_IO: - - status = - acpi_os_read_port((acpi_io_address) address, value, width); - break; - - default: + else if (info->return_object->package.count < 2) { ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); - return (AE_BAD_PARAMETER); + "Sleep State return package does not have at least two elements")); + status = AE_AML_NO_OPERAND; } - ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", - *value, width, ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); - - return (status); -} - -/****************************************************************************** - * - * FUNCTION: acpi_hw_low_level_write - * - * PARAMETERS: Width - 8, 16, or 32 - * Value - To be written - * Reg - GAS register structure - * - * RETURN: Status - * - * DESCRIPTION: Write to either memory or IO space. - * - ******************************************************************************/ - -acpi_status -acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) -{ - u64 address; - acpi_status status; - - ACPI_FUNCTION_NAME(hw_low_level_write); - - /* - * Must have a valid pointer to a GAS structure, and - * a non-zero address within. However, don't return an error - * because the PM1A/B code must not fail if B isn't present. - */ - if (!reg) { - return (AE_OK); - } + /* The first two elements must both be of type Integer */ - /* Get a local copy of the address. Handles possible alignment issues */ + else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) + != ACPI_TYPE_INTEGER) || + (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) + != ACPI_TYPE_INTEGER)) { + ACPI_ERROR((AE_INFO, + "Sleep State return package elements are not both Integers (%s, %s)", + acpi_ut_get_object_type_name(info->return_object-> + package.elements[0]), + acpi_ut_get_object_type_name(info->return_object-> + package.elements[1]))); + status = AE_AML_OPERAND_TYPE; + } else { + /* Valid _Sx_ package size, type, and value */ - ACPI_MOVE_64_TO_64(&address, ®->address); - if (!address) { - return (AE_OK); + *sleep_type_a = (u8) + (info->return_object->package.elements[0])->integer.value; + *sleep_type_b = (u8) + (info->return_object->package.elements[1])->integer.value; } - /* - * Two address spaces supported: Memory or IO. - * PCI_Config is not supported here because the GAS struct is insufficient - */ - switch (reg->space_id) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: - - status = acpi_os_write_memory((acpi_physical_address) address, - value, width); - break; - - case ACPI_ADR_SPACE_SYSTEM_IO: - - status = acpi_os_write_port((acpi_io_address) address, value, - width); - break; - - default: - ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); - return (AE_BAD_PARAMETER); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "While evaluating SleepState [%s], bad Sleep object %p type %s", + info->pathname, info->return_object, + acpi_ut_get_object_type_name(info-> + return_object))); } - ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", - value, width, ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); + acpi_ut_remove_reference(info->return_object); - return (status); + cleanup: + ACPI_FREE(info); + return_ACPI_STATUS(status); } + +ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/acpica/nsaccess.c similarity index 98% rename from drivers/acpi/namespace/nsaccess.c rename to drivers/acpi/acpica/nsaccess.c index c39a7f68b88..88303ebe924 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "amlcode.h" +#include "acnamesp.h" +#include "acdispat.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsaccess") @@ -165,11 +166,8 @@ acpi_status acpi_ns_root_initialize(void) obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY; - -#ifndef ACPI_DUMP_APP obj_desc->method.implementation = acpi_ut_osi_implementation; -#endif #endif break; @@ -521,11 +519,11 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, } /* - * Search namespace for each segment of the name. Loop through and + * Search namespace for each segment of the name. Loop through and * verify (or add to the namespace) each name segment. * * The object type is significant only at the last name - * segment. (We don't care about the types along the path, only + * segment. (We don't care about the types along the path, only * the type of the final target object.) */ this_search_type = ACPI_TYPE_ANY; @@ -591,6 +589,10 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, * segments). */ if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { + if (!this_node->object) { + return_ACPI_STATUS(AE_NOT_EXIST); + } + if (acpi_ns_opens_scope (((struct acpi_namespace_node *)this_node-> object)->type)) { diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/acpica/nsalloc.c similarity index 99% rename from drivers/acpi/namespace/nsalloc.c rename to drivers/acpi/acpica/nsalloc.c index 3a1740ac2ed..f976d848fe8 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsalloc") diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/acpica/nsdump.c similarity index 99% rename from drivers/acpi/namespace/nsdump.c rename to drivers/acpi/acpica/nsdump.c index cc0ae39440e..0da33c8e9ba 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsdump") diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c similarity index 99% rename from drivers/acpi/namespace/nsdumpdv.c rename to drivers/acpi/acpica/nsdumpdv.c index 428f50fde11..41994fe7fbb 100644 --- a/drivers/acpi/namespace/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -42,6 +42,7 @@ */ #include +#include "accommon.h" /* TBD: This entire module is apparently obsolete and should be removed */ @@ -49,7 +50,7 @@ ACPI_MODULE_NAME("nsdumpdv") #ifdef ACPI_OBSOLETE_FUNCTIONS #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) -#include +#include "acnamesp.h" /******************************************************************************* * * FUNCTION: acpi_ns_dump_one_device diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/acpica/nseval.c similarity index 81% rename from drivers/acpi/namespace/nseval.c rename to drivers/acpi/acpica/nseval.c index 4cdf03ac2b4..0f3d5f9b596 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acinterp.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nseval") @@ -89,6 +90,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) /* Initialize the return value to an invalid object */ info->return_object = NULL; + info->param_count = 0; /* * Get the actual namespace node for the target object. Handles these cases: @@ -141,41 +143,17 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) return_ACPI_STATUS(AE_NULL_OBJECT); } - /* - * Calculate the number of arguments being passed to the method - */ + /* Count the number of arguments being passed to the method */ - info->param_count = 0; if (info->parameters) { - while (info->parameters[info->param_count]) + while (info->parameters[info->param_count]) { + if (info->param_count > ACPI_METHOD_MAX_ARG) { + return_ACPI_STATUS(AE_LIMIT); + } info->param_count++; + } } - /* - * Warning if too few or too many arguments have been passed by the - * caller. We don't want to abort here with an error because an - * incorrect number of arguments may not cause the method to fail. - * However, the method will fail if there are too few arguments passed - * and the method attempts to use one of the missing ones. - */ - - if (info->param_count < info->obj_desc->method.param_count) { - ACPI_WARNING((AE_INFO, - "Insufficient arguments - " - "method [%4.4s] needs %d, found %d", - acpi_ut_get_node_name(info->resolved_node), - info->obj_desc->method.param_count, - info->param_count)); - } else if (info->param_count > - info->obj_desc->method.param_count) { - ACPI_WARNING((AE_INFO, - "Excess arguments - " - "method [%4.4s] needs %d, found %d", - acpi_ut_get_node_name(info-> - resolved_node), - info->obj_desc->method.param_count, - info->param_count)); - } ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", ACPI_LV_INFO, _COMPONENT); @@ -264,32 +242,13 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) } } - /* Validation of return values for ACPI-predefined methods and objects */ - - if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) { - /* - * If this is the first evaluation, check the return value. This - * ensures that any warnings will only be emitted during the very - * first evaluation of the object. - */ - if (!(node->flags & ANOBJ_EVALUATED)) { - /* - * Check for a predefined ACPI name. If found, validate the - * returned object. - * - * Note: Ignore return status for now, emit warnings if there are - * problems with the returned object. May change later to abort - * the method on invalid return object. - */ - (void)acpi_ns_check_predefined_names(node, - info-> - return_object); - } - - /* Mark the node as having been evaluated */ - - node->flags |= ANOBJ_EVALUATED; - } + /* + * Check input argument count against the ASL-defined count for a method. + * Also check predefined names: argument count and return value against + * the ACPI specification. Some incorrect return value types are repaired. + */ + (void)acpi_ns_check_predefined_names(node, info->param_count, + status, &info->return_object); /* Check if there is a return value that must be dealt with */ diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/acpica/nsinit.c similarity index 99% rename from drivers/acpi/namespace/nsinit.c rename to drivers/acpi/acpica/nsinit.c index e4c57510d79..13501cb8186 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acdispat.h" +#include "acinterp.h" #include #define _COMPONENT ACPI_NAMESPACE diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/acpica/nsload.c similarity index 99% rename from drivers/acpi/namespace/nsload.c rename to drivers/acpi/acpica/nsload.c index a4a412b7c02..a0ba9e12379 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acdispat.h" +#include "actables.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsload") diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/acpica/nsnames.c similarity index 99% rename from drivers/acpi/namespace/nsnames.c rename to drivers/acpi/acpica/nsnames.c index 42a39a7c96e..ae3dc10a7e8 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsnames") diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/acpica/nsobject.c similarity index 99% rename from drivers/acpi/namespace/nsobject.c rename to drivers/acpi/acpica/nsobject.c index 15fe09e24f7..08a97a57f8f 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsobject") diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/acpica/nsparse.c similarity index 98% rename from drivers/acpi/namespace/nsparse.c rename to drivers/acpi/acpica/nsparse.c index a82271a9dbb..b9e8d0070b6 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -42,10 +42,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acparser.h" +#include "acdispat.h" +#include "actables.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsparse") diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/acpica/nspredef.c similarity index 76% rename from drivers/acpi/namespace/nspredef.c rename to drivers/acpi/acpica/nspredef.c index 0f17cf0898c..452703290d3 100644 --- a/drivers/acpi/namespace/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -43,8 +43,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acpredef.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nspredef") @@ -72,7 +73,7 @@ ACPI_MODULE_NAME("nspredef") /* Local prototypes */ static acpi_status acpi_ns_check_package(char *pathname, - union acpi_operand_object *return_object, + union acpi_operand_object **return_object_ptr, const union acpi_predefined_info *predefined); static acpi_status @@ -82,13 +83,18 @@ acpi_ns_check_package_elements(char *pathname, static acpi_status acpi_ns_check_object_type(char *pathname, - union acpi_operand_object *return_object, + union acpi_operand_object **return_object_ptr, u32 expected_btypes, u32 package_index); static acpi_status acpi_ns_check_reference(char *pathname, union acpi_operand_object *return_object); +static acpi_status +acpi_ns_repair_object(u32 expected_btypes, + u32 package_index, + union acpi_operand_object **return_object_ptr); + /* * Names for the types that can be returned by the predefined objects. * Used for warning messages. Must be in the same order as the ACPI_RTYPEs @@ -108,8 +114,8 @@ static const char *acpi_rtype_names[] = { * FUNCTION: acpi_ns_check_predefined_names * * PARAMETERS: Node - Namespace node for the method/object - * return_object - Object returned from the evaluation of this - * method/object + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object * * RETURN: Status * @@ -119,8 +125,11 @@ static const char *acpi_rtype_names[] = { acpi_status acpi_ns_check_predefined_names(struct acpi_namespace_node *node, - union acpi_operand_object *return_object) + u32 user_param_count, + acpi_status return_status, + union acpi_operand_object **return_object_ptr) { + union acpi_operand_object *return_object = *return_object_ptr; acpi_status status = AE_OK; const union acpi_predefined_info *predefined; char *pathname; @@ -128,12 +137,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, /* Match the name for this method/object against the predefined list */ predefined = acpi_ns_check_for_predefined_name(node); - if (!predefined) { - - /* Name was not one of the predefined names */ - - return (AE_OK); - } /* Get the full pathname to the object, for use in error messages */ @@ -143,10 +146,37 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, } /* - * Check that the parameter count for this method is in accordance - * with the ACPI specification. + * Check that the parameter count for this method matches the ASL + * definition. For predefined names, ensure that both the caller and + * the method itself are in accordance with the ACPI specification. */ - acpi_ns_check_parameter_count(pathname, node, predefined); + acpi_ns_check_parameter_count(pathname, node, user_param_count, + predefined); + + /* If not a predefined name, we cannot validate the return object */ + + if (!predefined) { + goto exit; + } + + /* If the method failed, we cannot validate the return object */ + + if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { + goto exit; + } + + /* + * Only validate the return value on the first successful evaluation of + * the method. This ensures that any warnings will only be emitted during + * the very first evaluation of the method/object. + */ + if (node->flags & ANOBJ_EVALUATED) { + goto exit; + } + + /* Mark the node as having been successfully evaluated */ + + node->flags |= ANOBJ_EVALUATED; /* * If there is no return value, check if we require a return value for @@ -171,7 +201,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, * We have a return value, but if one wasn't expected, just exit, this is * not a problem * - * For example, if "Implicit return value" is enabled, methods will + * For example, if the "Implicit Return" feature is enabled, methods will * always return a value */ if (!predefined->info.expected_btypes) { @@ -182,7 +212,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, * Check that the type of the return object is what is expected for * this predefined name */ - status = acpi_ns_check_object_type(pathname, return_object, + status = acpi_ns_check_object_type(pathname, return_object_ptr, predefined->info.expected_btypes, ACPI_NOT_PACKAGE); if (ACPI_FAILURE(status)) { @@ -193,11 +223,12 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) { status = - acpi_ns_check_package(pathname, return_object, predefined); + acpi_ns_check_package(pathname, return_object_ptr, + predefined); } exit: - if (pathname) { + if (pathname != predefined->info.name) { ACPI_FREE(pathname); } @@ -210,6 +241,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, * * PARAMETERS: Pathname - Full pathname to the node (for error msgs) * Node - Namespace node for the method/object + * user_param_count - Number of args passed in by the caller * Predefined - Pointer to entry in predefined name table * * RETURN: None @@ -223,32 +255,76 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, void acpi_ns_check_parameter_count(char *pathname, struct acpi_namespace_node *node, + u32 user_param_count, const union acpi_predefined_info *predefined) { u32 param_count; u32 required_params_current; u32 required_params_old; - /* - * Check that the ASL-defined parameter count is what is expected for - * this predefined name. - * - * Methods have 0-7 parameters. All other types have zero. - */ + /* Methods have 0-7 parameters. All other types have zero. */ + param_count = 0; if (node->type == ACPI_TYPE_METHOD) { param_count = node->object->method.param_count; } - /* Validate parameter count - allow two different legal counts (_SCP) */ + /* Argument count check for non-predefined methods/objects */ + + if (!predefined) { + /* + * Warning if too few or too many arguments have been passed by the + * caller. An incorrect number of arguments may not cause the method + * to fail. However, the method will fail if there are too few + * arguments and the method attempts to use one of the missing ones. + */ + if (user_param_count < param_count) { + ACPI_WARNING((AE_INFO, + "%s: Insufficient arguments - needs %d, found %d", + pathname, param_count, user_param_count)); + } else if (user_param_count > param_count) { + ACPI_WARNING((AE_INFO, + "%s: Excess arguments - needs %d, found %d", + pathname, param_count, user_param_count)); + } + return; + } + + /* Allow two different legal argument counts (_SCP, etc.) */ required_params_current = predefined->info.param_count & 0x0F; required_params_old = predefined->info.param_count >> 4; + if (user_param_count != ACPI_UINT32_MAX) { + + /* Validate the user-supplied parameter count */ + + if ((user_param_count != required_params_current) && + (user_param_count != required_params_old)) { + ACPI_WARNING((AE_INFO, + "%s: Parameter count mismatch - caller passed %d, ACPI requires %d", + pathname, user_param_count, + required_params_current)); + } + } + + /* + * Only validate the argument count on the first successful evaluation of + * the method. This ensures that any warnings will only be emitted during + * the very first evaluation of the method/object. + */ + if (node->flags & ANOBJ_EVALUATED) { + return; + } + + /* + * Check that the ASL-defined parameter count is what is expected for + * this predefined name. + */ if ((param_count != required_params_current) && (param_count != required_params_old)) { ACPI_WARNING((AE_INFO, - "%s: Parameter count mismatch - ASL declared %d, expected %d", + "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", pathname, param_count, required_params_current)); } } @@ -307,8 +383,8 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct * FUNCTION: acpi_ns_check_package * * PARAMETERS: Pathname - Full pathname to the node (for error msgs) - * return_object - Object returned from the evaluation of a - * method or object + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object * Predefined - Pointer to entry in predefined name table * * RETURN: Status @@ -320,9 +396,10 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct static acpi_status acpi_ns_check_package(char *pathname, - union acpi_operand_object *return_object, + union acpi_operand_object **return_object_ptr, const union acpi_predefined_info *predefined) { + union acpi_operand_object *return_object = *return_object_ptr; const union acpi_predefined_info *package; union acpi_operand_object *sub_package; union acpi_operand_object **elements; @@ -408,7 +485,7 @@ acpi_ns_check_package(char *pathname, * elements must be of the same type */ for (i = 0; i < count; i++) { - status = acpi_ns_check_object_type(pathname, *elements, + status = acpi_ns_check_object_type(pathname, elements, package->ret_info. object_type1, i); if (ACPI_FAILURE(status)) { @@ -441,7 +518,7 @@ acpi_ns_check_package(char *pathname, status = acpi_ns_check_object_type(pathname, - *elements, + elements, package-> ret_info3. object_type[i], @@ -454,7 +531,7 @@ acpi_ns_check_package(char *pathname, status = acpi_ns_check_object_type(pathname, - *elements, + elements, package-> ret_info3. tail_object_type, @@ -471,7 +548,7 @@ acpi_ns_check_package(char *pathname, /* First element is the (Integer) count of sub-packages to follow */ - status = acpi_ns_check_object_type(pathname, *elements, + status = acpi_ns_check_object_type(pathname, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { return (status); @@ -509,7 +586,7 @@ acpi_ns_check_package(char *pathname, /* Each sub-object must be of type Package */ status = - acpi_ns_check_object_type(pathname, sub_package, + acpi_ns_check_object_type(pathname, &sub_package, ACPI_RTYPE_PACKAGE, i); if (ACPI_FAILURE(status)) { return (status); @@ -567,12 +644,8 @@ acpi_ns_check_package(char *pathname, for (j = 0; j < expected_count; j++) { status = acpi_ns_check_object_type(pathname, - sub_elements - [j], - package-> - ret_info2. - object_type - [j], j); + &sub_elements[j], + package->ret_info2.object_type[j], j); if (ACPI_FAILURE(status)) { return (status); } @@ -611,7 +684,7 @@ acpi_ns_check_package(char *pathname, status = acpi_ns_check_object_type(pathname, - *sub_elements, + sub_elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { @@ -708,7 +781,7 @@ acpi_ns_check_package_elements(char *pathname, * The second group can have a count of zero. */ for (i = 0; i < count1; i++) { - status = acpi_ns_check_object_type(pathname, *this_element, + status = acpi_ns_check_object_type(pathname, this_element, type1, i); if (ACPI_FAILURE(status)) { return (status); @@ -717,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname, } for (i = 0; i < count2; i++) { - status = acpi_ns_check_object_type(pathname, *this_element, + status = acpi_ns_check_object_type(pathname, this_element, type2, (i + count1)); if (ACPI_FAILURE(status)) { return (status); @@ -733,8 +806,8 @@ acpi_ns_check_package_elements(char *pathname, * FUNCTION: acpi_ns_check_object_type * * PARAMETERS: Pathname - Full pathname to the node (for error msgs) - * return_object - Object return from the execution of this - * method/object + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object * expected_btypes - Bitmap of expected return type(s) * package_index - Index of object within parent package (if * applicable - ACPI_NOT_PACKAGE otherwise) @@ -748,9 +821,10 @@ acpi_ns_check_package_elements(char *pathname, static acpi_status acpi_ns_check_object_type(char *pathname, - union acpi_operand_object *return_object, + union acpi_operand_object **return_object_ptr, u32 expected_btypes, u32 package_index) { + union acpi_operand_object *return_object = *return_object_ptr; acpi_status status = AE_OK; u32 return_btype; char type_buffer[48]; /* Room for 5 types */ @@ -814,6 +888,14 @@ acpi_ns_check_object_type(char *pathname, /* Is the object one of the expected types? */ if (!(return_btype & expected_btypes)) { + + /* Type mismatch -- attempt repair of the returned object */ + + status = acpi_ns_repair_object(expected_btypes, package_index, + return_object_ptr); + if (ACPI_SUCCESS(status)) { + return (status); + } goto type_error_exit; } @@ -898,3 +980,86 @@ acpi_ns_check_reference(char *pathname, return (AE_AML_OPERAND_TYPE); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_repair_object + * + * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * package_index - Used to determine if target is in a package + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. + * + * DESCRIPTION: Attempt to repair/convert a return object of a type that was + * not expected. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_repair_object(u32 expected_btypes, + u32 package_index, + union acpi_operand_object **return_object_ptr) +{ + union acpi_operand_object *return_object = *return_object_ptr; + union acpi_operand_object *new_object; + acpi_size length; + + switch (ACPI_GET_OBJECT_TYPE(return_object)) { + case ACPI_TYPE_BUFFER: + + if (!(expected_btypes & ACPI_RTYPE_STRING)) { + return (AE_AML_OPERAND_TYPE); + } + + /* + * Have a Buffer, expected a String, convert. Use a to_string + * conversion, no transform performed on the buffer data. The best + * example of this is the _BIF method, where the string data from + * the battery is often (incorrectly) returned as buffer object(s). + */ + length = 0; + while ((length < return_object->buffer.length) && + (return_object->buffer.pointer[length])) { + length++; + } + + /* Allocate a new string object */ + + new_object = acpi_ut_create_string_object(length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* + * Copy the raw buffer data with no transform. String is already NULL + * terminated at Length+1. + */ + ACPI_MEMCPY(new_object->string.pointer, + return_object->buffer.pointer, length); + + /* Install the new return object */ + + acpi_ut_remove_reference(return_object); + *return_object_ptr = new_object; + + /* + * If the object is a package element, we need to: + * 1. Decrement the reference count of the orignal object, it was + * incremented when building the package + * 2. Increment the reference count of the new object, it will be + * decremented when releasing the package + */ + if (package_index != ACPI_NOT_PACKAGE) { + acpi_ut_remove_reference(return_object); + acpi_ut_add_reference(new_object); + } + return (AE_OK); + + default: + break; + } + + return (AE_AML_OPERAND_TYPE); +} diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/acpica/nssearch.c similarity index 99% rename from drivers/acpi/namespace/nssearch.c rename to drivers/acpi/acpica/nssearch.c index a9a80bf811b..6fea13f3f52 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nssearch") diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/acpica/nsutils.c similarity index 98% rename from drivers/acpi/namespace/nsutils.c rename to drivers/acpi/acpica/nsutils.c index b0817e1127b..3e1149bf4aa 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -43,9 +43,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "amlcode.h" +#include "actables.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsutils") @@ -314,9 +315,15 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) * * strlen() + 1 covers the first name_seg, which has no path separator */ - if (acpi_ns_valid_root_prefix(next_external_char[0])) { + if (acpi_ns_valid_root_prefix(*next_external_char)) { info->fully_qualified = TRUE; next_external_char++; + + /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */ + + while (acpi_ns_valid_root_prefix(*next_external_char)) { + next_external_char++; + } } else { /* * Handle Carat prefixes diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/acpica/nswalk.c similarity index 99% rename from drivers/acpi/namespace/nswalk.c rename to drivers/acpi/acpica/nswalk.c index 3c905ce26d7..200895fa272 100644 --- a/drivers/acpi/namespace/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nswalk") diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c similarity index 99% rename from drivers/acpi/namespace/nsxfeval.c rename to drivers/acpi/acpica/nsxfeval.c index a085cc39c05..22a7171ac1e 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -43,8 +43,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfeval") diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/acpica/nsxfname.c similarity index 99% rename from drivers/acpi/namespace/nsxfname.c rename to drivers/acpi/acpica/nsxfname.c index 5efa4e7ddb0..9589fea2499 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfname") diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c similarity index 99% rename from drivers/acpi/namespace/nsxfobj.c rename to drivers/acpi/acpica/nsxfobj.c index 2b375ee80ce..1c7efc15225 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -43,7 +43,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfobj") diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/acpica/psargs.c similarity index 99% rename from drivers/acpi/parser/psargs.c rename to drivers/acpi/acpica/psargs.c index d830b29b85b..b161f3544b5 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -42,10 +42,11 @@ */ #include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acnamesp.h" +#include "acdispat.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psargs") diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/acpica/psloop.c similarity index 99% rename from drivers/acpi/parser/psloop.c rename to drivers/acpi/acpica/psloop.c index 4647039a0d8..c5f6ce19a40 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -50,9 +50,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acdispat.h" +#include "amlcode.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psloop") diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/acpica/psopcode.c similarity index 99% rename from drivers/acpi/parser/psopcode.c rename to drivers/acpi/acpica/psopcode.c index f425ab30eae..3bc3a60194d 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acopcode.h" +#include "amlcode.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psopcode") diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/acpica/psparse.c similarity index 97% rename from drivers/acpi/parser/psparse.c rename to drivers/acpi/acpica/psparse.c index 68e932f215e..70838e9b608 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -51,11 +51,12 @@ */ #include -#include -#include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acdispat.h" +#include "amlcode.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psparse") @@ -447,10 +448,22 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size)); + if (!walk_state->parser_state.aml) { + return_ACPI_STATUS(AE_NULL_OBJECT); + } + /* Create and initialize a new thread state */ thread = acpi_ut_create_thread_state(); if (!thread) { + if (walk_state->method_desc) { + + /* Executing a control method - additional cleanup */ + + acpi_ds_terminate_control_method( + walk_state->method_desc, walk_state); + } + acpi_ds_delete_walk_state(walk_state); return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/acpica/psscope.c similarity index 99% rename from drivers/acpi/parser/psscope.c rename to drivers/acpi/acpica/psscope.c index ee50e67c944..2feca5ca958 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/acpica/psscope.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acparser.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psscope") diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/acpica/pstree.c similarity index 99% rename from drivers/acpi/parser/pstree.c rename to drivers/acpi/acpica/pstree.c index 1dd355ddd18..4d3389118ec 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/acpica/pstree.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("pstree") diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/acpica/psutils.c similarity index 99% rename from drivers/acpi/parser/psutils.c rename to drivers/acpi/acpica/psutils.c index 7cf1f65cd5b..e636e078ad3 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psutils") diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/acpica/pswalk.c similarity index 98% rename from drivers/acpi/parser/pswalk.c rename to drivers/acpi/acpica/pswalk.c index 8b86ad5a320..78b8b791f2a 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acparser.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("pswalk") diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/acpica/psxface.c similarity index 90% rename from drivers/acpi/parser/psxface.c rename to drivers/acpi/acpica/psxface.c index 270469aae84..ff06032c0f0 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -42,9 +42,11 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acparser.h" +#include "acdispat.h" +#include "acinterp.h" +#include "amlcode.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psxface") @@ -278,6 +280,38 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) goto cleanup; } + /* Invoke an internal method if necessary */ + + if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { + status = info->obj_desc->method.implementation(walk_state); + info->return_object = walk_state->return_desc; + + /* Cleanup states */ + + acpi_ds_scope_stack_clear(walk_state); + acpi_ps_cleanup_scope(&walk_state->parser_state); + acpi_ds_terminate_control_method(walk_state->method_desc, + walk_state); + acpi_ds_delete_walk_state(walk_state); + goto cleanup; + } + + /* + * Start method evaluation with an implicit return of zero. + * This is done for Windows compatibility. + */ + if (acpi_gbl_enable_interpreter_slack) { + walk_state->implicit_return_obj = + acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); + if (!walk_state->implicit_return_obj) { + status = AE_NO_MEMORY; + acpi_ds_delete_walk_state(walk_state); + goto cleanup; + } + + walk_state->implicit_return_obj->integer.value = 0; + } + /* Parse the AML */ status = acpi_ps_parse_aml(walk_state); diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/acpica/rsaddr.c similarity index 99% rename from drivers/acpi/resources/rsaddr.c rename to drivers/acpi/acpica/rsaddr.c index 7f96332822b..1e437bfd8db 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsaddr") diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/acpica/rscalc.c similarity index 99% rename from drivers/acpi/resources/rscalc.c rename to drivers/acpi/acpica/rscalc.c index 8eaaecf9200..52865ee6bc7 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acresrc.h" +#include "acnamesp.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rscalc") diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/acpica/rscreate.c similarity index 99% rename from drivers/acpi/resources/rscreate.c rename to drivers/acpi/acpica/rscreate.c index 08b8d73e6ee..61566b1a061 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acresrc.h" +#include "acnamesp.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rscreate") diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/acpica/rsdump.c similarity index 99% rename from drivers/acpi/resources/rsdump.c rename to drivers/acpi/acpica/rsdump.c index 6bbbb7b8941..3f0ca5a12d3 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsdump") diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/acpica/rsinfo.c similarity index 99% rename from drivers/acpi/resources/rsinfo.c rename to drivers/acpi/acpica/rsinfo.c index 3f0a1fedbe0..77b25fdb459 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsinfo") diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/acpica/rsio.c similarity index 99% rename from drivers/acpi/resources/rsio.c rename to drivers/acpi/acpica/rsio.c index b66d42e7402..35a49aa9560 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/acpica/rsio.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsio") diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/acpica/rsirq.c similarity index 99% rename from drivers/acpi/resources/rsirq.c rename to drivers/acpi/acpica/rsirq.c index a8805efc036..2e0256983aa 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsirq") diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/acpica/rslist.c similarity index 99% rename from drivers/acpi/resources/rslist.c rename to drivers/acpi/acpica/rslist.c index b78c7e797a1..1b1dbc69f08 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/acpica/rsmemory.c similarity index 99% rename from drivers/acpi/resources/rsmemory.c rename to drivers/acpi/acpica/rsmemory.c index 63b21abd90b..ddc76cebdc9 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsmemory") diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/acpica/rsmisc.c similarity index 99% rename from drivers/acpi/resources/rsmisc.c rename to drivers/acpi/acpica/rsmisc.c index 96a6c035325..5bc49a55328 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsmisc") diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/acpica/rsutils.c similarity index 99% rename from drivers/acpi/resources/rsutils.c rename to drivers/acpi/acpica/rsutils.c index f7b3bcd59ba..bc03d596682 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acresrc.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsutils") diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/acpica/rsxface.c similarity index 99% rename from drivers/acpi/resources/rsxface.c rename to drivers/acpi/acpica/rsxface.c index f59f4c4e034..69a2aa5b5d8 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acresrc.h" +#include "acnamesp.h" #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsxface") diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/acpica/tbfadt.c similarity index 67% rename from drivers/acpi/tables/tbfadt.c rename to drivers/acpi/acpica/tbfadt.c index 2817158fb6a..3636e4f8fb7 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -42,15 +42,16 @@ */ #include -#include +#include "accommon.h" +#include "actables.h" #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbfadt") /* Local prototypes */ -static void inline +static inline void acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, - u8 byte_width, u64 address); + u8 space_id, u8 byte_width, u64 address); static void acpi_tb_convert_fadt(void); @@ -60,9 +61,10 @@ static void acpi_tb_validate_fadt(void); typedef struct acpi_fadt_info { char *name; - u8 target; - u8 source; + u8 address64; + u8 address32; u8 length; + u8 default_length; u8 type; } acpi_fadt_info; @@ -71,37 +73,61 @@ typedef struct acpi_fadt_info { #define ACPI_FADT_SEPARATE_LENGTH 2 static struct acpi_fadt_info fadt_info_table[] = { - {"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block), + {"Pm1aEventBlock", + ACPI_FADT_OFFSET(xpm1a_event_block), ACPI_FADT_OFFSET(pm1a_event_block), - ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED}, + ACPI_FADT_OFFSET(pm1_event_length), + ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ + ACPI_FADT_REQUIRED}, - {"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block), + {"Pm1bEventBlock", + ACPI_FADT_OFFSET(xpm1b_event_block), ACPI_FADT_OFFSET(pm1b_event_block), - ACPI_FADT_OFFSET(pm1_event_length), 0}, + ACPI_FADT_OFFSET(pm1_event_length), + ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ + 0}, - {"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block), + {"Pm1aControlBlock", + ACPI_FADT_OFFSET(xpm1a_control_block), ACPI_FADT_OFFSET(pm1a_control_block), - ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED}, + ACPI_FADT_OFFSET(pm1_control_length), + ACPI_PM1_REGISTER_WIDTH, + ACPI_FADT_REQUIRED}, - {"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block), + {"Pm1bControlBlock", + ACPI_FADT_OFFSET(xpm1b_control_block), ACPI_FADT_OFFSET(pm1b_control_block), - ACPI_FADT_OFFSET(pm1_control_length), 0}, + ACPI_FADT_OFFSET(pm1_control_length), + ACPI_PM1_REGISTER_WIDTH, + 0}, - {"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block), + {"Pm2ControlBlock", + ACPI_FADT_OFFSET(xpm2_control_block), ACPI_FADT_OFFSET(pm2_control_block), - ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH}, + ACPI_FADT_OFFSET(pm2_control_length), + ACPI_PM2_REGISTER_WIDTH, + ACPI_FADT_SEPARATE_LENGTH}, - {"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block), + {"PmTimerBlock", + ACPI_FADT_OFFSET(xpm_timer_block), ACPI_FADT_OFFSET(pm_timer_block), - ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED}, + ACPI_FADT_OFFSET(pm_timer_length), + ACPI_PM_TIMER_WIDTH, + ACPI_FADT_REQUIRED}, - {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block), + {"Gpe0Block", + ACPI_FADT_OFFSET(xgpe0_block), ACPI_FADT_OFFSET(gpe0_block), - ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH}, + ACPI_FADT_OFFSET(gpe0_block_length), + 0, + ACPI_FADT_SEPARATE_LENGTH}, - {"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block), + {"Gpe1Block", + ACPI_FADT_OFFSET(xgpe1_block), ACPI_FADT_OFFSET(gpe1_block), - ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH} + ACPI_FADT_OFFSET(gpe1_block_length), + 0, + ACPI_FADT_SEPARATE_LENGTH} }; #define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) @@ -122,9 +148,9 @@ static struct acpi_fadt_info fadt_info_table[] = { * ******************************************************************************/ -static void inline +static inline void acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, - u8 byte_width, u64 address) + u8 space_id, u8 byte_width, u64 address) { /* @@ -135,10 +161,10 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, /* All other fields are byte-wide */ - generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; - generic_address->bit_width = byte_width << 3; + generic_address->space_id = space_id; + generic_address->bit_width = (u8)ACPI_MUL_8(byte_width); generic_address->bit_offset = 0; - generic_address->access_width = 0; + generic_address->access_width = 0; /* Access width ANY */ } /******************************************************************************* @@ -225,7 +251,8 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, - "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX", + "FADT (revision %u) is longer than ACPI 2.0 version, " + "truncating length 0x%X to 0x%zX", table->revision, (unsigned)length, sizeof(struct acpi_table_fadt))); } @@ -244,7 +271,6 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) * 2) Validate some of the important values within the FADT */ acpi_tb_convert_fadt(); - acpi_tb_validate_fadt(); } /******************************************************************************* @@ -278,22 +304,36 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) static void acpi_tb_convert_fadt(void) { - u8 pm1_register_length; - struct acpi_generic_address *target; + u8 pm1_register_bit_width; + u8 pm1_register_byte_width; + struct acpi_generic_address *target64; u32 i; /* Update the local FADT table header length */ acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); - /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */ - + /* + * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. + * Later code will always use the X 64-bit field. Also, check for an + * address mismatch between the 32-bit and 64-bit address fields + * (FIRMWARE_CTRL/X_FIRMWARE_CTRL, DSDT/X_DSDT) which would indicate + * the presence of two FACS or two DSDT tables. + */ if (!acpi_gbl_FADT.Xfacs) { acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; + } else if (acpi_gbl_FADT.facs && + (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { + ACPI_WARNING((AE_INFO, + "32/64 FACS address mismatch in FADT - two FACS tables!")); } if (!acpi_gbl_FADT.Xdsdt) { acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; + } else if (acpi_gbl_FADT.dsdt && + (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { + ACPI_WARNING((AE_INFO, + "32/64 DSDT address mismatch in FADT - two DSDT tables!")); } /* @@ -312,18 +352,23 @@ static void acpi_tb_convert_fadt(void) } /* - * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" - * generic address structures as necessary. + * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" + * generic address structures as necessary. Later code will always use + * the 64-bit address structures. */ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { - target = + target64 = ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, - fadt_info_table[i].target); + fadt_info_table[i].address64); - /* Expand only if the X target is null */ + /* Expand only if the 64-bit X target is null */ - if (!target->address) { - acpi_tb_init_generic_address(target, + if (!target64->address) { + + /* The space_id is always I/O for the 32-bit legacy address fields */ + + acpi_tb_init_generic_address(target64, + ACPI_ADR_SPACE_SYSTEM_IO, *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, fadt_info_table @@ -332,10 +377,63 @@ static void acpi_tb_convert_fadt(void) &acpi_gbl_FADT, fadt_info_table [i]. - source)); + address32)); + } + } + + /* Validate FADT values now, before we make any changes */ + + acpi_tb_validate_fadt(); + + /* + * Optionally check all register lengths against the default values and + * update them if they are incorrect. + */ + if (acpi_gbl_use_default_register_widths) { + for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { + target64 = + ACPI_ADD_PTR(struct acpi_generic_address, + &acpi_gbl_FADT, + fadt_info_table[i].address64); + + /* + * If a valid register (Address != 0) and the (default_length > 0) + * (Not a GPE register), then check the width against the default. + */ + if ((target64->address) && + (fadt_info_table[i].default_length > 0) && + (fadt_info_table[i].default_length != + target64->bit_width)) { + ACPI_WARNING((AE_INFO, + "Invalid length for %s: %d, using default %d", + fadt_info_table[i].name, + target64->bit_width, + fadt_info_table[i]. + default_length)); + + /* Incorrect size, set width to the default */ + + target64->bit_width = + fadt_info_table[i].default_length; + } } } + /* + * Get the length of the individual PM1 registers (enable and status). + * Each register is defined to be (event block length / 2). + */ + pm1_register_bit_width = + (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width); + pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width); + + /* + * Adjust the lengths of the PM1 Event Blocks so that they can be used to + * access the PM1 status register(s). Use (width / 2) + */ + acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width; + acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width; + /* * Calculate separate GAS structs for the PM1 Enable registers. * These addresses do not appear (directly) in the FADT, so it is @@ -356,14 +454,14 @@ static void acpi_tb_convert_fadt(void) " PM1_EVT_LEN (%u)\n", acpi_gbl_FADT.xpm1a_event_block.bit_width, acpi_gbl_FADT.pm1_event_length); - pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); /* The PM1A register block is required */ acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, - pm1_register_length, + acpi_gbl_FADT.xpm1a_event_block.space_id, + pm1_register_byte_width, (acpi_gbl_FADT.xpm1a_event_block.address + - pm1_register_length)); + pm1_register_byte_width)); /* Don't forget to copy space_id of the GAS */ acpi_gbl_xpm1a_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; @@ -379,9 +477,10 @@ static void acpi_tb_convert_fadt(void) acpi_gbl_FADT.xpm1b_event_block.bit_width, acpi_gbl_FADT.pm1_event_length); acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, - pm1_register_length, + acpi_gbl_FADT.xpm1b_event_block.space_id, + pm1_register_byte_width, (acpi_gbl_FADT.xpm1b_event_block. - address + pm1_register_length)); + address + pm1_register_byte_width)); /* Don't forget to copy space_id of the GAS */ acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1b_event_block.space_id; @@ -411,26 +510,63 @@ static void acpi_tb_convert_fadt(void) static void acpi_tb_validate_fadt(void) { + char *name; u32 *address32; struct acpi_generic_address *address64; u8 length; u32 i; - /* Examine all of the 64-bit extended address fields (X fields) */ + /* + * Check for FACS and DSDT address mismatches. An address mismatch between + * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and + * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. + */ + if (acpi_gbl_FADT.facs && + (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { + ACPI_WARNING((AE_INFO, + "32/64X FACS address mismatch in FADT - " + "two FACS tables! %8.8X/%8.8X%8.8X", + acpi_gbl_FADT.facs, + ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs))); + } - for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { + if (acpi_gbl_FADT.dsdt && + (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { + ACPI_WARNING((AE_INFO, + "32/64X DSDT address mismatch in FADT - " + "two DSDT tables! %8.8X/%8.8X%8.8X", + acpi_gbl_FADT.dsdt, + ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt))); + } - /* Generate pointers to the 32-bit and 64-bit addresses and get the length */ + /* Examine all of the 64-bit extended address fields (X fields) */ - address64 = - ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, - fadt_info_table[i].target); + for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { + /* + * Generate pointers to the 32-bit and 64-bit addresses, get the + * register length (width), and the register name + */ + address64 = ACPI_ADD_PTR(struct acpi_generic_address, + &acpi_gbl_FADT, + fadt_info_table[i].address64); address32 = ACPI_ADD_PTR(u32, &acpi_gbl_FADT, - fadt_info_table[i].source); + fadt_info_table[i].address32); length = *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, fadt_info_table[i].length); + name = fadt_info_table[i].name; + + /* + * For each extended field, check for length mismatch between the + * legacy length field and the corresponding 64-bit X length field. + */ + if (address64 && (address64->bit_width != ACPI_MUL_8(length))) { + ACPI_WARNING((AE_INFO, + "32/64X length mismatch in %s: %d/%d", + name, ACPI_MUL_8(length), + address64->bit_width)); + } if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { /* @@ -439,8 +575,8 @@ static void acpi_tb_validate_fadt(void) */ if (!address64->address || !length) { ACPI_ERROR((AE_INFO, - "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X", - fadt_info_table[i].name, + "Required field %s has zero address and/or length: %8.8X%8.8X/%X", + name, ACPI_FORMAT_UINT64(address64-> address), length)); @@ -453,8 +589,8 @@ static void acpi_tb_validate_fadt(void) if ((address64->address && !length) || (!address64->address && length)) { ACPI_WARNING((AE_INFO, - "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X", - fadt_info_table[i].name, + "Optional field %s has zero address or length: %8.8X%8.8X/%X", + name, ACPI_FORMAT_UINT64(address64-> address), length)); @@ -466,8 +602,8 @@ static void acpi_tb_validate_fadt(void) if (address64->address && *address32 && (address64->address != (u64) * address32)) { ACPI_ERROR((AE_INFO, - "32/64X address mismatch in \"%s\": [%8.8X] [%8.8X%8.8X], using 64X", - fadt_info_table[i].name, *address32, + "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X", + name, *address32, ACPI_FORMAT_UINT64(address64->address))); } } diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/acpica/tbfind.c similarity index 99% rename from drivers/acpi/tables/tbfind.c rename to drivers/acpi/acpica/tbfind.c index 531584defbb..1054dfd4920 100644 --- a/drivers/acpi/tables/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "actables.h" #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbfind") diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/acpica/tbinstal.c similarity index 99% rename from drivers/acpi/tables/tbinstal.c rename to drivers/acpi/acpica/tbinstal.c index 18747ce8dd2..37374b21969 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "actables.h" #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbinstal") diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/acpica/tbutils.c similarity index 95% rename from drivers/acpi/tables/tbutils.c rename to drivers/acpi/acpica/tbutils.c index 0cc92ef5236..9684cc82793 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "actables.h" #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbutils") @@ -111,6 +112,30 @@ acpi_tb_check_xsdt(acpi_physical_address address) return AE_OK; } +/******************************************************************************* + * + * FUNCTION: acpi_tb_initialize_facs + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global + * for accessing the Global Lock and Firmware Waking Vector + * + ******************************************************************************/ + +acpi_status acpi_tb_initialize_facs(void) +{ + acpi_status status; + + status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, + ACPI_CAST_INDIRECT_PTR(struct + acpi_table_header, + &acpi_gbl_FACS)); + return status; +} + /******************************************************************************* * * FUNCTION: acpi_tb_tables_loaded @@ -420,7 +445,8 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) /* Differentiate between RSDT and XSDT root tables */ - if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { + if (rsdp->revision > 1 && rsdp->xsdt_physical_address + && !acpi_rsdt_forced) { /* * Root table is an XSDT (64-bit physical addresses). We must use the * XSDT if the revision is > 1 and the XSDT pointer is present, as per diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/acpica/tbxface.c similarity index 99% rename from drivers/acpi/tables/tbxface.c rename to drivers/acpi/acpica/tbxface.c index fd7770aa106..c3e841f3cde 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -43,8 +43,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "actables.h" #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxface") diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c similarity index 99% rename from drivers/acpi/tables/tbxfroot.c rename to drivers/acpi/acpica/tbxfroot.c index 2d157e0f98d..b7fc8dd4334 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "actables.h" #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxfroot") diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/acpica/utalloc.c similarity index 99% rename from drivers/acpi/utilities/utalloc.c rename to drivers/acpi/acpica/utalloc.c index 241c535c175..7580f6b3069 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acdebug.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utalloc") diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/acpica/utcopy.c similarity index 99% rename from drivers/acpi/utilities/utcopy.c rename to drivers/acpi/acpica/utcopy.c index 5b2f7c27b70..b0dcfd3c872 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_UTILITIES diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/acpica/utdebug.c similarity index 89% rename from drivers/acpi/utilities/utdebug.c rename to drivers/acpi/acpica/utdebug.c index fd66ecb6741..38821f53042 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -42,6 +42,7 @@ */ #include +#include "accommon.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utdebug") @@ -136,7 +137,7 @@ static const char *acpi_ut_trim_function_name(const char *function_name) /******************************************************************************* * - * FUNCTION: acpi_ut_debug_print + * FUNCTION: acpi_debug_print * * PARAMETERS: requested_debug_level - Requested debug print level * line_number - Caller's line number (for error output) @@ -154,11 +155,11 @@ static const char *acpi_ut_trim_function_name(const char *function_name) ******************************************************************************/ void ACPI_INTERNAL_VAR_XFACE -acpi_ut_debug_print(u32 requested_debug_level, - u32 line_number, - const char *function_name, - const char *module_name, - u32 component_id, const char *format, ...) +acpi_debug_print(u32 requested_debug_level, + u32 line_number, + const char *function_name, + const char *module_name, + u32 component_id, const char *format, ...) { acpi_thread_id thread_id; va_list args; @@ -205,11 +206,11 @@ acpi_ut_debug_print(u32 requested_debug_level, va_end(args); } -ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) +ACPI_EXPORT_SYMBOL(acpi_debug_print) /******************************************************************************* * - * FUNCTION: acpi_ut_debug_print_raw + * FUNCTION: acpi_debug_print_raw * * PARAMETERS: requested_debug_level - Requested debug print level * line_number - Caller's line number @@ -226,11 +227,11 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) * ******************************************************************************/ void ACPI_INTERNAL_VAR_XFACE -acpi_ut_debug_print_raw(u32 requested_debug_level, - u32 line_number, - const char *function_name, - const char *module_name, - u32 component_id, const char *format, ...) +acpi_debug_print_raw(u32 requested_debug_level, + u32 line_number, + const char *function_name, + const char *module_name, + u32 component_id, const char *format, ...) { va_list args; @@ -244,7 +245,7 @@ acpi_ut_debug_print_raw(u32 requested_debug_level, va_end(args); } -ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) +ACPI_EXPORT_SYMBOL(acpi_debug_print_raw) /******************************************************************************* * @@ -270,9 +271,9 @@ acpi_ut_trace(u32 line_number, acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr(); - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s\n", acpi_gbl_fn_entry_str); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s\n", acpi_gbl_fn_entry_str); } ACPI_EXPORT_SYMBOL(acpi_ut_trace) @@ -301,10 +302,9 @@ acpi_ut_trace_ptr(u32 line_number, acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr(); - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s %p\n", acpi_gbl_fn_entry_str, - pointer); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s %p\n", acpi_gbl_fn_entry_str, pointer); } /******************************************************************************* @@ -333,10 +333,9 @@ acpi_ut_trace_str(u32 line_number, acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr(); - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s %s\n", acpi_gbl_fn_entry_str, - string); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s %s\n", acpi_gbl_fn_entry_str, string); } /******************************************************************************* @@ -365,10 +364,9 @@ acpi_ut_trace_u32(u32 line_number, acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr(); - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s %08X\n", acpi_gbl_fn_entry_str, - integer); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s %08X\n", acpi_gbl_fn_entry_str, integer); } /******************************************************************************* @@ -393,9 +391,9 @@ acpi_ut_exit(u32 line_number, const char *module_name, u32 component_id) { - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s\n", acpi_gbl_fn_exit_str); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s\n", acpi_gbl_fn_exit_str); acpi_gbl_nesting_level--; } @@ -426,17 +424,16 @@ acpi_ut_status_exit(u32 line_number, { if (ACPI_SUCCESS(status)) { - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s %s\n", - acpi_gbl_fn_exit_str, - acpi_format_exception(status)); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, + component_id, "%s %s\n", acpi_gbl_fn_exit_str, + acpi_format_exception(status)); } else { - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s ****Exception****: %s\n", - acpi_gbl_fn_exit_str, - acpi_format_exception(status)); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, + component_id, "%s ****Exception****: %s\n", + acpi_gbl_fn_exit_str, + acpi_format_exception(status)); } acpi_gbl_nesting_level--; @@ -467,10 +464,10 @@ acpi_ut_value_exit(u32 line_number, u32 component_id, acpi_integer value) { - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s %8.8X%8.8X\n", - acpi_gbl_fn_exit_str, ACPI_FORMAT_UINT64(value)); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str, + ACPI_FORMAT_UINT64(value)); acpi_gbl_nesting_level--; } @@ -499,9 +496,9 @@ acpi_ut_ptr_exit(u32 line_number, const char *module_name, u32 component_id, u8 *ptr) { - acpi_ut_debug_print(ACPI_LV_FUNCTIONS, - line_number, function_name, module_name, - component_id, "%s %p\n", acpi_gbl_fn_exit_str, ptr); + acpi_debug_print(ACPI_LV_FUNCTIONS, + line_number, function_name, module_name, component_id, + "%s %p\n", acpi_gbl_fn_exit_str, ptr); acpi_gbl_nesting_level--; } diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/acpica/utdelete.c similarity index 99% rename from drivers/acpi/utilities/utdelete.c rename to drivers/acpi/acpica/utdelete.c index d197c6b29e1..a0be9e39531 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acinterp.h" +#include "acnamesp.h" +#include "acevents.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utdelete") diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/acpica/uteval.c similarity index 99% rename from drivers/acpi/utilities/uteval.c rename to drivers/acpi/acpica/uteval.c index 352747e49c7..da9450bc60f 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -42,8 +42,9 @@ */ #include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("uteval") @@ -129,7 +130,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) /* The interface is supported */ - return_ACPI_STATUS(AE_CTRL_TERMINATE); + return_ACPI_STATUS(AE_OK); } } @@ -143,13 +144,13 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) /* The interface is supported */ - return_ACPI_STATUS(AE_CTRL_TERMINATE); + return_ACPI_STATUS(AE_OK); } /* The interface is not supported */ return_desc->integer.value = 0; - return_ACPI_STATUS(AE_CTRL_TERMINATE); + return_ACPI_STATUS(AE_OK); } /******************************************************************************* diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/acpica/utglobal.c similarity index 99% rename from drivers/acpi/utilities/utglobal.c rename to drivers/acpi/acpica/utglobal.c index 17ed5ac840f..a3ab9d9da29 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -44,11 +44,11 @@ #define DEFINE_ACPI_GLOBALS #include -#include +#include "accommon.h" +#include "acnamesp.h" -ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) #define _COMPONENT ACPI_UTILITIES - ACPI_MODULE_NAME("utglobal") +ACPI_MODULE_NAME("utglobal") /******************************************************************************* * @@ -352,7 +352,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { "PCI_Config", "EmbeddedControl", "SMBus", - "CMOS", + "SystemCMOS", "PCIBARTarget", "DataTable" }; @@ -756,6 +756,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_gpe_xrupt_list_head = NULL; acpi_gbl_gpe_fadt_blocks[0] = NULL; acpi_gbl_gpe_fadt_blocks[1] = NULL; + acpi_current_gpe_count = 0; /* Global handlers */ @@ -771,6 +772,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_global_lock_mutex = NULL; acpi_gbl_global_lock_acquired = FALSE; acpi_gbl_global_lock_handle = 0; + acpi_gbl_global_lock_present = FALSE; /* Miscellaneous variables */ @@ -815,5 +817,7 @@ acpi_status acpi_ut_init_globals(void) return_ACPI_STATUS(AE_OK); } +ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) ACPI_EXPORT_SYMBOL(acpi_dbg_level) ACPI_EXPORT_SYMBOL(acpi_dbg_layer) +ACPI_EXPORT_SYMBOL(acpi_current_gpe_count) diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/acpica/utinit.c similarity index 98% rename from drivers/acpi/utilities/utinit.c rename to drivers/acpi/acpica/utinit.c index cae515fc02d..a54ca84eb36 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -42,9 +42,10 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acnamesp.h" +#include "acevents.h" +#include "actables.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utinit") diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/acpica/utmath.c similarity index 99% rename from drivers/acpi/utilities/utmath.c rename to drivers/acpi/acpica/utmath.c index c927324fdd2..c9f682d640e 100644 --- a/drivers/acpi/utilities/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -42,6 +42,7 @@ */ #include +#include "accommon.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmath") diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/acpica/utmisc.c similarity index 97% rename from drivers/acpi/utilities/utmisc.c rename to drivers/acpi/acpica/utmisc.c index 9089a158a87..c1f7f4e1a72 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -44,7 +44,8 @@ #include #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") @@ -1016,7 +1017,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, /******************************************************************************* * - * FUNCTION: acpi_ut_error, acpi_ut_warning, acpi_ut_info + * FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) @@ -1029,7 +1030,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, ******************************************************************************/ void ACPI_INTERNAL_VAR_XFACE -acpi_ut_error(const char *module_name, u32 line_number, const char *format, ...) +acpi_error(const char *module_name, u32 line_number, const char *format, ...) { va_list args; @@ -1042,8 +1043,8 @@ acpi_ut_error(const char *module_name, u32 line_number, const char *format, ...) } void ACPI_INTERNAL_VAR_XFACE -acpi_ut_exception(const char *module_name, - u32 line_number, acpi_status status, const char *format, ...) +acpi_exception(const char *module_name, + u32 line_number, acpi_status status, const char *format, ...) { va_list args; @@ -1056,11 +1057,8 @@ acpi_ut_exception(const char *module_name, va_end(args); } -EXPORT_SYMBOL(acpi_ut_exception); - void ACPI_INTERNAL_VAR_XFACE -acpi_ut_warning(const char *module_name, - u32 line_number, const char *format, ...) +acpi_warning(const char *module_name, u32 line_number, const char *format, ...) { va_list args; @@ -1073,7 +1071,7 @@ acpi_ut_warning(const char *module_name, } void ACPI_INTERNAL_VAR_XFACE -acpi_ut_info(const char *module_name, u32 line_number, const char *format, ...) +acpi_info(const char *module_name, u32 line_number, const char *format, ...) { va_list args; @@ -1088,3 +1086,8 @@ acpi_ut_info(const char *module_name, u32 line_number, const char *format, ...) acpi_os_printf("\n"); va_end(args); } + +ACPI_EXPORT_SYMBOL(acpi_error) +ACPI_EXPORT_SYMBOL(acpi_exception) +ACPI_EXPORT_SYMBOL(acpi_warning) +ACPI_EXPORT_SYMBOL(acpi_info) diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/acpica/utmutex.c similarity index 99% rename from drivers/acpi/utilities/utmutex.c rename to drivers/acpi/acpica/utmutex.c index 7331dde9e1b..14eb52c4d64 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -42,6 +42,7 @@ */ #include +#include "accommon.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmutex") diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/acpica/utobject.c similarity index 99% rename from drivers/acpi/utilities/utobject.c rename to drivers/acpi/acpica/utobject.c index 4bef3cfbacc..fd5ea7543e5 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "acnamesp.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utobject") diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/acpica/utresrc.c similarity index 99% rename from drivers/acpi/utilities/utresrc.c rename to drivers/acpi/acpica/utresrc.c index c3e3e1308ed..91b7c00236f 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -42,7 +42,8 @@ */ #include -#include +#include "accommon.h" +#include "amlresrc.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utresrc") diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/acpica/utstate.c similarity index 99% rename from drivers/acpi/utilities/utstate.c rename to drivers/acpi/acpica/utstate.c index 63a6d3d77d8..0440c958f5a 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -42,6 +42,7 @@ */ #include +#include "accommon.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utstate") diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/acpica/utxface.c similarity index 97% rename from drivers/acpi/utilities/utxface.c rename to drivers/acpi/acpica/utxface.c index c198a4d4058..078a22728c6 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -42,9 +42,11 @@ */ #include -#include -#include -#include +#include "accommon.h" +#include "acevents.h" +#include "acnamesp.h" +#include "acdebug.h" +#include "actables.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utxface") @@ -147,6 +149,16 @@ acpi_status acpi_enable_subsystem(u32 flags) } } + /* + * Obtain a permanent mapping for the FACS. This is required for the + * Global Lock and the Firmware Waking Vector + */ + status = acpi_tb_initialize_facs(); + if (ACPI_FAILURE(status)) { + ACPI_WARNING((AE_INFO, "Could not map the FACS table")); + return_ACPI_STATUS(status); + } + /* * Install the default op_region handlers. These are installed unless * other handlers have already been installed via the diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 1423b0c0cd2..65132f92045 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -471,7 +471,7 @@ static void sysfs_remove_battery(struct acpi_battery *battery) static int acpi_battery_update(struct acpi_battery *battery) { - int result; + int result, old_present = acpi_battery_present(battery); result = acpi_battery_get_status(battery); if (result) return result; @@ -482,7 +482,8 @@ static int acpi_battery_update(struct acpi_battery *battery) return 0; } #endif - if (!battery->update_time) { + if (!battery->update_time || + old_present != acpi_battery_present(battery)) { result = acpi_battery_get_info(battery); if (result) return result; diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 307963bd104..332fe4b2170 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -27,9 +27,6 @@ #include #include #include -#include -#include -#include ACPI_MODULE_NAME("cm_sbs"); #define ACPI_AC_CLASS "ac_adapter" diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index c4839689200..20223cbd0d1 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -9,7 +9,6 @@ #include #include #include -#include #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("debug"); diff --git a/drivers/acpi/dispatcher/Makefile b/drivers/acpi/dispatcher/Makefile deleted file mode 100644 index eb7e602a83c..00000000000 --- a/drivers/acpi/dispatcher/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ - dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ - dsinit.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 30f3ef236ec..8dfcbb8aff7 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -42,7 +42,6 @@ #include #include #include -#include #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_DEVICE_NAME "Embedded Controller" @@ -370,7 +369,7 @@ unlock: * Note: samsung nv5000 doesn't work with ec burst mode. * http://bugzilla.kernel.org/show_bug.cgi?id=4980 */ -int acpi_ec_burst_enable(struct acpi_ec *ec) +static int acpi_ec_burst_enable(struct acpi_ec *ec) { u8 d; struct transaction t = {.command = ACPI_EC_BURST_ENABLE, @@ -380,7 +379,7 @@ int acpi_ec_burst_enable(struct acpi_ec *ec) return acpi_ec_transaction(ec, &t, 0); } -int acpi_ec_burst_disable(struct acpi_ec *ec) +static int acpi_ec_burst_disable(struct acpi_ec *ec) { struct transaction t = {.command = ACPI_EC_BURST_DISABLE, .wdata = NULL, .rdata = NULL, @@ -756,10 +755,15 @@ static acpi_status acpi_ec_register_query_methods(acpi_handle handle, u32 level, void *context, void **return_value) { - struct acpi_namespace_node *node = handle; + char node_name[5]; + struct acpi_buffer buffer = { sizeof(node_name), node_name }; struct acpi_ec *ec = context; int value = 0; - if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { + acpi_status status; + + status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); + + if (ACPI_SUCCESS(status) && sscanf(node_name, "_Q%x", &value) == 1) { acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); } return AE_OK; @@ -978,9 +982,9 @@ static const struct acpi_device_id ec_device_ids[] = { int __init acpi_ec_ecdt_probe(void) { - int ret; acpi_status status; struct acpi_table_ecdt *ecdt_ptr; + acpi_handle dummy; boot_ec = make_acpi_ec(); if (!boot_ec) @@ -1006,30 +1010,31 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->gpe = ecdt_ptr->gpe; boot_ec->handle = ACPI_ROOT_OBJECT; acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); - } else { - /* This workaround is needed only on some broken machines, - * which require early EC, but fail to provide ECDT */ - acpi_handle x; - printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); - status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, - boot_ec, NULL); - /* Check that acpi_get_devices actually find something */ - if (ACPI_FAILURE(status) || !boot_ec->handle) - goto error; - /* We really need to limit this workaround, the only ASUS, - * which needs it, has fake EC._INI method, so use it as flag. - * Keep boot_ec struct as it will be needed soon. - */ - if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) - return -ENODEV; + /* Add some basic check against completely broken table */ + if (boot_ec->data_addr != boot_ec->command_addr) + goto install; + /* fall through */ } - - ret = ec_install_handlers(boot_ec); - if (!ret) { + /* This workaround is needed only on some broken machines, + * which require early EC, but fail to provide ECDT */ + printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); + status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, + boot_ec, NULL); + /* Check that acpi_get_devices actually find something */ + if (ACPI_FAILURE(status) || !boot_ec->handle) + goto error; + /* We really need to limit this workaround, the only ASUS, + * which needs it, has fake EC._INI method, so use it as flag. + * Keep boot_ec struct as it will be needed soon. + */ + if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) + return -ENODEV; +install: + if (!ec_install_handlers(boot_ec)) { first_ec = boot_ec; return 0; } - error: +error: kfree(boot_ec); boot_ec = NULL; return -ENODEV; diff --git a/drivers/acpi/events/Makefile b/drivers/acpi/events/Makefile deleted file mode 100644 index d29f2ee449c..00000000000 --- a/drivers/acpi/events/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := evevent.o evregion.o evsci.o evxfevnt.o \ - evmisc.o evrgnini.o evxface.o evxfregn.o \ - evgpe.o evgpeblk.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/executer/Makefile b/drivers/acpi/executer/Makefile deleted file mode 100644 index e09998aa012..00000000000 --- a/drivers/acpi/executer/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ - exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ - excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ - exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/hardware/Makefile b/drivers/acpi/hardware/Makefile deleted file mode 100644 index 438ad373b9a..00000000000 --- a/drivers/acpi/hardware/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := hwacpi.o hwgpe.o hwregs.o hwsleep.o - -obj-$(ACPI_FUTURE_USAGE) += hwtimer.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/main.c similarity index 92% rename from drivers/acpi/sleep/main.c rename to drivers/acpi/main.c index 28a691cc625..7e3c609cbef 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/main.c @@ -101,13 +101,26 @@ void __init acpi_old_suspend_ordering(void) * cases. */ static bool set_sci_en_on_resume; +/* + * The ACPI specification wants us to save NVS memory regions during hibernation + * and to restore them during the subsequent resume. However, it is not certain + * if this mechanism is going to work on all machines, so we allow the user to + * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line + * option. + */ +static bool s4_no_nvs; + +void __init acpi_s4_no_nvs(void) +{ + s4_no_nvs = true; +} /** * acpi_pm_disable_gpes - Disable the GPEs. */ static int acpi_pm_disable_gpes(void) { - acpi_hw_disable_all_gpes(); + acpi_disable_all_gpes(); return 0; } @@ -135,7 +148,7 @@ static int acpi_pm_prepare(void) int error = __acpi_pm_prepare(); if (!error) - acpi_hw_disable_all_gpes(); + acpi_disable_all_gpes(); return error; } @@ -267,7 +280,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) * (like wakeup GPE) haven't handler, this can avoid such GPE misfire. * acpi_leave_sleep_state will reenable specific GPEs later */ - acpi_hw_disable_all_gpes(); + acpi_disable_all_gpes(); local_irq_restore(flags); printk(KERN_DEBUG "Back to C!\n"); @@ -394,9 +407,25 @@ void __init acpi_no_s4_hw_signature(void) static int acpi_hibernation_begin(void) { - acpi_target_sleep_state = ACPI_STATE_S4; - acpi_sleep_tts_switch(acpi_target_sleep_state); - return 0; + int error; + + error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); + if (!error) { + acpi_target_sleep_state = ACPI_STATE_S4; + acpi_sleep_tts_switch(acpi_target_sleep_state); + } + + return error; +} + +static int acpi_hibernation_pre_snapshot(void) +{ + int error = acpi_pm_prepare(); + + if (!error) + hibernate_nvs_save(); + + return error; } static int acpi_hibernation_enter(void) @@ -417,6 +446,12 @@ static int acpi_hibernation_enter(void) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } +static void acpi_hibernation_finish(void) +{ + hibernate_nvs_free(); + acpi_pm_finish(); +} + static void acpi_hibernation_leave(void) { /* @@ -432,18 +467,20 @@ static void acpi_hibernation_leave(void) "cannot resume!\n"); panic("ACPI S4 hardware signature mismatch"); } + /* Restore the NVS memory area */ + hibernate_nvs_restore(); } static void acpi_pm_enable_gpes(void) { - acpi_hw_enable_all_runtime_gpes(); + acpi_enable_all_runtime_gpes(); } static struct platform_hibernation_ops acpi_hibernation_ops = { .begin = acpi_hibernation_begin, .end = acpi_pm_end, - .pre_snapshot = acpi_pm_prepare, - .finish = acpi_pm_finish, + .pre_snapshot = acpi_hibernation_pre_snapshot, + .finish = acpi_hibernation_finish, .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, @@ -469,8 +506,22 @@ static int acpi_hibernation_begin_old(void) error = acpi_sleep_prepare(ACPI_STATE_S4); + if (!error) { + if (!s4_no_nvs) + error = hibernate_nvs_alloc(); + if (!error) + acpi_target_sleep_state = ACPI_STATE_S4; + } + return error; +} + +static int acpi_hibernation_pre_snapshot_old(void) +{ + int error = acpi_pm_disable_gpes(); + if (!error) - acpi_target_sleep_state = ACPI_STATE_S4; + hibernate_nvs_save(); + return error; } @@ -481,8 +532,8 @@ static int acpi_hibernation_begin_old(void) static struct platform_hibernation_ops acpi_hibernation_ops_old = { .begin = acpi_hibernation_begin_old, .end = acpi_pm_end, - .pre_snapshot = acpi_pm_disable_gpes, - .finish = acpi_pm_finish, + .pre_snapshot = acpi_hibernation_pre_snapshot_old, + .finish = acpi_hibernation_finish, .prepare = acpi_pm_disable_gpes, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, @@ -622,7 +673,7 @@ static void acpi_power_off_prepare(void) { /* Prepare to power off the system */ acpi_sleep_prepare(ACPI_STATE_S5); - acpi_hw_disable_all_gpes(); + acpi_disable_all_gpes(); } static void acpi_power_off(void) @@ -671,7 +722,7 @@ int __init acpi_sleep_init(void) sleep_states[ACPI_STATE_S4] = 1; printk(" S4"); if (!nosigcheck) { - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, + acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs); if (facs) s4_hardware_signature = diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile deleted file mode 100644 index 371a2daf837..00000000000 --- a/drivers/acpi/namespace/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := nsaccess.o nsload.o nssearch.o nsxfeval.o \ - nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ - nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ - nsparse.o nspredef.o - -obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 25ceae9191e..c5e292aab0e 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -29,7 +29,6 @@ #include #include #include -#include #define ACPI_NUMA 0x80000000 #define _COMPONENT ACPI_NUMA diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index c8111424dcb..6729a4992f2 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -726,7 +726,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); if (!dpc) - return_ACPI_STATUS(AE_NO_MEMORY); + return AE_NO_MEMORY; dpc->function = function; dpc->context = context; @@ -747,7 +747,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, status = AE_ERROR; kfree(dpc); } - return_ACPI_STATUS(status); + return status; } acpi_status acpi_os_execute(acpi_execute_type type, diff --git a/drivers/acpi/parser/Makefile b/drivers/acpi/parser/Makefile deleted file mode 100644 index db24ee09cf1..00000000000 --- a/drivers/acpi/parser/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := psargs.o psparse.o psloop.o pstree.o pswalk.o \ - psopcode.o psscope.o psutils.o psxface.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 4b252ea0e95..95650f83ce2 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -99,7 +99,7 @@ acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id) */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device %s has PCI address %02x:%02x:%02x.%02x\n", + "Device %s has PCI address %04x:%02x:%02x.%d\n", acpi_device_bid(device), id->segment, id->bus, id->device, id->function)); @@ -111,12 +111,11 @@ EXPORT_SYMBOL(acpi_get_pci_id); int acpi_pci_bind(struct acpi_device *device) { int result = 0; - acpi_status status = AE_OK; - struct acpi_pci_data *data = NULL; - struct acpi_pci_data *pdata = NULL; - char *pathname = NULL; - struct acpi_buffer buffer = { 0, NULL }; - acpi_handle handle = NULL; + acpi_status status; + struct acpi_pci_data *data; + struct acpi_pci_data *pdata; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + acpi_handle handle; struct pci_dev *dev; struct pci_bus *bus; @@ -124,21 +123,18 @@ int acpi_pci_bind(struct acpi_device *device) if (!device || !device->parent) return -EINVAL; - pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); - if (!pathname) - return -ENOMEM; - buffer.length = ACPI_PATHNAME_MAX; - buffer.pointer = pathname; - data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); - if (!data) { - kfree(pathname); + if (!data) return -ENOMEM; + + status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + if (ACPI_FAILURE(status)) { + kfree(data); + return -ENODEV; } - acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", - pathname)); + (char *)buffer.pointer)); /* * Segment & Bus @@ -166,7 +162,7 @@ int acpi_pci_bind(struct acpi_device *device) data->id.device = device->pnp.bus_address >> 16; data->id.function = device->pnp.bus_address & 0xFFFF; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); @@ -196,7 +192,7 @@ int acpi_pci_bind(struct acpi_device *device) } if (!data->dev) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", + "Device %04x:%02x:%02x.%d not present in PCI namespace\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); result = -ENODEV; @@ -204,7 +200,7 @@ int acpi_pci_bind(struct acpi_device *device) } if (!data->dev->bus) { printk(KERN_ERR PREFIX - "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n", + "Device %04x:%02x:%02x.%d has invalid 'bus' field\n", data->id.segment, data->id.bus, data->id.device, data->id.function); result = -ENODEV; @@ -219,7 +215,7 @@ int acpi_pci_bind(struct acpi_device *device) */ if (data->dev->subordinate) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device %02x:%02x:%02x.%02x is a PCI bridge\n", + "Device %04x:%02x:%02x.%d is a PCI bridge\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); data->bus = data->dev->subordinate; @@ -262,7 +258,7 @@ int acpi_pci_bind(struct acpi_device *device) } end: - kfree(pathname); + kfree(buffer.pointer); if (result) kfree(data); @@ -272,25 +268,21 @@ int acpi_pci_bind(struct acpi_device *device) static int acpi_pci_unbind(struct acpi_device *device) { int result = 0; - acpi_status status = AE_OK; - struct acpi_pci_data *data = NULL; - char *pathname = NULL; - struct acpi_buffer buffer = { 0, NULL }; + acpi_status status; + struct acpi_pci_data *data; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; if (!device || !device->parent) return -EINVAL; - pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); - if (!pathname) - return -ENOMEM; + status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + if (ACPI_FAILURE(status)) + return -ENODEV; - buffer.length = ACPI_PATHNAME_MAX; - buffer.pointer = pathname; - acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n", - pathname)); - kfree(pathname); + (char *) buffer.pointer)); + kfree(buffer.pointer); status = acpi_get_data(device->handle, acpi_pci_data_handler, @@ -322,50 +314,44 @@ acpi_pci_bind_root(struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus) { int result = 0; - acpi_status status = AE_OK; + acpi_status status; struct acpi_pci_data *data = NULL; - char *pathname = NULL; - struct acpi_buffer buffer = { 0, NULL }; - - pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); - if (!pathname) - return -ENOMEM; - - buffer.length = ACPI_PATHNAME_MAX; - buffer.pointer = pathname; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; if (!device || !id || !bus) { - kfree(pathname); return -EINVAL; } data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); - if (!data) { - kfree(pathname); + if (!data) return -ENOMEM; - } data->id = *id; data->bus = bus; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; - acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + if (ACPI_FAILURE(status)) { + kfree (data); + return -ENODEV; + } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " - "%02x:%02x\n", pathname, id->segment, id->bus)); + "%04x:%02x\n", (char *)buffer.pointer, + id->segment, id->bus)); status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to attach ACPI-PCI context to device %s", - pathname)); + (char *)buffer.pointer)); result = -ENODEV; goto end; } end: - kfree(pathname); + kfree(buffer.pointer); if (result != 0) kfree(data); diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index bf79d83bdfb..891bdf6679f 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -4,6 +4,8 @@ * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh * Copyright (C) 2002 Dominik Brodowski + * (c) Copyright 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -41,29 +43,36 @@ #define _COMPONENT ACPI_PCI_COMPONENT ACPI_MODULE_NAME("pci_irq"); -static struct acpi_prt_list acpi_prt; +struct acpi_prt_entry { + struct list_head list; + struct acpi_pci_id id; + u8 pin; + acpi_handle link; + u32 index; /* GSI, or link _CRS index */ +}; + +static LIST_HEAD(acpi_prt_list); static DEFINE_SPINLOCK(acpi_prt_lock); +static inline char pin_name(int pin) +{ + return 'A' + pin - 1; +} + /* -------------------------------------------------------------------------- PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment, - int bus, - int device, int pin) +static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev, + int pin) { - struct acpi_prt_entry *entry = NULL; - - if (!acpi_prt.count) - return NULL; + struct acpi_prt_entry *entry; + int segment = pci_domain_nr(dev->bus); + int bus = dev->bus->number; + int device = PCI_SLOT(dev->devfn); - /* - * Parse through all PRT entries looking for a match on the specified - * PCI device's segment, bus, device, and pin (don't care about func). - * - */ spin_lock(&acpi_prt_lock); - list_for_each_entry(entry, &acpi_prt.entries, node) { + list_for_each_entry(entry, &acpi_prt_list, list) { if ((segment == entry->id.segment) && (bus == entry->id.bus) && (device == entry->id.device) @@ -72,7 +81,6 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment, return entry; } } - spin_unlock(&acpi_prt_lock); return NULL; } @@ -124,25 +132,27 @@ struct prt_quirk { char *actual_source; }; +#define PCI_INTX_PIN(c) (c - 'A' + 1) + /* * These systems have incorrect _PRT entries. The BIOS claims the PCI * interrupt at the listed segment/bus/device/pin is connected to the first * link device, but it is actually connected to the second. */ static struct prt_quirk prt_quirks[] = { - { medion_md9580, 0, 0, 9, 'A', + { medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'), "\\_SB_.PCI0.ISA_.LNKA", "\\_SB_.PCI0.ISA_.LNKB"}, - { dell_optiplex, 0, 0, 0xd, 'A', + { dell_optiplex, 0, 0, 0xd, PCI_INTX_PIN('A'), "\\_SB_.LNKB", "\\_SB_.LNKA"}, - { hp_t5710, 0, 0, 1, 'A', + { hp_t5710, 0, 0, 1, PCI_INTX_PIN('A'), "\\_SB_.PCI0.LNK1", "\\_SB_.PCI0.LNK3"}, }; -static void -do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt) +static void do_prt_fixups(struct acpi_prt_entry *entry, + struct acpi_pci_routing_table *prt) { int i; struct prt_quirk *quirk; @@ -158,42 +168,43 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt) entry->id.segment == quirk->segment && entry->id.bus == quirk->bus && entry->id.device == quirk->device && - entry->pin + 'A' == quirk->pin && + entry->pin == quirk->pin && !strcmp(prt->source, quirk->source) && strlen(prt->source) >= strlen(quirk->actual_source)) { printk(KERN_WARNING PREFIX "firmware reports " "%04x:%02x:%02x PCI INT %c connected to %s; " "changing to %s\n", entry->id.segment, entry->id.bus, - entry->id.device, 'A' + entry->pin, + entry->id.device, pin_name(entry->pin), prt->source, quirk->actual_source); strcpy(prt->source, quirk->actual_source); } } } -static int -acpi_pci_irq_add_entry(acpi_handle handle, - int segment, int bus, struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, + struct acpi_pci_routing_table *prt) { - struct acpi_prt_entry *entry = NULL; - - - if (!prt) - return -EINVAL; + struct acpi_prt_entry *entry; entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); if (!entry) return -ENOMEM; + /* + * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses + * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert + * it here. + */ entry->id.segment = segment; entry->id.bus = bus; entry->id.device = (prt->address >> 16) & 0xFFFF; - entry->id.function = prt->address & 0xFFFF; - entry->pin = prt->pin; + entry->pin = prt->pin + 1; do_prt_fixups(entry, prt); + entry->index = prt->source_index; + /* * Type 1: Dynamic * --------------- @@ -207,10 +218,9 @@ acpi_pci_irq_add_entry(acpi_handle handle, * (e.g. exists somewhere 'below' this _PRT entry in the ACPI * namespace). */ - if (prt->source[0]) { - acpi_get_handle(handle, prt->source, &entry->link.handle); - entry->link.index = prt->source_index; - } + if (prt->source[0]) + acpi_get_handle(handle, prt->source, &entry->link); + /* * Type 2: Static * -------------- @@ -218,84 +228,38 @@ acpi_pci_irq_add_entry(acpi_handle handle, * the IRQ value, which is hardwired to specific interrupt inputs on * the interrupt controller. */ - else - entry->link.index = prt->source_index; ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, - " %02X:%02X:%02X[%c] -> %s[%d]\n", + " %04x:%02x:%02x[%c] -> %s[%d]\n", entry->id.segment, entry->id.bus, - entry->id.device, ('A' + entry->pin), prt->source, - entry->link.index)); + entry->id.device, pin_name(entry->pin), + prt->source, entry->index)); spin_lock(&acpi_prt_lock); - list_add_tail(&entry->node, &acpi_prt.entries); - acpi_prt.count++; + list_add_tail(&entry->list, &acpi_prt_list); spin_unlock(&acpi_prt_lock); return 0; } -static void -acpi_pci_irq_del_entry(int segment, int bus, struct acpi_prt_entry *entry) -{ - if (segment == entry->id.segment && bus == entry->id.bus) { - acpi_prt.count--; - list_del(&entry->node); - kfree(entry); - } -} - int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) { - acpi_status status = AE_OK; - char *pathname = NULL; - struct acpi_buffer buffer = { 0, NULL }; - struct acpi_pci_routing_table *prt = NULL; - struct acpi_pci_routing_table *entry = NULL; - static int first_time = 1; - - - pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); - if (!pathname) - return -ENOMEM; - - if (first_time) { - acpi_prt.count = 0; - INIT_LIST_HEAD(&acpi_prt.entries); - first_time = 0; - } - - /* - * NOTE: We're given a 'handle' to the _PRT object's parent device - * (either a PCI root bridge or PCI-PCI bridge). - */ + acpi_status status; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_pci_routing_table *entry; - buffer.length = ACPI_PATHNAME_MAX; - buffer.pointer = pathname; - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ + status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + if (ACPI_FAILURE(status)) + return -ENODEV; printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", - pathname); + (char *) buffer.pointer); - /* - * Evaluate this _PRT and add its entries to our global list (acpi_prt). - */ + kfree(buffer.pointer); - buffer.length = 0; + buffer.length = ACPI_ALLOCATE_BUFFER; buffer.pointer = NULL; - kfree(pathname); - status = acpi_get_irq_routing_table(handle, &buffer); - if (status != AE_BUFFER_OVERFLOW) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRT [%s]", - acpi_format_exception(status))); - return -ENODEV; - } - - prt = kzalloc(buffer.length, GFP_KERNEL); - if (!prt) { - return -ENOMEM; - } - buffer.pointer = prt; status = acpi_get_irq_routing_table(handle, &buffer); if (ACPI_FAILURE(status)) { @@ -305,36 +269,30 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) return -ENODEV; } - entry = prt; - + entry = buffer.pointer; while (entry && (entry->length > 0)) { acpi_pci_irq_add_entry(handle, segment, bus, entry); entry = (struct acpi_pci_routing_table *) ((unsigned long)entry + entry->length); } - kfree(prt); - + kfree(buffer.pointer); return 0; } void acpi_pci_irq_del_prt(int segment, int bus) { - struct list_head *node = NULL, *n = NULL; - struct acpi_prt_entry *entry = NULL; - - if (!acpi_prt.count) { - return; - } + struct acpi_prt_entry *entry, *tmp; printk(KERN_DEBUG - "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n", segment, - bus); + "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", + segment, bus); spin_lock(&acpi_prt_lock); - list_for_each_safe(node, n, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); - - acpi_pci_irq_del_entry(segment, bus, entry); + list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { + if (segment == entry->id.segment && bus == entry->id.bus) { + list_del(&entry->list); + kfree(entry); + } } spin_unlock(&acpi_prt_lock); } @@ -342,162 +300,26 @@ void acpi_pci_irq_del_prt(int segment, int bus) /* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */ -typedef int (*irq_lookup_func) (struct acpi_prt_entry *, int *, int *, char **); - -static int -acpi_pci_allocate_irq(struct acpi_prt_entry *entry, - int *triggering, int *polarity, char **link) -{ - int irq; - - - if (entry->link.handle) { - irq = acpi_pci_link_allocate_irq(entry->link.handle, - entry->link.index, triggering, - polarity, link); - if (irq < 0) { - printk(KERN_WARNING PREFIX - "Invalid IRQ link routing entry\n"); - return -1; - } - } else { - irq = entry->link.index; - *triggering = ACPI_LEVEL_SENSITIVE; - *polarity = ACPI_ACTIVE_LOW; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); - return irq; -} - -static int -acpi_pci_free_irq(struct acpi_prt_entry *entry, - int *triggering, int *polarity, char **link) -{ - int irq; - - if (entry->link.handle) { - irq = acpi_pci_link_free_irq(entry->link.handle); - } else { - irq = entry->link.index; - } - return irq; -} - -#ifdef CONFIG_X86_IO_APIC -extern int noioapicquirk; - -static int bridge_has_boot_interrupt_variant(struct pci_bus *bus) +static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) { - struct pci_bus *bus_it; - - for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) { - if (!bus_it->self) - return 0; - - printk(KERN_INFO "vendor=%04x device=%04x\n", bus_it->self->vendor, - bus_it->self->device); - - if (bus_it->self->irq_reroute_variant) - return bus_it->self->irq_reroute_variant; - } - return 0; -} -#endif /* CONFIG_X86_IO_APIC */ - -/* - * acpi_pci_irq_lookup - * success: return IRQ >= 0 - * failure: return -1 - */ -static int -acpi_pci_irq_lookup(struct pci_bus *bus, - int device, - int pin, - int *triggering, - int *polarity, char **link, irq_lookup_func func) -{ - struct acpi_prt_entry *entry = NULL; - int segment = pci_domain_nr(bus); - int bus_nr = bus->number; - int ret; - - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Searching for PRT entry for %02x:%02x:%02x[%c]\n", - segment, bus_nr, device, ('A' + pin))); - - entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin); - if (!entry) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); - return -1; - } - - ret = func(entry, triggering, polarity, link); - -#ifdef CONFIG_X86_IO_APIC - /* - * Some chipsets (e.g. intel 6700PXH) generate a legacy INTx when the - * IRQ entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel - * does during interrupt handling). When this INTx generation cannot be - * disabled, we reroute these interrupts to their legacy equivalent to - * get rid of spurious interrupts. - */ - if (!noioapicquirk) { - switch (bridge_has_boot_interrupt_variant(bus)) { - case 0: - /* no rerouting necessary */ - break; - - case INTEL_IRQ_REROUTE_VARIANT: - /* - * Remap according to INTx routing table in 6700PXH - * specs, intel order number 302628-002, section - * 2.15.2. Other chipsets (80332, ...) have the same - * mapping and are handled here as well. - */ - printk(KERN_INFO "pci irq %d -> rerouted to legacy " - "irq %d\n", ret, (ret % 4) + 16); - ret = (ret % 4) + 16; - break; - - default: - printk(KERN_INFO "not rerouting irq %d to legacy irq: " - "unknown mapping\n", ret); - break; - } + struct acpi_prt_entry *entry; + struct pci_dev *bridge; + u8 bridge_pin, orig_pin = pin; + + entry = acpi_pci_irq_find_prt_entry(dev, pin); + if (entry) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n", + pci_name(dev), pin_name(pin))); + return entry; } -#endif /* CONFIG_X86_IO_APIC */ - - return ret; -} - -/* - * acpi_pci_irq_derive - * success: return IRQ >= 0 - * failure: return < 0 - */ -static int -acpi_pci_irq_derive(struct pci_dev *dev, - int pin, - int *triggering, - int *polarity, char **link, irq_lookup_func func) -{ - struct pci_dev *bridge = dev; - int irq = -1; - u8 bridge_pin = 0, orig_pin = pin; - - - if (!dev) - return -EINVAL; /* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */ - while (irq < 0 && bridge->bus->self) { - pin = (pin + PCI_SLOT(bridge->devfn)) % 4; - bridge = bridge->bus->self; + bridge = dev->bus->self; + while (bridge) { + pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1; if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { /* PC card has the same IRQ as its cardbridge */ @@ -506,50 +328,40 @@ acpi_pci_irq_derive(struct pci_dev *dev, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", pci_name(bridge))); - return -1; + return NULL; } - /* Pin is from 0 to 3 */ - bridge_pin--; pin = bridge_pin; } - irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), - pin, triggering, polarity, - link, func); - } + entry = acpi_pci_irq_find_prt_entry(bridge, pin); + if (entry) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Derived GSI for %s INT %c from %s\n", + pci_name(dev), pin_name(orig_pin), + pci_name(bridge))); + return entry; + } - if (irq < 0) { - dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n", - 'A' + orig_pin); - return -1; + dev = bridge; + bridge = dev->bus->self; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n", - irq, pci_name(dev), pci_name(bridge))); - - return irq; + dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n", + pin_name(orig_pin)); + return NULL; } -/* - * acpi_pci_irq_enable - * success: return 0 - * failure: return < 0 - */ - int acpi_pci_irq_enable(struct pci_dev *dev) { - int irq = 0; - u8 pin = 0; + struct acpi_prt_entry *entry; + int gsi; + u8 pin; int triggering = ACPI_LEVEL_SENSITIVE; int polarity = ACPI_ACTIVE_LOW; char *link = NULL; char link_desc[16]; int rc; - - if (!dev) - return -EINVAL; - pin = dev->pin; if (!pin) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -557,31 +369,9 @@ int acpi_pci_irq_enable(struct pci_dev *dev) pci_name(dev))); return 0; } - pin--; - - if (!dev->bus) { - dev_err(&dev->dev, "invalid (NULL) 'bus' field\n"); - return -ENODEV; - } - - /* - * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT - * values override any BIOS-assigned IRQs set during boot. - */ - irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, - &triggering, &polarity, &link, - acpi_pci_allocate_irq); - - /* - * If no PRT entry was found, we'll try to derive an IRQ from the - * device's parent bridge. - */ - if (irq < 0) - irq = acpi_pci_irq_derive(dev, pin, &triggering, - &polarity, &link, - acpi_pci_allocate_irq); - if (irq < 0) { + entry = acpi_pci_irq_lookup(dev, pin); + if (!entry) { /* * IDE legacy mode controller IRQs are magic. Why do compat * extensions always make such a nasty mess. @@ -590,12 +380,24 @@ int acpi_pci_irq_enable(struct pci_dev *dev) (dev->class & 0x05) == 0) return 0; } + + if (entry) { + if (entry->link) + gsi = acpi_pci_link_allocate_irq(entry->link, + entry->index, + &triggering, &polarity, + &link); + else + gsi = entry->index; + } else + gsi = -1; + /* * No IRQ known to the ACPI subsystem - maybe the BIOS / * driver reported one, then use it. Exit in any case. */ - if (irq < 0) { - dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin); + if (gsi < 0) { + dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin)); /* Interrupt Line values above 0xF are forbidden */ if (dev->irq > 0 && (dev->irq <= 0xF)) { printk(" - using IRQ %d\n", dev->irq); @@ -608,10 +410,10 @@ int acpi_pci_irq_enable(struct pci_dev *dev) } } - rc = acpi_register_gsi(irq, triggering, polarity); + rc = acpi_register_gsi(gsi, triggering, polarity); if (rc < 0) { dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", - 'A' + pin); + pin_name(pin)); return rc; } dev->irq = rc; @@ -622,7 +424,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) link_desc[0] = '\0'; dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n", - 'A' + pin, link_desc, irq, + pin_name(pin), link_desc, gsi, (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); @@ -636,42 +438,28 @@ void __attribute__ ((weak)) acpi_unregister_gsi(u32 i) void acpi_pci_irq_disable(struct pci_dev *dev) { - int gsi = 0; - u8 pin = 0; - int triggering = ACPI_LEVEL_SENSITIVE; - int polarity = ACPI_ACTIVE_LOW; - - - if (!dev || !dev->bus) - return; + struct acpi_prt_entry *entry; + int gsi; + u8 pin; pin = dev->pin; if (!pin) return; - pin--; - /* - * First we check the PCI IRQ routing table (PRT) for an IRQ. - */ - gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, - &triggering, &polarity, NULL, - acpi_pci_free_irq); - /* - * If no PRT entry was found, we'll try to derive an IRQ from the - * device's parent bridge. - */ - if (gsi < 0) - gsi = acpi_pci_irq_derive(dev, pin, - &triggering, &polarity, NULL, - acpi_pci_free_irq); - if (gsi < 0) + entry = acpi_pci_irq_lookup(dev, pin); + if (!entry) return; + if (entry->link) + gsi = acpi_pci_link_free_irq(entry->link); + else + gsi = entry->index; + /* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ). */ - dev_info(&dev->dev, "PCI INT %c disabled\n", 'A' + pin); + dev_info(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); acpi_unregister_gsi(gsi); } diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index e52ad91ce2d..1c6e73c7865 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -796,10 +796,6 @@ static int irqrouter_resume(struct sys_device *dev) struct list_head *node = NULL; struct acpi_pci_link *link = NULL; - - /* Make sure SCI is enabled again (Apple firmware bug?) */ - acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); - list_for_each(node, &acpi_link.entries) { link = list_entry(node, struct acpi_pci_link, node); if (!link) { @@ -912,7 +908,7 @@ static int __init acpi_irq_nobalance_set(char *str) __setup("acpi_irq_nobalance", acpi_irq_nobalance_set); -int __init acpi_irq_balance_set(char *str) +static int __init acpi_irq_balance_set(char *str) { acpi_irq_balance = 1; return 1; diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index bb7d50dd281..c926e7d4a0d 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -139,6 +139,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state) { acpi_status status = AE_OK; unsigned long long sta = 0; + char node_name[5]; + struct acpi_buffer buffer = { sizeof(node_name), node_name }; if (!handle || !state) @@ -151,8 +153,10 @@ static int acpi_power_get_state(acpi_handle handle, int *state) *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON: ACPI_POWER_RESOURCE_STATE_OFF; + acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", - acpi_ut_get_node_name(handle), + node_name, *state ? "on" : "off")); return 0; diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/proc.c similarity index 92% rename from drivers/acpi/sleep/proc.c rename to drivers/acpi/proc.c index 4dbc2271acf..428c911dba0 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/proc.c @@ -28,8 +28,6 @@ static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) { int i; - ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show"); - for (i = 0; i <= ACPI_STATE_S5; i++) { if (sleep_states[i]) { seq_printf(seq, "S%d ", i); @@ -86,49 +84,44 @@ acpi_system_write_sleep(struct file *file, #ifdef HAVE_ACPI_LEGACY_ALARM +static u32 cmos_bcd_read(int offset, int rtc_control); + static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) { u32 sec, min, hr; u32 day, mo, yr, cent = 0; + u32 today = 0; unsigned char rtc_control = 0; unsigned long flags; - ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show"); - spin_lock_irqsave(&rtc_lock, flags); - sec = CMOS_READ(RTC_SECONDS_ALARM); - min = CMOS_READ(RTC_MINUTES_ALARM); - hr = CMOS_READ(RTC_HOURS_ALARM); rtc_control = CMOS_READ(RTC_CONTROL); + sec = cmos_bcd_read(RTC_SECONDS_ALARM, rtc_control); + min = cmos_bcd_read(RTC_MINUTES_ALARM, rtc_control); + hr = cmos_bcd_read(RTC_HOURS_ALARM, rtc_control); /* If we ever get an FACP with proper values... */ - if (acpi_gbl_FADT.day_alarm) + if (acpi_gbl_FADT.day_alarm) { /* ACPI spec: only low 6 its should be cared */ day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; - else - day = CMOS_READ(RTC_DAY_OF_MONTH); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + day = bcd2bin(day); + } else + day = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); if (acpi_gbl_FADT.month_alarm) - mo = CMOS_READ(acpi_gbl_FADT.month_alarm); - else - mo = CMOS_READ(RTC_MONTH); + mo = cmos_bcd_read(acpi_gbl_FADT.month_alarm, rtc_control); + else { + mo = cmos_bcd_read(RTC_MONTH, rtc_control); + today = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); + } if (acpi_gbl_FADT.century) - cent = CMOS_READ(acpi_gbl_FADT.century); + cent = cmos_bcd_read(acpi_gbl_FADT.century, rtc_control); - yr = CMOS_READ(RTC_YEAR); + yr = cmos_bcd_read(RTC_YEAR, rtc_control); spin_unlock_irqrestore(&rtc_lock, flags); - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hr = bcd2bin(hr); - day = bcd2bin(day); - mo = bcd2bin(mo); - yr = bcd2bin(yr); - cent = bcd2bin(cent); - } - /* we're trusting the FADT (see above) */ if (!acpi_gbl_FADT.century) /* If we're not trusting the FADT, we should at least make it @@ -153,6 +146,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) else yr += cent * 100; + /* + * Show correct dates for alarms up to a month into the future. + * This solves issues for nearly all situations with the common + * 30-day alarm clocks in PC hardware. + */ + if (day < today) { + if (mo < 12) { + mo += 1; + } else { + mo = 1; + yr += 1; + } + } + seq_printf(seq, "%4.4u-", yr); (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); @@ -227,13 +234,11 @@ acpi_system_write_alarm(struct file *file, int adjust = 0; unsigned char rtc_control = 0; - ACPI_FUNCTION_TRACE("acpi_system_write_alarm"); - if (count > sizeof(alarm_string) - 1) - return_VALUE(-EINVAL); + return -EINVAL; if (copy_from_user(alarm_string, buffer, count)) - return_VALUE(-EFAULT); + return -EFAULT; alarm_string[count] = '\0'; @@ -334,7 +339,7 @@ acpi_system_write_alarm(struct file *file, result = 0; end: - return_VALUE(result ? result : count); + return result ? result : count; } #endif /* HAVE_ACPI_LEGACY_ALARM */ diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index a6b662c00b6..93f91142d7a 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -42,7 +42,7 @@ void acpi_reboot(void) case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_IO: printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); - acpi_hw_low_level_write(8, reset_value, rr); + acpi_reset(); break; } /* Wait ten seconds */ diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile deleted file mode 100644 index 8de4f69dfa0..00000000000 --- a/drivers/acpi/resources/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ - rscalc.o rsirq.o rsmemory.o rsutils.o - -obj-$(ACPI_FUTURE_USAGE) += rsdump.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index e53e590252c..0619734895b 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 39b7233c348..c54d7b6c406 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -10,7 +10,6 @@ #include #include -#include /* for acpi_ex_eisa_id_to_string() */ #define _COMPONENT ACPI_BUS_COMPONENT ACPI_MODULE_NAME("scan"); diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep.h similarity index 100% rename from drivers/acpi/sleep/sleep.h rename to drivers/acpi/sleep.h diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile deleted file mode 100644 index f1fb888c2d2..00000000000 --- a/drivers/acpi/sleep/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-y := wakeup.o -obj-y += main.o -obj-$(CONFIG_ACPI_SLEEP) += proc.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 6e4107f8240..391d0358a59 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -192,65 +192,6 @@ static struct attribute_group interrupt_stats_attr_group = { }; static struct kobj_attribute *counter_attrs; -static int count_num_gpes(void) -{ - int count = 0; - struct acpi_gpe_xrupt_info *gpe_xrupt_info; - struct acpi_gpe_block_info *gpe_block; - acpi_cpu_flags flags; - - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); - - gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; - while (gpe_xrupt_info) { - gpe_block = gpe_xrupt_info->gpe_block_list_head; - while (gpe_block) { - count += gpe_block->register_count * - ACPI_GPE_REGISTER_WIDTH; - gpe_block = gpe_block->next; - } - gpe_xrupt_info = gpe_xrupt_info->next; - } - acpi_os_release_lock(acpi_gbl_gpe_lock, flags); - - return count; -} - -static int get_gpe_device(int index, acpi_handle *handle) -{ - struct acpi_gpe_xrupt_info *gpe_xrupt_info; - struct acpi_gpe_block_info *gpe_block; - acpi_cpu_flags flags; - struct acpi_namespace_node *node; - - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); - - gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; - while (gpe_xrupt_info) { - gpe_block = gpe_xrupt_info->gpe_block_list_head; - node = gpe_block->node; - while (gpe_block) { - index -= gpe_block->register_count * - ACPI_GPE_REGISTER_WIDTH; - if (index < 0) { - acpi_os_release_lock(acpi_gbl_gpe_lock, flags); - /* return NULL if it's FADT GPE */ - if (node->type != ACPI_TYPE_DEVICE) - *handle = NULL; - else - *handle = node; - return 0; - } - node = gpe_block->node; - gpe_block = gpe_block->next; - } - gpe_xrupt_info = gpe_xrupt_info->next; - } - acpi_os_release_lock(acpi_gbl_gpe_lock, flags); - - return -ENODEV; -} - static void delete_gpe_attr_array(void) { struct event_counter *tmp = all_counters; @@ -309,7 +250,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) goto end; if (index < num_gpes) { - result = get_gpe_device(index, handle); + result = acpi_get_gpe_device(index, handle); if (result) { ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, "Invalid GPE 0x%x\n", index)); @@ -436,7 +377,7 @@ void acpi_irq_stats_init(void) if (all_counters) return; - num_gpes = count_num_gpes(); + num_gpes = acpi_current_gpe_count; num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile deleted file mode 100644 index 7385efa6162..00000000000 --- a/drivers/acpi/tables/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile deleted file mode 100644 index 88eff14c489..00000000000 --- a/drivers/acpi/utilities/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ - utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ - utstate.o utmutex.o utobject.o utcache.o utresrc.o - -EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c deleted file mode 100644 index 245fa80cf60..00000000000 --- a/drivers/acpi/utilities/utcache.c +++ /dev/null @@ -1,314 +0,0 @@ -/****************************************************************************** - * - * Module Name: utcache - local cache allocation routines - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2008, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include - -#define _COMPONENT ACPI_UTILITIES -ACPI_MODULE_NAME("utcache") -#ifdef ACPI_USE_LOCAL_CACHE -/******************************************************************************* - * - * FUNCTION: acpi_os_create_cache - * - * PARAMETERS: cache_name - Ascii name for the cache - * object_size - Size of each cached object - * max_depth - Maximum depth of the cache (in objects) - * return_cache - Where the new cache object is returned - * - * RETURN: Status - * - * DESCRIPTION: Create a cache object - * - ******************************************************************************/ -acpi_status -acpi_os_create_cache(char *cache_name, - u16 object_size, - u16 max_depth, struct acpi_memory_list ** return_cache) -{ - struct acpi_memory_list *cache; - - ACPI_FUNCTION_ENTRY(); - - if (!cache_name || !return_cache || (object_size < 16)) { - return (AE_BAD_PARAMETER); - } - - /* Create the cache object */ - - cache = acpi_os_allocate(sizeof(struct acpi_memory_list)); - if (!cache) { - return (AE_NO_MEMORY); - } - - /* Populate the cache object and return it */ - - ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list)); - cache->link_offset = 8; - cache->list_name = cache_name; - cache->object_size = object_size; - cache->max_depth = max_depth; - - *return_cache = cache; - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_os_purge_cache - * - * PARAMETERS: Cache - Handle to cache object - * - * RETURN: Status - * - * DESCRIPTION: Free all objects within the requested cache. - * - ******************************************************************************/ - -acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache) -{ - char *next; - - ACPI_FUNCTION_ENTRY(); - - if (!cache) { - return (AE_BAD_PARAMETER); - } - - /* Walk the list of objects in this cache */ - - while (cache->list_head) { - - /* Delete and unlink one cached state object */ - - next = *(ACPI_CAST_INDIRECT_PTR(char, - &(((char *)cache-> - list_head)[cache-> - link_offset]))); - ACPI_FREE(cache->list_head); - - cache->list_head = next; - cache->current_depth--; - } - - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_os_delete_cache - * - * PARAMETERS: Cache - Handle to cache object - * - * RETURN: Status - * - * DESCRIPTION: Free all objects within the requested cache and delete the - * cache object. - * - ******************************************************************************/ - -acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache) -{ - acpi_status status; - - ACPI_FUNCTION_ENTRY(); - - /* Purge all objects in the cache */ - - status = acpi_os_purge_cache(cache); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Now we can delete the cache object */ - - ACPI_FREE(cache); - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_os_release_object - * - * PARAMETERS: Cache - Handle to cache object - * Object - The object to be released - * - * RETURN: None - * - * DESCRIPTION: Release an object to the specified cache. If cache is full, - * the object is deleted. - * - ******************************************************************************/ - -acpi_status -acpi_os_release_object(struct acpi_memory_list * cache, void *object) -{ - acpi_status status; - - ACPI_FUNCTION_ENTRY(); - - if (!cache || !object) { - return (AE_BAD_PARAMETER); - } - - /* If cache is full, just free this object */ - - if (cache->current_depth >= cache->max_depth) { - ACPI_FREE(object); - ACPI_MEM_TRACKING(cache->total_freed++); - } - - /* Otherwise put this object back into the cache */ - - else { - status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Mark the object as cached */ - - ACPI_MEMSET(object, 0xCA, cache->object_size); - ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED); - - /* Put the object at the head of the cache list */ - - *(ACPI_CAST_INDIRECT_PTR(char, - &(((char *)object)[cache-> - link_offset]))) = - cache->list_head; - cache->list_head = object; - cache->current_depth++; - - (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); - } - - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_os_acquire_object - * - * PARAMETERS: Cache - Handle to cache object - * - * RETURN: the acquired object. NULL on error - * - * DESCRIPTION: Get an object from the specified cache. If cache is empty, - * the object is allocated. - * - ******************************************************************************/ - -void *acpi_os_acquire_object(struct acpi_memory_list *cache) -{ - acpi_status status; - void *object; - - ACPI_FUNCTION_NAME(os_acquire_object); - - if (!cache) { - return (NULL); - } - - status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); - if (ACPI_FAILURE(status)) { - return (NULL); - } - - ACPI_MEM_TRACKING(cache->requests++); - - /* Check the cache first */ - - if (cache->list_head) { - - /* There is an object available, use it */ - - object = cache->list_head; - cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char, - &(((char *) - object)[cache-> - link_offset]))); - - cache->current_depth--; - - ACPI_MEM_TRACKING(cache->hits++); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Object %p from %s cache\n", object, - cache->list_name)); - - status = acpi_ut_release_mutex(ACPI_MTX_CACHES); - if (ACPI_FAILURE(status)) { - return (NULL); - } - - /* Clear (zero) the previously used Object */ - - ACPI_MEMSET(object, 0, cache->object_size); - } else { - /* The cache is empty, create a new object */ - - ACPI_MEM_TRACKING(cache->total_allocated++); - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - if ((cache->total_allocated - cache->total_freed) > - cache->max_occupied) { - cache->max_occupied = - cache->total_allocated - cache->total_freed; - } -#endif - - /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ - - status = acpi_ut_release_mutex(ACPI_MTX_CACHES); - if (ACPI_FAILURE(status)) { - return (NULL); - } - - object = ACPI_ALLOCATE_ZEROED(cache->object_size); - if (!object) { - return (NULL); - } - } - - return (object); -} -#endif /* ACPI_USE_LOCAL_CACHE */ diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index baa44192972..f261737636d 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -481,6 +482,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) int status = AE_OK; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; + int state; arg0.integer.value = level; @@ -489,6 +491,10 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); device->brightness->curr = level; + for (state = 2; state < device->brightness->count; state++) + if (level == device->brightness->levels[state]) + device->backlight->props.brightness = state - 2; + return status; } @@ -625,6 +631,16 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) return status; } +/* + * Simple comparison function used to sort backlight levels. + */ + +static int +acpi_video_cmp_level(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + /* * Arg: * device : video output device (LCD, CRT, ..) @@ -676,6 +692,10 @@ acpi_video_init_brightness(struct acpi_video_device *device) count++; } + /* don't sort the first two brightness levels */ + sort(&br->levels[2], count - 2, sizeof(br->levels[2]), + acpi_video_cmp_level, NULL); + if (count < 2) goto out_free_levels; diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index f022eb6f563..50e3d2dbf3a 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -234,7 +234,7 @@ EXPORT_SYMBOL(acpi_video_display_switch_support); * To force that backlight or display output switching is processed by vendor * specific acpi drivers or video.ko driver. */ -int __init acpi_backlight(char *str) +static int __init acpi_backlight(char *str) { if (str == NULL || *str == '\0') return 1; @@ -250,7 +250,7 @@ int __init acpi_backlight(char *str) } __setup("acpi_backlight=", acpi_backlight); -int __init acpi_display_output(char *str) +static int __init acpi_display_output(char *str) { if (str == NULL || *str == '\0') return 1; diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/wakeup.c similarity index 96% rename from drivers/acpi/sleep/wakeup.c rename to drivers/acpi/wakeup.c index dea4c23df76..2d34806d45d 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "sleep.h" #define _COMPONENT ACPI_SYSTEM_COMPONENT @@ -28,8 +27,6 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) { struct list_head *node, *next; - ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep"); - spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, @@ -61,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_state) * Caution: this routine must be invoked when interrupt is disabled * Refer ACPI2.0: P212 */ - ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device"); spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = @@ -103,8 +99,6 @@ void acpi_disable_wakeup_device(u8 sleep_state) { struct list_head *node, *next; - ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device"); - spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index ef02e488d46..6273d98d00e 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -19,12 +19,6 @@ #include "libata.h" #include -#include -#include -#include -#include -#include -#include enum { ATA_ACPI_FILTER_SETXFER = 1 << 0, diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index e2e332d8ff9..8b77a9802df 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -13,12 +13,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 68f052b42ed..ed306eb1057 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include "tpm.h" #define TCG_EVENT_NAME_LEN_MAX 255 diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 8d7cf3f3145..f1df59f59a3 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -15,12 +15,14 @@ #include #define BREAK_FUZZ 4 /* 4 us */ +#define PRED_HISTORY_PCT 50 struct menu_device { int last_state_idx; unsigned int expected_us; unsigned int predicted_us; + unsigned int current_predicted_us; unsigned int last_measured_us; unsigned int elapsed_us; }; @@ -47,6 +49,12 @@ static int menu_select(struct cpuidle_device *dev) data->expected_us = (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000; + /* Recalculate predicted_us based on prediction_history_pct */ + data->predicted_us *= PRED_HISTORY_PCT; + data->predicted_us += (100 - PRED_HISTORY_PCT) * + data->current_predicted_us; + data->predicted_us /= 100; + /* find the deepest idle state that satisfies our constraints */ for (i = CPUIDLE_DRIVER_STATE_START + 1; i < dev->state_count; i++) { struct cpuidle_state *s = &dev->states[i]; @@ -97,7 +105,7 @@ static void menu_reflect(struct cpuidle_device *dev) measured_us = -1; /* Predict time until next break event */ - data->predicted_us = max(measured_us, data->last_measured_us); + data->current_predicted_us = max(measured_us, data->last_measured_us); if (last_idle_us + BREAK_FUZZ < data->expected_us - target->exit_latency) { diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 2f9e941968d..d8f295bdad7 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -18,12 +18,6 @@ #include #include -#include -#include -#include -#include -#include -#include #define REGS_PER_GTF 7 struct taskfile_array { diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3949a1c7345..419c378bd24 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -120,7 +120,7 @@ config TIFM_CORE cards are supported via 'MMC/SD Card support: TI Flash Media MMC/SD Interface support (MMC_TIFM_SD)'. - To compile this driver as a module, choose M here: the module will + To compile this driver as a module, choose M here: the module will be called tifm_core. config TIFM_7XX1 @@ -133,100 +133,9 @@ config TIFM_7XX1 To make actual use of the device, you will have to select some flash card format drivers, as outlined in the TIFM_CORE Help. - To compile this driver as a module, choose M here: the module will + To compile this driver as a module, choose M here: the module will be called tifm_7xx1. -config ACER_WMI - tristate "Acer WMI Laptop Extras (EXPERIMENTAL)" - depends on X86 - depends on EXPERIMENTAL - depends on ACPI - depends on LEDS_CLASS - depends on NEW_LEDS - depends on BACKLIGHT_CLASS_DEVICE - depends on SERIO_I8042 - depends on RFKILL - select ACPI_WMI - ---help--- - This is a driver for newer Acer (and Wistron) laptops. It adds - wireless radio and bluetooth control, and on some laptops, - exposes the mail LED and LCD backlight. - - For more information about this driver see - - - If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M - here. - -config ASUS_LAPTOP - tristate "Asus Laptop Extras (EXPERIMENTAL)" - depends on X86 - depends on ACPI - depends on EXPERIMENTAL && !ACPI_ASUS - depends on LEDS_CLASS - depends on NEW_LEDS - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is the new Linux driver for Asus laptops. It may also support some - MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate - standard ACPI events that go through /proc/acpi/events. It also adds - support for video output switching, LCD backlight control, Bluetooth and - Wlan control, and most importantly, allows you to blink those fancy LEDs. - - For more information and a userspace daemon for handling the extra - buttons see . - - If you have an ACPI-compatible ASUS laptop, say Y or M here. - -config FUJITSU_LAPTOP - tristate "Fujitsu Laptop Extras" - depends on X86 - depends on ACPI - depends on INPUT - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is a driver for laptops built by Fujitsu: - - * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks - * Possibly other Fujitsu laptop models - * Tested with S6410 and S7020 - - It adds support for LCD brightness control and some hotkeys. - - If you have a Fujitsu laptop, say Y or M here. - -config FUJITSU_LAPTOP_DEBUG - bool "Verbose debug mode for Fujitsu Laptop Extras" - depends on FUJITSU_LAPTOP - default n - ---help--- - Enables extra debug output from the fujitsu extras driver, at the - expense of a slight increase in driver size. - - If you are not sure, say N here. - -config TC1100_WMI - tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" - depends on X86 && !X86_64 - depends on EXPERIMENTAL - depends on ACPI - select ACPI_WMI - ---help--- - This is a driver for the WMI extensions (wireless and bluetooth power - control) of the HP Compaq TC1100 tablet. - -config HP_WMI - tristate "HP WMI extras" - depends on ACPI_WMI - depends on INPUT - depends on RFKILL - help - Say Y here if you want to support WMI-based hotkeys on HP laptops and - to read data from WMI such as docking or ambient light sensor state. - - To compile this driver as a module, choose M here: the module will - be called hp-wmi. - config ICS932S401 tristate "Integrated Circuits ICS932S401" depends on I2C && EXPERIMENTAL @@ -237,170 +146,6 @@ config ICS932S401 This driver can also be built as a module. If so, the module will be called ics932s401. -config MSI_LAPTOP - tristate "MSI Laptop Extras" - depends on X86 - depends on ACPI - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is a driver for laptops built by MSI (MICRO-STAR - INTERNATIONAL): - - MSI MegaBook S270 (MS-1013) - Cytron/TCM/Medion/Tchibo MD96100/SAM2000 - - It adds support for Bluetooth, WLAN and LCD brightness control. - - More information about this driver is available at - . - - If you have an MSI S270 laptop, say Y or M here. - -config PANASONIC_LAPTOP - tristate "Panasonic Laptop Extras" - depends on X86 && INPUT && ACPI - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This driver adds support for access to backlight control and hotkeys - on Panasonic Let's Note laptops. - - If you have a Panasonic Let's note laptop (such as the R1(N variant), - R2, R3, R5, T2, W2 and Y2 series), say Y. - -config COMPAL_LAPTOP - tristate "Compal Laptop Extras" - depends on X86 - depends on ACPI - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is a driver for laptops built by Compal: - - Compal FL90/IFL90 - Compal FL91/IFL91 - Compal FL92/JFL92 - Compal FT00/IFT00 - - It adds support for Bluetooth, WLAN and LCD brightness control. - - If you have an Compal FL9x/IFL9x/FT00 laptop, say Y or M here. - -config SONY_LAPTOP - tristate "Sony Laptop Extras" - depends on X86 && ACPI - select BACKLIGHT_CLASS_DEVICE - depends on INPUT - ---help--- - This mini-driver drives the SNC and SPIC devices present in the ACPI - BIOS of the Sony Vaio laptops. - - It gives access to some extra laptop functionalities like Bluetooth, - screen brightness control, Fn keys and allows powering on/off some - devices. - - Read for more information. - -config SONYPI_COMPAT - bool "Sonypi compatibility" - depends on SONY_LAPTOP - ---help--- - Build the sonypi driver compatibility code into the sony-laptop driver. - -config THINKPAD_ACPI - tristate "ThinkPad ACPI Laptop Extras" - depends on X86 && ACPI - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - select HWMON - select NVRAM - select INPUT - select NEW_LEDS - select LEDS_CLASS - select NET - select RFKILL - ---help--- - This is a driver for the IBM and Lenovo ThinkPad laptops. It adds - support for Fn-Fx key combinations, Bluetooth control, video - output switching, ThinkLight control, UltraBay eject and more. - For more information about this driver see - and - . - - This driver was formerly known as ibm-acpi. - - If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. - -config THINKPAD_ACPI_DEBUG - bool "Verbose debug mode" - depends on THINKPAD_ACPI - default n - ---help--- - Enables extra debugging information, at the expense of a slightly - increase in driver size. - - If you are not sure, say N here. - -config THINKPAD_ACPI_DOCK - bool "Legacy Docking Station Support" - depends on THINKPAD_ACPI - depends on ACPI_DOCK=n - default n - ---help--- - Allows the thinkpad_acpi driver to handle docking station events. - This support was made obsolete by the generic ACPI docking station - support (CONFIG_ACPI_DOCK). It will allow locking and removing the - laptop from the docking station, but will not properly connect PCI - devices. - - If you are not sure, say N here. - -config THINKPAD_ACPI_BAY - bool "Legacy Removable Bay Support" - depends on THINKPAD_ACPI - default y - ---help--- - Allows the thinkpad_acpi driver to handle removable bays. It will - electrically disable the device in the bay, and also generate - notifications when the bay lever is ejected or inserted. - - If you are not sure, say Y here. - -config THINKPAD_ACPI_VIDEO - bool "Video output control support" - depends on THINKPAD_ACPI - default y - ---help--- - Allows the thinkpad_acpi driver to provide an interface to control - the various video output ports. - - This feature often won't work well, depending on ThinkPad model, - display state, video output devices in use, whether there is a X - server running, phase of the moon, and the current mood of - Schroedinger's cat. If you can use X.org's RandR to control - your ThinkPad's video output ports instead of this feature, - don't think twice: do it and say N here to save some memory. - - If you are not sure, say Y here. - -config THINKPAD_ACPI_HOTKEY_POLL - bool "Support NVRAM polling for hot keys" - depends on THINKPAD_ACPI - default y - ---help--- - Some thinkpad models benefit from NVRAM polling to detect a few of - the hot key press events. If you know your ThinkPad model does not - need to do NVRAM polling to support any of the hot keys you use, - unselecting this option will save about 1kB of memory. - - ThinkPads T40 and newer, R52 and newer, and X31 and newer are - unlikely to need NVRAM polling in their latest BIOS versions. - - NVRAM polling can detect at most the following keys: ThinkPad/Access - IBM, Zoom, Switch Display (fn+F7), ThinkLight, Volume up/down/mute, - Brightness up/down, Display Expand (fn+F8), Hibernate (fn+F12). - - If you are not sure, say Y here. The driver enables polling only if - it is strictly necessary to do so. - config ATMEL_SSC tristate "Device driver for Atmel SSC peripheral" depends on AVR32 || ARCH_AT91 @@ -413,31 +158,6 @@ config ATMEL_SSC If unsure, say N. -config INTEL_MENLOW - tristate "Thermal Management driver for Intel menlow platform" - depends on ACPI_THERMAL - select THERMAL - depends on X86 - ---help--- - ACPI thermal management enhancement driver on - Intel Menlow platform. - - If unsure, say N. - -config EEEPC_LAPTOP - tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" - depends on X86 - depends on ACPI - depends on BACKLIGHT_CLASS_DEVICE - depends on HWMON - depends on EXPERIMENTAL - depends on RFKILL - ---help--- - This driver supports the Fn-Fx keys on Eee PC laptops. - It also adds the ability to switch camera/wlan on/off. - - If you have an Eee PC laptop, say Y or M here. - config ENCLOSURE_SERVICES tristate "Enclosure Services" default n diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 5de863a0e39..9cf8ae6e4b3 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -1,33 +1,20 @@ # # Makefile for misc devices that really don't fit anywhere else. # -obj- := misc.o # Dummy rule to force built-in.o to be made obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ -obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o -obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o -obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o -obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o -obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o -obj-$(CONFIG_HP_WMI) += hp-wmi.o obj-$(CONFIG_ICS932S401) += ics932s401.o -obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SGI_IOC4) += ioc4.o -obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o -obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o -obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o -obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o -obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index c62ab8d240a..1c114180106 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -33,7 +33,6 @@ #include #include #include -#include #define MY_NAME "acpi_pcihp" diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 27fd18f019f..db85284ffb6 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -217,7 +217,6 @@ struct hpc_ops { #ifdef CONFIG_ACPI #include #include -#include #include extern void __init pciehp_acpi_slot_detection_init(void); diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 3582512e722..deea8a187eb 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig new file mode 100644 index 00000000000..9652c3fe7f5 --- /dev/null +++ b/drivers/platform/Kconfig @@ -0,0 +1,5 @@ +# drivers/platform/Kconfig + +if X86 +source "drivers/platform/x86/Kconfig" +endif diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile new file mode 100644 index 00000000000..782953ae4c0 --- /dev/null +++ b/drivers/platform/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for linux/drivers/platform +# + +obj-$(CONFIG_X86) += x86/ diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig new file mode 100644 index 00000000000..e65448e99b4 --- /dev/null +++ b/drivers/platform/x86/Kconfig @@ -0,0 +1,375 @@ +# +# X86 Platform Specific Drivers +# + +menuconfig X86_PLATFORM_DEVICES + bool "X86 Platform Specific Device Drivers" + default y + ---help--- + Say Y here to get to see options for device drivers for various + x86 platforms, including vendor-specific laptop extension drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if X86_PLATFORM_DEVICES + +config ACER_WMI + tristate "Acer WMI Laptop Extras (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on ACPI + depends on LEDS_CLASS + depends on NEW_LEDS + depends on BACKLIGHT_CLASS_DEVICE + depends on SERIO_I8042 + depends on RFKILL + select ACPI_WMI + ---help--- + This is a driver for newer Acer (and Wistron) laptops. It adds + wireless radio and bluetooth control, and on some laptops, + exposes the mail LED and LCD backlight. + + For more information about this driver see + + + If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M + here. + +config ASUS_LAPTOP + tristate "Asus Laptop Extras (EXPERIMENTAL)" + depends on ACPI + depends on EXPERIMENTAL && !ACPI_ASUS + depends on LEDS_CLASS + depends on NEW_LEDS + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is the new Linux driver for Asus laptops. It may also support some + MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate + standard ACPI events that go through /proc/acpi/events. It also adds + support for video output switching, LCD backlight control, Bluetooth and + Wlan control, and most importantly, allows you to blink those fancy LEDs. + + For more information and a userspace daemon for handling the extra + buttons see . + + If you have an ACPI-compatible ASUS laptop, say Y or M here. + +config FUJITSU_LAPTOP + tristate "Fujitsu Laptop Extras" + depends on ACPI + depends on INPUT + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is a driver for laptops built by Fujitsu: + + * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks + * Possibly other Fujitsu laptop models + * Tested with S6410 and S7020 + + It adds support for LCD brightness control and some hotkeys. + + If you have a Fujitsu laptop, say Y or M here. + +config FUJITSU_LAPTOP_DEBUG + bool "Verbose debug mode for Fujitsu Laptop Extras" + depends on FUJITSU_LAPTOP + default n + ---help--- + Enables extra debug output from the fujitsu extras driver, at the + expense of a slight increase in driver size. + + If you are not sure, say N here. + +config TC1100_WMI + tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" + depends on !X86_64 + depends on EXPERIMENTAL + depends on ACPI + select ACPI_WMI + ---help--- + This is a driver for the WMI extensions (wireless and bluetooth power + control) of the HP Compaq TC1100 tablet. + +config HP_WMI + tristate "HP WMI extras" + depends on ACPI_WMI + depends on INPUT + depends on RFKILL + help + Say Y here if you want to support WMI-based hotkeys on HP laptops and + to read data from WMI such as docking or ambient light sensor state. + + To compile this driver as a module, choose M here: the module will + be called hp-wmi. + +config MSI_LAPTOP + tristate "MSI Laptop Extras" + depends on ACPI + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is a driver for laptops built by MSI (MICRO-STAR + INTERNATIONAL): + + MSI MegaBook S270 (MS-1013) + Cytron/TCM/Medion/Tchibo MD96100/SAM2000 + + It adds support for Bluetooth, WLAN and LCD brightness control. + + More information about this driver is available at + . + + If you have an MSI S270 laptop, say Y or M here. + +config PANASONIC_LAPTOP + tristate "Panasonic Laptop Extras" + depends on INPUT && ACPI + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This driver adds support for access to backlight control and hotkeys + on Panasonic Let's Note laptops. + + If you have a Panasonic Let's note laptop (such as the R1(N variant), + R2, R3, R5, T2, W2 and Y2 series), say Y. + +config COMPAL_LAPTOP + tristate "Compal Laptop Extras" + depends on ACPI + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is a driver for laptops built by Compal: + + Compal FL90/IFL90 + Compal FL91/IFL91 + Compal FL92/JFL92 + Compal FT00/IFT00 + + It adds support for Bluetooth, WLAN and LCD brightness control. + + If you have an Compal FL9x/IFL9x/FT00 laptop, say Y or M here. + +config SONY_LAPTOP + tristate "Sony Laptop Extras" + depends on ACPI + select BACKLIGHT_CLASS_DEVICE + depends on INPUT + ---help--- + This mini-driver drives the SNC and SPIC devices present in the ACPI + BIOS of the Sony Vaio laptops. + + It gives access to some extra laptop functionalities like Bluetooth, + screen brightness control, Fn keys and allows powering on/off some + devices. + + Read for more information. + +config SONYPI_COMPAT + bool "Sonypi compatibility" + depends on SONY_LAPTOP + ---help--- + Build the sonypi driver compatibility code into the sony-laptop driver. + +config THINKPAD_ACPI + tristate "ThinkPad ACPI Laptop Extras" + depends on ACPI + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE + select HWMON + select NVRAM + select INPUT + select NEW_LEDS + select LEDS_CLASS + select NET + select RFKILL + ---help--- + This is a driver for the IBM and Lenovo ThinkPad laptops. It adds + support for Fn-Fx key combinations, Bluetooth control, video + output switching, ThinkLight control, UltraBay eject and more. + For more information about this driver see + and + . + + This driver was formerly known as ibm-acpi. + + If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. + +config THINKPAD_ACPI_DEBUG + bool "Verbose debug mode" + depends on THINKPAD_ACPI + default n + ---help--- + Enables extra debugging information, at the expense of a slightly + increase in driver size. + + If you are not sure, say N here. + +config THINKPAD_ACPI_DOCK + bool "Legacy Docking Station Support" + depends on THINKPAD_ACPI + depends on ACPI_DOCK=n + default n + ---help--- + Allows the thinkpad_acpi driver to handle docking station events. + This support was made obsolete by the generic ACPI docking station + support (CONFIG_ACPI_DOCK). It will allow locking and removing the + laptop from the docking station, but will not properly connect PCI + devices. + + If you are not sure, say N here. + +config THINKPAD_ACPI_BAY + bool "Legacy Removable Bay Support" + depends on THINKPAD_ACPI + default y + ---help--- + Allows the thinkpad_acpi driver to handle removable bays. It will + electrically disable the device in the bay, and also generate + notifications when the bay lever is ejected or inserted. + + If you are not sure, say Y here. + +config THINKPAD_ACPI_VIDEO + bool "Video output control support" + depends on THINKPAD_ACPI + default y + ---help--- + Allows the thinkpad_acpi driver to provide an interface to control + the various video output ports. + + This feature often won't work well, depending on ThinkPad model, + display state, video output devices in use, whether there is a X + server running, phase of the moon, and the current mood of + Schroedinger's cat. If you can use X.org's RandR to control + your ThinkPad's video output ports instead of this feature, + don't think twice: do it and say N here to save some memory. + + If you are not sure, say Y here. + +config THINKPAD_ACPI_HOTKEY_POLL + bool "Support NVRAM polling for hot keys" + depends on THINKPAD_ACPI + default y + ---help--- + Some thinkpad models benefit from NVRAM polling to detect a few of + the hot key press events. If you know your ThinkPad model does not + need to do NVRAM polling to support any of the hot keys you use, + unselecting this option will save about 1kB of memory. + + ThinkPads T40 and newer, R52 and newer, and X31 and newer are + unlikely to need NVRAM polling in their latest BIOS versions. + + NVRAM polling can detect at most the following keys: ThinkPad/Access + IBM, Zoom, Switch Display (fn+F7), ThinkLight, Volume up/down/mute, + Brightness up/down, Display Expand (fn+F8), Hibernate (fn+F12). + + If you are not sure, say Y here. The driver enables polling only if + it is strictly necessary to do so. + +config INTEL_MENLOW + tristate "Thermal Management driver for Intel menlow platform" + depends on ACPI_THERMAL + select THERMAL + ---help--- + ACPI thermal management enhancement driver on + Intel Menlow platform. + + If unsure, say N. + +config EEEPC_LAPTOP + tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" + depends on ACPI + depends on EXPERIMENTAL + select BACKLIGHT_CLASS_DEVICE + select HWMON + select RFKILL + ---help--- + This driver supports the Fn-Fx keys on Eee PC laptops. + It also adds the ability to switch camera/wlan on/off. + + If you have an Eee PC laptop, say Y or M here. + + +config ACPI_WMI + tristate "WMI (EXPERIMENTAL)" + depends on ACPI + depends on EXPERIMENTAL + help + This driver adds support for the ACPI-WMI (Windows Management + Instrumentation) mapper device (PNP0C14) found on some systems. + + ACPI-WMI is a proprietary extension to ACPI to expose parts of the + ACPI firmware to userspace - this is done through various vendor + defined methods and data blocks in a PNP0C14 device, which are then + made available for userspace to call. + + The implementation of this in Linux currently only exposes this to + other kernel space drivers. + + This driver is a required dependency to build the firmware specific + drivers needed on many machines, including Acer and HP laptops. + + It is safe to enable this driver even if your DSDT doesn't define + any ACPI-WMI devices. + +config ACPI_ASUS + tristate "ASUS/Medion Laptop Extras" + depends on ACPI + select BACKLIGHT_CLASS_DEVICE + ---help--- + This driver provides support for extra features of ACPI-compatible + ASUS laptops. As some of Medion laptops are made by ASUS, it may also + support some Medion laptops (such as 9675 for example). It makes all + the extra buttons generate standard ACPI events that go through + /proc/acpi/events, and (on some models) adds support for changing the + display brightness and output, switching the LCD backlight on and off, + and most importantly, allows you to blink those fancy LEDs intended + for reporting mail and wireless status. + + Note: display switching code is currently considered EXPERIMENTAL, + toying with these values may even lock your machine. + + All settings are changed via /proc/acpi/asus directory entries. Owner + and group for these entries can be set with asus_uid and asus_gid + parameters. + + More information and a userspace daemon for handling the extra buttons + at . + + If you have an ACPI-compatible ASUS laptop, say Y or M here. This + driver is still under development, so if your laptop is unsupported or + something works not quite as expected, please use the mailing list + available on the above page (acpi4asus-user@lists.sourceforge.net). + + NOTE: This driver is deprecated and will probably be removed soon, + use asus-laptop instead. + +config ACPI_TOSHIBA + tristate "Toshiba Laptop Extras" + depends on ACPI + depends on INPUT + select INPUT_POLLDEV + select NET + select RFKILL + select BACKLIGHT_CLASS_DEVICE + ---help--- + This driver adds support for access to certain system settings + on "legacy free" Toshiba laptops. These laptops can be recognized by + their lack of a BIOS setup menu and APM support. + + On these machines, all system configuration is handled through the + ACPI. This driver is required for access to controls not covered + by the general ACPI drivers, such as LCD brightness, video output, + etc. + + This driver differs from the non-ACPI Toshiba laptop driver (located + under "Processor type and features") in several aspects. + Configuration is accessed by reading and writing text files in the + /proc tree instead of by program interface to /dev. Furthermore, no + power management functions are exposed, as those are handled by the + general ACPI drivers. + + More information about this driver is available at + . + + If you have a legacy free Toshiba laptop (such as the Libretto L1 + series), say Y. +endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile new file mode 100644 index 00000000000..1e9de2ae0de --- /dev/null +++ b/drivers/platform/x86/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for linux/drivers/platform/x86 +# x86 Platform-Specific Drivers +# +obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o +obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o +obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o +obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o +obj-$(CONFIG_ACER_WMI) += acer-wmi.o +obj-$(CONFIG_HP_WMI) += hp-wmi.o +obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o +obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o +obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o +obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o +obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o +obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o +obj-$(CONFIG_ACPI_WMI) += wmi.o +obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o +obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o diff --git a/drivers/misc/acer-wmi.c b/drivers/platform/x86/acer-wmi.c similarity index 100% rename from drivers/misc/acer-wmi.c rename to drivers/platform/x86/acer-wmi.c diff --git a/drivers/misc/asus-laptop.c b/drivers/platform/x86/asus-laptop.c similarity index 100% rename from drivers/misc/asus-laptop.c rename to drivers/platform/x86/asus-laptop.c diff --git a/drivers/acpi/asus_acpi.c b/drivers/platform/x86/asus_acpi.c similarity index 100% rename from drivers/acpi/asus_acpi.c rename to drivers/platform/x86/asus_acpi.c diff --git a/drivers/misc/compal-laptop.c b/drivers/platform/x86/compal-laptop.c similarity index 100% rename from drivers/misc/compal-laptop.c rename to drivers/platform/x86/compal-laptop.c diff --git a/drivers/misc/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c similarity index 100% rename from drivers/misc/eeepc-laptop.c rename to drivers/platform/x86/eeepc-laptop.c diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c similarity index 74% rename from drivers/misc/fujitsu-laptop.c rename to drivers/platform/x86/fujitsu-laptop.c index a7dd3e9fb79..65dc41540c6 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -3,6 +3,7 @@ /* Copyright (C) 2007,2008 Jonathan Woithe Copyright (C) 2008 Peter Gruber + Copyright (C) 2008 Tony Vroon Based on earlier work: Copyright (C) 2003 Shane Spencer Adrian Yee @@ -65,8 +66,11 @@ #include #include #include +#ifdef CONFIG_LEDS_CLASS +#include +#endif -#define FUJITSU_DRIVER_VERSION "0.4.3" +#define FUJITSU_DRIVER_VERSION "0.5.0" #define FUJITSU_LCD_N_LEVELS 8 @@ -83,6 +87,24 @@ #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 +/* FUNC interface - command values */ +#define FUNC_RFKILL 0x1000 +#define FUNC_LEDS 0x1001 +#define FUNC_BUTTONS 0x1002 +#define FUNC_BACKLIGHT 0x1004 + +/* FUNC interface - responses */ +#define UNSUPPORTED_CMD 0x80000000 + +#ifdef CONFIG_LEDS_CLASS +/* FUNC interface - LED control */ +#define FUNC_LED_OFF 0x1 +#define FUNC_LED_ON 0x30001 +#define KEYBOARD_LAMPS 0x100 +#define LOGOLAMP_POWERON 0x2000 +#define LOGOLAMP_ALWAYS 0x4000 +#endif + /* Hotkey details */ #define KEY1_CODE 0x410 /* codes for the keys in the GIRB register */ #define KEY2_CODE 0x411 @@ -133,7 +155,6 @@ struct fujitsu_t { static struct fujitsu_t *fujitsu; static int use_alt_lcd_levels = -1; -static int disable_brightness_keys = -1; static int disable_brightness_adjust = -1; /* Device used to access other hotkeys on the laptop */ @@ -145,8 +166,9 @@ struct fujitsu_hotkey_t { struct platform_device *pf_device; struct kfifo *fifo; spinlock_t fifo_lock; - - unsigned int irb; /* info about the pressed buttons */ + int rfkill_state; + int logolamp_registered; + int kblamps_registered; }; static struct fujitsu_hotkey_t *fujitsu_hotkey; @@ -154,12 +176,139 @@ static struct fujitsu_hotkey_t *fujitsu_hotkey; static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, void *data); +#ifdef CONFIG_LEDS_CLASS +static enum led_brightness logolamp_get(struct led_classdev *cdev); +static void logolamp_set(struct led_classdev *cdev, + enum led_brightness brightness); + +struct led_classdev logolamp_led = { + .name = "fujitsu::logolamp", + .brightness_get = logolamp_get, + .brightness_set = logolamp_set +}; + +static enum led_brightness kblamps_get(struct led_classdev *cdev); +static void kblamps_set(struct led_classdev *cdev, + enum led_brightness brightness); + +struct led_classdev kblamps_led = { + .name = "fujitsu::kblamps", + .brightness_get = kblamps_get, + .brightness_set = kblamps_set +}; +#endif + #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG static u32 dbg_level = 0x03; #endif static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data); +/* Fujitsu ACPI interface function */ + +static int call_fext_func(int cmd, int arg0, int arg1, int arg2) +{ + acpi_status status = AE_OK; + union acpi_object params[4] = { + { .type = ACPI_TYPE_INTEGER }, + { .type = ACPI_TYPE_INTEGER }, + { .type = ACPI_TYPE_INTEGER }, + { .type = ACPI_TYPE_INTEGER } + }; + struct acpi_object_list arg_list = { 4, ¶ms[0] }; + struct acpi_buffer output; + union acpi_object out_obj; + acpi_handle handle = NULL; + + status = acpi_get_handle(fujitsu_hotkey->acpi_handle, "FUNC", &handle); + if (ACPI_FAILURE(status)) { + vdbg_printk(FUJLAPTOP_DBG_ERROR, + "FUNC interface is not present\n"); + return -ENODEV; + } + + params[0].integer.value = cmd; + params[1].integer.value = arg0; + params[2].integer.value = arg1; + params[3].integer.value = arg2; + + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(handle, NULL, &arg_list, &output); + if (ACPI_FAILURE(status)) { + vdbg_printk(FUJLAPTOP_DBG_WARN, + "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) call failed\n", + cmd, arg0, arg1, arg2); + return -ENODEV; + } + + if (out_obj.type != ACPI_TYPE_INTEGER) { + vdbg_printk(FUJLAPTOP_DBG_WARN, + "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) did not " + "return an integer\n", + cmd, arg0, arg1, arg2); + return -ENODEV; + } + + vdbg_printk(FUJLAPTOP_DBG_TRACE, + "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) returned 0x%x\n", + cmd, arg0, arg1, arg2, (int)out_obj.integer.value); + return out_obj.integer.value; +} + +#ifdef CONFIG_LEDS_CLASS +/* LED class callbacks */ + +static void logolamp_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + if (brightness >= LED_FULL) { + call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); + call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON); + } else if (brightness >= LED_HALF) { + call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); + call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF); + } else { + call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF); + } +} + +static void kblamps_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + if (brightness >= LED_FULL) + call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON); + else + call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF); +} + +static enum led_brightness logolamp_get(struct led_classdev *cdev) +{ + enum led_brightness brightness = LED_OFF; + int poweron, always; + + poweron = call_fext_func(FUNC_LEDS, 0x2, LOGOLAMP_POWERON, 0x0); + if (poweron == FUNC_LED_ON) { + brightness = LED_HALF; + always = call_fext_func(FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0); + if (always == FUNC_LED_ON) + brightness = LED_FULL; + } + return brightness; +} + +static enum led_brightness kblamps_get(struct led_classdev *cdev) +{ + enum led_brightness brightness = LED_OFF; + + if (call_fext_func(FUNC_LEDS, 0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON) + brightness = LED_FULL; + + return brightness; +} +#endif + /* Hardware access for LCD brightness control */ static int set_lcd_level(int level) @@ -263,44 +412,34 @@ static int get_max_brightness(void) return fujitsu->max_brightness; } -static int get_lcd_level_alt(void) -{ - unsigned long long state = 0; - acpi_status status = AE_OK; - - vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n"); - - status = - acpi_evaluate_integer(fujitsu->acpi_handle, "GBLS", NULL, &state); - if (status < 0) - return status; - - fujitsu->brightness_level = state & 0x0fffffff; - - if (state & 0x80000000) - fujitsu->brightness_changed = 1; - else - fujitsu->brightness_changed = 0; - - return fujitsu->brightness_level; -} - /* Backlight device stuff */ static int bl_get_brightness(struct backlight_device *b) { - if (use_alt_lcd_levels) - return get_lcd_level_alt(); - else - return get_lcd_level(); + return get_lcd_level(); } static int bl_update_status(struct backlight_device *b) { + int ret; + if (b->props.power == 4) + ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x3); + else + ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x0); + if (ret != 0) + vdbg_printk(FUJLAPTOP_DBG_ERROR, + "Unable to adjust backlight power, error code %i\n", + ret); + if (use_alt_lcd_levels) - return set_lcd_level_alt(b->props.brightness); + ret = set_lcd_level_alt(b->props.brightness); else - return set_lcd_level(b->props.brightness); + ret = set_lcd_level(b->props.brightness); + if (ret != 0) + vdbg_printk(FUJLAPTOP_DBG_ERROR, + "Unable to adjust LCD brightness, error code %i\n", + ret); + return ret; } static struct backlight_ops fujitsubl_ops = { @@ -344,10 +483,7 @@ static ssize_t show_lcd_level(struct device *dev, int ret; - if (use_alt_lcd_levels) - ret = get_lcd_level_alt(); - else - ret = get_lcd_level(); + ret = get_lcd_level(); if (ret < 0) return ret; @@ -372,52 +508,71 @@ static ssize_t store_lcd_level(struct device *dev, if (ret < 0) return ret; - if (use_alt_lcd_levels) - ret = get_lcd_level_alt(); - else - ret = get_lcd_level(); + ret = get_lcd_level(); if (ret < 0) return ret; return count; } -/* Hardware access for hotkey device */ - -static int get_irb(void) +static ssize_t +ignore_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { - unsigned long long state = 0; - acpi_status status = AE_OK; - - vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n"); - - status = - acpi_evaluate_integer(fujitsu_hotkey->acpi_handle, "GIRB", NULL, - &state); - if (status < 0) - return status; + return count; +} - fujitsu_hotkey->irb = state; +static ssize_t +show_lid_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + return sprintf(buf, "unknown\n"); + if (fujitsu_hotkey->rfkill_state & 0x100) + return sprintf(buf, "open\n"); + else + return sprintf(buf, "closed\n"); +} - return fujitsu_hotkey->irb; +static ssize_t +show_dock_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + return sprintf(buf, "unknown\n"); + if (fujitsu_hotkey->rfkill_state & 0x200) + return sprintf(buf, "docked\n"); + else + return sprintf(buf, "undocked\n"); } static ssize_t -ignore_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +show_radios_state(struct device *dev, + struct device_attribute *attr, char *buf) { - return count; + if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + return sprintf(buf, "unknown\n"); + if (fujitsu_hotkey->rfkill_state & 0x20) + return sprintf(buf, "on\n"); + else + return sprintf(buf, "killed\n"); } static DEVICE_ATTR(max_brightness, 0444, show_max_brightness, ignore_store); static DEVICE_ATTR(brightness_changed, 0444, show_brightness_changed, ignore_store); static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); +static DEVICE_ATTR(lid, 0444, show_lid_state, ignore_store); +static DEVICE_ATTR(dock, 0444, show_dock_state, ignore_store); +static DEVICE_ATTR(radios, 0444, show_radios_state, ignore_store); static struct attribute *fujitsupf_attributes[] = { &dev_attr_brightness_changed.attr, &dev_attr_max_brightness.attr, &dev_attr_lcd_level.attr, + &dev_attr_lid.attr, + &dev_attr_dock.attr, + &dev_attr_radios.attr, NULL }; @@ -435,24 +590,16 @@ static struct platform_driver fujitsupf_driver = { static void dmi_check_cb_common(const struct dmi_system_id *id) { acpi_handle handle; - int have_blnf; printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n", id->ident); - have_blnf = ACPI_SUCCESS - (acpi_get_handle(NULL, "\\_SB.PCI0.GFX0.LCD.BLNF", &handle)); if (use_alt_lcd_levels == -1) { - vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detecting usealt\n"); - use_alt_lcd_levels = 1; - } - if (disable_brightness_keys == -1) { - vdbg_printk(FUJLAPTOP_DBG_TRACE, - "auto-detecting disable_keys\n"); - disable_brightness_keys = have_blnf ? 1 : 0; - } - if (disable_brightness_adjust == -1) { - vdbg_printk(FUJLAPTOP_DBG_TRACE, - "auto-detecting disable_adjust\n"); - disable_brightness_adjust = have_blnf ? 0 : 1; + if (ACPI_SUCCESS(acpi_get_handle(NULL, + "\\_SB.PCI0.LPCB.FJEX.SBL2", &handle))) + use_alt_lcd_levels = 1; + else + use_alt_lcd_levels = 0; + vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detected usealt as " + "%i\n", use_alt_lcd_levels); } } @@ -581,19 +728,14 @@ static int acpi_fujitsu_add(struct acpi_device *device) /* do config (detect defaults) */ use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; - disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0; disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; vdbg_printk(FUJLAPTOP_DBG_INFO, - "config: [alt interface: %d], [key disable: %d], [adjust disable: %d]\n", - use_alt_lcd_levels, disable_brightness_keys, - disable_brightness_adjust); + "config: [alt interface: %d], [adjust disable: %d]\n", + use_alt_lcd_levels, disable_brightness_adjust); if (get_max_brightness() <= 0) fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS; - if (use_alt_lcd_levels) - get_lcd_level_alt(); - else - get_lcd_level(); + get_lcd_level(); return result; @@ -644,43 +786,23 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) case ACPI_FUJITSU_NOTIFY_CODE1: keycode = 0; oldb = fujitsu->brightness_level; - get_lcd_level(); /* the alt version always yields changed */ + get_lcd_level(); newb = fujitsu->brightness_level; vdbg_printk(FUJLAPTOP_DBG_TRACE, "brightness button event [%i -> %i (%i)]\n", oldb, newb, fujitsu->brightness_changed); - if (oldb == newb && fujitsu->brightness_changed) { - keycode = 0; - if (disable_brightness_keys != 1) { - if (oldb == 0) { - acpi_bus_generate_proc_event - (fujitsu->dev, - ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, - 0); - keycode = KEY_BRIGHTNESSDOWN; - } else if (oldb == - (fujitsu->max_brightness) - 1) { - acpi_bus_generate_proc_event - (fujitsu->dev, - ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, - 0); - keycode = KEY_BRIGHTNESSUP; - } - } - } else if (oldb < newb) { + if (oldb < newb) { if (disable_brightness_adjust != 1) { if (use_alt_lcd_levels) set_lcd_level_alt(newb); else set_lcd_level(newb); } - if (disable_brightness_keys != 1) { - acpi_bus_generate_proc_event(fujitsu->dev, - ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0); - keycode = KEY_BRIGHTNESSUP; - } + acpi_bus_generate_proc_event(fujitsu->dev, + ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0); + keycode = KEY_BRIGHTNESSUP; } else if (oldb > newb) { if (disable_brightness_adjust != 1) { if (use_alt_lcd_levels) @@ -688,13 +810,9 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) else set_lcd_level(newb); } - if (disable_brightness_keys != 1) { - acpi_bus_generate_proc_event(fujitsu->dev, - ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0); - keycode = KEY_BRIGHTNESSDOWN; - } - } else { - keycode = KEY_UNKNOWN; + acpi_bus_generate_proc_event(fujitsu->dev, + ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0); + keycode = KEY_BRIGHTNESSDOWN; } break; default: @@ -771,7 +889,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) input->id.bustype = BUS_HOST; input->id.product = 0x06; input->dev.parent = &device->dev; - input->evbit[0] = BIT(EV_KEY); + + set_bit(EV_KEY, input->evbit); set_bit(fujitsu->keycode1, input->keybit); set_bit(fujitsu->keycode2, input->keybit); set_bit(fujitsu->keycode3, input->keybit); @@ -803,10 +922,44 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) printk(KERN_ERR "_INI Method failed\n"); } - i = 0; /* Discard hotkey ringbuffer */ - while (get_irb() != 0 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) ; + i = 0; + while (call_fext_func(FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0 + && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) + ; /* No action, result is discarded */ vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); + fujitsu_hotkey->rfkill_state = + call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + + /* Suspect this is a keymap of the application panel, print it */ + printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", + call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); + + #ifdef CONFIG_LEDS_CLASS + if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { + result = led_classdev_register(&fujitsu->pf_device->dev, + &logolamp_led); + if (result == 0) { + fujitsu_hotkey->logolamp_registered = 1; + } else { + printk(KERN_ERR "fujitsu-laptop: Could not register " + "LED handler for logo lamp, error %i\n", result); + } + } + + if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) && + (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) == 0x0)) { + result = led_classdev_register(&fujitsu->pf_device->dev, + &kblamps_led); + if (result == 0) { + fujitsu_hotkey->kblamps_registered = 1; + } else { + printk(KERN_ERR "fujitsu-laptop: Could not register " + "LED handler for keyboard lamps, error %i\n", result); + } + } + #endif + return result; end: @@ -852,16 +1005,15 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, input = fujitsu_hotkey->input; - vdbg_printk(FUJLAPTOP_DBG_TRACE, "Hotkey event\n"); + fujitsu_hotkey->rfkill_state = + call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); switch (event) { case ACPI_FUJITSU_NOTIFY_CODE1: i = 0; - while ((irb = get_irb()) != 0 - && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) { - vdbg_printk(FUJLAPTOP_DBG_TRACE, "GIRB result [%x]\n", - irb); - + while ((irb = + call_fext_func(FUNC_BUTTONS, 0x1, 0x0, 0x0)) != 0 + && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) { switch (irb & 0x4ff) { case KEY1_CODE: keycode = fujitsu->keycode1; @@ -1035,6 +1187,15 @@ static int __init fujitsu_init(void) goto fail_hotkey1; } + /* Sync backlight power status (needs FUJ02E3 device, hence deferred) */ + + if (!acpi_video_backlight_support()) { + if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3) + fujitsu->bl_device->props.power = 4; + else + fujitsu->bl_device->props.power = 0; + } + printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION " successfully loaded.\n"); @@ -1074,6 +1235,14 @@ fail_acpi: static void __exit fujitsu_cleanup(void) { + #ifdef CONFIG_LEDS_CLASS + if (fujitsu_hotkey->logolamp_registered != 0) + led_classdev_unregister(&logolamp_led); + + if (fujitsu_hotkey->kblamps_registered != 0) + led_classdev_unregister(&kblamps_led); + #endif + sysfs_remove_group(&fujitsu->pf_device->dev.kobj, &fujitsupf_attribute_group); platform_device_unregister(fujitsu->pf_device); @@ -1098,9 +1267,6 @@ module_exit(fujitsu_cleanup); module_param(use_alt_lcd_levels, uint, 0644); MODULE_PARM_DESC(use_alt_lcd_levels, "Use alternative interface for lcd_levels (needed for Lifebook s6410)."); -module_param(disable_brightness_keys, uint, 0644); -MODULE_PARM_DESC(disable_brightness_keys, - "Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device)."); module_param(disable_brightness_adjust, uint, 0644); MODULE_PARM_DESC(disable_brightness_adjust, "Disable brightness adjustment ."); #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG @@ -1108,12 +1274,13 @@ module_param_named(debug, dbg_level, uint, 0644); MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); #endif -MODULE_AUTHOR("Jonathan Woithe, Peter Gruber"); +MODULE_AUTHOR("Jonathan Woithe, Peter Gruber, Tony Vroon"); MODULE_DESCRIPTION("Fujitsu laptop extras support"); MODULE_VERSION(FUJITSU_DRIVER_VERSION); MODULE_LICENSE("GPL"); MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"); +MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1E6:*:cvrS6420:*"); MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"); static struct pnp_device_id pnp_ids[] = { diff --git a/drivers/misc/hp-wmi.c b/drivers/platform/x86/hp-wmi.c similarity index 100% rename from drivers/misc/hp-wmi.c rename to drivers/platform/x86/hp-wmi.c diff --git a/drivers/misc/intel_menlow.c b/drivers/platform/x86/intel_menlow.c similarity index 100% rename from drivers/misc/intel_menlow.c rename to drivers/platform/x86/intel_menlow.c diff --git a/drivers/misc/msi-laptop.c b/drivers/platform/x86/msi-laptop.c similarity index 100% rename from drivers/misc/msi-laptop.c rename to drivers/platform/x86/msi-laptop.c diff --git a/drivers/misc/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c similarity index 97% rename from drivers/misc/panasonic-laptop.c rename to drivers/platform/x86/panasonic-laptop.c index 4a1bc64485d..f30db367c82 100644 --- a/drivers/misc/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -241,8 +241,6 @@ static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val) }; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE("acpi_pcc_write_sset"); - status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SSET, ¶ms, NULL); @@ -254,8 +252,6 @@ static inline int acpi_pcc_get_sqty(struct acpi_device *device) unsigned long long s; acpi_status status; - ACPI_FUNCTION_TRACE("acpi_pcc_get_sqty"); - status = acpi_evaluate_integer(device->handle, METHOD_HKEY_SQTY, NULL, &s); if (ACPI_SUCCESS(status)) @@ -274,8 +270,6 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf) union acpi_object *hkey = NULL; int i; - ACPI_FUNCTION_TRACE("acpi_pcc_retrieve_biosdata"); - status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0, &buffer); if (ACPI_FAILURE(status)) { @@ -501,8 +495,6 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) int key_code, hkey_num; unsigned long long result; - ACPI_FUNCTION_TRACE("acpi_pcc_generate_keyinput"); - rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY, NULL, &result); if (!ACPI_SUCCESS(rc)) { @@ -538,8 +530,6 @@ static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data) { struct pcc_acpi *pcc = (struct pcc_acpi *) data; - ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_notify"); - switch (event) { case HKEY_NOTIFY: acpi_pcc_generate_keyinput(pcc); @@ -554,8 +544,6 @@ static int acpi_pcc_init_input(struct pcc_acpi *pcc) { int i, rc; - ACPI_FUNCTION_TRACE("acpi_pcc_init_input"); - pcc->input_dev = input_allocate_device(); if (!pcc->input_dev) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -597,8 +585,6 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device) struct pcc_acpi *pcc = acpi_driver_data(device); acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_resume"); - if (device == NULL || pcc == NULL) return -EINVAL; @@ -616,8 +602,6 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) struct pcc_acpi *pcc; int num_sifr, result; - ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_add"); - if (!device) return -EINVAL; @@ -714,8 +698,6 @@ static int __init acpi_pcc_init(void) { int result = 0; - ACPI_FUNCTION_TRACE("acpi_pcc_init"); - if (acpi_disabled) return -ENODEV; @@ -733,8 +715,6 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) { struct pcc_acpi *pcc = acpi_driver_data(device); - ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove"); - if (!device || !pcc) return -EINVAL; @@ -757,8 +737,6 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) static void __exit acpi_pcc_exit(void) { - ACPI_FUNCTION_TRACE("acpi_pcc_exit"); - acpi_bus_unregister_driver(&acpi_pcc_driver); } diff --git a/drivers/misc/sony-laptop.c b/drivers/platform/x86/sony-laptop.c similarity index 99% rename from drivers/misc/sony-laptop.c rename to drivers/platform/x86/sony-laptop.c index 571b211608d..537959d0714 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -935,14 +935,17 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) static acpi_status sony_walk_callback(acpi_handle handle, u32 level, void *context, void **return_value) { - struct acpi_namespace_node *node; - union acpi_operand_object *operand; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - node = (struct acpi_namespace_node *)handle; - operand = (union acpi_operand_object *)node->object; + if (ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) { + info = buffer.pointer; - printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", node->name.ascii, - (u32) operand->method.param_count); + printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", + (char *)&info->name, info->param_count); + + kfree(buffer.pointer); + } return AE_OK; } diff --git a/drivers/misc/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c similarity index 99% rename from drivers/misc/tc1100-wmi.c rename to drivers/platform/x86/tc1100-wmi.c index f25e4c974dc..b4a4aa9ee48 100644 --- a/drivers/misc/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c similarity index 99% rename from drivers/misc/thinkpad_acpi.c rename to drivers/platform/x86/thinkpad_acpi.c index 899766e16fa..3478453eba7 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -76,7 +76,6 @@ #include #include -#include #include diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c similarity index 100% rename from drivers/acpi/toshiba_acpi.c rename to drivers/platform/x86/toshiba_acpi.c diff --git a/drivers/acpi/wmi.c b/drivers/platform/x86/wmi.c similarity index 100% rename from drivers/acpi/wmi.c rename to drivers/platform/x86/wmi.c diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 383e47c392a..2834846a185 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "../base.h" #include "pnpacpi.h" diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h deleted file mode 100644 index 0c1ed387073..00000000000 --- a/include/acpi/acdisasm.h +++ /dev/null @@ -1,445 +0,0 @@ -/****************************************************************************** - * - * Name: acdisasm.h - AML disassembler - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2008, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#ifndef __ACDISASM_H__ -#define __ACDISASM_H__ - -#include "amlresrc.h" - -#define BLOCK_NONE 0 -#define BLOCK_PAREN 1 -#define BLOCK_BRACE 2 -#define BLOCK_COMMA_LIST 4 -#define ACPI_DEFAULT_RESNAME *(u32 *) "__RD" - -struct acpi_external_list { - char *path; - char *internal_path; - struct acpi_external_list *next; - u32 value; - u16 length; - u8 type; -}; - -extern struct acpi_external_list *acpi_gbl_external_list; - -typedef const struct acpi_dmtable_info { - u8 opcode; - u8 offset; - char *name; - -} acpi_dmtable_info; - -/* - * Values for Opcode above. - * Note: 0-7 must not change, used as a flag shift value - */ -#define ACPI_DMT_FLAG0 0 -#define ACPI_DMT_FLAG1 1 -#define ACPI_DMT_FLAG2 2 -#define ACPI_DMT_FLAG3 3 -#define ACPI_DMT_FLAG4 4 -#define ACPI_DMT_FLAG5 5 -#define ACPI_DMT_FLAG6 6 -#define ACPI_DMT_FLAG7 7 -#define ACPI_DMT_FLAGS0 8 -#define ACPI_DMT_FLAGS2 9 -#define ACPI_DMT_UINT8 10 -#define ACPI_DMT_UINT16 11 -#define ACPI_DMT_UINT24 12 -#define ACPI_DMT_UINT32 13 -#define ACPI_DMT_UINT56 14 -#define ACPI_DMT_UINT64 15 -#define ACPI_DMT_STRING 16 -#define ACPI_DMT_NAME4 17 -#define ACPI_DMT_NAME6 18 -#define ACPI_DMT_NAME8 19 -#define ACPI_DMT_CHKSUM 20 -#define ACPI_DMT_SPACEID 21 -#define ACPI_DMT_GAS 22 -#define ACPI_DMT_ASF 23 -#define ACPI_DMT_DMAR 24 -#define ACPI_DMT_HEST 25 -#define ACPI_DMT_HESTNTFY 26 -#define ACPI_DMT_HESTNTYP 27 -#define ACPI_DMT_MADT 28 -#define ACPI_DMT_SRAT 29 -#define ACPI_DMT_EXIT 30 -#define ACPI_DMT_SIG 31 - -typedef -void (*acpi_dmtable_handler) (struct acpi_table_header * table); - -struct acpi_dmtable_data { - char *signature; - struct acpi_dmtable_info *table_info; - acpi_dmtable_handler table_handler; - char *name; -}; - -struct acpi_op_walk_info { - u32 level; - u32 last_level; - u32 count; - u32 bit_offset; - u32 flags; - struct acpi_walk_state *walk_state; -}; - -typedef -acpi_status(*asl_walk_callback) (union acpi_parse_object * op, - u32 level, void *context); - -struct acpi_resource_tag { - u32 bit_index; - char *tag; -}; - -/* Strings used for decoding flags to ASL keywords */ - -extern const char *acpi_gbl_word_decode[]; -extern const char *acpi_gbl_irq_decode[]; -extern const char *acpi_gbl_lock_rule[]; -extern const char *acpi_gbl_access_types[]; -extern const char *acpi_gbl_update_rules[]; -extern const char *acpi_gbl_match_ops[]; - -extern struct acpi_dmtable_info acpi_dm_table_info_asf0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf1a[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf2a[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf3[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf4[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf_hdr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_boot[]; -extern struct acpi_dmtable_info acpi_dm_table_info_bert[]; -extern struct acpi_dmtable_info acpi_dm_table_info_cpep[]; -extern struct acpi_dmtable_info acpi_dm_table_info_cpep0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dbgp[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; -extern struct acpi_dmtable_info acpi_dm_table_info_einj[]; -extern struct acpi_dmtable_info acpi_dm_table_info_einj0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_erst[]; -extern struct acpi_dmtable_info acpi_dm_table_info_facs[]; -extern struct acpi_dmtable_info acpi_dm_table_info_fadt1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_fadt2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_gas[]; -extern struct acpi_dmtable_info acpi_dm_table_info_header[]; -extern struct acpi_dmtable_info acpi_dm_table_info_hest[]; -extern struct acpi_dmtable_info acpi_dm_table_info_hest9[]; -extern struct acpi_dmtable_info acpi_dm_table_info_hest_notify[]; -extern struct acpi_dmtable_info acpi_dm_table_info_hpet[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt3[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt4[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt5[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt6[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt7[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt8[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt9[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt10[]; -extern struct acpi_dmtable_info acpi_dm_table_info_madt_hdr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_mcfg[]; -extern struct acpi_dmtable_info acpi_dm_table_info_mcfg0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_rsdp1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_rsdp2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_sbst[]; -extern struct acpi_dmtable_info acpi_dm_table_info_slic[]; -extern struct acpi_dmtable_info acpi_dm_table_info_slit[]; -extern struct acpi_dmtable_info acpi_dm_table_info_spcr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_spmi[]; -extern struct acpi_dmtable_info acpi_dm_table_info_srat[]; -extern struct acpi_dmtable_info acpi_dm_table_info_srat_hdr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_srat0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_srat1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_srat2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_tcpa[]; -extern struct acpi_dmtable_info acpi_dm_table_info_wdrt[]; - -/* - * dmtable - */ -void acpi_dm_dump_data_table(struct acpi_table_header *table); - -acpi_status -acpi_dm_dump_table(u32 table_length, - u32 table_offset, - void *table, - u32 sub_table_length, struct acpi_dmtable_info *info); - -void acpi_dm_line_header(u32 offset, u32 byte_length, char *name); - -void acpi_dm_line_header2(u32 offset, u32 byte_length, char *name, u32 value); - -/* - * dmtbdump - */ -void acpi_dm_dump_asf(struct acpi_table_header *table); - -void acpi_dm_dump_cpep(struct acpi_table_header *table); - -void acpi_dm_dump_dmar(struct acpi_table_header *table); - -void acpi_dm_dump_einj(struct acpi_table_header *table); - -void acpi_dm_dump_erst(struct acpi_table_header *table); - -void acpi_dm_dump_fadt(struct acpi_table_header *table); - -void acpi_dm_dump_hest(struct acpi_table_header *table); - -void acpi_dm_dump_mcfg(struct acpi_table_header *table); - -void acpi_dm_dump_madt(struct acpi_table_header *table); - -u32 acpi_dm_dump_rsdp(struct acpi_table_header *table); - -void acpi_dm_dump_rsdt(struct acpi_table_header *table); - -void acpi_dm_dump_slit(struct acpi_table_header *table); - -void acpi_dm_dump_srat(struct acpi_table_header *table); - -void acpi_dm_dump_xsdt(struct acpi_table_header *table); - -/* - * dmwalk - */ -void -acpi_dm_disassemble(struct acpi_walk_state *walk_state, - union acpi_parse_object *origin, u32 num_opcodes); - -void -acpi_dm_walk_parse_tree(union acpi_parse_object *op, - asl_walk_callback descending_callback, - asl_walk_callback ascending_callback, void *context); - -/* - * dmopcode - */ -void -acpi_dm_disassemble_one_op(struct acpi_walk_state *walk_state, - struct acpi_op_walk_info *info, - union acpi_parse_object *op); - -void acpi_dm_decode_internal_object(union acpi_operand_object *obj_desc); - -u32 acpi_dm_list_type(union acpi_parse_object *op); - -void acpi_dm_method_flags(union acpi_parse_object *op); - -void acpi_dm_field_flags(union acpi_parse_object *op); - -void acpi_dm_address_space(u8 space_id); - -void acpi_dm_region_flags(union acpi_parse_object *op); - -void acpi_dm_match_op(union acpi_parse_object *op); - -u8 acpi_dm_comma_if_list_member(union acpi_parse_object *op); - -void acpi_dm_comma_if_field_member(union acpi_parse_object *op); - -/* - * dmnames - */ -u32 acpi_dm_dump_name(char *name); - -acpi_status -acpi_ps_display_object_pathname(struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -void acpi_dm_namestring(char *name); - -/* - * dmobject - */ -void -acpi_dm_display_internal_object(union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - -void acpi_dm_display_arguments(struct acpi_walk_state *walk_state); - -void acpi_dm_display_locals(struct acpi_walk_state *walk_state); - -void -acpi_dm_dump_method_info(acpi_status status, - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -/* - * dmbuffer - */ -void acpi_dm_disasm_byte_list(u32 level, u8 * byte_data, u32 byte_count); - -void -acpi_dm_byte_list(struct acpi_op_walk_info *info, union acpi_parse_object *op); - -void acpi_dm_is_eisa_id(union acpi_parse_object *op); - -void acpi_dm_eisa_id(u32 encoded_id); - -u8 acpi_dm_is_unicode_buffer(union acpi_parse_object *op); - -u8 acpi_dm_is_string_buffer(union acpi_parse_object *op); - -/* - * dmresrc - */ -void acpi_dm_dump_integer8(u8 value, char *name); - -void acpi_dm_dump_integer16(u16 value, char *name); - -void acpi_dm_dump_integer32(u32 value, char *name); - -void acpi_dm_dump_integer64(u64 value, char *name); - -void -acpi_dm_resource_template(struct acpi_op_walk_info *info, - union acpi_parse_object *op, - u8 * byte_data, u32 byte_count); - -acpi_status acpi_dm_is_resource_template(union acpi_parse_object *op); - -void acpi_dm_indent(u32 level); - -void acpi_dm_bit_list(u16 mask); - -void acpi_dm_decode_attribute(u8 attribute); - -void acpi_dm_descriptor_name(void); - -/* - * dmresrcl - */ -void -acpi_dm_word_descriptor(union aml_resource *resource, u32 length, u32 level); - -void -acpi_dm_dword_descriptor(union aml_resource *resource, u32 length, u32 level); - -void -acpi_dm_extended_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_qword_descriptor(union aml_resource *resource, u32 length, u32 level); - -void -acpi_dm_memory24_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_memory32_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_fixed_memory32_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_generic_register_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_interrupt_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_vendor_large_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void acpi_dm_vendor_common(char *name, u8 * byte_data, u32 length, u32 level); - -/* - * dmresrcs - */ -void -acpi_dm_irq_descriptor(union aml_resource *resource, u32 length, u32 level); - -void -acpi_dm_dma_descriptor(union aml_resource *resource, u32 length, u32 level); - -void acpi_dm_io_descriptor(union aml_resource *resource, u32 length, u32 level); - -void -acpi_dm_fixed_io_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_start_dependent_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_end_dependent_descriptor(union aml_resource *resource, - u32 length, u32 level); - -void -acpi_dm_vendor_small_descriptor(union aml_resource *resource, - u32 length, u32 level); - -/* - * dmutils - */ -void acpi_dm_add_to_external_list(char *path, u8 type, u32 value); - -/* - * dmrestag - */ -void acpi_dm_find_resources(union acpi_parse_object *root); - -void -acpi_dm_check_resource_reference(union acpi_parse_object *op, - struct acpi_walk_state *walk_state); - -#endif /* __ACDISASM_H__ */ diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 84f5cb24286..eda04546cdf 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -153,8 +153,9 @@ #define AE_AML_CIRCULAR_REFERENCE (acpi_status) (0x001E | AE_CODE_AML) #define AE_AML_BAD_RESOURCE_LENGTH (acpi_status) (0x001F | AE_CODE_AML) #define AE_AML_ILLEGAL_ADDRESS (acpi_status) (0x0020 | AE_CODE_AML) +#define AE_AML_INFINITE_LOOP (acpi_status) (0x0021 | AE_CODE_AML) -#define AE_CODE_AML_MAX 0x0020 +#define AE_CODE_AML_MAX 0x0021 /* * Internal exceptions used for control @@ -175,6 +176,8 @@ #define AE_CODE_CTRL_MAX 0x000D +/* Exception strings for acpi_format_exception */ + #ifdef DEFINE_ACPI_GLOBALS /* @@ -267,6 +270,7 @@ char const *acpi_gbl_exception_names_aml[] = { "AE_AML_CIRCULAR_REFERENCE", "AE_AML_BAD_RESOURCE_LENGTH", "AE_AML_ILLEGAL_ADDRESS", + "AE_AML_INFINITE_LOOP" }; char const *acpi_gbl_exception_names_ctrl[] = { diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index db8852d8bcf..5c823d5ab78 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -45,9 +45,9 @@ #define __ACOUTPUT_H__ /* - * Debug levels and component IDs. These are used to control the - * granularity of the output of the DEBUG_PRINT macro -- on a per- - * component basis and a per-exception-type basis. + * Debug levels and component IDs. These are used to control the + * granularity of the output of the ACPI_DEBUG_PRINT macro -- on a + * per-component basis and a per-exception-type basis. */ /* Component IDs are used in the global "DebugLayer" */ @@ -69,8 +69,10 @@ #define ACPI_COMPILER 0x00001000 #define ACPI_TOOLS 0x00002000 +#define ACPI_EXAMPLE 0x00004000 +#define ACPI_DRIVER 0x00008000 -#define ACPI_ALL_COMPONENTS 0x00003FFF +#define ACPI_ALL_COMPONENTS 0x0000FFFF #define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS) /* Component IDs reserved for ACPI drivers */ @@ -78,7 +80,7 @@ #define ACPI_ALL_DRIVERS 0xFFFF0000 /* - * Raw debug output levels, do not use these in the DEBUG_PRINT macros + * Raw debug output levels, do not use these in the ACPI_DEBUG_PRINT macros */ #define ACPI_LV_INIT 0x00000001 #define ACPI_LV_DEBUG_OBJECT 0x00000002 @@ -176,4 +178,95 @@ #define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT) #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) +#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) +/* + * Module name is included in both debug and non-debug versions primarily for + * error messages. The __FILE__ macro is not very useful for this, because it + * often includes the entire pathname to the module + */ +#define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name; +#else +#define ACPI_MODULE_NAME(name) +#endif + +/* + * Ascii error messages can be configured out + */ +#ifndef ACPI_NO_ERROR_MESSAGES +#define AE_INFO _acpi_module_name, __LINE__ + +/* + * Error reporting. Callers module and line number are inserted by AE_INFO, + * the plist contains a set of parens to allow variable-length lists. + * These macros are used for both the debug and non-debug versions of the code. + */ +#define ACPI_INFO(plist) acpi_info plist +#define ACPI_WARNING(plist) acpi_warning plist +#define ACPI_EXCEPTION(plist) acpi_exception plist +#define ACPI_ERROR(plist) acpi_error plist + +#else + +/* No error messages */ + +#define ACPI_INFO(plist) +#define ACPI_WARNING(plist) +#define ACPI_EXCEPTION(plist) +#define ACPI_ERROR(plist) + +#endif /* ACPI_NO_ERROR_MESSAGES */ + +/* + * Debug macros that are conditionally compiled + */ +#ifdef ACPI_DEBUG_OUTPUT + +/* + * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header, + * define it now. This is the case where there the compiler does not support + * a __FUNCTION__ macro or equivalent. + */ +#ifndef ACPI_GET_FUNCTION_NAME +#define ACPI_GET_FUNCTION_NAME _acpi_function_name + +/* + * The Name parameter should be the procedure name as a quoted string. + * The function name is also used by the function exit macros below. + * Note: (const char) is used to be compatible with the debug interfaces + * and macros such as __FUNCTION__. + */ +#define ACPI_FUNCTION_NAME(name) static const char _acpi_function_name[] = #name; + +#else +/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */ + +#define ACPI_FUNCTION_NAME(name) +#endif /* ACPI_GET_FUNCTION_NAME */ + +/* + * Common parameters used for debug output functions: + * line number, function name, module(file) name, component ID + */ +#define ACPI_DEBUG_PARAMETERS __LINE__, ACPI_GET_FUNCTION_NAME, _acpi_module_name, _COMPONENT + +/* + * Master debug print macros + * Print message if and only if: + * 1) Debug print for the current component is enabled + * 2) Debug error level or trace level for the print statement is enabled + */ +#define ACPI_DEBUG_PRINT(plist) acpi_debug_print plist +#define ACPI_DEBUG_PRINT_RAW(plist) acpi_debug_print_raw plist + +#else +/* + * This is the non-debug case -- make everything go away, + * leaving no executable debug code! + */ +#define ACPI_FUNCTION_NAME(a) +#define ACPI_DEBUG_PRINT(pl) +#define ACPI_DEBUG_PRINT_RAW(pl) + +#endif /* ACPI_DEBUG_OUTPUT */ + #endif /* __ACOUTPUT_H__ */ diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index c515ef6cc89..472b7bf0c5d 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Name: acpi.h - Master include file, Publics and external data. + * Name: acpi.h - Master public include file used to interface to ACPICA * *****************************************************************************/ @@ -45,25 +45,22 @@ #define __ACPI_H__ /* - * Common includes for all ACPI driver files - * We put them here because we don't want to duplicate them - * in the rest of the source code again and again. + * Public include files for use by code that will interface to ACPICA. + * + * Information includes the ACPICA data types, names, exceptions, and + * external interface prototypes. Also included are the definitions for + * all ACPI tables (FADT, MADT, etc.) + * + * Note: The order of these include files is important. */ -#include "acnames.h" /* Global ACPI names and strings */ -#include "acconfig.h" /* Configuration constants */ -#include "platform/acenv.h" /* Target environment specific items */ -#include "actypes.h" /* Fundamental common data types */ -#include "acexcep.h" /* ACPI exception codes */ -#include "acmacros.h" /* C macros */ +#include "platform/acenv.h" /* Environment-specific items */ +#include "acnames.h" /* Common ACPI names and strings */ +#include "actypes.h" /* ACPICA data types and structures */ +#include "acexcep.h" /* ACPICA exceptions */ #include "actbl.h" /* ACPI table definitions */ -#include "aclocal.h" /* Internal data types */ #include "acoutput.h" /* Error output and Debug macros */ -#include "acpiosxf.h" /* Interfaces to the ACPI-to-OS layer */ +#include "acrestyp.h" /* Resource Descriptor structs */ +#include "acpiosxf.h" /* OSL interfaces (ACPICA-to-OS) */ #include "acpixf.h" /* ACPI core subsystem external interfaces */ -#include "acobject.h" /* ACPI internal object */ -#include "acstruct.h" /* Common structures */ -#include "acglobal.h" /* All global variables */ -#include "achware.h" /* Hardware defines and interfaces */ -#include "acutils.h" /* Utility interfaces */ #endif /* __ACPI_H__ */ diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index b91440ac0d1..a62720a7edc 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -121,8 +121,11 @@ acpi_os_wait_semaphore(acpi_semaphore handle, u32 units, u16 timeout); acpi_status acpi_os_signal_semaphore(acpi_semaphore handle, u32 units); /* - * Mutex primitives + * Mutex primitives. May be configured to use semaphores instead via + * ACPI_MUTEX_TYPE (see platform/acenv.h) */ +#if (ACPI_MUTEX_TYPE != ACPI_BINARY_SEMAPHORE) + acpi_status acpi_os_create_mutex(acpi_mutex * out_handle); void acpi_os_delete_mutex(acpi_mutex handle); @@ -130,13 +133,7 @@ void acpi_os_delete_mutex(acpi_mutex handle); acpi_status acpi_os_acquire_mutex(acpi_mutex handle, u16 timeout); void acpi_os_release_mutex(acpi_mutex handle); - -/* Temporary macros for Mutex* interfaces, map to existing semaphore xfaces */ - -#define acpi_os_create_mutex(out_handle) acpi_os_create_semaphore (1, 1, out_handle) -#define acpi_os_delete_mutex(handle) (void) acpi_os_delete_semaphore (handle) -#define acpi_os_acquire_mutex(handle,time) acpi_os_wait_semaphore (handle, 1, time) -#define acpi_os_release_mutex(handle) (void) acpi_os_signal_semaphore (handle, 1) +#endif /* * Memory allocation and mapping diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 33bc0e3b195..c8e8cf45830 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -45,9 +45,32 @@ #ifndef __ACXFACE_H__ #define __ACXFACE_H__ +/* Current ACPICA subsystem version in YYYYMMDD format */ + +#define ACPI_CA_VERSION 0x20081204 + #include "actypes.h" #include "actbl.h" +extern u8 acpi_gbl_permanent_mmap; + +/* + * Globals that are publically available, allowing for + * run time configuration + */ +extern u32 acpi_dbg_level; +extern u32 acpi_dbg_layer; +extern u8 acpi_gbl_enable_interpreter_slack; +extern u8 acpi_gbl_all_methods_serialized; +extern u8 acpi_gbl_create_osi_method; +extern u8 acpi_gbl_leave_wake_gpes_disabled; +extern acpi_name acpi_gbl_trace_method_name; +extern u32 acpi_gbl_trace_flags; + +extern u32 acpi_current_gpe_count; +extern struct acpi_table_fadt acpi_gbl_FADT; + +extern u32 acpi_rsdt_forced; /* * Global interfaces */ @@ -79,11 +102,6 @@ const char *acpi_format_exception(acpi_status exception); acpi_status acpi_purge_cached_objects(void); -#ifdef ACPI_FUTURE_USAGE -acpi_status -acpi_install_initialization_handler(acpi_init_handler handler, u32 function); -#endif - /* * ACPI Memory management */ @@ -193,8 +211,11 @@ acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type); acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle); /* - * Event handler interfaces + * Handler interfaces */ +acpi_status +acpi_install_initialization_handler(acpi_init_handler handler, u32 function); + acpi_status acpi_install_fixed_event_handler(u32 acpi_event, acpi_event_handler handler, void *context); @@ -227,6 +248,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, u32 gpe_number, u32 type, acpi_event_handler address, void *context); +acpi_status +acpi_remove_gpe_handler(acpi_handle gpe_device, + u32 gpe_number, acpi_event_handler address); + #ifdef ACPI_FUTURE_USAGE acpi_status acpi_install_exception_handler(acpi_exception_handler handler); #endif @@ -238,10 +263,6 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle); acpi_status acpi_release_global_lock(u32 handle); -acpi_status -acpi_remove_gpe_handler(acpi_handle gpe_device, - u32 gpe_number, acpi_event_handler address); - acpi_status acpi_enable_event(u32 event, u32 flags); acpi_status acpi_disable_event(u32 event, u32 flags); @@ -250,6 +271,9 @@ acpi_status acpi_clear_event(u32 event); acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); +/* + * GPE Interfaces + */ acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type); acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); @@ -263,6 +287,12 @@ acpi_get_gpe_status(acpi_handle gpe_device, u32 gpe_number, u32 flags, acpi_event_status * event_status); +acpi_status acpi_disable_all_gpes(void); + +acpi_status acpi_enable_all_runtime_gpes(void); + +acpi_status acpi_get_gpe_device(u32 gpe_index, acpi_handle *gpe_device); + acpi_status acpi_install_gpe_block(acpi_handle gpe_device, struct acpi_generic_address *gpe_block_address, @@ -313,6 +343,8 @@ acpi_resource_to_address64(struct acpi_resource *resource, /* * Hardware (ACPI device) interfaces */ +acpi_status acpi_reset(void); + acpi_status acpi_get_register(u32 register_id, u32 * return_value); acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value); @@ -320,12 +352,14 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value); acpi_status acpi_set_register(u32 register_id, u32 value); acpi_status -acpi_set_firmware_waking_vector(acpi_physical_address physical_address); +acpi_set_firmware_waking_vector(u32 physical_address); -#ifdef ACPI_FUTURE_USAGE acpi_status -acpi_get_firmware_waking_vector(acpi_physical_address * physical_address); -#endif +acpi_set_firmware_waking_vector64(u64 physical_address); + +acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg); + +acpi_status acpi_write(u32 value, struct acpi_generic_address *reg); acpi_status acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); @@ -340,4 +374,42 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); acpi_status acpi_leave_sleep_state(u8 sleep_state); +/* + * Debug output + */ +void ACPI_INTERNAL_VAR_XFACE +acpi_error(const char *module_name, + u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); + +void ACPI_INTERNAL_VAR_XFACE +acpi_exception(const char *module_name, + u32 line_number, + acpi_status status, const char *format, ...) ACPI_PRINTF_LIKE(4); + +void ACPI_INTERNAL_VAR_XFACE +acpi_warning(const char *module_name, + u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); + +void ACPI_INTERNAL_VAR_XFACE +acpi_info(const char *module_name, + u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); + +#ifdef ACPI_DEBUG_OUTPUT + +void ACPI_INTERNAL_VAR_XFACE +acpi_debug_print(u32 requested_debug_level, + u32 line_number, + const char *function_name, + const char *module_name, + u32 component_id, const char *format, ...) ACPI_PRINTF_LIKE(6); + +void ACPI_INTERNAL_VAR_XFACE +acpi_debug_print_raw(u32 requested_debug_level, + u32 line_number, + const char *function_name, + const char *module_name, + u32 component_id, + const char *format, ...) ACPI_PRINTF_LIKE(6); +#endif + #endif /* __ACXFACE_H__ */ diff --git a/include/acpi/acrestyp.h b/include/acpi/acrestyp.h new file mode 100644 index 00000000000..9ffe00feada --- /dev/null +++ b/include/acpi/acrestyp.h @@ -0,0 +1,405 @@ +/****************************************************************************** + * + * Name: acrestyp.h - Defines, types, and structures for resource descriptors + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef __ACRESTYP_H__ +#define __ACRESTYP_H__ + +/* + * Definitions for Resource Attributes + */ +typedef u16 acpi_rs_length; /* Resource Length field is fixed at 16 bits */ +typedef u32 acpi_rsdesc_size; /* Max Resource Descriptor size is (Length+3) = (64_k-1)+3 */ + +/* + * Memory Attributes + */ +#define ACPI_READ_ONLY_MEMORY (u8) 0x00 +#define ACPI_READ_WRITE_MEMORY (u8) 0x01 + +#define ACPI_NON_CACHEABLE_MEMORY (u8) 0x00 +#define ACPI_CACHABLE_MEMORY (u8) 0x01 +#define ACPI_WRITE_COMBINING_MEMORY (u8) 0x02 +#define ACPI_PREFETCHABLE_MEMORY (u8) 0x03 + +/* + * IO Attributes + * The ISA IO ranges are: n000-n0_fFh, n400-n4_fFh, n800-n8_fFh, n_c00-n_cFFh. + * The non-ISA IO ranges are: n100-n3_fFh, n500-n7_fFh, n900-n_bFFh, n_cd0-n_fFFh. + */ +#define ACPI_NON_ISA_ONLY_RANGES (u8) 0x01 +#define ACPI_ISA_ONLY_RANGES (u8) 0x02 +#define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES) + +/* Type of translation - 1=Sparse, 0=Dense */ + +#define ACPI_SPARSE_TRANSLATION (u8) 0x01 + +/* + * IO Port Descriptor Decode + */ +#define ACPI_DECODE_10 (u8) 0x00 /* 10-bit IO address decode */ +#define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */ + +/* + * IRQ Attributes + */ +#define ACPI_LEVEL_SENSITIVE (u8) 0x00 +#define ACPI_EDGE_SENSITIVE (u8) 0x01 + +#define ACPI_ACTIVE_HIGH (u8) 0x00 +#define ACPI_ACTIVE_LOW (u8) 0x01 + +#define ACPI_EXCLUSIVE (u8) 0x00 +#define ACPI_SHARED (u8) 0x01 + +/* + * DMA Attributes + */ +#define ACPI_COMPATIBILITY (u8) 0x00 +#define ACPI_TYPE_A (u8) 0x01 +#define ACPI_TYPE_B (u8) 0x02 +#define ACPI_TYPE_F (u8) 0x03 + +#define ACPI_NOT_BUS_MASTER (u8) 0x00 +#define ACPI_BUS_MASTER (u8) 0x01 + +#define ACPI_TRANSFER_8 (u8) 0x00 +#define ACPI_TRANSFER_8_16 (u8) 0x01 +#define ACPI_TRANSFER_16 (u8) 0x02 + +/* + * Start Dependent Functions Priority definitions + */ +#define ACPI_GOOD_CONFIGURATION (u8) 0x00 +#define ACPI_ACCEPTABLE_CONFIGURATION (u8) 0x01 +#define ACPI_SUB_OPTIMAL_CONFIGURATION (u8) 0x02 + +/* + * 16, 32 and 64-bit Address Descriptor resource types + */ +#define ACPI_MEMORY_RANGE (u8) 0x00 +#define ACPI_IO_RANGE (u8) 0x01 +#define ACPI_BUS_NUMBER_RANGE (u8) 0x02 + +#define ACPI_ADDRESS_NOT_FIXED (u8) 0x00 +#define ACPI_ADDRESS_FIXED (u8) 0x01 + +#define ACPI_POS_DECODE (u8) 0x00 +#define ACPI_SUB_DECODE (u8) 0x01 + +#define ACPI_PRODUCER (u8) 0x00 +#define ACPI_CONSUMER (u8) 0x01 + +/* + * If possible, pack the following structures to byte alignment + */ +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#pragma pack(1) +#endif + +/* UUID data structures for use in vendor-defined resource descriptors */ + +struct acpi_uuid { + u8 data[ACPI_UUID_LENGTH]; +}; + +struct acpi_vendor_uuid { + u8 subtype; + u8 data[ACPI_UUID_LENGTH]; +}; + +/* + * Structures used to describe device resources + */ +struct acpi_resource_irq { + u8 descriptor_length; + u8 triggering; + u8 polarity; + u8 sharable; + u8 interrupt_count; + u8 interrupts[1]; +}; + +struct acpi_resource_dma { + u8 type; + u8 bus_master; + u8 transfer; + u8 channel_count; + u8 channels[1]; +}; + +struct acpi_resource_start_dependent { + u8 descriptor_length; + u8 compatibility_priority; + u8 performance_robustness; +}; + +/* + * The END_DEPENDENT_FUNCTIONS_RESOURCE struct is not + * needed because it has no fields + */ + +struct acpi_resource_io { + u8 io_decode; + u8 alignment; + u8 address_length; + u16 minimum; + u16 maximum; +}; + +struct acpi_resource_fixed_io { + u16 address; + u8 address_length; +}; + +struct acpi_resource_vendor { + u16 byte_length; + u8 byte_data[1]; +}; + +/* Vendor resource with UUID info (introduced in ACPI 3.0) */ + +struct acpi_resource_vendor_typed { + u16 byte_length; + u8 uuid_subtype; + u8 uuid[ACPI_UUID_LENGTH]; + u8 byte_data[1]; +}; + +struct acpi_resource_end_tag { + u8 checksum; +}; + +struct acpi_resource_memory24 { + u8 write_protect; + u16 minimum; + u16 maximum; + u16 alignment; + u16 address_length; +}; + +struct acpi_resource_memory32 { + u8 write_protect; + u32 minimum; + u32 maximum; + u32 alignment; + u32 address_length; +}; + +struct acpi_resource_fixed_memory32 { + u8 write_protect; + u32 address; + u32 address_length; +}; + +struct acpi_memory_attribute { + u8 write_protect; + u8 caching; + u8 range_type; + u8 translation; +}; + +struct acpi_io_attribute { + u8 range_type; + u8 translation; + u8 translation_type; + u8 reserved1; +}; + +union acpi_resource_attribute { + struct acpi_memory_attribute mem; + struct acpi_io_attribute io; + + /* Used for the *word_space macros */ + + u8 type_specific; +}; + +struct acpi_resource_source { + u8 index; + u16 string_length; + char *string_ptr; +}; + +/* Fields common to all address descriptors, 16/32/64 bit */ + +#define ACPI_RESOURCE_ADDRESS_COMMON \ + u8 resource_type; \ + u8 producer_consumer; \ + u8 decode; \ + u8 min_address_fixed; \ + u8 max_address_fixed; \ + union acpi_resource_attribute info; + +struct acpi_resource_address { +ACPI_RESOURCE_ADDRESS_COMMON}; + +struct acpi_resource_address16 { + ACPI_RESOURCE_ADDRESS_COMMON u16 granularity; + u16 minimum; + u16 maximum; + u16 translation_offset; + u16 address_length; + struct acpi_resource_source resource_source; +}; + +struct acpi_resource_address32 { + ACPI_RESOURCE_ADDRESS_COMMON u32 granularity; + u32 minimum; + u32 maximum; + u32 translation_offset; + u32 address_length; + struct acpi_resource_source resource_source; +}; + +struct acpi_resource_address64 { + ACPI_RESOURCE_ADDRESS_COMMON u64 granularity; + u64 minimum; + u64 maximum; + u64 translation_offset; + u64 address_length; + struct acpi_resource_source resource_source; +}; + +struct acpi_resource_extended_address64 { + ACPI_RESOURCE_ADDRESS_COMMON u8 revision_iD; + u64 granularity; + u64 minimum; + u64 maximum; + u64 translation_offset; + u64 address_length; + u64 type_specific; +}; + +struct acpi_resource_extended_irq { + u8 producer_consumer; + u8 triggering; + u8 polarity; + u8 sharable; + u8 interrupt_count; + struct acpi_resource_source resource_source; + u32 interrupts[1]; +}; + +struct acpi_resource_generic_register { + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 access_size; + u64 address; +}; + +/* ACPI_RESOURCE_TYPEs */ + +#define ACPI_RESOURCE_TYPE_IRQ 0 +#define ACPI_RESOURCE_TYPE_DMA 1 +#define ACPI_RESOURCE_TYPE_START_DEPENDENT 2 +#define ACPI_RESOURCE_TYPE_END_DEPENDENT 3 +#define ACPI_RESOURCE_TYPE_IO 4 +#define ACPI_RESOURCE_TYPE_FIXED_IO 5 +#define ACPI_RESOURCE_TYPE_VENDOR 6 +#define ACPI_RESOURCE_TYPE_END_TAG 7 +#define ACPI_RESOURCE_TYPE_MEMORY24 8 +#define ACPI_RESOURCE_TYPE_MEMORY32 9 +#define ACPI_RESOURCE_TYPE_FIXED_MEMORY32 10 +#define ACPI_RESOURCE_TYPE_ADDRESS16 11 +#define ACPI_RESOURCE_TYPE_ADDRESS32 12 +#define ACPI_RESOURCE_TYPE_ADDRESS64 13 +#define ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 14 /* ACPI 3.0 */ +#define ACPI_RESOURCE_TYPE_EXTENDED_IRQ 15 +#define ACPI_RESOURCE_TYPE_GENERIC_REGISTER 16 +#define ACPI_RESOURCE_TYPE_MAX 16 + +/* Master union for resource descriptors */ + +union acpi_resource_data { + struct acpi_resource_irq irq; + struct acpi_resource_dma dma; + struct acpi_resource_start_dependent start_dpf; + struct acpi_resource_io io; + struct acpi_resource_fixed_io fixed_io; + struct acpi_resource_vendor vendor; + struct acpi_resource_vendor_typed vendor_typed; + struct acpi_resource_end_tag end_tag; + struct acpi_resource_memory24 memory24; + struct acpi_resource_memory32 memory32; + struct acpi_resource_fixed_memory32 fixed_memory32; + struct acpi_resource_address16 address16; + struct acpi_resource_address32 address32; + struct acpi_resource_address64 address64; + struct acpi_resource_extended_address64 ext_address64; + struct acpi_resource_extended_irq extended_irq; + struct acpi_resource_generic_register generic_reg; + + /* Common fields */ + + struct acpi_resource_address address; /* Common 16/32/64 address fields */ +}; + +/* Common resource header */ + +struct acpi_resource { + u32 type; + u32 length; + union acpi_resource_data data; +}; + +/* restore default alignment */ + +#pragma pack() + +#define ACPI_RS_SIZE_NO_DATA 8 /* Id + Length fields */ +#define ACPI_RS_SIZE_MIN (u32) ACPI_ROUND_UP_TO_NATIVE_WORD (12) +#define ACPI_RS_SIZE(type) (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type)) + +#define ACPI_NEXT_RESOURCE(res) (struct acpi_resource *)((u8 *) res + res->length) + +struct acpi_pci_routing_table { + u32 length; + u32 pin; + acpi_integer address; /* here for 64-bit alignment */ + u32 source_index; + char source[4]; /* pad to 64 bits so sizeof() works in all cases */ +}; + +#endif /* __ACRESTYP_H__ */ diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 13a3d9ad92d..813e4b6c2c0 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -288,6 +288,31 @@ enum acpi_prefered_pm_profiles { #define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) +union acpi_name_union { + u32 integer; + char ascii[4]; +}; + +/* + * Internal ACPI Table Descriptor. One per ACPI table + */ +struct acpi_table_desc { + acpi_physical_address address; + struct acpi_table_header *pointer; + u32 length; /* Length fixed at 32 bits */ + union acpi_name_union signature; + acpi_owner_id owner_id; + u8 flags; +}; + +/* Flags for above */ + +#define ACPI_TABLE_ORIGIN_UNKNOWN (0) +#define ACPI_TABLE_ORIGIN_MAPPED (1) +#define ACPI_TABLE_ORIGIN_ALLOCATED (2) +#define ACPI_TABLE_ORIGIN_MASK (3) +#define ACPI_TABLE_IS_LOADED (4) + /* * Get the remaining ACPI tables */ diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 63f5b4cf4de..18963b96811 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -627,7 +627,7 @@ struct acpi_hest_aer_common { u32 uncorrectable_error_mask; u32 uncorrectable_error_severity; u32 correctable_error_mask; - u32 advanced_error_cababilities; + u32 advanced_error_capabilities; }; /* Hardware Error Notification */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 8222e8de0d1..a20aab51017 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -204,11 +204,10 @@ typedef u32 acpi_physical_address; /******************************************************************************* * - * OS-dependent and compiler-dependent types + * OS-dependent types * * If the defaults below are not appropriate for the host system, they can - * be defined in the compiler-specific or OS-specific header, and this will - * take precedence. + * be defined in the OS-specific header, and this will take precedence. * ******************************************************************************/ @@ -218,12 +217,6 @@ typedef u32 acpi_physical_address; #define acpi_thread_id acpi_size #endif -/* Object returned from acpi_os_create_lock */ - -#ifndef acpi_spinlock -#define acpi_spinlock void * -#endif - /* Flags for acpi_os_acquire_lock/acpi_os_release_lock */ #ifndef acpi_cpu_flags @@ -233,9 +226,51 @@ typedef u32 acpi_physical_address; /* Object returned from acpi_os_create_cache */ #ifndef acpi_cache_t +#ifdef ACPI_USE_LOCAL_CACHE #define acpi_cache_t struct acpi_memory_list +#else +#define acpi_cache_t void * +#endif +#endif + +/* + * Synchronization objects - Mutexes, Semaphores, and spin_locks + */ +#if (ACPI_MUTEX_TYPE == ACPI_BINARY_SEMAPHORE) +/* + * These macros are used if the host OS does not support a mutex object. + * Map the OSL Mutex interfaces to binary semaphores. + */ +#define acpi_mutex acpi_semaphore +#define acpi_os_create_mutex(out_handle) acpi_os_create_semaphore (1, 1, out_handle) +#define acpi_os_delete_mutex(handle) (void) acpi_os_delete_semaphore (handle) +#define acpi_os_acquire_mutex(handle,time) acpi_os_wait_semaphore (handle, 1, time) +#define acpi_os_release_mutex(handle) (void) acpi_os_signal_semaphore (handle, 1) +#endif + +/* Configurable types for synchronization objects */ + +#ifndef acpi_spinlock +#define acpi_spinlock void * +#endif + +#ifndef acpi_semaphore +#define acpi_semaphore void * +#endif + +#ifndef acpi_mutex +#define acpi_mutex void * #endif +/******************************************************************************* + * + * Compiler-dependent types + * + * If the defaults below are not appropriate for the host compiler, they can + * be defined in the compiler-specific header, and this will take precedence. + * + ******************************************************************************/ + /* Use C99 uintptr_t for pointer casting if available, "void *" otherwise */ #ifndef acpi_uintptr_t @@ -268,6 +303,43 @@ typedef u32 acpi_physical_address; #define ACPI_EXPORT_SYMBOL(symbol) #endif +/****************************************************************************** + * + * ACPI Specification constants (Do not change unless the specification changes) + * + *****************************************************************************/ + +/* Number of distinct FADT-based GPE register blocks (GPE0 and GPE1) */ + +#define ACPI_MAX_GPE_BLOCKS 2 + +/* Default ACPI register widths */ + +#define ACPI_GPE_REGISTER_WIDTH 8 +#define ACPI_PM1_REGISTER_WIDTH 16 +#define ACPI_PM2_REGISTER_WIDTH 8 +#define ACPI_PM_TIMER_WIDTH 32 + +/* Names within the namespace are 4 bytes long */ + +#define ACPI_NAME_SIZE 4 +#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */ +#define ACPI_PATH_SEPARATOR '.' + +/* Sizes for ACPI table headers */ + +#define ACPI_OEM_ID_SIZE 6 +#define ACPI_OEM_TABLE_ID_SIZE 8 + +/* ACPI/PNP hardware IDs */ + +#define PCI_ROOT_HID_STRING "PNP0A03" +#define PCI_EXPRESS_ROOT_HID_STRING "PNP0A08" + +/* PM Timer ticks per second (HZ) */ + +#define PM_TIMER_FREQUENCY 3579545 + /******************************************************************************* * * Independent types @@ -291,13 +363,18 @@ typedef u32 acpi_physical_address; #endif /* - * Mescellaneous types + * Miscellaneous types */ typedef u32 acpi_status; /* All ACPI Exceptions */ typedef u32 acpi_name; /* 4-byte ACPI name */ typedef char *acpi_string; /* Null terminated ASCII string */ typedef void *acpi_handle; /* Actually a ptr to a NS Node */ +/* Owner IDs are used to track namespace nodes for selective deletion */ + +typedef u8 acpi_owner_id; +#define ACPI_OWNER_ID_MAX 0xFF + struct uint64_struct { u32 lo; u32 hi; @@ -313,13 +390,8 @@ struct uint32_struct { u32 hi; }; -/* Synchronization objects */ - -#define acpi_mutex void * -#define acpi_semaphore void * - /* - * Acpi integer width. In ACPI version 1, integers are 32 bits. In ACPI + * Acpi integer width. In ACPI version 1, integers are 32 bits. In ACPI * version 2, integers are 64 bits. Note that this pertains to the ACPI integer * type only, not other integers used in the implementation of the ACPI CA * subsystem. @@ -338,10 +410,75 @@ typedef unsigned long long acpi_integer; #define ACPI_MAX16_DECIMAL_DIGITS 5 #define ACPI_MAX8_DECIMAL_DIGITS 3 +/* PM Timer ticks per second (HZ) */ + +#define PM_TIMER_FREQUENCY 3579545 + /* * Constants with special meanings */ #define ACPI_ROOT_OBJECT ACPI_ADD_PTR (acpi_handle, NULL, ACPI_MAX_PTR) +#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */ +#define ACPI_DO_NOT_WAIT 0 + +/******************************************************************************* + * + * Commonly used macros + * + ******************************************************************************/ + +/* Data manipulation */ + +#define ACPI_LOWORD(l) ((u16)(u32)(l)) +#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) +#define ACPI_LOBYTE(l) ((u8)(u16)(l)) +#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) + +/* Full 64-bit integer must be available on both 32-bit and 64-bit platforms */ + +struct acpi_integer_overlay { + u32 lo_dword; + u32 hi_dword; +}; + +#define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword) +#define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword) + +#define ACPI_SET_BIT(target,bit) ((target) |= (bit)) +#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) +#define ACPI_MIN(a,b) (((a)<(b))?(a):(b)) +#define ACPI_MAX(a,b) (((a)>(b))?(a):(b)) + +/* Size calculation */ + +#define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) + +/* Pointer manipulation */ + +#define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p)) +#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p)) +#define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_size)(b))) +#define ACPI_PTR_DIFF(a, b) (acpi_size) (ACPI_CAST_PTR (u8, (a)) - ACPI_CAST_PTR (u8, (b))) + +/* Pointer/Integer type conversions */ + +#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL,(acpi_size) i) +#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p, (void *) NULL) +#define ACPI_OFFSET(d, f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f), (void *) NULL) +#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) +#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) + +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b))) +#else +#define ACPI_COMPARE_NAME(a,b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE)) +#endif + +/******************************************************************************* + * + * Miscellaneous constants + * + ******************************************************************************/ /* * Initialization sequence @@ -414,7 +551,7 @@ typedef unsigned long long acpi_integer; #define ACPI_NOTIFY_MAX 0x0B /* - * Types associated with ACPI names and objects. The first group of + * Types associated with ACPI names and objects. The first group of * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition * of the ACPI object_type() operator (See the ACPI Spec). Therefore, * only add to the first group if the spec changes. @@ -731,6 +868,15 @@ struct acpi_buffer { #define ACPI_SINGLE_NAME 1 #define ACPI_NAME_TYPE_MAX 1 +/* + * Predefined Namespace items + */ +struct acpi_predefined_names { + char *name; + u8 type; + char *val; +}; + /* * Structure and flags for acpi_get_system_info */ @@ -787,7 +933,7 @@ acpi_status(*acpi_exception_handler) (acpi_status aml_status, u16 opcode, u32 aml_offset, void *context); -/* Table Event handler (Load, load_table etc) and types */ +/* Table Event handler (Load, load_table, etc.) and types */ typedef acpi_status(*acpi_tbl_handler) (u32 event, void *table, void *context); @@ -823,6 +969,12 @@ acpi_status(*acpi_walk_callback) (acpi_handle obj_handle, #define ACPI_INTERRUPT_NOT_HANDLED 0x00 #define ACPI_INTERRUPT_HANDLED 0x01 +/* Length of _HID, _UID, _CID, and UUID values */ + +#define ACPI_DEVICE_ID_LENGTH 0x09 +#define ACPI_MAX_CID_LENGTH 48 +#define ACPI_UUID_LENGTH 16 + /* Common string version of device HIDs and UIDs */ struct acpica_device_id { @@ -900,357 +1052,28 @@ struct acpi_mem_space_context { }; /* - * Definitions for Resource Attributes - */ -typedef u16 acpi_rs_length; /* Resource Length field is fixed at 16 bits */ -typedef u32 acpi_rsdesc_size; /* Max Resource Descriptor size is (Length+3) = (64_k-1)+3 */ - -/* - * Memory Attributes - */ -#define ACPI_READ_ONLY_MEMORY (u8) 0x00 -#define ACPI_READ_WRITE_MEMORY (u8) 0x01 - -#define ACPI_NON_CACHEABLE_MEMORY (u8) 0x00 -#define ACPI_CACHABLE_MEMORY (u8) 0x01 -#define ACPI_WRITE_COMBINING_MEMORY (u8) 0x02 -#define ACPI_PREFETCHABLE_MEMORY (u8) 0x03 - -/* - * IO Attributes - * The ISA IO ranges are: n000-n0_fFh, n400-n4_fFh, n800-n8_fFh, n_c00-n_cFFh. - * The non-ISA IO ranges are: n100-n3_fFh, n500-n7_fFh, n900-n_bFFh, n_cd0-n_fFFh. + * struct acpi_memory_list is used only if the ACPICA local cache is enabled */ -#define ACPI_NON_ISA_ONLY_RANGES (u8) 0x01 -#define ACPI_ISA_ONLY_RANGES (u8) 0x02 -#define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES) - -/* Type of translation - 1=Sparse, 0=Dense */ - -#define ACPI_SPARSE_TRANSLATION (u8) 0x01 - -/* - * IO Port Descriptor Decode - */ -#define ACPI_DECODE_10 (u8) 0x00 /* 10-bit IO address decode */ -#define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */ - -/* - * IRQ Attributes - */ -#define ACPI_LEVEL_SENSITIVE (u8) 0x00 -#define ACPI_EDGE_SENSITIVE (u8) 0x01 - -#define ACPI_ACTIVE_HIGH (u8) 0x00 -#define ACPI_ACTIVE_LOW (u8) 0x01 - -#define ACPI_EXCLUSIVE (u8) 0x00 -#define ACPI_SHARED (u8) 0x01 - -/* - * DMA Attributes - */ -#define ACPI_COMPATIBILITY (u8) 0x00 -#define ACPI_TYPE_A (u8) 0x01 -#define ACPI_TYPE_B (u8) 0x02 -#define ACPI_TYPE_F (u8) 0x03 - -#define ACPI_NOT_BUS_MASTER (u8) 0x00 -#define ACPI_BUS_MASTER (u8) 0x01 - -#define ACPI_TRANSFER_8 (u8) 0x00 -#define ACPI_TRANSFER_8_16 (u8) 0x01 -#define ACPI_TRANSFER_16 (u8) 0x02 - -/* - * Start Dependent Functions Priority definitions - */ -#define ACPI_GOOD_CONFIGURATION (u8) 0x00 -#define ACPI_ACCEPTABLE_CONFIGURATION (u8) 0x01 -#define ACPI_SUB_OPTIMAL_CONFIGURATION (u8) 0x02 - -/* - * 16, 32 and 64-bit Address Descriptor resource types - */ -#define ACPI_MEMORY_RANGE (u8) 0x00 -#define ACPI_IO_RANGE (u8) 0x01 -#define ACPI_BUS_NUMBER_RANGE (u8) 0x02 - -#define ACPI_ADDRESS_NOT_FIXED (u8) 0x00 -#define ACPI_ADDRESS_FIXED (u8) 0x01 - -#define ACPI_POS_DECODE (u8) 0x00 -#define ACPI_SUB_DECODE (u8) 0x01 - -#define ACPI_PRODUCER (u8) 0x00 -#define ACPI_CONSUMER (u8) 0x01 - -/* - * If possible, pack the following structures to byte alignment - */ -#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED -#pragma pack(1) +struct acpi_memory_list { + char *list_name; + void *list_head; + u16 object_size; + u16 max_depth; + u16 current_depth; + u16 link_offset; + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + + /* Statistics for debug memory tracking only */ + + u32 total_allocated; + u32 total_freed; + u32 max_occupied; + u32 total_size; + u32 current_total_size; + u32 requests; + u32 hits; #endif - -/* UUID data structures for use in vendor-defined resource descriptors */ - -struct acpi_uuid { - u8 data[ACPI_UUID_LENGTH]; -}; - -struct acpi_vendor_uuid { - u8 subtype; - u8 data[ACPI_UUID_LENGTH]; -}; - -/* - * Structures used to describe device resources - */ -struct acpi_resource_irq { - u8 descriptor_length; - u8 triggering; - u8 polarity; - u8 sharable; - u8 interrupt_count; - u8 interrupts[1]; -}; - -struct acpi_resource_dma { - u8 type; - u8 bus_master; - u8 transfer; - u8 channel_count; - u8 channels[1]; -}; - -struct acpi_resource_start_dependent { - u8 descriptor_length; - u8 compatibility_priority; - u8 performance_robustness; -}; - -/* - * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not - * needed because it has no fields - */ - -struct acpi_resource_io { - u8 io_decode; - u8 alignment; - u8 address_length; - u16 minimum; - u16 maximum; -}; - -struct acpi_resource_fixed_io { - u16 address; - u8 address_length; -}; - -struct acpi_resource_vendor { - u16 byte_length; - u8 byte_data[1]; -}; - -/* Vendor resource with UUID info (introduced in ACPI 3.0) */ - -struct acpi_resource_vendor_typed { - u16 byte_length; - u8 uuid_subtype; - u8 uuid[ACPI_UUID_LENGTH]; - u8 byte_data[1]; -}; - -struct acpi_resource_end_tag { - u8 checksum; -}; - -struct acpi_resource_memory24 { - u8 write_protect; - u16 minimum; - u16 maximum; - u16 alignment; - u16 address_length; -}; - -struct acpi_resource_memory32 { - u8 write_protect; - u32 minimum; - u32 maximum; - u32 alignment; - u32 address_length; -}; - -struct acpi_resource_fixed_memory32 { - u8 write_protect; - u32 address; - u32 address_length; -}; - -struct acpi_memory_attribute { - u8 write_protect; - u8 caching; - u8 range_type; - u8 translation; -}; - -struct acpi_io_attribute { - u8 range_type; - u8 translation; - u8 translation_type; - u8 reserved1; -}; - -union acpi_resource_attribute { - struct acpi_memory_attribute mem; - struct acpi_io_attribute io; - - /* Used for the *word_space macros */ - - u8 type_specific; -}; - -struct acpi_resource_source { - u8 index; - u16 string_length; - char *string_ptr; -}; - -/* Fields common to all address descriptors, 16/32/64 bit */ - -#define ACPI_RESOURCE_ADDRESS_COMMON \ - u8 resource_type; \ - u8 producer_consumer; \ - u8 decode; \ - u8 min_address_fixed; \ - u8 max_address_fixed; \ - union acpi_resource_attribute info; - -struct acpi_resource_address { -ACPI_RESOURCE_ADDRESS_COMMON}; - -struct acpi_resource_address16 { - ACPI_RESOURCE_ADDRESS_COMMON u16 granularity; - u16 minimum; - u16 maximum; - u16 translation_offset; - u16 address_length; - struct acpi_resource_source resource_source; -}; - -struct acpi_resource_address32 { - ACPI_RESOURCE_ADDRESS_COMMON u32 granularity; - u32 minimum; - u32 maximum; - u32 translation_offset; - u32 address_length; - struct acpi_resource_source resource_source; -}; - -struct acpi_resource_address64 { - ACPI_RESOURCE_ADDRESS_COMMON u64 granularity; - u64 minimum; - u64 maximum; - u64 translation_offset; - u64 address_length; - struct acpi_resource_source resource_source; -}; - -struct acpi_resource_extended_address64 { - ACPI_RESOURCE_ADDRESS_COMMON u8 revision_iD; - u64 granularity; - u64 minimum; - u64 maximum; - u64 translation_offset; - u64 address_length; - u64 type_specific; -}; - -struct acpi_resource_extended_irq { - u8 producer_consumer; - u8 triggering; - u8 polarity; - u8 sharable; - u8 interrupt_count; - struct acpi_resource_source resource_source; - u32 interrupts[1]; -}; - -struct acpi_resource_generic_register { - u8 space_id; - u8 bit_width; - u8 bit_offset; - u8 access_size; - u64 address; -}; - -/* ACPI_RESOURCE_TYPEs */ - -#define ACPI_RESOURCE_TYPE_IRQ 0 -#define ACPI_RESOURCE_TYPE_DMA 1 -#define ACPI_RESOURCE_TYPE_START_DEPENDENT 2 -#define ACPI_RESOURCE_TYPE_END_DEPENDENT 3 -#define ACPI_RESOURCE_TYPE_IO 4 -#define ACPI_RESOURCE_TYPE_FIXED_IO 5 -#define ACPI_RESOURCE_TYPE_VENDOR 6 -#define ACPI_RESOURCE_TYPE_END_TAG 7 -#define ACPI_RESOURCE_TYPE_MEMORY24 8 -#define ACPI_RESOURCE_TYPE_MEMORY32 9 -#define ACPI_RESOURCE_TYPE_FIXED_MEMORY32 10 -#define ACPI_RESOURCE_TYPE_ADDRESS16 11 -#define ACPI_RESOURCE_TYPE_ADDRESS32 12 -#define ACPI_RESOURCE_TYPE_ADDRESS64 13 -#define ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 14 /* ACPI 3.0 */ -#define ACPI_RESOURCE_TYPE_EXTENDED_IRQ 15 -#define ACPI_RESOURCE_TYPE_GENERIC_REGISTER 16 -#define ACPI_RESOURCE_TYPE_MAX 16 - -union acpi_resource_data { - struct acpi_resource_irq irq; - struct acpi_resource_dma dma; - struct acpi_resource_start_dependent start_dpf; - struct acpi_resource_io io; - struct acpi_resource_fixed_io fixed_io; - struct acpi_resource_vendor vendor; - struct acpi_resource_vendor_typed vendor_typed; - struct acpi_resource_end_tag end_tag; - struct acpi_resource_memory24 memory24; - struct acpi_resource_memory32 memory32; - struct acpi_resource_fixed_memory32 fixed_memory32; - struct acpi_resource_address16 address16; - struct acpi_resource_address32 address32; - struct acpi_resource_address64 address64; - struct acpi_resource_extended_address64 ext_address64; - struct acpi_resource_extended_irq extended_irq; - struct acpi_resource_generic_register generic_reg; - - /* Common fields */ - - struct acpi_resource_address address; /* Common 16/32/64 address fields */ -}; - -struct acpi_resource { - u32 type; - u32 length; - union acpi_resource_data data; -}; - -/* restore default alignment */ - -#pragma pack() - -#define ACPI_RS_SIZE_NO_DATA 8 /* Id + Length fields */ -#define ACPI_RS_SIZE_MIN (u32) ACPI_ROUND_UP_TO_NATIVE_WORD (12) -#define ACPI_RS_SIZE(type) (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type)) - -#define ACPI_NEXT_RESOURCE(res) (struct acpi_resource *)((u8 *) res + res->length) - -struct acpi_pci_routing_table { - u32 length; - u32 pin; - acpi_integer address; /* here for 64-bit alignment */ - u32 source_index; - char source[4]; /* pad to 64 bits so sizeof() works in all cases */ }; #endif /* __ACTYPES_H__ */ diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index fcd2572e428..e62f10d9a7d 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -44,14 +44,26 @@ #ifndef __ACENV_H__ #define __ACENV_H__ -/* +/* Types for ACPI_MUTEX_TYPE */ + +#define ACPI_BINARY_SEMAPHORE 0 +#define ACPI_OSL_MUTEX 1 + +/* Types for DEBUGGER_THREADING */ + +#define DEBUGGER_SINGLE_THREADED 0 +#define DEBUGGER_MULTI_THREADED 1 + +/****************************************************************************** + * * Configuration for ACPI tools and utilities - */ + * + *****************************************************************************/ #ifdef ACPI_LIBRARY /* * Note: The non-debug version of the acpi_library does not contain any - * debug support, for minimimal size. The debug version uses ACPI_FULL_DEBUG + * debug support, for minimal size. The debug version uses ACPI_FULL_DEBUG */ #define ACPI_USE_LOCAL_CACHE #endif @@ -75,17 +87,6 @@ #define ACPI_DBG_TRACK_ALLOCATIONS #endif -#ifdef ACPI_DASM_APP -#ifndef MSDOS -#define ACPI_DEBUG_OUTPUT -#endif -#define ACPI_APPLICATION -#define ACPI_DISASSEMBLER -#define ACPI_NO_METHOD_EXECUTION -#define ACPI_LARGE_NAMESPACE_NODE -#define ACPI_DATA_TABLE_DISASSEMBLY -#endif - #ifdef ACPI_APPLICATION #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_LOCAL_CACHE @@ -179,6 +180,19 @@ /*! [End] no source code translation !*/ +/****************************************************************************** + * + * Miscellaneous configuration + * + *****************************************************************************/ + +/* + * Are mutexes supported by the host? default is no, use binary semaphores. + */ +#ifndef ACPI_MUTEX_TYPE +#define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE +#endif + /* * Debugger threading model * Use single threaded if the entire subsystem is contained in an application @@ -187,9 +201,6 @@ * By default the model is single threaded if ACPI_APPLICATION is set, * multi-threaded if ACPI_APPLICATION is not set. */ -#define DEBUGGER_SINGLE_THREADED 0 -#define DEBUGGER_MULTI_THREADED 1 - #ifndef DEBUGGER_THREADING #ifdef ACPI_APPLICATION #define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 0515e754449..6d49b2a498c 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -46,6 +46,7 @@ #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_DO_WHILE_0 +#define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE #ifdef __KERNEL__ @@ -70,9 +71,6 @@ #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); #define strtoul simple_strtoul -/* Full namespace pathname length limit - arbitrary */ -#define ACPI_PATHNAME_MAX 256 - #else /* !__KERNEL__ */ #include diff --git a/include/linux/acpi.h b/include/linux/acpi.h index fba8051fb29..6fce2fc2d12 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -131,22 +131,6 @@ extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity); */ void acpi_unregister_gsi (u32 gsi); -struct acpi_prt_entry { - struct list_head node; - struct acpi_pci_id id; - u8 pin; - struct { - acpi_handle handle; - u32 index; - } link; - u32 irq; -}; - -struct acpi_prt_list { - int count; - struct list_head entries; -}; - struct pci_dev; int acpi_pci_irq_enable (struct pci_dev *dev); @@ -270,6 +254,7 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, #ifdef CONFIG_PM_SLEEP void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); +void __init acpi_s4_no_nvs(void); #endif /* CONFIG_PM_SLEEP */ #else /* CONFIG_ACPI */ diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index f7cc204fab0..20998746518 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -223,7 +223,6 @@ struct hotplug_params { #ifdef CONFIG_ACPI #include #include -#include extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, struct hotplug_params *hpp); int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 2ce8207686e..2b409c44db8 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -232,6 +232,11 @@ extern unsigned long get_safe_page(gfp_t gfp_mask); extern void hibernation_set_ops(struct platform_hibernation_ops *ops); extern int hibernate(void); +extern int hibernate_nvs_register(unsigned long start, unsigned long size); +extern int hibernate_nvs_alloc(void); +extern void hibernate_nvs_free(void); +extern void hibernate_nvs_save(void); +extern void hibernate_nvs_restore(void); #else /* CONFIG_HIBERNATION */ static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } static inline void swsusp_set_page_free(struct page *p) {} @@ -239,6 +244,14 @@ static inline void swsusp_unset_page_free(struct page *p) {} static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {} static inline int hibernate(void) { return -ENOSYS; } +static inline int hibernate_nvs_register(unsigned long a, unsigned long b) +{ + return 0; +} +static inline int hibernate_nvs_alloc(void) { return 0; } +static inline void hibernate_nvs_free(void) {} +static inline void hibernate_nvs_save(void) {} +static inline void hibernate_nvs_restore(void) {} #endif /* CONFIG_HIBERNATION */ #ifdef CONFIG_PM_SLEEP diff --git a/kernel/power/disk.c b/kernel/power/disk.c index f77d3819ef5..45e8541ab7e 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -258,12 +258,12 @@ int hibernation_snapshot(int platform_mode) { int error; - /* Free memory before shutting down devices. */ - error = swsusp_shrink_memory(); + error = platform_begin(platform_mode); if (error) return error; - error = platform_begin(platform_mode); + /* Free memory before shutting down devices. */ + error = swsusp_shrink_memory(); if (error) goto Close; diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 5d2ab836e99..f5fc2d7680f 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -192,12 +193,6 @@ static void *chain_alloc(struct chain_allocator *ca, unsigned int size) return ret; } -static void chain_free(struct chain_allocator *ca, int clear_page_nosave) -{ - free_list_of_pages(ca->chain, clear_page_nosave); - memset(ca, 0, sizeof(struct chain_allocator)); -} - /** * Data types related to memory bitmaps. * @@ -233,7 +228,7 @@ static void chain_free(struct chain_allocator *ca, int clear_page_nosave) #define BM_BITS_PER_BLOCK (PAGE_SIZE << 3) struct bm_block { - struct bm_block *next; /* next element of the list */ + struct list_head hook; /* hook into a list of bitmap blocks */ unsigned long start_pfn; /* pfn represented by the first bit */ unsigned long end_pfn; /* pfn represented by the last bit plus 1 */ unsigned long *data; /* bitmap representing pages */ @@ -244,24 +239,15 @@ static inline unsigned long bm_block_bits(struct bm_block *bb) return bb->end_pfn - bb->start_pfn; } -struct zone_bitmap { - struct zone_bitmap *next; /* next element of the list */ - unsigned long start_pfn; /* minimal pfn in this zone */ - unsigned long end_pfn; /* maximal pfn in this zone plus 1 */ - struct bm_block *bm_blocks; /* list of bitmap blocks */ - struct bm_block *cur_block; /* recently used bitmap block */ -}; - /* strcut bm_position is used for browsing memory bitmaps */ struct bm_position { - struct zone_bitmap *zone_bm; struct bm_block *block; int bit; }; struct memory_bitmap { - struct zone_bitmap *zone_bm_list; /* list of zone bitmaps */ + struct list_head blocks; /* list of bitmap blocks */ struct linked_page *p_list; /* list of pages used to store zone * bitmap objects and bitmap block * objects @@ -273,11 +259,7 @@ struct memory_bitmap { static void memory_bm_position_reset(struct memory_bitmap *bm) { - struct zone_bitmap *zone_bm; - - zone_bm = bm->zone_bm_list; - bm->cur.zone_bm = zone_bm; - bm->cur.block = zone_bm->bm_blocks; + bm->cur.block = list_entry(bm->blocks.next, struct bm_block, hook); bm->cur.bit = 0; } @@ -285,151 +267,184 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free); /** * create_bm_block_list - create a list of block bitmap objects + * @nr_blocks - number of blocks to allocate + * @list - list to put the allocated blocks into + * @ca - chain allocator to be used for allocating memory */ - -static inline struct bm_block * -create_bm_block_list(unsigned int nr_blocks, struct chain_allocator *ca) +static int create_bm_block_list(unsigned long pages, + struct list_head *list, + struct chain_allocator *ca) { - struct bm_block *bblist = NULL; + unsigned int nr_blocks = DIV_ROUND_UP(pages, BM_BITS_PER_BLOCK); while (nr_blocks-- > 0) { struct bm_block *bb; bb = chain_alloc(ca, sizeof(struct bm_block)); if (!bb) - return NULL; - - bb->next = bblist; - bblist = bb; + return -ENOMEM; + list_add(&bb->hook, list); } - return bblist; + + return 0; } +struct mem_extent { + struct list_head hook; + unsigned long start; + unsigned long end; +}; + /** - * create_zone_bm_list - create a list of zone bitmap objects + * free_mem_extents - free a list of memory extents + * @list - list of extents to empty */ +static void free_mem_extents(struct list_head *list) +{ + struct mem_extent *ext, *aux; -static inline struct zone_bitmap * -create_zone_bm_list(unsigned int nr_zones, struct chain_allocator *ca) + list_for_each_entry_safe(ext, aux, list, hook) { + list_del(&ext->hook); + kfree(ext); + } +} + +/** + * create_mem_extents - create a list of memory extents representing + * contiguous ranges of PFNs + * @list - list to put the extents into + * @gfp_mask - mask to use for memory allocations + */ +static int create_mem_extents(struct list_head *list, gfp_t gfp_mask) { - struct zone_bitmap *zbmlist = NULL; + struct zone *zone; - while (nr_zones-- > 0) { - struct zone_bitmap *zbm; + INIT_LIST_HEAD(list); - zbm = chain_alloc(ca, sizeof(struct zone_bitmap)); - if (!zbm) - return NULL; + for_each_zone(zone) { + unsigned long zone_start, zone_end; + struct mem_extent *ext, *cur, *aux; + + if (!populated_zone(zone)) + continue; - zbm->next = zbmlist; - zbmlist = zbm; + zone_start = zone->zone_start_pfn; + zone_end = zone->zone_start_pfn + zone->spanned_pages; + + list_for_each_entry(ext, list, hook) + if (zone_start <= ext->end) + break; + + if (&ext->hook == list || zone_end < ext->start) { + /* New extent is necessary */ + struct mem_extent *new_ext; + + new_ext = kzalloc(sizeof(struct mem_extent), gfp_mask); + if (!new_ext) { + free_mem_extents(list); + return -ENOMEM; + } + new_ext->start = zone_start; + new_ext->end = zone_end; + list_add_tail(&new_ext->hook, &ext->hook); + continue; + } + + /* Merge this zone's range of PFNs with the existing one */ + if (zone_start < ext->start) + ext->start = zone_start; + if (zone_end > ext->end) + ext->end = zone_end; + + /* More merging may be possible */ + cur = ext; + list_for_each_entry_safe_continue(cur, aux, list, hook) { + if (zone_end < cur->start) + break; + if (zone_end < cur->end) + ext->end = cur->end; + list_del(&cur->hook); + kfree(cur); + } } - return zbmlist; + + return 0; } /** * memory_bm_create - allocate memory for a memory bitmap */ - static int memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask, int safe_needed) { struct chain_allocator ca; - struct zone *zone; - struct zone_bitmap *zone_bm; - struct bm_block *bb; - unsigned int nr; + struct list_head mem_extents; + struct mem_extent *ext; + int error; chain_init(&ca, gfp_mask, safe_needed); + INIT_LIST_HEAD(&bm->blocks); - /* Compute the number of zones */ - nr = 0; - for_each_zone(zone) - if (populated_zone(zone)) - nr++; - - /* Allocate the list of zones bitmap objects */ - zone_bm = create_zone_bm_list(nr, &ca); - bm->zone_bm_list = zone_bm; - if (!zone_bm) { - chain_free(&ca, PG_UNSAFE_CLEAR); - return -ENOMEM; - } - - /* Initialize the zone bitmap objects */ - for_each_zone(zone) { - unsigned long pfn; + error = create_mem_extents(&mem_extents, gfp_mask); + if (error) + return error; - if (!populated_zone(zone)) - continue; + list_for_each_entry(ext, &mem_extents, hook) { + struct bm_block *bb; + unsigned long pfn = ext->start; + unsigned long pages = ext->end - ext->start; - zone_bm->start_pfn = zone->zone_start_pfn; - zone_bm->end_pfn = zone->zone_start_pfn + zone->spanned_pages; - /* Allocate the list of bitmap block objects */ - nr = DIV_ROUND_UP(zone->spanned_pages, BM_BITS_PER_BLOCK); - bb = create_bm_block_list(nr, &ca); - zone_bm->bm_blocks = bb; - zone_bm->cur_block = bb; - if (!bb) - goto Free; + bb = list_entry(bm->blocks.prev, struct bm_block, hook); - nr = zone->spanned_pages; - pfn = zone->zone_start_pfn; - /* Initialize the bitmap block objects */ - while (bb) { - unsigned long *ptr; + error = create_bm_block_list(pages, bm->blocks.prev, &ca); + if (error) + goto Error; - ptr = get_image_page(gfp_mask, safe_needed); - bb->data = ptr; - if (!ptr) - goto Free; + list_for_each_entry_continue(bb, &bm->blocks, hook) { + bb->data = get_image_page(gfp_mask, safe_needed); + if (!bb->data) { + error = -ENOMEM; + goto Error; + } bb->start_pfn = pfn; - if (nr >= BM_BITS_PER_BLOCK) { + if (pages >= BM_BITS_PER_BLOCK) { pfn += BM_BITS_PER_BLOCK; - nr -= BM_BITS_PER_BLOCK; + pages -= BM_BITS_PER_BLOCK; } else { /* This is executed only once in the loop */ - pfn += nr; + pfn += pages; } bb->end_pfn = pfn; - bb = bb->next; } - zone_bm = zone_bm->next; } + bm->p_list = ca.chain; memory_bm_position_reset(bm); - return 0; + Exit: + free_mem_extents(&mem_extents); + return error; - Free: + Error: bm->p_list = ca.chain; memory_bm_free(bm, PG_UNSAFE_CLEAR); - return -ENOMEM; + goto Exit; } /** * memory_bm_free - free memory occupied by the memory bitmap @bm */ - static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free) { - struct zone_bitmap *zone_bm; + struct bm_block *bb; - /* Free the list of bit blocks for each zone_bitmap object */ - zone_bm = bm->zone_bm_list; - while (zone_bm) { - struct bm_block *bb; + list_for_each_entry(bb, &bm->blocks, hook) + if (bb->data) + free_image_page(bb->data, clear_nosave_free); - bb = zone_bm->bm_blocks; - while (bb) { - if (bb->data) - free_image_page(bb->data, clear_nosave_free); - bb = bb->next; - } - zone_bm = zone_bm->next; - } free_list_of_pages(bm->p_list, clear_nosave_free); - bm->zone_bm_list = NULL; + + INIT_LIST_HEAD(&bm->blocks); } /** @@ -437,38 +452,33 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free) * to given pfn. The cur_zone_bm member of @bm and the cur_block member * of @bm->cur_zone_bm are updated. */ - static int memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, void **addr, unsigned int *bit_nr) { - struct zone_bitmap *zone_bm; struct bm_block *bb; - /* Check if the pfn is from the current zone */ - zone_bm = bm->cur.zone_bm; - if (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) { - zone_bm = bm->zone_bm_list; - /* We don't assume that the zones are sorted by pfns */ - while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) { - zone_bm = zone_bm->next; - - if (!zone_bm) - return -EFAULT; - } - bm->cur.zone_bm = zone_bm; - } - /* Check if the pfn corresponds to the current bitmap block */ - bb = zone_bm->cur_block; + /* + * Check if the pfn corresponds to the current bitmap block and find + * the block where it fits if this is not the case. + */ + bb = bm->cur.block; if (pfn < bb->start_pfn) - bb = zone_bm->bm_blocks; + list_for_each_entry_continue_reverse(bb, &bm->blocks, hook) + if (pfn >= bb->start_pfn) + break; - while (pfn >= bb->end_pfn) { - bb = bb->next; + if (pfn >= bb->end_pfn) + list_for_each_entry_continue(bb, &bm->blocks, hook) + if (pfn >= bb->start_pfn && pfn < bb->end_pfn) + break; - BUG_ON(!bb); - } - zone_bm->cur_block = bb; + if (&bb->hook == &bm->blocks) + return -EFAULT; + + /* The block has been found */ + bm->cur.block = bb; pfn -= bb->start_pfn; + bm->cur.bit = pfn + 1; *bit_nr = pfn; *addr = bb->data; return 0; @@ -519,6 +529,14 @@ static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn) return test_bit(bit, addr); } +static bool memory_bm_pfn_present(struct memory_bitmap *bm, unsigned long pfn) +{ + void *addr; + unsigned int bit; + + return !memory_bm_find_bit(bm, pfn, &addr, &bit); +} + /** * memory_bm_next_pfn - find the pfn that corresponds to the next set bit * in the bitmap @bm. If the pfn cannot be found, BM_END_OF_MAP is @@ -530,29 +548,21 @@ static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn) static unsigned long memory_bm_next_pfn(struct memory_bitmap *bm) { - struct zone_bitmap *zone_bm; struct bm_block *bb; int bit; + bb = bm->cur.block; do { - bb = bm->cur.block; - do { - bit = bm->cur.bit; - bit = find_next_bit(bb->data, bm_block_bits(bb), bit); - if (bit < bm_block_bits(bb)) - goto Return_pfn; - - bb = bb->next; - bm->cur.block = bb; - bm->cur.bit = 0; - } while (bb); - zone_bm = bm->cur.zone_bm->next; - if (zone_bm) { - bm->cur.zone_bm = zone_bm; - bm->cur.block = zone_bm->bm_blocks; - bm->cur.bit = 0; - } - } while (zone_bm); + bit = bm->cur.bit; + bit = find_next_bit(bb->data, bm_block_bits(bb), bit); + if (bit < bm_block_bits(bb)) + goto Return_pfn; + + bb = list_entry(bb->hook.next, struct bm_block, hook); + bm->cur.block = bb; + bm->cur.bit = 0; + } while (&bb->hook != &bm->blocks); + memory_bm_position_reset(bm); return BM_END_OF_MAP; @@ -808,8 +818,7 @@ static unsigned int count_free_highmem_pages(void) * We should save the page if it isn't Nosave or NosaveFree, or Reserved, * and it isn't a part of a free chunk of pages. */ - -static struct page *saveable_highmem_page(unsigned long pfn) +static struct page *saveable_highmem_page(struct zone *zone, unsigned long pfn) { struct page *page; @@ -817,6 +826,8 @@ static struct page *saveable_highmem_page(unsigned long pfn) return NULL; page = pfn_to_page(pfn); + if (page_zone(page) != zone) + return NULL; BUG_ON(!PageHighMem(page)); @@ -846,13 +857,16 @@ unsigned int count_highmem_pages(void) mark_free_pages(zone); max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (saveable_highmem_page(pfn)) + if (saveable_highmem_page(zone, pfn)) n++; } return n; } #else -static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } +static inline void *saveable_highmem_page(struct zone *z, unsigned long p) +{ + return NULL; +} #endif /* CONFIG_HIGHMEM */ /** @@ -863,8 +877,7 @@ static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } * of pages statically defined as 'unsaveable', and it isn't a part of * a free chunk of pages. */ - -static struct page *saveable_page(unsigned long pfn) +static struct page *saveable_page(struct zone *zone, unsigned long pfn) { struct page *page; @@ -872,6 +885,8 @@ static struct page *saveable_page(unsigned long pfn) return NULL; page = pfn_to_page(pfn); + if (page_zone(page) != zone) + return NULL; BUG_ON(PageHighMem(page)); @@ -903,7 +918,7 @@ unsigned int count_data_pages(void) mark_free_pages(zone); max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if(saveable_page(pfn)) + if (saveable_page(zone, pfn)) n++; } return n; @@ -944,7 +959,7 @@ static inline struct page * page_is_saveable(struct zone *zone, unsigned long pfn) { return is_highmem(zone) ? - saveable_highmem_page(pfn) : saveable_page(pfn); + saveable_highmem_page(zone, pfn) : saveable_page(zone, pfn); } static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) @@ -966,7 +981,7 @@ static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) * data modified by kmap_atomic() */ safe_copy_page(buffer, s_page); - dst = kmap_atomic(pfn_to_page(dst_pfn), KM_USER0); + dst = kmap_atomic(d_page, KM_USER0); memcpy(dst, buffer, PAGE_SIZE); kunmap_atomic(dst, KM_USER0); } else { @@ -975,7 +990,7 @@ static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) } } #else -#define page_is_saveable(zone, pfn) saveable_page(pfn) +#define page_is_saveable(zone, pfn) saveable_page(zone, pfn) static inline void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) { @@ -1459,9 +1474,7 @@ load_header(struct swsusp_info *info) * unpack_orig_pfns - for each element of @buf[] (1 page at a time) set * the corresponding bit in the memory bitmap @bm */ - -static inline void -unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm) +static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm) { int j; @@ -1469,8 +1482,13 @@ unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm) if (unlikely(buf[j] == BM_END_OF_MAP)) break; - memory_bm_set_bit(bm, buf[j]); + if (memory_bm_pfn_present(bm, buf[j])) + memory_bm_set_bit(bm, buf[j]); + else + return -EFAULT; } + + return 0; } /* List of "safe" pages that may be used to store data loaded from the suspend @@ -1608,7 +1626,7 @@ get_highmem_page_buffer(struct page *page, struct chain_allocator *ca) pbe = chain_alloc(ca, sizeof(struct highmem_pbe)); if (!pbe) { swsusp_free(); - return NULL; + return ERR_PTR(-ENOMEM); } pbe->orig_page = page; if (safe_highmem_pages > 0) { @@ -1677,7 +1695,7 @@ prepare_highmem_image(struct memory_bitmap *bm, unsigned int *nr_highmem_p) static inline void * get_highmem_page_buffer(struct page *page, struct chain_allocator *ca) { - return NULL; + return ERR_PTR(-EINVAL); } static inline void copy_last_highmem_page(void) {} @@ -1788,8 +1806,13 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca) { struct pbe *pbe; - struct page *page = pfn_to_page(memory_bm_next_pfn(bm)); + struct page *page; + unsigned long pfn = memory_bm_next_pfn(bm); + if (pfn == BM_END_OF_MAP) + return ERR_PTR(-EFAULT); + + page = pfn_to_page(pfn); if (PageHighMem(page)) return get_highmem_page_buffer(page, ca); @@ -1805,7 +1828,7 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca) pbe = chain_alloc(ca, sizeof(struct pbe)); if (!pbe) { swsusp_free(); - return NULL; + return ERR_PTR(-ENOMEM); } pbe->orig_address = page_address(page); pbe->address = safe_pages_list; @@ -1868,7 +1891,10 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count) return error; } else if (handle->prev <= nr_meta_pages) { - unpack_orig_pfns(buffer, ©_bm); + error = unpack_orig_pfns(buffer, ©_bm); + if (error) + return error; + if (handle->prev == nr_meta_pages) { error = prepare_image(&orig_bm, ©_bm); if (error) @@ -1879,12 +1905,14 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count) restore_pblist = NULL; handle->buffer = get_buffer(&orig_bm, &ca); handle->sync_read = 0; - if (!handle->buffer) - return -ENOMEM; + if (IS_ERR(handle->buffer)) + return PTR_ERR(handle->buffer); } } else { copy_last_highmem_page(); handle->buffer = get_buffer(&orig_bm, &ca); + if (IS_ERR(handle->buffer)) + return PTR_ERR(handle->buffer); if (handle->buffer != buffer) handle->sync_read = 0; } diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 023ff2a31d8..a92c9145155 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -262,3 +262,125 @@ int swsusp_shrink_memory(void) return 0; } + +/* + * Platforms, like ACPI, may want us to save some memory used by them during + * hibernation and to restore the contents of this memory during the subsequent + * resume. The code below implements a mechanism allowing us to do that. + */ + +struct nvs_page { + unsigned long phys_start; + unsigned int size; + void *kaddr; + void *data; + struct list_head node; +}; + +static LIST_HEAD(nvs_list); + +/** + * hibernate_nvs_register - register platform NVS memory region to save + * @start - physical address of the region + * @size - size of the region + * + * The NVS region need not be page-aligned (both ends) and we arrange + * things so that the data from page-aligned addresses in this region will + * be copied into separate RAM pages. + */ +int hibernate_nvs_register(unsigned long start, unsigned long size) +{ + struct nvs_page *entry, *next; + + while (size > 0) { + unsigned int nr_bytes; + + entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL); + if (!entry) + goto Error; + + list_add_tail(&entry->node, &nvs_list); + entry->phys_start = start; + nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK); + entry->size = (size < nr_bytes) ? size : nr_bytes; + + start += entry->size; + size -= entry->size; + } + return 0; + + Error: + list_for_each_entry_safe(entry, next, &nvs_list, node) { + list_del(&entry->node); + kfree(entry); + } + return -ENOMEM; +} + +/** + * hibernate_nvs_free - free data pages allocated for saving NVS regions + */ +void hibernate_nvs_free(void) +{ + struct nvs_page *entry; + + list_for_each_entry(entry, &nvs_list, node) + if (entry->data) { + free_page((unsigned long)entry->data); + entry->data = NULL; + if (entry->kaddr) { + iounmap(entry->kaddr); + entry->kaddr = NULL; + } + } +} + +/** + * hibernate_nvs_alloc - allocate memory necessary for saving NVS regions + */ +int hibernate_nvs_alloc(void) +{ + struct nvs_page *entry; + + list_for_each_entry(entry, &nvs_list, node) { + entry->data = (void *)__get_free_page(GFP_KERNEL); + if (!entry->data) { + hibernate_nvs_free(); + return -ENOMEM; + } + } + return 0; +} + +/** + * hibernate_nvs_save - save NVS memory regions + */ +void hibernate_nvs_save(void) +{ + struct nvs_page *entry; + + printk(KERN_INFO "PM: Saving platform NVS memory\n"); + + list_for_each_entry(entry, &nvs_list, node) + if (entry->data) { + entry->kaddr = ioremap(entry->phys_start, entry->size); + memcpy(entry->data, entry->kaddr, entry->size); + } +} + +/** + * hibernate_nvs_restore - restore NVS memory regions + * + * This function is going to be called with interrupts disabled, so it + * cannot iounmap the virtual addresses used to access the NVS region. + */ +void hibernate_nvs_restore(void) +{ + struct nvs_page *entry; + + printk(KERN_INFO "PM: Restoring platform NVS memory\n"); + + list_for_each_entry(entry, &nvs_list, node) + if (entry->data) + memcpy(entry->kaddr, entry->data, entry->size); +}