forked from mirrors/linux
Driver core changes for 6.16-rc1
Here are the driver core / kernfs changes for 6.16-rc1.
Not a huge number of changes this development cycle, here's the summary
of what is included in here:
- kernfs locking tweaks, pushing some global locks down into a per-fs
image lock
- rust driver core and pci device bindings added for new features.
- sysfs const work for bin_attributes. This churn should now be
completed for those types of attributes
- auxbus device creation helpers added
- fauxbus fix for creating sysfs files after the probe completed
properly
- other tiny updates for driver core things.
All of these have been in linux-next for over a week with no reported
issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-----BEGIN PGP SIGNATURE-----
iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaDbe+g8cZ3JlZ0Brcm9h
aC5jb20ACgkQMUfUDdst+ylYbACgl/MngU9pRnx5jZIQh6bWveFSeo8AnRE4U5x0
X+lgTPjGKL1RrV3C5HJp
=+0BA
-----END PGP SIGNATURE-----
Merge tag 'driver-core-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core updates from Greg KH:
"Here are the driver core / kernfs changes for 6.16-rc1.
Not a huge number of changes this development cycle, here's the
summary of what is included in here:
- kernfs locking tweaks, pushing some global locks down into a per-fs
image lock
- rust driver core and pci device bindings added for new features.
- sysfs const work for bin_attributes.
The final churn of switching away from and removing the
transitional struct members, "read_new", "write_new" and
"bin_attrs_new" will come after the merge window to avoid
unnecesary merge conflicts.
- auxbus device creation helpers added
- fauxbus fix for creating sysfs files after the probe completed
properly
- other tiny updates for driver core things.
All of these have been in linux-next for over a week with no reported
issues"
* tag 'driver-core-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core:
kernfs: Relax constraint in draining guard
Documentation: embargoed-hardware-issues.rst: Remove myself
drivers: hv: fix up const issue with vmbus_chan_bin_attrs
firmware_loader: use SHA-256 library API instead of crypto_shash API
docs: debugfs: do not recommend debugfs_remove_recursive
PM: wakeup: Do not expose 4 device wakeup source APIs
kernfs: switch global kernfs_rename_lock to per-fs lock
kernfs: switch global kernfs_idr_lock to per-fs lock
driver core: auxiliary bus: Fix IS_ERR() vs NULL mixup in __devm_auxiliary_device_create()
sysfs: constify attribute_group::bin_attrs
sysfs: constify bin_attribute argument of bin_attribute::read/write()
software node: Correct a OOB check in software_node_get_reference_args()
devres: simplify devm_kstrdup() using devm_kmemdup()
platform: replace magic number with macro PLATFORM_DEVID_NONE
component: do not try to unbind unbound components
driver core: auxiliary bus: add device creation helpers
driver core: faux: Add sysfs groups after probing
This commit is contained in:
commit
9d230d500b
20 changed files with 205 additions and 132 deletions
|
|
@ -229,22 +229,15 @@ module is unloaded without explicitly removing debugfs entries, the result
|
||||||
will be a lot of stale pointers and no end of highly antisocial behavior.
|
will be a lot of stale pointers and no end of highly antisocial behavior.
|
||||||
So all debugfs users - at least those which can be built as modules - must
|
So all debugfs users - at least those which can be built as modules - must
|
||||||
be prepared to remove all files and directories they create there. A file
|
be prepared to remove all files and directories they create there. A file
|
||||||
can be removed with::
|
or directory can be removed with::
|
||||||
|
|
||||||
void debugfs_remove(struct dentry *dentry);
|
void debugfs_remove(struct dentry *dentry);
|
||||||
|
|
||||||
The dentry value can be NULL or an error value, in which case nothing will
|
The dentry value can be NULL or an error value, in which case nothing will
|
||||||
be removed.
|
be removed. Note that this function will recursively remove all files and
|
||||||
|
directories underneath it. Previously, debugfs_remove_recursive() was used
|
||||||
Once upon a time, debugfs users were required to remember the dentry
|
to perform that task, but this function is now just an alias to
|
||||||
pointer for every debugfs file they created so that all files could be
|
debugfs_remove(). debugfs_remove_recursive() should be considered
|
||||||
cleaned up. We live in more civilized times now, though, and debugfs users
|
deprecated.
|
||||||
can call::
|
|
||||||
|
|
||||||
void debugfs_remove_recursive(struct dentry *dentry);
|
|
||||||
|
|
||||||
If this function is passed a pointer for the dentry corresponding to the
|
|
||||||
top-level directory, the entire hierarchy below that directory will be
|
|
||||||
removed.
|
|
||||||
|
|
||||||
.. [1] http://lwn.net/Articles/309298/
|
.. [1] http://lwn.net/Articles/309298/
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ The general idea is:
|
||||||
``my_variable``
|
``my_variable``
|
||||||
|
|
||||||
- Clean up the directory when removing the device
|
- Clean up the directory when removing the device
|
||||||
(``debugfs_remove_recursive(parent);``)
|
(``debugfs_remove(parent);``)
|
||||||
|
|
||||||
For the full documentation see :doc:`/filesystems/debugfs`.
|
For the full documentation see :doc:`/filesystems/debugfs`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,6 @@ an involved disclosed party. The current ambassadors list:
|
||||||
AMD Tom Lendacky <thomas.lendacky@amd.com>
|
AMD Tom Lendacky <thomas.lendacky@amd.com>
|
||||||
Ampere Darren Hart <darren@os.amperecomputing.com>
|
Ampere Darren Hart <darren@os.amperecomputing.com>
|
||||||
ARM Catalin Marinas <catalin.marinas@arm.com>
|
ARM Catalin Marinas <catalin.marinas@arm.com>
|
||||||
IBM Power Michael Ellerman <ellerman@au.ibm.com>
|
|
||||||
IBM Z Christian Borntraeger <borntraeger@de.ibm.com>
|
IBM Z Christian Borntraeger <borntraeger@de.ibm.com>
|
||||||
Intel Tony Luck <tony.luck@intel.com>
|
Intel Tony Luck <tony.luck@intel.com>
|
||||||
Qualcomm Trilok Soni <quic_tsoni@quicinc.com>
|
Qualcomm Trilok Soni <quic_tsoni@quicinc.com>
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,114 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
|
EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
|
||||||
|
|
||||||
|
static void auxiliary_device_release(struct device *dev)
|
||||||
|
{
|
||||||
|
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
|
||||||
|
|
||||||
|
kfree(auxdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* auxiliary_device_create - create a device on the auxiliary bus
|
||||||
|
* @dev: parent device
|
||||||
|
* @modname: module name used to create the auxiliary driver name.
|
||||||
|
* @devname: auxiliary bus device name
|
||||||
|
* @platform_data: auxiliary bus device platform data
|
||||||
|
* @id: auxiliary bus device id
|
||||||
|
*
|
||||||
|
* Helper to create an auxiliary bus device.
|
||||||
|
* The device created matches driver 'modname.devname' on the auxiliary bus.
|
||||||
|
*/
|
||||||
|
struct auxiliary_device *auxiliary_device_create(struct device *dev,
|
||||||
|
const char *modname,
|
||||||
|
const char *devname,
|
||||||
|
void *platform_data,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
struct auxiliary_device *auxdev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL);
|
||||||
|
if (!auxdev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
auxdev->id = id;
|
||||||
|
auxdev->name = devname;
|
||||||
|
auxdev->dev.parent = dev;
|
||||||
|
auxdev->dev.platform_data = platform_data;
|
||||||
|
auxdev->dev.release = auxiliary_device_release;
|
||||||
|
device_set_of_node_from_dev(&auxdev->dev, dev);
|
||||||
|
|
||||||
|
ret = auxiliary_device_init(auxdev);
|
||||||
|
if (ret) {
|
||||||
|
kfree(auxdev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = __auxiliary_device_add(auxdev, modname);
|
||||||
|
if (ret) {
|
||||||
|
/*
|
||||||
|
* It may look odd but auxdev should not be freed here.
|
||||||
|
* auxiliary_device_uninit() calls device_put() which call
|
||||||
|
* the device release function, freeing auxdev.
|
||||||
|
*/
|
||||||
|
auxiliary_device_uninit(auxdev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return auxdev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(auxiliary_device_create);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* auxiliary_device_destroy - remove an auxiliary device
|
||||||
|
* @auxdev: pointer to the auxdev to be removed
|
||||||
|
*
|
||||||
|
* Helper to remove an auxiliary device created with
|
||||||
|
* auxiliary_device_create()
|
||||||
|
*/
|
||||||
|
void auxiliary_device_destroy(void *auxdev)
|
||||||
|
{
|
||||||
|
struct auxiliary_device *_auxdev = auxdev;
|
||||||
|
|
||||||
|
auxiliary_device_delete(_auxdev);
|
||||||
|
auxiliary_device_uninit(_auxdev);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(auxiliary_device_destroy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __devm_auxiliary_device_create - create a managed device on the auxiliary bus
|
||||||
|
* @dev: parent device
|
||||||
|
* @modname: module name used to create the auxiliary driver name.
|
||||||
|
* @devname: auxiliary bus device name
|
||||||
|
* @platform_data: auxiliary bus device platform data
|
||||||
|
* @id: auxiliary bus device id
|
||||||
|
*
|
||||||
|
* Device managed helper to create an auxiliary bus device.
|
||||||
|
* The device created matches driver 'modname.devname' on the auxiliary bus.
|
||||||
|
*/
|
||||||
|
struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
|
||||||
|
const char *modname,
|
||||||
|
const char *devname,
|
||||||
|
void *platform_data,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
struct auxiliary_device *auxdev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
auxdev = auxiliary_device_create(dev, modname, devname, platform_data, id);
|
||||||
|
if (!auxdev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret = devm_add_action_or_reset(dev, auxiliary_device_destroy,
|
||||||
|
auxdev);
|
||||||
|
if (ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return auxdev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__devm_auxiliary_device_create);
|
||||||
|
|
||||||
void __init auxiliary_bus_init(void)
|
void __init auxiliary_bus_init(void)
|
||||||
{
|
{
|
||||||
WARN_ON(bus_register(&auxiliary_bus_type));
|
WARN_ON(bus_register(&auxiliary_bus_type));
|
||||||
|
|
|
||||||
|
|
@ -586,7 +586,8 @@ EXPORT_SYMBOL_GPL(component_master_is_bound);
|
||||||
static void component_unbind(struct component *component,
|
static void component_unbind(struct component *component,
|
||||||
struct aggregate_device *adev, void *data)
|
struct aggregate_device *adev, void *data)
|
||||||
{
|
{
|
||||||
WARN_ON(!component->bound);
|
if (WARN_ON(!component->bound))
|
||||||
|
return;
|
||||||
|
|
||||||
dev_dbg(adev->parent, "unbinding %s component %p (ops %ps)\n",
|
dev_dbg(adev->parent, "unbinding %s component %p (ops %ps)\n",
|
||||||
dev_name(component->dev), component, component->ops);
|
dev_name(component->dev), component, component->ops);
|
||||||
|
|
|
||||||
|
|
@ -987,17 +987,10 @@ EXPORT_SYMBOL_GPL(devm_krealloc);
|
||||||
*/
|
*/
|
||||||
char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp)
|
char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp)
|
||||||
{
|
{
|
||||||
size_t size;
|
|
||||||
char *buf;
|
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
size = strlen(s) + 1;
|
return devm_kmemdup(dev, s, strlen(s) + 1, gfp);
|
||||||
buf = devm_kmalloc(dev, size, gfp);
|
|
||||||
if (buf)
|
|
||||||
memcpy(buf, s, size);
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_kstrdup);
|
EXPORT_SYMBOL_GPL(devm_kstrdup);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
struct faux_object {
|
struct faux_object {
|
||||||
struct faux_device faux_dev;
|
struct faux_device faux_dev;
|
||||||
const struct faux_device_ops *faux_ops;
|
const struct faux_device_ops *faux_ops;
|
||||||
|
const struct attribute_group **groups;
|
||||||
};
|
};
|
||||||
#define to_faux_object(dev) container_of_const(dev, struct faux_object, faux_dev.dev)
|
#define to_faux_object(dev) container_of_const(dev, struct faux_object, faux_dev.dev)
|
||||||
|
|
||||||
|
|
@ -43,10 +44,21 @@ static int faux_probe(struct device *dev)
|
||||||
struct faux_object *faux_obj = to_faux_object(dev);
|
struct faux_object *faux_obj = to_faux_object(dev);
|
||||||
struct faux_device *faux_dev = &faux_obj->faux_dev;
|
struct faux_device *faux_dev = &faux_obj->faux_dev;
|
||||||
const struct faux_device_ops *faux_ops = faux_obj->faux_ops;
|
const struct faux_device_ops *faux_ops = faux_obj->faux_ops;
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
if (faux_ops && faux_ops->probe)
|
if (faux_ops && faux_ops->probe) {
|
||||||
ret = faux_ops->probe(faux_dev);
|
ret = faux_ops->probe(faux_dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add groups after the probe succeeds to ensure resources are
|
||||||
|
* initialized correctly
|
||||||
|
*/
|
||||||
|
ret = device_add_groups(dev, faux_obj->groups);
|
||||||
|
if (ret && faux_ops && faux_ops->remove)
|
||||||
|
faux_ops->remove(faux_dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -57,6 +69,8 @@ static void faux_remove(struct device *dev)
|
||||||
struct faux_device *faux_dev = &faux_obj->faux_dev;
|
struct faux_device *faux_dev = &faux_obj->faux_dev;
|
||||||
const struct faux_device_ops *faux_ops = faux_obj->faux_ops;
|
const struct faux_device_ops *faux_ops = faux_obj->faux_ops;
|
||||||
|
|
||||||
|
device_remove_groups(dev, faux_obj->groups);
|
||||||
|
|
||||||
if (faux_ops && faux_ops->remove)
|
if (faux_ops && faux_ops->remove)
|
||||||
faux_ops->remove(faux_dev);
|
faux_ops->remove(faux_dev);
|
||||||
}
|
}
|
||||||
|
|
@ -124,8 +138,9 @@ struct faux_device *faux_device_create_with_groups(const char *name,
|
||||||
if (!faux_obj)
|
if (!faux_obj)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Save off the callbacks so we can use them in the future */
|
/* Save off the callbacks and groups so we can use them in the future */
|
||||||
faux_obj->faux_ops = faux_ops;
|
faux_obj->faux_ops = faux_ops;
|
||||||
|
faux_obj->groups = groups;
|
||||||
|
|
||||||
/* Initialize the device portion and register it with the driver core */
|
/* Initialize the device portion and register it with the driver core */
|
||||||
faux_dev = &faux_obj->faux_dev;
|
faux_dev = &faux_obj->faux_dev;
|
||||||
|
|
@ -138,7 +153,6 @@ struct faux_device *faux_device_create_with_groups(const char *name,
|
||||||
else
|
else
|
||||||
dev->parent = &faux_bus_root;
|
dev->parent = &faux_bus_root;
|
||||||
dev->bus = &faux_bus_type;
|
dev->bus = &faux_bus_type;
|
||||||
dev->groups = groups;
|
|
||||||
dev_set_name(dev, "%s", name);
|
dev_set_name(dev, "%s", name);
|
||||||
|
|
||||||
ret = device_add(dev);
|
ret = device_add(dev);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ menu "Firmware loader"
|
||||||
|
|
||||||
config FW_LOADER
|
config FW_LOADER
|
||||||
tristate "Firmware loading facility" if EXPERT
|
tristate "Firmware loading facility" if EXPERT
|
||||||
select CRYPTO_HASH if FW_LOADER_DEBUG
|
select CRYPTO_LIB_SHA256 if FW_LOADER_DEBUG
|
||||||
select CRYPTO_SHA256 if FW_LOADER_DEBUG
|
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
This enables the firmware loading facility in the kernel. The kernel
|
This enables the firmware loading facility in the kernel. The kernel
|
||||||
|
|
@ -28,7 +27,6 @@ config FW_LOADER
|
||||||
|
|
||||||
config FW_LOADER_DEBUG
|
config FW_LOADER_DEBUG
|
||||||
bool "Log filenames and checksums for loaded firmware"
|
bool "Log filenames and checksums for loaded firmware"
|
||||||
depends on CRYPTO = FW_LOADER || CRYPTO=y
|
|
||||||
depends on DYNAMIC_DEBUG
|
depends on DYNAMIC_DEBUG
|
||||||
depends on FW_LOADER
|
depends on FW_LOADER
|
||||||
default FW_LOADER
|
default FW_LOADER
|
||||||
|
|
|
||||||
|
|
@ -806,41 +806,15 @@ static void fw_abort_batch_reqs(struct firmware *fw)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_FW_LOADER_DEBUG)
|
#if defined(CONFIG_FW_LOADER_DEBUG)
|
||||||
#include <crypto/hash.h>
|
|
||||||
#include <crypto/sha2.h>
|
#include <crypto/sha2.h>
|
||||||
|
|
||||||
static void fw_log_firmware_info(const struct firmware *fw, const char *name, struct device *device)
|
static void fw_log_firmware_info(const struct firmware *fw, const char *name, struct device *device)
|
||||||
{
|
{
|
||||||
struct shash_desc *shash;
|
u8 digest[SHA256_DIGEST_SIZE];
|
||||||
struct crypto_shash *alg;
|
|
||||||
u8 *sha256buf;
|
|
||||||
char *outbuf;
|
|
||||||
|
|
||||||
alg = crypto_alloc_shash("sha256", 0, 0);
|
sha256(fw->data, fw->size, digest);
|
||||||
if (IS_ERR(alg))
|
dev_dbg(device, "Loaded FW: %s, sha256: %*phN\n",
|
||||||
return;
|
name, SHA256_DIGEST_SIZE, digest);
|
||||||
|
|
||||||
sha256buf = kmalloc(SHA256_DIGEST_SIZE, GFP_KERNEL);
|
|
||||||
outbuf = kmalloc(SHA256_BLOCK_SIZE + 1, GFP_KERNEL);
|
|
||||||
shash = kmalloc(sizeof(*shash) + crypto_shash_descsize(alg), GFP_KERNEL);
|
|
||||||
if (!sha256buf || !outbuf || !shash)
|
|
||||||
goto out_free;
|
|
||||||
|
|
||||||
shash->tfm = alg;
|
|
||||||
|
|
||||||
if (crypto_shash_digest(shash, fw->data, fw->size, sha256buf) < 0)
|
|
||||||
goto out_free;
|
|
||||||
|
|
||||||
for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
|
|
||||||
sprintf(&outbuf[i * 2], "%02x", sha256buf[i]);
|
|
||||||
outbuf[SHA256_BLOCK_SIZE] = 0;
|
|
||||||
dev_dbg(device, "Loaded FW: %s, sha256: %s\n", name, outbuf);
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
kfree(shash);
|
|
||||||
kfree(outbuf);
|
|
||||||
kfree(sha256buf);
|
|
||||||
crypto_free_shash(alg);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void fw_log_firmware_info(const struct firmware *fw, const char *name,
|
static void fw_log_firmware_info(const struct firmware *fw, const char *name,
|
||||||
|
|
|
||||||
|
|
@ -982,7 +982,7 @@ struct platform_device * __init_or_module __platform_create_bundle(
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
pdev = platform_device_alloc(driver->driver.name, -1);
|
pdev = platform_device_alloc(driver->driver.name, PLATFORM_DEVID_NONE);
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ static DEFINE_IDA(wakeup_ida);
|
||||||
* wakeup_source_create - Create a struct wakeup_source object.
|
* wakeup_source_create - Create a struct wakeup_source object.
|
||||||
* @name: Name of the new wakeup source.
|
* @name: Name of the new wakeup source.
|
||||||
*/
|
*/
|
||||||
struct wakeup_source *wakeup_source_create(const char *name)
|
static struct wakeup_source *wakeup_source_create(const char *name)
|
||||||
{
|
{
|
||||||
struct wakeup_source *ws;
|
struct wakeup_source *ws;
|
||||||
const char *ws_name;
|
const char *ws_name;
|
||||||
|
|
@ -106,7 +106,6 @@ struct wakeup_source *wakeup_source_create(const char *name)
|
||||||
err_ws:
|
err_ws:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wakeup_source_create);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Record wakeup_source statistics being deleted into a dummy wakeup_source.
|
* Record wakeup_source statistics being deleted into a dummy wakeup_source.
|
||||||
|
|
@ -149,7 +148,7 @@ static void wakeup_source_free(struct wakeup_source *ws)
|
||||||
*
|
*
|
||||||
* Use only for wakeup source objects created with wakeup_source_create().
|
* Use only for wakeup source objects created with wakeup_source_create().
|
||||||
*/
|
*/
|
||||||
void wakeup_source_destroy(struct wakeup_source *ws)
|
static void wakeup_source_destroy(struct wakeup_source *ws)
|
||||||
{
|
{
|
||||||
if (!ws)
|
if (!ws)
|
||||||
return;
|
return;
|
||||||
|
|
@ -158,13 +157,12 @@ void wakeup_source_destroy(struct wakeup_source *ws)
|
||||||
wakeup_source_record(ws);
|
wakeup_source_record(ws);
|
||||||
wakeup_source_free(ws);
|
wakeup_source_free(ws);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wakeup_source_destroy);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wakeup_source_add - Add given object to the list of wakeup sources.
|
* wakeup_source_add - Add given object to the list of wakeup sources.
|
||||||
* @ws: Wakeup source object to add to the list.
|
* @ws: Wakeup source object to add to the list.
|
||||||
*/
|
*/
|
||||||
void wakeup_source_add(struct wakeup_source *ws)
|
static void wakeup_source_add(struct wakeup_source *ws)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
|
@ -179,13 +177,12 @@ void wakeup_source_add(struct wakeup_source *ws)
|
||||||
list_add_rcu(&ws->entry, &wakeup_sources);
|
list_add_rcu(&ws->entry, &wakeup_sources);
|
||||||
raw_spin_unlock_irqrestore(&events_lock, flags);
|
raw_spin_unlock_irqrestore(&events_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wakeup_source_add);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wakeup_source_remove - Remove given object from the wakeup sources list.
|
* wakeup_source_remove - Remove given object from the wakeup sources list.
|
||||||
* @ws: Wakeup source object to remove from the list.
|
* @ws: Wakeup source object to remove from the list.
|
||||||
*/
|
*/
|
||||||
void wakeup_source_remove(struct wakeup_source *ws)
|
static void wakeup_source_remove(struct wakeup_source *ws)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
|
@ -204,7 +201,6 @@ void wakeup_source_remove(struct wakeup_source *ws)
|
||||||
*/
|
*/
|
||||||
ws->timer.function = NULL;
|
ws->timer.function = NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wakeup_source_remove);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wakeup_source_register - Create wakeup source and add it to the list.
|
* wakeup_source_register - Create wakeup source and add it to the list.
|
||||||
|
|
|
||||||
|
|
@ -529,7 +529,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
|
||||||
if (prop->is_inline)
|
if (prop->is_inline)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (index * sizeof(*ref) >= prop->length)
|
if ((index + 1) * sizeof(*ref) > prop->length)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
ref_array = prop->pointer;
|
ref_array = prop->pointer;
|
||||||
|
|
|
||||||
|
|
@ -1841,7 +1841,7 @@ static struct attribute *vmbus_chan_attrs[] = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bin_attribute *vmbus_chan_bin_attrs[] = {
|
static const struct bin_attribute *vmbus_chan_bin_attrs[] = {
|
||||||
&chan_attr_ring_buffer,
|
&chan_attr_ring_buffer,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include "kernfs-internal.h"
|
#include "kernfs-internal.h"
|
||||||
|
|
||||||
DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */
|
|
||||||
/*
|
/*
|
||||||
* Don't use rename_lock to piggy back on pr_cont_buf. We don't want to
|
* Don't use rename_lock to piggy back on pr_cont_buf. We don't want to
|
||||||
* call pr_cont() while holding rename_lock. Because sometimes pr_cont()
|
* call pr_cont() while holding rename_lock. Because sometimes pr_cont()
|
||||||
|
|
@ -27,7 +26,6 @@ DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */
|
||||||
*/
|
*/
|
||||||
static DEFINE_SPINLOCK(kernfs_pr_cont_lock);
|
static DEFINE_SPINLOCK(kernfs_pr_cont_lock);
|
||||||
static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */
|
static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */
|
||||||
static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */
|
|
||||||
|
|
||||||
#define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
|
#define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
|
||||||
|
|
||||||
|
|
@ -229,7 +227,7 @@ int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
|
||||||
if (to) {
|
if (to) {
|
||||||
root = kernfs_root(to);
|
root = kernfs_root(to);
|
||||||
if (!(root->flags & KERNFS_ROOT_INVARIANT_PARENT)) {
|
if (!(root->flags & KERNFS_ROOT_INVARIANT_PARENT)) {
|
||||||
guard(read_lock_irqsave)(&kernfs_rename_lock);
|
guard(read_lock_irqsave)(&root->kernfs_rename_lock);
|
||||||
return kernfs_path_from_node_locked(to, from, buf, buflen);
|
return kernfs_path_from_node_locked(to, from, buf, buflen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -296,12 +294,14 @@ void pr_cont_kernfs_path(struct kernfs_node *kn)
|
||||||
struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn)
|
struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn)
|
||||||
{
|
{
|
||||||
struct kernfs_node *parent;
|
struct kernfs_node *parent;
|
||||||
|
struct kernfs_root *root;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
read_lock_irqsave(&kernfs_rename_lock, flags);
|
root = kernfs_root(kn);
|
||||||
|
read_lock_irqsave(&root->kernfs_rename_lock, flags);
|
||||||
parent = kernfs_parent(kn);
|
parent = kernfs_parent(kn);
|
||||||
kernfs_get(parent);
|
kernfs_get(parent);
|
||||||
read_unlock_irqrestore(&kernfs_rename_lock, flags);
|
read_unlock_irqrestore(&root->kernfs_rename_lock, flags);
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
@ -584,9 +584,9 @@ void kernfs_put(struct kernfs_node *kn)
|
||||||
if (kernfs_type(kn) == KERNFS_LINK)
|
if (kernfs_type(kn) == KERNFS_LINK)
|
||||||
kernfs_put(kn->symlink.target_kn);
|
kernfs_put(kn->symlink.target_kn);
|
||||||
|
|
||||||
spin_lock(&kernfs_idr_lock);
|
spin_lock(&root->kernfs_idr_lock);
|
||||||
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
|
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
|
||||||
spin_unlock(&kernfs_idr_lock);
|
spin_unlock(&root->kernfs_idr_lock);
|
||||||
|
|
||||||
call_rcu(&kn->rcu, kernfs_free_rcu);
|
call_rcu(&kn->rcu, kernfs_free_rcu);
|
||||||
|
|
||||||
|
|
@ -639,13 +639,13 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
||||||
goto err_out1;
|
goto err_out1;
|
||||||
|
|
||||||
idr_preload(GFP_KERNEL);
|
idr_preload(GFP_KERNEL);
|
||||||
spin_lock(&kernfs_idr_lock);
|
spin_lock(&root->kernfs_idr_lock);
|
||||||
ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC);
|
ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC);
|
||||||
if (ret >= 0 && ret < root->last_id_lowbits)
|
if (ret >= 0 && ret < root->last_id_lowbits)
|
||||||
root->id_highbits++;
|
root->id_highbits++;
|
||||||
id_highbits = root->id_highbits;
|
id_highbits = root->id_highbits;
|
||||||
root->last_id_lowbits = ret;
|
root->last_id_lowbits = ret;
|
||||||
spin_unlock(&kernfs_idr_lock);
|
spin_unlock(&root->kernfs_idr_lock);
|
||||||
idr_preload_end();
|
idr_preload_end();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_out2;
|
goto err_out2;
|
||||||
|
|
@ -681,9 +681,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
||||||
return kn;
|
return kn;
|
||||||
|
|
||||||
err_out3:
|
err_out3:
|
||||||
spin_lock(&kernfs_idr_lock);
|
spin_lock(&root->kernfs_idr_lock);
|
||||||
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
|
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
|
||||||
spin_unlock(&kernfs_idr_lock);
|
spin_unlock(&root->kernfs_idr_lock);
|
||||||
err_out2:
|
err_out2:
|
||||||
kmem_cache_free(kernfs_node_cache, kn);
|
kmem_cache_free(kernfs_node_cache, kn);
|
||||||
err_out1:
|
err_out1:
|
||||||
|
|
@ -989,10 +989,12 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
idr_init(&root->ino_idr);
|
idr_init(&root->ino_idr);
|
||||||
|
spin_lock_init(&root->kernfs_idr_lock);
|
||||||
init_rwsem(&root->kernfs_rwsem);
|
init_rwsem(&root->kernfs_rwsem);
|
||||||
init_rwsem(&root->kernfs_iattr_rwsem);
|
init_rwsem(&root->kernfs_iattr_rwsem);
|
||||||
init_rwsem(&root->kernfs_supers_rwsem);
|
init_rwsem(&root->kernfs_supers_rwsem);
|
||||||
INIT_LIST_HEAD(&root->supers);
|
INIT_LIST_HEAD(&root->supers);
|
||||||
|
rwlock_init(&root->kernfs_rename_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On 64bit ino setups, id is ino. On 32bit, low 32bits are ino.
|
* On 64bit ino setups, id is ino. On 32bit, low 32bits are ino.
|
||||||
|
|
@ -1580,8 +1582,9 @@ void kernfs_break_active_protection(struct kernfs_node *kn)
|
||||||
* invoked before finishing the kernfs operation. Note that while this
|
* invoked before finishing the kernfs operation. Note that while this
|
||||||
* function restores the active reference, it doesn't and can't actually
|
* function restores the active reference, it doesn't and can't actually
|
||||||
* restore the active protection - @kn may already or be in the process of
|
* restore the active protection - @kn may already or be in the process of
|
||||||
* being removed. Once kernfs_break_active_protection() is invoked, that
|
* being drained and removed. Once kernfs_break_active_protection() is
|
||||||
* protection is irreversibly gone for the kernfs operation instance.
|
* invoked, that protection is irreversibly gone for the kernfs operation
|
||||||
|
* instance.
|
||||||
*
|
*
|
||||||
* While this function may be called at any point after
|
* While this function may be called at any point after
|
||||||
* kernfs_break_active_protection() is invoked, its most useful location
|
* kernfs_break_active_protection() is invoked, its most useful location
|
||||||
|
|
@ -1789,7 +1792,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
||||||
/* rename_lock protects ->parent accessors */
|
/* rename_lock protects ->parent accessors */
|
||||||
if (old_parent != new_parent) {
|
if (old_parent != new_parent) {
|
||||||
kernfs_get(new_parent);
|
kernfs_get(new_parent);
|
||||||
write_lock_irq(&kernfs_rename_lock);
|
write_lock_irq(&root->kernfs_rename_lock);
|
||||||
|
|
||||||
rcu_assign_pointer(kn->__parent, new_parent);
|
rcu_assign_pointer(kn->__parent, new_parent);
|
||||||
|
|
||||||
|
|
@ -1797,7 +1800,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
||||||
if (new_name)
|
if (new_name)
|
||||||
rcu_assign_pointer(kn->name, new_name);
|
rcu_assign_pointer(kn->name, new_name);
|
||||||
|
|
||||||
write_unlock_irq(&kernfs_rename_lock);
|
write_unlock_irq(&root->kernfs_rename_lock);
|
||||||
kernfs_put(old_parent);
|
kernfs_put(old_parent);
|
||||||
} else {
|
} else {
|
||||||
/* name assignment is RCU protected, parent is the same */
|
/* name assignment is RCU protected, parent is the same */
|
||||||
|
|
|
||||||
|
|
@ -778,8 +778,9 @@ bool kernfs_should_drain_open_files(struct kernfs_node *kn)
|
||||||
/*
|
/*
|
||||||
* @kn being deactivated guarantees that @kn->attr.open can't change
|
* @kn being deactivated guarantees that @kn->attr.open can't change
|
||||||
* beneath us making the lockless test below safe.
|
* beneath us making the lockless test below safe.
|
||||||
|
* Callers post kernfs_unbreak_active_protection may be counted in
|
||||||
|
* kn->active by now, do not WARN_ON because of them.
|
||||||
*/
|
*/
|
||||||
WARN_ON_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS);
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
on = rcu_dereference(kn->attr.open);
|
on = rcu_dereference(kn->attr.open);
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@
|
||||||
#include <linux/kernfs.h>
|
#include <linux/kernfs.h>
|
||||||
#include <linux/fs_context.h>
|
#include <linux/fs_context.h>
|
||||||
|
|
||||||
extern rwlock_t kernfs_rename_lock;
|
|
||||||
|
|
||||||
struct kernfs_iattrs {
|
struct kernfs_iattrs {
|
||||||
kuid_t ia_uid;
|
kuid_t ia_uid;
|
||||||
kgid_t ia_gid;
|
kgid_t ia_gid;
|
||||||
|
|
@ -40,6 +38,7 @@ struct kernfs_root {
|
||||||
|
|
||||||
/* private fields, do not use outside kernfs proper */
|
/* private fields, do not use outside kernfs proper */
|
||||||
struct idr ino_idr;
|
struct idr ino_idr;
|
||||||
|
spinlock_t kernfs_idr_lock; /* root->ino_idr */
|
||||||
u32 last_id_lowbits;
|
u32 last_id_lowbits;
|
||||||
u32 id_highbits;
|
u32 id_highbits;
|
||||||
struct kernfs_syscall_ops *syscall_ops;
|
struct kernfs_syscall_ops *syscall_ops;
|
||||||
|
|
@ -52,6 +51,9 @@ struct kernfs_root {
|
||||||
struct rw_semaphore kernfs_iattr_rwsem;
|
struct rw_semaphore kernfs_iattr_rwsem;
|
||||||
struct rw_semaphore kernfs_supers_rwsem;
|
struct rw_semaphore kernfs_supers_rwsem;
|
||||||
|
|
||||||
|
/* kn->parent and kn->name */
|
||||||
|
rwlock_t kernfs_rename_lock;
|
||||||
|
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -107,6 +109,11 @@ static inline bool kernfs_root_is_locked(const struct kernfs_node *kn)
|
||||||
return lockdep_is_held(&kernfs_root(kn)->kernfs_rwsem);
|
return lockdep_is_held(&kernfs_root(kn)->kernfs_rwsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool kernfs_rename_is_locked(const struct kernfs_node *kn)
|
||||||
|
{
|
||||||
|
return lockdep_is_held(&kernfs_root(kn)->kernfs_rename_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static inline const char *kernfs_rcu_name(const struct kernfs_node *kn)
|
static inline const char *kernfs_rcu_name(const struct kernfs_node *kn)
|
||||||
{
|
{
|
||||||
return rcu_dereference_check(kn->name, kernfs_root_is_locked(kn));
|
return rcu_dereference_check(kn->name, kernfs_root_is_locked(kn));
|
||||||
|
|
@ -117,14 +124,15 @@ static inline struct kernfs_node *kernfs_parent(const struct kernfs_node *kn)
|
||||||
/*
|
/*
|
||||||
* The kernfs_node::__parent remains valid within a RCU section. The kn
|
* The kernfs_node::__parent remains valid within a RCU section. The kn
|
||||||
* can be reparented (and renamed) which changes the entry. This can be
|
* can be reparented (and renamed) which changes the entry. This can be
|
||||||
* avoided by locking kernfs_root::kernfs_rwsem or kernfs_rename_lock.
|
* avoided by locking kernfs_root::kernfs_rwsem or
|
||||||
|
* kernfs_root::kernfs_rename_lock.
|
||||||
* Both locks can be used to obtain a reference on __parent. Once the
|
* Both locks can be used to obtain a reference on __parent. Once the
|
||||||
* reference count reaches 0 then the node is about to be freed
|
* reference count reaches 0 then the node is about to be freed
|
||||||
* and can not be renamed (or become a different parent) anymore.
|
* and can not be renamed (or become a different parent) anymore.
|
||||||
*/
|
*/
|
||||||
return rcu_dereference_check(kn->__parent,
|
return rcu_dereference_check(kn->__parent,
|
||||||
kernfs_root_is_locked(kn) ||
|
kernfs_root_is_locked(kn) ||
|
||||||
lockdep_is_held(&kernfs_rename_lock) ||
|
kernfs_rename_is_locked(kn) ||
|
||||||
!atomic_read(&kn->count));
|
!atomic_read(&kn->count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ static void remove_files(struct kernfs_node *parent,
|
||||||
const struct attribute_group *grp)
|
const struct attribute_group *grp)
|
||||||
{
|
{
|
||||||
struct attribute *const *attr;
|
struct attribute *const *attr;
|
||||||
struct bin_attribute *const *bin_attr;
|
const struct bin_attribute *const *bin_attr;
|
||||||
|
|
||||||
if (grp->attrs)
|
if (grp->attrs)
|
||||||
for (attr = grp->attrs; *attr; attr++)
|
for (attr = grp->attrs; *attr; attr++)
|
||||||
|
|
@ -47,7 +47,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
|
||||||
const struct attribute_group *grp, int update)
|
const struct attribute_group *grp, int update)
|
||||||
{
|
{
|
||||||
struct attribute *const *attr;
|
struct attribute *const *attr;
|
||||||
struct bin_attribute *const *bin_attr;
|
const struct bin_attribute *const *bin_attr;
|
||||||
int error = 0, i;
|
int error = 0, i;
|
||||||
|
|
||||||
if (grp->attrs) {
|
if (grp->attrs) {
|
||||||
|
|
@ -521,7 +521,7 @@ static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grp->bin_attrs) {
|
if (grp->bin_attrs) {
|
||||||
struct bin_attribute *const *bin_attr;
|
const struct bin_attribute *const *bin_attr;
|
||||||
|
|
||||||
for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
|
for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
|
||||||
kn = kernfs_find_and_get(grp_kn, (*bin_attr)->attr.name);
|
kn = kernfs_find_and_get(grp_kn, (*bin_attr)->attr.name);
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,23 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *
|
||||||
|
|
||||||
void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
|
void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
|
||||||
|
|
||||||
|
struct auxiliary_device *auxiliary_device_create(struct device *dev,
|
||||||
|
const char *modname,
|
||||||
|
const char *devname,
|
||||||
|
void *platform_data,
|
||||||
|
int id);
|
||||||
|
void auxiliary_device_destroy(void *auxdev);
|
||||||
|
|
||||||
|
struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
|
||||||
|
const char *modname,
|
||||||
|
const char *devname,
|
||||||
|
void *platform_data,
|
||||||
|
int id);
|
||||||
|
|
||||||
|
#define devm_auxiliary_device_create(dev, devname, platform_data) \
|
||||||
|
__devm_auxiliary_device_create(dev, KBUILD_MODNAME, devname, \
|
||||||
|
platform_data, 0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* module_auxiliary_driver() - Helper macro for registering an auxiliary driver
|
* module_auxiliary_driver() - Helper macro for registering an auxiliary driver
|
||||||
* @__auxiliary_driver: auxiliary driver struct
|
* @__auxiliary_driver: auxiliary driver struct
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,6 @@ static inline void device_set_wakeup_path(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* drivers/base/power/wakeup.c */
|
/* drivers/base/power/wakeup.c */
|
||||||
extern struct wakeup_source *wakeup_source_create(const char *name);
|
|
||||||
extern void wakeup_source_destroy(struct wakeup_source *ws);
|
|
||||||
extern void wakeup_source_add(struct wakeup_source *ws);
|
|
||||||
extern void wakeup_source_remove(struct wakeup_source *ws);
|
|
||||||
extern struct wakeup_source *wakeup_source_register(struct device *dev,
|
extern struct wakeup_source *wakeup_source_register(struct device *dev,
|
||||||
const char *name);
|
const char *name);
|
||||||
extern void wakeup_source_unregister(struct wakeup_source *ws);
|
extern void wakeup_source_unregister(struct wakeup_source *ws);
|
||||||
|
|
@ -129,17 +125,6 @@ static inline bool device_can_wakeup(struct device *dev)
|
||||||
return dev->power.can_wakeup;
|
return dev->power.can_wakeup;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct wakeup_source *wakeup_source_create(const char *name)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void wakeup_source_destroy(struct wakeup_source *ws) {}
|
|
||||||
|
|
||||||
static inline void wakeup_source_add(struct wakeup_source *ws) {}
|
|
||||||
|
|
||||||
static inline void wakeup_source_remove(struct wakeup_source *ws) {}
|
|
||||||
|
|
||||||
static inline struct wakeup_source *wakeup_source_register(struct device *dev,
|
static inline struct wakeup_source *wakeup_source_register(struct device *dev,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ struct attribute_group {
|
||||||
int);
|
int);
|
||||||
struct attribute **attrs;
|
struct attribute **attrs;
|
||||||
union {
|
union {
|
||||||
struct bin_attribute **bin_attrs;
|
const struct bin_attribute *const *bin_attrs;
|
||||||
const struct bin_attribute *const *bin_attrs_new;
|
const struct bin_attribute *const *bin_attrs_new;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -306,11 +306,11 @@ struct bin_attribute {
|
||||||
size_t size;
|
size_t size;
|
||||||
void *private;
|
void *private;
|
||||||
struct address_space *(*f_mapping)(void);
|
struct address_space *(*f_mapping)(void);
|
||||||
ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
|
ssize_t (*read)(struct file *, struct kobject *, const struct bin_attribute *,
|
||||||
char *, loff_t, size_t);
|
char *, loff_t, size_t);
|
||||||
ssize_t (*read_new)(struct file *, struct kobject *, const struct bin_attribute *,
|
ssize_t (*read_new)(struct file *, struct kobject *, const struct bin_attribute *,
|
||||||
char *, loff_t, size_t);
|
char *, loff_t, size_t);
|
||||||
ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
|
ssize_t (*write)(struct file *, struct kobject *, const struct bin_attribute *,
|
||||||
char *, loff_t, size_t);
|
char *, loff_t, size_t);
|
||||||
ssize_t (*write_new)(struct file *, struct kobject *,
|
ssize_t (*write_new)(struct file *, struct kobject *,
|
||||||
const struct bin_attribute *, char *, loff_t, size_t);
|
const struct bin_attribute *, char *, loff_t, size_t);
|
||||||
|
|
@ -332,28 +332,11 @@ struct bin_attribute {
|
||||||
*/
|
*/
|
||||||
#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
|
#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
|
||||||
|
|
||||||
typedef ssize_t __sysfs_bin_rw_handler_new(struct file *, struct kobject *,
|
|
||||||
const struct bin_attribute *, char *, loff_t, size_t);
|
|
||||||
|
|
||||||
/* macros to create static binary attributes easier */
|
/* macros to create static binary attributes easier */
|
||||||
#define __BIN_ATTR(_name, _mode, _read, _write, _size) { \
|
#define __BIN_ATTR(_name, _mode, _read, _write, _size) { \
|
||||||
.attr = { .name = __stringify(_name), .mode = _mode }, \
|
.attr = { .name = __stringify(_name), .mode = _mode }, \
|
||||||
.read = _Generic(_read, \
|
.read = _read, \
|
||||||
__sysfs_bin_rw_handler_new * : NULL, \
|
.write = _write, \
|
||||||
default : _read \
|
|
||||||
), \
|
|
||||||
.read_new = _Generic(_read, \
|
|
||||||
__sysfs_bin_rw_handler_new * : _read, \
|
|
||||||
default : NULL \
|
|
||||||
), \
|
|
||||||
.write = _Generic(_write, \
|
|
||||||
__sysfs_bin_rw_handler_new * : NULL, \
|
|
||||||
default : _write \
|
|
||||||
), \
|
|
||||||
.write_new = _Generic(_write, \
|
|
||||||
__sysfs_bin_rw_handler_new * : _write, \
|
|
||||||
default : NULL \
|
|
||||||
), \
|
|
||||||
.size = _size, \
|
.size = _size, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue