瀏覽代碼

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:
  ACPI: remove CONFIG_ACPI_SYSTEM
  fujitsu-laptop: Use RFKILL support bitmask from firmware
  x86_64: Fix S3 fail path
  x86_64: acpi/wakeup_64 cleanup
  battery: don't assume we are fully charged when not charging or discharging
  ACPI: EC: Add delay for slow MSI controller
Linus Torvalds 16 年之前
父節點
當前提交
7c24af498f
共有 6 個文件被更改,包括 62 次插入36 次删除
  1. 10 20
      arch/x86/kernel/acpi/wakeup_64.S
  2. 0 7
      drivers/acpi/Kconfig
  3. 1 1
      drivers/acpi/Makefile
  4. 24 1
      drivers/acpi/battery.c
  5. 9 0
      drivers/acpi/ec.c
  6. 18 7
      drivers/platform/x86/fujitsu-laptop.c

+ 10 - 20
arch/x86/kernel/acpi/wakeup_64.S

@@ -13,7 +13,6 @@
 	 * Hooray, we are in Long 64-bit mode (but still running in low memory)
 	 * Hooray, we are in Long 64-bit mode (but still running in low memory)
 	 */
 	 */
 ENTRY(wakeup_long64)
 ENTRY(wakeup_long64)
-wakeup_long64:
 	movq	saved_magic, %rax
 	movq	saved_magic, %rax
 	movq	$0x123456789abcdef0, %rdx
 	movq	$0x123456789abcdef0, %rdx
 	cmpq	%rdx, %rax
 	cmpq	%rdx, %rax
@@ -34,16 +33,12 @@ wakeup_long64:
 
 
 	movq	saved_rip, %rax
 	movq	saved_rip, %rax
 	jmp	*%rax
 	jmp	*%rax
+ENDPROC(wakeup_long64)
 
 
 bogus_64_magic:
 bogus_64_magic:
 	jmp	bogus_64_magic
 	jmp	bogus_64_magic
 
 
-	.align 2
-	.p2align 4,,15
-.globl do_suspend_lowlevel
-	.type	do_suspend_lowlevel,@function
-do_suspend_lowlevel:
-.LFB5:
+ENTRY(do_suspend_lowlevel)
 	subq	$8, %rsp
 	subq	$8, %rsp
 	xorl	%eax, %eax
 	xorl	%eax, %eax
 	call	save_processor_state
 	call	save_processor_state
@@ -67,7 +62,7 @@ do_suspend_lowlevel:
 	pushfq
 	pushfq
 	popq	pt_regs_flags(%rax)
 	popq	pt_regs_flags(%rax)
 
 
-	movq	$.L97, saved_rip(%rip)
+	movq	$resume_point, saved_rip(%rip)
 
 
 	movq	%rsp, saved_rsp
 	movq	%rsp, saved_rsp
 	movq	%rbp, saved_rbp
 	movq	%rbp, saved_rbp
@@ -78,14 +73,12 @@ do_suspend_lowlevel:
 	addq	$8, %rsp
 	addq	$8, %rsp
 	movl	$3, %edi
 	movl	$3, %edi
 	xorl	%eax, %eax
 	xorl	%eax, %eax
-	jmp	acpi_enter_sleep_state
-.L97:
-	.p2align 4,,7
-.L99:
-	.align 4
-	movl	$24, %eax
-	movw	%ax, %ds
+	call	acpi_enter_sleep_state
+	/* in case something went wrong, restore the machine status and go on */
+	jmp	resume_point
 
 
+	.align 4
+resume_point:
 	/* We don't restore %rax, it must be 0 anyway */
 	/* We don't restore %rax, it must be 0 anyway */
 	movq	$saved_context, %rax
 	movq	$saved_context, %rax
 	movq	saved_context_cr4(%rax), %rbx
 	movq	saved_context_cr4(%rax), %rbx
@@ -117,12 +110,9 @@ do_suspend_lowlevel:
 	xorl	%eax, %eax
 	xorl	%eax, %eax
 	addq	$8, %rsp
 	addq	$8, %rsp
 	jmp	restore_processor_state
 	jmp	restore_processor_state
-.LFE5:
-.Lfe5:
-	.size	do_suspend_lowlevel, .Lfe5-do_suspend_lowlevel
-	
+ENDPROC(do_suspend_lowlevel)
+
 .data
 .data
