[PATCH v3 2/2] serial: fsl_lpuart: add DMA support

Yao Yuan yao.yuan at freescale.com
Thu Jan 16 01:02:41 EST 2014


Hi, Arnd
Thanks for your suggestion.

> -----Original Message-----
> From: linux-serial-owner at vger.kernel.org [mailto:linux-serial-
> owner at vger.kernel.org] On Behalf Of Arnd Bergmann
> Sent: Wednesday, January 15, 2014 5:26 PM
> To: Yuan Yao-B46683
> Cc: gregkh at linuxfoundation.org; shawn.guo at linaro.org;
> linux at arm.linux.org.uk; linux-arm-kernel at lists.infradead.org; linux-
> serial at vger.kernel.org
> Subject: Re: [PATCH v3 2/2] serial: fsl_lpuart: add DMA support
> 
> On Wednesday 15 January 2014, Yuan Yao wrote:
> > Add dma support for lpuart. This function depend on DMA driver.
> > You can turn on it by SERIAL_FSL_LPUART_DMA=y. And It works if dts node
> has dma properties.
> >
> > Signed-off-by: Yuan Yao <yao.yuan at freescale.com>
> 
> Most of the changes you did look good, but I have to say I'm not a fan of
> the #ifdef you added. I don't think you actually need to have the
> compile-time selection, and it would be best to just drop that part.
> 
> If you have a good reason to keep it, please change the code to more
> readable "if (IS_ENABLED(CONFIG_FSL_LPUART_DMA))" constructs.
> If you decide to do this, you will find that you need far fewer such
> conditionals because a lot of the code will automatically get dropped by
> the compiler.
> 

Thank you! I even not know the IS_ENABLED macro.
At the beginning I just think this can save the size of code. 
But now I think it's not very necessary.
I tend to cancel it.

> >  uart0: serial at 40027000 {
> > -	       compatible = "fsl,vf610-lpuart";
> > -	       reg = <0x40027000 0x1000>;
> > -	       interrupts = <0 61 0x00>;
> > -       };
> > +		compatible = "fsl,vf610-lpuart";
> > +		reg = <0x40027000 0x1000>;
> > +		interrupts = <0 61 0x00>;
> > +		clocks = <&clks VF610_CLK_UART0>;
> > +		clock-names = "ipg";
> > +		dma-names = "lpuart-tx","lpuart-rx";
> > +		dmas = <&edma0 0 VF610_EDMA_MUXID0_UART0_TX>,
> > +			<&edma0 0 VF610_EDMA_MUXID0_UART0_RX>;
> > +	};
> 
> You still haven't addressed my comment about removing the
> VF610_EDMA_MUXID0_UART0_TX macros.
>

Very sorry for forget it. At that time the VF610_EDMA_MUXID0_UART0_TX is because of eDMA driver request.
But now it also cancel the macro. So this is my fault. I will fix it next.

> >
> > +#ifdef CONFIG_SERIAL_FSL_LPUART_DMA
> > +#define DMA_MAXBURST		16
> > +#define DMA_MAXBURST_MASK	(DMA_MAXBURST - 1)
> > +#define FSL_UART_RX_DMA_BUFFER_SIZE	64
> > +#endif
> 
> For this part there was no need for the #ifdef to start with.
> 
> >  #define DRIVER_NAME	"fsl-lpuart"
> >  #define DEV_NAME	"ttyLP"
> >  #define UART_NR		6
> > @@ -121,6 +132,26 @@ struct lpuart_port {
> >  	struct clk		*clk;
> >  	unsigned int		txfifo_size;
> >  	unsigned int		rxfifo_size;
> > +
> > +#ifdef CONFIG_SERIAL_FSL_LPUART_DMA
> > +	bool			lpuart_dma_use;
> > +	struct dma_chan		*dma_tx_chan;
> > +	struct dma_chan		*dma_rx_chan;
> > +	struct dma_async_tx_descriptor  *dma_tx_desc;
> > +	struct dma_async_tx_descriptor  *dma_rx_desc;
> > +	dma_addr_t		dma_tx_buf_bus;
> > +	dma_addr_t		dma_rx_buf_bus;
> > +	dma_cookie_t		dma_tx_cookie;
> > +	dma_cookie_t		dma_rx_cookie;
> > +	unsigned char		*dma_tx_buf_virt;
> > +	unsigned char		*dma_rx_buf_virt;
> > +	unsigned int		dma_tx_bytes;
> > +	unsigned int		dma_rx_bytes;
> > +	int			dma_tx_in_progress;
> > +	int			dma_rx_in_progress;
> > +	unsigned int		dma_rx_timeout;
> > +	struct timer_list	lpuart_timer;
> > +#endif
> >  };
> 
> This part will result in a slight increase in data size even if dma
> support is turned off at compile time.
> 

Yes, I will fix it.

> >
> >  	temp = readb(port->membase + UARTCR2);
> >  	writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
> >
> > +#ifdef CONFIG_SERIAL_FSL_LPUART_DMA
> > +	if (sport->lpuart_dma_use) {
> > +		if (!uart_circ_empty(xmit) && !sport->dma_tx_in_progress)
> > +			lpuart_prepare_tx(sport);
> > +	} else {
> > +		if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
> > +			lpuart_transmit_buffer(sport);
> > +	}
> > +#else
> >  	if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
> >  		lpuart_transmit_buffer(sport);
> > +#endif
> >  }
> 
> So this can simply become
> 
> +	if (IS_ENABLED(CONFIG_SERIAL_FSL_LPUART_DMA) && sport-
> >lpuart_dma_use) {
> +		if (!uart_circ_empty(xmit) && !sport->dma_tx_in_progress)
> +			lpuart_prepare_tx(sport);
> +	} else {
> +		if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
> +			lpuart_trans	mit_buffer(sport);
> +	}
> 
> and the compiler will silently drop the lpuart_prepare_tx() function and
> everything it calls that isn't used elsewhere.
> 

It's wonderful. 

> 
> > +
> > +#ifdef CONFIG_SERIAL_FSL_LPUART_DMA
> > +	struct platform_device *pdev = to_platform_device(port->dev);
> > +	struct device_node *np = pdev->dev.of_node;
> > +
> > +	if (of_get_property(np, "dmas", NULL)) {
> > +		sport->lpuart_dma_use = true;
> > +		lpuart_dma_tx_request(port);
> > +		lpuart_dma_rx_request(port);
> > +		temp = readb(port->membase + UARTCR5);
> > +		writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
> > +	} else
> > +		sport->lpuart_dma_use = false;
> > +#endif
> 
> Same here.
> 
> > @@ -854,6 +1291,10 @@ static int __init lpuart_serial_init(void)
> >
> >  	pr_info("serial: Freescale lpuart driver\n");
> >
> > +#ifdef CONFIG_SERIAL_FSL_LPUART_DMA
> > +	pr_info("serial: Freescale lpuart dma support\n"); #endif
> > +
> 
> This message is not helpful in the long run, I'd rather see you drop the
> other one as well. Note that this function is called on *all* platforms
> when the driver is enabled, not just on those that actually have the uart.
> 
> 	Arnd
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial"
> in the body of a message to majordomo at vger.kernel.org More majordomo info
> at  http://vger.kernel.org/majordomo-info.html
> 



More information about the linux-arm-kernel mailing list