linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] use devm_ functions
@ 2012-01-24 13:00 Julia Lawall
  2012-01-24 13:00 ` [PATCH] drivers/video/omap2/dss: " Julia Lawall
  0 siblings, 1 reply; 3+ messages in thread
From: Julia Lawall @ 2012-01-24 13:00 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel-janitors, Florian Tobias Schandinat, linux-omap,
	linux-fbdev, linux-kernel

The semantic patch (http://coccinelle.lip6.fr/) used in generating this
patch is as follows.  Some manual cleanup was required.

virtual after_start
virtual returned
virtual arg
virtual get

virtual drop_labels

// ---------------------------------------------------------------------
// find functions

@plat depends on !after_start@
identifier i,pfn,rfn;
position p;
@@

struct platform_driver i@p = {
  .probe = pfn,
  .remove = (<+...rfn...+>),
};

// ---------------------------------------------------------------------
// set up iteration

@initialize:ocaml@

let drop_labels = ref false

type ret = UseReturned | UseReturned2 of string | UseArg | UseGet

let add pfn rfn alloc free devm_alloc file rule =
   let it = new iteration() in
   it#set_files [file];
   it#add_virtual_rule After_start;
   (if !drop_labels then it#add_virtual_rule Drop_labels);
   (match rule with
      UseReturned -> it#add_virtual_rule Returned
    | UseReturned2(free) -> it#add_virtual_rule Returned;
      it#add_virtual_identifier Second_free free
    | UseArg -> it#add_virtual_rule Arg
    | UseGet -> it#add_virtual_rule Get);
   it#add_virtual_identifier Pfn pfn;
   it#add_virtual_identifier Rfn rfn;
   it#add_virtual_identifier Alloc alloc;
   it#add_virtual_identifier Free free;
   it#add_virtual_identifier Devm_alloc devm_alloc;
   it#register()

@script:ocaml depends on drop_labels@
@@

drop_labels := true

@script:ocaml@
pfn << plat.pfn;
rfn << plat.rfn;
p << plat.p;
@@

let file = (List.hd p).file in
add pfn rfn "kmalloc" "kfree" "devm_kzalloc" file UseReturned;
add pfn rfn "kzalloc" "kfree" "devm_kzalloc" file UseReturned;
add pfn rfn "ioremap" "iounmap" "devm_ioremap" file UseReturned;
add pfn rfn "ioremap_nocache" "iounmap" "devm_ioremap_nocache" file
   UseReturned;

add pfn rfn "request_irq" "free_irq" "devm_request_irq" file UseArg;
add pfn rfn "request_threaded_irq" "free_irq" "devm_request_threaded_irq" file
  UseArg;
add pfn rfn "dma_alloc_coherent" "dma_free_coherent" "dmam_alloc_coherent"
  file UseArg;
add pfn rfn "dma_alloc_noncoherent" "dma_free_noncoherent"
  "dmam_alloc_noncoherent" file UseArg;

(* several possibilities... *)
add pfn rfn "request_region" "release_region" "devm_request_region" file
  UseGet;
add pfn rfn "request_mem_region" "release_mem_region"
  "devm_request_mem_region" file UseGet;
add pfn rfn "request_region" "release_region" "devm_request_region" file
  UseArg;
add pfn rfn "request_mem_region" "release_mem_region"
  "devm_request_mem_region" file UseArg;
(* fix a bug at the same time *)
add pfn rfn "request_region" "release_resource" "devm_request_region" file
  (UseReturned2("kfree"));
add pfn rfn "request_mem_region" "release_resource"
  "devm_request_mem_region" file (UseReturned2("kfree"));
add pfn rfn "ioport_map" "ioport_unmap" "devm_ioport_map" file UseReturned

// ---------------------------------------------------------------------
// process the initial definition of the probe function

@preprobe@
identifier virtual.pfn;
position p;
@@

pfn@p(...) { ... }

@probe@
identifier pfn;
position preprobe.p;
@@

pfn@p(...) { ... }

@labelled_return@
identifier probe.pfn,l;
expression e;
@@

pfn(...) { <+... l: return e; ...+> }

// ---------------------------------------------------------------------
// transform functions where free uses the result

@prb depends on returned exists@
identifier probe.pfn,pdev,virtual.alloc,virtual.free,virtual.second_free;
expression x;
expression list args;
position p1,p2,p3;
type T1,T2,T3;
@@

pfn(struct platform_device *pdev) { ... when any
x = (T1)alloc@p1(args)
<... when strict
     when any
     when forall
(
free@p2((T2)x,...);
... when != x
second_free@p3((T3)x,...);
|
free@p2((T2)x,...);
)
...>
}

@reme exists@
identifier virtual.rfn,virtual.free;
expression prb.x;
type T;
@@

rfn(...) { ... free((T)x,...); ... }

@rem depends on reme@
identifier virtual.rfn,virtual.free,virtual.second_free;
expression prb.x;
position p4,p5;
type T,T1;
@@

rfn(...) {
<... when strict
(
free@p4((T)x,...);
... when != x
second_free@p5((T1)x,...);
|
free@p4((T)x,...);
)
...>
}

@bad@
identifier virtual.free;
expression prb.x;
position p != {prb.p2,rem.p4};
type T;
@@

free@p((T)x,...)

@modif depends on rem && !bad@
expression x;
identifier prb.pdev,virtual.alloc,virtual.free,virtual.devm_alloc;
identifier virtual.second_free;
expression list args;
position prb.p1,prb.p2,prb.p3,rem.p4,rem.p5;
type T;
@@

(
- free@p2(...);
|
- second_free@p3(...);
|
- free@p4(...);
|
- second_free@p5(...);
|
  x =
- alloc@p1(
+ devm_alloc(&pdev->dev,
    args)
|
  x = 
- (T)alloc@p1(
+ (T)devm_alloc(&pdev->dev,
    args)
)

// ---------------------------------------------------------------------
// transform functions where free uses the first argument

@prbx depends on arg exists@
identifier probe.pfn,pdev,virtual.alloc,virtual.free;
expression x;
expression list args;
position p1,p2;
@@

pfn(struct platform_device *pdev) { ... when any
alloc@p1(x,args)
<... when strict
     when any
     when forall
free@p2(x,...)
...>
}

@remxe exists@
identifier virtual.rfn, virtual.free;
expression prbx.x;
@@

rfn(...) { ... free(x,...); ... }

@remx depends on remxe@
identifier virtual.rfn, virtual.free;
expression prbx.x;
position p3;
@@

rfn(...) {
<... when strict
free@p3(x,...)
...>
}

@badx@
identifier virtual.free;
expression prbx.x;
position p != {prbx.p2,remx.p3};
@@

free@p(x,...)

@modifx depends on remx && !badx@
expression x;
identifier prbx.pdev,virtual.alloc,virtual.free,virtual.devm_alloc;
expression list args;
position prbx.p1,prbx.p2,remx.p3;
@@

(
- free@p2(...);
|
- free@p3(...);
|
- alloc@p1(
+ devm_alloc(&pdev->dev,
   x,args)
)

// ---------------------------------------------------------------------
// transform functions where free uses the result of platform_get_resource

@prbg depends on get exists@
identifier probe.pfn,pdev,virtual.alloc,virtual.free;
expression x;
expression list args;
position p1,p2;
@@

pfn(struct platform_device *pdev) { ... when any
alloc@p1(x,args)
<... when strict
     when any
     when forall
free@p2(x,...)
...>
}

@remge exists@
identifier virtual.rfn, virtual.free;
identifier y;
identifier pdev;
@@

rfn(struct platform_device *pdev) { ... when any
y = platform_get_resource(pdev, IORESOURCE_MEM, 0)
...
free(y->start,...)
...
}

@remg depends on remge@
identifier virtual.rfn, virtual.free;
identifier y;
identifier pdev;
position p3;
@@

rfn(struct platform_device *pdev) {
<... when strict
y = platform_get_resource(pdev, IORESOURCE_MEM, 0)
... when strict
free@p3(y->start,...)
...>
}

@badg@
identifier virtual.free;
position p != {prbg.p2,remg.p3};
@@

free@p(...)

@modifg depends on remg && !badg@
expression x;
identifier prbg.pdev,virtual.alloc,virtual.free,virtual.devm_alloc;
expression list args;
position prbg.p1,prbg.p2,remg.p3;
@@

(
- free@p2(...);
|
- free@p3(...);
|
- alloc@p1(
+ devm_alloc(&pdev->dev,
   x,args)
)

// ---------------------------------------------------------------------
// cleanup, if the drvdata was only used to enable the free
// probably only relevant for kmalloc/kzalloc

@dclean depends on modif || modifx || modifg@
identifier virtual.rfn, pdev, i;
type T;
@@

rfn(struct platform_device *pdev) { ...
(
- T i = platform_get_drvdata(pdev);
|
- T i = dev_get_drvdata(&pdev->drv);
|
- T i;
  ... when != i
(
- i = platform_get_drvdata(pdev);
|
- i = dev_get_drvdata(&pdev->drv);
)
)
... when != i
}

@rclean depends on modif || modifx || modifg@
identifier virtual.rfn, pdev, i;
type T;
@@

rfn(struct platform_device *pdev) { ...
(
- T i = platform_get_resource(pdev,...);
|
- T i;
  ... when != i
- i = platform_get_resource(pdev,...);
)
... when != i
}

// ---------------------------------------------------------------------
// cleanup empty ifs, etc

@depends on modif || modifx || modifg@
identifier probe.pfn;
@@

pfn(...) { <...
- if (...) {}
...> }

@depends on modif || modifx || modifg@
identifier virtual.rfn;
@@

rfn(...) { <...
- if (...) {}
...> }

@depends on modif || modifx || modifg@
identifier probe.pfn;
expression ret,e;
@@

pfn(...) { <...
+ return
- ret =
 e;
- return ret;
...> }

@depends on modif || modifx || modifg@
identifier virtual.rfn;
expression ret,e;
@@

rfn(...) { <...
+ return
- ret =
 e;
- return ret;
...> }

// ---------------------------------------------------------------------

// this is likely to leave dead code, if l: is preceded by a return
// because we are control-flow based, there is no way to match on that
@depends on drop_labels && labelled_return && (modif || modifx || modifg)@
identifier l,l1,l2;
expression e;
statement S;
identifier probe.pfn;
identifier i;
statement S1,S2;
@@

pfn(...) { <...
- goto l;
+ goto l2;
...
-l:
<... when != S
     when any
l1:
...>
l2:
(
 (<+...i...+>);
|
 if (...) S1 else S2
|
 while (...) S1
|
 for (...;...;...) S1
|
 return e;
)
...> }

@depends on drop_labels && !labelled_return && (modif || modifx || modifg)@
identifier l,l1,l2;
expression e;
statement S;
identifier probe.pfn;
identifier i;
statement S1,S2;
@@

pfn(...) { <...
(
- goto l;
+ goto l2;
...
-l:
<... when != S
     when any
l1:
...>
l2:
(
 (<+...i...+>);
|
 if (...) S1 else S2
|
 while (...) S1
|
 for (...;...;...) S1
)
|
- goto l;
+ return e;
...
-l:
<... when != S
     when any
l1:
...>
return e;
)
...> }


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] drivers/video/omap2/dss: use devm_ functions
  2012-01-24 13:00 [PATCH] use devm_ functions Julia Lawall
@ 2012-01-24 13:00 ` Julia Lawall
  2012-01-25  8:30   ` Tomi Valkeinen
  0 siblings, 1 reply; 3+ messages in thread
From: Julia Lawall @ 2012-01-24 13:00 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: kernel-janitors, Florian Tobias Schandinat, linux-omap,
	linux-fbdev, linux-kernel

From: Julia Lawall <Julia.Lawall@lip6.fr>

The various devm_ functions allocate memory that is released when a driver
detaches.  This patch uses these functions for data that is allocated in
the probe function of a platform device and is only freed in the remove
function.

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>

---
 drivers/video/omap2/dss/dispc.c |   16 ++++++----------
 drivers/video/omap2/dss/dsi.c   |   28 +++++++++-------------------
 drivers/video/omap2/dss/dss.c   |    9 +++------
 drivers/video/omap2/dss/rfbi.c  |    5 ++---
 drivers/video/omap2/dss/venc.c  |    8 +++-----
 5 files changed, 23 insertions(+), 43 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a5ec7f3..6fa866a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3322,7 +3322,8 @@ static int omap_dispchw_probe(struct platform_device *pdev)
 		r = -EINVAL;
 		goto err_ioremap;
 	}
-	dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
+	dispc.base = devm_ioremap(&pdev->dev, dispc_mem->start,
+				  resource_size(dispc_mem));
 	if (!dispc.base) {
 		DSSERR("can't ioremap DISPC\n");
 		r = -ENOMEM;
@@ -3332,14 +3333,14 @@ static int omap_dispchw_probe(struct platform_device *pdev)
 	if (dispc.irq < 0) {
 		DSSERR("platform_get_irq failed\n");
 		r = -ENODEV;
-		goto err_irq;
+		goto err_ioremap;
 	}
 
-	r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
-		"OMAP DISPC", dispc.pdev);
+	r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
+			     IRQF_SHARED, "OMAP DISPC", dispc.pdev);
 	if (r < 0) {
 		DSSERR("request_irq failed\n");
-		goto err_irq;
+		goto err_ioremap;
 	}
 
 	pm_runtime_enable(&pdev->dev);
@@ -3362,9 +3363,6 @@ static int omap_dispchw_probe(struct platform_device *pdev)
 
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
-	free_irq(dispc.irq, dispc.pdev);
-err_irq:
-	iounmap(dispc.base);
 err_ioremap:
 	clk_put(dispc.dss_clk);
 err_get_clk:
@@ -3377,8 +3375,6 @@ static int omap_dispchw_remove(struct platform_device *pdev)
 
 	clk_put(dispc.dss_clk);
 
-	free_irq(dispc.irq, dispc.pdev);
-	iounmap(dispc.base);
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d4d676c..52b9359 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4695,7 +4695,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 	struct resource *dsi_mem;
 	struct dsi_data *dsi;
 
-	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
+	dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
 	if (!dsi) {
 		r = -ENOMEM;
 		goto err_alloc;
@@ -4724,7 +4724,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 
 	r = dsi_get_clocks(dsidev);
 	if (r)
-		goto err_get_clk;
+		goto err_alloc;
 
 	pm_runtime_enable(&dsidev->dev);
 
@@ -4742,7 +4742,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 		r = -EINVAL;
 		goto err_ioremap;
 	}
-	dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem));
+	dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
+				 resource_size(dsi_mem));
 	if (!dsi->base) {
 		DSSERR("can't ioremap DSI\n");
 		r = -ENOMEM;
@@ -4752,14 +4753,14 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 	if (dsi->irq < 0) {
 		DSSERR("platform_get_irq failed\n");
 		r = -ENODEV;
-		goto err_get_irq;
+		goto err_ioremap;
 	}
 
-	r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED,
-		dev_name(&dsidev->dev), dsi->pdev);
+	r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler,
+			     IRQF_SHARED, dev_name(&dsidev->dev), dsi->pdev);
 	if (r < 0) {
 		DSSERR("request_irq failed\n");
-		goto err_get_irq;
+		goto err_ioremap;
 	}
 
 	/* DSI VCs initialization */
@@ -4773,7 +4774,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 
 	r = dsi_runtime_get(dsidev);
 	if (r)
-		goto err_get_dsi;
+		goto err_ioremap;
 
 	rev = dsi_read_reg(dsidev, DSI_REVISION);
 	dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
@@ -4791,14 +4792,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 
 	return 0;
 
-err_get_dsi:
-	free_irq(dsi->irq, dsi->pdev);
-err_get_irq:
-	iounmap(dsi->base);
 err_ioremap:
 	pm_runtime_disable(&dsidev->dev);
-err_get_clk:
-	kfree(dsi);
 err_alloc:
 	return r;
 }
@@ -4823,11 +4818,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev)
 		dsi->vdds_dsi_reg = NULL;
 	}
 
-	free_irq(dsi->irq, dsi->pdev);
-	iounmap(dsi->base);
-
-	kfree(dsi);
-
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 1703345..e75f837 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -751,7 +751,8 @@ static int omap_dsshw_probe(struct platform_device *pdev)
 		r = -EINVAL;
 		goto err_ioremap;
 	}
-	dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
+	dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
+				resource_size(dss_mem));
 	if (!dss.base) {
 		DSSERR("can't ioremap DSS\n");
 		r = -ENOMEM;
@@ -760,7 +761,7 @@ static int omap_dsshw_probe(struct platform_device *pdev)
 
 	r = dss_get_clocks();
 	if (r)
-		goto err_clocks;
+		goto err_ioremap;
 
 	pm_runtime_enable(&pdev->dev);
 
@@ -808,8 +809,6 @@ err_dpi:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	dss_put_clocks();
-err_clocks:
-	iounmap(dss.base);
 err_ioremap:
 	return r;
 }
@@ -819,8 +818,6 @@ static int omap_dsshw_remove(struct platform_device *pdev)
 	dpi_exit();
 	sdi_exit();
 
-	iounmap(dss.base);
-
 	pm_runtime_disable(&pdev->dev);
 
 	dss_put_clocks();
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 814bb95..159e914 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -925,7 +925,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
 		r = -EINVAL;
 		goto err_ioremap;
 	}
-	rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
+	rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start,
+				 resource_size(rfbi_mem));
 	if (!rfbi.base) {
 		DSSERR("can't ioremap RFBI\n");
 		r = -ENOMEM;
@@ -963,7 +964,6 @@ err_get_ick:
 	rfbi_runtime_put();
 err_get_rfbi:
 	pm_runtime_disable(&pdev->dev);
-	iounmap(rfbi.base);
 err_ioremap:
 	return r;
 }
@@ -971,7 +971,6 @@ err_ioremap:
 static int omap_rfbihw_remove(struct platform_device *pdev)
 {
 	pm_runtime_disable(&pdev->dev);
-	iounmap(rfbi.base);
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index b3e9f90..1dfdde1 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -793,7 +793,8 @@ static int omap_venchw_probe(struct platform_device *pdev)
 		r = -EINVAL;
 		goto err_ioremap;
 	}
-	venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
+	venc.base = devm_ioremap(&pdev->dev, venc_mem->start,
+				 resource_size(venc_mem));
 	if (!venc.base) {
 		DSSERR("can't ioremap VENC\n");
 		r = -ENOMEM;
@@ -802,7 +803,7 @@ static int omap_venchw_probe(struct platform_device *pdev)
 
 	r = venc_get_clocks(pdev);
 	if (r)
-		goto err_get_clk;
+		goto err_ioremap;
 
 	pm_runtime_enable(&pdev->dev);
 
@@ -820,8 +821,6 @@ static int omap_venchw_probe(struct platform_device *pdev)
 err_get_venc:
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
-err_get_clk:
-	iounmap(venc.base);
 err_ioremap:
 	return r;
 }
@@ -837,7 +836,6 @@ static int omap_venchw_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
 
-	iounmap(venc.base);
 	return 0;
 }
 


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] drivers/video/omap2/dss: use devm_ functions
  2012-01-24 13:00 ` [PATCH] drivers/video/omap2/dss: " Julia Lawall
@ 2012-01-25  8:30   ` Tomi Valkeinen
  0 siblings, 0 replies; 3+ messages in thread
From: Tomi Valkeinen @ 2012-01-25  8:30 UTC (permalink / raw)
  To: Julia Lawall
  Cc: kernel-janitors, Florian Tobias Schandinat, linux-omap,
	linux-fbdev, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 493 bytes --]

Hi,

On Tue, 2012-01-24 at 14:00 +0100, Julia Lawall wrote:
> From: Julia Lawall <Julia.Lawall@lip6.fr>
> 
> The various devm_ functions allocate memory that is released when a
> driver
> detaches.  This patch uses these functions for data that is allocated
> in
> the probe function of a platform device and is only freed in the
> remove
> function.
> 
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>

Thanks, this looks very good. I'll apply to omapdss tree.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-01-25  8:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-24 13:00 [PATCH] use devm_ functions Julia Lawall
2012-01-24 13:00 ` [PATCH] drivers/video/omap2/dss: " Julia Lawall
2012-01-25  8:30   ` Tomi Valkeinen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).