Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bed9055 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Paul Mundt
Browse files

sh: fix a number of Oopses and leaks in SH framebuffer driver



Fix a number of Oopses, memory leaks and unbalanced calls on error paths in
sh_mobile_lcdcfb.c.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 83515bc7
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -695,6 +695,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
	 * 1) Enable Runtime PM
	 * 2) Force Runtime PM Resume since hardware is accessed from probe()
	 */
	priv->dev = &pdev->dev;
	pm_runtime_enable(priv->dev);
	pm_runtime_resume(priv->dev);
	return 0;
@@ -957,25 +958,24 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)

	if (!pdev->dev.platform_data) {
		dev_err(&pdev->dev, "no platform data defined\n");
		error = -EINVAL;
		goto err0;
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i = platform_get_irq(pdev, 0);
	if (!res || i < 0) {
		dev_err(&pdev->dev, "cannot get platform resources\n");
		error = -ENOENT;
		goto err0;
		return -ENOENT;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "cannot allocate device data\n");
		error = -ENOMEM;
		goto err0;
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, priv);

	error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
			    dev_name(&pdev->dev), priv);
	if (error) {
@@ -984,8 +984,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
	}

	priv->irq = i;
	priv->dev = &pdev->dev;
	platform_set_drvdata(pdev, priv);
	pdata = pdev->dev.platform_data;

	j = 0;
@@ -1099,9 +1097,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
		info = ch->info;

		if (info->fbdefio) {
			priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
			ch->sglist = vmalloc(sizeof(struct scatterlist) *
					info->fix.smem_len >> PAGE_SHIFT);
			if (!priv->ch->sglist) {
			if (!ch->sglist) {
				dev_err(&pdev->dev, "cannot allocate sglist\n");
				goto err1;
			}
@@ -1128,7 +1126,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
	return 0;
err1:
	sh_mobile_lcdc_remove(pdev);
 err0:

	return error;
}

@@ -1139,7 +1137,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
	int i;

	for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
		if (priv->ch[i].info->dev)
		if (priv->ch[i].info && priv->ch[i].info->dev)
			unregister_framebuffer(priv->ch[i].info);

	sh_mobile_lcdc_stop(priv);
@@ -1162,6 +1160,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
	if (priv->dot_clk)
		clk_put(priv->dot_clk);

	if (priv->dev)
		pm_runtime_disable(priv->dev);

	if (priv->base)