Gentle ping... > -----Original Message----- > From: Sherry Sun > Sent: 2022年3月21日 19:25 > To: gregkh@xxxxxxxxxxxxxxxxxxx; jirislaby@xxxxxxxxxx; Vabhav Sharma > <vabhav.sharma@xxxxxxx> > Cc: linux-serial@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; dl-linux-imx > <linux-imx@xxxxxxx> > Subject: [PATCH] tty: serial: fsl_lpuart: fix potential bug when using both > of_alias_get_id and ida_simple_get > > Now fsl_lpuart driver use both of_alias_get_id() and ida_simple_get() > in .probe(), which has the potential bug. For example, when remove the > lpuart7 alias in dts, of_alias_get_id() will return error, then call > ida_simple_get() to allocate the id 0 for lpuart7, this may confilct with the > lpuart4 which has alias 0. > > aliases { > ... > serial0 = &lpuart4; > serial1 = &lpuart5; > serial2 = &lpuart6; > serial3 = &lpuart7; > } > > So remove the ida_simple_get() in .probe(), return an error directly when > calling of_alias_get_id() fails, which is consistent with other uart drivers > behavior. > > Fixes: 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node dependence") > Signed-off-by: Sherry Sun <sherry.sun@xxxxxxx> > --- > drivers/tty/serial/fsl_lpuart.c | 24 ++++-------------------- > 1 file changed, 4 insertions(+), 20 deletions(-) > > diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c > index 452a015825ba..40465d23d7ad 100644 > --- a/drivers/tty/serial/fsl_lpuart.c > +++ b/drivers/tty/serial/fsl_lpuart.c > @@ -239,8 +239,6 @@ > /* IMX lpuart has four extra unused regs located at the beginning */ > #define IMX_REG_OFF 0x10 > > -static DEFINE_IDA(fsl_lpuart_ida); > - > enum lpuart_type { > VF610_LPUART, > LS1021A_LPUART, > @@ -276,7 +274,6 @@ struct lpuart_port { > int rx_dma_rng_buf_len; > unsigned int dma_tx_nents; > wait_queue_head_t dma_wait; > - bool id_allocated; > }; > > struct lpuart_soc_data { > @@ -2716,23 +2713,18 @@ static int lpuart_probe(struct platform_device > *pdev) > > ret = of_alias_get_id(np, "serial"); > if (ret < 0) { > - ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, > GFP_KERNEL); > - if (ret < 0) { > - dev_err(&pdev->dev, "port line is full, add device > failed\n"); > - return ret; > - } > - sport->id_allocated = true; > + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); > + return ret; > } > if (ret >= ARRAY_SIZE(lpuart_ports)) { > dev_err(&pdev->dev, "serial%d out of range\n", ret); > - ret = -EINVAL; > - goto failed_out_of_range; > + return -EINVAL; > } > sport->port.line = ret; > > ret = lpuart_enable_clks(sport); > if (ret) > - goto failed_clock_enable; > + return ret; > sport->port.uartclk = lpuart_get_baud_clk_rate(sport); > > lpuart_ports[sport->port.line] = sport; @@ -2781,10 +2773,6 @@ > static int lpuart_probe(struct platform_device *pdev) > failed_attach_port: > failed_irq_request: > lpuart_disable_clks(sport); > -failed_clock_enable: > -failed_out_of_range: > - if (sport->id_allocated) > - ida_simple_remove(&fsl_lpuart_ida, sport->port.line); > return ret; > } > > @@ -2794,9 +2782,6 @@ static int lpuart_remove(struct platform_device > *pdev) > > uart_remove_one_port(&lpuart_reg, &sport->port); > > - if (sport->id_allocated) > - ida_simple_remove(&fsl_lpuart_ida, sport->port.line); > - > lpuart_disable_clks(sport); > > if (sport->dma_tx_chan) > @@ -2926,7 +2911,6 @@ static int __init lpuart_serial_init(void) > > static void __exit lpuart_serial_exit(void) { > - ida_destroy(&fsl_lpuart_ida); > platform_driver_unregister(&lpuart_driver); > uart_unregister_driver(&lpuart_reg); > } > -- > 2.17.1