diff options
author | Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> | 2015-07-27 10:30:48 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2015-08-01 06:11:58 -0400 |
commit | e3311469734093724b10c2a81c1193197db03b78 (patch) | |
tree | 435b300b8fb5257f2d3cbd7003860241bd8a5f80 /drivers/i2c/i2c-core.c | |
parent | e952849a02524a247967bf7105f36fbb13cd00c2 (diff) |
i2c: fix leaked device refcount on of_find_i2c_* error path
If of_find_i2c_device_by_node() or of_find_i2c_adapter_by_node() find
a device by node, but its type does not match, a reference to that
device is still held. This change fixes the problem.
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 8b64cf38beac..c83e4d13cfc5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1340,13 +1340,17 @@ static int of_dev_node_match(struct device *dev, void *data) | |||
1340 | struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) | 1340 | struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) |
1341 | { | 1341 | { |
1342 | struct device *dev; | 1342 | struct device *dev; |
1343 | struct i2c_client *client; | ||
1343 | 1344 | ||
1344 | dev = bus_find_device(&i2c_bus_type, NULL, node, | 1345 | dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match); |
1345 | of_dev_node_match); | ||
1346 | if (!dev) | 1346 | if (!dev) |
1347 | return NULL; | 1347 | return NULL; |
1348 | 1348 | ||
1349 | return i2c_verify_client(dev); | 1349 | client = i2c_verify_client(dev); |
1350 | if (!client) | ||
1351 | put_device(dev); | ||
1352 | |||
1353 | return client; | ||
1350 | } | 1354 | } |
1351 | EXPORT_SYMBOL(of_find_i2c_device_by_node); | 1355 | EXPORT_SYMBOL(of_find_i2c_device_by_node); |
1352 | 1356 | ||
@@ -1354,13 +1358,17 @@ EXPORT_SYMBOL(of_find_i2c_device_by_node); | |||
1354 | struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) | 1358 | struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) |
1355 | { | 1359 | { |
1356 | struct device *dev; | 1360 | struct device *dev; |
1361 | struct i2c_adapter *adapter; | ||
1357 | 1362 | ||
1358 | dev = bus_find_device(&i2c_bus_type, NULL, node, | 1363 | dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match); |
1359 | of_dev_node_match); | ||
1360 | if (!dev) | 1364 | if (!dev) |
1361 | return NULL; | 1365 | return NULL; |
1362 | 1366 | ||
1363 | return i2c_verify_adapter(dev); | 1367 | adapter = i2c_verify_adapter(dev); |
1368 | if (!adapter) | ||
1369 | put_device(dev); | ||
1370 | |||
1371 | return adapter; | ||
1364 | } | 1372 | } |
1365 | EXPORT_SYMBOL(of_find_i2c_adapter_by_node); | 1373 | EXPORT_SYMBOL(of_find_i2c_adapter_by_node); |
1366 | #else | 1374 | #else |