Skip to contentSkip to conversation

ACPI patches for 2.6.23-rc2

PATCH New Len Brown 3 participants 16 messages Aug 3, 2007 – Aug 8, 2007 2 messages not in the archive

Subsystems (4)
lore
Share & tools
lore

Len Brown

author
#0 lore raw

As usual, please speak up if you see any issues
with these patches.

thanks,
-Len

author
#1 lore raw

PATCH 1/12 ACPI: add "acpi_no_auto_ssdt" bootparam

"acpi_no_auto_ssdt" prevents Linux from automatically loading all the SSDTs listed in the RSDT/XSDT.

This is needed for debugging. In particular,
it allows a DSDT override to optionally be a DSDT+SSDT override.

http://bugzilla.kernel.org/show_bug.cgi?id=3774

---
 Documentation/kernel-parameters.txt |    2 ++
 drivers/acpi/tables/tbxface.c       |   23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)
Documentation/kernel-parameters.txt +2 -0
index fb80e9f..379931e 100644
@@ -166,6 +166,8 @@ and is between 256 and 4096 characters. It is defined in the file
 	acpi_irq_isa=	[HW,ACPI] If irq_balance, mark listed IRQs used by ISA
 			Format: <irq>,<irq>...
 
+	acpi_no_auto_ssdt	[HW,ACPI] Disable automatic loading of SSDT
+
 	acpi_os_name=	[HW,ACPI] Tell ACPI BIOS the name of the OS
 			Format: To spoof as Windows 98: ="Microsoft Windows"
 
drivers/acpi/tables/tbxface.c +23 -0
index 5b302c4..a9e3331 100644
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("tbxface")
 /* Local prototypes */
 static acpi_status acpi_tb_load_namespace(void);
 
+static int no_auto_ssdt;
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_allocate_root_table
@@ -536,6 +538,10 @@ static acpi_status acpi_tb_load_namespace(void)
 
 		ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
 		acpi_tb_print_table_header(0, table);
+
+		if (no_auto_ssdt == 0) {
+			printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
+		}
 	}
 
 	status =
@@ -577,6 +583,11 @@ static acpi_status acpi_tb_load_namespace(void)
 			continue;
 		}
 
+		if (no_auto_ssdt) {
+			printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
+			continue;
+		}
+
 		/* Ignore errors while loading tables, get as many as possible */
 
 		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
@@ -622,3 +633,15 @@ acpi_status acpi_load_tables(void)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_load_tables)
+
+
+static int __init acpi_no_auto_ssdt_setup(char *s) {
+
+        printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
+
+        no_auto_ssdt = 1;
+
+        return 1;
+}
+
+__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#2 lore raw

PATCH 2/12 sony-laptop: restore the last user requested brightness level on resume.

In reply to Len Brown

From: Mattia Dongili <[email protected]>

---
 drivers/misc/sony-laptop.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/misc/sony-laptop.c +5 -0
index 14ee06c..9a803e1 100644
@@ -942,6 +942,11 @@ static int sony_nc_resume(struct acpi_device *device)
 		}
 	}
 
+	/* set the last requested brightness level */
+	if (sony_backlight_device &&
+			!sony_backlight_update_status(sony_backlight_device))
+		printk(KERN_WARNING DRV_PFX "unable to restore brightness level");
+
 	/* re-initialize models with specific requirements */
 	dmi_check_system(sony_nc_ids);
 
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#3 lore raw

PATCH 3/12 sony-laptop: sony_nc_ids[] can become static.

In reply to Len Brown

From: Adrian Bunk <[email protected]>

---
 drivers/misc/sony-laptop.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/misc/sony-laptop.c +1 -1
index 9a803e1..91da688 100644
@@ -845,7 +845,7 @@ static struct sony_nc_event sony_C_events[] = {
 };
 
 /* SNC-only model map */
-struct dmi_system_id sony_nc_ids[] = {
+static struct dmi_system_id sony_nc_ids[] = {
 		{
 			.ident = "Sony Vaio FE Series",
 			.callback = sony_nc_C_enable,
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#4 lore raw

PATCH 4/12 sonypi: fix ids member of struct acpi_driver

In reply to Len Brown

From: Eugene Teo <[email protected]>

ids member of struct acpi_driver is of type struct acpi_device_id, not a character array.

---
 drivers/char/sonypi.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
drivers/char/sonypi.c +6 -1
index 73037a4..aeec67e 100644
@@ -1147,10 +1147,15 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
+const static struct acpi_device_id sonypi_device_ids[] = {
+	{"SNY6001", 0},
+	{"", 0},
+};
+
 static struct acpi_driver sonypi_acpi_driver = {
 	.name           = "sonypi",
 	.class          = "hkey",
-	.ids            = "SNY6001",
+	.ids            = sonypi_device_ids,
 	.ops            = {
 		           .add = sonypi_acpi_add,
 			   .remove = sonypi_acpi_remove,
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#5 lore raw

PATCH 5/12 ACPI: thinkpad-acpi: fix the module init failure path

In reply to Len Brown

From: Henrique de Moraes Holschuh <[email protected]>

Thomas Renninger reports that if one tries to load thinkpad-acpi in a non-thinkpad, one gets:

Call Trace:
 [<ffffffff802fa57d>] kref_get+0x2f/0x36
 [<ffffffff802f97f7>] kobject_get+0x12/0x17
 [<ffffffff8036dfd7>] get_driver+0x14/0x1a
 [<ffffffff8036dfee>] driver_remove_file+0x11/0x32
 [<ffffffff8823b9be>] :thinkpad_acpi:thinkpad_acpi_module_exit+0xa8/0xfc
 [<ffffffff8824b8a0>] :thinkpad_acpi:thinkpad_acpi_module_init+0x74a/0x776
 [<ffffffff8024f968>] __link_module+0x0/0x25
 [<ffffffff80252269>] sys_init_module+0x162c/0x178f
 [<ffffffff8020bc2e>] system_call+0x7e/0x83

So, track if the platform driver and its driver attributes were registered, and only deallocate them in that case.

This patch is based on Thomas Renninger's patch for the issue.

---
 drivers/misc/thinkpad_acpi.c |   10 ++++++++--
 drivers/misc/thinkpad_acpi.h |    2 ++
 2 files changed, 10 insertions(+), 2 deletions(-)
drivers/misc/thinkpad_acpi.c +8 -2
index fa80f35..f6cd34a 100644
@@ -4668,12 +4668,15 @@ static int __init thinkpad_acpi_module_init(void)
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
+	tp_features.platform_drv_registered = 1;
+
 	ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
 	if (ret) {
 		printk(IBM_ERR "unable to create sysfs driver attributes\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
+	tp_features.platform_drv_attrs_registered = 1;
 
 
 	/* Device initialization */
@@ -4756,8 +4759,11 @@ static void thinkpad_acpi_module_exit(void)
 	if (tpacpi_pdev)
 		platform_device_unregister(tpacpi_pdev);
 
-	tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
-	platform_driver_unregister(&tpacpi_pdriver);
+	if (tp_features.platform_drv_attrs_registered)
+		tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
+
+	if (tp_features.platform_drv_registered)
+		platform_driver_unregister(&tpacpi_pdriver);
 
 	if (proc_dir)
 		remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
drivers/misc/thinkpad_acpi.h +2 -0
index 88af089..eee8809 100644
@@ -246,6 +246,8 @@ static struct {
 	u16 wan:1;
 	u16 fan_ctrl_status_undef:1;
 	u16 input_device_registered:1;
+	u16 platform_drv_registered:1;
+	u16 platform_drv_attrs_registered:1;
 } tp_features;
 
 struct thinkpad_id_data {
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#6 lore raw

PATCH 6/12 ACPI: button: re-scan lid state on resume

In reply to Len Brown

From: Richard Hughes <[email protected]>

On resume we need to refresh the lid status as we will not get an event if the lid opening was what triggered the suspend.
This manifests itself in users never getting a "lid open" event when a suspend happens because of lid close on hardware that supports wake on lid open. This makes userspace gets very confused indeed.

---
 drivers/acpi/button.c |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)
drivers/acpi/button.c +25 -0
index 5405813..b3c88aa 100644
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
 
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
+static int acpi_button_resume(struct acpi_device *device);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
 	.ids = button_device_ids,
 	.ops = {
 		.add = acpi_button_add,
+		.resume = acpi_button_resume,
 		.remove = acpi_button_remove,
 	},
 };
@@ -497,6 +499,29 @@ static int acpi_button_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
+/* this is needed to learn about changes made in suspended state */
+static int acpi_button_resume(struct acpi_device *device)
+{
+	struct acpi_button *button;
+	struct acpi_handle *handle;
+	struct input_dev *input;
+	unsigned long state;
+
+	button = device->driver_data;
+	handle = button->device->handle;
+	input = button->input;
+
+	/*
+	 * On resume we send the state; if it matches to what input layer
+	 * thinks then the event will not even reach userspace.
+	 */
+	if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+						NULL, &state)))
+		input_report_switch(input, SW_LID, !state);
+
+	return 0;
+}
+
 static int __init acpi_button_init(void)
 {
 	int result;
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#7 lore raw

PATCH 7/12 asus_acpi: fix possible double free (found by Coverity)

In reply to Len Brown

From: Jesper Juhl <[email protected]>

---
 drivers/acpi/asus_acpi.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/acpi/asus_acpi.c +1 -0
index 9c4bd22..86fd142 100644
@@ -1192,6 +1192,7 @@ static int asus_hotk_get_info(void)
 			break;
 		default:
 			kfree(model);
+			model = NULL;
 			break;
 		}
 	}
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#8 lore raw

PATCH 8/12 ACPI: EC: Remove noisy debug printk fron EC driver.

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

ACPI: EC: Handler for query 0x57 is not found!

---
 drivers/acpi/ec.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/acpi/ec.c +0 -1
index 469f3f5..dd384ec 100644
@@ -471,7 +471,6 @@ static void acpi_ec_gpe_query(void *ec_cxt)
 		}
 	}
 	mutex_unlock(&ec->lock);
