]> Pileus Git - ~andy/linux/blobdiff - drivers/spi/spi-tegra20-slink.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[~andy/linux] / drivers / spi / spi-tegra20-slink.c
index e66715ba37ed680811d7a53eb08e1b66979994c7..be3a069879c3d42bfb482771bc83733318c2273d 100644 (file)
@@ -33,8 +33,8 @@
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/reset.h>
 #include <linux/spi/spi.h>
-#include <linux/clk/tegra.h>
 
 #define SLINK_COMMAND                  0x000
 #define SLINK_BIT_LENGTH(x)            (((x) & 0x1f) << 0)
@@ -167,10 +167,10 @@ struct tegra_slink_data {
        spinlock_t                              lock;
 
        struct clk                              *clk;
+       struct reset_control                    *rst;
        void __iomem                            *base;
        phys_addr_t                             phys;
        unsigned                                irq;
-       int                                     dma_req_sel;
        u32                                     spi_max_frequency;
        u32                                     cur_speed;
 
@@ -196,7 +196,7 @@ struct tegra_slink_data {
        u32                                     rx_status;
        u32                                     status_reg;
        bool                                    is_packed;
-       unsigned long                           packed_size;
+       u32                                     packed_size;
 
        u32                                     command_reg;
        u32                                     command2_reg;
@@ -220,14 +220,14 @@ struct tegra_slink_data {
 static int tegra_slink_runtime_suspend(struct device *dev);
 static int tegra_slink_runtime_resume(struct device *dev);
 
-static inline unsigned long tegra_slink_readl(struct tegra_slink_data *tspi,
+static inline u32 tegra_slink_readl(struct tegra_slink_data *tspi,
                unsigned long reg)
 {
        return readl(tspi->base + reg);
 }
 
 static inline void tegra_slink_writel(struct tegra_slink_data *tspi,
-               unsigned long val, unsigned long reg)
+               u32 val, unsigned long reg)
 {
        writel(val, tspi->base + reg);
 
@@ -238,38 +238,30 @@ static inline void tegra_slink_writel(struct tegra_slink_data *tspi,
 
 static void tegra_slink_clear_status(struct tegra_slink_data *tspi)
 {
-       unsigned long val;
-       unsigned long val_write = 0;
+       u32 val_write;
 
-       val = tegra_slink_readl(tspi, SLINK_STATUS);
+       tegra_slink_readl(tspi, SLINK_STATUS);
 
        /* Write 1 to clear status register */
        val_write = SLINK_RDY | SLINK_FIFO_ERROR;
        tegra_slink_writel(tspi, val_write, SLINK_STATUS);
 }
 
-static unsigned long tegra_slink_get_packed_size(struct tegra_slink_data *tspi,
+static u32 tegra_slink_get_packed_size(struct tegra_slink_data *tspi,
                                  struct spi_transfer *t)
 {
-       unsigned long val;
-
        switch (tspi->bytes_per_word) {
        case 0:
-               val = SLINK_PACK_SIZE_4;
-               break;
+               return SLINK_PACK_SIZE_4;
        case 1:
-               val = SLINK_PACK_SIZE_8;
-               break;
+               return SLINK_PACK_SIZE_8;
        case 2:
-               val = SLINK_PACK_SIZE_16;
-               break;
+               return SLINK_PACK_SIZE_16;
        case 4:
-               val = SLINK_PACK_SIZE_32;
-               break;
+               return SLINK_PACK_SIZE_32;
        default:
-               val = 0;
+               return 0;
        }
-       return val;
 }
 
 static unsigned tegra_slink_calculate_curr_xfer_param(
@@ -312,10 +304,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(
 {
        unsigned nbytes;
        unsigned tx_empty_count;
-       unsigned long fifo_status;
+       u32 fifo_status;
        unsigned max_n_32bit;
        unsigned i, count;
-       unsigned long x;
        unsigned int written_words;
        unsigned fifo_words_left;
        u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos;
@@ -329,9 +320,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(
                nbytes = written_words * tspi->bytes_per_word;
                max_n_32bit = DIV_ROUND_UP(nbytes, 4);
                for (count = 0; count < max_n_32bit; count++) {
-                       x = 0;
+                       u32 x = 0;
                        for (i = 0; (i < 4) && nbytes; i++, nbytes--)
-                               x |= (*tx_buf++) << (i*8);
+                               x |= (u32)(*tx_buf++) << (i * 8);
                        tegra_slink_writel(tspi, x, SLINK_TX_FIFO);
                }
        } else {
@@ -339,10 +330,10 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(
                written_words = max_n_32bit;
                nbytes = written_words * tspi->bytes_per_word;
                for (count = 0; count < max_n_32bit; count++) {
-                       x = 0;
+                       u32 x = 0;
                        for (i = 0; nbytes && (i < tspi->bytes_per_word);
                                                        i++, nbytes--)
-                               x |= ((*tx_buf++) << i*8);
+                               x |= (u32)(*tx_buf++) << (i * 8);
                        tegra_slink_writel(tspi, x, SLINK_TX_FIFO);
                }
        }
@@ -354,9 +345,8 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
                struct tegra_slink_data *tspi, struct spi_transfer *t)
 {
        unsigned rx_full_count;
-       unsigned long fifo_status;
+       u32 fifo_status;
        unsigned i, count;
-       unsigned long x;
        unsigned int read_words = 0;
        unsigned len;
        u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_rx_pos;
@@ -366,7 +356,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
        if (tspi->is_packed) {
                len = tspi->curr_dma_words * tspi->bytes_per_word;
                for (count = 0; count < rx_full_count; count++) {
-                       x = tegra_slink_readl(tspi, SLINK_RX_FIFO);
+                       u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO);
                        for (i = 0; len && (i < 4); i++, len--)
                                *rx_buf++ = (x >> i*8) & 0xFF;
                }
@@ -374,7 +364,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
                read_words += tspi->curr_dma_words;
        } else {
                for (count = 0; count < rx_full_count; count++) {
-                       x = tegra_slink_readl(tspi, SLINK_RX_FIFO);
+                       u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO);
                        for (i = 0; (i < tspi->bytes_per_word); i++)
                                *rx_buf++ = (x >> (i*8)) & 0xFF;
                }
@@ -387,27 +377,24 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
 static void tegra_slink_copy_client_txbuf_to_spi_txbuf(
                struct tegra_slink_data *tspi, struct spi_transfer *t)
 {
-       unsigned len;
-
        /* Make the dma buffer to read by cpu */
        dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys,
                                tspi->dma_buf_size, DMA_TO_DEVICE);
 
        if (tspi->is_packed) {
-               len = tspi->curr_dma_words * tspi->bytes_per_word;
+               unsigned len = tspi->curr_dma_words * tspi->bytes_per_word;
                memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len);
        } else {
                unsigned int i;
                unsigned int count;
                u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos;
                unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word;
-               unsigned int x;
 
                for (count = 0; count < tspi->curr_dma_words; count++) {
-                       x = 0;
+                       u32 x = 0;
                        for (i = 0; consume && (i < tspi->bytes_per_word);
                                                        i++, consume--)
-                               x |= ((*tx_buf++) << i * 8);
+                               x |= (u32)(*tx_buf++) << (i * 8);
                        tspi->tx_dma_buf[count] = x;
                }
        }
@@ -434,14 +421,10 @@ static void tegra_slink_copy_spi_rxbuf_to_client_rxbuf(
                unsigned int i;
                unsigned int count;
                unsigned char *rx_buf = t->rx_buf + tspi->cur_rx_pos;
-               unsigned int x;
-               unsigned int rx_mask, bits_per_word;
+               u32 rx_mask = ((u32)1 << t->bits_per_word) - 1;
 
-               bits_per_word = t->bits_per_word;
-               rx_mask = (1 << bits_per_word) - 1;
                for (count = 0; count < tspi->curr_dma_words; count++) {
-                       x = tspi->rx_dma_buf[count];
-                       x &= rx_mask;
+                       u32 x = tspi->rx_dma_buf[count] & rx_mask;
                        for (i = 0; (i < tspi->bytes_per_word); i++)
                                *rx_buf++ = (x >> (i*8)) & 0xFF;
                }
@@ -501,17 +484,16 @@ static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len)
 static int tegra_slink_start_dma_based_transfer(
                struct tegra_slink_data *tspi, struct spi_transfer *t)
 {
-       unsigned long val;
-       unsigned long test_val;
+       u32 val;
        unsigned int len;
        int ret = 0;
-       unsigned long status;
+       u32 status;
 
        /* Make sure that Rx and Tx fifo are empty */
        status = tegra_slink_readl(tspi, SLINK_STATUS);
        if ((status & SLINK_FIFO_EMPTY) != SLINK_FIFO_EMPTY) {
-               dev_err(tspi->dev,
-                       "Rx/Tx fifo are not empty status 0x%08lx\n", status);
+               dev_err(tspi->dev, "Rx/Tx fifo are not empty status 0x%08x\n",
+                       (unsigned)status);
                return -EIO;
        }
 
@@ -551,9 +533,9 @@ static int tegra_slink_start_dma_based_transfer(
                }
 
                /* Wait for tx fifo to be fill before starting slink */
-               test_val = tegra_slink_readl(tspi, SLINK_STATUS);
-               while (!(test_val & SLINK_TX_FULL))
-                       test_val = tegra_slink_readl(tspi, SLINK_STATUS);
+               status = tegra_slink_readl(tspi, SLINK_STATUS);
+               while (!(status & SLINK_TX_FULL))
+                       status = tegra_slink_readl(tspi, SLINK_STATUS);
        }
 
        if (tspi->cur_direction & DATA_DIR_RX) {
@@ -587,7 +569,7 @@ static int tegra_slink_start_dma_based_transfer(
 static int tegra_slink_start_cpu_based_transfer(
                struct tegra_slink_data *tspi, struct spi_transfer *t)
 {
-       unsigned long val;
+       u32 val;
        unsigned cur_words;
 
        val = tspi->packed_size;
@@ -629,15 +611,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,
        dma_addr_t dma_phys;
        int ret;
        struct dma_slave_config dma_sconfig;
-       dma_cap_mask_t mask;
 
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       dma_chan = dma_request_channel(mask, NULL, NULL);
-       if (!dma_chan) {
-               dev_err(tspi->dev,
-                       "Dma channel is not available, will try later\n");
-               return -EPROBE_DEFER;
+       dma_chan = dma_request_slave_channel_reason(tspi->dev,
+                                               dma_to_memory ? "rx" : "tx");
+       if (IS_ERR(dma_chan)) {
+               ret = PTR_ERR(dma_chan);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(tspi->dev,
+                               "Dma channel is not available: %d\n", ret);
+               return ret;
        }
 
        dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size,
@@ -648,7 +630,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,
                return -ENOMEM;
        }
 
-       dma_sconfig.slave_id = tspi->dma_req_sel;
        if (dma_to_memory) {
                dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO;
                dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -714,8 +695,8 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
        u8 bits_per_word;
        unsigned total_fifo_words;
        int ret;
-       unsigned long command;
-       unsigned long command2;
+       u32 command;
+       u32 command2;
 
        bits_per_word = t->bits_per_word;
        speed = t->speed_hz;
@@ -762,17 +743,18 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
 
 static int tegra_slink_setup(struct spi_device *spi)
 {
-       struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);
-       unsigned long val;
-       unsigned long flags;
-       int ret;
-       unsigned int cs_pol_bit[MAX_CHIP_SELECT] = {
+       static const u32 cs_pol_bit[MAX_CHIP_SELECT] = {
                        SLINK_CS_POLARITY,
                        SLINK_CS_POLARITY1,
                        SLINK_CS_POLARITY2,
                        SLINK_CS_POLARITY3,
        };
 
+       struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);
+       u32 val;
+       unsigned long flags;
+       int ret;
+
        dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n",
                spi->bits_per_word,
                spi->mode & SPI_CPOL ? "" : "~",
@@ -884,9 +866,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)
                dev_err(tspi->dev,
                        "CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,
                                tspi->command2_reg, tspi->dma_control_reg);
-               tegra_periph_reset_assert(tspi->clk);
+               reset_control_assert(tspi->rst);
                udelay(2);
-               tegra_periph_reset_deassert(tspi->clk);
+               reset_control_deassert(tspi->rst);
                complete(&tspi->xfer_completion);
                goto exit;
        }
@@ -957,9 +939,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi)
                dev_err(tspi->dev,
                        "DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg,
                                tspi->command2_reg, tspi->dma_control_reg);
-               tegra_periph_reset_assert(tspi->clk);
+               reset_control_assert(tspi->rst);
                udelay(2);
-               tegra_periph_reset_deassert(tspi->clk);
+               reset_control_assert(tspi->rst);
                complete(&tspi->xfer_completion);
                spin_unlock_irqrestore(&tspi->lock, flags);
                return IRQ_HANDLED;
@@ -1020,11 +1002,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data)
 static void tegra_slink_parse_dt(struct tegra_slink_data *tspi)
 {
        struct device_node *np = tspi->dev->of_node;
-       u32 of_dma[2];
-
-       if (of_property_read_u32_array(np, "nvidia,dma-request-selector",
-                               of_dma, 2) >= 0)
-               tspi->dma_req_sel = of_dma[1];
 
        if (of_property_read_u32(np, "spi-max-frequency",
                                        &tspi->spi_max_frequency))
@@ -1118,25 +1095,25 @@ static int tegra_slink_probe(struct platform_device *pdev)
                goto exit_free_irq;
        }
 
+       tspi->rst = devm_reset_control_get(&pdev->dev, "spi");
+       if (IS_ERR(tspi->rst)) {
+               dev_err(&pdev->dev, "can not get reset\n");
+               ret = PTR_ERR(tspi->rst);
+               goto exit_free_irq;
+       }
+
        tspi->max_buf_size = SLINK_FIFO_DEPTH << 2;
        tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
 
-       if (tspi->dma_req_sel) {
-               ret = tegra_slink_init_dma_param(tspi, true);
-               if (ret < 0) {
-                       dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret);
-                       goto exit_free_irq;
-               }
-
-               ret = tegra_slink_init_dma_param(tspi, false);
-               if (ret < 0) {
-                       dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret);
-                       goto exit_rx_dma_free;
-               }
-               tspi->max_buf_size = tspi->dma_buf_size;
-               init_completion(&tspi->tx_dma_complete);
-               init_completion(&tspi->rx_dma_complete);
-       }
+       ret = tegra_slink_init_dma_param(tspi, true);
+       if (ret < 0)
+               goto exit_free_irq;
+       ret = tegra_slink_init_dma_param(tspi, false);
+       if (ret < 0)
+               goto exit_rx_dma_free;
+       tspi->max_buf_size = tspi->dma_buf_size;
+       init_completion(&tspi->tx_dma_complete);
+       init_completion(&tspi->rx_dma_complete);
 
        init_completion(&tspi->xfer_completion);