]> git.karo-electronics.de Git - linux-beck.git/commitdiff
spi: rspi: Use core message handling
authorGeert Uytterhoeven <geert+renesas@linux-m68k.org>
Fri, 24 Jan 2014 08:43:52 +0000 (09:43 +0100)
committerMark Brown <broonie@linaro.org>
Mon, 27 Jan 2014 20:02:09 +0000 (20:02 +0000)
Let the generic SPI core handle SPI messages, calling into our
rspi_transfer_one() method.

rspi_assert_ssl() and rspi_negate_ssl() are absorbed into
rspi_prepare_message() and rspi_unprepare_message(), as they actually
enable/disable the whole SPI function, instead of just (de)asserting the
chip select line.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
drivers/spi/spi-rspi.c

index ccd5cf201d04b173252f2456661f982abd5af95f..0e4d169c90d7045268dbf3abe56cf87f90d34b6d 100644 (file)
@@ -25,8 +25,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -181,10 +179,7 @@ struct rspi_data {
        void __iomem *addr;
        u32 max_speed_hz;
        struct spi_master *master;
-       struct list_head queue;
-       struct work_struct ws;
        wait_queue_head_t wait;
-       spinlock_t lock;
        struct clk *clk;
        u8 spsr;
        u16 spcmd;
@@ -345,16 +340,6 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
        return 0;
 }
 
-static void rspi_assert_ssl(const struct rspi_data *rspi)
-{
-       rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
-}
-
-static void rspi_negate_ssl(const struct rspi_data *rspi)
-{
-       rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
-}
-
 static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
        int remain = t->len;
@@ -739,56 +724,27 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t)
        return 0;
 }
 
-static void rspi_work(struct work_struct *work)
+static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+                            struct spi_transfer *xfer)
 {
-       struct rspi_data *rspi = container_of(work, struct rspi_data, ws);
-       struct spi_message *mesg;
-       struct spi_transfer *t;
-       unsigned long flags;
-       int ret;
-
-       while (1) {
-               spin_lock_irqsave(&rspi->lock, flags);
-               if (list_empty(&rspi->queue)) {
-                       spin_unlock_irqrestore(&rspi->lock, flags);
-                       break;
-               }
-               mesg = list_entry(rspi->queue.next, struct spi_message, queue);
-               list_del_init(&mesg->queue);
-               spin_unlock_irqrestore(&rspi->lock, flags);
-
-               rspi_assert_ssl(rspi);
-
-               list_for_each_entry(t, &mesg->transfers, transfer_list) {
-                       if (t->tx_buf) {
-                               if (rspi_is_dma(rspi, t))
-                                       ret = rspi_send_dma(rspi, t);
-                               else
-                                       ret = send_pio(rspi, t);
-                               if (ret < 0)
-                                       goto error;
-                       }
-                       if (t->rx_buf) {
-                               if (rspi_is_dma(rspi, t))
-                                       ret = rspi_receive_dma(rspi, t);
-                               else
-                                       ret = receive_pio(rspi, t);
-                               if (ret < 0)
-                                       goto error;
-                       }
-                       mesg->actual_length += t->len;
-               }
-               rspi_negate_ssl(rspi);
+       struct rspi_data *rspi = spi_master_get_devdata(master);
+       int ret = 0;
 
-               mesg->status = 0;
-               mesg->complete(mesg->context);
+       if (xfer->tx_buf) {
+               if (rspi_is_dma(rspi, xfer))
+                       ret = rspi_send_dma(rspi, xfer);
+               else
+                       ret = send_pio(rspi, xfer);
+               if (ret < 0)
+                       return ret;
        }
-
-       return;
-
-error:
-       mesg->status = ret;
-       mesg->complete(mesg->context);
+       if (xfer->rx_buf) {
+               if (rspi_is_dma(rspi, xfer))
+                       ret = rspi_receive_dma(rspi, xfer);
+               else
+                       ret = receive_pio(rspi, xfer);
+       }
+       return ret;
 }
 
 static int rspi_setup(struct spi_device *spi)
@@ -808,24 +764,26 @@ static int rspi_setup(struct spi_device *spi)
        return 0;
 }
 
-static int rspi_transfer(struct spi_device *spi, struct spi_message *mesg)
+static void rspi_cleanup(struct spi_device *spi)
 {
-       struct rspi_data *rspi = spi_master_get_devdata(spi->master);
-       unsigned long flags;
-
-       mesg->actual_length = 0;
-       mesg->status = -EINPROGRESS;
+}
 
-       spin_lock_irqsave(&rspi->lock, flags);
-       list_add_tail(&mesg->queue, &rspi->queue);
-       schedule_work(&rspi->ws);
-       spin_unlock_irqrestore(&rspi->lock, flags);
+static int rspi_prepare_message(struct spi_master *master,
+                               struct spi_message *message)
+{
+       struct rspi_data *rspi = spi_master_get_devdata(master);
 
+       rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
        return 0;
 }
 
-static void rspi_cleanup(struct spi_device *spi)
+static int rspi_unprepare_message(struct spi_master *master,
+                                 struct spi_message *message)
 {
+       struct rspi_data *rspi = spi_master_get_devdata(master);
+
+       rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+       return 0;
 }
 
 static irqreturn_t rspi_irq(int irq, void *_sr)
@@ -972,9 +930,6 @@ static int rspi_probe(struct platform_device *pdev)
        }
        clk_enable(rspi->clk);
 
-       INIT_LIST_HEAD(&rspi->queue);
-       spin_lock_init(&rspi->lock);
-       INIT_WORK(&rspi->ws, rspi_work);
        init_waitqueue_head(&rspi->wait);
 
        if (rspi_pd && rspi_pd->num_chipselect)
@@ -984,8 +939,10 @@ static int rspi_probe(struct platform_device *pdev)
 
        master->bus_num = pdev->id;
        master->setup = rspi_setup;
-       master->transfer = rspi_transfer;
+       master->transfer_one = rspi_transfer_one;
        master->cleanup = rspi_cleanup;
+       master->prepare_message = rspi_prepare_message;
+       master->unprepare_message = rspi_unprepare_message;
        master->mode_bits = SPI_CPHA | SPI_CPOL;
 
        ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,