All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] eeepc-wmi updates
@ 2011-01-24 16:23 Corentin Chary
  2011-01-24 16:23 ` [PATCH 01/14] eeepc-wmi: reorder keymap Corentin Chary
                   ` (13 more replies)
  0 siblings, 14 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

From: Corentin Chary <corentin.chary@gmail.com>

Hi Matthew,

Thanks to a generous donator, I was able to buy an Eeepc 1000H. It really
easier to make patch when you have the hardware :).

These patches add some features to eeepc-wmi that where already available in
eeepc-laptop (wimax, camera, cardr, wlan hotplug) and some new features
(backlight power).

You may want to take a look at "eeepc-wmi: add hotplug code for Eeepc 1000H"
and "eeepc-wmi: serialize access to wmi method" since you wrote the original
patch for eeepc-laptop.

It's probably way to late for 2.6.38, so let's queue them for 2.6.39. Anyway
if disitribution want to backport some patches, it should be easy to do with
any kernel >= 2.6.34.

Thanks,

Corentin Chary (14):
  eeepc-wmi: reorder keymap
  eeepc-wmi: add wlan key found on 1015P
  eeepc-wmi: add hotplug code for Eeepc 1000H
  eeepc-wmi: serialize access to wmi method
  eeepc-wmi: return proper error code in eeepc_rfkill_set()
  eeepc-wmi: add an helper using simple return codes
  eeepc-wmi: add hibernate/resume callbacks
  eeepc-wmi: switch to platform_create_bundle()
  eeepc-wmi: reorder defines
  eeepc-wmi: use the presence bit correctly
  eeepc-wmi: add camera and card reader support
  eeepc-wmi: add wimax support
  eeepc-wmi: set the right key code for 0xe9
  eeepc-wmi: support backlight power (bl_power) attribute

 Documentation/ABI/testing/sysfs-platform-eeepc-wmi |   14 +
 drivers/platform/x86/eeepc-wmi.c                   |  744 ++++++++++++++++----
 2 files changed, 633 insertions(+), 125 deletions(-)

-- 
1.7.3.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/14] eeepc-wmi: reorder keymap
  2011-01-24 16:23 [PATCH 00/14] eeepc-wmi updates Corentin Chary
@ 2011-01-24 16:23 ` Corentin Chary
  2011-01-24 16:23 ` [PATCH 02/14] eeepc-wmi: add wlan key found on 1015P Corentin Chary
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 4d38f98..350b7bc 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -74,18 +74,18 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 
 static const struct key_entry eeepc_wmi_keymap[] = {
 	/* Sleep already handled via generic ACPI code */
-	{ KE_KEY, 0x5d, { KEY_WLAN } },
-	{ KE_KEY, 0x32, { KEY_MUTE } },
-	{ KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
-	{ KE_KEY, 0x30, { KEY_VOLUMEUP } },
 	{ KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
 	{ KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
-	{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x30, { KEY_VOLUMEUP } },
+	{ KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+	{ KE_KEY, 0x32, { KEY_MUTE } },
+	{ KE_KEY, 0x5c, { KEY_F15 } },
+	{ KE_KEY, 0x5d, { KEY_WLAN } },
 	{ KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */
+	{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0xe0, { KEY_PROG1 } },
 	{ KE_KEY, 0xe1, { KEY_F14 } },
 	{ KE_KEY, 0xe9, { KEY_DISPLAY_OFF } },
-	{ KE_KEY, 0xe0, { KEY_PROG1 } },
-	{ KE_KEY, 0x5c, { KEY_F15 } },
 	{ KE_END, 0},
 };
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/14] eeepc-wmi: add wlan key found on 1015P
  2011-01-24 16:23 [PATCH 00/14] eeepc-wmi updates Corentin Chary
  2011-01-24 16:23 ` [PATCH 01/14] eeepc-wmi: reorder keymap Corentin Chary
@ 2011-01-24 16:23 ` Corentin Chary
  2011-01-24 16:23 ` [PATCH 03/14] eeepc-wmi: add hotplug code for Eeepc 1000H Corentin Chary
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 350b7bc..0d8217d 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -82,6 +82,7 @@ static const struct key_entry eeepc_wmi_keymap[] = {
 	{ KE_KEY, 0x5c, { KEY_F15 } },
 	{ KE_KEY, 0x5d, { KEY_WLAN } },
 	{ KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */
+	{ KE_KEY, 0x88, { KEY_WLAN } },
 	{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
 	{ KE_KEY, 0xe0, { KEY_PROG1 } },
 	{ KE_KEY, 0xe1, { KEY_F14 } },
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/14] eeepc-wmi: add hotplug code for Eeepc 1000H
  2011-01-24 16:23 [PATCH 00/14] eeepc-wmi updates Corentin Chary
  2011-01-24 16:23 ` [PATCH 01/14] eeepc-wmi: reorder keymap Corentin Chary
  2011-01-24 16:23 ` [PATCH 02/14] eeepc-wmi: add wlan key found on 1015P Corentin Chary
@ 2011-01-24 16:23 ` Corentin Chary
  2011-01-24 16:23 ` [PATCH 04/14] eeepc-wmi: serialize access to wmi method Corentin Chary
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Implement wireless like hotplug handling (code stolen from eeepc-laptop).

Reminder: on some models rfkill is implemented by logically unplugging the
wireless card from the PCI bus. Despite sending ACPI notifications, this does
not appear to be implemented using standard ACPI hotplug - nor does the
firmware provide the _OSC method required to support native PCIe hotplug.
The only sensible choice appears to be to handle the hotplugging directly in
the platform driver.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |  274 +++++++++++++++++++++++++++++++++++++-
 1 files changed, 273 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 0d8217d..01bc2b3 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -37,9 +37,12 @@
 #include <linux/backlight.h>
 #include <linux/leds.h>
 #include <linux/rfkill.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/platform_device.h>
+#include <linux/dmi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -72,6 +75,14 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
 
+static bool hotplug_wireless;
+
+module_param(hotplug_wireless, bool, 0444);
+MODULE_PARM_DESC(hotplug_wireless,
+		 "Enable hotplug for wireless device. "
+		 "If your laptop needs that, please report to "
+		 "acpi4asus-user@lists.sourceforge.net.");
+
 static const struct key_entry eeepc_wmi_keymap[] = {
 	/* Sleep already handled via generic ACPI code */
 	{ KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
@@ -109,6 +120,8 @@ struct eeepc_wmi_debug {
 };
 
 struct eeepc_wmi {
+	bool hotplug_wireless;
+
 	struct input_dev *inputdev;
 	struct backlight_device *backlight_device;
 	struct platform_device *platform_device;
@@ -122,6 +135,9 @@ struct eeepc_wmi {
 	struct rfkill *bluetooth_rfkill;
 	struct rfkill *wwan3g_rfkill;
 
+	struct hotplug_slot *hotplug_slot;
+	struct mutex hotplug_lock;
+
 	struct eeepc_wmi_debug debug;
 };
 
@@ -177,7 +193,8 @@ static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval)
 	u32 tmp;
 
 	status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
-			1, EEEPC_WMI_METHODID_DSTS, &input, &output);
+				     1, EEEPC_WMI_METHODID_DSTS,
+				     &input, &output);
 
 	if (ACPI_FAILURE(status))
 		return status;
@@ -334,6 +351,206 @@ static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
 }
 
 /*
+ * PCI hotplug (for wlan rfkill)
+ */
+static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi *eeepc)
+{
+	u32 retval;
+	acpi_status status;
+
+	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
+
+	if (ACPI_FAILURE(status))
+		return false;
+
+	return !(retval & 0x1);
+}
+
+static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
+{
+	struct pci_dev *dev;
+	struct pci_bus *bus;
+	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
+	bool absent;
+	u32 l;
+
+	if (eeepc->wlan_rfkill)
+		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
+
+	mutex_lock(&eeepc->hotplug_lock);
+
+	if (eeepc->hotplug_slot) {
+		bus = pci_find_bus(0, 1);
+		if (!bus) {
+			pr_warning("Unable to find PCI bus 1?\n");
+			goto out_unlock;
+		}
+
+		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
+			pr_err("Unable to read PCI config space?\n");
+			goto out_unlock;
+		}
+		absent = (l == 0xffffffff);
+
+		if (blocked != absent) {
+			pr_warning("BIOS says wireless lan is %s, "
+					"but the pci device is %s\n",
+				blocked ? "blocked" : "unblocked",
+				absent ? "absent" : "present");
+			pr_warning("skipped wireless hotplug as probably "
+					"inappropriate for this model\n");
+			goto out_unlock;
+		}
+
+		if (!blocked) {
+			dev = pci_get_slot(bus, 0);
+			if (dev) {
+				/* Device already present */
+				pci_dev_put(dev);
+				goto out_unlock;
+			}
+			dev = pci_scan_single_device(bus, 0);
+			if (dev) {
+				pci_bus_assign_resources(bus);
+				if (pci_bus_add_device(dev))
+					pr_err("Unable to hotplug wifi\n");
+			}
+		} else {
+			dev = pci_get_slot(bus, 0);
+			if (dev) {
+				pci_remove_bus_device(dev);
+				pci_dev_put(dev);
+			}
+		}
+	}
+
+out_unlock:
+	mutex_unlock(&eeepc->hotplug_lock);
+}
+
+static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct eeepc_wmi *eeepc = data;
+
+	if (event != ACPI_NOTIFY_BUS_CHECK)
+		return;
+
+	eeepc_rfkill_hotplug(eeepc);
+}
+
+static int eeepc_register_rfkill_notifier(struct eeepc_wmi *eeepc,
+					  char *node)
+{
+	acpi_status status;
+	acpi_handle handle;
+
+	status = acpi_get_handle(NULL, node, &handle);
+
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_install_notify_handler(handle,
+						     ACPI_SYSTEM_NOTIFY,
+						     eeepc_rfkill_notify,
+						     eeepc);
+		if (ACPI_FAILURE(status))
+			pr_warning("Failed to register notify on %s\n", node);
+	} else
+		return -ENODEV;
+
+	return 0;
+}
+
+static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi *eeepc,
+					     char *node)
+{
+	acpi_status status = AE_OK;
+	acpi_handle handle;
+
+	status = acpi_get_handle(NULL, node, &handle);
+
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_remove_notify_handler(handle,
+						     ACPI_SYSTEM_NOTIFY,
+						     eeepc_rfkill_notify);
+		if (ACPI_FAILURE(status))
+			pr_err("Error removing rfkill notify handler %s\n",
+				node);
+	}
+}
+
+static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
+				    u8 *value)
+{
+	u32 retval;
+	acpi_status status;
+
+	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	if (!retval || retval == 0x00060000)
+		return -ENODEV;
+	else
+		*value = (retval & 0x1);
+
+	return 0;
+}
+
+static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
+{
+	kfree(hotplug_slot->info);
+	kfree(hotplug_slot);
+}
+
+static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
+	.owner = THIS_MODULE,
+	.get_adapter_status = eeepc_get_adapter_status,
+	.get_power_status = eeepc_get_adapter_status,
+};
+
+static int eeepc_setup_pci_hotplug(struct eeepc_wmi *eeepc)
+{
+	int ret = -ENOMEM;
+	struct pci_bus *bus = pci_find_bus(0, 1);
+
+	if (!bus) {
+		pr_err("Unable to find wifi PCI bus\n");
+		return -ENODEV;
+	}
+
+	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
+	if (!eeepc->hotplug_slot)
+		goto error_slot;
+
+	eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
+					    GFP_KERNEL);
+	if (!eeepc->hotplug_slot->info)
+		goto error_info;
+
+	eeepc->hotplug_slot->private = eeepc;
+	eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
+	eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
+	eeepc_get_adapter_status(eeepc->hotplug_slot,
+				 &eeepc->hotplug_slot->info->adapter_status);
+
+	ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
+	if (ret) {
+		pr_err("Unable to register hotplug slot - %d\n", ret);
+		goto error_register;
+	}
+
+	return 0;
+
+error_register:
+	kfree(eeepc->hotplug_slot->info);
+error_info:
+	kfree(eeepc->hotplug_slot);
+	eeepc->hotplug_slot = NULL;
+error_slot:
+	return ret;
+}
+
+/*
  * Rfkill devices
  */
 static int eeepc_rfkill_set(void *data, bool blocked)
@@ -404,11 +621,22 @@ static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
 
 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
 {
+	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
+	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
+	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
 	if (eeepc->wlan_rfkill) {
 		rfkill_unregister(eeepc->wlan_rfkill);
 		rfkill_destroy(eeepc->wlan_rfkill);
 		eeepc->wlan_rfkill = NULL;
 	}
+	/*
+	 * Refresh pci hotplug in case the rfkill state was changed after
+	 * eeepc_unregister_rfkill_notifier()
+	 */
+	eeepc_rfkill_hotplug(eeepc);
+	if (eeepc->hotplug_slot)
+		pci_hp_deregister(eeepc->hotplug_slot);
+
 	if (eeepc->bluetooth_rfkill) {
 		rfkill_unregister(eeepc->bluetooth_rfkill);
 		rfkill_destroy(eeepc->bluetooth_rfkill);
@@ -425,6 +653,8 @@ static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
 {
 	int result = 0;
 
+	mutex_init(&eeepc->hotplug_lock);
+
 	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
 				  "eeepc-wlan", RFKILL_TYPE_WLAN,
 				  EEEPC_WMI_DEVID_WLAN);
@@ -446,6 +676,23 @@ static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
 	if (result && result != -ENODEV)
 		goto exit;
 
+	result = eeepc_setup_pci_hotplug(eeepc);
+	/*
+	 * If we get -EBUSY then something else is handling the PCI hotplug -
+	 * don't fail in this case
+	 */
+	if (result == -EBUSY)
+		result = 0;
+
+	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
+	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
+	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
+	/*
+	 * Refresh pci hotplug in case the rfkill state was changed during
+	 * setup.
+	 */
+	eeepc_rfkill_hotplug(eeepc);
+
 exit:
 	if (result && result != -ENODEV)
 		eeepc_wmi_rfkill_exit(eeepc);
@@ -771,6 +1018,28 @@ error_debugfs:
 /*
  * WMI Driver
  */
+static void eeepc_dmi_check(struct eeepc_wmi *eeepc)
+{
+	const char *model;
+
+	model = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!model)
+		return;
+
+	/*
+	 * Whitelist for wlan hotplug
+	 *
+	 * Eeepc 1000H needs the current hotplug code to handle
+	 * Fn+F2 correctly. We may add other Eeepc here later, but
+	 * it seems that most of the laptops supported by eeepc-wmi
+	 * don't need to be on this list
+	 */
+	if (strcmp(model, "1000H") == 0) {
+		eeepc->hotplug_wireless = true;
+		pr_info("wlan hotplug enabled\n");
+	}
+}
+
 static struct platform_device * __init eeepc_wmi_add(void)
 {
 	struct eeepc_wmi *eeepc;
@@ -781,6 +1050,9 @@ static struct platform_device * __init eeepc_wmi_add(void)
 	if (!eeepc)
 		return ERR_PTR(-ENOMEM);
 
+	eeepc->hotplug_wireless = hotplug_wireless;
+	eeepc_dmi_check(eeepc);
+
 	/*
 	 * Register the platform device first.  It is used as a parent for the
 	 * sub-devices below.
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/14] eeepc-wmi: serialize access to wmi method
  2011-01-24 16:23 [PATCH 00/14] eeepc-wmi updates Corentin Chary
                   ` (2 preceding siblings ...)
  2011-01-24 16:23 ` [PATCH 03/14] eeepc-wmi: add hotplug code for Eeepc 1000H Corentin Chary
@ 2011-01-24 16:23 ` Corentin Chary
  2011-01-24 16:23   ` Corentin Chary
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

\AMW0.WMBC, which is the main method that we use,
is not reentrant. When wireless hotpluging is enabled,
toggling the status of the wireless device using WMBC will
trigger a notification and the notification handler need to
call WMBC again to get the new status of the device, this
will trigger the following error:

ACPI Error (dswload-0802): [_T_0] Namespace lookup failure, AE_ALREADY_EXISTS
ACPI Exception: AE_ALREADY_EXISTS, During name lookup/catalog (20100428/psloop-231)
ACPI Error (psparse-0537): Method parse/execution failed [\AMW0.WMBC] (Node f7023b88), AE_ALREADY_EXISTS
ACPI: Marking method WMBC as Serialized because of AE_ALREADY_EXISTS error

Since there is currently no way to tell the acpi subsystem to mark
a method as serialized, we do it in eeepc-wmi.

Of course, we could let the first call fail, and then it would work,
but it doesn't seems really clean, and it will make the first
WMBC call return a random value.

This patch was tested on EeePc 1000H with a RaLink RT2860
wireless card using the rt2800pci driver. rt2860sta driver
seems to deadlock when we remove the pci device...

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   78 +++++++++++++++++++++++++++++++++++---
 1 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 01bc2b3..eb4c0ce 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -137,6 +137,9 @@ struct eeepc_wmi {
 
 	struct hotplug_slot *hotplug_slot;
 	struct mutex hotplug_lock;
+	struct mutex wmi_lock;
+	struct workqueue_struct *hotplug_workqueue;
+	struct work_struct hotplug_work;
 
 	struct eeepc_wmi_debug debug;
 };
@@ -370,15 +373,19 @@ static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
 {
 	struct pci_dev *dev;
 	struct pci_bus *bus;
-	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
+	bool blocked;
 	bool absent;
 	u32 l;
 
-	if (eeepc->wlan_rfkill)
-		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
+	mutex_lock(&eeepc->wmi_lock);
+	blocked = eeepc_wlan_rfkill_blocked(eeepc);
+	mutex_unlock(&eeepc->wmi_lock);
 
 	mutex_lock(&eeepc->hotplug_lock);
 
+	if (eeepc->wlan_rfkill)
+		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
+
 	if (eeepc->hotplug_slot) {
 		bus = pci_find_bus(0, 1);
 		if (!bus) {
@@ -435,7 +442,14 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 	if (event != ACPI_NOTIFY_BUS_CHECK)
 		return;
 
-	eeepc_rfkill_hotplug(eeepc);
+	/*
+	 * We can't call directly eeepc_rfkill_hotplug because most
+	 * of the time WMBC is still being executed and not reetrant.
+	 * There is currently no way to tell ACPICA that  we want this
+	 * method to be serialized, we schedule a eeepc_rfkill_hotplug
+	 * call later, in a safer context.
+	 */
+	queue_work(eeepc->hotplug_workqueue, &eeepc->hotplug_work);
 }
 
 static int eeepc_register_rfkill_notifier(struct eeepc_wmi *eeepc,
@@ -508,6 +522,14 @@ static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
 	.get_power_status = eeepc_get_adapter_status,
 };
 
+static void eeepc_hotplug_work(struct work_struct *work)
+{
+	struct eeepc_wmi *eeepc;
+
+	eeepc = container_of(work, struct eeepc_wmi, hotplug_work);
+	eeepc_rfkill_hotplug(eeepc);
+}
+
 static int eeepc_setup_pci_hotplug(struct eeepc_wmi *eeepc)
 {
 	int ret = -ENOMEM;
@@ -518,6 +540,13 @@ static int eeepc_setup_pci_hotplug(struct eeepc_wmi *eeepc)
 		return -ENODEV;
 	}
 
+	eeepc->hotplug_workqueue =
+		create_singlethread_workqueue("hotplug_workqueue");
+	if (!eeepc->hotplug_workqueue)
+		goto error_workqueue;
+
+	INIT_WORK(&eeepc->hotplug_work, eeepc_hotplug_work);
+
 	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
 	if (!eeepc->hotplug_slot)
 		goto error_slot;
@@ -547,6 +576,8 @@ error_info:
 	kfree(eeepc->hotplug_slot);
 	eeepc->hotplug_slot = NULL;
 error_slot:
+	destroy_workqueue(eeepc->hotplug_workqueue);
+error_workqueue:
 	return ret;
 }
 
@@ -575,6 +606,34 @@ static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
 	rfkill_set_sw_state(rfkill, !(retval & 0x1));
 }
 
+static int eeepc_rfkill_wlan_set(void *data, bool blocked)
+{
+	struct eeepc_wmi *eeepc = data;
+	int ret;
+
+	/*
+	 * This handler is enabled only if hotplug is enabled.
+	 * In this case, the eeepc_wmi_set_devstate() will
+	 * trigger a wmi notification and we need to wait
+	 * this call to finish before being able to call
+	 * any wmi method
+	 */
+	mutex_lock(&eeepc->wmi_lock);
+	ret = eeepc_rfkill_set((void *)(long)EEEPC_WMI_DEVID_WLAN, blocked);
+	mutex_unlock(&eeepc->wmi_lock);
+	return ret;
+}
+
+static void eeepc_rfkill_wlan_query(struct rfkill *rfkill, void *data)
+{
+	eeepc_rfkill_query(rfkill, (void *)(long)EEEPC_WMI_DEVID_WLAN);
+}
+
+static const struct rfkill_ops eeepc_rfkill_wlan_ops = {
+	.set_block = eeepc_rfkill_wlan_set,
+	.query = eeepc_rfkill_wlan_query,
+};
+
 static const struct rfkill_ops eeepc_rfkill_ops = {
 	.set_block = eeepc_rfkill_set,
 	.query = eeepc_rfkill_query,
@@ -603,8 +662,12 @@ static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
 	if (!retval || retval == 0x00060000)
 		return -ENODEV;
 
-	*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
-			       &eeepc_rfkill_ops, (void *)(long)dev_id);
+	if (dev_id == EEEPC_WMI_DEVID_WLAN && eeepc->hotplug_wireless)
+		*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
+				       &eeepc_rfkill_wlan_ops, eeepc);
+	else
+		*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
+				       &eeepc_rfkill_ops, (void *)(long)dev_id);
 
 	if (!*rfkill)
 		return -EINVAL;
@@ -636,6 +699,8 @@ static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
 	eeepc_rfkill_hotplug(eeepc);
 	if (eeepc->hotplug_slot)
 		pci_hp_deregister(eeepc->hotplug_slot);
+	if (eeepc->hotplug_workqueue)
+		destroy_workqueue(eeepc->hotplug_workqueue);
 
 	if (eeepc->bluetooth_rfkill) {
 		rfkill_unregister(eeepc->bluetooth_rfkill);
@@ -654,6 +719,7 @@ static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
 	int result = 0;
 
 	mutex_init(&eeepc->hotplug_lock);
+	mutex_init(&eeepc->wmi_lock);
 
 	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
 				  "eeepc-wlan", RFKILL_TYPE_WLAN,
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/14] eeepc-wmi: return proper error code in eeepc_rfkill_set()
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index eb4c0ce..d823458 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -588,8 +588,14 @@ static int eeepc_rfkill_set(void *data, bool blocked)
 {
 	int dev_id = (unsigned long)data;
 	u32 ctrl_param = !blocked;
+	acpi_status status;
+
+	status = eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
 
-	return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
+	return 0;
 }
 
 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/14] eeepc-wmi: return proper error code in eeepc_rfkill_set()
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index eb4c0ce..d823458 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -588,8 +588,14 @@ static int eeepc_rfkill_set(void *data, bool blocked)
 {
 	int dev_id = (unsigned long)data;
 	u32 ctrl_param = !blocked;
+	acpi_status status;
+
+	status = eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
 
-	return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
+	return 0;
 }
 
 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/14] eeepc-wmi: add an helper using simple return codes
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

eeepc_wmi_get_devstate returns an acpi_status, so each
call need extra logic to handle the return code. This
patch add a simple getter, returning a boolean (or a
negative error code).

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   96 +++++++++++++++----------------------
 1 files changed, 39 insertions(+), 57 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index d823458..de501fb 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -257,6 +257,29 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
 	return status;
 }
 
+/* Helper for special devices with magic return codes */
+static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+{
+	u32 retval = 0;
+	acpi_status status;
+
+	status = eeepc_wmi_get_devstate(dev_id, &retval);
+
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+
+	/* If the device is present, DSTS will always set some bits
+	 * 0x00070000 - 1110000000000000000 - device supported
+	 * 0x00060000 - 1100000000000000000 - not supported
+	 * 0x00020000 - 0100000000000000000 - device supported
+	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
+	 */
+	if (!retval || retval == 0x00060000)
+		return -ENODEV;
+
+	return retval & 0x1;
+}
+
 /*
  * LEDs
  */
@@ -290,23 +313,7 @@ static void tpd_led_set(struct led_classdev *led_cdev,
 
 static int read_tpd_state(struct eeepc_wmi *eeepc)
 {
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval);
-
-	if (ACPI_FAILURE(status))
-		return -1;
-	else if (!retval || retval == 0x00060000)
-		/*
-		 * if touchpad led is present, DSTS will set some bits,
-		 * usually 0x00020000.
-		 * 0x00060000 means that the device is not supported
-		 */
-		return -ENODEV;
-	else
-		/* Status is stored in the first bit */
-		return retval & 0x1;
+	return eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_TPDLED);
 }
 
 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
@@ -358,15 +365,11 @@ static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
  */
 static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi *eeepc)
 {
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
+	int result = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
 
-	if (ACPI_FAILURE(status))
+	if (result < 0)
 		return false;
-
-	return !(retval & 0x1);
+	return !result;
 }
 
 static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
@@ -494,19 +497,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi *eeepc,
 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
 				    u8 *value)
 {
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
-
-	if (ACPI_FAILURE(status))
-		return -EIO;
+	int result = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
 
-	if (!retval || retval == 0x00060000)
-		return -ENODEV;
-	else
-		*value = (retval & 0x1);
+	if (result < 0)
+		return result;
 
+	*value = !!result;
 	return 0;
 }
 
@@ -601,15 +597,14 @@ static int eeepc_rfkill_set(void *data, bool blocked)
 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
 {
 	int dev_id = (unsigned long)data;
-	u32 retval;
-	acpi_status status;
+	int result;
 
-	status = eeepc_wmi_get_devstate(dev_id, &retval);
+	result = eeepc_wmi_get_devstate_simple(dev_id);
 
-	if (ACPI_FAILURE(status))
+	if (result < 0)
 		return ;
 
-	rfkill_set_sw_state(rfkill, !(retval & 0x1));
+	rfkill_set_sw_state(rfkill, !result);
 }
 
 static int eeepc_rfkill_wlan_set(void *data, bool blocked)
@@ -650,23 +645,10 @@ static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
 			    const char *name,
 			    enum rfkill_type type, int dev_id)
 {
-	int result;
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(dev_id, &retval);
+	int result = eeepc_wmi_get_devstate_simple(dev_id);
 
-	if (ACPI_FAILURE(status))
-		return -1;
-
-	/* If the device is present, DSTS will always set some bits
-	 * 0x00070000 - 1110000000000000000 - device supported
-	 * 0x00060000 - 1100000000000000000 - not supported
-	 * 0x00020000 - 0100000000000000000 - device supported
-	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
-	 */
-	if (!retval || retval == 0x00060000)
-		return -ENODEV;
+	if (result < 0)
+		return result;
 
 	if (dev_id == EEEPC_WMI_DEVID_WLAN && eeepc->hotplug_wireless)
 		*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
@@ -678,7 +660,7 @@ static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
 	if (!*rfkill)
 		return -EINVAL;
 
-	rfkill_init_sw_state(*rfkill, !(retval & 0x1));
+	rfkill_init_sw_state(*rfkill, !result);
 	result = rfkill_register(*rfkill);
 	if (result) {
 		rfkill_destroy(*rfkill);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/14] eeepc-wmi: add an helper using simple return codes
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

eeepc_wmi_get_devstate returns an acpi_status, so each
call need extra logic to handle the return code. This
patch add a simple getter, returning a boolean (or a
negative error code).

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   96 +++++++++++++++----------------------
 1 files changed, 39 insertions(+), 57 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index d823458..de501fb 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -257,6 +257,29 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
 	return status;
 }
 
+/* Helper for special devices with magic return codes */
+static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+{
+	u32 retval = 0;
+	acpi_status status;
+
+	status = eeepc_wmi_get_devstate(dev_id, &retval);
+
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+
+	/* If the device is present, DSTS will always set some bits
+	 * 0x00070000 - 1110000000000000000 - device supported
+	 * 0x00060000 - 1100000000000000000 - not supported
+	 * 0x00020000 - 0100000000000000000 - device supported
+	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
+	 */
+	if (!retval || retval == 0x00060000)
+		return -ENODEV;
+
+	return retval & 0x1;
+}
+
 /*
  * LEDs
  */
@@ -290,23 +313,7 @@ static void tpd_led_set(struct led_classdev *led_cdev,
 
 static int read_tpd_state(struct eeepc_wmi *eeepc)
 {
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval);
-
-	if (ACPI_FAILURE(status))
-		return -1;
-	else if (!retval || retval == 0x00060000)
-		/*
-		 * if touchpad led is present, DSTS will set some bits,
-		 * usually 0x00020000.
-		 * 0x00060000 means that the device is not supported
-		 */
-		return -ENODEV;
-	else
-		/* Status is stored in the first bit */
-		return retval & 0x1;
+	return eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_TPDLED);
 }
 
 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
@@ -358,15 +365,11 @@ static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
  */
 static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi *eeepc)
 {
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
+	int result = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
 
-	if (ACPI_FAILURE(status))
+	if (result < 0)
 		return false;
-
-	return !(retval & 0x1);
+	return !result;
 }
 
 static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
@@ -494,19 +497,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi *eeepc,
 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
 				    u8 *value)
 {
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
-
-	if (ACPI_FAILURE(status))
-		return -EIO;
+	int result = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
 
-	if (!retval || retval == 0x00060000)
-		return -ENODEV;
-	else
-		*value = (retval & 0x1);
+	if (result < 0)
+		return result;
 
+	*value = !!result;
 	return 0;
 }
 
@@ -601,15 +597,14 @@ static int eeepc_rfkill_set(void *data, bool blocked)
 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
 {
 	int dev_id = (unsigned long)data;
-	u32 retval;
-	acpi_status status;
+	int result;
 
-	status = eeepc_wmi_get_devstate(dev_id, &retval);
+	result = eeepc_wmi_get_devstate_simple(dev_id);
 
-	if (ACPI_FAILURE(status))
+	if (result < 0)
 		return ;
 
-	rfkill_set_sw_state(rfkill, !(retval & 0x1));
+	rfkill_set_sw_state(rfkill, !result);
 }
 
 static int eeepc_rfkill_wlan_set(void *data, bool blocked)
@@ -650,23 +645,10 @@ static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
 			    const char *name,
 			    enum rfkill_type type, int dev_id)
 {
-	int result;
-	u32 retval;
-	acpi_status status;
-
-	status = eeepc_wmi_get_devstate(dev_id, &retval);
+	int result = eeepc_wmi_get_devstate_simple(dev_id);
 
-	if (ACPI_FAILURE(status))
-		return -1;
-
-	/* If the device is present, DSTS will always set some bits
-	 * 0x00070000 - 1110000000000000000 - device supported
-	 * 0x00060000 - 1100000000000000000 - not supported
-	 * 0x00020000 - 0100000000000000000 - device supported
-	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
-	 */
-	if (!retval || retval == 0x00060000)
-		return -ENODEV;
+	if (result < 0)
+		return result;
 
 	if (dev_id == EEEPC_WMI_DEVID_WLAN && eeepc->hotplug_wireless)
 		*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
@@ -678,7 +660,7 @@ static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
 	if (!*rfkill)
 		return -EINVAL;
 
-	rfkill_init_sw_state(*rfkill, !(retval & 0x1));
+	rfkill_init_sw_state(*rfkill, !result);
 	result = rfkill_register(*rfkill);
 	if (result) {
 		rfkill_destroy(*rfkill);
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/14] eeepc-wmi: add hibernate/resume callbacks
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   49 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index de501fb..583ba78 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -1183,10 +1183,59 @@ static int eeepc_wmi_remove(struct platform_device *device)
 	return 0;
 }
 
+/*
+ * Platform driver - hibernate/resume callbacks
+ */
+static int eeepc_hotk_thaw(struct device *device)
+{
+	struct eeepc_wmi *eeepc = dev_get_drvdata(device);
+
+	if (eeepc->wlan_rfkill) {
+		bool wlan;
+
+		/*
+		 * Work around bios bug - acpi _PTS turns off the wireless led
+		 * during suspend.  Normally it restores it on resume, but
+		 * we should kick it ourselves in case hibernation is aborted.
+		 */
+		wlan = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
+		eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_WLAN, wlan, NULL);
+	}
+
+	return 0;
+}
+
+static int eeepc_hotk_restore(struct device *device)
+{
+	struct eeepc_wmi *eeepc = dev_get_drvdata(device);
+	int bl;
+
+	/* Refresh both wlan rfkill state and pci hotplug */
+	if (eeepc->wlan_rfkill)
+		eeepc_rfkill_hotplug(eeepc);
+
+	if (eeepc->bluetooth_rfkill) {
+		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BLUETOOTH);
+		rfkill_set_sw_state(eeepc->bluetooth_rfkill, bl);
+}
+	if (eeepc->wwan3g_rfkill) {
+		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WWAN3G);
+		rfkill_set_sw_state(eeepc->wwan3g_rfkill, bl);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops eeepc_pm_ops = {
+	.thaw = eeepc_hotk_thaw,
+	.restore = eeepc_hotk_restore,
+};
+
 static struct platform_driver platform_driver = {
 	.driver = {
 		.name = EEEPC_WMI_FILE,
 		.owner = THIS_MODULE,
+		.pm = &eeepc_pm_ops,
 	},
 };
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/14] eeepc-wmi: add hibernate/resume callbacks
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   49 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index de501fb..583ba78 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -1183,10 +1183,59 @@ static int eeepc_wmi_remove(struct platform_device *device)
 	return 0;
 }
 
+/*
+ * Platform driver - hibernate/resume callbacks
+ */
+static int eeepc_hotk_thaw(struct device *device)
+{
+	struct eeepc_wmi *eeepc = dev_get_drvdata(device);
+
+	if (eeepc->wlan_rfkill) {
+		bool wlan;
+
+		/*
+		 * Work around bios bug - acpi _PTS turns off the wireless led
+		 * during suspend.  Normally it restores it on resume, but
+		 * we should kick it ourselves in case hibernation is aborted.
+		 */
+		wlan = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
+		eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_WLAN, wlan, NULL);
+	}
+
+	return 0;
+}
+
+static int eeepc_hotk_restore(struct device *device)
+{
+	struct eeepc_wmi *eeepc = dev_get_drvdata(device);
+	int bl;
+
+	/* Refresh both wlan rfkill state and pci hotplug */
+	if (eeepc->wlan_rfkill)
+		eeepc_rfkill_hotplug(eeepc);
+
+	if (eeepc->bluetooth_rfkill) {
+		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BLUETOOTH);
+		rfkill_set_sw_state(eeepc->bluetooth_rfkill, bl);
+}
+	if (eeepc->wwan3g_rfkill) {
+		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WWAN3G);
+		rfkill_set_sw_state(eeepc->wwan3g_rfkill, bl);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops eeepc_pm_ops = {
+	.thaw = eeepc_hotk_thaw,
+	.restore = eeepc_hotk_restore,
+};
+
 static struct platform_driver platform_driver = {
 	.driver = {
 		.name = EEEPC_WMI_FILE,
 		.owner = THIS_MODULE,
+		.pm = &eeepc_pm_ops,
 	},
 };
 
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/14] eeepc-wmi: switch to platform_create_bundle()
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

This allow to remove ~30 lines of code.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   75 +++++++++++---------------------------
 1 files changed, 22 insertions(+), 53 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 583ba78..1fc191b 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -144,9 +144,6 @@ struct eeepc_wmi {
 	struct eeepc_wmi_debug debug;
 };
 
-/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
-static struct platform_device *platform_device;
-
 static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
 {
 	int err;
@@ -932,33 +929,12 @@ static int eeepc_wmi_sysfs_init(struct platform_device *device)
  */
 static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
 {
-	int err;
-
-	eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
-	if (!eeepc->platform_device)
-		return -ENOMEM;
-	platform_set_drvdata(eeepc->platform_device, eeepc);
-
-	err = platform_device_add(eeepc->platform_device);
-	if (err)
-		goto fail_platform_device;
-
-	err = eeepc_wmi_sysfs_init(eeepc->platform_device);
-	if (err)
-		goto fail_sysfs;
-	return 0;
-
-fail_sysfs:
-	platform_device_del(eeepc->platform_device);
-fail_platform_device:
-	platform_device_put(eeepc->platform_device);
-	return err;
+	return eeepc_wmi_sysfs_init(eeepc->platform_device);
 }
 
 static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
 {
 	eeepc_wmi_sysfs_exit(eeepc->platform_device);
-	platform_device_unregister(eeepc->platform_device);
 }
 
 /*
@@ -1094,7 +1070,7 @@ static void eeepc_dmi_check(struct eeepc_wmi *eeepc)
 	}
 }
 
-static struct platform_device * __init eeepc_wmi_add(void)
+static int __init eeepc_wmi_add(struct platform_device *pdev)
 {
 	struct eeepc_wmi *eeepc;
 	acpi_status status;
@@ -1102,15 +1078,14 @@ static struct platform_device * __init eeepc_wmi_add(void)
 
 	eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
 	if (!eeepc)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
+
+	eeepc->platform_device = pdev;
+	platform_set_drvdata(eeepc->platform_device, eeepc);
 
 	eeepc->hotplug_wireless = hotplug_wireless;
 	eeepc_dmi_check(eeepc);
 
-	/*
-	 * Register the platform device first.  It is used as a parent for the
-	 * sub-devices below.
-	 */
 	err = eeepc_wmi_platform_init(eeepc);
 	if (err)
 		goto fail_platform;
@@ -1147,7 +1122,7 @@ static struct platform_device * __init eeepc_wmi_add(void)
 	if (err)
 		goto fail_debugfs;
 
-	return eeepc->platform_device;
+	return 0;
 
 fail_debugfs:
 	wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
@@ -1163,10 +1138,10 @@ fail_input:
 	eeepc_wmi_platform_exit(eeepc);
 fail_platform:
 	kfree(eeepc);
-	return ERR_PTR(err);
+	return err;
 }
 
-static int eeepc_wmi_remove(struct platform_device *device)
+static int __exit eeepc_wmi_remove(struct platform_device *device)
 {
 	struct eeepc_wmi *eeepc;
 
@@ -1232,6 +1207,7 @@ static const struct dev_pm_ops eeepc_pm_ops = {
 };
 
 static struct platform_driver platform_driver = {
+	.remove = __exit_p(eeepc_wmi_remove),
 	.driver = {
 		.name = EEEPC_WMI_FILE,
 		.owner = THIS_MODULE,
@@ -1260,10 +1236,8 @@ static int __init eeepc_wmi_check_atkd(void)
 	return -1;
 }
 
-static int __init eeepc_wmi_init(void)
+static int __init eeepc_wmi_probe(struct platform_device *pdev)
 {
-	int err;
-
 	if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
 	    !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
 		pr_warning("No known WMI GUID found\n");
@@ -1280,29 +1254,24 @@ static int __init eeepc_wmi_init(void)
 		return -ENODEV;
 	}
 
-	platform_device = eeepc_wmi_add();
-	if (IS_ERR(platform_device)) {
-		err = PTR_ERR(platform_device);
-		goto fail_eeepc_wmi;
-	}
+	return eeepc_wmi_add(pdev);
+}
 
-	err = platform_driver_register(&platform_driver);
-	if (err) {
-		pr_warning("Unable to register platform driver\n");
-		goto fail_platform_driver;
-	}
+static struct platform_device *platform_device;
 
+static int __init eeepc_wmi_init(void)
+{
+	platform_device = platform_create_bundle(&platform_driver,
+						 eeepc_wmi_probe,
+						 NULL, 0, NULL, 0);
+	if (IS_ERR(platform_device))
+		return PTR_ERR(platform_device);
 	return 0;
-
-fail_platform_driver:
-	eeepc_wmi_remove(platform_device);
-fail_eeepc_wmi:
-	return err;
 }
 
 static void __exit eeepc_wmi_exit(void)
 {
-	eeepc_wmi_remove(platform_device);
+	platform_device_unregister(platform_device);
 	platform_driver_unregister(&platform_driver);
 }
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/14] eeepc-wmi: switch to platform_create_bundle()
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

This allow to remove ~30 lines of code.

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   75 +++++++++++---------------------------
 1 files changed, 22 insertions(+), 53 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 583ba78..1fc191b 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -144,9 +144,6 @@ struct eeepc_wmi {
 	struct eeepc_wmi_debug debug;
 };
 
-/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
-static struct platform_device *platform_device;
-
 static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
 {
 	int err;
@@ -932,33 +929,12 @@ static int eeepc_wmi_sysfs_init(struct platform_device *device)
  */
 static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
 {
-	int err;
-
-	eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
-	if (!eeepc->platform_device)
-		return -ENOMEM;
-	platform_set_drvdata(eeepc->platform_device, eeepc);
-
-	err = platform_device_add(eeepc->platform_device);
-	if (err)
-		goto fail_platform_device;
-
-	err = eeepc_wmi_sysfs_init(eeepc->platform_device);
-	if (err)
-		goto fail_sysfs;
-	return 0;
-
-fail_sysfs:
-	platform_device_del(eeepc->platform_device);
-fail_platform_device:
-	platform_device_put(eeepc->platform_device);
-	return err;
+	return eeepc_wmi_sysfs_init(eeepc->platform_device);
 }
 
 static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
 {
 	eeepc_wmi_sysfs_exit(eeepc->platform_device);
-	platform_device_unregister(eeepc->platform_device);
 }
 
 /*
@@ -1094,7 +1070,7 @@ static void eeepc_dmi_check(struct eeepc_wmi *eeepc)
 	}
 }
 
-static struct platform_device * __init eeepc_wmi_add(void)
+static int __init eeepc_wmi_add(struct platform_device *pdev)
 {
 	struct eeepc_wmi *eeepc;
 	acpi_status status;
@@ -1102,15 +1078,14 @@ static struct platform_device * __init eeepc_wmi_add(void)
 
 	eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
 	if (!eeepc)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
+
+	eeepc->platform_device = pdev;
+	platform_set_drvdata(eeepc->platform_device, eeepc);
 
 	eeepc->hotplug_wireless = hotplug_wireless;
 	eeepc_dmi_check(eeepc);
 
-	/*
-	 * Register the platform device first.  It is used as a parent for the
-	 * sub-devices below.
-	 */
 	err = eeepc_wmi_platform_init(eeepc);
 	if (err)
 		goto fail_platform;
@@ -1147,7 +1122,7 @@ static struct platform_device * __init eeepc_wmi_add(void)
 	if (err)
 		goto fail_debugfs;
 
-	return eeepc->platform_device;
+	return 0;
 
 fail_debugfs:
 	wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
@@ -1163,10 +1138,10 @@ fail_input:
 	eeepc_wmi_platform_exit(eeepc);
 fail_platform:
 	kfree(eeepc);
-	return ERR_PTR(err);
+	return err;
 }
 
-static int eeepc_wmi_remove(struct platform_device *device)
+static int __exit eeepc_wmi_remove(struct platform_device *device)
 {
 	struct eeepc_wmi *eeepc;
 
@@ -1232,6 +1207,7 @@ static const struct dev_pm_ops eeepc_pm_ops = {
 };
 
 static struct platform_driver platform_driver = {
+	.remove = __exit_p(eeepc_wmi_remove),
 	.driver = {
 		.name = EEEPC_WMI_FILE,
 		.owner = THIS_MODULE,
@@ -1260,10 +1236,8 @@ static int __init eeepc_wmi_check_atkd(void)
 	return -1;
 }
 
-static int __init eeepc_wmi_init(void)
+static int __init eeepc_wmi_probe(struct platform_device *pdev)
 {
-	int err;
-
 	if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
 	    !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
 		pr_warning("No known WMI GUID found\n");
@@ -1280,29 +1254,24 @@ static int __init eeepc_wmi_init(void)
 		return -ENODEV;
 	}
 
-	platform_device = eeepc_wmi_add();
-	if (IS_ERR(platform_device)) {
-		err = PTR_ERR(platform_device);
-		goto fail_eeepc_wmi;
-	}
+	return eeepc_wmi_add(pdev);
+}
 
-	err = platform_driver_register(&platform_driver);
-	if (err) {
-		pr_warning("Unable to register platform driver\n");
-		goto fail_platform_driver;
-	}
+static struct platform_device *platform_device;
 
+static int __init eeepc_wmi_init(void)
+{
+	platform_device = platform_create_bundle(&platform_driver,
+						 eeepc_wmi_probe,
+						 NULL, 0, NULL, 0);
+	if (IS_ERR(platform_device))
+		return PTR_ERR(platform_device);
 	return 0;
-
-fail_platform_driver:
-	eeepc_wmi_remove(platform_device);
-fail_eeepc_wmi:
-	return err;
 }
 
 static void __exit eeepc_wmi_exit(void)
 {
-	eeepc_wmi_remove(platform_device);
+	platform_device_unregister(platform_device);
 	platform_driver_unregister(&platform_driver);
 }
 
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/14] eeepc-wmi: reorder defines
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 1fc191b..aa9e1d1 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -60,20 +60,20 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
 MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 
-#define NOTIFY_BRNUP_MIN	0x11
-#define NOTIFY_BRNUP_MAX	0x1f
-#define NOTIFY_BRNDOWN_MIN	0x20
-#define NOTIFY_BRNDOWN_MAX	0x2e
+#define NOTIFY_BRNUP_MIN		0x11
+#define NOTIFY_BRNUP_MAX		0x1f
+#define NOTIFY_BRNDOWN_MIN		0x20
+#define NOTIFY_BRNDOWN_MAX		0x2e
 
-#define EEEPC_WMI_METHODID_DEVS	0x53564544
-#define EEEPC_WMI_METHODID_DSTS	0x53544344
-#define EEEPC_WMI_METHODID_CFVS	0x53564643
+#define EEEPC_WMI_METHODID_DSTS		0x53544344
+#define EEEPC_WMI_METHODID_DEVS		0x53564544
+#define EEEPC_WMI_METHODID_CFVS		0x53564643
 
-#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
-#define EEEPC_WMI_DEVID_TPDLED		0x00100011
 #define EEEPC_WMI_DEVID_WLAN		0x00010011
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
+#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 static bool hotplug_wireless;
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/14] eeepc-wmi: reorder defines
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 1fc191b..aa9e1d1 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -60,20 +60,20 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
 MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 
-#define NOTIFY_BRNUP_MIN	0x11
-#define NOTIFY_BRNUP_MAX	0x1f
-#define NOTIFY_BRNDOWN_MIN	0x20
-#define NOTIFY_BRNDOWN_MAX	0x2e
+#define NOTIFY_BRNUP_MIN		0x11
+#define NOTIFY_BRNUP_MAX		0x1f
+#define NOTIFY_BRNDOWN_MIN		0x20
+#define NOTIFY_BRNDOWN_MAX		0x2e
 
-#define EEEPC_WMI_METHODID_DEVS	0x53564544
-#define EEEPC_WMI_METHODID_DSTS	0x53544344
-#define EEEPC_WMI_METHODID_CFVS	0x53564643
+#define EEEPC_WMI_METHODID_DSTS		0x53544344
+#define EEEPC_WMI_METHODID_DEVS		0x53564544
+#define EEEPC_WMI_METHODID_CFVS		0x53564643
 
-#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
-#define EEEPC_WMI_DEVID_TPDLED		0x00100011
 #define EEEPC_WMI_DEVID_WLAN		0x00010011
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
+#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 static bool hotplug_wireless;
 
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/14] eeepc-wmi: use the presence bit correctly
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

I checked some more DSDT, and it seems that I wasn't
totally right about the meaning of DSTS return value.
Bit 0 is clearly the status of the device, and I discovered
that bit 16 is set when the device is present.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index aa9e1d1..391c32b 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -75,6 +75,9 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
+#define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
+#define EEEPC_WMI_DSTS_PRESENCE_BIT	0x00010000
+
 static bool hotplug_wireless;
 
 module_param(hotplug_wireless, bool, 0444);
@@ -265,16 +268,10 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
 	if (ACPI_FAILURE(status))
 		return -EINVAL;
 
-	/* If the device is present, DSTS will always set some bits
-	 * 0x00070000 - 1110000000000000000 - device supported
-	 * 0x00060000 - 1100000000000000000 - not supported
-	 * 0x00020000 - 0100000000000000000 - device supported
-	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
-	 */
-	if (!retval || retval == 0x00060000)
+	if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
 		return -ENODEV;
 
-	return retval & 0x1;
+	return retval & EEEPC_WMI_DSTS_STATUS_BIT;
 }
 
 /*
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/14] eeepc-wmi: use the presence bit correctly
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

I checked some more DSDT, and it seems that I wasn't
totally right about the meaning of DSTS return value.
Bit 0 is clearly the status of the device, and I discovered
that bit 16 is set when the device is present.

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index aa9e1d1..391c32b 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -75,6 +75,9 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
+#define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
+#define EEEPC_WMI_DSTS_PRESENCE_BIT	0x00010000
+
 static bool hotplug_wireless;
 
 module_param(hotplug_wireless, bool, 0444);
@@ -265,16 +268,10 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
 	if (ACPI_FAILURE(status))
 		return -EINVAL;
 
-	/* If the device is present, DSTS will always set some bits
-	 * 0x00070000 - 1110000000000000000 - device supported
-	 * 0x00060000 - 1100000000000000000 - not supported
-	 * 0x00020000 - 0100000000000000000 - device supported
-	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
-	 */
-	if (!retval || retval == 0x00060000)
+	if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
 		return -ENODEV;
 
-	return retval & 0x1;
+	return retval & EEEPC_WMI_DSTS_STATUS_BIT;
 }
 
 /*
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/14] eeepc-wmi: add camera and card reader support
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 Documentation/ABI/testing/sysfs-platform-eeepc-wmi |   14 +++
 drivers/platform/x86/eeepc-wmi.c                   |   89 +++++++++++++++++++-
 2 files changed, 102 insertions(+), 1 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
index e4b5fef..9fc8d33 100644
--- a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
@@ -8,3 +8,17 @@ Description:
 		    * 0 -> Super Performance Mode
 		    * 1 -> High Performance Mode
 		    * 2 -> Power Saving Mode
+
+What:		/sys/devices/platform/eeepc-wmi/camera
+Date:		Jan 2010
+KernelVersion:	2.6.39
+Contact:	"Corentin Chary" <corentincj@iksaif.net>
+Description:
+		Control the camera. 1 means on, 0 means off.
+
+What:		/sys/devices/platform/eeepc-wmi/cardr
+Date:		Jan 2010
+KernelVersion:	2.6.39
+Contact:	"Corentin Chary" <corentincj@iksaif.net>
+Description:
+		Control the card reader. 1 means on, 0 means off.
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 391c32b..83415dd 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -73,6 +73,8 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
 #define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_CAMERA		0x00060013
+#define EEEPC_WMI_DEVID_CARDREADER	0x00080013
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 #define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
@@ -879,6 +881,70 @@ static void eeepc_wmi_notify(u32 value, void *context)
 	kfree(obj);
 }
 
+/*
+ * Sys helpers
+ */
+static int parse_arg(const char *buf, unsigned long count, int *val)
+{
+	if (!count)
+		return 0;
+	if (sscanf(buf, "%i", val) != 1)
+		return -EINVAL;
+	return count;
+}
+
+static ssize_t store_sys_wmi(int devid, const char *buf, size_t count)
+{
+	acpi_status status;
+	u32 retval;
+	int rv, value;
+
+	value = eeepc_wmi_get_devstate_simple(devid);
+	if (value == -ENODEV) /* Check device presence */
+		return value;
+
+	rv = parse_arg(buf, count, &value);
+	status = eeepc_wmi_set_devstate(devid, value, &retval);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+	return rv;
+}
+
+static ssize_t show_sys_wmi(int devid, char *buf)
+{
+	int value = eeepc_wmi_get_devstate_simple(devid);
+
+	if (value < 0)
+		return value;
+
+	return sprintf(buf, "%d\n", value);
+}
+
+#define EEEPC_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm)			\
+	static ssize_t show_##_name(struct device *dev,			\
+				    struct device_attribute *attr,	\
+				    char *buf)				\
+	{								\
+		return show_sys_wmi(_cm, buf);				\
+	}								\
+	static ssize_t store_##_name(struct device *dev,		\
+				     struct device_attribute *attr,	\
+				     const char *buf, size_t count)	\
+	{								\
+		return store_sys_wmi(_cm, buf, count);			\
+	}								\
+	static struct device_attribute dev_attr_##_name = {		\
+		.attr = {						\
+			.name = __stringify(_name),			\
+			.mode = _mode },				\
+		.show   = show_##_name,					\
+		.store  = store_##_name,				\
+	}
+
+EEEPC_WMI_CREATE_DEVICE_ATTR(camera, 0644, EEEPC_WMI_DEVID_CAMERA);
+EEEPC_WMI_CREATE_DEVICE_ATTR(cardr, 0644, EEEPC_WMI_DEVID_CARDREADER);
+
 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
@@ -904,11 +970,32 @@ static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
 
 static struct attribute *platform_attributes[] = {
 	&dev_attr_cpufv.attr,
+	&dev_attr_camera.attr,
+	&dev_attr_cardr.attr,
 	NULL
 };
 
+static mode_t eeepc_sysfs_is_visible(struct kobject *kobj,
+				     struct attribute *attr,
+				     int idx)
+{
+	bool supported = true;
+	int devid = -1;
+
+	if (attr == &dev_attr_camera.attr)
+		devid = EEEPC_WMI_DEVID_CAMERA;
+	else if (attr == &dev_attr_cardr.attr)
+		devid = EEEPC_WMI_DEVID_CARDREADER;
+
+	if (devid != -1)
+		supported = eeepc_wmi_get_devstate_simple(devid) != -ENODEV;
+
+	return supported ? attr->mode : 0;
+}
+
 static struct attribute_group platform_attribute_group = {
-	.attrs = platform_attributes
+	.is_visible	= eeepc_sysfs_is_visible,
+	.attrs		= platform_attributes
 };
 
 static void eeepc_wmi_sysfs_exit(struct platform_device *device)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/14] eeepc-wmi: add camera and card reader support
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 Documentation/ABI/testing/sysfs-platform-eeepc-wmi |   14 +++
 drivers/platform/x86/eeepc-wmi.c                   |   89 +++++++++++++++++++-
 2 files changed, 102 insertions(+), 1 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
index e4b5fef..9fc8d33 100644
--- a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
@@ -8,3 +8,17 @@ Description:
 		    * 0 -> Super Performance Mode
 		    * 1 -> High Performance Mode
 		    * 2 -> Power Saving Mode
+
+What:		/sys/devices/platform/eeepc-wmi/camera
+Date:		Jan 2010
+KernelVersion:	2.6.39
+Contact:	"Corentin Chary" <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
+Description:
+		Control the camera. 1 means on, 0 means off.
+
+What:		/sys/devices/platform/eeepc-wmi/cardr
+Date:		Jan 2010
+KernelVersion:	2.6.39
+Contact:	"Corentin Chary" <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
+Description:
+		Control the card reader. 1 means on, 0 means off.
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 391c32b..83415dd 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -73,6 +73,8 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
 #define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_CAMERA		0x00060013
+#define EEEPC_WMI_DEVID_CARDREADER	0x00080013
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 #define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
@@ -879,6 +881,70 @@ static void eeepc_wmi_notify(u32 value, void *context)
 	kfree(obj);
 }
 
+/*
+ * Sys helpers
+ */
+static int parse_arg(const char *buf, unsigned long count, int *val)
+{
+	if (!count)
+		return 0;
+	if (sscanf(buf, "%i", val) != 1)
+		return -EINVAL;
+	return count;
+}
+
+static ssize_t store_sys_wmi(int devid, const char *buf, size_t count)
+{
+	acpi_status status;
+	u32 retval;
+	int rv, value;
+
+	value = eeepc_wmi_get_devstate_simple(devid);
+	if (value == -ENODEV) /* Check device presence */
+		return value;
+
+	rv = parse_arg(buf, count, &value);
+	status = eeepc_wmi_set_devstate(devid, value, &retval);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+	return rv;
+}
+
+static ssize_t show_sys_wmi(int devid, char *buf)
+{
+	int value = eeepc_wmi_get_devstate_simple(devid);
+
+	if (value < 0)
+		return value;
+
+	return sprintf(buf, "%d\n", value);
+}
+
+#define EEEPC_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm)			\
+	static ssize_t show_##_name(struct device *dev,			\
+				    struct device_attribute *attr,	\
+				    char *buf)				\
+	{								\
+		return show_sys_wmi(_cm, buf);				\
+	}								\
+	static ssize_t store_##_name(struct device *dev,		\
+				     struct device_attribute *attr,	\
+				     const char *buf, size_t count)	\
+	{								\
+		return store_sys_wmi(_cm, buf, count);			\
+	}								\
+	static struct device_attribute dev_attr_##_name = {		\
+		.attr = {						\
+			.name = __stringify(_name),			\
+			.mode = _mode },				\
+		.show   = show_##_name,					\
+		.store  = store_##_name,				\
+	}
+
+EEEPC_WMI_CREATE_DEVICE_ATTR(camera, 0644, EEEPC_WMI_DEVID_CAMERA);
+EEEPC_WMI_CREATE_DEVICE_ATTR(cardr, 0644, EEEPC_WMI_DEVID_CARDREADER);
+
 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
@@ -904,11 +970,32 @@ static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
 
 static struct attribute *platform_attributes[] = {
 	&dev_attr_cpufv.attr,
+	&dev_attr_camera.attr,
+	&dev_attr_cardr.attr,
 	NULL
 };
 
+static mode_t eeepc_sysfs_is_visible(struct kobject *kobj,
+				     struct attribute *attr,
+				     int idx)
+{
+	bool supported = true;
+	int devid = -1;
+
+	if (attr == &dev_attr_camera.attr)
+		devid = EEEPC_WMI_DEVID_CAMERA;
+	else if (attr == &dev_attr_cardr.attr)
+		devid = EEEPC_WMI_DEVID_CARDREADER;
+
+	if (devid != -1)
+		supported = eeepc_wmi_get_devstate_simple(devid) != -ENODEV;
+
+	return supported ? attr->mode : 0;
+}
+
 static struct attribute_group platform_attribute_group = {
-	.attrs = platform_attributes
+	.is_visible	= eeepc_sysfs_is_visible,
+	.attrs		= platform_attributes
 };
 
 static void eeepc_wmi_sysfs_exit(struct platform_device *device)
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/14] eeepc-wmi: add wimax support
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 83415dd..0db7009 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -71,6 +71,7 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 
 #define EEEPC_WMI_DEVID_WLAN		0x00010011
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
+#define EEEPC_WMI_DEVID_WIMAX		0x00010017
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
 #define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
 #define EEEPC_WMI_DEVID_CAMERA		0x00060013
@@ -138,6 +139,7 @@ struct eeepc_wmi {
 
 	struct rfkill *wlan_rfkill;
 	struct rfkill *bluetooth_rfkill;
+	struct rfkill *wimax_rfkill;
 	struct rfkill *wwan3g_rfkill;
 
 	struct hotplug_slot *hotplug_slot;
@@ -691,6 +693,11 @@ static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
 		rfkill_destroy(eeepc->bluetooth_rfkill);
 		eeepc->bluetooth_rfkill = NULL;
 	}
+	if (eeepc->wimax_rfkill) {
+		rfkill_unregister(eeepc->wimax_rfkill);
+		rfkill_destroy(eeepc->wimax_rfkill);
+		eeepc->wimax_rfkill = NULL;
+	}
 	if (eeepc->wwan3g_rfkill) {
 		rfkill_unregister(eeepc->wwan3g_rfkill);
 		rfkill_destroy(eeepc->wwan3g_rfkill);
@@ -719,6 +726,13 @@ static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
 	if (result && result != -ENODEV)
 		goto exit;
 
+	result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
+				  "eeepc-wimax", RFKILL_TYPE_WIMAX,
+				  EEEPC_WMI_DEVID_WIMAX);
+
+	if (result && result != -ENODEV)
+		goto exit;
+
 	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
 				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
 				  EEEPC_WMI_DEVID_WWAN3G);
@@ -1276,7 +1290,11 @@ static int eeepc_hotk_restore(struct device *device)
 	if (eeepc->bluetooth_rfkill) {
 		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BLUETOOTH);
 		rfkill_set_sw_state(eeepc->bluetooth_rfkill, bl);
-}
+	}
+	if (eeepc->wimax_rfkill) {
+		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WIMAX);
+		rfkill_set_sw_state(eeepc->wimax_rfkill, bl);
+	}
 	if (eeepc->wwan3g_rfkill) {
 		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WWAN3G);
 		rfkill_set_sw_state(eeepc->wwan3g_rfkill, bl);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/14] eeepc-wmi: add wimax support
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 83415dd..0db7009 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -71,6 +71,7 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 
 #define EEEPC_WMI_DEVID_WLAN		0x00010011
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
+#define EEEPC_WMI_DEVID_WIMAX		0x00010017
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
 #define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
 #define EEEPC_WMI_DEVID_CAMERA		0x00060013
@@ -138,6 +139,7 @@ struct eeepc_wmi {
 
 	struct rfkill *wlan_rfkill;
 	struct rfkill *bluetooth_rfkill;
+	struct rfkill *wimax_rfkill;
 	struct rfkill *wwan3g_rfkill;
 
 	struct hotplug_slot *hotplug_slot;
@@ -691,6 +693,11 @@ static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
 		rfkill_destroy(eeepc->bluetooth_rfkill);
 		eeepc->bluetooth_rfkill = NULL;
 	}
+	if (eeepc->wimax_rfkill) {
+		rfkill_unregister(eeepc->wimax_rfkill);
+		rfkill_destroy(eeepc->wimax_rfkill);
+		eeepc->wimax_rfkill = NULL;
+	}
 	if (eeepc->wwan3g_rfkill) {
 		rfkill_unregister(eeepc->wwan3g_rfkill);
 		rfkill_destroy(eeepc->wwan3g_rfkill);
@@ -719,6 +726,13 @@ static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
 	if (result && result != -ENODEV)
 		goto exit;
 
+	result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
+				  "eeepc-wimax", RFKILL_TYPE_WIMAX,
+				  EEEPC_WMI_DEVID_WIMAX);
+
+	if (result && result != -ENODEV)
+		goto exit;
+
 	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
 				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
 				  EEEPC_WMI_DEVID_WWAN3G);
@@ -1276,7 +1290,11 @@ static int eeepc_hotk_restore(struct device *device)
 	if (eeepc->bluetooth_rfkill) {
 		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BLUETOOTH);
 		rfkill_set_sw_state(eeepc->bluetooth_rfkill, bl);
-}
+	}
+	if (eeepc->wimax_rfkill) {
+		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WIMAX);
+		rfkill_set_sw_state(eeepc->wimax_rfkill, bl);
+	}
 	if (eeepc->wwan3g_rfkill) {
 		bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WWAN3G);
 		rfkill_set_sw_state(eeepc->wwan3g_rfkill, bl);
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/14] eeepc-wmi: set the right key code for 0xe9
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

This key should power off the backlight, not the display,
it is also used in acpi/video.c to do the same thing.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 0db7009..75dd692 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -103,7 +103,7 @@ static const struct key_entry eeepc_wmi_keymap[] = {
 	{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
 	{ KE_KEY, 0xe0, { KEY_PROG1 } },
 	{ KE_KEY, 0xe1, { KEY_F14 } },
-	{ KE_KEY, 0xe9, { KEY_DISPLAY_OFF } },
+	{ KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
 	{ KE_END, 0},
 };
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/14] eeepc-wmi: set the right key code for 0xe9
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

This key should power off the backlight, not the display,
it is also used in acpi/video.c to do the same thing.

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 0db7009..75dd692 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -103,7 +103,7 @@ static const struct key_entry eeepc_wmi_keymap[] = {
 	{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
 	{ KE_KEY, 0xe0, { KEY_PROG1 } },
 	{ KE_KEY, 0xe1, { KEY_F14 } },
-	{ KE_KEY, 0xe9, { KEY_DISPLAY_OFF } },
+	{ KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
 	{ KE_END, 0},
 };
 
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 14/14] eeepc-wmi: support backlight power (bl_power) attribute
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-doc, linux-kernel,
	Randy Dunlap, Chris Bagwell, Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/eeepc-wmi.c |   75 +++++++++++++++++++++++++++++++-------
 1 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 75dd692..fcb6dfe 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -73,13 +73,16 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WIMAX		0x00010017
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
-#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050011
+#define EEEPC_WMI_DEVID_BRIGHTNESS	0x00050012
 #define EEEPC_WMI_DEVID_CAMERA		0x00060013
 #define EEEPC_WMI_DEVID_CARDREADER	0x00080013
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 #define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
 #define EEEPC_WMI_DSTS_PRESENCE_BIT	0x00010000
+#define EEEPC_WMI_DSTS_BRIGHTNESS_MASK	0x000000FF
+#define EEEPC_WMI_DSTS_MAX_BRIGTH_MASK	0x0000FF00
 
 static bool hotplug_wireless;
 
@@ -262,7 +265,7 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
 }
 
 /* Helper for special devices with magic return codes */
-static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+static int eeepc_wmi_get_devstate_bits(u32 dev_id, u32 mask)
 {
 	u32 retval = 0;
 	acpi_status status;
@@ -275,7 +278,12 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
 	if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
 		return -ENODEV;
 
-	return retval & EEEPC_WMI_DSTS_STATUS_BIT;
+	return retval & mask;
+}
+
+static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+{
+	return !!eeepc_wmi_get_devstate_bits(dev_id, EEEPC_WMI_DSTS_STATUS_BIT);
 }
 
 /*
@@ -770,34 +778,53 @@ exit:
 /*
  * Backlight
  */
+static int read_backlight_power(void)
+{
+	int ret = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BACKLIGHT);
+
+	if (ret < 0)
+		return ret;
+
+	return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+}
+
 static int read_brightness(struct backlight_device *bd)
 {
 	u32 retval;
 	acpi_status status;
 
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
+	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BRIGHTNESS, &retval);
 
 	if (ACPI_FAILURE(status))
-		return -1;
+		return -EIO;
 	else
-		return retval & 0xFF;
+		return retval & EEEPC_WMI_DSTS_BRIGHTNESS_MASK;
 }
 
 static int update_bl_status(struct backlight_device *bd)
 {
-
 	u32 ctrl_param;
 	acpi_status status;
+	int power;
 
 	ctrl_param = bd->props.brightness;
 
-	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BRIGHTNESS,
 					ctrl_param, NULL);
 
 	if (ACPI_FAILURE(status))
-		return -1;
-	else
-		return 0;
+		return -EIO;
+
+	power = read_backlight_power();
+	if (power != -ENODEV && bd->props.power != power) {
+		ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
+		status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+						ctrl_param, NULL);
+
+		if (ACPI_FAILURE(status))
+			return -EIO;
+	}
+	return 0;
 }
 
 static const struct backlight_ops eeepc_wmi_bl_ops = {
@@ -827,9 +854,29 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
 {
 	struct backlight_device *bd;
 	struct backlight_properties props;
+	int max;
+	int power;
+
+	max = eeepc_wmi_get_devstate_bits(EEEPC_WMI_DEVID_BRIGHTNESS,
+					  EEEPC_WMI_DSTS_MAX_BRIGTH_MASK);
+	power = read_backlight_power();
+
+	if (max < 0 && power < 0) {
+		/* Try to keep the original error */
+		if (max == -ENODEV && power == -ENODEV)
+			return -ENODEV;
+		if (max != -ENODEV)
+			return max;
+		else
+			return power;
+	}
+	if (max == -ENODEV)
+		max = 0;
+	if (power == -ENODEV)
+		power = FB_BLANK_UNBLANK;
 
 	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 15;
+	props.max_brightness = max;
 	bd = backlight_device_register(EEEPC_WMI_FILE,
 				       &eeepc->platform_device->dev, eeepc,
 				       &eeepc_wmi_bl_ops, &props);
@@ -841,7 +888,7 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
 	eeepc->backlight_device = bd;
 
 	bd->props.brightness = read_brightness(bd);
-	bd->props.power = FB_BLANK_UNBLANK;
+	bd->props.power = power;
 	backlight_update_status(bd);
 
 	return 0;
@@ -1202,7 +1249,7 @@ static int __init eeepc_wmi_add(struct platform_device *pdev)
 
 	if (!acpi_video_backlight_support()) {
 		err = eeepc_wmi_backlight_init(eeepc);
-		if (err)
+		if (err && err != -ENODEV)
 			goto fail_backlight;
 	} else
 		pr_info("Backlight controlled by ACPI video driver\n");
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 14/14] eeepc-wmi: support backlight power (bl_power) attribute
@ 2011-01-24 16:23   ` Corentin Chary
  0 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-24 16:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: acpi4asus-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Chris Bagwell,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	platform-driver-x86-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap

Signed-off-by: Corentin Chary <corentincj-EjuBZuxMvz2sTnJN9+BGXg@public.gmane.org>
---
 drivers/platform/x86/eeepc-wmi.c |   75 +++++++++++++++++++++++++++++++-------
 1 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 75dd692..fcb6dfe 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -73,13 +73,16 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WIMAX		0x00010017
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
-#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050011
+#define EEEPC_WMI_DEVID_BRIGHTNESS	0x00050012
 #define EEEPC_WMI_DEVID_CAMERA		0x00060013
 #define EEEPC_WMI_DEVID_CARDREADER	0x00080013
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 #define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
 #define EEEPC_WMI_DSTS_PRESENCE_BIT	0x00010000
+#define EEEPC_WMI_DSTS_BRIGHTNESS_MASK	0x000000FF
+#define EEEPC_WMI_DSTS_MAX_BRIGTH_MASK	0x0000FF00
 
 static bool hotplug_wireless;
 
@@ -262,7 +265,7 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
 }
 
 /* Helper for special devices with magic return codes */
-static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+static int eeepc_wmi_get_devstate_bits(u32 dev_id, u32 mask)
 {
 	u32 retval = 0;
 	acpi_status status;
@@ -275,7 +278,12 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
 	if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
 		return -ENODEV;
 
-	return retval & EEEPC_WMI_DSTS_STATUS_BIT;
+	return retval & mask;
+}
+
+static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+{
+	return !!eeepc_wmi_get_devstate_bits(dev_id, EEEPC_WMI_DSTS_STATUS_BIT);
 }
 
 /*
@@ -770,34 +778,53 @@ exit:
 /*
  * Backlight
  */
+static int read_backlight_power(void)
+{
+	int ret = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BACKLIGHT);
+
+	if (ret < 0)
+		return ret;
+
+	return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+}
+
 static int read_brightness(struct backlight_device *bd)
 {
 	u32 retval;
 	acpi_status status;
 
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
+	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BRIGHTNESS, &retval);
 
 	if (ACPI_FAILURE(status))
-		return -1;
+		return -EIO;
 	else
-		return retval & 0xFF;
+		return retval & EEEPC_WMI_DSTS_BRIGHTNESS_MASK;
 }
 
 static int update_bl_status(struct backlight_device *bd)
 {
-
 	u32 ctrl_param;
 	acpi_status status;
+	int power;
 
 	ctrl_param = bd->props.brightness;
 
-	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BRIGHTNESS,
 					ctrl_param, NULL);
 
 	if (ACPI_FAILURE(status))
-		return -1;
-	else
-		return 0;
+		return -EIO;
+
+	power = read_backlight_power();
+	if (power != -ENODEV && bd->props.power != power) {
+		ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
+		status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+						ctrl_param, NULL);
+
+		if (ACPI_FAILURE(status))
+			return -EIO;
+	}
+	return 0;
 }
 
 static const struct backlight_ops eeepc_wmi_bl_ops = {
@@ -827,9 +854,29 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
 {
 	struct backlight_device *bd;
 	struct backlight_properties props;
+	int max;
+	int power;
+
+	max = eeepc_wmi_get_devstate_bits(EEEPC_WMI_DEVID_BRIGHTNESS,
+					  EEEPC_WMI_DSTS_MAX_BRIGTH_MASK);
+	power = read_backlight_power();
+
+	if (max < 0 && power < 0) {
+		/* Try to keep the original error */
+		if (max == -ENODEV && power == -ENODEV)
+			return -ENODEV;
+		if (max != -ENODEV)
+			return max;
+		else
+			return power;
+	}
+	if (max == -ENODEV)
+		max = 0;
+	if (power == -ENODEV)
+		power = FB_BLANK_UNBLANK;
 
 	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 15;
+	props.max_brightness = max;
 	bd = backlight_device_register(EEEPC_WMI_FILE,
 				       &eeepc->platform_device->dev, eeepc,
 				       &eeepc_wmi_bl_ops, &props);
@@ -841,7 +888,7 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
 	eeepc->backlight_device = bd;
 
 	bd->props.brightness = read_brightness(bd);
-	bd->props.power = FB_BLANK_UNBLANK;
+	bd->props.power = power;
 	backlight_update_status(bd);
 
 	return 0;
@@ -1202,7 +1249,7 @@ static int __init eeepc_wmi_add(struct platform_device *pdev)
 
 	if (!acpi_video_backlight_support()) {
 		err = eeepc_wmi_backlight_init(eeepc);
-		if (err)
+		if (err && err != -ENODEV)
 			goto fail_backlight;
 	} else
 		pr_info("Backlight controlled by ACPI video driver\n");
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 14/14] eeepc-wmi: support backlight power (bl_power) attribute
  2011-01-24 16:23   ` Corentin Chary
  (?)
@ 2011-01-29  7:42   ` Corentin Chary
  -1 siblings, 0 replies; 26+ messages in thread
From: Corentin Chary @ 2011-01-29  7:42 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: platform-driver-x86, acpi4asus-user, linux-kernel, Randy Dunlap,
	Corentin Chary

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
The previous patch broke eeepc_wmi_get_devstate_simple(),
here is a fixed patch.

 drivers/platform/x86/eeepc-wmi.c |   75 +++++++++++++++++++++++++++++++-------
 1 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 75dd692..910eb00 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -73,13 +73,16 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 #define EEEPC_WMI_DEVID_BLUETOOTH	0x00010013
 #define EEEPC_WMI_DEVID_WIMAX		0x00010017
 #define EEEPC_WMI_DEVID_WWAN3G		0x00010019
-#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050011
+#define EEEPC_WMI_DEVID_BRIGHTNESS	0x00050012
 #define EEEPC_WMI_DEVID_CAMERA		0x00060013
 #define EEEPC_WMI_DEVID_CARDREADER	0x00080013
 #define EEEPC_WMI_DEVID_TPDLED		0x00100011
 
 #define EEEPC_WMI_DSTS_STATUS_BIT	0x00000001
 #define EEEPC_WMI_DSTS_PRESENCE_BIT	0x00010000
+#define EEEPC_WMI_DSTS_BRIGHTNESS_MASK	0x000000FF
+#define EEEPC_WMI_DSTS_MAX_BRIGTH_MASK	0x0000FF00
 
 static bool hotplug_wireless;
 
@@ -262,7 +265,7 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
 }
 
 /* Helper for special devices with magic return codes */
-static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+static int eeepc_wmi_get_devstate_bits(u32 dev_id, u32 mask)
 {
 	u32 retval = 0;
 	acpi_status status;
@@ -275,7 +278,12 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
 	if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
 		return -ENODEV;
 
-	return retval & EEEPC_WMI_DSTS_STATUS_BIT;
+	return retval & mask;
+}
+
+static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+{
+	return eeepc_wmi_get_devstate_bits(dev_id, EEEPC_WMI_DSTS_STATUS_BIT);
 }
 
 /*
@@ -770,34 +778,53 @@ exit:
 /*
  * Backlight
  */
+static int read_backlight_power(void)
+{
+	int ret = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BACKLIGHT);
+
+	if (ret < 0)
+		return ret;
+
+	return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+}
+
 static int read_brightness(struct backlight_device *bd)
 {
 	u32 retval;
 	acpi_status status;
 
-	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
+	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BRIGHTNESS, &retval);
 
 	if (ACPI_FAILURE(status))
-		return -1;
+		return -EIO;
 	else
-		return retval & 0xFF;
+		return retval & EEEPC_WMI_DSTS_BRIGHTNESS_MASK;
 }
 
 static int update_bl_status(struct backlight_device *bd)
 {
-
 	u32 ctrl_param;
 	acpi_status status;
+	int power;
 
 	ctrl_param = bd->props.brightness;
 
-	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BRIGHTNESS,
 					ctrl_param, NULL);
 
 	if (ACPI_FAILURE(status))
