-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplify patch with gpiochip_add_data, struct reduction, new GPIO API, and header cleanup. Signed-off-by: Rosen Penev <[email protected]> Link: openwrt/openwrt#16635 Signed-off-by: Robert Marko <[email protected]>
- Loading branch information
Showing
2 changed files
with
56 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,47 +10,32 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
--- | ||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h | ||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h | ||
@@ -25,6 +25,7 @@ | ||
@@ -25,6 +25,8 @@ | ||
#include <linux/completion.h> | ||
#include <linux/time.h> | ||
#include <linux/hw_random.h> | ||
+#include <linux/gpio/driver.h> | ||
+#include <linux/gpio/consumer.h> | ||
|
||
#include "common.h" | ||
#include "debug.h" | ||
@@ -991,6 +992,14 @@ struct ath_led { | ||
struct led_classdev cdev; | ||
}; | ||
|
||
+#ifdef CONFIG_GPIOLIB | ||
+struct ath9k_gpio_chip { | ||
+ struct ath_softc *sc; | ||
+ char label[32]; | ||
+ struct gpio_chip gchip; | ||
+}; | ||
+#endif | ||
+ | ||
struct ath_softc { | ||
struct ieee80211_hw *hw; | ||
struct device *dev; | ||
@@ -1046,6 +1055,9 @@ struct ath_softc { | ||
@@ -1046,6 +1048,10 @@ struct ath_softc { | ||
#ifdef CPTCFG_MAC80211_LEDS | ||
const char *led_default_trigger; | ||
struct list_head leds; | ||
+#ifdef CONFIG_GPIOLIB | ||
+ struct ath9k_gpio_chip *gpiochip; | ||
+ struct gpio_chip *gpiochip; | ||
+ struct gpio_desc *gpiodesc; | ||
+#endif | ||
#endif | ||
|
||
#ifdef CPTCFG_ATH9K_DEBUGFS | ||
--- a/drivers/net/wireless/ath/ath9k/gpio.c | ||
+++ b/drivers/net/wireless/ath/ath9k/gpio.c | ||
@@ -15,13 +15,131 @@ | ||
*/ | ||
@@ -16,12 +16,123 @@ | ||
|
||
#include "ath9k.h" | ||
+#include <linux/gpio.h> | ||
+ | ||
|
||
+#ifdef CPTCFG_MAC80211_LEDS | ||
+ | ||
+#ifdef CONFIG_GPIOLIB | ||
|
@@ -62,10 +47,9 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
+/* gpio_chip handler : set GPIO to input */ | ||
+static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, | ||
+ gchip); | ||
+ struct ath_softc *sc = gpiochip_get_data(chip); | ||
+ | ||
+ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio"); | ||
+ ath9k_hw_gpio_request_in(sc->sc_ah, offset, "ath9k-gpio"); | ||
+ | ||
+ return 0; | ||
+} | ||
|
@@ -74,88 +58,83 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
+static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset, | ||
+ int value) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, | ||
+ gchip); | ||
+ struct ath_softc *sc = gpiochip_get_data(chip); | ||
+ | ||
+ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio", | ||
+ ath9k_hw_gpio_request_out(sc->sc_ah, offset, "ath9k-gpio", | ||
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); | ||
+ ath9k_hw_set_gpio(sc->sc_ah, offset, value); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+/* gpio_chip handler : query GPIO direction (0=out, 1=in) */ | ||
+static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, | ||
+ gchip); | ||
+ struct ath_hw *ah = gc->sc->sc_ah; | ||
+ struct ath_softc *sc = gpiochip_get_data(chip); | ||
+ struct ath_hw *ah = sc->sc_ah; | ||
+ | ||
+ return !((REG_READ(ah, AR_GPIO_OE_OUT(ah)) >> (offset * 2)) & 3); | ||
+} | ||
+ | ||
+/* gpio_chip handler : get GPIO pin value */ | ||
+static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, | ||
+ gchip); | ||
+ struct ath_softc *sc = gpiochip_get_data(chip); | ||
+ | ||
+ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset); | ||
+ return ath9k_hw_gpio_get(sc->sc_ah, offset); | ||
+} | ||
+ | ||
+/* gpio_chip handler : set GPIO pin to value */ | ||
+static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset, | ||
+ int value) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, | ||
+ gchip); | ||
+ struct ath_softc *sc = gpiochip_get_data(chip); | ||
+ | ||
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); | ||
+ ath9k_hw_set_gpio(sc->sc_ah, offset, value); | ||
+} | ||
+ | ||
+/* register GPIO chip */ | ||
+static void ath9k_register_gpio_chip(struct ath_softc *sc) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc; | ||
+ struct gpio_chip *gc = sc->gpiochip; | ||
+ struct ath_hw *ah = sc->sc_ah; | ||
+ | ||
+ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL); | ||
+ gc = kzalloc(sizeof(struct gpio_chip), GFP_KERNEL); | ||
+ if (!gc) | ||
+ return; | ||
+ | ||
+ gc->sc = sc; | ||
+ snprintf(gc->label, sizeof(gc->label), "ath9k-%s", | ||
+ wiphy_name(sc->hw->wiphy)); | ||
+ gc->gchip.parent = sc->dev; | ||
+ gc->gchip.label = gc->label; | ||
+ gc->gchip.base = -1; /* determine base automatically */ | ||
+ gc->gchip.ngpio = ah->caps.num_gpio_pins; | ||
+ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input; | ||
+ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output; | ||
+ gc->gchip.get_direction = ath9k_gpio_pin_get_dir; | ||
+ gc->gchip.get = ath9k_gpio_pin_get; | ||
+ gc->gchip.set = ath9k_gpio_pin_set; | ||
+ | ||
+ if (gpiochip_add(&gc->gchip)) { | ||
+ gc->label = kasprintf(GFP_KERNEL, "ath9k-%s", | ||
+ wiphy_name(sc->hw->wiphy)); | ||
+ if (!gc->label) | ||
+ return; | ||
+ | ||
+ gc->parent = sc->dev; | ||
+ gc->base = -1; /* determine base automatically */ | ||
+ gc->ngpio = ah->caps.num_gpio_pins; | ||
+ gc->direction_input = ath9k_gpio_pin_cfg_input; | ||
+ gc->direction_output = ath9k_gpio_pin_cfg_output; | ||
+ gc->get_direction = ath9k_gpio_pin_get_dir; | ||
+ gc->get = ath9k_gpio_pin_get; | ||
+ gc->set = ath9k_gpio_pin_set; | ||
+ | ||
+ if (gpiochip_add_data(gc, sc)) { | ||
+ kfree(gc->label); | ||
+ kfree(gc); | ||
+ return; | ||
+ } | ||
+ | ||
+ gc->gchip.owner = NULL; | ||
+ sc->gpiochip = gc; | ||
+} | ||
+ | ||
+/* remove GPIO chip */ | ||
+static void ath9k_unregister_gpio_chip(struct ath_softc *sc) | ||
+{ | ||
+ struct ath9k_gpio_chip *gc = sc->gpiochip; | ||
+ struct gpio_chip *gc = sc->gpiochip; | ||
+ | ||
+ if (!gc) | ||
+ return; | ||
+ | ||
+ gpiochip_remove(&gc->gchip); | ||
+ gpiochip_remove(gc); | ||
+ kfree(gc->label); | ||
+ kfree(gc); | ||
+ sc->gpiochip = NULL; | ||
+} | ||
+ | ||
+#else /* CONFIG_GPIOLIB */ | ||
|
@@ -169,7 +148,7 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
+} | ||
+ | ||
+#endif /* CONFIG_GPIOLIB */ | ||
+ | ||
/********************************/ | ||
/* LED functions */ | ||
/********************************/ | ||
|
@@ -179,27 +158,27 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
static void ath_fill_led_pin(struct ath_softc *sc) | ||
{ | ||
struct ath_hw *ah = sc->sc_ah; | ||
@@ -79,6 +197,12 @@ static int ath_add_led(struct ath_softc | ||
@@ -79,6 +190,12 @@ static int ath_add_led(struct ath_softc | ||
else | ||
ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); | ||
|
||
+#ifdef CONFIG_GPIOLIB | ||
+ /* If there is GPIO chip configured, reserve LED pin */ | ||
+ if (sc->gpiochip) | ||
+ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name); | ||
+ sc->gpiodesc = gpiod_get(sc->dev, gpio->name, GPIOD_ASIS); | ||
+#endif | ||
+ | ||
return 0; | ||
} | ||
|
||
@@ -117,17 +241,24 @@ void ath_deinit_leds(struct ath_softc *s | ||
@@ -117,17 +234,24 @@ void ath_deinit_leds(struct ath_softc *s | ||
|
||
while (!list_empty(&sc->leds)) { | ||
led = list_first_entry(&sc->leds, struct ath_led, list); | ||
+#ifdef CONFIG_GPIOLIB | ||
+ /* If there is GPIO chip configured, free LED pin */ | ||
+ if (sc->gpiochip) | ||
+ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio); | ||
+ gpiod_put(sc->gpiodesc); | ||
+#endif | ||
list_del(&led->list); | ||
ath_led_brightness(&led->cdev, LED_OFF); | ||
|
@@ -217,7 +196,7 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
char led_name[32]; | ||
const char *trigger; | ||
|
||
@@ -136,6 +267,12 @@ void ath_init_leds(struct ath_softc *sc) | ||
@@ -136,6 +260,12 @@ void ath_init_leds(struct ath_softc *sc) | ||
if (AR_SREV_9100(sc->sc_ah)) | ||
return; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,27 +10,27 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
--- | ||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h | ||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h | ||
@@ -1057,6 +1057,7 @@ struct ath_softc { | ||
struct list_head leds; | ||
@@ -1051,6 +1051,7 @@ struct ath_softc { | ||
#ifdef CONFIG_GPIOLIB | ||
struct ath9k_gpio_chip *gpiochip; | ||
struct gpio_chip *gpiochip; | ||
struct gpio_desc *gpiodesc; | ||
+ struct platform_device *btnpdev; /* gpio-keys-polled */ | ||
#endif | ||
#endif | ||
|
||
--- a/drivers/net/wireless/ath/ath9k/gpio.c | ||
+++ b/drivers/net/wireless/ath/ath9k/gpio.c | ||
@@ -16,6 +16,8 @@ | ||
@@ -15,6 +15,8 @@ | ||
*/ | ||
|
||
#include "ath9k.h" | ||
#include <linux/gpio.h> | ||
+#include <linux/platform_device.h> | ||
+#include <linux/gpio_keys.h> | ||
|
||
#ifdef CPTCFG_MAC80211_LEDS | ||
|
||
@@ -124,6 +126,67 @@ static void ath9k_unregister_gpio_chip(s | ||
sc->gpiochip = NULL; | ||
@@ -117,6 +119,67 @@ static void ath9k_unregister_gpio_chip(s | ||
kfree(gc); | ||
} | ||
|
||
+/******************/ | ||
|
@@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
+ | ||
+ ath9k_hw_gpio_request_in(sc->sc_ah, ah->btns[i].gpio, | ||
+ "ath9k-gpio"); | ||
+ bt[i].gpio = sc->gpiochip->gchip.base + ah->btns[i].gpio; | ||
+ bt[i].gpio = sc->gpiochip->base + ah->btns[i].gpio; | ||
+ } | ||
+ | ||
+ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); | ||
|
@@ -97,7 +97,7 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
#else /* CONFIG_GPIOLIB */ | ||
|
||
static inline void ath9k_register_gpio_chip(struct ath_softc *sc) | ||
@@ -134,6 +197,14 @@ static inline void ath9k_unregister_gpio | ||
@@ -127,6 +190,14 @@ static inline void ath9k_unregister_gpio | ||
{ | ||
} | ||
|
||
|
@@ -112,15 +112,15 @@ Signed-off-by: Felix Fietkau <[email protected]> | |
#endif /* CONFIG_GPIOLIB */ | ||
|
||
/********************************/ | ||
@@ -239,6 +310,7 @@ void ath_deinit_leds(struct ath_softc *s | ||
@@ -232,6 +303,7 @@ void ath_deinit_leds(struct ath_softc *s | ||
{ | ||
struct ath_led *led; | ||
|
||
+ ath9k_deinit_buttons(sc); | ||
while (!list_empty(&sc->leds)) { | ||
led = list_first_entry(&sc->leds, struct ath_led, list); | ||
#ifdef CONFIG_GPIOLIB | ||
@@ -274,6 +346,7 @@ void ath_init_leds(struct ath_softc *sc) | ||
@@ -267,6 +339,7 @@ void ath_init_leds(struct ath_softc *sc) | ||
} | ||
|
||
ath_fill_led_pin(sc); | ||
|