regmap: debugfs: Allow writes to cache state settings
Subsystems (2)
v2 cover regmap: debugfs: Allow writes to cache state settings
PATCH 1: Export the bool read/write functions from debugfs so that they can
be re-used. This is based on
/gregkh/driver-core.git : driver-core-next
PATCH 2: Allow the regmap debugfs cache state entries to be writable
This is based on:
/broonie/regmap.git : for-next
Richard Fitzgerald (2):
debugfs: Export bool read/write functions
regmap: debugfs: Allow writes to cache state settings
drivers/base/regmap/regmap-debugfs.c | 90 ++++++++++++++++++++++++++++++++-- fs/debugfs/file.c | 14 +++-- include/linux/debugfs.h | 20 ++++++++ 3 files changed, 114 insertions(+), 10 deletions(-)
Signature · 1 line
1.7.2.5
PATCH v2 1/2 debugfs: Export bool read/write functions
The file read/write functions for bools have no special dependencies on debugfs internals and are sufficiently non-trivial to be worth exporting so clients can re-use the implementation.
--- fs/debugfs/file.c | 14 ++++++++------ include/linux/debugfs.h | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-)
fs/debugfs/file.c +8 -6
@@ -447,8 +447,8 @@ struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, }EXPORT_SYMBOL_GPL (debugfs_create_atomic_t); -static ssize_t read_file_bool (struct file *file,char __user *user_buf, -size_t count,loff_t *ppos) +ssize_t debugfs_read_file_bool (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) {char buf[3 ];u32 *val = file->private_data;
@@ -461,9 +461,10 @@ static ssize_t read_file_bool(struct file *file, char __user *user_buf, buf[2 ] =0x00 ;return simple_read_from_buffer (user_buf, count, ppos, buf,2 ); } +EXPORT_SYMBOL_GPL (debugfs_read_file_bool); -static ssize_t write_file_bool (struct file *file,const char __user *user_buf, -size_t count,loff_t *ppos) +ssize_t debugfs_write_file_bool (struct file *file,const char __user *user_buf, +size_t count,loff_t *ppos) {char buf[32 ];size_t buf_size;
@@ -480,10 +481,11 @@ static ssize_t write_file_bool(struct file *file, const char __user *user_buf,return count; } +EXPORT_SYMBOL_GPL (debugfs_write_file_bool);static const struct file_operations fops_bool = { - .read = read_file_bool, - .write = write_file_bool, + .read = debugfs_read_file_bool, + .write = debugfs_write_file_bool, .open = simple_open, .llseek = default_llseek, };
include/linux/debugfs.h +20 -0
@@ -117,6 +117,12 @@ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,bool debugfs_initialized (void ); +ssize_t debugfs_read_file_bool (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos); + +ssize_t debugfs_write_file_bool (struct file *file,const char __user *user_buf, +size_t count,loff_t *ppos); +#else #include <linux/err.h>
@@ -283,6 +289,20 @@ static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev,return ERR_PTR (-ENODEV ); } +static inline ssize_t debugfs_read_file_bool (struct file *file, +char __user *user_buf, +size_t count,loff_t *ppos) +{ +return -ENODEV ; +} + +static inline ssize_t debugfs_write_file_bool (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +return -ENODEV ; +} +#endif #endif
Signature · 1 line
1.7.2.5
Mark Brown
maintainerRe: [PATCH v2 1/2] debugfs: Export bool read/write functions
Quoted 3 lines · Richard Fitzgerald
The file read/write functions for bools have no special dependencies on debugfs internals and are sufficiently non-trivial to be worth exporting so clients can re-use the implementation.
Greg, I'm assuming you're OK with this? Please shout if not.
Quoted 90 lines
Signed-off-by Richard Fitzgerald <[email protected]>--- fs/debugfs/file.c | 14 ++++++++------ include/linux/debugfs.h | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-)fs/debugfs/file.c +8
-6@@ -447,8 +447,8 @@ struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, }EXPORT_SYMBOL_GPL (debugfs_create_atomic_t); -static ssize_t read_file_bool (struct file *file,char __user *user_buf, -size_t count,loff_t *ppos) +ssize_t debugfs_read_file_bool (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) {char buf[3 ];u32 *val = file->private_data;@@ -461,9 +461,10 @@ static ssize_t read_file_bool(struct file *file, char __user *user_buf, buf[2 ] =0x00 ;return simple_read_from_buffer (user_buf, count, ppos, buf,2 ); } +EXPORT_SYMBOL_GPL (debugfs_read_file_bool); -static ssize_t write_file_bool (struct file *file,const char __user *user_buf, -size_t count,loff_t *ppos) +ssize_t debugfs_write_file_bool (struct file *file,const char __user *user_buf, +size_t count,loff_t *ppos) {char buf[32 ];size_t buf_size;@@ -480,10 +481,11 @@ static ssize_t write_file_bool(struct file *file, const char __user *user_buf,return count; } +EXPORT_SYMBOL_GPL (debugfs_write_file_bool);static const struct file_operations fops_bool = { - .read = read_file_bool, - .write = write_file_bool, + .read = debugfs_read_file_bool, + .write = debugfs_write_file_bool, .open = simple_open, .llseek = default_llseek, };include/linux/debugfs.h +20
-0@@ -117,6 +117,12 @@ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,bool debugfs_initialized (void ); +ssize_t debugfs_read_file_bool (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos); + +ssize_t debugfs_write_file_bool (struct file *file,const char __user *user_buf, +size_t count,loff_t *ppos); +#else #include <linux/err.h> @@ -283,6 +289,20 @@ static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev,return ERR_PTR (-ENODEV ); } +static inline ssize_t debugfs_read_file_bool (struct file *file, +char __user *user_buf, +size_t count,loff_t *ppos) +{ +return -ENODEV ; +} + +static inline ssize_t debugfs_write_file_bool (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +return -ENODEV ; +} +#endif #endif Signature · 1 line
1.7.2.5
Re: [PATCH v2 1/2] debugfs: Export bool read/write functions
Quoted 6 lines · Mark Brown
Quoted 3 lines · Richard Fitzgerald
The file read/write functions for bools have no special dependencies on debugfs internals and are sufficiently non-trivial to be worth exporting so clients can re-use the implementation.
Greg, I'm assuming you're OK with this? Please shout if not.
Mark Brown
maintainerApplied "debugfs: Export bool read/write functions" to the regmap tree
In reply to Richard FitzgeraldThe patch
debugfs: Export bool read/write functions
has been applied to the regmap tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
0642ef6f2992eba46c41abb5ceb7d4fa14ba888eMon Sep 17 00:00:00 2001
From: Richard Fitzgerald <[email protected]>
Date: Tue, 23 Jun 2015 14:32:54 +0100
Subject: [PATCH] debugfs: Export bool read/write functions
The file read/write functions for bools have no special dependencies on debugfs internals and are sufficiently non-trivial to be worth exporting so clients can re-use the implementation.
--- fs/debugfs/file.c | 14 ++++++++------ include/linux/debugfs.h | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-)
fs/debugfs/file.c +8 -6
@@ -435,8 +435,8 @@ struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, }EXPORT_SYMBOL_GPL (debugfs_create_atomic_t); -static ssize_t read_file_bool (struct file *file,char __user *user_buf, -size_t count,loff_t *ppos) +ssize_t debugfs_read_file_bool (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) {char buf[3 ];u32 *val = file->private_data;
@@ -449,9 +449,10 @@ static ssize_t read_file_bool(struct file *file, char __user *user_buf, buf[2 ] =0x00 ;return simple_read_from_buffer (user_buf, count, ppos, buf,2 ); } +EXPORT_SYMBOL_GPL (debugfs_read_file_bool); -static ssize_t write_file_bool (struct file *file,const char __user *user_buf, -size_t count,loff_t *ppos) +ssize_t debugfs_write_file_bool (struct file *file,const char __user *user_buf, +size_t count,loff_t *ppos) {char buf[32 ];size_t buf_size;
@@ -468,10 +469,11 @@ static ssize_t write_file_bool(struct file *file, const char __user *user_buf,return count; } +EXPORT_SYMBOL_GPL (debugfs_write_file_bool);static const struct file_operations fops_bool = { - .read = read_file_bool, - .write = write_file_bool, + .read = debugfs_read_file_bool, + .write = debugfs_write_file_bool, .open = simple_open, .llseek = default_llseek, };
include/linux/debugfs.h +20 -0
@@ -116,6 +116,12 @@ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,bool debugfs_initialized (void ); +ssize_t debugfs_read_file_bool (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos); + +ssize_t debugfs_write_file_bool (struct file *file,const char __user *user_buf, +size_t count,loff_t *ppos); +#else #include <linux/err.h>
@@ -282,6 +288,20 @@ static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev,return ERR_PTR (-ENODEV ); } +static inline ssize_t debugfs_read_file_bool (struct file *file, +char __user *user_buf, +size_t count,loff_t *ppos) +{ +return -ENODEV ; +} + +static inline ssize_t debugfs_write_file_bool (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +return -ENODEV ; +} +#endif #endif
Signature · 1 line
2.1.4
Re: [PATCH v2 1/2] debugfs: Export bool read/write functions
In reply to Richard FitzgeraldQuoted 5 lines · Richard Fitzgerald
The file read/write functions for bools have no special dependencies on debugfs internals and are sufficiently non-trivial to be worth exporting so clients can re-use the implementation.
Signed-off-by Richard Fitzgerald <[email protected]>
PATCH v2 2/2 regmap: debugfs: Allow writes to cache state settings
In reply to Richard FitzgeraldAllow the user to write the cache_only and cache_bypass settings. This can be useful for debugging.
Since this can lead to the hardware getting out-of-sync with the cache, at least for the period that the cache state is forced, the kernel is tainted and the action is recorded in the kernel log.
When disabling cache_only through debugfs a cache sync will be performed.
--- drivers/base/regmap/regmap-debugfs.c | 90 ++++++++++++++++++++++++++++++++-- 1 files changed, 86 insertions(+), 4 deletions(-)
drivers/base/regmap/regmap-debugfs.c +86 -4
@@ -469,6 +469,87 @@ static const struct file_operations regmap_access_fops = { .llseek = default_llseek, }; +static ssize_t regmap_cache_only_write_file (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct regmap *map =container_of (file->private_data, + struct regmap, cache_only); +ssize_t result; +bool was_enabled, require_sync = false; +int err; + + map->lock (map->lock_arg); + + was_enabled = map->cache_only; + + result =debugfs_write_file_bool (file, user_buf, count, ppos); +if (result <0 ) { + map->unlock (map->lock_arg); +return result; + } + +if (map->cache_only && !was_enabled) { +dev_warn (map->dev,"debugfs cache_only=Y forced\n" ); +add_taint (TAINT_USER ,LOCKDEP_STILL_OK ); + }else if (!map->cache_only && was_enabled) { +dev_warn (map->dev,"debugfs cache_only=N forced: syncing cache\n" ); + require_sync = true; + } + + map->unlock (map->lock_arg); + +if (require_sync) { + err =regcache_sync (map); +if (err) +dev_err (map->dev,"Failed to sync cache %d\n" , err); + } + +return result; +} + +static const struct file_operations regmap_cache_only_fops = { + .open = simple_open, + .read = debugfs_read_file_bool, + .write = regmap_cache_only_write_file, +}; + +static ssize_t regmap_cache_bypass_write_file (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct regmap *map =container_of (file->private_data, + struct regmap, cache_bypass); +ssize_t result; +bool was_enabled; + + map->lock (map->lock_arg); + + was_enabled = map->cache_bypass; + + result =debugfs_write_file_bool (file, user_buf, count, ppos); +if (result <0 ) + goto out; + +if (map->cache_bypass && !was_enabled) { +dev_warn (map->dev,"debugfs cache_bypass=Y forced\n" ); +add_taint (TAINT_USER ,LOCKDEP_STILL_OK ); + }else if (!map->cache_bypass && was_enabled) { +dev_warn (map->dev,"debugfs cache_bypass=N forced\n" ); + } + +out: + map->unlock (map->lock_arg); + +return result; +} + +static const struct file_operations regmap_cache_bypass_fops = { + .open = simple_open, + .read = debugfs_read_file_bool, + .write = regmap_cache_bypass_write_file, +}; +void regmap_debugfs_init (struct regmap *map,const char *name) {struct rb_node *next;
@@ -530,12 +611,13 @@ void regmap_debugfs_init(struct regmap *map, const char *name) }if (map->cache_type) { -debugfs_create_bool ("cache_only" ,0400 , map->debugfs, - &map->cache_only); +debugfs_create_file ("cache_only" ,0600 , map->debugfs, + &map->cache_only, ®map_cache_only_fops);debugfs_create_bool ("cache_dirty" ,0400 , map->debugfs, &map->cache_dirty); -debugfs_create_bool ("cache_bypass" ,0400 , map->debugfs, - &map->cache_bypass); +debugfs_create_file ("cache_bypass" ,0600 , map->debugfs, + &map->cache_bypass, + ®map_cache_bypass_fops); } next =rb_first (&map->range_tree);
Signature · 1 line
1.7.2.5
Mark Brown
maintainerApplied "regmap: debugfs: Allow writes to cache state settings" to the regmap tree
The patch
regmap: debugfs: Allow writes to cache state settings
has been applied to the regmap tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
d3dc5430d68fb91a62d971648170b34d46ab85bcMon Sep 17 00:00:00 2001
From: Richard Fitzgerald <[email protected]>
Date: Tue, 23 Jun 2015 14:32:55 +0100
Subject: [PATCH] regmap: debugfs: Allow writes to cache state settings
Allow the user to write the cache_only and cache_bypass settings. This can be useful for debugging.
Since this can lead to the hardware getting out-of-sync with the cache, at least for the period that the cache state is forced, the kernel is tainted and the action is recorded in the kernel log.
When disabling cache_only through debugfs a cache sync will be performed.
--- drivers/base/regmap/regmap-debugfs.c | 90 ++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 4 deletions(-)
drivers/base/regmap/regmap-debugfs.c +86 -4
@@ -469,6 +469,87 @@ static const struct file_operations regmap_access_fops = { .llseek = default_llseek, }; +static ssize_t regmap_cache_only_write_file (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct regmap *map =container_of (file->private_data, + struct regmap, cache_only); +ssize_t result; +bool was_enabled, require_sync = false; +int err; + + map->lock (map->lock_arg); + + was_enabled = map->cache_only; + + result =debugfs_write_file_bool (file, user_buf, count, ppos); +if (result <0 ) { + map->unlock (map->lock_arg); +return result; + } + +if (map->cache_only && !was_enabled) { +dev_warn (map->dev,"debugfs cache_only=Y forced\n" ); +add_taint (TAINT_USER ,LOCKDEP_STILL_OK ); + }else if (!map->cache_only && was_enabled) { +dev_warn (map->dev,"debugfs cache_only=N forced: syncing cache\n" ); + require_sync = true; + } + + map->unlock (map->lock_arg); + +if (require_sync) { + err =regcache_sync (map); +if (err) +dev_err (map->dev,"Failed to sync cache %d\n" , err); + } + +return result; +} + +static const struct file_operations regmap_cache_only_fops = { + .open = simple_open, + .read = debugfs_read_file_bool, + .write = regmap_cache_only_write_file, +}; + +static ssize_t regmap_cache_bypass_write_file (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct regmap *map =container_of (file->private_data, + struct regmap, cache_bypass); +ssize_t result; +bool was_enabled; + + map->lock (map->lock_arg); + + was_enabled = map->cache_bypass; + + result =debugfs_write_file_bool (file, user_buf, count, ppos); +if (result <0 ) + goto out; + +if (map->cache_bypass && !was_enabled) { +dev_warn (map->dev,"debugfs cache_bypass=Y forced\n" ); +add_taint (TAINT_USER ,LOCKDEP_STILL_OK ); + }else if (!map->cache_bypass && was_enabled) { +dev_warn (map->dev,"debugfs cache_bypass=N forced\n" ); + } + +out: + map->unlock (map->lock_arg); + +return result; +} + +static const struct file_operations regmap_cache_bypass_fops = { + .open = simple_open, + .read = debugfs_read_file_bool, + .write = regmap_cache_bypass_write_file, +}; +void regmap_debugfs_init (struct regmap *map,const char *name) {struct rb_node *next;
@@ -530,12 +611,13 @@ void regmap_debugfs_init(struct regmap *map, const char *name) }if (map->cache_type) { -debugfs_create_bool ("cache_only" ,0400 , map->debugfs, - &map->cache_only); +debugfs_create_file ("cache_only" ,0600 , map->debugfs, + &map->cache_only, ®map_cache_only_fops);debugfs_create_bool ("cache_dirty" ,0400 , map->debugfs, &map->cache_dirty); -debugfs_create_bool ("cache_bypass" ,0400 , map->debugfs, - &map->cache_bypass); +debugfs_create_file ("cache_bypass" ,0600 , map->debugfs, + &map->cache_bypass, + ®map_cache_bypass_fops); } next =rb_first (&map->range_tree);
Signature · 1 line
2.1.4