diff options
Diffstat (limited to 'drivers/platform/x86/eeepc-laptop.c')
-rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 03bf522bd7ab..8153b3e59189 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -180,6 +180,7 @@ static struct key_entry eeepc_keymap[] = { | |||
180 | */ | 180 | */ |
181 | static int eeepc_hotk_add(struct acpi_device *device); | 181 | static int eeepc_hotk_add(struct acpi_device *device); |
182 | static int eeepc_hotk_remove(struct acpi_device *device, int type); | 182 | static int eeepc_hotk_remove(struct acpi_device *device, int type); |
183 | static int eeepc_hotk_resume(struct acpi_device *device); | ||
183 | 184 | ||
184 | static const struct acpi_device_id eeepc_device_ids[] = { | 185 | static const struct acpi_device_id eeepc_device_ids[] = { |
185 | {EEEPC_HOTK_HID, 0}, | 186 | {EEEPC_HOTK_HID, 0}, |
@@ -194,6 +195,7 @@ static struct acpi_driver eeepc_hotk_driver = { | |||
194 | .ops = { | 195 | .ops = { |
195 | .add = eeepc_hotk_add, | 196 | .add = eeepc_hotk_add, |
196 | .remove = eeepc_hotk_remove, | 197 | .remove = eeepc_hotk_remove, |
198 | .resume = eeepc_hotk_resume, | ||
197 | }, | 199 | }, |
198 | }; | 200 | }; |
199 | 201 | ||
@@ -512,15 +514,12 @@ static int notify_brn(void) | |||
512 | return -1; | 514 | return -1; |
513 | } | 515 | } |
514 | 516 | ||
515 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 517 | static void eeepc_rfkill_hotplug(void) |
516 | { | 518 | { |
517 | struct pci_dev *dev; | 519 | struct pci_dev *dev; |
518 | struct pci_bus *bus = pci_find_bus(0, 1); | 520 | struct pci_bus *bus = pci_find_bus(0, 1); |
519 | bool blocked; | 521 | bool blocked; |
520 | 522 | ||
521 | if (event != ACPI_NOTIFY_BUS_CHECK) | ||
522 | return; | ||
523 | |||
524 | if (!bus) { | 523 | if (!bus) { |
525 | printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); | 524 | printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); |
526 | return; | 525 | return; |
@@ -551,6 +550,14 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
551 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); | 550 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); |
552 | } | 551 | } |
553 | 552 | ||
553 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | ||
554 | { | ||
555 | if (event != ACPI_NOTIFY_BUS_CHECK) | ||
556 | return; | ||
557 | |||
558 | eeepc_rfkill_hotplug(); | ||
559 | } | ||
560 | |||
554 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | 561 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) |
555 | { | 562 | { |
556 | static struct key_entry *key; | 563 | static struct key_entry *key; |
@@ -675,8 +682,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
675 | if (!ehotk->eeepc_wlan_rfkill) | 682 | if (!ehotk->eeepc_wlan_rfkill) |
676 | goto wlan_fail; | 683 | goto wlan_fail; |
677 | 684 | ||
678 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, | 685 | rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill, |
679 | get_acpi(CM_ASL_WLAN) != 1); | 686 | get_acpi(CM_ASL_WLAN) != 1); |
680 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | 687 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); |
681 | if (result) | 688 | if (result) |
682 | goto wlan_fail; | 689 | goto wlan_fail; |
@@ -693,8 +700,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
693 | if (!ehotk->eeepc_bluetooth_rfkill) | 700 | if (!ehotk->eeepc_bluetooth_rfkill) |
694 | goto bluetooth_fail; | 701 | goto bluetooth_fail; |
695 | 702 | ||
696 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, | 703 | rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill, |
697 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 704 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
698 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); | 705 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); |
699 | if (result) | 706 | if (result) |
700 | goto bluetooth_fail; | 707 | goto bluetooth_fail; |
@@ -734,6 +741,33 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) | |||
734 | return 0; | 741 | return 0; |
735 | } | 742 | } |
736 | 743 | ||
744 | static int eeepc_hotk_resume(struct acpi_device *device) | ||
745 | { | ||
746 | if (ehotk->eeepc_wlan_rfkill) { | ||
747 | bool wlan; | ||
748 | |||
749 | /* Workaround - it seems that _PTS disables the wireless | ||
750 | without notification or changing the value read by WLAN. | ||
751 | Normally this is fine because the correct value is restored | ||
752 | from the non-volatile storage on resume, but we need to do | ||
753 | it ourself if case suspend is aborted, or we lose wireless. | ||
754 | */ | ||
755 | wlan = get_acpi(CM_ASL_WLAN); | ||
756 | set_acpi(CM_ASL_WLAN, wlan); | ||
757 | |||
758 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, | ||
759 | wlan != 1); | ||
760 | |||
761 | eeepc_rfkill_hotplug(); | ||
762 | } | ||
763 | |||
764 | if (ehotk->eeepc_bluetooth_rfkill) | ||
765 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, | ||
766 | get_acpi(CM_ASL_BLUETOOTH) != 1); | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
737 | /* | 771 | /* |
738 | * Hwmon | 772 | * Hwmon |
739 | */ | 773 | */ |