From a313dec6401f0ceaec77262b411d77c18aef27ee Mon Sep 17 00:00:00 2001
From: Corey Minyard <cminyard@mvista.com>
Date: Thu, 5 Apr 2018 22:06:45 -0500
Subject: [PATCH] ipmi_ssif: Convert over to a shutdown handler
Git-commit: a313dec6401f0ceaec77262b411d77c18aef27ee
Patch-mainline: v4.18-rc1
References: FATE#326156
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>
Acked-by: Takashi Iwai <tiwai@suse.de>
---
drivers/char/ipmi/ipmi_ssif.c | 51 +++++++++++++++++++++++-------------------
1 file changed, 29 insertions(+), 22 deletions(-)
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -1170,9 +1170,32 @@ MODULE_PARM_DESC(trydmi, "Setting this t
static DEFINE_MUTEX(ssif_infos_mutex);
static LIST_HEAD(ssif_infos);
+static void shutdown_ssif(void *send_info)
+{
+ struct ssif_info *ssif_info = send_info;
+
+ /* make sure the driver is not looking for flags any more. */
+ while (ssif_info->ssif_state != SSIF_NORMAL)
+ schedule_timeout(1);
+
+ ssif_info->stopping = true;
+ del_timer_sync(&ssif_info->retry_timer);
+ if (ssif_info->thread) {
+ complete(&ssif_info->wake_thread);
+ 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;
@@ -1183,23 +1206,11 @@ static int ssif_remove(struct i2c_client
* 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;
- }
+ intf = ssif_info->intf;
ssif_info->intf = NULL;
-
- /* make sure the driver is not looking for flags any more. */
- while (ssif_info->ssif_state != SSIF_NORMAL)
- schedule_timeout(1);
-
- ssif_info->stopping = true;
- del_timer_sync(&ssif_info->retry_timer);
- if (ssif_info->thread) {
- complete(&ssif_info->wake_thread);
- kthread_stop(ssif_info->thread);
- }
+ 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) {
@@ -1208,12 +1219,7 @@ static int ssif_remove(struct i2c_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,
@@ -1638,6 +1644,7 @@ static int ssif_probe(struct i2c_client
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;