diff options
author | Jérôme Pouiller <jerome.pouiller@silabs.com> | 2022-02-25 12:24:04 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-02-25 14:00:29 +0100 |
commit | c86176d51340d5ee29afffce63d79c4ece5d96bb (patch) | |
tree | 7d343fe254f6132fb8dbc97e8e93f910ca293610 | |
parent | 0803a85a6f236f648b80584bc02b86b092f43d5a (diff) |
staging: wfx: ensure HIF request has been sent before polling
wfx_bh_request_tx() send HIF request asynchronously through bh_work().
Then the caller will run wfx_bh_poll_irq() to poll the answer.
However it useless to burn CPU cycles for the polling while the request
has yet been sent. Worse, wfx_bh_poll_irq() may get the CPU and prevent
wfx_bh_request_tx() to run. This problem has been observed on mono core
architecture.
This first exchange is correct:
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003000
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003000
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003004
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003004
kworker/0:1H-40 [000] .... : io_read: QUEUE: 08 00 09 0c 00 00 00 00 3a 7b 00 30 (12 bytes)
kworker/0:1H-40 [000] .... : piggyback: CONTROL: 00003000
kworker/0:1H-40 [000] .... : hif_recv: 0:2:CNF_CONFIGURATION: 00 00 00 00 (8 bytes)
kworker/0:1H-40 [000] .... : io_read32: CONFIG: 03010200
kworker/0:1H-40 [000] .... : bh_stats: IND/REQ/CNF: 0/ 0/ 1, REQ in progress: 0, WUP: release
... while the following is not:
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003000
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003000
kworker/u2:1-24 [000] .... : io_read32: CONTROL: 00003000
[...loop until timeout...]
wfx-sdio mmc0:0001:1: time out while polling control register
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20220225112405.355599-10-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/wfx/bh.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 4c6ba9c342a6..bcea9d5b119c 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -295,6 +295,7 @@ void wfx_bh_poll_irq(struct wfx_dev *wdev) u32 reg; WARN(!wdev->poll_irq, "unexpected IRQ polling can mask IRQ"); + flush_workqueue(system_highpri_wq); start = ktime_get(); for (;;) { wfx_control_reg_read(wdev, ®); |