Commit 96e9cfeb authored by Alan Jenkins's avatar Alan Jenkins Committed by John W. Linville

eeepc-laptop: read rfkill soft-blocked state on resume

This will respect state changes over hibernation, e.g. if the user
disables the wireless in the BIOS setup screen.

It reveals an issue where ACPI silently kills the wireless on
suspend.  Normally, the BIOS restores the correct state from
non-volatile storage on boot.  But when hibernation is aborted,
the wireless would remain killed.  Fortunately we can work around
this in the resume handler by simply writing back the same value we
read from NVS.
Signed-off-by: default avatarAlan Jenkins <alan-jenkins@tuffmail.co.uk>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 06d5caf4
...@@ -180,6 +180,7 @@ static struct key_entry eeepc_keymap[] = { ...@@ -180,6 +180,7 @@ static struct key_entry eeepc_keymap[] = {
*/ */
static int eeepc_hotk_add(struct acpi_device *device); static int eeepc_hotk_add(struct acpi_device *device);
static int eeepc_hotk_remove(struct acpi_device *device, int type); static int eeepc_hotk_remove(struct acpi_device *device, int type);
static int eeepc_hotk_resume(struct acpi_device *device);
static const struct acpi_device_id eeepc_device_ids[] = { static const struct acpi_device_id eeepc_device_ids[] = {
{EEEPC_HOTK_HID, 0}, {EEEPC_HOTK_HID, 0},
...@@ -194,6 +195,7 @@ static struct acpi_driver eeepc_hotk_driver = { ...@@ -194,6 +195,7 @@ static struct acpi_driver eeepc_hotk_driver = {
.ops = { .ops = {
.add = eeepc_hotk_add, .add = eeepc_hotk_add,
.remove = eeepc_hotk_remove, .remove = eeepc_hotk_remove,
.resume = eeepc_hotk_resume,
}, },
}; };
...@@ -512,15 +514,12 @@ static int notify_brn(void) ...@@ -512,15 +514,12 @@ static int notify_brn(void)
return -1; return -1;
} }
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) static void eeepc_rfkill_hotplug(void)
{ {
struct pci_dev *dev; struct pci_dev *dev;
struct pci_bus *bus = pci_find_bus(0, 1); struct pci_bus *bus = pci_find_bus(0, 1);
bool blocked; bool blocked;
if (event != ACPI_NOTIFY_BUS_CHECK)
return;
if (!bus) { if (!bus) {
printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
return; return;
...@@ -551,6 +550,14 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) ...@@ -551,6 +550,14 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
} }
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
{
if (event != ACPI_NOTIFY_BUS_CHECK)
return;
eeepc_rfkill_hotplug();
}
static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
{ {
static struct key_entry *key; static struct key_entry *key;
...@@ -734,6 +741,33 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) ...@@ -734,6 +741,33 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
return 0; return 0;
} }
static int eeepc_hotk_resume(struct acpi_device *device)
{
if (ehotk->eeepc_wlan_rfkill) {
bool wlan;
/* Workaround - it seems that _PTS disables the wireless
without notification or changing the value read by WLAN.
Normally this is fine because the correct value is restored
from the non-volatile storage on resume, but we need to do
it ourself if case suspend is aborted, or we lose wireless.
*/
wlan = get_acpi(CM_ASL_WLAN);
set_acpi(CM_ASL_WLAN, wlan);
rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
wlan != 1);
eeepc_rfkill_hotplug();
}
if (ehotk->eeepc_bluetooth_rfkill)
rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
get_acpi(CM_ASL_BLUETOOTH) != 1);
return 0;
}
/* /*
* Hwmon * Hwmon
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment