Commit e2bde787131a01d0f2ca9baccaf3d107bf6c0c92

Authored by Julia Lawall
Committed by Samuel Ortiz
1 parent 8af5fe3bc5

mfd: Fix davinci memory leak

Error handling code following a kmalloc should free the allocated data.

The semantic match that finds the problem is as follows:
(http://www.emn.fr/x-info/coccinelle/)

// <smpl>
@r exists@
local idexpression x;
statement S;
expression E;
identifier f,f1,l;
position p1,p2;
expression *ptr != NULL;
@@

x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
...
if (x == NULL) S
<... when != x
     when != if (...) { <+...x...+> }
(
x->f1 = E
|
 (x->f1 == NULL || ...)
|
 f(...,x->f1,...)
)
...>
(
 return \(0\|<+...x...+>\|ptr\);
|
 return@p2 ...;
)

@script:python@
p1 << r.p1;
p2 << r.p2;
@@

print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line)
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 1 changed file with 4 additions and 2 deletions Inline Diff

drivers/mfd/davinci_voicecodec.c
1 /* 1 /*
2 * DaVinci Voice Codec Core Interface for TI platforms 2 * DaVinci Voice Codec Core Interface for TI platforms
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc 4 * Copyright (C) 2010 Texas Instruments, Inc
5 * 5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> 6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23 #include <linux/init.h> 23 #include <linux/init.h>
24 #include <linux/module.h> 24 #include <linux/module.h>
25 #include <linux/device.h> 25 #include <linux/device.h>
26 #include <linux/slab.h> 26 #include <linux/slab.h>
27 #include <linux/delay.h> 27 #include <linux/delay.h>
28 #include <linux/io.h> 28 #include <linux/io.h>
29 #include <linux/clk.h> 29 #include <linux/clk.h>
30 30
31 #include <sound/pcm.h> 31 #include <sound/pcm.h>
32 32
33 #include <linux/mfd/davinci_voicecodec.h> 33 #include <linux/mfd/davinci_voicecodec.h>
34 34
35 u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg) 35 u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg)
36 { 36 {
37 return __raw_readl(davinci_vc->base + reg); 37 return __raw_readl(davinci_vc->base + reg);
38 } 38 }
39 39
40 void davinci_vc_write(struct davinci_vc *davinci_vc, 40 void davinci_vc_write(struct davinci_vc *davinci_vc,
41 int reg, u32 val) 41 int reg, u32 val)
42 { 42 {
43 __raw_writel(val, davinci_vc->base + reg); 43 __raw_writel(val, davinci_vc->base + reg);
44 } 44 }
45 45
46 static int __init davinci_vc_probe(struct platform_device *pdev) 46 static int __init davinci_vc_probe(struct platform_device *pdev)
47 { 47 {
48 struct davinci_vc *davinci_vc; 48 struct davinci_vc *davinci_vc;
49 struct resource *res, *mem; 49 struct resource *res, *mem;
50 struct mfd_cell *cell = NULL; 50 struct mfd_cell *cell = NULL;
51 int ret; 51 int ret;
52 52
53 davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL); 53 davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL);
54 if (!davinci_vc) { 54 if (!davinci_vc) {
55 dev_dbg(&pdev->dev, 55 dev_dbg(&pdev->dev,
56 "could not allocate memory for private data\n"); 56 "could not allocate memory for private data\n");
57 return -ENOMEM; 57 return -ENOMEM;
58 } 58 }
59 59
60 davinci_vc->clk = clk_get(&pdev->dev, NULL); 60 davinci_vc->clk = clk_get(&pdev->dev, NULL);
61 if (IS_ERR(davinci_vc->clk)) { 61 if (IS_ERR(davinci_vc->clk)) {
62 dev_dbg(&pdev->dev, 62 dev_dbg(&pdev->dev,
63 "could not get the clock for voice codec\n"); 63 "could not get the clock for voice codec\n");
64 ret = -ENODEV; 64 ret = -ENODEV;
65 goto fail1; 65 goto fail1;
66 } 66 }
67 clk_enable(davinci_vc->clk); 67 clk_enable(davinci_vc->clk);
68 68
69 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 69 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
70 if (!res) { 70 if (!res) {
71 dev_err(&pdev->dev, "no mem resource\n"); 71 dev_err(&pdev->dev, "no mem resource\n");
72 ret = -ENODEV; 72 ret = -ENODEV;
73 goto fail2; 73 goto fail2;
74 } 74 }
75 75
76 davinci_vc->pbase = res->start; 76 davinci_vc->pbase = res->start;
77 davinci_vc->base_size = resource_size(res); 77 davinci_vc->base_size = resource_size(res);
78 78
79 mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size, 79 mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size,
80 pdev->name); 80 pdev->name);
81 if (!mem) { 81 if (!mem) {
82 dev_err(&pdev->dev, "VCIF region already claimed\n"); 82 dev_err(&pdev->dev, "VCIF region already claimed\n");
83 ret = -EBUSY; 83 ret = -EBUSY;
84 goto fail2; 84 goto fail2;
85 } 85 }
86 86
87 davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size); 87 davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size);
88 if (!davinci_vc->base) { 88 if (!davinci_vc->base) {
89 dev_err(&pdev->dev, "can't ioremap mem resource.\n"); 89 dev_err(&pdev->dev, "can't ioremap mem resource.\n");
90 ret = -ENOMEM; 90 ret = -ENOMEM;
91 goto fail3; 91 goto fail3;
92 } 92 }
93 93
94 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 94 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
95 if (!res) { 95 if (!res) {
96 dev_err(&pdev->dev, "no DMA resource\n"); 96 dev_err(&pdev->dev, "no DMA resource\n");
97 return -ENXIO; 97 ret = -ENXIO;
98 goto fail4;
98 } 99 }
99 100
100 davinci_vc->davinci_vcif.dma_tx_channel = res->start; 101 davinci_vc->davinci_vcif.dma_tx_channel = res->start;
101 davinci_vc->davinci_vcif.dma_tx_addr = 102 davinci_vc->davinci_vcif.dma_tx_addr =
102 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); 103 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO);
103 104
104 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 105 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
105 if (!res) { 106 if (!res) {
106 dev_err(&pdev->dev, "no DMA resource\n"); 107 dev_err(&pdev->dev, "no DMA resource\n");
107 return -ENXIO; 108 ret = -ENXIO;
109 goto fail4;
108 } 110 }
109 111
110 davinci_vc->davinci_vcif.dma_rx_channel = res->start; 112 davinci_vc->davinci_vcif.dma_rx_channel = res->start;
111 davinci_vc->davinci_vcif.dma_rx_addr = 113 davinci_vc->davinci_vcif.dma_rx_addr =
112 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); 114 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO);
113 115
114 davinci_vc->dev = &pdev->dev; 116 davinci_vc->dev = &pdev->dev;
115 davinci_vc->pdev = pdev; 117 davinci_vc->pdev = pdev;
116 118
117 /* Voice codec interface client */ 119 /* Voice codec interface client */
118 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; 120 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];
119 cell->name = "davinci_vcif"; 121 cell->name = "davinci_vcif";
120 cell->driver_data = davinci_vc; 122 cell->driver_data = davinci_vc;
121 123
122 /* Voice codec CQ93VC client */ 124 /* Voice codec CQ93VC client */
123 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; 125 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];
124 cell->name = "cq93vc"; 126 cell->name = "cq93vc";
125 cell->driver_data = davinci_vc; 127 cell->driver_data = davinci_vc;
126 128
127 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, 129 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
128 DAVINCI_VC_CELLS, NULL, 0); 130 DAVINCI_VC_CELLS, NULL, 0);
129 if (ret != 0) { 131 if (ret != 0) {
130 dev_err(&pdev->dev, "fail to register client devices\n"); 132 dev_err(&pdev->dev, "fail to register client devices\n");
131 goto fail4; 133 goto fail4;
132 } 134 }
133 135
134 return 0; 136 return 0;
135 137
136 fail4: 138 fail4:
137 iounmap(davinci_vc->base); 139 iounmap(davinci_vc->base);
138 fail3: 140 fail3:
139 release_mem_region(davinci_vc->pbase, davinci_vc->base_size); 141 release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
140 fail2: 142 fail2:
141 clk_disable(davinci_vc->clk); 143 clk_disable(davinci_vc->clk);
142 clk_put(davinci_vc->clk); 144 clk_put(davinci_vc->clk);
143 davinci_vc->clk = NULL; 145 davinci_vc->clk = NULL;
144 fail1: 146 fail1:
145 kfree(davinci_vc); 147 kfree(davinci_vc);
146 148
147 return ret; 149 return ret;
148 } 150 }
149 151
150 static int __devexit davinci_vc_remove(struct platform_device *pdev) 152 static int __devexit davinci_vc_remove(struct platform_device *pdev)
151 { 153 {
152 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 154 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
153 155
154 mfd_remove_devices(&pdev->dev); 156 mfd_remove_devices(&pdev->dev);
155 157
156 iounmap(davinci_vc->base); 158 iounmap(davinci_vc->base);
157 release_mem_region(davinci_vc->pbase, davinci_vc->base_size); 159 release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
158 160
159 clk_disable(davinci_vc->clk); 161 clk_disable(davinci_vc->clk);
160 clk_put(davinci_vc->clk); 162 clk_put(davinci_vc->clk);
161 davinci_vc->clk = NULL; 163 davinci_vc->clk = NULL;
162 164
163 kfree(davinci_vc); 165 kfree(davinci_vc);
164 166
165 return 0; 167 return 0;
166 } 168 }
167 169
168 static struct platform_driver davinci_vc_driver = { 170 static struct platform_driver davinci_vc_driver = {
169 .driver = { 171 .driver = {
170 .name = "davinci_voicecodec", 172 .name = "davinci_voicecodec",
171 .owner = THIS_MODULE, 173 .owner = THIS_MODULE,
172 }, 174 },
173 .remove = __devexit_p(davinci_vc_remove), 175 .remove = __devexit_p(davinci_vc_remove),
174 }; 176 };
175 177
176 static int __init davinci_vc_init(void) 178 static int __init davinci_vc_init(void)
177 { 179 {
178 return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe); 180 return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe);
179 } 181 }
180 module_init(davinci_vc_init); 182 module_init(davinci_vc_init);
181 183
182 static void __exit davinci_vc_exit(void) 184 static void __exit davinci_vc_exit(void)
183 { 185 {
184 platform_driver_unregister(&davinci_vc_driver); 186 platform_driver_unregister(&davinci_vc_driver);
185 } 187 }
186 module_exit(davinci_vc_exit); 188 module_exit(davinci_vc_exit);
187 189
188 MODULE_AUTHOR("Miguel Aguilar"); 190 MODULE_AUTHOR("Miguel Aguilar");
189 MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface"); 191 MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface");
190 MODULE_LICENSE("GPL"); 192 MODULE_LICENSE("GPL");
191 193