aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00rfkill.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00rfkill.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c114
1 files changed, 38 insertions, 76 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index fcef9885ab5e..04b29716d356 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -23,7 +23,6 @@
23 Abstract: rt2x00 rfkill routines. 23 Abstract: rt2x00 rfkill routines.
24 */ 24 */
25 25
26#include <linux/input-polldev.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/rfkill.h> 28#include <linux/rfkill.h>
@@ -45,28 +44,51 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
45 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 44 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
46 return 0; 45 return 0;
47 46
48 if (state == RFKILL_STATE_ON) { 47 if (state == RFKILL_STATE_UNBLOCKED) {
49 INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); 48 INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n");
50 __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); 49 __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
51 retval = rt2x00lib_enable_radio(rt2x00dev); 50 retval = rt2x00lib_enable_radio(rt2x00dev);
52 } else if (state == RFKILL_STATE_OFF) { 51 } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
53 INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); 52 INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n");
54 __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); 53 __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
55 rt2x00lib_disable_radio(rt2x00dev); 54 rt2x00lib_disable_radio(rt2x00dev);
55 } else {
56 WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n",
57 state);
56 } 58 }
57 59
58 return retval; 60 return retval;
59} 61}
60 62
61static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) 63static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
62{ 64{
63 struct rt2x00_dev *rt2x00dev = poll_dev->private; 65 struct rt2x00_dev *rt2x00dev = data;
64 int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
65 66
66 if (rt2x00dev->rfkill->state != state) { 67 *state = rt2x00dev->rfkill->state;
67 input_report_key(poll_dev->input, KEY_WLAN, 1); 68
68 input_report_key(poll_dev->input, KEY_WLAN, 0); 69 return 0;
69 } 70}
71
72static void rt2x00rfkill_poll(struct work_struct *work)
73{
74 struct rt2x00_dev *rt2x00dev =
75 container_of(work, struct rt2x00_dev, rfkill_work.work);
76 int state;
77
78 if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
79 return;
80
81 /*
82 * rfkill_poll reports 1 when the key has been pressed and the
83 * radio should be blocked.
84 */
85 state = !rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
86 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
87
88 rfkill_force_state(rt2x00dev->rfkill, state);
89
90 queue_delayed_work(rt2x00dev->hw->workqueue,
91 &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
70} 92}
71 93
72void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) 94void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -80,12 +102,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
80 return; 102 return;
81 } 103 }
82 104
83 if (input_register_polled_device(rt2x00dev->poll_dev)) {
84 ERROR(rt2x00dev, "Failed to register polled device.\n");
85 rfkill_unregister(rt2x00dev->rfkill);
86 return;
87 }
88
89 __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); 105 __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
90 106
91 /* 107 /*
@@ -93,7 +109,7 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
93 * and correctly sends the signal to the rfkill layer about this 109 * and correctly sends the signal to the rfkill layer about this
94 * state. 110 * state.
95 */ 111 */
96 rt2x00rfkill_poll(rt2x00dev->poll_dev); 112 rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work);
97} 113}
98 114
99void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) 115void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
@@ -102,38 +118,13 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
102 !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) 118 !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
103 return; 119 return;
104 120
105 input_unregister_polled_device(rt2x00dev->poll_dev); 121 cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
122
106 rfkill_unregister(rt2x00dev->rfkill); 123 rfkill_unregister(rt2x00dev->rfkill);
107 124
108 __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); 125 __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
109} 126}
110 127
111static struct input_polled_dev *
112rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev)
113{
114 struct input_polled_dev *poll_dev;
115
116 poll_dev = input_allocate_polled_device();
117 if (!poll_dev)
118 return NULL;
119
120 poll_dev->private = rt2x00dev;
121 poll_dev->poll = rt2x00rfkill_poll;
122 poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
123
124 poll_dev->input->name = rt2x00dev->ops->name;
125 poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
126 poll_dev->input->id.bustype = BUS_HOST;
127 poll_dev->input->id.vendor = 0x1814;
128 poll_dev->input->id.product = rt2x00dev->chip.rt;
129 poll_dev->input->id.version = rt2x00dev->chip.rev;
130 poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
131 poll_dev->input->evbit[0] = BIT(EV_KEY);
132 set_bit(KEY_WLAN, poll_dev->input->keybit);
133
134 return poll_dev;
135}
136
137void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) 128void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
138{ 129{
139 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) 130 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
@@ -150,14 +141,9 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
150 rt2x00dev->rfkill->data = rt2x00dev; 141 rt2x00dev->rfkill->data = rt2x00dev;
151 rt2x00dev->rfkill->state = -1; 142 rt2x00dev->rfkill->state = -1;
152 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; 143 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
144 rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
153 145
154 rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev); 146 INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
155 if (!rt2x00dev->poll_dev) {
156 ERROR(rt2x00dev, "Failed to allocate polled device.\n");
157 rfkill_free(rt2x00dev->rfkill);
158 rt2x00dev->rfkill = NULL;
159 return;
160 }
161 147
162 return; 148 return;
163} 149}
@@ -168,32 +154,8 @@ void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
168 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) 154 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
169 return; 155 return;
170 156
171 input_free_polled_device(rt2x00dev->poll_dev); 157 cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
172 rt2x00dev->poll_dev = NULL;
173 158
174 rfkill_free(rt2x00dev->rfkill); 159 rfkill_free(rt2x00dev->rfkill);
175 rt2x00dev->rfkill = NULL; 160 rt2x00dev->rfkill = NULL;
176} 161}
177
178void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
179{
180 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
181 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
182 return;
183
184 input_free_polled_device(rt2x00dev->poll_dev);
185 rt2x00dev->poll_dev = NULL;
186}
187
188void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
189{
190 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
191 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
192 return;
193
194 rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
195 if (!rt2x00dev->poll_dev) {
196 ERROR(rt2x00dev, "Failed to allocate polled device.\n");
197 return;
198 }
199}