@@ -561,8 +561,8 @@ SPI Master Methods
The subsystem calls the driver to transfer a single message while
queuing transfers that arrive in the meantime. When the driver is
finished with this message, it must call
- spi_finalize_current_message() so the subsystem can issue the next
- message. This may sleep.
+ spi_finalize_message() so the subsystem can issue the next message.
+ This may sleep.
``master->transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *transfer)``
The subsystem calls the driver to transfer a single transfer while
@@ -161,7 +161,7 @@ static int netup_spi_transfer(struct spi_master *master,
}
done:
msg->status = result;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return result;
}
@@ -1154,7 +1154,7 @@ static int msi2500_transfer_one_message(struct spi_master *master,
}
m->status = ret;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return ret;
}
@@ -248,7 +248,7 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi,
return -ENODEV;
}
- spi_finalize_current_message(master);
+ spi_finalize_message(message);
return 0;
}
@@ -150,7 +150,7 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master,
msg_done:
m->status = stat;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return 0;
}
@@ -396,7 +396,7 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
msg->status = 0;
msg->actual_length = msg->frame_length;
spi_engine->msg = NULL;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
disable_int |= SPI_ENGINE_INT_SYNC;
}
}
@@ -307,7 +307,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master,
mutex_unlock(&bs->bus_mutex);
msg->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return 0;
}
@@ -395,7 +395,7 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master,
}
exit:
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return 0;
}
@@ -145,6 +145,6 @@ int octeon_spi_transfer_one_message(struct spi_master *master,
err:
msg->status = status;
msg->actual_length = total_len;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return status;
}
@@ -382,7 +382,7 @@ static int falcon_sflash_xfer_one(struct spi_master *master,
}
m->status = ret;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return 0;
}
@@ -502,7 +502,7 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
error:
mesg->status = rc;
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(mesg);
return rc;
}
@@ -967,7 +967,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
}
message->status = status;
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(message);
return status;
}
@@ -470,7 +470,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
if (m->status == -EINPROGRESS)
m->status = ret;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return ret;
}
@@ -432,7 +432,7 @@ static int fsl_spi_do_one_msg(struct spi_master *master,
}
fsl_spi_setup_transfer(spi, NULL);
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return 0;
}
@@ -336,7 +336,7 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
mpc512x_psc_spi_transfer_setup(spi, NULL);
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return status;
}
@@ -293,7 +293,7 @@ static int mt7621_spi_transfer_one_message(struct spi_controller *master,
msg_done:
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return 0;
}
@@ -682,7 +682,7 @@ static int mtk_nor_transfer_one_message(struct spi_controller *master,
m->actual_length = trx_len;
msg_done:
m->status = stat;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return 0;
}
@@ -92,7 +92,7 @@ static void spi_mux_complete_cb(void *context)
m->complete = priv->child_msg_complete;
m->context = priv->child_msg_context;
m->spi = priv->child_msg_dev;
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(m);
mux_control_deselect(priv->mux);
}
@@ -432,7 +432,7 @@ static int mxs_spi_transfer_one(struct spi_master *master,
}
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return status;
}
@@ -335,7 +335,7 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return status;
}
@@ -434,7 +434,7 @@ static int pic32_sqi_one_message(struct spi_master *master,
/* release ring descr */
ring_desc_put(sqi, rdesc);
}
- spi_finalize_current_message(spi->master);
+ spi_finalize_message(msg);
return ret;
}
@@ -474,6 +474,7 @@ static void pl022_cs_control(struct pl022 *pl022, u32 command)
static void giveback(struct pl022 *pl022)
{
struct spi_transfer *last_transfer;
+ struct spi_message *msg;
pl022->next_msg_cs_active = false;
last_transfer = list_last_entry(&pl022->cur_msg->transfers,
@@ -515,6 +516,7 @@ static void giveback(struct pl022 *pl022)
}
+ msg = pl022->cur_msg;
pl022->cur_msg = NULL;
pl022->cur_transfer = NULL;
pl022->cur_chip = NULL;
@@ -523,7 +525,7 @@ static void giveback(struct pl022 *pl022)
writew((readw(SSP_CR1(pl022->virtbase)) &
(~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
- spi_finalize_current_message(pl022->master);
+ spi_finalize_message(msg);
}
/**
@@ -214,7 +214,7 @@ static int sc18is602_transfer_one(struct spi_master *master,
spi_transfer_delay_exec(t);
}
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return status;
}
@@ -204,7 +204,7 @@ static int hspi_transfer_one_message(struct spi_controller *ctlr,
ndelay(nsecs);
hspi_hw_cs_disable(hspi);
}
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(msg);
return ret;
}
@@ -1118,7 +1118,7 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
ret = 0;
exit:
msg->status = ret;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return ret;
}
@@ -351,7 +351,7 @@ static int tegra_sflash_transfer_one_message(struct spi_master *master,
exit:
tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);
msg->status = ret;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return ret;
}
@@ -1289,7 +1289,7 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master,
else
ret = tegra_qspi_non_combined_seq_xfer(tqspi, msg);
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return ret;
}
@@ -718,7 +718,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,
ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(m);
return status;
}
@@ -197,7 +197,7 @@ static int spi_xcomm_transfer_one(struct spi_master *master,
spi_xcomm_chipselect(spi_xcomm, spi, false);
msg->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return status;
}
@@ -1531,7 +1531,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
if (msg->status && ctlr->handle_err)
ctlr->handle_err(ctlr, msg);
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(msg);
return ret;
}
@@ -1676,7 +1676,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
pm_runtime_put(ctlr->dev.parent);
msg->status = ret;
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(msg);
mutex_unlock(&ctlr->io_mutex);
return;
@@ -1691,7 +1691,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
dev_err(&ctlr->dev, "failed to prepare message: %d\n",
ret);
msg->status = ret;
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(msg);
goto out;
}
ctlr->cur_msg_prepared = true;
@@ -1700,7 +1700,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
ret = spi_map_msg(ctlr, msg);
if (ret) {
msg->status = ret;
- spi_finalize_current_message(ctlr);
+ spi_finalize_message(msg);
goto out;
}
@@ -1896,23 +1896,19 @@ struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr)
EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
/**
- * spi_finalize_current_message() - the current message is complete
- * @ctlr: the controller to return the message to
+ * spi_finalize_message() - the current message is complete
+ * @mesg: the message to return to its controller.
*
- * Called by the driver to notify the core that the message in the front of the
- * queue is complete and can be removed from the queue.
+ * Called by the driver to notify the core that this message is complete and
+ * can be removed from the queue if it was a queued message.
*/
-void spi_finalize_current_message(struct spi_controller *ctlr)
+void spi_finalize_message(struct spi_message *mesg)
{
+ struct spi_controller *ctlr = mesg->spi->controller;
struct spi_transfer *xfer;
- struct spi_message *mesg;
unsigned long flags;
int ret;
- spin_lock_irqsave(&ctlr->queue_lock, flags);
- mesg = ctlr->cur_msg;
- spin_unlock_irqrestore(&ctlr->queue_lock, flags);
-
if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) {
list_for_each_entry(xfer, &mesg->transfers, transfer_list) {
ptp_read_system_postts(xfer->ptp_sts);
@@ -1956,7 +1952,7 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
if (mesg->complete)
mesg->complete(mesg->context);
}
-EXPORT_SYMBOL_GPL(spi_finalize_current_message);
+EXPORT_SYMBOL_GPL(spi_finalize_message);
static int spi_start_queue(struct spi_controller *ctlr)
{
@@ -371,7 +371,7 @@ static int gb_spi_transfer_one_message(struct spi_master *master,
out:
msg->status = ret;
clean_xfer_state(spi);
- spi_finalize_current_message(master);
+ spi_finalize_message(msg);
return ret;
}
@@ -394,8 +394,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
* @transfer_one_message: the subsystem calls the driver to transfer a single
* message while queuing transfers that arrive in the meantime. When the
* driver is finished with this message, it must call
- * spi_finalize_current_message() so the subsystem can issue the next
- * message
+ * spi_finalize_message() so the subsystem can issue the next message
* @unprepare_transfer_hardware: there are currently no more messages on the
* queue so the subsystem notifies the driver that it may relax the
* hardware by issuing this call
@@ -706,7 +705,7 @@ extern int spi_controller_resume(struct spi_controller *ctlr);
/* Calls the driver make to interact with the message queue */
extern struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr);
-extern void spi_finalize_current_message(struct spi_controller *ctlr);
+extern void spi_finalize_message(struct spi_message *mesg);
extern void spi_finalize_current_transfer(struct spi_controller *ctlr);
/* Helper calls for driver to timestamp transfer */
This change is necessary in order to prepare the SPI core to optimize different code paths. This function is the only one that requires every SPI message to go through the same message queue, because it relies on ctlr->cur_msg to be the message that has just been transferred. Accessing this queue requires the use of the corresponding spinlocks wherever applicable, which have a sizable performance penalty (see next patch(es)). Forcibly using the queue even for spi_sync also has the drawback that controller tear-down is always bounced to the worker thread, introducing an extra context switch. Signed-off-by: David Jander <david@protonic.nl> --- Documentation/spi/spi-summary.rst | 4 +-- .../media/pci/netup_unidvb/netup_unidvb_spi.c | 2 +- drivers/media/usb/msi2500/msi2500.c | 2 +- drivers/spi/spi-amd.c | 2 +- drivers/spi/spi-ar934x.c | 2 +- drivers/spi/spi-axi-spi-engine.c | 2 +- drivers/spi/spi-bcm63xx-hsspi.c | 2 +- drivers/spi/spi-bcm63xx.c | 2 +- drivers/spi/spi-cavium.c | 2 +- drivers/spi/spi-falcon.c | 2 +- drivers/spi/spi-fsi.c | 2 +- drivers/spi/spi-fsl-dspi.c | 2 +- drivers/spi/spi-fsl-espi.c | 2 +- drivers/spi/spi-fsl-spi.c | 2 +- drivers/spi/spi-mpc512x-psc.c | 2 +- drivers/spi/spi-mt7621.c | 2 +- drivers/spi/spi-mtk-nor.c | 2 +- drivers/spi/spi-mux.c | 2 +- drivers/spi/spi-mxs.c | 2 +- drivers/spi/spi-omap-100k.c | 2 +- drivers/spi/spi-pic32-sqi.c | 2 +- drivers/spi/spi-pl022.c | 4 ++- drivers/spi/spi-sc18is602.c | 2 +- drivers/spi/spi-sh-hspi.c | 2 +- drivers/spi/spi-tegra114.c | 2 +- drivers/spi/spi-tegra20-sflash.c | 2 +- drivers/spi/spi-tegra210-quad.c | 2 +- drivers/spi/spi-ti-qspi.c | 2 +- drivers/spi/spi-xcomm.c | 2 +- drivers/spi/spi.c | 26 ++++++++----------- drivers/staging/greybus/spilib.c | 2 +- include/linux/spi/spi.h | 5 ++-- 32 files changed, 46 insertions(+), 49 deletions(-)