History

tty: serial: fsl_lpuart: free IDs allocated by IDA

Since commit 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node dependence") the port line number can also be allocated by IDA, but in case of an error the ID will no be removed again. More importantly, any ID will be freed in remove(), even if it wasn't allocated but instead fetched by of_alias_get_id(). If it was not allocated by IDA there will be a warning: WARN(1, "ida_free called for id=%d which is not allocated.\n", id); Move the ID allocation more to the end of the probe() so that we still can use plain return in the first error cases.

Michael Walle committed 6 years ago

Commit 2b2e71f1 parent 0e28ed61 file · +24 −15Browse files

Unified · Split

drivers/tty/serial/fsl_lpuart.c+24−15
@@ -264,6 +264,7 @@ struct lpuart_port { · 263 unmodified lines
264 int rx_dma_rng_buf_len;264 int rx_dma_rng_buf_len;
265 unsigned int dma_tx_nents;265 unsigned int dma_tx_nents;
266 wait_queue_head_t dma_wait;266 wait_queue_head_t dma_wait;
267 bool id_allocated;
267};268};
268 269
269struct lpuart_soc_data {270struct lpuart_soc_data {
@@ -2422,19 +2423,6 @@ static int lpuart_probe(struct platform_device *pdev) · 2152 unmodified lines
2422 if (!sport)2423 if (!sport)
2423 return -ENOMEM;2424 return -ENOMEM;
2424 2425
2425 ret = of_alias_get_id(np, "serial");
2426 if (ret < 0) {
2427 ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
2428 if (ret < 0) {
2429 dev_err(&pdev->dev, "port line is full, add device failed\n");
2430 return ret;
2431 }
2432 }
2433 if (ret >= ARRAY_SIZE(lpuart_ports)) {
2434 dev_err(&pdev->dev, "serial%d out of range\n", ret);
2435 return -EINVAL;
2436 }
2437 sport->port.line = ret;
2438 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);2426 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2439 sport->port.membase = devm_ioremap_resource(&pdev->dev, res);2427 sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
2440 if (IS_ERR(sport->port.membase))2428 if (IS_ERR(sport->port.membase))
@@ -2479,9 +2467,25 @@ static int lpuart_probe(struct platform_device *pdev) · 38 unmodified lines
2479 }2467 }
2480 }2468 }
2481 2469
2470 ret = of_alias_get_id(np, "serial");
2471 if (ret < 0) {
2472 ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
2473 if (ret < 0) {
2474 dev_err(&pdev->dev, "port line is full, add device failed\n");
2475 return ret;
2476 }
2477 sport->id_allocated = true;
2478 }
2479 if (ret >= ARRAY_SIZE(lpuart_ports)) {
2480 dev_err(&pdev->dev, "serial%d out of range\n", ret);
2481 ret = -EINVAL;
2482 goto failed_out_of_range;
2483 }
2484 sport->port.line = ret;
2485
2482 ret = lpuart_enable_clks(sport);2486 ret = lpuart_enable_clks(sport);
2483 if (ret)2487 if (ret)
2484 return ret;2488 goto failed_clock_enable;
2485 sport->port.uartclk = lpuart_get_baud_clk_rate(sport);2489 sport->port.uartclk = lpuart_get_baud_clk_rate(sport);
2486 2490
2487 lpuart_ports[sport->port.line] = sport;2491 lpuart_ports[sport->port.line] = sport;
@@ -2531,6 +2535,10 @@ static int lpuart_probe(struct platform_device *pdev) · 43 unmodified lines
2531failed_attach_port:2535failed_attach_port:
2532failed_irq_request:2536failed_irq_request:
2533 lpuart_disable_clks(sport);2537 lpuart_disable_clks(sport);
2538failed_clock_enable:
2539failed_out_of_range:
2540 if (sport->id_allocated)
2541 ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
2534 return ret;2542 return ret;
2535}2543}
2536 2544
@@ -2540,7 +2548,8 @@ static int lpuart_remove(struct platform_device *pdev) · 3 unmodified lines
2540 2548
2541 uart_remove_one_port(&lpuart_reg, &sport->port);2549 uart_remove_one_port(&lpuart_reg, &sport->port);
2542 2550
2543 ida_simple_remove(&fsl_lpuart_ida, sport->port.line);2551 if (sport->id_allocated)
2552 ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
2544 2553
2545 lpuart_disable_clks(sport);2554 lpuart_disable_clks(sport);
2546 2555

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t