diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 7f54d2d2d13a..b78feb7ddde8 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -1402,6 +1402,8 @@ int btrtl_shutdown_realtek(struct hci_dev *hdev) struct sk_buff *skb; int ret; + bt_dev_info(hdev, "diag: btrtl_shutdown_realtek: sending HCI_OP_RESET"); + /* According to the vendor driver, BT must be reset on close to avoid * firmware crash. */ @@ -1411,6 +1413,7 @@ int btrtl_shutdown_realtek(struct hci_dev *hdev) bt_dev_err(hdev, "HCI reset during shutdown failed"); return ret; } + bt_dev_info(hdev, "diag: btrtl_shutdown_realtek: HCI_OP_RESET completed OK"); kfree_skb(skb); return 0; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 184e95c1625e..2369ca69af9c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -6,6 +6,7 @@ * Copyright (C) 2005-2008 Marcel Holtmann */ +#include "linux/bitops.h" #include #include #include @@ -4470,6 +4471,8 @@ static void btusb_disconnect(struct usb_interface *intf) struct btusb_data *data = usb_get_intfdata(intf); struct hci_dev *hdev; + bt_dev_info(data ? data->hdev : NULL, "diag: btusb_disconnect called for intf %p", intf); + BT_DBG("intf %p", intf); if (!data) @@ -4682,10 +4685,21 @@ static void btusb_coredump(struct device *dev) } #endif +static void btusb_shutdown(struct usb_interface *intf) +{ + struct btusb_data *data = usb_get_intfdata(intf); + + bt_dev_info(data ? data->hdev : NULL, + "diag: btusb_shutdown() reached intf %p, hdev up=%d", + intf, data && data->hdev ? test_bit(HCI_UP, &data->hdev->flags) : -1); + +} + static struct usb_driver btusb_driver = { .name = "btusb", .probe = btusb_probe, .disconnect = btusb_disconnect, + .shutdown = btusb_shutdown, .suspend = pm_ptr(btusb_suspend), .resume = pm_ptr(btusb_resume), .id_table = btusb_table, diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index eaa928bab240..f6c548681e45 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -2,6 +2,7 @@ /* Copyright(c) 2018-2019 Realtek Corporation */ +#include "hci.h" #include "main.h" #include "mac.h" #include "reg.h" @@ -166,6 +167,10 @@ static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev, /* if PCIE, toggle BIT_PFM_WOWL and try again */ value = rtw_read8(rtwdev, REG_SYS_PW_CTRL); + + rtw_info(rtwdev, "diag: pre-toggle REG_SYS_PW_CTRL=0x%02x, poll offset = 0x%x want=0x%x\n", + value, offset, cmd->value & cmd->mask); + 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); @@ -173,6 +178,9 @@ static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev, if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + rtw_info(rtwdev, "diag: post-toggle REG_SYS_PW_CTRL=0x%02x, retry poll read=0x%02x\n", + rtw_read8(rtwdev, REG_SYS_PW_CTRL), rtw_read8(rtwdev, offset)); + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) return 0; diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index a30467228912..e80cfa738262 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -2,6 +2,7 @@ /* Copyright(c) 2018-2019 Realtek Corporation */ +#include "linux/pci_regs.h" #include #include #include @@ -1909,6 +1910,10 @@ void rtw_pci_shutdown(struct pci_dev *pdev) struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct rtw_dev *rtwdev; const struct rtw_chip_info *chip; + int pm_cap; + u16 pmcsr = 0xffff; + + dev_info(&pdev->dev, "diag: rtw_pci_shutdown: entry, hw=%p\n", hw); if (!hw) return; @@ -1919,7 +1924,23 @@ void rtw_pci_shutdown(struct pci_dev *pdev) if (chip->ops->shutdown) chip->ops->shutdown(rtwdev); + pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + + if(pm_cap) { + pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pmcsr); + dev_info(&pdev->dev, "diag: pre-D3hot PMCSR=0x%04x (state=D%d)\n", + pmcsr, pmcsr & PCI_PM_CTRL_STATE_MASK); + } else { + dev_info(&pdev->dev, "diag: no PCI PM capability found\n"); + } + pci_set_power_state(pdev, PCI_D3hot); + + if(pm_cap){ + pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pmcsr); + dev_info(&pdev->dev, "diag: post-D3hot PMCSR=0x%04x (state=D%d)\n", + pmcsr, pmcsr & PCI_PM_CTRL_STATE_MASK); + } } EXPORT_SYMBOL(rtw_pci_shutdown); diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index c8d14128c363..2d170801196e 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -6,6 +6,7 @@ * Copyright 2023 NXP */ +#include "net/bluetooth/hci.h" #include #include @@ -5416,11 +5417,20 @@ static int hci_dev_shutdown(struct hci_dev *hdev) bool was_userchannel = hci_dev_test_and_clear_flag(hdev, HCI_USER_CHANNEL); + bt_dev_info(hdev, "diag: hci_dev_shtudown: HCI_UP=%d HCI_UNREGISTER=%d shutdown_cb=%ps", + test_bit(HCI_UP, &hdev->flags), + hci_dev_test_flag(hdev, HCI_UNREGISTER), + hdev->shutdown); + if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && test_bit(HCI_UP, &hdev->flags)) { /* Execute vendor specific shutdown routine */ - if (hdev->shutdown) + if (hdev->shutdown) { + bt_dev_info(hdev, "diag: calling vendor shutdown callback"); err = hdev->shutdown(hdev); + bt_dev_info(hdev, "diag: vendor shutdown returned %d", err); + + } } if (was_userchannel)