2011-05-27 05:08:35 +07:00
|
|
|
#include <linux/notifier.h>
|
2005-10-13 23:54:41 +07:00
|
|
|
|
2007-11-02 09:41:16 +07:00
|
|
|
/**
|
2010-11-16 05:13:18 +07:00
|
|
|
* struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
|
2007-11-02 09:41:16 +07:00
|
|
|
*
|
2010-11-16 05:13:18 +07:00
|
|
|
* @subsys - the struct kset that defines this subsystem
|
2011-12-15 05:29:38 +07:00
|
|
|
* @devices_kset - the subsystem's 'devices' directory
|
|
|
|
* @interfaces - list of subsystem interfaces associated
|
|
|
|
* @mutex - protect the devices, and interfaces lists.
|
2010-11-16 05:13:18 +07:00
|
|
|
*
|
|
|
|
* @drivers_kset - the list of drivers associated
|
2007-11-02 09:41:16 +07:00
|
|
|
* @klist_devices - the klist to iterate over the @devices_kset
|
|
|
|
* @klist_drivers - the klist to iterate over the @drivers_kset
|
|
|
|
* @bus_notifier - the bus notifier list for anything that cares about things
|
2010-11-16 05:13:18 +07:00
|
|
|
* on this bus.
|
2007-11-02 09:41:16 +07:00
|
|
|
* @bus - pointer back to the struct bus_type that this structure is associated
|
2010-11-16 05:13:18 +07:00
|
|
|
* with.
|
|
|
|
*
|
|
|
|
* @glue_dirs - "glue" directory to put in-between the parent device to
|
|
|
|
* avoid namespace conflicts
|
|
|
|
* @class - pointer back to the struct class that this structure is associated
|
|
|
|
* with.
|
2007-11-02 09:41:16 +07:00
|
|
|
*
|
|
|
|
* This structure is the one that is the actual kobject allowing struct
|
2010-11-16 05:13:18 +07:00
|
|
|
* bus_type/class to be statically allocated safely. Nothing outside of the
|
|
|
|
* driver core should ever touch these fields.
|
2007-11-02 09:41:16 +07:00
|
|
|
*/
|
2010-11-16 05:13:18 +07:00
|
|
|
struct subsys_private {
|
2007-11-02 09:41:16 +07:00
|
|
|
struct kset subsys;
|
|
|
|
struct kset *devices_kset;
|
2011-12-15 05:29:38 +07:00
|
|
|
struct list_head interfaces;
|
|
|
|
struct mutex mutex;
|
2010-11-16 05:13:18 +07:00
|
|
|
|
|
|
|
struct kset *drivers_kset;
|
2007-11-02 09:41:16 +07:00
|
|
|
struct klist klist_devices;
|
|
|
|
struct klist klist_drivers;
|
|
|
|
struct blocking_notifier_head bus_notifier;
|
|
|
|
unsigned int drivers_autoprobe:1;
|
|
|
|
struct bus_type *bus;
|
2010-11-16 05:13:18 +07:00
|
|
|
|
|
|
|
struct kset glue_dirs;
|
|
|
|
struct class *class;
|
2007-11-02 09:41:16 +07:00
|
|
|
};
|
2010-11-16 05:13:18 +07:00
|
|
|
#define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj)
|
2007-11-02 09:41:16 +07:00
|
|
|
|
2007-11-29 06:59:15 +07:00
|
|
|
struct driver_private {
|
|
|
|
struct kobject kobj;
|
|
|
|
struct klist klist_devices;
|
|
|
|
struct klist_node knode_bus;
|
|
|
|
struct module_kobject *mkobj;
|
|
|
|
struct device_driver *driver;
|
|
|
|
};
|
|
|
|
#define to_driver(obj) container_of(obj, struct driver_private, kobj)
|
2005-10-13 23:54:41 +07:00
|
|
|
|
2008-12-17 03:23:36 +07:00
|
|
|
/**
|
|
|
|
* struct device_private - structure to hold the private to the driver core portions of the device structure.
|
|
|
|
*
|
2008-12-17 03:24:56 +07:00
|
|
|
* @klist_children - klist containing all children of this device
|
|
|
|
* @knode_parent - node in sibling list
|
2008-12-17 03:25:49 +07:00
|
|
|
* @knode_driver - node in driver list
|
2008-12-17 03:26:21 +07:00
|
|
|
* @knode_bus - node in bus list
|
2012-03-09 03:17:22 +07:00
|
|
|
* @deferred_probe - entry in deferred_probe_list which is used to retry the
|
|
|
|
* binding of drivers which were unable to get all the resources needed by
|
|
|
|
* the device; typically because it depends on another driver getting
|
|
|
|
* probed first.
|
2015-06-29 21:59:02 +07:00
|
|
|
* @device - pointer back to the struct device that this structure is
|
2008-12-17 03:23:36 +07:00
|
|
|
* associated with.
|
|
|
|
*
|
|
|
|
* Nothing outside of the driver core should ever touch these fields.
|
|
|
|
*/
|
|
|
|
struct device_private {
|
2008-12-17 03:24:56 +07:00
|
|
|
struct klist klist_children;
|
|
|
|
struct klist_node knode_parent;
|
2008-12-17 03:25:49 +07:00
|
|
|
struct klist_node knode_driver;
|
2008-12-17 03:26:21 +07:00
|
|
|
struct klist_node knode_bus;
|
2012-03-09 03:17:22 +07:00
|
|
|
struct list_head deferred_probe;
|
2008-12-17 03:23:36 +07:00
|
|
|
struct device *device;
|
|
|
|
};
|
2008-12-17 03:24:56 +07:00
|
|
|
#define to_device_private_parent(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_parent)
|
2008-12-17 03:25:49 +07:00
|
|
|
#define to_device_private_driver(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_driver)
|
2008-12-17 03:26:21 +07:00
|
|
|
#define to_device_private_bus(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_bus)
|
2008-12-17 03:23:36 +07:00
|
|
|
|
2009-05-12 04:16:57 +07:00
|
|
|
extern int device_private_init(struct device *dev);
|
|
|
|
|
2007-11-02 09:41:16 +07:00
|
|
|
/* initialisation functions */
|
2005-10-13 23:54:41 +07:00
|
|
|
extern int devices_init(void);
|
|
|
|
extern int buses_init(void);
|
|
|
|
extern int classes_init(void);
|
|
|
|
extern int firmware_init(void);
|
2006-05-09 17:53:49 +07:00
|
|
|
#ifdef CONFIG_SYS_HYPERVISOR
|
|
|
|
extern int hypervisor_init(void);
|
|
|
|
#else
|
|
|
|
static inline int hypervisor_init(void) { return 0; }
|
|
|
|
#endif
|
2005-10-13 23:54:41 +07:00
|
|
|
extern int platform_bus_init(void);
|
2012-01-10 09:59:49 +07:00
|
|
|
extern void cpu_dev_init(void);
|
ACPI / hotplug / driver core: Handle containers in a special way
ACPI container devices require special hotplug handling, at least
on some systems, since generally user space needs to carry out
system-specific cleanup before it makes sense to offline devices in
the container. However, the current ACPI hotplug code for containers
first attempts to offline devices in the container and only then it
notifies user space of the container offline.
Moreover, after commit 202317a573b2 (ACPI / scan: Add acpi_device
objects for all device nodes in the namespace), ACPI device objects
representing containers are present as long as the ACPI namespace
nodes corresponding to them are present, which may be forever, even
if the container devices are physically detached from the system (the
return values of the corresponding _STA methods change in those
cases, but generally the namespace nodes themselves are still there).
Thus it is useful to introduce entities representing containers that
will go away during container hot-unplug.
The goal of this change is to address both the above issues.
The idea is to create a "companion" container system device for each
of the ACPI container device objects during the initial namespace
scan or on a hotplug event making the container present. That system
device will be unregistered on container removal. A new bus type
for container devices is added for this purpose, because device
offline and online operations need to be defined for them. The
online operation is a trivial function that is always successful
and the offline uses a callback pointed to by the container device's
offline member.
For ACPI containers that callback simply walks the list of ACPI
device objects right below the container object (its children) and
checks if all of their physical companion devices are offline. If
that's not the case, it returns -EBUSY and the container system
devivce cannot be put offline. Consequently, to put the container
system device offline, it is necessary to put all of the physical
devices depending on its ACPI companion object offline beforehand.
Container system devices created for ACPI container objects are
initially online. They are created by the container ACPI scan
handler whose hotplug.demand_offline flag is set. That causes
acpi_scan_hot_remove() to check if the companion container system
device is offline before attempting to remove an ACPI container or
any devices below it. If the check fails, a KOBJ_CHANGE uevent is
emitted for the container system device in question and user space
is expected to offline all devices below the container and the
container itself in response to it. Then, user space can finalize
the removal of the container with the help of its ACPI device
object's eject attribute in sysfs.
Tested-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-12-29 21:25:48 +07:00
|
|
|
extern void container_dev_init(void);
|
2005-10-13 23:54:41 +07:00
|
|
|
|
2013-03-13 01:30:05 +07:00
|
|
|
struct kobject *virtual_device_parent(struct device *dev);
|
|
|
|
|
2008-01-25 13:50:12 +07:00
|
|
|
extern int bus_add_device(struct device *dev);
|
2009-07-31 02:27:18 +07:00
|
|
|
extern void bus_probe_device(struct device *dev);
|
2008-01-25 13:50:12 +07:00
|
|
|
extern void bus_remove_device(struct device *dev);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2008-01-25 13:50:12 +07:00
|
|
|
extern int bus_add_driver(struct device_driver *drv);
|
|
|
|
extern void bus_remove_driver(struct device_driver *drv);
|
driver core: Functional dependencies tracking support
Currently, there is a problem with taking functional dependencies
between devices into account.
What I mean by a "functional dependency" is when the driver of device
B needs device A to be functional and (generally) its driver to be
present in order to work properly. This has certain consequences
for power management (suspend/resume and runtime PM ordering) and
shutdown ordering of these devices. In general, it also implies that
the driver of A needs to be working for B to be probed successfully
and it cannot be unbound from the device before the B's driver.
Support for representing those functional dependencies between
devices is added here to allow the driver core to track them and act
on them in certain cases where applicable.
The argument for doing that in the driver core is that there are
quite a few distinct use cases involving device dependencies, they
are relatively hard to get right in a driver (if one wants to
address all of them properly) and it only gets worse if multiplied
by the number of drivers potentially needing to do it. Morever, at
least one case (asynchronous system suspend/resume) cannot be handled
in a single driver at all, because it requires the driver of A to
wait for B to suspend (during system suspend) and the driver of B to
wait for A to resume (during system resume).
For this reason, represent dependencies between devices as "links",
with the help of struct device_link objects each containing pointers
to the "linked" devices, a list node for each of them, status
information, flags, and an RCU head for synchronization.
Also add two new list heads, representing the lists of links to the
devices that depend on the given one (consumers) and to the devices
depended on by it (suppliers), and a "driver presence status" field
(needed for figuring out initial states of device links) to struct
device.
The entire data structure consisting of all of the lists of link
objects for all devices is protected by a mutex (for link object
addition/removal and for list walks during device driver probing
and removal) and by SRCU (for list walking in other case that will
be introduced by subsequent change sets). If CONFIG_SRCU is not
selected, however, an rwsem is used for protecting the entire data
structure.
In addition, each link object has an internal status field whose
value reflects whether or not drivers are bound to the devices
pointed to by the link or probing/removal of their drivers is in
progress etc. That field is only modified under the device links
mutex, but it may be read outside of it in some cases (introduced by
subsequent change sets), so modifications of it are annotated with
WRITE_ONCE().
New links are added by calling device_link_add() which takes three
arguments: pointers to the devices in question and flags. In
particular, if DL_FLAG_STATELESS is set in the flags, the link status
is not to be taken into account for this link and the driver core
will not manage it. In turn, if DL_FLAG_AUTOREMOVE is set in the
flags, the driver core will remove the link automatically when the
consumer device driver unbinds from it.
One of the actions carried out by device_link_add() is to reorder
the lists used for device shutdown and system suspend/resume to
put the consumer device along with all of its children and all of
its consumers (and so on, recursively) to the ends of those lists
in order to ensure the right ordering between all of the supplier
and consumer devices.
For this reason, it is not possible to create a link between two
devices if the would-be supplier device already depends on the
would-be consumer device as either a direct descendant of it or a
consumer of one of its direct descendants or one of its consumers
and so on.
There are two types of link objects, persistent and non-persistent.
The persistent ones stay around until one of the target devices is
deleted, while the non-persistent ones are removed automatically when
the consumer driver unbinds from its device (ie. they are assumed to
be valid only as long as the consumer device has a driver bound to
it). Persistent links are created by default and non-persistent
links are created when the DL_FLAG_AUTOREMOVE flag is passed
to device_link_add().
Both persistent and non-persistent device links can be deleted
with an explicit call to device_link_del().
Links created without the DL_FLAG_STATELESS flag set are managed
by the driver core using a simple state machine. There are 5 states
each link can be in: DORMANT (unused), AVAILABLE (the supplier driver
is present and functional), CONSUMER_PROBE (the consumer driver is
probing), ACTIVE (both supplier and consumer drivers are present and
functional), and SUPPLIER_UNBIND (the supplier driver is unbinding).
The driver core updates the link state automatically depending on
what happens to the linked devices and for each link state specific
actions are taken in addition to that.
For example, if the supplier driver unbinds from its device, the
driver core will also unbind the drivers of all of its consumers
automatically under the assumption that they cannot function
properly without the supplier. Analogously, the driver core will
only allow the consumer driver to bind to its device if the
supplier driver is present and functional (ie. the link is in
the AVAILABLE state). If that's not the case, it will rely on
the existing deferred probing mechanism to wait for the supplier
driver to become available.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-30 23:32:16 +07:00
|
|
|
extern void device_release_driver_internal(struct device *dev,
|
|
|
|
struct device_driver *drv,
|
|
|
|
struct device *parent);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2008-01-25 13:50:12 +07:00
|
|
|
extern void driver_detach(struct device_driver *drv);
|
|
|
|
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
|
2012-03-05 22:47:41 +07:00
|
|
|
extern void driver_deferred_probe_del(struct device *dev);
|
2009-01-21 22:27:47 +07:00
|
|
|
static inline int driver_match_device(struct device_driver *drv,
|
|
|
|
struct device *dev)
|
|
|
|
{
|
2009-03-27 20:50:00 +07:00
|
|
|
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
|
2009-01-21 22:27:47 +07:00
|
|
|
}
|
2015-03-31 06:20:04 +07:00
|
|
|
extern bool driver_allows_async_probing(struct device_driver *drv);
|
2005-03-22 01:52:54 +07:00
|
|
|
|
2013-08-09 05:22:56 +07:00
|
|
|
extern int driver_add_groups(struct device_driver *drv,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
extern void driver_remove_groups(struct device_driver *drv,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
|
2006-06-21 03:59:20 +07:00
|
|
|
extern char *make_class_name(const char *name, struct kobject *kobj);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2007-06-18 06:42:54 +07:00
|
|
|
extern int devres_release_all(struct device *dev);
|
2015-11-10 16:42:34 +07:00
|
|
|
extern void device_block_probing(void);
|
|
|
|
extern void device_unblock_probing(void);
|
2007-04-14 03:15:19 +07:00
|
|
|
|
2011-12-15 05:29:38 +07:00
|
|
|
/* /sys/devices directory */
|
2007-11-01 22:29:06 +07:00
|
|
|
extern struct kset *devices_kset;
|
driver core: correct device's shutdown order
Now device's shutdown sequence is performed in reverse order of their
registration in devices_kset list and this sequence corresponds to the
reverse device's creation order. So, devices_kset data tracks
"parent<-child" device's dependencies only.
Unfortunately, that's not enough and causes problems in case of
implementing board's specific shutdown procedures. For example [1]:
"DRA7XX_evm uses PCF8575 and one of the PCF output lines feeds to
MMC/SD and this line should be driven high in order for the MMC/SD to
be detected. This line is modelled as regulator and the hsmmc driver
takes care of enabling and disabling it. In the case of 'reboot',
during shutdown path as part of it's cleanup process the hsmmc driver
disables this regulator. This makes MMC boot not functional."
To handle this issue the .shutdown() callback could be implemented
for PCF8575 device where corresponding GPIO pins will be configured to
states, required for correct warm/cold reset. This can be achieved
only when all .shutdown() callbacks have been called already for all
PCF8575's consumers. But devices_kset is not filled correctly now:
devices_kset: Device61 4e000000.dmm
devices_kset: Device62 48070000.i2c
devices_kset: Device63 48072000.i2c
devices_kset: Device64 48060000.i2c
devices_kset: Device65 4809c000.mmc
...
devices_kset: Device102 fixedregulator-sd
...
devices_kset: Device181 0-0020 // PCF8575
devices_kset: Device182 gpiochip496
devices_kset: Device183 0-0021 // PCF8575
devices_kset: Device184 gpiochip480
As can be seen from above .shutdown() callback for PCF8575 will be called
before its consumers, which, in turn means, that any changes of PCF8575
GPIO's pins will be or unsafe or overwritten later by GPIO's consumers.
The problem can be solved if devices_kset list will be filled not only
according device creation order, but also according device's probing
order to track "supplier<-consumer" dependencies also.
Hence, as a fix, lets add devices_kset_move_last(),
devices_kset_move_before(), devices_kset_move_after() and call them
from device_move() and also add call of devices_kset_move_last() in
really_probe(). After this change all entries in devices_kset will
be sorted according to device's creation ("parent<-child") and
probing ("supplier<-consumer") order.
devices_kset after:
devices_kset: Device121 48070000.i2c
devices_kset: Device122 i2c-0
...
devices_kset: Device147 regulator.24
devices_kset: Device148 0-0020
devices_kset: Device149 gpiochip496
devices_kset: Device150 0-0021
devices_kset: Device151 gpiochip480
devices_kset: Device152 0-0019
...
devices_kset: Device372 fixedregulator-sd
devices_kset: Device373 regulator.29
devices_kset: Device374 4809c000.mmc
devices_kset: Device375 mmc0
[1] http://www.spinics.net/lists/linux-mmc/msg29825.html
Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-07-28 00:43:01 +07:00
|
|
|
extern void devices_kset_move_last(struct device *dev);
|
2007-11-29 03:23:18 +07:00
|
|
|
|
2008-01-01 01:05:43 +07:00
|
|
|
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
|
2007-11-29 03:23:18 +07:00
|
|
|
extern void module_add_driver(struct module *mod, struct device_driver *drv);
|
|
|
|
extern void module_remove_driver(struct device_driver *drv);
|
|
|
|
#else
|
|
|
|
static inline void module_add_driver(struct module *mod,
|
|
|
|
struct device_driver *drv) { }
|
|
|
|
static inline void module_remove_driver(struct device_driver *drv) { }
|
|
|
|
#endif
|
Driver Core: devtmpfs - kernel-maintained tmpfs-based /dev
Devtmpfs lets the kernel create a tmpfs instance called devtmpfs
very early at kernel initialization, before any driver-core device
is registered. Every device with a major/minor will provide a
device node in devtmpfs.
Devtmpfs can be changed and altered by userspace at any time,
and in any way needed - just like today's udev-mounted tmpfs.
Unmodified udev versions will run just fine on top of it, and will
recognize an already existing kernel-created device node and use it.
The default node permissions are root:root 0600. Proper permissions
and user/group ownership, meaningful symlinks, all other policy still
needs to be applied by userspace.
If a node is created by devtmps, devtmpfs will remove the device node
when the device goes away. If the device node was created by
userspace, or the devtmpfs created node was replaced by userspace, it
will no longer be removed by devtmpfs.
If it is requested to auto-mount it, it makes init=/bin/sh work
without any further userspace support. /dev will be fully populated
and dynamic, and always reflect the current device state of the kernel.
With the commonly used dynamic device numbers, it solves the problem
where static devices nodes may point to the wrong devices.
It is intended to make the initial bootup logic simpler and more robust,
by de-coupling the creation of the inital environment, to reliably run
userspace processes, from a complex userspace bootstrap logic to provide
a working /dev.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Jan Blunck <jblunck@suse.de>
Tested-By: Harald Hoyer <harald@redhat.com>
Tested-By: Scott James Remnant <scott@ubuntu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-30 20:23:42 +07:00
|
|
|
|
|
|
|
#ifdef CONFIG_DEVTMPFS
|
|
|
|
extern int devtmpfs_init(void);
|
|
|
|
#else
|
|
|
|
static inline int devtmpfs_init(void) { return 0; }
|
|
|
|
#endif
|
driver core: Functional dependencies tracking support
Currently, there is a problem with taking functional dependencies
between devices into account.
What I mean by a "functional dependency" is when the driver of device
B needs device A to be functional and (generally) its driver to be
present in order to work properly. This has certain consequences
for power management (suspend/resume and runtime PM ordering) and
shutdown ordering of these devices. In general, it also implies that
the driver of A needs to be working for B to be probed successfully
and it cannot be unbound from the device before the B's driver.
Support for representing those functional dependencies between
devices is added here to allow the driver core to track them and act
on them in certain cases where applicable.
The argument for doing that in the driver core is that there are
quite a few distinct use cases involving device dependencies, they
are relatively hard to get right in a driver (if one wants to
address all of them properly) and it only gets worse if multiplied
by the number of drivers potentially needing to do it. Morever, at
least one case (asynchronous system suspend/resume) cannot be handled
in a single driver at all, because it requires the driver of A to
wait for B to suspend (during system suspend) and the driver of B to
wait for A to resume (during system resume).
For this reason, represent dependencies between devices as "links",
with the help of struct device_link objects each containing pointers
to the "linked" devices, a list node for each of them, status
information, flags, and an RCU head for synchronization.
Also add two new list heads, representing the lists of links to the
devices that depend on the given one (consumers) and to the devices
depended on by it (suppliers), and a "driver presence status" field
(needed for figuring out initial states of device links) to struct
device.
The entire data structure consisting of all of the lists of link
objects for all devices is protected by a mutex (for link object
addition/removal and for list walks during device driver probing
and removal) and by SRCU (for list walking in other case that will
be introduced by subsequent change sets). If CONFIG_SRCU is not
selected, however, an rwsem is used for protecting the entire data
structure.
In addition, each link object has an internal status field whose
value reflects whether or not drivers are bound to the devices
pointed to by the link or probing/removal of their drivers is in
progress etc. That field is only modified under the device links
mutex, but it may be read outside of it in some cases (introduced by
subsequent change sets), so modifications of it are annotated with
WRITE_ONCE().
New links are added by calling device_link_add() which takes three
arguments: pointers to the devices in question and flags. In
particular, if DL_FLAG_STATELESS is set in the flags, the link status
is not to be taken into account for this link and the driver core
will not manage it. In turn, if DL_FLAG_AUTOREMOVE is set in the
flags, the driver core will remove the link automatically when the
consumer device driver unbinds from it.
One of the actions carried out by device_link_add() is to reorder
the lists used for device shutdown and system suspend/resume to
put the consumer device along with all of its children and all of
its consumers (and so on, recursively) to the ends of those lists
in order to ensure the right ordering between all of the supplier
and consumer devices.
For this reason, it is not possible to create a link between two
devices if the would-be supplier device already depends on the
would-be consumer device as either a direct descendant of it or a
consumer of one of its direct descendants or one of its consumers
and so on.
There are two types of link objects, persistent and non-persistent.
The persistent ones stay around until one of the target devices is
deleted, while the non-persistent ones are removed automatically when
the consumer driver unbinds from its device (ie. they are assumed to
be valid only as long as the consumer device has a driver bound to
it). Persistent links are created by default and non-persistent
links are created when the DL_FLAG_AUTOREMOVE flag is passed
to device_link_add().
Both persistent and non-persistent device links can be deleted
with an explicit call to device_link_del().
Links created without the DL_FLAG_STATELESS flag set are managed
by the driver core using a simple state machine. There are 5 states
each link can be in: DORMANT (unused), AVAILABLE (the supplier driver
is present and functional), CONSUMER_PROBE (the consumer driver is
probing), ACTIVE (both supplier and consumer drivers are present and
functional), and SUPPLIER_UNBIND (the supplier driver is unbinding).
The driver core updates the link state automatically depending on
what happens to the linked devices and for each link state specific
actions are taken in addition to that.
For example, if the supplier driver unbinds from its device, the
driver core will also unbind the drivers of all of its consumers
automatically under the assumption that they cannot function
properly without the supplier. Analogously, the driver core will
only allow the consumer driver to bind to its device if the
supplier driver is present and functional (ie. the link is in
the AVAILABLE state). If that's not the case, it will rely on
the existing deferred probing mechanism to wait for the supplier
driver to become available.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-30 23:32:16 +07:00
|
|
|
|
|
|
|
/* Device links support */
|
|
|
|
extern int device_links_read_lock(void);
|
|
|
|
extern void device_links_read_unlock(int idx);
|
|
|
|
extern int device_links_check_suppliers(struct device *dev);
|
|
|
|
extern void device_links_driver_bound(struct device *dev);
|
|
|
|
extern void device_links_driver_cleanup(struct device *dev);
|
|
|
|
extern void device_links_no_driver(struct device *dev);
|
|
|
|
extern bool device_links_busy(struct device *dev);
|
|
|
|
extern void device_links_unbind_consumers(struct device *dev);
|