diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_ssif.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_ssif.c | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 18e4650c233b..29e67a80fb20 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c | |||
@@ -181,6 +181,8 @@ struct ssif_addr_info { | |||
181 | struct device *dev; | 181 | struct device *dev; |
182 | struct i2c_client *client; | 182 | struct i2c_client *client; |
183 | 183 | ||
184 | struct i2c_client *added_client; | ||
185 | |||
184 | struct mutex clients_mutex; | 186 | struct mutex clients_mutex; |
185 | struct list_head clients; | 187 | struct list_head clients; |
186 | 188 | ||
@@ -1214,18 +1216,11 @@ static void shutdown_ssif(void *send_info) | |||
1214 | complete(&ssif_info->wake_thread); | 1216 | complete(&ssif_info->wake_thread); |
1215 | kthread_stop(ssif_info->thread); | 1217 | kthread_stop(ssif_info->thread); |
1216 | } | 1218 | } |
1217 | |||
1218 | /* | ||
1219 | * No message can be outstanding now, we have removed the | ||
1220 | * upper layer and it permitted us to do so. | ||
1221 | */ | ||
1222 | kfree(ssif_info); | ||
1223 | } | 1219 | } |
1224 | 1220 | ||
1225 | static int ssif_remove(struct i2c_client *client) | 1221 | static int ssif_remove(struct i2c_client *client) |
1226 | { | 1222 | { |
1227 | struct ssif_info *ssif_info = i2c_get_clientdata(client); | 1223 | struct ssif_info *ssif_info = i2c_get_clientdata(client); |
1228 | struct ipmi_smi *intf; | ||
1229 | struct ssif_addr_info *addr_info; | 1224 | struct ssif_addr_info *addr_info; |
1230 | 1225 | ||
1231 | if (!ssif_info) | 1226 | if (!ssif_info) |
@@ -1235,9 +1230,7 @@ static int ssif_remove(struct i2c_client *client) | |||
1235 | * After this point, we won't deliver anything asychronously | 1230 | * After this point, we won't deliver anything asychronously |
1236 | * to the message handler. We can unregister ourself. | 1231 | * to the message handler. We can unregister ourself. |
1237 | */ | 1232 | */ |
1238 | intf = ssif_info->intf; | 1233 | ipmi_unregister_smi(ssif_info->intf); |
1239 | ssif_info->intf = NULL; | ||
1240 | ipmi_unregister_smi(intf); | ||
1241 | 1234 | ||
1242 | list_for_each_entry(addr_info, &ssif_infos, link) { | 1235 | list_for_each_entry(addr_info, &ssif_infos, link) { |
1243 | if (addr_info->client == client) { | 1236 | if (addr_info->client == client) { |
@@ -1246,6 +1239,8 @@ static int ssif_remove(struct i2c_client *client) | |||
1246 | } | 1239 | } |
1247 | } | 1240 | } |
1248 | 1241 | ||
1242 | kfree(ssif_info); | ||
1243 | |||
1249 | return 0; | 1244 | return 0; |
1250 | } | 1245 | } |
1251 | 1246 | ||
@@ -1648,15 +1643,9 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1648 | 1643 | ||
1649 | out: | 1644 | out: |
1650 | if (rv) { | 1645 | if (rv) { |
1651 | /* | 1646 | if (addr_info) |
1652 | * Note that if addr_info->client is assigned, we | 1647 | addr_info->client = NULL; |
1653 | * leave it. The i2c client hangs around even if we | 1648 | |
1654 | * return a failure here, and the failure here is not | ||
1655 | * propagated back to the i2c code. This seems to be | ||
1656 | * design intent, strange as it may be. But if we | ||
1657 | * don't leave it, ssif_platform_remove will not remove | ||
1658 | * the client like it should. | ||
1659 | */ | ||
1660 | dev_err(&client->dev, "Unable to start IPMI SSIF: %d\n", rv); | 1649 | dev_err(&client->dev, "Unable to start IPMI SSIF: %d\n", rv); |
1661 | kfree(ssif_info); | 1650 | kfree(ssif_info); |
1662 | } | 1651 | } |
@@ -1676,7 +1665,8 @@ static int ssif_adapter_handler(struct device *adev, void *opaque) | |||
1676 | if (adev->type != &i2c_adapter_type) | 1665 | if (adev->type != &i2c_adapter_type) |
1677 | return 0; | 1666 | return 0; |
1678 | 1667 | ||
1679 | i2c_new_device(to_i2c_adapter(adev), &addr_info->binfo); | 1668 | addr_info->added_client = i2c_new_device(to_i2c_adapter(adev), |
1669 | &addr_info->binfo); | ||
1680 | 1670 | ||
1681 | if (!addr_info->adapter_name) | 1671 | if (!addr_info->adapter_name) |
1682 | return 1; /* Only try the first I2C adapter by default. */ | 1672 | return 1; /* Only try the first I2C adapter by default. */ |
@@ -1849,7 +1839,7 @@ static int ssif_platform_remove(struct platform_device *dev) | |||
1849 | return 0; | 1839 | return 0; |
1850 | 1840 | ||
1851 | mutex_lock(&ssif_infos_mutex); | 1841 | mutex_lock(&ssif_infos_mutex); |
1852 | i2c_unregister_device(addr_info->client); | 1842 | i2c_unregister_device(addr_info->added_client); |
1853 | 1843 | ||
1854 | list_del(&addr_info->link); | 1844 | list_del(&addr_info->link); |
1855 | kfree(addr_info); | 1845 | kfree(addr_info); |