diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00rfkill.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00rfkill.c | 114 |
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 | ||
61 | static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) | 63 | static 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 | |||
72 | static 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 | ||
72 | void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | 94 | void 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 | ||
99 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | 115 | void 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 | ||
111 | static struct input_polled_dev * | ||
112 | rt2x00rfkill_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 | |||
137 | void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) | 128 | void 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 | |||
178 | void 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 | |||
188 | void 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 | } | ||