-	printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
 }
 
 static u32 acpi_ec_gpe_handler(void *data)
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#9 lore raw

PATCH 9/12 ACPI: Battery: Synchronize battery operations.

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

http://bugzilla.kernel.org/show_bug.cgi?id=8768

---
 drivers/acpi/battery.c |   47 +++++++++++++++++------------------------------
 1 files changed, 17 insertions(+), 30 deletions(-)
drivers/acpi/battery.c +17 -30
index 8165103..d7b499f 100644
@@ -113,7 +113,7 @@ struct acpi_battery_info {
 	acpi_string oem_info;
 };
 
-enum acpi_battery_files{
+enum acpi_battery_files {
 	ACPI_BATTERY_INFO = 0,
 	ACPI_BATTERY_STATE,
 	ACPI_BATTERY_ALARM,
@@ -129,13 +129,14 @@ struct acpi_battery_flags {
 };
 
 struct acpi_battery {
-	struct mutex mutex;
 	struct acpi_device *device;
 	struct acpi_battery_flags flags;
 	struct acpi_buffer bif_data;
 	struct acpi_buffer bst_data;
+	struct mutex lock;
 	unsigned long alarm;
 	unsigned long update_time[ACPI_BATTERY_NUMFILES];
+
 };
 
 inline int acpi_battery_present(struct acpi_battery *battery)
@@ -235,10 +236,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 		return 0;
 
 	/* Evaluate _BIF */
-
-	status =
-	    acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
-				 &buffer);
+	mutex_lock(&battery->lock);
+	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
+				      NULL, &buffer);
+	mutex_unlock(&battery->lock);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
 		return -ENODEV;
@@ -285,10 +286,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 		return 0;
 
 	/* Evaluate _BST */
-
-	status =
-	    acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
-				 &buffer);
+	mutex_lock(&battery->lock);
+	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
+				      NULL, &buffer);
+	mutex_unlock(&battery->lock);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
 		return -ENODEV;
@@ -336,9 +337,10 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 
 	arg0.integer.value = alarm;
 
-	status =
-	    acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+	mutex_lock(&battery->lock);
+	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
 				 &arg_list, NULL);
+	mutex_unlock(&battery->lock);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
@@ -658,8 +660,6 @@ acpi_battery_write_alarm(struct file *file,
 	if (!battery || (count > sizeof(alarm_string) - 1))
 		return -EINVAL;
 
-	mutex_lock(&battery->mutex);
-
 	result = acpi_battery_update(battery, 1, &update_result);
 	if (result) {
 		result = -ENODEV;
@@ -688,9 +688,7 @@ acpi_battery_write_alarm(struct file *file,
 	acpi_battery_check_result(battery, result);
 
 	if (!result)
-		result = count;
-
-	mutex_unlock(&battery->mutex);
+		return count;
 
 	return result;
 }
@@ -714,8 +712,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
 	int update_result = ACPI_BATTERY_NONE_UPDATE;
 	int update = 0;
 
-	mutex_lock(&battery->mutex);
-
 	update = (get_seconds() - battery->update_time[fid] >= update_time);
 	update = (update | battery->flags.update[fid]);
 
@@ -733,7 +729,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
 	result = acpi_read_funcs[fid].print(seq, result);
 	acpi_battery_check_result(battery, result);
 	battery->flags.update[fid] = result;
-	mutex_unlock(&battery->mutex);
 	return result;
 }
 
@@ -897,10 +892,7 @@ static int acpi_battery_add(struct acpi_device *device)
 	if (!battery)
 		return -ENOMEM;
 
-	mutex_init(&battery->mutex);
-
-	mutex_lock(&battery->mutex);
-
+	mutex_init(&battery->lock);
 	battery->device = device;
 	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
@@ -936,7 +928,6 @@ static int acpi_battery_add(struct acpi_device *device)
 		kfree(battery);
 	}
 
