Commit 388bc262 authored by Shubhrajyoti D's avatar Shubhrajyoti D Committed by Greg Kroah-Hartman

omap-serial: Fix the error handling in the omap_serial probe

The patch does the following

- The pm_runtime_disable is called in the remove not in the error
  case of probe.The patch calls the pm_runtime_disable in the error
  case.
- Calls pm_runtime_put in the error case.
- The  up is not freed in the error path. Fix the memory leak by using
  devm_* so that the memory need not be freed in the driver.
- Also the iounmap is not called fix the same by calling using devm_ioremap.
- Make the name of the error tags more meaningful.

Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Govindraj.R <govindraj.raja@ti.com>
Signed-off-by: default avatarShubhrajyoti D <shubhrajyoti@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c3d8b76f
...@@ -1381,29 +1381,24 @@ static int serial_omap_probe(struct platform_device *pdev) ...@@ -1381,29 +1381,24 @@ static int serial_omap_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
if (!request_mem_region(mem->start, resource_size(mem), if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
pdev->dev.driver->name)) { pdev->dev.driver->name)) {
dev_err(&pdev->dev, "memory region already claimed\n"); dev_err(&pdev->dev, "memory region already claimed\n");
return -EBUSY; return -EBUSY;
} }
dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
if (!dma_rx) { if (!dma_rx)
ret = -EINVAL; return -ENXIO;
goto err;
}
dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
if (!dma_tx) { if (!dma_tx)
ret = -EINVAL; return -ENXIO;
goto err;
} up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL);
if (!up)
return -ENOMEM;
up = kzalloc(sizeof(*up), GFP_KERNEL);
if (up == NULL) {
ret = -ENOMEM;
goto do_release_region;
}
up->pdev = pdev; up->pdev = pdev;
up->port.dev = &pdev->dev; up->port.dev = &pdev->dev;
up->port.type = PORT_OMAP; up->port.type = PORT_OMAP;
...@@ -1423,16 +1418,17 @@ static int serial_omap_probe(struct platform_device *pdev) ...@@ -1423,16 +1418,17 @@ static int serial_omap_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
up->port.line); up->port.line);
ret = -ENODEV; ret = -ENODEV;
goto err; goto err_port_line;
} }
sprintf(up->name, "OMAP UART%d", up->port.line); sprintf(up->name, "OMAP UART%d", up->port.line);
up->port.mapbase = mem->start; up->port.mapbase = mem->start;
up->port.membase = ioremap(mem->start, resource_size(mem)); up->port.membase = devm_ioremap(&pdev->dev, mem->start,
resource_size(mem));
if (!up->port.membase) { if (!up->port.membase) {
dev_err(&pdev->dev, "can't ioremap UART\n"); dev_err(&pdev->dev, "can't ioremap UART\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err_ioremap;
} }
up->port.flags = omap_up_info->flags; up->port.flags = omap_up_info->flags;
...@@ -1478,16 +1474,19 @@ static int serial_omap_probe(struct platform_device *pdev) ...@@ -1478,16 +1474,19 @@ static int serial_omap_probe(struct platform_device *pdev)
ret = uart_add_one_port(&serial_omap_reg, &up->port); ret = uart_add_one_port(&serial_omap_reg, &up->port);
if (ret != 0) if (ret != 0)
goto do_release_region; goto err_add_port;
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
platform_set_drvdata(pdev, up); platform_set_drvdata(pdev, up);
return 0; return 0;
err:
err_add_port:
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
err_ioremap:
err_port_line:
dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
pdev->id, __func__, ret); pdev->id, __func__, ret);
do_release_region:
release_mem_region(mem->start, resource_size(mem));
return ret; return ret;
} }
...@@ -1499,8 +1498,6 @@ static int serial_omap_remove(struct platform_device *dev) ...@@ -1499,8 +1498,6 @@ static int serial_omap_remove(struct platform_device *dev)
pm_runtime_disable(&up->pdev->dev); pm_runtime_disable(&up->pdev->dev);
uart_remove_one_port(&serial_omap_reg, &up->port); uart_remove_one_port(&serial_omap_reg, &up->port);
pm_qos_remove_request(&up->pm_qos_request); pm_qos_remove_request(&up->pm_qos_request);
kfree(up);
} }
platform_set_drvdata(dev, NULL); platform_set_drvdata(dev, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment