diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index f3266334063e..87b562e49a43 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -25,6 +25,7 @@ struct regmap_debugfs_node { struct list_head link; }; +static unsigned int dummy_index; static struct dentry *regmap_debugfs_root; static LIST_HEAD(regmap_debugfs_early_list); static DEFINE_MUTEX(regmap_debugfs_early_lock); @@ -40,6 +41,7 @@ static ssize_t regmap_name_read_file(struct file *file, loff_t *ppos) { struct regmap *map = file->private_data; + const char *name = "nodev"; int ret; char *buf; @@ -47,7 +49,10 @@ static ssize_t regmap_name_read_file(struct file *file, if (!buf) return -ENOMEM; - ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name); + if (map->dev && map->dev->driver) + name = map->dev->driver->name; + + ret = snprintf(buf, PAGE_SIZE, "%s\n", name); if (ret < 0) { kfree(buf); return ret; @@ -569,9 +574,20 @@ void regmap_debugfs_init(struct regmap *map, const char *name) name = devname; } + if (!strcmp(name, "dummy")) { + map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", + dummy_index); + name = map->debugfs_name; + dummy_index++; + } + map->debugfs = debugfs_create_dir(name, regmap_debugfs_root); if (!map->debugfs) { - dev_warn(map->dev, "Failed to create debugfs directory\n"); + dev_warn(map->dev, + "Failed to create %s debugfs directory\n", name); + + kfree(map->debugfs_name); + map->debugfs_name = NULL; return; } diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index 5189fd6182f6..5cadfd3394d8 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c @@ -28,6 +28,8 @@ struct regmap_mmio_context { void __iomem *regs; unsigned val_bytes; + + bool attached_clk; struct clk *clk; void (*reg_write)(struct regmap_mmio_context *ctx, @@ -363,4 +365,26 @@ struct regmap *__devm_regmap_init_mmio_clk(struct device *dev, } EXPORT_SYMBOL_GPL(__devm_regmap_init_mmio_clk); +int regmap_mmio_attach_clk(struct regmap *map, struct clk *clk) +{ + struct regmap_mmio_context *ctx = map->bus_context; + + ctx->clk = clk; + ctx->attached_clk = true; + + return clk_prepare(ctx->clk); +} +EXPORT_SYMBOL_GPL(regmap_mmio_attach_clk); + +void regmap_mmio_detach_clk(struct regmap *map) +{ + struct regmap_mmio_context *ctx = map->bus_context; + + clk_unprepare(ctx->clk); + + ctx->attached_clk = false; + ctx->clk = NULL; +} +EXPORT_SYMBOL_GPL(regmap_mmio_detach_clk); + MODULE_LICENSE("GPL v2"); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 9d042ee8707d..3bc84885eb91 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1116,6 +1116,8 @@ skip_format_initialization: ret = regmap_attach_dev(dev, map, config); if (ret != 0) goto err_regcache; + } else { + regmap_debugfs_init(map, config->name); } return map; diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 6a3aeba40e9e..5f7ad0552c03 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -21,6 +21,7 @@ #include struct module; +struct clk; struct device; struct i2c_client; struct irq_domain; @@ -905,6 +906,8 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_sdw, #config, \ sdw, config) +int regmap_mmio_attach_clk(struct regmap *map, struct clk *clk); +void regmap_mmio_detach_clk(struct regmap *map); void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config);