serial: lantiq: Add CCF suppport
Subsystems (3)
cover serial: lantiq: Add CCF suppport
This patch series is for adding common clock framework support for lantiq serial driver, mainly includes:
1) Add common clock framework support.
2) Modify the dts file according to the DT conventions.
3) Replace the platform dependent functions with kernel functions
Songjun Wu (14):
MIPS: dts: Change upper case to lower case
MIPS: dts: Add aliases node for lantiq danube serial
serial: lantiq: Get serial id from dts
serial: lantiq: Change ltq_w32_mask to asc_update_bits
MIPS: lantiq: Unselect SWAP_IO_SPACE when LANTIQ is selected
serial: lantiq: Use readl/writel instead of ltq_r32/ltq_w32
serial: lantiq: Rename fpiclk to freqclk
serial: lantiq: Replace clk_enable/clk_disable with clk generic API
serial: lantiq: Add CCF support
serial: lantiq: Reorder the head files
include: Add lantiq.h in include/linux/
serial: lantiq: Replace lantiq_soc.h with lantiq.h
serial: lantiq: Change init_lqasc to static declaration
dt-bindings: serial: lantiq: Add optional properties for CCF
.../devicetree/bindings/serial/lantiq_asc.txt | 15 +++ arch/mips/Kconfig | 1 - arch/mips/boot/dts/lantiq/danube.dtsi | 42 +++--- arch/mips/boot/dts/lantiq/easy50712.dts | 18 ++- drivers/tty/serial/lantiq.c | 145 ++++++++++++--------- include/linux/lantiq.h | 23 ++++ 6 files changed, 155 insertions(+), 89 deletions(-) create mode 100644 include/linux/lantiq.h
Signature · 1 line
2.11.0
PATCH RESEND 1/14 MIPS: dts: Change upper case to lower case
All the upper case in unit-address and hex constants are changed to lower case according to the DT conventions.
---
arch/mips/boot/dts/lantiq/danube.dtsi | 42 ++++++++++++++++----------------- arch/mips/boot/dts/lantiq/easy50712.dts | 14 +++++------ 2 files changed, 28 insertions(+), 28 deletions(-)
arch/mips/boot/dts/lantiq/danube.dtsi +21 -21
@@ -10,12 +10,12 @@ }; }; - biu@1F800000 { + biu@1f800000 { #address-cells = <1>; #size-cells = <1>; compatible = "lantiq,biu", "simple-bus"; - reg = <0x1F800000 0x800000>; - ranges = <0x0 0x1F800000 0x7FFFFF>; + reg = <0x1f800000 0x800000>; + ranges = <0x0 0x1f800000 0x7fffff>; icu0: icu@80200 { #interrupt-cells = <1>;
@@ -24,18 +24,18 @@ reg = <0x80200 0x120>; }; - watchdog@803F0 { + watchdog@803f0 { compatible = "lantiq,wdt"; - reg = <0x803F0 0x10>; + reg = <0x803f0 0x10>; }; }; - sram@1F000000 { + sram@1f000000 { #address-cells = <1>; #size-cells = <1>; compatible = "lantiq,sram"; - reg = <0x1F000000 0x800000>; - ranges = <0x0 0x1F000000 0x7FFFFF>; + reg = <0x1f000000 0x800000>; + ranges = <0x0 0x1f000000 0x7fffff>; eiu0: eiu@101000 { #interrupt-cells = <1>;
@@ -66,41 +66,41 @@ #address-cells = <1>; #size-cells = <1>; compatible = "lantiq,fpi", "simple-bus"; - ranges = <0x0 0x10000000 0xEEFFFFF>; - reg = <0x10000000 0xEF00000>; + ranges = <0x0 0x10000000 0xeefffff>; + reg = <0x10000000 0xef00000>; - gptu@E100A00 { + gptu@e100a00 { compatible = "lantiq,gptu-xway"; - reg = <0xE100A00 0x100>; + reg = <0xe100a00 0x100>; }; - serial@E100C00 { + serial@e100c00 { compatible = "lantiq,asc"; - reg = <0xE100C00 0x400>; + reg = <0xe100c00 0x400>; interrupt-parent = <&icu0>; interrupts = <112 113 114>; }; - dma0: dma@E104100 { + dma0: dma@e104100 { compatible = "lantiq,dma-xway"; - reg = <0xE104100 0x800>; + reg = <0xe104100 0x800>; }; - ebu0: ebu@E105300 { + ebu0: ebu@e105300 { compatible = "lantiq,ebu-xway"; - reg = <0xE105300 0x100>; + reg = <0xe105300 0x100>; }; - pci0: pci@E105400 { + pci0: pci@e105400 { #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; compatible = "lantiq,pci-xway"; bus-range = <0x0 0x0>; ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */ - 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */ + 0x1000000 0 0x00000000 0xae00000 0 0x200000>; /* io space */ reg = <0x7000000 0x8000 /* config space */ - 0xE105400 0x400>; /* pci bridge */ + 0xe105400 0x400>; /* pci bridge */ }; }; };
arch/mips/boot/dts/lantiq/easy50712.dts +7 -7
@@ -52,14 +52,14 @@ }; }; - gpio: pinmux@E100B10 { + gpio: pinmux@e100b10 { compatible = "lantiq,danube-pinctrl"; pinctrl-names = "default"; pinctrl-0 = <&state_default>; #gpio-cells = <2>; gpio-controller; - reg = <0xE100B10 0xA0>; + reg = <0xe100b10 0xa0>; state_default: pinmux { stp {
@@ -82,26 +82,26 @@ }; }; - etop@E180000 { + etop@e180000 { compatible = "lantiq,etop-xway"; - reg = <0xE180000 0x40000>; + reg = <0xe180000 0x40000>; interrupt-parent = <&icu0>; interrupts = <73 78>; phy-mode = "rmii"; mac-address = [ 00 11 22 33 44 55 ]; }; - stp0: stp@E100BB0 { + stp0: stp@e100bb0 { #gpio-cells = <2>; compatible = "lantiq,gpio-stp-xway"; gpio-controller; - reg = <0xE100BB0 0x40>; + reg = <0xe100bb0 0x40>; lantiq,shadow = <0xfff>; lantiq,groups = <0x3>; }; - pci@E105400 { + pci@e105400 { lantiq,bus-clock = <33333333>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = <
Signature · 1 line
2.11.0
PATCH RESEND 2/14 MIPS: dts: Add aliases node for lantiq danube serial
In reply to Songjun WuPrevious implementation uses a hard-coded register value to check if the current serial entity is the console entity.
Now the lantiq serial driver uses the aliases for the index of the serial port.
The lantiq danube serial dts are updated with aliases to support this.
---
arch/mips/boot/dts/lantiq/danube.dtsi | 2 +- arch/mips/boot/dts/lantiq/easy50712.dts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-)
arch/mips/boot/dts/lantiq/danube.dtsi +1 -1
@@ -74,7 +74,7 @@ reg = <0xe100a00 0x100>; }; - serial@e100c00 { + asc1: serial@e100c00 { compatible = "lantiq,asc"; reg = <0xe100c00 0x400>; interrupt-parent = <&icu0>;
arch/mips/boot/dts/lantiq/easy50712.dts +4 -0
@@ -4,6 +4,10 @@ /include/ "danube.dtsi" / { + aliases { + serial0 = &asc1; + }; + chosen { bootargs = "console=ttyLTQ0,115200 init=/etc/preinit"; };
Signature · 1 line
2.11.0
PATCH RESEND 3/14 serial: lantiq: Get serial id from dts
In reply to Songjun WuGet serial id from dts, also keep backward compatible when dts is not updated.
---
drivers/tty/serial/lantiq.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/tty/serial/lantiq.c +15 -4
@@ -688,7 +688,7 @@ lqasc_probe(struct platform_device *pdev)struct ltq_uart_port *ltq_port;struct uart_port *port;struct resource *mmres, irqres[3 ]; -int line =0 ; +int line;int ret; mmres =platform_get_resource (pdev,IORESOURCE_MEM ,0 );
@@ -699,9 +699,20 @@ lqasc_probe(struct platform_device *pdev)return -ENODEV ; } -/* check if this is the console port */ -if (mmres->start !=CPHYSADDR (LTQ_EARLY_ASC )) - line =1 ; +/* get serial id */ + line =of_alias_get_id (node,"serial" ); +if (line <0 ) { +if (IS_ENABLED (CONFIG_LANTIQ )) { +if (mmres->start ==CPHYSADDR (LTQ_EARLY_ASC )) + line =0 ; +else + line =1 ; + }else { +dev_err (&pdev->dev,"failed to get alias id, errno %d\n" , + line); +return line; + } + }if (lqasc_port[line]) {dev_err (&pdev->dev,"port %d already allocated\n" , line);
Signature · 1 line
2.11.0
PATCH RESEND 4/14 serial: lantiq: Change ltq_w32_mask to asc_update_bits
In reply to Songjun Wultq prefix is platform specific function, asc prefix is more generic.
---
drivers/tty/serial/lantiq.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-)
drivers/tty/serial/lantiq.c +20 -13
@@ -113,6 +113,13 @@ struct ltq_uart_port {unsigned int err_irq; }; +static inline void asc_update_bits (u32 clear,u32 set,void __iomem *reg) +{ +u32 tmp =readl (reg); + +writel ((tmp & ~clear) | set, reg); +} +static inline struct ltq_uart_port *to_ltq_uart_port (struct uart_port *port) {
@@ -163,16 +170,16 @@ lqasc_rx_chars(struct uart_port *port)if (rsr &ASCSTATE_ANY ) {if (rsr &ASCSTATE_PE ) { port->icount.parity++; -ltq_w32_mask (0 ,ASCWHBSTATE_CLRPE , +asc_update_bits (0 ,ASCWHBSTATE_CLRPE , port->membase +LTQ_ASC_WHBSTATE ); }else if (rsr &ASCSTATE_FE ) { port->icount.frame++; -ltq_w32_mask (0 ,ASCWHBSTATE_CLRFE , +asc_update_bits (0 ,ASCWHBSTATE_CLRFE , port->membase +LTQ_ASC_WHBSTATE ); }if (rsr &ASCSTATE_ROE ) { port->icount.overrun++; -ltq_w32_mask (0 ,ASCWHBSTATE_CLRROE , +asc_update_bits (0 ,ASCWHBSTATE_CLRROE , port->membase +LTQ_ASC_WHBSTATE ); }
@@ -252,7 +259,7 @@ lqasc_err_int(int irq, void *_port)struct uart_port *port = (struct uart_port *)_port;spin_lock_irqsave (<q_asc_lock, flags);/* clear any pending interrupts */ -ltq_w32_mask (0 ,ASCWHBSTATE_CLRPE |ASCWHBSTATE_CLRFE | +asc_update_bits (0 ,ASCWHBSTATE_CLRPE |ASCWHBSTATE_CLRFE |ASCWHBSTATE_CLRROE , port->membase +LTQ_ASC_WHBSTATE );spin_unlock_irqrestore (<q_asc_lock, flags);return IRQ_HANDLED ;
@@ -304,7 +311,7 @@ lqasc_startup(struct uart_port *port)clk_enable (ltq_port->clk); port->uartclk =clk_get_rate (ltq_port->fpiclk); -ltq_w32_mask (ASCCLC_DISS |ASCCLC_RMCMASK , (1 <<ASCCLC_RMCOFFSET ), +asc_update_bits (ASCCLC_DISS |ASCCLC_RMCMASK , (1 <<ASCCLC_RMCOFFSET ), port->membase +LTQ_ASC_CLC );ltq_w32 (0 , port->membase +LTQ_ASC_PISEL );
@@ -320,7 +327,7 @@ lqasc_startup(struct uart_port *port)* setting enable bits */ wmb (); -ltq_w32_mask (0 ,ASCCON_M_8ASYNC |ASCCON_FEN |ASCCON_TOEN | +asc_update_bits (0 ,ASCCON_M_8ASYNC |ASCCON_FEN |ASCCON_TOEN |ASCCON_ROEN , port->membase +LTQ_ASC_CON ); retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
@@ -364,9 +371,9 @@ lqasc_shutdown(struct uart_port *port)free_irq (ltq_port->err_irq, port);ltq_w32 (0 , port->membase +LTQ_ASC_CON ); -ltq_w32_mask (ASCRXFCON_RXFEN ,ASCRXFCON_RXFFLU , +asc_update_bits (ASCRXFCON_RXFEN ,ASCRXFCON_RXFFLU , port->membase +LTQ_ASC_RXFCON ); -ltq_w32_mask (ASCTXFCON_TXFEN ,ASCTXFCON_TXFFLU , +asc_update_bits (ASCTXFCON_TXFEN ,ASCTXFCON_TXFFLU , port->membase +LTQ_ASC_TXFCON );if (!IS_ERR (ltq_port->clk))clk_disable (ltq_port->clk);
@@ -438,7 +445,7 @@ lqasc_set_termios(struct uart_port *port,spin_lock_irqsave (<q_asc_lock, flags);/* set up CON */ -ltq_w32_mask (0 , con, port->membase +LTQ_ASC_CON ); +asc_update_bits (0 , con, port->membase +LTQ_ASC_CON );/* Set baud rate - take a divider of 2 into account */ baud =uart_get_baud_rate (port, new, old,0 , port->uartclk /16 );
@@ -446,19 +453,19 @@ lqasc_set_termios(struct uart_port *port, divisor = divisor /2 -1 ;/* disable the baudrate generator */ -ltq_w32_mask (ASCCON_R ,0 , port->membase +LTQ_ASC_CON ); +asc_update_bits (ASCCON_R ,0 , port->membase +LTQ_ASC_CON );/* make sure the fractional divider is off */ -ltq_w32_mask (ASCCON_FDE ,0 , port->membase +LTQ_ASC_CON ); +asc_update_bits (ASCCON_FDE ,0 , port->membase +LTQ_ASC_CON );/* set up to use divisor of 2 */ -ltq_w32_mask (ASCCON_BRS ,0 , port->membase +LTQ_ASC_CON ); +asc_update_bits (ASCCON_BRS ,0 , port->membase +LTQ_ASC_CON );/* now we can write the new baudrate into the register */ ltq_w32 (divisor, port->membase +LTQ_ASC_BG );/* turn the baudrate generator back on */ -ltq_w32_mask (0 ,ASCCON_R , port->membase +LTQ_ASC_CON ); +asc_update_bits (0 ,ASCCON_R , port->membase +LTQ_ASC_CON );/* enable rx */ ltq_w32 (ASCWHBSTATE_SETREN , port->membase +LTQ_ASC_WHBSTATE );
Signature · 1 line
2.11.0
PATCH RESEND 5/14 MIPS: lantiq: Unselect SWAP_IO_SPACE when LANTIQ is selected
In reply to Songjun WuSWAP_IO_SPACE macro prevents serial driver /drivers/tty/serial/lantiq.c to use readl/writel to replace ltq_r32/w32 which are SoC or platform specific APIs.
readl/writel are used for this serial driver to support multiple platforms and multiple architectures. The legacy lantiq platform(Danube) enables SWAP_IO_SPACE for supporting PCI due to some hardware bugs.
It's a little-endian bus plus PCI TX/RX swap enable impacted both data and control path for MIPS based platforms. But it is better to let PCI device driver to do endian swap since SWAP_IO_SPACE is a global wide macro which potentially impacts other peripheral like USB. ltq_r32/ltq_w32 is not impacted in other device drivers based on MIPS when SWAP_IO_SPACE is not selected as they use non-byte swapping OS API (__raw_read/__raw_writel).
---
arch/mips/Kconfig | 1 - 1 file changed, 1 deletion(-)
arch/mips/Kconfig +0 -1
@@ -406,7 +406,6 @@ config LANTIQ select SYS_SUPPORTS_VPE_LOADER select SYS_HAS_EARLY_PRINTK select GPIOLIB - select SWAP_IO_SPACE select BOOT_RAW select CLKDEV_LOOKUP select USE_OF
Signature · 1 line
2.11.0
PATCH RESEND 6/14 serial: lantiq: Use readl/writel instead of ltq_r32/ltq_w32
In reply to Songjun WuPrevious implementation uses platform-dependent functions ltq_w32()/ltq_r32() to access registers. Those functions are not available for other SoC which uses the same IP.
Change to OS provided readl()/writel() and readb()/writeb(), so that different SoCs can use the same driver.
---
drivers/tty/serial/lantiq.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
drivers/tty/serial/lantiq.c +19 -19
@@ -145,7 +145,7 @@ lqasc_start_tx(struct uart_port *port)static void lqasc_stop_rx (struct uart_port *port) { -ltq_w32 (ASCWHBSTATE_CLRREN , port->membase +LTQ_ASC_WHBSTATE ); +writel (ASCWHBSTATE_CLRREN , port->membase +LTQ_ASC_WHBSTATE ); } static int
@@ -154,11 +154,11 @@ lqasc_rx_chars(struct uart_port *port)struct tty_port *tport = &port->state->port;unsigned int ch =0 , rsr =0 , fifocnt; - fifocnt =ltq_r32 (port->membase +LTQ_ASC_FSTAT ) &ASCFSTAT_RXFFLMASK ; + fifocnt =readl (port->membase +LTQ_ASC_FSTAT ) &ASCFSTAT_RXFFLMASK ;while (fifocnt--) {u8 flag =TTY_NORMAL ; - ch =ltq_r8 (port->membase +LTQ_ASC_RBUF ); - rsr = (ltq_r32 (port->membase +LTQ_ASC_STATE ) + ch =readb (port->membase +LTQ_ASC_RBUF ); + rsr = (readl (port->membase +LTQ_ASC_STATE ) &ASCSTATE_ANY ) |UART_DUMMY_UER_RX ;tty_flip_buffer_push (tport); port->icount.rx++;
@@ -218,10 +218,10 @@ lqasc_tx_chars(struct uart_port *port)return ; } -while (((ltq_r32 (port->membase +LTQ_ASC_FSTAT ) & +while (((readl (port->membase +LTQ_ASC_FSTAT ) &ASCFSTAT_TXFREEMASK ) >>ASCFSTAT_TXFREEOFF ) !=0 ) {if (port->x_char) { -ltq_w8 (port->x_char, port->membase +LTQ_ASC_TBUF ); +writeb (port->x_char, port->membase +LTQ_ASC_TBUF ); port->icount.tx++; port->x_char =0 ;continue ;
@@ -230,7 +230,7 @@ lqasc_tx_chars(struct uart_port *port)if (uart_circ_empty (xmit))break ; -ltq_w8 (port->state->xmit.buf[port->state->xmit.tail], +writeb (port->state->xmit.buf[port->state->xmit.tail], port->membase +LTQ_ASC_TBUF ); xmit->tail = (xmit->tail +1 ) & (UART_XMIT_SIZE -1 ); port->icount.tx++;
@@ -246,7 +246,7 @@ lqasc_tx_int(int irq, void *_port)unsigned long flags;struct uart_port *port = (struct uart_port *)_port;spin_lock_irqsave (<q_asc_lock, flags); -ltq_w32 (ASC_IRNCR_TIR , port->membase +LTQ_ASC_IRNCR ); +writel (ASC_IRNCR_TIR , port->membase +LTQ_ASC_IRNCR );spin_unlock_irqrestore (<q_asc_lock, flags);lqasc_start_tx (port);return IRQ_HANDLED ;
@@ -271,7 +271,7 @@ lqasc_rx_int(int irq, void *_port)unsigned long flags;struct uart_port *port = (struct uart_port *)_port;spin_lock_irqsave (<q_asc_lock, flags); -ltq_w32 (ASC_IRNCR_RIR , port->membase +LTQ_ASC_IRNCR ); +writel (ASC_IRNCR_RIR , port->membase +LTQ_ASC_IRNCR );lqasc_rx_chars (port);spin_unlock_irqrestore (<q_asc_lock, flags);return IRQ_HANDLED ;
@@ -281,7 +281,7 @@ static unsigned int lqasc_tx_empty(struct uart_port *port) {int status; - status =ltq_r32 (port->membase +LTQ_ASC_FSTAT ) &ASCFSTAT_TXFFLMASK ; + status =readl (port->membase +LTQ_ASC_FSTAT ) &ASCFSTAT_TXFFLMASK ;return status ?0 :TIOCSER_TEMT ; }
@@ -314,12 +314,12 @@ lqasc_startup(struct uart_port *port)asc_update_bits (ASCCLC_DISS |ASCCLC_RMCMASK , (1 <<ASCCLC_RMCOFFSET ), port->membase +LTQ_ASC_CLC ); -ltq_w32 (0 , port->membase +LTQ_ASC_PISEL ); -ltq_w32 ( +writel (0 , port->membase +LTQ_ASC_PISEL ); +writel ( ((TXFIFO_FL <<ASCTXFCON_TXFITLOFF ) &ASCTXFCON_TXFITLMASK ) |ASCTXFCON_TXFEN |ASCTXFCON_TXFFLU , port->membase +LTQ_ASC_TXFCON ); -ltq_w32 ( +writel ( ((RXFIFO_FL <<ASCRXFCON_RXFITLOFF ) &ASCRXFCON_RXFITLMASK ) |ASCRXFCON_RXFEN |ASCRXFCON_RXFFLU , port->membase +LTQ_ASC_RXFCON );
@@ -351,7 +351,7 @@ lqasc_startup(struct uart_port *port) goto err2; } -ltq_w32 (ASC_IRNREN_RX |ASC_IRNREN_ERR |ASC_IRNREN_TX , +writel (ASC_IRNREN_RX |ASC_IRNREN_ERR |ASC_IRNREN_TX , port->membase +LTQ_ASC_IRNREN );return 0 ;
@@ -370,7 +370,7 @@ lqasc_shutdown(struct uart_port *port)free_irq (ltq_port->rx_irq, port);free_irq (ltq_port->err_irq, port); -ltq_w32 (0 , port->membase +LTQ_ASC_CON ); +writel (0 , port->membase +LTQ_ASC_CON );asc_update_bits (ASCRXFCON_RXFEN ,ASCRXFCON_RXFFLU , port->membase +LTQ_ASC_RXFCON ); asc_update_bits(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
@@ -462,13 +462,13 @@ lqasc_set_termios(struct uart_port *port,asc_update_bits (ASCCON_BRS ,0 , port->membase +LTQ_ASC_CON );/* now we can write the new baudrate into the register */ -ltq_w32 (divisor, port->membase +LTQ_ASC_BG ); +writel (divisor, port->membase +LTQ_ASC_BG );/* turn the baudrate generator back on */ asc_update_bits (0 ,ASCCON_R , port->membase +LTQ_ASC_CON );/* enable rx */ -ltq_w32 (ASCWHBSTATE_SETREN , port->membase +LTQ_ASC_WHBSTATE ); +writel (ASCWHBSTATE_SETREN , port->membase +LTQ_ASC_WHBSTATE );spin_unlock_irqrestore (<q_asc_lock, flags);
@@ -579,10 +579,10 @@ lqasc_console_putchar(struct uart_port *port, int ch)return ;do { - fifofree = (ltq_r32 (port->membase +LTQ_ASC_FSTAT ) + fifofree = (readl (port->membase +LTQ_ASC_FSTAT ) &ASCFSTAT_TXFREEMASK ) >>ASCFSTAT_TXFREEOFF ; }while (fifofree ==0 ); -ltq_w8 (ch, port->membase +LTQ_ASC_TBUF ); +writeb (ch, port->membase +LTQ_ASC_TBUF ); } static void lqasc_serial_port_write(struct uart_port *port, const char *s,
Signature · 1 line
2.11.0
PATCH RESEND 7/14 serial: lantiq: Rename fpiclk to freqclk
In reply to Songjun Wufpiclk is platform specific, freqclk is more generic.
---
drivers/tty/serial/lantiq.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/tty/serial/lantiq.c +5 -5
@@ -105,7 +105,7 @@ static DEFINE_SPINLOCK(ltq_asc_lock);struct ltq_uart_port {struct uart_port port;/* clock used to derive divider */ -struct clk *fpiclk; +struct clk *freqclk;/* clock gating of the ASC core */ struct clk *clk;unsigned int tx_irq;
@@ -309,7 +309,7 @@ lqasc_startup(struct uart_port *port)if (!IS_ERR (ltq_port->clk))clk_enable (ltq_port->clk); - port->uartclk =clk_get_rate (ltq_port->fpiclk); + port->uartclk =clk_get_rate (ltq_port->freqclk);asc_update_bits (ASCCLC_DISS |ASCCLC_RMCMASK , (1 <<ASCCLC_RMCOFFSET ), port->membase +LTQ_ASC_CLC );
@@ -632,7 +632,7 @@ lqasc_console_setup(struct console *co, char *options)if (!IS_ERR (ltq_port->clk))clk_enable (ltq_port->clk); - port->uartclk =clk_get_rate (ltq_port->fpiclk); + port->uartclk =clk_get_rate (ltq_port->freqclk);if (options)uart_parse_options (options, &baud, &parity, &bits, &flow);
@@ -744,8 +744,8 @@ lqasc_probe(struct platform_device *pdev) port->irq = irqres[0 ].start; port->mapbase = mmres->start; - ltq_port->fpiclk =clk_get_fpi (); -if (IS_ERR (ltq_port->fpiclk)) { + ltq_port->freqclk =clk_get_fpi (); +if (IS_ERR (ltq_port->freqclk)) {pr_err ("failed to get fpi clk\n" );return -ENOENT ; }
Signature · 1 line
2.11.0
PATCH RESEND 8/14 serial: lantiq: Replace clk_enable/clk_disable with clk generic API
In reply to Songjun WuThe clk driver has introduced new clock APIs that replace the existing clk_enable and clk_disable.
- clk_enable() APIs is replaced with clk_prepare_enable()
- clk_disable() API is replaced with clk_disable_unprepare()
---
drivers/tty/serial/lantiq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/tty/serial/lantiq.c +3 -3
@@ -308,7 +308,7 @@ lqasc_startup(struct uart_port *port)int retval;if (!IS_ERR (ltq_port->clk)) -clk_enable (ltq_port->clk); +clk_prepare_enable (ltq_port->clk); port->uartclk =clk_get_rate (ltq_port->freqclk); asc_update_bits(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
@@ -376,7 +376,7 @@ lqasc_shutdown(struct uart_port *port)asc_update_bits (ASCTXFCON_TXFEN ,ASCTXFCON_TXFFLU , port->membase +LTQ_ASC_TXFCON );if (!IS_ERR (ltq_port->clk)) -clk_disable (ltq_port->clk); +clk_disable_unprepare (ltq_port->clk); } static void
@@ -630,7 +630,7 @@ lqasc_console_setup(struct console *co, char *options) port = <q_port->port;if (!IS_ERR (ltq_port->clk)) -clk_enable (ltq_port->clk); +clk_prepare_enable (ltq_port->clk); port->uartclk =clk_get_rate (ltq_port->freqclk);
Signature · 1 line
2.11.0
PATCH RESEND 9/14 serial: lantiq: Add CCF support
In reply to Songjun WuPrevious implementation uses platform-dependent API to get the clock. Those functions are not available for other SoC which uses the same IP. The CCF (Common Clock Framework) have an abstraction based APIs for clock. In future, the platform specific code will be removed when the legacy soc use CCF as well.
Change to use CCF APIs to get clock and rate. So that different SoCs can use the same driver.
---
drivers/tty/serial/lantiq.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/tty/serial/lantiq.c +10 -2
@@ -744,14 +744,22 @@ lqasc_probe(struct platform_device *pdev) port->irq = irqres[0 ].start; port->mapbase = mmres->start; - ltq_port->freqclk =clk_get_fpi (); +if (IS_ENABLED (CONFIG_LANTIQ ) && !IS_ENABLED (CONFIG_COMMON_CLK )) + ltq_port->freqclk =clk_get_fpi (); +else + ltq_port->freqclk =devm_clk_get (&pdev->dev,"freq" ); + +if (IS_ERR (ltq_port->freqclk)) {pr_err ("failed to get fpi clk\n" );return -ENOENT ; }/* not all asc ports have clock gates, lets ignore the return code */ - ltq_port->clk =clk_get (&pdev->dev,NULL ); +if (IS_ENABLED (CONFIG_LANTIQ ) && !IS_ENABLED (CONFIG_COMMON_CLK )) + ltq_port->clk =clk_get (&pdev->dev,NULL ); +else + ltq_port->clk =devm_clk_get (&pdev->dev,"asc" ); ltq_port->tx_irq = irqres[0 ].start; ltq_port->rx_irq = irqres[1 ].start;
Signature · 1 line
2.11.0
PATCH RESEND 10/14 serial: lantiq: Reorder the head files
In reply to Songjun WuReorder the head files according to the coding style.
---
drivers/tty/serial/lantiq.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/tty/serial/lantiq.c +12 -12
@@ -8,22 +8,22 @@* Copyright (C) 2010 Thomas Langer, <[email protected]> */ -#include <linux/slab.h> -#include <linux/ioport.h> -#include <linux/init.h> +#include <linux/clk.h> #include <linux/console.h> -#include <linux/sysrq.h> #include <linux/device.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial_core.h> -#include <linux/serial.h> -#include <linux/of_platform.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/ioport.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/gpio.h> +#include <linux/of_platform.h> +#include <linux/serial.h> +#include <linux/serial_core.h> +#include <linux/slab.h> +#include <linux/sysrq.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> #include <lantiq_soc.h>
Signature · 1 line
2.11.0
PATCH RESEND 11/14 include: Add lantiq.h in include/linux/
In reply to Songjun WuIn some existing lantiq driver, the C codes include lantiq_soc.h header file directly.
./arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h ./arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
Those drivers need to be extended to support more platform. lantiq.h is added in include/linux/ to make it globally available and provides some wrapper codes.
---
include/linux/lantiq.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 include/linux/lantiq.h
include/linux/lantiq.h new file +23 -0
@@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __LINUX_LANTIQ_H +#define __LINUX_LANTIQ_H + +#ifdef CONFIG_LANTIQ +#include <lantiq_soc.h> +#else + +#ifndef LTQ_EARLY_ASC +#define LTQ_EARLY_ASC 0 +#endif + +#ifndef CPHYSADDR +#define CPHYSADDR (a) 0 +#endif + +static inline struct clk *clk_get_fpi (void ) +{ +return NULL ; +} +#endif /* CONFIG_LANTIQ */ +#endif /* __LINUX_LANTIQ_H */
Signature · 1 line
2.11.0
PATCH RESEND 12/14 serial: lantiq: Replace lantiq_soc.h with lantiq.h
In reply to Songjun WuIn this existing lantiq serial driver, lantiq_soc.h is defined in the arch directory,
./arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h ./arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
This driver need to be extended to support more platform, lantiq.h is added in include/linux/ to make it globally available and provide some wrapper code. Use lantiq.h to make the driver can find the correct header file.
---
drivers/tty/serial/lantiq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/tty/serial/lantiq.c +1 -2
@@ -15,6 +15,7 @@#include <linux/init.h> #include <linux/io.h> #include <linux/ioport.h> +#include <linux/lantiq.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_platform.h>
@@ -25,8 +26,6 @@#include <linux/tty.h> #include <linux/tty_flip.h> -#include <lantiq_soc.h> -#define PORT_LTQ_ASC 111#define MAXPORTS 2#define UART_DUMMY_UER_RX 1
Signature · 1 line
2.11.0
PATCH RESEND 13/14 serial: lantiq: Change init_lqasc to static declaration
In reply to Songjun Wuinit_lqasc() is only used internally, change to static declaration.
---
drivers/tty/serial/lantiq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/lantiq.c +1 -1
@@ -784,7 +784,7 @@ static struct platform_driver lqasc_driver = { }, }; -int __init +static int __init init_lqasc (void ) {int ret;
Signature · 1 line
2.11.0
PATCH RESEND 14/14 dt-bindings: serial: lantiq: Add optional properties for CCF
In reply to Songjun WuClocks and clock-names are updated in device tree binding.
---
Documentation/devicetree/bindings/serial/lantiq_asc.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
Documentation/devicetree/bindings/serial/lantiq_asc.txt +15 -0
@@ -6,8 +6,23 @@ Required properties: - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier depends on the interrupt-parent interrupt controller. +Optional properties: +- clocks: Should contain frequency clock and gate clock +- clock-names: Should be "freq" and "asc" + Example: +asc0: serial@16600000 { + compatible = "lantiq,asc"; + reg = <0x16600000 0x100000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cgu CLK_SSX4>, <&cgu GCLK_UART>; + clock-names = "freq", "asc"; +}; + asc1: serial@e100c00 { compatible = "lantiq,asc"; reg = <0xE100C00 0x400>;
Signature · 1 line
2.11.0