Disable rtw89_mac_send_rpwm() for USB and SDIO because it is called in atomic context and accessing hardware registers results in "scheduling while atomic" errors. Disable rtw89_mac_power_mode_change() because it prints an error message when rtw89_mac_send_rpwm() is disabled. Modify rtw89_ps_power_mode_change() to call rtw89_ps_power_mode_change_with_hci() only for PCI because the latter is probably relevant only for PCI and also because it calls napi_schedule(), which results in dereferencing a null pointer with USB. For USB and SDIO rtw89_ps_power_mode_change() probably needs to call rtw89_mac_power_mode_change() instead, in case deep power saving is ever enabled for USB or SDIO. Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx> --- v2: - Disable deep power saving for SDIO also. - Don't disable rtw89_ps_power_mode_change() for USB/SDIO. - Disable rtw89_mac_power_mode_change() for USB/SDIO. - Call rtw89_ps_power_mode_change_with_hci() only for PCI and call rtw89_mac_power_mode_change() for USB/SDIO. - Update the commit message. --- drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++ drivers/net/wireless/realtek/rtw89/ps.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 7f3c816d4704..2cebde9e9229 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1336,6 +1336,9 @@ static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev, { u16 request; + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) + return; + spin_lock_bh(&rtwdev->rpwm_lock); request = rtw89_read16(rtwdev, R_AX_RPWM); @@ -1412,6 +1415,9 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter) int ret; int i; + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) + return; + if (enter) state = rtw89_mac_get_req_pwr_state(rtwdev); else diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index 8e4fe73e7d77..9f63655b7568 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -57,7 +57,8 @@ static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev, static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter) { if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode) && - !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) + !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags) && + rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) rtw89_ps_power_mode_change_with_hci(rtwdev, enter); else rtw89_mac_power_mode_change(rtwdev, enter); -- 2.49.0