- int idx, shift, w_size;
-
- w_size = controller->w_size;
+-
+- while (controller->rx_bytes < xfer->len) {
+ int i, shift, num_bytes;
+ u32 word;
-- while (controller->rx_bytes < xfer->len) {
--
- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
- if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
- break;
- int idx, w_size;
+ u32 remainder, words_per_block, num_words;
+ bool is_block_mode = controller->mode == QUP_IO_M_MODE_BLOCK;
-+
+
+- w_size = controller->w_size;
+ remainder = DIV_ROUND_UP(xfer->len - controller->rx_bytes,
+ controller->w_size);
+ words_per_block = controller->in_blk_sz >> 2;
-+
+
+- while (controller->tx_bytes < xfer->len) {
+ do {
+ /* ACK by clearing service flag */
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
+ controller->base + QUP_OPERATIONAL);
-+
+
+- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
+- if (state & QUP_OP_OUT_FIFO_FULL)
+ if (is_block_mode) {
+ num_words = (remainder > words_per_block) ?
+ words_per_block : remainder;
+ if (!spi_qup_is_flag_set(controller,
+ QUP_OP_IN_FIFO_NOT_EMPTY))
+ break;
-
-- w_size = controller->w_size;
++
+ num_words = 1;
+ }
+
+ /* read up to the maximum transfer size available */
+ spi_qup_read_from_fifo(controller, xfer, num_words);
-
-- while (controller->tx_bytes < xfer->len) {
++
+ remainder -= num_words;
-
-- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
-- if (state & QUP_OP_OUT_FIFO_FULL)
++
+ /* if block mode, check to see if next block is available */
+ if (is_block_mode && !spi_qup_is_flag_set(controller,
+ QUP_OP_IN_BLOCK_READ_REQ))
- /* 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);
--
++ else
++ controller->mode = QUP_IO_M_MODE_BLOCK;
+
- if (!controller->qup_v1) {
- void __iomem *input_cnt;
--
++ return 0;
++}
+
- input_cnt = controller->base + QUP_MX_INPUT_CNT;
- /*
- * for DMA transfers, both QUP_MX_INPUT_CNT and
- 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);
+
+ qup->n_words = SPI_MAX_XFER;
+ else
+ qup->n_words = n_words % SPI_MAX_XFER;
-+
+
+- if (qup->mode == QUP_IO_M_MODE_FIFO)
+- spi_qup_write(qup, xfer);
+ if (qup->tx_buf && offset)
+ qup->tx_buf = xfer->tx_buf + offset * SPI_MAX_XFER;
-+
+
+- ret = spi_qup_set_state(qup, QUP_STATE_RUN);
+- if (ret) {
+- dev_warn(qup->dev, "cannot set RUN state\n");
+- return ret;
+- }
+ if (qup->rx_buf && offset)
+ qup->rx_buf = xfer->rx_buf + offset * SPI_MAX_XFER;
-+
+
+- if (!wait_for_completion_timeout(&qup->done, timeout))
+- return -ETIMEDOUT;
+ /* if the transaction is small enough, we need
+ * to fallback to FIFO mode */
+ if (qup->n_words <= (qup->in_fifo_sz / sizeof(u32)))
+ qup->mode = QUP_IO_M_MODE_FIFO;
-
-- if (qup->mode == QUP_IO_M_MODE_FIFO)
-- spi_qup_write(qup, xfer);
++
+ ret = spi_qup_io_config(spi, xfer);
+ if (ret)
+ return ret;
-
-- ret = spi_qup_set_state(qup, QUP_STATE_RUN);
-- if (ret) {
-- dev_warn(qup->dev, "cannot set RUN state\n");
-- return ret;
-- }
++
+ ret = spi_qup_set_state(qup, QUP_STATE_RUN);
+ if (ret) {
+ dev_warn(qup->dev, "cannot set RUN state\n");
+ return ret;
+ }
-
-- if (!wait_for_completion_timeout(&qup->done, timeout))
-- return -ETIMEDOUT;
++
+ ret = spi_qup_set_state(qup, QUP_STATE_PAUSE);
+ if (ret) {
+ dev_warn(qup->dev, "cannot set PAUSE state\n");
- ret = spi_qup_io_config(spi, xfer);
- if (ret)
- return ret;
--
++ rx_sgl = xfer->rx_sg.sgl;
++ tx_sgl = xfer->tx_sg.sgl;
+
- /* before issuing the descriptors, set the QUP to run */
- ret = spi_qup_set_state(qup, QUP_STATE_RUN);
- if (ret) {
- dev_warn(qup->dev, "cannot set RUN state\n");
- return ret;
- }
--
++ do {
++ int rx_nents = 0, tx_nents = 0;
+
- if (!qup->qup_v1) {
- if (xfer->rx_buf)
- rx_done = spi_qup_dma_done;
--
++ if (rx_sgl) {
++ rx_nents = sg_nents_for_len(rx_sgl, SPI_MAX_XFER);
++ if (rx_nents < 0)
++ rx_nents = sg_nents(rx_sgl);
+
- if (xfer->tx_buf)
- tx_done = spi_qup_dma_done;
- }
--
++ qup->n_words = spi_qup_sgl_get_size(rx_sgl, rx_nents) /
++ qup->w_size;
++ }
+
- if (xfer->rx_buf) {
- ret = spi_qup_prep_sg(master, xfer->rx_sg.sgl,
- xfer->rx_sg.nents, DMA_DEV_TO_MEM,
- rx_done, &qup->done);
- if (ret)
- return ret;
-+ rx_sgl = xfer->rx_sg.sgl;
-+ tx_sgl = xfer->tx_sg.sgl;
++ if (tx_sgl) {
++ tx_nents = sg_nents_for_len(tx_sgl, SPI_MAX_XFER);
++ if (tx_nents < 0)
++ tx_nents = sg_nents(tx_sgl);
- dma_async_issue_pending(master->dma_rx);
- }
-+ do {
-+ int rx_nents = 0, tx_nents = 0;
++ qup->n_words = spi_qup_sgl_get_size(tx_sgl, tx_nents) /
++ qup->w_size;
++ }
- if (xfer->tx_buf) {
- ret = spi_qup_prep_sg(master, xfer->tx_sg.sgl,
- xfer->tx_sg.nents, DMA_MEM_TO_DEV,
- tx_done, &qup->dma_tx_done);
-+ if (rx_sgl) {
-+ rx_nents = sg_nents_for_len(rx_sgl, SPI_MAX_XFER);
-+ if (rx_nents < 0)
-+ rx_nents = sg_nents(rx_sgl);
-+
-+ qup->n_words = spi_qup_sgl_get_size(rx_sgl, rx_nents) /
-+ qup->w_size;
-+ }
-+
-+ if (tx_sgl) {
-+ tx_nents = sg_nents_for_len(tx_sgl, SPI_MAX_XFER);
-+ if (tx_nents < 0)
-+ tx_nents = sg_nents(tx_sgl);
-+
-+ qup->n_words = spi_qup_sgl_get_size(tx_sgl, tx_nents) /
-+ qup->w_size;
-+ }
-+
+
+ ret = spi_qup_io_config(spi, xfer);
if (ret)
+ dev_warn(qup->dev, "cannot set RUN state\n");
+ return ret;
+ }
-+
+
+- if (xfer->rx_buf && !wait_for_completion_timeout(&qup->done, timeout))
+- return -ETIMEDOUT;
+ if (!qup->qup_v1) {
+ if (rx_sgl) {
+ rx_done = spi_qup_dma_done;
+ }
-+
+
+- if (xfer->tx_buf && !wait_for_completion_timeout(&qup->dma_tx_done, timeout))
+- ret = -ETIMEDOUT;
+ if (tx_sgl) {
+ tx_done = spi_qup_dma_done;
+ }
+ }
-+
+
+- return ret;
+ if (rx_sgl) {
+ ret = spi_qup_prep_sg(master, rx_sgl, rx_nents,
+ DMA_DEV_TO_MEM, rx_done,
+ pr_emerg(" tx timed out\n");
+ return -ETIMEDOUT;
+ }
-
-- if (xfer->rx_buf && !wait_for_completion_timeout(&qup->done, timeout))
-- return -ETIMEDOUT;
++
+ for (; rx_sgl && rx_nents--; rx_sgl = sg_next(rx_sgl));
+ for (; tx_sgl && tx_nents--; tx_sgl = sg_next(tx_sgl));
-
-- if (xfer->tx_buf && !wait_for_completion_timeout(&qup->dma_tx_done, timeout))
-- ret = -ETIMEDOUT;
++
+ } while (rx_sgl || tx_sgl);
-
-- return ret;
++
+ return 0;
}
+ };
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
-@@ -2,6 +2,9 @@
+@@ -2,6 +2,9 @@ config QCOM_GDSC
bool
select PM_GENERIC_DOMAINS if PM
config COMMON_CLK_QCOM
tristate "Support for Qualcomm's clock controllers"
depends on OF
-@@ -9,6 +12,19 @@
+@@ -9,6 +12,19 @@ config COMMON_CLK_QCOM
select REGMAP_MMIO
select RESET_CONTROLLER
select QCOM_GDSC
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -29,3 +29,4 @@
+@@ -29,3 +29,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
depends on COMMON_CLK_QCOM && QCOM_SMD_RPM
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
-@@ -23,3 +23,4 @@ obj-$(CONFIG_MSM_GCC_8974) += gcc-msm897
- obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
+@@ -30,3 +30,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
+ obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
--- /dev/null
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
-@@ -573,92 +573,61 @@
+@@ -573,92 +573,61 @@ dtb-$(CONFIG_ARCH_OMAP4) += \
omap4-var-stk-om44.dtb
dtb-$(CONFIG_SOC_AM43XX) += \
am43x-epos-evm.dtb \
+ 0x00094 0x4e /* PORT6_STATUS */
+ >;
+ };
-+
+
+- nand-ecc-strength = <4>;
+- nand-ecc-step-size = <512>;
+- nand-bus-width = <8>;
+ phy4: ethernet-phy@4 {
+ device_type = "ethernet-phy";
+ reg = <4>;
+ status = "ok";
+ phy-mode = "sgmii";
+ qcom,id = <2>;
-
-- nand-ecc-strength = <4>;
-- nand-ecc-step-size = <512>;
-- nand-bus-width = <8>;
++
+ fixed-link {
+ speed = <1000>;
+ full-duplex;