1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

Driver core and debugfs updates

Here is the big set of driver core and debugfs updates for 6.14-rc1.
 It's coming late in the merge cycle as there are a number of merge
 conflicts with your tree now, and I wanted to make sure they were
 working properly.  To resolve them, look in linux-next, and I will send
 the "fixup" patch as a response to the pull request.
 
 Included in here is a bunch of driver core, PCI, OF, and platform rust
 bindings (all acked by the different subsystem maintainers), hence the
 merge conflict with the rust tree, and some driver core api updates to
 mark things as const, which will also require some fixups due to new
 stuff coming in through other trees in this merge window.
 
 There are also a bunch of debugfs updates from Al, and there is at least
 one user that does have a regression with these, but Al is working on
 tracking down the fix for it.  In my use (and everyone else's linux-next
 use), it does not seem like a big issue at the moment.
 
 Here's a short list of the things in here:
   - driver core bindings for PCI, platform, OF, and some i/o functions.
     We are almost at the "write a real driver in rust" stage now,
     depending on what you want to do.
   - misc device rust bindings and a sample driver to show how to use
     them
   - debugfs cleanups in the fs as well as the users of the fs api for
     places where drivers got it wrong or were unnecessarily doing things
     in complex ways.
   - driver core const work, making more of the api take const * for
     different parameters to make the rust bindings easier overall.
   - other small fixes and updates
 
 All of these have been in linux-next with all of the aforementioned
 merge conflicts, and the one debugfs issue, which looks to be resolved
 "soon".
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZ5koPA8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ymFHACfT5acDKf2Bov2Lc/5u3vBW/R6ChsAnj+LmgVI
 hcDSPodj4szR40RRnzBd
 =u5Ey
 -----END PGP SIGNATURE-----

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

Pull driver core and debugfs updates from Greg KH:
 "Here is the big set of driver core and debugfs updates for 6.14-rc1.

  Included in here is a bunch of driver core, PCI, OF, and platform rust
  bindings (all acked by the different subsystem maintainers), hence the
  merge conflict with the rust tree, and some driver core api updates to
  mark things as const, which will also require some fixups due to new
  stuff coming in through other trees in this merge window.

  There are also a bunch of debugfs updates from Al, and there is at
  least one user that does have a regression with these, but Al is
  working on tracking down the fix for it. In my use (and everyone
  else's linux-next use), it does not seem like a big issue at the
  moment.

  Here's a short list of the things in here:

   - driver core rust bindings for PCI, platform, OF, and some i/o
     functions.

     We are almost at the "write a real driver in rust" stage now,
     depending on what you want to do.

   - misc device rust bindings and a sample driver to show how to use
     them

   - debugfs cleanups in the fs as well as the users of the fs api for
     places where drivers got it wrong or were unnecessarily doing
     things in complex ways.

   - driver core const work, making more of the api take const * for
     different parameters to make the rust bindings easier overall.

   - other small fixes and updates

  All of these have been in linux-next with all of the aforementioned
  merge conflicts, and the one debugfs issue, which looks to be resolved
  "soon""

* tag 'driver-core-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (95 commits)
  rust: device: Use as_char_ptr() to avoid explicit cast
  rust: device: Replace CString with CStr in property_present()
  devcoredump: Constify 'struct bin_attribute'
  devcoredump: Define 'struct bin_attribute' through macro
  rust: device: Add property_present()
  saner replacement for debugfs_rename()
  orangefs-debugfs: don't mess with ->d_name
  octeontx2: don't mess with ->d_parent or ->d_parent->d_name
  arm_scmi: don't mess with ->d_parent->d_name
  slub: don't mess with ->d_name
  sof-client-ipc-flood-test: don't mess with ->d_name
  qat: don't mess with ->d_name
  xhci: don't mess with ->d_iname
  mtu3: don't mess wiht ->d_iname
  greybus/camera - stop messing with ->d_iname
  mediatek: stop messing with ->d_iname
  netdevsim: don't embed file_operations into your structs
  b43legacy: make use of debugfs_get_aux()
  b43: stop embedding struct file_operations into their objects
  carl9170: stop embedding file_operations into their objects
  ...
This commit is contained in:
Linus Torvalds 2025-01-28 12:25:12 -08:00
commit 2ab002c755
121 changed files with 3255 additions and 995 deletions

View file

@ -211,18 +211,16 @@ seq_file content.
There are a couple of other directory-oriented helper functions::
struct dentry *debugfs_rename(struct dentry *old_dir,
struct dentry *old_dentry,
struct dentry *new_dir,
const char *new_name);
struct dentry *debugfs_change_name(struct dentry *dentry,
const char *fmt, ...);
struct dentry *debugfs_create_symlink(const char *name,
struct dentry *parent,
const char *target);
A call to debugfs_rename() will give a new name to an existing debugfs
file, possibly in a different directory. The new_name must not exist prior
to the call; the return value is old_dentry with updated information.
A call to debugfs_change_name() will give a new name to an existing debugfs
file, always in the same directory. The new_name must not exist prior
to the call; the return value is 0 on success and -E... on failuer.
Symbolic links can be created with debugfs_create_symlink().
There is one important thing that all debugfs users must take into account:

View file

@ -312,6 +312,7 @@ Code Seq# Include File Comments
<mailto:oe@port.de>
'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
'|' 00-7F linux/media.h
'|' 80-9F samples/ Any sample and example drivers
0x80 00-1F linux/fb.h
0x81 00-1F linux/vduse.h
0x89 00-06 arch/x86/include/asm/sockios.h

View file

@ -5366,6 +5366,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
F: drivers/char/
F: drivers/misc/
F: include/linux/miscdevice.h
F: samples/rust/rust_misc_device.rs
X: drivers/char/agp/
X: drivers/char/hw_random/
X: drivers/char/ipmi/
@ -7091,6 +7092,7 @@ F: include/linux/component.h
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
R: "Rafael J. Wysocki" <rafael@kernel.org>
R: Danilo Krummrich <dakr@kernel.org>
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
F: Documentation/core-api/kobject.rst
@ -7101,8 +7103,14 @@ F: include/linux/debugfs.h
F: include/linux/fwnode.h
F: include/linux/kobj*
F: include/linux/property.h
F: include/linux/sysfs.h
F: lib/kobj*
F: rust/kernel/device.rs
F: rust/kernel/device_id.rs
F: rust/kernel/devres.rs
F: rust/kernel/driver.rs
F: rust/kernel/platform.rs
F: samples/rust/rust_driver_platform.rs
DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS)
M: Nishanth Menon <nm@ti.com>
@ -17632,6 +17640,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
F: Documentation/ABI/testing/sysfs-firmware-ofw
F: drivers/of/
F: include/linux/of*.h
F: rust/kernel/of.rs
F: scripts/dtc/
F: tools/testing/selftests/dt/
K: of_overlay_notifier_
@ -18232,6 +18241,8 @@ F: include/asm-generic/pci*
F: include/linux/of_pci.h
F: include/linux/pci*
F: include/uapi/linux/pci*
F: rust/kernel/pci.rs
F: samples/rust/rust_driver_pci.rs
PCIE BANDWIDTH CONTROLLER
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
@ -19830,6 +19841,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
F: Documentation/RCU/
F: include/linux/rcu*
F: kernel/rcu/
F: rust/kernel/sync/rcu.rs
X: Documentation/RCU/torture.rst
X: include/linux/srcu*.h
X: kernel/rcu/srcu*.c

View file

@ -195,7 +195,7 @@ void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
unsigned long offset, unsigned long maxsize);
#define ecardm_iounmap(__ec, __addr) devm_iounmap(&(__ec)->dev, __addr)
extern struct bus_type ecard_bus_type;
extern const struct bus_type ecard_bus_type;
#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)

View file

@ -1124,7 +1124,7 @@ static int ecard_match(struct device *_dev, const struct device_driver *_drv)
return ret;
}
struct bus_type ecard_bus_type = {
const struct bus_type ecard_bus_type = {
.name = "ecard",
.dev_groups = ecard_dev_groups,
.match = ecard_match,

View file

@ -815,7 +815,7 @@ static int opal_add_one_export(struct kobject *parent, const char *export_name,
sysfs_bin_attr_init(attr);
attr->attr.name = name;
attr->attr.mode = 0400;
attr->read = sysfs_bin_attr_simple_read;
attr->read_new = sysfs_bin_attr_simple_read;
attr->private = __va(vals[0]);
attr->size = vals[1];

View file

@ -419,13 +419,13 @@ struct vio_remove_node_data {
u64 node;
};
static int vio_md_node_match(struct device *dev, void *arg)
static int vio_md_node_match(struct device *dev, const void *arg)
{
struct vio_dev *vdev = to_vio_dev(dev);
struct vio_remove_node_data *node_data;
const struct vio_remove_node_data *node_data;
u64 node;
node_data = (struct vio_remove_node_data *)arg;
node_data = (const struct vio_remove_node_data *)arg;
node = vio_vdev_node(node_data->hp, vdev);

View file

@ -1138,6 +1138,7 @@ static void blkcg_fill_root_iostats(void)
blkg_iostat_set(&blkg->iostat.cur, &tmp);
u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
}
class_dev_iter_exit(&iter);
}
static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s)

View file

@ -354,7 +354,7 @@ static struct device *next_device(struct klist_iter *i)
* count in the supplied callback.
*/
int bus_for_each_dev(const struct bus_type *bus, struct device *start,
void *data, int (*fn)(struct device *, void *))
void *data, device_iter_t fn)
{
struct subsys_private *sp = bus_to_subsys(bus);
struct klist_iter i;
@ -402,9 +402,12 @@ struct device *bus_find_device(const struct bus_type *bus,
klist_iter_init_node(&sp->klist_devices, &i,
(start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
while ((dev = next_device(&i))) {
if (match(dev, data)) {
get_device(dev);
break;
}
}
klist_iter_exit(&i);
subsys_put(sp);
return dev;

View file

@ -323,8 +323,12 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class,
struct subsys_private *sp = class_to_subsys(class);
struct klist_node *start_knode = NULL;
if (!sp)
memset(iter, 0, sizeof(*iter));
if (!sp) {
pr_crit("%s: class %p was not registered yet\n",
__func__, class);
return;
}
if (start)
start_knode = &start->p->knode_class;
@ -351,6 +355,9 @@ struct device *class_dev_iter_next(struct class_dev_iter *iter)
struct klist_node *knode;
struct device *dev;
if (!iter->sp)
return NULL;
while (1) {
knode = klist_next(&iter->ki);
if (!knode)
@ -395,7 +402,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_exit);
* code. There's no locking restriction.
*/
int class_for_each_device(const struct class *class, const struct device *start,
void *data, int (*fn)(struct device *, void *))
void *data, device_iter_t fn)
{
struct subsys_private *sp = class_to_subsys(class);
struct class_dev_iter iter;
@ -594,30 +601,10 @@ EXPORT_SYMBOL_GPL(class_compat_unregister);
* a bus device
* @cls: the compatibility class
* @dev: the target bus device
* @device_link: an optional device to which a "device" link should be created
*/
int class_compat_create_link(struct class_compat *cls, struct device *dev,
struct device *device_link)
int class_compat_create_link(struct class_compat *cls, struct device *dev)
{
int error;
error = sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev));
if (error)
return error;
/*
* Optionally add a "device" link (typically to the parent), as a
* class device would have one and we want to provide as much
* backwards compatibility as possible.
*/
if (device_link) {
error = sysfs_create_link(&dev->kobj, &device_link->kobj,
"device");
if (error)
sysfs_remove_link(cls->kobj, dev_name(dev));
}
return error;
return sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev));
}
EXPORT_SYMBOL_GPL(class_compat_create_link);
@ -626,14 +613,9 @@ EXPORT_SYMBOL_GPL(class_compat_create_link);
* a bus device
* @cls: the compatibility class
* @dev: the target bus device
* @device_link: an optional device to which a "device" link was previously
* created
*/
void class_compat_remove_link(struct class_compat *cls, struct device *dev,
struct device *device_link)
void class_compat_remove_link(struct class_compat *cls, struct device *dev)
{
if (device_link)
sysfs_remove_link(&dev->kobj, "device");
sysfs_remove_link(cls->kobj, dev_name(dev));
}
EXPORT_SYMBOL_GPL(class_compat_remove_link);

View file

