| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | * Microchip PIC32 SPI controller driver. | 
|---|
| 3 | 4 | * | 
|---|
| 4 | 5 | * Purna Chandra Mandal <purna.mandal@microchip.com> | 
|---|
| 5 | 6 | * Copyright (c) 2016, Microchip Technology Inc. | 
|---|
| 6 |  | - * | 
|---|
| 7 |  | - * This program is free software; you can distribute it and/or modify it | 
|---|
| 8 |  | - * under the terms of the GNU General Public License (Version 2) as | 
|---|
| 9 |  | - * published by the Free Software Foundation. | 
|---|
| 10 |  | - * | 
|---|
| 11 |  | - * This program is distributed in the hope it will be useful, but WITHOUT | 
|---|
| 12 |  | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|---|
| 13 |  | - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|---|
| 14 |  | - * for more details. | 
|---|
| 15 | 7 | */ | 
|---|
| 16 | 8 |  | 
|---|
| 17 | 9 | #include <linux/clk.h> | 
|---|
| .. | .. | 
|---|
| 560 | 552 | dev_err(&spi->dev, "wait error/timedout\n"); | 
|---|
| 561 | 553 | if (dma_issued) { | 
|---|
| 562 | 554 | dmaengine_terminate_all(master->dma_rx); | 
|---|
| 563 |  | -			dmaengine_terminate_all(master->dma_rx); | 
|---|
|  | 555 | +			dmaengine_terminate_all(master->dma_tx); | 
|---|
| 564 | 556 | } | 
|---|
| 565 | 557 | ret = -ETIMEDOUT; | 
|---|
| 566 | 558 | } else { | 
|---|
| .. | .. | 
|---|
| 615 | 607 | gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); | 
|---|
| 616 | 608 | } | 
|---|
| 617 | 609 |  | 
|---|
| 618 |  | -static void pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev) | 
|---|
|  | 610 | +static int pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev) | 
|---|
| 619 | 611 | { | 
|---|
| 620 | 612 | struct spi_master *master = pic32s->master; | 
|---|
| 621 |  | -	dma_cap_mask_t mask; | 
|---|
|  | 613 | +	int ret = 0; | 
|---|
| 622 | 614 |  | 
|---|
| 623 |  | -	dma_cap_zero(mask); | 
|---|
| 624 |  | -	dma_cap_set(DMA_SLAVE, mask); | 
|---|
|  | 615 | +	master->dma_rx = dma_request_chan(dev, "spi-rx"); | 
|---|
|  | 616 | +	if (IS_ERR(master->dma_rx)) { | 
|---|
|  | 617 | +		if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) | 
|---|
|  | 618 | +			ret = -EPROBE_DEFER; | 
|---|
|  | 619 | +		else | 
|---|
|  | 620 | +			dev_warn(dev, "RX channel not found.\n"); | 
|---|
| 625 | 621 |  | 
|---|
| 626 |  | -	master->dma_rx = dma_request_slave_channel_compat(mask, NULL, NULL, | 
|---|
| 627 |  | -							  dev, "spi-rx"); | 
|---|
| 628 |  | -	if (!master->dma_rx) { | 
|---|
| 629 |  | -		dev_warn(dev, "RX channel not found.\n"); | 
|---|
|  | 622 | +		master->dma_rx = NULL; | 
|---|
| 630 | 623 | goto out_err; | 
|---|
| 631 | 624 | } | 
|---|
| 632 | 625 |  | 
|---|
| 633 |  | -	master->dma_tx = dma_request_slave_channel_compat(mask, NULL, NULL, | 
|---|
| 634 |  | -							  dev, "spi-tx"); | 
|---|
| 635 |  | -	if (!master->dma_tx) { | 
|---|
| 636 |  | -		dev_warn(dev, "TX channel not found.\n"); | 
|---|
|  | 626 | +	master->dma_tx = dma_request_chan(dev, "spi-tx"); | 
|---|
|  | 627 | +	if (IS_ERR(master->dma_tx)) { | 
|---|
|  | 628 | +		if (PTR_ERR(master->dma_tx) == -EPROBE_DEFER) | 
|---|
|  | 629 | +			ret = -EPROBE_DEFER; | 
|---|
|  | 630 | +		else | 
|---|
|  | 631 | +			dev_warn(dev, "TX channel not found.\n"); | 
|---|
|  | 632 | + | 
|---|
|  | 633 | +		master->dma_tx = NULL; | 
|---|
| 637 | 634 | goto out_err; | 
|---|
| 638 | 635 | } | 
|---|
| 639 | 636 |  | 
|---|
| .. | .. | 
|---|
| 643 | 640 | /* DMA chnls allocated and prepared */ | 
|---|
| 644 | 641 | set_bit(PIC32F_DMA_PREP, &pic32s->flags); | 
|---|
| 645 | 642 |  | 
|---|
| 646 |  | -	return; | 
|---|
|  | 643 | +	return 0; | 
|---|
| 647 | 644 |  | 
|---|
| 648 | 645 | out_err: | 
|---|
| 649 |  | -	if (master->dma_rx) | 
|---|
|  | 646 | +	if (master->dma_rx) { | 
|---|
| 650 | 647 | dma_release_channel(master->dma_rx); | 
|---|
|  | 648 | +		master->dma_rx = NULL; | 
|---|
|  | 649 | +	} | 
|---|
| 651 | 650 |  | 
|---|
| 652 |  | -	if (master->dma_tx) | 
|---|
|  | 651 | +	if (master->dma_tx) { | 
|---|
| 653 | 652 | dma_release_channel(master->dma_tx); | 
|---|
|  | 653 | +		master->dma_tx = NULL; | 
|---|
|  | 654 | +	} | 
|---|
|  | 655 | + | 
|---|
|  | 656 | +	return ret; | 
|---|
| 654 | 657 | } | 
|---|
| 655 | 658 |  | 
|---|
| 656 | 659 | static void pic32_spi_dma_unprep(struct pic32_spi *pic32s) | 
|---|
| .. | .. | 
|---|
| 720 | 723 |  | 
|---|
| 721 | 724 | /* get irq resources: err-irq, rx-irq, tx-irq */ | 
|---|
| 722 | 725 | pic32s->fault_irq = platform_get_irq_byname(pdev, "fault"); | 
|---|
| 723 |  | -	if (pic32s->fault_irq < 0) { | 
|---|
| 724 |  | -		dev_err(&pdev->dev, "fault-irq not found\n"); | 
|---|
|  | 726 | +	if (pic32s->fault_irq < 0) | 
|---|
| 725 | 727 | return pic32s->fault_irq; | 
|---|
| 726 |  | -	} | 
|---|
| 727 | 728 |  | 
|---|
| 728 | 729 | pic32s->rx_irq = platform_get_irq_byname(pdev, "rx"); | 
|---|
| 729 |  | -	if (pic32s->rx_irq < 0) { | 
|---|
| 730 |  | -		dev_err(&pdev->dev, "rx-irq not found\n"); | 
|---|
|  | 730 | +	if (pic32s->rx_irq < 0) | 
|---|
| 731 | 731 | return pic32s->rx_irq; | 
|---|
| 732 |  | -	} | 
|---|
| 733 | 732 |  | 
|---|
| 734 | 733 | pic32s->tx_irq = platform_get_irq_byname(pdev, "tx"); | 
|---|
| 735 |  | -	if (pic32s->tx_irq < 0) { | 
|---|
| 736 |  | -		dev_err(&pdev->dev, "tx-irq not found\n"); | 
|---|
|  | 734 | +	if (pic32s->tx_irq < 0) | 
|---|
| 737 | 735 | return pic32s->tx_irq; | 
|---|
| 738 |  | -	} | 
|---|
| 739 | 736 |  | 
|---|
| 740 | 737 | /* get clock */ | 
|---|
| 741 | 738 | pic32s->clk = devm_clk_get(&pdev->dev, "mck0"); | 
|---|
| .. | .. | 
|---|
| 775 | 772 | if (ret) | 
|---|
| 776 | 773 | goto err_master; | 
|---|
| 777 | 774 |  | 
|---|
| 778 |  | -	master->dev.of_node	= of_node_get(pdev->dev.of_node); | 
|---|
|  | 775 | +	master->dev.of_node	= pdev->dev.of_node; | 
|---|
| 779 | 776 | master->mode_bits	= SPI_MODE_3 | SPI_MODE_0 | SPI_CS_HIGH; | 
|---|
| 780 | 777 | master->num_chipselect	= 1; /* single chip-select */ | 
|---|
| 781 | 778 | master->max_speed_hz	= clk_get_rate(pic32s->clk); | 
|---|
| .. | .. | 
|---|
| 791 | 788 | master->unprepare_transfer_hardware	= pic32_spi_unprepare_hardware; | 
|---|
| 792 | 789 |  | 
|---|
| 793 | 790 | /* optional DMA support */ | 
|---|
| 794 |  | -	pic32_spi_dma_prep(pic32s, &pdev->dev); | 
|---|
|  | 791 | +	ret = pic32_spi_dma_prep(pic32s, &pdev->dev); | 
|---|
|  | 792 | +	if (ret) | 
|---|
|  | 793 | +		goto err_bailout; | 
|---|
|  | 794 | + | 
|---|
| 795 | 795 | if (test_bit(PIC32F_DMA_PREP, &pic32s->flags)) | 
|---|
| 796 | 796 | master->can_dma	= pic32_spi_can_dma; | 
|---|
| 797 | 797 |  | 
|---|