summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPing-Ke Shih <pkshih@realtek.com>2020-04-22 11:46:03 +0800
committerKalle Valo <kvalo@codeaurora.org>2020-04-23 07:47:23 +0300
commitfd9ead385102652b43f628ca700810d343c52437 (patch)
tree671c42b33ed3d8eecd30546118d21b91295ee78c
parent4e223a5f5342fab01ccebf87714401f559dcc791 (diff)
downloadlinux-fd9ead385102652b43f628ca700810d343c52437.tar.gz
linux-fd9ead385102652b43f628ca700810d343c52437.tar.bz2
linux-fd9ead385102652b43f628ca700810d343c52437.zip
rtw88: decompose while(1) loop of power sequence polling command
The power polling command is one kind of power sequence commands. It's used to check hardware situation, and subsequent comamnds will be executed if hardware is ready. A special case is PCIE must toggle BIT_PFM_WOWL and try again if first try is failed. In order to reduce indentation to understand the code easier, move polling part to a separate function. Then, the 'while (1)...loop' is replaced by two statements to do first try and retry. Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20200422034607.28747-5-yhchuang@realtek.com
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 21b5c7173f0f..ac5d35153c8a 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -108,51 +108,55 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
return 0;
}
+static bool do_pwr_poll_cmd(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target)
+{
+ u32 cnt;
+
+ target &= mask;
+
+ for (cnt = 0; cnt < RTW_PWR_POLLING_CNT; cnt++) {
+ if ((rtw_read8(rtwdev, addr) & mask) == target)
+ return true;
+
+ udelay(50);
+ }
+
+ return false;
+}
+
static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev,
const struct rtw_pwr_seq_cmd *cmd)
{
u8 value;
- u8 flag = 0;
u32 offset;
- u32 cnt = RTW_PWR_POLLING_CNT;
if (cmd->base == RTW_PWR_ADDR_SDIO)
offset = cmd->offset | SDIO_LOCAL_OFFSET;
else
offset = cmd->offset;
- do {
- cnt--;
- value = rtw_read8(rtwdev, offset);
- value &= cmd->mask;
- if (value == (cmd->value & cmd->mask))
- return 0;
- if (cnt == 0) {
- if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
- flag == 0) {
- value = rtw_read8(rtwdev, REG_SYS_PW_CTRL);
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) {
- value &= ~BIT_PFM_WOWL;
- rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
- }
- value |= BIT_PFM_WOWL;
- rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
- value &= ~BIT_PFM_WOWL;
- rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) {
- value |= BIT_PFM_WOWL;
- rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
- }
-
- cnt = RTW_PWR_POLLING_CNT;
- flag = 1;
- } else {
- return -EBUSY;
- }
- } else {
- udelay(50);
- }
- } while (1);
+ if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value))
+ return 0;
+
+ if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_PCIE)
+ goto err;
+
+ /* if PCIE, toggle BIT_PFM_WOWL and try again */
+ value = rtw_read8(rtwdev, REG_SYS_PW_CTRL);
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D)
+ rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL);
+ rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL);
+ rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL);
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D)
+ rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL);
+
+ if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value))
+ return 0;
+
+err:
+ rtw_err(rtwdev, "failed to poll offset=0x%x mask=0x%x value=0x%x\n",
+ offset, cmd->mask, cmd->value);
+ return -EBUSY;
}
static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,