-		return -1;
-	else
-		return 0;
+		return -EIO;
+
+	power = read_backlight_power();
+	if (power != -ENODEV && bd->props.power != power) {
+		ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
+		status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+						ctrl_param, NULL);
+
+		if (ACPI_FAILURE(status))
+			return -EIO;
+	}
+	return 0;
 }
 
 static const struct backlight_ops eeepc_wmi_bl_ops = {
@@ -827,9 +854,29 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
 {
 	struct backlight_device *bd;
 	struct backlight_properties props;
+	int max;
+	int power;
+
+	max = eeepc_wmi_get_devstate_bits(EEEPC_WMI_DEVID_BRIGHTNESS,
+					  EEEPC_WMI_DSTS_MAX_BRIGTH_MASK);
+	power = read_backlight_power();
+
+	if (max < 0 && power < 0) {
+		/* Try to keep the original error */
+		if (max == -ENODEV && power == -ENODEV)
+			return -ENODEV;
+		if (max != -ENODEV)
+			return max;
+		else
+			return power;
+	}
+	if (max == -ENODEV)
+		max = 0;
+	if (power == -ENODEV)
+		power = FB_BLANK_UNBLANK;
 
 	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 15;
+	props.max_brightness = max;
 	bd = backlight_device_register(EEEPC_WMI_FILE,
 				       &eeepc->platform_device->dev, eeepc,
 				       &eeepc_wmi_bl_ops, &props);
@@ -841,7 +888,7 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
 	eeepc->backlight_device = bd;
 
 	bd->props.brightness = read_brightness(bd);
-	bd->props.power = FB_BLANK_UNBLANK;
+	bd->props.power = power;
 	backlight_update_status(bd);
 
 	return 0;
@@ -1202,7 +1249,7 @@ static int __init eeepc_wmi_add(struct platform_device *pdev)
 
 	if (!acpi_video_backlight_support()) {
 		err = eeepc_wmi_backlight_init(eeepc);
-		if (err)
+		if (err && err != -ENODEV)
 			goto fail_backlight;
 	} else
 		pr_info("Backlight controlled by ACPI video driver\n");
-- 
1.7.4.rc2


^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-01-29  7:40 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-24 16:23 [PATCH 00/14] eeepc-wmi updates Corentin Chary
2011-01-24 16:23 ` [PATCH 01/14] eeepc-wmi: reorder keymap Corentin Chary
2011-01-24 16:23 ` [PATCH 02/14] eeepc-wmi: add wlan key found on 1015P Corentin Chary
2011-01-24 16:23 ` [PATCH 03/14] eeepc-wmi: add hotplug code for Eeepc 1000H Corentin Chary
2011-01-24 16:23 ` [PATCH 04/14] eeepc-wmi: serialize access to wmi method Corentin Chary
2011-01-24 16:23 ` [PATCH 05/14] eeepc-wmi: return proper error code in eeepc_rfkill_set() Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 06/14] eeepc-wmi: add an helper using simple return codes Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 07/14] eeepc-wmi: add hibernate/resume callbacks Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 08/14] eeepc-wmi: switch to platform_create_bundle() Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 09/14] eeepc-wmi: reorder defines Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 10/14] eeepc-wmi: use the presence bit correctly Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 11/14] eeepc-wmi: add camera and card reader support Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 12/14] eeepc-wmi: add wimax support Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 13/14] eeepc-wmi: set the right key code for 0xe9 Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-24 16:23 ` [PATCH 14/14] eeepc-wmi: support backlight power (bl_power) attribute Corentin Chary
2011-01-24 16:23   ` Corentin Chary
2011-01-29  7:42   ` [PATCH v2 " Corentin Chary

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.