-	mutex_unlock(&battery->mutex);
 
 	return result;
 }
@@ -951,8 +942,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 
 	battery = acpi_driver_data(device);
 
-	mutex_lock(&battery->mutex);
-
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY,
 					    acpi_battery_notify);
@@ -963,9 +952,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 
 	kfree(battery->bst_data.pointer);
 
-	mutex_unlock(&battery->mutex);
-
-	mutex_destroy(&battery->mutex);
+	mutex_destroy(&battery->lock);
 
 	kfree(battery);
 
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#10 lore raw

PATCH 10/12 ACPI: EC: If ECDT is not found, look up EC in DSDT.

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

Some ASUS laptops access EC space from device _INI methods, but do not provide ECDT for early EC setup. In order to make them function properly, there is a need to find EC is DSDT before any _INI is called.

Similar functionality was turned on by acpi_fake_ecdt=1 command line before. Now it is on all the time.

http://bugzilla.kernel.org/show_bug.cgi?id=8598

---
 drivers/acpi/ec.c |   50 ++++++++++++++++++++++++++++----------------------
 1 files changed, 28 insertions(+), 22 deletions(-)
drivers/acpi/ec.c +28 -22
index dd384ec..4d7fe82 100644
@@ -664,30 +664,32 @@ acpi_ec_register_query_methods(acpi_handle handle, u32 level,
 	return AE_OK;
 }
 
-static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
+static acpi_status
+ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 {
-	if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
-				     ec_parse_io_ports, ec)))
-		return -EINVAL;
+	acpi_status status;
+
+	struct acpi_ec *ec = context;
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+				     ec_parse_io_ports, ec);
+	if (ACPI_FAILURE(status))
+		return status;
 
 	/* Get GPE bit assignment (EC events). */
 	/* TODO: Add support for _GPE returning a package */
-	if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
-		return -EINVAL;
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
+	if (ACPI_FAILURE(status))
+		return status;
 
 	/* Use the global lock for all EC transactions? */
 	acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
 
-	/* Find and register all query methods */
-	acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
-			    acpi_ec_register_query_methods, ec, NULL);
-
 	ec->handle = handle;
 
 	printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
 			  ec->gpe, ec->command_addr, ec->data_addr);
 
-	return 0;
+	return AE_CTRL_TERMINATE;
 }
 
 static int acpi_ec_add(struct acpi_device *device)
@@ -704,7 +706,8 @@ static int acpi_ec_add(struct acpi_device *device)
 	if (!ec)
 		return -ENOMEM;
 
-	if (ec_parse_device(ec, device->handle)) {
+	if (ec_parse_device(device->handle, 0, ec, NULL) !=
+	    AE_CTRL_TERMINATE) {
 		kfree(ec);
 		return -EINVAL;
 	}
@@ -867,18 +870,21 @@ int __init acpi_ec_ecdt_probe(void)
 	/*
 	 * Generate a boot ec context
 	 */
-
 	status = acpi_get_table(ACPI_SIG_ECDT, 1,
 				(struct acpi_table_header **)&ecdt_ptr);
-	if (ACPI_FAILURE(status))
-		goto error;
-
-	printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
-
-	boot_ec->command_addr = ecdt_ptr->control.address;
-	boot_ec->data_addr = ecdt_ptr->data.address;
-	boot_ec->gpe = ecdt_ptr->gpe;
-	boot_ec->handle = ACPI_ROOT_OBJECT;
+	if (ACPI_SUCCESS(status)) {
+		printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
+		boot_ec->command_addr = ecdt_ptr->control.address;
+		boot_ec->data_addr = ecdt_ptr->data.address;
+		boot_ec->gpe = ecdt_ptr->gpe;
+		boot_ec->handle = ACPI_ROOT_OBJECT;
+	} else {
+		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);
+		if (ACPI_FAILURE(status))
+			goto error;
+	}
 
 	ret = ec_install_handlers(boot_ec);
 	if (!ret) {
Signature · 1 line
1.5.3.rc3.7.gd58e
author
#11 lore raw

PATCH 11/12 ACPI: EC: fix build warning

In reply to Len Brown

drivers/acpi/ec.c:657: warning: ‘acpi_ec_register_query_methods’ defined but not used

---
 drivers/acpi/ec.c |   13 -------------
 1 files changed, 0 insertions(+), 13 deletions(-)
drivers/acpi/ec.c +0 -13
index 4d7fe82..6292890 100644
@@ -652,19 +652,6 @@ static struct acpi_ec *make_acpi_ec(void)
 }
 
 static acpi_status
