131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown/* 231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * Register map access API - debugfs 331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * 431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * Copyright 2011 Wolfson Microelectronics plc 531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * 631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * 831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * This program is free software; you can redistribute it and/or modify 931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * it under the terms of the GNU General Public License version 2 as 1031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown * published by the Free Software Foundation. 1131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown */ 1231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 1331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown#include <linux/slab.h> 1431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown#include <linux/mutex.h> 1531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown#include <linux/debugfs.h> 1631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown#include <linux/uaccess.h> 1751990e825431089747f8896244b5c17d3a6423f1Paul Gortmaker#include <linux/device.h> 1831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 1931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown#include "internal.h" 2031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 2131244e396fa9e4854cfd6dfe305983e77802c156Mark Brownstatic struct dentry *regmap_debugfs_root; 2231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 2321f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown/* Calculate the length of a fixed format */ 2421f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brownstatic size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size) 2521f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown{ 2621f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown snprintf(buf, buf_size, "%x", max_val); 2721f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown return strlen(buf); 2821f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown} 2921f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown 30f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamosstatic ssize_t regmap_name_read_file(struct file *file, 31f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos char __user *user_buf, size_t count, 32f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos loff_t *ppos) 33f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos{ 34f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos struct regmap *map = file->private_data; 35f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos int ret; 36f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos char *buf; 37f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos 38f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 39f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos if (!buf) 40f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos return -ENOMEM; 41f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos 42f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name); 43f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos if (ret < 0) { 44f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos kfree(buf); 45f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos return ret; 46f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos } 47f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos 48f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 49f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos kfree(buf); 50f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos return ret; 51f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos} 52f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos 53f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamosstatic const struct file_operations regmap_name_fops = { 54234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, 55f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos .read = regmap_name_read_file, 56f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos .llseek = default_llseek, 57f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos}; 58f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos 5931244e396fa9e4854cfd6dfe305983e77802c156Mark Brownstatic ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, 6031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown size_t count, loff_t *ppos) 6131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown{ 62cb3c2dcfa34072b785cf292ca0b66494496572b9Mark Brown int reg_len, val_len, tot_len; 6331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown size_t buf_pos = 0; 6431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown loff_t p = 0; 6531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown ssize_t ret; 6631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown int i; 6731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown struct regmap *map = file->private_data; 6831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown char *buf; 6931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown unsigned int val; 7031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 7131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (*ppos < 0 || !count) 7231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown return -EINVAL; 7331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 7431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown buf = kmalloc(count, GFP_KERNEL); 7531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (!buf) 7631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown return -ENOMEM; 7731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 7831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown /* Calculate the length of a fixed format */ 7921f555445676e5c7d30bb9b3487cb183d02e45e3Mark Brown reg_len = regmap_calc_reg_len(map->max_register, buf, count); 8031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown val_len = 2 * map->format.val_bytes; 8131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown tot_len = reg_len + val_len + 3; /* : \n */ 8231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 83d813ae9a105219255c07d382059de831186c10d0Mark Brown for (i = 0; i < map->max_register + 1; i++) { 848de2f081ef8ee716663f916df9f2a7d015fa0dadMark Brown if (!regmap_readable(map, i)) 8531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown continue; 8631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 878de2f081ef8ee716663f916df9f2a7d015fa0dadMark Brown if (regmap_precious(map, i)) 882efe1642b73e74604498175de032b8a604868fb7Mark Brown continue; 892efe1642b73e74604498175de032b8a604868fb7Mark Brown 9031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown /* If we're in the region the user is trying to read */ 9131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (p >= *ppos) { 9231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown /* ...but not beyond it */ 9331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (buf_pos >= count - 1 - tot_len) 9431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown break; 9531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 9631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown /* Format the register */ 9731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown snprintf(buf + buf_pos, count - buf_pos, "%.*x: ", 9831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown reg_len, i); 9931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown buf_pos += reg_len + 2; 10031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 10131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown /* Format the value, write all X if we can't read */ 10231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown ret = regmap_read(map, i, &val); 10331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (ret == 0) 10431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown snprintf(buf + buf_pos, count - buf_pos, 10531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown "%.*x", val_len, val); 10631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown else 10731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown memset(buf + buf_pos, 'X', val_len); 10831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown buf_pos += 2 * map->format.val_bytes; 10931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 11031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown buf[buf_pos++] = '\n'; 11131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown } 11231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown p += tot_len; 11331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown } 11431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 11531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown ret = buf_pos; 11631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 11731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (copy_to_user(user_buf, buf, buf_pos)) { 11831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown ret = -EFAULT; 11931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown goto out; 12031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown } 12131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 12231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown *ppos += buf_pos; 12331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 12431244e396fa9e4854cfd6dfe305983e77802c156Mark Brownout: 12531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown kfree(buf); 12631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown return ret; 12731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown} 12831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 12909c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos#undef REGMAP_ALLOW_WRITE_DEBUGFS 13009c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos#ifdef REGMAP_ALLOW_WRITE_DEBUGFS 13109c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos/* 13209c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos * This can be dangerous especially when we have clients such as 13309c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos * PMICs, therefore don't provide any real compile time configuration option 13409c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos * for this feature, people who want to use this will need to modify 13509c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos * the source code directly. 13609c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos */ 13709c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamosstatic ssize_t regmap_map_write_file(struct file *file, 13809c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos const char __user *user_buf, 13909c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos size_t count, loff_t *ppos) 14009c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos{ 14109c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos char buf[32]; 14209c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos size_t buf_size; 14309c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos char *start = buf; 14409c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos unsigned long reg, value; 14509c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos struct regmap *map = file->private_data; 14609c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos 14709c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos buf_size = min(count, (sizeof(buf)-1)); 14809c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos if (copy_from_user(buf, user_buf, buf_size)) 14909c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos return -EFAULT; 15009c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos buf[buf_size] = 0; 15109c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos 15209c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos while (*start == ' ') 15309c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos start++; 15409c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos reg = simple_strtoul(start, &start, 16); 15509c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos while (*start == ' ') 15609c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos start++; 15709c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos if (strict_strtoul(start, 16, &value)) 15809c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos return -EINVAL; 15909c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos 16009c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos /* Userspace has been fiddling around behind the kernel's back */ 16109c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos add_taint(TAINT_USER); 16209c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos 16309c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos regmap_write(map, reg, value); 16409c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos return buf_size; 16509c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos} 16609c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos#else 16709c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos#define regmap_map_write_file NULL 16809c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos#endif 16909c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos 17031244e396fa9e4854cfd6dfe305983e77802c156Mark Brownstatic const struct file_operations regmap_map_fops = { 171234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, 17231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown .read = regmap_map_read_file, 17309c6ecd394105c4864a0e409e181c9b1578c2a63Dimitris Papastamos .write = regmap_map_write_file, 17431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown .llseek = default_llseek, 17531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown}; 17631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 177449e38427fe57a6120fecd1051981c89ee862b3dMark Brownstatic ssize_t regmap_access_read_file(struct file *file, 178449e38427fe57a6120fecd1051981c89ee862b3dMark Brown char __user *user_buf, size_t count, 179449e38427fe57a6120fecd1051981c89ee862b3dMark Brown loff_t *ppos) 180449e38427fe57a6120fecd1051981c89ee862b3dMark Brown{ 181449e38427fe57a6120fecd1051981c89ee862b3dMark Brown int reg_len, tot_len; 182449e38427fe57a6120fecd1051981c89ee862b3dMark Brown size_t buf_pos = 0; 183449e38427fe57a6120fecd1051981c89ee862b3dMark Brown loff_t p = 0; 184449e38427fe57a6120fecd1051981c89ee862b3dMark Brown ssize_t ret; 185449e38427fe57a6120fecd1051981c89ee862b3dMark Brown int i; 186449e38427fe57a6120fecd1051981c89ee862b3dMark Brown struct regmap *map = file->private_data; 187449e38427fe57a6120fecd1051981c89ee862b3dMark Brown char *buf; 188449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 189449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (*ppos < 0 || !count) 190449e38427fe57a6120fecd1051981c89ee862b3dMark Brown return -EINVAL; 191449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 192449e38427fe57a6120fecd1051981c89ee862b3dMark Brown buf = kmalloc(count, GFP_KERNEL); 193449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (!buf) 194449e38427fe57a6120fecd1051981c89ee862b3dMark Brown return -ENOMEM; 195449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 196449e38427fe57a6120fecd1051981c89ee862b3dMark Brown /* Calculate the length of a fixed format */ 197449e38427fe57a6120fecd1051981c89ee862b3dMark Brown reg_len = regmap_calc_reg_len(map->max_register, buf, count); 198449e38427fe57a6120fecd1051981c89ee862b3dMark Brown tot_len = reg_len + 10; /* ': R W V P\n' */ 199449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 200d813ae9a105219255c07d382059de831186c10d0Mark Brown for (i = 0; i < map->max_register + 1; i++) { 201449e38427fe57a6120fecd1051981c89ee862b3dMark Brown /* Ignore registers which are neither readable nor writable */ 202449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (!regmap_readable(map, i) && !regmap_writeable(map, i)) 203449e38427fe57a6120fecd1051981c89ee862b3dMark Brown continue; 204449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 205449e38427fe57a6120fecd1051981c89ee862b3dMark Brown /* If we're in the region the user is trying to read */ 206449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (p >= *ppos) { 207449e38427fe57a6120fecd1051981c89ee862b3dMark Brown /* ...but not beyond it */ 208449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (buf_pos >= count - 1 - tot_len) 209449e38427fe57a6120fecd1051981c89ee862b3dMark Brown break; 210449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 211449e38427fe57a6120fecd1051981c89ee862b3dMark Brown /* Format the register */ 212449e38427fe57a6120fecd1051981c89ee862b3dMark Brown snprintf(buf + buf_pos, count - buf_pos, 213449e38427fe57a6120fecd1051981c89ee862b3dMark Brown "%.*x: %c %c %c %c\n", 214449e38427fe57a6120fecd1051981c89ee862b3dMark Brown reg_len, i, 215449e38427fe57a6120fecd1051981c89ee862b3dMark Brown regmap_readable(map, i) ? 'y' : 'n', 216449e38427fe57a6120fecd1051981c89ee862b3dMark Brown regmap_writeable(map, i) ? 'y' : 'n', 217449e38427fe57a6120fecd1051981c89ee862b3dMark Brown regmap_volatile(map, i) ? 'y' : 'n', 218449e38427fe57a6120fecd1051981c89ee862b3dMark Brown regmap_precious(map, i) ? 'y' : 'n'); 219449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 220449e38427fe57a6120fecd1051981c89ee862b3dMark Brown buf_pos += tot_len; 221449e38427fe57a6120fecd1051981c89ee862b3dMark Brown } 222449e38427fe57a6120fecd1051981c89ee862b3dMark Brown p += tot_len; 223449e38427fe57a6120fecd1051981c89ee862b3dMark Brown } 224449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 225449e38427fe57a6120fecd1051981c89ee862b3dMark Brown ret = buf_pos; 226449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 227449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (copy_to_user(user_buf, buf, buf_pos)) { 228449e38427fe57a6120fecd1051981c89ee862b3dMark Brown ret = -EFAULT; 229449e38427fe57a6120fecd1051981c89ee862b3dMark Brown goto out; 230449e38427fe57a6120fecd1051981c89ee862b3dMark Brown } 231449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 232449e38427fe57a6120fecd1051981c89ee862b3dMark Brown *ppos += buf_pos; 233449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 234449e38427fe57a6120fecd1051981c89ee862b3dMark Brownout: 235449e38427fe57a6120fecd1051981c89ee862b3dMark Brown kfree(buf); 236449e38427fe57a6120fecd1051981c89ee862b3dMark Brown return ret; 237449e38427fe57a6120fecd1051981c89ee862b3dMark Brown} 238449e38427fe57a6120fecd1051981c89ee862b3dMark Brown 239449e38427fe57a6120fecd1051981c89ee862b3dMark Brownstatic const struct file_operations regmap_access_fops = { 240234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, 241449e38427fe57a6120fecd1051981c89ee862b3dMark Brown .read = regmap_access_read_file, 242449e38427fe57a6120fecd1051981c89ee862b3dMark Brown .llseek = default_llseek, 243449e38427fe57a6120fecd1051981c89ee862b3dMark Brown}; 24431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 24531244e396fa9e4854cfd6dfe305983e77802c156Mark Brownvoid regmap_debugfs_init(struct regmap *map) 24631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown{ 24731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown map->debugfs = debugfs_create_dir(dev_name(map->dev), 24831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown regmap_debugfs_root); 24931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (!map->debugfs) { 25031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown dev_warn(map->dev, "Failed to create debugfs directory\n"); 25131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown return; 25231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown } 25331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 254f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos debugfs_create_file("name", 0400, map->debugfs, 255f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos map, ®map_name_fops); 256f0c2319f9f196726ebe4d7508fd8fbd804988db3Dimitris Papastamos 257449e38427fe57a6120fecd1051981c89ee862b3dMark Brown if (map->max_register) { 25831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown debugfs_create_file("registers", 0400, map->debugfs, 25931244e396fa9e4854cfd6dfe305983e77802c156Mark Brown map, ®map_map_fops); 260449e38427fe57a6120fecd1051981c89ee862b3dMark Brown debugfs_create_file("access", 0400, map->debugfs, 261449e38427fe57a6120fecd1051981c89ee862b3dMark Brown map, ®map_access_fops); 262449e38427fe57a6120fecd1051981c89ee862b3dMark Brown } 263028a01e601487b5991b70dba506dfe87d83543f6Mark Brown 264028a01e601487b5991b70dba506dfe87d83543f6Mark Brown if (map->cache_type) { 265028a01e601487b5991b70dba506dfe87d83543f6Mark Brown debugfs_create_bool("cache_only", 0400, map->debugfs, 266028a01e601487b5991b70dba506dfe87d83543f6Mark Brown &map->cache_only); 267028a01e601487b5991b70dba506dfe87d83543f6Mark Brown debugfs_create_bool("cache_dirty", 0400, map->debugfs, 268028a01e601487b5991b70dba506dfe87d83543f6Mark Brown &map->cache_dirty); 269028a01e601487b5991b70dba506dfe87d83543f6Mark Brown debugfs_create_bool("cache_bypass", 0400, map->debugfs, 270028a01e601487b5991b70dba506dfe87d83543f6Mark Brown &map->cache_bypass); 271028a01e601487b5991b70dba506dfe87d83543f6Mark Brown } 27231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown} 27331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 27431244e396fa9e4854cfd6dfe305983e77802c156Mark Brownvoid regmap_debugfs_exit(struct regmap *map) 27531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown{ 27631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown debugfs_remove_recursive(map->debugfs); 27731244e396fa9e4854cfd6dfe305983e77802c156Mark Brown} 27831244e396fa9e4854cfd6dfe305983e77802c156Mark Brown 27931244e396fa9e4854cfd6dfe305983e77802c156Mark Brownvoid regmap_debugfs_initcall(void) 28031244e396fa9e4854cfd6dfe305983e77802c156Mark Brown{ 28131244e396fa9e4854cfd6dfe305983e77802c156Mark Brown regmap_debugfs_root = debugfs_create_dir("regmap", NULL); 28231244e396fa9e4854cfd6dfe305983e77802c156Mark Brown if (!regmap_debugfs_root) { 28331244e396fa9e4854cfd6dfe305983e77802c156Mark Brown pr_warn("regmap: Failed to create debugfs root\n"); 28431244e396fa9e4854cfd6dfe305983e77802c156Mark Brown return; 28531244e396fa9e4854cfd6dfe305983e77802c156Mark Brown } 28631244e396fa9e4854cfd6dfe305983e77802c156Mark Brown} 287