diff mbox series

[v1] dmaengine: tegra-apb: Error out if DMA_PREP_INTERRUPT flag is unset

Message ID 20190529214355.15339-1-digetx@gmail.com
State Deferred
Headers show
Series [v1] dmaengine: tegra-apb: Error out if DMA_PREP_INTERRUPT flag is unset | expand

Commit Message

Dmitry Osipenko May 29, 2019, 9:43 p.m. UTC
Apparently driver was never tested with DMA_PREP_INTERRUPT flag being
unset since it completely disables interrupt handling instead of skipping
the callbacks invocations, hence putting channel into unusable state.

The flag is always set by all of kernel drivers that use APB DMA, so let's
error out in otherwise case for consistency. It won't be difficult to
support that case properly if ever will be needed.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/dma/tegra20-apb-dma.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Jon Hunter May 30, 2019, 12:01 p.m. UTC | #1
On 29/05/2019 22:43, Dmitry Osipenko wrote:
> Apparently driver was never tested with DMA_PREP_INTERRUPT flag being
> unset since it completely disables interrupt handling instead of skipping
> the callbacks invocations, hence putting channel into unusable state.
> 
> The flag is always set by all of kernel drivers that use APB DMA, so let's
> error out in otherwise case for consistency. It won't be difficult to
> support that case properly if ever will be needed.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/dma/tegra20-apb-dma.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
> index cf462b1abc0b..2c84a660ba36 100644
> --- a/drivers/dma/tegra20-apb-dma.c
> +++ b/drivers/dma/tegra20-apb-dma.c
> @@ -988,8 +988,12 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
>  		csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
>  	}
>  
> -	if (flags & DMA_PREP_INTERRUPT)
> +	if (flags & DMA_PREP_INTERRUPT) {
>  		csr |= TEGRA_APBDMA_CSR_IE_EOC;
> +	} else {
> +		WARN_ON_ONCE(1);
> +		return NULL;
> +	}
>  
>  	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
>  
> @@ -1131,8 +1135,12 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
>  		csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
>  	}
>  
> -	if (flags & DMA_PREP_INTERRUPT)
> +	if (flags & DMA_PREP_INTERRUPT) {
>  		csr |= TEGRA_APBDMA_CSR_IE_EOC;
> +	} else {
> +		WARN_ON_ONCE(1);
> +		return NULL;
> +	}
>  
>  	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;

Looks good to me.

Acked-by: Jon Hunter <jonathanh@nvidia.com>

Cheers
Jon
Dmitry Osipenko May 30, 2019, 5:32 p.m. UTC | #2
30.05.2019 15:01, Jon Hunter пишет:
> 
> On 29/05/2019 22:43, Dmitry Osipenko wrote:
>> Apparently driver was never tested with DMA_PREP_INTERRUPT flag being
>> unset since it completely disables interrupt handling instead of skipping
>> the callbacks invocations, hence putting channel into unusable state.
>>
>> The flag is always set by all of kernel drivers that use APB DMA, so let's
>> error out in otherwise case for consistency. It won't be difficult to
>> support that case properly if ever will be needed.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/dma/tegra20-apb-dma.c | 12 ++++++++++--
>>  1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
>> index cf462b1abc0b..2c84a660ba36 100644
>> --- a/drivers/dma/tegra20-apb-dma.c
>> +++ b/drivers/dma/tegra20-apb-dma.c
>> @@ -988,8 +988,12 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
>>  		csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
>>  	}
>>  
>> -	if (flags & DMA_PREP_INTERRUPT)
>> +	if (flags & DMA_PREP_INTERRUPT) {
>>  		csr |= TEGRA_APBDMA_CSR_IE_EOC;
>> +	} else {
>> +		WARN_ON_ONCE(1);
>> +		return NULL;
>> +	}
>>  
>>  	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
>>  
>> @@ -1131,8 +1135,12 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
>>  		csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
>>  	}
>>  
>> -	if (flags & DMA_PREP_INTERRUPT)
>> +	if (flags & DMA_PREP_INTERRUPT) {
>>  		csr |= TEGRA_APBDMA_CSR_IE_EOC;
>> +	} else {
>> +		WARN_ON_ONCE(1);
>> +		return NULL;
>> +	}
>>  
>>  	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
> 
> Looks good to me.
> 
> Acked-by: Jon Hunter <jonathanh@nvidia.com>
> 
> Cheers
> Jon
> 

Thanks
Vinod Koul June 4, 2019, 12:16 p.m. UTC | #3
On 30-05-19, 00:43, Dmitry Osipenko wrote:
> Apparently driver was never tested with DMA_PREP_INTERRUPT flag being
> unset since it completely disables interrupt handling instead of skipping
> the callbacks invocations, hence putting channel into unusable state.
> 
> The flag is always set by all of kernel drivers that use APB DMA, so let's
> error out in otherwise case for consistency. It won't be difficult to
> support that case properly if ever will be needed.

Applied, thanks
diff mbox series

Patch

diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index cf462b1abc0b..2c84a660ba36 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -988,8 +988,12 @@  static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
 		csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
 	}
 
-	if (flags & DMA_PREP_INTERRUPT)
+	if (flags & DMA_PREP_INTERRUPT) {
 		csr |= TEGRA_APBDMA_CSR_IE_EOC;
+	} else {
+		WARN_ON_ONCE(1);
+		return NULL;
+	}
 
 	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
 
@@ -1131,8 +1135,12 @@  static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
 		csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
 	}
 
-	if (flags & DMA_PREP_INTERRUPT)
+	if (flags & DMA_PREP_INTERRUPT) {
 		csr |= TEGRA_APBDMA_CSR_IE_EOC;
+	} else {
+		WARN_ON_ONCE(1);
+		return NULL;
+	}
 
 	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;