summaryrefslogtreecommitdiff
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorpascal paillet <p.paillet@st.com>2018-07-05 14:25:56 +0000
committerMark Brown <broonie@kernel.org>2018-07-05 18:55:08 +0100
commitd8842211b6f63d3f069df973d137de0a85964965 (patch)
tree9529118b161f6800a80aebbb26315f013997d84b /drivers/base/core.c
parent0380cf7dbaca75c524e34b30979f0806124fa8e6 (diff)
driver core: Add device_link_remove function
Device_link_remove uses the same arguments than device_link_add. The Goal is to avoid storing the link pointer. Signed-off-by: pascal paillet <p.paillet@st.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 36622b52e419..3b380b1f2768 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -365,6 +365,36 @@ void device_link_del(struct device_link *link)
}
EXPORT_SYMBOL_GPL(device_link_del);
+/**
+ * device_link_remove - remove a link between two devices.
+ * @consumer: Consumer end of the link.
+ * @supplier: Supplier end of the link.
+ *
+ * The caller must ensure proper synchronization of this function with runtime
+ * PM.
+ */
+void device_link_remove(void *consumer, struct device *supplier)
+{
+ struct device_link *link;
+
+ if (WARN_ON(consumer == supplier))
+ return;
+
+ device_links_write_lock();
+ device_pm_lock();
+
+ list_for_each_entry(link, &supplier->links.consumers, s_node) {
+ if (link->consumer == consumer) {
+ kref_put(&link->kref, __device_link_del);
+ break;
+ }
+ }
+
+ device_pm_unlock();
+ device_links_write_unlock();
+}
+EXPORT_SYMBOL_GPL(device_link_remove);
+
static void device_links_missing_supplier(struct device *dev)
{
struct device_link *link;