aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/rfkill.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/rfkill.c')
-rw-r--r--drivers/net/wireless/b43/rfkill.c115
1 files changed, 52 insertions, 63 deletions
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 800e0a61a7f5..9b1f905ffbf4 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -47,32 +47,35 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
47 struct b43_wldev *dev = poll_dev->private; 47 struct b43_wldev *dev = poll_dev->private;
48 struct b43_wl *wl = dev->wl; 48 struct b43_wl *wl = dev->wl;
49 bool enabled; 49 bool enabled;
50 bool report_change = 0;
50 51
51 mutex_lock(&wl->mutex); 52 mutex_lock(&wl->mutex);
52 B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED); 53 B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
53 enabled = b43_is_hw_radio_enabled(dev); 54 enabled = b43_is_hw_radio_enabled(dev);
54 if (unlikely(enabled != dev->radio_hw_enable)) { 55 if (unlikely(enabled != dev->radio_hw_enable)) {
55 dev->radio_hw_enable = enabled; 56 dev->radio_hw_enable = enabled;
57 report_change = 1;
56 b43info(wl, "Radio hardware status changed to %s\n", 58 b43info(wl, "Radio hardware status changed to %s\n",
57 enabled ? "ENABLED" : "DISABLED"); 59 enabled ? "ENABLED" : "DISABLED");
58 mutex_unlock(&wl->mutex); 60 }
61 mutex_unlock(&wl->mutex);
62
63 if (unlikely(report_change))
59 input_report_key(poll_dev->input, KEY_WLAN, enabled); 64 input_report_key(poll_dev->input, KEY_WLAN, enabled);
60 } else
61 mutex_unlock(&wl->mutex);
62} 65}
63 66
64/* Called when the RFKILL toggled in software. 67/* Called when the RFKILL toggled in software. */
65 * This is called without locking. */
66static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) 68static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
67{ 69{
68 struct b43_wldev *dev = data; 70 struct b43_wldev *dev = data;
69 struct b43_wl *wl = dev->wl; 71 struct b43_wl *wl = dev->wl;
70 int err = 0; 72 int err = 0;
71 73
72 mutex_lock(&wl->mutex); 74 if (!wl->rfkill.registered)
73 if (b43_status(dev) < B43_STAT_INITIALIZED) 75 return 0;
74 goto out_unlock;
75 76
77 mutex_lock(&wl->mutex);
78 B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
76 switch (state) { 79 switch (state) {
77 case RFKILL_STATE_ON: 80 case RFKILL_STATE_ON:
78 if (!dev->radio_hw_enable) { 81 if (!dev->radio_hw_enable) {
@@ -89,7 +92,6 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
89 b43_radio_turn_off(dev, 0); 92 b43_radio_turn_off(dev, 0);
90 break; 93 break;
91 } 94 }
92
93out_unlock: 95out_unlock:
94 mutex_unlock(&wl->mutex); 96 mutex_unlock(&wl->mutex);
95 97
@@ -98,11 +100,11 @@ out_unlock:
98 100
99char * b43_rfkill_led_name(struct b43_wldev *dev) 101char * b43_rfkill_led_name(struct b43_wldev *dev)
100{ 102{
101 struct b43_wl *wl = dev->wl; 103 struct b43_rfkill *rfk = &(dev->wl->rfkill);
102 104
103 if (!wl->rfkill.rfkill) 105 if (!rfk->registered)
104 return NULL; 106 return NULL;
105 return rfkill_get_led_name(wl->rfkill.rfkill); 107 return rfkill_get_led_name(rfk->rfkill);
106} 108}
107 109
108void b43_rfkill_init(struct b43_wldev *dev) 110void b43_rfkill_init(struct b43_wldev *dev)
@@ -111,53 +113,13 @@ void b43_rfkill_init(struct b43_wldev *dev)
111 struct b43_rfkill *rfk = &(wl->rfkill); 113 struct b43_rfkill *rfk = &(wl->rfkill);
112 int err; 114 int err;
113 115
114 if (rfk->rfkill) { 116 rfk->registered = 0;
115 err = rfkill_register(rfk->rfkill);
116 if (err) {
117 b43warn(wl, "Failed to register RF-kill button\n");
118 goto err_free_rfk;
119 }
120 }
121 if (rfk->poll_dev) {
122 err = input_register_polled_device(rfk->poll_dev);
123 if (err) {
124 b43warn(wl, "Failed to register RF-kill polldev\n");
125 goto err_free_polldev;
126 }
127 }
128
129 return;
130err_free_rfk:
131 rfkill_free(rfk->rfkill);
132 rfk->rfkill = NULL;
133err_free_polldev:
134 input_free_polled_device(rfk->poll_dev);
135 rfk->poll_dev = NULL;
136}
137
138void b43_rfkill_exit(struct b43_wldev *dev)
139{
140 struct b43_rfkill *rfk = &(dev->wl->rfkill);
141
142 if (rfk->poll_dev)
143 input_unregister_polled_device(rfk->poll_dev);
144 if (rfk->rfkill)
145 rfkill_unregister(rfk->rfkill);
146}
147
148void b43_rfkill_alloc(struct b43_wldev *dev)
149{
150 struct b43_wl *wl = dev->wl;
151 struct b43_rfkill *rfk = &(wl->rfkill);
152 117
118 rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
119 if (!rfk->rfkill)
120 goto out_error;
153 snprintf(rfk->name, sizeof(rfk->name), 121 snprintf(rfk->name, sizeof(rfk->name),
154 "b43-%s", wiphy_name(wl->hw->wiphy)); 122 "b43-%s", wiphy_name(wl->hw->wiphy));
155
156 rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
157 if (!rfk->rfkill) {
158 b43warn(wl, "Failed to allocate RF-kill button\n");
159 return;
160 }
161 rfk->rfkill->name = rfk->name; 123 rfk->rfkill->name = rfk->name;
162 rfk->rfkill->state = RFKILL_STATE_ON; 124 rfk->rfkill->state = RFKILL_STATE_ON;
163 rfk->rfkill->data = dev; 125 rfk->rfkill->data = dev;
@@ -165,18 +127,45 @@ void b43_rfkill_alloc(struct b43_wldev *dev)
165 rfk->rfkill->user_claim_unsupported = 1; 127 rfk->rfkill->user_claim_unsupported = 1;
166 128
167 rfk->poll_dev = input_allocate_polled_device(); 129 rfk->poll_dev = input_allocate_polled_device();
168 if (rfk->poll_dev) { 130 if (!rfk->poll_dev)
169 rfk->poll_dev->private = dev; 131 goto err_free_rfk;
170 rfk->poll_dev->poll = b43_rfkill_poll; 132 rfk->poll_dev->private = dev;
171 rfk->poll_dev->poll_interval = 1000; /* msecs */ 133 rfk->poll_dev->poll = b43_rfkill_poll;
172 } else 134 rfk->poll_dev->poll_interval = 1000; /* msecs */
173 b43warn(wl, "Failed to allocate RF-kill polldev\n"); 135
136 err = rfkill_register(rfk->rfkill);
137 if (err)
138 goto err_free_polldev;
139 err = input_register_polled_device(rfk->poll_dev);
140 if (err)
141 goto err_unreg_rfk;
142
143 rfk->registered = 1;
144
145 return;
146err_unreg_rfk:
147 rfkill_unregister(rfk->rfkill);
148err_free_polldev:
149 input_free_polled_device(rfk->poll_dev);
150 rfk->poll_dev = NULL;
151err_free_rfk:
152 rfkill_free(rfk->rfkill);
153 rfk->rfkill = NULL;
154out_error:
155 rfk->registered = 0;
156 b43warn(wl, "RF-kill button init failed\n");
174} 157}
175 158
176void b43_rfkill_free(struct b43_wldev *dev) 159void b43_rfkill_exit(struct b43_wldev *dev)
177{ 160{
178 struct b43_rfkill *rfk = &(dev->wl->rfkill); 161 struct b43_rfkill *rfk = &(dev->wl->rfkill);
179 162
163 if (!rfk->registered)
164 return;
165 rfk->registered = 0;
166
167 input_unregister_polled_device(rfk->poll_dev);
168 rfkill_unregister(rfk->rfkill);
180 input_free_polled_device(rfk->poll_dev); 169 input_free_polled_device(rfk->poll_dev);
181 rfk->poll_dev = NULL; 170 rfk->poll_dev = NULL;
182 rfkill_free(rfk->rfkill); 171 rfkill_free(rfk->rfkill);