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: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
72175d4ea4
Коммит
e7dd40105a
|
@ -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
|
||||
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
|
||||
===========
|
||||
|
||||
|
|
|
@ -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 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
|
||||
* or DL_FLAG_AUTOREMOVE_SUPPLIER set in @flags at the same time is invalid and
|
||||
* will cause NULL to be returned upfront.
|
||||
|
@ -228,7 +234,12 @@ struct device_link *device_link_add(struct device *consumer,
|
|||
|
||||
if (!consumer || !supplier ||
|
||||
(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;
|
||||
|
||||
if (flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) {
|
||||
|
@ -589,6 +600,9 @@ void device_links_driver_bound(struct device *dev)
|
|||
|
||||
WARN_ON(link->status != DL_STATE_DORMANT);
|
||||
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) {
|
||||
|
|
|
@ -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 void driver_deferred_probe_add(struct device *dev)
|
||||
void driver_deferred_probe_add(struct device *dev)
|
||||
{
|
||||
mutex_lock(&deferred_probe_mutex);
|
||||
if (list_empty(&dev->p->deferred_probe)) {
|
||||
|
|
|
@ -341,6 +341,7 @@ struct device *driver_find_device(struct device_driver *drv,
|
|||
struct device *start, 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);
|
||||
|
||||
/**
|
||||
|
@ -827,12 +828,14 @@ enum device_link_state {
|
|||
* 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.
|
||||
* 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_AUTOREMOVE_CONSUMER BIT(1)
|
||||
#define DL_FLAG_PM_RUNTIME BIT(2)
|
||||
#define DL_FLAG_RPM_ACTIVE BIT(3)
|
||||
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
|
||||
#define DL_FLAG_AUTOPROBE_CONSUMER BIT(5)
|
||||
|
||||
/**
|
||||
* struct device_link - Device link representation.
|
||||
|
|
Загрузка…
Ссылка в новой задаче