2017-11-07 16:30:07 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* device.h - generic, centralized driver model
|
|
|
|
*
|
|
|
|
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
|
2009-05-11 21:16:57 +00:00
|
|
|
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
* Copyright (c) 2008-2009 Novell Inc.
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
2019-06-18 15:34:59 +00:00
|
|
|
* See Documentation/driver-api/driver-model/ for more information.
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _DEVICE_H_
|
|
|
|
#define _DEVICE_H_
|
|
|
|
|
|
|
|
#include <linux/ioport.h>
|
|
|
|
#include <linux/kobject.h>
|
2005-03-21 19:49:14 +00:00
|
|
|
#include <linux/klist.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/list.h>
|
2008-05-28 16:28:39 +00:00
|
|
|
#include <linux/lockdep.h>
|
2006-08-15 05:43:17 +00:00
|
|
|
#include <linux/compiler.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/types.h>
|
2011-05-26 17:46:22 +00:00
|
|
|
#include <linux/mutex.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/pm.h>
|
2011-07-26 23:09:06 +00:00
|
|
|
#include <linux/atomic.h>
|
2012-05-14 07:47:57 +00:00
|
|
|
#include <linux/ratelimit.h>
|
2013-04-06 16:56:00 +00:00
|
|
|
#include <linux/uidgid.h>
|
2013-10-11 20:11:38 +00:00
|
|
|
#include <linux/gfp.h>
|
2018-05-09 05:29:52 +00:00
|
|
|
#include <linux/overflow.h>
|
2006-11-11 06:18:39 +00:00
|
|
|
#include <asm/device.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
struct device;
|
2008-12-16 20:23:36 +00:00
|
|
|
struct device_private;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct device_driver;
|
2007-11-28 23:59:15 +00:00
|
|
|
struct driver_private;
|
2011-05-26 17:46:22 +00:00
|
|
|
struct module;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct class;
|
2010-11-15 22:13:18 +00:00
|
|
|
struct subsys_private;
|
Driver core: udev triggered device-<>driver binding
We get two per-bus sysfs files:
ls-l /sys/subsystem/usb
drwxr-xr-x 2 root root 0 2007-02-16 16:42 devices
drwxr-xr-x 7 root root 0 2007-02-16 14:55 drivers
-rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe
--w------- 1 root root 4096 2007-02-16 16:42 drivers_probe
The flag "drivers_autoprobe" controls the behavior of the bus to bind
devices by default, or just initialize the device and leave it alone.
The command "drivers_probe" accepts a bus_id and the bus tries to bind a
driver to this device.
Systems who want to control the driver binding with udev, switch off the
bus initiated probing:
echo 0 > /sys/subsystem/usb/drivers_autoprobe
echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe
...
and initiate the probing with udev rules like:
ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel"
ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel"
...
Custom driver binding can happen in earlier rules by something like:
ACTION=="add", SUBSYSTEM=="usb", \
ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \
ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel"
This is intended to solve the modprobe.conf mess with "install-rules", custom
bind/unbind-scripts and all the weird things people invented over the years.
It should also provide the functionality "libusual" was supposed to do.
With udev, one can just write a udev rule to drive all USB-disks at the
third port of USB-hub by the "ub" driver, and everything else by
usb-storage. One can also instruct udev to bind different wireless
drivers to identical cards - just selected by the pcmcia slot-number, and
whatever ...
To use the mentioned rules, it needs udev version 106, to be able to
write ATTR{}="$kernel" to sysfs files.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2007-02-16 16:33:36 +00:00
|
|
|
struct bus_type;
|
2010-04-13 23:12:28 +00:00
|
|
|
struct device_node;
|
2015-03-16 22:49:03 +00:00
|
|
|
struct fwnode_handle;
|
2011-08-26 14:48:26 +00:00
|
|
|
struct iommu_ops;
|
2012-05-30 20:18:41 +00:00
|
|
|
struct iommu_group;
|
2016-09-13 09:54:14 +00:00
|
|
|
struct iommu_fwspec;
|
pinctrl: remove include file from <linux/device.h>
When pulling the recent pinctrl merge, I was surprised by how a
pinctrl-only pull request ended up rebuilding basically the whole
kernel.
The reason for that ended up being that <linux/device.h> included
<linux/pinctrl/devinfo.h>, so any change to that file ended up causing
pretty much every driver out there to be rebuilt.
The reason for that was because 'struct device' has this in it:
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
but we already avoid header includes for these kinds of things in that
header file, preferring to just use a forward-declaration of the
structure instead. Exactly to avoid this kind of header dependency.
Since some drivers seem to expect that <linux/pinctrl/devinfo.h> header
to come in automatically, move the include to <linux/pinctrl/pinctrl.h>
instead. It might be better to just make the includes more targeted,
but I'm not going to review every driver.
It would definitely be good to have a tool for finding and minimizing
header dependencies automatically - or at least help with them. Right
now we almost certainly end up having way too many of these things, and
it's hard to test every single configuration.
FWIW, you can get a sense of the "hotness" of a header file with something
like this after doing a full build:
find . -name '.*.o.cmd' -print0 |
xargs -0 tail --lines=+2 |
grep -v 'wildcard ' |
tr ' \\' '\n' |
sort | uniq -c | sort -n | less -S
which isn't exact (there are other things in those '*.o.cmd' than just
the dependencies, and the "--lines=+2" only removes the header), but
might a useful approximation.
With this patch, <linux/pinctrl/devinfo.h> drops to "only" having 833
users in the current x86-64 allmodconfig. In contrast, <linux/device.h>
has 14857 build files including it directly or indirectly.
Of course, the headers that absolutely _everybody_ includes (things like
<linux/types.h> etc) get a score of 23000+.
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-02-03 00:44:14 +00:00
|
|
|
struct dev_pin_info;
|
2019-06-03 14:57:46 +00:00
|
|
|
struct iommu_param;
|
Driver core: udev triggered device-<>driver binding
We get two per-bus sysfs files:
ls-l /sys/subsystem/usb
drwxr-xr-x 2 root root 0 2007-02-16 16:42 devices
drwxr-xr-x 7 root root 0 2007-02-16 14:55 drivers
-rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe
--w------- 1 root root 4096 2007-02-16 16:42 drivers_probe
The flag "drivers_autoprobe" controls the behavior of the bus to bind
devices by default, or just initialize the device and leave it alone.
The command "drivers_probe" accepts a bus_id and the bus tries to bind a
driver to this device.
Systems who want to control the driver binding with udev, switch off the
bus initiated probing:
echo 0 > /sys/subsystem/usb/drivers_autoprobe
echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe
...
and initiate the probing with udev rules like:
ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel"
ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel"
...
Custom driver binding can happen in earlier rules by something like:
ACTION=="add", SUBSYSTEM=="usb", \
ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \
ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel"
This is intended to solve the modprobe.conf mess with "install-rules", custom
bind/unbind-scripts and all the weird things people invented over the years.
It should also provide the functionality "libusual" was supposed to do.
With udev, one can just write a udev rule to drive all USB-disks at the
third port of USB-hub by the "ub" driver, and everything else by
usb-storage. One can also instruct udev to bind different wireless
drivers to identical cards - just selected by the pcmcia slot-number, and
whatever ...
To use the mentioned rules, it needs udev version 106, to be able to
write ATTR{}="$kernel" to sysfs files.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2007-02-16 16:33:36 +00:00
|
|
|
|
|
|
|
struct bus_attribute {
|
|
|
|
struct attribute attr;
|
2008-01-25 05:04:46 +00:00
|
|
|
ssize_t (*show)(struct bus_type *bus, char *buf);
|
|
|
|
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
|
Driver core: udev triggered device-<>driver binding
We get two per-bus sysfs files:
ls-l /sys/subsystem/usb
drwxr-xr-x 2 root root 0 2007-02-16 16:42 devices
drwxr-xr-x 7 root root 0 2007-02-16 14:55 drivers
-rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe
--w------- 1 root root 4096 2007-02-16 16:42 drivers_probe
The flag "drivers_autoprobe" controls the behavior of the bus to bind
devices by default, or just initialize the device and leave it alone.
The command "drivers_probe" accepts a bus_id and the bus tries to bind a
driver to this device.
Systems who want to control the driver binding with udev, switch off the
bus initiated probing:
echo 0 > /sys/subsystem/usb/drivers_autoprobe
echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe
...
and initiate the probing with udev rules like:
ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel"
ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel"
...
Custom driver binding can happen in earlier rules by something like:
ACTION=="add", SUBSYSTEM=="usb", \
ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \
ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel"
This is intended to solve the modprobe.conf mess with "install-rules", custom
bind/unbind-scripts and all the weird things people invented over the years.
It should also provide the functionality "libusual" was supposed to do.
With udev, one can just write a udev rule to drive all USB-disks at the
third port of USB-hub by the "ub" driver, and everything else by
usb-storage. One can also instruct udev to bind different wireless
drivers to identical cards - just selected by the pcmcia slot-number, and
whatever ...
To use the mentioned rules, it needs udev version 106, to be able to
write ATTR{}="$kernel" to sysfs files.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2007-02-16 16:33:36 +00:00
|
|
|
};
|
|
|
|
|
2013-07-14 23:05:54 +00:00
|
|
|
#define BUS_ATTR_RW(_name) \
|
|
|
|
struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
|
|
|
|
#define BUS_ATTR_RO(_name) \
|
|
|
|
struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
|
2018-07-11 13:20:32 +00:00
|
|
|
#define BUS_ATTR_WO(_name) \
|
|
|
|
struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
|
Driver core: udev triggered device-<>driver binding
We get two per-bus sysfs files:
ls-l /sys/subsystem/usb
drwxr-xr-x 2 root root 0 2007-02-16 16:42 devices
drwxr-xr-x 7 root root 0 2007-02-16 14:55 drivers
-rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe
--w------- 1 root root 4096 2007-02-16 16:42 drivers_probe
The flag "drivers_autoprobe" controls the behavior of the bus to bind
devices by default, or just initialize the device and leave it alone.
The command "drivers_probe" accepts a bus_id and the bus tries to bind a
driver to this device.
Systems who want to control the driver binding with udev, switch off the
bus initiated probing:
echo 0 > /sys/subsystem/usb/drivers_autoprobe
echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe
...
and initiate the probing with udev rules like:
ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel"
ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel"
...
Custom driver binding can happen in earlier rules by something like:
ACTION=="add", SUBSYSTEM=="usb", \
ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \
ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel"
This is intended to solve the modprobe.conf mess with "install-rules", custom
bind/unbind-scripts and all the weird things people invented over the years.
It should also provide the functionality "libusual" was supposed to do.
With udev, one can just write a udev rule to drive all USB-disks at the
third port of USB-hub by the "ub" driver, and everything else by
usb-storage. One can also instruct udev to bind different wireless
drivers to identical cards - just selected by the pcmcia slot-number, and
whatever ...
To use the mentioned rules, it needs udev version 106, to be able to
write ATTR{}="$kernel" to sysfs files.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2007-02-16 16:33:36 +00:00
|
|
|
|
|
|
|
extern int __must_check bus_create_file(struct bus_type *,
|
|
|
|
struct bus_attribute *);
|
|
|
|
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2011-05-04 23:55:36 +00:00
|
|
|
/**
|
|
|
|
* struct bus_type - The bus type of the device
|
|
|
|
*
|
|
|
|
* @name: The name of the bus.
|
2011-12-14 22:29:38 +00:00
|
|
|
* @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id).
|
|
|
|
* @dev_root: Default device to use as the parent.
|
2013-08-08 22:22:57 +00:00
|
|
|
* @bus_groups: Default attributes of the bus.
|
2013-08-08 22:22:55 +00:00
|
|
|
* @dev_groups: Default attributes of the devices on the bus.
|
2013-08-08 22:22:56 +00:00
|
|
|
* @drv_groups: Default attributes of the device drivers on the bus.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @match: Called, perhaps multiple times, whenever a new device or driver
|
2016-02-15 08:25:06 +00:00
|
|
|
* is added for this bus. It should return a positive value if the
|
|
|
|
* given device can be handled by the given driver and zero
|
|
|
|
* otherwise. It may also return error code if determining that
|
|
|
|
* the driver supports the device is not possible. In case of
|
|
|
|
* -EPROBE_DEFER it will queue the device for deferred probing.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @uevent: Called when a device is added, removed, or a few other things
|
|
|
|
* that generate uevents to add the environment variables.
|
|
|
|
* @probe: Called when a new device or driver add to this bus, and callback
|
|
|
|
* the specific driver's probe to initial the matched device.
|
|
|
|
* @remove: Called when a device removed from this bus.
|
|
|
|
* @shutdown: Called at shut-down time to quiesce the device.
|
Driver core: Add offline/online device operations
In some cases, graceful hot-removal of devices is not possible,
although in principle the devices in question support hotplug.
For example, that may happen for the last CPU in the system or
for memory modules holding kernel memory.
In those cases it is nice to be able to check if the given device
can be gracefully hot-removed before triggering a removal procedure
that cannot be aborted or reversed. Unfortunately, however, the
kernel currently doesn't provide any support for that.
To address that deficiency, introduce support for offline and
online operations that can be performed on devices, respectively,
before a hot-removal and in case when it is necessary (or convenient)
to put a device back online after a successful offline (that has not
been followed by removal). The idea is that the offline will fail
whenever the given device cannot be gracefully removed from the
system and it will not be allowed to use the device after a
successful offline (until a subsequent online) in analogy with the
existing CPU offline/online mechanism.
For now, the offline and online operations are introduced at the
bus type level, as that should be sufficient for the most urgent use
cases (CPUs and memory modules). In the future, however, the
approach may be extended to cover some more complicated device
offline/online scenarios involving device drivers etc.
The lock_device_hotplug() and unlock_device_hotplug() functions are
introduced because subsequent patches need to put larger pieces of
code under device_hotplug_lock to prevent race conditions between
device offline and removal from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-02 20:15:29 +00:00
|
|
|
*
|
|
|
|
* @online: Called to put the device back online (after offlining it).
|
|
|
|
* @offline: Called to put the device offline for hot-removal. May fail.
|
|
|
|
*
|
2011-05-04 23:55:36 +00:00
|
|
|
* @suspend: Called when a device on this bus wants to go to sleep mode.
|
|
|
|
* @resume: Called to bring a device on this bus out of sleep mode.
|
2017-01-18 13:04:37 +00:00
|
|
|
* @num_vf: Called to find out how many virtual functions a device on this
|
|
|
|
* bus supports.
|
2018-04-28 02:51:58 +00:00
|
|
|
* @dma_configure: Called to setup DMA configuration on a device on
|
2018-06-27 12:50:55 +00:00
|
|
|
* this bus.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @pm: Power management operations of this bus, callback the specific
|
|
|
|
* device driver's pm-ops.
|
2011-11-01 18:15:40 +00:00
|
|
|
* @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU
|
2011-08-26 14:48:26 +00:00
|
|
|
* driver implementations to a bus and allow the driver to do
|
|
|
|
* bus-specific setup
|
2011-05-04 23:55:36 +00:00
|
|
|
* @p: The private data of the driver core, only the driver core can
|
|
|
|
* touch this.
|
2013-06-26 03:57:06 +00:00
|
|
|
* @lock_key: Lock class key for use by the lock validator
|
2018-05-30 16:31:36 +00:00
|
|
|
* @need_parent_lock: When probing or removing a device on this bus, the
|
|
|
|
* device core should lock the device's parent.
|
2011-05-04 23:55:36 +00:00
|
|
|
*
|
|
|
|
* A bus is a channel between the processor and one or more devices. For the
|
|
|
|
* purposes of the device model, all devices are connected via a bus, even if
|
|
|
|
* it is an internal, virtual, "platform" bus. Buses can plug into each other.
|
|
|
|
* A USB controller is usually a PCI device, for example. The device model
|
|
|
|
* represents the actual connections between buses and the devices they control.
|
|
|
|
* A bus is represented by the bus_type structure. It contains the name, the
|
|
|
|
* default attributes, the bus' methods, PM operations, and the driver core's
|
|
|
|
* private data.
|
|
|
|
*/
|
2005-04-16 22:20:36 +00:00
|
|
|
struct bus_type {
|
2008-01-25 05:04:46 +00:00
|
|
|
const char *name;
|
2011-12-14 22:29:38 +00:00
|
|
|
const char *dev_name;
|
|
|
|
struct device *dev_root;
|
2013-08-08 22:22:57 +00:00
|
|
|
const struct attribute_group **bus_groups;
|
2013-08-08 22:22:55 +00:00
|
|
|
const struct attribute_group **dev_groups;
|
2013-08-08 22:22:56 +00:00
|
|
|
const struct attribute_group **drv_groups;
|
2008-01-25 05:04:46 +00:00
|
|
|
|
|
|
|
int (*match)(struct device *dev, struct device_driver *drv);
|
|
|
|
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
|
|
|
int (*probe)(struct device *dev);
|
|
|
|
int (*remove)(struct device *dev);
|
|
|
|
void (*shutdown)(struct device *dev);
|
|
|
|
|
Driver core: Add offline/online device operations
In some cases, graceful hot-removal of devices is not possible,
although in principle the devices in question support hotplug.
For example, that may happen for the last CPU in the system or
for memory modules holding kernel memory.
In those cases it is nice to be able to check if the given device
can be gracefully hot-removed before triggering a removal procedure
that cannot be aborted or reversed. Unfortunately, however, the
kernel currently doesn't provide any support for that.
To address that deficiency, introduce support for offline and
online operations that can be performed on devices, respectively,
before a hot-removal and in case when it is necessary (or convenient)
to put a device back online after a successful offline (that has not
been followed by removal). The idea is that the offline will fail
whenever the given device cannot be gracefully removed from the
system and it will not be allowed to use the device after a
successful offline (until a subsequent online) in analogy with the
existing CPU offline/online mechanism.
For now, the offline and online operations are introduced at the
bus type level, as that should be sufficient for the most urgent use
cases (CPUs and memory modules). In the future, however, the
approach may be extended to cover some more complicated device
offline/online scenarios involving device drivers etc.
The lock_device_hotplug() and unlock_device_hotplug() functions are
introduced because subsequent patches need to put larger pieces of
code under device_hotplug_lock to prevent race conditions between
device offline and removal from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-02 20:15:29 +00:00
|
|
|
int (*online)(struct device *dev);
|
|
|
|
int (*offline)(struct device *dev);
|
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
int (*suspend)(struct device *dev, pm_message_t state);
|
|
|
|
int (*resume)(struct device *dev);
|
Driver core: udev triggered device-<>driver binding
We get two per-bus sysfs files:
ls-l /sys/subsystem/usb
drwxr-xr-x 2 root root 0 2007-02-16 16:42 devices
drwxr-xr-x 7 root root 0 2007-02-16 14:55 drivers
-rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe
--w------- 1 root root 4096 2007-02-16 16:42 drivers_probe
The flag "drivers_autoprobe" controls the behavior of the bus to bind
devices by default, or just initialize the device and leave it alone.
The command "drivers_probe" accepts a bus_id and the bus tries to bind a
driver to this device.
Systems who want to control the driver binding with udev, switch off the
bus initiated probing:
echo 0 > /sys/subsystem/usb/drivers_autoprobe
echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe
...
and initiate the probing with udev rules like:
ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel"
ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel"
...
Custom driver binding can happen in earlier rules by something like:
ACTION=="add", SUBSYSTEM=="usb", \
ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \
ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel"
This is intended to solve the modprobe.conf mess with "install-rules", custom
bind/unbind-scripts and all the weird things people invented over the years.
It should also provide the functionality "libusual" was supposed to do.
With udev, one can just write a udev rule to drive all USB-disks at the
third port of USB-hub by the "ub" driver, and everything else by
usb-storage. One can also instruct udev to bind different wireless
drivers to identical cards - just selected by the pcmcia slot-number, and
whatever ...
To use the mentioned rules, it needs udev version 106, to be able to
write ATTR{}="$kernel" to sysfs files.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2007-02-16 16:33:36 +00:00
|
|
|
|
2017-01-18 13:04:37 +00:00
|
|
|
int (*num_vf)(struct device *dev);
|
|
|
|
|
2018-04-28 02:51:58 +00:00
|
|
|
int (*dma_configure)(struct device *dev);
|
|
|
|
|
2009-07-25 05:11:32 +00:00
|
|
|
const struct dev_pm_ops *pm;
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-20 21:00:01 +00:00
|
|
|
|
2014-06-27 07:03:12 +00:00
|
|
|
const struct iommu_ops *iommu_ops;
|
2011-08-26 14:48:26 +00:00
|
|
|
|
2010-11-15 22:13:18 +00:00
|
|
|
struct subsys_private *p;
|
2013-03-12 16:21:19 +00:00
|
|
|
struct lock_class_key lock_key;
|
2017-10-12 15:56:14 +00:00
|
|
|
|
2018-05-30 16:31:36 +00:00
|
|
|
bool need_parent_lock;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2013-03-12 16:21:19 +00:00
|
|
|
extern int __must_check bus_register(struct bus_type *bus);
|
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void bus_unregister(struct bus_type *bus);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int __must_check bus_rescan_devices(struct bus_type *bus);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* iterator helpers for buses */
|
2011-12-14 22:29:38 +00:00
|
|
|
struct subsys_dev_iter {
|
|
|
|
struct klist_iter ki;
|
|
|
|
const struct device_type *type;
|
|
|
|
};
|
2012-04-20 02:17:30 +00:00
|
|
|
void subsys_dev_iter_init(struct subsys_dev_iter *iter,
|
2011-12-14 22:29:38 +00:00
|
|
|
struct bus_type *subsys,
|
|
|
|
struct device *start,
|
|
|
|
const struct device_type *type);
|
|
|
|
struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter);
|
|
|
|
void subsys_dev_iter_exit(struct subsys_dev_iter *iter);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2019-07-23 22:18:32 +00:00
|
|
|
int device_match_name(struct device *dev, const void *name);
|
2019-06-14 17:54:01 +00:00
|
|
|
int device_match_of_node(struct device *dev, const void *np);
|
2019-07-23 22:18:34 +00:00
|
|
|
int device_match_fwnode(struct device *dev, const void *fwnode);
|
2019-07-23 22:18:35 +00:00
|
|
|
int device_match_devt(struct device *dev, const void *pdevt);
|
2019-07-23 22:18:36 +00:00
|
|
|
int device_match_acpi_dev(struct device *dev, const void *adev);
|
2019-07-23 22:18:37 +00:00
|
|
|
int device_match_any(struct device *dev, const void *unused);
|
2019-06-14 17:54:01 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
|
|
|
|
int (*fn)(struct device *dev, void *data));
|
|
|
|
struct device *bus_find_device(struct bus_type *bus, struct device *start,
|
2019-06-14 17:53:59 +00:00
|
|
|
const void *data,
|
|
|
|
int (*match)(struct device *dev, const void *data));
|
2019-07-23 22:18:32 +00:00
|
|
|
/**
|
|
|
|
* bus_find_device_by_name - device iterator for locating a particular device
|
|
|
|
* of a specific name.
|
|
|
|
* @bus: bus type
|
|
|
|
* @start: Device to begin with
|
|
|
|
* @name: name of the device to match
|
|
|
|
*/
|
|
|
|
static inline struct device *bus_find_device_by_name(struct bus_type *bus,
|
|
|
|
struct device *start,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return bus_find_device(bus, start, name, device_match_name);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:33 +00:00
|
|
|
/**
|
|
|
|
* bus_find_device_by_of_node : device iterator for locating a particular device
|
|
|
|
* matching the of_node.
|
|
|
|
* @bus: bus type
|
|
|
|
* @np: of_node of the device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
bus_find_device_by_of_node(struct bus_type *bus, const struct device_node *np)
|
|
|
|
{
|
|
|
|
return bus_find_device(bus, NULL, np, device_match_of_node);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:34 +00:00
|
|
|
/**
|
|
|
|
* bus_find_device_by_fwnode : device iterator for locating a particular device
|
|
|
|
* matching the fwnode.
|
|
|
|
* @bus: bus type
|
|
|
|
* @fwnode: fwnode of the device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
bus_find_device_by_fwnode(struct bus_type *bus, const struct fwnode_handle *fwnode)
|
|
|
|
{
|
|
|
|
return bus_find_device(bus, NULL, fwnode, device_match_fwnode);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:35 +00:00
|
|
|
/**
|
|
|
|
* bus_find_device_by_devt : device iterator for locating a particular device
|
|
|
|
* matching the device type.
|
|
|
|
* @bus: bus type
|
|
|
|
* @devt: device type of the device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *bus_find_device_by_devt(struct bus_type *bus,
|
|
|
|
dev_t devt)
|
|
|
|
{
|
|
|
|
return bus_find_device(bus, NULL, &devt, device_match_devt);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:37 +00:00
|
|
|
/**
|
|
|
|
* bus_find_next_device - Find the next device after a given device in a
|
|
|
|
* given bus.
|
2019-08-01 10:20:26 +00:00
|
|
|
* @bus: bus type
|
|
|
|
* @cur: device to begin the search with.
|
2019-07-23 22:18:37 +00:00
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
bus_find_next_device(struct bus_type *bus,struct device *cur)
|
|
|
|
{
|
|
|
|
return bus_find_device(bus, cur, NULL, device_match_any);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:36 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
struct acpi_device;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* bus_find_device_by_acpi_dev : device iterator for locating a particular device
|
|
|
|
* matching the ACPI COMPANION device.
|
|
|
|
* @bus: bus type
|
|
|
|
* @adev: ACPI COMPANION device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
bus_find_device_by_acpi_dev(struct bus_type *bus, const struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return bus_find_device(bus, NULL, adev, device_match_acpi_dev);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline struct device *
|
|
|
|
bus_find_device_by_acpi_dev(struct bus_type *bus, const void *adev)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-12-14 22:29:38 +00:00
|
|
|
struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
|
|
|
|
struct device *hint);
|
2010-06-16 09:44:18 +00:00
|
|
|
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
|
|
|
|
void *data, int (*fn)(struct device_driver *, void *));
|
2008-08-26 16:00:57 +00:00
|
|
|
void bus_sort_breadthfirst(struct bus_type *bus,
|
|
|
|
int (*compare)(const struct device *a,
|
|
|
|
const struct device *b));
|
Driver core: add notification of bus events
I finally did as you suggested and added the notifier to the struct
bus_type itself. There are still problems to be expected is something
attaches to a bus type where the code can hook in different struct
device sub-classes (which is imho a big bogosity but I won't even try to
argue that case now) but it will solve nicely a number of issues I've
had so far.
That also means that clients interested in registering for such
notifications have to do it before devices are added and after bus types
are registered. Fortunately, most bus types that matter for the various
usage scenarios I have in mind are registerd at postcore_initcall time,
which means I have a really nice spot at arch_initcall time to add my
notifiers.
There are 4 notifications provided. Device being added (before hooked to
the bus) and removed (failure of previous case or after being unhooked
from the bus), along with driver being bound to a device and about to be
unbound.
The usage I have for these are:
- The 2 first ones are used to maintain a struct device_ext that is
hooked to struct device.firmware_data. This structure contains for now a
pointer to the Open Firmware node related to the device (if any), the
NUMA node ID (for quick access to it) and the DMA operations pointers &
iommu table instance for DMA to/from this device. For bus types I own
(like IBM VIO or EBUS), I just maintain that structure directly from the
bus code when creating the devices. But for bus types managed by generic
code like PCI or platform (actually, of_platform which is a variation of
platform linked to Open Firmware device-tree), I need this notifier.
- The other two ones have a completely different usage scenario. I have
cases where multiple devices and their drivers depend on each other. For
example, the IBM EMAC network driver needs to attach to a MAL DMA engine
which is a separate device, and a PHY interface which is also a separate
device. They are all of_platform_device's (well, about to be with my
upcoming patches) but there is no say in what precise order the core
will "probe" them and instanciate the various modules. The solution I
found for that is to have the drivers for emac to use multithread_probe,
and wait for a driver to be bound to the target MAL and PHY control
devices (the device-tree contains reference to the MAL and PHY interface
nodes, which I can then match to of_platform_devices). Right now, I've
been polling, but with that notifier, I can more cleanly wait (with a
timeout of course).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2006-10-25 03:44:59 +00:00
|
|
|
/*
|
|
|
|
* Bus notifiers: Get notified of addition/removal of devices
|
|
|
|
* and binding/unbinding of drivers to devices.
|
|
|
|
* In the long run, it should be a replacement for the platform
|
|
|
|
* notify hooks.
|
|
|
|
*/
|
|
|
|
struct notifier_block;
|
|
|
|
|
|
|
|
extern int bus_register_notifier(struct bus_type *bus,
|
|
|
|
struct notifier_block *nb);
|
|
|
|
extern int bus_unregister_notifier(struct bus_type *bus,
|
|
|
|
struct notifier_block *nb);
|
|
|
|
|
|
|
|
/* All 4 notifers below get called with the target struct device *
|
|
|
|
* as an argument. Note that those functions are likely to be called
|
2010-02-17 18:57:05 +00:00
|
|
|
* with the device lock held in the core, so be careful.
|
Driver core: add notification of bus events
I finally did as you suggested and added the notifier to the struct
bus_type itself. There are still problems to be expected is something
attaches to a bus type where the code can hook in different struct
device sub-classes (which is imho a big bogosity but I won't even try to
argue that case now) but it will solve nicely a number of issues I've
had so far.
That also means that clients interested in registering for such
notifications have to do it before devices are added and after bus types
are registered. Fortunately, most bus types that matter for the various
usage scenarios I have in mind are registerd at postcore_initcall time,
which means I have a really nice spot at arch_initcall time to add my
notifiers.
There are 4 notifications provided. Device being added (before hooked to
the bus) and removed (failure of previous case or after being unhooked
from the bus), along with driver being bound to a device and about to be
unbound.
The usage I have for these are:
- The 2 first ones are used to maintain a struct device_ext that is
hooked to struct device.firmware_data. This structure contains for now a
pointer to the Open Firmware node related to the device (if any), the
NUMA node ID (for quick access to it) and the DMA operations pointers &
iommu table instance for DMA to/from this device. For bus types I own
(like IBM VIO or EBUS), I just maintain that structure directly from the
bus code when creating the devices. But for bus types managed by generic
code like PCI or platform (actually, of_platform which is a variation of
platform linked to Open Firmware device-tree), I need this notifier.
- The other two ones have a completely different usage scenario. I have
cases where multiple devices and their drivers depend on each other. For
example, the IBM EMAC network driver needs to attach to a MAL DMA engine
which is a separate device, and a PHY interface which is also a separate
device. They are all of_platform_device's (well, about to be with my
upcoming patches) but there is no say in what precise order the core
will "probe" them and instanciate the various modules. The solution I
found for that is to have the drivers for emac to use multithread_probe,
and wait for a driver to be bound to the target MAL and PHY control
devices (the device-tree contains reference to the MAL and PHY interface
nodes, which I can then match to of_platform_devices). Right now, I've
been polling, but with that notifier, I can more cleanly wait (with a
timeout of course).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2006-10-25 03:44:59 +00:00
|
|
|
*/
|
|
|
|
#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
|
2014-09-30 11:02:02 +00:00
|
|
|
#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device to be removed */
|
|
|
|
#define BUS_NOTIFY_REMOVED_DEVICE 0x00000003 /* device removed */
|
|
|
|
#define BUS_NOTIFY_BIND_DRIVER 0x00000004 /* driver about to be
|
2010-07-23 10:56:18 +00:00
|
|
|
bound */
|
2014-09-30 11:02:02 +00:00
|
|
|
#define BUS_NOTIFY_BOUND_DRIVER 0x00000005 /* driver bound to device */
|
|
|
|
#define BUS_NOTIFY_UNBIND_DRIVER 0x00000006 /* driver about to be
|
Driver core: add notification of bus events
I finally did as you suggested and added the notifier to the struct
bus_type itself. There are still problems to be expected is something
attaches to a bus type where the code can hook in different struct
device sub-classes (which is imho a big bogosity but I won't even try to
argue that case now) but it will solve nicely a number of issues I've
had so far.
That also means that clients interested in registering for such
notifications have to do it before devices are added and after bus types
are registered. Fortunately, most bus types that matter for the various
usage scenarios I have in mind are registerd at postcore_initcall time,
which means I have a really nice spot at arch_initcall time to add my
notifiers.
There are 4 notifications provided. Device being added (before hooked to
the bus) and removed (failure of previous case or after being unhooked
from the bus), along with driver being bound to a device and about to be
unbound.
The usage I have for these are:
- The 2 first ones are used to maintain a struct device_ext that is
hooked to struct device.firmware_data. This structure contains for now a
pointer to the Open Firmware node related to the device (if any), the
NUMA node ID (for quick access to it) and the DMA operations pointers &
iommu table instance for DMA to/from this device. For bus types I own
(like IBM VIO or EBUS), I just maintain that structure directly from the
bus code when creating the devices. But for bus types managed by generic
code like PCI or platform (actually, of_platform which is a variation of
platform linked to Open Firmware device-tree), I need this notifier.
- The other two ones have a completely different usage scenario. I have
cases where multiple devices and their drivers depend on each other. For
example, the IBM EMAC network driver needs to attach to a MAL DMA engine
which is a separate device, and a PHY interface which is also a separate
device. They are all of_platform_device's (well, about to be with my
upcoming patches) but there is no say in what precise order the core
will "probe" them and instanciate the various modules. The solution I
found for that is to have the drivers for emac to use multithread_probe,
and wait for a driver to be bound to the target MAL and PHY control
devices (the device-tree contains reference to the MAL and PHY interface
nodes, which I can then match to of_platform_devices). Right now, I've
been polling, but with that notifier, I can more cleanly wait (with a
timeout of course).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2006-10-25 03:44:59 +00:00
|
|
|
unbound */
|
2014-09-30 11:02:02 +00:00
|
|
|
#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000007 /* driver is unbound
|
2009-04-24 12:57:00 +00:00
|
|
|
from the device */
|
2015-12-04 21:49:17 +00:00
|
|
|
#define BUS_NOTIFY_DRIVER_NOT_BOUND 0x00000008 /* driver fails to be bound */
|
Driver core: add notification of bus events
I finally did as you suggested and added the notifier to the struct
bus_type itself. There are still problems to be expected is something
attaches to a bus type where the code can hook in different struct
device sub-classes (which is imho a big bogosity but I won't even try to
argue that case now) but it will solve nicely a number of issues I've
had so far.
That also means that clients interested in registering for such
notifications have to do it before devices are added and after bus types
are registered. Fortunately, most bus types that matter for the various
usage scenarios I have in mind are registerd at postcore_initcall time,
which means I have a really nice spot at arch_initcall time to add my
notifiers.
There are 4 notifications provided. Device being added (before hooked to
the bus) and removed (failure of previous case or after being unhooked
from the bus), along with driver being bound to a device and about to be
unbound.
The usage I have for these are:
- The 2 first ones are used to maintain a struct device_ext that is
hooked to struct device.firmware_data. This structure contains for now a
pointer to the Open Firmware node related to the device (if any), the
NUMA node ID (for quick access to it) and the DMA operations pointers &
iommu table instance for DMA to/from this device. For bus types I own
(like IBM VIO or EBUS), I just maintain that structure directly from the
bus code when creating the devices. But for bus types managed by generic
code like PCI or platform (actually, of_platform which is a variation of
platform linked to Open Firmware device-tree), I need this notifier.
- The other two ones have a completely different usage scenario. I have
cases where multiple devices and their drivers depend on each other. For
example, the IBM EMAC network driver needs to attach to a MAL DMA engine
which is a separate device, and a PHY interface which is also a separate
device. They are all of_platform_device's (well, about to be with my
upcoming patches) but there is no say in what precise order the core
will "probe" them and instanciate the various modules. The solution I
found for that is to have the drivers for emac to use multithread_probe,
and wait for a driver to be bound to the target MAL and PHY control
devices (the device-tree contains reference to the MAL and PHY interface
nodes, which I can then match to of_platform_devices). Right now, I've
been polling, but with that notifier, I can more cleanly wait (with a
timeout of course).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2006-10-25 03:44:59 +00:00
|
|
|
|
2007-11-02 02:41:16 +00:00
|
|
|
extern struct kset *bus_get_kset(struct bus_type *bus);
|
2007-11-02 02:41:16 +00:00
|
|
|
extern struct klist *bus_get_device_klist(struct bus_type *bus);
|
2007-11-02 02:41:16 +00:00
|
|
|
|
2015-03-30 23:20:04 +00:00
|
|
|
/**
|
|
|
|
* enum probe_type - device driver probe type to try
|
|
|
|
* Device drivers may opt in for special handling of their
|
|
|
|
* respective probe routines. This tells the core what to
|
|
|
|
* expect and prefer.
|
|
|
|
*
|
2015-03-30 23:20:06 +00:00
|
|
|
* @PROBE_DEFAULT_STRATEGY: Used by drivers that work equally well
|
|
|
|
* whether probed synchronously or asynchronously.
|
2015-03-30 23:20:04 +00:00
|
|
|
* @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which
|
|
|
|
* probing order is not essential for booting the system may
|
|
|
|
* opt into executing their probes asynchronously.
|
2015-03-30 23:20:06 +00:00
|
|
|
* @PROBE_FORCE_SYNCHRONOUS: Use this to annotate drivers that need
|
|
|
|
* their probe routines to run synchronously with driver and
|
|
|
|
* device registration (with the exception of -EPROBE_DEFER
|
|
|
|
* handling - re-probing always ends up being done asynchronously).
|
2015-03-30 23:20:04 +00:00
|
|
|
*
|
|
|
|
* Note that the end goal is to switch the kernel to use asynchronous
|
|
|
|
* probing by default, so annotating drivers with
|
|
|
|
* %PROBE_PREFER_ASYNCHRONOUS is a temporary measure that allows us
|
|
|
|
* to speed up boot process while we are validating the rest of the
|
|
|
|
* drivers.
|
|
|
|
*/
|
|
|
|
enum probe_type {
|
2015-03-30 23:20:05 +00:00
|
|
|
PROBE_DEFAULT_STRATEGY,
|
2015-03-30 23:20:04 +00:00
|
|
|
PROBE_PREFER_ASYNCHRONOUS,
|
2015-03-30 23:20:06 +00:00
|
|
|
PROBE_FORCE_SYNCHRONOUS,
|
2015-03-30 23:20:04 +00:00
|
|
|
};
|
|
|
|
|
2011-05-04 23:55:36 +00:00
|
|
|
/**
|
|
|
|
* struct device_driver - The basic device driver structure
|
|
|
|
* @name: Name of the device driver.
|
|
|
|
* @bus: The bus which the device of this driver belongs to.
|
|
|
|
* @owner: The module owner.
|
|
|
|
* @mod_name: Used for built-in modules.
|
|
|
|
* @suppress_bind_attrs: Disables bind/unbind via sysfs.
|
2015-03-30 23:20:04 +00:00
|
|
|
* @probe_type: Type of the probe (synchronous or asynchronous) to use.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @of_match_table: The open firmware table.
|
driver core / ACPI: Move ACPI support to core device and driver types
With ACPI 5 we are starting to see devices that don't natively support
discovery but can be enumerated with the help of the ACPI namespace.
Typically, these devices can be represented in the Linux device driver
model as platform devices or some serial bus devices, like SPI or I2C
devices.
Since we want to re-use existing drivers for those devices, we need a
way for drivers to specify the ACPI IDs of supported devices, so that
they can be matched against device nodes in the ACPI namespace. To
this end, it is sufficient to add a pointer to an array of supported
ACPI device IDs, that can be provided by the driver, to struct device.
Moreover, things like ACPI power management need to have access to
the ACPI handle of each supported device, because that handle is used
to invoke AML methods associated with the corresponding ACPI device
node. The ACPI handles of devices are now stored in the archdata
member structure of struct device whose definition depends on the
architecture and includes the ACPI handle only on x86 and ia64. Since
the pointer to an array of supported ACPI IDs is added to struct
device_driver in an architecture-independent way, it is logical to
move the ACPI handle from archdata to struct device itself at the same
time. This also makes code more straightforward in some places and
follows the example of Device Trees that have a poiter to struct
device_node in there too.
This changeset is based on Mika Westerberg's work.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2012-10-31 21:44:33 +00:00
|
|
|
* @acpi_match_table: The ACPI match table.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @probe: Called to query the existence of a specific device,
|
|
|
|
* whether this driver can work with it, and bind the driver
|
|
|
|
* to a specific device.
|
|
|
|
* @remove: Called when the device is removed from the system to
|
|
|
|
* unbind a device from this driver.
|
|
|
|
* @shutdown: Called at shut-down time to quiesce the device.
|
|
|
|
* @suspend: Called to put the device to sleep mode. Usually to a
|
|
|
|
* low power state.
|
|
|
|
* @resume: Called to bring a device from sleep mode.
|
|
|
|
* @groups: Default attributes that get created by the driver core
|
|
|
|
* automatically.
|
2019-07-31 12:43:40 +00:00
|
|
|
* @dev_groups: Additional attributes attached to device instance once the
|
|
|
|
* it is bound to the driver.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @pm: Power management operations of the device which matched
|
|
|
|
* this driver.
|
2018-04-08 21:57:07 +00:00
|
|
|
* @coredump: Called when sysfs entry is written to. The device driver
|
|
|
|
* is expected to call the dev_coredump API resulting in a
|
|
|
|
* uevent.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @p: Driver core's private data, no one other than the driver
|
|
|
|
* core can touch this.
|
|
|
|
*
|
|
|
|
* The device driver-model tracks all of the drivers known to the system.
|
|
|
|
* The main reason for this tracking is to enable the driver core to match
|
|
|
|
* up drivers with new devices. Once drivers are known objects within the
|
|
|
|
* system, however, a number of other things become possible. Device drivers
|
|
|
|
* can export information and configuration variables that are independent
|
|
|
|
* of any specific device.
|
|
|
|
*/
|
2005-04-16 22:20:36 +00:00
|
|
|
struct device_driver {
|
2007-11-28 23:59:15 +00:00
|
|
|
const char *name;
|
|
|
|
struct bus_type *bus;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-11-28 23:59:15 +00:00
|
|
|
struct module *owner;
|
2009-10-13 03:17:41 +00:00
|
|
|
const char *mod_name; /* used for built-in modules */
|
|
|
|
|
|
|
|
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
|
2015-03-30 23:20:04 +00:00
|
|
|
enum probe_type probe_type;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2010-04-13 23:13:01 +00:00
|
|
|
const struct of_device_id *of_match_table;
|
driver core / ACPI: Move ACPI support to core device and driver types
With ACPI 5 we are starting to see devices that don't natively support
discovery but can be enumerated with the help of the ACPI namespace.
Typically, these devices can be represented in the Linux device driver
model as platform devices or some serial bus devices, like SPI or I2C
devices.
Since we want to re-use existing drivers for those devices, we need a
way for drivers to specify the ACPI IDs of supported devices, so that
they can be matched against device nodes in the ACPI namespace. To
this end, it is sufficient to add a pointer to an array of supported
ACPI device IDs, that can be provided by the driver, to struct device.
Moreover, things like ACPI power management need to have access to
the ACPI handle of each supported device, because that handle is used
to invoke AML methods associated with the corresponding ACPI device
node. The ACPI handles of devices are now stored in the archdata
member structure of struct device whose definition depends on the
architecture and includes the ACPI handle only on x86 and ia64. Since
the pointer to an array of supported ACPI IDs is added to struct
device_driver in an architecture-independent way, it is logical to
move the ACPI handle from archdata to struct device itself at the same
time. This also makes code more straightforward in some places and
follows the example of Device Trees that have a poiter to struct
device_node in there too.
This changeset is based on Mika Westerberg's work.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2012-10-31 21:44:33 +00:00
|
|
|
const struct acpi_device_id *acpi_match_table;
|
2010-04-13 23:13:01 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
int (*probe) (struct device *dev);
|
|
|
|
int (*remove) (struct device *dev);
|
|
|
|
void (*shutdown) (struct device *dev);
|
|
|
|
int (*suspend) (struct device *dev, pm_message_t state);
|
|
|
|
int (*resume) (struct device *dev);
|
2009-06-24 17:06:31 +00:00
|
|
|
const struct attribute_group **groups;
|
2019-07-31 12:43:40 +00:00
|
|
|
const struct attribute_group **dev_groups;
|
2007-11-28 23:59:15 +00:00
|
|
|
|
2009-07-25 05:11:32 +00:00
|
|
|
const struct dev_pm_ops *pm;
|
2018-04-08 21:57:07 +00:00
|
|
|
void (*coredump) (struct device *dev);
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-20 21:00:01 +00:00
|
|
|
|
2007-11-28 23:59:15 +00:00
|
|
|
struct driver_private *p;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int __must_check driver_register(struct device_driver *drv);
|
|
|
|
extern void driver_unregister(struct device_driver *drv);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern struct device_driver *driver_find(const char *name,
|
|
|
|
struct bus_type *bus);
|
2006-07-18 17:59:59 +00:00
|
|
|
extern int driver_probe_done(void);
|
2009-02-21 08:45:07 +00:00
|
|
|
extern void wait_for_device_probe(void);
|
2009-02-14 00:59:06 +00:00
|
|
|
|
2007-02-17 18:13:42 +00:00
|
|
|
/* sysfs interface for exporting driver attributes */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
struct driver_attribute {
|
2008-01-25 05:04:46 +00:00
|
|
|
struct attribute attr;
|
|
|
|
ssize_t (*show)(struct device_driver *driver, char *buf);
|
|
|
|
ssize_t (*store)(struct device_driver *driver, const char *buf,
|
|
|
|
size_t count);
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2013-07-14 23:05:54 +00:00
|
|
|
#define DRIVER_ATTR_RW(_name) \
|
|
|
|
struct driver_attribute driver_attr_##_name = __ATTR_RW(_name)
|
|
|
|
#define DRIVER_ATTR_RO(_name) \
|
|
|
|
struct driver_attribute driver_attr_##_name = __ATTR_RO(_name)
|
2013-08-23 22:02:56 +00:00
|
|
|
#define DRIVER_ATTR_WO(_name) \
|
|
|
|
struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int __must_check driver_create_file(struct device_driver *driver,
|
2009-12-18 13:34:21 +00:00
|
|
|
const struct driver_attribute *attr);
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void driver_remove_file(struct device_driver *driver,
|
2009-12-18 13:34:21 +00:00
|
|
|
const struct driver_attribute *attr);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int __must_check driver_for_each_device(struct device_driver *drv,
|
|
|
|
struct device *start,
|
|
|
|
void *data,
|
|
|
|
int (*fn)(struct device *dev,
|
|
|
|
void *));
|
|
|
|
struct device *driver_find_device(struct device_driver *drv,
|
2019-06-14 17:54:00 +00:00
|
|
|
struct device *start, const void *data,
|
|
|
|
int (*match)(struct device *dev, const void *data));
|
2005-03-21 18:59:56 +00:00
|
|
|
|
2019-07-23 22:18:32 +00:00
|
|
|
/**
|
|
|
|
* driver_find_device_by_name - device iterator for locating a particular device
|
|
|
|
* of a specific name.
|
2019-08-09 10:20:33 +00:00
|
|
|
* @drv: the driver we're iterating
|
2019-07-23 22:18:32 +00:00
|
|
|
* @name: name of the device to match
|
|
|
|
*/
|
|
|
|
static inline struct device *driver_find_device_by_name(struct device_driver *drv,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return driver_find_device(drv, NULL, name, device_match_name);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:33 +00:00
|
|
|
/**
|
|
|
|
* driver_find_device_by_of_node- device iterator for locating a particular device
|
|
|
|
* by of_node pointer.
|
2019-08-09 10:20:33 +00:00
|
|
|
* @drv: the driver we're iterating
|
2019-07-23 22:18:33 +00:00
|
|
|
* @np: of_node pointer to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
driver_find_device_by_of_node(struct device_driver *drv,
|
|
|
|
const struct device_node *np)
|
|
|
|
{
|
|
|
|
return driver_find_device(drv, NULL, np, device_match_of_node);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:34 +00:00
|
|
|
/**
|
|
|
|
* driver_find_device_by_fwnode- device iterator for locating a particular device
|
|
|
|
* by fwnode pointer.
|
2019-08-09 10:20:33 +00:00
|
|
|
* @drv: the driver we're iterating
|
2019-07-23 22:18:34 +00:00
|
|
|
* @fwnode: fwnode pointer to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
driver_find_device_by_fwnode(struct device_driver *drv,
|
|
|
|
const struct fwnode_handle *fwnode)
|
|
|
|
{
|
|
|
|
return driver_find_device(drv, NULL, fwnode, device_match_fwnode);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:35 +00:00
|
|
|
/**
|
|
|
|
* driver_find_device_by_devt- device iterator for locating a particular device
|
|
|
|
* by devt.
|
2019-08-01 10:20:25 +00:00
|
|
|
* @drv: the driver we're iterating
|
2019-07-23 22:18:35 +00:00
|
|
|
* @devt: devt pointer to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *driver_find_device_by_devt(struct device_driver *drv,
|
|
|
|
dev_t devt)
|
|
|
|
{
|
|
|
|
return driver_find_device(drv, NULL, &devt, device_match_devt);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:37 +00:00
|
|
|
static inline struct device *driver_find_next_device(struct device_driver *drv,
|
|
|
|
struct device *start)
|
|
|
|
{
|
|
|
|
return driver_find_device(drv, start, NULL, device_match_any);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:36 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
/**
|
|
|
|
* driver_find_device_by_acpi_dev : device iterator for locating a particular
|
|
|
|
* device matching the ACPI_COMPANION device.
|
2019-08-09 10:20:33 +00:00
|
|
|
* @drv: the driver we're iterating
|
2019-07-23 22:18:36 +00:00
|
|
|
* @adev: ACPI_COMPANION device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
driver_find_device_by_acpi_dev(struct device_driver *drv,
|
|
|
|
const struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return driver_find_device(drv, NULL, adev, device_match_acpi_dev);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline struct device *
|
|
|
|
driver_find_device_by_acpi_dev(struct device_driver *drv, const void *adev)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-02-01 00:59:42 +00:00
|
|
|
void driver_deferred_probe_add(struct device *dev);
|
2018-07-09 15:41:48 +00:00
|
|
|
int driver_deferred_probe_check_state(struct device *dev);
|
driver: core: Allow subsystems to continue deferring probe
Some subsystems, such as pinctrl, allow continuing to defer probe
indefinitely. This is useful for devices that depend on resources
provided by devices that are only probed after the init stage.
One example of this can be seen on Tegra, where the DPAUX hardware
contains pinmuxing controls for pins that it shares with an I2C
controller. The I2C controller is typically used for communication
with a monitor over HDMI (DDC). However, other instances of the I2C
controller are used to access system critical components, such as a
PMIC. The I2C controller driver will therefore usually be a builtin
driver, whereas the DPAUX driver is part of the display driver that
is loaded from a module to avoid bloating the kernel image with all
of the DRM/KMS subsystem.
In this particular case the pins used by this I2C/DDC controller
become accessible very late in the boot process. However, since the
controller is only used in conjunction with display, that's not an
issue.
Unfortunately the driver core currently outputs a warning message
when a device fails to get the pinctrl before the end of the init
stage. That can be confusing for the user because it may sound like
an unwanted error occurred, whereas it's really an expected and
harmless situation.
In order to eliminate this warning, this patch allows callers of the
driver_deferred_probe_check_state() helper to specify that they want
to continue deferring probe, regardless of whether we're past the
init stage or not. All of the callers of that function are updated
for the new signature, but only the pinctrl subsystem passes a true
value in the new persist parameter if appropriate.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20190621151725.20414-1-thierry.reding@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-21 15:17:25 +00:00
|
|
|
int driver_deferred_probe_check_state_continue(struct device *dev);
|
2018-07-09 15:41:48 +00:00
|
|
|
|
2011-12-14 22:29:38 +00:00
|
|
|
/**
|
|
|
|
* struct subsys_interface - interfaces to device functions
|
2012-01-21 19:02:51 +00:00
|
|
|
* @name: name of the device function
|
|
|
|
* @subsys: subsytem of the devices to attach to
|
|
|
|
* @node: the list of functions registered at the subsystem
|
|
|
|
* @add_dev: device hookup to device function handler
|
|
|
|
* @remove_dev: device hookup to device function handler
|
2011-12-14 22:29:38 +00:00
|
|
|
*
|
|
|
|
* Simple interfaces attached to a subsystem. Multiple interfaces can
|
|
|
|
* attach to a subsystem and its devices. Unlike drivers, they do not
|
|
|
|
* exclusively claim or control devices. Interfaces usually represent
|
|
|
|
* a specific functionality of a subsystem/class of devices.
|
|
|
|
*/
|
|
|
|
struct subsys_interface {
|
|
|
|
const char *name;
|
|
|
|
struct bus_type *subsys;
|
|
|
|
struct list_head node;
|
|
|
|
int (*add_dev)(struct device *dev, struct subsys_interface *sif);
|
2015-07-30 09:34:01 +00:00
|
|
|
void (*remove_dev)(struct device *dev, struct subsys_interface *sif);
|
2011-12-14 22:29:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int subsys_interface_register(struct subsys_interface *sif);
|
|
|
|
void subsys_interface_unregister(struct subsys_interface *sif);
|
|
|
|
|
|
|
|
int subsys_system_register(struct bus_type *subsys,
|
|
|
|
const struct attribute_group **groups);
|
2013-03-12 18:30:05 +00:00
|
|
|
int subsys_virtual_register(struct bus_type *subsys,
|
|
|
|
const struct attribute_group **groups);
|
2011-12-14 22:29:38 +00:00
|
|
|
|
2011-05-04 23:55:36 +00:00
|
|
|
/**
|
|
|
|
* struct class - device classes
|
|
|
|
* @name: Name of the class.
|
|
|
|
* @owner: The module owner.
|
2016-11-28 15:41:41 +00:00
|
|
|
* @class_groups: Default attributes of this class.
|
2013-07-14 23:05:58 +00:00
|
|
|
* @dev_groups: Default attributes of the devices that belong to the class.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @dev_kobj: The kobject that represents this class and links it into the hierarchy.
|
|
|
|
* @dev_uevent: Called when a device is added, removed from this class, or a
|
|
|
|
* few other things that generate uevents to add the environment
|
|
|
|
* variables.
|
|
|
|
* @devnode: Callback to provide the devtmpfs.
|
|
|
|
* @class_release: Called to release this class.
|
|
|
|
* @dev_release: Called to release the device.
|
2017-08-11 13:44:43 +00:00
|
|
|
* @shutdown_pre: Called at shut-down time before driver shutdown.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @ns_type: Callbacks so sysfs can detemine namespaces.
|
|
|
|
* @namespace: Namespace of the device belongs to this class.
|
2018-07-20 21:56:50 +00:00
|
|
|
* @get_ownership: Allows class to specify uid/gid of the sysfs directories
|
|
|
|
* for the devices belonging to the class. Usually tied to
|
|
|
|
* device's namespace.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @pm: The default device power management operations of this class.
|
|
|
|
* @p: The private data of the driver core, no one other than the
|
|
|
|
* driver core can touch this.
|
|
|
|
*
|
|
|
|
* A class is a higher-level view of a device that abstracts out low-level
|
|
|
|
* implementation details. Drivers may see a SCSI disk or an ATA disk, but,
|
|
|
|
* at the class level, they are all simply disks. Classes allow user space
|
|
|
|
* to work with devices based on what they do, rather than how they are
|
|
|
|
* connected or how they work.
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
|
|
|
struct class {
|
2008-01-25 05:04:46 +00:00
|
|
|
const char *name;
|
|
|
|
struct module *owner;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2016-11-28 15:41:41 +00:00
|
|
|
const struct attribute_group **class_groups;
|
2013-07-14 23:05:58 +00:00
|
|
|
const struct attribute_group **dev_groups;
|
2008-04-21 17:51:07 +00:00
|
|
|
struct kobject *dev_kobj;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
|
2011-07-24 00:24:48 +00:00
|
|
|
char *(*devnode)(struct device *dev, umode_t *mode);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
void (*class_release)(struct class *class);
|
|
|
|
void (*dev_release)(struct device *dev);
|
2006-06-24 21:50:29 +00:00
|
|
|
|
2017-08-11 13:44:43 +00:00
|
|
|
int (*shutdown_pre)(struct device *dev);
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-20 21:00:01 +00:00
|
|
|
|
2010-03-30 18:31:25 +00:00
|
|
|
const struct kobj_ns_type_operations *ns_type;
|
|
|
|
const void *(*namespace)(struct device *dev);
|
|
|
|
|
2018-07-20 21:56:50 +00:00
|
|
|
void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid);
|
|
|
|
|
2009-07-25 05:11:32 +00:00
|
|
|
const struct dev_pm_ops *pm;
|
|
|
|
|
2010-11-15 22:13:18 +00:00
|
|
|
struct subsys_private *p;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2008-08-25 17:50:19 +00:00
|
|
|
struct class_dev_iter {
|
|
|
|
struct klist_iter ki;
|
|
|
|
const struct device_type *type;
|
|
|
|
};
|
|
|
|
|
2008-04-21 17:51:07 +00:00
|
|
|
extern struct kobject *sysfs_dev_block_kobj;
|
|
|
|
extern struct kobject *sysfs_dev_char_kobj;
|
2008-05-28 16:28:39 +00:00
|
|
|
extern int __must_check __class_register(struct class *class,
|
|
|
|
struct lock_class_key *key);
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void class_unregister(struct class *class);
|
2008-05-28 16:28:39 +00:00
|
|
|
|
|
|
|
/* This is a #define to keep the compiler from merging different
|
|
|
|
* instances of the __key variable */
|
|
|
|
#define class_register(class) \
|
|
|
|
({ \
|
|
|
|
static struct lock_class_key __key; \
|
|
|
|
__class_register(class, &__key); \
|
|
|
|
})
|
|
|
|
|
2009-08-04 10:55:34 +00:00
|
|
|
struct class_compat;
|
|
|
|
struct class_compat *class_compat_register(const char *name);
|
|
|
|
void class_compat_unregister(struct class_compat *cls);
|
|
|
|
int class_compat_create_link(struct class_compat *cls, struct device *dev,
|
|
|
|
struct device *device_link);
|
|
|
|
void class_compat_remove_link(struct class_compat *cls, struct device *dev,
|
|
|
|
struct device *device_link);
|
|
|
|
|
2012-04-20 02:17:30 +00:00
|
|
|
extern void class_dev_iter_init(struct class_dev_iter *iter,
|
|
|
|
struct class *class,
|
|
|
|
struct device *start,
|
|
|
|
const struct device_type *type);
|
2008-08-25 17:50:19 +00:00
|
|
|
extern struct device *class_dev_iter_next(struct class_dev_iter *iter);
|
|
|
|
extern void class_dev_iter_exit(struct class_dev_iter *iter);
|
|
|
|
|
2008-05-22 21:21:08 +00:00
|
|
|
extern int class_for_each_device(struct class *class, struct device *start,
|
|
|
|
void *data,
|
2008-01-22 07:27:08 +00:00
|
|
|
int (*fn)(struct device *dev, void *data));
|
2008-05-22 21:21:08 +00:00
|
|
|
extern struct device *class_find_device(struct class *class,
|
2013-02-01 19:40:17 +00:00
|
|
|
struct device *start, const void *data,
|
|
|
|
int (*match)(struct device *, const void *));
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2019-07-23 22:18:32 +00:00
|
|
|
/**
|
|
|
|
* class_find_device_by_name - device iterator for locating a particular device
|
|
|
|
* of a specific name.
|
|
|
|
* @class: class type
|
|
|
|
* @name: name of the device to match
|
|
|
|
*/
|
|
|
|
static inline struct device *class_find_device_by_name(struct class *class,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return class_find_device(class, NULL, name, device_match_name);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:33 +00:00
|
|
|
/**
|
|
|
|
* class_find_device_by_of_node : device iterator for locating a particular device
|
|
|
|
* matching the of_node.
|
|
|
|
* @class: class type
|
|
|
|
* @np: of_node of the device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
class_find_device_by_of_node(struct class *class, const struct device_node *np)
|
|
|
|
{
|
|
|
|
return class_find_device(class, NULL, np, device_match_of_node);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:34 +00:00
|
|
|
/**
|
|
|
|
* class_find_device_by_fwnode : device iterator for locating a particular device
|
|
|
|
* matching the fwnode.
|
|
|
|
* @class: class type
|
|
|
|
* @fwnode: fwnode of the device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
class_find_device_by_fwnode(struct class *class,
|
|
|
|
const struct fwnode_handle *fwnode)
|
|
|
|
{
|
|
|
|
return class_find_device(class, NULL, fwnode, device_match_fwnode);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:35 +00:00
|
|
|
/**
|
|
|
|
* class_find_device_by_devt : device iterator for locating a particular device
|
|
|
|
* matching the device type.
|
|
|
|
* @class: class type
|
|
|
|
* @devt: device type of the device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *class_find_device_by_devt(struct class *class,
|
|
|
|
dev_t devt)
|
|
|
|
{
|
|
|
|
return class_find_device(class, NULL, &devt, device_match_devt);
|
|
|
|
}
|
|
|
|
|
2019-07-23 22:18:36 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
struct acpi_device;
|
|
|
|
/**
|
|
|
|
* class_find_device_by_acpi_dev : device iterator for locating a particular
|
|
|
|
* device matching the ACPI_COMPANION device.
|
|
|
|
* @class: class type
|
|
|
|
* @adev: ACPI_COMPANION device to match.
|
|
|
|
*/
|
|
|
|
static inline struct device *
|
|
|
|
class_find_device_by_acpi_dev(struct class *class, const struct acpi_device *adev)
|
|
|
|
{
|
|
|
|
return class_find_device(class, NULL, adev, device_match_acpi_dev);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline struct device *
|
|
|
|
class_find_device_by_acpi_dev(struct class *class, const void *adev)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct class_attribute {
|
2008-01-25 05:04:46 +00:00
|
|
|
struct attribute attr;
|
2010-01-05 11:48:07 +00:00
|
|
|
ssize_t (*show)(struct class *class, struct class_attribute *attr,
|
|
|
|
char *buf);
|
|
|
|
ssize_t (*store)(struct class *class, struct class_attribute *attr,
|
|
|
|
const char *buf, size_t count);
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2013-07-14 23:05:54 +00:00
|
|
|
#define CLASS_ATTR_RW(_name) \
|
|
|
|
struct class_attribute class_attr_##_name = __ATTR_RW(_name)
|
|
|
|
#define CLASS_ATTR_RO(_name) \
|
|
|
|
struct class_attribute class_attr_##_name = __ATTR_RO(_name)
|
2016-11-22 17:31:49 +00:00
|
|
|
#define CLASS_ATTR_WO(_name) \
|
|
|
|
struct class_attribute class_attr_##_name = __ATTR_WO(_name)
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2013-09-12 02:29:04 +00:00
|
|
|
extern int __must_check class_create_file_ns(struct class *class,
|
|
|
|
const struct class_attribute *attr,
|
|
|
|
const void *ns);
|
|
|
|
extern void class_remove_file_ns(struct class *class,
|
|
|
|
const struct class_attribute *attr,
|
|
|
|
const void *ns);
|
|
|
|
|
|
|
|
static inline int __must_check class_create_file(struct class *class,
|
|
|
|
const struct class_attribute *attr)
|
|
|
|
{
|
|
|
|
return class_create_file_ns(class, attr, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void class_remove_file(struct class *class,
|
|
|
|
const struct class_attribute *attr)
|
|
|
|
{
|
|
|
|
return class_remove_file_ns(class, attr, NULL);
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2010-01-05 11:48:08 +00:00
|
|
|
/* Simple class attribute that is just a static string */
|
|
|
|
struct class_attribute_string {
|
|
|
|
struct class_attribute attr;
|
|
|
|
char *str;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Currently read-only only */
|
|
|
|
#define _CLASS_ATTR_STRING(_name, _mode, _str) \
|
|
|
|
{ __ATTR(_name, _mode, show_class_attr_string, NULL), _str }
|
|
|
|
#define CLASS_ATTR_STRING(_name, _mode, _str) \
|
|
|
|
struct class_attribute_string class_attr_##_name = \
|
|
|
|
_CLASS_ATTR_STRING(_name, _mode, _str)
|
|
|
|
|
|
|
|
extern ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr,
|
|
|
|
char *buf);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct class_interface {
|
|
|
|
struct list_head node;
|
|
|
|
struct class *class;
|
|
|
|
|
2006-09-13 13:34:05 +00:00
|
|
|
int (*add_dev) (struct device *, struct class_interface *);
|
|
|
|
void (*remove_dev) (struct device *, struct class_interface *);
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2006-08-15 05:43:17 +00:00
|
|
|
extern int __must_check class_interface_register(struct class_interface *);
|
2005-04-16 22:20:36 +00:00
|
|
|
extern void class_interface_unregister(struct class_interface *);
|
|
|
|
|
2008-05-28 16:28:39 +00:00
|
|
|
extern struct class * __must_check __class_create(struct module *owner,
|
|
|
|
const char *name,
|
|
|
|
struct lock_class_key *key);
|
2005-03-15 19:54:21 +00:00
|
|
|
extern void class_destroy(struct class *cls);
|
|
|
|
|
2008-05-28 16:28:39 +00:00
|
|
|
/* This is a #define to keep the compiler from merging different
|
|
|
|
* instances of the __key variable */
|
|
|
|
#define class_create(owner, name) \
|
|
|
|
({ \
|
|
|
|
static struct lock_class_key __key; \
|
|
|
|
__class_create(owner, name, &__key); \
|
|
|
|
})
|
|
|
|
|
2007-03-12 20:08:57 +00:00
|
|
|
/*
|
|
|
|
* The type of device, "struct device" is embedded in. A class
|
|
|
|
* or bus can contain devices of different types
|
|
|
|
* like "partitions" and "disks", "mouse" and "event".
|
|
|
|
* This identifies the device type and carries type-specific
|
|
|
|
* information, equivalent to the kobj_type of a kobject.
|
|
|
|
* If "name" is specified, the uevent will contain it in
|
|
|
|
* the DEVTYPE variable.
|
|
|
|
*/
|
2006-10-07 19:54:55 +00:00
|
|
|
struct device_type {
|
2007-03-12 20:08:57 +00:00
|
|
|
const char *name;
|
2009-06-24 17:06:31 +00:00
|
|
|
const struct attribute_group **groups;
|
2007-08-14 13:15:12 +00:00
|
|
|
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
2013-04-06 16:56:00 +00:00
|
|
|
char *(*devnode)(struct device *dev, umode_t *mode,
|
2013-04-11 18:43:29 +00:00
|
|
|
kuid_t *uid, kgid_t *gid);
|
2006-10-07 19:54:55 +00:00
|
|
|
void (*release)(struct device *dev);
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-20 21:00:01 +00:00
|
|
|
|
2009-07-25 05:11:32 +00:00
|
|
|
const struct dev_pm_ops *pm;
|
2006-10-07 19:54:55 +00:00
|
|
|
};
|
|
|
|
|
2005-10-01 12:49:43 +00:00
|
|
|
/* interface for exporting device attributes */
|
|
|
|
struct device_attribute {
|
|
|
|
struct attribute attr;
|
|
|
|
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf);
|
|
|
|
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count);
|
|
|
|
};
|
|
|
|
|
2011-12-14 22:29:38 +00:00
|
|
|
struct dev_ext_attribute {
|
|
|
|
struct device_attribute attr;
|
|
|
|
void *var;
|
|
|
|
};
|
|
|
|
|
|
|
|
ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf);
|
|
|
|
ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count);
|
|
|
|
ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf);
|
|
|
|
ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count);
|
2012-10-09 17:52:05 +00:00
|
|
|
ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf);
|
|
|
|
ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count);
|
2005-10-01 12:49:43 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
2011-12-14 22:29:38 +00:00
|
|
|
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
2017-12-18 10:08:29 +00:00
|
|
|
#define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \
|
|
|
|
struct device_attribute dev_attr_##_name = \
|
|
|
|
__ATTR_PREALLOC(_name, _mode, _show, _store)
|
2013-07-14 23:05:54 +00:00
|
|
|
#define DEVICE_ATTR_RW(_name) \
|
|
|
|
struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
|
|
|
|
#define DEVICE_ATTR_RO(_name) \
|
|
|
|
struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
|
2013-08-23 22:02:56 +00:00
|
|
|
#define DEVICE_ATTR_WO(_name) \
|
|
|
|
struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
|
2011-12-14 22:29:38 +00:00
|
|
|
#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
|
|
|
|
struct dev_ext_attribute dev_attr_##_name = \
|
|
|
|
{ __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
|
|
|
|
#define DEVICE_INT_ATTR(_name, _mode, _var) \
|
|
|
|
struct dev_ext_attribute dev_attr_##_name = \
|
2012-05-03 23:19:02 +00:00
|
|
|
{ __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) }
|
2012-10-09 17:52:05 +00:00
|
|
|
#define DEVICE_BOOL_ATTR(_name, _mode, _var) \
|
|
|
|
struct dev_ext_attribute dev_attr_##_name = \
|
|
|
|
{ __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) }
|
2012-05-14 17:30:03 +00:00
|
|
|
#define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
|
|
|
|
struct device_attribute dev_attr_##_name = \
|
|
|
|
__ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
|
2005-10-01 12:49:43 +00:00
|
|
|
|
2012-01-04 23:05:10 +00:00
|
|
|
extern int device_create_file(struct device *device,
|
|
|
|
const struct device_attribute *entry);
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void device_remove_file(struct device *dev,
|
2009-12-18 13:34:19 +00:00
|
|
|
const struct device_attribute *attr);
|
kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers
Sometimes it's necessary to implement a node which wants to delete
nodes including itself. This isn't straightforward because of kernfs
active reference. While a file operation is in progress, an active
reference is held and kernfs_remove() waits for all such references to
drain before completing. For a self-deleting node, this is a deadlock
as kernfs_remove() ends up waiting for an active reference that itself
is sitting on top of.
This currently is worked around in the sysfs layer using
sysfs_schedule_callback() which makes such removals asynchronous.
While it works, it's rather cumbersome and inherently breaks
synchronicity of the operation - the file operation which triggered
the operation may complete before the removal is finished (or even
started) and the removal may fail asynchronously. If a removal
operation is immmediately followed by another operation which expects
the specific name to be available (e.g. removal followed by rename
onto the same name), there's no way to make the latter operation
reliable.
The thing is there's no inherent reason for this to be asynchrnous.
All that's necessary to do this synchronous is a dedicated operation
which drops its own active ref and deactivates self. This patch
implements kernfs_remove_self() and its wrappers in sysfs and driver
core. kernfs_remove_self() is to be called from one of the file
operations, drops the active ref the task is holding, removes the self
node, and restores active ref to the dead node so that the ref is
balanced afterwards. __kernfs_remove() is updated so that it takes an
early exit if the target node is already fully removed so that the
active ref restored by kernfs_remove_self() after removal doesn't
confuse the deactivation path.
This makes implementing self-deleting nodes very easy. The normal
removal path doesn't even need to be changed to use
kernfs_remove_self() for the self-deleting node. The method can
invoke kernfs_remove_self() on itself before proceeding the normal
removal path. kernfs_remove() invoked on the node by the normal
deletion path will simply be ignored.
This will replace sysfs_schedule_callback(). A subtle feature of
sysfs_schedule_callback() is that it collapses multiple invocations -
even if multiple removals are triggered, the removal callback is run
only once. An equivalent effect can be achieved by testing the return
value of kernfs_remove_self() - only the one which gets %true return
value should proceed with actual deletion. All other instances of
kernfs_remove_self() will wait till the enclosing kernfs operation
which invoked the winning instance of kernfs_remove_self() finishes
and then return %false. This trivially makes all users of
kernfs_remove_self() automatically show correct synchronous behavior
even when there are multiple concurrent operations - all "echo 1 >
delete" instances will finish only after the whole operation is
completed by one of the instances.
Note that manipulation of active ref is implemented in separate public
functions - kernfs_[un]break_active_protection().
kernfs_remove_self() is the only user at the moment but this will be
used to cater to more complex cases.
v2: For !CONFIG_SYSFS, dummy version kernfs_remove_self() was missing
and sysfs_remove_file_self() had incorrect return type. Fix it.
Reported by kbuild test bot.
v3: kernfs_[un]break_active_protection() separated out from
kernfs_remove_self() and exposed as public API.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-02-03 19:03:01 +00:00
|
|
|
extern bool device_remove_file_self(struct device *dev,
|
|
|
|
const struct device_attribute *attr);
|
2006-09-19 16:39:19 +00:00
|
|
|
extern int __must_check device_create_bin_file(struct device *dev,
|
2009-12-18 13:34:20 +00:00
|
|
|
const struct bin_attribute *attr);
|
2006-09-19 16:39:19 +00:00
|
|
|
extern void device_remove_bin_file(struct device *dev,
|
2009-12-18 13:34:20 +00:00
|
|
|
const struct bin_attribute *attr);
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
|
|
|
|
/* device resource management */
|
|
|
|
typedef void (*dr_release_t)(struct device *dev, void *res);
|
|
|
|
typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
|
|
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_DEVRES
|
2015-10-06 00:35:55 +00:00
|
|
|
extern void *__devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
|
2016-05-20 00:10:55 +00:00
|
|
|
int nid, const char *name) __malloc;
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
#define devres_alloc(release, size, gfp) \
|
2015-10-06 00:35:55 +00:00
|
|
|
__devres_alloc_node(release, size, gfp, NUMA_NO_NODE, #release)
|
|
|
|
#define devres_alloc_node(release, size, gfp, nid) \
|
|
|
|
__devres_alloc_node(release, size, gfp, nid, #release)
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
#else
|
2015-10-06 00:35:55 +00:00
|
|
|
extern void *devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
|
2016-05-20 00:10:55 +00:00
|
|
|
int nid) __malloc;
|
2015-10-06 00:35:55 +00:00
|
|
|
static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
|
|
|
|
{
|
|
|
|
return devres_alloc_node(release, size, gfp, NUMA_NO_NODE);
|
|
|
|
}
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
#endif
|
2015-10-06 00:35:55 +00:00
|
|
|
|
2012-08-04 04:01:26 +00:00
|
|
|
extern void devres_for_each_res(struct device *dev, dr_release_t release,
|
|
|
|
dr_match_t match, void *match_data,
|
|
|
|
void (*fn)(struct device *, void *, void *),
|
|
|
|
void *data);
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
extern void devres_free(void *res);
|
|
|
|
extern void devres_add(struct device *dev, void *res);
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void *devres_find(struct device *dev, dr_release_t release,
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
dr_match_t match, void *match_data);
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void *devres_get(struct device *dev, void *new_res,
|
|
|
|
dr_match_t match, void *match_data);
|
|
|
|
extern void *devres_remove(struct device *dev, dr_release_t release,
|
|
|
|
dr_match_t match, void *match_data);
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
extern int devres_destroy(struct device *dev, dr_release_t release,
|
|
|
|
dr_match_t match, void *match_data);
|
2012-05-03 17:15:13 +00:00
|
|
|
extern int devres_release(struct device *dev, dr_release_t release,
|
|
|
|
dr_match_t match, void *match_data);
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
|
|
|
|
/* devres group */
|
|
|
|
extern void * __must_check devres_open_group(struct device *dev, void *id,
|
|
|
|
gfp_t gfp);
|
|
|
|
extern void devres_close_group(struct device *dev, void *id);
|
|
|
|
extern void devres_remove_group(struct device *dev, void *id);
|
|
|
|
extern int devres_release_group(struct device *dev, void *id);
|
|
|
|
|
2013-10-11 20:11:38 +00:00
|
|
|
/* managed devm_k.alloc/kfree for device drivers */
|
2016-05-20 00:10:55 +00:00
|
|
|
extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) __malloc;
|
2015-07-17 23:23:42 +00:00
|
|
|
extern __printf(3, 0)
|
|
|
|
char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt,
|
2016-05-20 00:10:55 +00:00
|
|
|
va_list ap) __malloc;
|
2014-08-20 13:26:35 +00:00
|
|
|
extern __printf(3, 4)
|
2016-05-20 00:10:55 +00:00
|
|
|
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...) __malloc;
|
2013-10-11 20:11:38 +00:00
|
|
|
static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
|
|
|
|
{
|
|
|
|
return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
|
|
|
|
}
|
|
|
|
static inline void *devm_kmalloc_array(struct device *dev,
|
|
|
|
size_t n, size_t size, gfp_t flags)
|
|
|
|
{
|
2018-05-09 05:29:52 +00:00
|
|
|
size_t bytes;
|
|
|
|
|
|
|
|
if (unlikely(check_mul_overflow(n, size, &bytes)))
|
2013-10-11 20:11:38 +00:00
|
|
|
return NULL;
|
2018-05-09 05:29:52 +00:00
|
|
|
|
|
|
|
return devm_kmalloc(dev, bytes, flags);
|
2013-10-11 20:11:38 +00:00
|
|
|
}
|
|
|
|
static inline void *devm_kcalloc(struct device *dev,
|
|
|
|
size_t n, size_t size, gfp_t flags)
|
|
|
|
{
|
|
|
|
return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
|
|
|
|
}
|
2018-10-14 15:20:07 +00:00
|
|
|
extern void devm_kfree(struct device *dev, const void *p);
|
2016-05-20 00:10:55 +00:00
|
|
|
extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc;
|
2018-10-14 15:20:09 +00:00
|
|
|
extern const char *devm_kstrdup_const(struct device *dev,
|
|
|
|
const char *s, gfp_t gfp);
|
2014-04-28 23:51:00 +00:00
|
|
|
extern void *devm_kmemdup(struct device *dev, const void *src, size_t len,
|
|
|
|
gfp_t gfp);
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
|
2014-05-16 08:26:35 +00:00
|
|
|
extern unsigned long devm_get_free_pages(struct device *dev,
|
|
|
|
gfp_t gfp_mask, unsigned int order);
|
|
|
|
extern void devm_free_pages(struct device *dev, unsigned long addr);
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
|
2019-07-04 22:14:45 +00:00
|
|
|
void __iomem *devm_ioremap_resource(struct device *dev,
|
|
|
|
const struct resource *res);
|
2011-10-25 13:16:47 +00:00
|
|
|
|
2018-06-05 03:21:26 +00:00
|
|
|
void __iomem *devm_of_iomap(struct device *dev,
|
|
|
|
struct device_node *node, int index,
|
|
|
|
resource_size_t *size);
|
|
|
|
|
2013-02-23 21:11:14 +00:00
|
|
|
/* allows to add/remove a custom action to devres stack */
|
|
|
|
int devm_add_action(struct device *dev, void (*action)(void *), void *data);
|
|
|
|
void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
|
2019-06-13 22:56:18 +00:00
|
|
|
void devm_release_action(struct device *dev, void (*action)(void *), void *data);
|
2013-02-23 21:11:14 +00:00
|
|
|
|
2015-12-23 12:27:19 +00:00
|
|
|
static inline int devm_add_action_or_reset(struct device *dev,
|
|
|
|
void (*action)(void *), void *data)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = devm_add_action(dev, action, data);
|
|
|
|
if (ret)
|
|
|
|
action(data);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-11-15 08:41:01 +00:00
|
|
|
/**
|
|
|
|
* devm_alloc_percpu - Resource-managed alloc_percpu
|
|
|
|
* @dev: Device to allocate per-cpu memory for
|
|
|
|
* @type: Type to allocate per-cpu memory for
|
|
|
|
*
|
|
|
|
* Managed alloc_percpu. Per-cpu memory allocated with this function is
|
|
|
|
* automatically freed on driver detach.
|
|
|
|
*
|
|
|
|
* RETURNS:
|
|
|
|
* Pointer to allocated memory on success, NULL on failure.
|
|
|
|
*/
|
|
|
|
#define devm_alloc_percpu(dev, type) \
|
|
|
|
((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \
|
|
|
|
__alignof__(type)))
|
|
|
|
|
|
|
|
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
|
|
|
|
size_t align);
|
|
|
|
void devm_free_percpu(struct device *dev, void __percpu *pdata);
|
|
|
|
|
2008-02-05 06:27:55 +00:00
|
|
|
struct device_dma_parameters {
|
|
|
|
/*
|
|
|
|
* a low level driver may set these to teach IOMMU code about
|
|
|
|
* sg limitations.
|
|
|
|
*/
|
|
|
|
unsigned int max_segment_size;
|
|
|
|
unsigned long segment_boundary_mask;
|
|
|
|
};
|
|
|
|
|
2018-03-20 12:57:02 +00:00
|
|
|
/**
|
|
|
|
* struct device_connection - Device Connection Descriptor
|
2019-02-13 07:45:52 +00:00
|
|
|
* @fwnode: The device node of the connected device
|
2018-03-20 12:57:02 +00:00
|
|
|
* @endpoint: The names of the two devices connected together
|
|
|
|
* @id: Unique identifier for the connection
|
|
|
|
* @list: List head, private, for internal use only
|
2019-02-13 07:45:52 +00:00
|
|
|
*
|
|
|
|
* NOTE: @fwnode is not used together with @endpoint. @fwnode is used when
|
|
|
|
* platform firmware defines the connection. When the connection is registered
|
|
|
|
* with device_connection_add() @endpoint is used instead.
|
2018-03-20 12:57:02 +00:00
|
|
|
*/
|
|
|
|
struct device_connection {
|
2019-02-13 07:45:52 +00:00
|
|
|
struct fwnode_handle *fwnode;
|
2018-03-20 12:57:02 +00:00
|
|
|
const char *endpoint[2];
|
|
|
|
const char *id;
|
|
|
|
struct list_head list;
|
|
|
|
};
|
|
|
|
|
2019-08-29 09:22:33 +00:00
|
|
|
typedef void *(*devcon_match_fn_t)(struct device_connection *con, int ep,
|
|
|
|
void *data);
|
|
|
|
|
|
|
|
void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
|
|
|
|
const char *con_id, void *data,
|
|
|
|
devcon_match_fn_t match);
|
2018-03-20 12:57:02 +00:00
|
|
|
void *device_connection_find_match(struct device *dev, const char *con_id,
|
2019-08-29 09:22:33 +00:00
|
|
|
void *data, devcon_match_fn_t match);
|
2018-03-20 12:57:02 +00:00
|
|
|
|
|
|
|
struct device *device_connection_find(struct device *dev, const char *con_id);
|
|
|
|
|
|
|
|
void device_connection_add(struct device_connection *con);
|
|
|
|
void device_connection_remove(struct device_connection *con);
|
|
|
|
|
2018-09-20 11:23:40 +00:00
|
|
|
/**
|
|
|
|
* device_connections_add - Add multiple device connections at once
|
|
|
|
* @cons: Zero terminated array of device connection descriptors
|
|
|
|
*/
|
|
|
|
static inline void device_connections_add(struct device_connection *cons)
|
|
|
|
{
|
|
|
|
struct device_connection *c;
|
|
|
|
|
|
|
|
for (c = cons; c->endpoint[0]; c++)
|
|
|
|
device_connection_add(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* device_connections_remove - Remove multiple device connections at once
|
|
|
|
* @cons: Zero terminated array of device connection descriptors
|
|
|
|
*/
|
|
|
|
static inline void device_connections_remove(struct device_connection *cons)
|
|
|
|
{
|
|
|
|
struct device_connection *c;
|
|
|
|
|
|
|
|
for (c = cons; c->endpoint[0]; c++)
|
|
|
|
device_connection_remove(c);
|
|
|
|
}
|
|
|
|
|
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 16:32:16 +00:00
|
|
|
/**
|
|
|
|
* enum device_link_state - Device link states.
|
|
|
|
* @DL_STATE_NONE: The presence of the drivers is not being tracked.
|
|
|
|
* @DL_STATE_DORMANT: None of the supplier/consumer drivers is present.
|
|
|
|
* @DL_STATE_AVAILABLE: The supplier driver is present, but the consumer is not.
|
|
|
|
* @DL_STATE_CONSUMER_PROBE: The consumer is probing (supplier driver present).
|
|
|
|
* @DL_STATE_ACTIVE: Both the supplier and consumer drivers are present.
|
|
|
|
* @DL_STATE_SUPPLIER_UNBIND: The supplier driver is unbinding.
|
|
|
|
*/
|
|
|
|
enum device_link_state {
|
|
|
|
DL_STATE_NONE = -1,
|
|
|
|
DL_STATE_DORMANT = 0,
|
|
|
|
DL_STATE_AVAILABLE,
|
|
|
|
DL_STATE_CONSUMER_PROBE,
|
|
|
|
DL_STATE_ACTIVE,
|
|
|
|
DL_STATE_SUPPLIER_UNBIND,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Device link flags.
|
|
|
|
*
|
driver core: Remove device link creation limitation
If device_link_add() is called for a consumer/supplier pair with an
existing device link between them and the existing link's type is
not in agreement with the flags passed to that function by its
caller, NULL will be returned. That is seriously inconvenient,
because it forces the callers of device_link_add() to worry about
what others may or may not do even if that is not relevant to them
for any other reasons.
It turns out, however, that this limitation can be made go away
relatively easily.
The underlying observation is that if DL_FLAG_STATELESS has been
passed to device_link_add() in flags for the given consumer/supplier
pair at least once, calling either device_link_del() or
device_link_remove() to release the link returned by it should work,
but there are no other requirements associated with that flag. In
turn, if at least one of the callers of device_link_add() for the
given consumer/supplier pair has not passed DL_FLAG_STATELESS to it
in flags, the driver core should track the status of the link and act
on it as appropriate (ie. the link should be treated as "managed").
This means that DL_FLAG_STATELESS needs to be set for managed device
links and it should be valid to call device_link_del() or
device_link_remove() to drop references to them in certain
sutiations.
To allow that to happen, introduce a new (internal) device link flag
called DL_FLAG_MANAGED and make device_link_add() set it automatically
whenever DL_FLAG_STATELESS is not passed to it. Also make it take
additional references to existing device links that were previously
stateless (that is, with DL_FLAG_STATELESS set and DL_FLAG_MANAGED
unset) and will need to be managed going forward and initialize
their status (which has been DL_STATE_NONE so far).
Accordingly, when a managed device link is dropped automatically
by the driver core, make it clear DL_FLAG_MANAGED, reset the link's
status back to DL_STATE_NONE and drop the reference to it associated
with DL_FLAG_MANAGED instead of just deleting it right away (to
allow it to stay around in case it still needs to be released
explicitly by someone).
With that, since setting DL_FLAG_STATELESS doesn't mean that the
device link in question is not managed any more, replace all of the
status-tracking checks against DL_FLAG_STATELESS with analogous
checks against DL_FLAG_MANAGED and update the documentation to
reflect these changes.
While at it, make device_link_add() reject flags that it does not
recognize, including DL_FLAG_MANAGED.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Saravana Kannan <saravanak@google.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Review-by: Saravana Kannan <saravanak@google.com>
Link: https://lore.kernel.org/r/2305283.AStDPdUUnE@kreacher
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-07-16 15:21:06 +00:00
|
|
|
* STATELESS: The core will not remove this link automatically.
|
2018-06-27 12:50:55 +00:00
|
|
|
* AUTOREMOVE_CONSUMER: Remove the link automatically on consumer driver unbind.
|
2016-10-30 16:32:31 +00:00
|
|
|
* 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.
|
2018-06-27 12:50:56 +00:00
|
|
|
* AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind.
|
2019-02-01 00:59:42 +00:00
|
|
|
* AUTOPROBE_CONSUMER: Probe consumer driver automatically after supplier binds.
|
driver core: Remove device link creation limitation
If device_link_add() is called for a consumer/supplier pair with an
existing device link between them and the existing link's type is
not in agreement with the flags passed to that function by its
caller, NULL will be returned. That is seriously inconvenient,
because it forces the callers of device_link_add() to worry about
what others may or may not do even if that is not relevant to them
for any other reasons.
It turns out, however, that this limitation can be made go away
relatively easily.
The underlying observation is that if DL_FLAG_STATELESS has been
passed to device_link_add() in flags for the given consumer/supplier
pair at least once, calling either device_link_del() or
device_link_remove() to release the link returned by it should work,
but there are no other requirements associated with that flag. In
turn, if at least one of the callers of device_link_add() for the
given consumer/supplier pair has not passed DL_FLAG_STATELESS to it
in flags, the driver core should track the status of the link and act
on it as appropriate (ie. the link should be treated as "managed").
This means that DL_FLAG_STATELESS needs to be set for managed device
links and it should be valid to call device_link_del() or
device_link_remove() to drop references to them in certain
sutiations.
To allow that to happen, introduce a new (internal) device link flag
called DL_FLAG_MANAGED and make device_link_add() set it automatically
whenever DL_FLAG_STATELESS is not passed to it. Also make it take
additional references to existing device links that were previously
stateless (that is, with DL_FLAG_STATELESS set and DL_FLAG_MANAGED
unset) and will need to be managed going forward and initialize
their status (which has been DL_STATE_NONE so far).
Accordingly, when a managed device link is dropped automatically
by the driver core, make it clear DL_FLAG_MANAGED, reset the link's
status back to DL_STATE_NONE and drop the reference to it associated
with DL_FLAG_MANAGED instead of just deleting it right away (to
allow it to stay around in case it still needs to be released
explicitly by someone).
With that, since setting DL_FLAG_STATELESS doesn't mean that the
device link in question is not managed any more, replace all of the
status-tracking checks against DL_FLAG_STATELESS with analogous
checks against DL_FLAG_MANAGED and update the documentation to
reflect these changes.
While at it, make device_link_add() reject flags that it does not
recognize, including DL_FLAG_MANAGED.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Saravana Kannan <saravanak@google.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Review-by: Saravana Kannan <saravanak@google.com>
Link: https://lore.kernel.org/r/2305283.AStDPdUUnE@kreacher
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-07-16 15:21:06 +00:00
|
|
|
* MANAGED: The core tracks presence of supplier/consumer drivers (internal).
|
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 16:32:16 +00:00
|
|
|
*/
|
2018-06-27 12:50:55 +00:00
|
|
|
#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)
|
2018-06-27 12:50:56 +00:00
|
|
|
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
|
2019-02-01 00:59:42 +00:00
|
|
|
#define DL_FLAG_AUTOPROBE_CONSUMER BIT(5)
|
driver core: Remove device link creation limitation
If device_link_add() is called for a consumer/supplier pair with an
existing device link between them and the existing link's type is
not in agreement with the flags passed to that function by its
caller, NULL will be returned. That is seriously inconvenient,
because it forces the callers of device_link_add() to worry about
what others may or may not do even if that is not relevant to them
for any other reasons.
It turns out, however, that this limitation can be made go away
relatively easily.
The underlying observation is that if DL_FLAG_STATELESS has been
passed to device_link_add() in flags for the given consumer/supplier
pair at least once, calling either device_link_del() or
device_link_remove() to release the link returned by it should work,
but there are no other requirements associated with that flag. In
turn, if at least one of the callers of device_link_add() for the
given consumer/supplier pair has not passed DL_FLAG_STATELESS to it
in flags, the driver core should track the status of the link and act
on it as appropriate (ie. the link should be treated as "managed").
This means that DL_FLAG_STATELESS needs to be set for managed device
links and it should be valid to call device_link_del() or
device_link_remove() to drop references to them in certain
sutiations.
To allow that to happen, introduce a new (internal) device link flag
called DL_FLAG_MANAGED and make device_link_add() set it automatically
whenever DL_FLAG_STATELESS is not passed to it. Also make it take
additional references to existing device links that were previously
stateless (that is, with DL_FLAG_STATELESS set and DL_FLAG_MANAGED
unset) and will need to be managed going forward and initialize
their status (which has been DL_STATE_NONE so far).
Accordingly, when a managed device link is dropped automatically
by the driver core, make it clear DL_FLAG_MANAGED, reset the link's
status back to DL_STATE_NONE and drop the reference to it associated
with DL_FLAG_MANAGED instead of just deleting it right away (to
allow it to stay around in case it still needs to be released
explicitly by someone).
With that, since setting DL_FLAG_STATELESS doesn't mean that the
device link in question is not managed any more, replace all of the
status-tracking checks against DL_FLAG_STATELESS with analogous
checks against DL_FLAG_MANAGED and update the documentation to
reflect these changes.
While at it, make device_link_add() reject flags that it does not
recognize, including DL_FLAG_MANAGED.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Saravana Kannan <saravanak@google.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Review-by: Saravana Kannan <saravanak@google.com>
Link: https://lore.kernel.org/r/2305283.AStDPdUUnE@kreacher
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-07-16 15:21:06 +00:00
|
|
|
#define DL_FLAG_MANAGED BIT(6)
|
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 16:32:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct device_link - Device link representation.
|
|
|
|
* @supplier: The device on the supplier end of the link.
|
|
|
|
* @s_node: Hook to the supplier device's list of links to consumers.
|
|
|
|
* @consumer: The device on the consumer end of the link.
|
|
|
|
* @c_node: Hook to the consumer device's list of links to suppliers.
|
|
|
|
* @status: The state of the link (with respect to the presence of drivers).
|
|
|
|
* @flags: Link flags.
|
2016-10-30 16:32:31 +00:00
|
|
|
* @rpm_active: Whether or not the consumer device is runtime-PM-active.
|
driver core: Introduce device links reference counting
If device_link_add() is invoked multiple times with the same supplier
and consumer combo, it will create the link on first addition and
return a pointer to the already existing link on all subsequent
additions.
The semantics for device_link_del() are quite different, it deletes
the link unconditionally, so multiple invocations are not allowed.
In other words, this snippet ...
struct device *dev1, *dev2;
struct device_link *link1, *link2;
link1 = device_link_add(dev1, dev2, 0);
link2 = device_link_add(dev1, dev2, 0);
device_link_del(link1);
device_link_del(link2);
... causes the following crash:
WARNING: CPU: 4 PID: 2686 at drivers/base/power/runtime.c:1611 pm_runtime_drop_link+0x40/0x50
[...]
list_del corruption, 0000000039b800a4->prev is LIST_POISON2 (00000000ecf79852)
kernel BUG at lib/list_debug.c:50!
The issue isn't as arbitrary as it may seem: Imagine a device link
which is added in both the supplier's and the consumer's ->probe hook.
The two drivers can't just call device_link_del() in their ->remove hook
without coordination.
Fix by counting multiple additions and dropping the device link only
when the last addition is unwound.
Signed-off-by: Lukas Wunner <lukas@wunner.de>
[ rjw: Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2018-02-10 18:27:12 +00:00
|
|
|
* @kref: Count repeated addition of the same link.
|
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 16:32:16 +00:00
|
|
|
* @rcu_head: An RCU head to use for deferred execution of SRCU callbacks.
|
2019-02-21 11:28:05 +00:00
|
|
|
* @supplier_preactivated: Supplier has been made active before consumer probe.
|
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 16:32:16 +00:00
|
|
|
*/
|
|
|
|
struct device_link {
|
|
|
|
struct device *supplier;
|
|
|
|
struct list_head s_node;
|
|
|
|
struct device *consumer;
|
|
|
|
struct list_head c_node;
|
|
|
|
enum device_link_state status;
|
|
|
|
u32 flags;
|
driver core: Fix handling of runtime PM flags in device_link_add()
After commit ead18c23c263 ("driver core: Introduce device links
reference counting"), if there is a link between the given supplier
and the given consumer already, device_link_add() will refcount it
and return it unconditionally without updating its flags. It is
possible, however, that the second (or any subsequent) caller of
device_link_add() for the same consumer-supplier pair will pass
DL_FLAG_PM_RUNTIME, possibly along with DL_FLAG_RPM_ACTIVE, in flags
to it and the existing link may not behave as expected then.
First, if DL_FLAG_PM_RUNTIME is not set in the existing link's flags
at all, it needs to be set like during the original initialization of
the link.
Second, if DL_FLAG_RPM_ACTIVE is passed to device_link_add() in flags
(in addition to DL_FLAG_PM_RUNTIME), the existing link should to be
updated to reflect the "active" runtime PM configuration of the
consumer-supplier pair and extra care must be taken here to avoid
possible destructive races with runtime PM of the consumer.
To that end, redefine the rpm_active field in struct device_link
as a refcount, initialize it to 1 and make rpm_resume() (for the
consumer) and device_link_add() increment it whenever they acquire
a runtime PM reference on the supplier device. Accordingly, make
rpm_suspend() (for the consumer) and pm_runtime_clean_up_links()
decrement it and drop runtime PM references to the supplier
device in a loop until rpm_active becones 1 again.
Fixes: ead18c23c263 ("driver core: Introduce device links reference counting")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-02-01 00:49:14 +00:00
|
|
|
refcount_t rpm_active;
|
driver core: Introduce device links reference counting
If device_link_add() is invoked multiple times with the same supplier
and consumer combo, it will create the link on first addition and
return a pointer to the already existing link on all subsequent
additions.
The semantics for device_link_del() are quite different, it deletes
the link unconditionally, so multiple invocations are not allowed.
In other words, this snippet ...
struct device *dev1, *dev2;
struct device_link *link1, *link2;
link1 = device_link_add(dev1, dev2, 0);
link2 = device_link_add(dev1, dev2, 0);
device_link_del(link1);
device_link_del(link2);
... causes the following crash:
WARNING: CPU: 4 PID: 2686 at drivers/base/power/runtime.c:1611 pm_runtime_drop_link+0x40/0x50
[...]
list_del corruption, 0000000039b800a4->prev is LIST_POISON2 (00000000ecf79852)
kernel BUG at lib/list_debug.c:50!
The issue isn't as arbitrary as it may seem: Imagine a device link
which is added in both the supplier's and the consumer's ->probe hook.
The two drivers can't just call device_link_del() in their ->remove hook
without coordination.
Fix by counting multiple additions and dropping the device link only
when the last addition is unwound.
Signed-off-by: Lukas Wunner <lukas@wunner.de>
[ rjw: Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2018-02-10 18:27:12 +00:00
|
|
|
struct kref kref;
|
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 16:32:16 +00:00
|
|
|
#ifdef CONFIG_SRCU
|
|
|
|
struct rcu_head rcu_head;
|
|
|
|
#endif
|
2019-02-19 16:53:26 +00:00
|
|
|
bool supplier_preactivated; /* Owned by consumer probe. */
|
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 16:32:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* enum dl_dev_state - Device driver presence tracking information.
|
|
|
|
* @DL_DEV_NO_DRIVER: There is no driver attached to the device.
|
|
|
|
* @DL_DEV_PROBING: A driver is probing.
|
|
|
|
* @DL_DEV_DRIVER_BOUND: The driver has been bound to the device.
|
|
|
|
* @DL_DEV_UNBINDING: The driver is unbinding from the device.
|
|
|
|
*/
|
|
|
|
enum dl_dev_state {
|
|
|
|
DL_DEV_NO_DRIVER = 0,
|
|
|
|
DL_DEV_PROBING,
|
|
|
|
DL_DEV_DRIVER_BOUND,
|
|
|
|
DL_DEV_UNBINDING,
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct dev_links_info - Device data related to device links.
|
|
|
|
* @suppliers: List of links to supplier devices.
|
|
|
|
* @consumers: List of links to consumer devices.
|
|
|
|
* @status: Driver status information.
|
|
|
|
*/
|
|
|
|
struct dev_links_info {
|
|
|
|
struct list_head suppliers;
|
|
|
|
struct list_head consumers;
|
|
|
|
enum dl_dev_state status;
|
|
|
|
};
|
|
|
|
|
2011-05-04 23:55:36 +00:00
|
|
|
/**
|
|
|
|
* struct device - The basic device structure
|
|
|
|
* @parent: The device's "parent" device, the device to which it is attached.
|
|
|
|
* In most cases, a parent device is some sort of bus or host
|
|
|
|
* controller. If parent is NULL, the device, is a top-level device,
|
|
|
|
* which is not usually what you want.
|
|
|
|
* @p: Holds the private data of the driver core portions of the device.
|
|
|
|
* See the comment of the struct device_private for detail.
|
|
|
|
* @kobj: A top-level, abstract class from which other classes are derived.
|
|
|
|
* @init_name: Initial name of the device.
|
|
|
|
* @type: The type of device.
|
|
|
|
* This identifies the device type and carries type-specific
|
|
|
|
* information.
|
|
|
|
* @mutex: Mutex to synchronize calls to its driver.
|
2019-07-18 01:08:26 +00:00
|
|
|
* @lockdep_mutex: An optional debug lock that a subsystem can use as a
|
|
|
|
* peer lock to gain localized lockdep coverage of the device_lock.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @bus: Type of bus device is on.
|
|
|
|
* @driver: Which driver has allocated this
|
|
|
|
* @platform_data: Platform data specific to the device.
|
|
|
|
* Example: For devices on custom boards, as typical of embedded
|
|
|
|
* and SOC based hardware, Linux often uses platform_data to point
|
|
|
|
* to board-specific structures describing devices and how they
|
|
|
|
* are wired. That can include what ports are available, chip
|
|
|
|
* variants, which GPIO pins act in what additional roles, and so
|
|
|
|
* on. This shrinks the "Board Support Packages" (BSPs) and
|
|
|
|
* minimizes board-specific #ifdefs in drivers.
|
2014-04-14 10:54:47 +00:00
|
|
|
* @driver_data: Private pointer for driver specific info.
|
2016-12-04 12:10:04 +00:00
|
|
|
* @links: Links to suppliers and consumers of this device.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @power: For device power management.
|
2017-09-05 18:16:27 +00:00
|
|
|
* See Documentation/driver-api/pm/devices.rst for details.
|
2011-06-22 23:52:55 +00:00
|
|
|
* @pm_domain: Provide callbacks that are executed during system suspend,
|
2011-05-04 23:55:36 +00:00
|
|
|
* hibernation, system resume and during runtime PM transitions
|
|
|
|
* along with subsystem-level and driver-level callbacks.
|
drivers/pinctrl: grab default handles from device core
This makes the device core auto-grab the pinctrl handle and set
the "default" (PINCTRL_STATE_DEFAULT) state for every device
that is present in the device model right before probe. This will
account for the lion's share of embedded silicon devcies.
A modification of the semantics for pinctrl_get() is also done:
previously if the pinctrl handle for a certain device was already
taken, the pinctrl core would return an error. Now, since the
core may have already default-grabbed the handle and set its
state to "default", if the handle was already taken, this will
be disregarded and the located, previously instanitated handle
will be returned to the caller.
This way all code in drivers explicitly requesting their pinctrl
handlers will still be functional, and drivers that want to
explicitly retrieve and switch their handles can still do that.
But if the desired functionality is just boilerplate of this
type in the probe() function:
struct pinctrl *p;
p = devm_pinctrl_get_select_default(&dev);
if (IS_ERR(p)) {
if (PTR_ERR(p) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_warn(&dev, "no pinctrl handle\n");
}
The discussion began with the addition of such boilerplate
to the omap4 keypad driver:
http://marc.info/?l=linux-input&m=135091157719300&w=2
A previous approach using notifiers was discussed:
http://marc.info/?l=linux-kernel&m=135263661110528&w=2
This failed because it could not handle deferred probes.
This patch alone does not solve the entire dilemma faced:
whether code should be distributed into the drivers or
if it should be centralized to e.g. a PM domain. But it
solves the immediate issue of the addition of boilerplate
to a lot of drivers that just want to grab the default
state. As mentioned, they can later explicitly retrieve
the handle and set different states, and this could as
well be done by e.g. PM domains as it is only related
to a certain struct device * pointer.
ChangeLog v4->v5 (Stephen):
- Simplified the devicecore grab code.
- Deleted a piece of documentation recommending that pins
be mapped to a device rather than hogged.
ChangeLog v3->v4 (Linus):
- Drop overzealous NULL checks.
- Move kref initialization to pinctrl_create().
- Seeking Tested-by from Stephen Warren so we do not disturb
the Tegra platform.
- Seeking ACK on this from Greg (and others who like it) so I
can merge it through the pinctrl subsystem.
ChangeLog v2->v3 (Linus):
- Abstain from using IS_ERR_OR_NULL() in the driver core,
Russell recently sent a patch to remove it. Handle the
NULL case explicitly even though it's a bogus case.
- Make sure we handle probe deferral correctly in the device
core file. devm_kfree() the container on error so we don't
waste memory for devices without pinctrl handles.
- Introduce reference counting into the pinctrl core using
<linux/kref.h> so that we don't release pinctrl handles
that have been obtained for two or more places.
ChangeLog v1->v2 (Linus):
- Only store a pointer in the device struct, and only allocate
this if it's really used by the device.
Cc: Felipe Balbi <balbi@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Mitch Bradley <wmb@firmworks.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Rickard Andersson <rickard.andersson@stericsson.com>
Cc: Russell King <linux@arm.linux.org.uk>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[swarren: fixed and simplified error-handling in pinctrl_bind_pins(), to
correctly handle deferred probe. Removed admonition from docs not to use
pinctrl hogs for devices]
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2013-01-22 17:56:14 +00:00
|
|
|
* @pins: For device pin management.
|
2017-08-06 14:00:05 +00:00
|
|
|
* See Documentation/driver-api/pinctl.rst for details.
|
2015-07-09 08:00:44 +00:00
|
|
|
* @msi_list: Hosts MSI descriptors
|
2015-07-28 13:46:10 +00:00
|
|
|
* @msi_domain: The generic MSI domain this device is using.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @numa_node: NUMA node this device is close to.
|
2017-08-24 22:09:10 +00:00
|
|
|
* @dma_ops: DMA mapping operations for this device.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @dma_mask: Dma mask (if dma'ble device).
|
|
|
|
* @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
|
|
|
|
* hardware supports 64-bit addresses for consistent allocations
|
|
|
|
* such descriptors.
|
2018-07-23 22:16:07 +00:00
|
|
|
* @bus_dma_mask: Mask of an upstream bridge or bus which imposes a smaller DMA
|
|
|
|
* limit than the device itself supports.
|
2014-04-24 15:30:01 +00:00
|
|
|
* @dma_pfn_offset: offset of DMA memory range relatively of RAM
|
2011-05-04 23:55:36 +00:00
|
|
|
* @dma_parms: A low level driver may set these to teach IOMMU code about
|
|
|
|
* segment limitations.
|
|
|
|
* @dma_pools: Dma pools (if dma'ble device).
|
|
|
|
* @dma_mem: Internal for coherent mem override.
|
2013-06-26 03:57:06 +00:00
|
|
|
* @cma_area: Contiguous memory area for dma allocations
|
2011-05-04 23:55:36 +00:00
|
|
|
* @archdata: For arch-specific additions.
|
|
|
|
* @of_node: Associated device tree node.
|
2015-03-16 22:49:03 +00:00
|
|
|
* @fwnode: Associated device node supplied by platform firmware.
|
2011-05-04 23:55:36 +00:00
|
|
|
* @devt: For creating the sysfs "dev".
|
2012-01-21 19:02:51 +00:00
|
|
|
* @id: device instance
|
2011-05-04 23:55:36 +00:00
|
|
|
* @devres_lock: Spinlock to protect the resource of the device.
|
|
|
|
* @devres_head: The resources list of the device.
|
|
|
|
* @knode_class: The node used to add the device to the class list.
|
|
|
|
* @class: The class of the device.
|
|
|
|
* @groups: Optional attribute groups.
|
|
|
|
* @release: Callback to free the device after all references have
|
|
|
|
* gone away. This should be set by the allocator of the
|
|
|
|
* device (i.e. the bus driver that discovered the device).
|
2013-06-26 03:57:06 +00:00
|
|
|
* @iommu_group: IOMMU group the device belongs to.
|
2016-09-13 09:54:14 +00:00
|
|
|
* @iommu_fwspec: IOMMU-specific properties supplied by firmware.
|
2019-06-03 14:57:46 +00:00
|
|
|
* @iommu_param: Per device generic IOMMU runtime data
|
2011-05-04 23:55:36 +00:00
|
|
|
*
|
Driver core: Add offline/online device operations
In some cases, graceful hot-removal of devices is not possible,
although in principle the devices in question support hotplug.
For example, that may happen for the last CPU in the system or
for memory modules holding kernel memory.
In those cases it is nice to be able to check if the given device
can be gracefully hot-removed before triggering a removal procedure
that cannot be aborted or reversed. Unfortunately, however, the
kernel currently doesn't provide any support for that.
To address that deficiency, introduce support for offline and
online operations that can be performed on devices, respectively,
before a hot-removal and in case when it is necessary (or convenient)
to put a device back online after a successful offline (that has not
been followed by removal). The idea is that the offline will fail
whenever the given device cannot be gracefully removed from the
system and it will not be allowed to use the device after a
successful offline (until a subsequent online) in analogy with the
existing CPU offline/online mechanism.
For now, the offline and online operations are introduced at the
bus type level, as that should be sufficient for the most urgent use
cases (CPUs and memory modules). In the future, however, the
approach may be extended to cover some more complicated device
offline/online scenarios involving device drivers etc.
The lock_device_hotplug() and unlock_device_hotplug() functions are
introduced because subsequent patches need to put larger pieces of
code under device_hotplug_lock to prevent race conditions between
device offline and removal from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-02 20:15:29 +00:00
|
|
|
* @offline_disabled: If set, the device is permanently online.
|
|
|
|
* @offline: Set after successful invocation of bus type's .offline().
|
driver core: add helper to reuse a device-tree node
Add a helper function to be used when reusing the device-tree node of
another device.
It is fairly common for drivers to reuse the device-tree node of a
parent (or other ancestor) device when creating class or bus devices
(e.g. gpio chips, i2c adapters, iio chips, spi masters, serdev, phys,
usb root hubs). But reusing a device-tree node may cause problems if the
new device is later probed as for example driver core would currently
attempt to reinitialise an already active associated pinmux
configuration.
Other potential issues include the platform-bus code unconditionally
dropping the device-tree node reference in its device destructor,
reinitialisation of other bus-managed resources such as clocks, and the
recently added DMA-setup in driver core.
Note that for most examples above this is currently not an issue as the
devices are never probed, but this is a problem for the USB bus which
has recently gained device-tree support. This was discovered and
worked-around in a rather ad-hoc fashion by commit dc5878abf49c ("usb:
core: move root hub's device node assignment after it is added to bus")
by not setting the of_node pointer until after the root-hub device has
been registered.
Instead we can allow devices to reuse a device-tree node by setting a
flag in their struct device that can be used by core, bus and driver
code to avoid resources from being over-allocated.
Note that the helper also grabs an extra reference to the device node,
which specifically balances the unconditional put in the platform-device
destructor.
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-06 15:59:00 +00:00
|
|
|
* @of_node_reused: Set if the device-tree node is shared with an ancestor
|
|
|
|
* device.
|
2018-08-19 12:53:20 +00:00
|
|
|
* @dma_coherent: this particular device is dma coherent, even if the
|
|
|
|
* architecture supports non-coherent devices.
|
2011-05-04 23:55:36 +00:00
|
|
|
*
|
|
|
|
* At the lowest level, every device in a Linux system is represented by an
|
|
|
|
* instance of struct device. The device structure contains the information
|
|
|
|
* that the device model core needs to model the system. Most subsystems,
|
|
|
|
* however, track additional information about the devices they host. As a
|
|
|
|
* result, it is rare for devices to be represented by bare device structures;
|
|
|
|
* instead, that structure, like kobject structures, is usually embedded within
|
|
|
|
* a higher-level representation of the device.
|
|
|
|
*/
|
2005-04-16 22:20:36 +00:00
|
|
|
struct device {
|
device.h: reorganize struct device
struct device is big, around 760 bytes on x86_64. It's not a critical
structure, but it is embedded everywhere, so making it smaller is always
a good thing.
With a recent patch that moved a field from struct device to the private
structure, some benchmarks showed a very odd regression, despite this
structure having nothing to do with those benchmarks. That caused me to
look into the layout of the structure. Using 'pahole', it showed a
number of holes and ways that the structure could be reordered in order
to align some cachelines better, as well as reduce the size of the
overall structure.
Move 'struct kobj' to the start of the structure, to keep that access
in the first cacheline, and try to organize things a bit more compactly
where possible
By doing these few moves, the result removes at least 8 bytes from
'struct device' on a 64bit system. Given we know there are systems with
at least 30k devices in memory at once, every little byte counts, and
this change could be a savings of 240k of kernel memory for them. On
"normal" systems the overall memory savings would be much less.
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-02-26 14:32:29 +00:00
|
|
|
struct kobject kobj;
|
2007-05-08 07:29:39 +00:00
|
|
|
struct device *parent;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-12-16 20:23:36 +00:00
|
|
|
struct device_private *p;
|
|
|
|
|
2008-05-30 17:45:12 +00:00
|
|
|
const char *init_name; /* initial name of the device */
|
2011-03-28 16:12:52 +00:00
|
|
|
const struct device_type *type;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
struct bus_type *bus; /* type of bus device is on */
|
2005-04-16 22:20:36 +00:00
|
|
|
struct device_driver *driver; /* which driver has allocated this
|
|
|
|
device */
|
2009-03-08 15:13:32 +00:00
|
|
|
void *platform_data; /* Platform specific data, device
|
|
|
|
core doesn't touch it */
|
2014-04-14 10:54:47 +00:00
|
|
|
void *driver_data; /* Driver data, set and get with
|
2019-02-05 12:19:52 +00:00
|
|
|
dev_set_drvdata/dev_get_drvdata */
|
2019-07-18 01:08:26 +00:00
|
|
|
#ifdef CONFIG_PROVE_LOCKING
|
|
|
|
struct mutex lockdep_mutex;
|
|
|
|
#endif
|
device.h: reorganize struct device
struct device is big, around 760 bytes on x86_64. It's not a critical
structure, but it is embedded everywhere, so making it smaller is always
a good thing.
With a recent patch that moved a field from struct device to the private
structure, some benchmarks showed a very odd regression, despite this
structure having nothing to do with those benchmarks. That caused me to
look into the layout of the structure. Using 'pahole', it showed a
number of holes and ways that the structure could be reordered in order
to align some cachelines better, as well as reduce the size of the
overall structure.
Move 'struct kobj' to the start of the structure, to keep that access
in the first cacheline, and try to organize things a bit more compactly
where possible
By doing these few moves, the result removes at least 8 bytes from
'struct device' on a 64bit system. Given we know there are systems with
at least 30k devices in memory at once, every little byte counts, and
this change could be a savings of 240k of kernel memory for them. On
"normal" systems the overall memory savings would be much less.
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-02-26 14:32:29 +00:00
|
|
|
struct mutex mutex; /* mutex to synchronize calls to
|
|
|
|
* its driver.
|
|
|
|
*/
|
|
|
|
|
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 16:32:16 +00:00
|
|
|
struct dev_links_info links;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct dev_pm_info power;
|
2011-06-22 23:52:55 +00:00
|
|
|
struct dev_pm_domain *pm_domain;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2015-07-28 13:46:10 +00:00
|
|
|
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
|
|
|
struct irq_domain *msi_domain;
|
|
|
|
#endif
|
drivers/pinctrl: grab default handles from device core
This makes the device core auto-grab the pinctrl handle and set
the "default" (PINCTRL_STATE_DEFAULT) state for every device
that is present in the device model right before probe. This will
account for the lion's share of embedded silicon devcies.
A modification of the semantics for pinctrl_get() is also done:
previously if the pinctrl handle for a certain device was already
taken, the pinctrl core would return an error. Now, since the
core may have already default-grabbed the handle and set its
state to "default", if the handle was already taken, this will
be disregarded and the located, previously instanitated handle
will be returned to the caller.
This way all code in drivers explicitly requesting their pinctrl
handlers will still be functional, and drivers that want to
explicitly retrieve and switch their handles can still do that.
But if the desired functionality is just boilerplate of this
type in the probe() function:
struct pinctrl *p;
p = devm_pinctrl_get_select_default(&dev);
if (IS_ERR(p)) {
if (PTR_ERR(p) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_warn(&dev, "no pinctrl handle\n");
}
The discussion began with the addition of such boilerplate
to the omap4 keypad driver:
http://marc.info/?l=linux-input&m=135091157719300&w=2
A previous approach using notifiers was discussed:
http://marc.info/?l=linux-kernel&m=135263661110528&w=2
This failed because it could not handle deferred probes.
This patch alone does not solve the entire dilemma faced:
whether code should be distributed into the drivers or
if it should be centralized to e.g. a PM domain. But it
solves the immediate issue of the addition of boilerplate
to a lot of drivers that just want to grab the default
state. As mentioned, they can later explicitly retrieve
the handle and set different states, and this could as
well be done by e.g. PM domains as it is only related
to a certain struct device * pointer.
ChangeLog v4->v5 (Stephen):
- Simplified the devicecore grab code.
- Deleted a piece of documentation recommending that pins
be mapped to a device rather than hogged.
ChangeLog v3->v4 (Linus):
- Drop overzealous NULL checks.
- Move kref initialization to pinctrl_create().
- Seeking Tested-by from Stephen Warren so we do not disturb
the Tegra platform.
- Seeking ACK on this from Greg (and others who like it) so I
can merge it through the pinctrl subsystem.
ChangeLog v2->v3 (Linus):
- Abstain from using IS_ERR_OR_NULL() in the driver core,
Russell recently sent a patch to remove it. Handle the
NULL case explicitly even though it's a bogus case.
- Make sure we handle probe deferral correctly in the device
core file. devm_kfree() the container on error so we don't
waste memory for devices without pinctrl handles.
- Introduce reference counting into the pinctrl core using
<linux/kref.h> so that we don't release pinctrl handles
that have been obtained for two or more places.
ChangeLog v1->v2 (Linus):
- Only store a pointer in the device struct, and only allocate
this if it's really used by the device.
Cc: Felipe Balbi <balbi@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Mitch Bradley <wmb@firmworks.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Rickard Andersson <rickard.andersson@stericsson.com>
Cc: Russell King <linux@arm.linux.org.uk>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[swarren: fixed and simplified error-handling in pinctrl_bind_pins(), to
correctly handle deferred probe. Removed admonition from docs not to use
pinctrl hogs for devices]
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2013-01-22 17:56:14 +00:00
|
|
|
#ifdef CONFIG_PINCTRL
|
|
|
|
struct dev_pin_info *pins;
|
|
|
|
#endif
|
2015-07-09 08:00:44 +00:00
|
|
|
#ifdef CONFIG_GENERIC_MSI_IRQ
|
|
|
|
struct list_head msi_list;
|
|
|
|
#endif
|
drivers/pinctrl: grab default handles from device core
This makes the device core auto-grab the pinctrl handle and set
the "default" (PINCTRL_STATE_DEFAULT) state for every device
that is present in the device model right before probe. This will
account for the lion's share of embedded silicon devcies.
A modification of the semantics for pinctrl_get() is also done:
previously if the pinctrl handle for a certain device was already
taken, the pinctrl core would return an error. Now, since the
core may have already default-grabbed the handle and set its
state to "default", if the handle was already taken, this will
be disregarded and the located, previously instanitated handle
will be returned to the caller.
This way all code in drivers explicitly requesting their pinctrl
handlers will still be functional, and drivers that want to
explicitly retrieve and switch their handles can still do that.
But if the desired functionality is just boilerplate of this
type in the probe() function:
struct pinctrl *p;
p = devm_pinctrl_get_select_default(&dev);
if (IS_ERR(p)) {
if (PTR_ERR(p) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_warn(&dev, "no pinctrl handle\n");
}
The discussion began with the addition of such boilerplate
to the omap4 keypad driver:
http://marc.info/?l=linux-input&m=135091157719300&w=2
A previous approach using notifiers was discussed:
http://marc.info/?l=linux-kernel&m=135263661110528&w=2
This failed because it could not handle deferred probes.
This patch alone does not solve the entire dilemma faced:
whether code should be distributed into the drivers or
if it should be centralized to e.g. a PM domain. But it
solves the immediate issue of the addition of boilerplate
to a lot of drivers that just want to grab the default
state. As mentioned, they can later explicitly retrieve
the handle and set different states, and this could as
well be done by e.g. PM domains as it is only related
to a certain struct device * pointer.
ChangeLog v4->v5 (Stephen):
- Simplified the devicecore grab code.
- Deleted a piece of documentation recommending that pins
be mapped to a device rather than hogged.
ChangeLog v3->v4 (Linus):
- Drop overzealous NULL checks.
- Move kref initialization to pinctrl_create().
- Seeking Tested-by from Stephen Warren so we do not disturb
the Tegra platform.
- Seeking ACK on this from Greg (and others who like it) so I
can merge it through the pinctrl subsystem.
ChangeLog v2->v3 (Linus):
- Abstain from using IS_ERR_OR_NULL() in the driver core,
Russell recently sent a patch to remove it. Handle the
NULL case explicitly even though it's a bogus case.
- Make sure we handle probe deferral correctly in the device
core file. devm_kfree() the container on error so we don't
waste memory for devices without pinctrl handles.
- Introduce reference counting into the pinctrl core using
<linux/kref.h> so that we don't release pinctrl handles
that have been obtained for two or more places.
ChangeLog v1->v2 (Linus):
- Only store a pointer in the device struct, and only allocate
this if it's really used by the device.
Cc: Felipe Balbi <balbi@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Mitch Bradley <wmb@firmworks.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Rickard Andersson <rickard.andersson@stericsson.com>
Cc: Russell King <linux@arm.linux.org.uk>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[swarren: fixed and simplified error-handling in pinctrl_bind_pins(), to
correctly handle deferred probe. Removed admonition from docs not to use
pinctrl hogs for devices]
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2013-01-22 17:56:14 +00:00
|
|
|
|
2017-01-20 21:04:02 +00:00
|
|
|
const struct dma_map_ops *dma_ops;
|
2005-04-16 22:20:36 +00:00
|
|
|
u64 *dma_mask; /* dma mask (if dma'able device) */
|
|
|
|
u64 coherent_dma_mask;/* Like dma_mask, but for
|
|
|
|
alloc_coherent mappings as
|
|
|
|
not all hardware supports
|
|
|
|
64 bit addresses for consistent
|
|
|
|
allocations such descriptors. */
|
2018-07-23 22:16:07 +00:00
|
|
|
u64 bus_dma_mask; /* upstream dma_mask constraint */
|
2014-04-24 15:30:01 +00:00
|
|
|
unsigned long dma_pfn_offset;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-02-05 06:27:55 +00:00
|
|
|
struct device_dma_parameters *dma_parms;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct list_head dma_pools; /* dma pools (if dma'ble) */
|
|
|
|
|
2019-02-03 19:12:02 +00:00
|
|
|
#ifdef CONFIG_DMA_DECLARE_COHERENT
|
2005-04-16 22:20:36 +00:00
|
|
|
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
|
|
|
|
override */
|
2018-12-25 13:03:32 +00:00
|
|
|
#endif
|
2013-07-29 12:31:45 +00:00
|
|
|
#ifdef CONFIG_DMA_CMA
|
2011-12-29 12:09:51 +00:00
|
|
|
struct cma *cma_area; /* contiguous memory area for dma
|
|
|
|
allocations */
|
|
|
|
#endif
|
2006-11-11 06:18:39 +00:00
|
|
|
/* arch specific additions */
|
|
|
|
struct dev_archdata archdata;
|
2011-01-21 16:24:48 +00:00
|
|
|
|
|
|
|
struct device_node *of_node; /* associated device tree node */
|
2015-03-16 22:49:03 +00:00
|
|
|
struct fwnode_handle *fwnode; /* firmware device node */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
device.h: reorganize struct device
struct device is big, around 760 bytes on x86_64. It's not a critical
structure, but it is embedded everywhere, so making it smaller is always
a good thing.
With a recent patch that moved a field from struct device to the private
structure, some benchmarks showed a very odd regression, despite this
structure having nothing to do with those benchmarks. That caused me to
look into the layout of the structure. Using 'pahole', it showed a
number of holes and ways that the structure could be reordered in order
to align some cachelines better, as well as reduce the size of the
overall structure.
Move 'struct kobj' to the start of the structure, to keep that access
in the first cacheline, and try to organize things a bit more compactly
where possible
By doing these few moves, the result removes at least 8 bytes from
'struct device' on a 64bit system. Given we know there are systems with
at least 30k devices in memory at once, every little byte counts, and
this change could be a savings of 240k of kernel memory for them. On
"normal" systems the overall memory savings would be much less.
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-02-26 14:32:29 +00:00
|
|
|
#ifdef CONFIG_NUMA
|
|
|
|
int numa_node; /* NUMA node this device is close to */
|
|
|
|
#endif
|
2008-10-16 21:51:35 +00:00
|
|
|
dev_t devt; /* dev_t, creates the sysfs "dev" */
|
2011-12-14 22:29:38 +00:00
|
|
|
u32 id; /* device instance */
|
2008-10-16 21:51:35 +00:00
|
|
|
|
devres: device resource management
Implement device resource management, in short, devres. A device
driver can allocate arbirary size of devres data which is associated
with a release function. On driver detach, release function is
invoked on the devres data, then, devres data is freed.
devreses are typed by associated release functions. Some devreses are
better represented by single instance of the type while others need
multiple instances sharing the same release function. Both usages are
supported.
devreses can be grouped using devres group such that a device driver
can easily release acquired resources halfway through initialization
or selectively release resources (e.g. resources for port 1 out of 4
ports).
This patch adds devres core including documentation and the following
managed interfaces.
* alloc/free : devm_kzalloc(), devm_kzfree()
* IO region : devm_request_region(), devm_release_region()
* IRQ : devm_request_irq(), devm_free_irq()
* DMA : dmam_alloc_coherent(), dmam_free_coherent(),
dmam_declare_coherent_memory(), dmam_pool_create(),
dmam_pool_destroy()
* PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed()
* iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(),
devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(),
pcim_iomap(), pcim_iounmap()
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
2007-01-20 07:00:26 +00:00
|
|
|
spinlock_t devres_lock;
|
|
|
|
struct list_head devres_head;
|
|
|
|
|
2006-10-07 19:54:55 +00:00
|
|
|
struct class *class;
|
2009-06-24 17:06:31 +00:00
|
|
|
const struct attribute_group **groups; /* optional groups */
|
2006-06-14 19:14:34 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
void (*release)(struct device *dev);
|
2012-05-30 20:18:41 +00:00
|
|
|
struct iommu_group *iommu_group;
|
2016-09-13 09:54:14 +00:00
|
|
|
struct iommu_fwspec *iommu_fwspec;
|
2019-06-03 14:57:46 +00:00
|
|
|
struct iommu_param *iommu_param;
|
Driver core: Add offline/online device operations
In some cases, graceful hot-removal of devices is not possible,
although in principle the devices in question support hotplug.
For example, that may happen for the last CPU in the system or
for memory modules holding kernel memory.
In those cases it is nice to be able to check if the given device
can be gracefully hot-removed before triggering a removal procedure
that cannot be aborted or reversed. Unfortunately, however, the
kernel currently doesn't provide any support for that.
To address that deficiency, introduce support for offline and
online operations that can be performed on devices, respectively,
before a hot-removal and in case when it is necessary (or convenient)
to put a device back online after a successful offline (that has not
been followed by removal). The idea is that the offline will fail
whenever the given device cannot be gracefully removed from the
system and it will not be allowed to use the device after a
successful offline (until a subsequent online) in analogy with the
existing CPU offline/online mechanism.
For now, the offline and online operations are introduced at the
bus type level, as that should be sufficient for the most urgent use
cases (CPUs and memory modules). In the future, however, the
approach may be extended to cover some more complicated device
offline/online scenarios involving device drivers etc.
The lock_device_hotplug() and unlock_device_hotplug() functions are
introduced because subsequent patches need to put larger pieces of
code under device_hotplug_lock to prevent race conditions between
device offline and removal from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-02 20:15:29 +00:00
|
|
|
|
|
|
|
bool offline_disabled:1;
|
|
|
|
bool offline:1;
|
driver core: add helper to reuse a device-tree node
Add a helper function to be used when reusing the device-tree node of
another device.
It is fairly common for drivers to reuse the device-tree node of a
parent (or other ancestor) device when creating class or bus devices
(e.g. gpio chips, i2c adapters, iio chips, spi masters, serdev, phys,
usb root hubs). But reusing a device-tree node may cause problems if the
new device is later probed as for example driver core would currently
attempt to reinitialise an already active associated pinmux
configuration.
Other potential issues include the platform-bus code unconditionally
dropping the device-tree node reference in its device destructor,
reinitialisation of other bus-managed resources such as clocks, and the
recently added DMA-setup in driver core.
Note that for most examples above this is currently not an issue as the
devices are never probed, but this is a problem for the USB bus which
has recently gained device-tree support. This was discovered and
worked-around in a rather ad-hoc fashion by commit dc5878abf49c ("usb:
core: move root hub's device node assignment after it is added to bus")
by not setting the of_node pointer until after the root-hub device has
been registered.
Instead we can allow devices to reuse a device-tree node by setting a
flag in their struct device that can be used by core, bus and driver
code to avoid resources from being over-allocated.
Note that the helper also grabs an extra reference to the device node,
which specifically balances the unconditional put in the platform-device
destructor.
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-06 15:59:00 +00:00
|
|
|
bool of_node_reused:1;
|
2018-08-19 12:53:20 +00:00
|
|
|
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
|
|
|
|
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
|
|
|
|
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
|
|
|
|
bool dma_coherent:1;
|
|
|
|
#endif
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2012-07-03 16:49:35 +00:00
|
|
|
static inline struct device *kobj_to_dev(struct kobject *kobj)
|
|
|
|
{
|
|
|
|
return container_of(kobj, struct device, kobj);
|
|
|
|
}
|
|
|
|
|
2018-11-30 11:51:52 +00:00
|
|
|
/**
|
|
|
|
* device_iommu_mapped - Returns true when the device DMA is translated
|
|
|
|
* by an IOMMU
|
|
|
|
* @dev: Device to perform the check on
|
|
|
|
*/
|
|
|
|
static inline bool device_iommu_mapped(struct device *dev)
|
|
|
|
{
|
|
|
|
return (dev->iommu_group != NULL);
|
|
|
|
}
|
|
|
|
|
2008-03-19 21:39:13 +00:00
|
|
|
/* Get the wakeup routines, which depend on struct device */
|
|
|
|
#include <linux/pm_wakeup.h>
|
|
|
|
|
2008-07-30 19:29:21 +00:00
|
|
|
static inline const char *dev_name(const struct device *dev)
|
2008-05-02 04:02:41 +00:00
|
|
|
{
|
2010-03-09 06:57:53 +00:00
|
|
|
/* Use the init name until the kobject becomes available */
|
|
|
|
if (dev->init_name)
|
|
|
|
return dev->init_name;
|
|
|
|
|
2009-01-25 14:17:37 +00:00
|
|
|
return kobject_name(&dev->kobj);
|
2008-05-02 04:02:41 +00:00
|
|
|
}
|
|
|
|
|
2011-11-01 00:11:33 +00:00
|
|
|
extern __printf(2, 3)
|
|
|
|
int dev_set_name(struct device *dev, const char *name, ...);
|
2008-05-30 00:16:40 +00:00
|
|
|
|
2006-12-07 04:32:33 +00:00
|
|
|
#ifdef CONFIG_NUMA
|
|
|
|
static inline int dev_to_node(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->numa_node;
|
|
|
|
}
|
|
|
|
static inline void set_dev_node(struct device *dev, int node)
|
|
|
|
{
|
|
|
|
dev->numa_node = node;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline int dev_to_node(struct device *dev)
|
|
|
|
{
|
2019-03-05 23:42:58 +00:00
|
|
|
return NUMA_NO_NODE;
|
2006-12-07 04:32:33 +00:00
|
|
|
}
|
|
|
|
static inline void set_dev_node(struct device *dev, int node)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-07-28 13:46:10 +00:00
|
|
|
static inline struct irq_domain *dev_get_msi_domain(const struct device *dev)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
|
|
|
return dev->msi_domain;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dev_set_msi_domain(struct device *dev, struct irq_domain *d)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
|
|
|
dev->msi_domain = d;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-04-14 10:58:53 +00:00
|
|
|
static inline void *dev_get_drvdata(const struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->driver_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dev_set_drvdata(struct device *dev, void *data)
|
|
|
|
{
|
|
|
|
dev->driver_data = data;
|
|
|
|
}
|
|
|
|
|
2011-08-25 13:33:50 +00:00
|
|
|
static inline struct pm_subsys_data *dev_to_psd(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev ? dev->power.subsys_data : NULL;
|
|
|
|
}
|
|
|
|
|
2009-03-01 13:10:49 +00:00
|
|
|
static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->kobj.uevent_suppress;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dev_set_uevent_suppress(struct device *dev, int val)
|
|
|
|
{
|
|
|
|
dev->kobj.uevent_suppress = val;
|
|
|
|
}
|
|
|
|
|
2005-09-22 07:47:24 +00:00
|
|
|
static inline int device_is_registered(struct device *dev)
|
|
|
|
{
|
2008-03-13 21:07:03 +00:00
|
|
|
return dev->kobj.state_in_sysfs;
|
2005-09-22 07:47:24 +00:00
|
|
|
}
|
|
|
|
|
PM: Asynchronous suspend and resume of devices
Theoretically, the total time of system sleep transitions (suspend
to RAM, hibernation) can be reduced by running suspend and resume
callbacks of device drivers in parallel with each other. However,
there are dependencies between devices such that we're not allowed
to suspend the parent of a device before suspending the device
itself. Analogously, we're not allowed to resume a device before
resuming its parent.
The most straightforward way to take these dependencies into accout
is to start the async threads used for suspending and resuming
devices at the core level, so that async_schedule() is called for
each suspend and resume callback supposed to be executed
asynchronously.
For this purpose, introduce a new device flag, power.async_suspend,
used to mark the devices whose suspend and resume callbacks are to be
executed asynchronously (ie. in parallel with the main suspend/resume
thread and possibly in parallel with each other) and helper function
device_enable_async_suspend() allowing one to set power.async_suspend
for given device (power.async_suspend is unset by default for all
devices). For each device with the power.async_suspend flag set the
PM core will use async_schedule() to execute its suspend and resume
callbacks.
The async threads started for different devices as a result of
calling async_schedule() are synchronized with each other and with
the main suspend/resume thread with the help of completions, in the
following way:
(1) There is a completion, power.completion, for each device object.
(2) Each device's completion is reset before calling async_schedule()
for the device or, in the case of devices with the
power.async_suspend flags unset, before executing the device's
suspend and resume callbacks.
(3) During suspend, right before running the bus type, device type
and device class suspend callbacks for the device, the PM core
waits for the completions of all the device's children to be
completed.
(4) During resume, right before running the bus type, device type and
device class resume callbacks for the device, the PM core waits
for the completion of the device's parent to be completed.
(5) The PM core completes power.completion for each device right
after the bus type, device type and device class suspend (or
resume) callbacks executed for the device have returned.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2010-01-23 21:23:32 +00:00
|
|
|
static inline void device_enable_async_suspend(struct device *dev)
|
|
|
|
{
|
2011-06-18 18:22:23 +00:00
|
|
|
if (!dev->power.is_prepared)
|
PM: Asynchronous suspend and resume of devices
Theoretically, the total time of system sleep transitions (suspend
to RAM, hibernation) can be reduced by running suspend and resume
callbacks of device drivers in parallel with each other. However,
there are dependencies between devices such that we're not allowed
to suspend the parent of a device before suspending the device
itself. Analogously, we're not allowed to resume a device before
resuming its parent.
The most straightforward way to take these dependencies into accout
is to start the async threads used for suspending and resuming
devices at the core level, so that async_schedule() is called for
each suspend and resume callback supposed to be executed
asynchronously.
For this purpose, introduce a new device flag, power.async_suspend,
used to mark the devices whose suspend and resume callbacks are to be
executed asynchronously (ie. in parallel with the main suspend/resume
thread and possibly in parallel with each other) and helper function
device_enable_async_suspend() allowing one to set power.async_suspend
for given device (power.async_suspend is unset by default for all
devices). For each device with the power.async_suspend flag set the
PM core will use async_schedule() to execute its suspend and resume
callbacks.
The async threads started for different devices as a result of
calling async_schedule() are synchronized with each other and with
the main suspend/resume thread with the help of completions, in the
following way:
(1) There is a completion, power.completion, for each device object.
(2) Each device's completion is reset before calling async_schedule()
for the device or, in the case of devices with the
power.async_suspend flags unset, before executing the device's
suspend and resume callbacks.
(3) During suspend, right before running the bus type, device type
and device class suspend callbacks for the device, the PM core
waits for the completions of all the device's children to be
completed.
(4) During resume, right before running the bus type, device type and
device class resume callbacks for the device, the PM core waits
for the completion of the device's parent to be completed.
(5) The PM core completes power.completion for each device right
after the bus type, device type and device class suspend (or
resume) callbacks executed for the device have returned.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2010-01-23 21:23:32 +00:00
|
|
|
dev->power.async_suspend = true;
|
|
|
|
}
|
|
|
|
|
2010-01-23 21:25:23 +00:00
|
|
|
static inline void device_disable_async_suspend(struct device *dev)
|
|
|
|
{
|
2011-06-18 18:22:23 +00:00
|
|
|
if (!dev->power.is_prepared)
|
2010-01-23 21:25:23 +00:00
|
|
|
dev->power.async_suspend = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool device_async_suspend_enabled(struct device *dev)
|
|
|
|
{
|
|
|
|
return !!dev->power.async_suspend;
|
|
|
|
}
|
|
|
|
|
2019-02-14 18:29:10 +00:00
|
|
|
static inline bool device_pm_not_required(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->power.no_pm;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void device_set_pm_not_required(struct device *dev)
|
|
|
|
{
|
|
|
|
dev->power.no_pm = true;
|
|
|
|
}
|
|
|
|
|
2012-08-13 12:00:25 +00:00
|
|
|
static inline void dev_pm_syscore_device(struct device *dev, bool val)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
dev->power.syscore = val;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags
The motivation for this change is to provide a way to work around
a problem with the direct-complete mechanism used for avoiding
system suspend/resume handling for devices in runtime suspend.
The problem is that some middle layer code (the PCI bus type and
the ACPI PM domain in particular) returns positive values from its
system suspend ->prepare callbacks regardless of whether the driver's
->prepare returns a positive value or 0, which effectively prevents
drivers from being able to control the direct-complete feature.
Some drivers need that control, however, and the PCI bus type has
grown its own flag to deal with this issue, but since it is not
limited to PCI, it is better to address it by adding driver flags at
the core level.
To that end, add a driver_flags field to struct dev_pm_info for flags
that can be set by device drivers at the probe time to inform the PM
core and/or bus types, PM domains and so on on the capabilities and/or
preferences of device drivers. Also add two static inline helpers
for setting that field and testing it against a given set of flags
and make the driver core clear it automatically on driver remove
and probe failures.
Define and document two PM driver flags related to the direct-
complete feature: NEVER_SKIP and SMART_PREPARE that can be used,
respectively, to indicate to the PM core that the direct-complete
mechanism should never be used for the device and to inform the
middle layer code (bus types, PM domains etc) that it can only
request the PM core to use the direct-complete mechanism for
the device (by returning a positive value from its ->prepare
callback) if it also has been requested by the driver.
While at it, make the core check pm_runtime_suspended() when
setting power.direct_complete so that it doesn't need to be
checked by ->prepare callbacks.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-10-25 12:12:29 +00:00
|
|
|
static inline void dev_pm_set_driver_flags(struct device *dev, u32 flags)
|
|
|
|
{
|
|
|
|
dev->power.driver_flags = flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool dev_pm_test_driver_flags(struct device *dev, u32 flags)
|
|
|
|
{
|
|
|
|
return !!(dev->power.driver_flags & flags);
|
|
|
|
}
|
|
|
|
|
2010-02-17 18:57:05 +00:00
|
|
|
static inline void device_lock(struct device *dev)
|
|
|
|
{
|
2010-01-29 20:39:02 +00:00
|
|
|
mutex_lock(&dev->mutex);
|
2010-02-17 18:57:05 +00:00
|
|
|
}
|
|
|
|
|
2016-01-21 14:18:47 +00:00
|
|
|
static inline int device_lock_interruptible(struct device *dev)
|
|
|
|
{
|
|
|
|
return mutex_lock_interruptible(&dev->mutex);
|
|
|
|
}
|
|
|
|
|
2010-02-17 18:57:05 +00:00
|
|
|
static inline int device_trylock(struct device *dev)
|
|
|
|
{
|
2010-01-29 20:39:02 +00:00
|
|
|
return mutex_trylock(&dev->mutex);
|
2010-02-17 18:57:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void device_unlock(struct device *dev)
|
|
|
|
{
|
2010-01-29 20:39:02 +00:00
|
|
|
mutex_unlock(&dev->mutex);
|
2010-02-17 18:57:05 +00:00
|
|
|
}
|
|
|
|
|
2014-12-03 21:40:27 +00:00
|
|
|
static inline void device_lock_assert(struct device *dev)
|
|
|
|
{
|
|
|
|
lockdep_assert_held(&dev->mutex);
|
|
|
|
}
|
|
|
|
|
2015-02-18 01:03:41 +00:00
|
|
|
static inline struct device_node *dev_of_node(struct device *dev)
|
|
|
|
{
|
2019-04-12 18:31:45 +00:00
|
|
|
if (!IS_ENABLED(CONFIG_OF) || !dev)
|
2015-02-18 01:03:41 +00:00
|
|
|
return NULL;
|
|
|
|
return dev->of_node;
|
|
|
|
}
|
|
|
|
|
2006-12-19 21:01:28 +00:00
|
|
|
void driver_init(void);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* High level routines for use by the bus drivers
|
|
|
|
*/
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int __must_check device_register(struct device *dev);
|
|
|
|
extern void device_unregister(struct device *dev);
|
|
|
|
extern void device_initialize(struct device *dev);
|
|
|
|
extern int __must_check device_add(struct device *dev);
|
|
|
|
extern void device_del(struct device *dev);
|
|
|
|
extern int device_for_each_child(struct device *dev, void *data,
|
|
|
|
int (*fn)(struct device *dev, void *data));
|
2015-07-27 15:04:00 +00:00
|
|
|
extern int device_for_each_child_reverse(struct device *dev, void *data,
|
|
|
|
int (*fn)(struct device *dev, void *data));
|
2008-01-25 05:04:46 +00:00
|
|
|
extern struct device *device_find_child(struct device *dev, void *data,
|
|
|
|
int (*match)(struct device *dev, void *data));
|
2019-05-31 14:15:37 +00:00
|
|
|
extern struct device *device_find_child_by_name(struct device *parent,
|
|
|
|
const char *name);
|
2010-08-05 15:38:18 +00:00
|
|
|
extern int device_rename(struct device *dev, const char *new_name);
|
2009-03-04 11:44:00 +00:00
|
|
|
extern int device_move(struct device *dev, struct device *new_parent,
|
|
|
|
enum dpm_order dpm_order);
|
2009-09-18 21:01:12 +00:00
|
|
|
extern const char *device_get_devnode(struct device *dev,
|
2013-04-11 18:43:29 +00:00
|
|
|
umode_t *mode, kuid_t *uid, kgid_t *gid,
|
2013-04-06 16:56:00 +00:00
|
|
|
const char **tmp);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
Driver core: Add offline/online device operations
In some cases, graceful hot-removal of devices is not possible,
although in principle the devices in question support hotplug.
For example, that may happen for the last CPU in the system or
for memory modules holding kernel memory.
In those cases it is nice to be able to check if the given device
can be gracefully hot-removed before triggering a removal procedure
that cannot be aborted or reversed. Unfortunately, however, the
kernel currently doesn't provide any support for that.
To address that deficiency, introduce support for offline and
online operations that can be performed on devices, respectively,
before a hot-removal and in case when it is necessary (or convenient)
to put a device back online after a successful offline (that has not
been followed by removal). The idea is that the offline will fail
whenever the given device cannot be gracefully removed from the
system and it will not be allowed to use the device after a
successful offline (until a subsequent online) in analogy with the
existing CPU offline/online mechanism.
For now, the offline and online operations are introduced at the
bus type level, as that should be sufficient for the most urgent use
cases (CPUs and memory modules). In the future, however, the
approach may be extended to cover some more complicated device
offline/online scenarios involving device drivers etc.
The lock_device_hotplug() and unlock_device_hotplug() functions are
introduced because subsequent patches need to put larger pieces of
code under device_hotplug_lock to prevent race conditions between
device offline and removal from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-02 20:15:29 +00:00
|
|
|
static inline bool device_supports_offline(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->bus && dev->bus->offline && dev->bus->online;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern void lock_device_hotplug(void);
|
|
|
|
extern void unlock_device_hotplug(void);
|
driver core / ACPI: Avoid device hot remove locking issues
device_hotplug_lock is held around the acpi_bus_trim() call in
acpi_scan_hot_remove() which generally removes devices (it removes
ACPI device objects at least, but it may also remove "physical"
device objects through .detach() callbacks of ACPI scan handlers).
Thus, potentially, device sysfs attributes are removed under that
lock and to remove those attributes it is necessary to hold the
s_active references of their directory entries for writing.
On the other hand, the execution of a .show() or .store() callback
from a sysfs attribute is carried out with that attribute's s_active
reference held for reading. Consequently, if any device sysfs
attribute that may be removed from within acpi_scan_hot_remove()
through acpi_bus_trim() has a .store() or .show() callback which
acquires device_hotplug_lock, the execution of that callback may
deadlock with the removal of the attribute. [Unfortunately, the
"online" device attribute of CPUs and memory blocks is one of them.]
To avoid such deadlocks, make all of the sysfs attribute callbacks
that need to lock device hotplug, for example store_online(), use
a special function, lock_device_hotplug_sysfs(), to lock device
hotplug and return the result of that function immediately if it is
not zero. This will cause the s_active reference of the directory
entry in question to be released and the syscall to be restarted
if device_hotplug_lock cannot be acquired.
[show_online() actually doesn't need to lock device hotplug, but
it is useful to serialize it with respect to device_offline() and
device_online() for the same device (in case user space attempts to
run them concurrently) which can be done with the help of
device_lock().]
Reported-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Reported-and-tested-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
2013-08-28 19:41:01 +00:00
|
|
|
extern int lock_device_hotplug_sysfs(void);
|
Driver core: Add offline/online device operations
In some cases, graceful hot-removal of devices is not possible,
although in principle the devices in question support hotplug.
For example, that may happen for the last CPU in the system or
for memory modules holding kernel memory.
In those cases it is nice to be able to check if the given device
can be gracefully hot-removed before triggering a removal procedure
that cannot be aborted or reversed. Unfortunately, however, the
kernel currently doesn't provide any support for that.
To address that deficiency, introduce support for offline and
online operations that can be performed on devices, respectively,
before a hot-removal and in case when it is necessary (or convenient)
to put a device back online after a successful offline (that has not
been followed by removal). The idea is that the offline will fail
whenever the given device cannot be gracefully removed from the
system and it will not be allowed to use the device after a
successful offline (until a subsequent online) in analogy with the
existing CPU offline/online mechanism.
For now, the offline and online operations are introduced at the
bus type level, as that should be sufficient for the most urgent use
cases (CPUs and memory modules). In the future, however, the
approach may be extended to cover some more complicated device
offline/online scenarios involving device drivers etc.
The lock_device_hotplug() and unlock_device_hotplug() functions are
introduced because subsequent patches need to put larger pieces of
code under device_hotplug_lock to prevent race conditions between
device offline and removal from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
2013-05-02 20:15:29 +00:00
|
|
|
extern int device_offline(struct device *dev);
|
|
|
|
extern int device_online(struct device *dev);
|
2015-04-03 21:23:37 +00:00
|
|
|
extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
|
|
|
|
extern void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
|
driver core: add helper to reuse a device-tree node
Add a helper function to be used when reusing the device-tree node of
another device.
It is fairly common for drivers to reuse the device-tree node of a
parent (or other ancestor) device when creating class or bus devices
(e.g. gpio chips, i2c adapters, iio chips, spi masters, serdev, phys,
usb root hubs). But reusing a device-tree node may cause problems if the
new device is later probed as for example driver core would currently
attempt to reinitialise an already active associated pinmux
configuration.
Other potential issues include the platform-bus code unconditionally
dropping the device-tree node reference in its device destructor,
reinitialisation of other bus-managed resources such as clocks, and the
recently added DMA-setup in driver core.
Note that for most examples above this is currently not an issue as the
devices are never probed, but this is a problem for the USB bus which
has recently gained device-tree support. This was discovered and
worked-around in a rather ad-hoc fashion by commit dc5878abf49c ("usb:
core: move root hub's device node assignment after it is added to bus")
by not setting the of_node pointer until after the root-hub device has
been registered.
Instead we can allow devices to reuse a device-tree node by setting a
flag in their struct device that can be used by core, bus and driver
code to avoid resources from being over-allocated.
Note that the helper also grabs an extra reference to the device node,
which specifically balances the unconditional put in the platform-device
destructor.
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-06 15:59:00 +00:00
|
|
|
void device_set_of_node_from_dev(struct device *dev, const struct device *dev2);
|
2015-04-03 21:23:37 +00:00
|
|
|
|
2017-01-18 13:04:39 +00:00
|
|
|
static inline int dev_num_vf(struct device *dev)
|
|
|
|
{
|
|
|
|
if (dev->bus && dev->bus->num_vf)
|
|
|
|
return dev->bus->num_vf(dev);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-15 12:58:26 +00:00
|
|
|
/*
|
|
|
|
* Root device objects for grouping under /sys/devices
|
|
|
|
*/
|
|
|
|
extern struct device *__root_device_register(const char *name,
|
|
|
|
struct module *owner);
|
2011-05-27 13:02:11 +00:00
|
|
|
|
2014-01-10 13:57:31 +00:00
|
|
|
/* This is a macro to avoid include problems with THIS_MODULE */
|
2011-05-27 13:02:11 +00:00
|
|
|
#define root_device_register(name) \
|
|
|
|
__root_device_register(name, THIS_MODULE)
|
|
|
|
|
2008-12-15 12:58:26 +00:00
|
|
|
extern void root_device_unregister(struct device *root);
|
|
|
|
|
2009-07-17 14:06:08 +00:00
|
|
|
static inline void *dev_get_platdata(const struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->platform_data;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* Manual binding of a device to driver. See drivers/base/bus.c
|
|
|
|
* for information on use.
|
|
|
|
*/
|
2006-08-15 05:43:20 +00:00
|
|
|
extern int __must_check device_bind_driver(struct device *dev);
|
2008-01-25 05:04:46 +00:00
|
|
|
extern void device_release_driver(struct device *dev);
|
|
|
|
extern int __must_check device_attach(struct device *dev);
|
2006-08-15 05:43:20 +00:00
|
|
|
extern int __must_check driver_attach(struct device_driver *drv);
|
2015-03-30 23:20:04 +00:00
|
|
|
extern void device_initial_probe(struct device *dev);
|
2006-08-15 05:43:20 +00:00
|
|
|
extern int __must_check device_reprobe(struct device *dev);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2016-01-07 15:46:12 +00:00
|
|
|
extern bool device_is_bound(struct device *dev);
|
|
|
|
|
2006-06-14 19:14:34 +00:00
|
|
|
/*
|
|
|
|
* Easy functions for dynamically creating devices on the fly
|
|
|
|
*/
|
2015-07-17 23:23:42 +00:00
|
|
|
extern __printf(5, 0)
|
|
|
|
struct device *device_create_vargs(struct class *cls, struct device *parent,
|
|
|
|
dev_t devt, void *drvdata,
|
|
|
|
const char *fmt, va_list vargs);
|
2011-11-01 00:11:33 +00:00
|
|
|
extern __printf(5, 6)
|
|
|
|
struct device *device_create(struct class *cls, struct device *parent,
|
|
|
|
dev_t devt, void *drvdata,
|
|
|
|
const char *fmt, ...);
|
2013-07-14 23:05:57 +00:00
|
|
|
extern __printf(6, 7)
|
|
|
|
struct device *device_create_with_groups(struct class *cls,
|
|
|
|
struct device *parent, dev_t devt, void *drvdata,
|
|
|
|
const struct attribute_group **groups,
|
|
|
|
const char *fmt, ...);
|
2006-06-14 19:14:34 +00:00
|
|
|
extern void device_destroy(struct class *cls, dev_t devt);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2017-07-20 00:24:31 +00:00
|
|
|
extern int __must_check device_add_groups(struct device *dev,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
extern void device_remove_groups(struct device *dev,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
|
2017-07-20 00:24:32 +00:00
|
|
|
static inline int __must_check device_add_group(struct device *dev,
|
|
|
|
const struct attribute_group *grp)
|
|
|
|
{
|
|
|
|
const struct attribute_group *groups[] = { grp, NULL };
|
|
|
|
|
|
|
|
return device_add_groups(dev, groups);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void device_remove_group(struct device *dev,
|
|
|
|
const struct attribute_group *grp)
|
|
|
|
{
|
|
|
|
const struct attribute_group *groups[] = { grp, NULL };
|
|
|
|
|
|
|
|
return device_remove_groups(dev, groups);
|
|
|
|
}
|
|
|
|
|
2017-07-20 00:24:33 +00:00
|
|
|
extern int __must_check devm_device_add_groups(struct device *dev,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
extern void devm_device_remove_groups(struct device *dev,
|
|
|
|
const struct attribute_group **groups);
|
|
|
|
extern int __must_check devm_device_add_group(struct device *dev,
|
|
|
|
const struct attribute_group *grp);
|
|
|
|
extern void devm_device_remove_group(struct device *dev,
|
|
|
|
const struct attribute_group *grp);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* Platform "fixup" functions - allow the platform to have their say
|
|
|
|
* about devices and actions that the general device layer doesn't
|
|
|
|
* know about.
|
|
|
|
*/
|
|
|
|
/* Notify platform of device discovery */
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int (*platform_notify)(struct device *dev);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-25 05:04:46 +00:00
|
|
|
extern int (*platform_notify_remove)(struct device *dev);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
|
2011-05-04 23:55:36 +00:00
|
|
|
/*
|
2005-04-16 22:20:36 +00:00
|
|
|
* get_device - atomically increment the reference count for the device.
|
|
|
|
*
|
|
|
|
*/
|
2008-01-25 05:04:46 +00:00
|
|
|
extern struct device *get_device(struct device *dev);
|
|
|
|
extern void put_device(struct device *dev);
|
2019-07-18 01:07:53 +00:00
|
|
|
extern bool kill_device(struct device *dev);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
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 13:23:42 +00:00
|
|
|
#ifdef CONFIG_DEVTMPFS
|
|
|
|
extern int devtmpfs_create_node(struct device *dev);
|
|
|
|
extern int devtmpfs_delete_node(struct device *dev);
|
2009-10-28 18:51:17 +00:00
|
|
|
extern int devtmpfs_mount(const char *mntdir);
|
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 13:23:42 +00:00
|
|
|
#else
|
|
|
|
static inline int devtmpfs_create_node(struct device *dev) { return 0; }
|
|
|
|
static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
|
|
|
|
static inline int devtmpfs_mount(const char *mountpoint) { return 0; }
|
|
|
|
#endif
|
|
|
|
|
2006-03-21 23:58:53 +00:00
|
|
|
/* drivers/base/power/shutdown.c */
|
2005-04-16 22:20:36 +00:00
|
|
|
extern void device_shutdown(void);
|
|
|
|
|
|
|
|
/* debugging and troubleshooting/diagnostic helpers. */
|
2008-07-30 19:29:21 +00:00
|
|
|
extern const char *dev_driver_string(const struct device *dev);
|
2010-06-27 01:02:34 +00:00
|
|
|
|
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 16:32:16 +00:00
|
|
|
/* Device links interface. */
|
|
|
|
struct device_link *device_link_add(struct device *consumer,
|
|
|
|
struct device *supplier, u32 flags);
|
|
|
|
void device_link_del(struct device_link *link);
|
2018-07-05 14:25:56 +00:00
|
|
|
void device_link_remove(void *consumer, struct device *supplier);
|
2010-06-27 01:02:34 +00:00
|
|
|
|
2018-05-09 15:15:46 +00:00
|
|
|
#ifndef dev_fmt
|
|
|
|
#define dev_fmt(fmt) fmt
|
|
|
|
#endif
|
|
|
|
|
2010-06-27 01:02:34 +00:00
|
|
|
#ifdef CONFIG_PRINTK
|
|
|
|
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(3, 0) __cold
|
2012-09-26 01:19:57 +00:00
|
|
|
int dev_vprintk_emit(int level, const struct device *dev,
|
|
|
|
const char *fmt, va_list args);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(3, 4) __cold
|
2012-09-13 03:13:37 +00:00
|
|
|
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
|
2012-09-13 03:11:29 +00:00
|
|
|
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(3, 4) __cold
|
2014-12-25 23:07:04 +00:00
|
|
|
void dev_printk(const char *level, const struct device *dev,
|
|
|
|
const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_emerg(const struct device *dev, const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_alert(const struct device *dev, const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_crit(const struct device *dev, const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_err(const struct device *dev, const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_warn(const struct device *dev, const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_notice(const struct device *dev, const char *fmt, ...);
|
2019-02-03 03:50:17 +00:00
|
|
|
__printf(2, 3) __cold
|
2014-12-25 23:07:04 +00:00
|
|
|
void _dev_info(const struct device *dev, const char *fmt, ...);
|
2010-06-27 01:02:34 +00:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2012-09-26 01:19:57 +00:00
|
|
|
static inline __printf(3, 0)
|
|
|
|
int dev_vprintk_emit(int level, const struct device *dev,
|
|
|
|
const char *fmt, va_list args)
|
2012-09-13 03:13:37 +00:00
|
|
|
{ return 0; }
|
|
|
|
static inline __printf(3, 4)
|
|
|
|
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
|
|
|
|
{ return 0; }
|
|
|
|
|
2014-12-25 23:07:04 +00:00
|
|
|
static inline void __dev_printk(const char *level, const struct device *dev,
|
|
|
|
struct va_format *vaf)
|
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(3, 4)
|
2014-12-25 23:07:04 +00:00
|
|
|
void dev_printk(const char *level, const struct device *dev,
|
2018-05-09 15:15:46 +00:00
|
|
|
const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
|
|
|
|
static inline __printf(2, 3)
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_emerg(const struct device *dev, const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(2, 3)
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_crit(const struct device *dev, const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(2, 3)
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_alert(const struct device *dev, const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(2, 3)
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_err(const struct device *dev, const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(2, 3)
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_warn(const struct device *dev, const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(2, 3)
|
2018-05-09 15:15:46 +00:00
|
|
|
void _dev_notice(const struct device *dev, const char *fmt, ...)
|
2014-12-25 23:07:04 +00:00
|
|
|
{}
|
2011-11-01 00:11:33 +00:00
|
|
|
static inline __printf(2, 3)
|
2014-12-25 23:07:04 +00:00
|
|
|
void _dev_info(const struct device *dev, const char *fmt, ...)
|
|
|
|
{}
|
2010-06-27 01:02:34 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2012-09-04 04:40:40 +00:00
|
|
|
/*
|
2018-05-09 15:15:46 +00:00
|
|
|
* #defines for all the dev_<level> macros to prefix with whatever
|
|
|
|
* possible use of #define dev_fmt(fmt) ...
|
2012-09-04 04:40:40 +00:00
|
|
|
*/
|
|
|
|
|
2018-05-09 15:15:46 +00:00
|
|
|
#define dev_emerg(dev, fmt, ...) \
|
|
|
|
_dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
|
|
|
#define dev_crit(dev, fmt, ...) \
|
|
|
|
_dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
|
|
|
#define dev_alert(dev, fmt, ...) \
|
|
|
|
_dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
|
|
|
#define dev_err(dev, fmt, ...) \
|
|
|
|
_dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
|
|
|
#define dev_warn(dev, fmt, ...) \
|
|
|
|
_dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
|
|
|
#define dev_notice(dev, fmt, ...) \
|
|
|
|
_dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
|
|
|
#define dev_info(dev, fmt, ...) \
|
|
|
|
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
2012-09-04 04:40:40 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_DYNAMIC_DEBUG)
|
2018-05-09 15:15:46 +00:00
|
|
|
#define dev_dbg(dev, fmt, ...) \
|
|
|
|
dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
2012-09-04 04:40:40 +00:00
|
|
|
#elif defined(DEBUG)
|
2018-05-09 15:15:46 +00:00
|
|
|
#define dev_dbg(dev, fmt, ...) \
|
|
|
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__)
|
2012-09-04 04:40:40 +00:00
|
|
|
#else
|
2018-05-09 15:15:46 +00:00
|
|
|
#define dev_dbg(dev, fmt, ...) \
|
|
|
|
({ \
|
|
|
|
if (0) \
|
|
|
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
2012-09-04 04:40:40 +00:00
|
|
|
})
|
|
|
|
#endif
|
|
|
|
|
2014-11-18 02:18:22 +00:00
|
|
|
#ifdef CONFIG_PRINTK
|
|
|
|
#define dev_level_once(dev_level, dev, fmt, ...) \
|
|
|
|
do { \
|
|
|
|
static bool __print_once __read_mostly; \
|
|
|
|
\
|
|
|
|
if (!__print_once) { \
|
|
|
|
__print_once = true; \
|
|
|
|
dev_level(dev, fmt, ##__VA_ARGS__); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
#else
|
|
|
|
#define dev_level_once(dev_level, dev, fmt, ...) \
|
|
|
|
do { \
|
|
|
|
if (0) \
|
|
|
|
dev_level(dev, fmt, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define dev_emerg_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_alert_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_crit_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_err_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_warn_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_notice_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_info_once(dev, fmt, ...) \
|
|
|
|
dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_dbg_once(dev, fmt, ...) \
|
2015-01-03 17:51:33 +00:00
|
|
|
dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__)
|
2014-11-18 02:18:22 +00:00
|
|
|
|
2012-05-14 07:47:57 +00:00
|
|
|
#define dev_level_ratelimited(dev_level, dev, fmt, ...) \
|
|
|
|
do { \
|
|
|
|
static DEFINE_RATELIMIT_STATE(_rs, \
|
|
|
|
DEFAULT_RATELIMIT_INTERVAL, \
|
|
|
|
DEFAULT_RATELIMIT_BURST); \
|
|
|
|
if (__ratelimit(&_rs)) \
|
|
|
|
dev_level(dev, fmt, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define dev_emerg_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_alert_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_crit_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_err_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_warn_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_notice_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__)
|
|
|
|
#define dev_info_ratelimited(dev, fmt, ...) \
|
|
|
|
dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
|
2013-08-27 14:47:34 +00:00
|
|
|
#if defined(CONFIG_DYNAMIC_DEBUG)
|
|
|
|
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
|
2012-05-14 07:47:57 +00:00
|
|
|
#define dev_dbg_ratelimited(dev, fmt, ...) \
|
2012-09-04 04:40:40 +00:00
|
|
|
do { \
|
|
|
|
static DEFINE_RATELIMIT_STATE(_rs, \
|
|
|
|
DEFAULT_RATELIMIT_INTERVAL, \
|
|
|
|
DEFAULT_RATELIMIT_BURST); \
|
|
|
|
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
linux/device.h: use DYNAMIC_DEBUG_BRANCH in dev_dbg_ratelimited
Patch series "various dynamic_debug patches", v4.
This started as an experiment to see how hard it would be to change the
four pointers in struct _ddebug into relative offsets, a la
CONFIG_GENERIC_BUG_RELATIVE_POINTERS, thus saving 16 bytes per pr_debug
site (and thus exactly making up for the extra space used by the
introduction of jump labels in 9049fc74). I stumbled on a few things
that are probably worth fixing regardless of whether that goal is deemed
worthwhile.
Back at v3 (in November), I redid the implementation on top of the fancy
new asm-macros stuff. Luckily enough, v3 didn't get picked up, since
the asm-macros were backed out again. I still want to do the
relative-pointers thing eventually, but we're close to the merge window
opening, so here's just most of the "incidental" patches, some of which
also serve as preparation for the relative pointers.
This patch (of 4):
dev_dbg_ratelimited tests the dynamic debug descriptor the old-fashioned
way, and doesn't utilize the static key/jump label implementation when
CONFIG_JUMP_LABEL is set. Use the DYNAMIC_DEBUG_BRANCH which is defined
appropriately.
Link: http://lkml.kernel.org/r/20190212214150.4807-2-linux@rasmusvillemoes.dk
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Jason Baron <jbaron@akamai.com>
Cc: David Sterba <dsterba@suse.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: "Rafael J . Wysocki" <rafael.j.wysocki@intel.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-03-08 00:27:21 +00:00
|
|
|
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
|
2012-09-04 04:40:40 +00:00
|
|
|
__ratelimit(&_rs)) \
|
2018-05-09 15:15:46 +00:00
|
|
|
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
|
2013-08-27 14:47:34 +00:00
|
|
|
##__VA_ARGS__); \
|
|
|
|
} while (0)
|
|
|
|
#elif defined(DEBUG)
|
|
|
|
#define dev_dbg_ratelimited(dev, fmt, ...) \
|
|
|
|
do { \
|
|
|
|
static DEFINE_RATELIMIT_STATE(_rs, \
|
|
|
|
DEFAULT_RATELIMIT_INTERVAL, \
|
|
|
|
DEFAULT_RATELIMIT_BURST); \
|
|
|
|
if (__ratelimit(&_rs)) \
|
2018-05-09 15:15:46 +00:00
|
|
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
2010-06-27 01:02:34 +00:00
|
|
|
} while (0)
|
2005-04-16 22:20:36 +00:00
|
|
|
#else
|
2016-03-24 21:19:40 +00:00
|
|
|
#define dev_dbg_ratelimited(dev, fmt, ...) \
|
|
|
|
do { \
|
|
|
|
if (0) \
|
2018-05-09 15:15:46 +00:00
|
|
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
2016-03-24 21:19:40 +00:00
|
|
|
} while (0)
|
2005-04-16 22:20:36 +00:00
|
|
|
#endif
|
|
|
|
|
2007-07-13 05:08:22 +00:00
|
|
|
#ifdef VERBOSE_DEBUG
|
|
|
|
#define dev_vdbg dev_dbg
|
|
|
|
#else
|
2018-05-09 15:15:46 +00:00
|
|
|
#define dev_vdbg(dev, fmt, ...) \
|
|
|
|
({ \
|
|
|
|
if (0) \
|
|
|
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
2010-06-27 01:02:34 +00:00
|
|
|
})
|
2007-07-13 05:08:22 +00:00
|
|
|
#endif
|
|
|
|
|
2008-09-21 02:08:39 +00:00
|
|
|
/*
|
2013-10-24 21:42:33 +00:00
|
|
|
* dev_WARN*() acts like dev_printk(), but with the key difference of
|
|
|
|
* using WARN/WARN_ONCE to include file/line information and a backtrace.
|
2008-09-21 02:08:39 +00:00
|
|
|
*/
|
|
|
|
#define dev_WARN(dev, format, arg...) \
|
2013-10-24 21:42:33 +00:00
|
|
|
WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
|
2008-09-21 02:08:39 +00:00
|
|
|
|
2011-03-16 13:59:35 +00:00
|
|
|
#define dev_WARN_ONCE(dev, condition, format, arg...) \
|
2013-10-24 21:42:33 +00:00
|
|
|
WARN_ONCE(condition, "%s %s: " format, \
|
|
|
|
dev_driver_string(dev), dev_name(dev), ## arg)
|
2011-03-16 13:59:35 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Create alias, so I can be autoloaded. */
|
|
|
|
#define MODULE_ALIAS_CHARDEV(major,minor) \
|
|
|
|
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
|
|
|
|
#define MODULE_ALIAS_CHARDEV_MAJOR(major) \
|
|
|
|
MODULE_ALIAS("char-major-" __stringify(major) "-*")
|
2010-09-08 14:54:17 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_SYSFS_DEPRECATED
|
|
|
|
extern long sysfs_deprecated;
|
|
|
|
#else
|
|
|
|
#define sysfs_deprecated 0
|
|
|
|
#endif
|
|
|
|
|
2011-11-16 09:13:35 +00:00
|
|
|
/**
|
|
|
|
* module_driver() - Helper macro for drivers that don't do anything
|
|
|
|
* special in module init/exit. This eliminates a lot of boilerplate.
|
|
|
|
* Each module may only use this macro once, and calling it replaces
|
|
|
|
* module_init() and module_exit().
|
|
|
|
*
|
2012-01-21 19:02:51 +00:00
|
|
|
* @__driver: driver name
|
|
|
|
* @__register: register function for this driver type
|
|
|
|
* @__unregister: unregister function for this driver type
|
2012-02-25 10:25:58 +00:00
|
|
|
* @...: Additional arguments to be passed to __register and __unregister.
|
2012-01-21 19:02:51 +00:00
|
|
|
*
|
2011-11-16 09:13:35 +00:00
|
|
|
* Use this macro to construct bus specific macros for registering
|
|
|
|
* drivers, and do not use it on its own.
|
|
|
|
*/
|
2012-02-25 10:25:58 +00:00
|
|
|
#define module_driver(__driver, __register, __unregister, ...) \
|
2011-11-16 09:13:35 +00:00
|
|
|
static int __init __driver##_init(void) \
|
|
|
|
{ \
|
2012-02-25 10:25:58 +00:00
|
|
|
return __register(&(__driver) , ##__VA_ARGS__); \
|
2011-11-16 09:13:35 +00:00
|
|
|
} \
|
|
|
|
module_init(__driver##_init); \
|
|
|
|
static void __exit __driver##_exit(void) \
|
|
|
|
{ \
|
2012-02-25 10:25:58 +00:00
|
|
|
__unregister(&(__driver) , ##__VA_ARGS__); \
|
2011-11-16 09:13:35 +00:00
|
|
|
} \
|
|
|
|
module_exit(__driver##_exit);
|
|
|
|
|
2015-05-02 00:10:57 +00:00
|
|
|
/**
|
|
|
|
* builtin_driver() - Helper macro for drivers that don't do anything
|
|
|
|
* special in init and have no exit. This eliminates some boilerplate.
|
|
|
|
* Each driver may only use this macro once, and calling it replaces
|
|
|
|
* device_initcall (or in some cases, the legacy __initcall). This is
|
|
|
|
* meant to be a direct parallel of module_driver() above but without
|
|
|
|
* the __exit stuff that is not used for builtin cases.
|
|
|
|
*
|
|
|
|
* @__driver: driver name
|
|
|
|
* @__register: register function for this driver type
|
|
|
|
* @...: Additional arguments to be passed to __register
|
|
|
|
*
|
|
|
|
* Use this macro to construct bus specific macros for registering
|
|
|
|
* drivers, and do not use it on its own.
|
|
|
|
*/
|
|
|
|
#define builtin_driver(__driver, __register, ...) \
|
|
|
|
static int __init __driver##_init(void) \
|
|
|
|
{ \
|
|
|
|
return __register(&(__driver) , ##__VA_ARGS__); \
|
|
|
|
} \
|
|
|
|
device_initcall(__driver##_init);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
#endif /* _DEVICE_H_ */
|