diff options
Diffstat (limited to 'drivers/net/wireless/b43/rfkill.c')
-rw-r--r-- | drivers/net/wireless/b43/rfkill.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 9b1f905ffbf4..98cf70c5fd47 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include "rfkill.h" | 25 | #include "rfkill.h" |
26 | #include "b43.h" | 26 | #include "b43.h" |
27 | 27 | ||
28 | #include <linux/kmod.h> | ||
29 | |||
28 | 30 | ||
29 | /* Returns TRUE, if the radio is enabled in hardware. */ | 31 | /* Returns TRUE, if the radio is enabled in hardware. */ |
30 | static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | 32 | static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) |
@@ -50,7 +52,10 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | |||
50 | bool report_change = 0; | 52 | bool report_change = 0; |
51 | 53 | ||
52 | mutex_lock(&wl->mutex); | 54 | mutex_lock(&wl->mutex); |
53 | B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED); | 55 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { |
56 | mutex_unlock(&wl->mutex); | ||
57 | return; | ||
58 | } | ||
54 | enabled = b43_is_hw_radio_enabled(dev); | 59 | enabled = b43_is_hw_radio_enabled(dev); |
55 | if (unlikely(enabled != dev->radio_hw_enable)) { | 60 | if (unlikely(enabled != dev->radio_hw_enable)) { |
56 | dev->radio_hw_enable = enabled; | 61 | dev->radio_hw_enable = enabled; |
@@ -60,8 +65,12 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | |||
60 | } | 65 | } |
61 | mutex_unlock(&wl->mutex); | 66 | mutex_unlock(&wl->mutex); |
62 | 67 | ||
63 | if (unlikely(report_change)) | 68 | /* send the radio switch event to the system - note both a key press |
64 | input_report_key(poll_dev->input, KEY_WLAN, enabled); | 69 | * and a release are required */ |
70 | if (unlikely(report_change)) { | ||
71 | input_report_key(poll_dev->input, KEY_WLAN, 1); | ||
72 | input_report_key(poll_dev->input, KEY_WLAN, 0); | ||
73 | } | ||
65 | } | 74 | } |
66 | 75 | ||
67 | /* Called when the RFKILL toggled in software. */ | 76 | /* Called when the RFKILL toggled in software. */ |
@@ -69,13 +78,15 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) | |||
69 | { | 78 | { |
70 | struct b43_wldev *dev = data; | 79 | struct b43_wldev *dev = data; |
71 | struct b43_wl *wl = dev->wl; | 80 | struct b43_wl *wl = dev->wl; |
72 | int err = 0; | 81 | int err = -EBUSY; |
73 | 82 | ||
74 | if (!wl->rfkill.registered) | 83 | if (!wl->rfkill.registered) |
75 | return 0; | 84 | return 0; |
76 | 85 | ||
77 | mutex_lock(&wl->mutex); | 86 | mutex_lock(&wl->mutex); |
78 | B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED); | 87 | if (b43_status(dev) < B43_STAT_INITIALIZED) |
88 | goto out_unlock; | ||
89 | err = 0; | ||
79 | switch (state) { | 90 | switch (state) { |
80 | case RFKILL_STATE_ON: | 91 | case RFKILL_STATE_ON: |
81 | if (!dev->radio_hw_enable) { | 92 | if (!dev->radio_hw_enable) { |
@@ -133,9 +144,25 @@ void b43_rfkill_init(struct b43_wldev *dev) | |||
133 | rfk->poll_dev->poll = b43_rfkill_poll; | 144 | rfk->poll_dev->poll = b43_rfkill_poll; |
134 | rfk->poll_dev->poll_interval = 1000; /* msecs */ | 145 | rfk->poll_dev->poll_interval = 1000; /* msecs */ |
135 | 146 | ||
147 | rfk->poll_dev->input->name = rfk->name; | ||
148 | rfk->poll_dev->input->id.bustype = BUS_HOST; | ||
149 | rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; | ||
150 | rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); | ||
151 | set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); | ||
152 | |||
136 | err = rfkill_register(rfk->rfkill); | 153 | err = rfkill_register(rfk->rfkill); |
137 | if (err) | 154 | if (err) |
138 | goto err_free_polldev; | 155 | goto err_free_polldev; |
156 | |||
157 | #ifdef CONFIG_RFKILL_INPUT_MODULE | ||
158 | /* B43 RF-kill isn't useful without the rfkill-input subsystem. | ||
159 | * Try to load the module. */ | ||
160 | err = request_module("rfkill-input"); | ||
161 | if (err) | ||
162 | b43warn(wl, "Failed to load the rfkill-input module. " | ||
163 | "The built-in radio LED will not work.\n"); | ||
164 | #endif /* CONFIG_RFKILL_INPUT */ | ||
165 | |||
139 | err = input_register_polled_device(rfk->poll_dev); | 166 | err = input_register_polled_device(rfk->poll_dev); |
140 | if (err) | 167 | if (err) |
141 | goto err_unreg_rfk; | 168 | goto err_unreg_rfk; |