Commit 975f9ce9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'driver-core-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core updates from Greg KH:
 "Here is a small set of changes for 5.6-rc1 for the driver core and
  some firmware subsystem changes.

  Included in here are:
   - device.h splitup like you asked for months ago
   - devtmpfs minor cleanups
   - firmware core minor changes
   - debugfs fix for lockdown mode
   - kernfs cleanup fix
   - cpu topology minor fix

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'driver-core-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (22 commits)
  firmware: Rename FW_OPT_NOFALLBACK to FW_OPT_NOFALLBACK_SYSFS
  devtmpfs: factor out common tail of devtmpfs_{create,delete}_node
  devtmpfs: initify a bit
  devtmpfs: simplify initialization of mount_dev
  devtmpfs: factor out setup part of devtmpfsd()
  devtmpfs: fix theoretical stale pointer deref in devtmpfsd()
  driver core: platform: fix u32 greater or equal to zero comparison
  cpu-topology: Don't error on more than CONFIG_NR_CPUS CPUs in device tree
  debugfs: Return -EPERM when locked down
  driver core: Print device when resources present in really_probe()
  driver core: Fix test_async_driver_probe if NUMA is disabled
  driver core: platform: Prevent resouce overflow from causing infinite loops
  fs/kernfs/dir.c: Clean code by removing always true condition
  component: do not dereference opaque pointer in debugfs
  drivers/component: remove modular code
  debugfs: Fix warnings when building documentation
  device.h: move 'struct driver' stuff out to device/driver.h
  device.h: move 'struct class' stuff out to device/class.h
  device.h: move 'struct bus' stuff out to device/bus.h
  device.h: move dev_printk()-like functions to dev_printk.h
  ...
