]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branches 'spi/fix/au1550', 'spi/fix/davinci', 'spi/fix/doc...
authorMark Brown <broonie@kernel.org>
Sat, 30 Aug 2014 18:28:04 +0000 (19:28 +0100)
committerMark Brown <broonie@kernel.org>
Sat, 30 Aug 2014 18:28:04 +0000 (19:28 +0100)
drivers/spi/spi-au1550.c
drivers/spi/spi-davinci.c
drivers/spi/spi-dw-pci.c
drivers/spi/spi-dw.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-rockchip.c
drivers/spi/spi-rspi.c
drivers/spi/spi.c
include/linux/spi/spi.h

index 40c3d43c9292ddd58e1b3f278a4d8b821a86d6f3..f40b34cdf2fc433ddb9722238cc80004efec52bf 100644 (file)
@@ -945,7 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev)
        spi_bitbang_stop(&hw->bitbang);
        free_irq(hw->irq, hw);
        iounmap((void __iomem *)hw->regs);
-       release_mem_region(r->start, sizeof(psc_spi_t));
+       release_mem_region(hw->ioarea->start, sizeof(psc_spi_t));
 
        if (hw->usedma) {
                au1550_spi_dma_rxtmp_free(hw);
index 276a3884fb3c1d43c928b0b975b8d7aa67f6be58..48f1d26e6ad9868f9ac8c8e11fb0953e90f707da 100644 (file)
@@ -417,16 +417,16 @@ static int davinci_spi_setup(struct spi_device *spi)
                                                  flags, dev_name(&spi->dev));
                        internal_cs = false;
                }
-       }
 
-       if (retval) {
-               dev_err(&spi->dev, "GPIO %d setup failed (%d)\n",
-                       spi->cs_gpio, retval);
-               return retval;
-       }
+               if (retval) {
+                       dev_err(&spi->dev, "GPIO %d setup failed (%d)\n",
+                               spi->cs_gpio, retval);
+                       return retval;
+               }
 
-       if (internal_cs)
-               set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select);
+               if (internal_cs)
+                       set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select);
+       }
 
        if (spi->mode & SPI_READY)
                set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK);
index 3f3dc1226edf19aefad97630e2112287f419cabc..e14960470d8d46a96eef045f612cc4bd23c1a7cb 100644 (file)
@@ -62,6 +62,8 @@ static int spi_pci_probe(struct pci_dev *pdev,
        if (ret)
                return ret;
 
+       dws->regs = pcim_iomap_table(pdev)[pci_bar];
+
        dws->bus_num = 0;
        dws->num_cs = 4;
        dws->irq = pdev->irq;
index 29f33143b795651e773ea7b9d5cc0f80c7cb2575..670f0627f3bfc793092495be55f3d6fd9854dd34 100644 (file)
@@ -271,7 +271,7 @@ static void giveback(struct dw_spi *dws)
                                        transfer_list);
 
        if (!last_transfer->cs_change)
-               spi_chip_sel(dws, dws->cur_msg->spi, 0);
+               spi_chip_sel(dws, msg->spi, 0);
 
        spi_finalize_current_message(dws->master);
 }
index 68441fa448de46323192325154c930afe191f3ab..352eed7463aca0dc23d104178538236f5534257c 100644 (file)
@@ -329,7 +329,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 disable_fifo:
        if (t->rx_buf != NULL)
                chconf &= ~OMAP2_MCSPI_CHCONF_FFER;
-       else
+
+       if (t->tx_buf != NULL)
                chconf &= ~OMAP2_MCSPI_CHCONF_FFET;
 
        mcspi_write_chconf0(spi, chconf);
index fe792106bdc5e65df920368eb495d14fab826841..46f45ca2c69400888de13f390decbf09a30f27d1 100644 (file)
@@ -1074,6 +1074,7 @@ static struct acpi_device_id pxa2xx_spi_acpi_match[] = {
        { "INT3430", 0 },
        { "INT3431", 0 },
        { "80860F0E", 0 },
+       { "8086228E", 0 },
        { },
 };
 MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match);
index c0743604b906c749b62d1fedaaa8f3250b70c0c9..cd0e08b0c9f66c7d99d1421e8fdbf882f62f7e77 100644 (file)
@@ -499,7 +499,7 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
        }
 
        /* div doesn't support odd number */
-       div = rs->max_freq / rs->speed;
+       div = max_t(u32, rs->max_freq / rs->speed, 1);
        div = (div + 1) & 0xfffe;
 
        spi_enable_chip(rs, 0);
@@ -678,7 +678,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
                rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR);
                rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR);
                rs->dma_tx.direction = DMA_MEM_TO_DEV;
-               rs->dma_tx.direction = DMA_DEV_TO_MEM;
+               rs->dma_rx.direction = DMA_DEV_TO_MEM;
 
                master->can_dma = rockchip_spi_can_dma;
                master->dma_tx = rs->dma_tx.ch;
index c850dfdfa9e32712136ed7515f1440dbe7906805..ad87a98f8f68f48f4191bac3f2202c45eb26dadf 100644 (file)
@@ -472,25 +472,52 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
        dma_cookie_t cookie;
        int ret;
 
-       if (tx) {
-               desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx,
-                                       tx->sgl, tx->nents, DMA_TO_DEVICE,
-                                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-               if (!desc_tx)
-                       goto no_dma;
-
-               irq_mask |= SPCR_SPTIE;
-       }
+       /* First prepare and submit the DMA request(s), as this may fail */
        if (rx) {
                desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx,
                                        rx->sgl, rx->nents, DMA_FROM_DEVICE,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-               if (!desc_rx)
-                       goto no_dma;
+               if (!desc_rx) {
+                       ret = -EAGAIN;
+                       goto no_dma_rx;
+               }
+
+               desc_rx->callback = rspi_dma_complete;
+               desc_rx->callback_param = rspi;
+               cookie = dmaengine_submit(desc_rx);
+               if (dma_submit_error(cookie)) {
+                       ret = cookie;
+                       goto no_dma_rx;
+               }
 
                irq_mask |= SPCR_SPRIE;
        }
 
