From ead18c23c263374ed098a7d955b29b4a466d4573 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 10 Feb 2018 19:27:12 +0100 Subject: driver core: Introduce device links reference counting If device_link_add() is invoked multiple times with the same supplier and consumer combo, it will create the link on first addition and return a pointer to the already existing link on all subsequent additions. The semantics for device_link_del() are quite different, it deletes the link unconditionally, so multiple invocations are not allowed. In other words, this snippet ... struct device *dev1, *dev2; struct device_link *link1, *link2; link1 = device_link_add(dev1, dev2, 0); link2 = device_link_add(dev1, dev2, 0); device_link_del(link1); device_link_del(link2); ... causes the following crash: WARNING: CPU: 4 PID: 2686 at drivers/base/power/runtime.c:1611 pm_runtime_drop_link+0x40/0x50 [...] list_del corruption, 0000000039b800a4->prev is LIST_POISON2 (00000000ecf79852) kernel BUG at lib/list_debug.c:50! The issue isn't as arbitrary as it may seem: Imagine a device link which is added in both the supplier's and the consumer's ->probe hook. The two drivers can't just call device_link_del() in their ->remove hook without coordination. Fix by counting multiple additions and dropping the device link only when the last addition is unwound. Signed-off-by: Lukas Wunner [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- include/linux/device.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index b093405ed525..abf952c82c6d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -769,6 +769,7 @@ enum device_link_state { * @status: The state of the link (with respect to the presence of drivers). * @flags: Link flags. * @rpm_active: Whether or not the consumer device is runtime-PM-active. + * @kref: Count repeated addition of the same link. * @rcu_head: An RCU head to use for deferred execution of SRCU callbacks. */ struct device_link { @@ -779,6 +780,7 @@ struct device_link { enum device_link_state status; u32 flags; bool rpm_active; + struct kref kref; #ifdef CONFIG_SRCU struct rcu_head rcu_head; #endif -- cgit v1.2.3 From 8ddfb47294c0f45a476a92ecf1e56cb5990c5468 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 9 Feb 2018 10:13:57 +0100 Subject: drivers: base: add description for .coredump() callback Commit 3c47d19ff4dc ("drivers: base: add coredump driver ops") added a new callback in struct device_driver, but not a kerneldoc description so here it is. Fixes: 3c47d19ff4dc ("drivers: base: add coredump driver ops") Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index b093405ed525..0b32a42db4ae 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -256,6 +256,7 @@ enum probe_type { * automatically. * @pm: Power management operations of the device which matched * this driver. + * @coredump: Called through sysfs to initiate a device coredump. * @p: Driver core's private data, no one other than the driver * core can touch this. * -- cgit v1.2.3 From f2d9b66d84f3ff5ea3aff111e6a403e04fa8bf37 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 20 Mar 2018 15:57:02 +0300 Subject: drivers: base: Unified device connection lookup Several frameworks - clk, gpio, phy, pmw, etc. - maintain lookup tables for describing connections and provide custom API for handling them. This introduces a single generic lookup table and API for the connections. The motivation for this commit is centralizing the connection lookup, but the goal is to ultimately extract the connection descriptions also from firmware by using the fwnode_graph_* functions and other mechanisms that are available. Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Heikki Krogerus Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index b093405ed525..204ff64279fd 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -729,6 +729,28 @@ struct device_dma_parameters { unsigned long segment_boundary_mask; }; +/** + * struct device_connection - Device Connection Descriptor + * @endpoint: The names of the two devices connected together + * @id: Unique identifier for the connection + * @list: List head, private, for internal use only + */ +struct device_connection { + const char *endpoint[2]; + const char *id; + struct list_head list; +}; + +void *device_connection_find_match(struct device *dev, const char *con_id, + void *data, + void *(*match)(struct device_connection *con, + int ep, void *data)); + +struct device *device_connection_find(struct device *dev, const char *con_id); + +void device_connection_add(struct device_connection *con); +void device_connection_remove(struct device_connection *con); + /** * enum device_link_state - Device link states. * @DL_STATE_NONE: The presence of the drivers is not being tracked. -- cgit v1.2.3