| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2008-2014, The Linux foundation. All rights reserved. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License rev 2 and |
|---|
| 6 | | - * only rev 2 as published by the free Software foundation. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 9 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | | - * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | | - * GNU General Public License for more details. |
|---|
| 12 | 4 | */ |
|---|
| 13 | 5 | |
|---|
| 14 | 6 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 281 | 273 | writel_relaxed(QUP_OP_IN_SERVICE_FLAG, |
|---|
| 282 | 274 | controller->base + QUP_OPERATIONAL); |
|---|
| 283 | 275 | |
|---|
| 276 | + if (!remainder) |
|---|
| 277 | + goto exit; |
|---|
| 278 | + |
|---|
| 284 | 279 | if (is_block_mode) { |
|---|
| 285 | 280 | num_words = (remainder > words_per_block) ? |
|---|
| 286 | 281 | words_per_block : remainder; |
|---|
| .. | .. |
|---|
| 310 | 305 | * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be |
|---|
| 311 | 306 | * present and this is used to determine if transaction is complete |
|---|
| 312 | 307 | */ |
|---|
| 313 | | - *opflags = readl_relaxed(controller->base + QUP_OPERATIONAL); |
|---|
| 314 | | - if (is_block_mode && *opflags & QUP_OP_MAX_INPUT_DONE_FLAG) |
|---|
| 315 | | - writel_relaxed(QUP_OP_IN_SERVICE_FLAG, |
|---|
| 316 | | - controller->base + QUP_OPERATIONAL); |
|---|
| 317 | | - |
|---|
| 308 | +exit: |
|---|
| 309 | + if (!remainder) { |
|---|
| 310 | + *opflags = readl_relaxed(controller->base + QUP_OPERATIONAL); |
|---|
| 311 | + if (is_block_mode && *opflags & QUP_OP_MAX_INPUT_DONE_FLAG) |
|---|
| 312 | + writel_relaxed(QUP_OP_IN_SERVICE_FLAG, |
|---|
| 313 | + controller->base + QUP_OPERATIONAL); |
|---|
| 314 | + } |
|---|
| 318 | 315 | } |
|---|
| 319 | 316 | |
|---|
| 320 | 317 | static void spi_qup_write_to_fifo(struct spi_qup *controller, u32 num_words) |
|---|
| .. | .. |
|---|
| 361 | 358 | /* ACK by clearing service flag */ |
|---|
| 362 | 359 | writel_relaxed(QUP_OP_OUT_SERVICE_FLAG, |
|---|
| 363 | 360 | controller->base + QUP_OPERATIONAL); |
|---|
| 361 | + |
|---|
| 362 | + /* make sure the interrupt is valid */ |
|---|
| 363 | + if (!remainder) |
|---|
| 364 | + return; |
|---|
| 364 | 365 | |
|---|
| 365 | 366 | if (is_block_mode) { |
|---|
| 366 | 367 | num_words = (remainder > words_per_block) ? |
|---|
| .. | .. |
|---|
| 575 | 576 | return 0; |
|---|
| 576 | 577 | } |
|---|
| 577 | 578 | |
|---|
| 579 | +static bool spi_qup_data_pending(struct spi_qup *controller) |
|---|
| 580 | +{ |
|---|
| 581 | + unsigned int remainder_tx, remainder_rx; |
|---|
| 582 | + |
|---|
| 583 | + remainder_tx = DIV_ROUND_UP(spi_qup_len(controller) - |
|---|
| 584 | + controller->tx_bytes, controller->w_size); |
|---|
| 585 | + |
|---|
| 586 | + remainder_rx = DIV_ROUND_UP(spi_qup_len(controller) - |
|---|
| 587 | + controller->rx_bytes, controller->w_size); |
|---|
| 588 | + |
|---|
| 589 | + return remainder_tx || remainder_rx; |
|---|
| 590 | +} |
|---|
| 591 | + |
|---|
| 578 | 592 | static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) |
|---|
| 579 | 593 | { |
|---|
| 580 | 594 | struct spi_qup *controller = dev_id; |
|---|
| 581 | 595 | u32 opflags, qup_err, spi_err; |
|---|
| 596 | + unsigned long flags; |
|---|
| 582 | 597 | int error = 0; |
|---|
| 583 | 598 | |
|---|
| 584 | 599 | qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS); |
|---|
| .. | .. |
|---|
| 610 | 625 | error = -EIO; |
|---|
| 611 | 626 | } |
|---|
| 612 | 627 | |
|---|
| 628 | + spin_lock_irqsave(&controller->lock, flags); |
|---|
| 629 | + if (!controller->error) |
|---|
| 630 | + controller->error = error; |
|---|
| 631 | + spin_unlock_irqrestore(&controller->lock, flags); |
|---|
| 632 | + |
|---|
| 613 | 633 | if (spi_qup_is_dma_xfer(controller->mode)) { |
|---|
| 614 | 634 | writel_relaxed(opflags, controller->base + QUP_OPERATIONAL); |
|---|
| 615 | 635 | } else { |
|---|
| .. | .. |
|---|
| 618 | 638 | |
|---|
| 619 | 639 | if (opflags & QUP_OP_OUT_SERVICE_FLAG) |
|---|
| 620 | 640 | spi_qup_write(controller); |
|---|
| 641 | + |
|---|
| 642 | + if (!spi_qup_data_pending(controller)) |
|---|
| 643 | + complete(&controller->done); |
|---|
| 621 | 644 | } |
|---|
| 622 | 645 | |
|---|
| 623 | | - if ((opflags & QUP_OP_MAX_INPUT_DONE_FLAG) || error) |
|---|
| 646 | + if (error) |
|---|
| 624 | 647 | complete(&controller->done); |
|---|
| 648 | + |
|---|
| 649 | + if (opflags & QUP_OP_MAX_INPUT_DONE_FLAG) { |
|---|
| 650 | + if (!spi_qup_is_dma_xfer(controller->mode)) { |
|---|
| 651 | + if (spi_qup_data_pending(controller)) |
|---|
| 652 | + return IRQ_HANDLED; |
|---|
| 653 | + } |
|---|
| 654 | + complete(&controller->done); |
|---|
| 655 | + } |
|---|
| 625 | 656 | |
|---|
| 626 | 657 | return IRQ_HANDLED; |
|---|
| 627 | 658 | } |
|---|
| .. | .. |
|---|
| 817 | 848 | { |
|---|
| 818 | 849 | struct spi_qup *controller = spi_master_get_devdata(master); |
|---|
| 819 | 850 | unsigned long timeout, flags; |
|---|
| 820 | | - int ret = -EIO; |
|---|
| 851 | + int ret; |
|---|
| 821 | 852 | |
|---|
| 822 | 853 | ret = spi_qup_io_prep(spi, xfer); |
|---|
| 823 | 854 | if (ret) |
|---|
| .. | .. |
|---|
| 842 | 873 | else |
|---|
| 843 | 874 | ret = spi_qup_do_pio(spi, xfer, timeout); |
|---|
| 844 | 875 | |
|---|
| 845 | | - if (ret) |
|---|
| 846 | | - goto exit; |
|---|
| 847 | | - |
|---|
| 848 | | -exit: |
|---|
| 849 | 876 | spi_qup_set_state(controller, QUP_STATE_RESET); |
|---|
| 850 | 877 | spin_lock_irqsave(&controller->lock, flags); |
|---|
| 851 | 878 | if (!ret) |
|---|
| .. | .. |
|---|
| 905 | 932 | int ret; |
|---|
| 906 | 933 | |
|---|
| 907 | 934 | /* allocate dma resources, if available */ |
|---|
| 908 | | - master->dma_rx = dma_request_slave_channel_reason(dev, "rx"); |
|---|
| 935 | + master->dma_rx = dma_request_chan(dev, "rx"); |
|---|
| 909 | 936 | if (IS_ERR(master->dma_rx)) |
|---|
| 910 | 937 | return PTR_ERR(master->dma_rx); |
|---|
| 911 | 938 | |
|---|
| 912 | | - master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); |
|---|
| 939 | + master->dma_tx = dma_request_chan(dev, "tx"); |
|---|
| 913 | 940 | if (IS_ERR(master->dma_tx)) { |
|---|
| 914 | 941 | ret = PTR_ERR(master->dma_tx); |
|---|
| 915 | 942 | goto err_tx; |
|---|
| .. | .. |
|---|
| 1172 | 1199 | return ret; |
|---|
| 1173 | 1200 | |
|---|
| 1174 | 1201 | ret = clk_prepare_enable(controller->cclk); |
|---|
| 1175 | | - if (ret) |
|---|
| 1202 | + if (ret) { |
|---|
| 1203 | + clk_disable_unprepare(controller->iclk); |
|---|
| 1176 | 1204 | return ret; |
|---|
| 1205 | + } |
|---|
| 1177 | 1206 | |
|---|
| 1178 | 1207 | /* Disable clocks auto gaiting */ |
|---|
| 1179 | 1208 | config = readl_relaxed(controller->base + QUP_CONFIG); |
|---|
| .. | .. |
|---|
| 1219 | 1248 | return ret; |
|---|
| 1220 | 1249 | |
|---|
| 1221 | 1250 | ret = clk_prepare_enable(controller->cclk); |
|---|
| 1222 | | - if (ret) |
|---|
| 1251 | + if (ret) { |
|---|
| 1252 | + clk_disable_unprepare(controller->iclk); |
|---|
| 1223 | 1253 | return ret; |
|---|
| 1254 | + } |
|---|
| 1224 | 1255 | |
|---|
| 1225 | 1256 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); |
|---|
| 1226 | 1257 | if (ret) |
|---|
| 1227 | | - return ret; |
|---|
| 1258 | + goto disable_clk; |
|---|
| 1228 | 1259 | |
|---|
| 1229 | | - return spi_master_resume(master); |
|---|
| 1260 | + ret = spi_master_resume(master); |
|---|
| 1261 | + if (ret) |
|---|
| 1262 | + goto disable_clk; |
|---|
| 1263 | + |
|---|
| 1264 | + return 0; |
|---|
| 1265 | + |
|---|
| 1266 | +disable_clk: |
|---|
| 1267 | + clk_disable_unprepare(controller->cclk); |
|---|
| 1268 | + clk_disable_unprepare(controller->iclk); |
|---|
| 1269 | + return ret; |
|---|
| 1230 | 1270 | } |
|---|
| 1231 | 1271 | #endif /* CONFIG_PM_SLEEP */ |
|---|
| 1232 | 1272 | |
|---|
| .. | .. |
|---|
| 1236 | 1276 | struct spi_qup *controller = spi_master_get_devdata(master); |
|---|
| 1237 | 1277 | int ret; |
|---|
| 1238 | 1278 | |
|---|
| 1239 | | - ret = pm_runtime_get_sync(&pdev->dev); |
|---|
| 1279 | + ret = pm_runtime_resume_and_get(&pdev->dev); |
|---|
| 1240 | 1280 | if (ret < 0) |
|---|
| 1241 | 1281 | return ret; |
|---|
| 1242 | 1282 | |
|---|