[PATCH 0/8] Improve Rx/Tx DMA implementation
Bhuvanchandra DV (5): tty: serial: fsl_lpuart: Fix broken 8m/s1 support tty: serial: fsl-lpuart: Use cyclic DMA for Rx tty: serial: fsl-lpuart: Use scatter/gather DMA for Tx Drop PIO to DMA switching and use scatter/gather DMA for Tx path to improve performance. tty: serial: fsl-lpuart: Update suspend/resume for DMA mode tty: serial: fsl_lpuart: Add support for RS-485 Stefan Agner (3): tty: serial: fsl_lpuart: consider TX FIFO too in tx_empty tty: serial: fsl_lpuart: support suspend/resume tty: serial: fsl_lpuart: fix clearing of receive flag drivers/clk/imx/clk-vf610.c | 12 +- drivers/tty/serial/fsl_lpuart.c | 810 +++- 2 files changed, 482 insertions(+), 340 deletions(-) -- 2.8.3
[PATCH 7/8] tty: serial: fsl-lpuart: Update suspend/resume for DMA mode
When DMA mode is enabled one need to make sure the DMA channels are idle before entering suspend mode especially when UART ports which are set as wakeup source and console port with no_console_suspend is set. This patch takes care of gracefully releasing DMA channels for the above two cases and start the DMA at resume. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/tty/serial/fsl_lpuart.c | 44 + 1 file changed, 44 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 27687d5..134090a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1943,6 +1943,30 @@ static int lpuart_suspend(struct device *dev) } uart_suspend_port(_reg, >port); + + if (sport->lpuart_dma_rx_use) { + /* +* EDMA driver during suspend will forcefully release any +* non-idle DMA channels. If port wakeup is enabled or if port +* is console port or 'no_console_suspend' is set the Rx DMA +* cannot resume as as expected, hence gracefully release the +* Rx DMA path before suspend and start Rx DMA path on resume. +*/ + if (sport->port.irq_wake) { + del_timer_sync(>lpuart_timer); + lpuart_dma_rx_free(>port); + } + + /* Disable Rx DMA to use UART port as wakeup source */ + writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_RDMAS, + sport->port.membase + UARTCR5); + } + + if (sport->lpuart_dma_tx_use) { + sport->dma_tx_in_progress = false; + dmaengine_terminate_all(sport->dma_tx_chan); + } + if (sport->port.suspended && !sport->port.irq_wake) clk_disable_unprepare(sport->clk); @@ -1970,6 +1994,26 @@ static int lpuart_resume(struct device *dev) writeb(temp, sport->port.membase + UARTCR2); } + if (sport->lpuart_dma_rx_use) { + if (sport->port.irq_wake) { + if (!lpuart_start_rx_dma(sport)) { + sport->lpuart_dma_rx_use = true; + rx_dma_timer_init(sport); + } else { + sport->lpuart_dma_rx_use = false; + } + } + } + + if (sport->dma_tx_chan && !lpuart_dma_tx_request(>port)) { + init_waitqueue_head(>dma_wait); + sport->lpuart_dma_tx_use = true; + writeb(readb(sport->port.membase + UARTCR5) | + UARTCR5_TDMAS, sport->port.membase + UARTCR5); + } else { + sport->lpuart_dma_tx_use = false; + } + uart_resume_port(_reg, >port); return 0; -- 2.8.3
[PATCH 2/8] tty: serial: fsl_lpuart: support suspend/resume
From: Stefan AgnerIn order to allow wake support in STOP sleep mode, clocks are needed. Use imx_clk_gate2_cgr to disable automatic clock gating in low power mode STOP. This allows to enable wake by UART using: echo enabled > /sys/class/tty/ttyLP0/power/wakeup However, if wake is not enabled, the driver should disable the clocks explicitly to save power. Signed-off-by: Stefan Agner --- drivers/clk/imx/clk-vf610.c | 12 ++-- drivers/tty/serial/fsl_lpuart.c | 16 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 3a1f244..0476353 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -315,12 +315,12 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7)); - clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7)); - clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8)); - clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10)); - clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10)); + clk[VF610_CLK_UART0] = imx_clk_gate2_cgr("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7), 0x2); + clk[VF610_CLK_UART1] = imx_clk_gate2_cgr("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8), 0x2); + clk[VF610_CLK_UART2] = imx_clk_gate2_cgr("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9), 0x2); + clk[VF610_CLK_UART3] = imx_clk_gate2_cgr("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10), 0x2); + clk[VF610_CLK_UART4] = imx_clk_gate2_cgr("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9), 0x2); + clk[VF610_CLK_UART5] = imx_clk_gate2_cgr("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10), 0x2); clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index fabfa7e..75a2098 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -483,9 +483,8 @@ static void lpuart_dma_rx_complete(void *arg) spin_unlock_irqrestore(>port.lock, flags); } -static void lpuart_timer_func(unsigned long data) +static void lpuart_dma_rx_terminate(struct lpuart_port *sport) { - struct lpuart_port *sport = (struct lpuart_port *)data; struct tty_port *port = >port.state->port; struct dma_tx_state state; unsigned long flags; @@ -510,6 +509,11 @@ static void lpuart_timer_func(unsigned long data) spin_unlock_irqrestore(>port.lock, flags); } +static void lpuart_timer_func(unsigned long data) +{ + lpuart_dma_rx_terminate((struct lpuart_port *)data); +} + static inline void lpuart_prepare_rx(struct lpuart_port *sport) { unsigned long flags; @@ -1925,7 +1929,12 @@ static int lpuart_suspend(struct device *dev) writeb(temp, sport->port.membase + UARTCR2); } + if (sport->dma_rx_in_progress) + lpuart_dma_rx_terminate(sport); + uart_suspend_port(_reg, >port); + if (sport->port.suspended && !sport->port.irq_wake) + clk_disable_unprepare(sport->clk); return 0; } @@ -1935,6 +1944,9 @@ static int lpuart_resume(struct device *dev) struct lpuart_port *sport = dev_get_drvdata(dev); unsigned long temp; + if (sport->port.suspended && !sport->port.irq_wake) + clk_prepare_enable(sport->clk); + if (sport->lpuart32) { lpuart32_setup_watermark(sport); temp = lpuart32_read(sport->port.membase + UARTCTRL); -- 2.8.3
[PATCH 2/8] tty: serial: fsl_lpuart: support suspend/resume
From: Stefan Agner In order to allow wake support in STOP sleep mode, clocks are needed. Use imx_clk_gate2_cgr to disable automatic clock gating in low power mode STOP. This allows to enable wake by UART using: echo enabled > /sys/class/tty/ttyLP0/power/wakeup However, if wake is not enabled, the driver should disable the clocks explicitly to save power. Signed-off-by: Stefan Agner --- drivers/clk/imx/clk-vf610.c | 12 ++-- drivers/tty/serial/fsl_lpuart.c | 16 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 3a1f244..0476353 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -315,12 +315,12 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7)); - clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7)); - clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8)); - clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10)); - clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10)); + clk[VF610_CLK_UART0] = imx_clk_gate2_cgr("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7), 0x2); + clk[VF610_CLK_UART1] = imx_clk_gate2_cgr("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8), 0x2); + clk[VF610_CLK_UART2] = imx_clk_gate2_cgr("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9), 0x2); + clk[VF610_CLK_UART3] = imx_clk_gate2_cgr("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10), 0x2); + clk[VF610_CLK_UART4] = imx_clk_gate2_cgr("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9), 0x2); + clk[VF610_CLK_UART5] = imx_clk_gate2_cgr("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10), 0x2); clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index fabfa7e..75a2098 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -483,9 +483,8 @@ static void lpuart_dma_rx_complete(void *arg) spin_unlock_irqrestore(>port.lock, flags); } -static void lpuart_timer_func(unsigned long data) +static void lpuart_dma_rx_terminate(struct lpuart_port *sport) { - struct lpuart_port *sport = (struct lpuart_port *)data; struct tty_port *port = >port.state->port; struct dma_tx_state state; unsigned long flags; @@ -510,6 +509,11 @@ static void lpuart_timer_func(unsigned long data) spin_unlock_irqrestore(>port.lock, flags); } +static void lpuart_timer_func(unsigned long data) +{ + lpuart_dma_rx_terminate((struct lpuart_port *)data); +} + static inline void lpuart_prepare_rx(struct lpuart_port *sport) { unsigned long flags; @@ -1925,7 +1929,12 @@ static int lpuart_suspend(struct device *dev) writeb(temp, sport->port.membase + UARTCR2); } + if (sport->dma_rx_in_progress) + lpuart_dma_rx_terminate(sport); + uart_suspend_port(_reg, >port); + if (sport->port.suspended && !sport->port.irq_wake) + clk_disable_unprepare(sport->clk); return 0; } @@ -1935,6 +1944,9 @@ static int lpuart_resume(struct device *dev) struct lpuart_port *sport = dev_get_drvdata(dev); unsigned long temp; + if (sport->port.suspended && !sport->port.irq_wake) + clk_prepare_enable(sport->clk); + if (sport->lpuart32) { lpuart32_setup_watermark(sport); temp = lpuart32_read(sport->port.membase + UARTCTRL); -- 2.8.3
[PATCH 0/8] Improve Rx/Tx DMA implementation
Bhuvanchandra DV (5): tty: serial: fsl_lpuart: Fix broken 8m/s1 support tty: serial: fsl-lpuart: Use cyclic DMA for Rx tty: serial: fsl-lpuart: Use scatter/gather DMA for Tx Drop PIO to DMA switching and use scatter/gather DMA for Tx path to improve performance. tty: serial: fsl-lpuart: Update suspend/resume for DMA mode tty: serial: fsl_lpuart: Add support for RS-485 Stefan Agner (3): tty: serial: fsl_lpuart: consider TX FIFO too in tx_empty tty: serial: fsl_lpuart: support suspend/resume tty: serial: fsl_lpuart: fix clearing of receive flag drivers/clk/imx/clk-vf610.c | 12 +- drivers/tty/serial/fsl_lpuart.c | 810 +++- 2 files changed, 482 insertions(+), 340 deletions(-) -- 2.8.3
[PATCH 7/8] tty: serial: fsl-lpuart: Update suspend/resume for DMA mode
When DMA mode is enabled one need to make sure the DMA channels are idle before entering suspend mode especially when UART ports which are set as wakeup source and console port with no_console_suspend is set. This patch takes care of gracefully releasing DMA channels for the above two cases and start the DMA at resume. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 44 + 1 file changed, 44 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 27687d5..134090a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1943,6 +1943,30 @@ static int lpuart_suspend(struct device *dev) } uart_suspend_port(_reg, >port); + + if (sport->lpuart_dma_rx_use) { + /* +* EDMA driver during suspend will forcefully release any +* non-idle DMA channels. If port wakeup is enabled or if port +* is console port or 'no_console_suspend' is set the Rx DMA +* cannot resume as as expected, hence gracefully release the +* Rx DMA path before suspend and start Rx DMA path on resume. +*/ + if (sport->port.irq_wake) { + del_timer_sync(>lpuart_timer); + lpuart_dma_rx_free(>port); + } + + /* Disable Rx DMA to use UART port as wakeup source */ + writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_RDMAS, + sport->port.membase + UARTCR5); + } + + if (sport->lpuart_dma_tx_use) { + sport->dma_tx_in_progress = false; + dmaengine_terminate_all(sport->dma_tx_chan); + } + if (sport->port.suspended && !sport->port.irq_wake) clk_disable_unprepare(sport->clk); @@ -1970,6 +1994,26 @@ static int lpuart_resume(struct device *dev) writeb(temp, sport->port.membase + UARTCR2); } + if (sport->lpuart_dma_rx_use) { + if (sport->port.irq_wake) { + if (!lpuart_start_rx_dma(sport)) { + sport->lpuart_dma_rx_use = true; + rx_dma_timer_init(sport); + } else { + sport->lpuart_dma_rx_use = false; + } + } + } + + if (sport->dma_tx_chan && !lpuart_dma_tx_request(>port)) { + init_waitqueue_head(>dma_wait); + sport->lpuart_dma_tx_use = true; + writeb(readb(sport->port.membase + UARTCR5) | + UARTCR5_TDMAS, sport->port.membase + UARTCR5); + } else { + sport->lpuart_dma_tx_use = false; + } + uart_resume_port(_reg, >port); return 0; -- 2.8.3
[PATCH 3/8] tty: serial: fsl_lpuart: fix clearing of receive flag
From: Stefan AgnerCommit 8e4934c6d6c6 ("tty: serial: fsl_lpuart: clear receive flag on FIFO flush") implemented clearing of the receive flag by reading the status register only. It turned out that even though we flush the FIFO afterwards, a explicit read of the data register is still required. This leads to a FIFO underrun. To avoid this, follow the advice in the overrun "Operation section": Unconditionally clear RXUF after using RXFLUSH. Signed-off-by: Stefan Agner --- drivers/tty/serial/fsl_lpuart.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 75a2098..97c1fda 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -935,13 +935,16 @@ static void lpuart_setup_watermark(struct lpuart_port *sport) writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE, sport->port.membase + UARTPFIFO); - /* explicitly clear RDRF */ - readb(sport->port.membase + UARTSR1); - /* flush Tx and Rx FIFO */ writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH, sport->port.membase + UARTCFIFO); + /* explicitly clear RDRF */ + if (readb(sport->port.membase + UARTSR1) & UARTSR1_RDRF) { + readb(sport->port.membase + UARTDR); + writeb(UARTSFIFO_RXUF, sport->port.membase + UARTSFIFO); + } + writeb(0, sport->port.membase + UARTTWFIFO); writeb(1, sport->port.membase + UARTRWFIFO); -- 2.8.3
[PATCH 4/8] tty: serial: fsl_lpuart: Fix broken 8m/s1 support
By default the driver always configure the mode as 8s1 even when 8m1 mode is selected. Fix this by adding support to control the space/mark bit. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/tty/serial/fsl_lpuart.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 97c1fda..615f191 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1220,13 +1220,14 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long flags; - unsigned char cr1, old_cr1, old_cr2, cr4, bdh, modem; + unsigned char cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem; unsigned int baud; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; unsigned int sbr, brfa; cr1 = old_cr1 = readb(sport->port.membase + UARTCR1); old_cr2 = readb(sport->port.membase + UARTCR2); + cr3 = readb(sport->port.membase + UARTCR3); cr4 = readb(sport->port.membase + UARTCR4); bdh = readb(sport->port.membase + UARTBDH); modem = readb(sport->port.membase + UARTMODEM); @@ -1274,7 +1275,10 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & PARENB)) { if (termios->c_cflag & CMSPAR) { cr1 &= ~UARTCR1_PE; - cr1 |= UARTCR1_M; + if (termios->c_cflag & PARODD) + cr3 |= UARTCR3_T8; + else + cr3 &= ~UARTCR3_T8; } else { cr1 |= UARTCR1_PE; if ((termios->c_cflag & CSIZE) == CS8) @@ -1342,6 +1346,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, writeb(cr4 | brfa, sport->port.membase + UARTCR4); writeb(bdh, sport->port.membase + UARTBDH); writeb(sbr & 0xFF, sport->port.membase + UARTBDL); + writeb(cr3, sport->port.membase + UARTCR3); writeb(cr1, sport->port.membase + UARTCR1); writeb(modem, sport->port.membase + UARTMODEM); -- 2.8.3
[PATCH 3/8] tty: serial: fsl_lpuart: fix clearing of receive flag
From: Stefan Agner Commit 8e4934c6d6c6 ("tty: serial: fsl_lpuart: clear receive flag on FIFO flush") implemented clearing of the receive flag by reading the status register only. It turned out that even though we flush the FIFO afterwards, a explicit read of the data register is still required. This leads to a FIFO underrun. To avoid this, follow the advice in the overrun "Operation section": Unconditionally clear RXUF after using RXFLUSH. Signed-off-by: Stefan Agner --- drivers/tty/serial/fsl_lpuart.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 75a2098..97c1fda 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -935,13 +935,16 @@ static void lpuart_setup_watermark(struct lpuart_port *sport) writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE, sport->port.membase + UARTPFIFO); - /* explicitly clear RDRF */ - readb(sport->port.membase + UARTSR1); - /* flush Tx and Rx FIFO */ writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH, sport->port.membase + UARTCFIFO); + /* explicitly clear RDRF */ + if (readb(sport->port.membase + UARTSR1) & UARTSR1_RDRF) { + readb(sport->port.membase + UARTDR); + writeb(UARTSFIFO_RXUF, sport->port.membase + UARTSFIFO); + } + writeb(0, sport->port.membase + UARTTWFIFO); writeb(1, sport->port.membase + UARTRWFIFO); -- 2.8.3
[PATCH 4/8] tty: serial: fsl_lpuart: Fix broken 8m/s1 support
By default the driver always configure the mode as 8s1 even when 8m1 mode is selected. Fix this by adding support to control the space/mark bit. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 97c1fda..615f191 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1220,13 +1220,14 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long flags; - unsigned char cr1, old_cr1, old_cr2, cr4, bdh, modem; + unsigned char cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem; unsigned int baud; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; unsigned int sbr, brfa; cr1 = old_cr1 = readb(sport->port.membase + UARTCR1); old_cr2 = readb(sport->port.membase + UARTCR2); + cr3 = readb(sport->port.membase + UARTCR3); cr4 = readb(sport->port.membase + UARTCR4); bdh = readb(sport->port.membase + UARTBDH); modem = readb(sport->port.membase + UARTMODEM); @@ -1274,7 +1275,10 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & PARENB)) { if (termios->c_cflag & CMSPAR) { cr1 &= ~UARTCR1_PE; - cr1 |= UARTCR1_M; + if (termios->c_cflag & PARODD) + cr3 |= UARTCR3_T8; + else + cr3 &= ~UARTCR3_T8; } else { cr1 |= UARTCR1_PE; if ((termios->c_cflag & CSIZE) == CS8) @@ -1342,6 +1346,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, writeb(cr4 | brfa, sport->port.membase + UARTCR4); writeb(bdh, sport->port.membase + UARTBDH); writeb(sbr & 0xFF, sport->port.membase + UARTBDL); + writeb(cr3, sport->port.membase + UARTCR3); writeb(cr1, sport->port.membase + UARTCR1); writeb(modem, sport->port.membase + UARTMODEM); -- 2.8.3
[PATCH] drm/panel: Add display timings for TPK U.S.A. LLC Fusion 7", 10.1" panels
Add support for TPK U.S.A. LLC Fusion 7", 10.1" panels to the DRM simple panel driver. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- This patch is based on top of Stefan's clock polarity patches[1] [1] https://lkml.org/lkml/2016/5/5/20 .../bindings/display/panel/tpk,f07a-0102.txt | 8 .../bindings/display/panel/tpk,f10a-0102.txt | 8 .../devicetree/bindings/vendor-prefixes.txt| 1 + drivers/gpu/drm/panel/panel-simple.c | 51 ++ 4 files changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt create mode 100644 Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt diff --git a/Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt b/Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt new file mode 100644 index 000..a2613b9 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt @@ -0,0 +1,8 @@ +TPK U.S.A. LLC Fusion 7" integrated projected capacitive touch display with, +800 x 480 (WVGA) LCD panel. + +Required properties: +- compatible: should be "tpk,f07a-0102" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt b/Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt new file mode 100644 index 000..b9d0511 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt @@ -0,0 +1,8 @@ +TPK U.S.A. LLC Fusion 10.1" integrated projected capacitive touch display with, +1024 x 600 (WSVGA) LCD panel. + +Required properties: +- compatible: should be "tpk,f10a-0102" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 86740d4..141aae4 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -247,6 +247,7 @@ toradex Toradex AG toshibaToshiba Corporation toumaz Toumaz tplink TP-LINK Technologies Co., Ltd. +tpkTPK U.S.A. LLC tronfy Tronfy tronsmart Tronsmart truly Truly Semiconductors Limited diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index b19c88f..b8778b1 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1204,6 +1204,51 @@ static const struct panel_desc shelly_sca07010_bfn_lnn = { .bus_format = MEDIA_BUS_FMT_RGB666_1X18, }; +static const struct drm_display_mode tpk_f07a_0102_mode = { + .clock = 33260, + .hdisplay = 800, + .hsync_start = 800 + 40, + .hsync_end = 800 + 40 + 128, + .htotal = 800 + 40 + 128 + 88, + .vdisplay = 480, + .vsync_start = 480 + 10, + .vsync_end = 480 + 10 + 2, + .vtotal = 480 + 10 + 2 + 33, + .vrefresh = 60, +}; + +static const struct panel_desc tpk_f07a_0102 = { + .modes = _f07a_0102_mode, + .num_modes = 1, + .size = { + .width = 152, + .height = 91, + }, + .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE, +}; + +static const struct drm_display_mode tpk_f10a_0102_mode = { + .clock = 45000, + .hdisplay = 1024, + .hsync_start = 1024 + 176, + .hsync_end = 1024 + 176 + 5, + .htotal = 1024 + 176 + 5 + 88, + .vdisplay = 600, + .vsync_start = 600 + 20, + .vsync_end = 600 + 20 + 5, + .vtotal = 600 + 20 + 5 + 25, + .vrefresh = 60, +}; + +static const struct panel_desc tpk_f10a_0102 = { + .modes = _f10a_0102_mode, + .num_modes = 1, + .size = { + .width = 223, + .height = 125, + }, +}; + static const struct display_timing urt_umsh_8596md_timing = { .pixelclock = { 3326, 3326, 3326 }, .hactive = { 800, 800, 800 }, @@ -1347,6 +1392,12 @@ static const struct of_device_id platform_of_match[] = { .compatible = "shelly,sca07010-bfn-lnn", .data = _sca07010_bfn_lnn, }, { + .compatible = "tpk,f07a-0102", + .data = _f07a_0102, + }, { + .compatible = "tpk,f10a-0102", + .data = _f10a_0102, + }, { .compatible = "urt,umsh-8596md-t", .data = _umsh_8596md_parallel, }, { -- 2.8.2
[PATCH] drm/panel: Add display timings for TPK U.S.A. LLC Fusion 7", 10.1" panels
Add support for TPK U.S.A. LLC Fusion 7", 10.1" panels to the DRM simple panel driver. Signed-off-by: Bhuvanchandra DV --- This patch is based on top of Stefan's clock polarity patches[1] [1] https://lkml.org/lkml/2016/5/5/20 .../bindings/display/panel/tpk,f07a-0102.txt | 8 .../bindings/display/panel/tpk,f10a-0102.txt | 8 .../devicetree/bindings/vendor-prefixes.txt| 1 + drivers/gpu/drm/panel/panel-simple.c | 51 ++ 4 files changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt create mode 100644 Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt diff --git a/Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt b/Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt new file mode 100644 index 000..a2613b9 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/tpk,f07a-0102.txt @@ -0,0 +1,8 @@ +TPK U.S.A. LLC Fusion 7" integrated projected capacitive touch display with, +800 x 480 (WVGA) LCD panel. + +Required properties: +- compatible: should be "tpk,f07a-0102" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt b/Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt new file mode 100644 index 000..b9d0511 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/tpk,f10a-0102.txt @@ -0,0 +1,8 @@ +TPK U.S.A. LLC Fusion 10.1" integrated projected capacitive touch display with, +1024 x 600 (WSVGA) LCD panel. + +Required properties: +- compatible: should be "tpk,f10a-0102" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 86740d4..141aae4 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -247,6 +247,7 @@ toradex Toradex AG toshibaToshiba Corporation toumaz Toumaz tplink TP-LINK Technologies Co., Ltd. +tpkTPK U.S.A. LLC tronfy Tronfy tronsmart Tronsmart truly Truly Semiconductors Limited diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index b19c88f..b8778b1 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1204,6 +1204,51 @@ static const struct panel_desc shelly_sca07010_bfn_lnn = { .bus_format = MEDIA_BUS_FMT_RGB666_1X18, }; +static const struct drm_display_mode tpk_f07a_0102_mode = { + .clock = 33260, + .hdisplay = 800, + .hsync_start = 800 + 40, + .hsync_end = 800 + 40 + 128, + .htotal = 800 + 40 + 128 + 88, + .vdisplay = 480, + .vsync_start = 480 + 10, + .vsync_end = 480 + 10 + 2, + .vtotal = 480 + 10 + 2 + 33, + .vrefresh = 60, +}; + +static const struct panel_desc tpk_f07a_0102 = { + .modes = _f07a_0102_mode, + .num_modes = 1, + .size = { + .width = 152, + .height = 91, + }, + .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE, +}; + +static const struct drm_display_mode tpk_f10a_0102_mode = { + .clock = 45000, + .hdisplay = 1024, + .hsync_start = 1024 + 176, + .hsync_end = 1024 + 176 + 5, + .htotal = 1024 + 176 + 5 + 88, + .vdisplay = 600, + .vsync_start = 600 + 20, + .vsync_end = 600 + 20 + 5, + .vtotal = 600 + 20 + 5 + 25, + .vrefresh = 60, +}; + +static const struct panel_desc tpk_f10a_0102 = { + .modes = _f10a_0102_mode, + .num_modes = 1, + .size = { + .width = 223, + .height = 125, + }, +}; + static const struct display_timing urt_umsh_8596md_timing = { .pixelclock = { 3326, 3326, 3326 }, .hactive = { 800, 800, 800 }, @@ -1347,6 +1392,12 @@ static const struct of_device_id platform_of_match[] = { .compatible = "shelly,sca07010-bfn-lnn", .data = _sca07010_bfn_lnn, }, { + .compatible = "tpk,f07a-0102", + .data = _f07a_0102, + }, { + .compatible = "tpk,f10a-0102", + .data = _f10a_0102, + }, { .compatible = "urt,umsh-8596md-t", .data = _umsh_8596md_parallel, }, { -- 2.8.2
Re: [RFC 1/2] spi: spidev: Use 'new_id' sysfs file for enabling spidev
On 04/20/2016 05:47 PM, Mark Brown wrote: On Wed, Apr 20, 2016 at 05:43:32PM +0530, Bhuvanchandra DV wrote: SPI drivers bind to the device as configured in DT, but in case of spidev(non DT approach) the device is not available in hand to bind the driver. So tried this approach of creating the device and then bind spidev. I agree this is not a standard way we bind SPI devices. With out a device available, seems it is not possible to bind spidev in non DT approach. Please correct me if i'm wrong. The DT should describe the hardware so the DT should describe whatever device is connected to the spidev, what you're trying to do is have spidev bind to these new compatible strings. The device which i was pointing earlier is the SPI master device(spiB.C) not the external h/w device interfaced to it. Yes, DT will describe the h/w interfaced on SPI master device(spiB.C). In case of spidev we are not supposed to describe in DT as it is not a real h/w. The intention of this patchset is to completely avoid spidev in DT and load it via sysfs new_id file for selected SPI master device(spiB.C). -- Best regards, Bhuvan
Re: [RFC 1/2] spi: spidev: Use 'new_id' sysfs file for enabling spidev
On 04/20/2016 05:47 PM, Mark Brown wrote: On Wed, Apr 20, 2016 at 05:43:32PM +0530, Bhuvanchandra DV wrote: SPI drivers bind to the device as configured in DT, but in case of spidev(non DT approach) the device is not available in hand to bind the driver. So tried this approach of creating the device and then bind spidev. I agree this is not a standard way we bind SPI devices. With out a device available, seems it is not possible to bind spidev in non DT approach. Please correct me if i'm wrong. The DT should describe the hardware so the DT should describe whatever device is connected to the spidev, what you're trying to do is have spidev bind to these new compatible strings. The device which i was pointing earlier is the SPI master device(spiB.C) not the external h/w device interfaced to it. Yes, DT will describe the h/w interfaced on SPI master device(spiB.C). In case of spidev we are not supposed to describe in DT as it is not a real h/w. The intention of this patchset is to completely avoid spidev in DT and load it via sysfs new_id file for selected SPI master device(spiB.C). -- Best regards, Bhuvan
Re: [RFC 1/2] spi: spidev: Use 'new_id' sysfs file for enabling spidev
On 04/18/2016 06:31 PM, Mark Brown wrote: On Mon, Apr 18, 2016 at 04:48:27PM +0530, Bhuvanchandra DV wrote: +++ b/Documentation/ABI/testing/sysfs-bus-spi-spidev @@ -0,0 +1,8 @@ +What: /sys/bus/spi/drivers/spidev/new_id +Date: March 2016 +Description: + This allows to load spidev at runtime. new_id file accepts bus + number and chip select in 'B.C' format. + e.g. + To load spidev1.1 at runtime: + $ echo 1.1 > /sys/bus/spi/drivers/spidev/new_id I would expect a new_id file to allow a new device identifier to be added to a driver at runtime but this isn't doing that, it's specifying by bus and chip select instead which is totally different to how we normally bind SPI devices. That seems likely to cause confusion down the line. I'd expect to be able to supply a DT compatible string or a Linux SPI ID. SPI drivers bind to the device as configured in DT, but in case of spidev(non DT approach) the device is not available in hand to bind the driver. So tried this approach of creating the device and then bind spidev. I agree this is not a standard way we bind SPI devices. With out a device available, seems it is not possible to bind spidev in non DT approach. Please correct me if i'm wrong. -- Best regards, Bhuvan
Re: [RFC 1/2] spi: spidev: Use 'new_id' sysfs file for enabling spidev
On 04/18/2016 06:31 PM, Mark Brown wrote: On Mon, Apr 18, 2016 at 04:48:27PM +0530, Bhuvanchandra DV wrote: +++ b/Documentation/ABI/testing/sysfs-bus-spi-spidev @@ -0,0 +1,8 @@ +What: /sys/bus/spi/drivers/spidev/new_id +Date: March 2016 +Description: + This allows to load spidev at runtime. new_id file accepts bus + number and chip select in 'B.C' format. + e.g. + To load spidev1.1 at runtime: + $ echo 1.1 > /sys/bus/spi/drivers/spidev/new_id I would expect a new_id file to allow a new device identifier to be added to a driver at runtime but this isn't doing that, it's specifying by bus and chip select instead which is totally different to how we normally bind SPI devices. That seems likely to cause confusion down the line. I'd expect to be able to supply a DT compatible string or a Linux SPI ID. SPI drivers bind to the device as configured in DT, but in case of spidev(non DT approach) the device is not available in hand to bind the driver. So tried this approach of creating the device and then bind spidev. I agree this is not a standard way we bind SPI devices. With out a device available, seems it is not possible to bind spidev in non DT approach. Please correct me if i'm wrong. -- Best regards, Bhuvan
[RFC 2/2] spi core: Add new sysfs 'num_chipselect' file
Add new sysfs 'num_chipselect' file to expose the maximum number of chipselects a SPI master can support. This allows to create a script in user space which automatically creates a new spidev instance for every chipselect on a bus. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> Signed-off-by: Stefan Agner <stefan.ag...@toradex.com> --- Documentation/spi/spi-summary | 3 +++ drivers/spi/spi.c | 23 +++ 2 files changed, 26 insertions(+) diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index d1824b3..b4d15e4 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -181,6 +181,9 @@ shows up in sysfs in several locations: controller managing bus "B". All spiB.* devices share one physical SPI bus segment, with SCLK, MOSI, and MISO. + /sys/class/spi_master/spiB/num_chipselect ... exposes the maximum + number of chipselects a SPI master can support. + Note that the actual location of the controller's class state depends on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time, the only class-specific state is the bus number ("B" in "spiB"), so diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index de2f2f9..c3eb29f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -67,6 +67,19 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) } static DEVICE_ATTR_RO(modalias); +static ssize_t +num_chipselect_show(struct device *dev, struct device_attribute *a, char *buf) +{ + struct spi_master *master = container_of(dev, +struct spi_master, dev); + + return sprintf(buf, "%d\n", master->num_chipselect); +} +static struct device_attribute dev_attr_num_chipselect = { + .attr = { .name = "num_chipselect", .mode = S_IRUGO }, + .show = num_chipselect_show, +}; + #define SPI_STATISTICS_ATTRS(field, file) \ static ssize_t spi_master_##field##_show(struct device *dev, \ struct device_attribute *attr, \ @@ -155,6 +168,15 @@ static const struct attribute_group spi_dev_group = { .attrs = spi_dev_attrs, }; +static struct attribute *spi_master_attrs[] = { + _attr_num_chipselect.attr, + NULL, +}; + +static const struct attribute_group spi_master_group = { + .attrs = spi_master_attrs, +}; + static struct attribute *spi_device_statistics_attrs[] = { _attr_spi_device_messages.attr, _attr_spi_device_transfers.attr, @@ -236,6 +258,7 @@ static const struct attribute_group spi_master_statistics_group = { }; static const struct attribute_group *spi_master_groups[] = { + _master_group, _master_statistics_group, NULL, }; -- 2.7.3
[RFC 1/2] spi: spidev: Use 'new_id' sysfs file for enabling spidev
Use sysfs new_id file to enable spidev at runtime. new_id file accepts bus number and chip select in 'B.C' format. With reference to the last ML discussion here[1] regarding the solution for spidev with device trees. This patch adds support to load spidevB.C via sysfs new_id file as suggested by Greg. [1] http://thread.gmane.org/gmane.linux.kernel.spi.devel/20331/focus=20369 Suggested-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> Signed-off-by: Stefan Agner <stefan.ag...@toradex.com> --- Documentation/ABI/testing/sysfs-bus-spi-spidev | 8 +++ drivers/spi/spidev.c | 75 +++--- 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-spi-spidev diff --git a/Documentation/ABI/testing/sysfs-bus-spi-spidev b/Documentation/ABI/testing/sysfs-bus-spi-spidev new file mode 100644 index 000..3f6e092 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-spi-spidev @@ -0,0 +1,8 @@ +What: /sys/bus/spi/drivers/spidev/new_id +Date: March 2016 +Description: + This allows to load spidev at runtime. new_id file accepts bus + number and chip select in 'B.C' format. + e.g. + To load spidev1.1 at runtime: + $ echo 1.1 > /sys/bus/spi/drivers/spidev/new_id diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e3c19f3..99e9842 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -667,6 +667,57 @@ static int spidev_release(struct inode *inode, struct file *filp) return 0; } +/** + * new_id_store - add a new spidevB.C instance + * @driver: target device driver + * @buf: buffer for scanning bus number and chip select + * @count: input size + * + * Adds a new dynamic spidev instance based on the requested bus number + * and chip select. + */ +static ssize_t new_id_store(struct device_driver *drv, const char *buf, + size_t count) +{ + int ret; + u32 bus, cs; + struct spi_device *spi; + struct spi_master *master; + + ret = sscanf(buf, "%u.%u", , ); + + if (ret < 2) + return -EINVAL; + + master = spi_busnum_to_master(bus); + if (!master) + return -ENODEV; + + if (cs >= master->num_chipselect) + return -ENODEV; + + spi = spi_alloc_device(master); + if (!spi) { + dev_err(>dev, "Couldn't allocate spidev device\n"); + return -ENOMEM;; + } + + spi->chip_select = cs; + master->bus_num = bus; + + strlcpy(spi->modalias, "spidev", sizeof(spi->modalias)); + + ret = spi_add_device(spi); + if (ret) { + dev_err(>dev, "Couldn't add spidev device\n"); + spi_dev_put(spi); + return ret; + } + + return count; +} +static DRIVER_ATTR_WO(new_id); + static const struct file_operations spidev_fops = { .owner =THIS_MODULE, /* REVISIT switch to aio primitives, so that userspace @@ -817,21 +868,33 @@ static int __init spidev_init(void) spidev_class = class_create(THIS_MODULE, "spidev"); if (IS_ERR(spidev_class)) { - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); - return PTR_ERR(spidev_class); + status = PTR_ERR(spidev_class); + goto err_unregister_chrdev; } status = spi_register_driver(_spi_driver); - if (status < 0) { - class_destroy(spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); - } + if (status < 0) + goto err_destroy_class; + + status = driver_create_file(_spi_driver.driver, _attr_new_id); + if (status < 0) + goto err_unregister_driver; + + return status; + +err_unregister_driver: + spi_unregister_driver(_spi_driver); +err_destroy_class: + class_destroy(spidev_class); +err_unregister_chrdev: + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); return status; } module_init(spidev_init); static void __exit spidev_exit(void) { + driver_remove_file(_spi_driver.driver, _attr_new_id); spi_unregister_driver(_spi_driver); class_destroy(spidev_class); unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); -- 2.7.3
[RFC 2/2] spi core: Add new sysfs 'num_chipselect' file
Add new sysfs 'num_chipselect' file to expose the maximum number of chipselects a SPI master can support. This allows to create a script in user space which automatically creates a new spidev instance for every chipselect on a bus. Signed-off-by: Bhuvanchandra DV Signed-off-by: Stefan Agner --- Documentation/spi/spi-summary | 3 +++ drivers/spi/spi.c | 23 +++ 2 files changed, 26 insertions(+) diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index d1824b3..b4d15e4 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -181,6 +181,9 @@ shows up in sysfs in several locations: controller managing bus "B". All spiB.* devices share one physical SPI bus segment, with SCLK, MOSI, and MISO. + /sys/class/spi_master/spiB/num_chipselect ... exposes the maximum + number of chipselects a SPI master can support. + Note that the actual location of the controller's class state depends on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time, the only class-specific state is the bus number ("B" in "spiB"), so diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index de2f2f9..c3eb29f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -67,6 +67,19 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) } static DEVICE_ATTR_RO(modalias); +static ssize_t +num_chipselect_show(struct device *dev, struct device_attribute *a, char *buf) +{ + struct spi_master *master = container_of(dev, +struct spi_master, dev); + + return sprintf(buf, "%d\n", master->num_chipselect); +} +static struct device_attribute dev_attr_num_chipselect = { + .attr = { .name = "num_chipselect", .mode = S_IRUGO }, + .show = num_chipselect_show, +}; + #define SPI_STATISTICS_ATTRS(field, file) \ static ssize_t spi_master_##field##_show(struct device *dev, \ struct device_attribute *attr, \ @@ -155,6 +168,15 @@ static const struct attribute_group spi_dev_group = { .attrs = spi_dev_attrs, }; +static struct attribute *spi_master_attrs[] = { + _attr_num_chipselect.attr, + NULL, +}; + +static const struct attribute_group spi_master_group = { + .attrs = spi_master_attrs, +}; + static struct attribute *spi_device_statistics_attrs[] = { _attr_spi_device_messages.attr, _attr_spi_device_transfers.attr, @@ -236,6 +258,7 @@ static const struct attribute_group spi_master_statistics_group = { }; static const struct attribute_group *spi_master_groups[] = { + _master_group, _master_statistics_group, NULL, }; -- 2.7.3
[RFC 1/2] spi: spidev: Use 'new_id' sysfs file for enabling spidev
Use sysfs new_id file to enable spidev at runtime. new_id file accepts bus number and chip select in 'B.C' format. With reference to the last ML discussion here[1] regarding the solution for spidev with device trees. This patch adds support to load spidevB.C via sysfs new_id file as suggested by Greg. [1] http://thread.gmane.org/gmane.linux.kernel.spi.devel/20331/focus=20369 Suggested-by: Greg Kroah-Hartman Signed-off-by: Bhuvanchandra DV Signed-off-by: Stefan Agner --- Documentation/ABI/testing/sysfs-bus-spi-spidev | 8 +++ drivers/spi/spidev.c | 75 +++--- 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-spi-spidev diff --git a/Documentation/ABI/testing/sysfs-bus-spi-spidev b/Documentation/ABI/testing/sysfs-bus-spi-spidev new file mode 100644 index 000..3f6e092 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-spi-spidev @@ -0,0 +1,8 @@ +What: /sys/bus/spi/drivers/spidev/new_id +Date: March 2016 +Description: + This allows to load spidev at runtime. new_id file accepts bus + number and chip select in 'B.C' format. + e.g. + To load spidev1.1 at runtime: + $ echo 1.1 > /sys/bus/spi/drivers/spidev/new_id diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e3c19f3..99e9842 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -667,6 +667,57 @@ static int spidev_release(struct inode *inode, struct file *filp) return 0; } +/** + * new_id_store - add a new spidevB.C instance + * @driver: target device driver + * @buf: buffer for scanning bus number and chip select + * @count: input size + * + * Adds a new dynamic spidev instance based on the requested bus number + * and chip select. + */ +static ssize_t new_id_store(struct device_driver *drv, const char *buf, + size_t count) +{ + int ret; + u32 bus, cs; + struct spi_device *spi; + struct spi_master *master; + + ret = sscanf(buf, "%u.%u", , ); + + if (ret < 2) + return -EINVAL; + + master = spi_busnum_to_master(bus); + if (!master) + return -ENODEV; + + if (cs >= master->num_chipselect) + return -ENODEV; + + spi = spi_alloc_device(master); + if (!spi) { + dev_err(>dev, "Couldn't allocate spidev device\n"); + return -ENOMEM;; + } + + spi->chip_select = cs; + master->bus_num = bus; + + strlcpy(spi->modalias, "spidev", sizeof(spi->modalias)); + + ret = spi_add_device(spi); + if (ret) { + dev_err(>dev, "Couldn't add spidev device\n"); + spi_dev_put(spi); + return ret; + } + + return count; +} +static DRIVER_ATTR_WO(new_id); + static const struct file_operations spidev_fops = { .owner =THIS_MODULE, /* REVISIT switch to aio primitives, so that userspace @@ -817,21 +868,33 @@ static int __init spidev_init(void) spidev_class = class_create(THIS_MODULE, "spidev"); if (IS_ERR(spidev_class)) { - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); - return PTR_ERR(spidev_class); + status = PTR_ERR(spidev_class); + goto err_unregister_chrdev; } status = spi_register_driver(_spi_driver); - if (status < 0) { - class_destroy(spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); - } + if (status < 0) + goto err_destroy_class; + + status = driver_create_file(_spi_driver.driver, _attr_new_id); + if (status < 0) + goto err_unregister_driver; + + return status; + +err_unregister_driver: + spi_unregister_driver(_spi_driver); +err_destroy_class: + class_destroy(spidev_class); +err_unregister_chrdev: + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); return status; } module_init(spidev_init); static void __exit spidev_exit(void) { + driver_remove_file(_spi_driver.driver, _attr_new_id); spi_unregister_driver(_spi_driver); class_destroy(spidev_class); unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); -- 2.7.3
[RFC 0/2] sysfs new_id file support for spidev
This patchset adds support for loading spidev via sysfs new_id file. Any comments/suggestions welcome! Bhuvanchandra DV (2): spi: spidev: Use 'new_id' sysfs file for enabling spidev spi core: Add new sysfs 'num_chipselect' file Documentation/ABI/testing/sysfs-bus-spi-spidev | 8 +++ Documentation/spi/spi-summary | 3 ++ drivers/spi/spi.c | 23 drivers/spi/spidev.c | 75 +++--- 4 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-spi-spidev -- 2.7.3
[RFC 0/2] sysfs new_id file support for spidev
This patchset adds support for loading spidev via sysfs new_id file. Any comments/suggestions welcome! Bhuvanchandra DV (2): spi: spidev: Use 'new_id' sysfs file for enabling spidev spi core: Add new sysfs 'num_chipselect' file Documentation/ABI/testing/sysfs-bus-spi-spidev | 8 +++ Documentation/spi/spi-summary | 3 ++ drivers/spi/spi.c | 23 drivers/spi/spidev.c | 75 +++--- 4 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-spi-spidev -- 2.7.3
[PATCH] spi: fsl-dspi: Set max_speed_hz for master
Calculate and update max speed from bus clock for SoC's using DSPI IP. The bus clock factor's are taken from the data sheet's of respective SoC's. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/spi/spi-fsl-dspi.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 59a1143..8753276 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -121,18 +121,22 @@ enum dspi_trans_mode { struct fsl_dspi_devtype_data { enum dspi_trans_mode trans_mode; + u8 max_clock_factor; }; static const struct fsl_dspi_devtype_data vf610_data = { .trans_mode = DSPI_EOQ_MODE, + .max_clock_factor = 2, }; static const struct fsl_dspi_devtype_data ls1021a_v1_data = { .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, }; static const struct fsl_dspi_devtype_data ls2085a_data = { .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, }; struct fsl_dspi { @@ -726,6 +730,9 @@ static int dspi_probe(struct platform_device *pdev) } clk_prepare_enable(dspi->clk); + master->max_speed_hz = + clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; + init_waitqueue_head(>waitq); platform_set_drvdata(pdev, master); -- 2.7.3
[PATCH] spi: fsl-dspi: Set max_speed_hz for master
Calculate and update max speed from bus clock for SoC's using DSPI IP. The bus clock factor's are taken from the data sheet's of respective SoC's. Signed-off-by: Bhuvanchandra DV --- drivers/spi/spi-fsl-dspi.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 59a1143..8753276 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -121,18 +121,22 @@ enum dspi_trans_mode { struct fsl_dspi_devtype_data { enum dspi_trans_mode trans_mode; + u8 max_clock_factor; }; static const struct fsl_dspi_devtype_data vf610_data = { .trans_mode = DSPI_EOQ_MODE, + .max_clock_factor = 2, }; static const struct fsl_dspi_devtype_data ls1021a_v1_data = { .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, }; static const struct fsl_dspi_devtype_data ls2085a_data = { .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, }; struct fsl_dspi { @@ -726,6 +730,9 @@ static int dspi_probe(struct platform_device *pdev) } clk_prepare_enable(dspi->clk); + master->max_speed_hz = + clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; + init_waitqueue_head(>waitq); platform_set_drvdata(pdev, master); -- 2.7.3
[PATCH] ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins
Add pinmux for UART_A RTS, CTS pin's. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> Acked-by: Stefan Agner <ste...@agner.ch> --- arch/arm/boot/dts/vf-colibri.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index e5949b9..700840f 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -213,6 +213,8 @@ fsl,pins = < VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 >; }; -- 2.7.1
[PATCH] ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins
Add pinmux for UART_A RTS, CTS pin's. Signed-off-by: Bhuvanchandra DV Acked-by: Stefan Agner --- arch/arm/boot/dts/vf-colibri.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index e5949b9..700840f 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -213,6 +213,8 @@ fsl,pins = < VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 >; }; -- 2.7.1
Re: [PATCH] ARM: dts: vf-colibri-eval-v3: Use enable-gpios for BL_ON
Ping! On 01/09/2016 12:29 PM, Bhuvanchandra DV wrote: Use pwm-backlight driver 'enable-gpios' property for backlight on/off control. Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri.dtsi | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index e5949b9..1c0da05 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -10,7 +10,10 @@ / { bl: backlight { compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <_gpio_bl_on>; pwms = < 0 500 0>; + enable-gpios = < 13 GPIO_ACTIVE_HIGH>; status = "disabled"; }; }; @@ -169,6 +172,12 @@ >; }; + pinctrl_gpio_bl_on: gpio_bl_on { + fsl,pins = < + VF610_PAD_PTC0__GPIO_45 0x22ef + >; + }; + pinctrl_i2c0: i2c0grp { fsl,pins = < VF610_PAD_PTB14__I2C0_SCL 0x37ff -- Best regards, Bhuvan
Re: [PATCH] ARM: dts: vf-colibri-eval-v3: Use enable-gpios for BL_ON
Ping! On 01/09/2016 12:29 PM, Bhuvanchandra DV wrote: Use pwm-backlight driver 'enable-gpios' property for backlight on/off control. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- arch/arm/boot/dts/vf-colibri.dtsi | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index e5949b9..1c0da05 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -10,7 +10,10 @@ / { bl: backlight { compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <_gpio_bl_on>; pwms = < 0 500 0>; + enable-gpios = < 13 GPIO_ACTIVE_HIGH>; status = "disabled"; }; }; @@ -169,6 +172,12 @@ >; }; + pinctrl_gpio_bl_on: gpio_bl_on { + fsl,pins = < + VF610_PAD_PTC0__GPIO_45 0x22ef + >; + }; + pinctrl_i2c0: i2c0grp { fsl,pins = < VF610_PAD_PTB14__I2C0_SCL 0x37ff -- Best regards, Bhuvan
Re: [PATCH v2] spi-fsl-dspi: Fix CTAR Register access
On 12/10/2015 12:45 PM, Alexander Stein wrote: On Thursday 10 December 2015 11:25:30, Bhuvanchandra DV wrote: DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Shouldn't the information put into struct fsl_dspi_devtype_data how much CTAR and CS the actual implementation has available? E.g. LS1021A has 6 CS and 4 CTAR I guess still this will not help us when CS instance greater than CTAR instance is selected. Other point to consider here is we are writing the CTAR register before every access, so for us there is no additional advantage of using multiple CTAR registers. Best regards, Alexander -- Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] spi-fsl-dspi: Fix CTAR Register access
On 12/10/2015 12:45 PM, Alexander Stein wrote: On Thursday 10 December 2015 11:25:30, Bhuvanchandra DV wrote: DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Shouldn't the information put into struct fsl_dspi_devtype_data how much CTAR and CS the actual implementation has available? E.g. LS1021A has 6 CS and 4 CTAR I guess still this will not help us when CS instance greater than CTAR instance is selected. Other point to consider here is we are writing the CTAR register before every access, so for us there is no additional advantage of using multiple CTAR registers. Best regards, Alexander -- Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] spi-fsl-dspi: Fix CTAR Register access
DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Signed-off-by: Bhuvanchandra DV --- drivers/spi/spi-fsl-dspi.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 59a1143..39412c9 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) { unsigned int val; - regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), ); + regmap_read(dspi->regmap, SPI_CTAR(0), ); return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; } @@ -257,7 +257,7 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word) return SPI_PUSHR_TXDATA(d16) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; } @@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi) */ if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi) if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); trans_mode = dspi->devtype_data->trans_mode; @@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) if (!dspi->len) { if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) { regmap_update_bits(dspi->regmap, - SPI_CTAR(dspi->cs), + SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] spi-fsl-dspi: Fix CTAR Register access
On 12/10/2015 02:11 AM, Mark Brown wrote: On Wed, Dec 09, 2015 at 11:51:39AM +0530, Bhuvanchandra DV wrote: DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver This doesn't apply against, current code - please check and resend. Will check and resend. -- Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] spi-fsl-dspi: Fix CTAR Register access
On 12/10/2015 02:11 AM, Mark Brown wrote: On Wed, Dec 09, 2015 at 11:51:39AM +0530, Bhuvanchandra DV wrote: DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver This doesn't apply against, current code - please check and resend. Will check and resend. -- Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] spi-fsl-dspi: Fix CTAR Register access
DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/spi/spi-fsl-dspi.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 59a1143..39412c9 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) { unsigned int val; - regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), ); + regmap_read(dspi->regmap, SPI_CTAR(0), ); return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; } @@ -257,7 +257,7 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word) return SPI_PUSHR_TXDATA(d16) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; } @@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi) */ if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi) if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); trans_mode = dspi->devtype_data->trans_mode; @@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) if (!dspi->len) { if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) { regmap_update_bits(dspi->regmap, - SPI_CTAR(dspi->cs), + SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] spi-fsl-dspi: Fix CTAR Register access
DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Signed-off-by: Bhuvanchandra DV --- drivers/spi/spi-fsl-dspi.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 01fa95b..b21c3c0 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -138,7 +138,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) { unsigned int val; - regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), ); + regmap_read(dspi->regmap, SPI_CTAR(0), ); return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; } @@ -231,7 +231,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) */ if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -250,7 +250,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) dspi_pushr = SPI_PUSHR_TXDATA(d16) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; dspi->len -= 2; @@ -265,7 +265,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) dspi_pushr = SPI_PUSHR_TXDATA(d8) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; dspi->len--; @@ -365,10 +365,10 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); if (transfer->speed_hz) - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); @@ -469,7 +469,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) if (!dspi->len) { if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); dspi->waitflags = 1; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] spi-fsl-dspi: Fix CTAR Register access
DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/spi/spi-fsl-dspi.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 01fa95b..b21c3c0 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -138,7 +138,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) { unsigned int val; - regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), ); + regmap_read(dspi->regmap, SPI_CTAR(0), ); return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; } @@ -231,7 +231,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) */ if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -250,7 +250,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) dspi_pushr = SPI_PUSHR_TXDATA(d16) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; dspi->len -= 2; @@ -265,7 +265,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) dspi_pushr = SPI_PUSHR_TXDATA(d8) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; dspi->len--; @@ -365,10 +365,10 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); if (transfer->speed_hz) - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); @@ -469,7 +469,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) if (!dspi->len) { if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); dspi->waitflags = 1; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] vf610_adc: Fix internal temperature calculation
Calculate ADCR_VTEMP25 using VTEMP25 at VREFH_ADC 3V3. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. VTEMP25 is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867. Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Acked-by: Fugang Duan Signed-off-by: Bhuvanchandra DV --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] vf610_adc: Fix internal temperature calculation
Calculate ADCR_VTEMP25 using VTEMP25 at VREFH_ADC 3V3. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. VTEMP25 is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867. Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Acked-by: Fugang Duan <b38...@freescale.com> Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] vf610_adc: Fix internal temperature calculation
Hi Stefan, Sorry! for the delay. On 10/08/2015 11:46 AM, Stefan Agner wrote: Hi Bhuvan, On 2015-09-23 06:43, Bhuvanchandra DV wrote: There is an observed temperature difference of ~20°C with the internal temperature reading and the temperature measured on SoC package. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. Voltage at 25°C is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867 and the final temperature readings differs with ~5°C from the external readings. I am not entirely happy with the message. The proposed changes seem not to alter the offset which would explain a ~20°C difference... Where do this 20°C come from? The ~20°C difference is observed at higher temperatures when VTEMP25 at VREDH_ADC of 3V0 is considered. Will update the comment according to the updated VTEMP25 constant instead of the 20°C difference which is confusing wrt the changes done here. Best regards, Bhuvan -- Stefan Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Signed-off-by: Bhuvanchandra DV --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME 1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] vf610_adc: Fix internal temperature calculation
Hi Stefan, Sorry! for the delay. On 10/08/2015 11:46 AM, Stefan Agner wrote: Hi Bhuvan, On 2015-09-23 06:43, Bhuvanchandra DV wrote: There is an observed temperature difference of ~20°C with the internal temperature reading and the temperature measured on SoC package. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. Voltage at 25°C is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867 and the final temperature readings differs with ~5°C from the external readings. I am not entirely happy with the message. The proposed changes seem not to alter the offset which would explain a ~20°C difference... Where do this 20°C come from? The ~20°C difference is observed at higher temperatures when VTEMP25 at VREDH_ADC of 3V0 is considered. Will update the comment according to the updated VTEMP25 constant instead of the 20°C difference which is confusing wrt the changes done here. Best regards, Bhuvan -- Stefan Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Signed-off-by: Bhuvanchandra DV<bhuvanchandra...@toradex.com> --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME 1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] vf610_adc: Fix internal temperature calculation
Hi Fugang, On 09/27/2015 09:23 PM, Jonathan Cameron wrote: On 23/09/15 14:43, Bhuvanchandra DV wrote: There is an observed temperature difference of ~20°C with the internal temperature reading and the temperature measured on SoC package. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. Voltage at 25°C is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867 and the final temperature readings differs with ~5°C from the external readings. Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Signed-off-by: Bhuvanchandra DV Looks fine to me, but I'll need an Ack from Fugang on this one as I don't know or have the part I'm afraid. Can you please give your ACK if the patch looks fine. Best regards, Bhuvan Jonathan --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME 1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] vf610_adc: Fix internal temperature calculation
Hi Fugang, On 09/27/2015 09:23 PM, Jonathan Cameron wrote: On 23/09/15 14:43, Bhuvanchandra DV wrote: There is an observed temperature difference of ~20°C with the internal temperature reading and the temperature measured on SoC package. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. Voltage at 25°C is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867 and the final temperature readings differs with ~5°C from the external readings. Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> Looks fine to me, but I'll need an Ack from Fugang on this one as I don't know or have the part I'm afraid. Can you please give your ACK if the patch looks fine. Best regards, Bhuvan Jonathan --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME 1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] vf610_adc: Fix internal temperature calculation
There is an observed temperature difference of ~20°C with the internal temperature reading and the temperature measured on SoC package. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. Voltage at 25°C is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867 and the final temperature readings differs with ~5°C from the external readings. Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Signed-off-by: Bhuvanchandra DV --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] vf610_adc: Fix internal temperature calculation
There is an observed temperature difference of ~20°C with the internal temperature reading and the temperature measured on SoC package. Existing calculations consider the typical values provided in datasheet. Those typical values are valid for VREFH_ADC at 3.0V. Voltage at 25°C is different for different VREFH_ADC voltages. With VREFH_ADC at 3.3V, voltage at 25°C is 0.699V. Hence update the VTEMP25 to 0.699V which gives ADCR@Temp25 as 867 and the final temperature readings differs with ~5°C from the external readings. Formula for finding ADCR@Temp25: ADCR@Temp25 = (ADCR@Vdd * V@TEMP25 * 10) / VDDconv ADCR@Vdd for 12-Bit ADC = 4095 VDDconv = VREFH_ADC * 10 VREFH_ADC@3.3V ADCR@Temp25 = (4095 * .699 * 10) / 33 ADCR@Temp25 ~= 867 | VREFH_ADC | V@TEMP25 | VDDconv | ADCR@Temp25 | | 3.0V| 0.696mV |30 | 950 | | 3.3V| 0.699mV |33 | 867 | Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- drivers/iio/adc/vf610_adc.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index f4df2a7..e7abc13 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -103,6 +103,13 @@ #define DEFAULT_SAMPLE_TIME1000 +/* V at 25°C of 696 mV */ +#define VF610_VTEMP25_3V0 950 +/* V at 25°C of 699 mV */ +#define VF610_VTEMP25_3V3 867 +/* Typical sensor slope coefficient at all temperatures */ +#define VF610_TEMP_SLOPE_COEFF 1840 + enum clk_sel { VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_ALTCLK_SET, @@ -636,11 +643,13 @@ static int vf610_read_raw(struct iio_dev *indio_dev, break; case IIO_TEMP: /* - * Calculate in degree Celsius times 1000 - * Using sensor slope of 1.84 mV/°C and - * V at 25°C of 696 mV - */ - *val = 25000 - ((int)info->value - 864) * 100 / 1840; +* Calculate in degree Celsius times 1000 +* Using the typical sensor slope of 1.84 mV/°C +* and VREFH_ADC at 3.3V, V at 25°C of 699 mV +*/ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 100 / VF610_TEMP_SLOPE_COEFF; + break; default: mutex_unlock(_dev->mlock); -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
On 06/08/2015 02:42 PM, Russell King - ARM Linux wrote: On Mon, Jun 01, 2015 at 10:51:06AM +0530, Bhuvanchandra DV wrote: +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ That's really not acceptable. You need to do something here so that you can _force_ RTS to be deasserted when the kernel buffers fill up - be that by stopping reading characters and letting the FIFO fill up or something of that ilk. Agreed, will fix this. Ignoring the rest of the flow control system in the kernel is not really acceptable. Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
Hello, On 06/08/2015 12:11 PM, Uwe Kleine-König wrote: Hello, On Mon, Jun 01, 2015 at 10:51:06AM +0530, Bhuvanchandra DV wrote: The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 63 + 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 08ce76f..532cfb7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -822,64 +822,15 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port->membase + UARTMODEM); - if (reg & UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; From reading the commit log I would expect that you only touch the set_mctrl function, but not get_mctrl. Assuming your code change is right, can you mention this in the commit log please? The bits UARTMODEM_TXCTSE and UARTMODEM_RXRTSE only control the automatic mode? OK, will use 'get/set_mctrl' instead of 'mctrl' in the commit log. Yes, those bits are only responsible for enabling/disabling the auto hardware flow control, not for controlling the RTS/CTS signals directly. What is the problem you're fixing here? I'm not sure how such an UART should be handled, but I imagine that you want to make use of automatic mode in some cases. Greg? Fixing the implementation of hardware flow control wrt LPUART hardware. Best regards Uwe Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
On 06/08/2015 02:42 PM, Russell King - ARM Linux wrote: On Mon, Jun 01, 2015 at 10:51:06AM +0530, Bhuvanchandra DV wrote: +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ That's really not acceptable. You need to do something here so that you can _force_ RTS to be deasserted when the kernel buffers fill up - be that by stopping reading characters and letting the FIFO fill up or something of that ilk. Agreed, will fix this. Ignoring the rest of the flow control system in the kernel is not really acceptable. Best regards, Bhuvan -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
Hello, On 06/08/2015 12:11 PM, Uwe Kleine-König wrote: Hello, On Mon, Jun 01, 2015 at 10:51:06AM +0530, Bhuvanchandra DV wrote: The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/tty/serial/fsl_lpuart.c | 63 + 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 08ce76f..532cfb7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -822,64 +822,15 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port-membase + UARTMODEM); - if (reg UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; From reading the commit log I would expect that you only touch the set_mctrl function, but not get_mctrl. Assuming your code change is right, can you mention this in the commit log please? The bits UARTMODEM_TXCTSE and UARTMODEM_RXRTSE only control the automatic mode? OK, will use 'get/set_mctrl' instead of 'mctrl' in the commit log. Yes, those bits are only responsible for enabling/disabling the auto hardware flow control, not for controlling the RTS/CTS signals directly. What is the problem you're fixing here? I'm not sure how such an UART should be handled, but I imagine that you want to make use of automatic mode in some cases. Greg? Fixing the implementation of hardware flow control wrt LPUART hardware. Best regards Uwe Best regards, Bhuvan -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 0/3] Add RS-485 support and fix RTS/CTS implementation
Hello, Ping! On 06/01/2015 10:51 AM, Bhuvanchandra DV wrote: Changes since V1: Use common get/set mctrl control methods for both lpuart, lpuart32 and fix indention. Bhuvanchandra DV (3): ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl tty: serial: fsl_lpuart: Add support for RS-485 arch/arm/boot/dts/vf-colibri.dtsi | 2 + drivers/tty/serial/fsl_lpuart.c | 103 -- 2 files changed, 57 insertions(+), 48 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 0/3] Add RS-485 support and fix RTS/CTS implementation
Hello, Ping! On 06/01/2015 10:51 AM, Bhuvanchandra DV wrote: Changes since V1: Use common get/set mctrl control methods for both lpuart, lpuart32 and fix indention. Bhuvanchandra DV (3): ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl tty: serial: fsl_lpuart: Add support for RS-485 arch/arm/boot/dts/vf-colibri.dtsi | 2 + drivers/tty/serial/fsl_lpuart.c | 103 -- 2 files changed, 57 insertions(+), 48 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 3/3] tty: serial: fsl_lpuart: Add support for RS-485
Enable Vybrid's build-in support for RS-485 auto RTS for controlling line direction of RS-485 transceiver driver. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 56 + 1 file changed, 56 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 532cfb7..7b4e04a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -820,6 +820,49 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) TIOCSER_TEMT : 0; } +static int lpuart_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct lpuart_port *sport = container_of(port, + struct lpuart_port, port); + u8 modem = readb(sport->port.membase + UARTMODEM) & + ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); + + writeb(modem, sport->port.membase + UARTMODEM); + + if (rs485->flags & SER_RS485_ENABLED) { + /* Enable auto RS-485 RTS mode */ + modem |= UARTMODEM_TXRTSE; + + /* +* RTS needs to be logic HIGH either during transer _or_ after +* transfer, other variants are not supported by the hardware. +*/ + if (!(rs485->flags & (SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND))) + rs485->flags |= SER_RS485_RTS_ON_SEND; + + if (rs485->flags & SER_RS485_RTS_ON_SEND && rs485->flags & + SER_RS485_RTS_AFTER_SEND) + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; + + /* +* The hardware defaults to RTS logic HIGH while transfer. +* Switch polarity in case RTS shall be logic HIGH +* after transfer. +* Note: UART is assumed to be active high. +*/ + if (rs485->flags & SER_RS485_RTS_AFTER_SEND) + modem |= UARTMODEM_TXRTSPOL; + } + + /* Store the new configuration */ + sport->port.rs485 = *rs485; + + writeb(modem, sport->port.membase + UARTMODEM); + return 0; +} + static unsigned int lpuart_get_mctrl(struct uart_port *port) { return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; @@ -1191,6 +1234,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, cr1 |= UARTCR1_M; } + /* When auto RS-485 RTS mode is enabled, +* hardware flow control need to be disabled. +*/ + if (sport->port.rs485.flags & SER_RS485_ENABLED) + termios->c_cflag &= ~CRTSCTS; + if (termios->c_cflag & CRTSCTS) { modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); } else { @@ -1749,6 +1798,8 @@ static int lpuart_probe(struct platform_device *pdev) sport->port.ops = _pops; sport->port.flags = UPF_BOOT_AUTOCONF; + sport->port.rs485_config = lpuart_config_rs485; + sport->clk = devm_clk_get(>dev, "ipg"); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); @@ -1789,6 +1840,11 @@ static int lpuart_probe(struct platform_device *pdev) dev_info(sport->port.dev, "DMA rx channel request failed, " "operating without rx DMA\n"); + if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time")) { + sport->port.rs485.flags |= SER_RS485_ENABLED; + sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND; + writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM); + return 0; } -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 1/3] ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins
Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 68ca125..ad6c5ca 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -174,6 +174,8 @@ fsl,pins = < VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 >; }; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 63 + 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 08ce76f..532cfb7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -822,64 +822,15 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port->membase + UARTMODEM); - if (reg & UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; -} - -static unsigned int lpuart32_get_mctrl(struct uart_port *port) -{ - unsigned int temp = 0; - unsigned long reg; - - reg = lpuart32_read(port->membase + UARTMODIR); - if (reg & UARTMODIR_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODIR_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned char temp; - - temp = readb(port->membase + UARTMODEM) & - ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); - - if (mctrl & TIOCM_RTS) - temp |= UARTMODEM_RXRTSE; - - if (mctrl & TIOCM_CTS) - temp |= UARTMODEM_TXCTSE; - - writeb(temp, port->membase + UARTMODEM); -} - -static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - unsigned long temp; - - temp = lpuart32_read(port->membase + UARTMODIR) & - ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE); - - if (mctrl & TIOCM_RTS) - temp |= UARTMODIR_RXRTSE; - - if (mctrl & TIOCM_CTS) - temp |= UARTMODIR_TXCTSE; - - lpuart32_write(temp, port->membase + UARTMODIR); +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ } static void lpuart_break_ctl(struct uart_port *port, int break_state) @@ -1515,8 +1466,8 @@ static struct uart_ops lpuart_pops = { static struct uart_ops lpuart32_pops = { .tx_empty = lpuart32_tx_empty, - .set_mctrl = lpuart32_set_mctrl, - .get_mctrl = lpuart32_get_mctrl, + .set_mctrl = lpuart_set_mctrl, + .get_mctrl = lpuart_get_mctrl, .stop_tx= lpuart32_stop_tx, .start_tx = lpuart32_start_tx, .stop_rx= lpuart32_stop_rx, -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 0/3] Add RS-485 support and fix RTS/CTS implementation
Changes since V1: Use common get/set mctrl control methods for both lpuart, lpuart32 and fix indention. Bhuvanchandra DV (3): ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl tty: serial: fsl_lpuart: Add support for RS-485 arch/arm/boot/dts/vf-colibri.dtsi | 2 + drivers/tty/serial/fsl_lpuart.c | 103 -- 2 files changed, 57 insertions(+), 48 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 3/3] tty: serial: fsl_lpuart: Add support for RS-485
Enable Vybrid's build-in support for RS-485 auto RTS for controlling line direction of RS-485 transceiver driver. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/tty/serial/fsl_lpuart.c | 56 + 1 file changed, 56 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 532cfb7..7b4e04a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -820,6 +820,49 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) TIOCSER_TEMT : 0; } +static int lpuart_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct lpuart_port *sport = container_of(port, + struct lpuart_port, port); + u8 modem = readb(sport-port.membase + UARTMODEM) + ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); + + writeb(modem, sport-port.membase + UARTMODEM); + + if (rs485-flags SER_RS485_ENABLED) { + /* Enable auto RS-485 RTS mode */ + modem |= UARTMODEM_TXRTSE; + + /* +* RTS needs to be logic HIGH either during transer _or_ after +* transfer, other variants are not supported by the hardware. +*/ + if (!(rs485-flags (SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND))) + rs485-flags |= SER_RS485_RTS_ON_SEND; + + if (rs485-flags SER_RS485_RTS_ON_SEND rs485-flags + SER_RS485_RTS_AFTER_SEND) + rs485-flags = ~SER_RS485_RTS_AFTER_SEND; + + /* +* The hardware defaults to RTS logic HIGH while transfer. +* Switch polarity in case RTS shall be logic HIGH +* after transfer. +* Note: UART is assumed to be active high. +*/ + if (rs485-flags SER_RS485_RTS_AFTER_SEND) + modem |= UARTMODEM_TXRTSPOL; + } + + /* Store the new configuration */ + sport-port.rs485 = *rs485; + + writeb(modem, sport-port.membase + UARTMODEM); + return 0; +} + static unsigned int lpuart_get_mctrl(struct uart_port *port) { return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; @@ -1191,6 +1234,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, cr1 |= UARTCR1_M; } + /* When auto RS-485 RTS mode is enabled, +* hardware flow control need to be disabled. +*/ + if (sport-port.rs485.flags SER_RS485_ENABLED) + termios-c_cflag = ~CRTSCTS; + if (termios-c_cflag CRTSCTS) { modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); } else { @@ -1749,6 +1798,8 @@ static int lpuart_probe(struct platform_device *pdev) sport-port.ops = lpuart_pops; sport-port.flags = UPF_BOOT_AUTOCONF; + sport-port.rs485_config = lpuart_config_rs485; + sport-clk = devm_clk_get(pdev-dev, ipg); if (IS_ERR(sport-clk)) { ret = PTR_ERR(sport-clk); @@ -1789,6 +1840,11 @@ static int lpuart_probe(struct platform_device *pdev) dev_info(sport-port.dev, DMA rx channel request failed, operating without rx DMA\n); + if (of_property_read_bool(np, linux,rs485-enabled-at-boot-time)) { + sport-port.rs485.flags |= SER_RS485_ENABLED; + sport-port.rs485.flags |= SER_RS485_RTS_ON_SEND; + writeb(UARTMODEM_TXRTSE, sport-port.membase + UARTMODEM); + return 0; } -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 1/3] ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins
Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf-colibri.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 68ca125..ad6c5ca 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -174,6 +174,8 @@ fsl,pins = VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 ; }; -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/tty/serial/fsl_lpuart.c | 63 + 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 08ce76f..532cfb7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -822,64 +822,15 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port-membase + UARTMODEM); - if (reg UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; -} - -static unsigned int lpuart32_get_mctrl(struct uart_port *port) -{ - unsigned int temp = 0; - unsigned long reg; - - reg = lpuart32_read(port-membase + UARTMODIR); - if (reg UARTMODIR_TXCTSE) - temp |= TIOCM_CTS; - - if (reg UARTMODIR_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned char temp; - - temp = readb(port-membase + UARTMODEM) - ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); - - if (mctrl TIOCM_RTS) - temp |= UARTMODEM_RXRTSE; - - if (mctrl TIOCM_CTS) - temp |= UARTMODEM_TXCTSE; - - writeb(temp, port-membase + UARTMODEM); -} - -static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - unsigned long temp; - - temp = lpuart32_read(port-membase + UARTMODIR) - ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE); - - if (mctrl TIOCM_RTS) - temp |= UARTMODIR_RXRTSE; - - if (mctrl TIOCM_CTS) - temp |= UARTMODIR_TXCTSE; - - lpuart32_write(temp, port-membase + UARTMODIR); +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ } static void lpuart_break_ctl(struct uart_port *port, int break_state) @@ -1515,8 +1466,8 @@ static struct uart_ops lpuart_pops = { static struct uart_ops lpuart32_pops = { .tx_empty = lpuart32_tx_empty, - .set_mctrl = lpuart32_set_mctrl, - .get_mctrl = lpuart32_get_mctrl, + .set_mctrl = lpuart_set_mctrl, + .get_mctrl = lpuart_get_mctrl, .stop_tx= lpuart32_stop_tx, .start_tx = lpuart32_start_tx, .stop_rx= lpuart32_stop_rx, -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 0/3] Add RS-485 support and fix RTS/CTS implementation
Changes since V1: Use common get/set mctrl control methods for both lpuart, lpuart32 and fix indention. Bhuvanchandra DV (3): ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl tty: serial: fsl_lpuart: Add support for RS-485 arch/arm/boot/dts/vf-colibri.dtsi | 2 + drivers/tty/serial/fsl_lpuart.c | 103 -- 2 files changed, 57 insertions(+), 48 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/3] tty: serial: fsl_lpuart: Add support for RS-485
On 05/29/2015 03:48 PM, Jakub Kiciński wrote: On Fri, 29 May 2015 13:35:54 +0530, Bhuvanchandra DV wrote: Enable Vybrid's build-in support for RS-485 auto RTS for controlling line direction of RS-485 transceiver driver. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 60 + 1 file changed, 60 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 357f623..c553b14 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -820,6 +820,50 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) TIOCSER_TEMT : 0; } +static int lpuart_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct lpuart_port *sport = container_of(port, + struct lpuart_port, port); + u8 modem = readb(sport->port.membase + UARTMODEM) & + ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); Please put empty line between variables and code. Ok + writeb(modem, sport->port.membase + UARTMODEM); + + if (rs485->flags & SER_RS485_ENABLED) { + /* Enable auto RS-485 RTS mode */ + modem |= UARTMODEM_TXRTSE; + + /* + * RTS needs to be logic HIGH either during transer _or_ after + * transfer, other variants are not supported by the hardware. + */ Indentation is off here. '*' should be aligned. Ok + if (!(rs485->flags & (SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND))) and here - things should be aligned on the containing bracket (SER_ under SER_ here). Ok + rs485->flags |= SER_RS485_RTS_ON_SEND; + + if (rs485->flags & SER_RS485_RTS_ON_SEND && + rs485->flags & SER_RS485_RTS_AFTER_SEND) and here - same bracket rule (rs485-> under rs485->) Ok + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; + + /* + * The hardware defaults to RTS logic HIGH while transfer. + * Switch polarity in case RTS shall be logic HIGH + * after transfer. + * Note: UART is assumed to be active high. + */ + if (rs485->flags & SER_RS485_RTS_ON_SEND) + modem &= ~UARTMODEM_TXRTSPOL; UARTMODEM_TXRTSPOL was already clear when you read modem. Ok + else if (rs485->flags & SER_RS485_RTS_AFTER_SEND) + modem |= UARTMODEM_TXRTSPOL; + } + + /* Store the new configuration */ + sport->port.rs485 = *rs485; + + writeb(modem, sport->port.membase + UARTMODEM); + return 0; +} + static unsigned int lpuart_get_mctrl(struct uart_port *port) { return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; [...] @@ -1802,6 +1854,14 @@ static int lpuart_probe(struct platform_device *pdev) dev_info(sport->port.dev, "DMA rx channel request failed, " "operating without rx DMA\n"); + if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time")) { + sport->port.rs485.flags |= SER_RS485_ENABLED; + sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND; + writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM); + } else { + sport->port.rs485.flags &= ~SER_RS485_ENABLED; Why the need to clear the flag? sport was kzalloc'ed. Will remove it. Best Regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
Hello Jakub, On 05/29/2015 03:34 PM, Jakub Kiciński wrote: On Fri, 29 May 2015 13:35:53 +0530, Bhuvanchandra DV wrote: The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV Now that the functions do nothing there is probably no point in keeping separate lpuart/lpuart32 variants. Agreed, will update it accordingly. Thanks! for pointing this. Best regards, Bhuvan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 56 - 1 file changed, 10 insertions(+), 46 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 08ce76f..357f623 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -822,64 +822,28 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port->membase + UARTMODEM); - if (reg & UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; } static unsigned int lpuart32_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned long reg; - - reg = lpuart32_read(port->membase + UARTMODIR); - if (reg & UARTMODIR_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODIR_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned char temp; - - temp = readb(port->membase + UARTMODEM) & - ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); - - if (mctrl & TIOCM_RTS) - temp |= UARTMODEM_RXRTSE; - - if (mctrl & TIOCM_CTS) - temp |= UARTMODEM_TXCTSE; - - writeb(temp, port->membase + UARTMODEM); +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ } static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned long temp; - - temp = lpuart32_read(port->membase + UARTMODIR) & - ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE); - - if (mctrl & TIOCM_RTS) - temp |= UARTMODIR_RXRTSE; - - if (mctrl & TIOCM_CTS) - temp |= UARTMODIR_TXCTSE; - - lpuart32_write(temp, port->membase + UARTMODIR); +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ } static void lpuart_break_ctl(struct uart_port *port, int break_state) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/3] ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins
Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 68ca125..ad6c5ca 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -174,6 +174,8 @@ fsl,pins = < VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 >; }; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/3] Add RS-485 support and fix RTS/CTS implementation
- Add pinmux for UART_0 RTS/CTS pins. - Since hardware can handle RTS/CTS flow control automatically, remove manual control of RTS/CTS from set/get mctrl. - Add RS-485 support for Vybird platform. Bhuvanchandra DV (3): ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl tty: serial: fsl_lpuart: Add support for RS-485 arch/arm/boot/dts/vf-colibri.dtsi | 2 + drivers/tty/serial/fsl_lpuart.c | 112 +++--- 2 files changed, 70 insertions(+), 44 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] tty: serial: fsl_lpuart: Add support for RS-485
Enable Vybrid's build-in support for RS-485 auto RTS for controlling line direction of RS-485 transceiver driver. Signed-off-by: Bhuvanchandra DV --- drivers/tty/serial/fsl_lpuart.c | 60 + 1 file changed, 60 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 357f623..c553b14 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -820,6 +820,50 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) TIOCSER_TEMT : 0; } +static int lpuart_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct lpuart_port *sport = container_of(port, + struct lpuart_port, port); + u8 modem = readb(sport->port.membase + UARTMODEM) & + ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); + writeb(modem, sport->port.membase + UARTMODEM); + + if (rs485->flags & SER_RS485_ENABLED) { + /* Enable auto RS-485 RTS mode */ + modem |= UARTMODEM_TXRTSE; + + /* + * RTS needs to be logic HIGH either during transer _or_ after + * transfer, other variants are not supported by the hardware. + */ + if (!(rs485->flags & (SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND))) + rs485->flags |= SER_RS485_RTS_ON_SEND; + + if (rs485->flags & SER_RS485_RTS_ON_SEND && + rs485->flags & SER_RS485_RTS_AFTER_SEND) + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; + + /* + * The hardware defaults to RTS logic HIGH while transfer. + * Switch polarity in case RTS shall be logic HIGH + * after transfer. + * Note: UART is assumed to be active high. + */ + if (rs485->flags & SER_RS485_RTS_ON_SEND) + modem &= ~UARTMODEM_TXRTSPOL; + else if (rs485->flags & SER_RS485_RTS_AFTER_SEND) + modem |= UARTMODEM_TXRTSPOL; + } + + /* Store the new configuration */ + sport->port.rs485 = *rs485; + + writeb(modem, sport->port.membase + UARTMODEM); + return 0; +} + static unsigned int lpuart_get_mctrl(struct uart_port *port) { return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; @@ -1204,6 +1248,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, cr1 |= UARTCR1_M; } + /* When auto RS-485 RTS mode is enabled, +* hardware flow control need to be disabled. +*/ + if (sport->port.rs485.flags & SER_RS485_ENABLED) + termios->c_cflag &= ~CRTSCTS; + if (termios->c_cflag & CRTSCTS) { modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); } else { @@ -1762,6 +1812,8 @@ static int lpuart_probe(struct platform_device *pdev) sport->port.ops = _pops; sport->port.flags = UPF_BOOT_AUTOCONF; + sport->port.rs485_config = lpuart_config_rs485; + sport->clk = devm_clk_get(>dev, "ipg"); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); @@ -1802,6 +1854,14 @@ static int lpuart_probe(struct platform_device *pdev) dev_info(sport->port.dev, "DMA rx channel request failed, " "operating without rx DMA\n"); + if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time")) { + sport->port.rs485.flags |= SER_RS485_ENABLED; + sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND; + writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM); + } else { + sport->port.rs485.flags &= ~SER_RS485_ENABLED; + } + return 0; } -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/3] Add RS-485 support and fix RTS/CTS implementation
- Add pinmux for UART_0 RTS/CTS pins. - Since hardware can handle RTS/CTS flow control automatically, remove manual control of RTS/CTS from set/get mctrl. - Add RS-485 support for Vybird platform. Bhuvanchandra DV (3): ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl tty: serial: fsl_lpuart: Add support for RS-485 arch/arm/boot/dts/vf-colibri.dtsi | 2 + drivers/tty/serial/fsl_lpuart.c | 112 +++--- 2 files changed, 70 insertions(+), 44 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] tty: serial: fsl_lpuart: Add support for RS-485
Enable Vybrid's build-in support for RS-485 auto RTS for controlling line direction of RS-485 transceiver driver. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/tty/serial/fsl_lpuart.c | 60 + 1 file changed, 60 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 357f623..c553b14 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -820,6 +820,50 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) TIOCSER_TEMT : 0; } +static int lpuart_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct lpuart_port *sport = container_of(port, + struct lpuart_port, port); + u8 modem = readb(sport-port.membase + UARTMODEM) + ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); + writeb(modem, sport-port.membase + UARTMODEM); + + if (rs485-flags SER_RS485_ENABLED) { + /* Enable auto RS-485 RTS mode */ + modem |= UARTMODEM_TXRTSE; + + /* + * RTS needs to be logic HIGH either during transer _or_ after + * transfer, other variants are not supported by the hardware. + */ + if (!(rs485-flags (SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND))) + rs485-flags |= SER_RS485_RTS_ON_SEND; + + if (rs485-flags SER_RS485_RTS_ON_SEND + rs485-flags SER_RS485_RTS_AFTER_SEND) + rs485-flags = ~SER_RS485_RTS_AFTER_SEND; + + /* + * The hardware defaults to RTS logic HIGH while transfer. + * Switch polarity in case RTS shall be logic HIGH + * after transfer. + * Note: UART is assumed to be active high. + */ + if (rs485-flags SER_RS485_RTS_ON_SEND) + modem = ~UARTMODEM_TXRTSPOL; + else if (rs485-flags SER_RS485_RTS_AFTER_SEND) + modem |= UARTMODEM_TXRTSPOL; + } + + /* Store the new configuration */ + sport-port.rs485 = *rs485; + + writeb(modem, sport-port.membase + UARTMODEM); + return 0; +} + static unsigned int lpuart_get_mctrl(struct uart_port *port) { return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; @@ -1204,6 +1248,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, cr1 |= UARTCR1_M; } + /* When auto RS-485 RTS mode is enabled, +* hardware flow control need to be disabled. +*/ + if (sport-port.rs485.flags SER_RS485_ENABLED) + termios-c_cflag = ~CRTSCTS; + if (termios-c_cflag CRTSCTS) { modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); } else { @@ -1762,6 +1812,8 @@ static int lpuart_probe(struct platform_device *pdev) sport-port.ops = lpuart_pops; sport-port.flags = UPF_BOOT_AUTOCONF; + sport-port.rs485_config = lpuart_config_rs485; + sport-clk = devm_clk_get(pdev-dev, ipg); if (IS_ERR(sport-clk)) { ret = PTR_ERR(sport-clk); @@ -1802,6 +1854,14 @@ static int lpuart_probe(struct platform_device *pdev) dev_info(sport-port.dev, DMA rx channel request failed, operating without rx DMA\n); + if (of_property_read_bool(np, linux,rs485-enabled-at-boot-time)) { + sport-port.rs485.flags |= SER_RS485_ENABLED; + sport-port.rs485.flags |= SER_RS485_RTS_ON_SEND; + writeb(UARTMODEM_TXRTSE, sport-port.membase + UARTMODEM); + } else { + sport-port.rs485.flags = ~SER_RS485_ENABLED; + } + return 0; } -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/3] ARM: dts: colibri-vf: Add pinmux for UART_0 aka UART_A RTS/CTS pins
Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf-colibri.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 68ca125..ad6c5ca 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -174,6 +174,8 @@ fsl,pins = VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 ; }; -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/tty/serial/fsl_lpuart.c | 56 - 1 file changed, 10 insertions(+), 46 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 08ce76f..357f623 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -822,64 +822,28 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port-membase + UARTMODEM); - if (reg UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; } static unsigned int lpuart32_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned long reg; - - reg = lpuart32_read(port-membase + UARTMODIR); - if (reg UARTMODIR_TXCTSE) - temp |= TIOCM_CTS; - - if (reg UARTMODIR_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned char temp; - - temp = readb(port-membase + UARTMODEM) - ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); - - if (mctrl TIOCM_RTS) - temp |= UARTMODEM_RXRTSE; - - if (mctrl TIOCM_CTS) - temp |= UARTMODEM_TXCTSE; - - writeb(temp, port-membase + UARTMODEM); +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ } static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned long temp; - - temp = lpuart32_read(port-membase + UARTMODIR) - ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE); - - if (mctrl TIOCM_RTS) - temp |= UARTMODIR_RXRTSE; - - if (mctrl TIOCM_CTS) - temp |= UARTMODIR_TXCTSE; - - lpuart32_write(temp, port-membase + UARTMODIR); +/* + * CTS/RTS can _only_ be handled + * automatically by the hardware. + */ } static void lpuart_break_ctl(struct uart_port *port, int break_state) -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/3] tty: serial: fsl_lpuart: Add support for RS-485
On 05/29/2015 03:48 PM, Jakub Kiciński wrote: On Fri, 29 May 2015 13:35:54 +0530, Bhuvanchandra DV wrote: Enable Vybrid's build-in support for RS-485 auto RTS for controlling line direction of RS-485 transceiver driver. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/tty/serial/fsl_lpuart.c | 60 + 1 file changed, 60 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 357f623..c553b14 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -820,6 +820,50 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) TIOCSER_TEMT : 0; } +static int lpuart_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct lpuart_port *sport = container_of(port, + struct lpuart_port, port); + u8 modem = readb(sport-port.membase + UARTMODEM) + ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); Please put empty line between variables and code. Ok + writeb(modem, sport-port.membase + UARTMODEM); + + if (rs485-flags SER_RS485_ENABLED) { + /* Enable auto RS-485 RTS mode */ + modem |= UARTMODEM_TXRTSE; + + /* + * RTS needs to be logic HIGH either during transer _or_ after + * transfer, other variants are not supported by the hardware. + */ Indentation is off here. '*' should be aligned. Ok + if (!(rs485-flags (SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND))) and here - things should be aligned on the containing bracket (SER_ under SER_ here). Ok + rs485-flags |= SER_RS485_RTS_ON_SEND; + + if (rs485-flags SER_RS485_RTS_ON_SEND + rs485-flags SER_RS485_RTS_AFTER_SEND) and here - same bracket rule (rs485- under rs485-) Ok + rs485-flags = ~SER_RS485_RTS_AFTER_SEND; + + /* + * The hardware defaults to RTS logic HIGH while transfer. + * Switch polarity in case RTS shall be logic HIGH + * after transfer. + * Note: UART is assumed to be active high. + */ + if (rs485-flags SER_RS485_RTS_ON_SEND) + modem = ~UARTMODEM_TXRTSPOL; UARTMODEM_TXRTSPOL was already clear when you read modem. Ok + else if (rs485-flags SER_RS485_RTS_AFTER_SEND) + modem |= UARTMODEM_TXRTSPOL; + } + + /* Store the new configuration */ + sport-port.rs485 = *rs485; + + writeb(modem, sport-port.membase + UARTMODEM); + return 0; +} + static unsigned int lpuart_get_mctrl(struct uart_port *port) { return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; [...] @@ -1802,6 +1854,14 @@ static int lpuart_probe(struct platform_device *pdev) dev_info(sport-port.dev, DMA rx channel request failed, operating without rx DMA\n); + if (of_property_read_bool(np, linux,rs485-enabled-at-boot-time)) { + sport-port.rs485.flags |= SER_RS485_ENABLED; + sport-port.rs485.flags |= SER_RS485_RTS_ON_SEND; + writeb(UARTMODEM_TXRTSE, sport-port.membase + UARTMODEM); + } else { + sport-port.rs485.flags = ~SER_RS485_ENABLED; Why the need to clear the flag? sport was kzalloc'ed. Will remove it. Best Regards, Bhuvan -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/3] tty: serial: fsl_lpuart: remove RTS/CTS control from set/get_mctrl
Hello Jakub, On 05/29/2015 03:34 PM, Jakub Kiciński wrote: On Fri, 29 May 2015 13:35:53 +0530, Bhuvanchandra DV wrote: The LPUART does not provide manual control of RTS/CTS signals, those can only be controlled by the hardware directly. Therefore manual control of those signals through mctrl can not be provided. The current implementation enables/disables the automatic control, which is not what mctrl should do, hence remove the incorrect implementation. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com Now that the functions do nothing there is probably no point in keeping separate lpuart/lpuart32 variants. Agreed, will update it accordingly. Thanks! for pointing this. Best regards, Bhuvan -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] spi: fsl-dspi: Remove possible memory leak of 'chip'
Move the check for spi->bits_per_word before allocation, to avoid memory leak. Signed-off-by: Dan Carpenter Signed-off-by: Bhuvanchandra DV --- drivers/spi/spi-fsl-dspi.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 4cda994..604b6d3 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -339,6 +339,13 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); unsigned char br = 0, pbr = 0, fmsz = 0; + if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) { + fmsz = spi->bits_per_word - 1; + } else { + pr_err("Invalid wordsize\n"); + return -ENODEV; + } + /* Only alloc on first setup */ chip = spi_get_ctldata(spi); if (chip == NULL) { @@ -350,12 +357,6 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; - if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) { - fmsz = spi->bits_per_word - 1; - } else { - pr_err("Invalid wordsize\n"); - return -ENODEV; - } chip->void_write_data = 0; -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] spi: fsl-dspi: Remove possible memory leak of 'chip'
Move the check for spi-bits_per_word before allocation, to avoid memory leak. Signed-off-by: Dan Carpenter dan.carpen...@oracle.com Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/spi/spi-fsl-dspi.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 4cda994..604b6d3 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -339,6 +339,13 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) struct fsl_dspi *dspi = spi_master_get_devdata(spi-master); unsigned char br = 0, pbr = 0, fmsz = 0; + if ((spi-bits_per_word = 4) (spi-bits_per_word = 16)) { + fmsz = spi-bits_per_word - 1; + } else { + pr_err(Invalid wordsize\n); + return -ENODEV; + } + /* Only alloc on first setup */ chip = spi_get_ctldata(spi); if (chip == NULL) { @@ -350,12 +357,6 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) chip-mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; - if ((spi-bits_per_word = 4) (spi-bits_per_word = 16)) { - fmsz = spi-bits_per_word - 1; - } else { - pr_err(Invalid wordsize\n); - return -ENODEV; - } chip-void_write_data = 0; -- 2.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2] ARM: vf-colibri: add SPI support and enable MCP2515 CAN
MCP2515 CAN controller is available on Colibri Evaluation board. Hence enable MCP2515 CAN. Acked-by: Stefan Agner Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 31 +++ arch/arm/boot/dts/vf-colibri.dtsi | 15 +++ 2 files changed, 46 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 36cafbf..606753e 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -12,6 +12,12 @@ bootargs = "console=ttyLP0,115200"; }; + clk16m: clk16m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1600>; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -47,6 +53,21 @@ status = "okay"; }; + { + status = "okay"; + + mcp2515can: can@0 { + compatible = "microchip,mcp2515"; + pinctrl-names = "default"; + pinctrl-0 = <_can_int>; + reg = <0>; + clocks = <>; + spi-max-frequency = <1000>; + interrupt-parent = <>; + interrupts = <11 GPIO_ACTIVE_LOW>; + }; +}; + { pinctrl-names = "default"; pinctrl-0 = <_esdhc1>; @@ -94,3 +115,13 @@ { vbus-supply = <_vbus_reg>; }; + + { + vf610-colibri { + pinctrl_can_int: can_int { + fsl,pins = < + VF610_PAD_PTB21__GPIO_430x22ed + >; + }; + }; +}; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 5c2b732..fbef082 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -23,6 +23,12 @@ status = "okay"; }; + { + bus-num = <1>; + pinctrl-names = "default"; + pinctrl-0 = <_dspi1>; +}; + { status = "okay"; }; @@ -107,6 +113,15 @@ >; }; + pinctrl_dspi1: dspi1grp { + fsl,pins = < + VF610_PAD_PTD5__DSPI1_CS0 0x33e2 + VF610_PAD_PTD6__DSPI1_SIN 0x33e1 + VF610_PAD_PTD7__DSPI1_SOUT 0x33e2 + VF610_PAD_PTD8__DSPI1_SCK 0x33e2 + >; + }; + pinctrl_esdhc1: esdhc1grp { fsl,pins = < VF610_PAD_PTA24__ESDHC1_CLK 0x31ef -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2] ARM: vf-colibri: add SPI support and enable MCP2515 CAN
MCP2515 CAN controller is available on Colibri Evaluation board. Hence enable MCP2515 CAN. Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 31 +++ arch/arm/boot/dts/vf-colibri.dtsi | 15 +++ 2 files changed, 46 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 36cafbf..606753e 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -12,6 +12,12 @@ bootargs = console=ttyLP0,115200; }; + clk16m: clk16m { + compatible = fixed-clock; + #clock-cells = 0; + clock-frequency = 1600; + }; + regulators { compatible = simple-bus; #address-cells = 1; @@ -47,6 +53,21 @@ status = okay; }; +dspi1 { + status = okay; + + mcp2515can: can@0 { + compatible = microchip,mcp2515; + pinctrl-names = default; + pinctrl-0 = pinctrl_can_int; + reg = 0; + clocks = clk16m; + spi-max-frequency = 1000; + interrupt-parent = gpio1; + interrupts = 11 GPIO_ACTIVE_LOW; + }; +}; + esdhc1 { pinctrl-names = default; pinctrl-0 = pinctrl_esdhc1; @@ -94,3 +115,13 @@ usbh1 { vbus-supply = usbh_vbus_reg; }; + +iomuxc { + vf610-colibri { + pinctrl_can_int: can_int { + fsl,pins = + VF610_PAD_PTB21__GPIO_430x22ed + ; + }; + }; +}; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 5c2b732..fbef082 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -23,6 +23,12 @@ status = okay; }; +dspi1 { + bus-num = 1; + pinctrl-names = default; + pinctrl-0 = pinctrl_dspi1; +}; + edma0 { status = okay; }; @@ -107,6 +113,15 @@ ; }; + pinctrl_dspi1: dspi1grp { + fsl,pins = + VF610_PAD_PTD5__DSPI1_CS0 0x33e2 + VF610_PAD_PTD6__DSPI1_SIN 0x33e1 + VF610_PAD_PTD7__DSPI1_SOUT 0x33e2 + VF610_PAD_PTD8__DSPI1_SCK 0x33e2 + ; + }; + pinctrl_esdhc1: esdhc1grp { fsl,pins = VF610_PAD_PTA24__ESDHC1_CLK 0x31ef -- 2.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/7] Add SPI support for Colibri modules and DSPI driver fixes
- Add second dspi instance. - Enable MCP2515 CAN controller which is avaialble on Colibri evaluation board. - Respin the stalled patches of dspi fixes. Previous discussion at: http://comments.gmane.org/gmane.linux.ports.arm.kernel/359542 Bhuvanchandra DV (4): ARM: vf610: add second DSPI instance ARM: vf-colibri: add SPI support and enable MCP2515 CAN spi: spi-fsl-dspi: Remove usage of devm_kalloc spi: spi-fsl-dspi: avoid preparing the clocks two times Chao Fu (3): spi: spi-fsl-dspi: Remove spi-bitbang spi: spi-fsl-dspi: split the resuable code spi: spi-fsl-dspi: Add support for TCFQ transfer mode .../devicetree/bindings/spi/spi-fsl-dspi.txt | 2 + arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 31 ++ arch/arm/boot/dts/vf-colibri.dtsi | 15 + arch/arm/boot/dts/vf500.dtsi | 4 + arch/arm/boot/dts/vfxxx.dtsi | 11 + drivers/spi/Kconfig| 1 - drivers/spi/spi-fsl-dspi.c | 314 + 7 files changed, 254 insertions(+), 124 deletions(-) -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 7/7] spi: spi-fsl-dspi: Add support for TCFQ transfer mode
From: Chao Fu TCFQ is interrupt of Transfer Complete Flag in DSPI module. EOQ is interrupt of End of Queue Flag in DSPI module. For adopting of different platform, either of them is a way of DSPI transfer data. This patch add TCF support for DSPI module in other platform. Signed-off-by: Bhuvanchandra DV --- .../devicetree/bindings/spi/spi-fsl-dspi.txt | 2 + drivers/spi/spi-fsl-dspi.c | 74 +++--- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index cbbe16e..b50439f 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt @@ -15,6 +15,8 @@ Optional property: - big-endian: If present the dspi device's registers are implemented in big endian mode, otherwise in native mode(same with CPU), for more detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. +- tcfq-mode: If present, the data transfer will be done at TCFQ interrupt. + By default, driver chooses EOQ interrupt if 'tcfq-mode' property was not set. Example: diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index e0ce906..feca2fd 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -63,9 +63,11 @@ #define SPI_CTAR0_SLAVE0x0c #define SPI_SR 0x2c +#define SPI_SR_TCFQF 0x8000 #define SPI_SR_EOQF0x1000 #define SPI_RSER 0x30 +#define SPI_RSER_TCFQE 0x8000 #define SPI_RSER_EOQFE 0x1000 #define SPI_PUSHR 0x34 @@ -105,6 +107,12 @@ struct chip_data { u16 void_write_data; }; +enum dspi_trans_mode { + DSPI_EOQ_MODE = 0, + DSPI_TCFQ_MODE, + DSPI_DMA_MODE, /*TODO*/ +}; + struct fsl_dspi { struct spi_master *master; struct platform_device *pdev; @@ -125,6 +133,7 @@ struct fsl_dspi { u8 cs; u16 void_write_data; u32 cs_change; + enum dspi_trans_modetrans_mode; wait_queue_head_t waitq; u32 waitflags; @@ -225,7 +234,7 @@ static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word) } } -static int dspi_transfer_write(struct fsl_dspi *dspi) +static int dspi_eoq_write(struct fsl_dspi *dspi) { int tx_count = 0; int tx_word; @@ -269,7 +278,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) return tx_count * (tx_word + 1); } -static int dspi_transfer_read(struct fsl_dspi *dspi) +static int dspi_eoq_read(struct fsl_dspi *dspi) { int rx_count = 0; int rx_word = is_double_byte_mode(dspi); @@ -283,6 +292,37 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) return rx_count; } +static int dspi_tcfq_write(struct fsl_dspi *dspi) +{ + int tx_word; + u32 dspi_pushr = 0; + + tx_word = is_double_byte_mode(dspi); + + if (tx_word && (dspi->len == 1)) { + dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; + regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); + tx_word = 0; + } + + dspi_pushr = dspi_data_to_pushr(dspi, tx_word); + + if ((dspi->cs_change) && (!dspi->len)) + dspi_pushr &= ~SPI_PUSHR_CONT; + + regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr); + + return tx_word + 1; +} + +static void dspi_tcfq_read(struct fsl_dspi *dspi) +{ + int rx_word = is_double_byte_mode(dspi); + + dspi_data_from_popr(dspi, rx_word); +} + static int dspi_transfer_one_message(struct spi_master *master, struct spi_message *message) { @@ -326,8 +366,13 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val); - regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); - message->actual_length += dspi_transfer_write(dspi); + if (dspi->trans_mode == DSPI_EOQ_MODE) { + regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); + message->actual_length += dspi_eoq_write(dspi); + } else if (dspi->trans_mode == DSPI_TCFQ_MODE) { + regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE); + message->actual_length += dspi_tcfq_write(dspi); + } if (wait_event_interruptible(dspi->waitq, dspi->waitflags)) dev_err(>pdev->dev, "wait transfer complete fail!\n"); @@ -399,8 +4
[PATCH 6/7] spi: spi-fsl-dspi: split the resuable code
From: Chao Fu Add two functions: - dspi_data_from_popr - dspi_data_to_pushr Signed-off-by: Bhuvanchandra DV --- drivers/spi/spi-fsl-dspi.c | 118 +++-- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index b20dbb5..e0ce906 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -167,12 +167,68 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, *br = ARRAY_SIZE(brs) - 1; } +static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word) +{ + u16 d16; + u8 d8; + + if (tx_word) { + if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) { + d16 = *(u16 *)dspi->tx; + dspi->tx += 2; + } else { + d16 = dspi->void_write_data; + } + + dspi->len -= 2; + + return SPI_PUSHR_TXDATA(d16) | + SPI_PUSHR_PCS(dspi->cs) | + SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CONT; + } else { + if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) { + + d8 = *(u8 *)dspi->tx; + dspi->tx++; + } else { + d8 = (u8)dspi->void_write_data; + } + + dspi->len--; + + return SPI_PUSHR_TXDATA(d8) | + SPI_PUSHR_PCS(dspi->cs) | + SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CONT; + } +} + +static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word) +{ + u16 d; + unsigned int val; + + if (rx_word) { + regmap_read(dspi->regmap, SPI_POPR, ); + d = SPI_POPR_RXDATA(val); + + if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) + *(u16 *)dspi->rx = d; + dspi->rx += 2; + } else { + regmap_read(dspi->regmap, SPI_POPR, ); + d = SPI_POPR_RXDATA(val); + if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) + *(u8 *)dspi->rx = d; + dspi->rx++; + } +} + static int dspi_transfer_write(struct fsl_dspi *dspi) { int tx_count = 0; int tx_word; - u16 d16; - u8 d8; u32 dspi_pushr = 0; int first = 1; @@ -190,39 +246,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) } while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) { - if (tx_word) { - if (dspi->len == 1) - break; - - if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) { - d16 = *(u16 *)dspi->tx; - dspi->tx += 2; - } else { - d16 = dspi->void_write_data; - } - - dspi_pushr = SPI_PUSHR_TXDATA(d16) | - SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | - SPI_PUSHR_CONT; - - dspi->len -= 2; - } else { - if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) { - - d8 = *(u8 *)dspi->tx; - dspi->tx++; - } else { - d8 = (u8)dspi->void_write_data; - } - - dspi_pushr = SPI_PUSHR_TXDATA(d8) | - SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | - SPI_PUSHR_CONT; - - dspi->len--; - } + dspi_pushr = dspi_data_to_pushr(dspi, tx_word); if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { /* last transfer in the transfer */ @@ -249,32 +273,10 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) { int rx_count = 0; int rx_word = is_double_byte_mode(dspi); - u16 d; while ((dspi->rx < dspi->rx_end) && (rx_count < DSPI_FIFO_SIZE)) { - if (rx_word) { - unsigned int val; - - if ((dspi->rx_end - dspi->rx) == 1) - break; - - regmap_read(dspi->regmap, SPI_POPR, ); - d = SPI_POPR_RXDATA(val); - - if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) - *(u16 *)dspi->rx = d; - dspi-
[PATCH 5/7] spi: spi-fsl-dspi: Remove spi-bitbang
From: Chao Fu DSPI module need cs change information in a spi transfer. According to cs change, DSPI will give last data the right flag. Bitbang provide cs change behind the last data in a transfer. So DSPI can not deal the last data in every transfer properly, so remove the bitbang in the driver. Signed-off-by: Bhuvanchandra DV --- drivers/spi/Kconfig| 1 - drivers/spi/spi-fsl-dspi.c | 144 ++--- 2 files changed, 71 insertions(+), 74 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9982998..6316d6d 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -292,7 +292,6 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate "Freescale DSPI controller" - select SPI_BITBANG select REGMAP_MMIO depends on SOC_VF610 || COMPILE_TEST help diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 5378148..b20dbb5 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -106,7 +106,7 @@ struct chip_data { }; struct fsl_dspi { - struct spi_bitbang bitbang; + struct spi_master *master; struct platform_device *pdev; struct regmap *regmap; @@ -114,6 +114,7 @@ struct fsl_dspi { struct clk *clk; struct spi_transfer *cur_transfer; + struct spi_message *cur_msg; struct chip_data*cur_chip; size_t len; void*tx; @@ -123,6 +124,7 @@ struct fsl_dspi { chardataflags; u8 cs; u16 void_write_data; + u32 cs_change; wait_queue_head_t waitq; u32 waitflags; @@ -225,6 +227,8 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { /* last transfer in the transfer */ dspi_pushr |= SPI_PUSHR_EOQ; + if ((dspi->cs_change) && (!dspi->len)) + dspi_pushr &= ~SPI_PUSHR_CONT; } else if (tx_word && (dspi->len == 1)) dspi_pushr |= SPI_PUSHR_EOQ; @@ -246,6 +250,7 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) int rx_count = 0; int rx_word = is_double_byte_mode(dspi); u16 d; + while ((dspi->rx < dspi->rx_end) && (rx_count < DSPI_FIFO_SIZE)) { if (rx_word) { @@ -276,64 +281,67 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) return rx_count; } -static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t) +static int dspi_transfer_one_message(struct spi_master *master, + struct spi_message *message) { - struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); - dspi->cur_transfer = t; - dspi->cur_chip = spi_get_ctldata(spi); - dspi->cs = spi->chip_select; - dspi->void_write_data = dspi->cur_chip->void_write_data; - - dspi->dataflags = 0; - dspi->tx = (void *)t->tx_buf; - dspi->tx_end = dspi->tx + t->len; - dspi->rx = t->rx_buf; - dspi->rx_end = dspi->rx + t->len; - dspi->len = t->len; - - if (!dspi->rx) - dspi->dataflags |= TRAN_STATE_RX_VOID; - - if (!dspi->tx) - dspi->dataflags |= TRAN_STATE_TX_VOID; - - regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val); - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val); - regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); - - if (t->speed_hz) + struct fsl_dspi *dspi = spi_master_get_devdata(master); + struct spi_device *spi = message->spi; + struct spi_transfer *transfer; + int status = 0; + message->actual_length = 0; + + list_for_each_entry(transfer, >transfers, transfer_list) { + dspi->cur_transfer = transfer; + dspi->cur_msg = message; + dspi->cur_chip = spi_get_ctldata(spi); + dspi->cs = spi->chip_select; + if (dspi->cur_transfer->transfer_list.next + == >cur_msg->transfers) + transfer->cs_change = 1; + dspi->cs_change = transfer->cs_change; + dspi->void_write_data = dspi->cur_chip->void_write_data; + + dspi->dataflags = 0; + dspi->tx = (void *)transfer->tx_buf; + dspi->tx_end = dspi->tx + transfer->len; + dspi->rx = transfer->rx_buf; +
[PATCH 3/7] spi: spi-fsl-dspi: Remove usage of devm_kzalloc
devm_* API was supposed to be used only in probe function call. Memory is allocated at 'probe' and free automatically at 'remove'. Usage of devm_* functions outside probe sometimes leads to memory leak. Avoid using devm_kzalloc in dspi_setup_transfer and use kzalloc instead. Also add the dspi_cleanup function to free the controller data upon cleanup. [1.027945] fsl-dspi 4002d000.dspi1: registered master spi1 [1.028664] spi spi1.0: setup mode 0, 8 bits/w, 5000 Hz max --> 0 [1.028877] [ cut here ] [1.036953] WARNING: CPU: 0 PID: 1 at drivers/base/dd.c:286 driver_probe_device+0x1d8/0x244() [1.052136] Modules linked in: [1.058525] CPU: 0 PID: 1 Comm: swapper Not tainted 3.19.0-rc1-104479-g702bebc #202 [1.072777] Backtrace: [1.078437] [<80011a04>] (dump_backtrace) from [<80011ce0>] (show_stack+0x18/0x1c) [1.092393] r6:011e r5:0009 r4: r3: [1.101639] [<80011cc8>] (show_stack) from [<805a2d18>] (dump_stack+0x24/0x28) [1.115701] [<805a2cf4>] (dump_stack) from [<80021564>] (warn_slowpath_common+0x74/0x8c) [1.130905] [<800214f0>] (warn_slowpath_common) from [<80021620>] (warn_slowpath_null+0x24/0x2c) [1.147289] r8: r7:807d5dd0 r6:802e2f54 r5:8ea1a200 r4:808444d4 [1.158272] [<800215fc>] (warn_slowpath_null) from [<802e2ee8>] (driver_probe_device+0x1d8/0x244) [1.175532] [<802e2d10>] (driver_probe_device) from [<802e2f9c>] (__device_attach+0x48/0x4c) [1.192583] r8: r7:8ea4 r6:802e2f54 r5:8ea1a200 r4:807d5dd0 r3:8035a150 [1.209718] [<802e2f54>] (__device_attach) from [<802e14ac>] (bus_for_each_drv+0x60/0x94) [1.227619] r5:8ea1a200 r4: [1.236097] [<802e144c>] (bus_for_each_drv) from [<802e2cd4>] (device_attach+0x7c/0x90) [1.253809] r6:807d5cc0 r5:8ea1a234 r4:8ea1a200 [1.263442] [<802e2c58>] (device_attach) from [<802e2338>] (bus_probe_device+0x8c/0xb0) [1.281269] r6:807d5cc0 r5:8ea1a200 r4:8ea1a208 r3:8e881cc0 [1.292124] [<802e22ac>] (bus_probe_device) from [<802e06c8>] (device_add+0x448/0x528) [1.309972] r6:8ea1a200 r5: r4:8ea1a208 r3:0001 [1.320830] [<802e0280>] (device_add) from [<8035a8c8>] (spi_add_device+0x9c/0x15c) [1.338382] r9:8e8ab210 r8: r7:8e8ab210 r6: r5:8ea4 r4:8ea1a200 [1.356236] [<8035a82c>] (spi_add_device) from [<8035c0a8>] (spi_register_master+0x4d8/0x73c) [1.374695] r7:8ea1a368 r6:8ea1a200 r5:8fde7f7c r4:8ea4 [1.385537] [<8035bbd0>] (spi_register_master) from [<8035d930>] (spi_bitbang_start+0x9c/0x108) [1.404100] r10:8088 r9:8e816f80 r8:8fde7c50 r7:8e8ab210 r6:8e8ab200 r5:8ea4 [1.421967] r4:8ea4 [1.429305] [<8035d894>] (spi_bitbang_start) from [<8035e334>] (dspi_probe+0x1d4/0x2bc) [1.446821] r4:8ea40210 r3:80845a10 [1.455241] [<8035e160>] (dspi_probe) from [<802e4854>] (platform_drv_probe+0x4c/0xac) [1.472666] r10: r9:8ea1c2c0 r8: r7:807d5e20 r6:807d5e20 r5:fdfb [1.490365] r4:8e8ab210 [1.497638] [<802e4808>] (platform_drv_probe) from [<802e2e20>] (driver_probe_device+0x110/0x244) [1.516021] r7:807d5e20 r6: r5:8e8ab210 r4:808444d4 [1.526612] [<802e2d10>] (driver_probe_device) from [<802e3034>] (__driver_attach+0x94/0x98) [1.544556] r8:807735e8 r7: r6:8e8ab244 r5:807d5e20 r4:8e8ab210 r3: [1.562013] [<802e2fa0>] (__driver_attach) from [<802e13f4>] (bus_for_each_dev+0x68/0x9c) [1.579714] r6:802e2fa0 r5:807d5e20 r4: r3:8e8ad03c [1.590310] [<802e138c>] (bus_for_each_dev) from [<802e2914>] (driver_attach+0x24/0x28) [1.607804] r6:807ca840 r5:8ea25700 r4:807d5e20 [1.617252] [<802e28f0>] (driver_attach) from [<802e25bc>] (bus_add_driver+0x150/0x1f8) [1.634584] [<802e246c>] (bus_add_driver) from [<802e3670>] (driver_register+0x80/0x100) [1.652292] r7:8e842038 r6:8078e0f8 r5:807b3460 r4:807d5e20 [1.662953] [<802e35f0>] (driver_register) from [<802e4798>] (__platform_driver_register+0x5c/0x64) [1.681772] r5:807b3460 r4:807b3460 [1.690234] [<802e473c>] (__platform_driver_register) from [<8078e114>] (fsl_dspi_driver_init+0x1c/0x20) [1.709306] [<8078e0f8>] (fsl_dspi_driver_init) from [<80008770>] (do_one_initcall+0x94/0x1d4) [1.727791] [<800086dc>] (do_one_initcall) from [<80773e38>] (kernel_init_freeable+0x130/0x1d0) [1.746412] r10:8079eef0 r9:8079eee4 r8:807735e8 r7:807f1c80 r6:807f1c80 r5:0006 [1.764399] r4:807a7bc8 [1.771813] [<80773d08>] (kernel_init_freeable) from [<8059f864>] (kernel_init+0x10/0xf0) [1.789660] r10:0000 r9:000000
[PATCH 4/7] spi: spi-fsl-dspi: avoid preparing the clock two times
regmap_read/regmap_write will expect the peripheral clock to be enabled before accessing the registers of the peripheral. Since the peripheral clock is enabled separatly, avoid redundant clock prepare (with devm_regmap_init_mmio_clk) and use devm_regmap_init_mmio instead. Acked-by: Stefan Agner Signed-off-by: Bhuvanchandra DV --- drivers/spi/spi-fsl-dspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 9b80d54..5378148 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -502,7 +502,7 @@ static int dspi_probe(struct platform_device *pdev) goto out_master_put; } - dspi->regmap = devm_regmap_init_mmio_clk(>dev, "dspi", base, + dspi->regmap = devm_regmap_init_mmio(>dev, base, _regmap_config); if (IS_ERR(dspi->regmap)) { dev_err(>dev, "failed to init regmap: %ld\n", -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/7] ARM: vf610: add second DSPI instance
Acked-by: Stefan Agner Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf500.dtsi | 4 arch/arm/boot/dts/vfxxx.dtsi | 11 +++ 2 files changed, 15 insertions(+) diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi index 1dbf8d2..f5f807c 100644 --- a/arch/arm/boot/dts/vf500.dtsi +++ b/arch/arm/boot/dts/vf500.dtsi @@ -66,6 +66,10 @@ interrupts = ; }; + { + interrupts = ; +}; + { interrupts = , ; diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index a29c7ce..789744b 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -139,6 +139,17 @@ status = "disabled"; }; + dspi1: dspi1@4002d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,vf610-dspi"; + reg = <0x4002d000 0x1000>; + clocks = < VF610_CLK_DSPI1>; + clock-names = "dspi"; + spi-num-chipselects = <5>; + status = "disabled"; + }; + sai2: sai@40031000 { compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/7] ARM: vf-colibri: add SPI support and enable MCP2515 CAN
MCP2515 CAN controller is available on Colibri Evaluation board. Hence enable MCP2515 CAN. Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 31 +++ arch/arm/boot/dts/vf-colibri.dtsi | 15 +++ 2 files changed, 46 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 36cafbf..69364b0 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -12,6 +12,12 @@ bootargs = "console=ttyLP0,115200"; }; + clk16m: clk16m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1600>; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -47,6 +53,21 @@ status = "okay"; }; + { + status = "okay"; + + can2: mcp2515@0 { + compatible = "microchip,mcp2515"; + pinctrl-names = "default"; + pinctrl-0 = <_can_int>; + reg = <0>; + clocks = <>; + spi-max-frequency = <1000>; + interrupt-parent = <>; + interrupts = <11 GPIO_ACTIVE_LOW>; + }; +}; + { pinctrl-names = "default"; pinctrl-0 = <_esdhc1>; @@ -94,3 +115,13 @@ { vbus-supply = <_vbus_reg>; }; + + { + vf610-colibri { + pinctrl_can_int: can_int { + fsl,pins = < + VF610_PAD_PTB21__GPIO_430x22ed + >; + }; + }; +}; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 5c2b732..fbef082 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -23,6 +23,12 @@ status = "okay"; }; + { + bus-num = <1>; + pinctrl-names = "default"; + pinctrl-0 = <_dspi1>; +}; + { status = "okay"; }; @@ -107,6 +113,15 @@ >; }; + pinctrl_dspi1: dspi1grp { + fsl,pins = < + VF610_PAD_PTD5__DSPI1_CS0 0x33e2 + VF610_PAD_PTD6__DSPI1_SIN 0x33e1 + VF610_PAD_PTD7__DSPI1_SOUT 0x33e2 + VF610_PAD_PTD8__DSPI1_SCK 0x33e2 + >; + }; + pinctrl_esdhc1: esdhc1grp { fsl,pins = < VF610_PAD_PTA24__ESDHC1_CLK 0x31ef -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/7] spi: spi-fsl-dspi: Remove spi-bitbang
From: Chao Fu b44...@freescale.com DSPI module need cs change information in a spi transfer. According to cs change, DSPI will give last data the right flag. Bitbang provide cs change behind the last data in a transfer. So DSPI can not deal the last data in every transfer properly, so remove the bitbang in the driver. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/spi/Kconfig| 1 - drivers/spi/spi-fsl-dspi.c | 144 ++--- 2 files changed, 71 insertions(+), 74 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9982998..6316d6d 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -292,7 +292,6 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate Freescale DSPI controller - select SPI_BITBANG select REGMAP_MMIO depends on SOC_VF610 || COMPILE_TEST help diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 5378148..b20dbb5 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -106,7 +106,7 @@ struct chip_data { }; struct fsl_dspi { - struct spi_bitbang bitbang; + struct spi_master *master; struct platform_device *pdev; struct regmap *regmap; @@ -114,6 +114,7 @@ struct fsl_dspi { struct clk *clk; struct spi_transfer *cur_transfer; + struct spi_message *cur_msg; struct chip_data*cur_chip; size_t len; void*tx; @@ -123,6 +124,7 @@ struct fsl_dspi { chardataflags; u8 cs; u16 void_write_data; + u32 cs_change; wait_queue_head_t waitq; u32 waitflags; @@ -225,6 +227,8 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) if (dspi-len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { /* last transfer in the transfer */ dspi_pushr |= SPI_PUSHR_EOQ; + if ((dspi-cs_change) (!dspi-len)) + dspi_pushr = ~SPI_PUSHR_CONT; } else if (tx_word (dspi-len == 1)) dspi_pushr |= SPI_PUSHR_EOQ; @@ -246,6 +250,7 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) int rx_count = 0; int rx_word = is_double_byte_mode(dspi); u16 d; + while ((dspi-rx dspi-rx_end) (rx_count DSPI_FIFO_SIZE)) { if (rx_word) { @@ -276,64 +281,67 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) return rx_count; } -static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t) +static int dspi_transfer_one_message(struct spi_master *master, + struct spi_message *message) { - struct fsl_dspi *dspi = spi_master_get_devdata(spi-master); - dspi-cur_transfer = t; - dspi-cur_chip = spi_get_ctldata(spi); - dspi-cs = spi-chip_select; - dspi-void_write_data = dspi-cur_chip-void_write_data; - - dspi-dataflags = 0; - dspi-tx = (void *)t-tx_buf; - dspi-tx_end = dspi-tx + t-len; - dspi-rx = t-rx_buf; - dspi-rx_end = dspi-rx + t-len; - dspi-len = t-len; - - if (!dspi-rx) - dspi-dataflags |= TRAN_STATE_RX_VOID; - - if (!dspi-tx) - dspi-dataflags |= TRAN_STATE_TX_VOID; - - regmap_write(dspi-regmap, SPI_MCR, dspi-cur_chip-mcr_val); - regmap_write(dspi-regmap, SPI_CTAR(dspi-cs), dspi-cur_chip-ctar_val); - regmap_write(dspi-regmap, SPI_RSER, SPI_RSER_EOQFE); - - if (t-speed_hz) + struct fsl_dspi *dspi = spi_master_get_devdata(master); + struct spi_device *spi = message-spi; + struct spi_transfer *transfer; + int status = 0; + message-actual_length = 0; + + list_for_each_entry(transfer, message-transfers, transfer_list) { + dspi-cur_transfer = transfer; + dspi-cur_msg = message; + dspi-cur_chip = spi_get_ctldata(spi); + dspi-cs = spi-chip_select; + if (dspi-cur_transfer-transfer_list.next + == dspi-cur_msg-transfers) + transfer-cs_change = 1; + dspi-cs_change = transfer-cs_change; + dspi-void_write_data = dspi-cur_chip-void_write_data; + + dspi-dataflags = 0; + dspi-tx = (void *)transfer-tx_buf; + dspi-tx_end = dspi-tx + transfer-len; + dspi-rx = transfer-rx_buf; + dspi-rx_end = dspi-rx + transfer-len; + dspi-len = transfer-len; + + if (!dspi-rx) + dspi-dataflags |= TRAN_STATE_RX_VOID; + + if (!dspi-tx) + dspi-dataflags
[PATCH 7/7] spi: spi-fsl-dspi: Add support for TCFQ transfer mode
From: Chao Fu b44...@freescale.com TCFQ is interrupt of Transfer Complete Flag in DSPI module. EOQ is interrupt of End of Queue Flag in DSPI module. For adopting of different platform, either of them is a way of DSPI transfer data. This patch add TCF support for DSPI module in other platform. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- .../devicetree/bindings/spi/spi-fsl-dspi.txt | 2 + drivers/spi/spi-fsl-dspi.c | 74 +++--- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index cbbe16e..b50439f 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt @@ -15,6 +15,8 @@ Optional property: - big-endian: If present the dspi device's registers are implemented in big endian mode, otherwise in native mode(same with CPU), for more detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. +- tcfq-mode: If present, the data transfer will be done at TCFQ interrupt. + By default, driver chooses EOQ interrupt if 'tcfq-mode' property was not set. Example: diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index e0ce906..feca2fd 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -63,9 +63,11 @@ #define SPI_CTAR0_SLAVE0x0c #define SPI_SR 0x2c +#define SPI_SR_TCFQF 0x8000 #define SPI_SR_EOQF0x1000 #define SPI_RSER 0x30 +#define SPI_RSER_TCFQE 0x8000 #define SPI_RSER_EOQFE 0x1000 #define SPI_PUSHR 0x34 @@ -105,6 +107,12 @@ struct chip_data { u16 void_write_data; }; +enum dspi_trans_mode { + DSPI_EOQ_MODE = 0, + DSPI_TCFQ_MODE, + DSPI_DMA_MODE, /*TODO*/ +}; + struct fsl_dspi { struct spi_master *master; struct platform_device *pdev; @@ -125,6 +133,7 @@ struct fsl_dspi { u8 cs; u16 void_write_data; u32 cs_change; + enum dspi_trans_modetrans_mode; wait_queue_head_t waitq; u32 waitflags; @@ -225,7 +234,7 @@ static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word) } } -static int dspi_transfer_write(struct fsl_dspi *dspi) +static int dspi_eoq_write(struct fsl_dspi *dspi) { int tx_count = 0; int tx_word; @@ -269,7 +278,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) return tx_count * (tx_word + 1); } -static int dspi_transfer_read(struct fsl_dspi *dspi) +static int dspi_eoq_read(struct fsl_dspi *dspi) { int rx_count = 0; int rx_word = is_double_byte_mode(dspi); @@ -283,6 +292,37 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) return rx_count; } +static int dspi_tcfq_write(struct fsl_dspi *dspi) +{ + int tx_word; + u32 dspi_pushr = 0; + + tx_word = is_double_byte_mode(dspi); + + if (tx_word (dspi-len == 1)) { + dspi-dataflags |= TRAN_STATE_WORD_ODD_NUM; + regmap_update_bits(dspi-regmap, SPI_CTAR(dspi-cs), + SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); + tx_word = 0; + } + + dspi_pushr = dspi_data_to_pushr(dspi, tx_word); + + if ((dspi-cs_change) (!dspi-len)) + dspi_pushr = ~SPI_PUSHR_CONT; + + regmap_write(dspi-regmap, SPI_PUSHR, dspi_pushr); + + return tx_word + 1; +} + +static void dspi_tcfq_read(struct fsl_dspi *dspi) +{ + int rx_word = is_double_byte_mode(dspi); + + dspi_data_from_popr(dspi, rx_word); +} + static int dspi_transfer_one_message(struct spi_master *master, struct spi_message *message) { @@ -326,8 +366,13 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_write(dspi-regmap, SPI_CTAR(dspi-cs), dspi-cur_chip-ctar_val); - regmap_write(dspi-regmap, SPI_RSER, SPI_RSER_EOQFE); - message-actual_length += dspi_transfer_write(dspi); + if (dspi-trans_mode == DSPI_EOQ_MODE) { + regmap_write(dspi-regmap, SPI_RSER, SPI_RSER_EOQFE); + message-actual_length += dspi_eoq_write(dspi); + } else if (dspi-trans_mode == DSPI_TCFQ_MODE) { + regmap_write(dspi-regmap, SPI_RSER, SPI_RSER_TCFQE); + message-actual_length += dspi_tcfq_write(dspi); + } if (wait_event_interruptible(dspi-waitq, dspi-waitflags)) dev_err(dspi-pdev-dev, wait transfer complete fail!\n); @@ -399,8 +444,13 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) struct
[PATCH 6/7] spi: spi-fsl-dspi: split the resuable code
From: Chao Fu b44...@freescale.com Add two functions: - dspi_data_from_popr - dspi_data_to_pushr Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/spi/spi-fsl-dspi.c | 118 +++-- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index b20dbb5..e0ce906 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -167,12 +167,68 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, *br = ARRAY_SIZE(brs) - 1; } +static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word) +{ + u16 d16; + u8 d8; + + if (tx_word) { + if (!(dspi-dataflags TRAN_STATE_TX_VOID)) { + d16 = *(u16 *)dspi-tx; + dspi-tx += 2; + } else { + d16 = dspi-void_write_data; + } + + dspi-len -= 2; + + return SPI_PUSHR_TXDATA(d16) | + SPI_PUSHR_PCS(dspi-cs) | + SPI_PUSHR_CTAS(dspi-cs) | + SPI_PUSHR_CONT; + } else { + if (!(dspi-dataflags TRAN_STATE_TX_VOID)) { + + d8 = *(u8 *)dspi-tx; + dspi-tx++; + } else { + d8 = (u8)dspi-void_write_data; + } + + dspi-len--; + + return SPI_PUSHR_TXDATA(d8) | + SPI_PUSHR_PCS(dspi-cs) | + SPI_PUSHR_CTAS(dspi-cs) | + SPI_PUSHR_CONT; + } +} + +static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word) +{ + u16 d; + unsigned int val; + + if (rx_word) { + regmap_read(dspi-regmap, SPI_POPR, val); + d = SPI_POPR_RXDATA(val); + + if (!(dspi-dataflags TRAN_STATE_RX_VOID)) + *(u16 *)dspi-rx = d; + dspi-rx += 2; + } else { + regmap_read(dspi-regmap, SPI_POPR, val); + d = SPI_POPR_RXDATA(val); + if (!(dspi-dataflags TRAN_STATE_RX_VOID)) + *(u8 *)dspi-rx = d; + dspi-rx++; + } +} + static int dspi_transfer_write(struct fsl_dspi *dspi) { int tx_count = 0; int tx_word; - u16 d16; - u8 d8; u32 dspi_pushr = 0; int first = 1; @@ -190,39 +246,7 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) } while (dspi-len (tx_count DSPI_FIFO_SIZE)) { - if (tx_word) { - if (dspi-len == 1) - break; - - if (!(dspi-dataflags TRAN_STATE_TX_VOID)) { - d16 = *(u16 *)dspi-tx; - dspi-tx += 2; - } else { - d16 = dspi-void_write_data; - } - - dspi_pushr = SPI_PUSHR_TXDATA(d16) | - SPI_PUSHR_PCS(dspi-cs) | - SPI_PUSHR_CTAS(dspi-cs) | - SPI_PUSHR_CONT; - - dspi-len -= 2; - } else { - if (!(dspi-dataflags TRAN_STATE_TX_VOID)) { - - d8 = *(u8 *)dspi-tx; - dspi-tx++; - } else { - d8 = (u8)dspi-void_write_data; - } - - dspi_pushr = SPI_PUSHR_TXDATA(d8) | - SPI_PUSHR_PCS(dspi-cs) | - SPI_PUSHR_CTAS(dspi-cs) | - SPI_PUSHR_CONT; - - dspi-len--; - } + dspi_pushr = dspi_data_to_pushr(dspi, tx_word); if (dspi-len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { /* last transfer in the transfer */ @@ -249,32 +273,10 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) { int rx_count = 0; int rx_word = is_double_byte_mode(dspi); - u16 d; while ((dspi-rx dspi-rx_end) (rx_count DSPI_FIFO_SIZE)) { - if (rx_word) { - unsigned int val; - - if ((dspi-rx_end - dspi-rx) == 1) - break; - - regmap_read(dspi-regmap, SPI_POPR, val); - d = SPI_POPR_RXDATA(val); - - if (!(dspi-dataflags TRAN_STATE_RX_VOID)) - *(u16 *)dspi-rx = d; - dspi-rx += 2; - - } else { - unsigned int val; - - regmap_read(dspi-regmap, SPI_POPR, val); - d = SPI_POPR_RXDATA(val
[PATCH 4/7] spi: spi-fsl-dspi: avoid preparing the clock two times
regmap_read/regmap_write will expect the peripheral clock to be enabled before accessing the registers of the peripheral. Since the peripheral clock is enabled separatly, avoid redundant clock prepare (with devm_regmap_init_mmio_clk) and use devm_regmap_init_mmio instead. Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/spi/spi-fsl-dspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 9b80d54..5378148 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -502,7 +502,7 @@ static int dspi_probe(struct platform_device *pdev) goto out_master_put; } - dspi-regmap = devm_regmap_init_mmio_clk(pdev-dev, dspi, base, + dspi-regmap = devm_regmap_init_mmio(pdev-dev, base, dspi_regmap_config); if (IS_ERR(dspi-regmap)) { dev_err(pdev-dev, failed to init regmap: %ld\n, -- 2.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/7] ARM: vf610: add second DSPI instance
Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf500.dtsi | 4 arch/arm/boot/dts/vfxxx.dtsi | 11 +++ 2 files changed, 15 insertions(+) diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi index 1dbf8d2..f5f807c 100644 --- a/arch/arm/boot/dts/vf500.dtsi +++ b/arch/arm/boot/dts/vf500.dtsi @@ -66,6 +66,10 @@ interrupts = GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH; }; +dspi1 { + interrupts = GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH; +}; + edma0 { interrupts = GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH, GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH; diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index a29c7ce..789744b 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -139,6 +139,17 @@ status = disabled; }; + dspi1: dspi1@4002d000 { + #address-cells = 1; + #size-cells = 0; + compatible = fsl,vf610-dspi; + reg = 0x4002d000 0x1000; + clocks = clks VF610_CLK_DSPI1; + clock-names = dspi; + spi-num-chipselects = 5; + status = disabled; + }; + sai2: sai@40031000 { compatible = fsl,vf610-sai; reg = 0x40031000 0x1000; -- 2.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/7] ARM: vf-colibri: add SPI support and enable MCP2515 CAN
MCP2515 CAN controller is available on Colibri Evaluation board. Hence enable MCP2515 CAN. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 31 +++ arch/arm/boot/dts/vf-colibri.dtsi | 15 +++ 2 files changed, 46 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 36cafbf..69364b0 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -12,6 +12,12 @@ bootargs = console=ttyLP0,115200; }; + clk16m: clk16m { + compatible = fixed-clock; + #clock-cells = 0; + clock-frequency = 1600; + }; + regulators { compatible = simple-bus; #address-cells = 1; @@ -47,6 +53,21 @@ status = okay; }; +dspi1 { + status = okay; + + can2: mcp2515@0 { + compatible = microchip,mcp2515; + pinctrl-names = default; + pinctrl-0 = pinctrl_can_int; + reg = 0; + clocks = clk16m; + spi-max-frequency = 1000; + interrupt-parent = gpio2; + interrupts = 11 GPIO_ACTIVE_LOW; + }; +}; + esdhc1 { pinctrl-names = default; pinctrl-0 = pinctrl_esdhc1; @@ -94,3 +115,13 @@ usbh1 { vbus-supply = usbh_vbus_reg; }; + +iomuxc { + vf610-colibri { + pinctrl_can_int: can_int { + fsl,pins = + VF610_PAD_PTB21__GPIO_430x22ed + ; + }; + }; +}; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 5c2b732..fbef082 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -23,6 +23,12 @@ status = okay; }; +dspi1 { + bus-num = 1; + pinctrl-names = default; + pinctrl-0 = pinctrl_dspi1; +}; + edma0 { status = okay; }; @@ -107,6 +113,15 @@ ; }; + pinctrl_dspi1: dspi1grp { + fsl,pins = + VF610_PAD_PTD5__DSPI1_CS0 0x33e2 + VF610_PAD_PTD6__DSPI1_SIN 0x33e1 + VF610_PAD_PTD7__DSPI1_SOUT 0x33e2 + VF610_PAD_PTD8__DSPI1_SCK 0x33e2 + ; + }; + pinctrl_esdhc1: esdhc1grp { fsl,pins = VF610_PAD_PTA24__ESDHC1_CLK 0x31ef -- 2.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/7] spi: spi-fsl-dspi: Remove usage of devm_kzalloc
devm_* API was supposed to be used only in probe function call. Memory is allocated at 'probe' and free automatically at 'remove'. Usage of devm_* functions outside probe sometimes leads to memory leak. Avoid using devm_kzalloc in dspi_setup_transfer and use kzalloc instead. Also add the dspi_cleanup function to free the controller data upon cleanup. [1.027945] fsl-dspi 4002d000.dspi1: registered master spi1 [1.028664] spi spi1.0: setup mode 0, 8 bits/w, 5000 Hz max -- 0 [1.028877] [ cut here ] [1.036953] WARNING: CPU: 0 PID: 1 at drivers/base/dd.c:286 driver_probe_device+0x1d8/0x244() [1.052136] Modules linked in: [1.058525] CPU: 0 PID: 1 Comm: swapper Not tainted 3.19.0-rc1-104479-g702bebc #202 [1.072777] Backtrace: [1.078437] [80011a04] (dump_backtrace) from [80011ce0] (show_stack+0x18/0x1c) [1.092393] r6:011e r5:0009 r4: r3: [1.101639] [80011cc8] (show_stack) from [805a2d18] (dump_stack+0x24/0x28) [1.115701] [805a2cf4] (dump_stack) from [80021564] (warn_slowpath_common+0x74/0x8c) [1.130905] [800214f0] (warn_slowpath_common) from [80021620] (warn_slowpath_null+0x24/0x2c) [1.147289] r8: r7:807d5dd0 r6:802e2f54 r5:8ea1a200 r4:808444d4 [1.158272] [800215fc] (warn_slowpath_null) from [802e2ee8] (driver_probe_device+0x1d8/0x244) [1.175532] [802e2d10] (driver_probe_device) from [802e2f9c] (__device_attach+0x48/0x4c) [1.192583] r8: r7:8ea4 r6:802e2f54 r5:8ea1a200 r4:807d5dd0 r3:8035a150 [1.209718] [802e2f54] (__device_attach) from [802e14ac] (bus_for_each_drv+0x60/0x94) [1.227619] r5:8ea1a200 r4: [1.236097] [802e144c] (bus_for_each_drv) from [802e2cd4] (device_attach+0x7c/0x90) [1.253809] r6:807d5cc0 r5:8ea1a234 r4:8ea1a200 [1.263442] [802e2c58] (device_attach) from [802e2338] (bus_probe_device+0x8c/0xb0) [1.281269] r6:807d5cc0 r5:8ea1a200 r4:8ea1a208 r3:8e881cc0 [1.292124] [802e22ac] (bus_probe_device) from [802e06c8] (device_add+0x448/0x528) [1.309972] r6:8ea1a200 r5: r4:8ea1a208 r3:0001 [1.320830] [802e0280] (device_add) from [8035a8c8] (spi_add_device+0x9c/0x15c) [1.338382] r9:8e8ab210 r8: r7:8e8ab210 r6: r5:8ea4 r4:8ea1a200 [1.356236] [8035a82c] (spi_add_device) from [8035c0a8] (spi_register_master+0x4d8/0x73c) [1.374695] r7:8ea1a368 r6:8ea1a200 r5:8fde7f7c r4:8ea4 [1.385537] [8035bbd0] (spi_register_master) from [8035d930] (spi_bitbang_start+0x9c/0x108) [1.404100] r10:8088 r9:8e816f80 r8:8fde7c50 r7:8e8ab210 r6:8e8ab200 r5:8ea4 [1.421967] r4:8ea4 [1.429305] [8035d894] (spi_bitbang_start) from [8035e334] (dspi_probe+0x1d4/0x2bc) [1.446821] r4:8ea40210 r3:80845a10 [1.455241] [8035e160] (dspi_probe) from [802e4854] (platform_drv_probe+0x4c/0xac) [1.472666] r10: r9:8ea1c2c0 r8: r7:807d5e20 r6:807d5e20 r5:fdfb [1.490365] r4:8e8ab210 [1.497638] [802e4808] (platform_drv_probe) from [802e2e20] (driver_probe_device+0x110/0x244) [1.516021] r7:807d5e20 r6: r5:8e8ab210 r4:808444d4 [1.526612] [802e2d10] (driver_probe_device) from [802e3034] (__driver_attach+0x94/0x98) [1.544556] r8:807735e8 r7: r6:8e8ab244 r5:807d5e20 r4:8e8ab210 r3: [1.562013] [802e2fa0] (__driver_attach) from [802e13f4] (bus_for_each_dev+0x68/0x9c) [1.579714] r6:802e2fa0 r5:807d5e20 r4: r3:8e8ad03c [1.590310] [802e138c] (bus_for_each_dev) from [802e2914] (driver_attach+0x24/0x28) [1.607804] r6:807ca840 r5:8ea25700 r4:807d5e20 [1.617252] [802e28f0] (driver_attach) from [802e25bc] (bus_add_driver+0x150/0x1f8) [1.634584] [802e246c] (bus_add_driver) from [802e3670] (driver_register+0x80/0x100) [1.652292] r7:8e842038 r6:8078e0f8 r5:807b3460 r4:807d5e20 [1.662953] [802e35f0] (driver_register) from [802e4798] (__platform_driver_register+0x5c/0x64) [1.681772] r5:807b3460 r4:807b3460 [1.690234] [802e473c] (__platform_driver_register) from [8078e114] (fsl_dspi_driver_init+0x1c/0x20) [1.709306] [8078e0f8] (fsl_dspi_driver_init) from [80008770] (do_one_initcall+0x94/0x1d4) [1.727791] [800086dc] (do_one_initcall) from [80773e38] (kernel_init_freeable+0x130/0x1d0) [1.746412] r10:8079eef0 r9:8079eee4 r8:807735e8 r7:807f1c80 r6:807f1c80 r5:0006 [1.764399] r4:807a7bc8 [1.771813] [80773d08] (kernel_init_freeable) from [8059f864] (kernel_init+0x10/0xf0) [1.789660] r10: r9: r8: r7: r6: r5:8059f854 [1.807381] r4: [1.814668] [8059f854] (kernel_init) from [8000e638] (ret_from_fork+0x14/0x3c) [1.831772] r4: r3:8e842000 [1.840212] ---[ end trace f7f1c89f62e53de9 ]--- Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/spi/spi-fsl-dspi.c | 14 -- 1 file changed, 12
[PATCH 0/7] Add SPI support for Colibri modules and DSPI driver fixes
- Add second dspi instance. - Enable MCP2515 CAN controller which is avaialble on Colibri evaluation board. - Respin the stalled patches of dspi fixes. Previous discussion at: http://comments.gmane.org/gmane.linux.ports.arm.kernel/359542 Bhuvanchandra DV (4): ARM: vf610: add second DSPI instance ARM: vf-colibri: add SPI support and enable MCP2515 CAN spi: spi-fsl-dspi: Remove usage of devm_kalloc spi: spi-fsl-dspi: avoid preparing the clocks two times Chao Fu (3): spi: spi-fsl-dspi: Remove spi-bitbang spi: spi-fsl-dspi: split the resuable code spi: spi-fsl-dspi: Add support for TCFQ transfer mode .../devicetree/bindings/spi/spi-fsl-dspi.txt | 2 + arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 31 ++ arch/arm/boot/dts/vf-colibri.dtsi | 15 + arch/arm/boot/dts/vf500.dtsi | 4 + arch/arm/boot/dts/vfxxx.dtsi | 11 + drivers/spi/Kconfig| 1 - drivers/spi/spi-fsl-dspi.c | 314 + 7 files changed, 254 insertions(+), 124 deletions(-) -- 2.2.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ARM: imx: clk-vf610: Add clock for UART4 and UART5
Add support for clock gating of UART4 and UART5. We use these UART's in a (not yet mainlined) device tree. Signed-off-by: Bhuvanchandra DV --- arch/arm/mach-imx/clk-vf610.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index cb21777..af338d2 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -267,6 +267,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8)); clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9)); clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10)); + clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9)); + clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10)); clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net: fec: Fix dual ethernet issue in VFxx
On i.MX28, the MDIO bus is shared between the two RMII interfaces. However, in newer designs, such as Vybrid, this is not the case. This patch adds a quirk for the single MDIO case. This allows to use both FEC interfaces working independently on Vybird. Signed-off-by: Bhuvanchandra DV --- drivers/net/ethernet/freescale/fec.h |3 +++ drivers/net/ethernet/freescale/fec_main.c |7 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 469691a..c9515bc 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -425,6 +425,9 @@ struct bufdesc_ex { */ #define FEC_QUIRK_BUG_CAPTURE (1 << 10) +/* Controller has only one MDIO bus for interfacing external PHY's */ +#define FEC_QUIRK_SINGLE_MDIO (1 << 11) + struct fec_enet_priv_tx_q { int index; unsigned char *tx_bounce[TX_RING_SIZE]; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 5ebdf8d..22b7748 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -91,7 +91,8 @@ static struct platform_device_id fec_devtype[] = { .driver_data = 0, }, { .name = "imx28-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, + .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | + FEC_QUIRK_SINGLE_MDIO, }, { .name = "imx6q-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | @@ -1952,7 +1953,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) * mdio interface in board design, and need to be configured by * fec0 mii_bus. */ - if ((fep->quirks & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { + if ((fep->quirks & FEC_QUIRK_SINGLE_MDIO) && fep->dev_id > 0) { /* fec1 uses fec0 mii_bus */ if (mii_cnt && fec0_mii_bus) { fep->mii_bus = fec0_mii_bus; @@ -2015,7 +2016,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) mii_cnt++; /* save fec0 mii_bus */ - if (fep->quirks & FEC_QUIRK_ENET_MAC) + if (fep->quirks & FEC_QUIRK_SINGLE_MDIO) fec0_mii_bus = fep->mii_bus; return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net: fec: Fix dual ethernet issue in VFxx
On i.MX28, the MDIO bus is shared between the two RMII interfaces. However, in newer designs, such as Vybrid, this is not the case. This patch adds a quirk for the single MDIO case. This allows to use both FEC interfaces working independently on Vybird. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- drivers/net/ethernet/freescale/fec.h |3 +++ drivers/net/ethernet/freescale/fec_main.c |7 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 469691a..c9515bc 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -425,6 +425,9 @@ struct bufdesc_ex { */ #define FEC_QUIRK_BUG_CAPTURE (1 10) +/* Controller has only one MDIO bus for interfacing external PHY's */ +#define FEC_QUIRK_SINGLE_MDIO (1 11) + struct fec_enet_priv_tx_q { int index; unsigned char *tx_bounce[TX_RING_SIZE]; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 5ebdf8d..22b7748 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -91,7 +91,8 @@ static struct platform_device_id fec_devtype[] = { .driver_data = 0, }, { .name = imx28-fec, - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, + .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | + FEC_QUIRK_SINGLE_MDIO, }, { .name = imx6q-fec, .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | @@ -1952,7 +1953,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) * mdio interface in board design, and need to be configured by * fec0 mii_bus. */ - if ((fep-quirks FEC_QUIRK_ENET_MAC) fep-dev_id 0) { + if ((fep-quirks FEC_QUIRK_SINGLE_MDIO) fep-dev_id 0) { /* fec1 uses fec0 mii_bus */ if (mii_cnt fec0_mii_bus) { fep-mii_bus = fec0_mii_bus; @@ -2015,7 +2016,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) mii_cnt++; /* save fec0 mii_bus */ - if (fep-quirks FEC_QUIRK_ENET_MAC) + if (fep-quirks FEC_QUIRK_SINGLE_MDIO) fec0_mii_bus = fep-mii_bus; return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ARM: imx: clk-vf610: Add clock for UART4 and UART5
Add support for clock gating of UART4 and UART5. We use these UART's in a (not yet mainlined) device tree. Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/mach-imx/clk-vf610.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index cb21777..af338d2 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -267,6 +267,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_UART1] = imx_clk_gate2(uart1, ipg_bus, CCM_CCGR0, CCM_CCGRx_CGn(8)); clk[VF610_CLK_UART2] = imx_clk_gate2(uart2, ipg_bus, CCM_CCGR0, CCM_CCGRx_CGn(9)); clk[VF610_CLK_UART3] = imx_clk_gate2(uart3, ipg_bus, CCM_CCGR0, CCM_CCGRx_CGn(10)); + clk[VF610_CLK_UART4] = imx_clk_gate2(uart4, ipg_bus, CCM_CCGR6, CCM_CCGRx_CGn(9)); + clk[VF610_CLK_UART5] = imx_clk_gate2(uart5, ipg_bus, CCM_CCGR6, CCM_CCGRx_CGn(10)); clk[VF610_CLK_I2C0] = imx_clk_gate2(i2c0, ipg_bus, CCM_CCGR4, CCM_CCGRx_CGn(6)); clk[VF610_CLK_I2C1] = imx_clk_gate2(i2c1, ipg_bus, CCM_CCGR4, CCM_CCGRx_CGn(7)); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V2 0/2] Add I2C and enable M41T0M6 RTC
Add I2C support on Colibri VFxx moduels and enable M41T0M6 RTC available on Colibri carrier boards. Bhuvanchandra DV (2): ARM: dts: vf-colibri: Add I2C support ARM: dts: vf-colibri-eval-v3.dts: Enable ST-M41T0M6 RTC arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 12 +++- arch/arm/boot/dts/vf-colibri.dtsi | 13 + 2 files changed, 24 insertions(+), 1 deletion(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V2 2/2] ARM: dts: vf-colibri-eval-v3.dts: Enable ST-M41T0M6 RTC
ST-M41T0M6 is available on Colibri carrier boards. Hence enable M41T0M6 RTC. Acked-by: Stefan Agner Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi |6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 7324bdc..20251a3 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -35,6 +35,12 @@ { status = "okay"; + + /* M41T0M6 real time clock on carrier board */ + rtc: m41t0m6@68 { + compatible = "st,m41t00"; + reg = <0x68>; + }; }; { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V2 1/2] ARM: dts: vf-colibri: Add I2C support
Acked-by: Stefan Agner Signed-off-by: Bhuvanchandra DV --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi |6 +- arch/arm/boot/dts/vf-colibri.dtsi | 13 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 80e8fbc..7324bdc 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -33,6 +33,10 @@ status = "okay"; }; + { + status = "okay"; +}; + { status = "okay"; }; @@ -51,4 +55,4 @@ { status = "okay"; -}; \ No newline at end of file +}; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index ab40367..471eec0 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -39,6 +39,12 @@ pinctrl-0 = <_fec1>; }; + { + clock-frequency = <40>; + pinctrl-names = "default"; + pinctrl-0 = <_i2c0>; +}; + { pinctrl-names = "default"; pinctrl-0 = <_pwm0>; @@ -102,6 +108,13 @@ >; }; + pinctrl_i2c0: i2c0grp { + fsl,pins = < + VF610_PAD_PTB14__I2C0_SCL 0x37ff + VF610_PAD_PTB15__I2C0_SDA 0x37ff + >; + }; + pinctrl_pwm0: pwm0grp { fsl,pins = < VF610_PAD_PTB0__FTM0_CH00x1182 -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V2 0/2] Add I2C and enable M41T0M6 RTC
Add I2C support on Colibri VFxx moduels and enable M41T0M6 RTC available on Colibri carrier boards. Bhuvanchandra DV (2): ARM: dts: vf-colibri: Add I2C support ARM: dts: vf-colibri-eval-v3.dts: Enable ST-M41T0M6 RTC arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 12 +++- arch/arm/boot/dts/vf-colibri.dtsi | 13 + 2 files changed, 24 insertions(+), 1 deletion(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V2 2/2] ARM: dts: vf-colibri-eval-v3.dts: Enable ST-M41T0M6 RTC
ST-M41T0M6 is available on Colibri carrier boards. Hence enable M41T0M6 RTC. Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi |6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 7324bdc..20251a3 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -35,6 +35,12 @@ i2c0 { status = okay; + + /* M41T0M6 real time clock on carrier board */ + rtc: m41t0m6@68 { + compatible = st,m41t00; + reg = 0x68; + }; }; pwm0 { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND PATCH V2 1/2] ARM: dts: vf-colibri: Add I2C support
Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Bhuvanchandra DV bhuvanchandra...@toradex.com --- arch/arm/boot/dts/vf-colibri-eval-v3.dtsi |6 +- arch/arm/boot/dts/vf-colibri.dtsi | 13 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index 80e8fbc..7324bdc 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -33,6 +33,10 @@ status = okay; }; +i2c0 { + status = okay; +}; + pwm0 { status = okay; }; @@ -51,4 +55,4 @@ uart2 { status = okay; -}; \ No newline at end of file +}; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index ab40367..471eec0 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -39,6 +39,12 @@ pinctrl-0 = pinctrl_fec1; }; +i2c0 { + clock-frequency = 40; + pinctrl-names = default; + pinctrl-0 = pinctrl_i2c0; +}; + pwm0 { pinctrl-names = default; pinctrl-0 = pinctrl_pwm0; @@ -102,6 +108,13 @@ ; }; + pinctrl_i2c0: i2c0grp { + fsl,pins = + VF610_PAD_PTB14__I2C0_SCL 0x37ff + VF610_PAD_PTB15__I2C0_SDA 0x37ff + ; + }; + pinctrl_pwm0: pwm0grp { fsl,pins = VF610_PAD_PTB0__FTM0_CH00x1182 -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/