| 1 | --- a/drivers/net/wireless/ath/ath9k/debug.c |
| 2 | +++ b/drivers/net/wireless/ath/ath9k/debug.c |
| 3 | @@ -1200,6 +1200,12 @@ int ath9k_init_debug(struct ath_hw *ah) |
| 4 | sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) |
| 5 | goto err; |
| 6 | |
| 7 | + debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, |
| 8 | + sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
| 9 | + |
| 10 | + debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, |
| 11 | + sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); |
| 12 | + |
| 13 | sc->debug.regidx = 0; |
| 14 | return 0; |
| 15 | err: |
| 16 | --- a/drivers/net/wireless/ath/ath9k/hw.h |
| 17 | +++ b/drivers/net/wireless/ath/ath9k/hw.h |
| 18 | @@ -795,6 +795,8 @@ struct ath_hw { |
| 19 | int initPDADC; |
| 20 | int PDADCdelta; |
| 21 | u8 led_pin; |
| 22 | + u32 gpio_mask; |
| 23 | + u32 gpio_val; |
| 24 | |
| 25 | struct ar5416IniArray iniModes; |
| 26 | struct ar5416IniArray iniCommon; |
| 27 | --- a/drivers/net/wireless/ath/ath9k/hw.c |
| 28 | +++ b/drivers/net/wireless/ath/ath9k/hw.c |
| 29 | @@ -1175,6 +1175,20 @@ static bool ath9k_hw_channel_change(stru |
| 30 | return true; |
| 31 | } |
| 32 | |
| 33 | +static void ath9k_hw_apply_gpio_override(struct ath_hw *ah) |
| 34 | +{ |
| 35 | + u32 gpio_mask = ah->gpio_mask; |
| 36 | + int i; |
| 37 | + |
| 38 | + for (i = 0; gpio_mask; i++, gpio_mask >>= 1) { |
| 39 | + if (!(gpio_mask & 1)) |
| 40 | + continue; |
| 41 | + |
| 42 | + ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); |
| 43 | + ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i))); |
| 44 | + } |
| 45 | +} |
| 46 | + |
| 47 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
| 48 | { |
| 49 | int count = 50; |
| 50 | @@ -1463,6 +1477,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st |
| 51 | if (AR_SREV_9300_20_OR_LATER(ah)) |
| 52 | ar9003_hw_bb_watchdog_config(ah); |
| 53 | |
| 54 | + ath9k_hw_apply_gpio_override(ah); |
| 55 | + |
| 56 | return 0; |
| 57 | } |
| 58 | EXPORT_SYMBOL(ath9k_hw_reset); |
| 59 | |