diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-03-31 09:53:44 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-01 17:14:09 -0400 |
commit | a2e1d52a32eab53f8ab03c4023310f65aaa054a7 (patch) | |
tree | 93f5f5692f220afbedc4512bdd372084097e5e54 /drivers/net/wireless/rt2x00/rt2x00leds.c | |
parent | e0b005fa1479045fe879944036268af3ebcd1835 (diff) |
rt2x00: Remove MAC80211_LEDS dependency
Implement triggers inside rt2x00 itself based
on input from mac80211. This replaces the method
of using the mac80211 trigger events which do
not work for USB drivers due to the scheduling
requirement.
After this patch RT2500USB_LEDS and RT73USB_LEDS
no longer need to be tagged as broken since they
now support LED handling again without having to
check for in_atomic().
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00leds.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00leds.c | 131 |
1 files changed, 67 insertions, 64 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index ca2d282a9f75..40c1f5c1b805 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -31,7 +31,10 @@ | |||
31 | 31 | ||
32 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) | 32 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) |
33 | { | 33 | { |
34 | if (!rt2x00dev->trigger_qual.registered) | 34 | struct rt2x00_led *led = &rt2x00dev->led_qual; |
35 | unsigned int brightness; | ||
36 | |||
37 | if ((led->type != LED_TYPE_QUALITY) || !(led->flags & LED_REGISTERED)) | ||
35 | return; | 38 | return; |
36 | 39 | ||
37 | /* | 40 | /* |
@@ -62,39 +65,51 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) | |||
62 | * is going to calculate the value and might use it in a | 65 | * is going to calculate the value and might use it in a |
63 | * division. | 66 | * division. |
64 | */ | 67 | */ |
65 | led_trigger_event(&rt2x00dev->trigger_qual.trigger, | 68 | brightness = ((LED_FULL / 6) * rssi) + 1; |
66 | ((LED_FULL / 6) * rssi) + 1); | 69 | if (brightness != led->led_dev.brightness) { |
70 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
71 | led->led_dev.brightness = brightness; | ||
72 | } | ||
67 | } | 73 | } |
68 | 74 | ||
69 | static int rt2x00leds_register_trigger(struct rt2x00_dev *rt2x00dev, | 75 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) |
70 | struct rt2x00_trigger *trigger, | ||
71 | const char *name) | ||
72 | { | 76 | { |
73 | int retval; | 77 | struct rt2x00_led *led = &rt2x00dev->led_assoc; |
78 | unsigned int brightness; | ||
74 | 79 | ||
75 | trigger->trigger.name = name; | 80 | if ((led->type != LED_TYPE_ASSOC) || !(led->flags & LED_REGISTERED)) |
76 | retval = led_trigger_register(&trigger->trigger); | 81 | return; |
77 | if (retval) { | 82 | |
78 | ERROR(rt2x00dev, "Failed to register led trigger.\n"); | 83 | brightness = enabled ? LED_FULL : LED_OFF; |
79 | return retval; | 84 | if (brightness != led->led_dev.brightness) { |
85 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
86 | led->led_dev.brightness = brightness; | ||
80 | } | 87 | } |
88 | } | ||
81 | 89 | ||
82 | trigger->registered = 1; | 90 | void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) |
91 | { | ||
92 | struct rt2x00_led *led = &rt2x00dev->led_radio; | ||
93 | unsigned int brightness; | ||
83 | 94 | ||
84 | return 0; | 95 | if ((led->type != LED_TYPE_RADIO) || !(led->flags & LED_REGISTERED)) |
96 | return; | ||
97 | |||
98 | brightness = enabled ? LED_FULL : LED_OFF; | ||
99 | if (brightness != led->led_dev.brightness) { | ||
100 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
101 | led->led_dev.brightness = brightness; | ||
102 | } | ||
85 | } | 103 | } |
86 | 104 | ||
87 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | 105 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, |
88 | struct rt2x00_led *led, | 106 | struct rt2x00_led *led, |
89 | enum led_type type, | 107 | const char *name) |
90 | const char *name, char *trigger) | ||
91 | { | 108 | { |
92 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | 109 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); |
93 | int retval; | 110 | int retval; |
94 | 111 | ||
95 | led->led_dev.name = name; | 112 | led->led_dev.name = name; |
96 | led->led_dev.brightness_set = rt2x00dev->ops->lib->led_brightness; | ||
97 | led->led_dev.default_trigger = trigger; | ||
98 | 113 | ||
99 | retval = led_classdev_register(device, &led->led_dev); | 114 | retval = led_classdev_register(device, &led->led_dev); |
100 | if (retval) { | 115 | if (retval) { |
@@ -102,115 +117,103 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | |||
102 | return retval; | 117 | return retval; |
103 | } | 118 | } |
104 | 119 | ||
105 | led->rt2x00dev = rt2x00dev; | 120 | led->flags |= LED_REGISTERED; |
106 | led->type = type; | ||
107 | led->registered = 1; | ||
108 | 121 | ||
109 | return 0; | 122 | return 0; |
110 | } | 123 | } |
111 | 124 | ||
112 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | 125 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) |
113 | { | 126 | { |
114 | char *trigger; | ||
115 | char dev_name[16]; | 127 | char dev_name[16]; |
116 | char name[32]; | 128 | char name[32]; |
117 | int retval; | 129 | int retval; |
118 | 130 | unsigned long on_period; | |
119 | if (!rt2x00dev->ops->lib->led_brightness) | 131 | unsigned long off_period; |
120 | return; | ||
121 | 132 | ||
122 | snprintf(dev_name, sizeof(dev_name), "%s-%s", | 133 | snprintf(dev_name, sizeof(dev_name), "%s-%s", |
123 | rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); | 134 | rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); |
124 | 135 | ||
125 | if (rt2x00dev->led_flags & LED_SUPPORT_RADIO) { | 136 | if (rt2x00dev->led_radio.flags & LED_INITIALIZED) { |
126 | trigger = ieee80211_get_radio_led_name(rt2x00dev->hw); | ||
127 | snprintf(name, sizeof(name), "%s:radio", dev_name); | 137 | snprintf(name, sizeof(name), "%s:radio", dev_name); |
128 | 138 | ||
129 | retval = rt2x00leds_register_led(rt2x00dev, | 139 | retval = rt2x00leds_register_led(rt2x00dev, |
130 | &rt2x00dev->led_radio, | 140 | &rt2x00dev->led_radio, |
131 | LED_TYPE_RADIO, | 141 | name); |
132 | name, trigger); | ||
133 | if (retval) | 142 | if (retval) |
134 | goto exit_fail; | 143 | goto exit_fail; |
135 | } | 144 | } |
136 | 145 | ||
137 | if (rt2x00dev->led_flags & LED_SUPPORT_ASSOC) { | 146 | if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) { |
138 | trigger = ieee80211_get_assoc_led_name(rt2x00dev->hw); | ||
139 | snprintf(name, sizeof(name), "%s:assoc", dev_name); | 147 | snprintf(name, sizeof(name), "%s:assoc", dev_name); |
140 | 148 | ||
141 | retval = rt2x00leds_register_led(rt2x00dev, | 149 | retval = rt2x00leds_register_led(rt2x00dev, |
142 | &rt2x00dev->led_assoc, | 150 | &rt2x00dev->led_assoc, |
143 | LED_TYPE_ASSOC, | 151 | name); |
144 | name, trigger); | ||
145 | if (retval) | 152 | if (retval) |
146 | goto exit_fail; | 153 | goto exit_fail; |
147 | } | 154 | } |
148 | 155 | ||
149 | if (rt2x00dev->led_flags & LED_SUPPORT_QUALITY) { | 156 | if (rt2x00dev->led_qual.flags & LED_INITIALIZED) { |
150 | snprintf(name, sizeof(name), "%s:quality", dev_name); | 157 | snprintf(name, sizeof(name), "%s:quality", dev_name); |
151 | 158 | ||
152 | retval = rt2x00leds_register_trigger(rt2x00dev, | ||
153 | &rt2x00dev->trigger_qual, | ||
154 | name); | ||
155 | |||
156 | retval = rt2x00leds_register_led(rt2x00dev, | 159 | retval = rt2x00leds_register_led(rt2x00dev, |
157 | &rt2x00dev->led_qual, | 160 | &rt2x00dev->led_qual, |
158 | LED_TYPE_QUALITY, | 161 | name); |
159 | name, name); | ||
160 | if (retval) | 162 | if (retval) |
161 | goto exit_fail; | 163 | goto exit_fail; |
162 | } | 164 | } |
163 | 165 | ||
166 | /* | ||
167 | * Initialize blink time to default value: | ||
168 | * On period: 70ms | ||
169 | * Off period: 30ms | ||
170 | */ | ||
171 | if (rt2x00dev->led_radio.led_dev.blink_set) { | ||
172 | on_period = 70; | ||
173 | off_period = 30; | ||
174 | rt2x00dev->led_radio.led_dev.blink_set( | ||
175 | &rt2x00dev->led_radio.led_dev, &on_period, &off_period); | ||
176 | } | ||
177 | |||
164 | return; | 178 | return; |
165 | 179 | ||
166 | exit_fail: | 180 | exit_fail: |
167 | rt2x00leds_unregister(rt2x00dev); | 181 | rt2x00leds_unregister(rt2x00dev); |
168 | } | 182 | } |
169 | 183 | ||
170 | static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger) | ||
171 | { | ||
172 | if (!trigger->registered) | ||
173 | return; | ||
174 | |||
175 | led_trigger_unregister(&trigger->trigger); | ||
176 | trigger->registered = 0; | ||
177 | } | ||
178 | |||
179 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) | 184 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) |
180 | { | 185 | { |
181 | if (!led->registered) | ||
182 | return; | ||
183 | |||
184 | led_classdev_unregister(&led->led_dev); | 186 | led_classdev_unregister(&led->led_dev); |
185 | |||
186 | led->led_dev.brightness_set(&led->led_dev, LED_OFF); | 187 | led->led_dev.brightness_set(&led->led_dev, LED_OFF); |
187 | led->registered = 0; | 188 | led->flags &= ~LED_REGISTERED; |
188 | } | 189 | } |
189 | 190 | ||
190 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | 191 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) |
191 | { | 192 | { |
192 | rt2x00leds_unregister_trigger(&rt2x00dev->trigger_qual); | 193 | if (rt2x00dev->led_qual.flags & LED_REGISTERED) |
193 | rt2x00leds_unregister_led(&rt2x00dev->led_qual); | 194 | rt2x00leds_unregister_led(&rt2x00dev->led_qual); |
194 | rt2x00leds_unregister_led(&rt2x00dev->led_assoc); | 195 | if (rt2x00dev->led_assoc.flags & LED_REGISTERED) |
195 | rt2x00leds_unregister_led(&rt2x00dev->led_radio); | 196 | rt2x00leds_unregister_led(&rt2x00dev->led_assoc); |
197 | if (rt2x00dev->led_radio.flags & LED_REGISTERED) | ||
198 | rt2x00leds_unregister_led(&rt2x00dev->led_radio); | ||
196 | } | 199 | } |
197 | 200 | ||
198 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | 201 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) |
199 | { | 202 | { |
200 | if (rt2x00dev->led_qual.registered) | 203 | if (rt2x00dev->led_qual.flags & LED_REGISTERED) |
201 | led_classdev_suspend(&rt2x00dev->led_qual.led_dev); | 204 | led_classdev_suspend(&rt2x00dev->led_qual.led_dev); |
202 | if (rt2x00dev->led_assoc.registered) | 205 | if (rt2x00dev->led_assoc.flags & LED_REGISTERED) |
203 | led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); | 206 | led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); |
204 | if (rt2x00dev->led_radio.registered) | 207 | if (rt2x00dev->led_radio.flags & LED_REGISTERED) |
205 | led_classdev_suspend(&rt2x00dev->led_radio.led_dev); | 208 | led_classdev_suspend(&rt2x00dev->led_radio.led_dev); |
206 | } | 209 | } |
207 | 210 | ||
208 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | 211 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) |
209 | { | 212 | { |
210 | if (rt2x00dev->led_radio.registered) | 213 | if (rt2x00dev->led_radio.flags & LED_REGISTERED) |
211 | led_classdev_resume(&rt2x00dev->led_radio.led_dev); | 214 | led_classdev_resume(&rt2x00dev->led_radio.led_dev); |
212 | if (rt2x00dev->led_assoc.registered) | 215 | if (rt2x00dev->led_assoc.flags & LED_REGISTERED) |
213 | led_classdev_resume(&rt2x00dev->led_assoc.led_dev); | 216 | led_classdev_resume(&rt2x00dev->led_assoc.led_dev); |
214 | if (rt2x00dev->led_qual.registered) | 217 | if (rt2x00dev->led_qual.flags & LED_REGISTERED) |
215 | led_classdev_resume(&rt2x00dev->led_qual.led_dev); | 218 | led_classdev_resume(&rt2x00dev->led_qual.led_dev); |
216 | } | 219 | } |