-ALIGN
 ENTRY(saved_rbp)	.quad	0
 ENTRY(saved_rbp)	.quad	0
 ENTRY(saved_rsi)	.quad	0
 ENTRY(saved_rsi)	.quad	0
 ENTRY(saved_rdi)	.quad	0
 ENTRY(saved_rdi)	.quad	0

+ 0 - 7
drivers/acpi/Kconfig

@@ -254,13 +254,6 @@ config ACPI_PCI_SLOT
 	  help you correlate PCI bus addresses with the physical geography
 	  help you correlate PCI bus addresses with the physical geography
 	  of your slots. If you are unsure, say N.
 	  of your slots. If you are unsure, say N.
 
 
-config ACPI_SYSTEM
-	bool
-	default y
-	help
-	  This driver will enable your system to shut down using ACPI, and
-	  dump your ACPI DSDT table using /proc/acpi/dsdt.
-
 config X86_PM_TIMER
 config X86_PM_TIMER
 	bool "Power Management Timer Support" if EMBEDDED
 	bool "Power Management Timer Support" if EMBEDDED
 	depends on X86
 	depends on X86

+ 1 - 1
drivers/acpi/Makefile

@@ -52,7 +52,7 @@ obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
 obj-y				+= power.o
 obj-y				+= power.o
-obj-$(CONFIG_ACPI_SYSTEM)	+= system.o event.o
+obj-y				+= system.o event.o
 obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
 obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
 obj-$(CONFIG_ACPI_NUMA)		+= numa.o
 obj-$(CONFIG_ACPI_NUMA)		+= numa.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o

+ 24 - 1
drivers/acpi/battery.c

@@ -138,6 +138,29 @@ static int acpi_battery_technology(struct acpi_battery *battery)
 
 
 static int acpi_battery_get_state(struct acpi_battery *battery);
 static int acpi_battery_get_state(struct acpi_battery *battery);
 
 
+static int acpi_battery_is_charged(struct acpi_battery *battery)
+{
+	/* either charging or discharging */
+	if (battery->state != 0)
+		return 0;
+
+	/* battery not reporting charge */
+	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
+	    battery->capacity_now == 0)
+		return 0;
+
+	/* good batteries update full_charge as the batteries degrade */
+	if (battery->full_charge_capacity == battery->capacity_now)
+		return 1;
+
+	/* fallback to using design values for broken batteries */
+	if (battery->design_capacity == battery->capacity_now)
+		return 1;
+
+	/* we don't do any sort of metric based on percentages */
+	return 0;
+}
+
 static int acpi_battery_get_property(struct power_supply *psy,
 static int acpi_battery_get_property(struct power_supply *psy,
 				     enum power_supply_property psp,
 				     enum power_supply_property psp,
 				     union power_supply_propval *val)
 				     union power_supply_propval *val)
@@ -155,7 +178,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 		else if (battery->state & 0x02)
 		else if (battery->state & 0x02)
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
-		else if (battery->state == 0)
+		else if (acpi_battery_is_charged(battery))
 			val->intval = POWER_SUPPLY_STATUS_FULL;
 			val->intval = POWER_SUPPLY_STATUS_FULL;
 		else
 		else
 			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
 			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;

+ 9 - 0
drivers/acpi/ec.c

@@ -120,6 +120,8 @@ static struct acpi_ec {
 	spinlock_t curr_lock;
 	spinlock_t curr_lock;
 } *boot_ec, *first_ec;
 } *boot_ec, *first_ec;
 
 
+static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
+
 /* --------------------------------------------------------------------------
 /* --------------------------------------------------------------------------
                              Transaction Management
                              Transaction Management
    -------------------------------------------------------------------------- */
    -------------------------------------------------------------------------- */
@@ -259,6 +261,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 		clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 		clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 		acpi_disable_gpe(NULL, ec->gpe);
 		acpi_disable_gpe(NULL, ec->gpe);
 	}
 	}
+	if (EC_FLAGS_MSI)
+		udelay(ACPI_EC_DELAY);
 	/* start transaction */
 	/* start transaction */
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	/* following two actions should be kept atomic */
 	/* following two actions should be kept atomic */
@@ -967,6 +971,11 @@ int __init acpi_ec_ecdt_probe(void)
 	/*
 	/*
 	 * Generate a boot ec context
 	 * Generate a boot ec context
 	 */
 	 */
