* [PATCH ath-next v2] wifi: ath9k: don't re-request the LED GPIO in ath9k_stop()
@ 2026-10-28 3:40 Rosen Penev
2026-10-28 9:21 ` Bartosz Golaszewski
0 siblings, 1 reply; 2+ messages in thread
From: Rosen Penev @ 2026-10-28 3:40 UTC (permalink / raw)
To: linux-wireless
Cc: Toke Høiland-Jørgensen, Linus Walleij,
Bartosz Golaszewski, Giedrius Statkevičius, Kalle Valo,
open list,
open list:GPIO
SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set)
ath9k_deinit_device() frees the LED pin in ath_deinit_leds() before it
unregisters the hw. ath9k_stop() then switches the LED pin back to an
input with ath9k_hw_gpio_request_in(). For a SoC GPIO outside of the
WMAC, ath9k_hw_gpio_request() takes a new descriptor through
gpiod_get_index() at that point, and nothing releases it again. The
next probe fails with "request GPIO12 failed:-16" and every LED update
hits the WARN_ON() in ath9k_hw_set_gpio(). That request also runs
under sc->sc_pcu_lock, while gpiod_get_index() and
gpiod_set_consumer_name() may sleep.
The input direction was only added for symmetry with ath9k_start(); the
suspend/resume fix that brought it back only needed the output side.
On WMAC pins it also undoes the "LED off" level written just before it.
Drop it, so the pin simply stays an output driven to the off level.
ath9k_stop() still writes the LED pin, so free the pin after
ieee80211_unregister_hw() instead of in ath_deinit_leds(); otherwise
that write hits the WARN_ON() in ath9k_hw_set_gpio() on SoC GPIOs. This
also frees the pin when the LED class device could not be registered,
which leaked it before.
Seen on a TP-Link Archer C7 v2 (QCA9558, LED on SoC GPIO 12) when
reloading ath9k.
Fixes: e34f2ff40e03 ("ath9k: bring back direction setting in ath9k_{start_stop}")
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
v2: remove ath9k_hw_gpio_free in ath_deinit_leds
drivers/net/wireless/ath/ath9k/gpio.c | 2 --
drivers/net/wireless/ath/ath9k/init.c | 5 +++++
drivers/net/wireless/ath/ath9k/main.c | 4 +---
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 2dbc7efdd637..d525d8ef9369 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -67,8 +67,6 @@ void ath_deinit_leds(struct ath_softc *sc)
ath_led_brightness(&sc->led_cdev, LED_OFF);
led_classdev_unregister(&sc->led_cdev);
-
- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin);
}
void ath_init_leds(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index a7a11781d83d..d35460e352d9 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1128,6 +1128,11 @@ void ath9k_deinit_device(struct ath_softc *sc)
ath9k_deinit_debug(sc);
ath9k_deinit_wow(hw);
ieee80211_unregister_hw(hw);
+
+ /* ath9k_stop() still drives the LED pin, so release it only now */
+ if (sc->sc_ah->led_pin >= 0)
+ ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin);
+
ath_rx_cleanup(sc);
ath9k_deinit_softc(sc);
}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 740a6fc7b067..07797cc89ee0 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -942,11 +942,9 @@ static void ath9k_stop(struct ieee80211_hw *hw, bool suspend)
spin_lock_bh(&sc->sc_pcu_lock);
- if (ah->led_pin >= 0) {
+ if (ah->led_pin >= 0)
ath9k_hw_set_gpio(ah, ah->led_pin,
(ah->config.led_active_high) ? 0 : 1);
- ath9k_hw_gpio_request_in(ah, ah->led_pin, NULL);
- }
ath_prepare_reset(sc);
--
2.56.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH ath-next v2] wifi: ath9k: don't re-request the LED GPIO in ath9k_stop()
2026-10-28 3:40 [PATCH ath-next v2] wifi: ath9k: don't re-request the LED GPIO in ath9k_stop() Rosen Penev
@ 2026-10-28 9:21 ` Bartosz Golaszewski
0 siblings, 0 replies; 2+ messages in thread
From: Bartosz Golaszewski @ 2026-10-28 9:21 UTC (permalink / raw)
To: Rosen Penev
Cc: Toke Høiland-Jørgensen, Linus Walleij,
Bartosz Golaszewski, Giedrius Statkevičius, Kalle Valo,
open list,
open list:GPIO
SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
linux-wireless
On Wed, 28 Oct 2026 04:40:57 +0100, Rosen Penev <rosenp@gmail.com> said:
> ath9k_deinit_device() frees the LED pin in ath_deinit_leds() before it
> unregisters the hw. ath9k_stop() then switches the LED pin back to an
> input with ath9k_hw_gpio_request_in(). For a SoC GPIO outside of the
> WMAC, ath9k_hw_gpio_request() takes a new descriptor through
> gpiod_get_index() at that point, and nothing releases it again. The
> next probe fails with "request GPIO12 failed:-16" and every LED update
> hits the WARN_ON() in ath9k_hw_set_gpio(). That request also runs
> under sc->sc_pcu_lock, while gpiod_get_index() and
> gpiod_set_consumer_name() may sleep.
>
> The input direction was only added for symmetry with ath9k_start(); the
> suspend/resume fix that brought it back only needed the output side.
> On WMAC pins it also undoes the "LED off" level written just before it.
> Drop it, so the pin simply stays an output driven to the off level.
>
> ath9k_stop() still writes the LED pin, so free the pin after
> ieee80211_unregister_hw() instead of in ath_deinit_leds(); otherwise
> that write hits the WARN_ON() in ath9k_hw_set_gpio() on SoC GPIOs. This
> also frees the pin when the LED class device could not be registered,
> which leaked it before.
>
> Seen on a TP-Link Archer C7 v2 (QCA9558, LED on SoC GPIO 12) when
> reloading ath9k.
>
> Fixes: e34f2ff40e03 ("ath9k: bring back direction setting in ath9k_{start_stop}")
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-28 9:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-28 3:40 [PATCH ath-next v2] wifi: ath9k: don't re-request the LED GPIO in ath9k_stop() Rosen Penev
2026-10-28 9:21 ` Bartosz Golaszewski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®