--- zzzz-none-000/linux-4.4.60/drivers/base/regmap/regmap-debugfs.c 2017-04-08 07:53:53.000000000 +0000 +++ dragonfly-4020-701/linux-4.4.60/drivers/base/regmap/regmap-debugfs.c 2018-11-08 13:36:17.000000000 +0000 @@ -259,8 +259,7 @@ count, ppos); } -#undef REGMAP_ALLOW_WRITE_DEBUGFS -#ifdef REGMAP_ALLOW_WRITE_DEBUGFS +#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS /* * This can be dangerous especially when we have clients such as * PMICs, therefore don't provide any real compile time configuration option @@ -310,6 +309,67 @@ .llseek = default_llseek, }; +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 CONFIG_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, +}; + static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -595,7 +655,7 @@ if (map->max_register || regmap_readable(map, 0)) { umode_t registers_mode; -#if defined(REGMAP_ALLOW_WRITE_DEBUGFS) +#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS registers_mode = 0600; #else registers_mode = 0400; @@ -603,6 +663,15 @@ debugfs_create_file("registers", registers_mode, map->debugfs, map, ®map_map_fops); + + 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); + debugfs_create_file("access", 0400, map->debugfs, map, ®map_access_fops); }