aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulia Lawall <Julia.Lawall@lip6.fr>2012-10-05 16:23:52 -0400
committerJean Delvare <khali@endymion.delvare>2012-10-05 16:23:52 -0400
commit71b578452ec6b2e8a470e3dae89055cd1068a9f0 (patch)
tree75632bf1c1e91a28bc76cc72c96e5a007a1e4305
parenteee543e8248150e8fb833943c71f40c7b1724600 (diff)
i2c-smbus: Convert kzalloc to devm_kzalloc
Converting kzalloc to devm_kzalloc simplifies the code and ensures that the result, alert, is freed after the irq allocated by the subsequent devm_request_irq. This in turn ensures that when an interrupt can be triggered, the alert structure is still available. The problem of a free after a devm_request_irq was found using the following semantic match (http://coccinelle.lip6.fr/) // <smpl> @r exists@ expression e1,e2,x,a,b,c,d; identifier free; position p1,p2; @@ devm_request_irq@p1(e1,e2,...,x) ... when any when != e2 = a when != x = b if (...) { ... when != e2 = c when != x = d free@p2(...,x,...); ... return ...; } // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/i2c/i2c-smbus.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index df3e0bf31eb3..92cdd2323b03 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -142,7 +142,8 @@ static int smbalert_probe(struct i2c_client *ara,
142 struct i2c_adapter *adapter = ara->adapter; 142 struct i2c_adapter *adapter = ara->adapter;
143 int res; 143 int res;
144 144
145 alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL); 145 alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
146 GFP_KERNEL);
146 if (!alert) 147 if (!alert)
147 return -ENOMEM; 148 return -ENOMEM;
148 149
@@ -154,10 +155,8 @@ static int smbalert_probe(struct i2c_client *ara,
154 if (setup->irq > 0) { 155 if (setup->irq > 0) {
155 res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq, 156 res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq,
156 0, "smbus_alert", alert); 157 0, "smbus_alert", alert);
157 if (res) { 158 if (res)
158 kfree(alert);
159 return res; 159 return res;
160 }
161 } 160 }
162 161
163 i2c_set_clientdata(ara, alert); 162 i2c_set_clientdata(ara, alert);
@@ -167,14 +166,12 @@ static int smbalert_probe(struct i2c_client *ara,
167 return 0; 166 return 0;
168} 167}
169 168
170/* IRQ resource is managed so it is freed automatically */ 169/* IRQ and memory resources are managed so they are freed automatically */
171static int smbalert_remove(struct i2c_client *ara) 170static int smbalert_remove(struct i2c_client *ara)
172{ 171{
173 struct i2c_smbus_alert *alert = i2c_get_clientdata(ara); 172 struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
174 173
175 cancel_work_sync(&alert->alert); 174 cancel_work_sync(&alert->alert);
176
177 kfree(alert);
178 return 0; 175 return 0;
179} 176}
180 177