]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
spi: axi-spi-engine: use message_prepare/unprepare
authorDavid Lechner <dlechner@baylibre.com>
Fri, 17 Nov 2023 20:13:01 +0000 (14:13 -0600)
committerMark Brown <broonie@kernel.org>
Mon, 20 Nov 2023 13:29:12 +0000 (13:29 +0000)
This modifies the AXI SPI Engine driver to make use of the
message_prepare and message_unprepare callbacks. This separates
the concerns of allocating and freeing the message state from the
transfer_one_message callback.

The main benfit of this is so that future callers of
spi_finalize_current_message() will not have to do manual cleanup
of the state.

Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://lore.kernel.org/r/20231117-axi-spi-engine-series-1-v1-10-cc59db999b87@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-axi-spi-engine.c

index 745000a9b2c73ff9b02e2c18ac685b3f225a9ed5..210bea23f433f323609c665949f77409912bfdce 100644 (file)
@@ -412,11 +412,7 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
 
                if (spi_engine->completed_id == st->sync_id) {
                        struct spi_message *msg = spi_engine->msg;
-                       struct spi_engine_message_state *st = msg->state;
 
-                       ida_free(&spi_engine->sync_ida, st->sync_id);
-                       kfree(st->p);
-                       kfree(st);
                        msg->status = 0;
                        msg->actual_length = msg->frame_length;
                        spi_engine->msg = NULL;
@@ -436,14 +432,12 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
        return IRQ_HANDLED;
 }
 
-static int spi_engine_transfer_one_message(struct spi_controller *host,
-       struct spi_message *msg)
+static int spi_engine_prepare_message(struct spi_controller *host,
+                                     struct spi_message *msg)
 {
        struct spi_engine_program p_dry, *p;
        struct spi_engine *spi_engine = spi_controller_get_devdata(host);
        struct spi_engine_message_state *st;
-       unsigned int int_enable = 0;
-       unsigned long flags;
        size_t size;
        int ret;
 
@@ -472,15 +466,41 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
 
        spi_engine_compile_message(spi_engine, msg, false, p);
 
-       spin_lock_irqsave(&spi_engine->lock, flags);
        spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC(st->sync_id));
 
-       msg->state = st;
-       spi_engine->msg = msg;
        st->p = p;
-
        st->cmd_buf = p->instructions;
        st->cmd_length = p->length;
+       msg->state = st;
+
+       return 0;
+}
+
+static int spi_engine_unprepare_message(struct spi_controller *host,
+                                       struct spi_message *msg)
+{
+       struct spi_engine *spi_engine = spi_controller_get_devdata(host);
+       struct spi_engine_message_state *st = msg->state;
+
+       ida_free(&spi_engine->sync_ida, st->sync_id);
+       kfree(st->p);
+       kfree(st);
+
+       return 0;
+}
+
+static int spi_engine_transfer_one_message(struct spi_controller *host,
+       struct spi_message *msg)
+{
+       struct spi_engine *spi_engine = spi_controller_get_devdata(host);
+       struct spi_engine_message_state *st = msg->state;
+       unsigned int int_enable = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&spi_engine->lock, flags);
+
+       spi_engine->msg = msg;
+
        if (spi_engine_write_cmd_fifo(spi_engine))
                int_enable |= SPI_ENGINE_INT_CMD_ALMOST_EMPTY;
 
@@ -572,6 +592,8 @@ static int spi_engine_probe(struct platform_device *pdev)
        host->bits_per_word_mask = SPI_BPW_MASK(8);
        host->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
        host->transfer_one_message = spi_engine_transfer_one_message;
+       host->prepare_message = spi_engine_prepare_message;
+       host->unprepare_message = spi_engine_unprepare_message;
        host->num_chipselect = 8;
 
        if (host->max_speed_hz == 0)