-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Michal schrieb am 28.01.2016 um 23:32: > From: Michal Cieslakiewicz <michal.cieslakiew...@wp.pl> > > 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> Acked-by: Hartmut Knaack <knaac...@gmx.de> > --- >
A few minor comments inline. > (Minor code cleanup - dummy init/deinit functions changed to static inline) > > .../patches/550-ath9k_enable_gpio_buttons.patch | 164 > +++++++++++++++++++++ > .../ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c | 18 +++ > .../ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h | 7 + > .../generic/files/include/linux/ath9k_platform.h | 4 + > 4 files changed, 193 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..01d0ade > --- /dev/null > +++ b/package/kernel/mac80211/patches/550-ath9k_enable_gpio_buttons.patch > @@ -0,0 +1,164 @@ > +--- 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) > + { > +@@ -843,6 +850,13 @@ 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) > ++{ > ++} I would leave an empty line here, too. > ++static inline void ath9k_deinit_buttons(struct ath_softc *sc) > ++{ > ++} > + #endif > + > + /************************/ > +@@ -1039,6 +1053,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) > +@@ -308,6 +310,83 @@ 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 drop this empty line. > ++ if (!bt) > ++ return; > ++ > ++ pdev = platform_device_alloc("gpio-keys-polled", PLATFORM_DEVID_AUTO); > ++ And this one, too. > ++ 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; > ++ > ++ return; > ++ > ++err_pdev_put: > ++ platform_device_put(pdev); > ++ > ++err_bt_free: > ++ kfree(bt); > ++} > ++ > ++/* remove GPIO buttons */ > ++void ath9k_deinit_buttons(struct ath_softc *sc) > ++{ > ++ struct gpio_keys_platform_data *gkpdata; > ++ struct gpio_keys_button *bt = NULL; > ++ > ++ if (!sc->gpiochip || !sc->btnpdev) > ++ return; > ++ > ++ gkpdata = sc->btnpdev->dev.platform_data; > ++ if (gkpdata) > ++ bt = gkpdata->buttons; > ++ > ++ platform_device_del(sc->btnpdev); > ++ platform_device_put(sc->btnpdev); > ++ > ++ sc->btnpdev = NULL; > ++ > ++ if (bt) > ++ kfree(bt); > ++} > ++ > + #endif > + > + /*******************/ > +--- a/drivers/net/wireless/ath/ath9k/init.c > ++++ b/drivers/net/wireless/ath/ath9k/init.c > +@@ -981,6 +981,7 @@ int ath9k_init_device(u16 devid, struct > + > + ath9k_register_gpio_chip(sc); > + ath_init_leds(sc); > ++ ath9k_init_buttons(sc); > + ath_start_rfkill_poll(sc); > + > + return 0; > +@@ -1026,6 +1027,7 @@ void ath9k_deinit_device(struct ath_soft > + ath9k_ps_wakeup(sc); > + > + wiphy_rfkill_stop_polling(sc->hw->wiphy); > ++ ath9k_deinit_buttons(sc); > + ath_deinit_leds(sc); > + ath9k_unregister_gpio_chip(sc); > + > +--- a/include/linux/ath9k_platform.h > ++++ b/include/linux/ath9k_platform.h > +@@ -46,6 +46,10 @@ struct ath9k_platform_data { > + int num_leds; > + const struct gpio_led *leds; > + const char *led_name; > ++ > ++ unsigned num_btns; > ++ const struct gpio_keys_button *btns; > ++ unsigned btn_poll_interval; > + }; > + > + #endif /* _LINUX_ATH9K_PLATFORM_H */ > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c > b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c > index bf80d4d..51f361e 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c > +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c > @@ -93,6 +93,24 @@ __init void ap9x_pci_setup_wmac_leds(unsigned wmac, struct > gpio_led *leds, > } > } > > +__init void ap9x_pci_setup_wmac_btns(unsigned wmac, > + struct gpio_keys_button *btns, > + unsigned num_btns, unsigned poll_interval) > +{ > + struct ath9k_platform_data *ap9x_wmac_data; > + > + if (wmac == 0) > + ap9x_wmac_data = &ap9x_wmac0_data; > + else if (wmac == 1) > + ap9x_wmac_data = &ap9x_wmac1_data; > + else > + return; Looking closer, I realized this can be done even shorter: if (!(ap9x_wmac_data = ap9x_pci_get_wmac_data(wmac))) return; > + > + ap9x_wmac_data->btns = btns; > + ap9x_wmac_data->num_btns = num_btns; > + ap9x_wmac_data->btn_poll_interval = poll_interval; > +} > + > static int ap91_pci_plat_dev_init(struct pci_dev *dev) > { > switch (PCI_SLOT(dev->devfn)) { > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h > b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h > index dcfe541..d7c0185 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h > +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h > @@ -12,6 +12,7 @@ > #define _ATH79_DEV_AP9X_PCI_H > > struct gpio_led; > +struct gpio_keys_button; > struct ath9k_platform_data; > > #if defined(CONFIG_ATH79_DEV_AP9X_PCI) > @@ -20,6 +21,8 @@ void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 > val); > void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, > int num_leds); > void ap9x_pci_setup_wmac_led_name(unsigned wmac, const char *led_name); > +void ap9x_pci_setup_wmac_btns(unsigned wmac, struct gpio_keys_button *btns, > + unsigned num_btns, unsigned poll_interval); > struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac); > > void ap91_pci_init(u8 *cal_data, u8 *mac_addr); > @@ -36,6 +39,10 @@ static inline void ap9x_pci_setup_wmac_leds(unsigned wmac, > int num_leds) {} > static inline void ap9x_pci_setup_wmac_led_name(unsigned wmac, > const char *led_name) {} > +static inline void ap9x_pci_setup_wmac_btns(unsigned wmac, > + struct gpio_keys_button *btns, > + unsigned num_btns, > + unsigned poll_interval) {} > static inline struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned > wmac) > { > return NULL; > diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h > b/target/linux/generic/files/include/linux/ath9k_platform.h > index 823e5ac..e543a64 100644 > --- a/target/linux/generic/files/include/linux/ath9k_platform.h > +++ b/target/linux/generic/files/include/linux/ath9k_platform.h > @@ -46,6 +46,10 @@ struct ath9k_platform_data { > int num_leds; > const struct gpio_led *leds; > const char *led_name; > + > + unsigned num_btns; > + const struct gpio_keys_button *btns; > + unsigned btn_poll_interval; > }; > > #endif /* _LINUX_ATH9K_PLATFORM_H */ > -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJWrQD6AAoJEANoShj6yJFIjSgP/2u3B/9hY/9k+Nw4BkQjtq/3 Wz51I2uiH71iedxGf/RAZLdh7TSz/mUgNWrPcPT574ARceh3Cs2XmamcxqcicyKx JjJd7S97Hlt0UWlyyg5ALO9vJ3c2zQpnHaEJOKZ3dEG6gLE8ZKEkd3tMCVsskaYk KrnYOIC4AzlB8yAp7BrI0n0SpRtb47vFtVM8JAxlLNq82Bu1ZtQfEYVqY1593Pkp gunDzbUSU5xHN53RXihkrubuhkSTHueKmvhPtZaaPCtDCkjZAcgQcuXfLKu24am5 /SoMK8sx+N8tW1wByzNytLh8G/slHhOgrbHHPF3mnjk/sNkR8OiAMQTQecgt4rx8 R+2xwR9WrVowL8lQoZk6Wodq3Gvih7GX7u+qaNJnCmtI9Nwe3uxw9fHP6q8mHYyL iON4zrcHwd1fSbJ0uAsf5WQUtEL1KdxwQP6j7I95ZaMH3IPY+0AzpH32QzmgRyjP z0yptEKbY+bdBqw45AvGDb0s5wa0tZKnVxtBUF42ARlJvAIeOvpYSmXPEUT+AwPz qacQaMOCxBmAf7os3WnhzLG+MvJZyxM09eBA27attE76d4x89ex6mMxz3nuaqcfP RmpxfduBIVVjunkZTHjkkQVJdVkM/sWs0omhX8YWXW0PPDNkL7m5+TOWV03S4Vur 8FuGNWYWABqv0ITM59TK =o3sV -----END PGP SIGNATURE-----
0xFAC89148.asc
Description: application/pgp-keys
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel