staging: wfx: drop async field from struct hif_cmd
The parameter "async" in wfx_cmd_send() allows to send command without waiting for the reply. In this case, the mutex hif_cmd.lock is released asynchronously in the context of the receiver workqueue. However, "kbuild test robot" complains about this architecture[1] since it is not able to follow the lock duration of hif_cmd.lock (and indeed, the state of the driver if the hardware wouldn't reply is not well defined). Besides, this feature is not really necessary. It is only used by hif_shutdown(). This function hijack the 'async' flag to run a command that won't answer. So, this patch removes the 'async' flag and introduces a 'no_reply' flag. Thus, the mutex hif_cmd.lock is only acquired/released from hif_cmd_send(). Therefore: - hif_shutdown() does not have to touch the private data of the struct hif_cmd - Kbuild test robot should be happy - the resulting code is simpler [1] https://lore.kernel.org/driverdev-devel/alpine.DEB.2.21.1910041317381.2992@hadrien/ Reported-by: kbuild test robot <lkp@intel.com> Reported-by: Julia Lawall <julia.lawall@lip6.fr> Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com> Link: https://lore.kernel.org/r/20200907101521.66082-31-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
c8fb880910
Коммит
3768c74b3a
|
@ -47,12 +47,7 @@ static int hif_generic_confirm(struct wfx_dev *wdev,
|
|||
}
|
||||
wdev->hif_cmd.ret = status;
|
||||
|
||||
if (!wdev->hif_cmd.async) {
|
||||
complete(&wdev->hif_cmd.done);
|
||||
} else {
|
||||
wdev->hif_cmd.buf_send = NULL;
|
||||
mutex_unlock(&wdev->hif_cmd.lock);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ static void *wfx_alloc_hif(size_t body_len, struct hif_msg **hif)
|
|||
}
|
||||
|
||||
int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
|
||||
void *reply, size_t reply_len, bool async)
|
||||
void *reply, size_t reply_len, bool no_reply)
|
||||
{
|
||||
const char *mib_name = "";
|
||||
const char *mib_sep = "";
|
||||
|
@ -55,8 +55,6 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
|
|||
int vif = request->interface;
|
||||
int ret;
|
||||
|
||||
WARN(wdev->hif_cmd.buf_recv && wdev->hif_cmd.async, "API usage error");
|
||||
|
||||
// Do not wait for any reply if chip is frozen
|
||||
if (wdev->chip_frozen)
|
||||
return -ETIMEDOUT;
|
||||
|
@ -69,14 +67,18 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
|
|||
wdev->hif_cmd.buf_send = request;
|
||||
wdev->hif_cmd.buf_recv = reply;
|
||||
wdev->hif_cmd.len_recv = reply_len;
|
||||
wdev->hif_cmd.async = async;
|
||||
complete(&wdev->hif_cmd.ready);
|
||||
|
||||
wfx_bh_request_tx(wdev);
|
||||
|
||||
// NOTE: no timeout is caught async is enabled
|
||||
if (async)
|
||||
if (no_reply) {
|
||||
// Chip won't reply. Give enough time to the wq to send the
|
||||
// buffer.
|
||||
msleep(100);
|
||||
wdev->hif_cmd.buf_send = NULL;
|
||||
mutex_unlock(&wdev->hif_cmd.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wdev->poll_irq)
|
||||
wfx_bh_poll_irq(wdev);
|
||||
|
@ -118,29 +120,21 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
|
|||
}
|
||||
|
||||
// This function is special. After HIF_REQ_ID_SHUT_DOWN, chip won't reply to any
|
||||
// request anymore. We need to slightly hack struct wfx_hif_cmd for that job. Be
|
||||
// careful to only call this function during device unregister.
|
||||
// request anymore. Obviously, only call this function during device unregister.
|
||||
int hif_shutdown(struct wfx_dev *wdev)
|
||||
{
|
||||
int ret;
|
||||
struct hif_msg *hif;
|
||||
|
||||
if (wdev->chip_frozen)
|
||||
return 0;
|
||||
wfx_alloc_hif(0, &hif);
|
||||
if (!hif)
|
||||
return -ENOMEM;
|
||||
wfx_fill_header(hif, -1, HIF_REQ_ID_SHUT_DOWN, 0);
|
||||
ret = wfx_cmd_send(wdev, hif, NULL, 0, true);
|
||||
// After this command, chip won't reply. Be sure to give enough time to
|
||||
// bh to send buffer:
|
||||
msleep(100);
|
||||
wdev->hif_cmd.buf_send = NULL;
|
||||
if (wdev->pdata.gpio_wakeup)
|
||||
gpiod_set_value(wdev->pdata.gpio_wakeup, 0);
|
||||
else
|
||||
control_reg_write(wdev, 0);
|
||||
mutex_unlock(&wdev->hif_cmd.lock);
|
||||
kfree(hif);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ struct wfx_hif_cmd {
|
|||
struct mutex lock;
|
||||
struct completion ready;
|
||||
struct completion done;
|
||||
bool async;
|
||||
struct hif_msg *buf_send;
|
||||
void *buf_recv;
|
||||
size_t len_recv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче