Message ID | 20250127124908.1510559-1-chandrashekar.devegowda@intel.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v4] Bluetooth: btintel_pcie: Support suspend-resume | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
tedd_an/SubjectPrefix | success | Gitlint PASS |
tedd_an/BuildKernel | success | BuildKernel PASS |
tedd_an/CheckAllWarning | success | CheckAllWarning PASS |
tedd_an/CheckSparse | success | CheckSparse PASS |
tedd_an/BuildKernel32 | success | BuildKernel32 PASS |
tedd_an/TestRunnerSetup | success | TestRunnerSetup PASS |
tedd_an/TestRunner_l2cap-tester | success | TestRunner PASS |
tedd_an/TestRunner_iso-tester | success | TestRunner PASS |
tedd_an/TestRunner_bnep-tester | success | TestRunner PASS |
tedd_an/TestRunner_mgmt-tester | success | TestRunner PASS |
tedd_an/TestRunner_rfcomm-tester | success | TestRunner PASS |
tedd_an/TestRunner_sco-tester | success | TestRunner PASS |
tedd_an/TestRunner_ioctl-tester | success | TestRunner PASS |
tedd_an/TestRunner_mesh-tester | fail | TestRunner_mesh-tester: Total: 10, Passed: 9 (90.0%), Failed: 1, Not Run: 0 |
tedd_an/TestRunner_smp-tester | success | TestRunner PASS |
tedd_an/TestRunner_userchan-tester | success | TestRunner PASS |
This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=928464 ---Test result--- Test Summary: CheckPatch PENDING 0.28 seconds GitLint PENDING 0.19 seconds SubjectPrefix PASS 0.12 seconds BuildKernel PASS 24.45 seconds CheckAllWarning PASS 29.03 seconds CheckSparse PASS 30.35 seconds BuildKernel32 PASS 24.14 seconds TestRunnerSetup PASS 434.00 seconds TestRunner_l2cap-tester PASS 22.21 seconds TestRunner_iso-tester PASS 32.08 seconds TestRunner_bnep-tester PASS 4.88 seconds TestRunner_mgmt-tester PASS 120.67 seconds TestRunner_rfcomm-tester PASS 7.72 seconds TestRunner_sco-tester PASS 9.47 seconds TestRunner_ioctl-tester PASS 8.19 seconds TestRunner_mesh-tester FAIL 6.25 seconds TestRunner_smp-tester PASS 7.13 seconds TestRunner_userchan-tester PASS 5.03 seconds IncrementalBuild PENDING 0.49 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: TestRunner_mesh-tester - FAIL Desc: Run mesh-tester with test-runner Output: Total: 10, Passed: 9 (90.0%), Failed: 1, Not Run: 0 Failed Test Cases Mesh - Send cancel - 2 Failed 0.101 seconds ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth
Dear Chandrashekar, Thank you for your patch. Some more minor things. Am 27.01.25 um 13:49 schrieb Chandrashekar Devegowda: > From: chandrashekar Devegowda <chandrashekar.devegowda@intel.com> Please capatilize the first name. > This patch contains the changes in driver for vendor specific handshake > during enter of D3 and D0 exit. Maybe state the problem at the very beginning, and say that all Intel Bluetooth devices do not enter D0. > Command to test host initiated wakeup after 60 seconds > sudo rtcwake -m mem -s 60 > > logs from testing: > Bluetooth: hci0: BT device resumed to D0 in 1016 usecs On what device did you test this? Were you able to measure a power consumption reduction? I am also asking this, thinking that recent Intel devices only support ACPI S0ix and not ACPI S3. > Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> > Signed-off-by: Kiran K <kiran.k@intel.com> > --- > changes in v4: > - Moved document and section details from the commit message as comment in code. > > changes in v3: > - Corrected the typo's > - Updated the CC list as suggested. > - Corrected the format specifiers in the logs. > > changes in v2: > - Updated the commit message with test steps and logs. > - Added logs to include the timeout message. > - Fixed a potential race condition during suspend and resume. > > drivers/bluetooth/btintel_pcie.c | 66 ++++++++++++++++++++++++++++++++ > drivers/bluetooth/btintel_pcie.h | 4 ++ > 2 files changed, 70 insertions(+) > > diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c > index 63eca52c0e0b..4627544a2a52 100644 > --- a/drivers/bluetooth/btintel_pcie.c > +++ b/drivers/bluetooth/btintel_pcie.c > @@ -274,6 +274,12 @@ static int btintel_pcie_reset_bt(struct btintel_pcie_data *data) > return reg == 0 ? 0 : -ENODEV; > } > > +static void btintel_pcie_set_persistence_mode(struct btintel_pcie_data *data) > +{ > + btintel_pcie_set_reg_bits(data, BTINTEL_PCIE_CSR_HW_BOOT_CONFIG, > + BTINTEL_PCIE_CSR_HW_BOOT_CONFIG_KEEP_ON); > +} > + > /* This function enables BT function by setting BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT bit in > * BTINTEL_PCIE_CSR_FUNC_CTRL_REG register and wait for MSI-X with > * BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0. > @@ -298,6 +304,8 @@ static int btintel_pcie_enable_bt(struct btintel_pcie_data *data) > */ > data->boot_stage_cache = 0x0; > > + btintel_pcie_set_persistence_mode(data); > + > /* Set MAC_INIT bit to start primary bootloader */ > reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG); > reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT | > @@ -1649,11 +1657,69 @@ static void btintel_pcie_remove(struct pci_dev *pdev) > pci_set_drvdata(pdev, NULL); > } > > +static int btintel_pcie_suspend(struct device *dev) > +{ > + struct btintel_pcie_data *data; > + int err; > + struct pci_dev *pdev = to_pci_dev(dev); > + > + data = pci_get_drvdata(pdev); > + data->gp0_received = false; > + /* The implementation is as per the Intel SAS document: > + * BT Platform Power Management SAS - IOSF and the specific sections are > + * 3.1 D0Exit (D3 Entry) Flow. > + */ > + btintel_pcie_wr_sleep_cntrl(data, BTINTEL_PCIE_STATE_D3_HOT); > + err = wait_event_timeout(data->gp0_wait_q, data->gp0_received, > + msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); > + if (!err) { > + bt_dev_err(data->hdev, "failed to receive gp0 interrupt for suspend in %d msecs", > + BTINTEL_DEFAULT_INTR_TIMEOUT_MS); > + return -EBUSY; > + } > + return 0; > +} > + > +static int btintel_pcie_resume(struct device *dev) > +{ > + struct btintel_pcie_data *data; > + struct pci_dev *pdev = to_pci_dev(dev); > + ktime_t calltime, delta, rettime; > + unsigned long long duration; > + int err; > + > + data = pci_get_drvdata(pdev); > + data->gp0_received = false; > + /* The implementation is as per the Intel SAS document: > + * BT Platform Power Management SAS - IOSF and the specific sections are > + * 3.2 D0Entry (D3 Exit) Flow Missing space in D0 Entry. > + */ > + calltime = ktime_get(); > + btintel_pcie_wr_sleep_cntrl(data, BTINTEL_PCIE_STATE_D0); > + err = wait_event_timeout(data->gp0_wait_q, data->gp0_received, > + msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); > + if (!err) { > + bt_dev_err(data->hdev, "failed to receive gp0 interrupt for resume in %d msecs", > + BTINTEL_DEFAULT_INTR_TIMEOUT_MS); > + return -EBUSY; > + } > + rettime = ktime_get(); > + delta = ktime_sub(rettime, calltime); > + duration = (unsigned long long)ktime_to_ns(delta) >> 10; > + bt_dev_info(data->hdev, "BT device resumed to D0 in %llu usecs", duration); Maybe also add *from D3*. > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(btintel_pcie_pm_ops, btintel_pcie_suspend, > + btintel_pcie_resume); > + > static struct pci_driver btintel_pcie_driver = { > .name = KBUILD_MODNAME, > .id_table = btintel_pcie_table, > .probe = btintel_pcie_probe, > .remove = btintel_pcie_remove, > + .driver.pm = &btintel_pcie_pm_ops, > }; > module_pci_driver(btintel_pcie_driver); > > diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h > index f9aada0543c4..38d0c8ea2b6f 100644 > --- a/drivers/bluetooth/btintel_pcie.h > +++ b/drivers/bluetooth/btintel_pcie.h > @@ -8,6 +8,7 @@ > > /* Control and Status Register(BTINTEL_PCIE_CSR) */ > #define BTINTEL_PCIE_CSR_BASE (0x000) > +#define BTINTEL_PCIE_CSR_HW_BOOT_CONFIG (BTINTEL_PCIE_CSR_BASE + 0x000) > #define BTINTEL_PCIE_CSR_FUNC_CTRL_REG (BTINTEL_PCIE_CSR_BASE + 0x024) > #define BTINTEL_PCIE_CSR_HW_REV_REG (BTINTEL_PCIE_CSR_BASE + 0x028) > #define BTINTEL_PCIE_CSR_RF_ID_REG (BTINTEL_PCIE_CSR_BASE + 0x09C) > @@ -48,6 +49,9 @@ > #define BTINTEL_PCIE_CSR_MSIX_IVAR_BASE (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0880) > #define BTINTEL_PCIE_CSR_MSIX_IVAR(cause) (BTINTEL_PCIE_CSR_MSIX_IVAR_BASE + (cause)) > > +/* CSR HW BOOT CONFIG Register */ > +#define BTINTEL_PCIE_CSR_HW_BOOT_CONFIG_KEEP_ON (BIT(31)) > + > /* Causes for the FH register interrupts */ > enum msix_fh_int_causes { > BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0 = BIT(0), /* cause 0 */ Kind regards, Paul
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index 63eca52c0e0b..4627544a2a52 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -274,6 +274,12 @@ static int btintel_pcie_reset_bt(struct btintel_pcie_data *data) return reg == 0 ? 0 : -ENODEV; } +static void btintel_pcie_set_persistence_mode(struct btintel_pcie_data *data) +{ + btintel_pcie_set_reg_bits(data, BTINTEL_PCIE_CSR_HW_BOOT_CONFIG, + BTINTEL_PCIE_CSR_HW_BOOT_CONFIG_KEEP_ON); +} + /* This function enables BT function by setting BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT bit in * BTINTEL_PCIE_CSR_FUNC_CTRL_REG register and wait for MSI-X with * BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0. @@ -298,6 +304,8 @@ static int btintel_pcie_enable_bt(struct btintel_pcie_data *data) */ data->boot_stage_cache = 0x0; + btintel_pcie_set_persistence_mode(data); + /* Set MAC_INIT bit to start primary bootloader */ reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG); reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT | @@ -1649,11 +1657,69 @@ static void btintel_pcie_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static int btintel_pcie_suspend(struct device *dev) +{ + struct btintel_pcie_data *data; + int err; + struct pci_dev *pdev = to_pci_dev(dev); + + data = pci_get_drvdata(pdev); + data->gp0_received = false; + /* The implementation is as per the Intel SAS document: + * BT Platform Power Management SAS - IOSF and the specific sections are + * 3.1 D0Exit (D3 Entry) Flow. + */ + btintel_pcie_wr_sleep_cntrl(data, BTINTEL_PCIE_STATE_D3_HOT); + err = wait_event_timeout(data->gp0_wait_q, data->gp0_received, + msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); + if (!err) { + bt_dev_err(data->hdev, "failed to receive gp0 interrupt for suspend in %d msecs", + BTINTEL_DEFAULT_INTR_TIMEOUT_MS); + return -EBUSY; + } + return 0; +} + +static int btintel_pcie_resume(struct device *dev) +{ + struct btintel_pcie_data *data; + struct pci_dev *pdev = to_pci_dev(dev); + ktime_t calltime, delta, rettime; + unsigned long long duration; + int err; + + data = pci_get_drvdata(pdev); + data->gp0_received = false; + /* The implementation is as per the Intel SAS document: + * BT Platform Power Management SAS - IOSF and the specific sections are + * 3.2 D0Entry (D3 Exit) Flow + */ + calltime = ktime_get(); + btintel_pcie_wr_sleep_cntrl(data, BTINTEL_PCIE_STATE_D0); + err = wait_event_timeout(data->gp0_wait_q, data->gp0_received, + msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); + if (!err) { + bt_dev_err(data->hdev, "failed to receive gp0 interrupt for resume in %d msecs", + BTINTEL_DEFAULT_INTR_TIMEOUT_MS); + return -EBUSY; + } + rettime = ktime_get(); + delta = ktime_sub(rettime, calltime); + duration = (unsigned long long)ktime_to_ns(delta) >> 10; + bt_dev_info(data->hdev, "BT device resumed to D0 in %llu usecs", duration); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(btintel_pcie_pm_ops, btintel_pcie_suspend, + btintel_pcie_resume); + static struct pci_driver btintel_pcie_driver = { .name = KBUILD_MODNAME, .id_table = btintel_pcie_table, .probe = btintel_pcie_probe, .remove = btintel_pcie_remove, + .driver.pm = &btintel_pcie_pm_ops, }; module_pci_driver(btintel_pcie_driver); diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h index f9aada0543c4..38d0c8ea2b6f 100644 --- a/drivers/bluetooth/btintel_pcie.h +++ b/drivers/bluetooth/btintel_pcie.h @@ -8,6 +8,7 @@ /* Control and Status Register(BTINTEL_PCIE_CSR) */ #define BTINTEL_PCIE_CSR_BASE (0x000) +#define BTINTEL_PCIE_CSR_HW_BOOT_CONFIG (BTINTEL_PCIE_CSR_BASE + 0x000) #define BTINTEL_PCIE_CSR_FUNC_CTRL_REG (BTINTEL_PCIE_CSR_BASE + 0x024) #define BTINTEL_PCIE_CSR_HW_REV_REG (BTINTEL_PCIE_CSR_BASE + 0x028) #define BTINTEL_PCIE_CSR_RF_ID_REG (BTINTEL_PCIE_CSR_BASE + 0x09C) @@ -48,6 +49,9 @@ #define BTINTEL_PCIE_CSR_MSIX_IVAR_BASE (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0880) #define BTINTEL_PCIE_CSR_MSIX_IVAR(cause) (BTINTEL_PCIE_CSR_MSIX_IVAR_BASE + (cause)) +/* CSR HW BOOT CONFIG Register */ +#define BTINTEL_PCIE_CSR_HW_BOOT_CONFIG_KEEP_ON (BIT(31)) + /* Causes for the FH register interrupts */ enum msix_fh_int_causes { BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0 = BIT(0), /* cause 0 */