mac80211: ath9k: rework led allocation

Embed gpio_led struct in ath_led. Simpler Allocation.

Use a flex array for the name. Allows using a single allocation.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21933
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Rosen Penev 2025-06-07 20:13:26 -07:00 committed by Robert Marko
parent 06f5205dc8
commit f01807e353
4 changed files with 28 additions and 33 deletions

View file

@ -13,7 +13,7 @@ Signed-off-by: Paweł Owoc <frut3k7@gmail.com>
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -2682,7 +2682,7 @@ int ath11k_wmi_send_wmm_update_cmd_tlv(s
@@ -2688,7 +2688,7 @@ int ath11k_wmi_send_wmm_update_cmd_tlv(s
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
cmd->vdev_id = vdev_id;

View file

@ -10,21 +10,22 @@
#else
static inline void ath_init_leds(struct ath_softc *sc)
{
@@ -980,6 +983,13 @@ void ath_ant_comb_scan(struct ath_softc
@@ -980,6 +983,14 @@ void ath_ant_comb_scan(struct ath_softc
#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
+struct ath_led {
+ struct list_head list;
+ struct ath_softc *sc;
+ const struct gpio_led *gpio;
+ struct gpio_led gpio;
+ struct led_classdev cdev;
+ char name[];
+};
+
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -1035,9 +1045,8 @@ struct ath_softc {
@@ -1035,9 +1046,8 @@ struct ath_softc {
spinlock_t chan_lock;
#ifdef CPTCFG_MAC80211_LEDS
@ -38,7 +39,7 @@
#ifdef CPTCFG_ATH9K_DEBUGFS
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -39,61 +39,111 @@ static void ath_fill_led_pin(struct ath_
@@ -39,61 +39,112 @@ static void ath_fill_led_pin(struct ath_
else
ah->led_pin = ATH_LED_PIN_DEF;
}
@ -49,16 +50,17 @@
+{
+ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
+ struct ath_softc *sc = led->sc;
+ const struct gpio_led *gpio = &led->gpio;
+
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
+ (brightness != LED_OFF) ^ led->gpio->active_low);
+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio,
+ (brightness != LED_OFF) ^ gpio->active_low);
+ ath9k_ps_restore(sc);
+}
+
+static int ath_add_led(struct ath_softc *sc, struct ath_led *led)
+{
+ const struct gpio_led *gpio = led->gpio;
+ const struct gpio_led *gpio = &led->gpio;
+ int ret;
+
+ led->cdev.name = gpio->name;
@ -94,30 +96,28 @@
- u32 val = (brightness == LED_OFF);
+ struct ath_led *led;
+ struct gpio_led *gpio;
+ char *_name;
+ int ret;
- if (sc->sc_ah->config.led_active_high)
- val = !val;
+ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1,
+ GFP_KERNEL);
+ led = kzalloc(struct_size(led, name, strlen(name) + 1), GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ led->gpio = gpio = (struct gpio_led *) (led + 1);
+ _name = (char *) (led->gpio + 1);
+ strcpy(led->name, name);
+
+ strcpy(_name, name);
+ gpio->name = _name;
+ gpio = &led->gpio;
+ gpio->name = led->name;
+ gpio->gpio = gpio_num;
+ gpio->active_low = active_low;
+ gpio->default_trigger = trigger;
+
+ ret = ath_add_led(sc, led);
+ if (unlikely(ret < 0))
+ kfree(led);
+ if (likely(ret >= 0))
+ return ret;
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
+ kfree(led);
+ return ret;
}
@ -126,6 +126,7 @@
- if (!sc->led_registered)
- return;
+ struct ath_led *led;
+ struct gpio_led *gpio;
- ath_led_brightness(&sc->led_cdev, LED_OFF);
- led_classdev_unregister(&sc->led_cdev);
@ -136,7 +137,8 @@
+ list_del(&led->list);
+ ath_led_brightness(&led->cdev, LED_OFF);
+ led_classdev_unregister(&led->cdev);
+ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
+ gpio = &led->gpio;
+ ath9k_hw_gpio_free(sc->sc_ah, gpio->gpio);
+ kfree(led);
+ }
}

View file

@ -13,7 +13,7 @@ Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -73,8 +73,11 @@ static int ath_add_led(struct ath_softc
@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc
ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);

View file

@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#include "common.h"
#include "debug.h"
@@ -1047,6 +1049,10 @@ struct ath_softc {
@@ -1048,6 +1050,10 @@ struct ath_softc {
#ifdef CPTCFG_MAC80211_LEDS
const char *led_default_trigger;
struct list_head leds;
@ -157,7 +157,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static void ath_fill_led_pin(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
@@ -79,6 +189,12 @@ static int ath_add_led(struct ath_softc
@@ -80,6 +190,12 @@ static int ath_add_led(struct ath_softc
else
ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
@ -170,7 +170,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return 0;
}
@@ -117,16 +233,23 @@ void ath_deinit_leds(struct ath_softc *s
@@ -117,6 +233,11 @@ void ath_deinit_leds(struct ath_softc *s
while (!list_empty(&sc->leds)) {
led = list_first_entry(&sc->leds, struct ath_led, list);
@ -182,27 +182,20 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
list_del(&led->list);
ath_led_brightness(&led->cdev, LED_OFF);
led_classdev_unregister(&led->cdev);
ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
@@ -124,6 +245,7 @@ void ath_deinit_leds(struct ath_softc *s
ath9k_hw_gpio_free(sc->sc_ah, gpio->gpio);
kfree(led);
}
+ ath9k_unregister_gpio_chip(sc);
}
void ath_init_leds(struct ath_softc *sc)
{
+ struct device_node *np = sc->dev->of_node;
char led_name[32];
const char *trigger;
@@ -135,6 +258,15 @@ void ath_init_leds(struct ath_softc *sc)
@@ -136,6 +258,12 @@ void ath_init_leds(struct ath_softc *sc)
if (AR_SREV_9100(sc->sc_ah))
return;
+ if (!np)
+ ath9k_register_gpio_chip(sc);
+
+ /* setup gpio controller only if requested and skip the led_pin setup */
+ if (of_property_read_bool(np, "gpio-controller")) {
+ if (device_property_present(sc->dev, "gpio-controller")) {
+ ath9k_register_gpio_chip(sc);
+ return;
+ }