Commit e7dd4010 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Greg Kroah-Hartman

driver core: Add device link flag DL_FLAG_AUTOPROBE_CONSUMER

Add a new device link flag, DL_FLAG_AUTOPROBE_CONSUMER, to request the
driver core to probe for a consumer driver automatically after binding
a driver to the supplier device on a persistent managed device link.

As unbinding the supplier driver on a managed device link causes the
consumer driver to be detached from its device automatically, this
flag provides a complementary mechanism which is needed to address
some "composite device" use cases.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 72175d4e
...@@ -94,6 +94,15 @@ Similarly, when the device link is added from supplier's ``->probe`` callback, ...@@ -94,6 +94,15 @@ Similarly, when the device link is added from supplier's ``->probe`` callback,
``DL_FLAG_AUTOREMOVE_SUPPLIER`` causes the device link to be automatically ``DL_FLAG_AUTOREMOVE_SUPPLIER`` causes the device link to be automatically
purged when the supplier fails to probe or later unbinds. purged when the supplier fails to probe or later unbinds.
If neither ``DL_FLAG_AUTOREMOVE_CONSUMER`` nor ``DL_FLAG_AUTOREMOVE_SUPPLIER``
is set, ``DL_FLAG_AUTOPROBE_CONSUMER`` can be used to request the driver core
to probe for a driver for the consumer driver on the link automatically after
a driver has been bound to the supplier device.
Note, however, that any combinations of ``DL_FLAG_AUTOREMOVE_CONSUMER``,
``DL_FLAG_AUTOREMOVE_SUPPLIER`` or ``DL_FLAG_AUTOPROBE_CONSUMER`` with
``DL_FLAG_STATELESS`` are invalid and cannot be used.
Limitations Limitations
=========== ===========
......
...@@ -208,6 +208,12 @@ static void device_link_rpm_prepare(struct device *consumer, ...@@ -208,6 +208,12 @@ static void device_link_rpm_prepare(struct device *consumer,
* the link will be maintained until one of the devices pointed to by it (either * the link will be maintained until one of the devices pointed to by it (either
* the consumer or the supplier) is unregistered. * the consumer or the supplier) is unregistered.
* *
* Also, if DL_FLAG_STATELESS, DL_FLAG_AUTOREMOVE_CONSUMER and
* DL_FLAG_AUTOREMOVE_SUPPLIER are not set in @flags (that is, a persistent
* managed device link is being added), the DL_FLAG_AUTOPROBE_CONSUMER flag can
* be used to request the driver core to automaticall probe for a consmer
* driver after successfully binding a driver to the supplier device.
*
* The combination of DL_FLAG_STATELESS and either DL_FLAG_AUTOREMOVE_CONSUMER * The combination of DL_FLAG_STATELESS and either DL_FLAG_AUTOREMOVE_CONSUMER
* or DL_FLAG_AUTOREMOVE_SUPPLIER set in @flags at the same time is invalid and * or DL_FLAG_AUTOREMOVE_SUPPLIER set in @flags at the same time is invalid and
* will cause NULL to be returned upfront. * will cause NULL to be returned upfront.
...@@ -228,7 +234,12 @@ struct device_link *device_link_add(struct device *consumer, ...@@ -228,7 +234,12 @@ struct device_link *device_link_add(struct device *consumer,
if (!consumer || !supplier || if (!consumer || !supplier ||
(flags & DL_FLAG_STATELESS && (flags & DL_FLAG_STATELESS &&
flags & (DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_AUTOREMOVE_SUPPLIER))) flags & (DL_FLAG_AUTOREMOVE_CONSUMER |
DL_FLAG_AUTOREMOVE_SUPPLIER |
DL_FLAG_AUTOPROBE_CONSUMER)) ||
(flags & DL_FLAG_AUTOPROBE_CONSUMER &&
flags & (DL_FLAG_AUTOREMOVE_CONSUMER |
DL_FLAG_AUTOREMOVE_SUPPLIER)))
return NULL; return NULL;
if (flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) { if (flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) {
...@@ -589,6 +600,9 @@ void device_links_driver_bound(struct device *dev) ...@@ -589,6 +600,9 @@ void device_links_driver_bound(struct device *dev)
WARN_ON(link->status != DL_STATE_DORMANT); WARN_ON(link->status != DL_STATE_DORMANT);
WRITE_ONCE(link->status, DL_STATE_AVAILABLE); WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
if (link->flags & DL_FLAG_AUTOPROBE_CONSUMER)
driver_deferred_probe_add(link->consumer);
} }
list_for_each_entry(link, &dev->links.suppliers, c_node) { list_for_each_entry(link, &dev->links.suppliers, c_node) {
......
...@@ -116,7 +116,7 @@ static void deferred_probe_work_func(struct work_struct *work) ...@@ -116,7 +116,7 @@ static void deferred_probe_work_func(struct work_struct *work)
} }
static DECLARE_WORK(deferred_probe_work, deferred_probe_work_func); static DECLARE_WORK(deferred_probe_work, deferred_probe_work_func);
static void driver_deferred_probe_add(struct device *dev) void driver_deferred_probe_add(struct device *dev)
{ {
mutex_lock(&deferred_probe_mutex); mutex_lock(&deferred_probe_mutex);
if (list_empty(&dev->p->deferred_probe)) { if (list_empty(&dev->p->deferred_probe)) {
......
...@@ -341,6 +341,7 @@ struct device *driver_find_device(struct device_driver *drv, ...@@ -341,6 +341,7 @@ struct device *driver_find_device(struct device_driver *drv,
struct device *start, void *data, struct device *start, void *data,
int (*match)(struct device *dev, void *data)); int (*match)(struct device *dev, void *data));
void driver_deferred_probe_add(struct device *dev);
int driver_deferred_probe_check_state(struct device *dev); int driver_deferred_probe_check_state(struct device *dev);
/** /**
...@@ -827,12 +828,14 @@ enum device_link_state { ...@@ -827,12 +828,14 @@ enum device_link_state {
* PM_RUNTIME: If set, the runtime PM framework will use this link. * PM_RUNTIME: If set, the runtime PM framework will use this link.
* RPM_ACTIVE: Run pm_runtime_get_sync() on the supplier during link creation. * RPM_ACTIVE: Run pm_runtime_get_sync() on the supplier during link creation.
* AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind. * AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind.
* AUTOPROBE_CONSUMER: Probe consumer driver automatically after supplier binds.
*/ */
#define DL_FLAG_STATELESS BIT(0) #define DL_FLAG_STATELESS BIT(0)
#define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1) #define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1)
#define DL_FLAG_PM_RUNTIME BIT(2) #define DL_FLAG_PM_RUNTIME BIT(2)
#define DL_FLAG_RPM_ACTIVE BIT(3) #define DL_FLAG_RPM_ACTIVE BIT(3)
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4) #define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
#define DL_FLAG_AUTOPROBE_CONSUMER BIT(5)
/** /**
* struct device_link - Device link representation. * struct device_link - Device link representation.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment