Commit ee98476b authored by Jaya Kumar's avatar Jaya Kumar Committed by Russell King
Browse files

[ARM] 5116/1: pxafb: cleanup and fix order of failure handling



This issue was found by Krzysztof Helt and Eric Miao.

pxafb had issues in the order with which it cleaned up if errors occurred
during a probe. This patch reorders the failure handling sequence and also
frees the cmap and clk.

Signed-off-by: default avatarJaya Kumar <jayakumar.lkml@gmail.com>
Acked-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Acked-by: default avatarEric Miao <eric.miao@marvell.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f1edfc42
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -1685,14 +1685,14 @@ static int __init pxafb_probe(struct platform_device *dev)
	if (r == NULL) {
		dev_err(&dev->dev, "no I/O memory resource defined\n");
		ret = -ENODEV;
		goto failed;
		goto failed_fbi;
	}

	r = request_mem_region(r->start, r->end - r->start + 1, dev->name);
	if (r == NULL) {
		dev_err(&dev->dev, "failed to request I/O memory\n");
		ret = -EBUSY;
		goto failed;
		goto failed_fbi;
	}

	fbi->mmio_base = ioremap(r->start, r->end - r->start + 1);
@@ -1735,8 +1735,17 @@ static int __init pxafb_probe(struct platform_device *dev)
	 * This makes sure that our colour bitfield
	 * descriptors are correctly initialised.
	 */
	pxafb_check_var(&fbi->fb.var, &fbi->fb);
	pxafb_set_par(&fbi->fb);
	ret = pxafb_check_var(&fbi->fb.var, &fbi->fb);
	if (ret) {
		dev_err(&dev->dev, "failed to get suitable mode\n");
		goto failed_free_irq;
	}

	ret = pxafb_set_par(&fbi->fb);
	if (ret) {
		dev_err(&dev->dev, "Failed to set parameters\n");
		goto failed_free_irq;
	}

	platform_set_drvdata(dev, fbi);

@@ -1744,7 +1753,7 @@ static int __init pxafb_probe(struct platform_device *dev)
	if (ret < 0) {
		dev_err(&dev->dev,
			"Failed to register framebuffer device: %d\n", ret);
		goto failed_free_irq;
		goto failed_free_cmap;
	}

#ifdef CONFIG_CPU_FREQ
@@ -1763,18 +1772,23 @@ static int __init pxafb_probe(struct platform_device *dev)

	return 0;

failed_free_cmap:
	if (fbi->fb.cmap.len)
		fb_dealloc_cmap(&fbi->fb.cmap);
failed_free_irq:
	free_irq(irq, fbi);
failed_free_res:
	release_mem_region(r->start, r->end - r->start + 1);
failed_free_io:
	iounmap(fbi->mmio_base);
failed_free_mem:
	dma_free_writecombine(&dev->dev, fbi->map_size,
			fbi->map_cpu, fbi->map_dma);
failed:
failed_free_io:
	iounmap(fbi->mmio_base);
failed_free_res:
	release_mem_region(r->start, r->end - r->start + 1);
failed_fbi:
	clk_put(fbi->clk);
	platform_set_drvdata(dev, NULL);
	kfree(fbi);
failed:
	return ret;
}