-acpi_ec_register_query_methods(acpi_handle handle, u32 level,
-			       void *context, void **return_value)
-{
-	struct acpi_namespace_node *node = handle;
-	struct acpi_ec *ec = context;
-	int value = 0;
-	if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
-		acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
-	}
-	return AE_OK;
-}
-
-static acpi_status
 ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 {
 	acpi_status status;
Signature · 5 lines
1.5.3.rc3.7.gd58e
-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author
#12 lore raw

PATCH 12/12 ACPI: EC: Switch from boot_ec as soon as we find its desc in DSDT.

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

Some ASUS laptops fail to use boot time EC
and need to eventually switch to one described in DSDT.

http://bugzilla.kernel.org/show_bug.cgi?id=8709

---
 drivers/acpi/ec.c |   45 ++++++++++++++++-----------------------------
 1 files changed, 16 insertions(+), 29 deletions(-)
drivers/acpi/ec.c +16 -29
index 6292890..71caa7d 100644
@@ -679,6 +679,14 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 	return AE_CTRL_TERMINATE;
 }
 
+static void ec_remove_handlers(struct acpi_ec *ec)
+{
+	acpi_remove_address_space_handler(ec->handle,
+					  ACPI_ADR_SPACE_EC,
+					  &acpi_ec_space_handler);
+	acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
 	struct acpi_ec *ec = NULL;
@@ -702,16 +710,15 @@ static int acpi_ec_add(struct acpi_device *device)
 	/* Check if we found the boot EC */
 	if (boot_ec) {
 		if (boot_ec->gpe == ec->gpe) {
-			/* We might have incorrect info for GL at boot time */
 			mutex_lock(&boot_ec->lock);
-			boot_ec->global_lock = ec->global_lock;
-			/* Copy handlers from new ec into boot ec */
-			list_splice(&ec->list, &boot_ec->list);
+			ec_remove_handlers(boot_ec);
 			mutex_unlock(&boot_ec->lock);
-			kfree(ec);
-			ec = boot_ec;
+			mutex_destroy(&boot_ec->lock);
+			kfree(boot_ec);
+			first_ec = boot_ec = NULL;
 		}
-	} else
+	}
+	if (!first_ec)
 		first_ec = ec;
 	ec->handle = device->handle;
 	acpi_driver_data(device) = ec;
@@ -740,9 +747,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 	if (ec == first_ec)
 		first_ec = NULL;
 
-	/* Don't touch boot EC */
-	if (boot_ec != ec)
-		kfree(ec);
 	return 0;
 }
 
@@ -806,9 +810,7 @@ static int acpi_ec_start(struct acpi_device *device)
 	if (!ec)
 		return -EINVAL;
 
-	/* Boot EC is already working */
-	if (ec != boot_ec)
-		ret = ec_install_handlers(ec);
+	ret = ec_install_handlers(ec);
 
 	/* EC is fully operational, allow queries */
 	atomic_set(&ec->query_pending, 0);
@@ -818,7 +820,6 @@ static int acpi_ec_start(struct acpi_device *device)
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct acpi_ec *ec;
 
 	if (!device)
@@ -827,21 +828,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 	ec = acpi_driver_data(device);
 	if (!ec)
 		return -EINVAL;
-
-	/* Don't touch boot EC */
-	if (ec == boot_ec)
-		return 0;
-
-	status = acpi_remove_address_space_handler(ec->handle,
-						   ACPI_ADR_SPACE_EC,
-						   &acpi_ec_space_handler);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
-
-	status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
-
+	ec_remove_handlers(ec);
 	return 0;
 }
 
Signature · 1 line
1.5.3.rc3.7.gd58e

