提交 b0b36b86 编写于 作者: B Bryan Freed 提交者: Mark Brown

spi: Unlock a spinlock before calling into the controller driver.

spi_pump_messages() calls into a controller driver with
unprepare_transfer_hardware() which is documented as "This may sleep".
As in the prepare_transfer_hardware() call below, we should release the
queue_lock spinlock before making the call.
Rework the logic a bit to hold queue_lock to protect the 'busy' flag,
then release it to call unprepare_transfer_hardware().
Signed-off-by: NBryan Freed <bfreed@chromium.org>
Reviewed-by: NDoug Anderson <dianders@chromium.org>
Signed-off-by: NDoug Anderson <dianders@chromium.org>
Acked-by: NLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
上级 375981f2
...@@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work) ...@@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work)
/* Lock queue and check for queue work */ /* Lock queue and check for queue work */
spin_lock_irqsave(&master->queue_lock, flags); spin_lock_irqsave(&master->queue_lock, flags);
if (list_empty(&master->queue) || !master->running) { if (list_empty(&master->queue) || !master->running) {
if (master->busy && master->unprepare_transfer_hardware) { if (!master->busy) {
ret = master->unprepare_transfer_hardware(master); spin_unlock_irqrestore(&master->queue_lock, flags);
if (ret) { return;
spin_unlock_irqrestore(&master->queue_lock, flags);
dev_err(&master->dev,
"failed to unprepare transfer hardware\n");
return;
}
} }
master->busy = false; master->busy = false;
spin_unlock_irqrestore(&master->queue_lock, flags); spin_unlock_irqrestore(&master->queue_lock, flags);
if (master->unprepare_transfer_hardware &&
master->unprepare_transfer_hardware(master))
dev_err(&master->dev,
"failed to unprepare transfer hardware\n");
return; return;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册