diff mbox series

[1/4] Bluetooth: btusb: mediatek: use readx_poll_timeout instead of open coding

Message ID 43b68b1f48c20b1dfcd7e6663c3dcb38e4e0648c.1663020936.git.objelf@gmail.com (mailing list archive)
State Superseded
Headers show
Series [1/4] Bluetooth: btusb: mediatek: use readx_poll_timeout instead of open coding | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/checkpatch success Checkpatch PASS
tedd_an/gitlint success Gitlint PASS
tedd_an/subjectprefix success PASS
tedd_an/buildkernel fail Build Kernel make FAIL: drivers/bluetooth/btmtk.c: In function ‘btmtk_coredump_notify’: drivers/bluetooth/btmtk.c:111:7: error: ‘HCI_DEVCOREDUMP_ACTIVE’ undeclared (first use in this function); did you mean ‘BTMTK_COREDUMP_ACTIVE’? 111 | case HCI_DEVCOREDUMP_ACTIVE: | ^~~~~~~~~~~~~~~~~~~~~~ | BTMTK_COREDUMP_ACTIVE drivers/bluetooth/btmtk.c:111:7: note: each undeclared identifier is reported only once for each function it appears in drivers/bluetooth/btmtk.c:114:7: error: ‘HCI_DEVCOREDUMP_TIMEOUT’ undeclared (first use in this function); did you mean ‘HCI_DISCONN_TIMEOUT’? 114 | case HCI_DEVCOREDUMP_TIMEOUT: | ^~~~~~~~~~~~~~~~~~~~~~~ | HCI_DISCONN_TIMEOUT drivers/bluetooth/btmtk.c:115:7: error: ‘HCI_DEVCOREDUMP_ABORT’ undeclared (first use in this function) 115 | case HCI_DEVCOREDUMP_ABORT: | ^~~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c:116:7: error: ‘HCI_DEVCOREDUMP_DONE’ undeclared (first use in this function) 116 | case HCI_DEVCOREDUMP_DONE: | ^~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c: In function ‘btmtk_register_coredump’: drivers/bluetooth/btmtk.c:376:2: error: implicit declaration of function ‘hci_devcoredump_register’ [-Werror=implicit-function-declaration] 376 | hci_devcoredump_register(hdev, btmtk_coredump, btmtk_coredump_hdr, | ^~~~~~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c: In function ‘btmtk_process_coredump’: drivers/bluetooth/btmtk.c:393:9: error: implicit declaration of function ‘hci_devcoredump_init’ [-Werror=implicit-function-declaration] 393 | err = hci_devcoredump_init(hdev, 1024000); | ^~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c:397:30: error: ‘struct hci_dev’ has no member named ‘dump’ 397 | schedule_delayed_work(&hdev->dump.dump_timeout, | ^~ drivers/bluetooth/btmtk.c:402:9: error: implicit declaration of function ‘hci_devcoredump_append’ [-Werror=implicit-function-declaration] 402 | err = hci_devcoredump_append(hdev, skb); | ^~~~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c:409:4: error: implicit declaration of function ‘hci_devcoredump_complete’ [-Werror=implicit-function-declaration] 409 | hci_devcoredump_complete(hdev); | ^~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors make[2]: *** [scripts/Makefile.build:249: drivers/bluetooth/btmtk.o] Error 1 make[1]: *** [scripts/Makefile.build:465: drivers/bluetooth] Error 2 make: *** [Makefile:1855: drivers] Error 2
tedd_an/buildkernel32 fail Build Kernel32 make FAIL: drivers/bluetooth/btmtk.c: In function ‘btmtk_coredump_notify’: drivers/bluetooth/btmtk.c:111:7: error: ‘HCI_DEVCOREDUMP_ACTIVE’ undeclared (first use in this function); did you mean ‘BTMTK_COREDUMP_ACTIVE’? 111 | case HCI_DEVCOREDUMP_ACTIVE: | ^~~~~~~~~~~~~~~~~~~~~~ | BTMTK_COREDUMP_ACTIVE drivers/bluetooth/btmtk.c:111:7: note: each undeclared identifier is reported only once for each function it appears in drivers/bluetooth/btmtk.c:114:7: error: ‘HCI_DEVCOREDUMP_TIMEOUT’ undeclared (first use in this function); did you mean ‘HCI_DISCONN_TIMEOUT’? 114 | case HCI_DEVCOREDUMP_TIMEOUT: | ^~~~~~~~~~~~~~~~~~~~~~~ | HCI_DISCONN_TIMEOUT drivers/bluetooth/btmtk.c:115:7: error: ‘HCI_DEVCOREDUMP_ABORT’ undeclared (first use in this function) 115 | case HCI_DEVCOREDUMP_ABORT: | ^~~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c:116:7: error: ‘HCI_DEVCOREDUMP_DONE’ undeclared (first use in this function) 116 | case HCI_DEVCOREDUMP_DONE: | ^~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c: In function ‘btmtk_register_coredump’: drivers/bluetooth/btmtk.c:376:2: error: implicit declaration of function ‘hci_devcoredump_register’ [-Werror=implicit-function-declaration] 376 | hci_devcoredump_register(hdev, btmtk_coredump, btmtk_coredump_hdr, | ^~~~~~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c: In function ‘btmtk_process_coredump’: drivers/bluetooth/btmtk.c:393:9: error: implicit declaration of function ‘hci_devcoredump_init’ [-Werror=implicit-function-declaration] 393 | err = hci_devcoredump_init(hdev, 1024000); | ^~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c:397:30: error: ‘struct hci_dev’ has no member named ‘dump’ 397 | schedule_delayed_work(&hdev->dump.dump_timeout, | ^~ drivers/bluetooth/btmtk.c:402:9: error: implicit declaration of function ‘hci_devcoredump_append’ [-Werror=implicit-function-declaration] 402 | err = hci_devcoredump_append(hdev, skb); | ^~~~~~~~~~~~~~~~~~~~~~ drivers/bluetooth/btmtk.c:409:4: error: implicit declaration of function ‘hci_devcoredump_complete’ [-Werror=implicit-function-declaration] 409 | hci_devcoredump_complete(hdev); | ^~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors make[2]: *** [scripts/Makefile.build:249: drivers/bluetooth/btmtk.o] Error 1 make[1]: *** [scripts/Makefile.build:465: drivers/bluetooth] Error 2 make: *** [Makefile:1855: drivers] Error 2
tedd_an/incremental_build pending Incremental Build Kernel SKIP(Build Fail)
tedd_an/testrunnersetup success Test Runner Setup PASS
tedd_an/testrunnerl2cap-tester success Total: 40, Passed: 40 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunneriso-tester success Total: 55, Passed: 55 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnerbnep-tester success Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnermgmt-tester success Total: 494, Passed: 494 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnerrfcomm-tester success Total: 10, Passed: 10 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnersco-tester success Total: 12, Passed: 12 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnersmp-tester success Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunneruserchan-tester success Total: 4, Passed: 4 (100.0%), Failed: 0, Not Run: 0

Commit Message

Sean Wang Sept. 12, 2022, 10:18 p.m. UTC
From: Sean Wang <sean.wang@mediatek.com>

Use readx_poll_timeout instead of open coding to poll the hardware reset
status until it is done.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 drivers/bluetooth/btusb.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

Comments

bluez.test.bot@gmail.com Sept. 12, 2022, 11:10 p.m. UTC | #1
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=676354

---Test result---

Test Summary:
CheckPatch                    PASS      5.17 seconds
GitLint                       FAIL      1.94 seconds
SubjectPrefix                 PASS      1.26 seconds
BuildKernel                   FAIL      46.70 seconds
BuildKernel32                 FAIL      40.93 seconds
Incremental Build with patchesERROR     0.19 seconds
TestRunner: Setup             PASS      684.69 seconds
TestRunner: l2cap-tester      PASS      21.12 seconds
TestRunner: iso-tester        PASS      21.32 seconds
TestRunner: bnep-tester       PASS      8.21 seconds
TestRunner: mgmt-tester       PASS      132.98 seconds
TestRunner: rfcomm-tester     PASS      12.65 seconds
TestRunner: sco-tester        PASS      12.08 seconds
TestRunner: smp-tester        PASS      12.00 seconds
TestRunner: userchan-tester   PASS      8.63 seconds

Details
##############################
Test: GitLint - FAIL - 1.94 seconds
Run gitlint with rule in .gitlint
[4/4] Bluetooth: btusb: mediatek: add MediaTek devcoredump support
19: B1 Line exceeds max length (127>80): "in https://patchwork.kernel.org/project/bluetooth/patch/20220809083112.v4.3.Iaf638bb9f885f5880ab1b4e7ae2f73dd53a54661@changeid/"


##############################
Test: BuildKernel - FAIL - 46.70 seconds
Build Kernel with minimal configuration supports Bluetooth
drivers/bluetooth/btmtk.c: In function ‘btmtk_coredump_notify’:
drivers/bluetooth/btmtk.c:111:7: error: ‘HCI_DEVCOREDUMP_ACTIVE’ undeclared (first use in this function); did you mean ‘BTMTK_COREDUMP_ACTIVE’?
  111 |  case HCI_DEVCOREDUMP_ACTIVE:
      |       ^~~~~~~~~~~~~~~~~~~~~~
      |       BTMTK_COREDUMP_ACTIVE
drivers/bluetooth/btmtk.c:111:7: note: each undeclared identifier is reported only once for each function it appears in
drivers/bluetooth/btmtk.c:114:7: error: ‘HCI_DEVCOREDUMP_TIMEOUT’ undeclared (first use in this function); did you mean ‘HCI_DISCONN_TIMEOUT’?
  114 |  case HCI_DEVCOREDUMP_TIMEOUT:
      |       ^~~~~~~~~~~~~~~~~~~~~~~
      |       HCI_DISCONN_TIMEOUT
drivers/bluetooth/btmtk.c:115:7: error: ‘HCI_DEVCOREDUMP_ABORT’ undeclared (first use in this function)
  115 |  case HCI_DEVCOREDUMP_ABORT:
      |       ^~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c:116:7: error: ‘HCI_DEVCOREDUMP_DONE’ undeclared (first use in this function)
  116 |  case HCI_DEVCOREDUMP_DONE:
      |       ^~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c: In function ‘btmtk_register_coredump’:
drivers/bluetooth/btmtk.c:376:2: error: implicit declaration of function ‘hci_devcoredump_register’ [-Werror=implicit-function-declaration]
  376 |  hci_devcoredump_register(hdev, btmtk_coredump, btmtk_coredump_hdr,
      |  ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c: In function ‘btmtk_process_coredump’:
drivers/bluetooth/btmtk.c:393:9: error: implicit declaration of function ‘hci_devcoredump_init’ [-Werror=implicit-function-declaration]
  393 |   err = hci_devcoredump_init(hdev, 1024000);
      |         ^~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c:397:30: error: ‘struct hci_dev’ has no member named ‘dump’
  397 |   schedule_delayed_work(&hdev->dump.dump_timeout,
      |                              ^~
drivers/bluetooth/btmtk.c:402:9: error: implicit declaration of function ‘hci_devcoredump_append’ [-Werror=implicit-function-declaration]
  402 |   err = hci_devcoredump_append(hdev, skb);
      |         ^~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c:409:4: error: implicit declaration of function ‘hci_devcoredump_complete’ [-Werror=implicit-function-declaration]
  409 |    hci_devcoredump_complete(hdev);
      |    ^~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:249: drivers/bluetooth/btmtk.o] Error 1
make[1]: *** [scripts/Makefile.build:465: drivers/bluetooth] Error 2
make: *** [Makefile:1855: drivers] Error 2


##############################
Test: BuildKernel32 - FAIL - 40.93 seconds
Build 32bit Kernel with minimal configuration supports Bluetooth
drivers/bluetooth/btmtk.c: In function ‘btmtk_coredump_notify’:
drivers/bluetooth/btmtk.c:111:7: error: ‘HCI_DEVCOREDUMP_ACTIVE’ undeclared (first use in this function); did you mean ‘BTMTK_COREDUMP_ACTIVE’?
  111 |  case HCI_DEVCOREDUMP_ACTIVE:
      |       ^~~~~~~~~~~~~~~~~~~~~~
      |       BTMTK_COREDUMP_ACTIVE
drivers/bluetooth/btmtk.c:111:7: note: each undeclared identifier is reported only once for each function it appears in
drivers/bluetooth/btmtk.c:114:7: error: ‘HCI_DEVCOREDUMP_TIMEOUT’ undeclared (first use in this function); did you mean ‘HCI_DISCONN_TIMEOUT’?
  114 |  case HCI_DEVCOREDUMP_TIMEOUT:
      |       ^~~~~~~~~~~~~~~~~~~~~~~
      |       HCI_DISCONN_TIMEOUT
drivers/bluetooth/btmtk.c:115:7: error: ‘HCI_DEVCOREDUMP_ABORT’ undeclared (first use in this function)
  115 |  case HCI_DEVCOREDUMP_ABORT:
      |       ^~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c:116:7: error: ‘HCI_DEVCOREDUMP_DONE’ undeclared (first use in this function)
  116 |  case HCI_DEVCOREDUMP_DONE:
      |       ^~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c: In function ‘btmtk_register_coredump’:
drivers/bluetooth/btmtk.c:376:2: error: implicit declaration of function ‘hci_devcoredump_register’ [-Werror=implicit-function-declaration]
  376 |  hci_devcoredump_register(hdev, btmtk_coredump, btmtk_coredump_hdr,
      |  ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c: In function ‘btmtk_process_coredump’:
drivers/bluetooth/btmtk.c:393:9: error: implicit declaration of function ‘hci_devcoredump_init’ [-Werror=implicit-function-declaration]
  393 |   err = hci_devcoredump_init(hdev, 1024000);
      |         ^~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c:397:30: error: ‘struct hci_dev’ has no member named ‘dump’
  397 |   schedule_delayed_work(&hdev->dump.dump_timeout,
      |                              ^~
drivers/bluetooth/btmtk.c:402:9: error: implicit declaration of function ‘hci_devcoredump_append’ [-Werror=implicit-function-declaration]
  402 |   err = hci_devcoredump_append(hdev, skb);
      |         ^~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/btmtk.c:409:4: error: implicit declaration of function ‘hci_devcoredump_complete’ [-Werror=implicit-function-declaration]
  409 |    hci_devcoredump_complete(hdev);
      |    ^~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:249: drivers/bluetooth/btmtk.o] Error 1
make[1]: *** [scripts/Makefile.build:465: drivers/bluetooth] Error 2
make: *** [Makefile:1855: drivers] Error 2


##############################
Test: Incremental Build with patches - SKIPPED - 0.19 seconds
Incremental build per patch in the series
buildkernel failed



---
Regards,
Linux Bluetooth
AngeloGioacchino Del Regno Sept. 13, 2022, 7:47 a.m. UTC | #2
Il 13/09/22 00:18, sean.wang@mediatek.com ha scritto:
> From: Sean Wang <sean.wang@mediatek.com>
> 
> Use readx_poll_timeout instead of open coding to poll the hardware reset
> status until it is done.
> 
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>

Hello Sean, thanks for the patch!
However, there's something to improve...

> ---
>   drivers/bluetooth/btusb.c | 32 ++++++++++++++++++--------------
>   1 file changed, 18 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index c3daba17de7f..4dc9cae3e937 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c

..snip..

> @@ -2910,18 +2918,14 @@ static void btusb_mtk_cmd_timeout(struct hci_dev *hdev)
>   	btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
>   	btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
>   
> -	/* Poll the register until reset is completed */
> -	do {
> -		btusb_mtk_uhw_reg_read(data, MTK_BT_MISC, &val);
> -		if (val & MTK_BT_RST_DONE) {
> -			bt_dev_dbg(hdev, "Bluetooth Reset Successfully");
> -			break;
> -		}
> +	err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
> +				 val & MTK_BT_RST_DONE,
> +				 100000, 1000000);

I agree with using readx_poll_timeout() instead of open coding the same, but
there's a catch: this macro uses usleep_range(), which is meant to be used
for sleeping less than ~20ms.

Even the kerneldoc at include/linux/iopoll.h advertises that:

  * @sleep_us: Maximum time to sleep between reads in us (0
  *            tight-loops).  Should be less than ~20ms since usleep_range
  *            is used (see Documentation/timers/timers-howto.rst).

So, if there's any reason for which you can't sleep for less than 100ms
per iteration, I'm afraid that you can't use readx_poll_timeout()...
...otherwise, please change sleep_us to 20000 and keep the timeout at 1 sec.

Regards,
Angelo

> +	if (err < 0)
> +		bt_dev_err(hdev, "Reset timeout");
>   
> -		bt_dev_dbg(hdev, "Polling Bluetooth Reset CR");
> -		retry++;
> -		msleep(MTK_BT_RESET_WAIT_MS);
> -	} while (retry < MTK_BT_RESET_NUM_TRIES);
> +	if (val & MTK_BT_RST_DONE)
> +		bt_dev_dbg(hdev, "Bluetooth Reset Successfully");
>   
>   	btusb_mtk_id_get(data, 0x70010200, &val);
>   	if (!val)
Sean Wang Sept. 14, 2022, 10:59 p.m. UTC | #3
HI Angelo,

On Tue, Sep 13, 2022 at 1:04 AM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 13/09/22 00:18, sean.wang@mediatek.com ha scritto:
> > From: Sean Wang <sean.wang@mediatek.com>
> >
> > Use readx_poll_timeout instead of open coding to poll the hardware reset
> > status until it is done.
> >
> > Signed-off-by: Sean Wang <sean.wang@mediatek.com>
>
> Hello Sean, thanks for the patch!
> However, there's something to improve...
>
> > ---
> >   drivers/bluetooth/btusb.c | 32 ++++++++++++++++++--------------
> >   1 file changed, 18 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> > index c3daba17de7f..4dc9cae3e937 100644
> > --- a/drivers/bluetooth/btusb.c
> > +++ b/drivers/bluetooth/btusb.c
>
> ..snip..
>
> > @@ -2910,18 +2918,14 @@ static void btusb_mtk_cmd_timeout(struct hci_dev *hdev)
> >       btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
> >       btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
> >
> > -     /* Poll the register until reset is completed */
> > -     do {
> > -             btusb_mtk_uhw_reg_read(data, MTK_BT_MISC, &val);
> > -             if (val & MTK_BT_RST_DONE) {
> > -                     bt_dev_dbg(hdev, "Bluetooth Reset Successfully");
> > -                     break;
> > -             }
> > +     err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
> > +                              val & MTK_BT_RST_DONE,
> > +                              100000, 1000000);
>
> I agree with using readx_poll_timeout() instead of open coding the same, but
> there's a catch: this macro uses usleep_range(), which is meant to be used
> for sleeping less than ~20ms.
>
> Even the kerneldoc at include/linux/iopoll.h advertises that:
>
>   * @sleep_us: Maximum time to sleep between reads in us (0
>   *            tight-loops).  Should be less than ~20ms since usleep_range
>   *            is used (see Documentation/timers/timers-howto.rst).
>
> So, if there's any reason for which you can't sleep for less than 100ms
> per iteration, I'm afraid that you can't use readx_poll_timeout()...
> ...otherwise, please change sleep_us to 20000 and keep the timeout at 1 sec.
>

It should be able to be done with polling in 20ms until 1 sec expires
or it is done. It increases some cost in the bus transaction
interacting with the device, but it seemed fine for me because the
code path is cold, it is only working in the device reset which should
rarely happen, and only involves when it is really necessary. That is
a nice catch. I was trying not to break the existing logic
but overlooked the requirements of the API.

    Sean

> Regards,
> Angelo
>
> > +     if (err < 0)
> > +             bt_dev_err(hdev, "Reset timeout");
> >
> > -             bt_dev_dbg(hdev, "Polling Bluetooth Reset CR");
> > -             retry++;
> > -             msleep(MTK_BT_RESET_WAIT_MS);
> > -     } while (retry < MTK_BT_RESET_NUM_TRIES);
> > +     if (val & MTK_BT_RST_DONE)
> > +             bt_dev_dbg(hdev, "Bluetooth Reset Successfully");
> >
> >       btusb_mtk_id_get(data, 0x70010200, &val);
> >       if (!val)
>
diff mbox series

Patch

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c3daba17de7f..4dc9cae3e937 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2318,8 +2318,6 @@  static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
 #define MTK_EP_RST_OPT		0x74011890
 #define MTK_EP_RST_IN_OUT_OPT	0x00010001
 #define MTK_BT_RST_DONE		0x00000100
-#define MTK_BT_RESET_WAIT_MS	100
-#define MTK_BT_RESET_NUM_TRIES	10
 
 static void btusb_mtk_wmt_recv(struct urb *urb)
 {
@@ -2690,6 +2688,16 @@  static int btusb_mtk_id_get(struct btusb_data *data, u32 reg, u32 *id)
 	return btusb_mtk_reg_read(data, reg, id);
 }
 
+static u32 btusb_mtk_reset_done(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hci_get_drvdata(hdev);
+	u32 val = 0;
+
+	btusb_mtk_uhw_reg_read(data, MTK_BT_MISC, &val);
+
+	return val;
+}
+
 static int btusb_mtk_setup(struct hci_dev *hdev)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
@@ -2879,7 +2887,7 @@  static void btusb_mtk_cmd_timeout(struct hci_dev *hdev)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	u32 val;
-	int err, retry = 0;
+	int err;
 
 	/* It's MediaTek specific bluetooth reset mechanism via USB */
 	if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
@@ -2910,18 +2918,14 @@  static void btusb_mtk_cmd_timeout(struct hci_dev *hdev)
 	btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
 	btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
 
-	/* Poll the register until reset is completed */
-	do {
-		btusb_mtk_uhw_reg_read(data, MTK_BT_MISC, &val);
-		if (val & MTK_BT_RST_DONE) {
-			bt_dev_dbg(hdev, "Bluetooth Reset Successfully");
-			break;
-		}
+	err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
+				 val & MTK_BT_RST_DONE,
+				 100000, 1000000);
+	if (err < 0)
+		bt_dev_err(hdev, "Reset timeout");
 
-		bt_dev_dbg(hdev, "Polling Bluetooth Reset CR");
-		retry++;
-		msleep(MTK_BT_RESET_WAIT_MS);
-	} while (retry < MTK_BT_RESET_NUM_TRIES);
+	if (val & MTK_BT_RST_DONE)
+		bt_dev_dbg(hdev, "Bluetooth Reset Successfully");
 
 	btusb_mtk_id_get(data, 0x70010200, &val);
 	if (!val)