diff mbox series

mfd: syscon: Use a unique name with regmap_config

Message ID 20200122202746.30703-1-s-anna@ti.com (mailing list archive)
State New, archived
Headers show
Series mfd: syscon: Use a unique name with regmap_config | expand

Commit Message

Suman Anna Jan. 22, 2020, 8:27 p.m. UTC
The DT node full name is currently being used in regmap_config
which in turn is used to create the regmap debugfs directories.
This name however is not guaranteed to be unique and the regmap
debugfs registration can fail in the cases where the syscon nodes
have the same unit-address but are present in different DT node
hierarchies. Replace this logic using the syscon reg resource
address instead (inspired from logic used while creating platform
devices) to ensure a unique name is given for each syscon.

Signed-off-by: Suman Anna <s-anna@ti.com>
---
Hi Lee,

I ran into this issue while trying to add multiple different instances
of the same IP using the ti-sysc node hierarchy on OMAP.

Not sure if you prefer to consider this as a fix or as an improvement.
So, haven't added a Fixes tag.

regards
Suman

 drivers/mfd/syscon.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

kernel test robot Jan. 25, 2020, 3:48 a.m. UTC | #1
Hi Suman,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on arm-soc/for-next linux/master linus/master v5.5-rc7 next-20200124]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Suman-Anna/mfd-syscon-Use-a-unique-name-with-regmap_config/20200124-202741
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 7.5.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.5.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/mfd/syscon.c: In function 'of_syscon_register':
>> drivers/mfd/syscon.c:104:55: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'resource_size_t {aka unsigned int}' [-Wformat=]
     syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np, res.start);
                                                       ~~~^       ~~~~~~~~~
                                                       %x

vim +104 drivers/mfd/syscon.c

    42	
    43	static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
    44	{
    45		struct clk *clk;
    46		struct syscon *syscon;
    47		struct regmap *regmap;
    48		void __iomem *base;
    49		u32 reg_io_width;
    50		int ret;
    51		struct regmap_config syscon_config = syscon_regmap_config;
    52		struct resource res;
    53	
    54		syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
    55		if (!syscon)
    56			return ERR_PTR(-ENOMEM);
    57	
    58		if (of_address_to_resource(np, 0, &res)) {
    59			ret = -ENOMEM;
    60			goto err_map;
    61		}
    62	
    63		base = ioremap(res.start, resource_size(&res));
    64		if (!base) {
    65			ret = -ENOMEM;
    66			goto err_map;
    67		}
    68	
    69		/* Parse the device's DT node for an endianness specification */
    70		if (of_property_read_bool(np, "big-endian"))
    71			syscon_config.val_format_endian = REGMAP_ENDIAN_BIG;
    72		else if (of_property_read_bool(np, "little-endian"))
    73			syscon_config.val_format_endian = REGMAP_ENDIAN_LITTLE;
    74		else if (of_property_read_bool(np, "native-endian"))
    75			syscon_config.val_format_endian = REGMAP_ENDIAN_NATIVE;
    76	
    77		/*
    78		 * search for reg-io-width property in DT. If it is not provided,
    79		 * default to 4 bytes. regmap_init_mmio will return an error if values
    80		 * are invalid so there is no need to check them here.
    81		 */
    82		ret = of_property_read_u32(np, "reg-io-width", &reg_io_width);
    83		if (ret)
    84			reg_io_width = 4;
    85	
    86		ret = of_hwspin_lock_get_id(np, 0);
    87		if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) {
    88			syscon_config.use_hwlock = true;
    89			syscon_config.hwlock_id = ret;
    90			syscon_config.hwlock_mode = HWLOCK_IRQSTATE;
    91		} else if (ret < 0) {
    92			switch (ret) {
    93			case -ENOENT:
    94				/* Ignore missing hwlock, it's optional. */
    95				break;
    96			default:
    97				pr_err("Failed to retrieve valid hwlock: %d\n", ret);
    98				/* fall-through */
    99			case -EPROBE_DEFER:
   100				goto err_regmap;
   101			}
   102		}
   103	
 > 104		syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np, res.start);
   105		syscon_config.reg_stride = reg_io_width;
   106		syscon_config.val_bits = reg_io_width * 8;
   107		syscon_config.max_register = resource_size(&res) - reg_io_width;
   108	
   109		regmap = regmap_init_mmio(NULL, base, &syscon_config);
   110		kfree(syscon_config.name);
   111		if (IS_ERR(regmap)) {
   112			pr_err("regmap init failed\n");
   113			ret = PTR_ERR(regmap);
   114			goto err_regmap;
   115		}
   116	
   117		if (check_clk) {
   118			clk = of_clk_get(np, 0);
   119			if (IS_ERR(clk)) {
   120				ret = PTR_ERR(clk);
   121				/* clock is optional */
   122				if (ret != -ENOENT)
   123					goto err_clk;
   124			} else {
   125				ret = regmap_mmio_attach_clk(regmap, clk);
   126				if (ret)
   127					goto err_attach;
   128			}
   129		}
   130	
   131		syscon->regmap = regmap;
   132		syscon->np = np;
   133	
   134		spin_lock(&syscon_list_slock);
   135		list_add_tail(&syscon->list, &syscon_list);
   136		spin_unlock(&syscon_list_slock);
   137	
   138		return syscon;
   139	
   140	err_attach:
   141		if (!IS_ERR(clk))
   142			clk_put(clk);
   143	err_clk:
   144		regmap_exit(regmap);
   145	err_regmap:
   146		iounmap(base);
   147	err_map:
   148		kfree(syscon);
   149		return ERR_PTR(ret);
   150	}
   151	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
diff mbox series

Patch

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index e22197c832e8..8915b35eef4f 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -101,12 +101,13 @@  static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
 		}
 	}
 
-	syscon_config.name = of_node_full_name(np);
+	syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np, res.start);
 	syscon_config.reg_stride = reg_io_width;
 	syscon_config.val_bits = reg_io_width * 8;
 	syscon_config.max_register = resource_size(&res) - reg_io_width;
 
 	regmap = regmap_init_mmio(NULL, base, &syscon_config);
+	kfree(syscon_config.name);
 	if (IS_ERR(regmap)) {
 		pr_err("regmap init failed\n");
 		ret = PTR_ERR(regmap);