MIPS: SGI-IP27: Fix platform-device leak in bridge_platform_create()
In error case in bridge_platform_create after calling
platform_device_add()/platform_device_add_data()/
platform_device_add_resources(), release the failed
'pdev' or it will be leak, call platform_device_put()
to fix this problem.
Besides, 'pdev' is divided into 'pdev_wd' and 'pdev_bd',
use platform_device_unregister() to release sgi_w1
resources when xtalk-bridge registration fails.
Fixes: 5dc76a96e9
("MIPS: PCI: use information from 1-wire PROM for IOC3 detection")
Signed-off-by: Lin Yujun <linyujun809@huawei.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
parent
1e6d11fe72
commit
11bec9cba4
|
@ -27,15 +27,18 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
|
|||
{
|
||||
struct xtalk_bridge_platform_data *bd;
|
||||
struct sgi_w1_platform_data *wd;
|
||||
struct platform_device *pdev;
|
||||
struct platform_device *pdev_wd;
|
||||
struct platform_device *pdev_bd;
|
||||
struct resource w1_res;
|
||||
unsigned long offset;
|
||||
|
||||
offset = NODE_OFFSET(nasid);
|
||||
|
||||
wd = kzalloc(sizeof(*wd), GFP_KERNEL);
|
||||
if (!wd)
|
||||
goto no_mem;
|
||||
if (!wd) {
|
||||
pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
|
||||
offset + (widget << SWIN_SIZE_BITS));
|
||||
|
@ -46,24 +49,35 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
|
|||
w1_res.end = w1_res.start + 3;
|
||||
w1_res.flags = IORESOURCE_MEM;
|
||||
|
||||
pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
|
||||
if (!pdev) {
|
||||
kfree(wd);
|
||||
goto no_mem;
|
||||
pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
|
||||
if (!pdev_wd) {
|
||||
pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
|
||||
goto err_kfree_wd;
|
||||
}
|
||||
if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
|
||||
pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget);
|
||||
goto err_put_pdev_wd;
|
||||
}
|
||||
if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
|
||||
pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
|
||||
goto err_put_pdev_wd;
|
||||
}
|
||||
if (platform_device_add(pdev_wd)) {
|
||||
pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
|
||||
goto err_put_pdev_wd;
|
||||
}
|
||||
platform_device_add_resources(pdev, &w1_res, 1);
|
||||
platform_device_add_data(pdev, wd, sizeof(*wd));
|
||||
/* platform_device_add_data() duplicates the data */
|
||||
kfree(wd);
|
||||
platform_device_add(pdev);
|
||||
|
||||
bd = kzalloc(sizeof(*bd), GFP_KERNEL);
|
||||
if (!bd)
|
||||
goto no_mem;
|
||||
pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
|
||||
if (!pdev) {
|
||||
kfree(bd);
|
||||
goto no_mem;
|
||||
if (!bd) {
|
||||
pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
|
||||
goto err_unregister_pdev_wd;
|
||||
}
|
||||
pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
|
||||
if (!pdev_bd) {
|
||||
pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
|
||||
goto err_kfree_bd;
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,15 +98,31 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
|
|||
bd->io.flags = IORESOURCE_IO;
|
||||
bd->io_offset = offset;
|
||||
|
||||
platform_device_add_data(pdev, bd, sizeof(*bd));
|
||||
if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
|
||||
pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
|
||||
goto err_put_pdev_bd;
|
||||
}
|
||||
if (platform_device_add(pdev_bd)) {
|
||||
pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
|
||||
goto err_put_pdev_bd;
|
||||
}
|
||||
/* platform_device_add_data() duplicates the data */
|
||||
kfree(bd);
|
||||
platform_device_add(pdev);
|
||||
pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget);
|
||||
return;
|
||||
|
||||
no_mem:
|
||||
pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
|
||||
err_put_pdev_bd:
|
||||
platform_device_put(pdev_bd);
|
||||
err_kfree_bd:
|
||||
kfree(bd);
|
||||
err_unregister_pdev_wd:
|
||||
platform_device_unregister(pdev_wd);
|
||||
return;
|
||||
err_put_pdev_wd:
|
||||
platform_device_put(pdev_wd);
|
||||
err_kfree_wd:
|
||||
kfree(wd);
|
||||
return;
|
||||
}
|
||||
|
||||
static int probe_one_port(nasid_t nasid, int widget, int masterwid)
|
||||
|
|
Loading…
Reference in New Issue