5.11.21-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 139/601 ARM: dts: renesas: Add mmc aliases into R-Car Gen2 board dts files
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit da926e813fc7f9f0912fa413981a1f5ba63a536d ]
After set PROBE_PREFER_ASYNCHRONOUS flag on the mmc host drivers, the order of /dev/mmcblkN was not fixed in some SoCs which have multiple SDHI and/or MMCIF controllers. So, we were hard to use such a device as rootfs by using the kernel parameter like "root=/dev/mmcblkNpM".
According to the discussion on a mainling list [1], we can add mmc aliases to fix the issue. So, add such aliases into R-Car Gen2 board dts files. Note that, since R-Car Gen2 is even more complicated about SDHI and/or MMCIF channels variations and they share pins, add the aliases into board dts files instead of SoC dtsi files.
--- arch/arm/boot/dts/r8a7790-lager.dts | 3 +++ arch/arm/boot/dts/r8a7791-koelsch.dts | 3 +++ arch/arm/boot/dts/r8a7791-porter.dts | 2 ++ arch/arm/boot/dts/r8a7793-gose.dts | 3 +++ arch/arm/boot/dts/r8a7794-alt.dts | 3 +++ arch/arm/boot/dts/r8a7794-silk.dts | 2 ++ 6 files changed, 16 insertions(+)
arch/arm/boot/dts/r8a7790-lager.dts +3 -0
@@ -53,6 +53,9 @@ i2c11 = &i2cexio1; i2c12 = &i2chdmi; i2c13 = &i2cpwr; + mmc0 = &mmcif1; + mmc1 = &sdhi0; + mmc2 = &sdhi2; }; chosen {
arch/arm/boot/dts/r8a7791-koelsch.dts +3 -0
@@ -53,6 +53,9 @@ i2c12 = &i2cexio1; i2c13 = &i2chdmi; i2c14 = &i2cexio4; + mmc0 = &sdhi0; + mmc1 = &sdhi1; + mmc2 = &sdhi2; }; chosen {
arch/arm/boot/dts/r8a7791-porter.dts +2 -0
@@ -28,6 +28,8 @@ serial0 = &scif0; i2c9 = &gpioi2c2; i2c10 = &i2chdmi; + mmc0 = &sdhi0; + mmc1 = &sdhi2; }; chosen {
arch/arm/boot/dts/r8a7793-gose.dts +3 -0
@@ -49,6 +49,9 @@ i2c10 = &gpioi2c4; i2c11 = &i2chdmi; i2c12 = &i2cexio4; + mmc0 = &sdhi0; + mmc1 = &sdhi1; + mmc2 = &sdhi2; }; chosen {
arch/arm/boot/dts/r8a7794-alt.dts +3 -0
@@ -19,6 +19,9 @@ i2c10 = &gpioi2c4; i2c11 = &i2chdmi; i2c12 = &i2cexio4; + mmc0 = &mmcif0; + mmc1 = &sdhi0; + mmc2 = &sdhi1; }; chosen {
arch/arm/boot/dts/r8a7794-silk.dts +2 -0
@@ -31,6 +31,8 @@ serial0 = &scif2; i2c9 = &gpioi2c1; i2c10 = &i2chdmi; + mmc0 = &mmcif0; + mmc1 = &sdhi1; }; chosen {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 140/601 arm64: dts: renesas: Add mmc aliases into board dts files
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit d765a4f302cc046ca23453ba990d21120ceadbbd ]
After the commit 7320915c8861 ("mmc: Set PROBE_PREFER_ASYNCHRONOUS for drivers that existed in v4.14"), the order of /dev/mmcblkN was not fixed in some SoCs which have multiple sdhi controllers. So, we were hard to use an sdhi device as rootfs by using the kernel parameter like "root=/dev/mmcblkNpM".
According to the discussion on a mainling list [1], we can add mmc aliases to fix the issue. So, add such aliases into Renesas arm64 board dts files. Notes that mmc0 is an eMMC channel if available.
--- arch/arm64/boot/dts/renesas/hihope-common.dtsi | 3 +++ arch/arm64/boot/dts/renesas/r8a774a1-beacon-rzg2m-kit.dts | 3 +++ arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts | 2 ++ arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts | 3 +++ arch/arm64/boot/dts/renesas/salvator-common.dtsi | 3 +++ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1 + arch/arm64/boot/dts/renesas/ulcb.dtsi | 2 ++ 7 files changed, 17 insertions(+)
arch/arm64/boot/dts/renesas/hihope-common.dtsi +3 -0
@@ -12,6 +12,9 @@ aliases { serial0 = &scif2; serial1 = &hscif0; + mmc0 = &sdhi3; + mmc1 = &sdhi0; + mmc2 = &sdhi2; }; chosen {
arch/arm64/boot/dts/renesas/r8a774a1-beacon-rzg2m-kit.dts +3 -0
@@ -21,6 +21,9 @@ serial4 = &hscif2; serial5 = &scif5; ethernet0 = &avb; + mmc0 = &sdhi3; + mmc1 = &sdhi0; + mmc2 = &sdhi2; }; chosen {
arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts +2 -0
@@ -17,6 +17,8 @@ aliases { serial0 = &scif2; serial1 = &hscif2; + mmc0 = &sdhi0; + mmc1 = &sdhi3; }; chosen {
arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts +3 -0
@@ -16,6 +16,9 @@ aliases { serial0 = &scif2; ethernet0 = &avb; + mmc0 = &sdhi3; + mmc1 = &sdhi0; + mmc2 = &sdhi1; }; chosen {
arch/arm64/boot/dts/renesas/salvator-common.dtsi +3 -0
@@ -36,6 +36,9 @@ serial0 = &scif2; serial1 = &hscif1; ethernet0 = &avb; + mmc0 = &sdhi2; + mmc1 = &sdhi0; + mmc2 = &sdhi3; }; chosen {
arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +1 -0
@@ -16,6 +16,7 @@ aliases { serial1 = &hscif0; serial2 = &scif1; + mmc2 = &sdhi3; }; clksndsel: clksndsel {
arch/arm64/boot/dts/renesas/ulcb.dtsi +2 -0
@@ -23,6 +23,8 @@ aliases { serial0 = &scif2; ethernet0 = &avb; + mmc0 = &sdhi2; + mmc1 = &sdhi0; }; chosen {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 141/601 bus: ti-sysc: Fix initializing module_pa for modules without sysc register
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
[ Upstream commit 7bad5af826aba00487fed9a3300d3f43f0cba11b ]
We have interconnect target modules with no known registers using only clocks and resets, but we still want to detect them based on the module IO range. So let's call sysc_parse_and_check_child_range() earlier so we have module_pa properly initialized.
--- drivers/bus/ti-sysc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/bus/ti-sysc.c +3 -3
@@ -901,9 +901,6 @@ static int sysc_map_and_check_registers(struct sysc *ddata)struct device_node *np = ddata->dev->of_node;int error; -if (!of_get_property (np,"reg" ,NULL )) -return 0 ; - error =sysc_parse_and_check_child_range (ddata);if (error)return error;
@@ -914,6 +911,9 @@ static int sysc_map_and_check_registers(struct sysc *ddata)sysc_check_children (ddata); +if (!of_get_property (np,"reg" ,NULL )) +return 0 ; + error =sysc_parse_registers (ddata);if (error)return error;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 142/601 x86/platform/uv: Set section block size for hubless architectures
In reply to Greg Kroah-HartmanFrom: Mike Travis <[email protected]>
[ Upstream commit 6840a150b9daf35e4d21ab9780d0a03b4ed74a5b ]
Commit
bbbd2b51a2aa ("x86/platform/UV: Use new set memory block size function")
added a call to set the block size value that is needed by the kernel to set the boundaries in the section list. This was done for UV Hubbed systems but missed in the UV Hubless setup. Fix that mistake by adding that same set call for hubless systems, which support the same NVRAMs and Intel BIOS, thus the same problem occurs.
[ bp: Massage commit message. ]
--- arch/x86/kernel/apic/x2apic_uv_x.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kernel/apic/x2apic_uv_x.c +3 -0
@@ -1671,6 +1671,9 @@ static __init int uv_system_init_hubless(void)if (rc <0 )return rc; +/* Set section block size for current node memory */ +set_block_size (); +/* Create user access node */ if (rc >=0 )uv_setup_proc_files (1 );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 143/601 serial: stm32: fix code cleaning warnings and checks
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 92fc00238675a15cc48f09694949f0c0012e0ff4 ]
Fixes checkpatch --strict warnings and checks:
- checkpatch --strict "Unnecessary parentheses"
- checkpatch --strict "Blank lines aren't necessary before a close brace
- checkpatch --strict "Alignment should match open parenthesis"
- checkpatch --strict "Please don't use multiple blank lines"
- checkpatch --strict "Comparison to NULL could be written ..."
- visual check code ordering warning
--- drivers/tty/serial/stm32-usart.c | 33 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-)
drivers/tty/serial/stm32-usart.c +15 -18
@@ -176,8 +176,7 @@ static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res, status =dmaengine_tx_status (stm32_port->rx_ch, stm32_port->rx_ch->cookie, &state); -if ((status ==DMA_IN_PROGRESS ) && - (*last_res != state.residue)) +if (status ==DMA_IN_PROGRESS && (*last_res != state.residue))return 1 ;else return 0 ;
@@ -464,7 +463,7 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)writel_relaxed (USART_ICR_RTOCF , port->membase + ofs->icr); -if ((sr &USART_SR_WUF ) && (ofs->icr !=UNDEF_REG )) +if ((sr &USART_SR_WUF ) && ofs->icr !=UNDEF_REG )writel_relaxed (USART_ICR_WUCF , port->membase + ofs->icr);
@@ -620,7 +619,6 @@ static void stm32_stop_rx(struct uart_port *port)stm32_clr_bits (port, ofs->cr1, stm32_port->cr1_irq);if (stm32_port->cr3_irq)stm32_clr_bits (port, ofs->cr3, stm32_port->cr3_irq); - }/* Handle breaks - ignored by us */
@@ -724,7 +722,7 @@ static unsigned int stm32_get_databits(struct ktermios *termios) }static void stm32_set_termios (struct uart_port *port,struct ktermios *termios, -struct ktermios *old) +struct ktermios *old) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -923,7 +921,7 @@ stm32_verify_port(struct uart_port *port, struct serial_struct *ser) }static void stm32_pm (struct uart_port *port,unsigned int state, -unsigned int oldstate) +unsigned int oldstate) {struct stm32_port *stm32port =container_of (port, struct stm32_port, port);
@@ -973,18 +971,17 @@ static int stm32_init_port(struct stm32_port *stm32port,struct resource *res;int ret; + ret =platform_get_irq (pdev,0 ); +if (ret <=0 ) +return ret ? : -ENODEV ; + port->iotype =UPIO_MEM ; port->flags =UPF_BOOT_AUTOCONF ; port->ops = &stm32_uart_ops; port->dev = &pdev->dev; port->fifosize = stm32port->info->cfg.fifosize; port->has_sysrq =IS_ENABLED (CONFIG_SERIAL_STM32_CONSOLE ); - - ret =platform_get_irq (pdev,0 ); -if (ret <=0 ) -return ret ? : -ENODEV ; port->irq = ret; - port->rs485_config = stm32_config_rs485; ret =stm32_init_rs485 (port, pdev);
@@ -1101,8 +1098,8 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,return -ENODEV ; } stm32port->rx_buf =dma_alloc_coherent (&pdev->dev,RX_BUF_L , - &stm32port->rx_dma_buf, -GFP_KERNEL ); + &stm32port->rx_dma_buf, +GFP_KERNEL );if (!stm32port->rx_buf) { ret = -ENOMEM ; goto alloc_err;
@@ -1177,8 +1174,8 @@ static int stm32_of_dma_tx_probe(struct stm32_port *stm32port,return -ENODEV ; } stm32port->tx_buf =dma_alloc_coherent (&pdev->dev,TX_BUF_L , - &stm32port->tx_dma_buf, -GFP_KERNEL ); + &stm32port->tx_dma_buf, +GFP_KERNEL );if (!stm32port->tx_buf) { ret = -ENOMEM ; goto alloc_err;
@@ -1322,7 +1319,6 @@ static int stm32_serial_remove(struct platform_device *pdev)return err; } -#ifdef CONFIG_SERIAL_STM32_CONSOLE static void stm32_console_putchar (struct uart_port *port,int ch) {
@@ -1335,7 +1331,8 @@ static void stm32_console_putchar(struct uart_port *port, int ch)writel_relaxed (ch, port->membase + ofs->tdr); } -static void stm32_console_write (struct console *co,const char *s,unsigned cnt) +static void stm32_console_write (struct console *co,const char *s, +unsigned int cnt) {struct uart_port *port = &stm32_ports[co->index].port;struct stm32_port *stm32_port =to_stm32_port (port);
@@ -1388,7 +1385,7 @@ static int stm32_console_setup(struct console *co, char *options)* this to be called during the uart port registration when the * driver gets probed and the port should be mapped at that point. */ -if (stm32port->port.mapbase ==0 || stm32port->port.membase ==NULL ) +if (stm32port->port.mapbase ==0 || !stm32port->port.membase)return -ENXIO ;if (options)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 144/601 serial: stm32: add "_usart" prefix in functions name
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 56f9a76c27b51bc8e9bb938734e3de03819569ae ]
Adds the prefix "_usart" in the name of stm32 usart functions in order to ease the usage of kernel trace and tools, such as f-trace. Allows to trace "stm32_usart_*" functions with f-trace. Without this patch, all the driver functions needs to be added manually in f-trace filter.
--- drivers/tty/serial/stm32-usart.c | 348 ++++++++++++++++--------------- 1 file changed, 177 insertions(+), 171 deletions(-)
drivers/tty/serial/stm32-usart.c +177 -171
@@ -34,15 +34,15 @@#include "serial_mctrl_gpio.h" #include "stm32-usart.h" -static void stm32_stop_tx (struct uart_port *port); -static void stm32_transmit_chars (struct uart_port *port); +static void stm32_usart_stop_tx (struct uart_port *port); +static void stm32_usart_transmit_chars (struct uart_port *port);static inline struct stm32_port *to_stm32_port (struct uart_port *port) { return container_of(port, struct stm32_port, port); } -static void stm32_set_bits (struct uart_port *port,u32 reg,u32 bits) +static void stm32_usart_set_bits (struct uart_port *port,u32 reg,u32 bits) {u32 val;
@@ -51,7 +51,7 @@ static void stm32_set_bits(struct uart_port *port, u32 reg, u32 bits)writel_relaxed (val, port->membase + reg); } -static void stm32_clr_bits (struct uart_port *port,u32 reg,u32 bits) +static void stm32_usart_clr_bits (struct uart_port *port,u32 reg,u32 bits) {u32 val;
@@ -60,8 +60,8 @@ static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)writel_relaxed (val, port->membase + reg); } -static void stm32_config_reg_rs485 (u32 *cr1,u32 *cr3,u32 delay_ADE, -u32 delay_DDE,u32 baud) +static void stm32_usart_config_reg_rs485 (u32 *cr1,u32 *cr3,u32 delay_ADE, +u32 delay_DDE,u32 baud) {u32 rs485_deat_dedt;u32 rs485_deat_dedt_max = (USART_CR1_DEAT_MASK >>USART_CR1_DEAT_SHIFT );
@@ -95,8 +95,8 @@ static void stm32_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE, *cr1 |= rs485_deat_dedt; } -static int stm32_config_rs485 (struct uart_port *port, -struct serial_rs485 *rs485conf) +static int stm32_usart_config_rs485 (struct uart_port *port, +struct serial_rs485 *rs485conf) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -104,7 +104,7 @@ static int stm32_config_rs485(struct uart_port *port,u32 usartdiv, baud, cr1, cr3;bool over8; -stm32_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); port->rs485 = *rs485conf;
@@ -122,9 +122,10 @@ static int stm32_config_rs485(struct uart_port *port, << USART_BRR_04_R_SHIFT; baud =DIV_ROUND_CLOSEST (port->uartclk, usartdiv); -stm32_config_reg_rs485 (&cr1, &cr3, - rs485conf->delay_rts_before_send, - rs485conf->delay_rts_after_send, baud); +stm32_usart_config_reg_rs485 (&cr1, &cr3, + rs485conf->delay_rts_before_send, + rs485conf->delay_rts_after_send, + baud);if (rs485conf->flags &SER_RS485_RTS_ON_SEND ) { cr3 &= ~USART_CR3_DEP ;
@@ -137,18 +138,19 @@ static int stm32_config_rs485(struct uart_port *port,writel_relaxed (cr3, port->membase + ofs->cr3);writel_relaxed (cr1, port->membase + ofs->cr1); }else { -stm32_clr_bits (port, ofs->cr3,USART_CR3_DEM |USART_CR3_DEP ); -stm32_clr_bits (port, ofs->cr1, -USART_CR1_DEDT_MASK |USART_CR1_DEAT_MASK ); +stm32_usart_clr_bits (port, ofs->cr3, +USART_CR3_DEM |USART_CR3_DEP ); +stm32_usart_clr_bits (port, ofs->cr1, +USART_CR1_DEDT_MASK |USART_CR1_DEAT_MASK ); } -stm32_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit));return 0 ; } -static int stm32_init_rs485 (struct uart_port *port, -struct platform_device *pdev) +static int stm32_usart_init_rs485 (struct uart_port *port, +struct platform_device *pdev) {struct serial_rs485 *rs485conf = &port->rs485;
@@ -162,8 +164,8 @@ static int stm32_init_rs485(struct uart_port *port,return uart_get_rs485_mode (port); } -static int stm32_pending_rx (struct uart_port *port,u32 *sr,int *last_res, -bool threaded) +static int stm32_usart_pending_rx (struct uart_port *port,u32 *sr, +int *last_res,bool threaded) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -186,8 +188,8 @@ static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res,return 0 ; } -static unsigned long stm32_get_char (struct uart_port *port,u32 *sr, -int *last_res) +static unsigned long stm32_usart_get_char (struct uart_port *port,u32 *sr, +int *last_res) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -206,7 +208,7 @@ static unsigned long stm32_get_char(struct uart_port *port, u32 *sr,return c; } -static void stm32_receive_chars (struct uart_port *port,bool threaded) +static void stm32_usart_receive_chars (struct uart_port *port,bool threaded) {struct tty_port *tport = &port->state->port;struct stm32_port *stm32_port =to_stm32_port (port);
@@ -218,7 +220,8 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)if (irqd_is_wakeup_set (irq_get_irq_data (port->irq)))pm_wakeup_event (tport->tty->dev,0 ); -while (stm32_pending_rx (port, &sr, &stm32_port->last_res, threaded)) { +while (stm32_usart_pending_rx (port, &sr, &stm32_port->last_res, + threaded)) { sr |=USART_SR_DUMMY_RX ; flag =TTY_NORMAL ;
@@ -237,7 +240,7 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)writel_relaxed (sr &USART_SR_ERR_MASK , port->membase + ofs->icr); - c =stm32_get_char (port, &sr, &stm32_port->last_res); + c =stm32_usart_get_char (port, &sr, &stm32_port->last_res); port->icount.rx++;if (sr &USART_SR_ERR_MASK ) {if (sr &USART_SR_ORE ) {
@@ -277,20 +280,20 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)spin_lock (&port->lock); } -static void stm32_tx_dma_complete (void *arg) +static void stm32_usart_tx_dma_complete (void *arg) {struct uart_port *port = arg;struct stm32_port *stm32port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32port->info->ofs; -stm32_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); stm32port->tx_dma_busy = false;/* Let's see if we have pending data to send */ -stm32_transmit_chars (port); +stm32_usart_transmit_chars (port); } -static void stm32_tx_interrupt_enable (struct uart_port *port) +static void stm32_usart_tx_interrupt_enable (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -300,30 +303,30 @@ static void stm32_tx_interrupt_enable(struct uart_port *port)* or TX empty irq when FIFO is disabled */ if (stm32_port->fifoen) -stm32_set_bits (port, ofs->cr3,USART_CR3_TXFTIE ); +stm32_usart_set_bits (port, ofs->cr3,USART_CR3_TXFTIE );else -stm32_set_bits (port, ofs->cr1,USART_CR1_TXEIE ); +stm32_usart_set_bits (port, ofs->cr1,USART_CR1_TXEIE ); } -static void stm32_tx_interrupt_disable (struct uart_port *port) +static void stm32_usart_tx_interrupt_disable (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;if (stm32_port->fifoen) -stm32_clr_bits (port, ofs->cr3,USART_CR3_TXFTIE ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_TXFTIE );else -stm32_clr_bits (port, ofs->cr1,USART_CR1_TXEIE ); +stm32_usart_clr_bits (port, ofs->cr1,USART_CR1_TXEIE ); } -static void stm32_transmit_chars_pio (struct uart_port *port) +static void stm32_usart_transmit_chars_pio (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;struct circ_buf *xmit = &port->state->xmit;if (stm32_port->tx_dma_busy) { -stm32_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); stm32_port->tx_dma_busy = false; }
@@ -338,12 +341,12 @@ static void stm32_transmit_chars_pio(struct uart_port *port)/* rely on TXE irq (mask or unmask) for sending remaining data */ if (uart_circ_empty (xmit)) -stm32_tx_interrupt_disable (port); +stm32_usart_tx_interrupt_disable (port);else -stm32_tx_interrupt_enable (port); +stm32_usart_tx_interrupt_enable (port); } -static void stm32_transmit_chars_dma (struct uart_port *port) +static void stm32_usart_transmit_chars_dma (struct uart_port *port) {struct stm32_port *stm32port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
@@ -385,7 +388,7 @@ static void stm32_transmit_chars_dma(struct uart_port *port)if (!desc) goto fallback_err; - desc->callback = stm32_tx_dma_complete; + desc->callback = stm32_usart_tx_dma_complete; desc->callback_param = port;/* Push current DMA TX transaction in the pending queue */
@@ -398,7 +401,7 @@ static void stm32_transmit_chars_dma(struct uart_port *port)/* Issue pending DMA TX requests */ dma_async_issue_pending (stm32port->tx_ch); -stm32_set_bits (port, ofs->cr3,USART_CR3_DMAT ); +stm32_usart_set_bits (port, ofs->cr3,USART_CR3_DMAT ); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE -1 ); port->icount.tx += count;
@@ -406,10 +409,10 @@ static void stm32_transmit_chars_dma(struct uart_port *port) fallback_err:for (i = count; i >0 ; i--) -stm32_transmit_chars_pio (port); +stm32_usart_transmit_chars_pio (port); } -static void stm32_transmit_chars (struct uart_port *port) +static void stm32_usart_transmit_chars (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -417,38 +420,38 @@ static void stm32_transmit_chars(struct uart_port *port)if (port->x_char) {if (stm32_port->tx_dma_busy) -stm32_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT );writel_relaxed (port->x_char, port->membase + ofs->tdr); port->x_char =0 ; port->icount.tx++;if (stm32_port->tx_dma_busy) -stm32_set_bits (port, ofs->cr3,USART_CR3_DMAT ); +stm32_usart_set_bits (port, ofs->cr3,USART_CR3_DMAT );return ; }if (uart_circ_empty (xmit) ||uart_tx_stopped (port)) { -stm32_tx_interrupt_disable (port); +stm32_usart_tx_interrupt_disable (port);return ; }if (ofs->icr ==UNDEF_REG ) -stm32_clr_bits (port, ofs->isr,USART_SR_TC ); +stm32_usart_clr_bits (port, ofs->isr,USART_SR_TC );else writel_relaxed (USART_ICR_TCCF , port->membase + ofs->icr);if (stm32_port->tx_ch) -stm32_transmit_chars_dma (port); +stm32_usart_transmit_chars_dma (port);else -stm32_transmit_chars_pio (port); +stm32_usart_transmit_chars_pio (port);if (uart_circ_chars_pending (xmit) <WAKEUP_CHARS )uart_write_wakeup (port);if (uart_circ_empty (xmit)) -stm32_tx_interrupt_disable (port); +stm32_usart_tx_interrupt_disable (port); } -static irqreturn_t stm32_interrupt (int irq,void *ptr) +static irqreturn_t stm32_usart_interrupt (int irq,void *ptr) {struct uart_port *port = ptr;struct stm32_port *stm32_port =to_stm32_port (port);
@@ -468,10 +471,10 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr) port->membase + ofs->icr);if ((sr &USART_SR_RXNE ) && !(stm32_port->rx_ch)) -stm32_receive_chars (port, false); +stm32_usart_receive_chars (port, false);if ((sr &USART_SR_TXE ) && !(stm32_port->tx_ch)) -stm32_transmit_chars (port); +stm32_usart_transmit_chars (port);spin_unlock (&port->lock);
@@ -481,7 +484,7 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)return IRQ_HANDLED ; } -static irqreturn_t stm32_threaded_interrupt (int irq,void *ptr) +static irqreturn_t stm32_usart_threaded_interrupt (int irq,void *ptr) {struct uart_port *port = ptr;struct stm32_port *stm32_port =to_stm32_port (port);
@@ -489,14 +492,14 @@ static irqreturn_t stm32_threaded_interrupt(int irq, void *ptr)spin_lock (&port->lock);if (stm32_port->rx_ch) -stm32_receive_chars (port, true); +stm32_usart_receive_chars (port, true);spin_unlock (&port->lock);return IRQ_HANDLED ; } -static unsigned int stm32_tx_empty (struct uart_port *port) +static unsigned int stm32_usart_tx_empty (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -504,20 +507,20 @@ static unsigned int stm32_tx_empty(struct uart_port *port)return readl_relaxed (port->membase + ofs->isr) &USART_SR_TXE ; } -static void stm32_set_mctrl (struct uart_port *port,unsigned int mctrl) +static void stm32_usart_set_mctrl (struct uart_port *port,unsigned int mctrl) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;if ((mctrl &TIOCM_RTS ) && (port->status &UPSTAT_AUTORTS )) -stm32_set_bits (port, ofs->cr3,USART_CR3_RTSE ); +stm32_usart_set_bits (port, ofs->cr3,USART_CR3_RTSE );else -stm32_clr_bits (port, ofs->cr3,USART_CR3_RTSE ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_RTSE );mctrl_gpio_set (stm32_port->gpios, mctrl); } -static unsigned int stm32_get_mctrl (struct uart_port *port) +static unsigned int stm32_usart_get_mctrl (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);unsigned int ret;
@@ -528,23 +531,23 @@ static unsigned int stm32_get_mctrl(struct uart_port *port)return mctrl_gpio_get (stm32_port->gpios, &ret); } -static void stm32_enable_ms (struct uart_port *port) +static void stm32_usart_enable_ms (struct uart_port *port) {mctrl_gpio_enable_ms (to_stm32_port (port)->gpios); } -static void stm32_disable_ms (struct uart_port *port) +static void stm32_usart_disable_ms (struct uart_port *port) {mctrl_gpio_disable_ms (to_stm32_port (port)->gpios); }/* Transmit stop */ -static void stm32_stop_tx (struct uart_port *port) +static void stm32_usart_stop_tx (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct serial_rs485 *rs485conf = &port->rs485; -stm32_tx_interrupt_disable (port); +stm32_usart_tx_interrupt_disable (port);if (rs485conf->flags &SER_RS485_ENABLED ) {if (rs485conf->flags &SER_RS485_RTS_ON_SEND ) {
@@ -558,7 +561,7 @@ static void stm32_stop_tx(struct uart_port *port) }/* There are probably characters waiting to be transmitted. */ -static void stm32_start_tx (struct uart_port *port) +static void stm32_usart_start_tx (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct serial_rs485 *rs485conf = &port->rs485;
@@ -577,56 +580,56 @@ static void stm32_start_tx(struct uart_port *port) } } -stm32_transmit_chars (port); +stm32_usart_transmit_chars (port); }/* Throttle the remote when input buffer is about to overflow. */ -static void stm32_throttle (struct uart_port *port) +static void stm32_usart_throttle (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;unsigned long flags;spin_lock_irqsave (&port->lock, flags); -stm32_clr_bits (port, ofs->cr1, stm32_port->cr1_irq); +stm32_usart_clr_bits (port, ofs->cr1, stm32_port->cr1_irq);if (stm32_port->cr3_irq) -stm32_clr_bits (port, ofs->cr3, stm32_port->cr3_irq); +stm32_usart_clr_bits (port, ofs->cr3, stm32_port->cr3_irq);spin_unlock_irqrestore (&port->lock, flags); }/* Unthrottle the remote, the input buffer can now accept data. */ -static void stm32_unthrottle (struct uart_port *port) +static void stm32_usart_unthrottle (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;unsigned long flags;spin_lock_irqsave (&port->lock, flags); -stm32_set_bits (port, ofs->cr1, stm32_port->cr1_irq); +stm32_usart_set_bits (port, ofs->cr1, stm32_port->cr1_irq);if (stm32_port->cr3_irq) -stm32_set_bits (port, ofs->cr3, stm32_port->cr3_irq); +stm32_usart_set_bits (port, ofs->cr3, stm32_port->cr3_irq);spin_unlock_irqrestore (&port->lock, flags); }/* Receive stop */ -static void stm32_stop_rx (struct uart_port *port) +static void stm32_usart_stop_rx (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -stm32_clr_bits (port, ofs->cr1, stm32_port->cr1_irq); +stm32_usart_clr_bits (port, ofs->cr1, stm32_port->cr1_irq);if (stm32_port->cr3_irq) -stm32_clr_bits (port, ofs->cr3, stm32_port->cr3_irq); +stm32_usart_clr_bits (port, ofs->cr3, stm32_port->cr3_irq); }/* Handle breaks - ignored by us */ -static void stm32_break_ctl (struct uart_port *port,int break_state) +static void stm32_usart_break_ctl (struct uart_port *port,int break_state) { } -static int stm32_startup (struct uart_port *port) +static int stm32_usart_startup (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -634,15 +637,15 @@ static int stm32_startup(struct uart_port *port)u32 val;int ret; - ret =request_threaded_irq (port->irq, stm32_interrupt, - stm32_threaded_interrupt, + ret =request_threaded_irq (port->irq, stm32_usart_interrupt, + stm32_usart_threaded_interrupt,IRQF_NO_SUSPEND , name, port);if (ret)return ret;/* RX FIFO Flush */ if (ofs->rqr !=UNDEF_REG ) -stm32_set_bits (port, ofs->rqr,USART_RQR_RXFRQ ); +stm32_usart_set_bits (port, ofs->rqr,USART_RQR_RXFRQ );/* Tx and RX FIFO configuration */ if (stm32_port->fifoen) {
@@ -657,12 +660,12 @@ static int stm32_startup(struct uart_port *port) val = stm32_port->cr1_irq |USART_CR1_RE ;if (stm32_port->fifoen) val |=USART_CR1_FIFOEN ; -stm32_set_bits (port, ofs->cr1, val); +stm32_usart_set_bits (port, ofs->cr1, val);return 0 ; } -static void stm32_shutdown (struct uart_port *port) +static void stm32_usart_shutdown (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -671,7 +674,7 @@ static void stm32_shutdown(struct uart_port *port)int ret;/* Disable modem control interrupts */ -stm32_disable_ms (port); +stm32_usart_disable_ms (port); val =USART_CR1_TXEIE |USART_CR1_TE ; val |= stm32_port->cr1_irq |USART_CR1_RE ;
@@ -686,12 +689,12 @@ static void stm32_shutdown(struct uart_port *port)if (ret)dev_err (port->dev,"transmission complete not set\n" ); -stm32_clr_bits (port, ofs->cr1, val); +stm32_usart_clr_bits (port, ofs->cr1, val);free_irq (port->irq, port); } -static unsigned int stm32_get_databits (struct ktermios *termios) +static unsigned int stm32_usart_get_databits (struct ktermios *termios) {unsigned int bits;
@@ -721,8 +724,9 @@ static unsigned int stm32_get_databits(struct ktermios *termios)return bits; } -static void stm32_set_termios (struct uart_port *port,struct ktermios *termios, -struct ktermios *old) +static void stm32_usart_set_termios (struct uart_port *port, +struct ktermios *termios, +struct ktermios *old) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -746,8 +750,8 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,/* flush RX & TX FIFO */ if (ofs->rqr !=UNDEF_REG ) -stm32_set_bits (port, ofs->rqr, -USART_RQR_TXFRQ |USART_RQR_RXFRQ ); +stm32_usart_set_bits (port, ofs->rqr, +USART_RQR_TXFRQ |USART_RQR_RXFRQ ); cr1 =USART_CR1_TE |USART_CR1_RE ;if (stm32_port->fifoen)
@@ -760,7 +764,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,if (cflag &CSTOPB ) cr2 |=USART_CR2_STOP_2B ; - bits =stm32_get_databits (termios); + bits =stm32_usart_get_databits (termios); stm32_port->rdr_mask = (BIT (bits) -1 );if (cflag &PARENB ) {
@@ -813,9 +817,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,/* Handle modem control interrupts */ if (UART_ENABLE_MS (port, termios->c_cflag)) -stm32_enable_ms (port); +stm32_usart_enable_ms (port);else -stm32_disable_ms (port); +stm32_usart_disable_ms (port); usartdiv =DIV_ROUND_CLOSEST (port->uartclk, baud);
@@ -828,11 +832,11 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,if (usartdiv <16 ) { oversampling =8 ; cr1 |=USART_CR1_OVER8 ; -stm32_set_bits (port, ofs->cr1,USART_CR1_OVER8 ); +stm32_usart_set_bits (port, ofs->cr1,USART_CR1_OVER8 ); }else { oversampling =16 ; cr1 &= ~USART_CR1_OVER8 ; -stm32_clr_bits (port, ofs->cr1,USART_CR1_OVER8 ); +stm32_usart_clr_bits (port, ofs->cr1,USART_CR1_OVER8 ); } mantissa = (usartdiv / oversampling) <<USART_BRR_DIV_M_SHIFT ;
@@ -869,9 +873,10 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, cr3 |=USART_CR3_DMAR ;if (rs485conf->flags &SER_RS485_ENABLED ) { -stm32_config_reg_rs485 (&cr1, &cr3, - rs485conf->delay_rts_before_send, - rs485conf->delay_rts_after_send, baud); +stm32_usart_config_reg_rs485 (&cr1, &cr3, + rs485conf->delay_rts_before_send, + rs485conf->delay_rts_after_send, + baud);if (rs485conf->flags &SER_RS485_RTS_ON_SEND ) { cr3 &= ~USART_CR3_DEP ; rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND ;
@@ -889,39 +894,39 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,writel_relaxed (cr2, port->membase + ofs->cr2);writel_relaxed (cr1, port->membase + ofs->cr1); -stm32_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit));spin_unlock_irqrestore (&port->lock, flags); } -static const char *stm32_type (struct uart_port *port) +static const char *stm32_usart_type (struct uart_port *port) {return (port->type ==PORT_STM32 ) ?DRIVER_NAME :NULL ; } -static void stm32_release_port (struct uart_port *port) +static void stm32_usart_release_port (struct uart_port *port) { } -static int stm32_request_port (struct uart_port *port) +static int stm32_usart_request_port (struct uart_port *port) {return 0 ; } -static void stm32_config_port (struct uart_port *port,int flags) +static void stm32_usart_config_port (struct uart_port *port,int flags) {if (flags &UART_CONFIG_TYPE ) port->type =PORT_STM32 ; }static int -stm32_verify_port (struct uart_port *port,struct serial_struct *ser) +stm32_usart_verify_port (struct uart_port *port,struct serial_struct *ser) {/* No user changeable parameters */ return -EINVAL ; } -static void stm32_pm (struct uart_port *port,unsigned int state, -unsigned int oldstate) +static void stm32_usart_pm (struct uart_port *port,unsigned int state, +unsigned int oldstate) {struct stm32_port *stm32port =container_of (port, struct stm32_port, port);
@@ -935,7 +940,7 @@ static void stm32_pm(struct uart_port *port, unsigned int state,break ;case UART_PM_STATE_OFF :spin_lock_irqsave (&port->lock, flags); -stm32_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit));spin_unlock_irqrestore (&port->lock, flags);pm_runtime_put_sync (port->dev);break ;
@@ -943,29 +948,29 @@ static void stm32_pm(struct uart_port *port, unsigned int state, }static const struct uart_ops stm32_uart_ops = { - .tx_empty = stm32_tx_empty, - .set_mctrl = stm32_set_mctrl, - .get_mctrl = stm32_get_mctrl, - .stop_tx = stm32_stop_tx, - .start_tx = stm32_start_tx, - .throttle = stm32_throttle, - .unthrottle = stm32_unthrottle, - .stop_rx = stm32_stop_rx, - .enable_ms = stm32_enable_ms, - .break_ctl = stm32_break_ctl, - .startup = stm32_startup, - .shutdown = stm32_shutdown, - .set_termios = stm32_set_termios, - .pm = stm32_pm, - .type = stm32_type, - .release_port = stm32_release_port, - .request_port = stm32_request_port, - .config_port = stm32_config_port, - .verify_port = stm32_verify_port, + .tx_empty = stm32_usart_tx_empty, + .set_mctrl = stm32_usart_set_mctrl, + .get_mctrl = stm32_usart_get_mctrl, + .stop_tx = stm32_usart_stop_tx, + .start_tx = stm32_usart_start_tx, + .throttle = stm32_usart_throttle, + .unthrottle = stm32_usart_unthrottle, + .stop_rx = stm32_usart_stop_rx, + .enable_ms = stm32_usart_enable_ms, + .break_ctl = stm32_usart_break_ctl, + .startup = stm32_usart_startup, + .shutdown = stm32_usart_shutdown, + .set_termios = stm32_usart_set_termios, + .pm = stm32_usart_pm, + .type = stm32_usart_type, + .release_port = stm32_usart_release_port, + .request_port = stm32_usart_request_port, + .config_port = stm32_usart_config_port, + .verify_port = stm32_usart_verify_port, }; -static int stm32_init_port (struct stm32_port *stm32port, -struct platform_device *pdev) +static int stm32_usart_init_port (struct stm32_port *stm32port, +struct platform_device *pdev) {struct uart_port *port = &stm32port->port;struct resource *res;
@@ -982,9 +987,9 @@ static int stm32_init_port(struct stm32_port *stm32port, port->fifosize = stm32port->info->cfg.fifosize; port->has_sysrq =IS_ENABLED (CONFIG_SERIAL_STM32_CONSOLE ); port->irq = ret; - port->rs485_config = stm32_config_rs485; + port->rs485_config = stm32_usart_config_rs485; - ret =stm32_init_rs485 (port, pdev); + ret =stm32_usart_init_rs485 (port, pdev);if (ret)return ret;
@@ -1043,7 +1048,7 @@ err_clk:return ret; } -static struct stm32_port *stm32_of_get_stm32_port (struct platform_device *pdev) +static struct stm32_port *stm32_usart_of_get_port (struct platform_device *pdev) {struct device_node *np = pdev->dev.of_node;int id;
@@ -1081,8 +1086,8 @@ static const struct of_device_id stm32_match[] = {MODULE_DEVICE_TABLE (of, stm32_match);#endif -static int stm32_of_dma_rx_probe (struct stm32_port *stm32port, -struct platform_device *pdev) +static int stm32_usart_of_dma_rx_probe (struct stm32_port *stm32port, +struct platform_device *pdev) {struct stm32_usart_offsets *ofs = &stm32port->info->ofs;struct uart_port *port = &stm32port->port;
@@ -1156,8 +1161,8 @@ alloc_err:return ret; } -static int stm32_of_dma_tx_probe (struct stm32_port *stm32port, -struct platform_device *pdev) +static int stm32_usart_of_dma_tx_probe (struct stm32_port *stm32port, +struct platform_device *pdev) {struct stm32_usart_offsets *ofs = &stm32port->info->ofs;struct uart_port *port = &stm32port->port;
@@ -1207,13 +1212,13 @@ alloc_err:return ret; } -static int stm32_serial_probe (struct platform_device *pdev) +static int stm32_usart_serial_probe (struct platform_device *pdev) {const struct of_device_id *match;struct stm32_port *stm32port;int ret; - stm32port =stm32_of_get_stm32_port (pdev); + stm32port =stm32_usart_of_get_port (pdev);if (!stm32port)return -ENODEV ;
@@ -1223,7 +1228,7 @@ static int stm32_serial_probe(struct platform_device *pdev)else return -EINVAL ; - ret =stm32_init_port (stm32port, pdev); + ret =stm32_usart_init_port (stm32port, pdev);if (ret)return ret;
@@ -1244,11 +1249,11 @@ static int stm32_serial_probe(struct platform_device *pdev)if (ret) goto err_wirq; - ret =stm32_of_dma_rx_probe (stm32port, pdev); + ret =stm32_usart_of_dma_rx_probe (stm32port, pdev);if (ret)dev_info (&pdev->dev,"interrupt mode used for rx (no dma)\n" ); - ret =stm32_of_dma_tx_probe (stm32port, pdev); + ret =stm32_usart_of_dma_tx_probe (stm32port, pdev);if (ret)dev_info (&pdev->dev,"interrupt mode used for tx (no dma)\n" );
@@ -1275,7 +1280,7 @@ err_uninit:return ret; } -static int stm32_serial_remove (struct platform_device *pdev) +static int stm32_usart_serial_remove (struct platform_device *pdev) {struct uart_port *port =platform_get_drvdata (pdev);struct stm32_port *stm32_port =to_stm32_port (port);
@@ -1284,7 +1289,7 @@ static int stm32_serial_remove(struct platform_device *pdev)pm_runtime_get_sync (&pdev->dev); -stm32_clr_bits (port, ofs->cr3,USART_CR3_DMAR ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAR );if (stm32_port->rx_ch)dma_release_channel (stm32_port->rx_ch);
@@ -1294,7 +1299,7 @@ static int stm32_serial_remove(struct platform_device *pdev)RX_BUF_L , stm32_port->rx_buf, stm32_port->rx_dma_buf); -stm32_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT );if (stm32_port->tx_ch)dma_release_channel (stm32_port->tx_ch);
@@ -1320,7 +1325,7 @@ static int stm32_serial_remove(struct platform_device *pdev) }#ifdef CONFIG_SERIAL_STM32_CONSOLE -static void stm32_console_putchar (struct uart_port *port,int ch) +static void stm32_usart_console_putchar (struct uart_port *port,int ch) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -1331,8 +1336,8 @@ static void stm32_console_putchar(struct uart_port *port, int ch)writel_relaxed (ch, port->membase + ofs->tdr); } -static void stm32_console_write (struct console *co,const char *s, -unsigned int cnt) +static void stm32_usart_console_write (struct console *co,const char *s, +unsigned int cnt) {struct uart_port *port = &stm32_ports[co->index].port;struct stm32_port *stm32_port =to_stm32_port (port);
@@ -1356,7 +1361,7 @@ static void stm32_console_write(struct console *co, const char *s, new_cr1 |=USART_CR1_TE |BIT (cfg->uart_enable_bit);writel_relaxed (new_cr1, port->membase + ofs->cr1); -uart_console_write (port, s, cnt, stm32_console_putchar); +uart_console_write (port, s, cnt, stm32_usart_console_putchar);/* Restore interrupt state */ writel_relaxed (old_cr1, port->membase + ofs->cr1);
@@ -1366,7 +1371,7 @@ static void stm32_console_write(struct console *co, const char *s,local_irq_restore (flags); } -static int stm32_console_setup (struct console *co,char *options) +static int stm32_usart_console_setup (struct console *co,char *options) {struct stm32_port *stm32port;int baud =9600 ;
@@ -1397,8 +1402,8 @@ static int stm32_console_setup(struct console *co, char *options)static struct console stm32_console = { .name =STM32_SERIAL_NAME , .device = uart_console_device, - .write = stm32_console_write, - .setup = stm32_console_setup, + .write = stm32_usart_console_write, + .setup = stm32_usart_console_setup, .flags =CON_PRINTBUFFER , .index =-1 , .data = &stm32_usart_driver,
@@ -1419,8 +1424,8 @@ static struct uart_driver stm32_usart_driver = { .cons = STM32_SERIAL_CONSOLE, }; -static void __maybe_unused stm32_serial_enable_wakeup (struct uart_port *port, -bool enable) +static void __maybe_unused stm32_usart_serial_en_wakeup (struct uart_port *port, +bool enable) {struct stm32_port *stm32_port =to_stm32_port (port);struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -1431,29 +1436,29 @@ static void __maybe_unused stm32_serial_enable_wakeup(struct uart_port *port,return ;if (enable) { -stm32_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); -stm32_set_bits (port, ofs->cr1,USART_CR1_UESM ); +stm32_usart_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_set_bits (port, ofs->cr1,USART_CR1_UESM ); val =readl_relaxed (port->membase + ofs->cr3); val &= ~USART_CR3_WUS_MASK ;/* Enable Wake up interrupt from low power on start bit */ val |=USART_CR3_WUS_START_BIT |USART_CR3_WUFIE ;writel_relaxed (val, port->membase + ofs->cr3); -stm32_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); }else { -stm32_clr_bits (port, ofs->cr1,USART_CR1_UESM ); +stm32_usart_clr_bits (port, ofs->cr1,USART_CR1_UESM ); } } -static int __maybe_unused stm32_serial_suspend (struct device *dev) +static int __maybe_unused stm32_usart_serial_suspend (struct device *dev) {struct uart_port *port =dev_get_drvdata (dev);uart_suspend_port (&stm32_usart_driver, port);if (device_may_wakeup (dev)) -stm32_serial_enable_wakeup (port, true); +stm32_usart_serial_en_wakeup (port, true);else -stm32_serial_enable_wakeup (port, false); +stm32_usart_serial_en_wakeup (port, false);/* * When "no_console_suspend" is enabled, keep the pinctrl default state
@@ -1471,19 +1476,19 @@ static int __maybe_unused stm32_serial_suspend(struct device *dev)return 0 ; } -static int __maybe_unused stm32_serial_resume (struct device *dev) +static int __maybe_unused stm32_usart_serial_resume (struct device *dev) {struct uart_port *port =dev_get_drvdata (dev);pinctrl_pm_select_default_state (dev);if (device_may_wakeup (dev)) -stm32_serial_enable_wakeup (port, false); +stm32_usart_serial_en_wakeup (port, false);return uart_resume_port (&stm32_usart_driver, port); } -static int __maybe_unused stm32_serial_runtime_suspend (struct device *dev) +static int __maybe_unused stm32_usart_runtime_suspend (struct device *dev) {struct uart_port *port =dev_get_drvdata (dev); struct stm32_port *stm32port = container_of(port,
@@ -1494,7 +1499,7 @@ static int __maybe_unused stm32_serial_runtime_suspend(struct device *dev)return 0 ; } -static int __maybe_unused stm32_serial_runtime_resume (struct device *dev) +static int __maybe_unused stm32_usart_runtime_resume (struct device *dev) {struct uart_port *port =dev_get_drvdata (dev); struct stm32_port *stm32port = container_of(port,
@@ -1504,14 +1509,15 @@ static int __maybe_unused stm32_serial_runtime_resume(struct device *dev) }static const struct dev_pm_ops stm32_serial_pm_ops = { - SET_RUNTIME_PM_OPS(stm32_serial_runtime_suspend, - stm32_serial_runtime_resume, NULL) -SET_SYSTEM_SLEEP_PM_OPS (stm32_serial_suspend, stm32_serial_resume) + SET_RUNTIME_PM_OPS(stm32_usart_runtime_suspend, + stm32_usart_runtime_resume, NULL) +SET_SYSTEM_SLEEP_PM_OPS (stm32_usart_serial_suspend, + stm32_usart_serial_resume) };static struct platform_driver stm32_serial_driver = { - .probe = stm32_serial_probe, - .remove = stm32_serial_remove, + .probe = stm32_usart_serial_probe, + .remove = stm32_usart_serial_remove, .driver = { .name =DRIVER_NAME , .pm = &stm32_serial_pm_ops,
@@ -1519,7 +1525,7 @@ static struct platform_driver stm32_serial_driver = { }, }; -static int __init usart_init (void ) +static int __init stm32_usart_init (void ) {static char banner[]__initdata ="STM32 USART driver initialized" ;int ret;
@@ -1537,14 +1543,14 @@ static int __init usart_init(void)return ret; } -static void __exit usart_exit(void) +static void __exit stm32_usart_exit(void) {platform_driver_unregister (&stm32_serial_driver);uart_unregister_driver (&stm32_usart_driver); } -module_init (usart_init); -module_exit (usart_exit); +module_init (stm32_usart_init); +module_exit (stm32_usart_exit);MODULE_ALIAS ("platform:" DRIVER_NAME );MODULE_DESCRIPTION ("STMicroelectronics STM32 serial port driver" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 145/601 serial: stm32: fix probe and remove order for dma
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 87fd0741d6dcf63ebdb14050c2b921ae14c7f307 ]
The probe and remove orders are wrong as the uart_port is registered before saving device data in the probe, and unregistered after DMA resource deallocation in the remove. uart_port registering should be done at the end of probe and unregistering should be done at the begin of remove to avoid resource allocation issues.
Fix probe and remove orders. This enforce resource allocation occur at proper time.
Terminate both DMA rx and tx transfers before removing device.
Move pm_runtime after uart_remove_one_port() call in remove() to keep the probe error path.
--- drivers/tty/serial/stm32-usart.c | 57 ++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 13 deletions(-)
drivers/tty/serial/stm32-usart.c +44 -13
@@ -1245,10 +1245,6 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)device_set_wakeup_enable (&pdev->dev, false); } - ret =uart_add_one_port (&stm32_usart_driver, &stm32port->port); -if (ret) - goto err_wirq; - ret =stm32_usart_of_dma_rx_probe (stm32port, pdev);if (ret)dev_info (&pdev->dev,"interrupt mode used for rx (no dma)\n" );
@@ -1262,11 +1258,40 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)pm_runtime_get_noresume (&pdev->dev);pm_runtime_set_active (&pdev->dev);pm_runtime_enable (&pdev->dev); + + ret =uart_add_one_port (&stm32_usart_driver, &stm32port->port); +if (ret) + goto err_port; +pm_runtime_put_sync (&pdev->dev);return 0 ; -err_wirq: +err_port: +pm_runtime_disable (&pdev->dev); +pm_runtime_set_suspended (&pdev->dev); +pm_runtime_put_noidle (&pdev->dev); + +if (stm32port->rx_ch) { +dmaengine_terminate_async (stm32port->rx_ch); +dma_release_channel (stm32port->rx_ch); + } + +if (stm32port->rx_dma_buf) +dma_free_coherent (&pdev->dev, +RX_BUF_L , stm32port->rx_buf, + stm32port->rx_dma_buf); + +if (stm32port->tx_ch) { +dmaengine_terminate_async (stm32port->tx_ch); +dma_release_channel (stm32port->tx_ch); + } + +if (stm32port->tx_dma_buf) +dma_free_coherent (&pdev->dev, +TX_BUF_L , stm32port->tx_buf, + stm32port->tx_dma_buf); +if (stm32port->wakeirq >0 )dev_pm_clear_wake_irq (&pdev->dev);
@@ -1288,11 +1313,20 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)int err;pm_runtime_get_sync (&pdev->dev); + err =uart_remove_one_port (&stm32_usart_driver, port); +if (err) +return (err); + +pm_runtime_disable (&pdev->dev); +pm_runtime_set_suspended (&pdev->dev); +pm_runtime_put_noidle (&pdev->dev);stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAR ); -if (stm32_port->rx_ch) +if (stm32_port->rx_ch) { +dmaengine_terminate_async (stm32_port->rx_ch);dma_release_channel (stm32_port->rx_ch); + }if (stm32_port->rx_dma_buf) dma_free_coherent(&pdev->dev,
@@ -1301,8 +1335,10 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); -if (stm32_port->tx_ch) +if (stm32_port->tx_ch) { +dmaengine_terminate_async (stm32_port->tx_ch);dma_release_channel (stm32_port->tx_ch); + }if (stm32_port->tx_dma_buf) dma_free_coherent(&pdev->dev,
@@ -1316,12 +1352,7 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)clk_disable_unprepare (stm32_port->clk); - err =uart_remove_one_port (&stm32_usart_driver, port); - -pm_runtime_disable (&pdev->dev); -pm_runtime_put_noidle (&pdev->dev); - -return err; +return 0 ; }#ifdef CONFIG_SERIAL_STM32_CONSOLE
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 146/601 serial: stm32: Use of_device_get_match_data()
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit d825f0bea20f49a8f413a6acd7c4100ea55edf6d ]
This driver casts away the constness of struct stm32_usart_info that is pointed to by the of match table. Use of_device_get_match_data() instead of of_match_device() here and push the const throughout the code so that we don't cast away const. This nicely avoids referencing the match table when it is undefined with configurations where CONFIG_OF=n and fixes the const issues.
--- drivers/tty/serial/stm32-usart.c | 71 +++++++++++++++----------------- drivers/tty/serial/stm32-usart.h | 2 +- 2 files changed, 35 insertions(+), 38 deletions(-)
drivers/tty/serial/stm32-usart.c +34 -37
@@ -99,8 +99,8 @@ static int stm32_usart_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -struct stm32_usart_config *cfg = &stm32_port->info->cfg; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_config *cfg = &stm32_port->info->cfg;u32 usartdiv, baud, cr1, cr3;bool over8;
@@ -168,7 +168,7 @@ static int stm32_usart_pending_rx(struct uart_port *port, u32 *sr, int *last_res, bool threaded) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;enum dma_status status;struct dma_tx_state state;
@@ -192,7 +192,7 @@ static unsigned long stm32_usart_get_char(struct uart_port *port, u32 *sr, int *last_res) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;unsigned long c;if (stm32_port->rx_ch) {
@@ -212,7 +212,7 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded) {struct tty_port *tport = &port->state->port;struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;unsigned long c;u32 sr;char flag;
@@ -284,7 +284,7 @@ static void stm32_usart_tx_dma_complete(void *arg) {struct uart_port *port = arg;struct stm32_port *stm32port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); stm32port->tx_dma_busy = false;
@@ -296,7 +296,7 @@ static void stm32_usart_tx_dma_complete(void *arg)static void stm32_usart_tx_interrupt_enable (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;/* * Enables TX FIFO threashold irq when FIFO is enabled,
@@ -311,7 +311,7 @@ static void stm32_usart_tx_interrupt_enable(struct uart_port *port)static void stm32_usart_tx_interrupt_disable (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;if (stm32_port->fifoen)stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_TXFTIE );
@@ -322,7 +322,7 @@ static void stm32_usart_tx_interrupt_disable(struct uart_port *port)static void stm32_usart_transmit_chars_pio (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;struct circ_buf *xmit = &port->state->xmit;if (stm32_port->tx_dma_busy) {
@@ -349,7 +349,7 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port)static void stm32_usart_transmit_chars_dma (struct uart_port *port) {struct stm32_port *stm32port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;struct circ_buf *xmit = &port->state->xmit;struct dma_async_tx_descriptor *desc =NULL ;unsigned int count, i;
@@ -415,7 +415,7 @@ fallback_err:static void stm32_usart_transmit_chars (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;struct circ_buf *xmit = &port->state->xmit;if (port->x_char) {
@@ -455,7 +455,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) {struct uart_port *port = ptr;struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;u32 sr;spin_lock (&port->lock);
@@ -502,7 +502,7 @@ static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)static unsigned int stm32_usart_tx_empty (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;return readl_relaxed (port->membase + ofs->isr) &USART_SR_TXE ; }
@@ -510,7 +510,7 @@ static unsigned int stm32_usart_tx_empty(struct uart_port *port)static void stm32_usart_set_mctrl (struct uart_port *port,unsigned int mctrl) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;if ((mctrl &TIOCM_RTS ) && (port->status &UPSTAT_AUTORTS ))stm32_usart_set_bits (port, ofs->cr3,USART_CR3_RTSE );
@@ -587,7 +587,7 @@ static void stm32_usart_start_tx(struct uart_port *port)static void stm32_usart_throttle (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;unsigned long flags;spin_lock_irqsave (&port->lock, flags);
@@ -602,7 +602,7 @@ static void stm32_usart_throttle(struct uart_port *port)static void stm32_usart_unthrottle (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;unsigned long flags;spin_lock_irqsave (&port->lock, flags);
@@ -617,7 +617,7 @@ static void stm32_usart_unthrottle(struct uart_port *port)static void stm32_usart_stop_rx (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;stm32_usart_clr_bits (port, ofs->cr1, stm32_port->cr1_irq);if (stm32_port->cr3_irq)
@@ -632,7 +632,7 @@ static void stm32_usart_break_ctl(struct uart_port *port, int break_state)static int stm32_usart_startup (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;const char *name =to_platform_device (port->dev)->name;u32 val;int ret;
@@ -668,8 +668,8 @@ static int stm32_usart_startup(struct uart_port *port)static void stm32_usart_shutdown (struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -struct stm32_usart_config *cfg = &stm32_port->info->cfg; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_config *cfg = &stm32_port->info->cfg;u32 val, isr;int ret;
@@ -729,8 +729,8 @@ static void stm32_usart_set_termios(struct uart_port *port, struct ktermios *old) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -struct stm32_usart_config *cfg = &stm32_port->info->cfg; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_config *cfg = &stm32_port->info->cfg;struct serial_rs485 *rs485conf = &port->rs485;unsigned int baud, bits;u32 usartdiv, mantissa, fraction, oversampling;
@@ -930,8 +930,8 @@ static void stm32_usart_pm(struct uart_port *port, unsigned int state, {struct stm32_port *stm32port =container_of (port, struct stm32_port, port); -struct stm32_usart_offsets *ofs = &stm32port->info->ofs; -struct stm32_usart_config *cfg = &stm32port->info->cfg; +const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +const struct stm32_usart_config *cfg = &stm32port->info->cfg;unsigned long flags =0 ;switch (state) {
@@ -1089,7 +1089,7 @@ MODULE_DEVICE_TABLE(of, stm32_match);static int stm32_usart_of_dma_rx_probe (struct stm32_port *stm32port,struct platform_device *pdev) { -struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;struct uart_port *port = &stm32port->port;struct device *dev = &pdev->dev;struct dma_slave_config config;
@@ -1164,7 +1164,7 @@ alloc_err:static int stm32_usart_of_dma_tx_probe (struct stm32_port *stm32port,struct platform_device *pdev) { -struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;struct uart_port *port = &stm32port->port;struct device *dev = &pdev->dev;struct dma_slave_config config;
@@ -1214,7 +1214,6 @@ alloc_err:static int stm32_usart_serial_probe (struct platform_device *pdev) { -const struct of_device_id *match;struct stm32_port *stm32port;int ret;
@@ -1222,10 +1221,8 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)if (!stm32port)return -ENODEV ; - match =of_match_device (stm32_match, &pdev->dev); -if (match && match->data) - stm32port->info = (struct stm32_usart_info *)match->data; -else + stm32port->info =of_device_get_match_data (&pdev->dev); +if (!stm32port->info)return -EINVAL ; ret =stm32_usart_init_port (stm32port, pdev);
@@ -1309,7 +1306,7 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) {struct uart_port *port =platform_get_drvdata (pdev);struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;int err;pm_runtime_get_sync (&pdev->dev);
@@ -1359,7 +1356,7 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)static void stm32_usart_console_putchar (struct uart_port *port,int ch) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;while (!(readl_relaxed (port->membase + ofs->isr) &USART_SR_TXE ))cpu_relax ();
@@ -1372,8 +1369,8 @@ static void stm32_usart_console_write(struct console *co, const char *s, {struct uart_port *port = &stm32_ports[co->index].port;struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -struct stm32_usart_config *cfg = &stm32_port->info->cfg; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_config *cfg = &stm32_port->info->cfg;unsigned long flags;u32 old_cr1, new_cr1;int locked =1 ;
@@ -1459,8 +1456,8 @@ static void __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, bool enable) {struct stm32_port *stm32_port =to_stm32_port (port); -struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -struct stm32_usart_config *cfg = &stm32_port->info->cfg; +const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_config *cfg = &stm32_port->info->cfg;u32 val;if (stm32_port->wakeirq <=0 )
drivers/tty/serial/stm32-usart.h +1 -1
@@ -259,7 +259,7 @@ struct stm32_usart_info stm32h7_info = {struct stm32_port {struct uart_port port;struct clk *clk; -struct stm32_usart_info *info; +const struct stm32_usart_info *info;struct dma_chan *rx_ch;/* dma rx channel */ dma_addr_t rx_dma_buf;/* dma rx buffer bus address */ unsigned char *rx_buf;/* dma rx buffer cpu address */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 147/601 serial: stm32: fix startup by enabling usart for reception
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit f4518a8a75f5be1a121b0c95ad9c6b1eb27d920e ]
RX is configured, but usart is not enabled in startup function. Kernel documentation specifies that startup should enable the port for reception.
Fix the startup by enabling usart for reception.
--- drivers/tty/serial/stm32-usart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/stm32-usart.c +2 -1
@@ -633,6 +633,7 @@ static int stm32_usart_startup(struct uart_port *port) {struct stm32_port *stm32_port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +const struct stm32_usart_config *cfg = &stm32_port->info->cfg;const char *name =to_platform_device (port->dev)->name;u32 val;int ret;
@@ -657,7 +658,7 @@ static int stm32_usart_startup(struct uart_port *port) }/* RX FIFO enabling */ - val = stm32_port->cr1_irq |USART_CR1_RE ; + val = stm32_port->cr1_irq |USART_CR1_RE |BIT (cfg->uart_enable_bit);if (stm32_port->fifoen) val |=USART_CR1_FIFOEN ;stm32_usart_set_bits (port, ofs->cr1, val);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 148/601 serial: stm32: fix incorrect characters on console
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit f264c6f6aece81a9f8fbdf912b20bd3feb476a7a ]
Incorrect characters are observed on console during boot. This issue occurs when init/main.c is modifying termios settings to open /dev/console on the rootfs.
This patch adds a waiting loop in set_termios to wait for TX shift register empty (and TX FIFO if any) before stopping serial port.
--- drivers/tty/serial/stm32-usart.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/tty/serial/stm32-usart.c +11 -1
@@ -736,8 +736,9 @@ static void stm32_usart_set_termios(struct uart_port *port,unsigned int baud, bits;u32 usartdiv, mantissa, fraction, oversampling;tcflag_t cflag = termios->c_cflag; -u32 cr1, cr2, cr3; +u32 cr1, cr2, cr3, isr;unsigned long flags; +int ret;if (!stm32_port->hw_flow_control) cflag &= ~CRTSCTS ;
@@ -746,6 +747,15 @@ static void stm32_usart_set_termios(struct uart_port *port,spin_lock_irqsave (&port->lock, flags); + ret =readl_relaxed_poll_timeout_atomic (port->membase + ofs->isr, + isr, + (isr &USART_SR_TC ), +10 ,100000 ); + +/* Send the TC error message only when ISR_TC is not set. */ +if (ret) +dev_err (port->dev,"Transmission is not complete\n" ); +/* Stop serial port and reset value */ writel_relaxed (0 , port->membase + ofs->cr1);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 149/601 serial: stm32: fix TX and RX FIFO thresholds
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 25a8e7611da5513b388165661b17173c26e12c04 ]
TX and RX FIFO thresholds may be cleared after suspend/resume, depending on the low power mode.
Those configurations (done in startup) are not effective for UART console, as:
- the reference manual indicates that FIFOEN bit can only be written when the USART is disabled (UE=0)
- a set_termios (where UE is set) is requested firstly for console enabling, before the startup.
--- drivers/tty/serial/stm32-usart.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-)
drivers/tty/serial/stm32-usart.c +9 -14
@@ -648,19 +648,8 @@ static int stm32_usart_startup(struct uart_port *port)if (ofs->rqr !=UNDEF_REG )stm32_usart_set_bits (port, ofs->rqr,USART_RQR_RXFRQ ); -/* Tx and RX FIFO configuration */ -if (stm32_port->fifoen) { - val =readl_relaxed (port->membase + ofs->cr3); - val &= ~(USART_CR3_TXFTCFG_MASK |USART_CR3_RXFTCFG_MASK ); - val |=USART_CR3_TXFTCFG_HALF <<USART_CR3_TXFTCFG_SHIFT ; - val |=USART_CR3_RXFTCFG_HALF <<USART_CR3_RXFTCFG_SHIFT ; -writel_relaxed (val, port->membase + ofs->cr3); - } - -/* RX FIFO enabling */ +/* RX enabling */ val = stm32_port->cr1_irq |USART_CR1_RE |BIT (cfg->uart_enable_bit); -if (stm32_port->fifoen) - val |=USART_CR1_FIFOEN ;stm32_usart_set_bits (port, ofs->cr1, val);return 0 ;
@@ -768,9 +757,15 @@ static void stm32_usart_set_termios(struct uart_port *port,if (stm32_port->fifoen) cr1 |=USART_CR1_FIFOEN ; cr2 =0 ; + +/* Tx and RX FIFO configuration */ cr3 =readl_relaxed (port->membase + ofs->cr3); - cr3 &=USART_CR3_TXFTIE |USART_CR3_RXFTCFG_MASK |USART_CR3_RXFTIE - |USART_CR3_TXFTCFG_MASK ; + cr3 &=USART_CR3_TXFTIE |USART_CR3_RXFTIE ; +if (stm32_port->fifoen) { + cr3 &= ~(USART_CR3_TXFTCFG_MASK |USART_CR3_RXFTCFG_MASK ); + cr3 |=USART_CR3_TXFTCFG_HALF <<USART_CR3_TXFTCFG_SHIFT ; + cr3 |=USART_CR3_RXFTCFG_HALF <<USART_CR3_RXFTCFG_SHIFT ; + }if (cflag &CSTOPB ) cr2 |=USART_CR2_STOP_2B ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 150/601 serial: stm32: fix a deadlock condition with wakeup event
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit ad7676812437a00a4c6be155fc17926069f99084 ]
Deadlock issue is seen when enabling CONFIG_PROVE_LOCKING=Y, and uart console as wakeup source. Deadlock occurs when resuming from low power mode if system is waked up via usart console.
The deadlock is triggered 100% when also disabling console suspend prior to go to suspend.
Simplified call stack, deadlock condition:
- stm32_console_write <-- spin_lock already held
- print_circular_bug
- pm_wakeup_dev_event <-- triggers lockdep as seen above
- stm32_receive_chars
- stm32_interrupt <-- wakeup via uart console, takes the lock
So, revisit spin_lock in stm32-usart driver:
- there is no need to hold the lock to access ICR (atomic clear of status flags)
- only hold the lock inside stm32_receive_chars() routine (no need to call pm_wakeup_dev_event with lock held)
- keep stm32_transmit_chars() routine called with lock held
--- drivers/tty/serial/stm32-usart.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
drivers/tty/serial/stm32-usart.c +15 -12
@@ -213,13 +213,18 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)struct tty_port *tport = &port->state->port;struct stm32_port *stm32_port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -unsigned long c; +unsigned long c, flags;u32 sr;char flag;if (irqd_is_wakeup_set (irq_get_irq_data (port->irq)))pm_wakeup_event (tport->tty->dev,0 ); +if (threaded) +spin_lock_irqsave (&port->lock, flags); +else +spin_lock (&port->lock); +while (stm32_usart_pending_rx (port, &sr, &stm32_port->last_res, threaded)) { sr |=USART_SR_DUMMY_RX ;
@@ -275,9 +280,12 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)uart_insert_char (port, sr,USART_SR_ORE , c, flag); } -spin_unlock (&port->lock); +if (threaded) +spin_unlock_irqrestore (&port->lock, flags); +else +spin_unlock (&port->lock); +tty_flip_buffer_push (tport); -spin_lock (&port->lock); }static void stm32_usart_tx_dma_complete (void *arg)
@@ -458,8 +466,6 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;u32 sr; -spin_lock (&port->lock); - sr =readl_relaxed (port->membase + ofs->isr);if ((sr &USART_SR_RTOF ) && ofs->icr !=UNDEF_REG )
@@ -473,10 +479,11 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)if ((sr &USART_SR_RXNE ) && !(stm32_port->rx_ch))stm32_usart_receive_chars (port, false); -if ((sr &USART_SR_TXE ) && !(stm32_port->tx_ch)) +if ((sr &USART_SR_TXE ) && !(stm32_port->tx_ch)) { +spin_lock (&port->lock);stm32_usart_transmit_chars (port); - -spin_unlock (&port->lock); +spin_unlock (&port->lock); + }if (stm32_port->rx_ch)return IRQ_WAKE_THREAD ;
@@ -489,13 +496,9 @@ static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)struct uart_port *port = ptr;struct stm32_port *stm32_port =to_stm32_port (port); -spin_lock (&port->lock); -if (stm32_port->rx_ch)stm32_usart_receive_chars (port, true); -spin_unlock (&port->lock); -return IRQ_HANDLED ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 151/601 serial: stm32: fix wake-up flag handling
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 12761869f0efa524348e2ae31827fd52eebf3f0d ]
This patch fixes several issue with wake-up handling:
- the WUF irq is handled several times at wake-up
- the USART is disabled / enabled at suspend to set wake-up flag. It can cause glitches during RX.
This patch fix those issues:
- clear wake-up flag and disable wake-up irq in WUF irq handling
- enable wake-up from low power on start bit detection at port configuration
- Unmask the wake-up flag irq at suspend and mask it at resume
In addition, pm_wakeup_event handling is moved from receice_chars to WUF irq handling.
--- drivers/tty/serial/stm32-usart.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
drivers/tty/serial/stm32-usart.c +19 -13
@@ -217,9 +217,6 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)u32 sr;char flag; -if (irqd_is_wakeup_set (irq_get_irq_data (port->irq))) -pm_wakeup_event (tport->tty->dev,0 ); -if (threaded)spin_lock_irqsave (&port->lock, flags);else
@@ -462,6 +459,7 @@ static void stm32_usart_transmit_chars(struct uart_port *port)static irqreturn_t stm32_usart_interrupt (int irq,void *ptr) {struct uart_port *port = ptr; +struct tty_port *tport = &port->state->port;struct stm32_port *stm32_port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;u32 sr;
@@ -472,9 +470,14 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)writel_relaxed (USART_ICR_RTOCF , port->membase + ofs->icr); -if ((sr &USART_SR_WUF ) && ofs->icr !=UNDEF_REG ) +if ((sr &USART_SR_WUF ) && ofs->icr !=UNDEF_REG ) { +/* Clear wake up flag and disable wake up interrupt */ writel_relaxed (USART_ICR_WUCF , port->membase + ofs->icr); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_WUFIE ); +if (irqd_is_wakeup_set (irq_get_irq_data (port->irq))) +pm_wakeup_event (tport->tty->dev,0 ); + }if ((sr &USART_SR_RXNE ) && !(stm32_port->rx_ch))stm32_usart_receive_chars (port, false);
@@ -899,6 +902,12 @@ static void stm32_usart_set_termios(struct uart_port *port, cr1 &= ~(USART_CR1_DEDT_MASK |USART_CR1_DEAT_MASK ); } +/* Configure wake up from low power on start bit detection */ +if (stm32_port->wakeirq >0 ) { + cr3 &= ~USART_CR3_WUS_MASK ; + cr3 |=USART_CR3_WUS_START_BIT ; + } +writel_relaxed (cr3, port->membase + ofs->cr3);writel_relaxed (cr2, port->membase + ofs->cr2);writel_relaxed (cr1, port->membase + ofs->cr1);
@@ -1466,23 +1475,20 @@ static void __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, {struct stm32_port *stm32_port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -const struct stm32_usart_config *cfg = &stm32_port->info->cfg; -u32 val;if (stm32_port->wakeirq <=0 )return ; +/* +* Enable low-power wake-up and wake-up irq if argument is set to +* "enable", disable low-power wake-up and wake-up irq otherwise +*/ if (enable) { -stm32_usart_clr_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit));stm32_usart_set_bits (port, ofs->cr1,USART_CR1_UESM ); - val =readl_relaxed (port->membase + ofs->cr3); - val &= ~USART_CR3_WUS_MASK ; -/* Enable Wake up interrupt from low power on start bit */ - val |=USART_CR3_WUS_START_BIT |USART_CR3_WUFIE ; -writel_relaxed (val, port->membase + ofs->cr3); -stm32_usart_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit)); +stm32_usart_set_bits (port, ofs->cr3,USART_CR3_WUFIE ); }else {stm32_usart_clr_bits (port, ofs->cr1,USART_CR1_UESM ); +stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_WUFIE ); } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 152/601 serial: stm32: fix a deadlock in set_termios
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 436c97936001776f16153771ee887f125443e974 ]
CTS/RTS GPIOs support that has been added recently to STM32 UART driver has introduced scheduled code in a set_termios part protected by a spin lock. This generates a potential deadlock scenario:
Chain exists of:
&irq_desc_lock_class --> console_owner --> &port_lock_key
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&port_lock_key);
lock(console_owner);
lock(&port_lock_key);lock(&irq_desc_lock_class);
*** DEADLOCK ***
4 locks held by stty/766:
Move the scheduled code after the spinlock.
--- drivers/tty/serial/stm32-usart.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/tty/serial/stm32-usart.c +6 -6
@@ -827,12 +827,6 @@ static void stm32_usart_set_termios(struct uart_port *port, cr3 |=USART_CR3_CTSE |USART_CR3_RTSE ; } -/* Handle modem control interrupts */ -if (UART_ENABLE_MS (port, termios->c_cflag)) -stm32_usart_enable_ms (port); -else -stm32_usart_disable_ms (port); - usartdiv =DIV_ROUND_CLOSEST (port->uartclk, baud);/*
@@ -914,6 +908,12 @@ static void stm32_usart_set_termios(struct uart_port *port,stm32_usart_set_bits (port, ofs->cr1,BIT (cfg->uart_enable_bit));spin_unlock_irqrestore (&port->lock, flags); + +/* Handle modem control interrupts */ +if (UART_ENABLE_MS (port, termios->c_cflag)) +stm32_usart_enable_ms (port); +else +stm32_usart_disable_ms (port); }static const char *stm32_usart_type (struct uart_port *port)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 153/601 serial: liteuart: fix return value check in liteuart_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit cebeddd6d0d9f839b9df2930b6a768b54913a763 ]
In case of error, the function devm_platform_get_and_ioremap_resource() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().
--- drivers/tty/serial/liteuart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/liteuart.c +2 -2
@@ -270,8 +270,8 @@ static int liteuart_probe(struct platform_device *pdev)/* get membase */ port->membase =devm_platform_get_and_ioremap_resource (pdev,0 ,NULL ); -if (!port->membase) -return -ENXIO ; +if (IS_ERR (port->membase)) +return PTR_ERR (port->membase);/* values not from device tree */ port->dev = &pdev->dev;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 154/601 serial: stm32: fix tx dma completion, release channel
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit fb4f2e04ac13e7c400e6b86afbbd314a5a2a7e8d ]
This patch add a proper release of dma channels when completing dma tx.
--- drivers/tty/serial/stm32-usart.c | 1 + 1 file changed, 1 insertion(+)
drivers/tty/serial/stm32-usart.c +1 -0
@@ -291,6 +291,7 @@ static void stm32_usart_tx_dma_complete(void *arg)struct stm32_port *stm32port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +dmaengine_terminate_async (stm32port->tx_ch);stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); stm32port->tx_dma_busy = false;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 155/601 serial: stm32: call stm32_transmit_chars locked
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit f16b90c2d9db3e6ac719d1946b9d335ca4ab33f3 ]
stm32_transmit_chars should be called under lock also in tx DMA callback.
--- drivers/tty/serial/stm32-usart.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/tty/serial/stm32-usart.c +3 -0
@@ -290,13 +290,16 @@ static void stm32_usart_tx_dma_complete(void *arg)struct uart_port *port = arg;struct stm32_port *stm32port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; +unsigned long flags;dmaengine_terminate_async (stm32port->tx_ch);stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); stm32port->tx_dma_busy = false;/* Let's see if we have pending data to send */ +spin_lock_irqsave (&port->lock, flags);stm32_usart_transmit_chars (port); +spin_unlock_irqrestore (&port->lock, flags); }static void stm32_usart_tx_interrupt_enable (struct uart_port *port)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 156/601 serial: stm32: fix FIFO flush in startup and set_termios
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 315e2d8a125ad77a1bc28f621162713f3e7aef48 ]
Fifo flush set USART_RQR register by calling stm32_usart_set_bits routine (Read/Modify/Write). USART_RQR register is a write only register. So, read before write isn't correct / relevant to flush the FIFOs.
Replace stm32_usart_set_bits call by writel_relaxed.
--- drivers/tty/serial/stm32-usart.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/tty/serial/stm32-usart.c +3 -3
@@ -656,7 +656,7 @@ static int stm32_usart_startup(struct uart_port *port)/* RX FIFO Flush */ if (ofs->rqr !=UNDEF_REG ) -stm32_usart_set_bits (port, ofs->rqr,USART_RQR_RXFRQ ); +writel_relaxed (USART_RQR_RXFRQ , port->membase + ofs->rqr);/* RX enabling */ val = stm32_port->cr1_irq |USART_CR1_RE |BIT (cfg->uart_enable_bit);
@@ -760,8 +760,8 @@ static void stm32_usart_set_termios(struct uart_port *port,/* flush RX & TX FIFO */ if (ofs->rqr !=UNDEF_REG ) -stm32_usart_set_bits (port, ofs->rqr, -USART_RQR_TXFRQ |USART_RQR_RXFRQ ); +writel_relaxed (USART_RQR_TXFRQ |USART_RQR_RXFRQ , + port->membase + ofs->rqr); cr1 =USART_CR1_TE |USART_CR1_RE ;if (stm32_port->fifoen)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 157/601 serial: stm32: add FIFO flush when port is closed
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 9f77d19207a0e8ba814c8ceb22e90ce7cb2aef64 ]
Transmission complete error is sent when ISR_TC is not set. If port closure is requested despite data in TDR / TX FIFO has not been sent (because of flow control), ISR_TC is not set and error message is sent on port closure but also when a new port is opened.
Flush the data when port is closed, so the error isn't printed twice upon next port opening.
--- drivers/tty/serial/stm32-usart.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/tty/serial/stm32-usart.c +5 -0
@@ -689,6 +689,11 @@ static void stm32_usart_shutdown(struct uart_port *port)if (ret)dev_err (port->dev,"transmission complete not set\n" ); +/* flush RX & TX FIFO */ +if (ofs->rqr !=UNDEF_REG ) +writel_relaxed (USART_RQR_TXFRQ |USART_RQR_RXFRQ , + port->membase + ofs->rqr); +stm32_usart_clr_bits (port, ofs->cr1, val);free_irq (port->irq, port);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 158/601 serial: stm32: fix tx_empty condition
In reply to Greg Kroah-HartmanFrom: Erwan Le Ray <[email protected]>
[ Upstream commit 3db1d52466dc11dca4e47ef12a6e6e97f846af62 ]
In "tx_empty", we should poll TC bit in both DMA and PIO modes (instead of TXE) to check transmission data register has been transmitted independently of the FIFO mode. TC indicates that both transmit register and shift register are empty. When shift register is empty, tx_empty should return TIOCSER_TEMT instead of TC value.
Cleans the USART_CR_TC TCCF register define (transmission complete clear flag) as it is duplicate of USART_ICR_TCCF.
--- drivers/tty/serial/stm32-usart.c | 5 ++++- drivers/tty/serial/stm32-usart.h | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/tty/serial/stm32-usart.c +4 -1
@@ -514,7 +514,10 @@ static unsigned int stm32_usart_tx_empty(struct uart_port *port)struct stm32_port *stm32_port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -return readl_relaxed (port->membase + ofs->isr) &USART_SR_TXE ; +if (readl_relaxed (port->membase + ofs->isr) &USART_SR_TC ) +return TIOCSER_TEMT ; + +return 0 ; }static void stm32_usart_set_mctrl (struct uart_port *port,unsigned int mctrl)
drivers/tty/serial/stm32-usart.h +0 -3
@@ -127,9 +127,6 @@ struct stm32_usart_info stm32h7_info = {/* Dummy bits */ #define USART_SR_DUMMY_RX BIT(16) -/* USART_ICR (F7) */ -#define USART_CR_TC BIT(6) -/* USART_DR */ #define USART_DR_MASK GENMASK(8, 0)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 159/601 usb: typec: tcpm: Handle vbus shutoff when in source mode
In reply to Greg Kroah-HartmanFrom: Badhri Jagan Sridharan <[email protected]>
[ Upstream commit 7771bcc7f5a727d6e3f7a80b0b075a75cb664fb2 ]
While in source mode, vbus could be shutoff by protections circuits. TCPM does not move back to toggling state to re-initiate connection. Fix this by moving to SRC_UNATTACHED state when vbus shuts off while in source mode.
--- drivers/usb/typec/tcpm/tcpm.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/usb/typec/tcpm/tcpm.c +11 -0
@@ -4287,6 +4287,17 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)/* Do nothing, waiting for sink detection */ break ; +case SRC_STARTUP : +case SRC_SEND_CAPABILITIES : +case SRC_SEND_CAPABILITIES_TIMEOUT : +case SRC_NEGOTIATE_CAPABILITIES : +case SRC_TRANSITION_SUPPLY : +case SRC_READY : +case SRC_WAIT_NEW_CAPABILITIES : +/* Force to unattached state to re-initiate connection */ +tcpm_set_state (port,SRC_UNATTACHED ,0 ); +break ; +case PORT_RESET :/* * State set back to default mode once the timer completes.
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 160/601 usb: typec: tcpci: Check ROLE_CONTROL while interpreting CC_STATUS
In reply to Greg Kroah-HartmanFrom: Badhri Jagan Sridharan <[email protected]>
[ Upstream commit 19c234a14eafca78e0bc14ffb8be3891096ce147 ]
While interpreting CC_STATUS, ROLE_CONTROL has to be read to make sure that CC1/CC2 is not forced presenting Rp/Rd.
Quoted 1 line
From the TCPCI spec:
4.4.5.2 ROLE_CONTROL (Normative):
The TCPM shall write B6 (DRP) = 0b and B3..0 (CC1/CC2) if it wishes to control the Rp/Rd directly instead of having the TCPC perform DRP toggling autonomously. When controlling Rp/Rd directly, the TCPM writes to B3..0 (CC1/CC2) each time it wishes to change the CC1/CC2 values. This control is used for TCPM-TCPC implementing Source or Sink only as well as when a connection has been detected via DRP toggling but the TCPM wishes to attempt Try.Src or Try.Snk.
Table 4-22. CC_STATUS Register Definition:
If (ROLE_CONTROL.CC1 = Rd) or ConnectResult=1)
00b: SNK.Open (Below maximum vRa)
01b: SNK.Default (Above minimum vRd-Connect)
10b: SNK.Power1.5 (Above minimum vRd-Connect) Detects Rp-1.5A 11b: SNK.Power3.0 (Above minimum vRd-Connect) Detects Rp-3.0A
If (ROLE_CONTROL.CC2=Rd) or (ConnectResult=1)
00b: SNK.Open (Below maximum vRa)
01b: SNK.Default (Above minimum vRd-Connect)
10b: SNK.Power1.5 (Above minimum vRd-Connect) Detects Rp 1.5A 11b: SNK.Power3.0 (Above minimum vRd-Connect) Detects Rp 3.0A
--- drivers/usb/typec/tcpm/tcpci.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
drivers/usb/typec/tcpm/tcpci.c +18 -3
@@ -24,6 +24,15 @@#define AUTO_DISCHARGE_PD_HEADROOM_MV 850#define AUTO_DISCHARGE_PPS_HEADROOM_MV 1250 +#define tcpc_presenting_cc1_rd (reg) \ + (!(TCPC_ROLE_CTRL_DRP & (reg)) && \ + (((reg) & (TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT)) == \ + (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT))) +#define tcpc_presenting_cc2_rd (reg) \ + (!(TCPC_ROLE_CTRL_DRP & (reg)) && \ + (((reg) & (TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT)) == \ + (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT))) +struct tcpci {struct device *dev;
@@ -178,19 +187,25 @@ static int tcpci_get_cc(struct tcpc_dev *tcpc, enum typec_cc_status *cc1, enum typec_cc_status *cc2) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); -unsigned int reg; +unsigned int reg, role_control;int ret; + ret =regmap_read (tcpci->regmap,TCPC_ROLE_CTRL , &role_control); +if (ret <0 ) +return ret; + ret =regmap_read (tcpci->regmap,TCPC_CC_STATUS , ®);if (ret <0 )return ret; *cc1 =tcpci_to_typec_cc ((reg >>TCPC_CC_STATUS_CC1_SHIFT ) &TCPC_CC_STATUS_CC1_MASK , - reg &TCPC_CC_STATUS_TERM ); + reg &TCPC_CC_STATUS_TERM || +tcpc_presenting_cc1_rd (role_control)); *cc2 =tcpci_to_typec_cc ((reg >>TCPC_CC_STATUS_CC2_SHIFT ) &TCPC_CC_STATUS_CC2_MASK , - reg &TCPC_CC_STATUS_TERM ); + reg &TCPC_CC_STATUS_TERM || +tcpc_presenting_cc2_rd (role_control));return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 161/601 usb: typec: tps6598x: Fix return value check in tps6598x_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit 604c75893a01c8a3b5bd6dac55535963cd44c3f5 ]
In case of error, the function device_get_named_child_node() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test.
--- drivers/usb/typec/tps6598x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/typec/tps6598x.c +2 -2
@@ -614,8 +614,8 @@ static int tps6598x_probe(struct i2c_client *client)return ret; fwnode =device_get_named_child_node (&client->dev,"connector" ); -if (IS_ERR (fwnode)) -return PTR_ERR (fwnode); +if (!fwnode) +return -ENODEV ; tps->role_sw =fwnode_usb_role_switch_get (fwnode);if (IS_ERR (tps->role_sw)) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 162/601 usb: typec: stusb160x: fix return value check in stusb160x_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit f2d90e07b5df2c7745ae66d2d48cc350d3f1c7d2 ]
In case of error, the function device_get_named_child_node() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test.
--- drivers/usb/typec/stusb160x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/typec/stusb160x.c +2 -2
@@ -682,8 +682,8 @@ static int stusb160x_probe(struct i2c_client *client) } fwnode =device_get_named_child_node (chip->dev,"connector" ); -if (IS_ERR (fwnode)) -return PTR_ERR (fwnode); +if (!fwnode) +return -ENODEV ;/* * When both VDD and VSYS power supplies are present, the low power
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 163/601 mfd: intel_pmt: Fix nuisance messages and handling of disabled capabilities
In reply to Greg Kroah-HartmanFrom: David E. Box <[email protected]>
[ Upstream commit a1a5c1c3df282dc122508a17500317266ef19e46 ]
Some products will be available that have PMT capabilities that are not supported. Remove the warnings in this instance to avoid nuisance messages and confusion.
Also return an error code for capabilities that are disabled by quirk to prevent them from keeping the driver loaded if only disabled capabilities are found.
--- drivers/mfd/intel_pmt.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/mfd/intel_pmt.c +3 -8
@@ -79,19 +79,18 @@ static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header,case DVSEC_INTEL_ID_WATCHER :if (quirks &PMT_QUIRK_NO_WATCHER ) {dev_info (dev,"Watcher not supported\n" ); -return 0 ; +return -EINVAL ; } name ="pmt_watcher" ;break ;case DVSEC_INTEL_ID_CRASHLOG :if (quirks &PMT_QUIRK_NO_CRASHLOG ) {dev_info (dev,"Crashlog not supported\n" ); -return 0 ; +return -EINVAL ; } name ="pmt_crashlog" ;break ;default : -dev_err (dev,"Unrecognized PMT capability: %d\n" , id);return -EINVAL ; }
@@ -174,12 +173,8 @@ static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) header.offset =INTEL_DVSEC_TABLE_OFFSET (table); ret =pmt_add_dev (pdev, &header, quirks); -if (ret) { -dev_warn (&pdev->dev, -"Failed to add device for DVSEC id %d\n" , - header.id); +if (ret)continue ; - } found_devices = true; }while (true);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 164/601 regmap: set debugfs_name to NULL after it is freed
In reply to Greg Kroah-HartmanFrom: Meng Li <[email protected]>
[ Upstream commit e41a962f82e7afb5b1ee644f48ad0b3aee656268 ]
There is a upstream commit cffa4b2122f5("regmap:debugfs:
Fix a memory leak when calling regmap_attach_dev") that adds a if condition when create name for debugfs_name. With below function invoking logical, debugfs_name is freed in regmap_debugfs_exit(), but it is not created again because of the if condition introduced by above commit. regmap_reinit_cache()
regmap_debugfs_exit() ... regmap_debugfs_init()
So, set debugfs_name to NULL after it is freed.
--- drivers/base/regmap/regmap-debugfs.c | 1 + 1 file changed, 1 insertion(+)
drivers/base/regmap/regmap-debugfs.c +1 -0
@@ -660,6 +660,7 @@ void regmap_debugfs_exit(struct regmap *map)regmap_debugfs_free_dump_cache (map);mutex_unlock (&map->cache_lock);kfree (map->debugfs_name); + map->debugfs_name =NULL ; }else {struct regmap_debugfs_node *node, *tmp;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 165/601 spi: rockchip: avoid objtool warning
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit e50989527faeafb79f45a0f7529ba8e01dff1fff ]
Building this file with clang leads to a an unreachable code path causing a warning from objtool:
drivers/spi/spi-rockchip.o: warning: objtool: rockchip_spi_transfer_one()+0x2e0: sibling call from callable instruction with modified stack frame
Change the unreachable() into an error return that can be handled if it ever happens, rather than silently crashing the kernel.
--- drivers/spi/spi-rockchip.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/spi/spi-rockchip.c +10 -3
@@ -476,7 +476,7 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs,return 1 ; } -static void rockchip_spi_config (struct rockchip_spi *rs, +static int rockchip_spi_config (struct rockchip_spi *rs,struct spi_device *spi,struct spi_transfer *xfer,bool use_dma,bool slave_mode) {
@@ -521,7 +521,9 @@ static void rockchip_spi_config(struct rockchip_spi *rs,* ctlr->bits_per_word_mask, so this shouldn't * happen */ -unreachable (); +dev_err (rs->dev,"unknown bits per word: %d\n" , + xfer->bits_per_word); +return -EINVAL ; }if (use_dma) {
@@ -554,6 +556,8 @@ static void rockchip_spi_config(struct rockchip_spi *rs,*/ writel_relaxed (2 *DIV_ROUND_UP (rs->freq,2 * xfer->speed_hz), rs->regs +ROCKCHIP_SPI_BAUDR ); + +return 0 ; }static size_t rockchip_spi_max_transfer_size (struct spi_device *spi)
@@ -577,6 +581,7 @@ static int rockchip_spi_transfer_one( struct spi_transfer *xfer) {struct rockchip_spi *rs =spi_controller_get_devdata (ctlr); +int ret;bool use_dma; WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
@@ -596,7 +601,9 @@ static int rockchip_spi_transfer_one( use_dma = ctlr->can_dma ? ctlr->can_dma (ctlr, spi, xfer) : false; -rockchip_spi_config (rs, spi, xfer, use_dma, ctlr->slave); + ret =rockchip_spi_config (rs, spi, xfer, use_dma, ctlr->slave); +if (ret) +return ret;if (use_dma)return rockchip_spi_prepare_dma (rs, ctlr, xfer);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 166/601 mtd: rawnand: fsmc: Fix error code in fsmc_nand_probe()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit e7a97528e3c787802d8c643d6ab2f428511bb047 ]
If dma_request_channel() fails then the probe fails and it should return a negative error code, but currently it returns success.
--- drivers/mtd/nand/raw/fsmc_nand.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mtd/nand/raw/fsmc_nand.c +2 -0
@@ -1077,11 +1077,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) host->read_dma_chan =dma_request_channel (mask, filter,NULL );if (!host->read_dma_chan) {dev_err (&pdev->dev,"Unable to get read dma channel\n" ); + ret = -ENODEV ; goto disable_clk; } host->write_dma_chan =dma_request_channel (mask, filter,NULL );if (!host->write_dma_chan) {dev_err (&pdev->dev,"Unable to get write dma channel\n" ); + ret = -ENODEV ; goto release_dma_read_chan; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 167/601 mtd: rawnand: brcmnand: fix OOB R/W with Hamming ECC
In reply to Greg Kroah-HartmanFrom: Álvaro Fernández Rojas <[email protected]>
[ Upstream commit f5200c14242fb8fa4a9b93f7fd4064d237e58785 ]
Hamming ECC doesn't cover the OOB data, so reading or writing OOB shall always be done without ECC enabled.
This is a problem when adding JFFS2 cleanmarkers to erased blocks. If JFFS2 clenmarkers are added to the OOB with ECC enabled, OOB bytes will be changed from ff ff ff to 00 00 00, reporting incorrect ECC errors.
--- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +6 -0
@@ -2688,6 +2688,12 @@ static int brcmnand_attach_chip(struct nand_chip *chip) ret =brcmstb_choose_ecc_layout (host); +/* If OOB is written with ECC enabled it will cause ECC errors */ +if (is_hamming_ecc (host->ctrl, &host->hwcfg)) { + chip->ecc.write_oob = brcmnand_write_oob_raw; + chip->ecc.read_oob = brcmnand_read_oob_raw; + } +return ret; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 168/601 mtd: Handle possible -EPROBE_DEFER from parse_mtd_partitions()
In reply to Greg Kroah-HartmanFrom: Manivannan Sadhasivam <[email protected]>
[ Upstream commit 08608adb520e51403be7592c2214846fa440a23a ]
There are chances that the parse_mtd_partitions() function will return -EPROBE_DEFER in mtd_device_parse_register(). This might happen when the dependency is not available for the parser. For instance, on SDX55 the MTD_QCOMSMEM_PARTS parser depends on the QCOM_SMEM driver to parse the partitions defined in the shared memory region. With the current flow, the error returned from parse_mtd_partitions() will be discarded in favor of trying to add the fallback partition.
This will prevent the driver to end up in probe deferred pool and the partitions won't be parsed even after the QCOM_SMEM driver is available.
Fix this issue by bailing out of mtd_device_parse_register() when -EPROBE_DEFER error is returned from parse_mtd_partitions() function and propagate the error code to the driver core for probing later.
--- drivers/mtd/mtdcore.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mtd/mtdcore.c +3 -0
@@ -820,6 +820,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,/* Prefer parsed partitions over driver-provided fallback */ ret =parse_mtd_partitions (mtd, types, parser_data); +if (ret == -EPROBE_DEFER ) + goto out; +if (ret >0 ) ret =0 ;else if (nr_parts)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 169/601 mtd: rawnand: qcom: Return actual error code instead of -ENODEV
In reply to Greg Kroah-HartmanFrom: Manivannan Sadhasivam <[email protected]>
[ Upstream commit 55fbb9ba4f06cb6aff32daca1e1910173c13ec51 ]
In qcom_probe_nand_devices() function, the error code returned by qcom_nand_host_init_and_register() is converted to -ENODEV in the case of failure. This poses issue if -EPROBE_DEFER is returned when the dependency is not available for a component like parser.
So let's restructure the error handling logic a bit and return the actual error code in case of qcom_nand_host_init_and_register() failure.
--- drivers/mtd/nand/raw/qcom_nandc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/mtd/nand/raw/qcom_nandc.c +2 -5
@@ -2896,7 +2896,7 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)struct device *dev = nandc->dev;struct device_node *dn = dev->of_node, *child;struct qcom_nand_host *host; -int ret; +int ret = -ENODEV ;for_each_available_child_of_node (dn, child) { host =devm_kzalloc (dev,sizeof (*host),GFP_KERNEL );
@@ -2914,10 +2914,7 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)list_add_tail (&host->node, &nandc->host_list); } -if (list_empty (&nandc->host_list)) -return -ENODEV ; - -return 0 ; +return ret; }/* parse custom DT properties here */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 170/601 mtd: dont lock when recursively deleting partitions
In reply to Greg Kroah-HartmanFrom: David Bauer <[email protected]>
[ Upstream commit cb4543054c5c4fd33df960b41d7b483ebca8e786 ]
When recursively deleting partitions, don't acquire the masters partition lock twice. Otherwise the process ends up in a deadlocked state.
--- drivers/mtd/mtdpart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/mtdpart.c +1 -1
@@ -331,7 +331,7 @@ static int __del_mtd_partitions(struct mtd_info *mtd)list_for_each_entry_safe (child, next, &mtd->partitions, part.node) {if (mtd_has_partitions (child)) -del_mtd_partitions (child); +__del_mtd_partitions (child);pr_info ("Deleting %s MTD partition\n" , child->name); ret =del_mtd_device (child);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 171/601 mtd: maps: fix error return code of physmap_flash_remove()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit 620b90d30c08684dc6ebee07c72755d997f9d1f6 ]
When platform_get_drvdata() returns NULL to info, no error return code of physmap_flash_remove() is assigned.
To fix this bug, err is assigned with -EINVAL in this case
--- drivers/mtd/maps/physmap-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/mtd/maps/physmap-core.c +3 -1
@@ -69,8 +69,10 @@ static int physmap_flash_remove(struct platform_device *dev)int i, err =0 ; info =platform_get_drvdata (dev); -if (!info) +if (!info) { + err = -EINVAL ; goto out; + }if (info->cmtd) { err =mtd_device_unregister (info->cmtd);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 172/601 ARM: dts: stm32: fix usart 2 & 3 pinconf to wake up with flow control
In reply to Greg Kroah-HartmanFrom: Valentin CARON - foss <[email protected]>
[ Upstream commit a1429f3d3029b65cd4032f6218d5290911377ce4 ]
Modify usart 2 & 3 pins to allow wake up from low power mode while the hardware flow control is activated. UART RTS pin need to stay configure in idle mode to receive characters in order to wake up.
--- arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +18 -3
@@ -1868,10 +1868,15 @@ usart2_idle_pins_c: usart2-idle-2 { pins1 { pinmux = <STM32_PINMUX('D', 5, ANALOG)>, /* USART2_TX */ - <STM32_PINMUX('D', 4, ANALOG)>, /* USART2_RTS */ <STM32_PINMUX('D', 3, ANALOG)>; /* USART2_CTS_NSS */ }; pins2 { + pinmux = <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + pins3 { pinmux = <STM32_PINMUX('D', 6, AF7)>; /* USART2_RX */ bias-disable; };
@@ -1917,10 +1922,15 @@ usart3_idle_pins_b: usart3-idle-1 { pins1 { pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */ - <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */ <STM32_PINMUX('I', 10, ANALOG)>; /* USART3_CTS_NSS */ }; pins2 { + pinmux = <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins3 { pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */ bias-disable; };
@@ -1953,10 +1963,15 @@ usart3_idle_pins_c: usart3-idle-2 { pins1 { pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */ - <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */ <STM32_PINMUX('B', 13, ANALOG)>; /* USART3_CTS_NSS */ }; pins2 { + pinmux = <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins3 { pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */ bias-disable; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 173/601 arm64: dts: ti: k3-j721e-main: Update the speed modes supported and their itap delay values for MMCSD subsystems
In reply to Greg Kroah-HartmanFrom: Aswath Govindraju <[email protected]>
[ Upstream commit eb8f6194e8074d7b00642dd75cf04d13e1b218e4 ]
According to latest errata of J721e [1], HS400 mode is not supported in MMCSD0 subsystem (i2024) and SDR104 mode is not supported in MMCSD1/2 subsystems (i2090). Therefore, replace mmc-hs400-1_8v with mmc-hs200-1_8v in MMCSD0 subsystem and add a sdhci mask to disable SDR104 speed mode.
Also, update the itap delay values for all the MMCSD subsystems according the latest J721e data sheet[2]
[1] - https://www.ti.com/lit/er/sprz455/sprz455.pdf
[2] - https://www.ti.com/lit/ds/symlink/tda4vm.pdf
--- arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +16 -1
@@ -1078,13 +1078,16 @@ assigned-clocks = <&k3_clks 91 1>; assigned-clock-parents = <&k3_clks 91 2>; bus-width = <8>; - mmc-hs400-1_8v; + mmc-hs200-1_8v; mmc-ddr-1_8v; ti,otap-del-sel-legacy = <0xf>; ti,otap-del-sel-mmc-hs = <0xf>; ti,otap-del-sel-ddr52 = <0x5>; ti,otap-del-sel-hs200 = <0x6>; ti,otap-del-sel-hs400 = <0x0>; + ti,itap-del-sel-legacy = <0x10>; + ti,itap-del-sel-mmc-hs = <0xa>; + ti,itap-del-sel-ddr52 = <0x3>; ti,trm-icp = <0x8>; ti,strobe-sel = <0x77>; dma-coherent;
@@ -1105,9 +1108,15 @@ ti,otap-del-sel-sdr25 = <0xf>; ti,otap-del-sel-sdr50 = <0xc>; ti,otap-del-sel-ddr50 = <0xc>; + ti,itap-del-sel-legacy = <0x0>; + ti,itap-del-sel-sd-hs = <0x0>; + ti,itap-del-sel-sdr12 = <0x0>; + ti,itap-del-sel-sdr25 = <0x0>; + ti,itap-del-sel-ddr50 = <0x2>; ti,trm-icp = <0x8>; ti,clkbuf-sel = <0x7>; dma-coherent; + sdhci-caps-mask = <0x2 0x0>; }; main_sdhci2: sdhci@4f98000 {
@@ -1125,9 +1134,15 @@ ti,otap-del-sel-sdr25 = <0xf>; ti,otap-del-sel-sdr50 = <0xc>; ti,otap-del-sel-ddr50 = <0xc>; + ti,itap-del-sel-legacy = <0x0>; + ti,itap-del-sel-sd-hs = <0x0>; + ti,itap-del-sel-sdr12 = <0x0>; + ti,itap-del-sel-sdr25 = <0x0>; + ti,itap-del-sel-ddr50 = <0x2>; ti,trm-icp = <0x8>; ti,clkbuf-sel = <0x7>; dma-coherent; + sdhci-caps-mask = <0x2 0x0>; }; usbss0: cdns-usb@4104000 {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 174/601 iio: adis16480: fix pps mode sampling frequency math
In reply to Greg Kroah-HartmanFrom: Nuno Sa <[email protected]>
[ Upstream commit 0463e60f087069adf25a815cd88753946aca2565 ]
When using PPS mode, the input clock needs to be scaled so that we have an IMU sample rate between (optimally) 4000 and 4250. After this, we can use the decimation filter to lower the sampling rate in order to get what the user wants. Optimally, the user sample rate is a multiple of both the IMU sample rate and the input clock. Hence, calculating the sync_scale dynamically gives us better chances of achieving a perfect/integer value for DEC_RATE. The math here is:
1. lcm of the input clock and the desired output rate.
2. get the highest multiple of the previous result lower than the adis max rate.
3. The last result becomes the IMU sample rate. Use that to calculate SYNC_SCALE and DEC_RATE (to get the user output rate).
--- drivers/iio/imu/adis16480.c | 128 ++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 34 deletions(-)
drivers/iio/imu/adis16480.c +94 -34
@@ -10,6 +10,7 @@#include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/math.h> #include <linux/mutex.h> #include <linux/device.h> #include <linux/kernel.h>
@@ -17,6 +18,7 @@#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/module.h> +#include <linux/lcm.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h>
@@ -170,6 +172,11 @@ static const char * const adis16480_int_pin_names[4] = { [ADIS16480_PIN_DIO4] = "DIO4", }; +static bool low_rate_allow; +module_param (low_rate_allow, bool,0444 ); +MODULE_PARM_DESC (low_rate_allow, +"Allow IMU rates below the minimum advisable when external clk is used in PPS mode (default: N)" ); +#ifdef CONFIG_DEBUG_FS static ssize_t adis16480_show_firmware_revision(struct file *file,
@@ -312,7 +319,8 @@ static int adis16480_debugfs_init(struct iio_dev *indio_dev)static int adis16480_set_freq (struct iio_dev *indio_dev,int val,int val2) {struct adis16480 *st =iio_priv (indio_dev); -unsigned int t, reg; +unsigned int t, sample_rate = st->clk_freq; +int ret;if (val <0 || val2 <0 )return -EINVAL ;
@@ -321,28 +329,65 @@ static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2)if (t ==0 )return -EINVAL ; +mutex_lock (&st->adis.state_lock);/* -* When using PPS mode, the rate of data collection is equal to the -* product of the external clock frequency and the scale factor in the -* SYNC_SCALE register. -* When using sync mode, or internal clock, the output data rate is -* equal with the clock frequency divided by DEC_RATE + 1. +* When using PPS mode, the input clock needs to be scaled so that we have an IMU +* sample rate between (optimally) 4000 and 4250. After this, we can use the +* decimation filter to lower the sampling rate in order to get what the user wants. +* Optimally, the user sample rate is a multiple of both the IMU sample rate and +* the input clock. Hence, calculating the sync_scale dynamically gives us better +* chances of achieving a perfect/integer value for DEC_RATE. The math here is: +* 1. lcm of the input clock and the desired output rate. +* 2. get the highest multiple of the previous result lower than the adis max rate. +* 3. The last result becomes the IMU sample rate. Use that to calculate SYNC_SCALE +* and DEC_RATE (to get the user output rate) */ if (st->clk_mode ==ADIS16480_CLK_PPS ) { - t = t / st->clk_freq; - reg =ADIS16495_REG_SYNC_SCALE ; - }else { - t = st->clk_freq / t; - reg =ADIS16480_REG_DEC_RATE ; +unsigned long scaled_rate =lcm (st->clk_freq, t); +int sync_scale; + +/* +* If lcm is bigger than the IMU maximum sampling rate there's no perfect +* solution. In this case, we get the highest multiple of the input clock +* lower than the IMU max sample rate. +*/ +if (scaled_rate > st->chip_info->int_clk) + scaled_rate = st->chip_info->int_clk / st->clk_freq * st->clk_freq; +else + scaled_rate = st->chip_info->int_clk / scaled_rate * scaled_rate; + +/* +* This is not an hard requirement but it's not advised to run the IMU +* with a sample rate lower than 4000Hz due to possible undersampling +* issues. However, there are users that might really want to take the risk. +* Hence, we provide a module parameter for them. If set, we allow sample +* rates lower than 4KHz. By default, we won't allow this and we just roundup +* the rate to the next multiple of the input clock bigger than 4KHz. This +* is done like this as in some cases (when DEC_RATE is 0) might give +* us the closest value to the one desired by the user... +*/ +if (scaled_rate <4000000 && !low_rate_allow) + scaled_rate =roundup (4000000 , st->clk_freq); + + sync_scale = scaled_rate / st->clk_freq; + ret =__adis_write_reg_16 (&st->adis,ADIS16495_REG_SYNC_SCALE , sync_scale); +if (ret) + goto error; + + sample_rate = scaled_rate; } + t =DIV_ROUND_CLOSEST (sample_rate, t); +if (t) + t--; +if (t > st->chip_info->max_dec_rate) t = st->chip_info->max_dec_rate; -if ((t !=0 ) && (st->clk_mode !=ADIS16480_CLK_PPS )) - t--; - -return adis_write_reg_16 (&st->adis, reg, t); + ret =__adis_write_reg_16 (&st->adis,ADIS16480_REG_DEC_RATE , t); +error: +mutex_unlock (&st->adis.state_lock); +return ret; }static int adis16480_get_freq (struct iio_dev *indio_dev,int *val,int *val2)
@@ -350,34 +395,35 @@ static int adis16480_get_freq(struct iio_dev *indio_dev, int *val, int *val2)struct adis16480 *st =iio_priv (indio_dev);uint16_t t;int ret; -unsigned int freq; -unsigned int reg; +unsigned int freq, sample_rate = st->clk_freq; -if (st->clk_mode ==ADIS16480_CLK_PPS ) - reg =ADIS16495_REG_SYNC_SCALE ; -else - reg =ADIS16480_REG_DEC_RATE ; +mutex_lock (&st->adis.state_lock); + +if (st->clk_mode ==ADIS16480_CLK_PPS ) { +u16 sync_scale; + + ret =__adis_read_reg_16 (&st->adis,ADIS16495_REG_SYNC_SCALE , &sync_scale); +if (ret) + goto error; - ret =adis_read_reg_16 (&st->adis, reg, &t); + sample_rate = st->clk_freq * sync_scale; + } + + ret =__adis_read_reg_16 (&st->adis,ADIS16480_REG_DEC_RATE , &t);if (ret) -return ret; + goto error; -/* -* When using PPS mode, the rate of data collection is equal to the -* product of the external clock frequency and the scale factor in the -* SYNC_SCALE register. -* When using sync mode, or internal clock, the output data rate is -* equal with the clock frequency divided by DEC_RATE + 1. -*/ -if (st->clk_mode ==ADIS16480_CLK_PPS ) - freq = st->clk_freq * t; -else - freq = st->clk_freq / (t +1 ); +mutex_unlock (&st->adis.state_lock); + + freq =DIV_ROUND_CLOSEST (sample_rate, (t +1 )); *val = freq /1000 ; *val2 = (freq %1000 ) *1000 ;return IIO_VAL_INT_PLUS_MICRO ; +error: +mutex_unlock (&st->adis.state_lock); +return ret; }enum {
@@ -1278,6 +1324,20 @@ static int adis16480_probe(struct spi_device *spi) st->clk_freq =clk_get_rate (st->ext_clk); st->clk_freq *=1000 ;/* micro */ +if (st->clk_mode ==ADIS16480_CLK_PPS ) { +u16 sync_scale; + +/* +* In PPS mode, the IMU sample rate is the clk_freq * sync_scale. Hence, +* default the IMU sample rate to the highest multiple of the input clock +* lower than the IMU max sample rate. The internal sample rate is the +* max... +*/ + sync_scale = st->chip_info->int_clk / st->clk_freq; + ret =__adis_write_reg_16 (&st->adis,ADIS16495_REG_SYNC_SCALE , sync_scale); +if (ret) +return ret; + } }else { st->clk_freq = st->chip_info->int_clk; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 175/601 arm64: dts: qcom: sc7180: trogdor: Fix trip point config of charger thermal zone
In reply to Greg Kroah-HartmanFrom: Matthias Kaehlcke <[email protected]>
[ Upstream commit 38f3267def6511171aef0f056ad172686903603f ]
The trip point configuration of the charger thermal zone for trogdor is missing a node for the critical trip point. Add the missing node.
--- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +5 -3
@@ -22,9 +22,11 @@ thermal-sensors = <&pm6150_adc_tm 1>; trips { - temperature = <125000>; - hysteresis = <1000>; - type = "critical"; + charger-crit { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; }; }; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 176/601 arm64: dts: qcom: sm8250: Fix level triggered PMU interrupt polarity
In reply to Greg Kroah-HartmanFrom: Sai Prakash Ranjan <[email protected]>
[ Upstream commit 93138ef5ac923b10f81575d35dbcb83136cbfc40 ]
As per interrupt documentation for SM8250 SoC, the polarity for level triggered PMU interrupt is low, fix this.
--- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sm8250.dtsi +1 -1
@@ -216,7 +216,7 @@ pmu { compatible = "arm,armv8-pmuv3"; - interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; }; psci {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 177/601 arm64: dts: qcom: sm8250: Fix timer interrupt to specify EL2 physical timer
In reply to Greg Kroah-HartmanFrom: Sai Prakash Ranjan <[email protected]>
[ Upstream commit 29a3349543e4ce3fe4e2a761403cc629e3534c67 ]
ARM architected timer interrupts DT property specifies EL2/HYP physical interrupt and not EL2/HYP virtual interrupt for the 4th interrupt property. As per interrupt documentation for SM8250 SoC, the EL2/HYP physical timer interrupt is 10 and EL2/HYP virtual timer interrupt is 12, so fix the 4th timer interrupt to be EL2 physical timer interrupt (10 in this case).
--- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sm8250.dtsi +1 -1
@@ -2832,7 +2832,7 @@ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 12 + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 178/601 arm64: dts: qcom: sc7180: Avoid glitching SPI CS at bootup on trogdor
In reply to Greg Kroah-HartmanFrom: Douglas Anderson <[email protected]>
[ Upstream commit e440e30e26dd6b0424002ad0ddcbbcea783efd85 ]
At boot time the following happens:
1. Device core gets ready to probe our SPI driver.
2. Device core applies SPI controller's "default" pinctrl.
3. Device core calls the SPI driver's probe() function which will eventually setup the chip select GPIO as "unasserted".
Thinking about the above, we can find:
a) For SPI devices that the BIOS inits (Cr50 and EC), the BIOS would have had them configured as "GENI" pins and not as "GPIO" pins.
b) It turns out that our BIOS also happens to init these pins as "output" (even though it doesn't need to since they're not muxed as GPIO) but leaves them at the default state of "low".
c) As soon as we apply the "default" chip select it'll switch the function to GPIO and stop driving the chip select high (which is how "GENI" was driving it) and start driving it low.
d) As of commit 9378f46040be ("UPSTREAM: spi: spi-geni-qcom: Use the new method of gpio CS control"), when the SPI core inits things it inits the GPIO to be "deasserted". Prior to that commit the GPIO was left untouched until first use.
e) When the first transaction happens we'll assert the chip select and then deassert it after done.
So before the commit to change us to use gpio descriptors we used to have a _really long_ assertion of chip select before our first transaction (because it got pulled down and then the first "assert" was a no-op). That wasn't great but (apparently) didn't cause any real harm.
After the commit to change us to use gpio descriptors we end up glitching the chip select line during probe. It would go low and then high with no data transferred. The other side ought to be robust against this, but it certainly could cause some confusion. It's known to at least cause an error message on the EC console and it's believed that, under certain timing conditions, it could be getting the EC into a confused state causing the EC driver to fail to probe.
Let's fix things to avoid the glitch. We'll add an extra pinctrl entry that sets the value of the pin to output high (CS deasserted) before doing anything else. We'll do this in its own pinctrl node that comes before the normal pinctrl entries to ensure that the order is correct and that this gets applied before the mux change.
This change is in the trogdor board file rather than in the SoC dtsi file because chip select polarity can be different depending on what's hooked up and it doesn't feel worth it to spam the SoC dtsi file with both options. The board file would need to pick the right one anyway.
--- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 27 +++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +24 -3
@@ -838,17 +838,17 @@ hp_i2c: &i2c9 { }; &spi0 { - pinctrl-0 = <&qup_spi0_cs_gpio>; + pinctrl-0 = <&qup_spi0_cs_gpio_init_high>, <&qup_spi0_cs_gpio>; cs-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; }; &spi6 { - pinctrl-0 = <&qup_spi6_cs_gpio>; + pinctrl-0 = <&qup_spi6_cs_gpio_init_high>, <&qup_spi6_cs_gpio>; cs-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; }; ap_spi_fp: &spi10 { - pinctrl-0 = <&qup_spi10_cs_gpio>; + pinctrl-0 = <&qup_spi10_cs_gpio_init_high>, <&qup_spi10_cs_gpio>; cs-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; cros_ec_fp: ec@0 {
@@ -1402,6 +1402,27 @@ ap_spi_fp: &spi10 { }; }; + qup_spi0_cs_gpio_init_high: qup-spi0-cs-gpio-init-high { + pinconf { + pins = "gpio37"; + output-high; + }; + }; + + qup_spi6_cs_gpio_init_high: qup-spi6-cs-gpio-init-high { + pinconf { + pins = "gpio62"; + output-high; + }; + }; + + qup_spi10_cs_gpio_init_high: qup-spi10-cs-gpio-init-high { + pinconf { + pins = "gpio89"; + output-high; + }; + }; + qup_uart3_sleep: qup-uart3-sleep { pinmux { pins = "gpio38", "gpio39",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 179/601 arm64: dts: qcom: sdm845: fix number of pins in gpio-ranges
In reply to Greg Kroah-HartmanFrom: Shawn Guo <[email protected]>
[ Upstream commit 02058fc3839df65ff64de2a6b1c5de8c9fd705c1 ]
The last cell of 'gpio-ranges' should be number of GPIO pins, and in case of qcom platform it should match msm_pinctrl_soc_data.ngpio rather than msm_pinctrl_soc_data.ngpio - 1.
This fixes the problem that when the last GPIO pin in the range is configured with the following call sequence, it always fails with -EPROBE_DEFER.
pinctrl_gpio_set_config()
pinctrl_get_device_gpio_range()
pinctrl_match_gpio_range()
--- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +1 -1
@@ -2384,7 +2384,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 150>; + gpio-ranges = <&tlmm 0 0 151>; wakeup-parent = <&pdc_intc>; cci0_default: cci0-default {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 180/601 arm64: dts: qcom: sm8150: fix number of pins in gpio-ranges
In reply to Greg Kroah-HartmanFrom: Shawn Guo <[email protected]>
[ Upstream commit de3abdf3d15c6e7f456e2de3f9da78f3a31414cc ]
The last cell of 'gpio-ranges' should be number of GPIO pins, and in case of qcom platform it should match msm_pinctrl_soc_data.ngpio rather than msm_pinctrl_soc_data.ngpio - 1.
This fixes the problem that when the last GPIO pin in the range is configured with the following call sequence, it always fails with -EPROBE_DEFER.
pinctrl_gpio_set_config()
pinctrl_get_device_gpio_range()
pinctrl_match_gpio_range()
--- arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sm8150.dtsi +1 -1
@@ -757,7 +757,7 @@ <0x0 0x03D00000 0x0 0x300000>; reg-names = "west", "east", "north", "south"; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; - gpio-ranges = <&tlmm 0 0 175>; + gpio-ranges = <&tlmm 0 0 176>; gpio-controller; #gpio-cells = <2>; interrupt-controller;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 181/601 arm64: dts: qcom: sm8250: fix number of pins in gpio-ranges
In reply to Greg Kroah-HartmanFrom: Shawn Guo <[email protected]>
[ Upstream commit e526cb03e2aed42866a0919485a3d8ac130972cf ]
The last cell of 'gpio-ranges' should be number of GPIO pins, and in case of qcom platform it should match msm_pinctrl_soc_data.ngpio rather than msm_pinctrl_soc_data.ngpio - 1.
This fixes the problem that when the last GPIO pin in the range is configured with the following call sequence, it always fails with -EPROBE_DEFER.
pinctrl_gpio_set_config()
pinctrl_get_device_gpio_range()
pinctrl_match_gpio_range()
--- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sm8250.dtsi +1 -1
@@ -1877,7 +1877,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 180>; + gpio-ranges = <&tlmm 0 0 181>; wakeup-parent = <&pdc>; qup_i2c0_default: qup-i2c0-default {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 182/601 arm64: dts: qcom: db845c: fix correct powerdown pin for WSA881x
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit c561740e7cfefaf3003a256f3a0cd9f8a069137c ]
WSA881x powerdown pin is connected to GPIO1 not gpio2, so correct this. This was working so far due to a shift bug in gpio driver, however once that is fixed this will stop working, so fix this!
--- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm845-db845c.dts +2 -2
@@ -1015,7 +1015,7 @@ left_spkr: wsa8810-left{ compatible = "sdw10217201000"; reg = <0 1>; - powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; + powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_HIGH>; #thermal-sensor-cells = <0>; sound-name-prefix = "SpkrLeft"; #sound-dai-cells = <0>;
@@ -1023,7 +1023,7 @@ right_spkr: wsa8810-right{ compatible = "sdw10217201000"; - powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; + powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_HIGH>; reg = <0 2>; #thermal-sensor-cells = <0>; sound-name-prefix = "SpkrRight";
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 183/601 crypto: sun8i-ss - Fix memory leak of object d when dma_iv fails to map
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 98b5ef3e97b16eaeeedb936f8bda3594ff84a70e ]
In the case where the dma_iv mapping fails, the return error path leaks the memory allocated to object d. Fix this by adding a new error return label and jumping to this to ensure d is free'd before the return.
Addresses-Coverity: ("Resource leak")
--- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c +3 -1
@@ -103,7 +103,8 @@ int sun8i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src, dma_iv =dma_map_single (ss->dev, ctx->seed, ctx->slen,DMA_TO_DEVICE );if (dma_mapping_error (ss->dev, dma_iv)) {dev_err (ss->dev,"Cannot DMA MAP IV\n" ); -return -EFAULT ; + err = -EFAULT ; + goto err_free; } dma_dst =dma_map_single (ss->dev, d, todo,DMA_FROM_DEVICE );
@@ -167,6 +168,7 @@ err_iv:memcpy (ctx->seed, d + dlen, ctx->slen); }memzero_explicit (d, todo); +err_free:kfree (d);return err;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 184/601 spi: stm32: drop devres version of spi_register_master
In reply to Greg Kroah-HartmanFrom: Antonio Borneo <[email protected]>
[ Upstream commit 8d559a64f00b59af9cc02b803ff52f6e6880a651 ]
A call to spi_unregister_master() triggers calling remove() for all the spi devices binded to the spi master.
Some spi device driver requires to "talk" with the spi device during the remove(), e.g.:
- a LCD panel like drivers/gpu/drm/panel/panel-lg-lg4573.c will turn off the backlighting sending a command over spi.
This implies that the spi master must be fully functional when spi_unregister_master() is called, either if it is called explicitly in the master's remove() code or implicitly by the devres framework.
Devres calls devres_release_all() to release all the resources "after" the remove() of the spi master driver (check code of __device_release_driver() in drivers/base/dd.c).
If the spi master driver has an empty remove() then there would be no issue; the devres_release_all() will release everything in reverse order w.r.t. probe().
But if code in spi master driver remove() disables the spi or makes it not functional (like in this spi-stm32), then devres cannot be used safely for unregistering the spi master and the binded spi devices.
Replace devm_spi_register_master() with spi_register_master() and add spi_unregister_master() as first action in remove().
--- drivers/spi/spi-stm32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/spi/spi-stm32.c +2 -1
@@ -1950,7 +1950,7 @@ static int stm32_spi_probe(struct platform_device *pdev)pm_runtime_set_active (&pdev->dev);pm_runtime_enable (&pdev->dev); - ret =devm_spi_register_master (&pdev->dev, master); + ret =spi_register_master (master);if (ret) {dev_err (&pdev->dev,"spi master registration failed: %d\n" , ret);
@@ -1987,6 +1987,7 @@ static int stm32_spi_remove(struct platform_device *pdev)struct spi_master *master =platform_get_drvdata (pdev);struct stm32_spi *spi =spi_master_get_devdata (master); +spi_unregister_master (master); spi->cfg->disable (spi);if (master->dma_tx)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 185/601 regulator: bd9576: Fix return from bd957x_probe()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 320fcd6bbd2b500923db518902c2c640242d2b50 ]
The probe() function returns an uninitialized variable in the success path. There is no need for the "err" variable at all, just delete it.
--- drivers/regulator/bd9576-regulator.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/regulator/bd9576-regulator.c +4 -7
@@ -206,7 +206,7 @@ static int bd957x_probe(struct platform_device *pdev) {struct regmap *regmap;struct regulator_config config = {0 }; -int i, err; +int i;bool vout_mode, ddr_sel;const struct bd957x_regulator_data *reg_data = &bd9576_regulators[0 ];unsigned int num_reg_data =ARRAY_SIZE (bd9576_regulators);
@@ -279,8 +279,7 @@ static int bd957x_probe(struct platform_device *pdev)break ;default :dev_err (&pdev->dev,"Unsupported chip type\n" ); - err = -EINVAL ; - goto err; +return -EINVAL ; } config.dev = pdev->dev.parent;
@@ -300,8 +299,7 @@ static int bd957x_probe(struct platform_device *pdev)dev_err (&pdev->dev,"failed to register %s regulator\n" , desc->name); - err =PTR_ERR (rdev); - goto err; +return PTR_ERR (rdev); }/* * Clear the VOUT1 GPIO setting - rest of the regulators do not
@@ -310,8 +308,7 @@ static int bd957x_probe(struct platform_device *pdev) config.ena_gpiod =NULL ; } -err: -return err; +return 0 ; }static const struct platform_device_id bd957x_pmic_id[] = {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 186/601 arm64: dts: renesas: r8a77980: Fix vin4-7 endpoint binding
In reply to Greg Kroah-HartmanFrom: Vladimir Barinov <[email protected]>
[ Upstream commit c8aebc1346522d3569690867ce3996642ad52e01 ]
This fixes the bindings in media framework:
The CSI40 is endpoint number 2
The CSI41 is endpoint number 3
--- arch/arm64/boot/dts/renesas/r8a77980.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/renesas/r8a77980.dtsi +8 -8
@@ -992,8 +992,8 @@ reg = <1>; - vin4csi41: endpoint@2 { - reg = <2>; + vin4csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin4>; }; };
@@ -1020,8 +1020,8 @@ reg = <1>; - vin5csi41: endpoint@2 { - reg = <2>; + vin5csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin5>; }; };
@@ -1048,8 +1048,8 @@ reg = <1>; - vin6csi41: endpoint@2 { - reg = <2>; + vin6csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin6>; }; };
@@ -1076,8 +1076,8 @@ reg = <1>; - vin7csi41: endpoint@2 { - reg = <2>; + vin7csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin7>; }; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 187/601 selftests/x86: Add a missing .note.GNU-stack section to thunks_32.S
In reply to Greg Kroah-HartmanFrom: Andy Lutomirski <[email protected]>
[ Upstream commit f706bb59204ba1c47e896b456c97977fc97b7964 ]
test_syscall_vdso_32 ended up with an executable stacks because the asm was missing the annotation that says that it is modern and doesn't need an executable stack. Add the annotation.
This was missed in commit aeaaf005da1d ("selftests/x86: Add missing .note.GNU-stack sections").
--- tools/testing/selftests/x86/thunks_32.S | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/selftests/x86/thunks_32.S +2 -0
@@ -45,3 +45,5 @@ call64_from_32: ret .size call64_from_32, .-call64_from_32 + +.section .note.GNU-stack,"",%progbits
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 188/601 spi: stm32: Fix use-after-free on unbind
In reply to Greg Kroah-HartmanFrom: Alain Volmat <[email protected]>
[ Upstream commit 79c6246ae8793448c05da86a4c82298eed8549b0 ]
stm32_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
--- drivers/spi/spi-stm32.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-)
drivers/spi/spi-stm32.c +10 -14
@@ -1830,7 +1830,7 @@ static int stm32_spi_probe(struct platform_device *pdev)struct resource *res;int ret; - master =spi_alloc_master (&pdev->dev,sizeof (struct stm32_spi )); + master =devm_spi_alloc_master (&pdev->dev,sizeof (struct stm32_spi ));if (!master) {dev_err (&pdev->dev,"spi master allocation failed\n" );return -ENOMEM ;
@@ -1848,18 +1848,16 @@ static int stm32_spi_probe(struct platform_device *pdev) res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); spi->base =devm_ioremap_resource (&pdev->dev, res); -if (IS_ERR (spi->base)) { - ret =PTR_ERR (spi->base); - goto err_master_put; - } +if (IS_ERR (spi->base)) +return PTR_ERR (spi->base); spi->phys_addr = (dma_addr_t )res->start; spi->irq =platform_get_irq (pdev,0 ); -if (spi->irq <=0 ) { - ret =dev_err_probe (&pdev->dev, spi->irq,"failed to get irq\n" ); - goto err_master_put; - } +if (spi->irq <=0 ) +return dev_err_probe (&pdev->dev, spi->irq, +"failed to get irq\n" ); + ret = devm_request_threaded_irq(&pdev->dev, spi->irq, spi->cfg->irq_handler_event, spi->cfg->irq_handler_thread,
@@ -1867,20 +1865,20 @@ static int stm32_spi_probe(struct platform_device *pdev)if (ret) {dev_err (&pdev->dev,"irq%d request failed: %d\n" , spi->irq, ret); - goto err_master_put; +return ret; } spi->clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (spi->clk)) { ret =PTR_ERR (spi->clk);dev_err (&pdev->dev,"clk get failed: %d\n" , ret); - goto err_master_put; +return ret; } ret =clk_prepare_enable (spi->clk);if (ret) {dev_err (&pdev->dev,"clk enable failed: %d\n" , ret); - goto err_master_put; +return ret; } spi->clk_rate =clk_get_rate (spi->clk);if (!spi->clk_rate) {
@@ -1976,8 +1974,6 @@ err_dma_release:dma_release_channel (spi->dma_rx); err_clk_disable:clk_disable_unprepare (spi->clk); -err_master_put: -spi_master_put (master);return ret; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 189/601 Drivers: hv: vmbus: Drop error message when No request id available
In reply to Greg Kroah-HartmanFrom: Andrea Parri (Microsoft) <[email protected]>
[ Upstream commit 0c85c54bf7faeb80c6b76901ed77d93acef0207d ]
Running out of request IDs on a channel essentially produces the same effect as running out of space in the ring buffer, in that -EAGAIN is returned. The error message in hv_ringbuffer_write() should either be dropped (since we don't output a message when the ring buffer is full) or be made conditional/debug-only.
--- drivers/hv/ring_buffer.c | 1 - 1 file changed, 1 deletion(-)
drivers/hv/ring_buffer.c +0 -1
@@ -313,7 +313,6 @@ int hv_ringbuffer_write(struct vmbus_channel *channel, rqst_id =vmbus_next_request_id (&channel->requestor, requestid);if (rqst_id ==VMBUS_RQST_ERROR ) {spin_unlock_irqrestore (&outring_info->ring_lock, flags); -pr_err ("No request id available\n" );return -EAGAIN ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 190/601 x86/microcode: Check for offline CPUs before requesting new microcode
In reply to Greg Kroah-HartmanFrom: Otavio Pontes <[email protected]>
[ Upstream commit 7189b3c11903667808029ec9766a6e96de5012a5 ]
Currently, the late microcode loading mechanism checks whether any CPUs are offlined, and, in such a case, aborts the load attempt.
However, this must be done before the kernel caches new microcode from the filesystem. Otherwise, when offlined CPUs are onlined later, those cores are going to be updated through the CPU hotplug notifier callback with the new microcode, while CPUs previously onine will continue to run with the older microcode.
For example:
Turn off one core (2 threads):
echo 0 > /sys/devices/system/cpu/cpu3/online
echo 0 > /sys/devices/system/cpu/cpu1/online
Install the ucode fails because a primary SMT thread is offline:
cp intel-ucode/06-8e-09 /lib/firmware/intel-ucode/ echo 1 > /sys/devices/system/cpu/microcode/reload
bash: echo: write error: Invalid argument
Turn the core back on
echo 1 > /sys/devices/system/cpu/cpu3/online
echo 1 > /sys/devices/system/cpu/cpu1/online
cat /proc/cpuinfo |grep microcode
microcode : 0x30
microcode : 0xde
microcode : 0x30
microcode : 0xde
The rationale for why the update is aborted when at least one primary thread is offline is because even if that thread is soft-offlined and idle, it will still have to participate in broadcasted MCE's synchronization dance or enter SMM, and in both examples it will execute instructions so it better have the same microcode revision as the other cores.
[ bp: Heavily edit and extend commit message with the reasoning behind all
this. ]
--- arch/x86/kernel/cpu/microcode/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/kernel/cpu/microcode/core.c +4 -4
@@ -629,16 +629,16 @@ static ssize_t reload_store(struct device *dev,if (val !=1 )return size; - tmp_ret = microcode_ops->request_microcode_fw (bsp, µcode_pdev->dev, true); -if (tmp_ret !=UCODE_NEW ) -return size; -get_online_cpus (); ret =check_online_cpus ();if (ret) goto put; + tmp_ret = microcode_ops->request_microcode_fw (bsp, µcode_pdev->dev, true); +if (tmp_ret !=UCODE_NEW ) + goto put; +mutex_lock (µcode_mutex); ret =microcode_reload_late ();mutex_unlock (µcode_mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 191/601 devtmpfs: fix placement of complete() call
In reply to Greg Kroah-HartmanFrom: Rasmus Villemoes <[email protected]>
[ Upstream commit 38f087de8947700d3b06d3d1594490e0f611c5d1 ]
Calling complete() from within the __init function is wrong - theoretically, the init process could proceed all the way to freeing the init mem before the devtmpfsd thread gets to execute the return instruction in devtmpfs_setup().
In practice, it seems to be harmless as gcc inlines devtmpfs_setup() into devtmpfsd(). So the calls of the __init functions init_chdir() etc. actually happen from devtmpfs_setup(), but the __ref on that one silences modpost (it's all right, because those calls happen before the complete()). But it does make the __init annotation of the setup function moot, which we'll fix in a subsequent patch.
--- drivers/base/devtmpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/devtmpfs.c +1 -1
@@ -416,7 +416,6 @@ static int __init devtmpfs_setup(void *p)init_chroot ("." ); out: *(int *)p = err; -complete (&setup_done);return err; }
@@ -429,6 +428,7 @@ static int __ref devtmpfsd(void *p) {int err =devtmpfs_setup (p); +complete (&setup_done);if (err)return err;devtmpfs_work_loop ();
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 192/601 usb: gadget: pch_udc: Replace cpu_to_le32() by lower_32_bits()
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 91356fed6afd1c83bf0d3df1fc336d54e38f0458 ]
Either way ~0 will be in the correct byte order, hence replace cpu_to_le32() by lower_32_bits(). Moreover, it makes sparse happy, otherwise it complains:
.../pch_udc.c:1813:27: warning: incorrect type in assignment (different base types).../pch_udc.c:1813:27: expected unsigned int [usertype] dataptr.../pch_udc.c:1813:27: got restricted __le32 [usertype]
--- drivers/usb/gadget/udc/pch_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/pch_udc.c +1 -1
@@ -1765,7 +1765,7 @@ static struct usb_request *pch_udc_alloc_request(struct usb_ep *usbep, }/* prevent from using desc. - set HOST BUSY */ dma_desc->status |=PCH_UDC_BS_HST_BSY ; - dma_desc->dataptr =cpu_to_le32 (DMA_ADDR_INVALID ); + dma_desc->dataptr =lower_32_bits (DMA_ADDR_INVALID ); req->td_data = dma_desc; req->td_data_last = dma_desc; req->chain_len =1 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 193/601 usb: gadget: pch_udc: Check if driver is present before calling ->setup()
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit fbdbbe6d3ee502b3bdeb4f255196bb45003614be ]
Since we have a separate routine for VBUS sense, the interrupt may occur before gadget driver is present. Hence, ->setup() call may oops the kernel:
[ 55.245843] BUG: kernel NULL pointer dereference, address: 00000010 ... [ 55.245843] EIP: pch_udc_isr.cold+0x162/0x33f ... [ 55.245843] <IRQ> [ 55.245843] ? pch_udc_svc_data_out+0x160/0x160
Check if driver is present before calling ->setup().
--- drivers/usb/gadget/udc/pch_udc.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
drivers/usb/gadget/udc/pch_udc.c +18 -10
@@ -2307,6 +2307,21 @@ static void pch_udc_svc_data_out(struct pch_udc_dev *dev, int ep_num)pch_udc_set_dma (dev,DMA_DIR_RX ); } +static int pch_udc_gadget_setup (struct pch_udc_dev *dev) + __must_hold(&dev->lock) +{ +int rc; + +/* In some cases we can get an interrupt before driver gets setup */ +if (!dev->driver) +return -ESHUTDOWN ; + +spin_unlock (&dev->lock); + rc = dev->driver->setup (&dev->gadget, &dev->setup_data); +spin_lock (&dev->lock); +return rc; +} +/** * pch_udc_svc_control_in() - Handle Control IN endpoint interrupts * @dev: Reference to the device structure
@@ -2378,15 +2393,12 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IDX ].ep; else /* OUT */ dev->gadget.ep0 = &ep->ep; -spin_lock (&dev->lock);/* If Mass storage Reset */ if ((dev->setup_data.bRequestType ==0x21 ) && (dev->setup_data.bRequest ==0xFF )) dev->prot_stall =0 ;/* call gadget with setup data received */ - setup_supported = dev->driver->setup (&dev->gadget, - &dev->setup_data); -spin_unlock (&dev->lock); + setup_supported =pch_udc_gadget_setup (dev);if (dev->setup_data.bRequestType &USB_DIR_IN ) { ep->td_data->status = (ep->td_data->status &
@@ -2634,9 +2646,7 @@ static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev) dev->ep[i].halted =0 ; } dev->stall =0 ; -spin_unlock (&dev->lock); - dev->driver->setup (&dev->gadget, &dev->setup_data); -spin_lock (&dev->lock); +pch_udc_gadget_setup (dev); }/**
@@ -2671,9 +2681,7 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) dev->stall =0 ;/* call gadget zero with setup data received */ -spin_unlock (&dev->lock); - dev->driver->setup (&dev->gadget, &dev->setup_data); -spin_lock (&dev->lock); +pch_udc_gadget_setup (dev); }/**
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 194/601 usb: gadget: pch_udc: Check for DMA mapping error
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 4a28d77e359009b846951b06f7c0d8eec8dce298 ]
DMA mapping might fail, we have to check it with dma_mapping_error(). Otherwise DMA-API is not happy:
DMA-API: pch_udc 0000:02:02.4: device driver failed to check map error[device address=0x00000000027ee678] [size=64 bytes] [mapped as single]
--- drivers/usb/gadget/udc/pch_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/pch_udc.c +1 -1
@@ -2955,7 +2955,7 @@ static int init_dma_pools(struct pch_udc_dev *dev) dev->dma_addr =dma_map_single (&dev->pdev->dev, ep0out_buf,UDC_EP0OUT_BUFF_SIZE *4 ,DMA_FROM_DEVICE ); -return 0 ; +return dma_mapping_error (&dev->pdev->dev, dev->dma_addr); } static int pch_udc_start(struct usb_gadget *g,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 195/601 usb: gadget: pch_udc: Initialize device pointer before use
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 971d080212be4ce2b91047d25a657f46d3e39635 ]
During conversion to use GPIO descriptors the device pointer, which is applied to devm_gpiod_get(), is not yet initialized.
Move initialization in the ->probe() in order to have it set before use.
--- drivers/usb/gadget/udc/pch_udc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/gadget/udc/pch_udc.c +3 -2
@@ -1369,6 +1369,7 @@ static irqreturn_t pch_vbus_gpio_irq(int irq, void *data)*/ static int pch_vbus_gpio_init (struct pch_udc_dev *dev) { +struct device *d = &dev->pdev->dev;int err;int irq_num =0 ;struct gpio_desc *gpiod;
@@ -1377,7 +1378,7 @@ static int pch_vbus_gpio_init(struct pch_udc_dev *dev) dev->vbus_gpio.intr =0 ;/* Retrieve the GPIO line from the USB gadget device */ - gpiod =devm_gpiod_get (dev->gadget.dev.parent,NULL ,GPIOD_IN ); + gpiod =devm_gpiod_get (d,NULL ,GPIOD_IN );if (IS_ERR (gpiod))return PTR_ERR (gpiod);gpiod_set_consumer_name (gpiod,"pch_vbus" );
@@ -3080,6 +3081,7 @@ static int pch_udc_probe(struct pci_dev *pdev,if (retval)return retval; + dev->pdev = pdev;pci_set_drvdata (pdev, dev);/* Determine BAR based on PCI ID */
@@ -3121,7 +3123,6 @@ static int pch_udc_probe(struct pci_dev *pdev,/* device struct setup */ spin_lock_init (&dev->lock); - dev->pdev = pdev; dev->gadget.ops = &pch_udc_ops; retval =init_dma_pools (dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 196/601 usb: gadget: pch_udc: Provide a GPIO line used on Intel Minnowboard (v1)
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 049d3db625a652e23488db88b6104de4d5b62f16 ]
Intel Minnowboard (v1) uses SCH GPIO line SUS7 (i.e. 12) for VBUS sense. Provide a DMI based quirk to have it's being used.
--- drivers/usb/gadget/udc/pch_udc.c | 71 +++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 14 deletions(-)
drivers/usb/gadget/udc/pch_udc.c +57 -14
@@ -7,12 +7,14 @@#include <linux/module.h> #include <linux/pci.h> #include <linux/delay.h> +#include <linux/dmi.h> #include <linux/errno.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/machine.h> #include <linux/list.h> #include <linux/interrupt.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> -#include <linux/gpio/consumer.h> #include <linux/irq.h> #define PCH_VBUS_PERIOD 3000/* VBUS polling period (msec) */
@@ -1359,6 +1361,43 @@ static irqreturn_t pch_vbus_gpio_irq(int irq, void *data)return IRQ_HANDLED ; } +static struct gpiod_lookup_table minnowboard_udc_gpios = { + .dev_id ="0000:02:02.4" , + .table = { +GPIO_LOOKUP ("sch_gpio.33158" ,12 ,NULL ,GPIO_ACTIVE_HIGH ), + {} + }, +}; + +static const struct dmi_system_id pch_udc_gpio_dmi_table[] = { + { + .ident ="MinnowBoard" , + .matches = { +DMI_MATCH (DMI_BOARD_NAME ,"MinnowBoard" ), + }, + .driver_data = &minnowboard_udc_gpios, + }, + { } +}; + +static void pch_vbus_gpio_remove_table (void *table) +{ +gpiod_remove_lookup_table (table); +} + +static int pch_vbus_gpio_add_table (struct pch_udc_dev *dev) +{ +struct device *d = &dev->pdev->dev; +const struct dmi_system_id *dmi; + + dmi =dmi_first_match (pch_udc_gpio_dmi_table); +if (!dmi) +return 0 ; + +gpiod_add_lookup_table (dmi->driver_data); +return devm_add_action_or_reset (d, pch_vbus_gpio_remove_table, dmi->driver_data); +} +/** * pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS. * @dev: Reference to the driver structure
@@ -1377,8 +1416,12 @@ static int pch_vbus_gpio_init(struct pch_udc_dev *dev) dev->vbus_gpio.port =NULL ; dev->vbus_gpio.intr =0 ; + err =pch_vbus_gpio_add_table (dev); +if (err) +return err; +/* Retrieve the GPIO line from the USB gadget device */ - gpiod =devm_gpiod_get (d,NULL ,GPIOD_IN ); + gpiod =devm_gpiod_get_optional (d,NULL ,GPIOD_IN );if (IS_ERR (gpiod))return PTR_ERR (gpiod);gpiod_set_consumer_name (gpiod,"pch_vbus" );
@@ -2888,14 +2931,20 @@ static void pch_udc_pcd_reinit(struct pch_udc_dev *dev)* @dev: Reference to the driver structure * * Return codes: -* 0: Success +* 0: Success +* -%ERRNO: All kind of errors when retrieving VBUS GPIO */ static int pch_udc_pcd_init (struct pch_udc_dev *dev) { +int ret; +pch_udc_init (dev);pch_udc_pcd_reinit (dev); -pch_vbus_gpio_init (dev); -return 0 ; + + ret =pch_vbus_gpio_init (dev); +if (ret) +pch_udc_exit (dev); +return ret; }/**
@@ -3097,16 +3146,10 @@ static int pch_udc_probe(struct pci_dev *pdev, dev->base_addr =pcim_iomap_table (pdev)[bar]; -/* -* FIXME: add a GPIO descriptor table to pdev.dev using -* gpiod_add_descriptor_table() from <linux/gpio/machine.h> based on -* the PCI subsystem ID. The system-dependent GPIO is necessary for -* VBUS operation. -*/ -/* initialize the hardware */ -if (pch_udc_pcd_init (dev)) -return -ENODEV ; + retval =pch_udc_pcd_init (dev); +if (retval) +return retval;pci_enable_msi (pdev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 197/601 crypto: ccp - fix command queuing to TEE ring buffer
In reply to Greg Kroah-HartmanFrom: Rijo Thomas <[email protected]>
[ Upstream commit 00aa6e65aa04e500a11a2c91e92a11c37b9e234d ]
Multiple threads or clients can submit a command to the TEE ring buffer. This patch helps to synchronize command submission to the ring.
One thread shall write a command to a TEE ring buffer entry only if:
- Trusted OS has notified that the TEE command for the given entry has been processed and driver has copied the TEE response into client buffer.
- The command entry is empty and can be written into.
After a command has been written to the TEE ring buffer, the global wptr (mutex protected) shall be incremented for use by next client.
If PSP became unresponsive while processing TEE request from a client, then further command submission to queue will be disabled.
--- drivers/crypto/ccp/tee-dev.c | 49 +++++++++++++++++++++++++----------- drivers/crypto/ccp/tee-dev.h | 20 +++++++++++++-- 2 files changed, 53 insertions(+), 16 deletions(-)
drivers/crypto/ccp/tee-dev.c +35 -14
@@ -36,6 +36,7 @@ static int tee_alloc_ring(struct psp_tee_device *tee, int ring_size)if (!start_addr)return -ENOMEM ; +memset (start_addr,0x0 , ring_size); rb_mgr->ring_start = start_addr; rb_mgr->ring_size = ring_size; rb_mgr->ring_pa =__psp_pa (start_addr);
@@ -244,41 +245,54 @@ static int tee_submit_cmd(struct psp_tee_device *tee, enum tee_cmd_id cmd_id, void *buf, size_t len, struct tee_ring_cmd **resp) { struct tee_ring_cmd *cmd; -u32 rptr, wptr;int nloop =1000 , ret =0 ; +u32 rptr; *resp =NULL ;mutex_lock (&tee->rb_mgr.mutex); - wptr = tee->rb_mgr.wptr; - -/* Check if ring buffer is full */ +/* Loop until empty entry found in ring buffer */ do { +/* Get pointer to ring buffer command entry */ + cmd = (struct tee_ring_cmd *) + (tee->rb_mgr.ring_start + tee->rb_mgr.wptr); + rptr =ioread32 (tee->io_regs + tee->vdata->ring_rptr_reg); -if (!(wptr +sizeof (struct tee_ring_cmd ) == rptr)) +/* Check if ring buffer is full or command entry is waiting +* for response from TEE +*/ +if (!(tee->rb_mgr.wptr +sizeof (struct tee_ring_cmd ) == rptr || + cmd->flag ==CMD_WAITING_FOR_RESPONSE ))break ; -dev_info (tee->dev,"tee: ring buffer full. rptr = %u wptr = %u\n" , - rptr, wptr); +dev_dbg (tee->dev,"tee: ring buffer full. rptr = %u wptr = %u\n" , + rptr, tee->rb_mgr.wptr); -/* Wait if ring buffer is full */ +/* Wait if ring buffer is full or TEE is processing data */ mutex_unlock (&tee->rb_mgr.mutex);schedule_timeout_interruptible (msecs_to_jiffies (10 ));mutex_lock (&tee->rb_mgr.mutex); }while (--nloop); -if (!nloop && (wptr +sizeof (struct tee_ring_cmd ) == rptr)) { -dev_err (tee->dev,"tee: ring buffer full. rptr = %u wptr = %u\n" , - rptr, wptr); +if (!nloop && + (tee->rb_mgr.wptr +sizeof (struct tee_ring_cmd ) == rptr || + cmd->flag ==CMD_WAITING_FOR_RESPONSE )) { +dev_err (tee->dev,"tee: ring buffer full. rptr = %u wptr = %u response flag %u\n" , + rptr, tee->rb_mgr.wptr, cmd->flag); ret = -EBUSY ; goto unlock; } -/* Pointer to empty data entry in ring buffer */ - cmd = (struct tee_ring_cmd *)(tee->rb_mgr.ring_start + wptr); +/* Do not submit command if PSP got disabled while processing any +* command in another thread +*/ +if (psp_dead) { + ret = -EBUSY ; + goto unlock; + }/* Write command data into ring buffer */ cmd->cmd_id = cmd_id;
@@ -286,6 +300,9 @@ static int tee_submit_cmd(struct psp_tee_device *tee, enum tee_cmd_id cmd_id,memset (&cmd->buf[0 ],0 ,sizeof (cmd->buf));memcpy (&cmd->buf[0 ], buf, len); +/* Indicate driver is waiting for response */ + cmd->flag =CMD_WAITING_FOR_RESPONSE ; +/* Update local copy of write pointer */ tee->rb_mgr.wptr +=sizeof (struct tee_ring_cmd );if (tee->rb_mgr.wptr >= tee->rb_mgr.ring_size)
@@ -353,12 +370,16 @@ int psp_tee_process_cmd(enum tee_cmd_id cmd_id, void *buf, size_t len,return ret; ret =tee_wait_cmd_completion (tee, resp,TEE_DEFAULT_TIMEOUT ); -if (ret) +if (ret) { + resp->flag =CMD_RESPONSE_TIMEDOUT ;return ret; + }memcpy (buf, &resp->buf[0 ], len); *status = resp->status; + resp->flag =CMD_RESPONSE_COPIED ; +return 0 ; }EXPORT_SYMBOL (psp_tee_process_cmd);
drivers/crypto/ccp/tee-dev.h +18 -2
@@ -1,6 +1,6 @@/* SPDX-License-Identifier: MIT */ /* -* Copyright 2019 Advanced Micro Devices, Inc. +* Copyright (C) 2019,2021 Advanced Micro Devices, Inc. * * Author: Rijo Thomas <[email protected]> * Author: Devaraj Rangasamy <[email protected]>
@@ -18,7 +18,7 @@#include <linux/mutex.h> #define TEE_DEFAULT_TIMEOUT 10 -#define MAX_BUFFER_SIZE 992 +#define MAX_BUFFER_SIZE 988/** * enum tee_ring_cmd_id - TEE interface commands for ring buffer configuration
@@ -81,6 +81,20 @@ enum tee_cmd_state { TEE_CMD_STATE_COMPLETED, }; +/** +* enum cmd_resp_state - TEE command's response status maintained by driver +* @CMD_RESPONSE_INVALID: initial state when no command is written to ring +* @CMD_WAITING_FOR_RESPONSE: driver waiting for response from TEE +* @CMD_RESPONSE_TIMEDOUT: failed to get response from TEE +* @CMD_RESPONSE_COPIED: driver has copied response from TEE +*/ +enum cmd_resp_state { +CMD_RESPONSE_INVALID , +CMD_WAITING_FOR_RESPONSE , +CMD_RESPONSE_TIMEDOUT , +CMD_RESPONSE_COPIED , +}; +/** * struct tee_ring_cmd - Structure of the command buffer in TEE ring * @cmd_id: refers to &enum tee_cmd_id. Command id for the ring buffer
@@ -91,6 +105,7 @@ enum tee_cmd_state {* @pdata: private data (currently unused) * @res1: reserved region * @buf: TEE command specific buffer +* @flag: refers to &enum cmd_resp_state */ struct tee_ring_cmd {u32 cmd_id;
@@ -100,6 +115,7 @@ struct tee_ring_cmd {u64 pdata;u32 res1[2 ];u8 buf[MAX_BUFFER_SIZE ]; +u32 flag;/* Total size: 1024 bytes */ } __packed;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 198/601 crypto: qat - dont release uninitialized resources
In reply to Greg Kroah-HartmanFrom: Tong Zhang <[email protected]>
[ Upstream commit b66accaab3791e15ac99c92f236d0d3a6d5bd64e ]
adf_vf_isr_resource_alloc() is not unwinding correctly when error happens and it want to release uninitialized resources. To fix this, only release initialized resources.
[ 1.792845] Trying to free already-free IRQ 11 [ 1.793091] WARNING: CPU: 0 PID: 182 at kernel/irq/manage.c:1821 free_irq+0x202/0x380 [ 1.801340] Call Trace: [ 1.801477] adf_vf_isr_resource_free+0x32/0xb0 [intel_qat] [ 1.801785] adf_vf_isr_resource_alloc+0x14d/0x150 [intel_qat] [ 1.802105] adf_dev_init+0xba/0x140 [intel_qat]
--- drivers/crypto/qat/qat_common/adf_vf_isr.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/crypto/qat/qat_common/adf_vf_isr.c +13 -4
@@ -261,17 +261,26 @@ int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev) goto err_out;if (adf_setup_pf2vf_bh (accel_dev)) - goto err_out; + goto err_disable_msi;if (adf_setup_bh (accel_dev)) - goto err_out; + goto err_cleanup_pf2vf_bh;if (adf_request_msi_irq (accel_dev)) - goto err_out; + goto err_cleanup_bh;return 0 ; + +err_cleanup_bh: +adf_cleanup_bh (accel_dev); + +err_cleanup_pf2vf_bh: +adf_cleanup_pf2vf_bh (accel_dev); + +err_disable_msi: +adf_disable_msi (accel_dev); + err_out: -adf_vf_isr_resource_free (accel_dev);return -EFAULT ; }EXPORT_SYMBOL_GPL (adf_vf_isr_resource_alloc);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 199/601 crypto: qat - ADF_STATUS_PF_RUNNING should be set after adf_dev_init
In reply to Greg Kroah-HartmanFrom: Tong Zhang <[email protected]>
[ Upstream commit 8609f5cfdc872fc3a462efa6a3eca5cb1e2f6446 ]
ADF_STATUS_PF_RUNNING is (only) used and checked by adf_vf2pf_shutdown() before calling adf_iov_putmsg()->mutex_lock(vf2pf_lock), however the vf2pf_lock is initialized in adf_dev_init(), which can fail and when it fail, the vf2pf_lock is either not initialized or destroyed, a subsequent use of vf2pf_lock will cause issue.
To fix this issue, only set this flag if adf_dev_init() returns 0.
[ 7.178404] BUG: KASAN: user-memory-access in __mutex_lock.isra.0+0x1ac/0x7c0 [ 7.180345] Call Trace: [ 7.182576] mutex_lock+0xc9/0xd0 [ 7.183257] adf_iov_putmsg+0x118/0x1a0 [intel_qat] [ 7.183541] adf_vf2pf_shutdown+0x4d/0x7b [intel_qat] [ 7.183834] adf_dev_shutdown+0x172/0x2b0 [intel_qat] [ 7.184127] adf_probe+0x5e9/0x600 [qat_dh895xccvf]
--- drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 4 ++-- drivers/crypto/qat/qat_c62xvf/adf_drv.c | 4 ++-- drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-)
drivers/crypto/qat/qat_c3xxxvf/adf_drv.c +2 -2
@@ -184,12 +184,12 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (ret) goto out_err_free_reg; -set_bit (ADF_STATUS_PF_RUNNING , &accel_dev->status); - ret =adf_dev_init (accel_dev);if (ret) goto out_err_dev_shutdown; +set_bit (ADF_STATUS_PF_RUNNING , &accel_dev->status); + ret =adf_dev_start (accel_dev);if (ret) goto out_err_dev_stop;
drivers/crypto/qat/qat_c62xvf/adf_drv.c +2 -2
@@ -184,12 +184,12 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (ret) goto out_err_free_reg; -set_bit (ADF_STATUS_PF_RUNNING , &accel_dev->status); - ret =adf_dev_init (accel_dev);if (ret) goto out_err_dev_shutdown; +set_bit (ADF_STATUS_PF_RUNNING , &accel_dev->status); + ret =adf_dev_start (accel_dev);if (ret) goto out_err_dev_stop;
drivers/crypto/qat/qat_dh895xccvf/adf_drv.c +2 -2
@@ -184,12 +184,12 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (ret) goto out_err_free_reg; -set_bit (ADF_STATUS_PF_RUNNING , &accel_dev->status); - ret =adf_dev_init (accel_dev);if (ret) goto out_err_dev_shutdown; +set_bit (ADF_STATUS_PF_RUNNING , &accel_dev->status); + ret =adf_dev_start (accel_dev);if (ret) goto out_err_dev_stop;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 200/601 fotg210-udc: Fix DMA on EP0 for length > max packet size
In reply to Greg Kroah-HartmanFrom: Fabian Vogt <[email protected]>
[ Upstream commit 755915fc28edfc608fa89a163014acb2f31c1e19 ]
For a 75 Byte request, it would send the first 64 separately, then detect that the remaining 11 Byte fit into a single DMA, but due to this bug set the length to the original 75 Bytes. This leads to a DMA failure (which is ignored...) and the request completes without the remaining bytes having been sent.
--- drivers/usb/gadget/udc/fotg210-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/fotg210-udc.c +1 -1
@@ -346,7 +346,7 @@ static void fotg210_start_dma(struct fotg210_ep *ep,if (req->req.length - req->req.actual > ep->ep.maxpacket) length = ep->ep.maxpacket;else - length = req->req.length; + length = req->req.length - req->req.actual; } d = dma_map_single(dev, buffer, length,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 201/601 fotg210-udc: Fix EP0 IN requests bigger than two packets
In reply to Greg Kroah-HartmanFrom: Fabian Vogt <[email protected]>
[ Upstream commit 078ba935651e149c92c41161e0322e3372cc2705 ]
For a 134 Byte packet, it sends the first two 64 Byte packets just fine, but then notice that less than a packet is remaining and call fotg210_done without actually sending the rest.
--- drivers/usb/gadget/udc/fotg210-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/fotg210-udc.c +1 -1
@@ -820,7 +820,7 @@ static void fotg210_ep0in(struct fotg210_udc *fotg210)if (req->req.length)fotg210_start_dma (ep, req); -if ((req->req.length - req->req.actual) < ep->ep.maxpacket) +if (req->req.actual == req->req.length)fotg210_done (ep, req,0 ); }else {fotg210_set_cxdone (fotg210);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 202/601 fotg210-udc: Remove a dubious condition leading to fotg210_done
In reply to Greg Kroah-HartmanFrom: Fabian Vogt <[email protected]>
[ Upstream commit c7f755b243494d6043aadcd9a2989cb157958b95 ]
When the EP0 IN request was not completed but less than a packet sent, it would complete the request successfully. That doesn't make sense and can't really happen as fotg210_start_dma always sends min(length, maxpkt) bytes.
--- drivers/usb/gadget/udc/fotg210-udc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/gadget/udc/fotg210-udc.c +1 -2
@@ -379,8 +379,7 @@ static void fotg210_ep0_queue(struct fotg210_ep *ep, }if (ep->dir_in) {/* if IN */ fotg210_start_dma (ep, req); -if ((req->req.length == req->req.actual) || - (req->req.actual < ep->ep.maxpacket)) +if (req->req.length == req->req.actual)fotg210_done (ep, req,0 ); }else {/* OUT */ u32 value =ioread32 (ep->fotg210->reg +FOTG210_DMISGR0 );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 203/601 fotg210-udc: Mask GRP2 interrupts we dont handle
In reply to Greg Kroah-HartmanFrom: Fabian Vogt <[email protected]>
[ Upstream commit 9aee3a23d6455200702f3a57e731fa11e8408667 ]
Currently it leaves unhandled interrupts unmasked, but those are never acked. In the case of a "device idle" interrupt, this leads to an effectively frozen system until plugging it in.
--- drivers/usb/gadget/udc/fotg210-udc.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/gadget/udc/fotg210-udc.c +6 -0
@@ -1026,6 +1026,12 @@ static void fotg210_init(struct fotg210_udc *fotg210) value &= ~DMCR_GLINT_EN ;iowrite32 (value, fotg210->reg +FOTG210_DMCR ); +/* enable only grp2 irqs we handle */ +iowrite32 (~(DISGR2_DMA_ERROR |DISGR2_RX0BYTE_INT |DISGR2_TX0BYTE_INT + |DISGR2_ISO_SEQ_ABORT_INT |DISGR2_ISO_SEQ_ERR_INT + |DISGR2_RESM_INT |DISGR2_SUSP_INT |DISGR2_USBRST_INT ), + fotg210->reg +FOTG210_DMISGR2 ); +/* disable all fifo interrupt */ iowrite32 (~(u32 )0 , fotg210->reg +FOTG210_DMISGR1 );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 204/601 fotg210-udc: Dont DMA more than the buffer can take
In reply to Greg Kroah-HartmanFrom: Fabian Vogt <[email protected]>
[ Upstream commit 3e7c2510bdfe89a9ec223dd7acd6bfc8bb1cbeb6 ]
Before this, it wrote as much as available into the buffer, even if it didn't fit.
--- drivers/usb/gadget/udc/fotg210-udc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/gadget/udc/fotg210-udc.c +3 -2
@@ -338,8 +338,9 @@ static void fotg210_start_dma(struct fotg210_ep *ep, }else { buffer = req->req.buf + req->req.actual; length =ioread32 (ep->fotg210->reg + -FOTG210_FIBCR (ep->epnum -1 )); - length &=FIBCR_BCFX ; +FOTG210_FIBCR (ep->epnum -1 )) &FIBCR_BCFX ; +if (length > req->req.length - req->req.actual) + length = req->req.length - req->req.actual; } }else { buffer = req->req.buf + req->req.actual;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 205/601 fotg210-udc: Complete OUT requests on short packets
In reply to Greg Kroah-HartmanFrom: Fabian Vogt <[email protected]>
[ Upstream commit 75bb93be0027123b5db6cbcce89eb62f0f6b3c5b ]
A short packet indicates the end of a transfer and marks the request as complete.
--- drivers/usb/gadget/udc/fotg210-udc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/usb/gadget/udc/fotg210-udc.c +6 -2
@@ -849,12 +849,16 @@ static void fotg210_out_fifo_handler(struct fotg210_ep *ep) {struct fotg210_request *req =list_entry (ep->queue.next, struct fotg210_request, queue); +int disgr1 =ioread32 (ep->fotg210->reg +FOTG210_DISGR1 );fotg210_start_dma (ep, req); -/* finish out transfer */ +/* Complete the request when it's full or a short packet arrived. +* Like other drivers, short_not_ok isn't handled. +*/ +if (req->req.length == req->req.actual || - req->req.actual < ep->ep.maxpacket) + (disgr1 &DISGR1_SPK_INT (ep->epnum -1 )))fotg210_done (ep, req,0 ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 206/601 usb: gadget: s3c: Fix incorrect resources releasing
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 42067ccd9eb2077979ac3ce8b7b95c694bd09e14 ]
Since commit 188db4435ac6 ("usb: gadget: s3c: use platform resources"), 'request_mem_region()' and 'ioremap()' are no more used, so they don't need to be undone in the error handling path of the probe and in the remove function.
Remove these calls and the unneeded 'rsrc_start' and 'rsrc_len' global variables.
--- drivers/usb/gadget/udc/s3c2410_udc.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
drivers/usb/gadget/udc/s3c2410_udc.c +3 -11
@@ -54,8 +54,6 @@ static struct clk *udc_clock;static struct clk *usb_bus_clock;static void __iomem *base_addr;static int irq_usbd; -static u64 rsrc_start; -static u64 rsrc_len;static struct dentry *s3c2410_udc_debugfs_root;static inline u32 udc_read (u32 reg)
@@ -1775,7 +1773,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) base_addr =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (base_addr)) { retval =PTR_ERR (base_addr); - goto err_mem; + goto err; } the_controller = udc;
@@ -1793,7 +1791,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev)if (retval !=0 ) {dev_err (dev,"cannot get irq %i, err %d\n" , irq_usbd, retval); retval = -EBUSY ; - goto err_map; + goto err; }dev_dbg (dev,"got irq %i\n" , irq_usbd);
@@ -1864,10 +1862,7 @@ err_gpio_claim:gpio_free (udc_info->vbus_pin); err_int:free_irq (irq_usbd, udc); -err_map: -iounmap (base_addr); -err_mem: -release_mem_region (rsrc_start, rsrc_len); +err:return retval; }
@@ -1899,9 +1894,6 @@ static int s3c2410_udc_remove(struct platform_device *pdev)free_irq (irq_usbd, udc); -iounmap (base_addr); -release_mem_region (rsrc_start, rsrc_len); -if (!IS_ERR (udc_clock) && udc_clock !=NULL ) {clk_disable_unprepare (udc_clock);clk_put (udc_clock);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 207/601 usb: gadget: s3c: Fix the error handling path in s3c2410_udc_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit e5242861ec6a0bce25b4cd10af0fc8a508fd067d ]
Some 'clk_prepare_enable()' and 'clk_get()' must be undone in the error handling path of the probe function, as already done in the remove function.
--- drivers/usb/gadget/udc/s3c2410_udc.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/usb/gadget/udc/s3c2410_udc.c +12 -4
@@ -1750,7 +1750,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev) udc_clock =clk_get (NULL ,"usb-device" );if (IS_ERR (udc_clock)) {dev_err (dev,"failed to get udc clock source\n" ); -return PTR_ERR (udc_clock); + retval =PTR_ERR (udc_clock); + goto err_usb_bus_clk; }clk_prepare_enable (udc_clock);
@@ -1773,7 +1774,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) base_addr =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (base_addr)) { retval =PTR_ERR (base_addr); - goto err; + goto err_udc_clk; } the_controller = udc;
@@ -1791,7 +1792,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev)if (retval !=0 ) {dev_err (dev,"cannot get irq %i, err %d\n" , irq_usbd, retval); retval = -EBUSY ; - goto err; + goto err_udc_clk; }dev_dbg (dev,"got irq %i\n" , irq_usbd);
@@ -1862,7 +1863,14 @@ err_gpio_claim:gpio_free (udc_info->vbus_pin); err_int:free_irq (irq_usbd, udc); -err: +err_udc_clk: +clk_disable_unprepare (udc_clock); +clk_put (udc_clock); + udc_clock =NULL ; +err_usb_bus_clk: +clk_disable_unprepare (usb_bus_clock); +clk_put (usb_bus_clock); + usb_bus_clock =NULL ;return retval; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 208/601 dt-bindings: serial: stm32: Use type: object instead of false for additionalProperties
In reply to Greg Kroah-HartmanFrom: dillon min <[email protected]>
[ Upstream commit 9f299d3264c67a892af87337dbaa0bdd20830c0c ]
To use additional properties 'bluetooth' on serial, need replace false with 'type: object' for 'additionalProperties' to make it as a node, else will run into dtbs_check warnings.
'arch/arm/boot/dts/stm32h750i-art-pi.dt.yaml: serial@40004800:
'bluetooth' does not match any of the regexes: 'pinctrl-[0-9]+'
--- Documentation/devicetree/bindings/serial/st,stm32-uart.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/serial/st,stm32-uart.yaml +2 -1
@@ -77,7 +77,8 @@ required: - interrupts - clocks -additionalProperties: false +additionalProperties: + type: object examples: - |
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 209/601 mtd: require write permissions for locking and badblock ioctls
In reply to Greg Kroah-HartmanFrom: Michael Walle <[email protected]>
[ Upstream commit 1e97743fd180981bef5f01402342bb54bf1c6366 ]
MEMLOCK, MEMUNLOCK and OTPLOCK modify protection bits. Thus require write permission. Depending on the hardware MEMLOCK might even be write-once, e.g. for SPI-NOR flashes with their WP# tied to GND. OTPLOCK is always write-once.
MEMSETBADBLOCK modifies the bad block table.
--- drivers/mtd/mtdchar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mtd/mtdchar.c +4 -4
@@ -651,16 +651,12 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)case MEMGETINFO :case MEMREADOOB :case MEMREADOOB64 : -case MEMLOCK : -case MEMUNLOCK :case MEMISLOCKED :case MEMGETOOBSEL :case MEMGETBADBLOCK : -case MEMSETBADBLOCK :case OTPSELECT :case OTPGETREGIONCOUNT :case OTPGETREGIONINFO : -case OTPLOCK :case ECCGETLAYOUT :case ECCGETSTATS :case MTDFILEMODE :
@@ -671,9 +667,13 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)/* "dangerous" commands */ case MEMERASE :case MEMERASE64 : +case MEMLOCK : +case MEMUNLOCK : +case MEMSETBADBLOCK :case MEMWRITEOOB :case MEMWRITEOOB64 :case MEMWRITE : +case OTPLOCK :if (!(file->f_mode &FMODE_WRITE ))return -EPERM ;break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 210/601 arm64: dts: renesas: r8a779a0: Fix PMU interrupt
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit bbbf6db5a0b56199702bb225132831bced2eee41 ]
Should use PPI No.7 for the PMU. Otherwise, the perf command didn't show any information.
--- arch/arm64/boot/dts/renesas/r8a779a0.dtsi | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
arch/arm64/boot/dts/renesas/r8a779a0.dtsi +1 -4
@@ -50,10 +50,7 @@ pmu_a76 { compatible = "arm,cortex-a76-pmu"; - interrupts-extended = <&gic GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; }; /* External SCIF clock - to be overridden by boards that provide it */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 211/601 arm64: dts: mt8183: Add gce client reg for display subcomponents
In reply to Greg Kroah-HartmanFrom: Hsin-Yi Wang <[email protected]>
[ Upstream commit b7a8f50a1437164607f73831075c06120aa1f3b3 ]
Add mediatek,gce-client-reg for mmsys, ccorr, aal, gamma, dither.
--- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm64/boot/dts/mediatek/mt8183.dtsi +7 -0
@@ -969,6 +969,9 @@ compatible = "mediatek,mt8183-mmsys", "syscon"; reg = <0 0x14000000 0 0x1000>; #clock-cells = <1>; + mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>, + <&gce 1 CMDQ_THR_PRIO_HIGHEST>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>; }; ovl0: ovl@14008000 {
@@ -1044,6 +1047,7 @@ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>; power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; clocks = <&mmsys CLK_MM_DISP_CCORR0>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>; }; aal0: aal@14010000 {
@@ -1053,6 +1057,7 @@ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_LOW>; power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; clocks = <&mmsys CLK_MM_DISP_AAL0>; + mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0 0x1000>; }; gamma0: gamma@14011000 {
@@ -1061,6 +1066,7 @@ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_LOW>; power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; clocks = <&mmsys CLK_MM_DISP_GAMMA0>; + mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>; }; dither0: dither@14012000 {
@@ -1069,6 +1075,7 @@ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>; power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; clocks = <&mmsys CLK_MM_DISP_DITHER0>; + mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>; }; dsi0: dsi@14014000 {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 212/601 arm64: dts: mt8173: fix wrong power-domain phandle of pmic
In reply to Greg Kroah-HartmanFrom: Chunfeng Yun <[email protected]>
[ Upstream commit 4db2b9af3ee92e6c51c6a9a5dc2748e4bc1800f9 ]
Due to power domain controller is added, the power domain's phanle is also changed from 'scpsys' to 'spm', but forget to modify pmic node's
--- arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/mediatek/mt8173-evb.dts +1 -1
@@ -294,7 +294,7 @@ &pwrap { /* Only MT8173 E1 needs USB power domain */ - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + power-domains = <&spm MT8173_POWER_DOMAIN_USB>; pmic: mt6397 { compatible = "mediatek,mt6397";
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 213/601 bus: qcom: Put child node before return
In reply to Greg Kroah-HartmanFrom: Pan Bian <[email protected]>
[ Upstream commit ac6ad7c2a862d682bb584a4bc904d89fa7721af8 ]
Put child node before return to fix potential reference count leak. Generally, the reference count of child is incremented and decremented automatically in the macro for_each_available_child_of_node() and should be decremented manually if the loop is broken in loop body.
--- drivers/bus/qcom-ebi2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/bus/qcom-ebi2.c +3 -1
@@ -353,8 +353,10 @@ static int qcom_ebi2_probe(struct platform_device *pdev)/* Figure out the chipselect */ ret =of_property_read_u32 (child,"reg" , &csindex); -if (ret) +if (ret) { +of_node_put (child);return ret; + }if (csindex >5 ) { dev_err(dev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 214/601 soundwire: bus: Fix device found flag correctly
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit f03690f4f6992225d05dbd1171212e5be5a370dd ]
found flag is used to indicate SoundWire devices that are both enumerated on the bus and available in the device list. However this flag is not reset correctly after one iteration, This could miss some of the devices that are enumerated on the bus but not in device list. So reset this correctly to fix this issue!
--- drivers/soundwire/bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/soundwire/bus.c +2 -1
@@ -703,7 +703,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)struct sdw_slave *slave, *_s;struct sdw_slave_id id;struct sdw_msg msg; -bool found = false; +bool found;int count =0 , ret;u64 addr;
@@ -735,6 +735,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)sdw_extract_slave_id (bus, addr, &id); + found = false;/* Now compare with entries */ list_for_each_entry_safe (slave, _s, &bus->slaves, node) {if (sdw_compare_devid (slave, id) ==0 ) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 215/601 phy: ti: j721e-wiz: Delete "clk_div_sel" clk provider during cleanup
In reply to Greg Kroah-HartmanFrom: Kishon Vijay Abraham I <[email protected]>
[ Upstream commit 7e52a39f1942b771213678c56002ce90a2f126d2 ]
commit 091876cc355d ("phy: ti: j721e-wiz: Add support for WIZ module present in TI J721E SoC") modeled both MUX clocks and DIVIDER clocks in wiz. However during cleanup, it removed only the MUX clock provider. Remove the DIVIDER clock provider here.
--- drivers/phy/ti/phy-j721e-wiz.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/phy/ti/phy-j721e-wiz.c +6 -0
@@ -615,6 +615,12 @@ static void wiz_clock_cleanup(struct wiz *wiz, struct device_node *node)of_clk_del_provider (clk_node);of_node_put (clk_node); } + +for (i =0 ; i < wiz->clk_div_sel_num; i++) { + clk_node =of_get_child_by_name (node, clk_div_sel[i].node_name); +of_clk_del_provider (clk_node); +of_node_put (clk_node); + } }static int wiz_clock_init (struct wiz *wiz,struct device_node *node)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 216/601 phy: ralink: phy-mt7621-pci: fix XTAL bitmask
In reply to Greg Kroah-HartmanFrom: Sergio Paracuellos <[email protected]>
[ Upstream commit 982313c38f2f3793b6435ff50997ae96a2274f5a ]
When this was rewriten to get mainlined and start to use 'linux/bitfield.h' headers, XTAL_MASK was wrong. It must mask three bits but only two were used. Hence properly fix it to make things work.
--- drivers/phy/ralink/phy-mt7621-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/ralink/phy-mt7621-pci.c +1 -1
@@ -62,7 +62,7 @@#define RG_PE1_FRC_MSTCKDIV BIT(5) -#define XTAL_MASK GENMASK(7, 6) +#define XTAL_MASK GENMASK(8, 6)#define MAX_PHYS 2
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 217/601 phy: marvell: ARMADA375_USBCLUSTER_PHY should not default to y, unconditionally
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 6cb17707aad869de163d7bf42c253caf501be4e2 ]
Merely enabling CONFIG_COMPILE_TEST should not enable additional code. To fix this, restrict the automatic enabling of ARMADA375_USBCLUSTER_PHY to MACH_ARMADA_375, and ask the user in case of compile-testing.
--- drivers/phy/marvell/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/marvell/Kconfig +2 -2
@@ -3,8 +3,8 @@ # Phy drivers for Marvell platforms # config ARMADA375_USBCLUSTER_PHY - def_bool y - depends on MACH_ARMADA_375 || COMPILE_TEST + bool "Armada 375 USB cluster PHY support" if COMPILE_TEST + default y if MACH_ARMADA_375 depends on OF && HAS_IOMEM select GENERIC_PHY
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 218/601 phy: ralink: phy-mt7621-pci: fix return value check in mt7621_pci_phy_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit b976c987511e34a2e9b23545de912a121a9eded5 ]
Fix the return value check which testing the wrong variable in mt7621_pci_phy_probe().
--- drivers/phy/ralink/phy-mt7621-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/ralink/phy-mt7621-pci.c +2 -2
@@ -319,9 +319,9 @@ static int mt7621_pci_phy_probe(struct platform_device *pdev)return PTR_ERR (phy->regmap); phy->phy =devm_phy_create (dev, dev->of_node, &mt7621_pci_phy_ops); -if (IS_ERR (phy)) { +if (IS_ERR (phy->phy)) {dev_err (dev,"failed to create phy\n" ); -return PTR_ERR (phy); +return PTR_ERR (phy->phy); }phy_set_drvdata (phy->phy, phy);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 219/601 phy: ingenic: Fix a typo in ingenic_usb_phy_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit 446c200ee3e8f6faf189ef6f25a0f5bb294afae4 ]
Fix the return value check typo which testing the wrong variable in ingenic_usb_phy_probe().
--- drivers/phy/ingenic/phy-ingenic-usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/ingenic/phy-ingenic-usb.c +2 -2
@@ -375,8 +375,8 @@ static int ingenic_usb_phy_probe(struct platform_device *pdev) } priv->phy =devm_phy_create (dev,NULL , &ingenic_usb_phy_ops); -if (IS_ERR (priv)) -return PTR_ERR (priv); +if (IS_ERR (priv->phy)) +return PTR_ERR (priv->phy);phy_set_drvdata (priv->phy, priv);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 220/601 arm64: dts: mediatek: fix reset GPIO level on pumpkin
In reply to Greg Kroah-HartmanFrom: Fabien Parent <[email protected]>
[ Upstream commit a7dceafed43a4a610d340da3703653cca2c50c1d ]
The tca6416 chip is active low. Fix the reset-gpios value.
--- arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +1 -1
@@ -56,7 +56,7 @@ tca6416: gpio@20 { compatible = "ti,tca6416"; reg = <0x20>; - reset-gpios = <&pio 65 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 65 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&tca6416_pins>;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 221/601 NFSv4.2: fix copy stateid copying for the async copy
In reply to Greg Kroah-HartmanFrom: Olga Kornievskaia <[email protected]>
[ Upstream commit e739b12042b6b079a397a3c234f96c09d1de0b40 ]
This patch fixes Dan Carpenter's report that the static checker found a problem where memcpy() was copying into too small of a buffer.
--- fs/nfsd/nfs4proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfsd/nfs4proc.c +2 -2
@@ -1540,8 +1540,8 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (!nfs4_init_copy_state (nn, copy)) goto out_err;refcount_set (&async_copy->refcount,1 ); -memcpy (©->cp_res.cb_stateid, ©->cp_stateid, -sizeof (copy->cp_stateid)); +memcpy (©->cp_res.cb_stateid, ©->cp_stateid.stid, +sizeof (copy->cp_res.cb_stateid));dup_copy_fields (copy, async_copy); async_copy->copy_task =kthread_create (nfsd4_do_async_copy, async_copy,"%s" ,"copy thread" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 222/601 crypto: poly1305 - fix poly1305_core_setkey() declaration
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 8d195e7a8ada68928f2aedb2c18302a4518fe68e ]
gcc-11 points out a mismatch between the declaration and the definition of poly1305_core_setkey():
lib/crypto/poly1305-donna32.c:13:67: error: argument 2 of type ‘const u8[16]’ {aka ‘const unsigned char[16]’} with mismatched bound [-Werror=array-parameter=]
13 | void poly1305_core_setkey(struct poly1305_core_key *key, const u8 raw_key[16])
| ~~~~~~~~~^~~~~~~~~~~
In file included from lib/crypto/poly1305-donna32.c:11:include/crypto/internal/poly1305.h:21:68: note: previously declared as ‘const u8 *’ {aka ‘const unsigned char *’}
21 | void poly1305_core_setkey(struct poly1305_core_key *key, const u8 *raw_key);
This is harmless in principle, as the calling conventions are the same, but the more specific prototype allows better type checking in the caller.
Change the declaration to match the actual function definition. The poly1305_simd_init() is a bit suspicious here, as it previously had a 32-byte argument type, but looks like it needs to take the 16-byte POLY1305_BLOCK_SIZE array instead.
--- arch/arm/crypto/poly1305-glue.c | 2 +- arch/arm64/crypto/poly1305-glue.c | 2 +- arch/mips/crypto/poly1305-glue.c | 2 +- arch/x86/crypto/poly1305_glue.c | 6 +++--- include/crypto/internal/poly1305.h | 3 ++- include/crypto/poly1305.h | 6 ++++-- lib/crypto/poly1305-donna32.c | 3 ++- lib/crypto/poly1305-donna64.c | 3 ++- lib/crypto/poly1305.c | 3 ++- 9 files changed, 18 insertions(+), 12 deletions(-)
arch/arm/crypto/poly1305-glue.c +1 -1
@@ -29,7 +29,7 @@ void __weak poly1305_blocks_neon(void *state, const u8 *src, u32 len, u32 hibit)static __ro_after_init DEFINE_STATIC_KEY_FALSE (have_neon); -void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 *key) +void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 key[POLY1305_KEY_SIZE ]) {poly1305_init_arm (&dctx->h, key); dctx->s[0 ] =get_unaligned_le32 (key +16 );
arch/arm64/crypto/poly1305-glue.c +1 -1
@@ -25,7 +25,7 @@ asmlinkage void poly1305_emit(void *state, u8 *digest, const u32 *nonce);static __ro_after_init DEFINE_STATIC_KEY_FALSE (have_neon); -void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 *key) +void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 key[POLY1305_KEY_SIZE ]) {poly1305_init_arm64 (&dctx->h, key); dctx->s[0 ] =get_unaligned_le32 (key +16 );
arch/mips/crypto/poly1305-glue.c +1 -1
@@ -17,7 +17,7 @@ asmlinkage void poly1305_init_mips(void *state, const u8 *key); asmlinkage void poly1305_blocks_mips(void *state, const u8 *src, u32 len, u32 hibit); asmlinkage void poly1305_emit_mips(void *state, u8 *digest, const u32 *nonce); -void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 *key) +void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 key[POLY1305_KEY_SIZE ]) {poly1305_init_mips (&dctx->h, key); dctx->s[0 ] =get_unaligned_le32 (key +16 );
arch/x86/crypto/poly1305_glue.c +3 -3
@@ -16,7 +16,7 @@#include <asm/simd.h> asmlinkage void poly1305_init_x86_64(void *ctx, -const u8 key[POLY1305_KEY_SIZE ]); +const u8 key[POLY1305_BLOCK_SIZE ]); asmlinkage void poly1305_blocks_x86_64(void *ctx, const u8 *inp,const size_t len,const u32 padbit); asmlinkage void poly1305_emit_x86_64(void *ctx, u8 mac[POLY1305_DIGEST_SIZE],
@@ -81,7 +81,7 @@ static void convert_to_base2_64(void *ctx) state->is_base2_26 =0 ; } -static void poly1305_simd_init (void *ctx,const u8 key[POLY1305_KEY_SIZE ]) +static void poly1305_simd_init (void *ctx,const u8 key[POLY1305_BLOCK_SIZE ]) {poly1305_init_x86_64 (ctx, key); }
@@ -129,7 +129,7 @@ static void poly1305_simd_emit(void *ctx, u8 mac[POLY1305_DIGEST_SIZE],poly1305_emit_avx (ctx, mac, nonce); } -void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 *key) +void poly1305_init_arch (struct poly1305_desc_ctx *dctx,const u8 key[POLY1305_KEY_SIZE ]) {poly1305_simd_init (&dctx->h, key); dctx->s[0 ] =get_unaligned_le32 (&key[16 ]);
include/crypto/internal/poly1305.h +2 -1
@@ -18,7 +18,8 @@* only the ε-almost-∆-universal hash function (not the full MAC) is computed. */ -void poly1305_core_setkey (struct poly1305_core_key *key,const u8 *raw_key); +void poly1305_core_setkey (struct poly1305_core_key *key, +const u8 raw_key[POLY1305_BLOCK_SIZE ]);static inline void poly1305_core_init (struct poly1305_state *state) { *state = (struct poly1305_state ){};
include/crypto/poly1305.h +4 -2
@@ -58,8 +58,10 @@ struct poly1305_desc_ctx { }; }; -void poly1305_init_arch (struct poly1305_desc_ctx *desc,const u8 *key); -void poly1305_init_generic (struct poly1305_desc_ctx *desc,const u8 *key); +void poly1305_init_arch (struct poly1305_desc_ctx *desc, +const u8 key[POLY1305_KEY_SIZE ]); +void poly1305_init_generic (struct poly1305_desc_ctx *desc, +const u8 key[POLY1305_KEY_SIZE ]);static inline void poly1305_init (struct poly1305_desc_ctx *desc,const u8 *key) {
lib/crypto/poly1305-donna32.c +2 -1
@@ -10,7 +10,8 @@#include <asm/unaligned.h> #include <crypto/internal/poly1305.h> -void poly1305_core_setkey (struct poly1305_core_key *key,const u8 raw_key[16 ]) +void poly1305_core_setkey (struct poly1305_core_key *key, +const u8 raw_key[POLY1305_BLOCK_SIZE ]) {/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ key->key.r[0 ] = (get_unaligned_le32 (&raw_key[0 ])) &0x3ffffff ;
lib/crypto/poly1305-donna64.c +2 -1
@@ -12,7 +12,8 @@typedef __uint128_t u128 ; -void poly1305_core_setkey (struct poly1305_core_key *key,const u8 raw_key[16 ]) +void poly1305_core_setkey (struct poly1305_core_key *key, +const u8 raw_key[POLY1305_BLOCK_SIZE ]) {u64 t0, t1;
lib/crypto/poly1305.c +2 -1
@@ -12,7 +12,8 @@#include <linux/module.h> #include <asm/unaligned.h> -void poly1305_init_generic (struct poly1305_desc_ctx *desc,const u8 *key) +void poly1305_init_generic (struct poly1305_desc_ctx *desc, +const u8 key[POLY1305_KEY_SIZE ]) {poly1305_core_setkey (&desc->core_r, key); desc->s[0 ] =get_unaligned_le32 (key +16 );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 223/601 crypto: qat - fix error path in adf_isr_resource_alloc()
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 83dc1173d73f80cbce2fee4d308f51f87b2f26ae ]
The function adf_isr_resource_alloc() is not unwinding correctly in case of error.
This patch fixes the error paths and propagate the errors to the caller.
--- drivers/crypto/qat/qat_common/adf_isr.c | 29 ++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/crypto/qat/qat_common/adf_isr.c +21 -8
@@ -291,19 +291,32 @@ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev) ret =adf_isr_alloc_msix_entry_table (accel_dev);if (ret) -return ret; -if (adf_enable_msix (accel_dev)) goto err_out; -if (adf_setup_bh (accel_dev)) - goto err_out; + ret =adf_enable_msix (accel_dev); +if (ret) + goto err_free_msix_table; -if (adf_request_irqs (accel_dev)) - goto err_out; + ret =adf_setup_bh (accel_dev); +if (ret) + goto err_disable_msix; + + ret =adf_request_irqs (accel_dev); +if (ret) + goto err_cleanup_bh;return 0 ; + +err_cleanup_bh: +adf_cleanup_bh (accel_dev); + +err_disable_msix: +adf_disable_msix (&accel_dev->accel_pci_dev); + +err_free_msix_table: +adf_isr_free_msix_entry_table (accel_dev); + err_out: -adf_isr_resource_free (accel_dev); -return -EFAULT ; +return ret; }EXPORT_SYMBOL_GPL (adf_isr_resource_alloc);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 224/601 usb: gadget: aspeed: fix dma map failure
In reply to Greg Kroah-HartmanFrom: Tao Ren <[email protected]>
[ Upstream commit bd4d607044b961cecbf8c4c2f3bb5da4fb156993 ]
Currently the virtual port_dev device is passed to DMA API, and this is wrong because the device passed to DMA API calls must be the actual hardware device performing the DMA.
The patch replaces usb_gadget_map_request/usb_gadget_unmap_request APIs with usb_gadget_map_request_by_dev/usb_gadget_unmap_request_by_dev APIs so the DMA capable platform device can be passed to the DMA APIs.
The patch fixes below backtrace detected on Facebook AST2500 OpenBMC platforms:
[<80106550>] show_stack+0x20/0x24 [<80106868>] dump_stack+0x28/0x30 [<80823540>] __warn+0xfc/0x110 [<8011ac30>] warn_slowpath_fmt+0xb0/0xc0 [<8011ad44>] dma_map_page_attrs+0x24c/0x314 [<8016a27c>] usb_gadget_map_request_by_dev+0x100/0x1e4 [<805cedd8>] usb_gadget_map_request+0x1c/0x20 [<805cefbc>] ast_vhub_epn_queue+0xa0/0x1d8 [<7f02f710>] usb_ep_queue+0x48/0xc4 [<805cd3e8>] ecm_do_notify+0xf8/0x248 [<7f145920>] ecm_set_alt+0xc8/0x1d0 [<7f145c34>] composite_setup+0x680/0x1d30 [<7f00deb8>] ast_vhub_ep0_handle_setup+0xa4/0x1bc [<7f02ee94>] ast_vhub_dev_irq+0x58/0x84 [<7f0309e0>] ast_vhub_irq+0xb0/0x1c8 [<7f02e118>] __handle_irq_event_percpu+0x50/0x19c [<8015e5bc>] handle_irq_event_percpu+0x38/0x8c [<8015e758>] handle_irq_event+0x38/0x4c
--- drivers/usb/gadget/udc/aspeed-vhub/core.c | 3 ++- drivers/usb/gadget/udc/aspeed-vhub/epn.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/usb/gadget/udc/aspeed-vhub/core.c +2 -1
@@ -36,6 +36,7 @@ void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req, int status) {bool internal = req->internal; +struct ast_vhub *vhub = ep->vhub;EPVDBG (ep,"completing request @%p, status %d\n" , req, status);
@@ -46,7 +47,7 @@ void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req,if (req->req.dma) {if (!WARN_ON (!ep->dev)) -usb_gadget_unmap_request (&ep->dev->gadget, +usb_gadget_unmap_request_by_dev (&vhub->pdev->dev, &req->req, ep->epn.is_in); req->req.dma =0 ; }
drivers/usb/gadget/udc/aspeed-vhub/epn.c +1 -1
@@ -376,7 +376,7 @@ static int ast_vhub_epn_queue(struct usb_ep* u_ep, struct usb_request *u_req,if (ep->epn.desc_mode || ((((unsigned long )u_req->buf &7 ) ==0 ) && (ep->epn.is_in || !(u_req->length & (u_ep->maxpacket -1 ))))) { - rc =usb_gadget_map_request (&ep->dev->gadget, u_req, + rc =usb_gadget_map_request_by_dev (&vhub->pdev->dev, u_req, ep->epn.is_in);if (rc) { dev_warn(&vhub->pdev->dev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 225/601 USB: gadget: udc: fix wrong pointer passed to IS_ERR() and PTR_ERR()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 2e3d055bf27d70204cae349335a62a4f9b7c165a ]
IS_ERR() and PTR_ERR() use wrong pointer, it should be udc->virt_addr, fix it.
--- drivers/usb/gadget/udc/snps_udc_plat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/gadget/udc/snps_udc_plat.c +2 -2
@@ -114,8 +114,8 @@ static int udc_plat_probe(struct platform_device *pdev) res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); udc->virt_addr =devm_ioremap_resource (dev, res); -if (IS_ERR (udc->regs)) -return PTR_ERR (udc->regs); +if (IS_ERR (udc->virt_addr)) +return PTR_ERR (udc->virt_addr);/* udc csr registers base */ udc->csr = udc->virt_addr +UDC_CSR_ADDR ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 226/601 drivers: nvmem: Fix voltage settings for QTI qfprom-efuse
In reply to Greg Kroah-HartmanFrom: Ravi Kumar Bokka <[email protected]>
[ Upstream commit 9ec4f4b0e9fd3ad4b9a38bddb75b516ea09f4628 ]
QFPROM controller hardware requires 1.8V min for fuse blowing. So, this change sets the voltage to 1.8V, required to blow the fuse for qfprom-efuse controller.
To disable fuse blowing, we set the voltage to 0V since this may be a shared rail and may be able to run at a lower rate when we're not blowing fuses.
--- drivers/nvmem/qfprom.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
drivers/nvmem/qfprom.c +21 -0
@@ -127,6 +127,16 @@ static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv, {int ret; +/* +* This may be a shared rail and may be able to run at a lower rate +* when we're not blowing fuses. At the moment, the regulator framework +* applies voltage constraints even on disabled rails, so remove our +* constraints and allow the rail to be adjusted by other users. +*/ + ret =regulator_set_voltage (priv->vcc,0 ,INT_MAX ); +if (ret) +dev_warn (priv->dev,"Failed to set 0 voltage (ignoring)\n" ); + ret =regulator_disable (priv->vcc);if (ret)dev_warn (priv->dev,"Failed to disable regulator (ignoring)\n" );
@@ -172,6 +182,17 @@ static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv, goto err_clk_prepared; } +/* +* Hardware requires 1.8V min for fuse blowing; this may be +* a rail shared do don't specify a max--regulator constraints +* will handle. +*/ + ret =regulator_set_voltage (priv->vcc,1800000 ,INT_MAX ); +if (ret) { +dev_err (priv->dev,"Failed to set 1.8 voltage\n" ); + goto err_clk_rate_set; + } + ret =regulator_enable (priv->vcc);if (ret) {dev_err (priv->dev,"Failed to enable regulator\n" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 227/601 driver core: platform: Declare early_platform_cleanup() prototype
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 1768289b44bae847612751d418fc5c5e680b5e5c ]
Compiler is not happy:
CC drivers/base/platform.odrivers/base/platform.c:1557:20: warning: no previous prototype for ‘early_platform_cleanup’ [-Wmissing-prototypes]
1557 | void __weak __init early_platform_cleanup(void) { }
| ^~~~~~~~~~~~~~~~~~~~~~
Declare early_platform_cleanup() prototype in the header to make everyone happy.
--- include/linux/platform_device.h | 3 +++ 1 file changed, 3 insertions(+)
include/linux/platform_device.h +3 -0
@@ -359,4 +359,7 @@ static inline int is_sh_early_platform_device(struct platform_device *pdev) }#endif /* CONFIG_SUPERH */ +/* For now only SuperH uses it */ +void early_platform_cleanup (void ); +#endif /* _PLATFORM_DEVICE_H_ */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 228/601 ARM: dts: qcom: msm8974-lge-nexus5: correct fuel gauge interrupt trigger level
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 9d816b423dab5b59beec5e39b97428feac599ba7 ]
The Maxim fuel gauge datasheets describe the interrupt line as active low with a requirement of acknowledge from the CPU. The falling edge interrupt will mostly work but it's not correct.
--- arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts +1 -1
@@ -575,7 +575,7 @@ maxim,rcomp = /bits/ 8 <0x4d>; interrupt-parent = <&msmgpio>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&fuelgauge_pin>;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 229/601 ARM: dts: qcom: msm8974-samsung-klte: correct fuel gauge interrupt trigger level
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 5fde3361ba57a9b4eb560dabf859176909d61004 ]
The Maxim fuel gauge datasheets describe the interrupt line as active low with a requirement of acknowledge from the CPU. The falling edge interrupt will mostly work but it's not correct.
--- arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts +1 -1
@@ -691,7 +691,7 @@ maxim,rcomp = /bits/ 8 <0x56>; interrupt-parent = <&pma8084_gpios>; - interrupts = <21 IRQ_TYPE_EDGE_FALLING>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&fuelgauge_pin>;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 230/601 memory: pl353: fix mask of ECC page_size config register
In reply to Greg Kroah-HartmanFrom: gexueyuan <[email protected]>
[ Upstream commit 25dcca7fedcd4e31cb368ad846bfd738c0c6307c ]
The mask for page size of ECC Configuration Register should be 0x3, according to the datasheet of PL353 smc.
--- drivers/memory/pl353-smc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/memory/pl353-smc.c +1 -1
@@ -63,7 +63,7 @@/* ECC memory config register specific constants */ #define PL353_SMC_ECC_MEMCFG_MODE_MASK 0xC#define PL353_SMC_ECC_MEMCFG_MODE_SHIFT 2 -#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK 0xC +#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK 0x3#define PL353_SMC_DC_UPT_NAND_REGS ((4 << 23) |/* CS: NAND chip */ \ (2 << 21)) /* UpdateRegs operation */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 231/601 soundwire: stream: fix memory leak in stream config error path
In reply to Greg Kroah-HartmanFrom: Rander Wang <[email protected]>
[ Upstream commit 48f17f96a81763c7c8bf5500460a359b9939359f ]
When stream config is failed, master runtime will release all slave runtime in the slave_rt_list, but slave runtime is not added to the list at this time. This patch frees slave runtime in the config error path to fix the memory leak.
--- drivers/soundwire/stream.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/soundwire/stream.c +9 -1
@@ -1375,8 +1375,16 @@ int sdw_stream_add_slave(struct sdw_slave *slave, } ret =sdw_config_stream (&slave->dev, stream, stream_config, true); -if (ret) +if (ret) { +/* +* sdw_release_master_stream will release s_rt in slave_rt_list in +* stream_error case, but s_rt is only added to slave_rt_list +* when sdw_config_stream is successful, so free s_rt explicitly +* when sdw_config_stream is failed. +*/ +kfree (s_rt); goto stream_error; + }list_add_tail (&s_rt->m_rt_node, &m_rt->slave_rt_list);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 232/601 m68k: mvme147,mvme16x: Dont wipe PCC timer config bits
In reply to Greg Kroah-HartmanFrom: Finn Thain <[email protected]>
[ Upstream commit 43262178c043032e7c42d00de44c818ba05f9967 ]
Don't clear the timer 1 configuration bits when clearing the interrupt flag and counter overflow. As Michael reported, "This results in no timer interrupts being delivered after the first. Initialization then hangs in calibrate_delay as the jiffies counter is not updated."
On mvme16x, enable the timer after requesting the irq, consistent with mvme147.
--- arch/m68k/include/asm/mvme147hw.h | 3 +++ arch/m68k/mvme147/config.c | 14 ++++++++------ arch/m68k/mvme16x/config.c | 14 ++++++++------ 3 files changed, 19 insertions(+), 12 deletions(-)
arch/m68k/include/asm/mvme147hw.h +3 -0
@@ -66,6 +66,9 @@ struct pcc_regs {#define PCC_INT_ENAB 0x08#define PCC_TIMER_INT_CLR 0x80 + +#define PCC_TIMER_TIC_EN 0x01 +#define PCC_TIMER_COC_EN 0x02#define PCC_TIMER_CLR_OVF 0x04#define PCC_LEVEL_ABORT 0x07
arch/m68k/mvme147/config.c +8 -6
@@ -114,8 +114,10 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id)unsigned long flags;local_irq_save (flags); - m147_pcc->t1_int_cntrl =PCC_TIMER_INT_CLR ; - m147_pcc->t1_cntrl =PCC_TIMER_CLR_OVF ; + m147_pcc->t1_cntrl =PCC_TIMER_CLR_OVF |PCC_TIMER_COC_EN | +PCC_TIMER_TIC_EN ; + m147_pcc->t1_int_cntrl =PCC_INT_ENAB |PCC_TIMER_INT_CLR | +PCC_LEVEL_TIMER1 ; clk_total +=PCC_TIMER_CYCLES ;legacy_timer_tick (1 );local_irq_restore (flags);
@@ -133,10 +135,10 @@ void mvme147_sched_init (void)/* Init the clock with a value */ /* The clock counter increments until 0xFFFF then reloads */ m147_pcc->t1_preload =PCC_TIMER_PRELOAD ; - m147_pcc->t1_cntrl =0x0 ;/* clear timer */ - m147_pcc->t1_cntrl =0x3 ;/* start timer */ - m147_pcc->t1_int_cntrl =PCC_TIMER_INT_CLR ;/* clear pending ints */ - m147_pcc->t1_int_cntrl =PCC_INT_ENAB |PCC_LEVEL_TIMER1 ; + m147_pcc->t1_cntrl =PCC_TIMER_CLR_OVF |PCC_TIMER_COC_EN | +PCC_TIMER_TIC_EN ; + m147_pcc->t1_int_cntrl =PCC_INT_ENAB |PCC_TIMER_INT_CLR | +PCC_LEVEL_TIMER1 ;clocksource_register_hz (&mvme147_clk,PCC_TIMER_CLOCK_FREQ ); }
arch/m68k/mvme16x/config.c +8 -6
@@ -366,6 +366,7 @@ static u32 clk_total;#define PCCTOVR1_COC_EN 0x02#define PCCTOVR1_OVR_CLR 0x04 +#define PCCTIC1_INT_LEVEL 6#define PCCTIC1_INT_CLR 0x08#define PCCTIC1_INT_EN 0x10
@@ -374,8 +375,8 @@ static irqreturn_t mvme16x_timer_int (int irq, void *dev_id)unsigned long flags;local_irq_save (flags); -out_8 (PCCTIC1 ,in_8 (PCCTIC1 ) |PCCTIC1_INT_CLR ); -out_8 (PCCTOVR1 ,PCCTOVR1_OVR_CLR ); +out_8 (PCCTOVR1 ,PCCTOVR1_OVR_CLR |PCCTOVR1_TIC_EN |PCCTOVR1_COC_EN ); +out_8 (PCCTIC1 ,PCCTIC1_INT_EN |PCCTIC1_INT_CLR |PCCTIC1_INT_LEVEL ); clk_total +=PCC_TIMER_CYCLES ;legacy_timer_tick (1 );local_irq_restore (flags);
@@ -389,14 +390,15 @@ void mvme16x_sched_init(void)int irq;/* Using PCCchip2 or MC2 chip tick timer 1 */ -out_be32 (PCCTCNT1 ,0 ); -out_be32 (PCCTCMP1 ,PCC_TIMER_CYCLES ); -out_8 (PCCTOVR1 ,in_8 (PCCTOVR1 ) |PCCTOVR1_TIC_EN |PCCTOVR1_COC_EN ); -out_8 (PCCTIC1 ,PCCTIC1_INT_EN |6 );if (request_irq (MVME16x_IRQ_TIMER, mvme16x_timer_int,IRQF_TIMER ,"timer" ,NULL ))panic ("Couldn't register timer int" ); +out_be32 (PCCTCNT1 ,0 ); +out_be32 (PCCTCMP1 ,PCC_TIMER_CYCLES ); +out_8 (PCCTOVR1 ,PCCTOVR1_OVR_CLR |PCCTOVR1_TIC_EN |PCCTOVR1_COC_EN ); +out_8 (PCCTIC1 ,PCCTIC1_INT_EN |PCCTIC1_INT_CLR |PCCTIC1_INT_LEVEL ); +clocksource_register_hz (&mvme16x_clk,PCC_TIMER_CLOCK_FREQ );if (brdno ==0x0162 || brdno ==0x172 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 233/601 firmware: qcom_scm: Make __qcom_scm_is_call_available() return bool
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit 9d11af8b06a811c5c4878625f51ce109e2af4e80 ]
Make __qcom_scm_is_call_available() return bool instead of int. The function has "is" in the name, so it should return a bool to indicate the truth of the call being available. Unfortunately, it can return a number < 0 which also looks "true", but not all callers expect that and thus they think a call is available when really the check to see if the call is available failed to figure it out.
--- drivers/firmware/qcom_scm.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/firmware/qcom_scm.c +8 -11
@@ -113,9 +113,6 @@ static void qcom_scm_clk_disable(void)clk_disable_unprepare (__scm->bus_clk); } -static int __qcom_scm_is_call_available (struct device *dev,u32 svc_id, -u32 cmd_id); -enum qcom_scm_convention qcom_scm_convention;static bool has_queried__read_mostly ;static DEFINE_SPINLOCK (query_lock);
@@ -219,8 +216,8 @@ static int qcom_scm_call_atomic(struct device *dev, } } -static int __qcom_scm_is_call_available (struct device *dev,u32 svc_id, -u32 cmd_id) +static bool __qcom_scm_is_call_available (struct device *dev,u32 svc_id, +u32 cmd_id) {int ret;struct qcom_scm_desc desc = {
@@ -247,7 +244,7 @@ static int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, ret =qcom_scm_call (dev, &desc, &res); -return ret ? : res.result[0 ]; +return ret ? false : !!res.result[0 ]; }/**
@@ -585,9 +582,8 @@ bool qcom_scm_pas_supported(u32 peripheral) };struct qcom_scm_res res; - ret =__qcom_scm_is_call_available (__scm->dev,QCOM_SCM_SVC_PIL , -QCOM_SCM_PIL_PAS_IS_SUPPORTED ); -if (ret <=0 ) +if (!__qcom_scm_is_call_available (__scm->dev,QCOM_SCM_SVC_PIL , +QCOM_SCM_PIL_PAS_IS_SUPPORTED ))return false; ret =qcom_scm_call (__scm->dev, &desc, &res);
@@ -1054,17 +1050,18 @@ EXPORT_SYMBOL(qcom_scm_ice_set_key);*/ bool qcom_scm_hdcp_available (void ) { +bool avail;int ret =qcom_scm_clk_enable ();if (ret)return ret; - ret =__qcom_scm_is_call_available (__scm->dev,QCOM_SCM_SVC_HDCP , + avail =__qcom_scm_is_call_available (__scm->dev,QCOM_SCM_SVC_HDCP ,QCOM_SCM_HDCP_INVOKE );qcom_scm_clk_disable (); -return ret >0 ; +return avail; }EXPORT_SYMBOL (qcom_scm_hdcp_available);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 234/601 firmware: qcom_scm: Reduce locking section for __get_convention()
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit f6ea568f0ddcdfad52807110ed8983e610f0e03b ]
We shouldn't need to hold this spinlock here around the entire SCM call into the firmware and back. Instead, we should be able to query the firmware, potentially in parallel with other CPUs making the same convention detection firmware call, and then grab the lock to update the calling convention detected. The convention doesn't change at runtime so calling into firmware more than once is possibly wasteful but simpler. Besides, this is the slow path, not the fast path where we've already detected the convention used.
More importantly, this allows us to add more logic here to workaround the case where the firmware call to check for availability isn't implemented in the firmware at all. In that case we can check the firmware node compatible string and force a calling convention.
Note that we remove the 'has_queried' logic that is repeated twice. That could lead to the calling convention being printed multiple times to the kernel logs if the bool is true but __query_convention() is running on multiple CPUs. We also shorten the time where the lock is held, but we keep the lock held around the printk because it doesn't seem hugely important to drop it for that.
--- drivers/firmware/qcom_scm-smc.c | 12 ++++--- drivers/firmware/qcom_scm.c | 55 ++++++++++++++++----------------- drivers/firmware/qcom_scm.h | 7 +++-- 3 files changed, 39 insertions(+), 35 deletions(-)
drivers/firmware/qcom_scm-smc.c +7 -5
@@ -77,8 +77,10 @@ static void __scm_smc_do(const struct arm_smccc_args *smc, }while (res->a0 ==QCOM_SCM_V2_EBUSY ); } -int scm_smc_call (struct device *dev,const struct qcom_scm_desc *desc, -struct qcom_scm_res *res,bool atomic) + +int __scm_smc_call (struct device *dev,const struct qcom_scm_desc *desc, +enum qcom_scm_convention qcom_convention, +struct qcom_scm_res *res,bool atomic) {int arglen = desc->arginfo &0xf ;int i;
@@ -87,9 +89,8 @@ int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,size_t alloc_len;gfp_t flag = atomic ?GFP_ATOMIC :GFP_KERNEL ;u32 smccc_call_type = atomic ?ARM_SMCCC_FAST_CALL :ARM_SMCCC_STD_CALL ; -u32 qcom_smccc_convention = - (qcom_scm_convention ==SMC_CONVENTION_ARM_32 ) ? -ARM_SMCCC_SMC_32 :ARM_SMCCC_SMC_64 ; +u32 qcom_smccc_convention = (qcom_convention ==SMC_CONVENTION_ARM_32 ) ? +ARM_SMCCC_SMC_32 :ARM_SMCCC_SMC_64 ;struct arm_smccc_res smc_res;struct arm_smccc_args smc = {0 };
@@ -148,4 +149,5 @@ int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, }return (long )smc_res.a0 ?qcom_scm_remap_error (smc_res.a0) :0 ; + }
drivers/firmware/qcom_scm.c +27 -28
81 lines not on this page · raw message
drivers/firmware/qcom_scm.h +5 -2
@@ -61,8 +61,11 @@ struct qcom_scm_res { };#define SCM_SMC_FNID (s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) -extern int scm_smc_call (struct device *dev,const struct qcom_scm_desc *desc, -struct qcom_scm_res *res,bool atomic); +extern int __scm_smc_call (struct device *dev,const struct qcom_scm_desc *desc, +enum qcom_scm_convention qcom_convention, +struct qcom_scm_res *res,bool atomic); +#define scm_smc_call (dev, desc, res, atomic) \ + __scm_smc_call((dev), (desc), qcom_scm_convention, (res), (atomic))#define SCM_LEGACY_FNID (s, c) (((s) << 10) | ((c) & 0x3ff)) extern int scm_legacy_call_atomic(struct device *dev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 235/601 firmware: qcom_scm: Workaround lack of "is available" call on SC7180
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit 257f2935cbbf14b16912c635fcd8ff43345c953b ]
Some SC7180 firmwares don't implement the QCOM_SCM_INFO_IS_CALL_AVAIL API, so we can't probe the calling convention. We detect the legacy calling convention on these firmwares, because the availability call always fails and legacy is the fallback. This leads to problems where the rmtfs driver fails to probe, because it tries to assign memory with a bad calling convention, which then leads to modem failing to load and all networking, even wifi, to fail. Ouch!
Let's force the calling convention to be what it always is on this SoC, i.e. arm64. Of course, the calling convention is not the same thing as implementing the QCOM_SCM_INFO_IS_CALL_AVAIL API. The absence of the "is this call available" API from the firmware means that any call to __qcom_scm_is_call_available() fails. This is OK for now though because none of the calls that are checked for existence are implemented on firmware running on sc7180. If such a call needs to be checked for existence in the future, we presume that firmware will implement this API and then things will "just work".
--- drivers/firmware/qcom_scm.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/firmware/qcom_scm.c +16 -2
@@ -131,6 +131,7 @@ static enum qcom_scm_convention __get_convention(void)struct qcom_scm_res res;enum qcom_scm_convention probed_convention;int ret; +bool forced = false;if (likely (qcom_scm_convention !=SMC_CONVENTION_UNKNOWN ))return qcom_scm_convention;
@@ -144,6 +145,18 @@ static enum qcom_scm_convention __get_convention(void)if (!ret && res.result[0 ] ==1 ) goto found; +/* +* Some SC7180 firmwares didn't implement the +* QCOM_SCM_INFO_IS_CALL_AVAIL call, so we fallback to forcing ARM_64 +* calling conventions on these firmwares. Luckily we don't make any +* early calls into the firmware on these SoCs so the device pointer +* will be valid here to check if the compatible matches. +*/ +if (of_device_is_compatible (__scm ? __scm->dev->of_node :NULL ,"qcom,scm-sc7180" )) { + forced = true; + goto found; + } + probed_convention =SMC_CONVENTION_ARM_32 ; ret =__scm_smc_call (NULL , &desc, probed_convention, &res, true);if (!ret && res.result[0 ] ==1 )
@@ -154,8 +167,9 @@ found:spin_lock_irqsave (&scm_query_lock, flags);if (probed_convention != qcom_scm_convention) { qcom_scm_convention = probed_convention; -pr_info ("qcom_scm: convention: %s\n" , - qcom_scm_convention_names[qcom_scm_convention]); +pr_info ("qcom_scm: convention: %s%s\n" , + qcom_scm_convention_names[qcom_scm_convention], + forced ?" (forced)" :"" ); }spin_unlock_irqrestore (&scm_query_lock, flags);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 236/601 iio: adc: Kconfig: make AD9467 depend on ADI_AXI_ADC symbol
In reply to Greg Kroah-HartmanFrom: Alexandru Ardelean <[email protected]>
[ Upstream commit 194eafc9c1d49b53b59de9821fb63d423344cae3 ]
Because a dependency on HAS_IOMEM and OF was added for the ADI AXI ADC driver, this makes the AD9467 driver have some build/dependency issues when OF is disabled (typically on ACPI archs like x86).
This is because the selection of the AD9467 enforces the ADI_AXI_ADC symbol which is blocked by the OF (and potentially HAS_IOMEM) being disabled.
To fix this, we make the AD9467 driver depend on the ADI_AXI_ADC symbol. The AD9467 driver cannot operate on it's own. It requires the ADI AXI ADC driver to stream data (or some similar IIO interface).
So, the fix here is to make the AD9467 symbol depend on the ADI_AXI_ADC symbol. At some point this could become it's own subgroup of high-speed ADCs.
--- drivers/iio/adc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/Kconfig +1 -1
@@ -249,7 +249,7 @@ config AD799X config AD9467 tristate "Analog Devices AD9467 High Speed ADC driver" depends on SPI - select ADI_AXI_ADC + depends on ADI_AXI_ADC help Say yes here to build support for Analog Devices: * AD9467 16-Bit, 200 MSPS/250 MSPS Analog-to-Digital Converter
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 237/601 mtd: rawnand: gpmi: Fix a double free in gpmi_nand_init
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit 076de75de1e53160e9b099f75872c1f9adf41a0b ]
If the callee gpmi_alloc_dma_buffer() failed to alloc memory for this->raw_buffer, gpmi_free_dma_buffer() will be called to free this->auxiliary_virt. But this->auxiliary_virt is still a non-NULL and valid ptr.
Then gpmi_alloc_dma_buffer() returns err and gpmi_free_dma_buffer() is called again to free this->auxiliary_virt in err_out. This causes a double free.
As gpmi_free_dma_buffer() has already called in gpmi_alloc_dma_buffer's error path, so it should return err directly instead of releasing the dma buffer again.
--- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +1 -1
@@ -2449,7 +2449,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) this->bch_geometry.auxiliary_size =128 ; ret =gpmi_alloc_dma_buffer (this);if (ret) - goto err_out; +return ret;nand_controller_init (&this->base); this->base.ops = &gpmi_nand_controller_ops;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 238/601 irqchip/gic-v3: Fix OF_BAD_ADDR error handling
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 8e13d96670a4c050d4883e6743a9e9858e5cfe10 ]
When building with extra warnings enabled, clang points out a mistake in the error handling:
drivers/irqchip/irq-gic-v3-mbi.c:306:21: error: result of comparison of constant 18446744073709551615 with expression of type 'phys_addr_t' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare]
if (mbi_phys_base == OF_BAD_ADDR) {Truncate the constant to the same type as the variable it gets compared to, to shut make the check work and void the warning.
--- drivers/irqchip/irq-gic-v3-mbi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-gic-v3-mbi.c +1 -1
@@ -303,7 +303,7 @@ int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent) reg =of_get_property (np,"mbi-alias" ,NULL );if (reg) { mbi_phys_base =of_translate_address (np, reg); -if (mbi_phys_base ==OF_BAD_ADDR ) { +if (mbi_phys_base == (phys_addr_t )OF_BAD_ADDR ) { ret = -ENXIO ; goto err_free_mbi; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 239/601 staging: comedi: tests: ni_routes_test: Fix compilation error
In reply to Greg Kroah-HartmanFrom: Ian Abbott <[email protected]>
[ Upstream commit 6db58ed2b2d9bb1792eace4f9aa70e8bdd730ffc ]
The ni_routes_test module is not currently selectable using the Kconfig files, but can be built by specifying CONFIG_COMEDI_TESTS=m on the "make" command line. It currently fails to compile due to an extra parameter added to the ni_assign_device_routes function by commit e3b7ce73c578 ("staging: comedi: ni_routes: Allow alternate board name for routes"). Fix it by supplying the value NULL for the added alt_board_name parameter (which specifies that there is no alternate board name).
--- drivers/staging/comedi/drivers/tests/ni_routes_test.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/staging/comedi/drivers/tests/ni_routes_test.c +4 -2
@@ -217,7 +217,8 @@ void test_ni_assign_device_routes(void)const u8 *table, *oldtable;init_pci_6070e (); -ni_assign_device_routes (ni_eseries, pci_6070e, &private.routing_tables); +ni_assign_device_routes (ni_eseries, pci_6070e,NULL , + &private.routing_tables); devroutes = private.routing_tables.valid_routes; table = private.routing_tables.route_values;
@@ -253,7 +254,8 @@ void test_ni_assign_device_routes(void) olddevroutes = devroutes; oldtable = table;init_pci_6220 (); -ni_assign_device_routes (ni_mseries, pci_6220, &private.routing_tables); +ni_assign_device_routes (ni_mseries, pci_6220,NULL , + &private.routing_tables); devroutes = private.routing_tables.valid_routes; table = private.routing_tables.route_values;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 240/601 staging: rtl8192u: Fix potential infinite loop
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit f9b9263a25dc3d2eaaa829e207434db6951ca7bc ]
The for-loop iterates with a u8 loop counter i and compares this with the loop upper limit of riv->ieee80211->LinkDetectInfo.SlotNum that is a u16 type. There is a potential infinite loop if SlotNum is larger than the u8 loop counter. Fix this by making the loop counter the same type as SlotNum.
Addresses-Coverity: ("Infinite loop")
--- drivers/staging/rtl8192u/r8192U_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8192u/r8192U_core.c +1 -1
@@ -3208,7 +3208,7 @@ static void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, u32 *TotalRxDataNum) {u16 SlotIndex; -u8 i; +u16 i; *TotalRxBcnNum =0 ; *TotalRxDataNum =0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 241/601 staging: fwserial: fix TIOCSSERIAL implementation
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit a7eaaa9d1032e68669bb479496087ba8fc155ab6 ]
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
A non-privileged user has only ever been able to set the since long deprecated ASYNC_SPD flags and trying to change any other *supported* feature should result in -EPERM being returned. Setting the current values for any supported features should return success.
Fix the fwserial implementation which was returning -EPERM also for a privileged user when trying to change certain unsupported parameters, and instead return success consistently.
--- drivers/staging/fwserial/fwserial.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/staging/fwserial/fwserial.c +0 -4
@@ -1234,10 +1234,6 @@ static int set_serial_info(struct tty_struct *tty,struct fwtty_port *port = tty->driver_data;unsigned int cdelay; -if (ss->irq !=0 || ss->port !=0 || ss->custom_divisor !=0 || - ss->baud_base !=400000000 ) -return -EPERM ; - cdelay =msecs_to_jiffies (ss->close_delay *10 );mutex_lock (&port->port.mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 242/601 staging: fwserial: fix TIOCGSERIAL implementation
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 5e84a66f3682af4f177bb24bb2ad5135c51f764a ]
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
The xmit_fifo_size parameter could be used to set the hardware transmit fifo size of a legacy UART when it could not be detected, but the interface is limited to eight bits and should be left unset when not used.
Fix the fwserial implementation by dropping its custom interpretation of the unused xmit_fifo_size field, which was overflowed with the driver FIFO size. Also leave the type and flags fields unset as these cannot be changed.
The close_delay and closing_wait parameters returned by TIOCGSERIAL are specified in centiseconds. The driver does not yet support changing closing_wait, but let's report back the default value actually used (30 seconds).
--- drivers/staging/fwserial/fwserial.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/staging/fwserial/fwserial.c +3 -4
@@ -1218,13 +1218,12 @@ static int get_serial_info(struct tty_struct *tty,struct fwtty_port *port = tty->driver_data;mutex_lock (&port->port.mutex); - ss->type =PORT_UNKNOWN ; - ss->line = port->port.tty->index; - ss->flags = port->port.flags; - ss->xmit_fifo_size =FWTTY_PORT_TXFIFO_LEN ; + ss->line = port->index; ss->baud_base =400000000 ; ss->close_delay =jiffies_to_msecs (port->port.close_delay) /10 ; + ss->closing_wait =3000 ;mutex_unlock (&port->port.mutex); +return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 243/601 staging: greybus: uart: fix unprivileged TIOCCSERIAL
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 60c6b305c11b5fd167ce5e2ce42f3a9098c388f0 ]
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
A non-privileged user has only ever been able to set the since long deprecated ASYNC_SPD flags and trying to change any other *supported* feature should result in -EPERM being returned. Setting the current values for any supported features should return success.
Fix the greybus implementation which instead indicated that the TIOCSSERIAL ioctl was not even implemented when a non-privileged user set the current values.
--- drivers/staging/greybus/uart.c | 2 -- 1 file changed, 2 deletions(-)
drivers/staging/greybus/uart.c +0 -2
@@ -641,8 +641,6 @@ static int set_serial_info(struct tty_struct *tty,if ((close_delay != gb_tty->port.close_delay) || (closing_wait != gb_tty->port.closing_wait)) retval = -EPERM ; -else - retval = -EOPNOTSUPP ; }else { gb_tty->port.close_delay = close_delay; gb_tty->port.closing_wait = closing_wait;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 244/601 platform/x86: dell-wmi-sysman: Make init_bios_attributes() ACPI object parsing more robust
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 5e3f5973c8dfd2b80268f1825ed2f2ddf81d3267 ]
Make init_bios_attributes() ACPI object parsing more robust:
1. Always check that the type of the return ACPI object is package, rather then only checking this for instance_id == 0
2. Check that the package has the minimum amount of elements which will be consumed by the populate_foo_data() for the attr_type
Note/TODO: The populate_foo_data() functions should also be made more robust. The should check the type of each of the elements matches the type which they expect and in case of populate_enum_data() obj->package.count should be passed to it as an argument and it should re-check this itself since it consume a variable number of elements.
--- drivers/platform/x86/dell-wmi-sysman/sysman.c | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-)
drivers/platform/x86/dell-wmi-sysman/sysman.c +28 -4
@@ -399,6 +399,7 @@ static int init_bios_attributes(int attr_type, const char *guid)union acpi_object *obj =NULL ;union acpi_object *elements;struct kset *tmp_set; +int min_elements;/* instance_id needs to be reset for each type GUID * also, instance IDs are unique within GUID but not across
@@ -409,14 +410,38 @@ static int init_bios_attributes(int attr_type, const char *guid) retval =alloc_attributes_data (attr_type);if (retval)return retval; + +switch (attr_type) { +case ENUM : min_elements =8 ;break ; +case INT : min_elements =9 ;break ; +case STR : min_elements =8 ;break ; +case PO : min_elements =4 ;break ; +default : +pr_err ("Error: Unknown attr_type: %d\n" , attr_type); +return -EINVAL ; + } +/* need to use specific instance_id and guid combination to get right data */ obj =get_wmiobj_pointer (instance_id, guid); -if (!obj || obj->type !=ACPI_TYPE_PACKAGE ) +if (!obj)return -ENODEV ; - elements = obj->package.elements;mutex_lock (&wmi_priv.mutex); -while (elements) { +while (obj) { +if (obj->type !=ACPI_TYPE_PACKAGE ) { +pr_err ("Error: Expected ACPI-package type, got: %d\n" , obj->type); + retval = -EIO ; + goto err_attr_init; + } + +if (obj->package.count < min_elements) { +pr_err ("Error: ACPI-package does not have enough elements: %d < %d\n" , + obj->package.count, min_elements); + goto nextobj; + } + + elements = obj->package.elements; +/* sanity checking */ if (elements[ATTR_NAME ].type !=ACPI_TYPE_STRING ) {pr_debug ("incorrect element type\n" );
@@ -481,7 +506,6 @@ nextobj:kfree (obj); instance_id++; obj =get_wmiobj_pointer (instance_id, guid); - elements = obj ? obj->package.elements :NULL ; }mutex_unlock (&wmi_priv.mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 245/601 soc: qcom: pdr: Fix error return code in pdr_register_listener
In reply to Greg Kroah-HartmanFrom: Qinglang Miao <[email protected]>
[ Upstream commit 769738fc49bb578e05d404b481a9241d18147d86 ]
Fix to return the error code -EREMOTEIO from pdr_register_listener rather than 0.
--- drivers/soc/qcom/pdr_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soc/qcom/pdr_interface.c +1 -1
@@ -153,7 +153,7 @@ static int pdr_register_listener(struct pdr_handle *pdr,if (resp.resp.result !=QMI_RESULT_SUCCESS_V01 ) {pr_err ("PDR: %s register listener failed: 0x%x\n" , pds->service_path, resp.resp.error); -return ret; +return -EREMOTEIO ; } pds->state = resp.curr_state;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 246/601 PM / devfreq: Use more accurate returned new_freq as resume_freq
In reply to Greg Kroah-HartmanFrom: Dong Aisheng <[email protected]>
[ Upstream commit 62453f1ba5d5def9d58e140a50f3f168f028da38 ]
Use the more accurate returned new_freq as resume_freq. It's the same as how devfreq->previous_freq was updated.
--- drivers/devfreq/devfreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/devfreq/devfreq.c +1 -1
@@ -387,7 +387,7 @@ static int devfreq_set_target(struct devfreq *devfreq, unsigned long new_freq, devfreq->previous_freq = new_freq;if (devfreq->suspend_freq) - devfreq->resume_freq = cur_freq; + devfreq->resume_freq = new_freq;return err; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 247/601 clocksource/drivers/timer-ti-dm: Fix posted mode status check order
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
[ Upstream commit 212709926c5493a566ca4086ad4f4b0d4e66b553 ]
When the timer is configured in posted mode, we need to check the write- posted status register (TWPS) before writing to the register.
We now check TWPS after the write starting with commit 52762fbd1c47 ("clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support").
For example, in the TRM for am571x the following is documented in chapter "22.2.4.13.1.1 Write Posting Synchronization Mode":
"For each register, a status bit is provided in the timer write-posted
status (TWPS) register. In this mode, it is mandatory that software check this status bit before any write access. If a write is attempted to a register with a previous access pending, the previous access is discarded without notice."
The regression happened when I updated the code to use standard read/write accessors for the driver instead of using __omap_dm_timer_load_start(). We have__omap_dm_timer_load_start() check the TWPS status correctly using __omap_dm_timer_write().
--- drivers/clocksource/timer-ti-dm-systimer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/clocksource/timer-ti-dm-systimer.c +6 -6
@@ -449,13 +449,13 @@ static int dmtimer_set_next_event(unsigned long cycles,struct dmtimer_systimer *t = &clkevt->t;void __iomem *pend = t->base + t->pend; -writel_relaxed (0xffffffff - cycles, t->base + t->counter);while (readl_relaxed (pend) &WP_TCRR )cpu_relax (); +writel_relaxed (0xffffffff - cycles, t->base + t->counter); -writel_relaxed (OMAP_TIMER_CTRL_ST , t->base + t->ctrl);while (readl_relaxed (pend) &WP_TCLR )cpu_relax (); +writel_relaxed (OMAP_TIMER_CTRL_ST , t->base + t->ctrl);return 0 ; }
@@ -490,18 +490,18 @@ static int dmtimer_set_periodic(struct clock_event_device *evt)dmtimer_clockevent_shutdown (evt);/* Looks like we need to first set the load value separately */ -writel_relaxed (clkevt->period, t->base + t->load);while (readl_relaxed (pend) &WP_TLDR )cpu_relax (); +writel_relaxed (clkevt->period, t->base + t->load); -writel_relaxed (clkevt->period, t->base + t->counter);while (readl_relaxed (pend) &WP_TCRR )cpu_relax (); +writel_relaxed (clkevt->period, t->base + t->counter); -writel_relaxed (OMAP_TIMER_CTRL_AR |OMAP_TIMER_CTRL_ST , - t->base + t->ctrl);while (readl_relaxed (pend) &WP_TCLR )cpu_relax (); +writel_relaxed (OMAP_TIMER_CTRL_AR |OMAP_TIMER_CTRL_ST , + t->base + t->ctrl);return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 248/601 clocksource/drivers/timer-ti-dm: Add missing set_state_oneshot_stopped
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
[ Upstream commit ac4daf737674b4d29e19b7c300caff3bcf7160d8 ]
To avoid spurious timer interrupts when KTIME_MAX is used, we need to configure set_state_oneshot_stopped(). Although implementing this is optional, it still affects things like power management for the extra timer interrupt.
For more information, please see commit 8fff52fd5093 ("clockevents:
Introduce CLOCK_EVT_STATE_ONESHOT_STOPPED state") and commit cf8c5009ee37 ("clockevents/drivers/arm_arch_timer: Implement ->set_state_oneshot_stopped()").
--- drivers/clocksource/timer-ti-dm-systimer.c | 1 + 1 file changed, 1 insertion(+)
drivers/clocksource/timer-ti-dm-systimer.c +1 -0
@@ -554,6 +554,7 @@ static int __init dmtimer_clockevent_init(struct device_node *np) dev->set_state_shutdown = dmtimer_clockevent_shutdown; dev->set_state_periodic = dmtimer_set_periodic; dev->set_state_oneshot = dmtimer_clockevent_shutdown; + dev->set_state_oneshot_stopped = dmtimer_clockevent_shutdown; dev->tick_resume = dmtimer_clockevent_shutdown; dev->cpumask = cpu_possible_mask;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 249/601 clocksource/drivers/ingenic_ost: Fix return value check in ingenic_ost_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit 2a65f7e2772613debd03fa2492e76a635aa04545 ]
In case of error, the function device_node_to_regmap() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().
--- drivers/clocksource/ingenic-ost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clocksource/ingenic-ost.c +2 -2
@@ -88,9 +88,9 @@ static int __init ingenic_ost_probe(struct platform_device *pdev)return PTR_ERR (ost->regs); map =device_node_to_regmap (dev->parent->of_node); -if (!map) { +if (IS_ERR (map)) {dev_err (dev,"regmap not found" ); -return -EINVAL ; +return PTR_ERR (map); } ost->clk =devm_clk_get (dev,"ost" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 250/601 spi: Fix use-after-free with devm_spi_alloc_*
In reply to Greg Kroah-HartmanFrom: William A. Kennington III <[email protected]>
[ Upstream commit 794aaf01444d4e765e2b067cba01cc69c1c68ed9 ]
We can't rely on the contents of the devres list during spi_unregister_controller(), as the list is already torn down at the time we perform devres_find() for devm_spi_release_controller. This causes devices registered with devm_spi_alloc_{master,slave}() to be mistakenly identified as legacy, non-devm managed devices and have their reference counters decremented below 0.
------------[ cut here ]------------ WARNING: CPU: 1 PID: 660 at lib/refcount.c:28 refcount_warn_saturate+0x108/0x174 [<b0396f04>] (refcount_warn_saturate) from [<b03c56a4>] (kobject_put+0x90/0x98) [<b03c5614>] (kobject_put) from [<b0447b4c>] (put_device+0x20/0x24) r4:b6700140 [<b0447b2c>] (put_device) from [<b07515e8>] (devm_spi_release_controller+0x3c/0x40) [<b07515ac>] (devm_spi_release_controller) from [<b045343c>] (release_nodes+0x84/0xc4) r5:b6700180 r4:b6700100 [<b04533b8>] (release_nodes) from [<b0454160>] (devres_release_all+0x5c/0x60) r8:b1638c54 r7:b117ad94 r6:b1638c10 r5:b117ad94 r4:b163dc10 [<b0454104>] (devres_release_all) from [<b044e41c>] (__device_release_driver+0x144/0x1ec) r5:b117ad94 r4:b163dc10 [<b044e2d8>] (__device_release_driver) from [<b044f70c>] (device_driver_detach+0x84/0xa0) r9:00000000 r8:00000000 r7:b117ad94 r6:b163dc54 r5:b1638c10 r4:b163dc10 [<b044f688>] (device_driver_detach) from [<b044d274>] (unbind_store+0xe4/0xf8)
Instead, determine the devm allocation state as a flag on the controller which is guaranteed to be stable during cleanup.
--- drivers/spi/spi.c | 9 ++------- include/linux/spi/spi.h | 3 +++ 2 files changed, 5 insertions(+), 7 deletions(-)
drivers/spi/spi.c +2 -7
@@ -2488,6 +2488,7 @@ struct spi_controller *__devm_spi_alloc_controller(struct device *dev, ctlr =__spi_alloc_controller (dev, size, slave);if (ctlr) { + ctlr->devm_allocated = true; *ptr = ctlr;devres_add (dev, ptr); }else {
@@ -2834,11 +2835,6 @@ int devm_spi_register_controller(struct device *dev, }EXPORT_SYMBOL_GPL (devm_spi_register_controller); -static int devm_spi_match_controller (struct device *dev,void *res,void *ctlr) -{ -return *(struct spi_controller **)res == ctlr; -} -static int __unregister (struct device *dev,void *null) {spi_unregister_device (to_spi_device (dev));
@@ -2885,8 +2881,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)/* Release the last reference on the controller if its driver * has not yet been converted to devm_spi_alloc_master/slave(). */ -if (!devres_find (ctlr->dev.parent, devm_spi_release_controller, - devm_spi_match_controller, ctlr)) +if (!ctlr->devm_allocated)put_device (&ctlr->dev);/* free bus id */
include/linux/spi/spi.h +3 -0
@@ -512,6 +512,9 @@ struct spi_controller {#define SPI_MASTER_GPIO_SS BIT(5)/* GPIO CS must select slave */ +/* flag indicating this is a non-devres managed controller */ +bool devm_allocated; +/* flag indicating this is an SPI slave controller */ bool slave;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 251/601 spi: fsl: add missing iounmap() on error in of_fsl_spi_probe()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 5fed9fe5b41aea58e5b32be506dc50c9ab9a0e4d ]
Add the missing iounmap() before return from of_fsl_spi_probe() in the error handling case.
--- drivers/spi/spi-fsl-spi.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
drivers/spi/spi-fsl-spi.c +18 -5
@@ -707,6 +707,11 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)struct resource mem;int irq, type;int ret; +bool spisel_boot = false; +#if IS_ENABLED (CONFIG_FSL_SOC ) +struct mpc8xxx_spi_probe_info *pinfo =NULL ; +#endif + ret =of_mpc8xxx_spi_probe (ofdev);if (ret)
@@ -715,9 +720,8 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) type =fsl_spi_get_type (&ofdev->dev);if (type ==TYPE_FSL ) {struct fsl_spi_platform_data *pdata =dev_get_platdata (dev); -bool spisel_boot = false;#if IS_ENABLED (CONFIG_FSL_SOC ) -struct mpc8xxx_spi_probe_info *pinfo =to_of_pinfo (pdata); + pinfo =to_of_pinfo (pdata); spisel_boot =of_property_read_bool (np,"fsl,spisel_boot" );if (spisel_boot) {
@@ -746,15 +750,24 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) ret =of_address_to_resource (np,0 , &mem);if (ret) -return ret; + goto unmap_out; irq =platform_get_irq (ofdev,0 ); -if (irq <0 ) -return irq; +if (irq <0 ) { + ret = irq; + goto unmap_out; + } master =fsl_spi_probe (dev, &mem, irq);return PTR_ERR_OR_ZERO (master); + +unmap_out: +#if IS_ENABLED (CONFIG_FSL_SOC ) +if (spisel_boot) +iounmap (pinfo->immr_spi_cs); +#endif +return ret; }static int of_fsl_spi_remove (struct platform_device *ofdev)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 252/601 soc: qcom: mdt_loader: Validate that p_filesz < p_memsz
In reply to Greg Kroah-HartmanFrom: Bjorn Andersson <[email protected]>
[ Upstream commit 84168d1b54e76a1bcb5192991adde5176abe02e3 ]
The code validates that segments of p_memsz bytes of a segment will fit in the provided memory region, but does not validate that p_filesz bytes will, which means that an incorrectly crafted ELF header might write beyond the provided memory region.
--- drivers/soc/qcom/mdt_loader.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/soc/qcom/mdt_loader.c +8 -0
@@ -230,6 +230,14 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,break ; } +if (phdr->p_filesz > phdr->p_memsz) { +dev_err (dev, +"refusing to load segment %d with p_filesz > p_memsz\n" , + i); + ret = -EINVAL ; +break ; + } + ptr = mem_region + offset;if (phdr->p_filesz && phdr->p_offset < fw->size) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 253/601 soc: qcom: mdt_loader: Detect truncated read of segments
In reply to Greg Kroah-HartmanFrom: Bjorn Andersson <[email protected]>
[ Upstream commit 0648c55e3a21ccd816e99b6600d6199fbf39d23a ]
Given that no validation of how much data the firmware loader read in for a given segment truncated segment files would best case result in a hash verification failure, without any indication of what went wrong.
Improve this by validating that the firmware loader did return the amount of data requested.
--- drivers/soc/qcom/mdt_loader.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/soc/qcom/mdt_loader.c +9 -0
@@ -261,6 +261,15 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,break ; } +if (seg_fw->size != phdr->p_filesz) { +dev_err (dev, +"failed to load segment %d from truncated file %s\n" , + i, fw_name); +release_firmware (seg_fw); + ret = -EINVAL ; +break ; + } +release_firmware (seg_fw); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 254/601 PM: runtime: Replace inline function pm_runtime_callbacks_present()
In reply to Greg Kroah-HartmanFrom: YueHaibing <[email protected]>
[ Upstream commit 953c1fd96b1a70bcbbfb10973c2126eba8d891c7 ]
Commit 9a7875461fd0 ("PM: runtime: Replace pm_runtime_callbacks_present()") forgot to change the inline version.
--- include/linux/pm_runtime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/pm_runtime.h +1 -1
@@ -265,7 +265,7 @@ static inline void pm_runtime_no_callbacks(struct device *dev) {}static inline void pm_runtime_irq_safe (struct device *dev) {}static inline bool pm_runtime_is_irq_safe (struct device *dev) {return false; } -static inline bool pm_runtime_callbacks_present (struct device *dev) {return false; } +static inline bool pm_runtime_has_no_callbacks (struct device *dev) {return false; }static inline void pm_runtime_mark_last_busy (struct device *dev) {}static inline void __pm_runtime_use_autosuspend (struct device *dev,bool use) {}
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 255/601 cpuidle: Fix ARM_QCOM_SPM_CPUIDLE configuration
In reply to Greg Kroah-HartmanFrom: He Ying <[email protected]>
[ Upstream commit 498ba2a8a2756694b6f3888857426dbc8a5e6b6c ]
When CONFIG_ARM_QCOM_SPM_CPUIDLE is y and CONFIG_MMU is not set, compiling errors are encountered as follows:
drivers/cpuidle/cpuidle-qcom-spm.o: In function `spm_dev_probe':
cpuidle-qcom-spm.c:(.text+0x140): undefined reference to cpu_resume_arm' cpuidle-qcom-spm.c:(.text+0x148): undefined reference to cpu_resume_arm'
Note that cpu_resume_arm is defined when MMU is set. So, add dependency on MMU in ARM_QCOM_SPM_CPUIDLE configuration.
--- drivers/cpuidle/Kconfig.arm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpuidle/Kconfig.arm +1 -1
@@ -107,7 +107,7 @@ config ARM_TEGRA_CPUIDLE config ARM_QCOM_SPM_CPUIDLE bool "CPU Idle Driver for Qualcomm Subsystem Power Manager (SPM)" - depends on (ARCH_QCOM || COMPILE_TEST) && !ARM64 + depends on (ARCH_QCOM || COMPILE_TEST) && !ARM64 && MMU select ARM_CPU_SUSPEND select CPU_IDLE_MULTIPLE_DRIVERS select DT_IDLE_STATES
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 256/601 ACPI: CPPC: Replace cppc_attr with kobj_attribute
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 2bc6262c6117dd18106d5aa50d53e945b5d99c51 ]
All of the CPPC sysfs show functions are called via indirect call in kobj_attr_show(), where they should be of type
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
because that is the type of the ->show() member in 'struct kobj_attribute' but they are actually of type
ssize_t (*show)(struct kobject *kobj, struct attribute *attr, char *buf);
because of the ->show() member in 'struct cppc_attr', resulting in a Control Flow Integrity violation [1].
$ cat /sys/devices/system/cpu/cpu0/acpi_cppc/highest_perf 3400
$ dmesg | grep "CFI failure" [ 175.970559] CFI failure (target: show_highest_perf+0x0/0x8):
As far as I can tell, the only difference between 'struct cppc_attr' and 'struct kobj_attribute' aside from the type of the attr parameter is the type of the count parameter in the ->store() member (ssize_t vs. size_t), which does not actually matter because all of these nodes are read-only.
Eliminate 'struct cppc_attr' in favor of 'struct kobj_attribute' to fix the violation.
[1]: https://lore.kernel.org/r/[email protected]/
--- drivers/acpi/cppc_acpi.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
drivers/acpi/cppc_acpi.c +3 -11
@@ -119,23 +119,15 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);*/ #define NUM_RETRIES 500ULL -struct cppc_attr { -struct attribute attr; -ssize_t (*show)(struct kobject *kobj, -struct attribute *attr,char *buf); -ssize_t (*store)(struct kobject *kobj, -struct attribute *attr,const char *c,ssize_t count); -}; -#define define_one_cppc_ro (_name) \ -static struct cppc_attr _name = \ +static struct kobj_attribute _name = \ __ATTR(_name, 0444, show_##_name, NULL)#define to_cpc_desc (a) container_of(a, struct cpc_desc, kobj)#define show_cppc_data (access_fn, struct_name, member_name) \ static ssize_t show_##member_name(struct kobject *kobj, \ - struct attribute *attr, char *buf) \ + struct kobj_attribute *attr, char *buf) \ { \ struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); \ struct struct_name st_name = {0}; \
@@ -161,7 +153,7 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);show_cppc_data (cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);static ssize_t show_feedback_ctrs (struct kobject *kobj, -struct attribute *attr,char *buf) +struct kobj_attribute *attr,char *buf) {struct cpc_desc *cpc_ptr =to_cpc_desc (kobj);struct cppc_perf_fb_ctrs fb_ctrs = {0 };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 257/601 crypto: allwinner - add missing CRYPTO_ prefix
In reply to Greg Kroah-HartmanFrom: Corentin Labbe <[email protected]>
[ Upstream commit ac1af1a788b2002eb9d6f5ca6054517ad27f1930 ]
Some CONFIG select miss CRYPTO_.
--- drivers/crypto/allwinner/Kconfig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/crypto/allwinner/Kconfig +7 -7
@@ -62,10 +62,10 @@ config CRYPTO_DEV_SUN8I_CE_DEBUG config CRYPTO_DEV_SUN8I_CE_HASH bool "Enable support for hash on sun8i-ce" depends on CRYPTO_DEV_SUN8I_CE - select MD5 - select SHA1 - select SHA256 - select SHA512 + select CRYPTO_MD5 + select CRYPTO_SHA1 + select CRYPTO_SHA256 + select CRYPTO_SHA512 help Say y to enable support for hash algorithms.
@@ -123,8 +123,8 @@ config CRYPTO_DEV_SUN8I_SS_PRNG config CRYPTO_DEV_SUN8I_SS_HASH bool "Enable support for hash on sun8i-ss" depends on CRYPTO_DEV_SUN8I_SS - select MD5 - select SHA1 - select SHA256 + select CRYPTO_MD5 + select CRYPTO_SHA1 + select CRYPTO_SHA256 help Say y to enable support for hash algorithms.
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 258/601 crypto: sun8i-ss - Fix memory leak of pad
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 50274b01ac1689b1a3f6bc4b5b3dbf361a55dd3a ]
It appears there are several failure return paths that don't seem to be free'ing pad. Fix these.
Addresses-Coverity: ("Resource leak")
--- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +4 -3
@@ -348,8 +348,10 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) bf = (__le32 *)pad; result =kzalloc (digestsize,GFP_KERNEL |GFP_DMA ); -if (!result) +if (!result) { +kfree (pad);return -ENOMEM ; + }for (i =0 ; i <MAX_SG ; i++) { rctx->t_dst[i].addr =0 ;
@@ -435,10 +437,9 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)dma_unmap_sg (ss->dev, areq->src, nr_sgs,DMA_TO_DEVICE );dma_unmap_single (ss->dev, addr_res, digestsize,DMA_FROM_DEVICE ); -kfree (pad); -memcpy (areq->result, result, algt->alg.hash.halg.digestsize); theend: +kfree (pad);kfree (result);crypto_finalize_hash_request (engine, breq, err);return 0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 259/601 crypto: sa2ul - Fix memory leak of rxd
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 854b7737199848a91f6adfa0a03cf6f0c46c86e8 ]
There are two error return paths that are not freeing rxd and causing memory leaks. Fix these.
Addresses-Coverity: ("Resource leak")
--- drivers/crypto/sa2ul.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/crypto/sa2ul.c +6 -2
@@ -1146,8 +1146,10 @@ static int sa_run(struct sa_req *req) mapped_sg->sgt.sgl = src; mapped_sg->sgt.orig_nents = src_nents; ret =dma_map_sgtable (ddev, &mapped_sg->sgt, dir_src,0 ); -if (ret) +if (ret) { +kfree (rxd);return ret; + } mapped_sg->dir = dir_src; mapped_sg->mapped = true;
@@ -1155,8 +1157,10 @@ static int sa_run(struct sa_req *req) mapped_sg->sgt.sgl = req->src; mapped_sg->sgt.orig_nents = sg_nents; ret =dma_map_sgtable (ddev, &mapped_sg->sgt, dir_src,0 ); -if (ret) +if (ret) { +kfree (rxd);return ret; + } mapped_sg->dir = dir_src; mapped_sg->mapped = true;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 260/601 crypto: qat - Fix a double free in adf_create_ring
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit f7cae626cabb3350b23722b78fe34dd7a615ca04 ]
In adf_create_ring, if the callee adf_init_ring() failed, the callee will free the ring->base_addr by dma_free_coherent() and return -EFAULT. Then adf_create_ring will goto err and the ring->base_addr will be freed again in adf_cleanup_ring().
My patch sets ring->base_addr to NULL after the first freed to avoid the double free.
--- drivers/crypto/qat/qat_common/adf_transport.c | 1 + 1 file changed, 1 insertion(+)
drivers/crypto/qat/qat_common/adf_transport.c +1 -0
@@ -171,6 +171,7 @@ static int adf_init_ring(struct adf_etr_ring_data *ring)dev_err (&GET_DEV (accel_dev),"Ring address not aligned\n" );dma_free_coherent (&GET_DEV (accel_dev), ring_size_bytes, ring->base_addr, ring->dma_addr); + ring->base_addr =NULL ;return -EFAULT ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 261/601 cpufreq: armada-37xx: Fix setting TBG parent for load levels
In reply to Greg Kroah-HartmanFrom: Marek Behún <[email protected]>
[ Upstream commit 22592df194e31baf371906cc720da38fa0ab68f5 ]
With CPU frequency determining software [1] we have discovered that after this driver does one CPU frequency change, the base frequency of the CPU is set to the frequency of TBG-A-P clock, instead of the TBG that is parent to the CPU.
This can be reproduced on EspressoBIN and Turris MOX:
cd /sys/devices/system/cpu/cpufreq/policy0 echo powersave >scaling_governor
echo performance >scaling_governor
Running the mhz tool before this driver is loaded reports 1000 MHz, and after loading the driver and executing commands above the tool reports 800 MHz.
The change of TBG clock selector is supposed to happen in function armada37xx_cpufreq_dvfs_setup. Before the function returns, it does this:
parent = clk_get_parent(clk);
clk_set_parent(clk, parent);
The armada-37xx-periph clock driver has the .set_parent method implemented correctly for this, so if the method was actually called, this would work. But since the introduction of the common clock framework in commit b2476490ef11 ("clk: introduce the common clock..."), the clk_set_parent function checks whether the parent is actually changing, and if the requested new parent is same as the old parent (which is obviously the case for the code above), the .set_parent method is not called at all.
This patch fixes this issue by filling the correct TBG clock selector directly in the armada37xx_cpufreq_dvfs_setup during the filling of other registers at the same address. But the determination of CPU TBG index cannot be done via the common clock framework, therefore we need to access the North Bridge Peripheral Clock registers directly in this driver.
[1] https://github.com/wtarreau/mhz
--- drivers/cpufreq/armada-37xx-cpufreq.c | 35 ++++++++++++++++++--------- 1 file changed, 23 insertions(+), 12 deletions(-)
drivers/cpufreq/armada-37xx-cpufreq.c +23 -12
@@ -25,6 +25,10 @@#include "cpufreq-dt.h" +/* Clk register set */ +#define ARMADA_37XX_CLK_TBG_SEL 0 +#define ARMADA_37XX_CLK_TBG_SEL_CPU_OFF 22 +/* Power management in North Bridge register set */ #define ARMADA_37XX_NB_L0L1 0x18#define ARMADA_37XX_NB_L2L3 0x1C
@@ -120,10 +124,15 @@ static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)* will be configured then the DVFS will be enabled. */ static void __init armada37xx_cpufreq_dvfs_setup (struct regmap *base, -struct clk *clk,u8 *divider) +struct regmap *clk_base,u8 *divider) { +u32 cpu_tbg_sel;int load_lvl; -struct clk *parent; + +/* Determine to which TBG clock is CPU connected */ +regmap_read (clk_base,ARMADA_37XX_CLK_TBG_SEL , &cpu_tbg_sel); + cpu_tbg_sel >>=ARMADA_37XX_CLK_TBG_SEL_CPU_OFF ; + cpu_tbg_sel &=ARMADA_37XX_NB_TBG_SEL_MASK ;for (load_lvl =0 ; load_lvl <LOAD_LEVEL_NR ; load_lvl++) {unsigned int reg, mask, val, offset =0 ;
@@ -142,6 +151,11 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base, mask = (ARMADA_37XX_NB_CLK_SEL_MASK <<ARMADA_37XX_NB_CLK_SEL_OFF ); +/* Set TBG index, for all levels we use the same TBG */ + val = cpu_tbg_sel <<ARMADA_37XX_NB_TBG_SEL_OFF ; + mask = (ARMADA_37XX_NB_TBG_SEL_MASK + <<ARMADA_37XX_NB_TBG_SEL_OFF ); +/* * Set cpu divider based on the pre-computed array in * order to have balanced step.
@@ -160,14 +174,6 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,regmap_update_bits (base, reg, mask, val); } - -/* -* Set cpu clock source, for all the level we keep the same -* clock source that the one already configured. For this one -* we need to use the clock framework -*/ - parent =clk_get_parent (clk); -clk_set_parent (clk, parent); }/*
@@ -358,11 +364,16 @@ static int __init armada37xx_cpufreq_driver_init(void)struct platform_device *pdev;unsigned long freq;unsigned int cur_frequency, base_frequency; -struct regmap *nb_pm_base, *avs_base; +struct regmap *nb_clk_base, *nb_pm_base, *avs_base;struct device *cpu_dev;int load_lvl, ret;struct clk *clk, *parent; + nb_clk_base = +syscon_regmap_lookup_by_compatible ("marvell,armada-3700-periph-clock-nb" ); +if (IS_ERR (nb_clk_base)) +return -ENODEV ; + nb_pm_base =syscon_regmap_lookup_by_compatible ("marvell,armada-3700-nb-pm" );
@@ -439,7 +450,7 @@ static int __init armada37xx_cpufreq_driver_init(void)armada37xx_cpufreq_avs_configure (avs_base, dvfs);armada37xx_cpufreq_avs_setup (avs_base, dvfs); -armada37xx_cpufreq_dvfs_setup (nb_pm_base, clk, dvfs->divider); +armada37xx_cpufreq_dvfs_setup (nb_pm_base, nb_clk_base, dvfs->divider);clk_put (clk); for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 262/601 clk: mvebu: armada-37xx-periph: remove .set_parent method for CPU PM clock
In reply to Greg Kroah-HartmanFrom: Marek Behún <[email protected]>
[ Upstream commit 4e435a9dd26c46ac018997cc0562d50b1a96f372 ]
Remove the .set_parent method in clk_pm_cpu_ops.
This method was supposed to be needed by the armada-37xx-cpufreq driver, but was never actually called due to wrong assumptions in the cpufreq driver. After this was fixed in the cpufreq driver, this method is not needed anymore.
--- drivers/clk/mvebu/armada-37xx-periph.c | 28 -------------------------- 1 file changed, 28 deletions(-)
drivers/clk/mvebu/armada-37xx-periph.c +0 -28
@@ -440,33 +440,6 @@ static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)return val; } -static int clk_pm_cpu_set_parent (struct clk_hw *hw,u8 index) -{ -struct clk_pm_cpu *pm_cpu =to_clk_pm_cpu (hw); -struct regmap *base = pm_cpu->nb_pm_base; -int load_level; - -/* -* We set the clock parent only if the DVFS is available but -* not enabled. -*/ -if (IS_ERR (base) ||armada_3700_pm_dvfs_is_enabled (base)) -return -EINVAL ; - -/* Set the parent clock for all the load level */ -for (load_level =0 ; load_level <LOAD_LEVEL_NR ; load_level++) { -unsigned int reg, mask, val, - offset =ARMADA_37XX_NB_TBG_SEL_OFF ; - -armada_3700_pm_dvfs_update_regs (load_level, ®, &offset); - - val = index << offset; - mask =ARMADA_37XX_NB_TBG_SEL_MASK << offset; -regmap_update_bits (base, reg, mask, val); - } -return 0 ; -} -static unsigned long clk_pm_cpu_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) {
@@ -592,7 +565,6 @@ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,static const struct clk_ops clk_pm_cpu_ops = { .get_parent = clk_pm_cpu_get_parent, - .set_parent = clk_pm_cpu_set_parent, .round_rate = clk_pm_cpu_round_rate, .set_rate = clk_pm_cpu_set_rate, .recalc_rate = clk_pm_cpu_recalc_rate,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 263/601 cpufreq: armada-37xx: Fix the AVS value for load L1
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit d118ac2062b5b8331c8768ac81e016617e0996ee ]
The original CPU voltage value for load L1 is too low for Armada 37xx SoC when base CPU frequency is 1000 or 1200 MHz. It leads to instabilities where CPU gets stuck soon after dynamic voltage scaling from load L1 to L0.
Update the CPU voltage value for load L1 accordingly when base frequency is 1000 or 1200 MHz. The minimal L1 value for base CPU frequency 1000 MHz is updated from the original 1.05V to 1.108V and for 1200 MHz is updated to 1.155V. This minimal L1 value is used only in the case when it is lower than value for L0.
This change fixes CPU instability issues on 1 GHz and 1.2 GHz variants of Espressobin and 1 GHz Turris Mox.
Marvell previously for 1 GHz variant of Espressobin provided a patch [1] suitable only for their Marvell Linux kernel 4.4 fork which workarounded this issue. Patch forced CPU voltage value to 1.108V in all loads. But such change does not fix CPU instability issues on 1.2 GHz variants of Armada 3720 SoC.
During testing we come to the conclusion that using 1.108V as minimal value for L1 load makes 1 GHz variants of Espressobin and Turris Mox boards stable. And similarly 1.155V for 1.2 GHz variant of Espressobin.
These two values 1.108V and 1.155V are documented in Armada 3700 Hardware Specifications as typical initial CPU voltage values.
Discussion about this issue is also at the Armbian forum [2].
[1] - https://github.com/MarvellEmbeddedProcessors/linux-marvell/commit/dc33b62c90696afb6adc7dbcc4ebbd48bedec269
[2] - https://forum.armbian.com/topic/10429-how-to-make-espressobin-v7-stable/
--- drivers/cpufreq/armada-37xx-cpufreq.c | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
drivers/cpufreq/armada-37xx-cpufreq.c +37 -0
@@ -73,6 +73,8 @@#define LOAD_LEVEL_NR 4#define MIN_VOLT_MV 1000 +#define MIN_VOLT_MV_FOR_L1_1000MHZ 1108 +#define MIN_VOLT_MV_FOR_L1_1200MHZ 1155/* AVS value for the corresponding voltage (in mV) */ static int avs_map[] = {
@@ -208,6 +210,8 @@ static u32 armada_37xx_avs_val_match(int target_vm)* - L2 & L3 voltage should be about 150mv smaller than L0 voltage. * This function calculates L1 & L2 & L3 AVS values dynamically based * on L0 voltage and fill all AVS values to the AVS value table. +* When base CPU frequency is 1000 or 1200 MHz then there is additional +* minimal avs value for load L1. */ static void __init armada37xx_cpufreq_avs_configure (struct regmap *base,struct armada_37xx_dvfs *dvfs)
@@ -239,6 +243,19 @@ static void __init armada37xx_cpufreq_avs_configure(struct regmap *base,for (load_level =1 ; load_level <LOAD_LEVEL_NR ; load_level++) dvfs->avs[load_level] = avs_min; +/* +* Set the avs values for load L0 and L1 when base CPU frequency +* is 1000/1200 MHz to its typical initial values according to +* the Armada 3700 Hardware Specifications. +*/ +if (dvfs->cpu_freq_max >=1000 *1000 *1000 ) { +if (dvfs->cpu_freq_max >=1200 *1000 *1000 ) + avs_min =armada_37xx_avs_val_match (MIN_VOLT_MV_FOR_L1_1200MHZ ); +else + avs_min =armada_37xx_avs_val_match (MIN_VOLT_MV_FOR_L1_1000MHZ ); + dvfs->avs[0 ] = dvfs->avs[1 ] = avs_min; + } +return ; }
@@ -258,6 +275,26 @@ static void __init armada37xx_cpufreq_avs_configure(struct regmap *base, target_vm = avs_map[l0_vdd_min] -150 ; target_vm = target_vm >MIN_VOLT_MV ? target_vm :MIN_VOLT_MV ; dvfs->avs[2 ] = dvfs->avs[3 ] =armada_37xx_avs_val_match (target_vm); + +/* +* Fix the avs value for load L1 when base CPU frequency is 1000/1200 MHz, +* otherwise the CPU gets stuck when switching from load L1 to load L0. +* Also ensure that avs value for load L1 is not higher than for L0. +*/ +if (dvfs->cpu_freq_max >=1000 *1000 *1000 ) { +u32 avs_min_l1; + +if (dvfs->cpu_freq_max >=1200 *1000 *1000 ) + avs_min_l1 =armada_37xx_avs_val_match (MIN_VOLT_MV_FOR_L1_1200MHZ ); +else + avs_min_l1 =armada_37xx_avs_val_match (MIN_VOLT_MV_FOR_L1_1000MHZ ); + +if (avs_min_l1 > dvfs->avs[0 ]) + avs_min_l1 = dvfs->avs[0 ]; + +if (dvfs->avs[1 ] < avs_min_l1) + dvfs->avs[1 ] = avs_min_l1; + } } static void __init armada37xx_cpufreq_avs_setup(struct regmap *base,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 264/601 clk: mvebu: armada-37xx-periph: Fix switching CPU freq from 250 Mhz to 1 GHz
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 4decb9187589f61fe9fc2bc4d9b01160b0a610c5 ]
It was observed that the workaround introduced by commit 61c40f35f5cd ("clk: mvebu: armada-37xx-periph: Fix switching CPU rate from 300Mhz to 1.2GHz") when base CPU frequency is 1.2 GHz is also required when base CPU frequency is 1 GHz. Otherwise switching CPU frequency directly from L2 (250 MHz) to L0 (1 GHz) causes a crash.
When base CPU frequency is just 800 MHz no crashed were observed during switch from L2 to L0.
--- drivers/clk/mvebu/armada-37xx-periph.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/clk/mvebu/armada-37xx-periph.c +7 -5
@@ -487,8 +487,10 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, }/* -* Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz -* respectively) to L0 frequency (1.2 Ghz) requires a significant +* Workaround when base CPU frequnecy is 1000 or 1200 MHz +* +* Switching the CPU from the L2 or L3 frequencies (250/300 or 200 MHz +* respectively) to L0 frequency (1/1.2 GHz) requires a significant * amount of time to let VDD stabilize to the appropriate * voltage. This amount of time is large enough that it cannot be * covered by the hardware countdown register. Due to this, the CPU
@@ -498,15 +500,15 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate,* To work around this problem, we prevent switching directly from the * L2/L3 frequencies to the L0 frequency, and instead switch to the L1 * frequency in-between. The sequence therefore becomes: -* 1. First switch from L2/L3(200/300MHz) to L1(600MHZ) +* 1. First switch from L2/L3 (200/250/300 MHz) to L1 (500/600 MHz) * 2. Sleep 20ms for stabling VDD voltage -* 3. Then switch from L1(600MHZ) to L0(1200Mhz). +* 3. Then switch from L1 (500/600 MHz) to L0 (1000/1200 MHz). */ static void clk_pm_cpu_set_rate_wa (unsigned long rate,struct regmap *base) {unsigned int cur_level; -if (rate !=1200 *1000 *1000 ) +if (rate <1000 *1000 *1000 )return ;regmap_read (base,ARMADA_37XX_NB_CPU_LOAD , &cur_level);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 265/601 clk: mvebu: armada-37xx-periph: Fix workaround for switching from L1 to L0
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit e93033aff684641f71a436ca7a9d2a742126baaf ]
When CPU frequency is at 250 MHz and set_rate() is called with 500 MHz (L1) quickly followed by a call with 1 GHz (L0), the CPU does not necessarily stay in L1 for at least 20ms as is required by Marvell errata.
This situation happens frequently with the ondemand cpufreq governor and can be also reproduced with userspace governor. In most cases it causes CPU to crash.
This change fixes the above issue and ensures that the CPU always stays in L1 for at least 20ms when switching from any state to L0.
--- drivers/clk/mvebu/armada-37xx-periph.c | 45 ++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-)
drivers/clk/mvebu/armada-37xx-periph.c +39 -6
@@ -84,6 +84,7 @@ struct clk_pm_cpu {void __iomem *reg_div;u8 shift_div;struct regmap *nb_pm_base; +unsigned long l1_expiration; };#define to_clk_double_div (_hw) container_of(_hw, struct clk_double_div, hw)
@@ -504,22 +505,52 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate,* 2. Sleep 20ms for stabling VDD voltage * 3. Then switch from L1 (500/600 MHz) to L0 (1000/1200 MHz). */ -static void clk_pm_cpu_set_rate_wa (unsigned long rate,struct regmap *base) +static void clk_pm_cpu_set_rate_wa (struct clk_pm_cpu *pm_cpu, +unsigned int new_level,unsigned long rate, +struct regmap *base) {unsigned int cur_level; -if (rate <1000 *1000 *1000 ) -return ; -regmap_read (base,ARMADA_37XX_NB_CPU_LOAD , &cur_level); cur_level &=ARMADA_37XX_NB_CPU_LOAD_MASK ; -if (cur_level <=ARMADA_37XX_DVFS_LOAD_1 ) + +if (cur_level == new_level) +return ; + +/* +* System wants to go to L1 on its own. If we are going from L2/L3, +* remember when 20ms will expire. If from L0, set the value so that +* next switch to L0 won't have to wait. +*/ +if (new_level ==ARMADA_37XX_DVFS_LOAD_1 ) { +if (cur_level ==ARMADA_37XX_DVFS_LOAD_0 ) + pm_cpu->l1_expiration = jiffies; +else + pm_cpu->l1_expiration = jiffies +msecs_to_jiffies (20 );return ; + } + +/* +* If we are setting to L2/L3, just invalidate L1 expiration time, +* sleeping is not needed. +*/ +if (rate <1000 *1000 *1000 ) + goto invalidate_l1_exp; + +/* +* We are going to L0 with rate >= 1GHz. Check whether we have been at +* L1 for long enough time. If not, go to L1 for 20ms. +*/ +if (pm_cpu->l1_expiration && jiffies >= pm_cpu->l1_expiration) + goto invalidate_l1_exp;regmap_update_bits (base,ARMADA_37XX_NB_CPU_LOAD ,ARMADA_37XX_NB_CPU_LOAD_MASK ,ARMADA_37XX_DVFS_LOAD_1 );msleep (20 ); + +invalidate_l1_exp: + pm_cpu->l1_expiration =0 ; } static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -553,7 +584,9 @@ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, reg =ARMADA_37XX_NB_CPU_LOAD ; mask =ARMADA_37XX_NB_CPU_LOAD_MASK ; -clk_pm_cpu_set_rate_wa (rate, base); +/* Apply workaround when base CPU frequency is 1000 or 1200 MHz */ +if (parent_rate >=1000 *1000 *1000 ) +clk_pm_cpu_set_rate_wa (pm_cpu, load_level, rate, base);regmap_update_bits (base, reg, mask, load_level);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 266/601 cpufreq: armada-37xx: Fix driver cleanup when registration failed
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 92963903a8e11b9576eb7249f8e81eefa93b6f96 ]
Commit 8db82563451f ("cpufreq: armada-37xx: fix frequency calculation for opp") changed calculation of frequency passed to the dev_pm_opp_add() function call. But the code for dev_pm_opp_remove() function call was not updated, so the driver cleanup phase does not work when registration fails.
This fixes the issue by using the same frequency in both calls.
--- drivers/cpufreq/armada-37xx-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/armada-37xx-cpufreq.c +1 -1
@@ -521,7 +521,7 @@ disable_dvfs: remove_opp:/* clean-up the already added opp before leaving */ while (load_lvl-- >ARMADA_37XX_DVFS_LOAD_0 ) { - freq = cur_frequency / dvfs->divider[load_lvl]; + freq = base_frequency / dvfs->divider[load_lvl];dev_pm_opp_remove (cpu_dev, freq); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 267/601 cpufreq: armada-37xx: Fix determining base CPU frequency
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 8bad3bf23cbc40abe1d24cec08a114df6facf858 ]
When current CPU load is not L0 then loading armada-37xx-cpufreq.ko driver fails with following error:
# modprobe armada-37xx-cpufreq
[ 502.702097] Unsupported CPU frequency 250 MHzThis issue was partially fixed by commit 8db82563451f ("cpufreq:
armada-37xx: fix frequency calculation for opp"), but only for calculating CPU frequency for opp.
Fix this also for determination of base CPU frequency.
--- drivers/cpufreq/armada-37xx-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/armada-37xx-cpufreq.c +1 -1
@@ -469,7 +469,7 @@ static int __init armada37xx_cpufreq_driver_init(void)return -EINVAL ; } - dvfs =armada_37xx_cpu_freq_info_get (cur_frequency); + dvfs =armada_37xx_cpu_freq_info_get (base_frequency);if (!dvfs) {clk_put (clk);return -EINVAL ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 268/601 spi: spi-zynqmp-gqspi: use wait_for_completion_timeout to make zynqmp_qspi_exec_op not interruptible
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit a16bff68b75fd082d36aa0b14b540bd7a3ebebbd ]
When Ctrl+C occurs during the process of zynqmp_qspi_exec_op, the function wait_for_completion_interruptible_timeout will return a non-zero value -ERESTARTSYS immediately. This will disrupt the SPI memory operation because the data transmitting may begin before the command or address transmitting completes. Use wait_for_completion_timeout to prevent the process from being interruptible.
This patch fixes the error as below:
root@xilinx-zynqmp:~# flash_erase /dev/mtd3 0 0
Erasing 4 Kibyte @ 3d000 -- 4 % complete
(Press Ctrl+C)
[ 169.581911] zynqmp-qspi ff0f0000.spi: Chip select timed out
[ 170.585907] zynqmp-qspi ff0f0000.spi: Chip select timed out
[ 171.589910] zynqmp-qspi ff0f0000.spi: Chip select timed out
[ 172.593910] zynqmp-qspi ff0f0000.spi: Chip select timed out
[ 173.597907] zynqmp-qspi ff0f0000.spi: Chip select timed out
[ 173.603480] spi-nor spi0.0: Erase operation failed.
[ 173.608368] spi-nor spi0.0: Attempted to modify a protected sector.--- drivers/spi/spi-zynqmp-gqspi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +3 -3
@@ -973,7 +973,7 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,zynqmp_gqspi_write (xqspi,GQSPI_IER_OFST ,GQSPI_IER_GENFIFOEMPTY_MASK |GQSPI_IER_TXNOT_FULL_MASK ); -if (!wait_for_completion_interruptible_timeout +if (!wait_for_completion_timeout (&xqspi->data_completion,msecs_to_jiffies (1000 ))) { err = -ETIMEDOUT ;kfree (tmpbuf);
@@ -1001,7 +1001,7 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,GQSPI_IER_TXEMPTY_MASK |GQSPI_IER_GENFIFOEMPTY_MASK | GQSPI_IER_TXNOT_FULL_MASK); -if (!wait_for_completion_interruptible_timeout +if (!wait_for_completion_timeout (&xqspi->data_completion,msecs_to_jiffies (1000 ))) { err = -ETIMEDOUT ; goto return_err;
@@ -1076,7 +1076,7 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem, GQSPI_IER_RXEMPTY_MASK); } } -if (!wait_for_completion_interruptible_timeout +if (!wait_for_completion_timeout (&xqspi->data_completion,msecs_to_jiffies (1000 ))) err = -ETIMEDOUT ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 269/601 spi: spi-zynqmp-gqspi: add mutex locking for exec_op
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit a0f65be6e880a14d3445b75e7dc03d7d015fc922 ]
The spi-mem framework has no locking to prevent ctlr->mem_ops->exec_op from concurrency. So add the locking to zynqmp_qspi_exec_op.
--- drivers/spi/spi-zynqmp-gqspi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/spi/spi-zynqmp-gqspi.c +5 -0
@@ -173,6 +173,7 @@ struct zynqmp_qspi {u32 genfifoentry;enum mode_type mode;struct completion data_completion; +struct mutex op_lock; };/**
@@ -951,6 +952,7 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, op->dummy.buswidth, op->data.buswidth); +mutex_lock (&xqspi->op_lock);zynqmp_qspi_config_op (xqspi, mem->spi);zynqmp_qspi_chipselect (mem->spi, false); genfifoentry |= xqspi->genfifocs;
@@ -1084,6 +1086,7 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem, return_err:zynqmp_qspi_chipselect (mem->spi, true); +mutex_unlock (&xqspi->op_lock);return err; }
@@ -1156,6 +1159,8 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) goto clk_dis_pclk; } +mutex_init (&xqspi->op_lock); +pm_runtime_use_autosuspend (&pdev->dev);pm_runtime_set_autosuspend_delay (&pdev->dev,SPI_AUTOSUSPEND_TIMEOUT );pm_runtime_set_active (&pdev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 270/601 spi: spi-zynqmp-gqspi: transmit dummy circles by using the controllers internal functionality
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 8ad07d79bd56a531990a1a3f3f1c0eb19d2de806 ]
There is a data corruption issue that occurs in the reading operation (cmd:0x6c) when transmitting common data as dummy circles.
The gqspi controller has the functionality to send dummy clock circles. When writing data with the fields [receive, transmit, data_xfer] = [0,0,1] to the Generic FIFO, and configuring the correct SPI mode, the controller will transmit dummy circles.
So let's switch to hardware dummy cycles transfer to fix this issue.
--- drivers/spi/spi-zynqmp-gqspi.c | 40 +++++++++++++++------------------- 1 file changed, 18 insertions(+), 22 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +18 -22
@@ -521,7 +521,7 @@ static void zynqmp_qspi_filltxfifo(struct zynqmp_qspi *xqspi, int size) {u32 count =0 , intermediate; -while ((xqspi->bytes_to_transfer >0 ) && (count < size)) { +while ((xqspi->bytes_to_transfer >0 ) && (count < size) && (xqspi->txbuf)) {memcpy (&intermediate, xqspi->txbuf,4 );zynqmp_gqspi_write (xqspi,GQSPI_TXD_OFST , intermediate);
@@ -580,7 +580,7 @@ static void zynqmp_qspi_fillgenfifo(struct zynqmp_qspi *xqspi, u8 nbits, genfifoentry |=GQSPI_GENFIFO_DATA_XFER ; genfifoentry |=GQSPI_GENFIFO_TX ; transfer_len = xqspi->bytes_to_transfer; - }else { + }else if (xqspi->rxbuf) { genfifoentry &= ~GQSPI_GENFIFO_TX ; genfifoentry |=GQSPI_GENFIFO_DATA_XFER ; genfifoentry |=GQSPI_GENFIFO_RX ;
@@ -588,6 +588,11 @@ static void zynqmp_qspi_fillgenfifo(struct zynqmp_qspi *xqspi, u8 nbits, transfer_len = xqspi->dma_rx_bytes; else transfer_len = xqspi->bytes_to_receive; + }else { +/* Sending dummy circles here */ + genfifoentry &= ~(GQSPI_GENFIFO_TX |GQSPI_GENFIFO_RX ); + genfifoentry |=GQSPI_GENFIFO_DATA_XFER ; + transfer_len = xqspi->bytes_to_transfer; } genfifoentry |=zynqmp_qspi_selectspimode (xqspi, nbits); xqspi->genfifoentry = genfifoentry;
@@ -1011,32 +1016,23 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem, }if (op->dummy.nbytes) { - tmpbuf =kzalloc (op->dummy.nbytes,GFP_KERNEL |GFP_DMA ); -if (!tmpbuf) -return -ENOMEM ; -memset (tmpbuf,0xff , op->dummy.nbytes); -reinit_completion (&xqspi->data_completion); - xqspi->txbuf = tmpbuf; + xqspi->txbuf =NULL ; xqspi->rxbuf =NULL ; - xqspi->bytes_to_transfer = op->dummy.nbytes; +/* +* xqspi->bytes_to_transfer here represents the dummy circles +* which need to be sent. +*/ + xqspi->bytes_to_transfer = op->dummy.nbytes *8 / op->dummy.buswidth; xqspi->bytes_to_receive =0 ; -zynqmp_qspi_write_op (xqspi, op->dummy.buswidth, +/* +* Using op->data.buswidth instead of op->dummy.buswidth here because +* we need to use it to configure the correct SPI mode. +*/ +zynqmp_qspi_write_op (xqspi, op->data.buswidth, genfifoentry);zynqmp_gqspi_write (xqspi,GQSPI_CONFIG_OFST ,zynqmp_gqspi_read (xqspi,GQSPI_CONFIG_OFST ) |GQSPI_CFG_START_GEN_FIFO_MASK ); -zynqmp_gqspi_write (xqspi,GQSPI_IER_OFST , -GQSPI_IER_TXEMPTY_MASK | -GQSPI_IER_GENFIFOEMPTY_MASK | -GQSPI_IER_TXNOT_FULL_MASK ); -if (!wait_for_completion_interruptible_timeout - (&xqspi->data_completion,msecs_to_jiffies (1000 ))) { - err = -ETIMEDOUT ; -kfree (tmpbuf); - goto return_err; - } - -kfree (tmpbuf); }if (op->data.nbytes) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 271/601 spi: spi-zynqmp-gqspi: fix incorrect operating mode in zynqmp_qspi_read_op
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 41d310930084502433fcb3c4baf219e7424b7734 ]
When starting a read operation, we should call zynqmp_qspi_setuprxdma first to set xqspi->mode according to xqspi->bytes_to_receive and to calculate correct xqspi->dma_rx_bytes. Then in the function zynqmp_qspi_fillgenfifo, generate the appropriate command with operating mode and bytes to transfer, and fill the GENFIFO with the command to perform the read operation.
Calling zynqmp_qspi_fillgenfifo before zynqmp_qspi_setuprxdma will result in incorrect transfer length and operating mode. So change the calling order to fix this issue.
--- drivers/spi/spi-zynqmp-gqspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-zynqmp-gqspi.c +1 -1
@@ -827,8 +827,8 @@ static void zynqmp_qspi_write_op(struct zynqmp_qspi *xqspi, u8 tx_nbits,static void zynqmp_qspi_read_op (struct zynqmp_qspi *xqspi,u8 rx_nbits,u32 genfifoentry) { -zynqmp_qspi_fillgenfifo (xqspi, rx_nbits, genfifoentry);zynqmp_qspi_setuprxdma (xqspi); +zynqmp_qspi_fillgenfifo (xqspi, rx_nbits, genfifoentry); }/**
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 272/601 spi: fsl-lpspi: Fix PM reference leak in lpspi_prepare_xfer_hardware()
In reply to Greg Kroah-HartmanFrom: Wang Li <[email protected]>
[ Upstream commit a03675497970a93fcf25d81d9d92a59c2d7377a7 ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
--- drivers/spi/spi-fsl-lpspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-fsl-lpspi.c +1 -1
@@ -200,7 +200,7 @@ static int lpspi_prepare_xfer_hardware(struct spi_controller *controller)spi_controller_get_devdata (controller);int ret; - ret =pm_runtime_get_sync (fsl_lpspi->dev); + ret =pm_runtime_resume_and_get (fsl_lpspi->dev);if (ret <0 ) {dev_err (fsl_lpspi->dev,"failed to enable clock\n" );return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 273/601 usb: gadget: r8a66597: Add missing null check on return from platform_get_resource
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 9c2076090c2815fe7c49676df68dde7e60a9b9fc ]
The call to platform_get_resource can potentially return a NULL pointer on failure, so add this check and return -EINVAL if it fails.
Addresses-Coverity: ("Dereference null return")
--- drivers/usb/gadget/udc/r8a66597-udc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/gadget/udc/r8a66597-udc.c +2 -0
@@ -1849,6 +1849,8 @@ static int r8a66597_probe(struct platform_device *pdev)return PTR_ERR (reg); ires =platform_get_resource (pdev,IORESOURCE_IRQ ,0 ); +if (!ires) +return -EINVAL ; irq = ires->start; irq_trigger = ires->flags &IRQF_TRIGGER_MASK ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 274/601 USB: cdc-acm: fix unprivileged TIOCCSERIAL
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit dd5619582d60007139f0447382d2839f4f9e339b ]
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
A non-privileged user has only ever been able to set the since long deprecated ASYNC_SPD flags and trying to change any other *supported* feature should result in -EPERM being returned. Setting the current values for any supported features should return success.
Fix the cdc-acm implementation which instead indicated that the TIOCSSERIAL ioctl was not even implemented when a non-privileged user set the current values.
--- drivers/usb/class/cdc-acm.c | 2 -- 1 file changed, 2 deletions(-)
drivers/usb/class/cdc-acm.c +0 -2
@@ -955,8 +955,6 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)if ((close_delay != acm->port.close_delay) || (closing_wait != acm->port.closing_wait)) retval = -EPERM ; -else - retval = -EOPNOTSUPP ; }else { acm->port.close_delay = close_delay; acm->port.closing_wait = closing_wait;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 275/601 USB: cdc-acm: fix TIOCGSERIAL implementation
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 496960274153bdeb9d1f904ff1ea875cef8232c1 ]
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
The xmit_fifo_size parameter could be used to set the hardware transmit fifo size of a legacy UART when it could not be detected, but the interface is limited to eight bits and should be left unset when it is not used.
Similarly, baud_base could be used to set the UART base clock when it could not be detected, but might as well be left unset when it is not known (which is the case for CDC).
Fix the cdc-acm TIOCGSERIAL implementation by dropping its custom interpretation of the unused xmit_fifo_size and baud_base fields, which overflowed the former with the URB buffer size and set the latter to the current line speed. Also return the port line number, which is the only other value used besides the close parameters.
Note that the current line speed can still be retrieved through the standard termios interfaces.
--- drivers/usb/class/cdc-acm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/class/cdc-acm.c +1 -2
@@ -929,8 +929,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) {struct acm *acm = tty->driver_data; - ss->xmit_fifo_size = acm->writesize; - ss->baud_base =le32_to_cpu (acm->line.dwDTERate); + ss->line = acm->minor; ss->close_delay =jiffies_to_msecs (acm->port.close_delay) /10 ; ss->closing_wait = acm->port.closing_wait ==ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE :
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 276/601 tty: actually undefine superseded ASYNC flags
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit d09845e98a05850a8094ea8fd6dd09a8e6824fff ]
Some kernel-internal ASYNC flags have been superseded by tty-port flags and should no longer be used by kernel drivers.
Fix the misspelled "__KERNEL__" compile guards which failed their sole purpose to break out-of-tree drivers that have not yet been updated.
--- include/uapi/linux/tty_flags.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/uapi/linux/tty_flags.h +2 -2
@@ -39,7 +39,7 @@* WARNING: These flags are no longer used and have been superceded by the * TTY_PORT_ flags in the iflags field (and not userspace-visible) */ -#ifndef _KERNEL_ +#ifndef __KERNEL__#define ASYNCB_INITIALIZED 31/* Serial port was initialized */ #define ASYNCB_SUSPENDED 30/* Serial port is suspended */ #define ASYNCB_NORMAL_ACTIVE 29/* Normal device is active */
@@ -81,7 +81,7 @@#define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI)#define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI) -#ifndef _KERNEL_ +#ifndef __KERNEL__/* These flags are no longer used (and were always masked from userspace) */ #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED)#define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 277/601 tty: fix return value for unsupported ioctls
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 1b8b20868a6d64cfe8174a21b25b74367bdf0560 ]
Drivers should return -ENOTTY ("Inappropriate I/O control operation") when an ioctl isn't supported, while -EINVAL is used for invalid arguments.
Fix up the TIOCMGET, TIOCMSET and TIOCGICOUNT helpers which returned -EINVAL when a tty driver did not implement the corresponding operations.
Note that the TIOCMGET and TIOCMSET helpers predate git and do not get a corresponding Fixes tag below.
--- drivers/tty/tty_io.c | 8 ++++---- include/linux/tty_driver.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/tty/tty_io.c +4 -4
@@ -2494,14 +2494,14 @@ out:* @p: pointer to result * * Obtain the modem status bits from the tty driver if the feature -* is supported. Return -EINVAL if it is not available. +* is supported. Return -ENOTTY if it is not available. * * Locking: none (up to the driver) */ static int tty_tiocmget (struct tty_struct *tty,int __user *p) { -int retval = -EINVAL ; +int retval = -ENOTTY ;if (tty->ops->tiocmget) { retval = tty->ops->tiocmget (tty);
@@ -2519,7 +2519,7 @@ static int tty_tiocmget(struct tty_struct *tty, int __user *p)* @p: pointer to desired bits * * Set the modem status bits from the tty driver if the feature -* is supported. Return -EINVAL if it is not available. +* is supported. Return -ENOTTY if it is not available. * * Locking: none (up to the driver) */
@@ -2531,7 +2531,7 @@ static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd,unsigned int set, clear, val;if (tty->ops->tiocmset ==NULL ) -return -EINVAL ; +return -ENOTTY ; retval =get_user (val, p);if (retval)
include/linux/tty_driver.h +1 -1
@@ -228,7 +228,7 @@* * Called when the device receives a TIOCGICOUNT ioctl. Passed a kernel * structure to complete. This method is optional and will only be called -* if provided (otherwise EINVAL will be returned). +* if provided (otherwise ENOTTY will be returned). */ #include <linux/export.h>
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 278/601 tty: fix return value for unsupported termiox ioctls
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 8871de06ff78e9333d86c87d7071452b690e7c9b ]
Drivers should return -ENOTTY ("Inappropriate I/O control operation") when an ioctl isn't supported, while -EINVAL is used for invalid arguments.
Support for termiox was added by commit 1d65b4a088de ("tty: Add termiox") in 2008 but no driver support ever followed and it was recently ripped out by commit e0efb3168d34 ("tty: Remove dead termiox code").
Fix the return value for the unsupported termiox ioctls, which have always returned -EINVAL, by explicitly returning -ENOTTY rather than removing them completely and falling back to the default unrecognised- ioctl handling.
--- drivers/tty/tty_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/tty_ioctl.c +2 -2
@@ -774,8 +774,8 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,case TCSETX :case TCSETXW :case TCSETXF : -return -EINVAL ; -#endif +return -ENOTTY ; +#endif case TIOCGSOFTCAR :copy_termios (real_tty, &kterm); ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 279/601 serial: core: return early on unsupported ioctls
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 79c5966cec7b148199386ef9933c31b999379065 ]
Drivers can return -ENOIOCTLCMD when an ioctl is not recognised to tell the upper layers to continue looking for a handler.
This is not the case for the RS485 and ISO7816 ioctls whose handlers should return -ENOTTY directly in case a serial driver does not implement the corresponding methods.
--- drivers/tty/serial/serial_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/tty/serial/serial_core.c +3 -3
@@ -1306,7 +1306,7 @@ static int uart_set_rs485_config(struct uart_port *port,unsigned long flags;if (!port->rs485_config) -return -ENOIOCTLCMD ; +return -ENOTTY ;if (copy_from_user (&rs485, rs485_user,sizeof (*rs485_user)))return -EFAULT ;
@@ -1330,7 +1330,7 @@ static int uart_get_iso7816_config(struct uart_port *port,struct serial_iso7816 aux;if (!port->iso7816_config) -return -ENOIOCTLCMD ; +return -ENOTTY ;spin_lock_irqsave (&port->lock, flags); aux = port->iso7816;
@@ -1350,7 +1350,7 @@ static int uart_set_iso7816_config(struct uart_port *port,unsigned long flags;if (!port->iso7816_config) -return -ENOIOCTLCMD ; +return -ENOTTY ;if (copy_from_user (&iso7816, iso7816_user,sizeof (*iso7816_user)))return -EFAULT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 280/601 firmware: qcom-scm: Fix QCOM_SCM configuration
In reply to Greg Kroah-HartmanFrom: He Ying <[email protected]>
[ Upstream commit 2954a6f12f250890ec2433cec03ba92784d613e8 ]
When CONFIG_QCOM_SCM is y and CONFIG_HAVE_ARM_SMCCC is not set, compiling errors are encountered as follows:
drivers/firmware/qcom_scm-smc.o: In function `__scm_smc_do_quirk':
qcom_scm-smc.c:(.text+0x36): undefined reference to __arm_smccc_smc' drivers/firmware/qcom_scm-legacy.o: In function scm_legacy_call':
qcom_scm-legacy.c:(.text+0xe2): undefined reference to __arm_smccc_smc' drivers/firmware/qcom_scm-legacy.o: In function scm_legacy_call_atomic':
qcom_scm-legacy.c:(.text+0x1f0): undefined reference to `__arm_smccc_smc'
Note that __arm_smccc_smc is defined when HAVE_ARM_SMCCC is y. So add dependency on HAVE_ARM_SMCCC in QCOM_SCM configuration.
--- drivers/firmware/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/firmware/Kconfig +1 -0
@@ -237,6 +237,7 @@ config INTEL_STRATIX10_RSU config QCOM_SCM bool depends on ARM || ARM64 + depends on HAVE_ARM_SMCCC select RESET_CONTROLLER config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 281/601 node: fix device cleanups in error handling code
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 4ce535ec0084f0d712317cb99d383cad3288e713 ]
We can't use kfree() to free device managed resources so the kfree(dev) is against the rules.
It's easier to write this code if we open code the device_register() as a device_initialize() and device_add(). That way if dev_set_name() set name fails we can call put_device() and it will clean up correctly.
--- drivers/base/node.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
drivers/base/node.c +12 -14
@@ -268,21 +268,20 @@ static void node_init_cache_dev(struct node *node)if (!dev)return ; +device_initialize (dev); dev->parent = &node->dev; dev->release = node_cache_release;if (dev_set_name (dev,"memory_side_cache" )) - goto free_dev; + goto put_device; -if (device_register (dev)) - goto free_name; +if (device_add (dev)) + goto put_device;pm_runtime_no_callbacks (dev); node->cache_dev = dev;return ; -free_name: -kfree_const (dev->kobj.name); -free_dev: -kfree (dev); +put_device: +put_device (dev); }/**
@@ -319,25 +318,24 @@ void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs)return ; dev = &info->dev; +device_initialize (dev); dev->parent = node->cache_dev; dev->release = node_cacheinfo_release; dev->groups = cache_groups;if (dev_set_name (dev,"index%d" , cache_attrs->level)) - goto free_cache; + goto put_device; info->cache_attrs = *cache_attrs; -if (device_register (dev)) { +if (device_add (dev)) {dev_warn (&node->dev,"failed to add cache level:%d\n" , cache_attrs->level); - goto free_name; + goto put_device; }pm_runtime_no_callbacks (dev);list_add_tail (&info->node, &node->cache_attrs);return ; -free_name: -kfree_const (dev->kobj.name); -free_cache: -kfree (info); +put_device: +put_device (dev); }static void node_remove_caches (struct node *node)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 282/601 crypto: chelsio - Read rxchannel-id from firmware
In reply to Greg Kroah-HartmanFrom: Ayush Sawal <[email protected]>
[ Upstream commit 16a9874fe468855e8ddd72883ca903f706d0a9d0 ]
The rxchannel id is updated by the driver using the port no value, but this does not ensure that the value is correct. So now rx channel value is obtained from etoc channel map value.
--- drivers/crypto/chelsio/chcr_algo.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +17 -2
@@ -769,13 +769,14 @@ static inline void create_wreq(struct chcr_context *ctx,struct uld_ctx *u_ctx =ULD_CTX (ctx);unsigned int tx_channel_id, rx_channel_id;unsigned int txqidx =0 , rxqidx =0 ; -unsigned int qid, fid; +unsigned int qid, fid, portno;get_qidxs (req, &txqidx, &rxqidx); qid = u_ctx->lldi.rxq_ids[rxqidx]; fid = u_ctx->lldi.rxq_ids[0 ]; + portno = rxqidx / ctx->rxq_perchan; tx_channel_id = txqidx / ctx->txq_perchan; - rx_channel_id = rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[portno]); chcr_req->wreq.op_to_cctx_size =FILL_WR_OP_CCTX_SIZE ;
@@ -806,6 +807,7 @@ static struct sk_buff *create_cipher_wr(struct cipher_wr_param *wrparam) {struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (wrparam->req);struct chcr_context *ctx =c_ctx (tfm); +struct uld_ctx *u_ctx =ULD_CTX (ctx);struct ablk_ctx *ablkctx =ABLK_CTX (ctx);struct sk_buff *skb =NULL ;struct chcr_wr *chcr_req;
@@ -822,6 +824,7 @@ static struct sk_buff *create_cipher_wr(struct cipher_wr_param *wrparam)struct adapter *adap =padap (ctx->dev);unsigned int rx_channel_id = reqctx->rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]); nents =sg_nents_xlen (reqctx->dstsg, wrparam->bytes,CHCR_DST_SG_SIZE , reqctx->dst_ofst); dst_size =get_space_for_phys_dsgl (nents);
@@ -1580,6 +1583,7 @@ static struct sk_buff *create_hash_wr(struct ahash_request *req,int error =0 ;unsigned int rx_channel_id = req_ctx->rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]); transhdr_len =HASH_TRANSHDR_SIZE (param->kctx_len); req_ctx->hctx_wr.imm = (transhdr_len + param->bfr_len + param->sg_len) <=SGE_MAX_WR_LEN ;
@@ -2438,6 +2442,7 @@ static struct sk_buff *create_authenc_wr(struct aead_request *req, {struct crypto_aead *tfm =crypto_aead_reqtfm (req);struct chcr_context *ctx =a_ctx (tfm); +struct uld_ctx *u_ctx =ULD_CTX (ctx);struct chcr_aead_ctx *aeadctx =AEAD_CTX (ctx);struct chcr_authenc_ctx *actx =AUTHENC_CTX (aeadctx);struct chcr_aead_reqctx *reqctx =aead_request_ctx (req);
@@ -2457,6 +2462,7 @@ static struct sk_buff *create_authenc_wr(struct aead_request *req,struct adapter *adap =padap (ctx->dev);unsigned int rx_channel_id = reqctx->rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]);if (req->cryptlen ==0 )return NULL ;
@@ -2710,9 +2716,11 @@ void chcr_add_aead_dst_ent(struct aead_request *req,struct dsgl_walk dsgl_walk;unsigned int authsize =crypto_aead_authsize (tfm);struct chcr_context *ctx =a_ctx (tfm); +struct uld_ctx *u_ctx =ULD_CTX (ctx);u32 temp;unsigned int rx_channel_id = reqctx->rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]);dsgl_walk_init (&dsgl_walk, phys_cpl);dsgl_walk_add_page (&dsgl_walk,IV + reqctx->b0_len, reqctx->iv_dma); temp = req->assoclen + req->cryptlen +
@@ -2752,9 +2760,11 @@ void chcr_add_cipher_dst_ent(struct skcipher_request *req,struct chcr_skcipher_req_ctx *reqctx =skcipher_request_ctx (req);struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (wrparam->req);struct chcr_context *ctx =c_ctx (tfm); +struct uld_ctx *u_ctx =ULD_CTX (ctx);struct dsgl_walk dsgl_walk;unsigned int rx_channel_id = reqctx->rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]);dsgl_walk_init (&dsgl_walk, phys_cpl);dsgl_walk_add_sg (&dsgl_walk, reqctx->dstsg, wrparam->bytes, reqctx->dst_ofst);
@@ -2958,6 +2968,7 @@ static void fill_sec_cpl_for_aead(struct cpl_tx_sec_pdu *sec_cpl, {struct crypto_aead *tfm =crypto_aead_reqtfm (req);struct chcr_context *ctx =a_ctx (tfm); +struct uld_ctx *u_ctx =ULD_CTX (ctx);struct chcr_aead_ctx *aeadctx =AEAD_CTX (ctx);struct chcr_aead_reqctx *reqctx =aead_request_ctx (req);unsigned int cipher_mode =CHCR_SCMD_CIPHER_MODE_AES_CCM ;
@@ -2967,6 +2978,8 @@ static void fill_sec_cpl_for_aead(struct cpl_tx_sec_pdu *sec_cpl,unsigned int tag_offset =0 , auth_offset =0 ;unsigned int assoclen; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]); +if (get_aead_subtype (tfm) ==CRYPTO_ALG_SUB_TYPE_AEAD_RFC4309 ) assoclen = req->assoclen -8 ;else
@@ -3127,6 +3140,7 @@ static struct sk_buff *create_gcm_wr(struct aead_request *req, {struct crypto_aead *tfm =crypto_aead_reqtfm (req);struct chcr_context *ctx =a_ctx (tfm); +struct uld_ctx *u_ctx =ULD_CTX (ctx);struct chcr_aead_ctx *aeadctx =AEAD_CTX (ctx);struct chcr_aead_reqctx *reqctx =aead_request_ctx (req);struct sk_buff *skb =NULL ;
@@ -3143,6 +3157,7 @@ static struct sk_buff *create_gcm_wr(struct aead_request *req,struct adapter *adap =padap (ctx->dev);unsigned int rx_channel_id = reqctx->rxqidx / ctx->rxq_perchan; + rx_channel_id =cxgb4_port_e2cchan (u_ctx->lldi.ports[rx_channel_id]);if (get_aead_subtype (tfm) ==CRYPTO_ALG_SUB_TYPE_AEAD_RFC4106 ) assoclen = req->assoclen -8 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 283/601 usbip: vudc: fix missing unlock on error in usbip_sockfd_store()
In reply to Greg Kroah-HartmanFrom: Ye Bin <[email protected]>
[ Upstream commit 1d08ed588c6a85a35a24c82eb4cf0807ec2b366a ]
Add the missing unlock before return from function usbip_sockfd_store() in the error handling case.
--- drivers/usb/usbip/vudc_sysfs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/usbip/vudc_sysfs.c +2 -0
@@ -156,12 +156,14 @@ static ssize_t usbip_sockfd_store(struct device *dev, tcp_rx =kthread_create (&v_rx_loop, &udc->ud,"vudc_rx" );if (IS_ERR (tcp_rx)) {sockfd_put (socket); +mutex_unlock (&udc->ud.sysfs_lock);return -EINVAL ; } tcp_tx =kthread_create (&v_tx_loop, &udc->ud,"vudc_tx" );if (IS_ERR (tcp_tx)) {kthread_stop (tcp_rx);sockfd_put (socket); +mutex_unlock (&udc->ud.sysfs_lock);return -EINVAL ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 284/601 m68k: Add missing mmap_read_lock() to sys_cacheflush()
In reply to Greg Kroah-HartmanFrom: Liam Howlett <[email protected]>
[ Upstream commit f829b4b212a315b912cb23fd10aaf30534bb5ce9 ]
When the superuser flushes the entire cache, the mmap_read_lock() is not taken, but mmap_read_unlock() is called. Add the missing mmap_read_lock() call.
--- arch/m68k/kernel/sys_m68k.c | 2 ++ 1 file changed, 2 insertions(+)
arch/m68k/kernel/sys_m68k.c +2 -0
@@ -388,6 +388,8 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) ret = -EPERM ;if (!capable (CAP_SYS_ADMIN )) goto out; + +mmap_read_lock (current->mm); }else {struct vm_area_struct *vma;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 285/601 spi: spi-zynqmp-gqspi: Fix missing unlock on error in zynqmp_qspi_exec_op()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit 6043357263fbe2df0bf0736d971ad5dce7d19dc1 ]
Add the missing unlock before return from function zynqmp_qspi_exec_op() in the error handling case.
--- drivers/spi/spi-zynqmp-gqspi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/spi/spi-zynqmp-gqspi.c +3 -1
@@ -965,8 +965,10 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,if (op->cmd.opcode) { tmpbuf =kzalloc (op->cmd.nbytes,GFP_KERNEL |GFP_DMA ); -if (!tmpbuf) +if (!tmpbuf) { +mutex_unlock (&xqspi->op_lock);return -ENOMEM ; + } tmpbuf[0 ] = op->cmd.opcode;reinit_completion (&xqspi->data_completion); xqspi->txbuf = tmpbuf;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 286/601 memory: renesas-rpc-if: fix possible NULL pointer dereference of resource
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 59e27d7c94aa02da039b000d33c304c179395801 ]
The platform_get_resource_byname() can return NULL which would be immediately dereferenced by resource_size(). Instead dereference it after validating the resource.
Addresses-Coverity: Dereference null return value
--- drivers/memory/renesas-rpc-if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/memory/renesas-rpc-if.c +1 -1
@@ -192,10 +192,10 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev) } res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"dirmap" ); - rpc->size =resource_size (res); rpc->dirmap =devm_ioremap_resource (&pdev->dev, res);if (IS_ERR (rpc->dirmap)) rpc->dirmap =NULL ; + rpc->size =resource_size (res); rpc->rstc =devm_reset_control_get_exclusive (&pdev->dev,NULL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 287/601 memory: samsung: exynos5422-dmc: handle clk_set_parent() failure
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 132c17c3ff878c7beaba51bdd275d5cc654c0e33 ]
clk_set_parent() can fail and ignoring such case could lead to invalid clock setup for given frequency.
Addresses-Coverity: Unchecked return value
--- drivers/memory/samsung/exynos5422-dmc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/memory/samsung/exynos5422-dmc.c +3 -1
@@ -1298,7 +1298,9 @@ static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc) dmc->curr_volt = target_volt; -clk_set_parent (dmc->mout_mx_mspll_ccore, dmc->mout_spll); + ret =clk_set_parent (dmc->mout_mx_mspll_ccore, dmc->mout_spll); +if (ret) +return ret;clk_prepare_enable (dmc->fout_bpll);clk_prepare_enable (dmc->mout_bpll);
Signature · 1 line
2.30.2