greybus: Cleanup connection leftovers
authorViresh Kumar <viresh.kumar@linaro.org>
Thu, 9 Jul 2015 05:26:30 +0000 (10:56 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Mon, 13 Jul 2015 22:40:37 +0000 (15:40 -0700)
This wouldn't happen normally, but in a buggy corner case it is possible
that all the connections aren't removed properly and they are still
present after the interfaces and endo are removed.

Warn in such a case and cleanup connections, so that /sys/bus/greybus/
can be removed while removing greybus modules.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/connection.h
drivers/staging/greybus/core.c

index 6994a84..65a2bd5 100644 (file)
@@ -313,3 +313,13 @@ void gb_connection_exit(struct gb_connection *connection)
                                 cport_id, ret);
        }
 }
+
+void gb_hd_connections_exit(struct greybus_host_device *hd)
+{
+       struct gb_connection *connection;
+
+       list_for_each_entry(connection, &hd->connections, hd_links) {
+               gb_connection_exit(connection);
+               gb_connection_destroy(connection);
+       }
+}
index acf9183..ad699db 100644 (file)
@@ -50,6 +50,7 @@ void gb_connection_destroy(struct gb_connection *connection);
 
 int gb_connection_init(struct gb_connection *connection);
 void gb_connection_exit(struct gb_connection *connection);
+void gb_hd_connections_exit(struct greybus_host_device *hd);
 
 void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
                        u8 *data, size_t length);
index 925e1dc..3b1be2d 100644 (file)
@@ -235,6 +235,13 @@ void greybus_remove_hd(struct greybus_host_device *hd)
         */
        gb_interfaces_remove(hd);
        gb_endo_remove(hd->endo);
+
+       /*
+        * Make sure there are no leftovers that can potentially corrupt sysfs.
+        */
+       if (WARN_ON(!list_empty(&hd->connections)))
+               gb_hd_connections_exit(hd);
+
        kref_put_mutex(&hd->kref, free_hd, &hd_mutex);
 }
 EXPORT_SYMBOL_GPL(greybus_remove_hd);