@@ -559,6 +559,38 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word)
559559 return err ;
560560}
561561
562+ static void atmel_spi_release_dma (void * data )
563+ {
564+ struct spi_controller * host = data ;
565+ struct atmel_spi * as = spi_controller_get_devdata (host );
566+ struct device * dev = & as -> pdev -> dev ;
567+
568+ if (host -> dma_tx ) {
569+ dma_release_channel (host -> dma_tx );
570+ host -> dma_tx = NULL ;
571+ }
572+
573+ if (host -> dma_rx ) {
574+ dma_release_channel (host -> dma_rx );
575+ host -> dma_rx = NULL ;
576+ }
577+
578+ if (IS_ENABLED (CONFIG_SOC_SAM_V4_V5 )) {
579+ if (as -> addr_tx_bbuf ) {
580+ dma_free_coherent (dev , SPI_MAX_DMA_XFER ,
581+ as -> addr_tx_bbuf ,
582+ as -> dma_addr_tx_bbuf );
583+ as -> addr_tx_bbuf = NULL ;
584+ }
585+ if (as -> addr_rx_bbuf ) {
586+ dma_free_coherent (dev , SPI_MAX_DMA_XFER ,
587+ as -> addr_rx_bbuf ,
588+ as -> dma_addr_rx_bbuf );
589+ as -> addr_rx_bbuf = NULL ;
590+ }
591+ }
592+ }
593+
562594static int atmel_spi_configure_dma (struct spi_controller * host ,
563595 struct atmel_spi * as )
564596{
@@ -569,7 +601,8 @@ static int atmel_spi_configure_dma(struct spi_controller *host,
569601 if (IS_ERR (host -> dma_tx )) {
570602 err = PTR_ERR (host -> dma_tx );
571603 dev_dbg (dev , "No TX DMA channel, DMA is disabled\n" );
572- goto error_clear ;
604+ host -> dma_tx = NULL ;
605+ return err ;
573606 }
574607
575608 host -> dma_rx = dma_request_chan (dev , "rx" );
@@ -580,26 +613,45 @@ static int atmel_spi_configure_dma(struct spi_controller *host,
580613 * requested tx channel.
581614 */
582615 dev_dbg (dev , "No RX DMA channel, DMA is disabled\n" );
583- goto error ;
616+ host -> dma_rx = NULL ;
617+ goto err_release_dma ;
584618 }
585619
586620 err = atmel_spi_dma_slave_config (as , 8 );
587621 if (err )
588- goto error ;
622+ goto err_release_dma ;
623+
624+ if (IS_ENABLED (CONFIG_SOC_SAM_V4_V5 )) {
625+ as -> addr_tx_bbuf = dma_alloc_coherent (dev , SPI_MAX_DMA_XFER ,
626+ & as -> dma_addr_tx_bbuf ,
627+ GFP_KERNEL | GFP_DMA );
628+ if (!as -> addr_tx_bbuf ) {
629+ err = - ENOMEM ;
630+ goto err_release_dma ;
631+ }
632+
633+ as -> addr_rx_bbuf = dma_alloc_coherent (dev , SPI_MAX_DMA_XFER ,
634+ & as -> dma_addr_rx_bbuf ,
635+ GFP_KERNEL | GFP_DMA );
636+ if (!as -> addr_rx_bbuf ) {
637+ err = - ENOMEM ;
638+ goto err_release_dma ;
639+ }
640+ }
641+
642+ err = devm_add_action_or_reset (dev , atmel_spi_release_dma , host );
643+ if (err )
644+ return err ;
589645
590646 dev_info (& as -> pdev -> dev ,
591- "Using %s (tx) and %s (rx) for DMA transfers\n" ,
592- dma_chan_name (host -> dma_tx ),
593- dma_chan_name (host -> dma_rx ));
647+ "Using %s (tx) and %s (rx) for DMA transfers\n" ,
648+ dma_chan_name (host -> dma_tx ), dma_chan_name (host -> dma_rx ));
594649
595650 return 0 ;
596- error :
597- if (!IS_ERR (host -> dma_rx ))
598- dma_release_channel (host -> dma_rx );
599- if (!IS_ERR (host -> dma_tx ))
600- dma_release_channel (host -> dma_tx );
601- error_clear :
602- host -> dma_tx = host -> dma_rx = NULL ;
651+
652+ err_release_dma :
653+ atmel_spi_release_dma (host );
654+
603655 return err ;
604656}
605657
@@ -611,18 +663,6 @@ static void atmel_spi_stop_dma(struct spi_controller *host)
611663 dmaengine_terminate_all (host -> dma_tx );
612664}
613665
614- static void atmel_spi_release_dma (struct spi_controller * host )
615- {
616- if (host -> dma_rx ) {
617- dma_release_channel (host -> dma_rx );
618- host -> dma_rx = NULL ;
619- }
620- if (host -> dma_tx ) {
621- dma_release_channel (host -> dma_tx );
622- host -> dma_tx = NULL ;
623- }
624- }
625-
626666/* This function is called by the DMA driver from tasklet context */
627667static void dma_callback (void * data )
628668{
@@ -1581,30 +1621,6 @@ static int atmel_spi_probe(struct platform_device *pdev)
15811621 as -> use_pdc = true;
15821622 }
15831623
1584- if (IS_ENABLED (CONFIG_SOC_SAM_V4_V5 )) {
1585- as -> addr_rx_bbuf = dma_alloc_coherent (& pdev -> dev ,
1586- SPI_MAX_DMA_XFER ,
1587- & as -> dma_addr_rx_bbuf ,
1588- GFP_KERNEL | GFP_DMA );
1589- if (!as -> addr_rx_bbuf ) {
1590- as -> use_dma = false;
1591- } else {
1592- as -> addr_tx_bbuf = dma_alloc_coherent (& pdev -> dev ,
1593- SPI_MAX_DMA_XFER ,
1594- & as -> dma_addr_tx_bbuf ,
1595- GFP_KERNEL | GFP_DMA );
1596- if (!as -> addr_tx_bbuf ) {
1597- as -> use_dma = false;
1598- dma_free_coherent (& pdev -> dev , SPI_MAX_DMA_XFER ,
1599- as -> addr_rx_bbuf ,
1600- as -> dma_addr_rx_bbuf );
1601- }
1602- }
1603- if (!as -> use_dma )
1604- dev_info (host -> dev .parent ,
1605- " can not allocate dma coherent memory\n" );
1606- }
1607-
16081624 if (as -> caps .has_dma_support && !as -> use_dma )
16091625 dev_info (& pdev -> dev , "Atmel SPI Controller using PIO only\n" );
16101626
@@ -1664,13 +1680,10 @@ static int atmel_spi_probe(struct platform_device *pdev)
16641680out_free_dma :
16651681 pm_runtime_disable (& pdev -> dev );
16661682 pm_runtime_set_suspended (& pdev -> dev );
1667-
1668- if (as -> use_dma )
1669- atmel_spi_release_dma (host );
1670-
16711683 spi_writel (as , CR , SPI_BIT (SWRST ));
16721684 spi_writel (as , CR , SPI_BIT (SWRST )); /* AT91SAM9263 Rev B workaround */
1673- clk_disable_unprepare (as -> gclk );
1685+ if (as -> gclk )
1686+ clk_disable_unprepare (as -> gclk );
16741687out_disable_clk :
16751688 clk_disable_unprepare (clk );
16761689
@@ -1687,18 +1700,8 @@ static void atmel_spi_remove(struct platform_device *pdev)
16871700 spi_unregister_controller (host );
16881701
16891702 /* reset the hardware and block queue progress */
1690- if (as -> use_dma ) {
1703+ if (as -> use_dma )
16911704 atmel_spi_stop_dma (host );
1692- atmel_spi_release_dma (host );
1693- if (IS_ENABLED (CONFIG_SOC_SAM_V4_V5 )) {
1694- dma_free_coherent (& pdev -> dev , SPI_MAX_DMA_XFER ,
1695- as -> addr_tx_bbuf ,
1696- as -> dma_addr_tx_bbuf );
1697- dma_free_coherent (& pdev -> dev , SPI_MAX_DMA_XFER ,
1698- as -> addr_rx_bbuf ,
1699- as -> dma_addr_rx_bbuf );
1700- }
1701- }
17021705
17031706 spin_lock_irq (& as -> lock );
17041707 spi_writel (as , CR , SPI_BIT (SWRST ));
0 commit comments