+       if (tx) {
+               desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx,
+                                       tx->sgl, tx->nents, DMA_TO_DEVICE,
+                                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (!desc_tx) {
+                       ret = -EAGAIN;
+                       goto no_dma_tx;
+               }
+
+               if (rx) {
+                       /* No callback */
+                       desc_tx->callback = NULL;
+               } else {
+                       desc_tx->callback = rspi_dma_complete;
+                       desc_tx->callback_param = rspi;
+               }
+               cookie = dmaengine_submit(desc_tx);
+               if (dma_submit_error(cookie)) {
+                       ret = cookie;
+                       goto no_dma_tx;
+               }
+
+               irq_mask |= SPCR_SPTIE;
+       }
+
        /*
         * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be
         * called. So, this driver disables the IRQ while DMA transfer.
@@ -503,34 +530,24 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
        rspi_enable_irq(rspi, irq_mask);
        rspi->dma_callbacked = 0;
 
-       if (rx) {
-               desc_rx->callback = rspi_dma_complete;
-               desc_rx->callback_param = rspi;
-               cookie = dmaengine_submit(desc_rx);
-               if (dma_submit_error(cookie))
-                       return cookie;
+       /* Now start DMA */
+       if (rx)
                dma_async_issue_pending(rspi->master->dma_rx);
-       }
-       if (tx) {
-               if (rx) {
-                       /* No callback */
-                       desc_tx->callback = NULL;
-               } else {
-                       desc_tx->callback = rspi_dma_complete;
-                       desc_tx->callback_param = rspi;
-               }
-               cookie = dmaengine_submit(desc_tx);
-               if (dma_submit_error(cookie))
-                       return cookie;
+       if (tx)
                dma_async_issue_pending(rspi->master->dma_tx);
-       }
 
        ret = wait_event_interruptible_timeout(rspi->wait,
                                               rspi->dma_callbacked, HZ);
        if (ret > 0 && rspi->dma_callbacked)
                ret = 0;
-       else if (!ret)
+       else if (!ret) {
+               dev_err(&rspi->master->dev, "DMA timeout\n");
                ret = -ETIMEDOUT;
+               if (tx)
+                       dmaengine_terminate_all(rspi->master->dma_tx);
+               if (rx)
+                       dmaengine_terminate_all(rspi->master->dma_rx);
+       }
 
        rspi_disable_irq(rspi, irq_mask);
 
@@ -541,11 +558,16 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
 
        return ret;
 
-no_dma:
-       pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
-                    dev_driver_string(&rspi->master->dev),
-                    dev_name(&rspi->master->dev));
-       return -EAGAIN;
+no_dma_tx:
+       if (rx)
+               dmaengine_terminate_all(rspi->master->dma_rx);
+no_dma_rx:
+       if (ret == -EAGAIN) {
+               pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
+                            dev_driver_string(&rspi->master->dev),
+                            dev_name(&rspi->master->dev));
+       }
+       return ret;
 }
 
 static void rspi_receive_init(const struct rspi_data *rspi)
index e0531baf2782ae78f086db7af5201fcaef4bc92a..ca935df80c88e98b7ae2e8ddbd24cf87c54f55ef 100644 (file)
@@ -848,6 +848,7 @@ out:
 
 /**
  * spi_finalize_current_transfer - report completion of a transfer
+ * @master: the master reporting completion
  *
  * Called by SPI drivers using the core transfer_one_message()
  * implementation to notify it that the current interrupt driven
index e713543336f12a972e3eaa200f9c73a42920ba97..46d188a9947c6401bfa91f7f32802c8d4707c025 100644 (file)
@@ -253,6 +253,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  *     the device whose settings are being modified.
  * @transfer: adds a message to the controller's transfer queue.
  * @cleanup: frees controller-specific state
+ * @can_dma: determine whether this master supports DMA
  * @queued: whether this master is providing an internal message queue
  * @kworker: thread struct for message pump
  * @kworker_task: pointer to task for message pump kworker thread
@@ -262,6 +263,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @cur_msg: the currently in-flight message
  * @cur_msg_prepared: spi_prepare_message was called for the currently
  *                    in-flight message
+ * @cur_msg_mapped: message has been mapped for DMA
  * @xfer_completion: used by core transfer_one_message()
  * @busy: message pump is busy
  * @running: message pump is running
@@ -299,6 +301,10 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *     number. Any individual value may be -ENOENT for CS lines that
  *     are not GPIOs (driven by the SPI controller itself).
+ * @dma_tx: DMA transmit channel
+ * @dma_rx: DMA receive channel
+ * @dummy_rx: dummy receive buffer for full-duplex devices
+ * @dummy_tx: dummy transmit buffer for full-duplex devices
  *
  * Each SPI master controller can communicate with one or more @spi_device
  * children.  These make a small bus, sharing MOSI, MISO and SCK signals
@@ -632,6 +638,7 @@ struct spi_transfer {
  *     addresses for each transfer buffer
  * @complete: called to report transaction completions
  * @context: the argument to complete() when it's called
+ * @frame_length: the total number of bytes in the message
  * @actual_length: the total number of bytes that were transferred in all
  *     successful segments
  * @status: zero for success, else negative errno