diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_leds.c | 68 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_leds.h | 2 |
3 files changed, 50 insertions, 21 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index b1a24de0b7b0..6af0f3f71f3a 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h | |||
@@ -108,6 +108,7 @@ struct rtl8187_priv { | |||
108 | struct delayed_work work; | 108 | struct delayed_work work; |
109 | struct ieee80211_hw *dev; | 109 | struct ieee80211_hw *dev; |
110 | #ifdef CONFIG_RTL8187_LEDS | 110 | #ifdef CONFIG_RTL8187_LEDS |
111 | struct rtl8187_led led_radio; | ||
111 | struct rtl8187_led led_tx; | 112 | struct rtl8187_led led_tx; |
112 | struct rtl8187_led led_rx; | 113 | struct rtl8187_led led_rx; |
113 | struct delayed_work led_on; | 114 | struct delayed_work led_on; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index cf8a4a40fdf6..ded44c045eb2 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c | |||
@@ -105,19 +105,36 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, | |||
105 | struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, | 105 | struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, |
106 | led_dev); | 106 | led_dev); |
107 | struct ieee80211_hw *hw = led->dev; | 107 | struct ieee80211_hw *hw = led->dev; |
108 | struct rtl8187_priv *priv = hw->priv; | 108 | struct rtl8187_priv *priv; |
109 | static bool radio_on; | ||
109 | 110 | ||
110 | if (brightness == LED_OFF) { | 111 | if (!hw) |
111 | ieee80211_queue_delayed_work(hw, &priv->led_off, 0); | 112 | return; |
112 | /* The LED is off for 1/20 sec so that it just blinks. */ | 113 | priv = hw->priv; |
113 | ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20); | 114 | if (led->is_radio) { |
114 | } else | 115 | if (brightness == LED_FULL) { |
115 | ieee80211_queue_delayed_work(hw, &priv->led_on, 0); | 116 | ieee80211_queue_delayed_work(hw, &priv->led_on, 0); |
117 | radio_on = true; | ||
118 | } else if (radio_on) { | ||
119 | radio_on = false; | ||
120 | cancel_delayed_work_sync(&priv->led_on); | ||
121 | ieee80211_queue_delayed_work(hw, &priv->led_off, 0); | ||
122 | } | ||
123 | } else if (radio_on) { | ||
124 | if (brightness == LED_OFF) { | ||
125 | ieee80211_queue_delayed_work(hw, &priv->led_off, 0); | ||
126 | /* The LED is off for 1/20 sec - it just blinks. */ | ||
127 | ieee80211_queue_delayed_work(hw, &priv->led_on, | ||
128 | HZ / 20); | ||
129 | } else | ||
130 | ieee80211_queue_delayed_work(hw, &priv->led_on, 0); | ||
131 | } | ||
116 | } | 132 | } |
117 | 133 | ||
118 | static int rtl8187_register_led(struct ieee80211_hw *dev, | 134 | static int rtl8187_register_led(struct ieee80211_hw *dev, |
119 | struct rtl8187_led *led, const char *name, | 135 | struct rtl8187_led *led, const char *name, |
120 | const char *default_trigger, u8 ledpin) | 136 | const char *default_trigger, u8 ledpin, |
137 | bool is_radio) | ||
121 | { | 138 | { |
122 | int err; | 139 | int err; |
123 | struct rtl8187_priv *priv = dev->priv; | 140 | struct rtl8187_priv *priv = dev->priv; |
@@ -128,6 +145,7 @@ static int rtl8187_register_led(struct ieee80211_hw *dev, | |||
128 | return -EINVAL; | 145 | return -EINVAL; |
129 | led->dev = dev; | 146 | led->dev = dev; |
130 | led->ledpin = ledpin; | 147 | led->ledpin = ledpin; |
148 | led->is_radio = is_radio; | ||
131 | strncpy(led->name, name, sizeof(led->name)); | 149 | strncpy(led->name, name, sizeof(led->name)); |
132 | 150 | ||
133 | led->led_dev.name = led->name; | 151 | led->led_dev.name = led->name; |
@@ -145,7 +163,11 @@ static int rtl8187_register_led(struct ieee80211_hw *dev, | |||
145 | 163 | ||
146 | static void rtl8187_unregister_led(struct rtl8187_led *led) | 164 | static void rtl8187_unregister_led(struct rtl8187_led *led) |
147 | { | 165 | { |
166 | struct ieee80211_hw *hw = led->dev; | ||
167 | struct rtl8187_priv *priv = hw->priv; | ||
168 | |||
148 | led_classdev_unregister(&led->led_dev); | 169 | led_classdev_unregister(&led->led_dev); |
170 | flush_delayed_work(&priv->led_off); | ||
149 | led->dev = NULL; | 171 | led->dev = NULL; |
150 | } | 172 | } |
151 | 173 | ||
@@ -183,33 +205,37 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) | |||
183 | INIT_DELAYED_WORK(&priv->led_off, led_turn_off); | 205 | INIT_DELAYED_WORK(&priv->led_off, led_turn_off); |
184 | 206 | ||
185 | snprintf(name, sizeof(name), | 207 | snprintf(name, sizeof(name), |
208 | "rtl8187-%s::radio", wiphy_name(dev->wiphy)); | ||
209 | err = rtl8187_register_led(dev, &priv->led_radio, name, | ||
210 | ieee80211_get_radio_led_name(dev), ledpin, true); | ||
211 | if (err) | ||
212 | return; | ||
213 | |||
214 | snprintf(name, sizeof(name), | ||
186 | "rtl8187-%s::tx", wiphy_name(dev->wiphy)); | 215 | "rtl8187-%s::tx", wiphy_name(dev->wiphy)); |
187 | err = rtl8187_register_led(dev, &priv->led_tx, name, | 216 | err = rtl8187_register_led(dev, &priv->led_tx, name, |
188 | ieee80211_get_tx_led_name(dev), ledpin); | 217 | ieee80211_get_tx_led_name(dev), ledpin, false); |
189 | if (err) | 218 | if (err) |
190 | goto error; | 219 | goto err_tx; |
220 | |||
191 | snprintf(name, sizeof(name), | 221 | snprintf(name, sizeof(name), |
192 | "rtl8187-%s::rx", wiphy_name(dev->wiphy)); | 222 | "rtl8187-%s::rx", wiphy_name(dev->wiphy)); |
193 | err = rtl8187_register_led(dev, &priv->led_rx, name, | 223 | err = rtl8187_register_led(dev, &priv->led_rx, name, |
194 | ieee80211_get_rx_led_name(dev), ledpin); | 224 | ieee80211_get_rx_led_name(dev), ledpin, false); |
195 | if (!err) { | 225 | if (!err) |
196 | ieee80211_queue_delayed_work(dev, &priv->led_on, 0); | ||
197 | return; | 226 | return; |
198 | } | 227 | |
199 | /* registration of RX LED failed - unregister TX */ | 228 | /* registration of RX LED failed - unregister */ |
200 | rtl8187_unregister_led(&priv->led_tx); | 229 | rtl8187_unregister_led(&priv->led_tx); |
201 | error: | 230 | err_tx: |
202 | /* If registration of either failed, cancel delayed work */ | 231 | rtl8187_unregister_led(&priv->led_radio); |
203 | cancel_delayed_work_sync(&priv->led_off); | ||
204 | cancel_delayed_work_sync(&priv->led_on); | ||
205 | } | 232 | } |
206 | 233 | ||
207 | void rtl8187_leds_exit(struct ieee80211_hw *dev) | 234 | void rtl8187_leds_exit(struct ieee80211_hw *dev) |
208 | { | 235 | { |
209 | struct rtl8187_priv *priv = dev->priv; | 236 | struct rtl8187_priv *priv = dev->priv; |
210 | 237 | ||
211 | /* turn the LED off before exiting */ | 238 | rtl8187_unregister_led(&priv->led_radio); |
212 | ieee80211_queue_delayed_work(dev, &priv->led_off, 0); | ||
213 | rtl8187_unregister_led(&priv->led_rx); | 239 | rtl8187_unregister_led(&priv->led_rx); |
214 | rtl8187_unregister_led(&priv->led_tx); | 240 | rtl8187_unregister_led(&priv->led_tx); |
215 | cancel_delayed_work_sync(&priv->led_off); | 241 | cancel_delayed_work_sync(&priv->led_off); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h index a0332027aead..efe8041bdda4 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.h +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h | |||
@@ -47,6 +47,8 @@ struct rtl8187_led { | |||
47 | u8 ledpin; | 47 | u8 ledpin; |
48 | /* The unique name string for this LED device. */ | 48 | /* The unique name string for this LED device. */ |
49 | char name[RTL8187_LED_MAX_NAME_LEN + 1]; | 49 | char name[RTL8187_LED_MAX_NAME_LEN + 1]; |
50 | /* If the LED is radio or tx/rx */ | ||
51 | bool is_radio; | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); | 54 | void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); |