From 92d0216f28c7d55d581d98ede6b6a795bcfca9a3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Dec 2005 01:42:17 -0500 Subject: [PATCH] --- yaml --- r: 14847 b: refs/heads/master c: 220ec706645ecf13ee3a87046d17316303905698 h: refs/heads/master i: 14845: 44358815c94b300d092ad979c3042fe4d36640af 14843: c62beb016633d23340bd1f51714e3c9ed6a38773 14839: 1d6e1eee389c33e85d50afbc61ac84dbc733e142 14831: ea9ab8df491a0b5542e5845175cd39c7838c5971 14815: 176e96fdebfbc5c99fea7cd723b57b8cc4a2fd59 14783: 2c090f6c7d61d2eeeccb1447d438e9b4f6035e08 14719: 029f64605acef7c73cfb46e4720171d0165a78af 14591: 0d7116b479580e66df5e93bc3e91e19311f8819f 14335: 17c11290a85606a80545b40505262233069d4eee v: v3 --- [refs] | 2 +- trunk/arch/i386/kernel/acpi/boot.c | 7 +++++++ trunk/drivers/acpi/Kconfig | 1 - trunk/drivers/acpi/Makefile | 2 +- trunk/drivers/acpi/processor_core.c | 15 +++++++++++++++ trunk/drivers/acpi/processor_idle.c | 29 ++++++++++++++++++++++++----- trunk/drivers/acpi/scan.c | 2 +- trunk/drivers/acpi/video.c | 2 +- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 30aaa996ba51..7bb4c3d488b7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1cbf4c563c0eaaf11c552a88b374e213181c6ddd +refs/heads/master: 220ec706645ecf13ee3a87046d17316303905698 diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index 76b1135d401a..447fa9e33ffb 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -638,6 +638,13 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) return 0; pmtmr_ioport = fadt->xpm_tmr_blk.address; + /* + * "X" fields are optional extensions to the original V1.0 + * fields, so we must selectively expand V1.0 fields if the + * corresponding X field is zero. + */ + if (!pmtmr_ioport) + pmtmr_ioport = fadt->V1_pm_tmr_blk; } else { /* FADT rev. 1 */ pmtmr_ioport = fadt->V1_pm_tmr_blk; diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index fe1e8126fbae..fce21c257523 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -197,7 +197,6 @@ config ACPI_ASUS config ACPI_IBM tristate "IBM ThinkPad Laptop Extras" depends on X86 - default y ---help--- This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds support for Fn-Fx key combinations, Bluetooth control, video diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index a18243488c66..5984b4f6715a 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -16,7 +16,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) # ACPI Boot-Time Table Parsing # obj-y += tables.o -obj-y += blacklist.o +obj-$(CONFIG_X86) += blacklist.o # # ACPI Core Subsystem (Interpreter) diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 421792562642..0c561c571f29 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -543,6 +543,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr) return_VALUE(0); } +static void *processor_device_array[NR_CPUS]; + static int acpi_processor_start(struct acpi_device *device) { int result = 0; @@ -561,6 +563,19 @@ static int acpi_processor_start(struct acpi_device *device) BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0)); + /* + * Buggy BIOS check + * ACPI id of processors can be reported wrongly by the BIOS. + * Don't trust it blindly + */ + if (processor_device_array[pr->id] != NULL && + processor_device_array[pr->id] != (void *)device) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "BIOS reporting wrong ACPI id" + "for the processor\n")); + return_VALUE(-ENODEV); + } + processor_device_array[pr->id] = (void *)device; + processors[pr->id] = pr; result = acpi_processor_add_fs(device); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 70d8a6ec0920..83fd1b6c10c4 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -280,6 +280,16 @@ static void acpi_processor_idle(void) cx->usage++; +#ifdef CONFIG_HOTPLUG_CPU + /* + * Check for P_LVL2_UP flag before entering C2 and above on + * an SMP system. We do it here instead of doing it at _CST/P_LVL + * detection phase, to work cleanly with logical CPU hotplug. + */ + if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && + !pr->flags.has_cst && acpi_fadt.plvl2_up) + cx->type = ACPI_STATE_C1; +#endif /* * Sleep: * ------ @@ -534,6 +544,15 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) pr->power.states[ACPI_STATE_C0].valid = 1; pr->power.states[ACPI_STATE_C1].valid = 1; +#ifndef CONFIG_HOTPLUG_CPU + /* + * Check for P_LVL2_UP flag before entering C2 and above on + * an SMP system. + */ + if ((num_online_cpus() > 1) && acpi_fadt.plvl2_up) + return_VALUE(-ENODEV); +#endif + /* determine C2 and C3 address from pblk */ pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4; pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; @@ -690,7 +709,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) /* Validate number of power states discovered */ if (pr->power.count < 2) - status = -ENODEV; + status = -EFAULT; end: acpi_os_free(buffer.pointer); @@ -841,11 +860,11 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) * this function */ result = acpi_processor_get_power_info_cst(pr); - if ((result) || (acpi_processor_power_verify(pr) < 2)) { + if (result == -ENODEV) result = acpi_processor_get_power_info_fadt(pr); - if ((result) || (acpi_processor_power_verify(pr) < 2)) - result = acpi_processor_get_power_info_default_c1(pr); - } + + if ((result) || (acpi_processor_power_verify(pr) < 2)) + result = acpi_processor_get_power_info_default_c1(pr); /* * Set Default Policy diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 23e2c6968a11..31218e1d2a18 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -1110,7 +1110,7 @@ acpi_add_single_object(struct acpi_device **child, * * TBD: Assumes LDM provides driver hot-plug capability. */ - result = acpi_bus_find_driver(device); + acpi_bus_find_driver(device); end: if (!result) diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index f051b151580d..d10668f14699 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -812,7 +812,7 @@ acpi_video_device_write_brightness(struct file *file, ACPI_FUNCTION_TRACE("acpi_video_device_write_brightness"); - if (!dev || count + 1 > sizeof str) + if (!dev || !dev->brightness || count + 1 > sizeof str) return_VALUE(-EINVAL); if (copy_from_user(str, buffer, count))