diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-21 13:34:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-21 13:34:15 -0700 |
commit | 241590e5a1d1b6219c8d3045c167f2fbcc076cbb (patch) | |
tree | 39a624fb0adfe08007fe772987a494b2695cf68a /drivers | |
parent | bb41fe35dce709ea8f91d313c558ee6c68f705ef (diff) | |
parent | 6aeb8850e0f39869d43768603a75c0431562a429 (diff) | |
download | lwn-241590e5a1d1b6219c8d3045c167f2fbcc076cbb.tar.gz lwn-241590e5a1d1b6219c8d3045c167f2fbcc076cbb.zip |
Merge tag 'driver-core-6.9-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 and kernfs changes for 6.9-rc1.
Nothing all that crazy here, just some good updates that include:
- automatic attribute group hiding from Dan Williams (he fixed up my
horrible attempt at doing this.)
- kobject lock contention fixes from Eric Dumazet
- driver core cleanups from Andy
- kernfs rcu work from Tejun
- fw_devlink changes to resolve some reported issues
- other minor changes, all details in the shortlog
All of these have been in linux-next for a long time with no reported
issues"
* tag 'driver-core-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (28 commits)
device: core: Log warning for devices pending deferred probe on timeout
driver: core: Use dev_* instead of pr_* so device metadata is added
driver: core: Log probe failure as error and with device metadata
of: property: fw_devlink: Add support for "post-init-providers" property
driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
driver core: Adds flags param to fwnode_link_add()
debugfs: fix wait/cancellation handling during remove
device property: Don't use "proxy" headers
device property: Move enum dev_dma_attr to fwnode.h
driver core: Move fw_devlink stuff to where it belongs
driver core: Drop unneeded 'extern' keyword in fwnode.h
firmware_loader: Suppress warning on FW_OPT_NO_WARN flag
sysfs:Addresses documentation in sysfs_merge_group and sysfs_unmerge_group.
firmware_loader: introduce __free() cleanup hanler
platform-msi: Remove usage of the deprecated ida_simple_xx() API
sysfs: Introduce DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE()
sysfs: Document new "group visible" helpers
sysfs: Fix crash on empty group attributes array
sysfs: Introduce a mechanism to hide static attribute_groups
sysfs: Introduce a mechanism to hide static attribute_groups
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/component.c | 4 | ||||
-rw-r--r-- | drivers/base/core.c | 72 | ||||
-rw-r--r-- | drivers/base/cpu.c | 2 | ||||
-rw-r--r-- | drivers/base/dd.c | 32 | ||||
-rw-r--r-- | drivers/base/firmware_loader/main.c | 16 | ||||
-rw-r--r-- | drivers/base/platform-msi.c | 6 | ||||
-rw-r--r-- | drivers/base/property.c | 67 | ||||
-rw-r--r-- | drivers/base/swnode.c | 13 | ||||
-rw-r--r-- | drivers/firmware/efi/sysfb_efi.c | 2 | ||||
-rw-r--r-- | drivers/of/property.c | 15 |
10 files changed, 131 insertions, 98 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index 7dbf14a1d915..741497324d78 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -751,7 +751,7 @@ static int __component_add(struct device *dev, const struct component_ops *ops, * component_bind_all(). See also &struct component_ops. * * @subcomponent must be nonzero and is used to differentiate between multiple - * components registerd on the same device @dev. These components are match + * components registered on the same device @dev. These components are match * using component_match_add_typed(). * * The component needs to be unregistered at driver unload/disconnect by @@ -781,7 +781,7 @@ EXPORT_SYMBOL_GPL(component_add_typed); * The component needs to be unregistered at driver unload/disconnect by * calling component_del(). * - * See also component_add_typed() for a variant that allows multipled different + * See also component_add_typed() for a variant that allows multiple different * components on the same device. */ int component_add(struct device *dev, const struct component_ops *ops) diff --git a/drivers/base/core.c b/drivers/base/core.c index 9828da9b933c..b93f3c5716ae 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -92,12 +92,13 @@ static int __fwnode_link_add(struct fwnode_handle *con, return 0; } -int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) +int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup, + u8 flags) { int ret; mutex_lock(&fwnode_link_lock); - ret = __fwnode_link_add(con, sup, 0); + ret = __fwnode_link_add(con, sup, flags); mutex_unlock(&fwnode_link_lock); return ret; } @@ -1011,7 +1012,8 @@ static struct fwnode_handle *fwnode_links_check_suppliers( return NULL; list_for_each_entry(link, &fwnode->suppliers, c_hook) - if (!(link->flags & FWLINK_FLAG_CYCLE)) + if (!(link->flags & + (FWLINK_FLAG_CYCLE | FWLINK_FLAG_IGNORE))) return link->supplier; return NULL; @@ -1871,6 +1873,7 @@ static void fw_devlink_unblock_consumers(struct device *dev) device_links_write_unlock(); } +#define get_dev_from_fwnode(fwnode) get_device((fwnode)->dev) static bool fwnode_init_without_drv(struct fwnode_handle *fwnode) { @@ -1902,6 +1905,63 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode) } /** + * fwnode_is_ancestor_of - Test if @ancestor is ancestor of @child + * @ancestor: Firmware which is tested for being an ancestor + * @child: Firmware which is tested for being the child + * + * A node is considered an ancestor of itself too. + * + * Return: true if @ancestor is an ancestor of @child. Otherwise, returns false. + */ +static bool fwnode_is_ancestor_of(const struct fwnode_handle *ancestor, + const struct fwnode_handle *child) +{ + struct fwnode_handle *parent; + + if (IS_ERR_OR_NULL(ancestor)) + return false; + + if (child == ancestor) + return true; + + fwnode_for_each_parent_node(child, parent) { + if (parent == ancestor) { + fwnode_handle_put(parent); + return true; + } + } + return false; +} + +/** + * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode + * @fwnode: firmware node + * + * Given a firmware node (@fwnode), this function finds its closest ancestor + * firmware node that has a corresponding struct device and returns that struct + * device. + * + * The caller is responsible for calling put_device() on the returned device + * pointer. + * + * Return: a pointer to the device of the @fwnode's closest ancestor. + */ +static struct device *fwnode_get_next_parent_dev(const struct fwnode_handle *fwnode) +{ + struct fwnode_handle *parent; + struct device *dev; + + fwnode_for_each_parent_node(fwnode, parent) { + dev = get_dev_from_fwnode(parent); + if (dev) { + fwnode_handle_put(parent); + return dev; + } + } + return NULL; +} + +/** * __fw_devlink_relax_cycles - Relax and mark dependency cycles. * @con: Potential consumer device. * @sup_handle: Potential supplier's fwnode. @@ -1962,6 +2022,9 @@ static bool __fw_devlink_relax_cycles(struct device *con, } list_for_each_entry(link, &sup_handle->suppliers, c_hook) { + if (link->flags & FWLINK_FLAG_IGNORE) + continue; + if (__fw_devlink_relax_cycles(con, link->supplier)) { __fwnode_link_cycle(link); ret = true; @@ -2040,6 +2103,9 @@ static int fw_devlink_create_devlink(struct device *con, int ret = 0; u32 flags; + if (link->flags & FWLINK_FLAG_IGNORE) + return 0; + if (con->fwnode == link->consumer) flags = fw_devlink_get_flags(link->flags); else diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index f5a6bffce518..56fba44ba391 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -366,7 +366,7 @@ static int cpu_uevent(const struct device *dev, struct kobj_uevent_env *env) } #endif -struct bus_type cpu_subsys = { +const struct bus_type cpu_subsys = { .name = "cpu", .dev_name = "cpu", .match = cpu_subsys_match, diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 85152537dbf1..83d352394fdf 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -313,7 +313,7 @@ static void deferred_probe_timeout_work_func(struct work_struct *work) mutex_lock(&deferred_probe_mutex); list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe) - dev_info(p->device, "deferred probe pending: %s", p->deferred_probe_reason ?: "(reason unknown)\n"); + dev_warn(p->device, "deferred probe pending: %s", p->deferred_probe_reason ?: "(reason unknown)\n"); mutex_unlock(&deferred_probe_mutex); fw_devlink_probing_done(); @@ -397,13 +397,12 @@ bool device_is_bound(struct device *dev) static void driver_bound(struct device *dev) { if (device_is_bound(dev)) { - pr_warn("%s: device %s already bound\n", - __func__, kobject_name(&dev->kobj)); + dev_warn(dev, "%s: device already bound\n", __func__); return; } - pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name, - __func__, dev_name(dev)); + dev_dbg(dev, "driver: '%s': %s: bound to device\n", dev->driver->name, + __func__); klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); device_links_driver_bound(dev); @@ -587,13 +586,13 @@ static int call_driver_probe(struct device *dev, struct device_driver *drv) break; case -ENODEV: case -ENXIO: - pr_debug("%s: probe of %s rejects match %d\n", - drv->name, dev_name(dev), ret); + dev_dbg(dev, "probe with driver %s rejects match %d\n", + drv->name, ret); break; default: /* driver matched but the probe failed */ - pr_warn("%s: probe of %s failed with error %d\n", - drv->name, dev_name(dev), ret); + dev_err(dev, "probe with driver %s failed with error %d\n", + drv->name, ret); break; } @@ -620,8 +619,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) if (link_ret == -EPROBE_DEFER) return link_ret; - pr_debug("bus: '%s': %s: probing driver %s with device %s\n", - drv->bus->name, __func__, drv->name, dev_name(dev)); + dev_dbg(dev, "bus: '%s': %s: probing driver %s with device\n", + drv->bus->name, __func__, drv->name); if (!list_empty(&dev->devres_head)) { dev_crit(dev, "Resources present before probing\n"); ret = -EBUSY; @@ -644,8 +643,7 @@ re_probe: ret = driver_sysfs_add(dev); if (ret) { - pr_err("%s: driver_sysfs_add(%s) failed\n", - __func__, dev_name(dev)); + dev_err(dev, "%s: driver_sysfs_add failed\n", __func__); goto sysfs_failed; } @@ -706,8 +704,8 @@ re_probe: dev->pm_domain->sync(dev); driver_bound(dev); - pr_debug("bus: '%s': %s: bound device %s to driver %s\n", - drv->bus->name, __func__, dev_name(dev), drv->name); + dev_dbg(dev, "bus: '%s': %s: bound device to driver %s\n", + drv->bus->name, __func__, drv->name); goto done; dev_sysfs_state_synced_failed: @@ -786,8 +784,8 @@ static int __driver_probe_device(struct device_driver *drv, struct device *dev) return -EBUSY; dev->can_match = true; - pr_debug("bus: '%s': %s: matched device %s with driver %s\n", - drv->bus->name, __func__, dev_name(dev), drv->name); + dev_dbg(dev, "bus: '%s': %s: matched device with driver %s\n", + drv->bus->name, __func__, drv->name); pm_runtime_get_suppliers(dev); if (dev->parent) diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index ea28102d421e..da8ca01d011c 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -551,12 +551,16 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv, file_size_ptr, READING_FIRMWARE); if (rc < 0) { - if (rc != -ENOENT) - dev_warn(device, "loading %s failed with error %d\n", - path, rc); - else - dev_dbg(device, "loading %s failed for no such file or directory.\n", - path); + if (!(fw_priv->opt_flags & FW_OPT_NO_WARN)) { + if (rc != -ENOENT) + dev_warn(device, + "loading %s failed with error %d\n", + path, rc); + else + dev_dbg(device, + "loading %s failed for no such file or directory.\n", + path); + } continue; } size = rc; diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 0d01890160f3..11f5fdf65b9e 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -174,8 +174,8 @@ static int platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec, if (!datap) return -ENOMEM; - datap->devid = ida_simple_get(&platform_msi_devid_ida, - 0, 1 << DEV_ID_SHIFT, GFP_KERNEL); + datap->devid = ida_alloc_max(&platform_msi_devid_ida, + (1 << DEV_ID_SHIFT) - 1, GFP_KERNEL); if (datap->devid < 0) { err = datap->devid; kfree(datap); @@ -193,7 +193,7 @@ static void platform_msi_free_priv_data(struct device *dev) struct platform_msi_priv_data *data = dev->msi.data->platform_data; dev->msi.data->platform_data = NULL; - ida_simple_remove(&platform_msi_devid_ida, data->devid); + ida_free(&platform_msi_devid_ida, data->devid); kfree(data); } diff --git a/drivers/base/property.c b/drivers/base/property.c index a1b01ab42052..7324a704a9a1 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -7,15 +7,16 @@ * Mika Westerberg <mika.westerberg@linux.intel.com> */ -#include <linux/acpi.h> +#include <linux/device.h> +#include <linux/err.h> #include <linux/export.h> -#include <linux/kernel.h> +#include <linux/kconfig.h> #include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_graph.h> -#include <linux/of_irq.h> #include <linux/property.h> #include <linux/phy.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/types.h> struct fwnode_handle *__dev_fwnode(struct device *dev) { @@ -700,34 +701,6 @@ struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode) EXPORT_SYMBOL_GPL(fwnode_get_next_parent); /** - * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode - * @fwnode: firmware node - * - * Given a firmware node (@fwnode), this function finds its closest ancestor - * firmware node that has a corresponding struct device and returns that struct - * device. - * - * The caller is responsible for calling put_device() on the returned device - * pointer. - * - * Return: a pointer to the device of the @fwnode's closest ancestor. - */ -struct device *fwnode_get_next_parent_dev(const struct fwnode_handle *fwnode) -{ - struct fwnode_handle *parent; - struct device *dev; - - fwnode_for_each_parent_node(fwnode, parent) { - dev = get_dev_from_fwnode(parent); - if (dev) { - fwnode_handle_put(parent); - return dev; - } - } - return NULL; -} - -/** * fwnode_count_parents - Return the number of parents a node has * @fwnode: The node the parents of which are to be counted * @@ -774,34 +747,6 @@ struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode, EXPORT_SYMBOL_GPL(fwnode_get_nth_parent); /** - * fwnode_is_ancestor_of - Test if @ancestor is ancestor of @child - * @ancestor: Firmware which is tested for being an ancestor - * @child: Firmware which is tested for being the child - * - * A node is considered an ancestor of itself too. - * - * Return: true if @ancestor is an ancestor of @child. Otherwise, returns false. - */ -bool fwnode_is_ancestor_of(const struct fwnode_handle *ancestor, const struct fwnode_handle *child) -{ - struct fwnode_handle *parent; - - if (IS_ERR_OR_NULL(ancestor)) - return false; - - if (child == ancestor) - return true; - - fwnode_for_each_parent_node(child, parent) { - if (parent == ancestor) { - fwnode_handle_put(parent); - return true; - } - } - return false; -} - -/** * fwnode_get_next_child_node - Return the next child node handle for a node * @fwnode: Firmware node to find the next child node for. * @child: Handle to one of the node's child nodes or a %NULL handle. diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 36512fb75a20..eb6eb25b343b 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -6,10 +6,21 @@ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> */ +#include <linux/container_of.h> #include <linux/device.h> -#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/idr.h> +#include <linux/init.h> +#include <linux/kobject.h> +#include <linux/kstrtox.h> +#include <linux/list.h> #include <linux/property.h> #include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/sysfs.h> +#include <linux/types.h> #include "base.h" diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index 456d0e5eaf78..cc807ed35aed 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -336,7 +336,7 @@ static int efifb_add_links(struct fwnode_handle *fwnode) if (!sup_np) return 0; - fwnode_link_add(fwnode, of_fwnode_handle(sup_np)); + fwnode_link_add(fwnode, of_fwnode_handle(sup_np), 0); of_node_put(sup_np); return 0; diff --git a/drivers/of/property.c b/drivers/of/property.c index f61de622f870..a6358ee99b74 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -1072,7 +1072,8 @@ of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, } static void of_link_to_phandle(struct device_node *con_np, - struct device_node *sup_np) + struct device_node *sup_np, + u8 flags) { struct device_node *tmp_np = of_node_get(sup_np); @@ -1091,7 +1092,7 @@ static void of_link_to_phandle(struct device_node *con_np, tmp_np = of_get_next_parent(tmp_np); } - fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np)); + fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np), flags); } /** @@ -1204,6 +1205,8 @@ static struct device_node *parse_##fname(struct device_node *np, \ * to a struct device, implement this ops so fw_devlink can use it * to find the true consumer. * @optional: Describes whether a supplier is mandatory or not + * @fwlink_flags: Optional fwnode link flags to use when creating a fwnode link + * for this property. * * Returns: * parse_prop() return values are @@ -1216,6 +1219,7 @@ struct supplier_bindings { const char *prop_name, int index); struct device_node *(*get_con_dev)(struct device_node *np); bool optional; + u8 fwlink_flags; }; DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells") @@ -1247,6 +1251,7 @@ DEFINE_SIMPLE_PROP(leds, "leds", NULL) DEFINE_SIMPLE_PROP(backlight, "backlight", NULL) DEFINE_SIMPLE_PROP(panel, "panel", NULL) DEFINE_SIMPLE_PROP(msi_parent, "msi-parent", "#msi-cells") +DEFINE_SIMPLE_PROP(post_init_providers, "post-init-providers", NULL) DEFINE_SUFFIX_PROP(regulators, "-supply", NULL) DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells") @@ -1357,6 +1362,10 @@ static const struct supplier_bindings of_supplier_bindings[] = { { .parse_prop = parse_regulators, }, { .parse_prop = parse_gpio, }, { .parse_prop = parse_gpios, }, + { + .parse_prop = parse_post_init_providers, + .fwlink_flags = FWLINK_FLAG_IGNORE, + }, {} }; @@ -1401,7 +1410,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name) : of_node_get(con_np); matched = true; i++; - of_link_to_phandle(con_dev_np, phandle); + of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags); of_node_put(phandle); of_node_put(con_dev_np); } |