18c2ecf20Sopenharmony_ci.. _device_link:
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci============
48c2ecf20Sopenharmony_ciDevice links
58c2ecf20Sopenharmony_ci============
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciBy default, the driver core only enforces dependencies between devices
88c2ecf20Sopenharmony_cithat are borne out of a parent/child relationship within the device
98c2ecf20Sopenharmony_cihierarchy: When suspending, resuming or shutting down the system, devices
108c2ecf20Sopenharmony_ciare ordered based on this relationship, i.e. children are always suspended
118c2ecf20Sopenharmony_cibefore their parent, and the parent is always resumed before its children.
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ciSometimes there is a need to represent device dependencies beyond the
148c2ecf20Sopenharmony_cimere parent/child relationship, e.g. between siblings, and have the
158c2ecf20Sopenharmony_cidriver core automatically take care of them.
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciSecondly, the driver core by default does not enforce any driver presence
188c2ecf20Sopenharmony_cidependencies, i.e. that one device must be bound to a driver before
198c2ecf20Sopenharmony_cianother one can probe or function correctly.
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ciOften these two dependency types come together, so a device depends on
228c2ecf20Sopenharmony_cianother one both with regards to driver presence *and* with regards to
238c2ecf20Sopenharmony_cisuspend/resume and shutdown ordering.
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ciDevice links allow representation of such dependencies in the driver core.
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ciIn its standard or *managed* form, a device link combines *both* dependency
288c2ecf20Sopenharmony_citypes:  It guarantees correct suspend/resume and shutdown ordering between a
298c2ecf20Sopenharmony_ci"supplier" device and its "consumer" devices, and it guarantees driver
308c2ecf20Sopenharmony_cipresence on the supplier.  The consumer devices are not probed before the
318c2ecf20Sopenharmony_cisupplier is bound to a driver, and they're unbound before the supplier
328c2ecf20Sopenharmony_ciis unbound.
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciWhen driver presence on the supplier is irrelevant and only correct
358c2ecf20Sopenharmony_cisuspend/resume and shutdown ordering is needed, the device link may
368c2ecf20Sopenharmony_cisimply be set up with the ``DL_FLAG_STATELESS`` flag.  In other words,
378c2ecf20Sopenharmony_cienforcing driver presence on the supplier is optional.
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciAnother optional feature is runtime PM integration:  By setting the
408c2ecf20Sopenharmony_ci``DL_FLAG_PM_RUNTIME`` flag on addition of the device link, the PM core
418c2ecf20Sopenharmony_ciis instructed to runtime resume the supplier and keep it active
428c2ecf20Sopenharmony_ciwhenever and for as long as the consumer is runtime resumed.
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ciUsage
458c2ecf20Sopenharmony_ci=====
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ciThe earliest point in time when device links can be added is after
488c2ecf20Sopenharmony_ci:c:func:`device_add()` has been called for the supplier and
498c2ecf20Sopenharmony_ci:c:func:`device_initialize()` has been called for the consumer.
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciIt is legal to add them later, but care must be taken that the system
528c2ecf20Sopenharmony_ciremains in a consistent state:  E.g. a device link cannot be added in
538c2ecf20Sopenharmony_cithe midst of a suspend/resume transition, so either commencement of
548c2ecf20Sopenharmony_cisuch a transition needs to be prevented with :c:func:`lock_system_sleep()`,
558c2ecf20Sopenharmony_cior the device link needs to be added from a function which is guaranteed
568c2ecf20Sopenharmony_cinot to run in parallel to a suspend/resume transition, such as from a
578c2ecf20Sopenharmony_cidevice ``->probe`` callback or a boot-time PCI quirk.
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ciAnother example for an inconsistent state would be a device link that
608c2ecf20Sopenharmony_cirepresents a driver presence dependency, yet is added from the consumer's
618c2ecf20Sopenharmony_ci``->probe`` callback while the supplier hasn't started to probe yet:  Had the
628c2ecf20Sopenharmony_cidriver core known about the device link earlier, it wouldn't have probed the
638c2ecf20Sopenharmony_ciconsumer in the first place.  The onus is thus on the consumer to check
648c2ecf20Sopenharmony_cipresence of the supplier after adding the link, and defer probing on
658c2ecf20Sopenharmony_cinon-presence.  [Note that it is valid to create a link from the consumer's
668c2ecf20Sopenharmony_ci``->probe`` callback while the supplier is still probing, but the consumer must
678c2ecf20Sopenharmony_ciknow that the supplier is functional already at the link creation time (that is
688c2ecf20Sopenharmony_cithe case, for instance, if the consumer has just acquired some resources that
698c2ecf20Sopenharmony_ciwould not have been available had the supplier not been functional then).]
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ciIf a device link with ``DL_FLAG_STATELESS`` set (i.e. a stateless device link)
728c2ecf20Sopenharmony_ciis added in the ``->probe`` callback of the supplier or consumer driver, it is
738c2ecf20Sopenharmony_citypically deleted in its ``->remove`` callback for symmetry.  That way, if the
748c2ecf20Sopenharmony_cidriver is compiled as a module, the device link is added on module load and
758c2ecf20Sopenharmony_ciorderly deleted on unload.  The same restrictions that apply to device link
768c2ecf20Sopenharmony_ciaddition (e.g. exclusion of a parallel suspend/resume transition) apply equally
778c2ecf20Sopenharmony_cito deletion.  Device links managed by the driver core are deleted automatically
788c2ecf20Sopenharmony_ciby it.
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ciSeveral flags may be specified on device link addition, two of which
818c2ecf20Sopenharmony_cihave already been mentioned above:  ``DL_FLAG_STATELESS`` to express that no
828c2ecf20Sopenharmony_cidriver presence dependency is needed (but only correct suspend/resume and
838c2ecf20Sopenharmony_cishutdown ordering) and ``DL_FLAG_PM_RUNTIME`` to express that runtime PM
848c2ecf20Sopenharmony_ciintegration is desired.
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ciTwo other flags are specifically targeted at use cases where the device
878c2ecf20Sopenharmony_cilink is added from the consumer's ``->probe`` callback:  ``DL_FLAG_RPM_ACTIVE``
888c2ecf20Sopenharmony_cican be specified to runtime resume the supplier and prevent it from suspending
898c2ecf20Sopenharmony_cibefore the consumer is runtime suspended.  ``DL_FLAG_AUTOREMOVE_CONSUMER``
908c2ecf20Sopenharmony_cicauses the device link to be automatically purged when the consumer fails to
918c2ecf20Sopenharmony_ciprobe or later unbinds.
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciSimilarly, when the device link is added from supplier's ``->probe`` callback,
948c2ecf20Sopenharmony_ci``DL_FLAG_AUTOREMOVE_SUPPLIER`` causes the device link to be automatically
958c2ecf20Sopenharmony_cipurged when the supplier fails to probe or later unbinds.
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ciIf neither ``DL_FLAG_AUTOREMOVE_CONSUMER`` nor ``DL_FLAG_AUTOREMOVE_SUPPLIER``
988c2ecf20Sopenharmony_ciis set, ``DL_FLAG_AUTOPROBE_CONSUMER`` can be used to request the driver core
998c2ecf20Sopenharmony_cito probe for a driver for the consumer driver on the link automatically after
1008c2ecf20Sopenharmony_cia driver has been bound to the supplier device.
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciNote, however, that any combinations of ``DL_FLAG_AUTOREMOVE_CONSUMER``,
1038c2ecf20Sopenharmony_ci``DL_FLAG_AUTOREMOVE_SUPPLIER`` or ``DL_FLAG_AUTOPROBE_CONSUMER`` with
1048c2ecf20Sopenharmony_ci``DL_FLAG_STATELESS`` are invalid and cannot be used.
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciLimitations
1078c2ecf20Sopenharmony_ci===========
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ciDriver authors should be aware that a driver presence dependency for managed
1108c2ecf20Sopenharmony_cidevice links (i.e. when ``DL_FLAG_STATELESS`` is not specified on link addition)
1118c2ecf20Sopenharmony_cimay cause probing of the consumer to be deferred indefinitely.  This can become
1128c2ecf20Sopenharmony_cia problem if the consumer is required to probe before a certain initcall level
1138c2ecf20Sopenharmony_ciis reached.  Worse, if the supplier driver is blacklisted or missing, the
1148c2ecf20Sopenharmony_ciconsumer will never be probed.
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ciMoreover, managed device links cannot be deleted directly.  They are deleted
1178c2ecf20Sopenharmony_ciby the driver core when they are not necessary any more in accordance with the
1188c2ecf20Sopenharmony_ci``DL_FLAG_AUTOREMOVE_CONSUMER`` and ``DL_FLAG_AUTOREMOVE_SUPPLIER`` flags.
1198c2ecf20Sopenharmony_ciHowever, stateless device links (i.e. device links with ``DL_FLAG_STATELESS``
1208c2ecf20Sopenharmony_ciset) are expected to be removed by whoever called :c:func:`device_link_add()`
1218c2ecf20Sopenharmony_cito add them with the help of either :c:func:`device_link_del()` or
1228c2ecf20Sopenharmony_ci:c:func:`device_link_remove()`.
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ciPassing ``DL_FLAG_RPM_ACTIVE`` along with ``DL_FLAG_STATELESS`` to
1258c2ecf20Sopenharmony_ci:c:func:`device_link_add()` may cause the PM-runtime usage counter of the
1268c2ecf20Sopenharmony_cisupplier device to remain nonzero after a subsequent invocation of either
1278c2ecf20Sopenharmony_ci:c:func:`device_link_del()` or :c:func:`device_link_remove()` to remove the
1288c2ecf20Sopenharmony_cidevice link returned by it.  This happens if :c:func:`device_link_add()` is
1298c2ecf20Sopenharmony_cicalled twice in a row for the same consumer-supplier pair without removing the
1308c2ecf20Sopenharmony_cilink between these calls, in which case allowing the PM-runtime usage counter
1318c2ecf20Sopenharmony_ciof the supplier to drop on an attempt to remove the link may cause it to be
1328c2ecf20Sopenharmony_cisuspended while the consumer is still PM-runtime-active and that has to be
1338c2ecf20Sopenharmony_ciavoided.  [To work around this limitation it is sufficient to let the consumer
1348c2ecf20Sopenharmony_ciruntime suspend at least once, or call :c:func:`pm_runtime_set_suspended()` for
1358c2ecf20Sopenharmony_ciit with PM-runtime disabled, between the :c:func:`device_link_add()` and
1368c2ecf20Sopenharmony_ci:c:func:`device_link_del()` or :c:func:`device_link_remove()` calls.]
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ciSometimes drivers depend on optional resources.  They are able to operate
1398c2ecf20Sopenharmony_ciin a degraded mode (reduced feature set or performance) when those resources
1408c2ecf20Sopenharmony_ciare not present.  An example is an SPI controller that can use a DMA engine
1418c2ecf20Sopenharmony_cior work in PIO mode.  The controller can determine presence of the optional
1428c2ecf20Sopenharmony_ciresources at probe time but on non-presence there is no way to know whether
1438c2ecf20Sopenharmony_cithey will become available in the near future (due to a supplier driver
1448c2ecf20Sopenharmony_ciprobing) or never.  Consequently it cannot be determined whether to defer
1458c2ecf20Sopenharmony_ciprobing or not.  It would be possible to notify drivers when optional
1468c2ecf20Sopenharmony_ciresources become available after probing, but it would come at a high cost
1478c2ecf20Sopenharmony_cifor drivers as switching between modes of operation at runtime based on the
1488c2ecf20Sopenharmony_ciavailability of such resources would be much more complex than a mechanism
1498c2ecf20Sopenharmony_cibased on probe deferral.  In any case optional resources are beyond the
1508c2ecf20Sopenharmony_ciscope of device links.
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ciExamples
1538c2ecf20Sopenharmony_ci========
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci* An MMU device exists alongside a busmaster device, both are in the same
1568c2ecf20Sopenharmony_ci  power domain.  The MMU implements DMA address translation for the busmaster
1578c2ecf20Sopenharmony_ci  device and shall be runtime resumed and kept active whenever and as long
1588c2ecf20Sopenharmony_ci  as the busmaster device is active.  The busmaster device's driver shall
1598c2ecf20Sopenharmony_ci  not bind before the MMU is bound.  To achieve this, a device link with
1608c2ecf20Sopenharmony_ci  runtime PM integration is added from the busmaster device (consumer)
1618c2ecf20Sopenharmony_ci  to the MMU device (supplier).  The effect with regards to runtime PM
1628c2ecf20Sopenharmony_ci  is the same as if the MMU was the parent of the master device.
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci  The fact that both devices share the same power domain would normally
1658c2ecf20Sopenharmony_ci  suggest usage of a struct dev_pm_domain or struct generic_pm_domain,
1668c2ecf20Sopenharmony_ci  however these are not independent devices that happen to share a power
1678c2ecf20Sopenharmony_ci  switch, but rather the MMU device serves the busmaster device and is
1688c2ecf20Sopenharmony_ci  useless without it.  A device link creates a synthetic hierarchical
1698c2ecf20Sopenharmony_ci  relationship between the devices and is thus more apt.
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci* A Thunderbolt host controller comprises a number of PCIe hotplug ports
1728c2ecf20Sopenharmony_ci  and an NHI device to manage the PCIe switch.  On resume from system sleep,
1738c2ecf20Sopenharmony_ci  the NHI device needs to re-establish PCI tunnels to attached devices
1748c2ecf20Sopenharmony_ci  before the hotplug ports can resume.  If the hotplug ports were children
1758c2ecf20Sopenharmony_ci  of the NHI, this resume order would automatically be enforced by the
1768c2ecf20Sopenharmony_ci  PM core, but unfortunately they're aunts.  The solution is to add
1778c2ecf20Sopenharmony_ci  device links from the hotplug ports (consumers) to the NHI device
1788c2ecf20Sopenharmony_ci  (supplier).  A driver presence dependency is not necessary for this
1798c2ecf20Sopenharmony_ci  use case.
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci* Discrete GPUs in hybrid graphics laptops often feature an HDA controller
1828c2ecf20Sopenharmony_ci  for HDMI/DP audio.  In the device hierarchy the HDA controller is a sibling
1838c2ecf20Sopenharmony_ci  of the VGA device, yet both share the same power domain and the HDA
1848c2ecf20Sopenharmony_ci  controller is only ever needed when an HDMI/DP display is attached to the
1858c2ecf20Sopenharmony_ci  VGA device.  A device link from the HDA controller (consumer) to the
1868c2ecf20Sopenharmony_ci  VGA device (supplier) aptly represents this relationship.
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci* ACPI allows definition of a device start order by way of _DEP objects.
1898c2ecf20Sopenharmony_ci  A classical example is when ACPI power management methods on one device
1908c2ecf20Sopenharmony_ci  are implemented in terms of I\ :sup:`2`\ C accesses and require a specific
1918c2ecf20Sopenharmony_ci  I\ :sup:`2`\ C controller to be present and functional for the power
1928c2ecf20Sopenharmony_ci  management of the device in question to work.
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci* In some SoCs a functional dependency exists from display, video codec and
1958c2ecf20Sopenharmony_ci  video processing IP cores on transparent memory access IP cores that handle
1968c2ecf20Sopenharmony_ci  burst access and compression/decompression.
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ciAlternatives
1998c2ecf20Sopenharmony_ci============
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci* A struct dev_pm_domain can be used to override the bus,
2028c2ecf20Sopenharmony_ci  class or device type callbacks.  It is intended for devices sharing
2038c2ecf20Sopenharmony_ci  a single on/off switch, however it does not guarantee a specific
2048c2ecf20Sopenharmony_ci  suspend/resume ordering, this needs to be implemented separately.
2058c2ecf20Sopenharmony_ci  It also does not by itself track the runtime PM status of the involved
2068c2ecf20Sopenharmony_ci  devices and turn off the power switch only when all of them are runtime
2078c2ecf20Sopenharmony_ci  suspended.  Furthermore it cannot be used to enforce a specific shutdown
2088c2ecf20Sopenharmony_ci  ordering or a driver presence dependency.
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci* A struct generic_pm_domain is a lot more heavyweight than a
2118c2ecf20Sopenharmony_ci  device link and does not allow for shutdown ordering or driver presence
2128c2ecf20Sopenharmony_ci  dependencies.  It also cannot be used on ACPI systems.
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ciImplementation
2158c2ecf20Sopenharmony_ci==============
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ciThe device hierarchy, which -- as the name implies -- is a tree,
2188c2ecf20Sopenharmony_cibecomes a directed acyclic graph once device links are added.
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ciOrdering of these devices during suspend/resume is determined by the
2218c2ecf20Sopenharmony_cidpm_list.  During shutdown it is determined by the devices_kset.  With
2228c2ecf20Sopenharmony_cino device links present, the two lists are a flattened, one-dimensional
2238c2ecf20Sopenharmony_cirepresentations of the device tree such that a device is placed behind
2248c2ecf20Sopenharmony_ciall its ancestors.  That is achieved by traversing the ACPI namespace
2258c2ecf20Sopenharmony_cior OpenFirmware device tree top-down and appending devices to the lists
2268c2ecf20Sopenharmony_cias they are discovered.
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ciOnce device links are added, the lists need to satisfy the additional
2298c2ecf20Sopenharmony_ciconstraint that a device is placed behind all its suppliers, recursively.
2308c2ecf20Sopenharmony_ciTo ensure this, upon addition of the device link the consumer and the
2318c2ecf20Sopenharmony_cientire sub-graph below it (all children and consumers of the consumer)
2328c2ecf20Sopenharmony_ciare moved to the end of the list.  (Call to :c:func:`device_reorder_to_tail()`
2338c2ecf20Sopenharmony_cifrom :c:func:`device_link_add()`.)
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ciTo prevent introduction of dependency loops into the graph, it is
2368c2ecf20Sopenharmony_civerified upon device link addition that the supplier is not dependent
2378c2ecf20Sopenharmony_cion the consumer or any children or consumers of the consumer.
2388c2ecf20Sopenharmony_ci(Call to :c:func:`device_is_dependent()` from :c:func:`device_link_add()`.)
2398c2ecf20Sopenharmony_ciIf that constraint is violated, :c:func:`device_link_add()` will return
2408c2ecf20Sopenharmony_ci``NULL`` and a ``WARNING`` will be logged.
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ciNotably this also prevents the addition of a device link from a parent
2438c2ecf20Sopenharmony_cidevice to a child.  However the converse is allowed, i.e. a device link
2448c2ecf20Sopenharmony_cifrom a child to a parent.  Since the driver core already guarantees
2458c2ecf20Sopenharmony_cicorrect suspend/resume and shutdown ordering between parent and child,
2468c2ecf20Sopenharmony_cisuch a device link only makes sense if a driver presence dependency is
2478c2ecf20Sopenharmony_cineeded on top of that.  In this case driver authors should weigh
2488c2ecf20Sopenharmony_cicarefully if a device link is at all the right tool for the purpose.
2498c2ecf20Sopenharmony_ciA more suitable approach might be to simply use deferred probing or
2508c2ecf20Sopenharmony_ciadd a device flag causing the parent driver to be probed before the
2518c2ecf20Sopenharmony_cichild one.
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ciState machine
2548c2ecf20Sopenharmony_ci=============
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci.. kernel-doc:: include/linux/device.h
2578c2ecf20Sopenharmony_ci   :functions: device_link_state
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci::
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci                 .=============================.
2628c2ecf20Sopenharmony_ci                 |                             |
2638c2ecf20Sopenharmony_ci                 v                             |
2648c2ecf20Sopenharmony_ci DORMANT <=> AVAILABLE <=> CONSUMER_PROBE => ACTIVE
2658c2ecf20Sopenharmony_ci    ^                                          |
2668c2ecf20Sopenharmony_ci    |                                          |
2678c2ecf20Sopenharmony_ci    '============ SUPPLIER_UNBIND <============'
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci* The initial state of a device link is automatically determined by
2708c2ecf20Sopenharmony_ci  :c:func:`device_link_add()` based on the driver presence on the supplier
2718c2ecf20Sopenharmony_ci  and consumer.  If the link is created before any devices are probed, it
2728c2ecf20Sopenharmony_ci  is set to ``DL_STATE_DORMANT``.
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci* When a supplier device is bound to a driver, links to its consumers
2758c2ecf20Sopenharmony_ci  progress to ``DL_STATE_AVAILABLE``.
2768c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_driver_bound()` from
2778c2ecf20Sopenharmony_ci  :c:func:`driver_bound()`.)
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci* Before a consumer device is probed, presence of supplier drivers is
2808c2ecf20Sopenharmony_ci  verified by checking the consumer device is not in the wait_for_suppliers
2818c2ecf20Sopenharmony_ci  list and by checking that links to suppliers are in ``DL_STATE_AVAILABLE``
2828c2ecf20Sopenharmony_ci  state.  The state of the links is updated to ``DL_STATE_CONSUMER_PROBE``.
2838c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_check_suppliers()` from
2848c2ecf20Sopenharmony_ci  :c:func:`really_probe()`.)
2858c2ecf20Sopenharmony_ci  This prevents the supplier from unbinding.
2868c2ecf20Sopenharmony_ci  (Call to :c:func:`wait_for_device_probe()` from
2878c2ecf20Sopenharmony_ci  :c:func:`device_links_unbind_consumers()`.)
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci* If the probe fails, links to suppliers revert back to ``DL_STATE_AVAILABLE``.
2908c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_no_driver()` from :c:func:`really_probe()`.)
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci* If the probe succeeds, links to suppliers progress to ``DL_STATE_ACTIVE``.
2938c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_driver_bound()` from :c:func:`driver_bound()`.)
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci* When the consumer's driver is later on removed, links to suppliers revert
2968c2ecf20Sopenharmony_ci  back to ``DL_STATE_AVAILABLE``.
2978c2ecf20Sopenharmony_ci  (Call to :c:func:`__device_links_no_driver()` from
2988c2ecf20Sopenharmony_ci  :c:func:`device_links_driver_cleanup()`, which in turn is called from
2998c2ecf20Sopenharmony_ci  :c:func:`__device_release_driver()`.)
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci* Before a supplier's driver is removed, links to consumers that are not
3028c2ecf20Sopenharmony_ci  bound to a driver are updated to ``DL_STATE_SUPPLIER_UNBIND``.
3038c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_busy()` from
3048c2ecf20Sopenharmony_ci  :c:func:`__device_release_driver()`.)
3058c2ecf20Sopenharmony_ci  This prevents the consumers from binding.
3068c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_check_suppliers()` from
3078c2ecf20Sopenharmony_ci  :c:func:`really_probe()`.)
3088c2ecf20Sopenharmony_ci  Consumers that are bound are freed from their driver; consumers that are
3098c2ecf20Sopenharmony_ci  probing are waited for until they are done.
3108c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_unbind_consumers()` from
3118c2ecf20Sopenharmony_ci  :c:func:`__device_release_driver()`.)
3128c2ecf20Sopenharmony_ci  Once all links to consumers are in ``DL_STATE_SUPPLIER_UNBIND`` state,
3138c2ecf20Sopenharmony_ci  the supplier driver is released and the links revert to ``DL_STATE_DORMANT``.
3148c2ecf20Sopenharmony_ci  (Call to :c:func:`device_links_driver_cleanup()` from
3158c2ecf20Sopenharmony_ci  :c:func:`__device_release_driver()`.)
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ciAPI
3188c2ecf20Sopenharmony_ci===
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ciSee device_link_add(), device_link_del() and device_link_remove().
321