A message that is not in the archive (sent off-list or not yet received): 6c77088daa419b0bba83b0ce162e2f25a1a5e131.1186180370.git.len.brown@intel.com

#14 lore raw

Re: [PATCH 06/12] ACPI: button: re-scan lid state on resume

Hi Len,

Could have another look at linux-acpi thread:
[patch] Refresh lid state on resume
http://marc.info/?t=118467309200008&r=1&w=2

It came out that moving GPE activation before _WAK is called, fixes the problem. Not sure whether this one should still be added. IMO we should try with the real fix (moving GPEs before _WAK) first. If there are still machines having the problem, adding this one can still be added at later time, it's harmless.
The patch to activate GPEs before _WAK is this one, can you take it pls:
http://marc.info/?l=linux-acpi&m=118587857102639&w=2
or do you think it's too risky?

Thanks,

Thomas

Quoted 64 lines · Len Brown

From: Richard Hughes <[email protected]>

On resume we need to refresh the lid status as we will not get an event if the lid opening was what triggered the suspend.
This manifests itself in users never getting a "lid open" event when a suspend happens because of lid close on hardware that supports wake on lid open. This makes userspace gets very confused indeed.

---
 drivers/acpi/button.c |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)
drivers/acpi/button.c +25 -0
index 5405813..b3c88aa 100644
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
 
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
+static int acpi_button_resume(struct acpi_device *device);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
 	.ids = button_device_ids,
 	.ops = {
 		.add = acpi_button_add,
+		.resume = acpi_button_resume,
 		.remove = acpi_button_remove,
 	},
 };
@@ -497,6 +499,29 @@ static int acpi_button_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
+/* this is needed to learn about changes made in suspended state */
+static int acpi_button_resume(struct acpi_device *device)
+{
+	struct acpi_button *button;
+	struct acpi_handle *handle;
+	struct input_dev *input;
+	unsigned long state;
+
+	button = device->driver_data;
+	handle = button->device->handle;
+	input = button->input;
+
+	/*
+	 * On resume we send the state; if it matches to what input layer
+	 * thinks then the event will not even reach userspace.
+	 */
+	if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+						NULL, &state)))
+		input_report_switch(input, SW_LID, !state);
+
+	return 0;
+}
+
 static int __init acpi_button_init(void)
 {
 	int result;

A message that is not in the archive (sent off-list or not yet received): 67effe8fff32f60bdf51cba484766ba6003005bb.1186180370.git.len.brown@intel.com

#16 lore raw

Re: [PATCH 01/12] ACPI: add "acpi_no_auto_ssdt" bootparam

Quoted 7 lines · Len Brown

"acpi_no_auto_ssdt" prevents Linux from automatically loading all the SSDTs listed in the RSDT/XSDT.

This is needed for debugging. In particular,
it allows a DSDT override to optionally be a DSDT+SSDT override.

http://bugzilla.kernel.org/show_bug.cgi?id=3774

I don't understand why this is needed.
Shouldn't it work like that:
- Modified tables are loaded before original, BIOS provided ones
- If later tables have the same unique table id they are ignored. I can remember that this check was added more than a year ago, not sure whether it still exists, it should...

Thanks,

Thomas

reviewer
#17 lore raw

Re: [PATCH 01/12] ACPI: add "acpi_no_auto_ssdt" bootparam

Quoted 9 lines · Thomas Renninger
Quoted 7 lines · Len Brown

"acpi_no_auto_ssdt" prevents Linux from automatically loading all the SSDTs listed in the RSDT/XSDT.

This is needed for debugging. In particular,
it allows a DSDT override to optionally be a DSDT+SSDT override.

http://bugzilla.kernel.org/show_bug.cgi?id=3774

Quoted 7 lines

I don't understand why this is needed.
Shouldn't it work like that:
- Modified tables are loaded before original, BIOS provided ones
- If later tables have the same unique table id they are ignored. I can remember that this check was added more than a year ago, not sure whether it still exists, it should...

There _are_ no modified SSDTs -- only a modified DSDT.

The default case is that the modified DSDT gets loaded instead of the BIOS version, and then it gets augmented by any BIOS SSDTs.

However, that doesn't handle the case where we want to load a modified DSDT and _not_ load the BIOS SSDTs. This may be because we wanted to override the SSDTs and we've sucked that code into the modified DSDT and changed it, or we may simply not want the code that the BIOS provides in the SSDT mucking with our modified DSDT.

-Len