+	if (dmi_name_in_vendors("Micro-Star") ||
+	    dmi_name_in_vendors("Notebook")) {
+		pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
+		EC_FLAGS_MSI = 1;
+	}
 	status = acpi_get_table(ACPI_SIG_ECDT, 1,
 	status = acpi_get_table(ACPI_SIG_ECDT, 1,
 				(struct acpi_table_header **)&ecdt_ptr);
 				(struct acpi_table_header **)&ecdt_ptr);
 	if (ACPI_SUCCESS(status)) {
 	if (ACPI_SUCCESS(status)) {

+ 18 - 7
drivers/platform/x86/fujitsu-laptop.c

@@ -166,6 +166,7 @@ struct fujitsu_hotkey_t {
 	struct platform_device *pf_device;
 	struct platform_device *pf_device;
 	struct kfifo *fifo;
 	struct kfifo *fifo;
 	spinlock_t fifo_lock;
 	spinlock_t fifo_lock;
+	int rfkill_supported;
 	int rfkill_state;
 	int rfkill_state;
 	int logolamp_registered;
 	int logolamp_registered;
 	int kblamps_registered;
 	int kblamps_registered;
@@ -526,7 +527,7 @@ static ssize_t
 show_lid_state(struct device *dev,
 show_lid_state(struct device *dev,
 			struct device_attribute *attr, char *buf)
 			struct device_attribute *attr, char *buf)
 {
 {
-	if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+	if (!(fujitsu_hotkey->rfkill_supported & 0x100))
 		return sprintf(buf, "unknown\n");
 		return sprintf(buf, "unknown\n");
 	if (fujitsu_hotkey->rfkill_state & 0x100)
 	if (fujitsu_hotkey->rfkill_state & 0x100)
 		return sprintf(buf, "open\n");
 		return sprintf(buf, "open\n");
@@ -538,7 +539,7 @@ static ssize_t
 show_dock_state(struct device *dev,
 show_dock_state(struct device *dev,
 			struct device_attribute *attr, char *buf)
 			struct device_attribute *attr, char *buf)
 {
 {
-	if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+	if (!(fujitsu_hotkey->rfkill_supported & 0x200))
 		return sprintf(buf, "unknown\n");
 		return sprintf(buf, "unknown\n");
 	if (fujitsu_hotkey->rfkill_state & 0x200)
 	if (fujitsu_hotkey->rfkill_state & 0x200)
 		return sprintf(buf, "docked\n");
 		return sprintf(buf, "docked\n");
@@ -550,7 +551,7 @@ static ssize_t
 show_radios_state(struct device *dev,
 show_radios_state(struct device *dev,
 			struct device_attribute *attr, char *buf)
 			struct device_attribute *attr, char *buf)
 {
 {
-	if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+	if (!(fujitsu_hotkey->rfkill_supported & 0x20))
 		return sprintf(buf, "unknown\n");
 		return sprintf(buf, "unknown\n");
 	if (fujitsu_hotkey->rfkill_state & 0x20)
 	if (fujitsu_hotkey->rfkill_state & 0x20)
 		return sprintf(buf, "on\n");
 		return sprintf(buf, "on\n");
@@ -928,8 +929,17 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 		; /* No action, result is discarded */
 		; /* No action, result is discarded */
 	vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
 	vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
 
 
-	fujitsu_hotkey->rfkill_state =
-		call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
+	fujitsu_hotkey->rfkill_supported =
+		call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0);
+
+	/* Make sure our bitmask of supported functions is cleared if the
+	   RFKILL function block is not implemented, like on the S7020. */
+	if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD)
+		fujitsu_hotkey->rfkill_supported = 0;
+
+	if (fujitsu_hotkey->rfkill_supported)
+		fujitsu_hotkey->rfkill_state =
+			call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
 
 
 	/* Suspect this is a keymap of the application panel, print it */
 	/* Suspect this is a keymap of the application panel, print it */
 	printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n",
 	printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n",
@@ -1005,8 +1015,9 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
 
 
 	input = fujitsu_hotkey->input;
 	input = fujitsu_hotkey->input;
 
 
-	fujitsu_hotkey->rfkill_state =
-		call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
+	if (fujitsu_hotkey->rfkill_supported)
+		fujitsu_hotkey->rfkill_state =
+			call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
 
 
 	switch (event) {
 	switch (event) {
 	case ACPI_FUJITSU_NOTIFY_CODE1:
 	case ACPI_FUJITSU_NOTIFY_CODE1: