summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2018-04-05 22:06:45 -0500
committerCorey Minyard <cminyard@mvista.com>2018-04-18 10:23:00 -0500
commita313dec6401f0ceaec77262b411d77c18aef27ee (patch)
tree3c29094c915c7790b626e55af826a3386eafc468 /drivers/char
parent7960f18a56475bf2177c5ff56c72eb4c12c56440 (diff)
downloadlinux-stable-a313dec6401f0ceaec77262b411d77c18aef27ee.tar.gz
linux-stable-a313dec6401f0ceaec77262b411d77c18aef27ee.tar.bz2
linux-stable-a313dec6401f0ceaec77262b411d77c18aef27ee.zip
ipmi_ssif: Convert over to a shutdown handler
Move the shutdown handling to a shutdown function called from the IPMI core code. That makes for a cleaner shutdown. Signed-off-by: Corey Minyard <cminyard@mvista.com>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 2db97fd08a8f..0f3dd94519d9 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -1225,25 +1225,9 @@ static const struct attribute_group ipmi_ssif_dev_attr_group = {
.attrs = ipmi_ssif_dev_attrs,
};
-static int ssif_remove(struct i2c_client *client)
+static void shutdown_ssif(void *send_info)
{
- struct ssif_info *ssif_info = i2c_get_clientdata(client);
- struct ssif_addr_info *addr_info;
- int rv;
-
- if (!ssif_info)
- return 0;
-
- /*
- * After this point, we won't deliver anything asychronously
- * to the message handler. We can unregister ourself.
- */
- rv = ipmi_unregister_smi(ssif_info->intf);
- if (rv) {
- pr_err(PFX "Unable to unregister device: errno=%d\n", rv);
- return rv;
- }
- ssif_info->intf = NULL;
+ struct ssif_info *ssif_info = send_info;
device_remove_group(&ssif_info->client->dev, &ipmi_ssif_dev_attr_group);
dev_set_drvdata(&ssif_info->client->dev, NULL);
@@ -1259,6 +1243,33 @@ static int ssif_remove(struct i2c_client *client)
kthread_stop(ssif_info->thread);
}
+ /*
+ * No message can be outstanding now, we have removed the
+ * upper layer and it permitted us to do so.
+ */
+ kfree(ssif_info);
+}
+
+static int ssif_remove(struct i2c_client *client)
+{
+ struct ssif_info *ssif_info = i2c_get_clientdata(client);
+ struct ipmi_smi *intf;
+ struct ssif_addr_info *addr_info;
+ int rv;
+
+ if (!ssif_info)
+ return 0;
+
+ /*
+ * After this point, we won't deliver anything asychronously
+ * to the message handler. We can unregister ourself.
+ */
+ intf = ssif_info->intf;
+ ssif_info->intf = NULL;
+ rv = ipmi_unregister_smi(intf);
+ if (rv)
+ pr_err(PFX "Unable to unregister device: errno=%d\n", rv);
+
list_for_each_entry(addr_info, &ssif_infos, link) {
if (addr_info->client == client) {
addr_info->client = NULL;
@@ -1266,12 +1277,7 @@ static int ssif_remove(struct i2c_client *client)
}
}
- /*
- * No message can be outstanding now, we have removed the
- * upper layer and it permitted us to do so.
- */
- kfree(ssif_info);
- return 0;
+ return rv;
}
static int do_cmd(struct i2c_client *client, int len, unsigned char *msg,
@@ -1697,6 +1703,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
ssif_info->handlers.owner = THIS_MODULE;
ssif_info->handlers.start_processing = ssif_start_processing;
+ ssif_info->handlers.shutdown = shutdown_ssif;
ssif_info->handlers.get_smi_info = get_smi_info;
ssif_info->handlers.sender = sender;
ssif_info->handlers.request_events = request_events;