diff mbox series

[v3,1/3] regulator: Add regulator_bulk_get_all

Message ID 20220523052807.4044800-2-clabbe@baylibre.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series arm64: add ethernet to orange pi 3 | expand

Checks

Context Check Description
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 5319 this patch: 5319
netdev/cc_maintainers success CCed 2 of 2 maintainers
netdev/build_clang success Errors and warnings before: 540 this patch: 540
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 4159 this patch: 4159
netdev/checkpatch warning WARNING: Block comments use a trailing */ on a separate line WARNING: line length of 83 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Corentin LABBE May 23, 2022, 5:28 a.m. UTC
It work exactly like regulator_bulk_get() but instead of working on a
provided list of names, it seek all consumers properties matching
xxx-supply.

Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
 drivers/regulator/core.c           | 92 ++++++++++++++++++++++++++++++
 include/linux/regulator/consumer.h |  2 +
 2 files changed, 94 insertions(+)

Comments

kernel test robot May 23, 2022, 9:54 a.m. UTC | #1
Hi Corentin,

I love your patch! Yet something to improve:

[auto build test ERROR on broonie-regulator/for-next]
[also build test ERROR on sunxi/sunxi/for-next linus/master v5.18 next-20220520]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Corentin-Labbe/arm64-add-ethernet-to-orange-pi-3/20220523-133344
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
config: i386-randconfig-a012-20220523 (https://download.01.org/0day-ci/archive/20220523/202205231748.IZoXf2Sf-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 768a1ca5eccb678947f4155e38a5f5744dcefb56)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/179be86f748a2cce87423bb16f4f967c97bf5d9b
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Corentin-Labbe/arm64-add-ethernet-to-orange-pi-3/20220523-133344
        git checkout 179be86f748a2cce87423bb16f4f967c97bf5d9b
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

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

All errors (new ones prefixed by >>):

>> drivers/regulator/core.c:4870:2: error: call to undeclared function 'for_each_property_of_node'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
           for_each_property_of_node(np, prop) {
           ^
>> drivers/regulator/core.c:4870:37: error: expected ';' after expression
           for_each_property_of_node(np, prop) {
                                              ^
                                              ;
>> drivers/regulator/core.c:4873:4: error: 'continue' statement not in loop statement
                           continue;
                           ^
   drivers/regulator/core.c:4876:4: error: 'continue' statement not in loop statement
                           continue;
                           ^
   drivers/regulator/core.c:4887:4: error: 'continue' statement not in loop statement
                           continue;
                           ^
   5 errors generated.


vim +/for_each_property_of_node +4870 drivers/regulator/core.c

  4839	
  4840	/*
  4841	 * regulator_bulk_get_all - get multiple regulator consumers
  4842	 *
  4843	 * @dev:	Device to supply
  4844	 * @np:		device node to search for consumers
  4845	 * @consumers:  Configuration of consumers; clients are stored here.
  4846	 *
  4847	 * @return number of regulators on success, an errno on failure.
  4848	 *
  4849	 * This helper function allows drivers to get several regulator
  4850	 * consumers in one operation.  If any of the regulators cannot be
  4851	 * acquired then any regulators that were allocated will be freed
  4852	 * before returning to the caller.
  4853	 */
  4854	int regulator_bulk_get_all(struct device *dev, struct device_node *np,
  4855				   struct regulator_bulk_data **consumers)
  4856	{
  4857		int num_consumers = 0;
  4858		struct regulator *tmp;
  4859		struct property *prop;
  4860		int i, n = 0, ret;
  4861		char name[64];
  4862	
  4863		*consumers = NULL;
  4864	
  4865	/*
  4866	 * first pass: get numbers of xxx-supply
  4867	 * second pass: fill consumers
  4868	 * */
  4869	restart:
> 4870		for_each_property_of_node(np, prop) {
  4871			i = is_supply_name(prop->name);
  4872			if (i == 0)
> 4873				continue;
  4874			if (!*consumers) {
  4875				num_consumers++;
  4876				continue;
  4877			} else {
  4878				memcpy(name, prop->name, i);
  4879				name[i] = '\0';
  4880				tmp = regulator_get(dev, name);
  4881				if (!tmp) {
  4882					ret = -EINVAL;
  4883					goto error;
  4884				}
  4885				(*consumers)[n].consumer = tmp;
  4886				n++;
  4887				continue;
  4888			}
  4889		}
  4890		if (*consumers)
  4891			return num_consumers;
  4892		if (num_consumers == 0)
  4893			return 0;
  4894		*consumers = kmalloc_array(num_consumers,
  4895					   sizeof(struct regulator_bulk_data),
  4896					   GFP_KERNEL);
  4897		if (!*consumers)
  4898			return -ENOMEM;
  4899		goto restart;
  4900	
  4901	error:
  4902		while (--n >= 0)
  4903			regulator_put(consumers[n]->consumer);
  4904		return ret;
  4905	}
  4906	EXPORT_SYMBOL_GPL(regulator_bulk_get_all);
  4907
kernel test robot May 23, 2022, 10:04 a.m. UTC | #2
Hi Corentin,

I love your patch! Yet something to improve:

[auto build test ERROR on broonie-regulator/for-next]
[also build test ERROR on sunxi/sunxi/for-next linus/master v5.18 next-20220520]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Corentin-Labbe/arm64-add-ethernet-to-orange-pi-3/20220523-133344
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
config: hexagon-buildonly-randconfig-r002-20220522 (https://download.01.org/0day-ci/archive/20220523/202205231709.3Wo0pW9z-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 768a1ca5eccb678947f4155e38a5f5744dcefb56)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/179be86f748a2cce87423bb16f4f967c97bf5d9b
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Corentin-Labbe/arm64-add-ethernet-to-orange-pi-3/20220523-133344
        git checkout 179be86f748a2cce87423bb16f4f967c97bf5d9b
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/

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

All errors (new ones prefixed by >>):

>> drivers/regulator/core.c:4870:2: error: call to undeclared function 'for_each_property_of_node'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
           for_each_property_of_node(np, prop) {
           ^
>> drivers/regulator/core.c:4870:37: error: expected ';' after expression
           for_each_property_of_node(np, prop) {
                                              ^
                                              ;
>> drivers/regulator/core.c:4873:4: error: 'continue' statement not in loop statement
                           continue;
                           ^
   drivers/regulator/core.c:4876:4: error: 'continue' statement not in loop statement
                           continue;
                           ^
   drivers/regulator/core.c:4887:4: error: 'continue' statement not in loop statement
                           continue;
                           ^
   5 errors generated.


vim +/for_each_property_of_node +4870 drivers/regulator/core.c

  4839	
  4840	/*
  4841	 * regulator_bulk_get_all - get multiple regulator consumers
  4842	 *
  4843	 * @dev:	Device to supply
  4844	 * @np:		device node to search for consumers
  4845	 * @consumers:  Configuration of consumers; clients are stored here.
  4846	 *
  4847	 * @return number of regulators on success, an errno on failure.
  4848	 *
  4849	 * This helper function allows drivers to get several regulator
  4850	 * consumers in one operation.  If any of the regulators cannot be
  4851	 * acquired then any regulators that were allocated will be freed
  4852	 * before returning to the caller.
  4853	 */
  4854	int regulator_bulk_get_all(struct device *dev, struct device_node *np,
  4855				   struct regulator_bulk_data **consumers)
  4856	{
  4857		int num_consumers = 0;
  4858		struct regulator *tmp;
  4859		struct property *prop;
  4860		int i, n = 0, ret;
  4861		char name[64];
  4862	
  4863		*consumers = NULL;
  4864	
  4865	/*
  4866	 * first pass: get numbers of xxx-supply
  4867	 * second pass: fill consumers
  4868	 * */
  4869	restart:
> 4870		for_each_property_of_node(np, prop) {
  4871			i = is_supply_name(prop->name);
  4872			if (i == 0)
> 4873				continue;
  4874			if (!*consumers) {
  4875				num_consumers++;
  4876				continue;
  4877			} else {
  4878				memcpy(name, prop->name, i);
  4879				name[i] = '\0';
  4880				tmp = regulator_get(dev, name);
  4881				if (!tmp) {
  4882					ret = -EINVAL;
  4883					goto error;
  4884				}
  4885				(*consumers)[n].consumer = tmp;
  4886				n++;
  4887				continue;
  4888			}
  4889		}
  4890		if (*consumers)
  4891			return num_consumers;
  4892		if (num_consumers == 0)
  4893			return 0;
  4894		*consumers = kmalloc_array(num_consumers,
  4895					   sizeof(struct regulator_bulk_data),
  4896					   GFP_KERNEL);
  4897		if (!*consumers)
  4898			return -ENOMEM;
  4899		goto restart;
  4900	
  4901	error:
  4902		while (--n >= 0)
  4903			regulator_put(consumers[n]->consumer);
  4904		return ret;
  4905	}
  4906	EXPORT_SYMBOL_GPL(regulator_bulk_get_all);
  4907
Mark Brown May 23, 2022, 1:17 p.m. UTC | #3
On Mon, May 23, 2022 at 05:28:05AM +0000, Corentin Labbe wrote:

> +	*consumers = NULL;
> +
> +/*
> + * first pass: get numbers of xxx-supply
> + * second pass: fill consumers
> + * */
> +restart:

Please fix the identation of this comment so it looks less like an
error.  TBH I'm not sure it isn't easier to just use krealloc() and have
one loop here, or just write two separate loops given how little is
shared.
diff mbox series

Patch

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 1e54a833f2cf..7286bcf3821a 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4813,6 +4813,98 @@  static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
 	bulk->ret = regulator_enable(bulk->consumer);
 }
 
+/*
+ * Check if name is a supply name according to the '*-supply' pattern
+ * return 0 if false
+ * return length of supply name without the -supply
+ */
+static int is_supply_name(const char *name)
+{
+	int strs, i;
+
+	strs = strlen(name);
+	/* string need to be at minimum len(x-supply) */
+	if (strs < 8)
+		return 0;
+	for (i = strs - 6; i > 0; i--) {
+		/* find first '-' and check if right part is supply */
+		if (name[i] != '-')
+			continue;
+		if (strcmp(name + i + 1, "supply") != 0)
+			return 0;
+		return i;
+	}
+	return 0;
+}
+
+/*
+ * regulator_bulk_get_all - get multiple regulator consumers
+ *
+ * @dev:	Device to supply
+ * @np:		device node to search for consumers
+ * @consumers:  Configuration of consumers; clients are stored here.
+ *
+ * @return number of regulators on success, an errno on failure.
+ *
+ * This helper function allows drivers to get several regulator
+ * consumers in one operation.  If any of the regulators cannot be
+ * acquired then any regulators that were allocated will be freed
+ * before returning to the caller.
+ */
+int regulator_bulk_get_all(struct device *dev, struct device_node *np,
+			   struct regulator_bulk_data **consumers)
+{
+	int num_consumers = 0;
+	struct regulator *tmp;
+	struct property *prop;
+	int i, n = 0, ret;
+	char name[64];
+
+	*consumers = NULL;
+
+/*
+ * first pass: get numbers of xxx-supply
+ * second pass: fill consumers
+ * */
+restart:
+	for_each_property_of_node(np, prop) {
+		i = is_supply_name(prop->name);
+		if (i == 0)
+			continue;
+		if (!*consumers) {
+			num_consumers++;
+			continue;
+		} else {
+			memcpy(name, prop->name, i);
+			name[i] = '\0';
+			tmp = regulator_get(dev, name);
+			if (!tmp) {
+				ret = -EINVAL;
+				goto error;
+			}
+			(*consumers)[n].consumer = tmp;
+			n++;
+			continue;
+		}
+	}
+	if (*consumers)
+		return num_consumers;
+	if (num_consumers == 0)
+		return 0;
+	*consumers = kmalloc_array(num_consumers,
+				   sizeof(struct regulator_bulk_data),
+				   GFP_KERNEL);
+	if (!*consumers)
+		return -ENOMEM;
+	goto restart;
+
+error:
+	while (--n >= 0)
+		regulator_put(consumers[n]->consumer);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_bulk_get_all);
+
 /**
  * regulator_bulk_enable - enable multiple regulator consumers
  *
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index bbf6590a6dec..b9b1d1cbdd07 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -238,6 +238,8 @@  int regulator_disable_deferred(struct regulator *regulator, int ms);
 
 int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
 				    struct regulator_bulk_data *consumers);
+int __must_check regulator_bulk_get_all(struct device *dev, struct device_node *np,
+					struct regulator_bulk_data **consumers);
 int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
 					 struct regulator_bulk_data *consumers);
 int __must_check regulator_bulk_enable(int num_consumers,