From 1adf51702e94063fb058ce13226ec5a04d15cfd4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 13 Mar 2017 13:30:10 +0100 Subject: ipq806x: clean up patches, port missing patches from 4.4 Signed-off-by: John Crispin Signed-off-by: Felix Fietkau --- ...factor-spi_qup_io_config-in-two-functions.patch | 202 +++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 target/linux/ipq806x/patches-4.9/0009-spi-qup-refactor-spi_qup_io_config-in-two-functions.patch (limited to 'target/linux/ipq806x/patches-4.9/0009-spi-qup-refactor-spi_qup_io_config-in-two-functions.patch') diff --git a/target/linux/ipq806x/patches-4.9/0009-spi-qup-refactor-spi_qup_io_config-in-two-functions.patch b/target/linux/ipq806x/patches-4.9/0009-spi-qup-refactor-spi_qup_io_config-in-two-functions.patch new file mode 100644 index 0000000000..36c225badc --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/0009-spi-qup-refactor-spi_qup_io_config-in-two-functions.patch @@ -0,0 +1,202 @@ +From e06f04d55752e460d8f332f28317aebc27ab1b17 Mon Sep 17 00:00:00 2001 +From: Matthew McClintock +Date: Tue, 26 Apr 2016 12:57:46 -0500 +Subject: [PATCH 09/69] spi: qup: refactor spi_qup_io_config in two functions + +This is preparation for handling transactions larger than 64K-1 bytes in +block mode which is currently unsupported quietly fails. + +We need to break these into two functions 1) prep is called once per +spi_message and 2) io_config is calle once per spi-qup bus transaction + +This is just refactoring, there should be no functional change + +Signed-off-by: Matthew McClintock +--- + drivers/spi/spi-qup.c | 141 ++++++++++++++++++++++++++++++-------------------- + 1 file changed, 86 insertions(+), 55 deletions(-) + +--- a/drivers/spi/spi-qup.c ++++ b/drivers/spi/spi-qup.c +@@ -585,12 +585,11 @@ static irqreturn_t spi_qup_qup_irq(int i + return IRQ_HANDLED; + } + +-/* set clock freq ... bits per word */ +-static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) ++/* set clock freq ... bits per word, determine mode */ ++static int spi_qup_io_prep(struct spi_device *spi, struct spi_transfer *xfer) + { + struct spi_qup *controller = spi_master_get_devdata(spi->master); +- u32 config, iomode, control; +- int ret, n_words; ++ int ret; + + if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) { + dev_err(controller->dev, "too big size for loopback %d > %d\n", +@@ -605,56 +604,94 @@ static int spi_qup_io_config(struct spi_ + return -EIO; + } + +- if (spi_qup_set_state(controller, QUP_STATE_RESET)) { +- dev_err(controller->dev, "cannot set RESET state\n"); +- return -EIO; +- } +- + controller->w_size = DIV_ROUND_UP(xfer->bits_per_word, 8); + controller->n_words = xfer->len / controller->w_size; +- n_words = controller->n_words; + +- if (n_words <= (controller->in_fifo_sz / sizeof(u32))) { ++ if (controller->n_words <= (controller->in_fifo_sz / sizeof(u32))) + controller->mode = QUP_IO_M_MODE_FIFO; +- writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT); +- writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT); +- /* must be zero for FIFO */ +- writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT); +- writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); +- } else if (spi->master->can_dma && +- spi->master->can_dma(spi->master, spi, xfer) && +- spi->master->cur_msg_mapped) { ++ else if (spi->master->can_dma && ++ spi->master->can_dma(spi->master, spi, xfer) && ++ spi->master->cur_msg_mapped) + controller->mode = QUP_IO_M_MODE_BAM; +- writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); +- writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); +- /* must be zero for BLOCK and BAM */ +- writel_relaxed(0, controller->base + QUP_MX_READ_CNT); +- writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); +- +- if (!controller->qup_v1) { +- void __iomem *input_cnt; +- +- input_cnt = controller->base + QUP_MX_INPUT_CNT; +- /* +- * for DMA transfers, both QUP_MX_INPUT_CNT and +- * QUP_MX_OUTPUT_CNT must be zero to all cases but one. +- * That case is a non-balanced transfer when there is +- * only a rx_buf. +- */ +- if (xfer->tx_buf) +- writel_relaxed(0, input_cnt); +- else +- writel_relaxed(n_words, input_cnt); ++ else ++ controller->mode = QUP_IO_M_MODE_BLOCK; ++ ++ return 0; ++} + ++/* prep qup for another spi transaction of specific type */ ++static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) ++{ ++ struct spi_qup *controller = spi_master_get_devdata(spi->master); ++ u32 config, iomode, control; ++ unsigned long flags; ++ ++ reinit_completion(&controller->done); ++ reinit_completion(&controller->dma_tx_done); ++ ++ spin_lock_irqsave(&controller->lock, flags); ++ controller->xfer = xfer; ++ controller->error = 0; ++ controller->rx_bytes = 0; ++ controller->tx_bytes = 0; ++ spin_unlock_irqrestore(&controller->lock, flags); ++ ++ ++ if (spi_qup_set_state(controller, QUP_STATE_RESET)) { ++ dev_err(controller->dev, "cannot set RESET state\n"); ++ return -EIO; ++ } ++ ++ switch (controller->mode) { ++ case QUP_IO_M_MODE_FIFO: ++ writel_relaxed(controller->n_words, ++ controller->base + QUP_MX_READ_CNT); ++ writel_relaxed(controller->n_words, ++ controller->base + QUP_MX_WRITE_CNT); ++ /* must be zero for FIFO */ ++ writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT); + writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); +- } +- } else { +- controller->mode = QUP_IO_M_MODE_BLOCK; +- writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); +- writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); +- /* must be zero for BLOCK and BAM */ +- writel_relaxed(0, controller->base + QUP_MX_READ_CNT); +- writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); ++ break; ++ case QUP_IO_M_MODE_BAM: ++ writel_relaxed(controller->n_words, ++ controller->base + QUP_MX_INPUT_CNT); ++ writel_relaxed(controller->n_words, ++ controller->base + QUP_MX_OUTPUT_CNT); ++ /* must be zero for BLOCK and BAM */ ++ writel_relaxed(0, controller->base + QUP_MX_READ_CNT); ++ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); ++ if (!controller->qup_v1) { ++ void __iomem *input_cnt; ++ ++ input_cnt = controller->base + QUP_MX_INPUT_CNT; ++ /* ++ * for DMA transfers, both QUP_MX_INPUT_CNT and ++ * QUP_MX_OUTPUT_CNT must be zero to all cases ++ * but one. That case is a non-balanced ++ * transfer when there is only a rx_buf. ++ */ ++ if (xfer->tx_buf) ++ writel_relaxed(0, input_cnt); ++ else ++ writel_relaxed(controller->n_words, ++ input_cnt); ++ ++ writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); ++ } ++ break; ++ case QUP_IO_M_MODE_BLOCK: ++ writel_relaxed(controller->n_words, ++ controller->base + QUP_MX_INPUT_CNT); ++ writel_relaxed(controller->n_words, ++ controller->base + QUP_MX_OUTPUT_CNT); ++ /* must be zero for BLOCK and BAM */ ++ writel_relaxed(0, controller->base + QUP_MX_READ_CNT); ++ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); ++ break; ++ default: ++ dev_err(controller->dev, "unknown mode = %d\n", ++ controller->mode); ++ return -EIO; + } + + iomode = readl_relaxed(controller->base + QUP_IO_M_MODES); +@@ -743,6 +780,10 @@ static int spi_qup_transfer_one(struct s + unsigned long timeout, flags; + int ret = -EIO; + ++ ret = spi_qup_io_prep(spi, xfer); ++ if (ret) ++ return ret; ++ + ret = spi_qup_io_config(spi, xfer); + if (ret) + return ret; +@@ -751,16 +792,6 @@ static int spi_qup_transfer_one(struct s + timeout = DIV_ROUND_UP(xfer->len * 8, timeout); + timeout = 100 * msecs_to_jiffies(timeout); + +- reinit_completion(&controller->done); +- reinit_completion(&controller->dma_tx_done); +- +- spin_lock_irqsave(&controller->lock, flags); +- controller->xfer = xfer; +- controller->error = 0; +- controller->rx_bytes = 0; +- controller->tx_bytes = 0; +- spin_unlock_irqrestore(&controller->lock, flags); +- + if (spi_qup_is_dma_xfer(controller->mode)) + ret = spi_qup_do_dma(master, xfer, timeout); + else -- cgit v1.2.3