diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-25 10:42:22 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-25 10:42:22 -0700 |
commit | c2a96b7f187fb6a455836d4a6e113947ff11de97 (patch) | |
tree | 139dddcaffbf4fd9e9ee2e1ddce9ce3940f6eec7 /drivers/base | |
parent | b2eed73360dffea91ea64e8f19330c950dd42ebb (diff) | |
parent | b57d5ffc3ab507d0e19fc8b90b19c76af43fb790 (diff) |
Merge tag 'driver-core-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH:
"Here is the big set of driver core changes for 6.11-rc1.
Lots of stuff in here, with not a huge diffstat, but apis are evolving
which required lots of files to be touched. Highlights of the changes
in here are:
- platform remove callback api final fixups (Uwe took many releases
to get here, finally!)
- Rust bindings for basic firmware apis and initial driver-core
interactions.
It's not all that useful for a "write a whole driver in rust" type
of thing, but the firmware bindings do help out the phy rust
drivers, and the driver core bindings give a solid base on which
others can start their work.
There is still a long way to go here before we have a multitude of
rust drivers being added, but it's a great first step.
- driver core const api changes.
This reached across all bus types, and there are some fix-ups for
some not-common bus types that linux-next and 0-day testing shook
out.
This work is being done to help make the rust bindings more safe,
as well as the C code, moving toward the end-goal of allowing us to
put driver structures into read-only memory. We aren't there yet,
but are getting closer.
- minor devres cleanups and fixes found by code inspection
- arch_topology minor changes
- other minor driver core cleanups
All of these have been in linux-next for a very long time with no
reported problems"
* tag 'driver-core-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (55 commits)
ARM: sa1100: make match function take a const pointer
sysfs/cpu: Make crash_hotplug attribute world-readable
dio: Have dio_bus_match() callback take a const *
zorro: make match function take a const pointer
driver core: module: make module_[add|remove]_driver take a const *
driver core: make driver_find_device() take a const *
driver core: make driver_[create|remove]_file take a const *
firmware_loader: fix soundness issue in `request_internal`
firmware_loader: annotate doctests as `no_run`
devres: Correct code style for functions that return a pointer type
devres: Initialize an uninitialized struct member
devres: Fix memory leakage caused by driver API devm_free_percpu()
devres: Fix devm_krealloc() wasting memory
driver core: platform: Switch to use kmemdup_array()
driver core: have match() callback in struct bus_type take a const *
MAINTAINERS: add Rust device abstractions to DRIVER CORE
device: rust: improve safety comments
MAINTAINERS: add Danilo as FIRMWARE LOADER maintainer
MAINTAINERS: add Rust FW abstractions to FIRMWARE LOADER
firmware: rust: improve safety comments
...
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/arch_topology.c | 145 | ||||
-rw-r--r-- | drivers/base/auxiliary.c | 10 | ||||
-rw-r--r-- | drivers/base/base.h | 16 | ||||
-rw-r--r-- | drivers/base/core.c | 17 | ||||
-rw-r--r-- | drivers/base/cpu.c | 4 | ||||
-rw-r--r-- | drivers/base/dd.c | 30 | ||||
-rw-r--r-- | drivers/base/devres.c | 34 | ||||
-rw-r--r-- | drivers/base/driver.c | 10 | ||||
-rw-r--r-- | drivers/base/firmware_loader/Kconfig | 7 | ||||
-rw-r--r-- | drivers/base/isa.c | 2 | ||||
-rw-r--r-- | drivers/base/module.c | 6 | ||||
-rw-r--r-- | drivers/base/platform.c | 26 |
12 files changed, 164 insertions, 143 deletions
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index c66d070207a0..75fcb75d5515 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -8,6 +8,7 @@ #include <linux/acpi.h> #include <linux/cacheinfo.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpufreq.h> #include <linux/device.h> @@ -513,10 +514,10 @@ core_initcall(free_raw_capacity); */ static int __init get_cpu_for_node(struct device_node *node) { - struct device_node *cpu_node; int cpu; + struct device_node *cpu_node __free(device_node) = + of_parse_phandle(node, "cpu", 0); - cpu_node = of_parse_phandle(node, "cpu", 0); if (!cpu_node) return -1; @@ -527,7 +528,6 @@ static int __init get_cpu_for_node(struct device_node *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; } @@ -538,28 +538,28 @@ static int __init parse_core(struct device_node *core, int package_id, bool leaf = true; int i = 0; int cpu; - struct device_node *t; do { snprintf(name, sizeof(name), "thread%d", i); - t = of_get_child_by_name(core, name); - if (t) { - leaf = false; - cpu = get_cpu_for_node(t); - if (cpu >= 0) { - cpu_topology[cpu].package_id = package_id; - cpu_topology[cpu].cluster_id = cluster_id; - cpu_topology[cpu].core_id = core_id; - cpu_topology[cpu].thread_id = i; - } else if (cpu != -ENODEV) { - pr_err("%pOF: Can't get CPU for thread\n", t); - of_node_put(t); - return -EINVAL; - } - of_node_put(t); + struct device_node *t __free(device_node) = + of_get_child_by_name(core, name); + + if (!t) + break; + + leaf = false; + cpu = get_cpu_for_node(t); + if (cpu >= 0) { + cpu_topology[cpu].package_id = package_id; + cpu_topology[cpu].cluster_id = cluster_id; + cpu_topology[cpu].core_id = core_id; + cpu_topology[cpu].thread_id = i; + } else if (cpu != -ENODEV) { + pr_err("%pOF: Can't get CPU for thread\n", t); + return -EINVAL; } i++; - } while (t); + } while (1); cpu = get_cpu_for_node(core); if (cpu >= 0) { @@ -586,7 +586,6 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, char name[20]; bool leaf = true; bool has_cores = false; - struct device_node *c; int core_id = 0; int i, ret; @@ -598,49 +597,50 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, i = 0; do { snprintf(name, sizeof(name), "cluster%d", i); - c = of_get_child_by_name(cluster, name); - if (c) { - leaf = false; - ret = parse_cluster(c, package_id, i, depth + 1); - if (depth > 0) - pr_warn("Topology for clusters of clusters not yet supported\n"); - of_node_put(c); - if (ret != 0) - return ret; - } + struct device_node *c __free(device_node) = + of_get_child_by_name(cluster, name); + + if (!c) + break; + + leaf = false; + ret = parse_cluster(c, package_id, i, depth + 1); + if (depth > 0) + pr_warn("Topology for clusters of clusters not yet supported\n"); + if (ret != 0) + return ret; i++; - } while (c); + } while (1); /* Now check for cores */ i = 0; do { snprintf(name, sizeof(name), "core%d", i); - c = of_get_child_by_name(cluster, name); - if (c) { - has_cores = true; - - if (depth == 0) { - pr_err("%pOF: cpu-map children should be clusters\n", - c); - of_node_put(c); - return -EINVAL; - } + struct device_node *c __free(device_node) = + of_get_child_by_name(cluster, name); - if (leaf) { - ret = parse_core(c, package_id, cluster_id, - core_id++); - } else { - pr_err("%pOF: Non-leaf cluster with core %s\n", - cluster, name); - ret = -EINVAL; - } + if (!c) + break; + + has_cores = true; - of_node_put(c); + if (depth == 0) { + pr_err("%pOF: cpu-map children should be clusters\n", c); + return -EINVAL; + } + + if (leaf) { + ret = parse_core(c, package_id, cluster_id, core_id++); if (ret != 0) return ret; + } else { + pr_err("%pOF: Non-leaf cluster with core %s\n", + cluster, name); + return -EINVAL; } + i++; - } while (c); + } while (1); if (leaf && !has_cores) pr_warn("%pOF: empty cluster\n", cluster); @@ -651,22 +651,24 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, static int __init parse_socket(struct device_node *socket) { char name[20]; - struct device_node *c; bool has_socket = false; int package_id = 0, ret; do { snprintf(name, sizeof(name), "socket%d", package_id); - c = of_get_child_by_name(socket, name); - if (c) { - has_socket = true; - ret = parse_cluster(c, package_id, -1, 0); - of_node_put(c); - if (ret != 0) - return ret; - } + struct device_node *c __free(device_node) = + of_get_child_by_name(socket, name); + + if (!c) + break; + + has_socket = true; + ret = parse_cluster(c, package_id, -1, 0); + if (ret != 0) + return ret; + package_id++; - } while (c); + } while (1); if (!has_socket) ret = parse_cluster(socket, 0, -1, 0); @@ -676,11 +678,11 @@ static int __init parse_socket(struct device_node *socket) static int __init parse_dt_topology(void) { - struct device_node *cn, *map; int ret = 0; int cpu; + struct device_node *cn __free(device_node) = + of_find_node_by_path("/cpus"); - cn = of_find_node_by_path("/cpus"); if (!cn) { pr_err("No CPU information found in DT\n"); return 0; @@ -690,13 +692,15 @@ static int __init parse_dt_topology(void) * When topology is provided cpu-map is essentially a root * cluster with restricted subnodes. */ - map = of_get_child_by_name(cn, "cpu-map"); + struct device_node *map __free(device_node) = + of_get_child_by_name(cn, "cpu-map"); + if (!map) - goto out; + return ret; ret = parse_socket(map); if (ret != 0) - goto out_map; + return ret; topology_normalize_cpu_scale(); @@ -706,14 +710,9 @@ static int __init parse_dt_topology(void) */ for_each_possible_cpu(cpu) if (cpu_topology[cpu].package_id < 0) { - ret = -EINVAL; - break; + return -EINVAL; } -out_map: - of_node_put(map); -out: - of_node_put(cn); return ret; } #endif diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index 3f01f4ec69e5..54b92839e05c 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -177,10 +177,10 @@ static const struct auxiliary_device_id *auxiliary_match_id(const struct auxilia return NULL; } -static int auxiliary_match(struct device *dev, struct device_driver *drv) +static int auxiliary_match(struct device *dev, const struct device_driver *drv) { struct auxiliary_device *auxdev = to_auxiliary_dev(dev); - struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); + const struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); return !!auxiliary_match_id(auxdrv->id_table, auxdev); } @@ -203,7 +203,7 @@ static const struct dev_pm_ops auxiliary_dev_pm_ops = { static int auxiliary_bus_probe(struct device *dev) { - struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); + const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); struct auxiliary_device *auxdev = to_auxiliary_dev(dev); int ret; @@ -222,7 +222,7 @@ static int auxiliary_bus_probe(struct device *dev) static void auxiliary_bus_remove(struct device *dev) { - struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); + const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); struct auxiliary_device *auxdev = to_auxiliary_dev(dev); if (auxdrv->remove) @@ -232,7 +232,7 @@ static void auxiliary_bus_remove(struct device *dev) static void auxiliary_bus_shutdown(struct device *dev) { - struct auxiliary_driver *auxdrv = NULL; + const struct auxiliary_driver *auxdrv = NULL; struct auxiliary_device *auxdev; if (dev->driver) { diff --git a/drivers/base/base.h b/drivers/base/base.h index db4f910e8e36..0b53593372d7 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -112,7 +112,7 @@ struct device_private { struct klist_node knode_bus; struct klist_node knode_class; struct list_head deferred_probe; - struct device_driver *async_driver; + const struct device_driver *async_driver; char *deferred_probe_reason; struct device *device; u8 dead:1; @@ -155,13 +155,13 @@ bool bus_is_registered(const struct bus_type *bus); int bus_add_driver(struct device_driver *drv); void bus_remove_driver(struct device_driver *drv); -void device_release_driver_internal(struct device *dev, struct device_driver *drv, +void device_release_driver_internal(struct device *dev, const struct device_driver *drv, struct device *parent); -void driver_detach(struct device_driver *drv); +void driver_detach(const struct device_driver *drv); void driver_deferred_probe_del(struct device *dev); void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf); -static inline int driver_match_device(struct device_driver *drv, +static inline int driver_match_device(const struct device_driver *drv, struct device *dev) { return drv->bus->match ? drv->bus->match(dev, drv) : 1; @@ -175,8 +175,8 @@ static inline void dev_sync_state(struct device *dev) dev->driver->sync_state(dev); } -int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups); -void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups); +int driver_add_groups(const struct device_driver *drv, const struct attribute_group **groups); +void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups); void device_driver_detach(struct device *dev); int devres_release_all(struct device *dev); @@ -192,8 +192,8 @@ extern struct kset *devices_kset; void devices_kset_move_last(struct device *dev); #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) -int module_add_driver(struct module *mod, struct device_driver *drv); -void module_remove_driver(struct device_driver *drv); +int module_add_driver(struct module *mod, const struct device_driver *drv); +void module_remove_driver(const struct device_driver *drv); #else static inline int module_add_driver(struct module *mod, struct device_driver *drv) diff --git a/drivers/base/core.c b/drivers/base/core.c index 2b4c0624b704..730cae66607c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -5021,11 +5021,22 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; - if (err != -EPROBE_DEFER) { - dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); - } else { + switch (err) { + case -EPROBE_DEFER: device_set_deferred_probe_reason(dev, &vaf); dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); + break; + + case -ENOMEM: + /* + * We don't print anything on -ENOMEM, there is already enough + * output. + */ + break; + + default: + dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); + break; } va_end(args); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index b57326fd48d4..fdaa24bb641a 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -26,7 +26,7 @@ static DEFINE_PER_CPU(struct device *, cpu_sys_devices); -static int cpu_subsys_match(struct device *dev, struct device_driver *drv) +static int cpu_subsys_match(struct device *dev, const struct device_driver *drv) { /* ACPI style match is the only one that may succeed. */ if (acpi_driver_match_device(dev, drv)) @@ -316,7 +316,7 @@ static ssize_t crash_hotplug_show(struct device *dev, { return sysfs_emit(buf, "%d\n", crash_check_hotplug_support()); } -static DEVICE_ATTR_ADMIN_RO(crash_hotplug); +static DEVICE_ATTR_RO(crash_hotplug); #endif static void cpu_device_release(struct device *dev) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 83d352394fdf..9b745ba54de1 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -568,7 +568,7 @@ static void device_remove(struct device *dev) dev->driver->remove(dev); } -static int call_driver_probe(struct device *dev, struct device_driver *drv) +static int call_driver_probe(struct device *dev, const struct device_driver *drv) { int ret = 0; @@ -599,7 +599,7 @@ static int call_driver_probe(struct device *dev, struct device_driver *drv) return ret; } -static int really_probe(struct device *dev, struct device_driver *drv) +static int really_probe(struct device *dev, const struct device_driver *drv) { bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) && !drv->suppress_bind_attrs; @@ -628,7 +628,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) } re_probe: - dev->driver = drv; + // FIXME - this cast should not be needed "soon" + dev->driver = (struct device_driver *)drv; /* If using pinctrl, bind pins now before probing */ ret = pinctrl_bind_pins(dev); @@ -727,7 +728,7 @@ done: /* * For initcall_debug, show the driver probe time. */ -static int really_probe_debug(struct device *dev, struct device_driver *drv) +static int really_probe_debug(struct device *dev, const struct device_driver *drv) { ktime_t calltime, rettime; int ret; @@ -774,7 +775,7 @@ void wait_for_device_probe(void) } EXPORT_SYMBOL_GPL(wait_for_device_probe); -static int __driver_probe_device(struct device_driver *drv, struct device *dev) +static int __driver_probe_device(const struct device_driver *drv, struct device *dev) { int ret = 0; @@ -819,7 +820,7 @@ static int __driver_probe_device(struct device_driver *drv, struct device *dev) * * If the device has a parent, runtime-resume the parent before driver probing. */ -static int driver_probe_device(struct device_driver *drv, struct device *dev) +static int driver_probe_device(const struct device_driver *drv, struct device *dev) { int trigger_count = atomic_read(&deferred_trigger_count); int ret; @@ -863,7 +864,7 @@ static int __init save_async_options(char *buf) } __setup("driver_async_probe=", save_async_options); -static bool driver_allows_async_probing(struct device_driver *drv) +static bool driver_allows_async_probing(const struct device_driver *drv) { switch (drv->probe_type) { case PROBE_PREFER_ASYNCHRONOUS: @@ -1117,7 +1118,7 @@ static void __device_driver_unlock(struct device *dev, struct device *parent) * Manually attach driver to a device. Will acquire both @dev lock and * @dev->parent lock if needed. Returns 0 on success, -ERR on failure. */ -int device_driver_attach(struct device_driver *drv, struct device *dev) +int device_driver_attach(const struct device_driver *drv, struct device *dev) { int ret; @@ -1137,7 +1138,7 @@ EXPORT_SYMBOL_GPL(device_driver_attach); static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie) { struct device *dev = _dev; - struct device_driver *drv; + const struct device_driver *drv; int ret; __device_driver_lock(dev, dev->parent); @@ -1153,7 +1154,7 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie) static int __driver_attach(struct device *dev, void *data) { - struct device_driver *drv = data; + const struct device_driver *drv = data; bool async = false; int ret; @@ -1226,9 +1227,10 @@ static int __driver_attach(struct device *dev, void *data) * returns 0 and the @dev->driver is set, we've found a * compatible pair. */ -int driver_attach(struct device_driver *drv) +int driver_attach(const struct device_driver *drv) { - return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); + /* The (void *) will be put back to const * in __driver_attach() */ + return bus_for_each_dev(drv->bus, NULL, (void *)drv, __driver_attach); } EXPORT_SYMBOL_GPL(driver_attach); @@ -1284,7 +1286,7 @@ static void __device_release_driver(struct device *dev, struct device *parent) } void device_release_driver_internal(struct device *dev, - struct device_driver *drv, + const struct device_driver *drv, struct device *parent) { __device_driver_lock(dev, parent); @@ -1333,7 +1335,7 @@ void device_driver_detach(struct device *dev) * driver_detach - detach driver from all devices it controls. * @drv: driver. */ -void driver_detach(struct device_driver *drv) +void driver_detach(const struct device_driver *drv) { struct device_private *dev_prv; struct device *dev; diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 3df0025d12aa..a2ce0ead06a6 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -85,7 +85,7 @@ static void group_close_release(struct device *dev, void *res) /* noop */ } -static struct devres_group * node_to_group(struct devres_node *node) +static struct devres_group *node_to_group(struct devres_node *node) { if (node->release == &group_open_release) return container_of(node, struct devres_group, node[0]); @@ -107,8 +107,8 @@ static bool check_dr_size(size_t size, size_t *tot_size) return true; } -static __always_inline struct devres * alloc_dr(dr_release_t release, - size_t size, gfp_t gfp, int nid) +static __always_inline struct devres *alloc_dr(dr_release_t release, + size_t size, gfp_t gfp, int nid) { size_t tot_size; struct devres *dr; @@ -283,8 +283,8 @@ static struct devres *find_dr(struct device *dev, dr_release_t release, * RETURNS: * Pointer to found devres, NULL if not found. */ -void * devres_find(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) +void *devres_find(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data) { struct devres *dr; unsigned long flags; @@ -313,8 +313,8 @@ EXPORT_SYMBOL_GPL(devres_find); * RETURNS: * Pointer to found or added devres. */ -void * devres_get(struct device *dev, void *new_res, - dr_match_t match, void *match_data) +void *devres_get(struct device *dev, void *new_res, + dr_match_t match, void *match_data) { struct devres *new_dr = container_of(new_res, struct devres, data); struct devres *dr; @@ -349,8 +349,8 @@ EXPORT_SYMBOL_GPL(devres_get); * RETURNS: * Pointer to removed devres on success, NULL if not found. */ -void * devres_remove(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) +void *devres_remove(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data) { struct devres *dr; unsigned long flags; @@ -549,7 +549,7 @@ int devres_release_all(struct device *dev) * RETURNS: * ID of the new group, NULL on failure. */ -void * devres_open_group(struct device *dev, void *id, gfp_t gfp) +void *devres_open_group(struct device *dev, void *id, gfp_t gfp) { struct devres_group *grp; unsigned long flags; @@ -567,6 +567,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) grp->id = grp; if (id) grp->id = id; + grp->color = 0; spin_lock_irqsave(&dev->devres_lock, flags); add_dr(dev, &grp->node[0]); @@ -576,7 +577,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) EXPORT_SYMBOL_GPL(devres_open_group); /* Find devres group with ID @id. If @id is NULL, look for the latest. */ -static struct devres_group * find_group(struct device *dev, void *id) +static struct devres_group *find_group(struct device *dev, void *id) { struct devres_node *node; @@ -896,9 +897,12 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp) /* * Otherwise: allocate new, larger chunk. We need to allocate before * taking the lock as most probably the caller uses GFP_KERNEL. + * alloc_dr() will call check_dr_size() to reserve extra memory + * for struct devres automatically, so size @new_size user request + * is delivered to it directly as devm_kmalloc() does. */ new_dr = alloc_dr(devm_kmalloc_release, - total_new_size, gfp, dev_to_node(dev)); + new_size, gfp, dev_to_node(dev)); if (!new_dr) return NULL; @@ -1222,7 +1226,11 @@ EXPORT_SYMBOL_GPL(__devm_alloc_percpu); */ void devm_free_percpu(struct device *dev, void __percpu *pdata) { - WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, + /* + * Use devres_release() to prevent memory leakage as + * devm_free_pages() does. + */ + WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match, (__force void *)pdata)); } EXPORT_SYMBOL_GPL(devm_free_percpu); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index c8436c26ed6a..88c6fd1f1992 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -148,7 +148,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); * if it does. If the callback returns non-zero, this function will * return to the caller and not iterate over any more devices. */ -struct device *driver_find_device(struct device_driver *drv, +struct device *driver_find_device(const struct device_driver *drv, struct device *start, const void *data, int (*match)(struct device *dev, const void *data)) { @@ -173,7 +173,7 @@ EXPORT_SYMBOL_GPL(driver_find_device); * @drv: driver. * @attr: driver attribute descriptor. */ -int driver_create_file(struct device_driver *drv, +int driver_create_file(const struct device_driver *drv, const struct driver_attribute *attr) { int error; @@ -191,7 +191,7 @@ EXPORT_SYMBOL_GPL(driver_create_file); * @drv: driver. * @attr: driver attribute descriptor. */ -void driver_remove_file(struct device_driver *drv, +void driver_remove_file(const struct device_driver *drv, const struct driver_attribute *attr) { if (drv) @@ -199,13 +199,13 @@ void driver_remove_file(struct device_driver *drv, } EXPORT_SYMBOL_GPL(driver_remove_file); -int driver_add_groups(struct device_driver *drv, +int driver_add_groups(const struct device_driver *drv, const struct attribute_group **groups) { return sysfs_create_groups(&drv->p->kobj, groups); } -void driver_remove_groups(struct device_driver *drv, +void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups) { sysfs_remove_groups(&drv->p->kobj, groups); diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 5ca00e02fe82..a03701674265 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -37,6 +37,13 @@ config FW_LOADER_DEBUG SHA256 checksums to the kernel log for each firmware file that is loaded. +config RUST_FW_LOADER_ABSTRACTIONS + bool "Rust Firmware Loader abstractions" + depends on RUST + depends on FW_LOADER=y + help + This enables the Rust abstractions for the firmware loader API. + if FW_LOADER config FW_LOADER_PAGED_BUF diff --git a/drivers/base/isa.c b/drivers/base/isa.c index e23d0b49a793..bfd9215c9070 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -23,7 +23,7 @@ struct isa_dev { #define to_isa_dev(x) container_of((x), struct isa_dev, dev) -static int isa_bus_match(struct device *dev, struct device_driver *driver) +static int isa_bus_match(struct device *dev, const struct device_driver *driver) { struct isa_driver *isa_driver = to_isa_driver(driver); diff --git a/drivers/base/module.c b/drivers/base/module.c index a1b55da07127..7af224e6914a 100644 --- a/drivers/base/module.c +++ b/drivers/base/module.c @@ -9,7 +9,7 @@ #include <linux/string.h> #include "base.h" -static char *make_driver_name(struct device_driver *drv) +static char *make_driver_name(const struct device_driver *drv) { char *driver_name; @@ -30,7 +30,7 @@ static void module_create_drivers_dir(struct module_kobject *mk) mutex_unlock(&drivers_dir_mutex); } -int module_add_driver(struct module *mod, struct device_driver *drv) +int module_add_driver(struct module *mod, const struct device_driver *drv) { char *driver_name; struct module_kobject *mk = NULL; @@ -89,7 +89,7 @@ out: return ret; } -void module_remove_driver(struct device_driver *drv) +void module_remove_driver(const struct device_driver *drv) { struct module_kobject *mk = NULL; char *driver_name; diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 10c577963418..4c3ee6521ba5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -608,7 +608,7 @@ int platform_device_add_resources(struct platform_device *pdev, struct resource *r = NULL; if (res) { - r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); + r = kmemdup_array(res, num, sizeof(*r), GFP_KERNEL); if (!r) return -ENOMEM; } @@ -1122,7 +1122,7 @@ static int platform_legacy_resume(struct device *dev) int platform_pm_suspend(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1140,7 +1140,7 @@ int platform_pm_suspend(struct device *dev) int platform_pm_resume(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1162,7 +1162,7 @@ int platform_pm_resume(struct device *dev) int platform_pm_freeze(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1180,7 +1180,7 @@ int platform_pm_freeze(struct device *dev) int platform_pm_thaw(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1198,7 +1198,7 @@ int platform_pm_thaw(struct device *dev) int platform_pm_poweroff(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1216,7 +1216,7 @@ int platform_pm_poweroff(struct device *dev) int platform_pm_restore(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1332,7 +1332,7 @@ __ATTRIBUTE_GROUPS(platform_dev); * and compare it against the name of the driver. Return whether they match * or not. */ -static int platform_match(struct device *dev, struct device_driver *drv) +static int platform_match(struct device *dev, const struct device_driver *drv) { struct platform_device *pdev = to_platform_device(dev); struct platform_driver *pdrv = to_platform_driver(drv); @@ -1420,14 +1420,8 @@ static void platform_remove(struct device *_dev) struct platform_driver *drv = to_platform_driver(_dev->driver); struct platform_device *dev = to_platform_device(_dev); - if (drv->remove_new) { - drv->remove_new(dev); - } else if (drv->remove) { - int ret = drv->remove(dev); - - if (ret) - dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n"); - } + if (drv->remove) + drv->remove(dev); dev_pm_domain_detach(_dev, true); } |