diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/arch_topology.c | 20 | ||||
-rw-r--r-- | drivers/base/base.h | 19 | ||||
-rw-r--r-- | drivers/base/bus.c | 1 | ||||
-rw-r--r-- | drivers/base/class.c | 1 | ||||
-rw-r--r-- | drivers/base/component.c | 11 | ||||
-rw-r--r-- | drivers/base/dd.c | 5 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 79 | ||||
-rw-r--r-- | drivers/base/driver.c | 1 | ||||
-rw-r--r-- | drivers/base/firmware_loader/fallback.c | 11 | ||||
-rw-r--r-- | drivers/base/firmware_loader/firmware.h | 16 | ||||
-rw-r--r-- | drivers/base/firmware_loader/main.c | 2 | ||||
-rw-r--r-- | drivers/base/platform.c | 12 | ||||
-rw-r--r-- | drivers/base/test/test_async_driver_probe.c | 3 |
13 files changed, 108 insertions, 73 deletions
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 1eb81f113786..6119e11a9f95 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -248,6 +248,16 @@ core_initcall(free_raw_capacity); #endif #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) { struct device_node *cpu_node; @@ -261,7 +271,8 @@ static int __init get_cpu_for_node(struct device_node *node) if (cpu >= 0) topology_parse_cpu_capacity(cpu_node, cpu); 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); return cpu; @@ -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].core_id = core_id; cpu_topology[cpu].thread_id = i; - } else { - pr_err("%pOF: Can't get CPU for thread\n", - t); + } else if (cpu != -ENODEV) { + pr_err("%pOF: Can't get CPU for thread\n", t); of_node_put(t); return -EINVAL; } @@ -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].core_id = core_id; - } else if (leaf) { + } else if (leaf && cpu != -ENODEV) { pr_err("%pOF: Can't get CPU for leaf core\n", core); return -EINVAL; } diff --git a/drivers/base/base.h b/drivers/base/base.h index 0d32544b6f91..40fb069a8a7e 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -1,4 +1,15 @@ /* 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> /** @@ -175,3 +186,11 @@ extern void device_links_unbind_consumers(struct device *dev); /* device pm support */ 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 diff --git a/drivers/base/bus.c b/drivers/base/bus.c index a1d1e8256324..886e9054999a 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -9,6 +9,7 @@ */ #include <linux/async.h> +#include <linux/device/bus.h> #include <linux/device.h> #include <linux/module.h> #include <linux/errno.h> diff --git a/drivers/base/class.c b/drivers/base/class.c index d8a6a5864c2e..bcd410e6d70a 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -8,6 +8,7 @@ * Copyright (c) 2003-2004 IBM Corp. */ +#include <linux/device/class.h> #include <linux/device.h> #include <linux/module.h> #include <linux/init.h> diff --git a/drivers/base/component.c b/drivers/base/component.c index 532a3a5d8f63..c7879f5ae2fb 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -11,7 +11,6 @@ #include <linux/device.h> #include <linux/kref.h> #include <linux/list.h> -#include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> #include <linux/debugfs.h> @@ -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_puts(s, "-------------------------------------------------------------\n"); 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), - match->compare[i].component ? - "registered" : "not registered"); + seq_printf(s, "%-40s %20s\n", + component ? dev_name(component->dev) : "(unknown)", + component ? (component->bound ? "bound" : "not bound") : "not registered"); } mutex_unlock(&component_mutex); @@ -775,5 +774,3 @@ void component_del(struct device *dev, const struct component_ops *ops) kfree(component); } EXPORT_SYMBOL_GPL(component_del); - -MODULE_LICENSE("GPL v2"); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index d811e60610d3..b25bcab2a26b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -516,7 +516,10 @@ static int really_probe(struct device *dev, struct device_driver *drv) atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", 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: dev->driver = drv; diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 6cdbf1531238..5995c437cbdf 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -30,11 +30,7 @@ static struct task_struct *thread; -#if defined CONFIG_DEVTMPFS_MOUNT -static int mount_dev = 1; -#else -static int mount_dev; -#endif +static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT); static DEFINE_SPINLOCK(req_lock); @@ -93,6 +89,23 @@ static inline int is_blockdev(struct device *dev) static inline int is_blockdev(struct device *dev) { return 0; } #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) { const char *tmp = NULL; @@ -117,19 +130,7 @@ int devtmpfs_create_node(struct device *dev) req.dev = dev; - 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; + return devtmpfs_submit_req(&req, tmp); } int devtmpfs_delete_node(struct device *dev) @@ -147,18 +148,7 @@ int devtmpfs_delete_node(struct device *dev) req.mode = 0; req.dev = dev; - 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; + return devtmpfs_submit_req(&req, tmp); } static int dev_mkdir(const char *name, umode_t mode) @@ -359,7 +349,7 @@ static int handle_remove(const char *nodename, struct device *dev) * If configured, or requested by the commandline, devtmpfs will be * auto-mounted after the kernel mounted the root filesystem. */ -int devtmpfs_mount(void) +int __init devtmpfs_mount(void) { int err; @@ -388,18 +378,30 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, return handle_remove(name, dev); } -static int devtmpfsd(void *p) +static int devtmpfs_setup(void *p) { - int *err = p; - *err = ksys_unshare(CLONE_NEWNS); - if (*err) + int err; + + err = ksys_unshare(CLONE_NEWNS); + if (err) goto out; - *err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); - if (*err) + err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); + if (err) goto out; ksys_chdir("/.."); /* will traverse into overmounted root */ ksys_chroot("."); +out: + *(int *)p = err; complete(&setup_done); + return err; +} + +static int devtmpfsd(void *p) +{ + int err = devtmpfs_setup(p); + + if (err) + return err; while (1) { spin_lock(&req_lock); while (requests) { @@ -420,9 +422,6 @@ static int devtmpfsd(void *p) schedule(); } return 0; -out: - complete(&setup_done); - return *err; } /* diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 4e5ca632f35e..57c68769e157 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -8,6 +8,7 @@ * Copyright (c) 2007 Novell Inc. */ +#include <linux/device/driver.h> #include <linux/device.h> #include <linux/module.h> #include <linux/errno.h> diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 62ee90b4db56..8704e1bae175 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -606,7 +606,7 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) return false; } - if ((opt_flags & FW_OPT_NOFALLBACK)) + if ((opt_flags & FW_OPT_NOFALLBACK_SYSFS)) return false; /* 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) * interface. Userspace is in charge of loading the firmware through the sysfs * loading interface. This sysfs fallback mechanism may be disabled completely * 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 - * flag, if so it would also disable the fallback mechanism. A system may want - * to enfoce the sysfs fallback mechanism at all times, it can do this by - * setting ignore_sysfs_fallback to false and force_sysfs_fallback to true. + * If this is false we check if the internal API caller set the + * @FW_OPT_NOFALLBACK_SYSFS flag, if so it would also disable the fallback + * mechanism. A system may want to enforce the sysfs fallback mechanism at all + * 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 * with CONFIG_FW_LOADER_USER_HELPER_FALLBACK. **/ diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 7ecd590e67fe..8656e5239a80 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -27,16 +27,16 @@ * 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 * firmware caching mechanism. - * @FW_OPT_NOFALLBACK: Disable the fallback mechanism. Takes precedence over - * &FW_OPT_UEVENT and &FW_OPT_USERHELPER. + * @FW_OPT_NOFALLBACK_SYSFS: Disable the sysfs fallback mechanism. Takes + * precedence over &FW_OPT_UEVENT and &FW_OPT_USERHELPER. */ enum fw_opt { - FW_OPT_UEVENT = BIT(0), - FW_OPT_NOWAIT = BIT(1), - FW_OPT_USERHELPER = BIT(2), - FW_OPT_NO_WARN = BIT(3), - FW_OPT_NOCACHE = BIT(4), - FW_OPT_NOFALLBACK = BIT(5), + FW_OPT_UEVENT = BIT(0), + FW_OPT_NOWAIT = BIT(1), + FW_OPT_USERHELPER = BIT(2), + FW_OPT_NO_WARN = BIT(3), + FW_OPT_NOCACHE = BIT(4), + FW_OPT_NOFALLBACK_SYSFS = BIT(5), }; enum fw_status { diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 249add8c5e05..57133a9dad09 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -877,7 +877,7 @@ int request_firmware_direct(const struct firmware **firmware_p, __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, NULL, 0, FW_OPT_UEVENT | FW_OPT_NO_WARN | - FW_OPT_NOFALLBACK); + FW_OPT_NOFALLBACK_SYSFS); module_put(THIS_MODULE); return ret; } diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cf6b6b722e5c..7fa654f1288b 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -27,6 +27,7 @@ #include <linux/limits.h> #include <linux/property.h> #include <linux/kmemleak.h> +#include <linux/types.h> #include "base.h" #include "power/power.h" @@ -48,7 +49,7 @@ EXPORT_SYMBOL_GPL(platform_bus); struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num) { - int i; + u32 i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; @@ -255,7 +256,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name) { - int i; + u32 i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; @@ -501,7 +502,8 @@ EXPORT_SYMBOL_GPL(platform_device_add_properties); */ int platform_device_add(struct platform_device *pdev) { - int i, ret; + u32 i; + int ret; if (!pdev) return -EINVAL; @@ -569,7 +571,7 @@ int platform_device_add(struct platform_device *pdev) pdev->id = PLATFORM_DEVID_AUTO; } - while (--i >= 0) { + while (i--) { struct resource *r = &pdev->resource[i]; if (r->parent) release_resource(r); @@ -590,7 +592,7 @@ EXPORT_SYMBOL_GPL(platform_device_add); */ void platform_device_del(struct platform_device *pdev) { - int i; + u32 i; if (!IS_ERR_OR_NULL(pdev)) { device_del(&pdev->dev); diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c index f4b1d8e54daf..3bb7beb127a9 100644 --- a/drivers/base/test/test_async_driver_probe.c +++ b/drivers/base/test/test_async_driver_probe.c @@ -44,7 +44,8 @@ static int test_probe(struct platform_device *pdev) * performing an async init on that node. */ 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_to_node(dev), numa_node_id()); atomic_inc(&warnings); |