parents 7ba31c3f 85db1cde
...@@ -248,6 +248,16 @@ core_initcall(free_raw_capacity); ...@@ -248,6 +248,16 @@ core_initcall(free_raw_capacity);
#endif #endif
#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV) #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
/*
* This function returns the logic cpu number of the node.
* There are basically three kinds of return values:
* (1) logic cpu number which is > 0.
* (2) -ENODEV when the device tree(DT) node is valid and found in the DT but
* there is no possible logical CPU in the kernel to match. This happens
* when CONFIG_NR_CPUS is configure to be smaller than the number of
* CPU nodes in DT. We need to just ignore this case.
* (3) -1 if the node does not exist in the device tree
*/
static int __init get_cpu_for_node(struct device_node *node) static int __init get_cpu_for_node(struct device_node *node)
{ {
struct device_node *cpu_node; struct device_node *cpu_node;
...@@ -261,7 +271,8 @@ static int __init get_cpu_for_node(struct device_node *node) ...@@ -261,7 +271,8 @@ static int __init get_cpu_for_node(struct device_node *node)
if (cpu >= 0) if (cpu >= 0)
topology_parse_cpu_capacity(cpu_node, cpu); topology_parse_cpu_capacity(cpu_node, cpu);
else else
pr_crit("Unable to find CPU node for %pOF\n", cpu_node); pr_info("CPU node for %pOF exist but the possible cpu range is :%*pbl\n",
cpu_node, cpumask_pr_args(cpu_possible_mask));
of_node_put(cpu_node); of_node_put(cpu_node);
return cpu; return cpu;
...@@ -286,9 +297,8 @@ static int __init parse_core(struct device_node *core, int package_id, ...@@ -286,9 +297,8 @@ static int __init parse_core(struct device_node *core, int package_id,
cpu_topology[cpu].package_id = package_id; cpu_topology[cpu].package_id = package_id;
cpu_topology[cpu].core_id = core_id; cpu_topology[cpu].core_id = core_id;
cpu_topology[cpu].thread_id = i; cpu_topology[cpu].thread_id = i;
} else { } else if (cpu != -ENODEV) {
pr_err("%pOF: Can't get CPU for thread\n", pr_err("%pOF: Can't get CPU for thread\n", t);
t);
of_node_put(t); of_node_put(t);
return -EINVAL; return -EINVAL;
} }
...@@ -307,7 +317,7 @@ static int __init parse_core(struct device_node *core, int package_id, ...@@ -307,7 +317,7 @@ static int __init parse_core(struct device_node *core, int package_id,
cpu_topology[cpu].package_id = package_id; cpu_topology[cpu].package_id = package_id;
cpu_topology[cpu].core_id = core_id; cpu_topology[cpu].core_id = core_id;
} else if (leaf) { } else if (leaf && cpu != -ENODEV) {
pr_err("%pOF: Can't get CPU for leaf core\n", core); pr_err("%pOF: Can't get CPU for leaf core\n", core);
return -EINVAL; return -EINVAL;
} }
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2008-2012 Novell Inc.
* Copyright (c) 2012-2019 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Copyright (c) 2012-2019 Linux Foundation
*
* Core driver model functions and structures that should not be
* shared outside of the drivers/base/ directory.
*
*/
#include <linux/notifier.h> #include <linux/notifier.h>
/** /**
...@@ -175,3 +186,11 @@ extern void device_links_unbind_consumers(struct device *dev); ...@@ -175,3 +186,11 @@ extern void device_links_unbind_consumers(struct device *dev);
/* device pm support */ /* device pm support */
void device_pm_move_to_tail(struct device *dev); void device_pm_move_to_tail(struct device *dev);
#ifdef CONFIG_DEVTMPFS
int devtmpfs_create_node(struct device *dev);
int devtmpfs_delete_node(struct device *dev);
#else
static inline int devtmpfs_create_node(struct device *dev) { return 0; }
static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
#endif
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <linux/async.h> #include <linux/async.h>
#include <linux/device/bus.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (c) 2003-2004 IBM Corp. * Copyright (c) 2003-2004 IBM Corp.
*/ */
#include <linux/device/class.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
...@@ -102,11 +101,11 @@ static int component_devices_show(struct seq_file *s, void *data) ...@@ -102,11 +101,11 @@ static int component_devices_show(struct seq_file *s, void *data)
seq_printf(s, "%-40s %20s\n", "device name", "status"); seq_printf(s, "%-40s %20s\n", "device name", "status");
seq_puts(s, "-------------------------------------------------------------\n"); seq_puts(s, "-------------------------------------------------------------\n");
for (i = 0; i < match->num; i++) { for (i = 0; i < match->num; i++) {
struct device *d = (struct device *)match->compare[i].data; struct component *component = match->compare[i].component;
seq_printf(s, "%-40s %20s\n", dev_name(d), seq_printf(s, "%-40s %20s\n",
match->compare[i].component ? component ? dev_name(component->dev) : "(unknown)",
"registered" : "not registered"); component ? (component->bound ? "bound" : "not bound") : "not registered");
} }
mutex_unlock(&component_mutex); mutex_unlock(&component_mutex);
...@@ -775,5 +774,3 @@ void component_del(struct device *dev, const struct component_ops *ops) ...@@ -775,5 +774,3 @@ void component_del(struct device *dev, const struct component_ops *ops)
kfree(component); kfree(component);
} }
EXPORT_SYMBOL_GPL(component_del); EXPORT_SYMBOL_GPL(component_del);
MODULE_LICENSE("GPL v2");
...@@ -516,7 +516,10 @@ static int really_probe(struct device *dev, struct device_driver *drv) ...@@ -516,7 +516,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
atomic_inc(&probe_count); atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n", pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
drv->bus->name, __func__, drv->name, dev_name(dev)); drv->bus->name, __func__, drv->name, dev_name(dev));
WARN_ON(!list_empty(&dev->devres_head)); if (!list_empty(&dev->devres_head)) {
dev_crit(dev, "Resources present before probing\n");
return -EBUSY;
}
re_probe: re_probe:
dev->driver = drv; dev->driver = drv;
......
...@@ -30,11 +30,7 @@ ...@@ -30,11 +30,7 @@
static struct task_struct *thread; static struct task_struct *thread;
#if defined CONFIG_DEVTMPFS_MOUNT static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT);
static int mount_dev = 1;
#else
static int mount_dev;
#endif
static DEFINE_SPINLOCK(req_lock); static DEFINE_SPINLOCK(req_lock);
...@@ -93,6 +89,23 @@ static inline int is_blockdev(struct device *dev) ...@@ -93,6 +89,23 @@ static inline int is_blockdev(struct device *dev)
static inline int is_blockdev(struct device *dev) { return 0; } static inline int is_blockdev(struct device *dev) { return 0; }
#endif #endif
static int devtmpfs_submit_req(struct req *req, const char *tmp)
{
init_completion(&req->done);
spin_lock(&req_lock);
req->next = requests;
requests = req;
spin_unlock(&req_lock);
wake_up_process(thread);
wait_for_completion(&req->done);
kfree(tmp);
return req->err;
}
int devtmpfs_create_node(struct device *dev) int devtmpfs_create_node(struct device *dev)
{ {
const char *tmp = NULL; const char *tmp = NULL;
...@@ -117,19 +130,7 @@ int devtmpfs_create_node(struct device *dev) ...@@ -117,19 +130,7 @@ int devtmpfs_create_node(struct device *dev)
req.dev = dev; req.dev = dev;
init_completion(&req.done); return devtmpfs_submit_req(&req, tmp);
spin_lock(&req_lock);
req.next = requests;
requests = &req;
spin_unlock(&req_lock);
wake_up_process(thread);
wait_for_completion(&req.done);
kfree(tmp);
return req.err;
} }
int devtmpfs_delete_node(struct device *dev) int devtmpfs_delete_node(struct device *dev)
...@@ -147,18 +148,7 @@ int devtmpfs_delete_node(struct device *dev) ...@@ -147,18 +148,7 @@ int devtmpfs_delete_node(struct device *dev)
req.mode = 0; req.mode = 0;
req.dev = dev; req.dev = dev;
init_completion(&req.done); return devtmpfs_submit_req(&req, tmp);
spin_lock(&req_lock);
req.next = requests;
requests = &req;
spin_unlock(&req_lock);
wake_up_process(thread);
wait_for_completion(&req.done);
kfree(tmp);
return req.err;
} }
static int dev_mkdir(const char *name, umode_t mode) static int dev_mkdir(const char *name, umode_t mode)
...@@ -359,7 +349,7 @@ static int handle_remove(const char *nodename, struct device *dev) ...@@ -359,7 +349,7 @@ static int handle_remove(const char *nodename, struct device *dev)
* If configured, or requested by the commandline, devtmpfs will be * If configured, or requested by the commandline, devtmpfs will be
* auto-mounted after the kernel mounted the root filesystem. * auto-mounted after the kernel mounted the root filesystem.
*/ */
int devtmpfs_mount(void) int __init devtmpfs_mount(void)
{ {
int err; int err;
...@@ -388,18 +378,30 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, ...@@ -388,18 +378,30 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
return handle_remove(name, dev); return handle_remove(name, dev);
} }
static int devtmpfsd(void *p) static int devtmpfs_setup(void *p)
{ {
int *err = p; int err;
*err = ksys_unshare(CLONE_NEWNS);
if (*err) err = ksys_unshare(CLONE_NEWNS);
if (err)
goto out; goto out;
*err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
if (*err) if (err)
goto out; goto out;
ksys_chdir("/.."); /* will traverse into overmounted root */ ksys_chdir("/.."); /* will traverse into overmounted root */
ksys_chroot("."); ksys_chroot(".");
out:
*(int *)p = err;
complete(&setup_done); complete(&setup_done);
return err;
}
static int devtmpfsd(void *p)
{
int err = devtmpfs_setup(p);
if (err)
return err;
while (1) { while (1) {
spin_lock(&req_lock); spin_lock(&req_lock);
while (requests) { while (requests) {
...@@ -420,9 +422,6 @@ static int devtmpfsd(void *p) ...@@ -420,9 +422,6 @@ static int devtmpfsd(void *p)
schedule(); schedule();
} }
return 0; return 0;
out:
complete(&setup_done);
return *err;
} }
/* /*
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (c) 2007 Novell Inc. * Copyright (c) 2007 Novell Inc.
*/ */
#include <linux/device/driver.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
......
...@@ -606,7 +606,7 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) ...@@ -606,7 +606,7 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags)
return false; return false;
} }
if ((opt_flags & FW_OPT_NOFALLBACK)) if ((opt_flags & FW_OPT_NOFALLBACK_SYSFS))
return false; return false;
/* Also permit LSMs and IMA to fail firmware sysfs fallback */ /* Also permit LSMs and IMA to fail firmware sysfs fallback */
...@@ -630,10 +630,11 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) ...@@ -630,10 +630,11 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags)
* interface. Userspace is in charge of loading the firmware through the sysfs * interface. Userspace is in charge of loading the firmware through the sysfs
* loading interface. This sysfs fallback mechanism may be disabled completely * loading interface. This sysfs fallback mechanism may be disabled completely
* on a system by setting the proc sysctl value ignore_sysfs_fallback to true. * on a system by setting the proc sysctl value ignore_sysfs_fallback to true.
* If this false we check if the internal API caller set the @FW_OPT_NOFALLBACK * If this is false we check if the internal API caller set the
* flag, if so it would also disable the fallback mechanism. A system may want * @FW_OPT_NOFALLBACK_SYSFS flag, if so it would also disable the fallback
* to enfoce the sysfs fallback mechanism at all times, it can do this by * mechanism. A system may want to enforce the sysfs fallback mechanism at all
* setting ignore_sysfs_fallback to false and force_sysfs_fallback to true. * times, it can do this by setting ignore_sysfs_fallback to false and
* force_sysfs_fallback to true.
* Enabling force_sysfs_fallback is functionally equivalent to build a kernel * Enabling force_sysfs_fallback is functionally equivalent to build a kernel
* with CONFIG_FW_LOADER_USER_HELPER_FALLBACK. * with CONFIG_FW_LOADER_USER_HELPER_FALLBACK.
**/ **/
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
* firmware file lookup on storage is avoided. Used for calls where the * firmware file lookup on storage is avoided. Used for calls where the
* file may be too big, or where the driver takes charge of its own * file may be too big, or where the driver takes charge of its own
* firmware caching mechanism. * firmware caching mechanism.
* @FW_OPT_NOFALLBACK: Disable the fallback mechanism. Takes precedence over * @FW_OPT_NOFALLBACK_SYSFS: Disable the sysfs fallback mechanism. Takes
* &FW_OPT_UEVENT and &FW_OPT_USERHELPER. * precedence over &FW_OPT_UEVENT and &FW_OPT_USERHELPER.
*/ */
enum fw_opt { enum fw_opt {
FW_OPT_UEVENT = BIT(0), FW_OPT_UEVENT = BIT(0),
...@@ -36,7 +36,7 @@ enum fw_opt { ...@@ -36,7 +36,7 @@ enum fw_opt {
FW_OPT_USERHELPER = BIT(2), FW_OPT_USERHELPER = BIT(2),
FW_OPT_NO_WARN = BIT(3), FW_OPT_NO_WARN = BIT(3),
FW_OPT_NOCACHE = BIT(4), FW_OPT_NOCACHE = BIT(4),
FW_OPT_NOFALLBACK = BIT(5), FW_OPT_NOFALLBACK_SYSFS = BIT(5),
}; };
enum fw_status { enum fw_status {
......
...@@ -877,7 +877,7 @@ int request_firmware_direct(const struct firmware **firmware_p, ...@@ -877,7 +877,7 @@ int request_firmware_direct(const struct firmware **firmware_p,
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
ret = _request_firmware(firmware_p, name, device, NULL, 0, ret = _request_firmware(firmware_p, name, device, NULL, 0,
FW_OPT_UEVENT | FW_OPT_NO_WARN | FW_OPT_UEVENT | FW_OPT_NO_WARN |
FW_OPT_NOFALLBACK); FW_OPT_NOFALLBACK_SYSFS);
module_put(THIS_MODULE); module_put(THIS_MODULE);
return ret; return ret;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/limits.h> #include <linux/limits.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/kmemleak.h> #include <linux/kmemleak.h>
#include <linux/types.h>
#include "base.h" #include "base.h"
#include "power/power.h" #include "power/power.h"
...@@ -48,7 +49,7 @@ EXPORT_SYMBOL_GPL(platform_bus); ...@@ -48,7 +49,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
struct resource *platform_get_resource(struct platform_device *dev, struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num) unsigned int type, unsigned int num)
{ {
int i; u32 i;
for (i = 0; i < dev->num_resources; i++) { for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i]; struct resource *r = &dev->resource[i];
...@@ -255,7 +256,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev, ...@@ -255,7 +256,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
unsigned int type, unsigned int type,
const char *name) const char *name)
{ {
int i; u32 i;
for (i = 0; i < dev->num_resources; i++) { for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i]; struct resource *r = &dev->resource[i];
...@@ -501,7 +502,8 @@ EXPORT_SYMBOL_GPL(platform_device_add_properties); ...@@ -501,7 +502,8 @@ EXPORT_SYMBOL_GPL(platform_device_add_properties);
*/ */
int platform_device_add(struct platform_device *pdev) int platform_device_add(struct platform_device *pdev)
{ {
int i, ret; u32 i;
int ret;
if (!pdev) if (!pdev)
return -EINVAL; return -EINVAL;
...@@ -569,7 +571,7 @@ int platform_device_add(struct platform_device *pdev) ...@@ -569,7 +571,7 @@ int platform_device_add(struct platform_device *pdev)
pdev->id = PLATFORM_DEVID_AUTO; pdev->id = PLATFORM_DEVID_AUTO;
} }
while (--i >= 0) { while (i--) {
struct resource *r = &pdev->resource[i]; struct resource *r = &pdev->resource[i];
if (r->parent) if (r->parent)
release_resource(r); release_resource(r);
...@@ -590,7 +592,7 @@ EXPORT_SYMBOL_GPL(platform_device_add); ...@@ -590,7 +592,7 @@ EXPORT_SYMBOL_GPL(platform_device_add);
*/ */
void platform_device_del(struct platform_device *pdev) void platform_device_del(struct platform_device *pdev)
{ {
int i; u32 i;
if (!IS_ERR_OR_NULL(pdev)) { if (!IS_ERR_OR_NULL(pdev)) {
device_del(&pdev->dev); device_del(&pdev->dev);
......
...@@ -44,7 +44,8 @@ static int test_probe(struct platform_device *pdev) ...@@ -44,7 +44,8 @@ static int test_probe(struct platform_device *pdev)
* performing an async init on that node. * performing an async init on that node.
*/ */
if (dev->driver->probe_type == PROBE_PREFER_ASYNCHRONOUS) { if (dev->driver->probe_type == PROBE_PREFER_ASYNCHRONOUS) {
if (dev_to_node(dev) != numa_node_id()) { if (IS_ENABLED(CONFIG_NUMA) &&
dev_to_node(dev) != numa_node_id()) {
dev_warn(dev, "NUMA node mismatch %d != %d\n", dev_warn(dev, "NUMA node mismatch %d != %d\n",
dev_to_node(dev), numa_node_id()); dev_to_node(dev), numa_node_id());
atomic_inc(&warnings); atomic_inc(&warnings);
......
...@@ -142,7 +142,7 @@ EXPORT_SYMBOL_GPL(debugfs_file_put); ...@@ -142,7 +142,7 @@ EXPORT_SYMBOL_GPL(debugfs_file_put);
* We also need to exclude any file that has ways to write or alter it as root * We also need to exclude any file that has ways to write or alter it as root
* can bypass the permissions check. * can bypass the permissions check.
*/ */
static bool debugfs_is_locked_down(struct inode *inode, static int debugfs_locked_down(struct inode *inode,
struct file *filp, struct file *filp,
const struct file_operations *real_fops) const struct file_operations *real_fops)
{ {
...@@ -151,9 +151,12 @@ static bool debugfs_is_locked_down(struct inode *inode, ...@@ -151,9 +151,12 @@ static bool debugfs_is_locked_down(struct inode *inode,
!real_fops->unlocked_ioctl && !real_fops->unlocked_ioctl &&
!real_fops->compat_ioctl && !real_fops->compat_ioctl &&
!real_fops->mmap) !real_fops->mmap)
return false; return 0;
if (security_locked_down(LOCKDOWN_DEBUGFS))
return -EPERM;
return security_locked_down(LOCKDOWN_DEBUGFS); return 0;
} }
static int open_proxy_open(struct inode *inode, struct file *filp) static int open_proxy_open(struct inode *inode, struct file *filp)
...@@ -168,7 +171,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp) ...@@ -168,7 +171,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
real_fops = debugfs_real_fops(filp); real_fops = debugfs_real_fops(filp);
r = debugfs_is_locked_down(inode, filp, real_fops); r = debugfs_locked_down(inode, filp, real_fops);
if (r) if (r)
goto out; goto out;
...@@ -298,7 +301,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp) ...@@ -298,7 +301,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
real_fops = debugfs_real_fops(filp); real_fops = debugfs_real_fops(filp);
r = debugfs_is_locked_down(inode, filp, real_fops); r = debugfs_locked_down(inode, filp, real_fops);
if (r) if (r)
goto out; goto out;
...@@ -496,10 +499,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n"); ...@@ -496,10 +499,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n");
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
* be returned. * be returned.
*/ */
struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *debugfs_create_u32(const char *name, umode_t mode,
...@@ -581,10 +584,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n"); ...@@ -581,10 +584,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n");
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
* be returned. * be returned.
*/ */
struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *debugfs_create_ulong(const char *name, umode_t mode,
...@@ -846,10 +849,10 @@ static const struct file_operations fops_bool_wo = { ...@@ -846,10 +849,10 @@ static const struct file_operations fops_bool_wo = {
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
* be returned. * be returned.
*/ */
struct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *debugfs_create_bool(const char *name, umode_t mode,
...@@ -899,10 +902,10 @@ static const struct file_operations fops_blob = { ...@@ -899,10 +902,10 @@ static const struct file_operations fops_blob = {
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
* be returned. * be returned.
*/ */
struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *debugfs_create_blob(const char *name, umode_t mode,
...@@ -1091,10 +1094,10 @@ static const struct file_operations fops_regset32 = { ...@@ -1091,10 +1094,10 @@ static const struct file_operations fops_regset32 = {
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
* be returned. * be returned.
*/ */
struct dentry *debugfs_create_regset32(const char *name, umode_t mode, struct dentry *debugfs_create_regset32(const char *name, umode_t mode,
...@@ -1158,4 +1161,3 @@ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, ...@@ -1158,4 +1161,3 @@ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
&debugfs_devm_entry_ops); &debugfs_devm_entry_ops);
} }
EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile); EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile);
...@@ -423,7 +423,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, ...@@ -423,7 +423,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * If debugfs is not enabled in the kernel, the value -%ENODEV will be
...@@ -502,7 +502,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe); ...@@ -502,7 +502,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe);
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * If debugfs is not enabled in the kernel, the value -%ENODEV will be
...@@ -534,7 +534,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_size); ...@@ -534,7 +534,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_size);
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is * pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded, * to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned. * returned.
* *
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * If debugfs is not enabled in the kernel, the value -%ENODEV will be
...@@ -627,7 +627,7 @@ EXPORT_SYMBOL(debugfs_create_automount); ...@@ -627,7 +627,7 @@ EXPORT_SYMBOL(debugfs_create_automount);
* This function will return a pointer to a dentry if it succeeds. This * This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the symbolic * pointer must be passed to the debugfs_remove() function when the symbolic
* link is to be removed (no automatic cleanup happens if your module is * link is to be removed (no automatic cleanup happens if your module is
* unloaded, you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) * unloaded, you are responsible here.) If an error occurs, ERR_PTR(-ERROR)
* will be returned. * will be returned.
* *
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * If debugfs is not enabled in the kernel, the value -%ENODEV will be
...@@ -906,4 +906,3 @@ static int __init debugfs_init(void) ...@@ -906,4 +906,3 @@ static int __init debugfs_init(void)
return retval; return retval;
} }
core_initcall(debugfs_init); core_initcall(debugfs_init);
...@@ -1266,7 +1266,7 @@ void kernfs_activate(struct kernfs_node *kn) ...@@ -1266,7 +1266,7 @@ void kernfs_activate(struct kernfs_node *kn)
pos = NULL; pos = NULL;
while ((pos = kernfs_next_descendant_post(pos, kn))) { while ((pos = kernfs_next_descendant_post(pos, kn))) {
if (!pos || (pos->flags & KERNFS_ACTIVATED)) if (pos->flags & KERNFS_ACTIVATED)
continue; continue;
WARN_ON_ONCE(pos->parent && RB_EMPTY_NODE(&pos->rb)); WARN_ON_ONCE(pos->parent && RB_EMPTY_NODE(&pos->rb));
......
// SPDX-License-Identifier: GPL-2.0
/*
* dev_printk.h - printk messages helpers for devices
*
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2008-2009 Novell Inc.
*
*/
#ifndef _DEVICE_PRINTK_H_
#define _DEVICE_PRINTK_H_
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/ratelimit.h>
#ifndef dev_fmt
#define dev_fmt(fmt) fmt
#endif
struct device;
#ifdef CONFIG_PRINTK
__printf(3, 0) __cold
int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args);
__printf(3, 4) __cold
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
__printf(3, 4) __cold
void dev_printk(const char *level, const struct device *dev,
const char *fmt, ...);
__printf(2, 3) __cold
void _dev_emerg(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_alert(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_crit(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_err(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_warn(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_notice(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_info(const struct device *dev, const char *fmt, ...);
#else
static inline __printf(3, 0)
int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args)
{ return 0; }
static inline __printf(3, 4)
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
{ return 0; }
static inline void __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{}
static inline __printf(3, 4)
void dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_emerg(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_crit(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_alert(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_err(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_warn(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_notice(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_info(const struct device *dev, const char *fmt, ...)
{}
#endif
/*
* #defines for all the dev_<level> macros to prefix with whatever
* possible use of #define dev_fmt(fmt) ...
*/
#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__)
#if defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, fmt, ...) \
dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
#elif defined(DEBUG)
#define dev_dbg(dev, fmt, ...) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__)
#else
#define dev_dbg(dev, fmt, ...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
})
#endif
#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, ...) \
dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__)
#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__)
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__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)) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#else
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
if (0) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#endif
#ifdef VERBOSE_DEBUG
#define dev_vdbg dev_dbg
#else
#define dev_vdbg(dev, fmt, ...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
})
#endif
/*
* dev_WARN*() acts like dev_printk(), but with the key difference of
* using WARN/WARN_ONCE to include file/line information and a backtrace.
*/
#define dev_WARN(dev, format, arg...) \
WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
#define dev_WARN_ONCE(dev, condition, format, arg...) \
WARN_ONCE(condition, "%s %s: " format, \
dev_driver_string(dev), dev_name(dev), ## arg)
#endif /* _DEVICE_PRINTK_H_ */
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#ifndef _DEVICE_H_ #ifndef _DEVICE_H_
#define _DEVICE_H_ #define _DEVICE_H_
#include <linux/dev_printk.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/klist.h> #include <linux/klist.h>
...@@ -22,10 +23,12 @@ ...@@ -22,10 +23,12 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/ratelimit.h>
#include <linux/uidgid.h> #include <linux/uidgid.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/overflow.h> #include <linux/overflow.h>
#include <linux/device/bus.h>
#include <linux/device/class.h>
#include <linux/device/driver.h>
#include <asm/device.h> #include <asm/device.h>
struct device; struct device;
...@@ -35,7 +38,6 @@ struct driver_private; ...@@ -35,7 +38,6 @@ struct driver_private;
struct module; struct module;
struct class; struct class;
struct subsys_private; struct subsys_private;
struct bus_type;
struct device_node; struct device_node;
struct fwnode_handle; struct fwnode_handle;
struct iommu_ops; struct iommu_ops;
...@@ -44,490 +46,6 @@ struct iommu_fwspec; ...@@ -44,490 +46,6 @@ struct iommu_fwspec;
struct dev_pin_info; struct dev_pin_info;
struct iommu_param; struct iommu_param;
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *bus, char *buf);
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
#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)
#define BUS_ATTR_WO(_name) \
struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
extern int __must_check bus_create_file(struct bus_type *,
struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
/**
* struct bus_type - The bus type of the device
*
* @name: The name of the bus.
* @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id).
* @dev_root: Default device to use as the parent.
* @bus_groups: Default attributes of the bus.
* @dev_groups: Default attributes of the devices on the bus.
* @drv_groups: Default attributes of the device drivers on the bus.
* @match: Called, perhaps multiple times, whenever a new device or driver
* 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.
* @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.
* @sync_state: Called to sync device state to software state after all the
* state tracking consumers linked to this device (present at
* the time of late_initcall) have successfully bound to a
* driver. If the device has no consumers, this function will
* be called at late_initcall_sync level. If the device has
* consumers that are never bound to a driver, this function
* will never get called until they do.
* @remove: Called when a device removed from this bus.
* @shutdown: Called at shut-down time to quiesce the device.
*
* @online: Called to put the device back online (after offlining it).
* @offline: Called to put the device offline for hot-removal. May fail.
*
* @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.
* @num_vf: Called to find out how many virtual functions a device on this
* bus supports.
* @dma_configure: Called to setup DMA configuration on a device on
* this bus.
* @pm: Power management operations of this bus, callback the specific
* device driver's pm-ops.
* @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU
* driver implementations to a bus and allow the driver to do
* bus-specific setup
* @p: The private data of the driver core, only the driver core can
* touch this.
* @lock_key: Lock class key for use by the lock validator
* @need_parent_lock: When probing or removing a device on this bus, the
* device core should lock the device's parent.
*
* 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.
*/
struct bus_type {
const char *name;
const char *dev_name;
struct device *dev_root;
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
void (*sync_state)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*online)(struct device *dev);
int (*offline)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
int (*num_vf)(struct device *dev);
int (*dma_configure)(struct device *dev);
const struct dev_pm_ops *pm;
const struct iommu_ops *iommu_ops;
struct subsys_private *p;
struct lock_class_key lock_key;
bool need_parent_lock;
};
extern int __must_check bus_register(struct bus_type *bus);
extern void bus_unregister(struct bus_type *bus);
extern int __must_check bus_rescan_devices(struct bus_type *bus);
/* iterator helpers for buses */
struct subsys_dev_iter {
struct klist_iter ki;
const struct device_type *type;
};
void subsys_dev_iter_init(struct subsys_dev_iter *iter,
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);
int device_match_name(struct device *dev, const void *name);
int device_match_of_node(struct device *dev, const void *np);
int device_match_fwnode(struct device *dev, const void *fwnode);
int device_match_devt(struct device *dev, const void *pdevt);
int device_match_acpi_dev(struct device *dev, const void *adev);
int device_match_any(struct device *dev, const void *unused);
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,
const void *data,
int (*match)(struct device *dev, const void *data));
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* bus_find_next_device - Find the next device after a given device in a
* given bus.
* @bus: bus type
* @cur: device to begin the search with.
*/
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);
}
#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
struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
struct device *hint);
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
void *data, int (*fn)(struct device_driver *, void *));
void bus_sort_breadthfirst(struct bus_type *bus,
int (*compare)(const struct device *a,
const struct device *b));
/*
* 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
* with the device lock held in the core, so be careful.
*/
#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
#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
bound */
#define BUS_NOTIFY_BOUND_DRIVER 0x00000005 /* driver bound to device */
#define BUS_NOTIFY_UNBIND_DRIVER 0x00000006 /* driver about to be
unbound */
#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000007 /* driver is unbound
from the device */
#define BUS_NOTIFY_DRIVER_NOT_BOUND 0x00000008 /* driver fails to be bound */
extern struct kset *bus_get_kset(struct bus_type *bus);
extern struct klist *bus_get_device_klist(struct bus_type *bus);
/**
* 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.
*
* @PROBE_DEFAULT_STRATEGY: Used by drivers that work equally well
* whether probed synchronously or asynchronously.
* @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which
* probing order is not essential for booting the system may
* opt into executing their probes asynchronously.
* @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).
*
* 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 {
PROBE_DEFAULT_STRATEGY,
PROBE_PREFER_ASYNCHRONOUS,
PROBE_FORCE_SYNCHRONOUS,
};
/**
* 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.
* @probe_type: Type of the probe (synchronous or asynchronous) to use.
* @of_match_table: The open firmware table.
* @acpi_match_table: The ACPI match table.
* @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.
* @sync_state: Called to sync device state to software state after all the
* state tracking consumers linked to this device (present at
* the time of late_initcall) have successfully bound to a
* driver. If the device has no consumers, this function will
* be called at late_initcall_sync level. If the device has
* consumers that are never bound to a driver, this function
* will never get called until they do.
* @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.
* @dev_groups: Additional attributes attached to device instance once the
* it is bound to the driver.
* @pm: Power management operations of the device which matched
* this driver.
* @coredump: Called when sysfs entry is written to. The device driver
* is expected to call the dev_coredump API resulting in a
* uevent.
* @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.
*/
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
enum probe_type probe_type;
const struct of_device_id *of_match_table;
const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
void (*sync_state)(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);
const struct attribute_group **groups;
const struct attribute_group **dev_groups;
const struct dev_pm_ops *pm;
void (*coredump) (struct device *dev);
struct driver_private *p;
};
extern int __must_check driver_register(struct device_driver *drv);
extern void driver_unregister(struct device_driver *drv);
extern struct device_driver *driver_find(const char *name,
struct bus_type *bus);
extern int driver_probe_done(void);
extern void wait_for_device_probe(void);
/* sysfs interface for exporting driver attributes */
struct driver_attribute {
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);
};
#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)
#define DRIVER_ATTR_WO(_name) \
struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
extern int __must_check driver_create_file(struct device_driver *driver,
const struct driver_attribute *attr);
extern void driver_remove_file(struct device_driver *driver,
const struct driver_attribute *attr);
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,
struct device *start, const void *data,
int (*match)(struct device *dev, const void *data));
/**
* driver_find_device_by_name - device iterator for locating a particular device
* of a specific name.
* @drv: the driver we're iterating
* @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);
}
/**
* driver_find_device_by_of_node- device iterator for locating a particular device
* by of_node pointer.
* @drv: the driver we're iterating
* @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);
}
/**
* driver_find_device_by_fwnode- device iterator for locating a particular device
* by fwnode pointer.
* @drv: the driver we're iterating
* @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);
}
/**
* driver_find_device_by_devt- device iterator for locating a particular device
* by devt.
* @drv: the driver we're iterating
* @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);
}
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);
}
#ifdef CONFIG_ACPI
/**
* driver_find_device_by_acpi_dev : device iterator for locating a particular
* device matching the ACPI_COMPANION device.
* @drv: the driver we're iterating
* @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
void driver_deferred_probe_add(struct device *dev);
int driver_deferred_probe_check_state(struct device *dev);
int driver_deferred_probe_check_state_continue(struct device *dev);
/** /**
* struct subsys_interface - interfaces to device functions * struct subsys_interface - interfaces to device functions
* @name: name of the device function * @name: name of the device function
...@@ -557,246 +75,6 @@ int subsys_system_register(struct bus_type *subsys, ...@@ -557,246 +75,6 @@ int subsys_system_register(struct bus_type *subsys,
int subsys_virtual_register(struct bus_type *subsys, int subsys_virtual_register(struct bus_type *subsys,
const struct attribute_group **groups); const struct attribute_group **groups);
/**
* struct class - device classes
* @name: Name of the class.
* @owner: The module owner.
* @class_groups: Default attributes of this class.
* @dev_groups: Default attributes of the devices that belong to the class.
* @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.
* @shutdown_pre: Called at shut-down time before driver shutdown.
* @ns_type: Callbacks so sysfs can detemine namespaces.
* @namespace: Namespace of the device belongs to this class.
* @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.
* @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.
*/
struct class {
const char *name;
struct module *owner;
const struct attribute_group **class_groups;
const struct attribute_group **dev_groups;
struct kobject *dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, umode_t *mode);
void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev);
int (*shutdown_pre)(struct device *dev);
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid);
const struct dev_pm_ops *pm;
struct subsys_private *p;
};
struct class_dev_iter {
struct klist_iter ki;
const struct device_type *type;
};
extern struct kobject *sysfs_dev_block_kobj;
extern struct kobject *sysfs_dev_char_kobj;
extern int __must_check __class_register(struct class *class,
struct lock_class_key *key);
extern void class_unregister(struct class *class);
/* 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); \
})
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);
extern void class_dev_iter_init(struct class_dev_iter *iter,
struct class *class,
struct device *start,
const struct device_type *type);
extern struct device *class_dev_iter_next(struct class_dev_iter *iter);
extern void class_dev_iter_exit(struct class_dev_iter *iter);
extern int class_for_each_device(struct class *class, struct device *start,
void *data,
int (*fn)(struct device *dev, void *data));
extern struct device *class_find_device(struct class *class,
struct device *start, const void *data,
int (*match)(struct device *, const void *));
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
#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
struct class_attribute {
struct attribute attr;
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);
};
#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)
#define CLASS_ATTR_WO(_name) \
struct class_attribute class_attr_##_name = __ATTR_WO(_name)
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);
}
/* 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);
struct class_interface {
struct list_head node;
struct class *class;
int (*add_dev) (struct device *, struct class_interface *);
void (*remove_dev) (struct device *, struct class_interface *);
};
extern int __must_check class_interface_register(struct class_interface *);
extern void class_interface_unregister(struct class_interface *);
extern struct class * __must_check __class_create(struct module *owner,
const char *name,
struct lock_class_key *key);
extern void class_destroy(struct class *cls);
/* 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); \
})
/* /*
* The type of device, "struct device" is embedded in. A class * The type of device, "struct device" is embedded in. A class
* or bus can contain devices of different types * or bus can contain devices of different types
...@@ -1520,8 +798,6 @@ static inline struct device_node *dev_of_node(struct device *dev) ...@@ -1520,8 +798,6 @@ static inline struct device_node *dev_of_node(struct device *dev)
return dev->of_node; return dev->of_node;
} }
void driver_init(void);
/* /*
* High level routines for use by the bus drivers * High level routines for use by the bus drivers
*/ */
...@@ -1664,12 +940,8 @@ extern void put_device(struct device *dev); ...@@ -1664,12 +940,8 @@ extern void put_device(struct device *dev);
extern bool kill_device(struct device *dev); extern bool kill_device(struct device *dev);
#ifdef CONFIG_DEVTMPFS #ifdef CONFIG_DEVTMPFS
extern int devtmpfs_create_node(struct device *dev);
extern int devtmpfs_delete_node(struct device *dev);
extern int devtmpfs_mount(void); extern int devtmpfs_mount(void);
#else #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(void) { return 0; } static inline int devtmpfs_mount(void) { return 0; }
#endif #endif
...@@ -1687,221 +959,6 @@ void device_link_remove(void *consumer, struct device *supplier); ...@@ -1687,221 +959,6 @@ void device_link_remove(void *consumer, struct device *supplier);
void device_links_supplier_sync_state_pause(void); void device_links_supplier_sync_state_pause(void);
void device_links_supplier_sync_state_resume(void); void device_links_supplier_sync_state_resume(void);
#ifndef dev_fmt
#define dev_fmt(fmt) fmt
#endif
#ifdef CONFIG_PRINTK
__printf(3, 0) __cold
int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args);
__printf(3, 4) __cold
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
__printf(3, 4) __cold
void dev_printk(const char *level, const struct device *dev,
const char *fmt, ...);
__printf(2, 3) __cold
void _dev_emerg(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_alert(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_crit(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_err(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_warn(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_notice(const struct device *dev, const char *fmt, ...);
__printf(2, 3) __cold
void _dev_info(const struct device *dev, const char *fmt, ...);
#else
static inline __printf(3, 0)
int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args)
{ return 0; }
static inline __printf(3, 4)
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
{ return 0; }
static inline void __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{}
static inline __printf(3, 4)
void dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_emerg(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_crit(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_alert(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_err(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_warn(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_notice(const struct device *dev, const char *fmt, ...)
{}
static inline __printf(2, 3)
void _dev_info(const struct device *dev, const char *fmt, ...)
{}
#endif
/*
* #defines for all the dev_<level> macros to prefix with whatever
* possible use of #define dev_fmt(fmt) ...
*/
#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__)
#if defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, fmt, ...) \
dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
#elif defined(DEBUG)
#define dev_dbg(dev, fmt, ...) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__)
#else
#define dev_dbg(dev, fmt, ...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
})
#endif
#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, ...) \
dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__)
#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__)
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
__ratelimit(&_rs)) \
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
##__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)) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#else
#define dev_dbg_ratelimited(dev, fmt, ...) \
do { \
if (0) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#endif
#ifdef VERBOSE_DEBUG
#define dev_vdbg dev_dbg
#else
#define dev_vdbg(dev, fmt, ...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
})
#endif
/*
* dev_WARN*() acts like dev_printk(), but with the key difference of
* using WARN/WARN_ONCE to include file/line information and a backtrace.
*/
#define dev_WARN(dev, format, arg...) \
WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
#define dev_WARN_ONCE(dev, condition, format, arg...) \
WARN_ONCE(condition, "%s %s: " format, \
dev_driver_string(dev), dev_name(dev), ## arg)
/* Create alias, so I can be autoloaded. */ /* Create alias, so I can be autoloaded. */
#define MODULE_ALIAS_CHARDEV(major,minor) \ #define MODULE_ALIAS_CHARDEV(major,minor) \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
...@@ -1914,52 +971,4 @@ extern long sysfs_deprecated; ...@@ -1914,52 +971,4 @@ extern long sysfs_deprecated;
#define sysfs_deprecated 0 #define sysfs_deprecated 0
#endif #endif
/**
* 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().
*
* @__driver: driver name
* @__register: register function for this driver type
* @__unregister: unregister function for this driver type
* @...: Additional arguments to be passed to __register and __unregister.
*
* Use this macro to construct bus specific macros for registering
* drivers, and do not use it on its own.
*/
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);
/**
* 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);
#endif /* _DEVICE_H_ */ #endif /* _DEVICE_H_ */
// SPDX-License-Identifier: GPL-2.0
/*
* bus.h - the bus-specific portions of the driver model
*
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2008-2009 Novell Inc.
* Copyright (c) 2012-2019 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Copyright (c) 2012-2019 Linux Foundation
*
* See Documentation/driver-api/driver-model/ for more information.
*/
#ifndef _DEVICE_BUS_H_
#define _DEVICE_BUS_H_
#include <linux/kobject.h>
#include <linux/klist.h>
#include <linux/pm.h>
struct device_driver;
struct fwnode_handle;
/**
* struct bus_type - The bus type of the device
*
* @name: The name of the bus.
* @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id).
* @dev_root: Default device to use as the parent.
* @bus_groups: Default attributes of the bus.
* @dev_groups: Default attributes of the devices on the bus.
* @drv_groups: Default attributes of the device drivers on the bus.
* @match: Called, perhaps multiple times, whenever a new device or driver
* 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.
* @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.
* @sync_state: Called to sync device state to software state after all the
* state tracking consumers linked to this device (present at
* the time of late_initcall) have successfully bound to a
* driver. If the device has no consumers, this function will
* be called at late_initcall_sync level. If the device has
* consumers that are never bound to a driver, this function
* will never get called until they do.
* @remove: Called when a device removed from this bus.
* @shutdown: Called at shut-down time to quiesce the device.
*
* @online: Called to put the device back online (after offlining it).
* @offline: Called to put the device offline for hot-removal. May fail.
*
* @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.
* @num_vf: Called to find out how many virtual functions a device on this
* bus supports.
* @dma_configure: Called to setup DMA configuration on a device on
* this bus.
* @pm: Power management operations of this bus, callback the specific
* device driver's pm-ops.
* @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU
* driver implementations to a bus and allow the driver to do
* bus-specific setup
* @p: The private data of the driver core, only the driver core can
* touch this.
* @lock_key: Lock class key for use by the lock validator
* @need_parent_lock: When probing or removing a device on this bus, the
* device core should lock the device's parent.
*
* 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.
*/
struct bus_type {
const char *name;
const char *dev_name;
struct device *dev_root;
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
void (*sync_state)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*online)(struct device *dev);
int (*offline)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
int (*num_vf)(struct device *dev);
int (*dma_configure)(struct device *dev);
const struct dev_pm_ops *pm;
const struct iommu_ops *iommu_ops;
struct subsys_private *p;
struct lock_class_key lock_key;
bool need_parent_lock;
};
extern int __must_check bus_register(struct bus_type *bus);
extern void bus_unregister(struct bus_type *bus);
extern int __must_check bus_rescan_devices(struct bus_type *bus);
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *bus, char *buf);
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
#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)
#define BUS_ATTR_WO(_name) \
struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
extern int __must_check bus_create_file(struct bus_type *,
struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
/* Generic device matching functions that all busses can use to match with */
int device_match_name(struct device *dev, const void *name);
int device_match_of_node(struct device *dev, const void *np);
int device_match_fwnode(struct device *dev, const void *fwnode);
int device_match_devt(struct device *dev, const void *pdevt);
int device_match_acpi_dev(struct device *dev, const void *adev);
int device_match_any(struct device *dev, const void *unused);
/* iterator helpers for buses */
struct subsys_dev_iter {
struct klist_iter ki;
const struct device_type *type;
};
void subsys_dev_iter_init(struct subsys_dev_iter *iter,
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);
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,
const void *data,
int (*match)(struct device *dev, const void *data));
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* bus_find_next_device - Find the next device after a given device in a
* given bus.
* @bus: bus type
* @cur: device to begin the search with.
*/
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);
}
#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
struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
struct device *hint);
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
void *data, int (*fn)(struct device_driver *, void *));
void bus_sort_breadthfirst(struct bus_type *bus,
int (*compare)(const struct device *a,
const struct device *b));
/*
* 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
* with the device lock held in the core, so be careful.
*/
#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
#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
bound */
#define BUS_NOTIFY_BOUND_DRIVER 0x00000005 /* driver bound to device */
#define BUS_NOTIFY_UNBIND_DRIVER 0x00000006 /* driver about to be
unbound */
#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000007 /* driver is unbound
from the device */
#define BUS_NOTIFY_DRIVER_NOT_BOUND 0x00000008 /* driver fails to be bound */
extern struct kset *bus_get_kset(struct bus_type *bus);
extern struct klist *bus_get_device_klist(struct bus_type *bus);
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* The class-specific portions of the driver model
*
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2008-2009 Novell Inc.
* Copyright (c) 2012-2019 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Copyright (c) 2012-2019 Linux Foundation
*
* See Documentation/driver-api/driver-model/ for more information.
*/
#ifndef _DEVICE_CLASS_H_
#define _DEVICE_CLASS_H_
#include <linux/kobject.h>
#include <linux/klist.h>
#include <linux/pm.h>
#include <linux/device/bus.h>
struct device;
struct fwnode_handle;
/**
* struct class - device classes
* @name: Name of the class.
* @owner: The module owner.
* @class_groups: Default attributes of this class.
* @dev_groups: Default attributes of the devices that belong to the class.
* @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.
* @shutdown_pre: Called at shut-down time before driver shutdown.
* @ns_type: Callbacks so sysfs can detemine namespaces.
* @namespace: Namespace of the device belongs to this class.
* @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.
* @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.
*/
struct class {
const char *name;
struct module *owner;
const struct attribute_group **class_groups;
const struct attribute_group **dev_groups;
struct kobject *dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, umode_t *mode);
void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev);
int (*shutdown_pre)(struct device *dev);
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid);
const struct dev_pm_ops *pm;
struct subsys_private *p;
};
struct class_dev_iter {
struct klist_iter ki;
const struct device_type *type;
};
extern struct kobject *sysfs_dev_block_kobj;
extern struct kobject *sysfs_dev_char_kobj;
extern int __must_check __class_register(struct class *class,
struct lock_class_key *key);
extern void class_unregister(struct class *class);
/* 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); \
})
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);
extern void class_dev_iter_init(struct class_dev_iter *iter,
struct class *class,
struct device *start,
const struct device_type *type);
extern struct device *class_dev_iter_next(struct class_dev_iter *iter);
extern void class_dev_iter_exit(struct class_dev_iter *iter);
extern int class_for_each_device(struct class *class, struct device *start,
void *data,
int (*fn)(struct device *dev, void *data));
extern struct device *class_find_device(struct class *class,
struct device *start, const void *data,
int (*match)(struct device *, const void *));
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
#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
struct class_attribute {
struct attribute attr;
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);
};
#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)
#define CLASS_ATTR_WO(_name) \
struct class_attribute class_attr_##_name = __ATTR_WO(_name)
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);
}
/* 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);
struct class_interface {
struct list_head node;
struct class *class;
int (*add_dev) (struct device *, struct class_interface *);
void (*remove_dev) (struct device *, struct class_interface *);
};
extern int __must_check class_interface_register(struct class_interface *);
extern void class_interface_unregister(struct class_interface *);
extern struct class * __must_check __class_create(struct module *owner,
const char *name,
struct lock_class_key *key);
extern void class_destroy(struct class *cls);
/* 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); \
})
#endif /* _DEVICE_CLASS_H_ */
// SPDX-License-Identifier: GPL-2.0
/*
* The driver-specific portions of the driver model
*
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (c) 2008-2009 Novell Inc.
* Copyright (c) 2012-2019 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Copyright (c) 2012-2019 Linux Foundation
*
* See Documentation/driver-api/driver-model/ for more information.
*/
#ifndef _DEVICE_DRIVER_H_
#define _DEVICE_DRIVER_H_
#include <linux/kobject.h>
#include <linux/klist.h>
#include <linux/pm.h>
#include <linux/device/bus.h>
/**
* 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.
*
* @PROBE_DEFAULT_STRATEGY: Used by drivers that work equally well
* whether probed synchronously or asynchronously.
* @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which
* probing order is not essential for booting the system may
* opt into executing their probes asynchronously.
* @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).
*
* 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 {
PROBE_DEFAULT_STRATEGY,
PROBE_PREFER_ASYNCHRONOUS,
PROBE_FORCE_SYNCHRONOUS,
};
/**
* 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.
* @probe_type: Type of the probe (synchronous or asynchronous) to use.
* @of_match_table: The open firmware table.
* @acpi_match_table: The ACPI match table.
* @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.
* @sync_state: Called to sync device state to software state after all the
* state tracking consumers linked to this device (present at
* the time of late_initcall) have successfully bound to a
* driver. If the device has no consumers, this function will
* be called at late_initcall_sync level. If the device has
* consumers that are never bound to a driver, this function
* will never get called until they do.
* @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.
* @dev_groups: Additional attributes attached to device instance once the
* it is bound to the driver.
* @pm: Power management operations of the device which matched
* this driver.
* @coredump: Called when sysfs entry is written to. The device driver
* is expected to call the dev_coredump API resulting in a
* uevent.
* @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.
*/
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
enum probe_type probe_type;
const struct of_device_id *of_match_table;
const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
void (*sync_state)(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);
const struct attribute_group **groups;
const struct attribute_group **dev_groups;
const struct dev_pm_ops *pm;
void (*coredump) (struct device *dev);
struct driver_private *p;
};
extern int __must_check driver_register(struct device_driver *drv);
extern void driver_unregister(struct device_driver *drv);
extern struct device_driver *driver_find(const char *name,
struct bus_type *bus);
extern int driver_probe_done(void);
extern void wait_for_device_probe(void);
/* sysfs interface for exporting driver attributes */
struct driver_attribute {
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);
};
#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)
#define DRIVER_ATTR_WO(_name) \
struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
extern int __must_check driver_create_file(struct device_driver *driver,
const struct driver_attribute *attr);
extern void driver_remove_file(struct device_driver *driver,
const struct driver_attribute *attr);
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,
struct device *start, const void *data,
int (*match)(struct device *dev, const void *data));
/**
* driver_find_device_by_name - device iterator for locating a particular device
* of a specific name.
* @drv: the driver we're iterating
* @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);
}
/**
* driver_find_device_by_of_node- device iterator for locating a particular device
* by of_node pointer.
* @drv: the driver we're iterating
* @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);
}
/**
* driver_find_device_by_fwnode- device iterator for locating a particular device
* by fwnode pointer.
* @drv: the driver we're iterating
* @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);
}
/**
* driver_find_device_by_devt- device iterator for locating a particular device
* by devt.
* @drv: the driver we're iterating
* @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);
}
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);
}
#ifdef CONFIG_ACPI
/**
* driver_find_device_by_acpi_dev : device iterator for locating a particular
* device matching the ACPI_COMPANION device.
* @drv: the driver we're iterating
* @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
void driver_deferred_probe_add(struct device *dev);
int driver_deferred_probe_check_state(struct device *dev);
int driver_deferred_probe_check_state_continue(struct device *dev);
void driver_init(void);
/**
* 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().
*
* @__driver: driver name
* @__register: register function for this driver type
* @__unregister: unregister function for this driver type
* @...: Additional arguments to be passed to __register and __unregister.
*
* Use this macro to construct bus specific macros for registering
* drivers, and do not use it on its own.
*/
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);
/**
* 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);
#endif /* _DEVICE_DRIVER_H_ */
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/kmemleak.h> #include <linux/kmemleak.h>
#include <linux/pid_namespace.h> #include <linux/pid_namespace.h>
#include <linux/device.h> #include <linux/device/driver.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/init.h> #include <linux/sched/init.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment