On 2016-02-01 22:29, Michal wrote: > From: Michal Cieslakiewicz <michal.cieslakiew...@wp.pl> > Subject: [PATCH v4 5/8] mac80211: ath9k: enable GPIO buttons > > Enable platform-defined GPIO button support for ath9k device. Key poller > is activated for attached platform buttons. Requires ath9k GPIO chip access. > > Signed-off-by: Michal Cieslakiewicz <michal.cieslakiew...@wp.pl> > --- > .../patches/550-ath9k_enable_gpio_buttons.patch | 178 > +++++++++++++++++++++ > .../ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c | 14 ++ > .../ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h | 7 + > .../generic/files/include/linux/ath9k_platform.h | 4 + > 4 files changed, 203 insertions(+) > create mode 100644 > package/kernel/mac80211/patches/550-ath9k_enable_gpio_buttons.patch > > diff --git > a/package/kernel/mac80211/patches/550-ath9k_enable_gpio_buttons.patch > b/package/kernel/mac80211/patches/550-ath9k_enable_gpio_buttons.patch > new file mode 100644 > index 0000000..485ccc3 > --- /dev/null > +++ b/package/kernel/mac80211/patches/550-ath9k_enable_gpio_buttons.patch > @@ -0,0 +1,178 @@ > +From: Michal Cieslakiewicz <michal.cieslakiew...@wp.pl> > +Date: Sun, 31 Jan 2016 21:14:18 +0100 > +Subject: [PATCH v4 5/8] mac80211: ath9k: enable GPIO buttons > + > +Enable platform-defined GPIO button support for ath9k device. Key poller > +is activated for attached platform buttons. Requires ath9k GPIO chip access. > + > +Signed-off-by: Michal Cieslakiewicz <michal.cieslakiew...@wp.pl> > +--- > + drivers/net/wireless/ath/ath9k/ath9k.h | 16 ++++++ > + drivers/net/wireless/ath/ath9k/gpio.c | 77 > +++++++++++++++++++++++++++++++++ > + drivers/net/wireless/ath/ath9k/init.c | 2 > + include/linux/ath9k_platform.h | 4 + > + 4 files changed, 99 insertions(+) > + > +--- a/drivers/net/wireless/ath/ath9k/ath9k.h > ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h > +@@ -825,6 +825,13 @@ int ath_create_gpio_led(struct ath_softc > + void ath9k_register_gpio_chip(struct ath_softc *sc); > + void ath9k_unregister_gpio_chip(struct ath_softc *sc); > + > ++/******************/ > ++/* GPIO Buttons */ > ++/******************/ > ++ > ++void ath9k_init_buttons(struct ath_softc *sc); > ++void ath9k_deinit_buttons(struct ath_softc *sc); > ++ > + #else > + static inline void ath_init_leds(struct ath_softc *sc) > + { > +@@ -844,6 +851,14 @@ static inline void ath9k_register_gpio_c > + static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc) > + { > + } > ++ > ++static inline void ath9k_init_buttons(struct ath_softc *sc) > ++{ > ++} > ++ > ++static inline void ath9k_deinit_buttons(struct ath_softc *sc) > ++{ > ++} > + #endif > + > + /************************/ > +@@ -1040,6 +1055,7 @@ struct ath_softc { > + const char *led_default_trigger; > + struct list_head leds; > + struct ath9k_gpio_chip *gpiochip; > ++ struct platform_device *btnpdev; /* gpio-keys-polled */ > + #endif > + > + #ifdef CPTCFG_ATH9K_DEBUGFS > +--- a/drivers/net/wireless/ath/ath9k/gpio.c > ++++ b/drivers/net/wireless/ath/ath9k/gpio.c > +@@ -24,6 +24,8 @@ > + #ifdef CPTCFG_MAC80211_LEDS > + > + #include <asm-generic/gpio.h> > ++#include <linux/platform_device.h> > ++#include <linux/gpio_keys.h> > + > + static void ath_led_brightness(struct led_classdev *led_cdev, > + enum led_brightness brightness) > +@@ -307,6 +309,81 @@ void ath9k_unregister_gpio_chip(struct a > + sc->gpiochip = NULL; > + } > + > ++/******************/ > ++/* GPIO Buttons */ > ++/******************/ > ++ > ++/* add GPIO buttons */ > ++void ath9k_init_buttons(struct ath_softc *sc) > ++{ > ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; > ++ struct platform_device *pdev; > ++ struct gpio_keys_platform_data gkpdata; > ++ struct gpio_keys_button *bt; > ++ int i; > ++ > ++ if (!sc->gpiochip) > ++ return; > ++ > ++ bt = kmemdup(pdata->btns, > ++ pdata->num_btns * sizeof(struct gpio_keys_button), > ++ GFP_KERNEL); I would suggest using devm_kmemdup here, so you can skip the kfree.
> ++ if (!bt) > ++ return; > ++ > ++ pdev = platform_device_alloc("gpio-keys-polled", PLATFORM_DEVID_AUTO); > ++ if (!pdev) > ++ goto err_bt_free; > ++ > ++ for (i = 0; i < pdata->num_btns; i++) { > ++ ath9k_hw_cfg_gpio_input(sc->sc_ah, pdata->btns[i].gpio); > ++ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio; > ++ } > ++ > ++ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); > ++ gkpdata.buttons = bt; > ++ gkpdata.nbuttons = pdata->num_btns; > ++ gkpdata.poll_interval = pdata->btn_poll_interval; > ++ > ++ if (platform_device_add_data(pdev, &gkpdata, sizeof(gkpdata))) > ++ goto err_pdev_put; > ++ > ++ if (platform_device_add(pdev)) > ++ goto err_pdev_put; > ++ > ++ sc->btnpdev = pdev; I think it would be a good idea to use the ath9k device as a parent for the platform device. - Felix _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel