diff options
author | Alan Jenkins <alan-jenkins@tuffmail.co.uk> | 2009-08-28 08:56:33 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-28 15:21:11 -0400 |
commit | dcf443b5813074031a45b05ad9c57da98bcae329 (patch) | |
tree | a5f9174917244e639efab172f9cab1552c7dac7c /drivers/platform | |
parent | 6d41839e762f8b8b03dbb97fd0d41b244d0bc902 (diff) |
eeepc-laptop: use a mutex to serialize pci hotplug (resume vs. notify)
Commit d0265f0 "eeepc-laptop: fix hot-unplug on resume" used a workqueue
to protect pci hotplug against multiple simultaneous calls during
resume. It seems to work, but a mutex would be more appropriate.
This is in preparation to fix the potential pci hotplug race on unload.
Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 69d73ed2c8ab..179010386981 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -143,7 +143,7 @@ struct eeepc_hotk { | |||
143 | struct rfkill *bluetooth_rfkill; | 143 | struct rfkill *bluetooth_rfkill; |
144 | struct rfkill *wwan3g_rfkill; | 144 | struct rfkill *wwan3g_rfkill; |
145 | struct hotplug_slot *hotplug_slot; | 145 | struct hotplug_slot *hotplug_slot; |
146 | struct work_struct hotplug_work; | 146 | struct mutex hotplug_lock; |
147 | }; | 147 | }; |
148 | 148 | ||
149 | /* The actual device the driver binds to */ | 149 | /* The actual device the driver binds to */ |
@@ -661,7 +661,7 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, | |||
661 | return 0; | 661 | return 0; |
662 | } | 662 | } |
663 | 663 | ||
664 | static void eeepc_hotplug_work(struct work_struct *work) | 664 | static void eeepc_rfkill_hotplug(void) |
665 | { | 665 | { |
666 | struct pci_dev *dev; | 666 | struct pci_dev *dev; |
667 | struct pci_bus *bus; | 667 | struct pci_bus *bus; |
@@ -669,13 +669,15 @@ static void eeepc_hotplug_work(struct work_struct *work) | |||
669 | 669 | ||
670 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); | 670 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); |
671 | 671 | ||
672 | mutex_lock(&ehotk->hotplug_lock); | ||
673 | |||
672 | if (ehotk->hotplug_slot == NULL) | 674 | if (ehotk->hotplug_slot == NULL) |
673 | return; | 675 | goto out_unlock; |
674 | 676 | ||
675 | bus = pci_find_bus(0, 1); | 677 | bus = pci_find_bus(0, 1); |
676 | if (!bus) { | 678 | if (!bus) { |
677 | pr_warning("Unable to find PCI bus 1?\n"); | 679 | pr_warning("Unable to find PCI bus 1?\n"); |
678 | return; | 680 | goto out_unlock; |
679 | } | 681 | } |
680 | 682 | ||
681 | if (!blocked) { | 683 | if (!blocked) { |
@@ -683,7 +685,7 @@ static void eeepc_hotplug_work(struct work_struct *work) | |||
683 | if (dev) { | 685 | if (dev) { |
684 | /* Device already present */ | 686 | /* Device already present */ |
685 | pci_dev_put(dev); | 687 | pci_dev_put(dev); |
686 | return; | 688 | goto out_unlock; |
687 | } | 689 | } |
688 | dev = pci_scan_single_device(bus, 0); | 690 | dev = pci_scan_single_device(bus, 0); |
689 | if (dev) { | 691 | if (dev) { |
@@ -698,6 +700,9 @@ static void eeepc_hotplug_work(struct work_struct *work) | |||
698 | pci_dev_put(dev); | 700 | pci_dev_put(dev); |
699 | } | 701 | } |
700 | } | 702 | } |
703 | |||
704 | out_unlock: | ||
705 | mutex_unlock(&ehotk->hotplug_lock); | ||
701 | } | 706 | } |
702 | 707 | ||
703 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 708 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
@@ -705,7 +710,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
705 | if (event != ACPI_NOTIFY_BUS_CHECK) | 710 | if (event != ACPI_NOTIFY_BUS_CHECK) |
706 | return; | 711 | return; |
707 | 712 | ||
708 | schedule_work(&ehotk->hotplug_work); | 713 | eeepc_rfkill_hotplug(); |
709 | } | 714 | } |
710 | 715 | ||
711 | static void eeepc_hotk_notify(struct acpi_device *device, u32 event) | 716 | static void eeepc_hotk_notify(struct acpi_device *device, u32 event) |
@@ -896,7 +901,7 @@ static int eeepc_hotk_resume(struct acpi_device *device) | |||
896 | 901 | ||
897 | rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); | 902 | rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); |
898 | 903 | ||
899 | schedule_work(&ehotk->hotplug_work); | 904 | eeepc_rfkill_hotplug(); |
900 | } | 905 | } |
901 | 906 | ||
902 | if (ehotk->bluetooth_rfkill) | 907 | if (ehotk->bluetooth_rfkill) |
@@ -1097,7 +1102,7 @@ static int eeepc_rfkill_init(struct device *dev) | |||
1097 | { | 1102 | { |
1098 | int result = 0; | 1103 | int result = 0; |
1099 | 1104 | ||
1100 | INIT_WORK(&ehotk->hotplug_work, eeepc_hotplug_work); | 1105 | mutex_init(&ehotk->hotplug_lock); |
1101 | 1106 | ||
1102 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | 1107 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); |
1103 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | 1108 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); |