staging: wfx: introduce a way to poll IRQ

It is possible to check if an IRQ is ending by polling the control
register. This function must used with care: if an IRQ fires while the
host reads control register, the IRQ can be lost. However, it could be
useful in some cases.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200505123757.39506-8-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Jérôme Pouiller 2020-05-05 14:37:49 +02:00 committed by Greg Kroah-Hartman
parent a7efb62509
commit 57aa557f11
2 changed files with 29 additions and 0 deletions

View File

@ -307,6 +307,34 @@ void wfx_bh_request_tx(struct wfx_dev *wdev)
queue_work(system_highpri_wq, &wdev->hif.bh);
}
/*
* If IRQ is not available, this function allow to manually poll the control
* register and simulate an IRQ ahen an event happened.
*
* Note that the device has a bug: If an IRQ raise while host read control
* register, the IRQ is lost. So, use this function carefully (only duing
* device initialisation).
*/
void wfx_bh_poll_irq(struct wfx_dev *wdev)
{
ktime_t now, start;
u32 reg;
start = ktime_get();
for (;;) {
control_reg_read(wdev, &reg);
now = ktime_get();
if (reg & 0xFFF)
break;
if (ktime_after(now, ktime_add_ms(start, 1000))) {
dev_err(wdev->dev, "time out while polling control register\n");
return;
}
udelay(200);
}
wfx_bh_request_rx(wdev);
}
void wfx_bh_register(struct wfx_dev *wdev)
{
INIT_WORK(&wdev->hif.bh, bh_work);

View File

@ -28,5 +28,6 @@ void wfx_bh_register(struct wfx_dev *wdev);
void wfx_bh_unregister(struct wfx_dev *wdev);
void wfx_bh_request_rx(struct wfx_dev *wdev);
void wfx_bh_request_tx(struct wfx_dev *wdev);
void wfx_bh_poll_irq(struct wfx_dev *wdev);
#endif /* WFX_BH_H */