diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2009-01-03 13:56:02 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 15:59:47 -0500 |
commit | cca3e99861e883358ceb39ad17c9eaee082138a5 (patch) | |
tree | 7876976ddc1e60e510fdf905ac9fd3fca939d1d7 /drivers | |
parent | c97c92d92715ea4ea2d7cf00957e8a014439bdd8 (diff) |
rt2x00: Replace RFKILL with INPUT
As discussed on linux-wireless rt2x00 does not offer a true RFKILL key,
for that reason RFKILL support should be entirely removed.
The key which is attached to the hardware should be treated as normal
input device instead. Implement input_poll_dev support to poll the device
frequently. When the key status has changed report it as a SW event.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/rt2x00/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00rfkill.c | 122 |
4 files changed, 46 insertions, 90 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 178b313293b4..bfc5d9cf716e 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -97,10 +97,11 @@ config RT2X00_LIB_CRYPTO | |||
97 | 97 | ||
98 | config RT2X00_LIB_RFKILL | 98 | config RT2X00_LIB_RFKILL |
99 | boolean | 99 | boolean |
100 | default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n) | 100 | default y if (RT2X00_LIB=y && INPUT=y) || (RT2X00_LIB=m && INPUT!=n) |
101 | select INPUT_POLLDEV | ||
101 | 102 | ||
102 | comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00" | 103 | comment "rt2x00 rfkill support disabled due to modularized INPUT and built-in rt2x00" |
103 | depends on RT2X00_LIB=y && RFKILL=m | 104 | depends on RT2X00_LIB=y && INPUT=m |
104 | 105 | ||
105 | config RT2X00_LIB_LEDS | 106 | config RT2X00_LIB_LEDS |
106 | boolean | 107 | boolean |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 890c7216cf38..27c0f335f403 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/leds.h> | 33 | #include <linux/leds.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | #include <linux/input-polldev.h> | ||
36 | 37 | ||
37 | #include <net/mac80211.h> | 38 | #include <net/mac80211.h> |
38 | 39 | ||
@@ -638,8 +639,8 @@ struct rt2x00_dev { | |||
638 | unsigned long rfkill_state; | 639 | unsigned long rfkill_state; |
639 | #define RFKILL_STATE_ALLOCATED 1 | 640 | #define RFKILL_STATE_ALLOCATED 1 |
640 | #define RFKILL_STATE_REGISTERED 2 | 641 | #define RFKILL_STATE_REGISTERED 2 |
641 | struct rfkill *rfkill; | 642 | #define RFKILL_STATE_BLOCKED 3 |
642 | struct delayed_work rfkill_work; | 643 | struct input_polled_dev *rfkill_poll_dev; |
643 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | 644 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
644 | 645 | ||
645 | /* | 646 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 5e8df250e50d..92918f315ee5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -33,7 +33,7 @@ | |||
33 | * Both the link tuner as the rfkill will be called once per second. | 33 | * Both the link tuner as the rfkill will be called once per second. |
34 | */ | 34 | */ |
35 | #define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) ) | 35 | #define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) ) |
36 | #define RFKILL_POLL_INTERVAL ( round_jiffies_relative(HZ) ) | 36 | #define RFKILL_POLL_INTERVAL ( 1000 ) |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * rt2x00_rate: Per rate device information | 39 | * rt2x00_rate: Per rate device information |
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index 3298cae1e12d..595efd05ce44 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
@@ -25,73 +25,30 @@ | |||
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/rfkill.h> | ||
29 | 28 | ||
30 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
31 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
32 | 31 | ||
33 | static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state) | 32 | static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) |
34 | { | 33 | { |
35 | struct rt2x00_dev *rt2x00dev = data; | 34 | struct rt2x00_dev *rt2x00dev = poll_dev->private; |
36 | int retval = 0; | 35 | int state, old_state; |
37 | |||
38 | if (unlikely(!rt2x00dev)) | ||
39 | return 0; | ||
40 | |||
41 | /* | ||
42 | * Only continue if there are enabled interfaces. | ||
43 | */ | ||
44 | if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) | ||
45 | return 0; | ||
46 | |||
47 | if (state == RFKILL_STATE_UNBLOCKED) { | ||
48 | INFO(rt2x00dev, "RFKILL event: enabling radio.\n"); | ||
49 | clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags); | ||
50 | retval = rt2x00lib_enable_radio(rt2x00dev); | ||
51 | } else if (state == RFKILL_STATE_SOFT_BLOCKED) { | ||
52 | INFO(rt2x00dev, "RFKILL event: disabling radio.\n"); | ||
53 | set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags); | ||
54 | rt2x00lib_disable_radio(rt2x00dev); | ||
55 | } else { | ||
56 | WARNING(rt2x00dev, "RFKILL event: unknown state %d.\n", state); | ||
57 | } | ||
58 | |||
59 | return retval; | ||
60 | } | ||
61 | |||
62 | static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state) | ||
63 | { | ||
64 | struct rt2x00_dev *rt2x00dev = data; | ||
65 | |||
66 | /* | ||
67 | * rfkill_poll reports 1 when the key has been pressed and the | ||
68 | * radio should be blocked. | ||
69 | */ | ||
70 | *state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ? | ||
71 | RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED; | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static void rt2x00rfkill_poll(struct work_struct *work) | ||
77 | { | ||
78 | struct rt2x00_dev *rt2x00dev = | ||
79 | container_of(work, struct rt2x00_dev, rfkill_work.work); | ||
80 | enum rfkill_state state; | ||
81 | 36 | ||
82 | if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) || | 37 | if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) || |
83 | !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | 38 | !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) |
84 | return; | 39 | return; |
85 | 40 | ||
86 | /* | 41 | /* |
87 | * Poll latest state and report it to rfkill who should sort | 42 | * Poll latest state, if the state is different then the previous state, |
88 | * out if the state should be toggled or not. | 43 | * we should generate an input event. |
89 | */ | 44 | */ |
90 | if (!rt2x00rfkill_get_state(rt2x00dev, &state)) | 45 | state = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); |
91 | rfkill_force_state(rt2x00dev->rfkill, state); | 46 | old_state = !!test_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state); |
92 | 47 | ||
93 | queue_delayed_work(rt2x00dev->hw->workqueue, | 48 | if (old_state != state) { |
94 | &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL); | 49 | input_report_switch(poll_dev->input, SW_RFKILL_ALL, state); |
50 | change_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state); | ||
51 | } | ||
95 | } | 52 | } |
96 | 53 | ||
97 | void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | 54 | void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) |
@@ -100,8 +57,8 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | |||
100 | test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) | 57 | test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) |
101 | return; | 58 | return; |
102 | 59 | ||
103 | if (rfkill_register(rt2x00dev->rfkill)) { | 60 | if (input_register_polled_device(rt2x00dev->rfkill_poll_dev)) { |
104 | ERROR(rt2x00dev, "Failed to register rfkill handler.\n"); | 61 | ERROR(rt2x00dev, "Failed to register polled device.\n"); |
105 | return; | 62 | return; |
106 | } | 63 | } |
107 | 64 | ||
@@ -109,10 +66,10 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | |||
109 | 66 | ||
110 | /* | 67 | /* |
111 | * Force initial poll which will detect the initial device state, | 68 | * Force initial poll which will detect the initial device state, |
112 | * and correctly sends the signal to the rfkill layer about this | 69 | * and correctly sends the signal to the input layer about this |
113 | * state. | 70 | * state. |
114 | */ | 71 | */ |
115 | rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work); | 72 | rt2x00rfkill_poll(rt2x00dev->rfkill_poll_dev); |
116 | } | 73 | } |
117 | 74 | ||
118 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | 75 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) |
@@ -121,52 +78,49 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | |||
121 | !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) | 78 | !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) |
122 | return; | 79 | return; |
123 | 80 | ||
124 | cancel_delayed_work_sync(&rt2x00dev->rfkill_work); | 81 | input_unregister_polled_device(rt2x00dev->rfkill_poll_dev); |
125 | |||
126 | rfkill_unregister(rt2x00dev->rfkill); | ||
127 | 82 | ||
128 | __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); | 83 | __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); |
129 | } | 84 | } |
130 | 85 | ||
131 | void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) | 86 | void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) |
132 | { | 87 | { |
133 | struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy); | 88 | struct input_polled_dev *poll_dev; |
134 | 89 | ||
135 | if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) | 90 | if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) |
136 | return; | 91 | return; |
137 | 92 | ||
138 | rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN); | 93 | poll_dev = input_allocate_polled_device(); |
139 | if (!rt2x00dev->rfkill) { | 94 | if (!poll_dev) { |
140 | ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); | 95 | ERROR(rt2x00dev, "Failed to allocate polled device.\n"); |
141 | return; | 96 | return; |
142 | } | 97 | } |
143 | 98 | ||
144 | __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state); | 99 | poll_dev->private = rt2x00dev; |
100 | poll_dev->poll = rt2x00rfkill_poll; | ||
101 | poll_dev->poll_interval = RFKILL_POLL_INTERVAL; | ||
145 | 102 | ||
146 | rt2x00dev->rfkill->name = rt2x00dev->ops->name; | 103 | poll_dev->input->name = rt2x00dev->ops->name; |
147 | rt2x00dev->rfkill->data = rt2x00dev; | 104 | poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); |
148 | rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; | 105 | poll_dev->input->id.bustype = BUS_HOST; |
149 | if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) { | 106 | poll_dev->input->id.vendor = 0x1814; |
150 | rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state; | 107 | poll_dev->input->id.product = rt2x00dev->chip.rt; |
151 | rt2x00dev->rfkill->state = | 108 | poll_dev->input->id.version = rt2x00dev->chip.rev; |
152 | rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ? | 109 | poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy); |
153 | RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED; | 110 | poll_dev->input->evbit[0] = BIT(EV_SW); |
154 | } else { | 111 | poll_dev->input->swbit[0] = BIT(SW_RFKILL_ALL); |
155 | rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
156 | } | ||
157 | 112 | ||
158 | INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll); | 113 | rt2x00dev->rfkill_poll_dev = poll_dev; |
159 | 114 | ||
160 | return; | 115 | __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state); |
161 | } | 116 | } |
162 | 117 | ||
163 | void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) | 118 | void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) |
164 | { | 119 | { |
165 | if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) | 120 | if (!__test_and_clear_bit(RFKILL_STATE_ALLOCATED, |
121 | &rt2x00dev->rfkill_state)) | ||
166 | return; | 122 | return; |
167 | 123 | ||
168 | cancel_delayed_work_sync(&rt2x00dev->rfkill_work); | 124 | input_free_polled_device(rt2x00dev->rfkill_poll_dev); |
169 | 125 | rt2x00dev->rfkill_poll_dev = NULL; | |
170 | rfkill_free(rt2x00dev->rfkill); | ||
171 | rt2x00dev->rfkill = NULL; | ||
172 | } | 126 | } |