aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/connection.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2016-05-27 17:26:22 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2016-05-27 12:19:29 -0700
commit7aefe7918f8e053f9cd8077fcc98182689f1341e (patch)
tree6e3c9c0ac0d8687477a3963c81f89b252aeb1423 /drivers/staging/greybus/connection.c
parentgreybus: drop a bogus semicolon (diff)
downloadlinux-dev-7aefe7918f8e053f9cd8077fcc98182689f1341e.tar.xz
linux-dev-7aefe7918f8e053f9cd8077fcc98182689f1341e.zip
greybus: core: avoid I/O to disconnected interfaces
Add new helper to disable connections to interfaces that have already been disconnected (e.g. forcibly removed). The connection tear-down procedure differs enough depending on whether the interface is still present or already gone to warrant a dedicated helper. This will become more obvious with the new tear-down procedure, which involves I/O on the connection being tore down. This also simplifies handling of the legacy bootrom, which does not support the new tear-down operations. Specifically, this allows us to remove the early control-connection tear down during interface disable, and also avoids some error messages currently printed during legacy mode switch (i.e. bootrom boot-over-UniPro) and forcible removal. Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/connection.c')
-rw-r--r--drivers/staging/greybus/connection.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index ac3be2fceade..7e07ef832b7c 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -654,6 +654,27 @@ out_unlock:
}
EXPORT_SYMBOL_GPL(gb_connection_disable);
+/* Disable a connection without communicating with the remote end. */
+void gb_connection_disable_forced(struct gb_connection *connection)
+{
+ mutex_lock(&connection->mutex);
+
+ if (connection->state == GB_CONNECTION_STATE_DISABLED)
+ goto out_unlock;
+
+ spin_lock_irq(&connection->lock);
+ connection->state = GB_CONNECTION_STATE_DISABLED;
+ gb_connection_cancel_operations(connection, -ESHUTDOWN);
+ spin_unlock_irq(&connection->lock);
+
+ gb_connection_svc_connection_destroy(connection);
+ gb_connection_hd_cport_disable(connection);
+
+out_unlock:
+ mutex_unlock(&connection->mutex);
+}
+EXPORT_SYMBOL_GPL(gb_connection_disable_forced);
+
/* Caller must have disabled the connection before destroying it. */
void gb_connection_destroy(struct gb_connection *connection)
{