2015-06-23 13:30:12

by Richard Fitzgerald

[permalink] [raw]
Subject: [PATCH v2 0/2] 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(-)

--
1.7.2.5


2015-06-23 13:30:19

by Richard Fitzgerald

[permalink] [raw]
Subject: [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.

Signed-off-by: Richard Fitzgerald <[email protected]>
---
fs/debugfs/file.c | 14 ++++++++------
include/linux/debugfs.h | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 830a7e7..95ae5ee 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -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,
};
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index cb25af4..1545962 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -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
--
1.7.2.5

2015-06-23 13:30:26

by Richard Fitzgerald

[permalink] [raw]
Subject: [PATCH v2 2/2] 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.

Signed-off-by: Richard Fitzgerald <[email protected]>
---
drivers/base/regmap/regmap-debugfs.c | 90 ++++++++++++++++++++++++++++++++--
1 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 5799a0b..6a61e4f 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -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, &regmap_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,
+ &regmap_cache_bypass_fops);
}

next = rb_first(&map->range_tree);
--
1.7.2.5

2015-07-17 18:22:23

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] debugfs: Export bool read/write functions

On Tue, Jun 23, 2015 at 02:32:54PM +0100, Richard Fitzgerald wrote:
> 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.

> Signed-off-by: Richard Fitzgerald <[email protected]>
> ---
> fs/debugfs/file.c | 14 ++++++++------
> include/linux/debugfs.h | 20 ++++++++++++++++++++
> 2 files changed, 28 insertions(+), 6 deletions(-)
>
> diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
> index 830a7e7..95ae5ee 100644
> --- a/fs/debugfs/file.c
> +++ b/fs/debugfs/file.c
> @@ -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,
> };
> diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
> index cb25af4..1545962 100644
> --- a/include/linux/debugfs.h
> +++ b/include/linux/debugfs.h
> @@ -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
> --
> 1.7.2.5
>
>


Attachments:
(No filename) (3.15 kB)
signature.asc (473.00 B)
Digital signature
Download all attachments

2015-07-19 18:45:58

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] debugfs: Export bool read/write functions

On Fri, Jul 17, 2015 at 07:22:12PM +0100, Mark Brown wrote:
> On Tue, Jun 23, 2015 at 02:32:54PM +0100, Richard Fitzgerald wrote:
> > 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.


Acked-by: Greg Kroah-Hartman <[email protected]>

2015-07-20 17:52:45

by Mark Brown

[permalink] [raw]
Subject: Applied "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

>From d3dc5430d68fb91a62d971648170b34d46ab85bc Mon 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.

Signed-off-by: Richard Fitzgerald <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
---
drivers/base/regmap/regmap-debugfs.c | 90 ++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 4 deletions(-)

diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 5799a0b9e6cc..6a61e4fa73a2 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -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, &regmap_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,
+ &regmap_cache_bypass_fops);
}

next = rb_first(&map->range_tree);
--
2.1.4

2015-07-20 17:52:51

by Mark Brown

[permalink] [raw]
Subject: Applied "debugfs: Export bool read/write functions" to the regmap tree

The 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

>From 0642ef6f2992eba46c41abb5ceb7d4fa14ba888e Mon 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.

Signed-off-by: Richard Fitzgerald <[email protected]>
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
---
fs/debugfs/file.c | 14 ++++++++------
include/linux/debugfs.h | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 284f9aa0028b..6c55ade071c3 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -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,
};
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 420311bcee38..9beb636b97eb 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -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
--
2.1.4

2015-08-05 20:09:57

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] debugfs: Export bool read/write functions

On Tue, Jun 23, 2015 at 02:32:54PM +0100, Richard Fitzgerald wrote:
> 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]>

Acked-by: Greg Kroah-Hartman <[email protected]>