]> Pileus Git - ~andy/linux/blobdiff - drivers/spi/spi-atmel.c
Merge remote-tracking branch 'spi/topic/tle62x0' into spi-next
[~andy/linux] / drivers / spi / spi-atmel.c
index 380387a47b1d86fe4e6a8a7ef22a537bfb85517a..fd7cc566095a40cb22d27519726c4faa14a5f37d 100644 (file)
@@ -360,12 +360,12 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
                gpio_set_value(asd->npcs_pin, !active);
 }
 
-static void atmel_spi_lock(struct atmel_spi *as)
+static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock)
 {
        spin_lock_irqsave(&as->lock, as->flags);
 }
 
-static void atmel_spi_unlock(struct atmel_spi *as)
+static void atmel_spi_unlock(struct atmel_spi *as) __releases(&as->lock)
 {
        spin_unlock_irqrestore(&as->lock, as->flags);
 }
@@ -424,10 +424,15 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as,
        return err;
 }
 
-static bool filter(struct dma_chan *chan, void *slave)
+static bool filter(struct dma_chan *chan, void *pdata)
 {
-       struct  at_dma_slave *sl = slave;
+       struct atmel_spi_dma *sl_pdata = pdata;
+       struct at_dma_slave *sl;
 
+       if (!sl_pdata)
+               return false;
+
+       sl = &sl_pdata->dma_slave;
        if (sl->dma_dev == chan->device->dev) {
                chan->private = sl;
                return true;
@@ -438,24 +443,31 @@ static bool filter(struct dma_chan *chan, void *slave)
 
 static int atmel_spi_configure_dma(struct atmel_spi *as)
 {
-       struct at_dma_slave *sdata = &as->dma.dma_slave;
        struct dma_slave_config slave_config;
+       struct device *dev = &as->pdev->dev;
        int err;
 
-       if (sdata && sdata->dma_dev) {
-               dma_cap_mask_t mask;
+       dma_cap_mask_t mask;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
 
-               /* Try to grab two DMA channels */
-               dma_cap_zero(mask);
-               dma_cap_set(DMA_SLAVE, mask);
-               as->dma.chan_tx = dma_request_channel(mask, filter, sdata);
-               if (as->dma.chan_tx)
-                       as->dma.chan_rx =
-                               dma_request_channel(mask, filter, sdata);
+       as->dma.chan_tx = dma_request_slave_channel_compat(mask, filter,
+                                                          &as->dma,
+                                                          dev, "tx");
+       if (!as->dma.chan_tx) {
+               dev_err(dev,
+                       "DMA TX channel not available, SPI unable to use DMA\n");
+               err = -EBUSY;
+               goto error;
        }
-       if (!as->dma.chan_rx || !as->dma.chan_tx) {
-               dev_err(&as->pdev->dev,
-                       "DMA channel not available, SPI unable to use DMA\n");
+
+       as->dma.chan_rx = dma_request_slave_channel_compat(mask, filter,
+                                                          &as->dma,
+                                                          dev, "rx");
+
+       if (!as->dma.chan_rx) {
+               dev_err(dev,
+                       "DMA RX channel not available, SPI unable to use DMA\n");
                err = -EBUSY;
                goto error;
        }
@@ -617,9 +629,9 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
                goto err_dma;
 
        dev_dbg(master->dev.parent,
-               "  start dma xfer %p: len %u tx %p/%08x rx %p/%08x\n",
-               xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
-               xfer->rx_buf, xfer->rx_dma);
+               "  start dma xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
+               xfer, xfer->len, xfer->tx_buf, (unsigned long long)xfer->tx_dma,
+               xfer->rx_buf, (unsigned long long)xfer->rx_dma);
 
        /* Enable relevant interrupts */
        spi_writel(as, IER, SPI_BIT(OVRES));
@@ -720,9 +732,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,
                spi_writel(as, TCR, len);
 
                dev_dbg(&msg->spi->dev,
-                       "  start xfer %p: len %u tx %p/%08x rx %p/%08x\n",
-                       xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
-                       xfer->rx_buf, xfer->rx_dma);
+                       "  start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
+                       xfer, xfer->len, xfer->tx_buf,
+                       (unsigned long long)xfer->tx_dma, xfer->rx_buf,
+                       (unsigned long long)xfer->rx_dma);
        } else {
                xfer = as->next_transfer;
                remaining = as->next_remaining_bytes;
@@ -759,9 +772,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,
                spi_writel(as, TNCR, len);
 
                dev_dbg(&msg->spi->dev,
-                       "  next xfer %p: len %u tx %p/%08x rx %p/%08x\n",
-                       xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
-                       xfer->rx_buf, xfer->rx_dma);
+                       "  next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
+                       xfer, xfer->len, xfer->tx_buf,
+                       (unsigned long long)xfer->tx_dma, xfer->rx_buf,
+                       (unsigned long long)xfer->rx_dma);
                ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES);
        } else {
                spi_writel(as, RNCR, 0);
@@ -1268,13 +1282,6 @@ static int atmel_spi_setup(struct spi_device *spi)
                return -EINVAL;
        }
 
-       if (bits < 8 || bits > 16) {
-               dev_dbg(&spi->dev,
-                               "setup: invalid bits_per_word %u (8 to 16)\n",
-                               bits);
-               return -EINVAL;
-       }
-
        /* see notes above re chipselect */
        if (!atmel_spi_is_v2(as)
                        && spi->chip_select == 0
@@ -1515,7 +1522,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
 
        /* the spi->mode bits understood by this driver: */
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-
+       master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
        master->dev.of_node = pdev->dev.of_node;
        master->bus_num = pdev->id;
        master->num_chipselect = master->dev.of_node ? 0 : 4;
@@ -1574,7 +1581,9 @@ static int atmel_spi_probe(struct platform_device *pdev)
                goto out_unmap_regs;
 
        /* Initialize the hardware */
-       clk_enable(clk);
+       ret = clk_prepare_enable(clk);
+       if (ret)
+               goto out_unmap_regs;
        spi_writel(as, CR, SPI_BIT(SWRST));
        spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
        if (as->caps.has_wdrbt) {
@@ -1604,7 +1613,7 @@ out_free_dma:
 
        spi_writel(as, CR, SPI_BIT(SWRST));
        spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
-       clk_disable(clk);
+       clk_disable_unprepare(clk);
        free_irq(irq, master);
 out_unmap_regs:
        iounmap(as->regs);
@@ -1656,7 +1665,7 @@ static int atmel_spi_remove(struct platform_device *pdev)
        dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
                        as->buffer_dma);
 
-       clk_disable(as->clk);
+       clk_disable_unprepare(as->clk);
        clk_put(as->clk);
        free_irq(as->irq, master);
        iounmap(as->regs);
@@ -1673,7 +1682,7 @@ static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg)
        struct spi_master       *master = platform_get_drvdata(pdev);
        struct atmel_spi        *as = spi_master_get_devdata(master);
 
-       clk_disable(as->clk);
+       clk_disable_unprepare(as->clk);
        return 0;
 }
 
@@ -1682,7 +1691,7 @@ static int atmel_spi_resume(struct platform_device *pdev)
        struct spi_master       *master = platform_get_drvdata(pdev);
        struct atmel_spi        *as = spi_master_get_devdata(master);
 
-       clk_enable(as->clk);
+       return clk_prepare_enable(as->clk);
        return 0;
 }