Blob Blame History Raw
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;