Loading drivers/base/regmap/regmap-debugfs.c +91 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -518,10 +599,11 @@ void regmap_debugfs_init(struct regmap *map, const char *name) if (map->max_register || regmap_readable(map, 0)) { umode_t registers_mode; if (IS_ENABLED(REGMAP_ALLOW_WRITE_DEBUGFS)) #if defined(REGMAP_ALLOW_WRITE_DEBUGFS) registers_mode = 0600; else #else registers_mode = 0400; #endif debugfs_create_file("registers", registers_mode, map->debugfs, map, ®map_map_fops); Loading @@ -530,12 +612,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); Loading drivers/base/regmap/regmap.c +43 −8 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change); bool *change, bool force_write); static int _regmap_bus_reg_read(void *context, unsigned int reg, unsigned int *val); Loading Loading @@ -1186,7 +1186,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, ret = _regmap_update_bits(map, range->selector_reg, range->selector_mask, win_page << range->selector_shift, &page_chg); &page_chg, false); map->work_buf = orig_work_buf; Loading Loading @@ -1657,6 +1657,18 @@ int regmap_fields_write(struct regmap_field *field, unsigned int id, } EXPORT_SYMBOL_GPL(regmap_fields_write); int regmap_fields_force_write(struct regmap_field *field, unsigned int id, unsigned int val) { if (id >= field->id_size) return -EINVAL; return regmap_write_bits(field->regmap, field->reg + (field->id_offset * id), field->mask, val << field->shift); } EXPORT_SYMBOL_GPL(regmap_fields_force_write); /** * regmap_fields_update_bits(): Perform a read/modify/write cycle * on the register field Loading Loading @@ -2466,7 +2478,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_read); static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change) bool *change, bool force_write) { int ret; unsigned int tmp, orig; Loading @@ -2478,7 +2490,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, tmp = orig & ~mask; tmp |= val & mask; if (tmp != orig) { if (force_write || (tmp != orig)) { ret = _regmap_write(map, reg, tmp); if (change) *change = true; Loading Loading @@ -2506,13 +2518,36 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, int ret; map->lock(map->lock_arg); ret = _regmap_update_bits(map, reg, mask, val, NULL); ret = _regmap_update_bits(map, reg, mask, val, NULL, false); map->unlock(map->lock_arg); return ret; } EXPORT_SYMBOL_GPL(regmap_update_bits); /** * regmap_write_bits: Perform a read/modify/write cycle on the register map * * @map: Register map to update * @reg: Register to update * @mask: Bitmask to change * @val: New value for bitmask * * Returns zero for success, a negative number on error. */ int regmap_write_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val) { int ret; map->lock(map->lock_arg); ret = _regmap_update_bits(map, reg, mask, val, NULL, true); map->unlock(map->lock_arg); return ret; } EXPORT_SYMBOL_GPL(regmap_write_bits); /** * regmap_update_bits_async: Perform a read/modify/write cycle on the register * map asynchronously Loading @@ -2537,7 +2572,7 @@ int regmap_update_bits_async(struct regmap *map, unsigned int reg, map->async = true; ret = _regmap_update_bits(map, reg, mask, val, NULL); ret = _regmap_update_bits(map, reg, mask, val, NULL, false); map->async = false; Loading Loading @@ -2566,7 +2601,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, int ret; map->lock(map->lock_arg); ret = _regmap_update_bits(map, reg, mask, val, change); ret = _regmap_update_bits(map, reg, mask, val, change, false); map->unlock(map->lock_arg); return ret; } Loading Loading @@ -2599,7 +2634,7 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg, map->async = true; ret = _regmap_update_bits(map, reg, mask, val, change); ret = _regmap_update_bits(map, reg, mask, val, change, false); map->async = false; Loading drivers/regulator/core.c +1 −1 Original line number Diff line number Diff line Loading @@ -1244,7 +1244,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, regulator->debugfs = debugfs_create_dir(regulator->supply_name, rdev->debugfs); if (!regulator->debugfs) { rdev_warn(rdev, "Failed to create debugfs directory\n"); rdev_dbg(rdev, "Failed to create debugfs directory\n"); } else { debugfs_create_u32("uA_load", 0444, regulator->debugfs, ®ulator->uA_load); Loading fs/debugfs/file.c +8 −6 Original line number Diff line number Diff line Loading @@ -435,7 +435,7 @@ 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, ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char buf[3]; Loading @@ -449,8 +449,9 @@ 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, ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { char buf[32]; Loading @@ -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, }; Loading include/linux/debugfs.h +20 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading
drivers/base/regmap/regmap-debugfs.c +91 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -518,10 +599,11 @@ void regmap_debugfs_init(struct regmap *map, const char *name) if (map->max_register || regmap_readable(map, 0)) { umode_t registers_mode; if (IS_ENABLED(REGMAP_ALLOW_WRITE_DEBUGFS)) #if defined(REGMAP_ALLOW_WRITE_DEBUGFS) registers_mode = 0600; else #else registers_mode = 0400; #endif debugfs_create_file("registers", registers_mode, map->debugfs, map, ®map_map_fops); Loading @@ -530,12 +612,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); Loading
drivers/base/regmap/regmap.c +43 −8 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change); bool *change, bool force_write); static int _regmap_bus_reg_read(void *context, unsigned int reg, unsigned int *val); Loading Loading @@ -1186,7 +1186,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, ret = _regmap_update_bits(map, range->selector_reg, range->selector_mask, win_page << range->selector_shift, &page_chg); &page_chg, false); map->work_buf = orig_work_buf; Loading Loading @@ -1657,6 +1657,18 @@ int regmap_fields_write(struct regmap_field *field, unsigned int id, } EXPORT_SYMBOL_GPL(regmap_fields_write); int regmap_fields_force_write(struct regmap_field *field, unsigned int id, unsigned int val) { if (id >= field->id_size) return -EINVAL; return regmap_write_bits(field->regmap, field->reg + (field->id_offset * id), field->mask, val << field->shift); } EXPORT_SYMBOL_GPL(regmap_fields_force_write); /** * regmap_fields_update_bits(): Perform a read/modify/write cycle * on the register field Loading Loading @@ -2466,7 +2478,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_read); static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change) bool *change, bool force_write) { int ret; unsigned int tmp, orig; Loading @@ -2478,7 +2490,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, tmp = orig & ~mask; tmp |= val & mask; if (tmp != orig) { if (force_write || (tmp != orig)) { ret = _regmap_write(map, reg, tmp); if (change) *change = true; Loading Loading @@ -2506,13 +2518,36 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, int ret; map->lock(map->lock_arg); ret = _regmap_update_bits(map, reg, mask, val, NULL); ret = _regmap_update_bits(map, reg, mask, val, NULL, false); map->unlock(map->lock_arg); return ret; } EXPORT_SYMBOL_GPL(regmap_update_bits); /** * regmap_write_bits: Perform a read/modify/write cycle on the register map * * @map: Register map to update * @reg: Register to update * @mask: Bitmask to change * @val: New value for bitmask * * Returns zero for success, a negative number on error. */ int regmap_write_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val) { int ret; map->lock(map->lock_arg); ret = _regmap_update_bits(map, reg, mask, val, NULL, true); map->unlock(map->lock_arg); return ret; } EXPORT_SYMBOL_GPL(regmap_write_bits); /** * regmap_update_bits_async: Perform a read/modify/write cycle on the register * map asynchronously Loading @@ -2537,7 +2572,7 @@ int regmap_update_bits_async(struct regmap *map, unsigned int reg, map->async = true; ret = _regmap_update_bits(map, reg, mask, val, NULL); ret = _regmap_update_bits(map, reg, mask, val, NULL, false); map->async = false; Loading Loading @@ -2566,7 +2601,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, int ret; map->lock(map->lock_arg); ret = _regmap_update_bits(map, reg, mask, val, change); ret = _regmap_update_bits(map, reg, mask, val, change, false); map->unlock(map->lock_arg); return ret; } Loading Loading @@ -2599,7 +2634,7 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg, map->async = true; ret = _regmap_update_bits(map, reg, mask, val, change); ret = _regmap_update_bits(map, reg, mask, val, change, false); map->async = false; Loading
drivers/regulator/core.c +1 −1 Original line number Diff line number Diff line Loading @@ -1244,7 +1244,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, regulator->debugfs = debugfs_create_dir(regulator->supply_name, rdev->debugfs); if (!regulator->debugfs) { rdev_warn(rdev, "Failed to create debugfs directory\n"); rdev_dbg(rdev, "Failed to create debugfs directory\n"); } else { debugfs_create_u32("uA_load", 0444, regulator->debugfs, ®ulator->uA_load); Loading
fs/debugfs/file.c +8 −6 Original line number Diff line number Diff line Loading @@ -435,7 +435,7 @@ 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, ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char buf[3]; Loading @@ -449,8 +449,9 @@ 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, ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { char buf[32]; Loading @@ -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, }; Loading
include/linux/debugfs.h +20 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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