License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2019-12-10 03:32:58 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
|
|
|
|
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
* Copyright (c) 2008-2012 Novell Inc.
|
|
|
|
* Copyright (c) 2012-2019 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
* Copyright (c) 2012-2019 Linux Foundation
|
|
|
|
*
|
|
|
|
* Core driver model functions and structures that should not be
|
|
|
|
* shared outside of the drivers/base/ directory.
|
|
|
|
*
|
|
|
|
*/
|
2011-05-27 06:08:35 +08:00
|
|
|
#include <linux/notifier.h>
|
2005-10-14 00:54:41 +08:00
|
|
|
|
2007-11-02 10:41:16 +08:00
|
|
|
/**
|
2010-11-16 06:13:18 +08:00
|
|
|
* struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
|
2007-11-02 10:41:16 +08:00
|
|
|
*
|
2010-11-16 06:13:18 +08:00
|
|
|
* @subsys - the struct kset that defines this subsystem
|
2011-12-15 06:29:38 +08:00
|
|
|
* @devices_kset - the subsystem's 'devices' directory
|
|
|
|
* @interfaces - list of subsystem interfaces associated
|
|
|
|
* @mutex - protect the devices, and interfaces lists.
|
2010-11-16 06:13:18 +08:00
|
|
|
*
|
|
|
|
* @drivers_kset - the list of drivers associated
|
2007-11-02 10:41:16 +08: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 06:13:18 +08:00
|
|
|
* on this bus.
|
2007-11-02 10:41:16 +08:00
|
|
|
* @bus - pointer back to the struct bus_type that this structure is associated
|
2010-11-16 06:13:18 +08:00
|
|
|
* with.
|
2023-03-14 02:29:04 +08:00
|
|
|
* @dev_root: Default device to use as the parent.
|
2010-11-16 06:13:18 +08:00
|
|
|
*
|
|
|
|
* @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.
|
2023-03-24 17:08:14 +08:00
|
|
|
* @lock_key: Lock class key for use by the lock validator
|
2007-11-02 10:41:16 +08:00
|
|
|
*
|
|
|
|
* This structure is the one that is the actual kobject allowing struct
|
2010-11-16 06:13:18 +08:00
|
|
|
* bus_type/class to be statically allocated safely. Nothing outside of the
|
|
|
|
* driver core should ever touch these fields.
|
2007-11-02 10:41:16 +08:00
|
|
|
*/
|
2010-11-16 06:13:18 +08:00
|
|
|
struct subsys_private {
|
2007-11-02 10:41:16 +08:00
|
|
|
struct kset subsys;
|
|
|
|
struct kset *devices_kset;
|
2011-12-15 06:29:38 +08:00
|
|
|
struct list_head interfaces;
|
|
|
|
struct mutex mutex;
|
2010-11-16 06:13:18 +08:00
|
|
|
|
|
|
|
struct kset *drivers_kset;
|
2007-11-02 10:41:16 +08:00
|
|
|
struct klist klist_devices;
|
|
|
|
struct klist klist_drivers;
|
|
|
|
struct blocking_notifier_head bus_notifier;
|
|
|
|
unsigned int drivers_autoprobe:1;
|
2023-03-14 02:29:06 +08:00
|
|
|
const struct bus_type *bus;
|
2023-03-14 02:29:04 +08:00
|
|
|
struct device *dev_root;
|
2010-11-16 06:13:18 +08:00
|
|
|
|
|
|
|
struct kset glue_dirs;
|
2023-04-03 01:58:47 +08:00
|
|
|
const struct class *class;
|
2023-02-01 16:33:49 +08:00
|
|
|
|
|
|
|
struct lock_class_key lock_key;
|
2007-11-02 10:41:16 +08:00
|
|
|
};
|
2023-01-11 17:33:27 +08:00
|
|
|
#define to_subsys_private(obj) container_of_const(obj, struct subsys_private, subsys.kobj)
|
2007-11-02 10:41:16 +08:00
|
|
|
|
2023-02-08 19:13:10 +08:00
|
|
|
static inline struct subsys_private *subsys_get(struct subsys_private *sp)
|
|
|
|
{
|
|
|
|
if (sp)
|
|
|
|
kset_get(&sp->subsys);
|
|
|
|
return sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void subsys_put(struct subsys_private *sp)
|
|
|
|
{
|
|
|
|
if (sp)
|
|
|
|
kset_put(&sp->subsys);
|
|
|
|
}
|
|
|
|
|
2023-03-31 17:33:12 +08:00
|
|
|
struct subsys_private *class_to_subsys(const struct class *class);
|
|
|
|
|
2007-11-29 07:59:15 +08: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-14 00:54:41 +08:00
|
|
|
|
2008-12-17 04:23:36 +08:00
|
|
|
/**
|
|
|
|
* struct device_private - structure to hold the private to the driver core portions of the device structure.
|
|
|
|
*
|
2008-12-17 04:24:56 +08:00
|
|
|
* @klist_children - klist containing all children of this device
|
|
|
|
* @knode_parent - node in sibling list
|
2008-12-17 04:25:49 +08:00
|
|
|
* @knode_driver - node in driver list
|
2008-12-17 04:26:21 +08:00
|
|
|
* @knode_bus - node in bus list
|
2019-01-18 10:34:59 +08:00
|
|
|
* @knode_class - node in class list
|
2012-03-09 04:17:22 +08: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.
|
2019-01-23 02:39:21 +08:00
|
|
|
* @async_driver - pointer to device driver awaiting probe via async_probe
|
2015-06-29 22:59:02 +08:00
|
|
|
* @device - pointer back to the struct device that this structure is
|
2008-12-17 04:23:36 +08:00
|
|
|
* associated with.
|
2019-01-23 02:39:10 +08:00
|
|
|
* @dead - This device is currently either in the process of or has been
|
|
|
|
* removed from the system. Any asynchronous events scheduled for this
|
|
|
|
* device should exit without taking any action.
|
2008-12-17 04:23:36 +08:00
|
|
|
*
|
|
|
|
* Nothing outside of the driver core should ever touch these fields.
|
|
|
|
*/
|
|
|
|
struct device_private {
|
2008-12-17 04:24:56 +08:00
|
|
|
struct klist klist_children;
|
|
|
|
struct klist_node knode_parent;
|
2008-12-17 04:25:49 +08:00
|
|
|
struct klist_node knode_driver;
|
2008-12-17 04:26:21 +08:00
|
|
|
struct klist_node knode_bus;
|
2019-01-18 10:34:59 +08:00
|
|
|
struct klist_node knode_class;
|
2012-03-09 04:17:22 +08:00
|
|
|
struct list_head deferred_probe;
|
2019-01-23 02:39:21 +08:00
|
|
|
struct device_driver *async_driver;
|
2020-07-13 22:43:22 +08:00
|
|
|
char *deferred_probe_reason;
|
2008-12-17 04:23:36 +08:00
|
|
|
struct device *device;
|
2019-01-23 02:39:10 +08:00
|
|
|
u8 dead:1;
|
2008-12-17 04:23:36 +08:00
|
|
|
};
|
2008-12-17 04:24:56 +08:00
|
|
|
#define to_device_private_parent(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_parent)
|
2008-12-17 04:25:49 +08:00
|
|
|
#define to_device_private_driver(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_driver)
|
2008-12-17 04:26:21 +08:00
|
|
|
#define to_device_private_bus(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_bus)
|
2019-01-18 10:34:59 +08:00
|
|
|
#define to_device_private_class(obj) \
|
|
|
|
container_of(obj, struct device_private, knode_class)
|
2008-12-17 04:23:36 +08:00
|
|
|
|
2007-11-02 10:41:16 +08:00
|
|
|
/* initialisation functions */
|
2023-03-24 20:27:09 +08:00
|
|
|
int devices_init(void);
|
|
|
|
int buses_init(void);
|
|
|
|
int classes_init(void);
|
|
|
|
int firmware_init(void);
|
2006-05-09 18:53:49 +08:00
|
|
|
#ifdef CONFIG_SYS_HYPERVISOR
|
2023-03-24 20:27:09 +08:00
|
|
|
int hypervisor_init(void);
|
2006-05-09 18:53:49 +08:00
|
|
|
#else
|
|
|
|
static inline int hypervisor_init(void) { return 0; }
|
|
|
|
#endif
|
2023-03-24 20:27:09 +08:00
|
|
|
int platform_bus_init(void);
|
|
|
|
void cpu_dev_init(void);
|
|
|
|
void container_dev_init(void);
|
2021-02-11 04:16:11 +08:00
|
|
|
#ifdef CONFIG_AUXILIARY_BUS
|
2023-03-24 20:27:09 +08:00
|
|
|
void auxiliary_bus_init(void);
|
2021-02-11 04:16:11 +08:00
|
|
|
#else
|
|
|
|
static inline void auxiliary_bus_init(void) { }
|
|
|
|
#endif
|
2005-10-14 00:54:41 +08:00
|
|
|
|
2013-03-13 02:30:05 +08:00
|
|
|
struct kobject *virtual_device_parent(struct device *dev);
|
|
|
|
|
2023-03-24 20:27:09 +08:00
|
|
|
int bus_add_device(struct device *dev);
|
|
|
|
void bus_probe_device(struct device *dev);
|
|
|
|
void bus_remove_device(struct device *dev);
|
2023-01-11 17:23:31 +08:00
|
|
|
void bus_notify(struct device *dev, enum bus_notifier_event value);
|
2023-02-08 19:13:25 +08:00
|
|
|
bool bus_is_registered(const struct bus_type *bus);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2023-03-24 20:27:09 +08:00
|
|
|
int bus_add_driver(struct device_driver *drv);
|
|
|
|
void bus_remove_driver(struct device_driver *drv);
|
|
|
|
void device_release_driver_internal(struct device *dev, struct device_driver *drv,
|
|
|
|
struct device *parent);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2023-03-24 20:27:09 +08:00
|
|
|
void driver_detach(struct device_driver *drv);
|
|
|
|
void driver_deferred_probe_del(struct device *dev);
|
|
|
|
void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf);
|
2009-01-21 23:27:47 +08:00
|
|
|
static inline int driver_match_device(struct device_driver *drv,
|
|
|
|
struct device *dev)
|
|
|
|
{
|
2009-03-27 21:50:00 +08:00
|
|
|
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
|
2009-01-21 23:27:47 +08:00
|
|
|
}
|
2005-03-22 02:52:54 +08:00
|
|
|
|
2023-03-04 08:53:54 +08:00
|
|
|
static inline void dev_sync_state(struct device *dev)
|
|
|
|
{
|
|
|
|
if (dev->bus->sync_state)
|
|
|
|
dev->bus->sync_state(dev);
|
|
|
|
else if (dev->driver && dev->driver->sync_state)
|
|
|
|
dev->driver->sync_state(dev);
|
|
|
|
}
|
|
|
|
|
2023-03-24 20:27:09 +08:00
|
|
|
int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups);
|
|
|
|
void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups);
|
2019-01-23 02:39:16 +08:00
|
|
|
void device_driver_detach(struct device *dev);
|
2013-08-09 06:22:56 +08:00
|
|
|
|
2023-03-24 20:27:09 +08:00
|
|
|
int devres_release_all(struct device *dev);
|
|
|
|
void device_block_probing(void);
|
|
|
|
void device_unblock_probing(void);
|
|
|
|
void deferred_probe_extend_timeout(void);
|
|
|
|
void driver_deferred_probe_trigger(void);
|
2023-01-11 19:30:09 +08:00
|
|
|
const char *device_get_devnode(const struct device *dev, umode_t *mode,
|
|
|
|
kuid_t *uid, kgid_t *gid, const char **tmp);
|
2007-04-14 04:15:19 +08:00
|
|
|
|
2011-12-15 06:29:38 +08:00
|
|
|
/* /sys/devices directory */
|
2007-11-01 23:29:06 +08:00
|
|
|
extern struct kset *devices_kset;
|
2023-03-24 20:27:09 +08:00
|
|
|
void devices_kset_move_last(struct device *dev);
|
2007-11-29 04:23:18 +08:00
|
|
|
|
2008-01-01 02:05:43 +08:00
|
|
|
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
|
2023-03-24 20:27:09 +08:00
|
|
|
void module_add_driver(struct module *mod, struct device_driver *drv);
|
|
|
|
void module_remove_driver(struct device_driver *drv);
|
2007-11-29 04:23:18 +08:00
|
|
|
#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 21:23:42 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_DEVTMPFS
|
2023-03-24 20:27:09 +08:00
|
|
|
int devtmpfs_init(void);
|
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 21:23:42 +08:00
|
|
|
#else
|
|
|
|
static inline int devtmpfs_init(void) { return 0; }
|
|
|
|
#endif
|
2023-03-31 17:33:15 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
|
|
extern struct class block_class;
|
|
|
|
static inline bool is_blockdev(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->class == &block_class;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline bool is_blockdev(struct device *dev) { return false; }
|
|
|
|
#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-31 00:32:16 +08:00
|
|
|
|
|
|
|
/* Device links support */
|
2023-03-24 20:27:09 +08:00
|
|
|
int device_links_read_lock(void);
|
|
|
|
void device_links_read_unlock(int idx);
|
|
|
|
int device_links_read_lock_held(void);
|
|
|
|
int device_links_check_suppliers(struct device *dev);
|
|
|
|
void device_links_force_bind(struct device *dev);
|
|
|
|
void device_links_driver_bound(struct device *dev);
|
|
|
|
void device_links_driver_cleanup(struct device *dev);
|
|
|
|
void device_links_no_driver(struct device *dev);
|
|
|
|
bool device_links_busy(struct device *dev);
|
|
|
|
void device_links_unbind_consumers(struct device *dev);
|
|
|
|
void fw_devlink_drivers_done(void);
|
|
|
|
void fw_devlink_probing_done(void);
|
2018-04-11 07:57:06 +08:00
|
|
|
|
|
|
|
/* device pm support */
|
|
|
|
void device_pm_move_to_tail(struct device *dev);
|
2019-12-10 03:32:59 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_DEVTMPFS
|
|
|
|
int devtmpfs_create_node(struct device *dev);
|
2023-02-14 15:59:13 +08:00
|
|
|
int devtmpfs_delete_node(struct device *dev);
|
2019-12-10 03:32:59 +08:00
|
|
|
#else
|
|
|
|
static inline int devtmpfs_create_node(struct device *dev) { return 0; }
|
2023-02-14 15:59:13 +08:00
|
|
|
static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
|
2019-12-10 03:32:59 +08:00
|
|
|
#endif
|
2021-07-13 01:27:12 +08:00
|
|
|
|
|
|
|
void software_node_notify(struct device *dev);
|
|
|
|
void software_node_notify_remove(struct device *dev);
|