@ -3980,7 +3980,7 @@ const char *device_get_devnode(const struct device *dev,
* other than 0, we break out and return that value.
*/
int device_for_each_child(struct device *parent, void *data,
int (*fn)(struct device *dev, void *data))
device_iter_t fn)
{
struct klist_iter i;
struct device *child;
@ -4010,7 +4010,7 @@ EXPORT_SYMBOL_GPL(device_for_each_child);
* other than 0, we break out and return that value.
*/
int device_for_each_child_reverse(struct device *parent, void *data,
int (*fn)(struct device *dev, void *data))
device_iter_t fn)
{
struct klist_iter i;
struct device *child;
@ -4043,14 +4043,14 @@ EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
* device_for_each_child_reverse_from();
*/
int device_for_each_child_reverse_from(struct device *parent,
struct device *from, const void *data,
int (*fn)(struct device *, const void *))
struct device *from, void *data,
device_iter_t fn)
{
struct klist_iter i;
struct device *child;
int error = 0;
if (!parent->p)
if (!parent || !parent->p)
return 0;
klist_iter_init_node(&parent->p->klist_children, &i,
@ -4079,8 +4079,8 @@ EXPORT_SYMBOL_GPL(device_for_each_child_reverse_from);
*
* NOTE: you will need to drop the reference with put_device() after use.
*/
struct device *device_find_child(struct device *parent, void *data,
int (*match)(struct device *dev, void *data))
struct device *device_find_child(struct device *parent, const void *data,
device_match_t match)
{
struct klist_iter i;
struct device *child;
@ -4089,62 +4089,17 @@ struct device *device_find_child(struct device *parent, void *data,
return NULL;
klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (match(child, data) && get_device(child))
while ((child = next_device(&i))) {
if (match(child, data)) {
get_device(child);
break;
}
}
klist_iter_exit(&i);
return child;
}
EXPORT_SYMBOL_GPL(device_find_child);
/**
* device_find_child_by_name - device iterator for locating a child device.
* @parent: parent struct device
* @name: name of the child device
*
* This is similar to the device_find_child() function above, but it
* returns a reference to a device that has the name @name.
*
* NOTE: you will need to drop the reference with put_device() after use.
*/
struct device *device_find_child_by_name(struct device *parent,
const char *name)
{
struct klist_iter i;
struct device *child;
if (!parent)
return NULL;
klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (sysfs_streq(dev_name(child), name) && get_device(child))
break;
klist_iter_exit(&i);
return child;
}
EXPORT_SYMBOL_GPL(device_find_child_by_name);
static int match_any(struct device *dev, void *unused)
{
return 1;
}
/**
* device_find_any_child - device iterator for locating a child device, if any.
* @parent: parent struct device
*
* This is similar to the device_find_child() function above, but it
* returns a reference to a child device, if any.
*
* NOTE: you will need to drop the reference with put_device() after use.
*/
struct device *device_find_any_child(struct device *parent)
{
return device_find_child(parent, NULL, match_any);
}
EXPORT_SYMBOL_GPL(device_find_any_child);
int __init devices_init(void)
{
devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
@ -5244,15 +5199,21 @@ int device_match_name(struct device *dev, const void *name)
}
EXPORT_SYMBOL_GPL(device_match_name);
int device_match_type(struct device *dev, const void *type)
{
return dev->type == type;
}
EXPORT_SYMBOL_GPL(device_match_type);
int device_match_of_node(struct device *dev, const void *np)
{
return dev->of_node == np;
return np && dev->of_node == np;
}
EXPORT_SYMBOL_GPL(device_match_of_node);
int device_match_fwnode(struct device *dev, const void *fwnode)
{
return dev_fwnode(dev) == fwnode;
return fwnode && dev_fwnode(dev) == fwnode;
}
EXPORT_SYMBOL_GPL(device_match_fwnode);
@ -5264,13 +5225,13 @@ EXPORT_SYMBOL_GPL(device_match_devt);
int device_match_acpi_dev(struct device *dev, const void *adev)
{
return ACPI_COMPANION(dev) == adev;
return adev && ACPI_COMPANION(dev) == adev;
}
EXPORT_SYMBOL(device_match_acpi_dev);
int device_match_acpi_handle(struct device *dev, const void *handle)
{
return ACPI_HANDLE(dev) == handle;
return handle && ACPI_HANDLE(dev) == handle;
}
EXPORT_SYMBOL(device_match_acpi_handle);

View file

@ -106,7 +106,7 @@ static void devcd_del(struct work_struct *wk)
}
static ssize_t devcd_data_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buffer, loff_t offset, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
@ -116,7 +116,7 @@ static ssize_t devcd_data_read(struct file *filp, struct kobject *kobj,
}
static ssize_t devcd_data_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buffer, loff_t offset, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
@ -132,19 +132,15 @@ static ssize_t devcd_data_write(struct file *filp, struct kobject *kobj,
return count;
}
static struct bin_attribute devcd_attr_data = {
.attr = { .name = "data", .mode = S_IRUSR | S_IWUSR, },
.size = 0,
.read = devcd_data_read,
.write = devcd_data_write,
};
static const struct bin_attribute devcd_attr_data =
__BIN_ATTR(data, 0600, devcd_data_read, devcd_data_write, 0);
static struct bin_attribute *devcd_dev_bin_attrs[] = {
static const struct bin_attribute *const devcd_dev_bin_attrs[] = {
&devcd_attr_data, NULL,
};
static const struct attribute_group devcd_dev_group = {
.bin_attrs = devcd_dev_bin_attrs,
.bin_attrs_new = devcd_dev_bin_attrs,
};
static const struct attribute_group *devcd_dev_groups[] = {
@ -186,9 +182,9 @@ static ssize_t disabled_show(const struct class *class, const struct class_attri
* mutex_lock(&devcd->mutex);
*
*
* In the above diagram, It looks like disabled_store() would be racing with parallely
* In the above diagram, it looks like disabled_store() would be racing with parallelly
* running devcd_del() and result in memory abort while acquiring devcd->mutex which
* is called after kfree of devcd memory after dropping its last reference with
* is called after kfree of devcd memory after dropping its last reference with
* put_device(). However, this will not happens as fn(dev, data) runs
* with its own reference to device via klist_node so it is not its last reference.
* so, above situation would not occur.
@ -285,6 +281,8 @@ static void devcd_free_sgtable(void *data)
* @offset: start copy from @offset@ bytes from the head of the data
* in the given scatterlist
* @data_len: the length of the data in the sg_table
*
* Returns: the number of bytes copied
*/
static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
size_t buf_len, void *data,

View file

@ -750,25 +750,38 @@ int __devm_add_action(struct device *dev, void (*action)(void *), void *data, co
EXPORT_SYMBOL_GPL(__devm_add_action);
/**
* devm_remove_action() - removes previously added custom action
* devm_remove_action_nowarn() - removes previously added custom action
* @dev: Device that owns the action
* @action: Function implementing the action
* @data: Pointer to data passed to @action implementation
*
* Removes instance of @action previously added by devm_add_action().
* Both action and data should match one of the existing entries.
*
* In contrast to devm_remove_action(), this function does not WARN() if no
* entry could have been found.
*
* This should only be used if the action is contained in an object with
* independent lifetime management, e.g. the Devres rust abstraction.
*
* Causing the warning from regular driver code most likely indicates an abuse
* of the devres API.
*
* Returns: 0 on success, -ENOENT if no entry could have been found.
*/
void devm_remove_action(struct device *dev, void (*action)(void *), void *data)
int devm_remove_action_nowarn(struct device *dev,
void (*action)(void *),
void *data)
{
struct action_devres devres = {
.data = data,
.action = action,
};
WARN_ON(devres_destroy(dev, devm_action_release, devm_action_match,
&devres));
return devres_destroy(dev, devm_action_release, devm_action_match,
&devres);
}
EXPORT_SYMBOL_GPL(devm_remove_action);
EXPORT_SYMBOL_GPL(devm_remove_action_nowarn);
/**
* devm_release_action() - release previously added custom action

View file

@ -115,7 +115,7 @@ EXPORT_SYMBOL_GPL(driver_set_override);
* Iterate over the @drv's list of devices calling @fn for each one.
*/
int driver_for_each_device(struct device_driver *drv, struct device *start,
void *data, int (*fn)(struct device *, void *))
void *data, device_iter_t fn)
{
struct klist_iter i;
struct device *dev;
@ -160,9 +160,12 @@ struct device *driver_find_device(const struct device_driver *drv,
klist_iter_init_node(&drv->p->klist_devices, &i,
(start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
while ((dev = next_device(&i))) {
if (match(dev, data)) {
get_device(dev);
break;
}
}
klist_iter_exit(&i);
return dev;
}

View file

@ -259,7 +259,7 @@ static void firmware_rw(struct fw_priv *fw_priv, char *buffer,
}
static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buffer, loff_t offset, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
@ -316,7 +316,7 @@ static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size)
* the driver as a firmware image.
**/
static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buffer, loff_t offset, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
@ -356,11 +356,11 @@ out:
return retval;
}
static struct bin_attribute firmware_attr_data = {
static const struct bin_attribute firmware_attr_data = {
.attr = { .name = "data", .mode = 0644 },
.size = 0,
.read = firmware_data_read,
.write = firmware_data_write,
.read_new = firmware_data_read,
.write_new = firmware_data_write,
};
static struct attribute *fw_dev_attrs[] = {
@ -374,14 +374,14 @@ static struct attribute *fw_dev_attrs[] = {
NULL
};
static struct bin_attribute *fw_dev_bin_attrs[] = {
static const struct bin_attribute *const fw_dev_bin_attrs[] = {
&firmware_attr_data,
NULL
};
static const struct attribute_group fw_dev_attr_group = {
.attrs = fw_dev_attrs,
.bin_attrs = fw_dev_bin_attrs,
.bin_attrs_new = fw_dev_bin_attrs,
#ifdef CONFIG_FW_UPLOAD
.is_visible = fw_upload_is_visible,
#endif

View file

@ -12,6 +12,7 @@ config TEST_ASYNC_DRIVER_PROBE
config DM_KUNIT_TEST
tristate "KUnit Tests for the device model" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
config DRIVER_PE_KUNIT_TEST
tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS

View file

@ -1,8 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#include <kunit/platform_device.h>
#include <kunit/resource.h>
#include <linux/device.h>
#include <linux/device/bus.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#define DEVICE_NAME "test"
@ -217,7 +220,43 @@ static struct kunit_suite platform_device_devm_test_suite = {
.test_cases = platform_device_devm_tests,
};
kunit_test_suite(platform_device_devm_test_suite);
static void platform_device_find_by_null_test(struct kunit *test)
{
struct platform_device *pdev;
int ret;
pdev = kunit_platform_device_alloc(test, DEVICE_NAME, PLATFORM_DEVID_NONE);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
ret = kunit_platform_device_add(test, pdev);
KUNIT_ASSERT_EQ(test, ret, 0);
KUNIT_EXPECT_PTR_EQ(test, of_find_device_by_node(NULL), NULL);
KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_of_node(&platform_bus_type, NULL), NULL);
KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_fwnode(&platform_bus_type, NULL), NULL);
KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_acpi_dev(&platform_bus_type, NULL), NULL);
KUNIT_EXPECT_FALSE(test, device_match_of_node(&pdev->dev, NULL));
KUNIT_EXPECT_FALSE(test, device_match_fwnode(&pdev->dev, NULL));
KUNIT_EXPECT_FALSE(test, device_match_acpi_dev(&pdev->dev, NULL));
KUNIT_EXPECT_FALSE(test, device_match_acpi_handle(&pdev->dev, NULL));
}
static struct kunit_case platform_device_match_tests[] = {
KUNIT_CASE(platform_device_find_by_null_test),
{}
};
static struct kunit_suite platform_device_match_test_suite = {
.name = "platform-device-match",
.test_cases = platform_device_match_tests,
};
kunit_test_suites(
&platform_device_devm_test_suite,
&platform_device_match_test_suite,
);
MODULE_DESCRIPTION("Test module for platform devices");
MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");

View file

@ -918,12 +918,12 @@ struct vdc_check_port_data {
char *type;
};
static int vdc_device_probed(struct device *dev, void *arg)
static int vdc_device_probed(struct device *dev, const void *arg)
{
struct vio_dev *vdev = to_vio_dev(dev);
struct vdc_check_port_data *port_data;
const struct vdc_check_port_data *port_data;
port_data = (struct vdc_check_port_data *)arg;
port_data = (const struct vdc_check_port_data *)arg;
if ((vdev->dev_no == port_data->dev_no) &&
(!(strcmp((char *)&vdev->type, port_data->type))) &&

View file

@ -22,8 +22,8 @@ struct fsl_mc_child_objs {
struct fsl_mc_obj_desc *child_array;
};
static bool fsl_mc_device_match(struct fsl_mc_device *mc_dev,
struct fsl_mc_obj_desc *obj_desc)
static bool fsl_mc_device_match(const struct fsl_mc_device *mc_dev,
const struct fsl_mc_obj_desc *obj_desc)
{
return mc_dev->obj_desc.id == obj_desc->id &&
strcmp(mc_dev->obj_desc.type, obj_desc->type) == 0;
@ -112,9 +112,9 @@ void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev,
}
EXPORT_SYMBOL_GPL(dprc_remove_devices);
static int __fsl_mc_device_match(struct device *dev, void *data)
static int __fsl_mc_device_match(struct device *dev, const void *data)
{
struct fsl_mc_obj_desc *obj_desc = data;
const struct fsl_mc_obj_desc *obj_desc = data;
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
return fsl_mc_device_match(mc_dev, obj_desc);

View file

@ -320,90 +320,90 @@ const struct bus_type fsl_mc_bus_type = {
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
struct device_type fsl_mc_bus_dprc_type = {
const struct device_type fsl_mc_bus_dprc_type = {
.name = "fsl_mc_bus_dprc"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dprc_type);
struct device_type fsl_mc_bus_dpni_type = {
const struct device_type fsl_mc_bus_dpni_type = {
.name = "fsl_mc_bus_dpni"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpni_type);
struct device_type fsl_mc_bus_dpio_type = {
const struct device_type fsl_mc_bus_dpio_type = {
.name = "fsl_mc_bus_dpio"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpio_type);
struct device_type fsl_mc_bus_dpsw_type = {
const struct device_type fsl_mc_bus_dpsw_type = {
.name = "fsl_mc_bus_dpsw"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpsw_type);
struct device_type fsl_mc_bus_dpbp_type = {
const struct device_type fsl_mc_bus_dpbp_type = {
.name = "fsl_mc_bus_dpbp"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpbp_type);
struct device_type fsl_mc_bus_dpcon_type = {
const struct device_type fsl_mc_bus_dpcon_type = {
.name = "fsl_mc_bus_dpcon"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpcon_type);
struct device_type fsl_mc_bus_dpmcp_type = {
const struct device_type fsl_mc_bus_dpmcp_type = {
.name = "fsl_mc_bus_dpmcp"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpmcp_type);
struct device_type fsl_mc_bus_dpmac_type = {
const struct device_type fsl_mc_bus_dpmac_type = {
.name = "fsl_mc_bus_dpmac"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpmac_type);
struct device_type fsl_mc_bus_dprtc_type = {
const struct device_type fsl_mc_bus_dprtc_type = {
.name = "fsl_mc_bus_dprtc"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dprtc_type);
struct device_type fsl_mc_bus_dpseci_type = {
const struct device_type fsl_mc_bus_dpseci_type = {
.name = "fsl_mc_bus_dpseci"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpseci_type);
struct device_type fsl_mc_bus_dpdmux_type = {
const struct device_type fsl_mc_bus_dpdmux_type = {
.name = "fsl_mc_bus_dpdmux"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmux_type);
struct device_type fsl_mc_bus_dpdcei_type = {
const struct device_type fsl_mc_bus_dpdcei_type = {
.name = "fsl_mc_bus_dpdcei"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdcei_type);
struct device_type fsl_mc_bus_dpaiop_type = {
const struct device_type fsl_mc_bus_dpaiop_type = {
.name = "fsl_mc_bus_dpaiop"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpaiop_type);
struct device_type fsl_mc_bus_dpci_type = {
const struct device_type fsl_mc_bus_dpci_type = {
.name = "fsl_mc_bus_dpci"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpci_type);
struct device_type fsl_mc_bus_dpdmai_type = {
const struct device_type fsl_mc_bus_dpdmai_type = {
.name = "fsl_mc_bus_dpdmai"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmai_type);
struct device_type fsl_mc_bus_dpdbg_type = {
const struct device_type fsl_mc_bus_dpdbg_type = {
.name = "fsl_mc_bus_dpdbg"
};
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdbg_type);
static struct device_type *fsl_mc_get_device_type(const char *type)
static const struct device_type *fsl_mc_get_device_type(const char *type)
{
static const struct {
struct device_type *dev_type;
const struct device_type *dev_type;
const char *type;
} dev_types[] = {
{ &fsl_mc_bus_dprc_type, "dprc" },

View file

@ -473,22 +473,6 @@ unlock_and_exit:
}
DEFINE_SHOW_STORE_ATTRIBUTE(tl_control);
static int get_rp_index_from_file(const struct file *f, u8 *rp_id, u8 rp_num)
{
char alpha;
u8 index;
int ret;
ret = sscanf(f->f_path.dentry->d_name.name, ADF_TL_RP_REGS_FNAME, &alpha);
if (ret != 1)
return -EINVAL;
index = ADF_TL_DBG_RP_INDEX_ALPHA(alpha);
*rp_id = index;
return 0;
}
static int adf_tl_dbg_change_rp_index(struct adf_accel_dev *accel_dev,
unsigned int new_rp_num,
unsigned int rp_regs_index)
@ -611,18 +595,11 @@ static int tl_rp_data_show(struct seq_file *s, void *unused)
{
struct adf_accel_dev *accel_dev = s->private;
u8 rp_regs_index;
u8 max_rp;
int ret;
if (!accel_dev)
return -EINVAL;
max_rp = GET_TL_DATA(accel_dev).max_rp;
ret = get_rp_index_from_file(s->file, &rp_regs_index, max_rp);
if (ret) {
dev_dbg(&GET_DEV(accel_dev), "invalid RP data file name\n");
return ret;
}
rp_regs_index = debugfs_get_aux_num(s->file);
return tl_print_rp_data(accel_dev, s, rp_regs_index);
}
@ -635,7 +612,6 @@ static ssize_t tl_rp_data_write(struct file *file, const char __user *userbuf,
struct adf_telemetry *telemetry;
unsigned int new_rp_num;
u8 rp_regs_index;
u8 max_rp;
int ret;
accel_dev = seq_f->private;
@ -643,15 +619,10 @@ static ssize_t tl_rp_data_write(struct file *file, const char __user *userbuf,
return -EINVAL;
telemetry = accel_dev->telemetry;
max_rp = GET_TL_DATA(accel_dev).max_rp;
mutex_lock(&telemetry->wr_lock);
ret = get_rp_index_from_file(file, &rp_regs_index, max_rp);
if (ret) {
dev_dbg(&GET_DEV(accel_dev), "invalid RP data file name\n");
goto unlock_and_exit;
}
rp_regs_index = debugfs_get_aux_num(file);
ret = kstrtou32_from_user(userbuf, count, 10, &new_rp_num);
if (ret)
@ -689,7 +660,8 @@ void adf_tl_dbgfs_add(struct adf_accel_dev *accel_dev)
for (i = 0; i < max_rp; i++) {
snprintf(name, sizeof(name), ADF_TL_RP_REGS_FNAME,
ADF_TL_DBG_RP_ALPHA_INDEX(i));
debugfs_create_file(name, 0644, dir, accel_dev, &tl_rp_data_fops);
debugfs_create_file_aux_num(name, 0644, dir, accel_dev, i,
&tl_rp_data_fops);
}
}

View file

@ -703,7 +703,7 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
return 0;
}
static int commit_reap(struct device *dev, const void *data)
static int commit_reap(struct device *dev, void *data)
{
struct cxl_port *port = to_cxl_port(dev->parent);
struct cxl_decoder *cxld;

View file

@ -252,9 +252,9 @@ static int devm_cxl_enable_mem(struct device *host, struct cxl_dev_state *cxlds)
}
/* require dvsec ranges to be covered by a locked platform window */
static int dvsec_range_allowed(struct device *dev, void *arg)
static int dvsec_range_allowed(struct device *dev, const void *arg)
{
struct range *dev_range = arg;
const struct range *dev_range = arg;
struct cxl_decoder *cxld;
if (!is_root_decoder(dev))

View file

@ -51,17 +51,6 @@ struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev)
}
EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm_bridge, "CXL");
bool is_cxl_nvdimm_bridge(struct device *dev)
{
return dev->type == &cxl_nvdimm_bridge_type;
}
EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, "CXL");
static int match_nvdimm_bridge(struct device *dev, void *data)
{
return is_cxl_nvdimm_bridge(dev);
}
/**
* cxl_find_nvdimm_bridge() - find a bridge device relative to a port
* @port: any descendant port of an nvdimm-bridge associated
@ -75,7 +64,9 @@ struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port)
if (!cxl_root)
return NULL;
dev = device_find_child(&cxl_root->port.dev, NULL, match_nvdimm_bridge);
dev = device_find_child(&cxl_root->port.dev,
&cxl_nvdimm_bridge_type,
device_match_type);
if (!dev)
return NULL;

View file

@ -778,7 +778,7 @@ out:
return rc;
}
static int check_commit_order(struct device *dev, const void *data)
static int check_commit_order(struct device *dev, void *data)
{
struct cxl_decoder *cxld = to_cxl_decoder(dev);
@ -792,7 +792,7 @@ static int check_commit_order(struct device *dev, const void *data)
return 0;
}
static int match_free_decoder(struct device *dev, void *data)
static int match_free_decoder(struct device *dev, const void *data)
{
struct cxl_port *port = to_cxl_port(dev->parent);
struct cxl_decoder *cxld;
@ -824,9 +824,9 @@ static int match_free_decoder(struct device *dev, void *data)
return 1;
}
static int match_auto_decoder(struct device *dev, void *data)
static int match_auto_decoder(struct device *dev, const void *data)
{
struct cxl_region_params *p = data;
const struct cxl_region_params *p = data;
struct cxl_decoder *cxld;
struct range *r;
@ -1733,10 +1733,12 @@ static struct cxl_port *next_port(struct cxl_port *port)
return port->parent_dport->port;
}
static int match_switch_decoder_by_range(struct device *dev, void *data)
static int match_switch_decoder_by_range(struct device *dev,
const void *data)
{
struct cxl_switch_decoder *cxlsd;
struct range *r1, *r2 = data;
const struct range *r1, *r2 = data;
if (!is_switch_decoder(dev))
return 0;
@ -3187,9 +3189,10 @@ err:
return rc;
}
static int match_root_decoder_by_range(struct device *dev, void *data)
static int match_root_decoder_by_range(struct device *dev,
const void *data)
{
struct range *r1, *r2 = data;
const struct range *r1, *r2 = data;
struct cxl_root_decoder *cxlrd;
if (!is_root_decoder(dev))
@ -3200,11 +3203,11 @@ static int match_root_decoder_by_range(struct device *dev, void *data)
return range_contains(r1, r2);
}
static int match_region_by_range(struct device *dev, void *data)
static int match_region_by_range(struct device *dev, const void *data)
{
struct cxl_region_params *p;
struct cxl_region *cxlr;
struct range *r = data;
const struct range *r = data;
int rc = 0;
if (!is_cxl_region(dev))

View file

@ -864,7 +864,6 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
struct cxl_port *port);
struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev);
bool is_cxl_nvdimm(struct device *dev);
bool is_cxl_nvdimm_bridge(struct device *dev);
int devm_cxl_add_nvdimm(struct cxl_port *parent_port, struct cxl_memdev *cxlmd);
struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port);

View file

@ -988,7 +988,7 @@ int fw_device_set_broadcast_channel(struct device *dev, void *gen)
return 0;
}
static int compare_configuration_rom(struct device *dev, void *data)
static int compare_configuration_rom(struct device *dev, const void *data)
{
const struct fw_device *old = fw_device(dev);
const u32 *config_rom = data;
@ -1039,7 +1039,7 @@ static void fw_device_init(struct work_struct *work)
//
// serialize config_rom access.
scoped_guard(rwsem_read, &fw_device_rwsem) {
found = device_find_child(card->device, (void *)device->config_rom,
found = device_find_child(card->device, device->config_rom,
compare_configuration_rom);
}
if (found) {

View file

@ -238,10 +238,10 @@ static int scmi_dev_match(struct device *dev, const struct device_driver *drv)
return 0;
}
static int scmi_match_by_id_table(struct device *dev, void *data)
static int scmi_match_by_id_table(struct device *dev, const void *data)
{
struct scmi_device *sdev = to_scmi_dev(dev);
struct scmi_device_id *id_table = data;
const struct scmi_device_id *id_table = data;
return sdev->protocol_id == id_table->protocol_id &&
(id_table->name && !strcmp(sdev->name, id_table->name));

View file

@ -886,10 +886,8 @@ static __poll_t scmi_dbg_raw_mode_message_poll(struct file *filp,
static int scmi_dbg_raw_mode_open(struct inode *inode, struct file *filp)
{
u8 id;
struct scmi_raw_mode_info *raw;
struct scmi_dbg_raw_data *rd;
const char *id_str = filp->f_path.dentry->d_parent->d_name.name;
if (!inode->i_private)
return -ENODEV;
@ -915,8 +913,8 @@ static int scmi_dbg_raw_mode_open(struct inode *inode, struct file *filp)
}
/* Grab channel ID from debugfs entry naming if any */
if (!kstrtou8(id_str, 16, &id))
rd->chan_id = id;
/* not set - reassing 0 we already had after kzalloc() */
rd->chan_id = debugfs_get_aux_num(filp);
rd->raw = raw;
filp->private_data = rd;
@ -1225,10 +1223,12 @@ void *scmi_raw_mode_init(const struct scmi_handle *handle,
snprintf(cdir, 8, "0x%02X", channels[i]);
chd = debugfs_create_dir(cdir, top_chans);
debugfs_create_file("message", 0600, chd, raw,
debugfs_create_file_aux_num("message", 0600, chd,
raw, channels[i],
&scmi_dbg_raw_mode_message_fops);
debugfs_create_file("message_async", 0600, chd, raw,
debugfs_create_file_aux_num("message_async", 0600, chd,
raw, channels[i],
&scmi_dbg_raw_mode_message_async_fops);
}
}

View file

@ -47,9 +47,9 @@ static long __init parse_acpi_path(const struct efi_dev_path *node,
return 0;
}
static int __init match_pci_dev(struct device *dev, void *data)
static int __init match_pci_dev(struct device *dev, const void *data)
{
unsigned int devfn = *(unsigned int *)data;
unsigned int devfn = *(const unsigned int *)data;
return dev_is_pci(dev) && to_pci_dev(dev)->devfn == devfn;
}

View file

@ -413,11 +413,6 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)
return devm_add_action_or_reset(dev, gpio_sim_sysfs_remove, chip);
}
static int gpio_sim_dev_match_fwnode(struct device *dev, void *data)
{
return device_match_fwnode(dev, data);
}
static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev)
{
struct gpio_sim_chip *chip;
@ -503,7 +498,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev)
if (ret)
return ret;
chip->dev = device_find_child(dev, swnode, gpio_sim_dev_match_fwnode);
chip->dev = device_find_child(dev, swnode, device_match_fwnode);
if (!chip->dev)
return -ENODEV;

View file

@ -358,7 +358,7 @@ static const struct of_device_id mtk_drm_of_ids[] = {
};
MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
static int mtk_drm_match(struct device *dev, void *data)
static int mtk_drm_match(struct device *dev, const void *data)
{
if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
return true;

View file

@ -332,7 +332,7 @@ static int hwmon_attr_base(enum hwmon_sensor_types type)
static DEFINE_MUTEX(hwmon_pec_mutex);
static int hwmon_match_device(struct device *dev, void *data)
static int hwmon_match_device(struct device *dev, const void *data)
{
return dev->class == &hwmon_class;
}

View file

@ -1310,7 +1310,7 @@ new_device_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_WO(new_device);
static int __i2c_find_user_addr(struct device *dev, void *addrp)
static int __i2c_find_user_addr(struct device *dev, const void *addrp)
{
struct i2c_client *client = i2c_verify_client(dev);
unsigned short addr = *(unsigned short *)addrp;

View file

@ -438,7 +438,7 @@ static int omnia_mcu_get_features(const struct i2c_client *mcu_client)
return reply;
}
static int omnia_match_mcu_client(struct device *dev, void *data)
static int omnia_match_mcu_client(struct device *dev, const void *data)
{
struct i2c_client *client;

View file

@ -125,7 +125,7 @@ static const struct hwmon_chip_info temp_chip_info = {
};
#endif
static int match_i2c_adap(struct device *dev, void *data)
static int match_i2c_adap(struct device *dev, const void *data)
{
return i2c_verify_adapter(dev) ? 1 : 0;
}
@ -141,7 +141,7 @@ static struct i2c_adapter *get_i2c_adap(struct platform_device *pdev)
return dev ? to_i2c_adapter(dev) : NULL;
}
static int match_spi_adap(struct device *dev, void *data)
static int match_spi_adap(struct device *dev, const void *data)
{
return to_spi_device(dev) ? 1 : 0;
}

View file

@ -42,7 +42,7 @@ struct mux_state {
unsigned int state;
};
static struct class mux_class = {
static const struct class mux_class = {
.name = "mux",
};

View file

@ -63,13 +63,8 @@ void bond_debug_unregister(struct bonding *bond)
void bond_debug_reregister(struct bonding *bond)
{
struct dentry *d;
d = debugfs_rename(bonding_debug_root, bond->debug_dir,
bonding_debug_root, bond->dev->name);
if (!IS_ERR(d)) {
bond->debug_dir = d;
} else {
int err = debugfs_change_name(bond->debug_dir, "%s", bond->dev->name);
if (err) {
netdev_warn(bond->dev, "failed to reregister, so just unregister old one\n");
bond_debug_unregister(bond);
}

View file

@ -505,21 +505,6 @@ void xgbe_debugfs_exit(struct xgbe_prv_data *pdata)
void xgbe_debugfs_rename(struct xgbe_prv_data *pdata)
{
char *buf;
if (!pdata->xgbe_debugfs)
return;
buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
if (!buf)
return;
if (!strcmp(pdata->xgbe_debugfs->d_name.name, buf))
goto out;
debugfs_rename(pdata->xgbe_debugfs->d_parent, pdata->xgbe_debugfs,
pdata->xgbe_debugfs->d_parent, buf);
out:
kfree(buf);
debugfs_change_name(pdata->xgbe_debugfs,
"amd-xgbe-%s", pdata->netdev->name);
}

View file

@ -917,19 +917,18 @@ static void print_npa_qsize(struct seq_file *m, struct rvu_pfvf *pfvf)
/* The 'qsize' entry dumps current Aura/Pool context Qsize
* and each context's current enable/disable status in a bitmap.
*/
static int rvu_dbg_qsize_display(struct seq_file *filp, void *unsused,
static int rvu_dbg_qsize_display(struct seq_file *s, void *unsused,
int blktype)
{
void (*print_qsize)(struct seq_file *filp,
void (*print_qsize)(struct seq_file *s,
struct rvu_pfvf *pfvf) = NULL;
struct dentry *current_dir;
struct rvu_pfvf *pfvf;
struct rvu *rvu;
int qsize_id;
u16 pcifunc;
int blkaddr;
rvu = filp->private;
rvu = s->private;
switch (blktype) {
case BLKTYPE_NPA:
qsize_id = rvu->rvu_dbg.npa_qsize_id;
@ -945,32 +944,28 @@ static int rvu_dbg_qsize_display(struct seq_file *filp, void *unsused,
return -EINVAL;
}
if (blktype == BLKTYPE_NPA) {
if (blktype == BLKTYPE_NPA)
blkaddr = BLKADDR_NPA;
} else {
current_dir = filp->file->f_path.dentry->d_parent;
blkaddr = (!strcmp(current_dir->d_name.name, "nix1") ?
BLKADDR_NIX1 : BLKADDR_NIX0);
}
else
blkaddr = debugfs_get_aux_num(s->file);
if (!rvu_dbg_is_valid_lf(rvu, blkaddr, qsize_id, &pcifunc))
return -EINVAL;
pfvf = rvu_get_pfvf(rvu, pcifunc);
print_qsize(filp, pfvf);
print_qsize(s, pfvf);
return 0;
}
static ssize_t rvu_dbg_qsize_write(struct file *filp,
static ssize_t rvu_dbg_qsize_write(struct file *file,
const char __user *buffer, size_t count,
loff_t *ppos, int blktype)
{
char *blk_string = (blktype == BLKTYPE_NPA) ? "npa" : "nix";
struct seq_file *seqfile = filp->private_data;
struct seq_file *seqfile = file->private_data;
char *cmd_buf, *cmd_buf_tmp, *subtoken;
struct rvu *rvu = seqfile->private;
struct dentry *current_dir;
int blkaddr;
u16 pcifunc;
int ret, lf;
@ -996,13 +991,10 @@ static ssize_t rvu_dbg_qsize_write(struct file *filp,
goto qsize_write_done;
}
if (blktype == BLKTYPE_NPA) {
if (blktype == BLKTYPE_NPA)
blkaddr = BLKADDR_NPA;
} else {
current_dir = filp->f_path.dentry->d_parent;
blkaddr = (!strcmp(current_dir->d_name.name, "nix1") ?
BLKADDR_NIX1 : BLKADDR_NIX0);
}
else
blkaddr = debugfs_get_aux_num(file);
if (!rvu_dbg_is_valid_lf(rvu, blkaddr, lf, &pcifunc)) {
ret = -EINVAL;
@ -2704,8 +2696,8 @@ static void rvu_dbg_nix_init(struct rvu *rvu, int blkaddr)
&rvu_dbg_nix_ndc_tx_hits_miss_fops);
debugfs_create_file("ndc_rx_hits_miss", 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_ndc_rx_hits_miss_fops);
debugfs_create_file("qsize", 0600, rvu->rvu_dbg.nix, rvu,
&rvu_dbg_nix_qsize_fops);
debugfs_create_file_aux_num("qsize", 0600, rvu->rvu_dbg.nix, rvu,
blkaddr, &rvu_dbg_nix_qsize_fops);
debugfs_create_file("ingress_policer_ctx", 0600, rvu->rvu_dbg.nix, nix_hw,
&rvu_dbg_nix_band_prof_ctx_fops);
debugfs_create_file("ingress_policer_rsrc", 0600, rvu->rvu_dbg.nix, nix_hw,
@ -2854,28 +2846,14 @@ static int cgx_print_stats(struct seq_file *s, int lmac_id)
return err;
}
static int rvu_dbg_derive_lmacid(struct seq_file *filp, int *lmac_id)
static int rvu_dbg_derive_lmacid(struct seq_file *s)
{
struct dentry *current_dir;
char *buf;
current_dir = filp->file->f_path.dentry->d_parent;
buf = strrchr(current_dir->d_name.name, 'c');
if (!buf)
return -EINVAL;
return kstrtoint(buf + 1, 10, lmac_id);
return debugfs_get_aux_num(s->file);
}
static int rvu_dbg_cgx_stat_display(struct seq_file *filp, void *unused)
static int rvu_dbg_cgx_stat_display(struct seq_file *s, void *unused)
{
int lmac_id, err;
err = rvu_dbg_derive_lmacid(filp, &lmac_id);
if (!err)
return cgx_print_stats(filp, lmac_id);
return err;
return cgx_print_stats(s, rvu_dbg_derive_lmacid(s));
}
RVU_DEBUG_SEQ_FOPS(cgx_stat, cgx_stat_display, NULL);
@ -2933,15 +2911,9 @@ static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
return 0;
}
static int rvu_dbg_cgx_dmac_flt_display(struct seq_file *filp, void *unused)
static int rvu_dbg_cgx_dmac_flt_display(struct seq_file *s, void *unused)
{
int err, lmac_id;
err = rvu_dbg_derive_lmacid(filp, &lmac_id);
if (!err)
return cgx_print_dmac_flt(filp, lmac_id);
return err;
return cgx_print_dmac_flt(s, rvu_dbg_derive_lmacid(s));
}
RVU_DEBUG_SEQ_FOPS(cgx_dmac_flt, cgx_dmac_flt_display, NULL);
@ -2980,10 +2952,10 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)
rvu->rvu_dbg.lmac =
debugfs_create_dir(dname, rvu->rvu_dbg.cgx);
debugfs_create_file("stats", 0600, rvu->rvu_dbg.lmac,
cgx, &rvu_dbg_cgx_stat_fops);
debugfs_create_file("mac_filter", 0600,
rvu->rvu_dbg.lmac, cgx,
debugfs_create_file_aux_num("stats", 0600, rvu->rvu_dbg.lmac,
cgx, lmac_id, &rvu_dbg_cgx_stat_fops);
debugfs_create_file_aux_num("mac_filter", 0600,
rvu->rvu_dbg.lmac, cgx, lmac_id,
&rvu_dbg_cgx_dmac_flt_fops);
}
}

View file

@ -3742,10 +3742,7 @@ static int skge_device_event(struct notifier_block *unused,
skge = netdev_priv(dev);
switch (event) {
case NETDEV_CHANGENAME:
if (skge->debugfs)
skge->debugfs = debugfs_rename(skge_debug,
skge->debugfs,
skge_debug, dev->name);
debugfs_change_name(skge->debugfs, "%s", dev->name);
break;
case NETDEV_GOING_DOWN:

View file

@ -4494,10 +4494,7 @@ static int sky2_device_event(struct notifier_block *unused,
switch (event) {
case NETDEV_CHANGENAME:
if (sky2->debugfs) {
sky2->debugfs = debugfs_rename(sky2_debug, sky2->debugfs,
sky2_debug, dev->name);
}
debugfs_change_name(sky2->debugfs, "%s", dev->name);
break;
case NETDEV_GOING_DOWN:

View file

@ -6535,11 +6535,7 @@ static int stmmac_device_event(struct notifier_block *unused,
switch (event) {
case NETDEV_CHANGENAME:
if (priv->dbgfs_dir)
priv->dbgfs_dir = debugfs_rename(stmmac_fs_dir,
priv->dbgfs_dir,
stmmac_fs_dir,
dev->name);
debugfs_change_name(priv->dbgfs_dir, "%s", dev->name);
break;
}
done:

View file

@ -331,7 +331,6 @@ enum nsim_dev_hwstats_do {
};
struct nsim_dev_hwstats_fops {
const struct file_operations fops;
enum nsim_dev_hwstats_do action;
enum netdev_offload_xstats_type type;
};
@ -342,13 +341,12 @@ nsim_dev_hwstats_do_write(struct file *file,
size_t count, loff_t *ppos)
{
struct nsim_dev_hwstats *hwstats = file->private_data;
struct nsim_dev_hwstats_fops *hwsfops;
const struct nsim_dev_hwstats_fops *hwsfops;
struct list_head *hwsdev_list;
int ifindex;
int err;
hwsfops = container_of(debugfs_real_fops(file),
struct nsim_dev_hwstats_fops, fops);
hwsfops = debugfs_get_aux(file);
err = kstrtoint_from_user(data, count, 0, &ifindex);
if (err)
@ -381,14 +379,13 @@ nsim_dev_hwstats_do_write(struct file *file,
return count;
}
static struct debugfs_short_fops debugfs_ops = {
.write = nsim_dev_hwstats_do_write,
.llseek = generic_file_llseek,
};
#define NSIM_DEV_HWSTATS_FOPS(ACTION, TYPE) \
{ \
.fops = { \
.open = simple_open, \
.write = nsim_dev_hwstats_do_write, \
.llseek = generic_file_llseek, \
.owner = THIS_MODULE, \
}, \
.action = ACTION, \
.type = TYPE, \
}
@ -433,12 +430,12 @@ int nsim_dev_hwstats_init(struct nsim_dev *nsim_dev)
goto err_remove_hwstats_recursive;
}
debugfs_create_file("enable_ifindex", 0200, hwstats->l3_ddir, hwstats,
&nsim_dev_hwstats_l3_enable_fops.fops);
debugfs_create_file("disable_ifindex", 0200, hwstats->l3_ddir, hwstats,
&nsim_dev_hwstats_l3_disable_fops.fops);
debugfs_create_file("fail_next_enable", 0200, hwstats->l3_ddir, hwstats,
&nsim_dev_hwstats_l3_fail_fops.fops);
debugfs_create_file_aux("enable_ifindex", 0200, hwstats->l3_ddir, hwstats,
&nsim_dev_hwstats_l3_enable_fops, &debugfs_ops);
debugfs_create_file_aux("disable_ifindex", 0200, hwstats->l3_ddir, hwstats,
&nsim_dev_hwstats_l3_disable_fops, &debugfs_ops);
debugfs_create_file_aux("fail_next_enable", 0200, hwstats->l3_ddir, hwstats,
&nsim_dev_hwstats_l3_fail_fops, &debugfs_ops);
INIT_DELAYED_WORK(&hwstats->traffic_dw,
&nsim_dev_hwstats_traffic_work);

View file

@ -54,7 +54,6 @@ struct carl9170_debugfs_fops {
char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize,
ssize_t *len);
ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size);
const struct file_operations fops;
enum carl9170_device_state req_dev_state;
};
@ -62,7 +61,7 @@ struct carl9170_debugfs_fops {
static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct carl9170_debugfs_fops *dfops;
const struct carl9170_debugfs_fops *dfops;
struct ar9170 *ar;
char *buf = NULL, *res_buf = NULL;
ssize_t ret = 0;
@ -75,8 +74,7 @@ static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
if (!ar)
return -ENODEV;
dfops = container_of(debugfs_real_fops(file),
struct carl9170_debugfs_fops, fops);
dfops = debugfs_get_aux(file);
if (!dfops->read)
return -ENOSYS;
@ -113,7 +111,7 @@ out_free:
static ssize_t carl9170_debugfs_write(struct file *file,
const char __user *userbuf, size_t count, loff_t *ppos)
{
struct carl9170_debugfs_fops *dfops;
const struct carl9170_debugfs_fops *dfops;
struct ar9170 *ar;
char *buf = NULL;
int err = 0;
@ -128,8 +126,7 @@ static ssize_t carl9170_debugfs_write(struct file *file,
if (!ar)
return -ENODEV;
dfops = container_of(debugfs_real_fops(file),
struct carl9170_debugfs_fops, fops);
dfops = debugfs_get_aux(file);
if (!dfops->write)
return -ENOSYS;
@ -165,6 +162,11 @@ out_free:
return err;
}
static struct debugfs_short_fops debugfs_fops = {
.read = carl9170_debugfs_read,
.write = carl9170_debugfs_write,
};
#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \
_attr, _dstate) \
static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
@ -173,12 +175,6 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
.write = _write, \
.attr = _attr, \
.req_dev_state = _dstate, \
.fops = { \
.open = simple_open, \
.read = carl9170_debugfs_read, \
.write = carl9170_debugfs_write, \
.owner = THIS_MODULE \
}, \
}
#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \
@ -816,9 +812,9 @@ void carl9170_debugfs_register(struct ar9170 *ar)
ar->hw->wiphy->debugfsdir);
#define DEBUGFS_ADD(name) \
debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \
ar->debug_dir, ar, \
&carl_debugfs_##name ## _ops.fops)
debugfs_create_file_aux(#name, carl_debugfs_##name ##_ops.attr, \
ar->debug_dir, ar, &carl_debugfs_##name ## _ops, \
&debugfs_fops)
DEBUGFS_ADD(usb_tx_anch_urbs);
DEBUGFS_ADD(usb_rx_pool_urbs);

View file

@ -30,7 +30,6 @@ static struct dentry *rootdir;
struct b43_debugfs_fops {
ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize);
int (*write)(struct b43_wldev *dev, const char *buf, size_t count);
struct file_operations fops;
/* Offset of struct b43_dfs_file in struct b43_dfsentry */
size_t file_struct_offset;
};
@ -491,7 +490,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct b43_wldev *dev;
struct b43_debugfs_fops *dfops;
const struct b43_debugfs_fops *dfops;
struct b43_dfs_file *dfile;
ssize_t ret;
char *buf;
@ -511,8 +510,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
goto out_unlock;
}
dfops = container_of(debugfs_real_fops(file),
struct b43_debugfs_fops, fops);
dfops = debugfs_get_aux(file);
if (!dfops->read) {
err = -ENOSYS;
goto out_unlock;
@ -555,7 +553,7 @@ static ssize_t b43_debugfs_write(struct file *file,
size_t count, loff_t *ppos)
{
struct b43_wldev *dev;
struct b43_debugfs_fops *dfops;
const struct b43_debugfs_fops *dfops;
char *buf;
int err = 0;
@ -573,8 +571,7 @@ static ssize_t b43_debugfs_write(struct file *file,
goto out_unlock;
}
dfops = container_of(debugfs_real_fops(file),
struct b43_debugfs_fops, fops);
dfops = debugfs_get_aux(file);
if (!dfops->write) {
err = -ENOSYS;
goto out_unlock;
@ -602,16 +599,16 @@ out_unlock:
}
static struct debugfs_short_fops debugfs_ops = {
.read = b43_debugfs_read,
.write = b43_debugfs_write,
.llseek = generic_file_llseek,
};
#define B43_DEBUGFS_FOPS(name, _read, _write) \
static struct b43_debugfs_fops fops_##name = { \
.read = _read, \
.write = _write, \
.fops = { \
.open = simple_open, \
.read = b43_debugfs_read, \
.write = b43_debugfs_write, \
.llseek = generic_file_llseek, \
}, \
.file_struct_offset = offsetof(struct b43_dfsentry, \
file_##name), \
}
@ -703,9 +700,9 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
#define ADD_FILE(name, mode) \
do { \
debugfs_create_file(__stringify(name), \
debugfs_create_file_aux(__stringify(name), \
mode, e->subdir, dev, \
&fops_##name.fops); \
&fops_##name, &debugfs_ops); \
} while (0)

View file

@ -31,7 +31,6 @@ static struct dentry *rootdir;
struct b43legacy_debugfs_fops {
ssize_t (*read)(struct b43legacy_wldev *dev, char *buf, size_t bufsize);
int (*write)(struct b43legacy_wldev *dev, const char *buf, size_t count);
struct file_operations fops;
/* Offset of struct b43legacy_dfs_file in struct b43legacy_dfsentry */
size_t file_struct_offset;
/* Take wl->irq_lock before calling read/write? */
@ -188,7 +187,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct b43legacy_wldev *dev;
struct b43legacy_debugfs_fops *dfops;
const struct b43legacy_debugfs_fops *dfops;
struct b43legacy_dfs_file *dfile;
ssize_t ret;
char *buf;
@ -208,8 +207,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
goto out_unlock;
}
dfops = container_of(debugfs_real_fops(file),
struct b43legacy_debugfs_fops, fops);
dfops = debugfs_get_aux(file);
if (!dfops->read) {
err = -ENOSYS;
goto out_unlock;
@ -257,7 +255,7 @@ static ssize_t b43legacy_debugfs_write(struct file *file,
size_t count, loff_t *ppos)
{
struct b43legacy_wldev *dev;
struct b43legacy_debugfs_fops *dfops;
const struct b43legacy_debugfs_fops *dfops;
char *buf;
int err = 0;
@ -275,8 +273,7 @@ static ssize_t b43legacy_debugfs_write(struct file *file,
goto out_unlock;
}
dfops = container_of(debugfs_real_fops(file),
struct b43legacy_debugfs_fops, fops);
dfops = debugfs_get_aux(file);
if (!dfops->write) {
err = -ENOSYS;
goto out_unlock;
@ -308,17 +305,16 @@ out_unlock:
return err ? err : count;
}
static struct debugfs_short_fops debugfs_ops = {
.read = b43legacy_debugfs_read,
.write = b43legacy_debugfs_write,
.llseek = generic_file_llseek
};
#define B43legacy_DEBUGFS_FOPS(name, _read, _write, _take_irqlock) \
static struct b43legacy_debugfs_fops fops_##name = { \
.read = _read, \
.write = _write, \
.fops = { \
.open = simple_open, \
.read = b43legacy_debugfs_read, \
.write = b43legacy_debugfs_write, \
.llseek = generic_file_llseek, \
}, \
.file_struct_offset = offsetof(struct b43legacy_dfsentry, \
file_##name), \
.take_irqlock = _take_irqlock, \
@ -386,9 +382,9 @@ void b43legacy_debugfs_add_device(struct b43legacy_wldev *dev)
#define ADD_FILE(name, mode) \
do { \
debugfs_create_file(__stringify(name), mode, \
debugfs_create_file_aux(__stringify(name), mode, \
e->subdir, dev, \
&fops_##name.fops); \
&fops_##name, &debugfs_ops); \
} while (0)

View file

@ -1212,7 +1212,7 @@ enum nd_ioctl_mode {
DIMM_IOCTL,
};
static int match_dimm(struct device *dev, void *data)
static int match_dimm(struct device *dev, const void *data)
{
long id = (long) data;

View file

@ -67,13 +67,6 @@ bool nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
return claimed;
}
static int namespace_match(struct device *dev, void *data)
{
char *name = data;
return strcmp(name, dev_name(dev)) == 0;
}
static bool is_idle(struct device *dev, struct nd_namespace_common *ndns)
{
struct nd_region *nd_region = to_nd_region(dev->parent);
@ -168,7 +161,7 @@ ssize_t nd_namespace_store(struct device *dev,
goto out;
}
found = device_find_child(dev->parent, name, namespace_match);
found = device_find_child_by_name(dev->parent, name);
if (!found) {
dev_dbg(dev, "'%s' not found under %s\n", name,
dev_name(dev->parent));

View file

@ -33,6 +33,11 @@
reg = <0x100>;
};
};
test-device@2 {
compatible = "test,rust-device";
reg = <0x2>;
};
};
platform-tests-2 {

View file

@ -217,7 +217,7 @@ static void opp_migrate_dentry(struct opp_device *opp_dev,
{
struct opp_device *new_dev = NULL, *iter;
const struct device *dev;
struct dentry *dentry;
int err;
/* Look for next opp-dev */
list_for_each_entry(iter, &opp_table->dev_list, node)
@ -234,16 +234,14 @@ static void opp_migrate_dentry(struct opp_device *opp_dev,
opp_set_dev_name(dev, opp_table->dentry_name);
dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir,
opp_table->dentry_name);
if (IS_ERR(dentry)) {
err = debugfs_change_name(opp_dev->dentry, "%s", opp_table->dentry_name);
if (err) {
dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
__func__, dev_name(opp_dev->dev), dev_name(dev));
return;
}
new_dev->dentry = dentry;
opp_table->dentry = dentry;
new_dev->dentry = opp_table->dentry = opp_dev->dentry;
}
/**

View file

@ -381,17 +381,12 @@ static const char *const u3_phy_files[] = {
static int u2_phy_params_show(struct seq_file *sf, void *unused)
{
struct mtk_phy_instance *inst = sf->private;
const char *fname = file_dentry(sf->file)->d_iname;
struct u2phy_banks *u2_banks = &inst->u2_banks;
void __iomem *com = u2_banks->com;
u32 max = 0;
u32 tmp = 0;
u32 val = 0;
int ret;
ret = match_string(u2_phy_files, ARRAY_SIZE(u2_phy_files), fname);
if (ret < 0)
return ret;
int ret = debugfs_get_aux_num(sf->file);
switch (ret) {
case U2P_EYE_VRT:
@ -438,7 +433,7 @@ static int u2_phy_params_show(struct seq_file *sf, void *unused)
break;
}
seq_printf(sf, "%s : %d [0, %d]\n", fname, val, max);
seq_printf(sf, "%s : %d [0, %d]\n", u2_phy_files[ret], val, max);
return 0;
}
@ -451,23 +446,18 @@ static int u2_phy_params_open(struct inode *inode, struct file *file)
static ssize_t u2_phy_params_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
const char *fname = file_dentry(file)->d_iname;
struct seq_file *sf = file->private_data;
struct mtk_phy_instance *inst = sf->private;
struct u2phy_banks *u2_banks = &inst->u2_banks;
void __iomem *com = u2_banks->com;
ssize_t rc;
u32 val;
int ret;
int ret = debugfs_get_aux_num(file);
rc = kstrtouint_from_user(ubuf, USER_BUF_LEN(count), 0, &val);
if (rc)
return rc;
ret = match_string(u2_phy_files, ARRAY_SIZE(u2_phy_files), fname);
if (ret < 0)
return (ssize_t)ret;
switch (ret) {
case U2P_EYE_VRT:
mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL, val);
@ -516,23 +506,18 @@ static void u2_phy_dbgfs_files_create(struct mtk_phy_instance *inst)
int i;
for (i = 0; i < count; i++)
debugfs_create_file(u2_phy_files[i], 0644, inst->phy->debugfs,
inst, &u2_phy_fops);
debugfs_create_file_aux_num(u2_phy_files[i], 0644, inst->phy->debugfs,
inst, i, &u2_phy_fops);
}
static int u3_phy_params_show(struct seq_file *sf, void *unused)
{
struct mtk_phy_instance *inst = sf->private;
const char *fname = file_dentry(sf->file)->d_iname;
struct u3phy_banks *u3_banks = &inst->u3_banks;
u32 val = 0;
u32 max = 0;
u32 tmp;
int ret;
ret = match_string(u3_phy_files, ARRAY_SIZE(u3_phy_files), fname);
if (ret < 0)
return ret;
int ret = debugfs_get_aux_num(sf->file);
switch (ret) {
case U3P_EFUSE_EN:
@ -564,7 +549,7 @@ static int u3_phy_params_show(struct seq_file *sf, void *unused)
break;
}
seq_printf(sf, "%s : %d [0, %d]\n", fname, val, max);
seq_printf(sf, "%s : %d [0, %d]\n", u3_phy_files[ret], val, max);
return 0;
}
@ -577,23 +562,18 @@ static int u3_phy_params_open(struct inode *inode, struct file *file)
static ssize_t u3_phy_params_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
const char *fname = file_dentry(file)->d_iname;
struct seq_file *sf = file->private_data;
struct mtk_phy_instance *inst = sf->private;
struct u3phy_banks *u3_banks = &inst->u3_banks;
void __iomem *phyd = u3_banks->phyd;
ssize_t rc;
u32 val;
int ret;
int ret = debugfs_get_aux_num(sf->file);
rc = kstrtouint_from_user(ubuf, USER_BUF_LEN(count), 0, &val);
if (rc)
return rc;
ret = match_string(u3_phy_files, ARRAY_SIZE(u3_phy_files), fname);
if (ret < 0)
return (ssize_t)ret;
switch (ret) {
case U3P_EFUSE_EN:
mtk_phy_update_field(phyd + U3P_U3_PHYD_RSV,
@ -636,8 +616,8 @@ static void u3_phy_dbgfs_files_create(struct mtk_phy_instance *inst)
int i;
for (i = 0; i < count; i++)
debugfs_create_file(u3_phy_files[i], 0644, inst->phy->debugfs,
inst, &u3_phy_fops);
debugfs_create_file_aux_num(u3_phy_files[i], 0644, inst->phy->debugfs,
inst, i, &u3_phy_fops);
}
static int phy_type_show(struct seq_file *sf, void *unused)

View file

@ -1285,7 +1285,7 @@ static int pwm_export_child(struct device *pwmchip_dev, struct pwm_device *pwm)
return 0;
}
static int pwm_unexport_match(struct device *pwm_dev, void *data)
static int pwm_unexport_match(struct device *pwm_dev, const void *data)
{
return pwm_from_dev(pwm_dev) == data;
}

View file

@ -377,9 +377,9 @@ EXPORT_SYMBOL(rpmsg_get_mtu);
* this is used to make sure we're not creating rpmsg devices for channels
* that already exist.
*/
static int rpmsg_device_match(struct device *dev, void *data)
static int rpmsg_device_match(struct device *dev, const void *data)
{
struct rpmsg_channel_info *chinfo = data;
const struct rpmsg_channel_info *chinfo = data;
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src)

View file

@ -128,7 +128,7 @@ static int s390_vary_chpid(struct chp_id chpid, int on)
* Channel measurement related functions
*/
static ssize_t measurement_chars_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct channel_path *chp;
@ -142,11 +142,11 @@ static ssize_t measurement_chars_read(struct file *filp, struct kobject *kobj,
return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars,
sizeof(chp->cmg_chars));
}
static BIN_ATTR_ADMIN_RO(measurement_chars, sizeof(struct cmg_chars));
static const BIN_ATTR_ADMIN_RO(measurement_chars, sizeof(struct cmg_chars));
static ssize_t measurement_chars_full_read(struct file *filp,
struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct channel_path *chp = to_channelpath(kobj_to_dev(kobj));
@ -196,22 +196,22 @@ static ssize_t chp_measurement_copy_block(void *buf, loff_t off, size_t count,
}
static ssize_t measurement_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
return chp_measurement_copy_block(buf, off, count, kobj, false);
}
static BIN_ATTR_ADMIN_RO(measurement, sizeof(struct cmg_entry));
static const BIN_ATTR_ADMIN_RO(measurement, sizeof(struct cmg_entry));
static ssize_t ext_measurement_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
return chp_measurement_copy_block(buf, off, count, kobj, true);
}
static BIN_ATTR_ADMIN_RO(ext_measurement, sizeof(struct cmg_ext_entry));
static const BIN_ATTR_ADMIN_RO(ext_measurement, sizeof(struct cmg_ext_entry));
static struct bin_attribute *measurement_attrs[] = {
static const struct bin_attribute *measurement_attrs[] = {
&bin_attr_measurement_chars,
&bin_attr_measurement_chars_full,
&bin_attr_measurement,
@ -435,7 +435,7 @@ static ssize_t speed_bps_show(struct device *dev,
static DEVICE_ATTR_RO(speed_bps);
static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
const struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
struct channel_path *chp = to_channelpath(kobj_to_dev(kobj));
@ -448,10 +448,10 @@ static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
return rc;
}
static BIN_ATTR_RO(util_string,
sizeof(((struct channel_path_desc_fmt3 *)0)->util_str));
static const BIN_ATTR_RO(util_string,
sizeof(((struct channel_path_desc_fmt3 *)0)->util_str));
static struct bin_attribute *chp_bin_attrs[] = {
static const struct bin_attribute *const chp_bin_attrs[] = {
&bin_attr_util_string,
NULL,
};
@ -468,9 +468,9 @@ static struct attribute *chp_attrs[] = {
&dev_attr_speed_bps.attr,
NULL,
};
static struct attribute_group chp_attr_group = {
static const struct attribute_group chp_attr_group = {
.attrs = chp_attrs,
.bin_attrs = chp_bin_attrs,
.bin_attrs_new = chp_bin_attrs,
};
static const struct attribute_group *chp_attr_groups[] = {
&chp_attr_group,

View file

@ -7189,7 +7189,8 @@ exit_new_nt_list:
* 1: if flashnode entry is non-persistent
* 0: if flashnode entry is persistent
**/
static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data)
static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev,
const void *data)
{
struct iscsi_bus_flash_session *fnode_sess;

View file

@ -1324,7 +1324,7 @@ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
* 1 on success
* 0 on failure
*/
static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
static int iscsi_is_flashnode_conn_dev(struct device *dev, const void *data)
{
return dev->bus == &iscsi_flashnode_bus;
}
@ -1335,7 +1335,7 @@ static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn)
return 0;
}
static int flashnode_match_index(struct device *dev, void *data)
static int flashnode_match_index(struct device *dev, const void *data)
{
struct iscsi_bus_flash_session *fnode_sess = NULL;
int ret = 0;
@ -1344,7 +1344,7 @@ static int flashnode_match_index(struct device *dev, void *data)
goto exit_match_index;
fnode_sess = iscsi_dev_to_flash_session(dev);
ret = (fnode_sess->target_id == *((int *)data)) ? 1 : 0;
ret = (fnode_sess->target_id == *((const int *)data)) ? 1 : 0;
exit_match_index:
return ret;
@ -1389,8 +1389,8 @@ iscsi_get_flashnode_by_index(struct Scsi_Host *shost, uint32_t idx)
* %NULL on failure
*/
struct device *
iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
int (*fn)(struct device *dev, void *data))
iscsi_find_flashnode_sess(struct Scsi_Host *shost, const void *data,
device_match_t fn)
{
return device_find_child(&shost->shost_gendev, data, fn);
}

View file

@ -328,7 +328,8 @@ void slim_report_absent(struct slim_device *sbdev)
}
EXPORT_SYMBOL_GPL(slim_report_absent);
static bool slim_eaddr_equal(struct slim_eaddr *a, struct slim_eaddr *b)
static bool slim_eaddr_equal(const struct slim_eaddr *a,
const struct slim_eaddr *b)
{
return (a->manf_id == b->manf_id &&
a->prod_code == b->prod_code &&
@ -336,9 +337,9 @@ static bool slim_eaddr_equal(struct slim_eaddr *a, struct slim_eaddr *b)
a->instance == b->instance);
}
static int slim_match_dev(struct device *dev, void *data)
static int slim_match_dev(struct device *dev, const void *data)
{
struct slim_eaddr *e_addr = data;
const struct slim_eaddr *e_addr = data;
struct slim_device *sbdev = to_slim_device(dev);
return slim_eaddr_equal(&sbdev->e_addr, e_addr);
@ -384,21 +385,13 @@ struct slim_device *slim_get_device(struct slim_controller *ctrl,
}
EXPORT_SYMBOL_GPL(slim_get_device);
static int of_slim_match_dev(struct device *dev, void *data)
{
struct device_node *np = data;
struct slim_device *sbdev = to_slim_device(dev);
return (sbdev->dev.of_node == np);
}
static struct slim_device *of_find_slim_device(struct slim_controller *ctrl,
struct device_node *np)
{
struct slim_device *sbdev;
struct device *dev;
dev = device_find_child(ctrl->dev, np, of_slim_match_dev);
dev = device_find_child(ctrl->dev, np, device_match_of_node);
if (dev) {
sbdev = to_slim_device(dev);
return sbdev;

View file

@ -1128,18 +1128,7 @@ done:
static int gb_camera_debugfs_open(struct inode *inode, struct file *file)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
const struct gb_camera_debugfs_entry *entry =
&gb_camera_debugfs_entries[i];
if (!strcmp(file->f_path.dentry->d_iname, entry->name)) {
file->private_data = (void *)entry;
break;
}
}
file->private_data = (void *)debugfs_get_aux(file);
return 0;
}
@ -1175,8 +1164,8 @@ static int gb_camera_debugfs_init(struct gb_camera *gcam)
gcam->debugfs.buffers[i].length = 0;
debugfs_create_file(entry->name, entry->mask,
gcam->debugfs.root, gcam,
debugfs_create_file_aux(entry->name, entry->mask,
gcam->debugfs.root, gcam, entry,
&gb_camera_debugfs_ops);
}

View file

@ -472,7 +472,7 @@ struct tb_retimer_lookup {
u8 index;
};
static int retimer_match(struct device *dev, void *data)
static int retimer_match(struct device *dev, const void *data)
{
const struct tb_retimer_lookup *lookup = data;
struct tb_retimer *rt = tb_to_retimer(dev);

View file

@ -1026,7 +1026,7 @@ static int remove_missing_service(struct device *dev, void *data)
return 0;
}
static int find_service(struct device *dev, void *data)
static int find_service(struct device *dev, const void *data)
{
const struct tb_property *p = data;
struct tb_service *svc;

View file

@ -2349,9 +2349,9 @@ struct uart_match {
struct uart_driver *driver;
};
static int serial_match_port(struct device *dev, void *data)
static int serial_match_port(struct device *dev, const void *data)
{
struct uart_match *match = data;
const struct uart_match *match = data;
struct tty_driver *tty_drv = match->driver->tty_driver;
dev_t devt = MKDEV(tty_drv->major, tty_drv->minor_start) +
match->port->line;

View file

@ -232,16 +232,7 @@ static struct xhci_file_map ring_files[] = {
static int xhci_ring_open(struct inode *inode, struct file *file)
{
int i;
struct xhci_file_map *f_map;
const char *file_name = file_dentry(file)->d_iname;
for (i = 0; i < ARRAY_SIZE(ring_files); i++) {
f_map = &ring_files[i];
if (strcmp(f_map->name, file_name) == 0)
break;
}
const struct xhci_file_map *f_map = debugfs_get_aux(file);
return single_open(file, f_map->show, inode->i_private);
}
@ -318,16 +309,7 @@ static struct xhci_file_map context_files[] = {
static int xhci_context_open(struct inode *inode, struct file *file)
{
int i;
struct xhci_file_map *f_map;
const char *file_name = file_dentry(file)->d_iname;
for (i = 0; i < ARRAY_SIZE(context_files); i++) {
f_map = &context_files[i];
if (strcmp(f_map->name, file_name) == 0)
break;
}
const struct xhci_file_map *f_map = debugfs_get_aux(file);
return single_open(file, f_map->show, inode->i_private);
}
@ -410,7 +392,8 @@ static void xhci_debugfs_create_files(struct xhci_hcd *xhci,
int i;
for (i = 0; i < nentries; i++)
debugfs_create_file(files[i].name, 0444, parent, data, fops);
debugfs_create_file_aux(files[i].name, 0444, parent,
data, &files[i], fops);
}
static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci,

View file

@ -257,16 +257,7 @@ static const struct mtu3_file_map mtu3_ep_files[] = {
static int mtu3_ep_open(struct inode *inode, struct file *file)
{
const char *file_name = file_dentry(file)->d_iname;
const struct mtu3_file_map *f_map;
int i;
for (i = 0; i < ARRAY_SIZE(mtu3_ep_files); i++) {
f_map = &mtu3_ep_files[i];
if (strcmp(f_map->name, file_name) == 0)
break;
}
const struct mtu3_file_map *f_map = debugfs_get_aux(file);
return single_open(file, f_map->show, inode->i_private);
}
@ -289,17 +280,8 @@ static const struct debugfs_reg32 mtu3_prb_regs[] = {
static int mtu3_probe_show(struct seq_file *sf, void *unused)
{
const char *file_name = file_dentry(sf->file)->d_iname;
struct mtu3 *mtu = sf->private;
const struct debugfs_reg32 *regs;
int i;
for (i = 0; i < ARRAY_SIZE(mtu3_prb_regs); i++) {
regs = &mtu3_prb_regs[i];
if (strcmp(regs->name, file_name) == 0)
break;
}
const struct debugfs_reg32 *regs = debugfs_get_aux(sf->file);
seq_printf(sf, "0x%04x - 0x%08x\n", (u32)regs->offset,
mtu3_readl(mtu->ippc_base, (u32)regs->offset));
@ -315,13 +297,11 @@ static int mtu3_probe_open(struct inode *inode, struct file *file)
static ssize_t mtu3_probe_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
const char *file_name = file_dentry(file)->d_iname;
struct seq_file *sf = file->private_data;
struct mtu3 *mtu = sf->private;
const struct debugfs_reg32 *regs;
const struct debugfs_reg32 *regs = debugfs_get_aux(file);
char buf[32];
u32 val;
int i;
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
@ -329,12 +309,6 @@ static ssize_t mtu3_probe_write(struct file *file, const char __user *ubuf,
if (kstrtou32(buf, 0, &val))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(mtu3_prb_regs); i++) {
regs = &mtu3_prb_regs[i];
if (strcmp(regs->name, file_name) == 0)
break;
}
mtu3_writel(mtu->ippc_base, (u32)regs->offset, val);
return count;
@ -359,8 +333,8 @@ static void mtu3_debugfs_create_prb_files(struct mtu3 *mtu)
for (i = 0; i < ARRAY_SIZE(mtu3_prb_regs); i++) {
regs = &mtu3_prb_regs[i];
debugfs_create_file(regs->name, 0644, dir_prb,
mtu, &mtu3_probe_fops);
debugfs_create_file_aux(regs->name, 0644, dir_prb,
mtu, regs, &mtu3_probe_fops);
}
mtu3_debugfs_regset(mtu, mtu->ippc_base, mtu3_prb_regs,
@ -380,8 +354,8 @@ static void mtu3_debugfs_create_ep_dir(struct mtu3_ep *mep,
for (i = 0; i < ARRAY_SIZE(mtu3_ep_files); i++) {
files = &mtu3_ep_files[i];
debugfs_create_file(files->name, 0444, dir_ep,
mep, &mtu3_ep_fops);
debugfs_create_file_aux(files->name, 0444, dir_ep,
mep, files, &mtu3_ep_fops);
}
}

View file

@ -230,10 +230,10 @@ static const char * const usb_modes[] = {
/* ------------------------------------------------------------------------- */
/* Alternate Modes */
static int altmode_match(struct device *dev, void *data)
static int altmode_match(struct device *dev, const void *data)
{
struct typec_altmode *adev = to_typec_altmode(dev);
struct typec_device_id *id = data;
const struct typec_device_id *id = data;
if (!is_typec_altmode(dev))
return 0;
@ -1284,11 +1284,6 @@ const struct device_type typec_cable_dev_type = {
.release = typec_cable_release,
};
static int cable_match(struct device *dev, void *data)
{
return is_typec_cable(dev);
}
/**
* typec_cable_get - Get a reference to the USB Type-C cable
* @port: The USB Type-C Port the cable is connected to
@ -1300,7 +1295,8 @@ struct typec_cable *typec_cable_get(struct typec_port *port)
{
struct device *dev;
dev = device_find_child(&port->dev, NULL, cable_match);
dev = device_find_child(&port->dev, &typec_cable_dev_type,
device_match_type);
if (!dev)
return NULL;
@ -2030,16 +2026,12 @@ const struct device_type typec_port_dev_type = {
/* --------------------------------------- */
/* Driver callbacks to report role updates */
static int partner_match(struct device *dev, void *data)
{
return is_typec_partner(dev);
}
static struct typec_partner *typec_get_partner(struct typec_port *port)
{
struct device *dev;
dev = device_find_child(&port->dev, NULL, partner_match);
dev = device_find_child(&port->dev, &typec_partner_dev_type,
device_match_type);
if (!dev)
return NULL;
@ -2172,7 +2164,9 @@ void typec_set_pwr_opmode(struct typec_port *port,
sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode");
kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
partner_dev = device_find_child(&port->dev, NULL, partner_match);
partner_dev = device_find_child(&port->dev,
&typec_partner_dev_type,
device_match_type);
if (partner_dev) {
struct typec_partner *partner = to_typec_partner(partner_dev);
@ -2336,7 +2330,9 @@ int typec_get_negotiated_svdm_version(struct typec_port *port)
enum usb_pd_svdm_ver svdm_version;
struct device *partner_dev;
partner_dev = device_find_child(&port->dev, NULL, partner_match);
partner_dev = device_find_child(&port->dev,
&typec_partner_dev_type,
device_match_type);
if (!partner_dev)
return -ENODEV;
@ -2363,7 +2359,8 @@ int typec_get_cable_svdm_version(struct typec_port *port)
enum usb_pd_svdm_ver svdm_version;
struct device *cable_dev;
cable_dev = device_find_child(&port->dev, NULL, cable_match);
cable_dev = device_find_child(&port->dev, &typec_cable_dev_type,
device_match_type);
if (!cable_dev)
return -ENODEV;

View file

@ -76,7 +76,7 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
if (ret)
return ret;
ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
ret = class_compat_create_link(mdev_bus_compat_class, dev);
if (ret)
dev_warn(dev, "Failed to create compatibility class link\n");
@ -98,7 +98,7 @@ void mdev_unregister_parent(struct mdev_parent *parent)
dev_info(parent->dev, "MDEV: Unregistering\n");
down_write(&parent->unreg_sem);
class_compat_remove_link(mdev_bus_compat_class, parent->dev, NULL);
class_compat_remove_link(mdev_bus_compat_class, parent->dev);
device_for_each_child(parent->dev, NULL, mdev_device_remove_cb);
parent_remove_sysfs_files(parent);
up_write(&parent->unreg_sem);

View file

@ -47,11 +47,17 @@ const struct file_operations debugfs_noop_file_operations = {
#define F_DENTRY(filp) ((filp)->f_path.dentry)
const void *debugfs_get_aux(const struct file *file)
{
return DEBUGFS_I(file_inode(file))->aux;
}
EXPORT_SYMBOL_GPL(debugfs_get_aux);
const struct file_operations *debugfs_real_fops(const struct file *filp)
{
struct debugfs_fsdata *fsd = F_DENTRY(filp)->d_fsdata;
if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) {
if (!fsd) {
/*
* Urgh, we've been called w/o a protecting
* debugfs_file_get().
@ -84,9 +90,11 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
return -EINVAL;
d_fsd = READ_ONCE(dentry->d_fsdata);
if (!((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) {
if (d_fsd) {
fsd = d_fsd;
} else {
struct inode *inode = dentry->d_inode;
if (WARN_ON(mode == DBGFS_GET_ALREADY))
return -EINVAL;
@ -95,23 +103,38 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
return -ENOMEM;
if (mode == DBGFS_GET_SHORT) {
fsd->real_fops = NULL;
fsd->short_fops = (void *)((unsigned long)d_fsd &
~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
const struct debugfs_short_fops *ops;
ops = fsd->short_fops = DEBUGFS_I(inode)->short_fops;
if (ops->llseek)
fsd->methods |= HAS_LSEEK;
if (ops->read)
fsd->methods |= HAS_READ;
if (ops->write)
fsd->methods |= HAS_WRITE;
} else {
fsd->real_fops = (void *)((unsigned long)d_fsd &
~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
fsd->short_fops = NULL;
const struct file_operations *ops;
ops = fsd->real_fops = DEBUGFS_I(inode)->real_fops;
if (ops->llseek)
fsd->methods |= HAS_LSEEK;
if (ops->read)
fsd->methods |= HAS_READ;
if (ops->write)
fsd->methods |= HAS_WRITE;
if (ops->unlocked_ioctl)
fsd->methods |= HAS_IOCTL;
if (ops->poll)
fsd->methods |= HAS_POLL;
}
refcount_set(&fsd->active_users, 1);
init_completion(&fsd->active_users_drained);
INIT_LIST_HEAD(&fsd->cancellations);
mutex_init(&fsd->cancellations_mtx);
if (cmpxchg(&dentry->d_fsdata, d_fsd, fsd) != d_fsd) {
d_fsd = cmpxchg(&dentry->d_fsdata, NULL, fsd);
if (d_fsd) {
mutex_destroy(&fsd->cancellations_mtx);
kfree(fsd);
fsd = READ_ONCE(dentry->d_fsdata);
fsd = d_fsd;
}
}
@ -208,8 +231,7 @@ void debugfs_enter_cancellation(struct file *file,
return;
fsd = READ_ONCE(dentry->d_fsdata);
if (WARN_ON(!fsd ||
((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)))
if (WARN_ON(!fsd))
return;
mutex_lock(&fsd->cancellations_mtx);
@ -240,8 +262,7 @@ void debugfs_leave_cancellation(struct file *file,
return;
fsd = READ_ONCE(dentry->d_fsdata);
if (WARN_ON(!fsd ||
((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)))
if (WARN_ON(!fsd))
return;
mutex_lock(&fsd->cancellations_mtx);
@ -322,13 +343,16 @@ const struct file_operations debugfs_open_proxy_file_operations = {
#define PROTO(args...) args
#define ARGS(args...) args
#define FULL_PROXY_FUNC(name, ret_type, filp, proto, args) \
#define FULL_PROXY_FUNC(name, ret_type, filp, proto, args, bit, ret) \
static ret_type full_proxy_ ## name(proto) \
{ \
struct dentry *dentry = F_DENTRY(filp); \
struct dentry *dentry = F_DENTRY(filp); \
struct debugfs_fsdata *fsd = dentry->d_fsdata; \
const struct file_operations *real_fops; \
ret_type r; \
\
if (!(fsd->methods & bit)) \
return ret; \
r = debugfs_file_get(dentry); \
if (unlikely(r)) \
return r; \
@ -338,17 +362,18 @@ static ret_type full_proxy_ ## name(proto) \
return r; \
}
#define FULL_PROXY_FUNC_BOTH(name, ret_type, filp, proto, args) \
#define FULL_PROXY_FUNC_BOTH(name, ret_type, filp, proto, args, bit, ret) \
static ret_type full_proxy_ ## name(proto) \
{ \
struct dentry *dentry = F_DENTRY(filp); \
struct debugfs_fsdata *fsd; \
struct debugfs_fsdata *fsd = dentry->d_fsdata; \
ret_type r; \
\
if (!(fsd->methods & bit)) \
return ret; \
r = debugfs_file_get(dentry); \
if (unlikely(r)) \
return r; \
fsd = dentry->d_fsdata; \
if (fsd->real_fops) \
r = fsd->real_fops->name(args); \
else \
@ -359,29 +384,32 @@ static ret_type full_proxy_ ## name(proto) \
FULL_PROXY_FUNC_BOTH(llseek, loff_t, filp,
PROTO(struct file *filp, loff_t offset, int whence),
ARGS(filp, offset, whence));
ARGS(filp, offset, whence), HAS_LSEEK, -ESPIPE);
FULL_PROXY_FUNC_BOTH(read, ssize_t, filp,
PROTO(struct file *filp, char __user *buf, size_t size,
loff_t *ppos),
ARGS(filp, buf, size, ppos));
ARGS(filp, buf, size, ppos), HAS_READ, -EINVAL);
FULL_PROXY_FUNC_BOTH(write, ssize_t, filp,
PROTO(struct file *filp, const char __user *buf,
size_t size, loff_t *ppos),
ARGS(filp, buf, size, ppos));
ARGS(filp, buf, size, ppos), HAS_WRITE, -EINVAL);
FULL_PROXY_FUNC(unlocked_ioctl, long, filp,
PROTO(struct file *filp, unsigned int cmd, unsigned long arg),
ARGS(filp, cmd, arg));
ARGS(filp, cmd, arg), HAS_IOCTL, -ENOTTY);
static __poll_t full_proxy_poll(struct file *filp,
struct poll_table_struct *wait)
{
struct dentry *dentry = F_DENTRY(filp);
struct debugfs_fsdata *fsd = dentry->d_fsdata;
__poll_t r = 0;
const struct file_operations *real_fops;
if (!(fsd->methods & HAS_POLL))
return DEFAULT_POLLMASK;
if (debugfs_file_get(dentry))
return EPOLLHUP;
@ -393,9 +421,7 @@ static __poll_t full_proxy_poll(struct file *filp,
static int full_proxy_release(struct inode *inode, struct file *filp)
{
const struct dentry *dentry = F_DENTRY(filp);
const struct file_operations *real_fops = debugfs_real_fops(filp);
const struct file_operations *proxy_fops = filp->f_op;
int r = 0;
/*
@ -404,49 +430,21 @@ static int full_proxy_release(struct inode *inode, struct file *filp)
* not to leak any resources. Releasers must not assume that
* ->i_private is still being meaningful here.
*/
if (real_fops && real_fops->release)
if (real_fops->release)
r = real_fops->release(inode, filp);
replace_fops(filp, d_inode(dentry)->i_fop);
kfree(proxy_fops);
fops_put(real_fops);
return r;
}
static void __full_proxy_fops_init(struct file_operations *proxy_fops,
struct debugfs_fsdata *fsd)
{
proxy_fops->release = full_proxy_release;
if ((fsd->real_fops && fsd->real_fops->llseek) ||
(fsd->short_fops && fsd->short_fops->llseek))
proxy_fops->llseek = full_proxy_llseek;
if ((fsd->real_fops && fsd->real_fops->read) ||
(fsd->short_fops && fsd->short_fops->read))
proxy_fops->read = full_proxy_read;
if ((fsd->real_fops && fsd->real_fops->write) ||
(fsd->short_fops && fsd->short_fops->write))
proxy_fops->write = full_proxy_write;
if (fsd->real_fops && fsd->real_fops->poll)
proxy_fops->poll = full_proxy_poll;
if (fsd->real_fops && fsd->real_fops->unlocked_ioctl)
proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl;
}
static int full_proxy_open(struct inode *inode, struct file *filp,
enum dbgfs_get_mode mode)
static int full_proxy_open_regular(struct inode *inode, struct file *filp)
{
struct dentry *dentry = F_DENTRY(filp);
const struct file_operations *real_fops;
struct file_operations *proxy_fops = NULL;
struct debugfs_fsdata *fsd;
int r;
r = __debugfs_file_get(dentry, mode);
r = __debugfs_file_get(dentry, DBGFS_GET_REGULAR);
if (r)
return r == -EIO ? -ENOENT : r;
@ -456,7 +454,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp,
if (r)
goto out;
if (real_fops && !fops_get(real_fops)) {
if (!fops_get(real_fops)) {
#ifdef CONFIG_MODULES
if (real_fops->owner &&
real_fops->owner->state == MODULE_STATE_GOING) {
@ -472,55 +470,52 @@ static int full_proxy_open(struct inode *inode, struct file *filp,
goto out;
}
proxy_fops = kzalloc(sizeof(*proxy_fops), GFP_KERNEL);
if (!proxy_fops) {
r = -ENOMEM;
goto free_proxy;
}
__full_proxy_fops_init(proxy_fops, fsd);
replace_fops(filp, proxy_fops);
if (!real_fops || real_fops->open) {
if (real_fops)
r = real_fops->open(inode, filp);
else
r = simple_open(inode, filp);
if (real_fops->open) {
r = real_fops->open(inode, filp);
if (r) {
replace_fops(filp, d_inode(dentry)->i_fop);
goto free_proxy;
} else if (filp->f_op != proxy_fops) {
fops_put(real_fops);
} else if (filp->f_op != &debugfs_full_proxy_file_operations) {
/* No protection against file removal anymore. */
WARN(1, "debugfs file owner replaced proxy fops: %pd",
dentry);
goto free_proxy;
fops_put(real_fops);
}
}
goto out;
free_proxy:
kfree(proxy_fops);
fops_put(real_fops);
out:
debugfs_file_put(dentry);
return r;
}
static int full_proxy_open_regular(struct inode *inode, struct file *filp)
{
return full_proxy_open(inode, filp, DBGFS_GET_REGULAR);
}
const struct file_operations debugfs_full_proxy_file_operations = {
.open = full_proxy_open_regular,
.release = full_proxy_release,
.llseek = full_proxy_llseek,
.read = full_proxy_read,
.write = full_proxy_write,
.poll = full_proxy_poll,
.unlocked_ioctl = full_proxy_unlocked_ioctl
};
static int full_proxy_open_short(struct inode *inode, struct file *filp)
{
return full_proxy_open(inode, filp, DBGFS_GET_SHORT);
struct dentry *dentry = F_DENTRY(filp);
int r;
r = __debugfs_file_get(dentry, DBGFS_GET_SHORT);
if (r)
return r == -EIO ? -ENOENT : r;
r = debugfs_locked_down(inode, filp, NULL);
if (!r)
r = simple_open(inode, filp);
debugfs_file_put(dentry);
return r;
}
const struct file_operations debugfs_full_short_proxy_file_operations = {
.open = full_proxy_open_short,
.llseek = full_proxy_llseek,
.read = full_proxy_read,
.write = full_proxy_write,
};
ssize_t debugfs_attr_read(struct file *file, char __user *buf,

View file

@ -208,16 +208,34 @@ static int debugfs_show_options(struct seq_file *m, struct dentry *root)
return 0;
}
static struct kmem_cache *debugfs_inode_cachep __ro_after_init;
static void init_once(void *foo)
{
struct debugfs_inode_info *info = foo;
inode_init_once(&info->vfs_inode);
}
static struct inode *debugfs_alloc_inode(struct super_block *sb)
{
struct debugfs_inode_info *info;
info = alloc_inode_sb(sb, debugfs_inode_cachep, GFP_KERNEL);
if (!info)
return NULL;
return &info->vfs_inode;
}
static void debugfs_free_inode(struct inode *inode)
{
if (S_ISLNK(inode->i_mode))
kfree(inode->i_link);
free_inode_nonrcu(inode);
kmem_cache_free(debugfs_inode_cachep, DEBUGFS_I(inode));
}
static const struct super_operations debugfs_super_operations = {
.statfs = simple_statfs,
.show_options = debugfs_show_options,
.alloc_inode = debugfs_alloc_inode,
.free_inode = debugfs_free_inode,
};
@ -225,23 +243,18 @@ static void debugfs_release_dentry(struct dentry *dentry)
{
struct debugfs_fsdata *fsd = dentry->d_fsdata;
if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)
return;
/* check it wasn't a dir (no fsdata) or automount (no real_fops) */
if (fsd && (fsd->real_fops || fsd->short_fops)) {
if (fsd) {
WARN_ON(!list_empty(&fsd->cancellations));
mutex_destroy(&fsd->cancellations_mtx);
}
kfree(fsd);
}
static struct vfsmount *debugfs_automount(struct path *path)
{
struct debugfs_fsdata *fsd = path->dentry->d_fsdata;
struct inode *inode = path->dentry->d_inode;
return fsd->automount(path->dentry, d_inode(path->dentry)->i_private);
return DEBUGFS_I(inode)->automount(path->dentry, inode->i_private);
}
static const struct dentry_operations debugfs_dops = {
@ -411,6 +424,7 @@ static struct dentry *end_creating(struct dentry *dentry)
static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const void *aux,
const struct file_operations *proxy_fops,
const void *real_fops)
{
@ -441,9 +455,11 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
inode->i_private = data;
inode->i_op = &debugfs_file_inode_operations;
if (!real_fops)
proxy_fops = &debugfs_noop_file_operations;
inode->i_fop = proxy_fops;
dentry->d_fsdata = (void *)((unsigned long)real_fops |
DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
DEBUGFS_I(inode)->raw = real_fops;
DEBUGFS_I(inode)->aux = aux;
d_instantiate(dentry, inode);
fsnotify_create(d_inode(dentry->d_parent), dentry);
@ -452,30 +468,22 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
struct dentry *debugfs_create_file_full(const char *name, umode_t mode,
struct dentry *parent, void *data,
const void *aux,
const struct file_operations *fops)
{
if (WARN_ON((unsigned long)fops &
DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))
return ERR_PTR(-EINVAL);
return __debugfs_create_file(name, mode, parent, data,
fops ? &debugfs_full_proxy_file_operations :
&debugfs_noop_file_operations,
return __debugfs_create_file(name, mode, parent, data, aux,
&debugfs_full_proxy_file_operations,
fops);
}
EXPORT_SYMBOL_GPL(debugfs_create_file_full);
struct dentry *debugfs_create_file_short(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct debugfs_short_fops *fops)
struct dentry *parent, void *data,
const void *aux,
const struct debugfs_short_fops *fops)
{
if (WARN_ON((unsigned long)fops &
DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))
return ERR_PTR(-EINVAL);
return __debugfs_create_file(name, mode, parent, data,
fops ? &debugfs_full_short_proxy_file_operations :
&debugfs_noop_file_operations,
return __debugfs_create_file(name, mode, parent, data, aux,
&debugfs_full_short_proxy_file_operations,
fops);
}
EXPORT_SYMBOL_GPL(debugfs_create_file_short);
@ -512,9 +520,8 @@ struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
const struct file_operations *fops)
{
return __debugfs_create_file(name, mode, parent, data,
fops ? &debugfs_open_proxy_file_operations :
&debugfs_noop_file_operations,
return __debugfs_create_file(name, mode, parent, data, NULL,
&debugfs_open_proxy_file_operations,
fops);
}
EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe);
@ -624,23 +631,13 @@ struct dentry *debugfs_create_automount(const char *name,
void *data)
{
struct dentry *dentry = start_creating(name, parent);
struct debugfs_fsdata *fsd;
struct inode *inode;
if (IS_ERR(dentry))
return dentry;
fsd = kzalloc(sizeof(*fsd), GFP_KERNEL);
if (!fsd) {
failed_creating(dentry);
return ERR_PTR(-ENOMEM);
}
fsd->automount = f;
if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
failed_creating(dentry);
kfree(fsd);
return ERR_PTR(-EPERM);
}
@ -648,14 +645,13 @@ struct dentry *debugfs_create_automount(const char *name,
if (unlikely(!inode)) {
pr_err("out of free dentries, can not create automount '%s'\n",
name);
kfree(fsd);
return failed_creating(dentry);
}
make_empty_dir_inode(inode);
inode->i_flags |= S_AUTOMOUNT;
inode->i_private = data;
dentry->d_fsdata = fsd;
DEBUGFS_I(inode)->automount = f;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode);
d_instantiate(dentry, inode);
@ -730,7 +726,7 @@ static void __debugfs_file_removed(struct dentry *dentry)
*/
smp_mb();
fsd = READ_ONCE(dentry->d_fsdata);
if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)
if (!fsd)
return;
/* if this was the last reference, we're done */
@ -834,76 +830,70 @@ void debugfs_lookup_and_remove(const char *name, struct dentry *parent)
EXPORT_SYMBOL_GPL(debugfs_lookup_and_remove);
/**
* debugfs_rename - rename a file/directory in the debugfs filesystem
* @old_dir: a pointer to the parent dentry for the renamed object. This
* should be a directory dentry.
* @old_dentry: dentry of an object to be renamed.
* @new_dir: a pointer to the parent dentry where the object should be
* moved. This should be a directory dentry.
* @new_name: a pointer to a string containing the target name.
* debugfs_change_name - rename a file/directory in the debugfs filesystem
* @dentry: dentry of an object to be renamed.
* @fmt: format for new name
*
* This function renames a file/directory in debugfs. The target must not
* exist for rename to succeed.
*
* This function will return a pointer to old_dentry (which is updated to
* reflect renaming) if it succeeds. If an error occurs, ERR_PTR(-ERROR)
* will be returned.
* This function will return 0 on success and -E... on failure.
*
* If debugfs is not enabled in the kernel, the value -%ENODEV will be
* returned.
*/
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
struct dentry *new_dir, const char *new_name)
int __printf(2, 3) debugfs_change_name(struct dentry *dentry, const char *fmt, ...)
{
int error;
struct dentry *dentry = NULL, *trap;
int error = 0;
const char *new_name;
struct name_snapshot old_name;
struct dentry *parent, *target;
struct inode *dir;
va_list ap;
if (IS_ERR(old_dir))
return old_dir;
if (IS_ERR(new_dir))
return new_dir;
if (IS_ERR_OR_NULL(old_dentry))
return old_dentry;
if (IS_ERR_OR_NULL(dentry))
return 0;
trap = lock_rename(new_dir, old_dir);
/* Source or destination directories don't exist? */
if (d_really_is_negative(old_dir) || d_really_is_negative(new_dir))
goto exit;
/* Source does not exist, cyclic rename, or mountpoint? */
if (d_really_is_negative(old_dentry) || old_dentry == trap ||
d_mountpoint(old_dentry))
goto exit;
dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
/* Lookup failed, cyclic rename or target exists? */
if (IS_ERR(dentry) || dentry == trap || d_really_is_positive(dentry))
goto exit;
va_start(ap, fmt);
new_name = kvasprintf_const(GFP_KERNEL, fmt, ap);
va_end(ap);
if (!new_name)
return -ENOMEM;
take_dentry_name_snapshot(&old_name, old_dentry);
parent = dget_parent(dentry);
dir = d_inode(parent);
inode_lock(dir);
error = simple_rename(&nop_mnt_idmap, d_inode(old_dir), old_dentry,
d_inode(new_dir), dentry, 0);
if (error) {
release_dentry_name_snapshot(&old_name);
goto exit;
take_dentry_name_snapshot(&old_name, dentry);
if (WARN_ON_ONCE(dentry->d_parent != parent)) {
error = -EINVAL;
goto out;
}
d_move(old_dentry, dentry);
fsnotify_move(d_inode(old_dir), d_inode(new_dir), &old_name.name,
d_is_dir(old_dentry),
NULL, old_dentry);
if (strcmp(old_name.name.name, new_name) == 0)
goto out;
target = lookup_one_len(new_name, parent, strlen(new_name));
if (IS_ERR(target)) {
error = PTR_ERR(target);
goto out;
}
if (d_really_is_positive(target)) {
dput(target);
error = -EINVAL;
goto out;
}
simple_rename_timestamp(dir, dentry, dir, target);
d_move(dentry, target);
dput(target);
fsnotify_move(dir, dir, &old_name.name, d_is_dir(dentry), NULL, dentry);
out:
release_dentry_name_snapshot(&old_name);
unlock_rename(new_dir, old_dir);
dput(dentry);
return old_dentry;
exit:
if (dentry && !IS_ERR(dentry))
dput(dentry);
unlock_rename(new_dir, old_dir);
if (IS_ERR(dentry))
return dentry;
return ERR_PTR(-EINVAL);
inode_unlock(dir);
dput(parent);
kfree_const(new_name);
return error;
}
EXPORT_SYMBOL_GPL(debugfs_rename);
EXPORT_SYMBOL_GPL(debugfs_change_name);
/**
* debugfs_initialized - Tells whether debugfs has been registered
@ -939,12 +929,22 @@ static int __init debugfs_init(void)
if (retval)
return retval;
retval = register_filesystem(&debug_fs_type);
if (retval)
debugfs_inode_cachep = kmem_cache_create("debugfs_inode_cache",
sizeof(struct debugfs_inode_info), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT,
init_once);
if (debugfs_inode_cachep == NULL) {
sysfs_remove_mount_point(kernel_kobj, "debug");
else
debugfs_registered = true;
return -ENOMEM;
}
return retval;
retval = register_filesystem(&debug_fs_type);
if (retval) { // Really not going to happen
sysfs_remove_mount_point(kernel_kobj, "debug");
kmem_cache_destroy(debugfs_inode_cachep);
return retval;
}
debugfs_registered = true;
return 0;
}
core_initcall(debugfs_init);

View file

@ -11,6 +11,22 @@
struct file_operations;
struct debugfs_inode_info {
struct inode vfs_inode;
union {
const void *raw;
const struct file_operations *real_fops;
const struct debugfs_short_fops *short_fops;
debugfs_automount_t automount;
};
const void *aux;
};
static inline struct debugfs_inode_info *DEBUGFS_I(struct inode *inode)
{
return container_of(inode, struct debugfs_inode_info, vfs_inode);
}
/* declared over in file.c */
extern const struct file_operations debugfs_noop_file_operations;
extern const struct file_operations debugfs_open_proxy_file_operations;
@ -20,29 +36,25 @@ extern const struct file_operations debugfs_full_short_proxy_file_operations;
struct debugfs_fsdata {
const struct file_operations *real_fops;
const struct debugfs_short_fops *short_fops;
union {
/* automount_fn is used when real_fops is NULL */
debugfs_automount_t automount;
struct {
refcount_t active_users;
struct completion active_users_drained;
struct {
refcount_t active_users;
struct completion active_users_drained;
/* protect cancellations */
struct mutex cancellations_mtx;
struct list_head cancellations;
};
/* protect cancellations */
struct mutex cancellations_mtx;
struct list_head cancellations;
unsigned int methods;
};
};
/*
* A dentry's ->d_fsdata either points to the real fops or to a
* dynamically allocated debugfs_fsdata instance.
* In order to distinguish between these two cases, a real fops
* pointer gets its lowest bit set.
*/
#define DEBUGFS_FSDATA_IS_REAL_FOPS_BIT BIT(0)
enum {
HAS_READ = 1,
HAS_WRITE = 2,
HAS_LSEEK = 4,
HAS_POLL = 8,
HAS_IOCTL = 16
};
/* Access BITS */
#define DEBUGFS_ALLOW_API BIT(0)
#define DEBUGFS_ALLOW_MOUNT BIT(1)

View file

@ -206,8 +206,8 @@ static void orangefs_kernel_debug_init(void)
pr_info("%s: overflow 1!\n", __func__);
}
debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer,
&kernel_debug_fops);
debugfs_create_file_aux_num(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer,
0, &kernel_debug_fops);
}
@ -306,11 +306,10 @@ static void orangefs_client_debug_init(void)
pr_info("%s: overflow! 2\n", __func__);
}
client_debug_dentry = debugfs_create_file(ORANGEFS_CLIENT_DEBUG_FILE,
0444,
debug_dir,
c_buffer,
&kernel_debug_fops);
client_debug_dentry = debugfs_create_file_aux_num(
ORANGEFS_CLIENT_DEBUG_FILE,
0444, debug_dir, c_buffer, 1,
&kernel_debug_fops);
}
/* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
@ -418,8 +417,7 @@ static ssize_t orangefs_debug_write(struct file *file,
* A service operation is required to set a new client-side
* debug mask.
*/
if (!strcmp(file->f_path.dentry->d_name.name,
ORANGEFS_KMOD_DEBUG_FILE)) {
if (!debugfs_get_aux_num(file)) { // kernel-debug
debug_string_to_mask(buf, &orangefs_gossip_debug_mask, 0);
debug_mask_to_string(&orangefs_gossip_debug_mask, 0);
debug_string = kernel_debug_string;

View file

@ -817,7 +817,7 @@ EXPORT_SYMBOL_GPL(sysfs_emit_at);
* Returns number of bytes written to @buf.
*/
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
const struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
memcpy(buf, attr->private + off, count);

View file

@ -67,21 +67,23 @@ static const struct file_operations __fops = { \
typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_lookup(const char *name, struct dentry *parent);
struct debugfs_short_fops {
ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
loff_t (*llseek) (struct file *, loff_t, int);
};
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_lookup(const char *name, struct dentry *parent);
struct dentry *debugfs_create_file_full(const char *name, umode_t mode,
struct dentry *parent, void *data,
const void *aux,
const struct file_operations *fops);
struct dentry *debugfs_create_file_short(const char *name, umode_t mode,
struct dentry *parent, void *data,
const void *aux,
const struct debugfs_short_fops *fops);
/**
@ -126,7 +128,15 @@ struct dentry *debugfs_create_file_short(const char *name, umode_t mode,
const struct debugfs_short_fops *: debugfs_create_file_short, \
struct file_operations *: debugfs_create_file_full, \
struct debugfs_short_fops *: debugfs_create_file_short) \
(name, mode, parent, data, fops)
(name, mode, parent, data, NULL, fops)
#define debugfs_create_file_aux(name, mode, parent, data, aux, fops) \
_Generic(fops, \
const struct file_operations *: debugfs_create_file_full, \
const struct debugfs_short_fops *: debugfs_create_file_short, \
struct file_operations *: debugfs_create_file_full, \
struct debugfs_short_fops *: debugfs_create_file_short) \
(name, mode, parent, data, aux, fops)
struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
struct dentry *parent, void *data,
@ -153,6 +163,7 @@ void debugfs_remove(struct dentry *dentry);
void debugfs_lookup_and_remove(const char *name, struct dentry *parent);
const struct file_operations *debugfs_real_fops(const struct file *filp);
const void *debugfs_get_aux(const struct file *file);
int debugfs_file_get(struct dentry *dentry);
void debugfs_file_put(struct dentry *dentry);
@ -164,8 +175,7 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
size_t len, loff_t *ppos);
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
struct dentry *new_dir, const char *new_name);
int debugfs_change_name(struct dentry *dentry, const char *fmt, ...) __printf(2, 3);
void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent,
u8 *value);
@ -259,6 +269,14 @@ static inline struct dentry *debugfs_lookup(const char *name,
return ERR_PTR(-ENODEV);
}
static inline struct dentry *debugfs_create_file_aux(const char *name,
umode_t mode, struct dentry *parent,
void *data, void *aux,
const void *fops)
{
return ERR_PTR(-ENODEV);
}
static inline struct dentry *debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const void *fops)
@ -312,6 +330,7 @@ static inline void debugfs_lookup_and_remove(const char *name,
{ }
const struct file_operations *debugfs_real_fops(const struct file *filp);
void *debugfs_get_aux(const struct file *file);
static inline int debugfs_file_get(struct dentry *dentry)
{
@ -341,10 +360,10 @@ static inline ssize_t debugfs_attr_write_signed(struct file *file,
return -ENODEV;
}
static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
struct dentry *new_dir, char *new_name)
static inline int __printf(2, 3) debugfs_change_name(struct dentry *dentry,
const char *fmt, ...)
{
return ERR_PTR(-ENODEV);
return -ENODEV;
}
static inline void debugfs_create_u8(const char *name, umode_t mode,
@ -452,6 +471,11 @@ static inline ssize_t debugfs_read_file_str(struct file *file,
#endif
#define debugfs_create_file_aux_num(name, mode, parent, data, n, fops) \
debugfs_create_file_aux(name, mode, parent, data, \
(void *)(unsigned long)n, fops)
#define debugfs_get_aux_num(f) (unsigned long)debugfs_get_aux(f)
/**
* debugfs_create_xul - create a debugfs file that is used to read and write an
* unsigned long value, formatted in hexadecimal

View file

@ -399,7 +399,23 @@ void __iomem *devm_of_iomap(struct device *dev,
#endif
/* allows to add/remove a custom action to devres stack */
void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
int devm_remove_action_nowarn(struct device *dev, void (*action)(void *), void *data);
/**
* devm_remove_action() - removes previously added custom action
* @dev: Device that owns the action
* @action: Function implementing the action
* @data: Pointer to data passed to @action implementation
*
* Removes instance of @action previously added by devm_add_action().
* Both action and data should match one of the existing entries.
*/
static inline
void devm_remove_action(struct device *dev, void (*action)(void *), void *data)
{
WARN_ON(devm_remove_action_nowarn(dev, action, data));
}
void devm_release_action(struct device *dev, void (*action)(void *), void *data);
int __devm_add_action(struct device *dev, void (*action)(void *), void *data, const char *name);
@ -1074,18 +1090,44 @@ void device_del(struct device *dev);
DEFINE_FREE(device_del, struct device *, if (_T) device_del(_T))
int device_for_each_child(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data));
int device_for_each_child_reverse(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data));
int device_for_each_child(struct device *parent, void *data,
device_iter_t fn);
int device_for_each_child_reverse(struct device *parent, void *data,
device_iter_t fn);
int device_for_each_child_reverse_from(struct device *parent,
struct device *from, const void *data,
int (*fn)(struct device *, const void *));
struct device *device_find_child(struct device *dev, void *data,
int (*match)(struct device *dev, void *data));
struct device *device_find_child_by_name(struct device *parent,
const char *name);
struct device *device_find_any_child(struct device *parent);
struct device *from, void *data,
device_iter_t fn);
struct device *device_find_child(struct device *parent, const void *data,
device_match_t match);
/**
* device_find_child_by_name - device iterator for locating a child device.
* @parent: parent struct device
* @name: name of the child device
*
* This is similar to the device_find_child() function above, but it
* returns a reference to a device that has the name @name.
*
* NOTE: you will need to drop the reference with put_device() after use.
*/
static inline struct device *device_find_child_by_name(struct device *parent,
const char *name)
{
return device_find_child(parent, name, device_match_name);
}
/**
* device_find_any_child - device iterator for locating a child device, if any.
* @parent: parent struct device
*
* This is similar to the device_find_child() function above, but it
* returns a reference to a child device, if any.
*
* NOTE: you will need to drop the reference with put_device() after use.
*/
static inline struct device *device_find_any_child(struct device *parent)
{
return device_find_child(parent, NULL, device_match_any);
}
int device_rename(struct device *dev, const char *new_name);
int device_move(struct device *dev, struct device *new_parent,

View file

@ -134,6 +134,7 @@ typedef int (*device_match_t)(struct device *dev, const void *data);
/* 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_type(struct device *dev, const void *type);
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);
@ -141,9 +142,12 @@ int device_match_acpi_dev(struct device *dev, const void *adev);
int device_match_acpi_handle(struct device *dev, const void *handle);
int device_match_any(struct device *dev, const void *unused);
/* Device iterating function type for various driver core for_each APIs */
typedef int (*device_iter_t)(struct device *dev, void *data);
/* iterator helpers for buses */
int bus_for_each_dev(const struct bus_type *bus, struct device *start, void *data,
int (*fn)(struct device *dev, void *data));
int bus_for_each_dev(const struct bus_type *bus, struct device *start,
void *data, device_iter_t fn);
struct device *bus_find_device(const struct bus_type *bus, struct device *start,
const void *data, device_match_t match);
/**

View file

@ -82,18 +82,16 @@ bool class_is_registered(const struct class *class);
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);
int class_compat_create_link(struct class_compat *cls, struct device *dev);
void class_compat_remove_link(struct class_compat *cls, struct device *dev);
void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class,
const struct device *start, const struct device_type *type);
struct device *class_dev_iter_next(struct class_dev_iter *iter);
void class_dev_iter_exit(struct class_dev_iter *iter);
int class_for_each_device(const struct class *class, const struct device *start, void *data,
int (*fn)(struct device *dev, void *data));
int class_for_each_device(const struct class *class, const struct device *start,
void *data, device_iter_t fn);
struct device *class_find_device(const struct class *class, const struct device *start,
const void *data, device_match_t match);

View file

@ -154,7 +154,7 @@ void driver_remove_file(const struct device_driver *driver,
int driver_set_override(struct device *dev, const char **override,
const char *s, size_t len);
int __must_check driver_for_each_device(struct device_driver *drv, struct device *start,
void *data, int (*fn)(struct device *dev, void *));
void *data, device_iter_t fn);
struct device *driver_find_device(const struct device_driver *drv,
struct device *start, const void *data,
device_match_t match);

View file

@ -438,21 +438,21 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev,
extern const struct bus_type fsl_mc_bus_type;
extern struct device_type fsl_mc_bus_dprc_type;
extern struct device_type fsl_mc_bus_dpni_type;
extern struct device_type fsl_mc_bus_dpio_type;
extern struct device_type fsl_mc_bus_dpsw_type;
extern struct device_type fsl_mc_bus_dpbp_type;
extern struct device_type fsl_mc_bus_dpcon_type;
extern struct device_type fsl_mc_bus_dpmcp_type;
extern struct device_type fsl_mc_bus_dpmac_type;
extern struct device_type fsl_mc_bus_dprtc_type;
extern struct device_type fsl_mc_bus_dpseci_type;
extern struct device_type fsl_mc_bus_dpdmux_type;
extern struct device_type fsl_mc_bus_dpdcei_type;
extern struct device_type fsl_mc_bus_dpaiop_type;
extern struct device_type fsl_mc_bus_dpci_type;
extern struct device_type fsl_mc_bus_dpdmai_type;
extern const struct device_type fsl_mc_bus_dprc_type;
extern const struct device_type fsl_mc_bus_dpni_type;
extern const struct device_type fsl_mc_bus_dpio_type;
extern const struct device_type fsl_mc_bus_dpsw_type;
extern const struct device_type fsl_mc_bus_dpbp_type;
extern const struct device_type fsl_mc_bus_dpcon_type;
extern const struct device_type fsl_mc_bus_dpmcp_type;
extern const struct device_type fsl_mc_bus_dpmac_type;
extern const struct device_type fsl_mc_bus_dprtc_type;
extern const struct device_type fsl_mc_bus_dpseci_type;
extern const struct device_type fsl_mc_bus_dpdmux_type;
extern const struct device_type fsl_mc_bus_dpdcei_type;
extern const struct device_type fsl_mc_bus_dpaiop_type;
extern const struct device_type fsl_mc_bus_dpci_type;
extern const struct device_type fsl_mc_bus_dpdmai_type;
static inline bool is_fsl_mc_bus_dprc(const struct fsl_mc_device *mc_dev)
{

View file

@ -52,8 +52,6 @@ const struct kobj_ns_type_operations *kobj_ns_ops(const struct kobject *kobj);
bool kobj_ns_current_may_mount(enum kobj_ns_type type);
void *kobj_ns_grab_current(enum kobj_ns_type type);
const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
const void *kobj_ns_initial(enum kobj_ns_type type);
void kobj_ns_drop(enum kobj_ns_type type, void *ns);
#endif /* _LINUX_KOBJECT_NS_H */

View file

@ -293,7 +293,7 @@ __ATTRIBUTE_GROUPS(_name)
#define BIN_ATTRIBUTE_GROUPS(_name) \
static const struct attribute_group _name##_group = { \
.bin_attrs = _name##_attrs, \
.bin_attrs_new = _name##_attrs, \
}; \
__ATTRIBUTE_GROUPS(_name)
@ -511,7 +511,7 @@ __printf(3, 4)
int sysfs_emit_at(char *buf, int at, const char *fmt, ...);
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
const struct bin_attribute *attr, char *buf,
loff_t off, size_t count);
#else /* CONFIG_SYSFS */
@ -774,7 +774,7 @@ static inline int sysfs_emit_at(char *buf, int at, const char *fmt, ...)
static inline ssize_t sysfs_bin_attr_simple_read(struct file *file,
struct kobject *kobj,
struct bin_attribute *attr,
const struct bin_attribute *attr,
char *buf, loff_t off,
size_t count)
{

View file

@ -493,8 +493,8 @@ extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost);
extern int iscsi_flashnode_bus_match(struct device *dev,
const struct device_driver *drv);
extern struct device *
iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
int (*fn)(struct device *dev, void *data));
iscsi_find_flashnode_sess(struct Scsi_Host *shost, const void *data,
device_match_t fn);
extern struct device *
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);

View file

@ -8001,17 +8001,6 @@ struct btf_module {
static LIST_HEAD(btf_modules);
static DEFINE_MUTEX(btf_module_mutex);
static ssize_t
btf_module_read(struct file *file, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t len)
{
const struct btf *btf = bin_attr->private;
memcpy(buf, btf->data + off, len);
return len;
}
static void purge_cand_cache(struct btf *btf);
static int btf_module_notify(struct notifier_block *nb, unsigned long op,
@ -8072,8 +8061,8 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op,
attr->attr.name = btf->name;
attr->attr.mode = 0444;
attr->size = btf->data_size;
attr->private = btf;
attr->read = btf_module_read;
attr->private = btf->data;
attr->read_new = sysfs_bin_attr_simple_read;
err = sysfs_create_bin_file(btf_kobj, attr);
if (err) {

View file

@ -12,24 +12,16 @@
extern char __start_BTF[];
extern char __stop_BTF[];
static ssize_t
btf_vmlinux_read(struct file *file, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t len)
{
memcpy(buf, __start_BTF + off, len);
return len;
}
static struct bin_attribute bin_attr_btf_vmlinux __ro_after_init = {
.attr = { .name = "vmlinux", .mode = 0444, },
.read = btf_vmlinux_read,
.read_new = sysfs_bin_attr_simple_read,
};
struct kobject *btf_kobj;
static int __init btf_vmlinux_init(void)
{
bin_attr_btf_vmlinux.private = __start_BTF;
bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF;
if (bin_attr_btf_vmlinux.size == 0)

View file

@ -29,25 +29,12 @@ asm (
extern char kernel_headers_data[];
extern char kernel_headers_data_end[];
static ssize_t
ikheaders_read(struct file *file, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t len)
{
memcpy(buf, &kernel_headers_data[off], len);
return len;
}
static struct bin_attribute kheaders_attr __ro_after_init = {
.attr = {
.name = "kheaders.tar.xz",
.mode = 0444,
},
.read = &ikheaders_read,
};
static struct bin_attribute kheaders_attr __ro_after_init =
__BIN_ATTR_SIMPLE_RO(kheaders.tar.xz, 0444);
static int __init ikheaders_init(void)
{
kheaders_attr.private = kernel_headers_data;
kheaders_attr.size = (kernel_headers_data_end -
kernel_headers_data);
return sysfs_create_bin_file(kernel_kobj, &kheaders_attr);

View file

@ -239,21 +239,7 @@ extern const void __start_notes;
extern const void __stop_notes;
#define notes_size (&__stop_notes - &__start_notes)
static ssize_t notes_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
memcpy(buf, &__start_notes + off, count);
return count;
}
static struct bin_attribute notes_attr __ro_after_init = {
.attr = {
.name = "notes",
.mode = S_IRUGO,
},
.read = &notes_read,
};
static __ro_after_init BIN_ATTR_SIMPLE_RO(notes);
struct kobject *kernel_kobj;
EXPORT_SYMBOL_GPL(kernel_kobj);
@ -307,8 +293,9 @@ static int __init ksysfs_init(void)
goto kset_exit;
if (notes_size > 0) {
notes_attr.size = notes_size;
error = sysfs_create_bin_file(kernel_kobj, &notes_attr);
bin_attr_notes.private = (void *)&__start_notes;
bin_attr_notes.size = notes_size;
error = sysfs_create_bin_file(kernel_kobj, &bin_attr_notes);
if (error)
goto group_exit;
}

View file

@ -190,7 +190,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info)
nattr->attr.mode = 0444;
nattr->size = info->sechdrs[i].sh_size;
nattr->private = (void *)info->sechdrs[i].sh_addr;
nattr->read = sysfs_bin_attr_simple_read;
nattr->read_new = sysfs_bin_attr_simple_read;
*(gattr++) = nattr++;
}
++loaded;

View file

@ -1096,30 +1096,6 @@ void *kobj_ns_grab_current(enum kobj_ns_type type)
}
EXPORT_SYMBOL_GPL(kobj_ns_grab_current);
const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
{
const void *ns = NULL;
spin_lock(&kobj_ns_type_lock);
if (kobj_ns_type_is_valid(type) && kobj_ns_ops_tbl[type])
ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
spin_unlock(&kobj_ns_type_lock);
return ns;
}
const void *kobj_ns_initial(enum kobj_ns_type type)
{
const void *ns = NULL;
spin_lock(&kobj_ns_type_lock);
if (kobj_ns_type_is_valid(type) && kobj_ns_ops_tbl[type])
ns = kobj_ns_ops_tbl[type]->initial_ns();
spin_unlock(&kobj_ns_type_lock);
return ns;
}
void kobj_ns_drop(enum kobj_ns_type type, void *ns)
{
spin_lock(&kobj_ns_type_lock);

View file

@ -195,8 +195,6 @@ int shrinker_debugfs_add(struct shrinker *shrinker)
int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
{
struct dentry *entry;
char buf[128];
const char *new, *old;
va_list ap;
int ret = 0;
@ -213,18 +211,8 @@ int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
old = shrinker->name;
shrinker->name = new;
if (shrinker->debugfs_entry) {
snprintf(buf, sizeof(buf), "%s-%d", shrinker->name,
shrinker->debugfs_id);
entry = debugfs_rename(shrinker_debugfs_root,
shrinker->debugfs_entry,
shrinker_debugfs_root, buf);
if (IS_ERR(entry))
ret = PTR_ERR(entry);
else
shrinker->debugfs_entry = entry;
}
ret = debugfs_change_name(shrinker->debugfs_entry, "%s-%d",
shrinker->name, shrinker->debugfs_id);
mutex_unlock(&shrinker_mutex);

View file

@ -7509,10 +7509,7 @@ static int slab_debug_trace_open(struct inode *inode, struct file *filep)
return -ENOMEM;
}
if (strcmp(filep->f_path.dentry->d_name.name, "alloc_traces") == 0)
alloc = TRACK_ALLOC;
else
alloc = TRACK_FREE;
alloc = debugfs_get_aux_num(filep);
if (!alloc_loc_track(t, PAGE_SIZE / sizeof(struct location), GFP_KERNEL)) {
bitmap_free(obj_map);
@ -7568,11 +7565,11 @@ static void debugfs_slab_add(struct kmem_cache *s)
slab_cache_dir = debugfs_create_dir(s->name, slab_debugfs_root);
debugfs_create_file("alloc_traces", 0400,
slab_cache_dir, s, &slab_debugfs_fops);
debugfs_create_file_aux_num("alloc_traces", 0400, slab_cache_dir, s,
TRACK_ALLOC, &slab_debugfs_fops);
debugfs_create_file("free_traces", 0400,
slab_cache_dir, s, &slab_debugfs_fops);
debugfs_create_file_aux_num("free_traces", 0400, slab_cache_dir, s,
TRACK_FREE, &slab_debugfs_fops);
}
void debugfs_slab_release(struct kmem_cache *s)

View file

@ -1367,7 +1367,7 @@ static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn)
return dsa_switch_parse_ports_of(ds, dn);
}
static int dev_is_class(struct device *dev, void *class)
static int dev_is_class(struct device *dev, const void *class)
{
if (dev->class != NULL && !strcmp(dev->class->name, class))
return 1;

View file

@ -57,14 +57,11 @@ DEFINE_SHOW_ATTRIBUTE(hsr_node_table);
void hsr_debugfs_rename(struct net_device *dev)
{
struct hsr_priv *priv = netdev_priv(dev);
struct dentry *d;
int err;
d = debugfs_rename(hsr_debugfs_root_dir, priv->node_tbl_root,
hsr_debugfs_root_dir, dev->name);
if (IS_ERR(d))
err = debugfs_change_name(priv->node_tbl_root, "%s", dev->name);
if (err)
netdev_warn(dev, "failed to rename\n");
else
priv->node_tbl_root = d;
}
/* hsr_debugfs_init - create hsr node_table file for dumping

View file

@ -1025,16 +1025,7 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
{
struct dentry *dir;
char buf[10 + IFNAMSIZ];
dir = sdata->vif.debugfs_dir;
if (IS_ERR_OR_NULL(dir))
return;
sprintf(buf, "netdev:%s", sdata->name);
debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
debugfs_change_name(sdata->vif.debugfs_dir, "netdev:%s", sdata->name);
}
void ieee80211_debugfs_recreate_netdev(struct ieee80211_sub_if_data *sdata,

View file

@ -143,10 +143,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
if (result)
return result;
if (!IS_ERR_OR_NULL(rdev->wiphy.debugfsdir))
debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
rdev->wiphy.debugfsdir,
rdev->wiphy.debugfsdir->d_parent, newname);
debugfs_change_name(rdev->wiphy.debugfsdir, "%s", newname);
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);

View file

@ -20,9 +20,13 @@
#include <linux/jump_label.h>
#include <linux/mdio.h>
#include <linux/miscdevice.h>
#include <linux/of_device.h>
#include <linux/pci.h>
#include <linux/phy.h>
#include <linux/pid_namespace.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/property.h>
#include <linux/refcount.h>
#include <linux/sched.h>
#include <linux/security.h>

10
rust/helpers/device.c Normal file
View file

@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/device.h>
int rust_helper_devm_add_action(struct device *dev,
void (*action)(void *),
void *data)
{
return devm_add_action(dev, action, data);
}

View file

@ -12,14 +12,19 @@
#include "build_assert.c"
#include "build_bug.c"
#include "cred.c"
#include "device.c"
#include "err.c"
#include "fs.c"
#include "io.c"
#include "jump_label.c"
#include "kunit.c"
#include "mutex.c"
#include "page.c"
#include "platform.c"
#include "pci.c"
#include "pid_namespace.c"
#include "rbtree.c"
#include "rcu.c"
#include "refcount.c"
#include "security.c"
#include "signal.c"

101
rust/helpers/io.c Normal file
View file

@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/io.h>
void __iomem *rust_helper_ioremap(phys_addr_t offset, size_t size)
{
return ioremap(offset, size);
}
void rust_helper_iounmap(volatile void __iomem *addr)
{
iounmap(addr);
}
u8 rust_helper_readb(const volatile void __iomem *addr)
{
return readb(addr);
}
u16 rust_helper_readw(const volatile void __iomem *addr)
{
return readw(addr);
}
u32 rust_helper_readl(const volatile void __iomem *addr)
{
return readl(addr);
}
#ifdef CONFIG_64BIT
u64 rust_helper_readq(const volatile void __iomem *addr)
{
return readq(addr);
}
#endif
void rust_helper_writeb(u8 value, volatile void __iomem *addr)
{
writeb(value, addr);
}
void rust_helper_writew(u16 value, volatile void __iomem *addr)
{
writew(value, addr);
}
void rust_helper_writel(u32 value, volatile void __iomem *addr)
{
writel(value, addr);
}
#ifdef CONFIG_64BIT
void rust_helper_writeq(u64 value, volatile void __iomem *addr)
{
writeq(value, addr);
}
#endif
u8 rust_helper_readb_relaxed(const volatile void __iomem *addr)
{
return readb_relaxed(addr);
}
u16 rust_helper_readw_relaxed(const volatile void __iomem *addr)
{
return readw_relaxed(addr);
}
u32 rust_helper_readl_relaxed(const volatile void __iomem *addr)
{
return readl_relaxed(addr);
}
#ifdef CONFIG_64BIT
u64 rust_helper_readq_relaxed(const volatile void __iomem *addr)
{
return readq_relaxed(addr);
}
#endif
void rust_helper_writeb_relaxed(u8 value, volatile void __iomem *addr)
{
writeb_relaxed(value, addr);
}
void rust_helper_writew_relaxed(u16 value, volatile void __iomem *addr)
{
writew_relaxed(value, addr);
}
void rust_helper_writel_relaxed(u32 value, volatile void __iomem *addr)
{
writel_relaxed(value, addr);
}
#ifdef CONFIG_64BIT
void rust_helper_writeq_relaxed(u64 value, volatile void __iomem *addr)
{
writeq_relaxed(value, addr);
}
#endif

18
rust/helpers/pci.c Normal file
View file

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
void rust_helper_pci_set_drvdata(struct pci_dev *pdev, void *data)
{
pci_set_drvdata(pdev, data);
}
void *rust_helper_pci_get_drvdata(struct pci_dev *pdev)
{
return pci_get_drvdata(pdev);
}
resource_size_t rust_helper_pci_resource_len(struct pci_dev *pdev, int bar)
{
return pci_resource_len(pdev, bar);
}

13
rust/helpers/platform.c Normal file
View file

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/platform_device.h>
void *rust_helper_platform_get_drvdata(const struct platform_device *pdev)
{
return platform_get_drvdata(pdev);
}
void rust_helper_platform_set_drvdata(struct platform_device *pdev, void *data)
{
platform_set_drvdata(pdev, data);
}

13
rust/helpers/rcu.c Normal file
View file

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/rcupdate.h>
void rust_helper_rcu_read_lock(void)
{
rcu_read_lock();
}
void rust_helper_rcu_read_unlock(void)
{
rcu_read_unlock();
}

View file

@ -6,6 +6,7 @@
use crate::{
bindings,
str::CStr,
types::{ARef, Opaque},
};
use core::{fmt, ptr};
@ -180,6 +181,12 @@ impl Device {
)
};
}
/// Checks if property is present or not.
pub fn property_present(&self, name: &CStr) -> bool {
// SAFETY: By the invariant of `CStr`, `name` is null-terminated.
unsafe { bindings::device_property_present(self.as_raw().cast_const(), name.as_char_ptr()) }
}
}
// SAFETY: Instances of `Device` are always reference-counted.

Some files were not shown because too many files have changed in this diff Show more