Loading drivers/base/regmap/Kconfig +9 −0 Original line number Diff line number Diff line Loading @@ -53,3 +53,12 @@ config REGMAP_SCCB config REGMAP_I3C tristate depends on I3C config REGMAP_QTI_DEBUG bool "Regmap QTI debug feature support" depends on REGMAP && DEBUG_FS && QGKI help Say yes to enable QTI debug features. This provides a runtime debugfs interface to read and write a subset of regmap registers. This interface is more performant and easier to use than the traditional method which dumps all registers defined in a given regmap. drivers/base/regmap/internal.h +5 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,11 @@ struct regmap { struct list_head debugfs_off_cache; struct mutex cache_lock; #ifdef CONFIG_REGMAP_QTI_DEBUG unsigned int dump_address; unsigned int dump_count; #endif #endif unsigned int max_register; Loading drivers/base/regmap/regmap-debugfs.c +73 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,69 @@ static const struct file_operations regmap_map_fops = { .llseek = default_llseek, }; #ifdef CONFIG_REGMAP_QTI_DEBUG static ssize_t regmap_data_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct regmap *map = file->private_data; int new_count; regmap_calc_tot_len(map, NULL, 0); new_count = map->dump_count * map->debugfs_tot_len; if (new_count > count) new_count = count; if (*ppos == 0) *ppos = map->dump_address * map->debugfs_tot_len; else if (*ppos >= map->dump_address * map->debugfs_tot_len + map->dump_count * map->debugfs_tot_len) return 0; return regmap_read_debugfs(map, 0, map->max_register, user_buf, new_count, ppos); } #ifdef REGMAP_ALLOW_WRITE_DEBUGFS static ssize_t regmap_data_write_file(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { char buf[32]; size_t buf_size; char *start = buf; unsigned long value; struct regmap *map = file->private_data; int ret; buf_size = min(count, (sizeof(buf)-1)); if (copy_from_user(buf, user_buf, buf_size)) return -EFAULT; buf[buf_size] = 0; while (*start == ' ') start++; if (kstrtoul(start, 16, &value)) return -EINVAL; /* Userspace has been fiddling around behind the kernel's back */ add_taint(TAINT_USER, LOCKDEP_STILL_OK); ret = regmap_write(map, map->dump_address, value); if (ret < 0) return ret; return buf_size; } #else #define regmap_data_write_file NULL #endif static const struct file_operations regmap_data_fops = { .open = simple_open, .read = regmap_data_read_file, .write = regmap_data_write_file, .llseek = default_llseek, }; #endif static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { Loading Loading @@ -608,6 +671,16 @@ void regmap_debugfs_init(struct regmap *map, const char *name) map, ®map_map_fops); debugfs_create_file("access", 0400, map->debugfs, map, ®map_access_fops); #ifdef CONFIG_REGMAP_QTI_DEBUG debugfs_create_x32("address", 0600, map->debugfs, &map->dump_address); map->dump_count = 1; debugfs_create_u32("count", 0600, map->debugfs, &map->dump_count); debugfs_create_file("data", registers_mode, map->debugfs, map, ®map_data_fops); #endif } if (map->cache_type) { Loading Loading
drivers/base/regmap/Kconfig +9 −0 Original line number Diff line number Diff line Loading @@ -53,3 +53,12 @@ config REGMAP_SCCB config REGMAP_I3C tristate depends on I3C config REGMAP_QTI_DEBUG bool "Regmap QTI debug feature support" depends on REGMAP && DEBUG_FS && QGKI help Say yes to enable QTI debug features. This provides a runtime debugfs interface to read and write a subset of regmap registers. This interface is more performant and easier to use than the traditional method which dumps all registers defined in a given regmap.
drivers/base/regmap/internal.h +5 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,11 @@ struct regmap { struct list_head debugfs_off_cache; struct mutex cache_lock; #ifdef CONFIG_REGMAP_QTI_DEBUG unsigned int dump_address; unsigned int dump_count; #endif #endif unsigned int max_register; Loading
drivers/base/regmap/regmap-debugfs.c +73 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,69 @@ static const struct file_operations regmap_map_fops = { .llseek = default_llseek, }; #ifdef CONFIG_REGMAP_QTI_DEBUG static ssize_t regmap_data_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct regmap *map = file->private_data; int new_count; regmap_calc_tot_len(map, NULL, 0); new_count = map->dump_count * map->debugfs_tot_len; if (new_count > count) new_count = count; if (*ppos == 0) *ppos = map->dump_address * map->debugfs_tot_len; else if (*ppos >= map->dump_address * map->debugfs_tot_len + map->dump_count * map->debugfs_tot_len) return 0; return regmap_read_debugfs(map, 0, map->max_register, user_buf, new_count, ppos); } #ifdef REGMAP_ALLOW_WRITE_DEBUGFS static ssize_t regmap_data_write_file(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { char buf[32]; size_t buf_size; char *start = buf; unsigned long value; struct regmap *map = file->private_data; int ret; buf_size = min(count, (sizeof(buf)-1)); if (copy_from_user(buf, user_buf, buf_size)) return -EFAULT; buf[buf_size] = 0; while (*start == ' ') start++; if (kstrtoul(start, 16, &value)) return -EINVAL; /* Userspace has been fiddling around behind the kernel's back */ add_taint(TAINT_USER, LOCKDEP_STILL_OK); ret = regmap_write(map, map->dump_address, value); if (ret < 0) return ret; return buf_size; } #else #define regmap_data_write_file NULL #endif static const struct file_operations regmap_data_fops = { .open = simple_open, .read = regmap_data_read_file, .write = regmap_data_write_file, .llseek = default_llseek, }; #endif static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { Loading Loading @@ -608,6 +671,16 @@ void regmap_debugfs_init(struct regmap *map, const char *name) map, ®map_map_fops); debugfs_create_file("access", 0400, map->debugfs, map, ®map_access_fops); #ifdef CONFIG_REGMAP_QTI_DEBUG debugfs_create_x32("address", 0600, map->debugfs, &map->dump_address); map->dump_count = 1; debugfs_create_u32("count", 0600, map->debugfs, &map->dump_count); debugfs_create_file("data", registers_mode, map->debugfs, map, ®map_data_fops); #endif } if (map->cache_type) { Loading