thermal/core: cooling device duplicate creation check

Message ID 20221026120321.735-1-huangqibo.tech@gmail.com
State New
Headers
Series thermal/core: cooling device duplicate creation check |

Commit Message

Qibo Huang Oct. 26, 2022, 12:03 p.m. UTC
  From: huangqibo <huangqibo@xiaomi.com>

Because creating a cooling device may have duplicate names.
When creating, first check thermal_cdev_list whether
there is a device with the same name. If it has the same name,
it returns a reference to the cooling device.

Signed-off-by: huangqibo <huangqibo@xiaomi.com>
---
 drivers/thermal/thermal_core.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
  

Comments

kernel test robot Oct. 26, 2022, 3:58 p.m. UTC | #1
Hi Qibo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on rafael-pm/thermal]
[also build test WARNING on linus/master v6.1-rc2 next-20221026]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
patch link:    https://lore.kernel.org/r/20221026120321.735-1-huangqibo.tech%40gmail.com
patch subject: [PATCH] thermal/core: cooling device duplicate creation check
config: m68k-allyesconfig
compiler: m68k-linux-gcc (GCC) 12.1.0
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/b9ffa61b51bd8fb000c57f602e94908c46345283
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
        git checkout b9ffa61b51bd8fb000c57f602e94908c46345283
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/

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

All warnings (new ones prefixed by >>):

   drivers/thermal/thermal_core.c: In function '__thermal_cooling_device_register':
   drivers/thermal/thermal_core.c:877:24: error: implicit declaration of function 'thermal_cdev_get_zone_by_name'; did you mean 'thermal_zone_get_zone_by_name'? [-Werror=implicit-function-declaration]
     877 |                 cdev = thermal_cdev_get_zone_by_name(type);
         |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                        thermal_zone_get_zone_by_name
>> drivers/thermal/thermal_core.c:877:22: warning: assignment to 'struct thermal_cooling_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     877 |                 cdev = thermal_cdev_get_zone_by_name(type);
         |                      ^
   drivers/thermal/thermal_core.c: At top level:
>> drivers/thermal/thermal_core.c:1444:32: warning: no previous prototype for 'thermal_cdev_get_zone_by_name' [-Wmissing-prototypes]
    1444 | struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
         |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/thermal/thermal_core.c:1444:32: error: conflicting types for 'thermal_cdev_get_zone_by_name'; have 'struct thermal_cooling_device *(const char *)'
   drivers/thermal/thermal_core.c:877:24: note: previous implicit declaration of 'thermal_cdev_get_zone_by_name' with type 'int()'
     877 |                 cdev = thermal_cdev_get_zone_by_name(type);
         |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +877 drivers/thermal/thermal_core.c

   846	
   847	/**
   848	 * __thermal_cooling_device_register() - register a new thermal cooling device
   849	 * @np:		a pointer to a device tree node.
   850	 * @type:	the thermal cooling device type.
   851	 * @devdata:	device private data.
   852	 * @ops:		standard thermal cooling devices callbacks.
   853	 *
   854	 * This interface function adds a new thermal cooling device (fan/processor/...)
   855	 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
   856	 * to all the thermal zone devices registered at the same time.
   857	 * It also gives the opportunity to link the cooling device to a device tree
   858	 * node, so that it can be bound to a thermal zone created out of device tree.
   859	 *
   860	 * Return: a pointer to the created struct thermal_cooling_device or an
   861	 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
   862	 */
   863	static struct thermal_cooling_device *
   864	__thermal_cooling_device_register(struct device_node *np,
   865					  const char *type, void *devdata,
   866					  const struct thermal_cooling_device_ops *ops)
   867	{
   868		struct thermal_cooling_device *cdev;
   869		struct thermal_zone_device *pos = NULL;
   870		int id, ret;
   871	
   872		if (!ops || !ops->get_max_state || !ops->get_cur_state ||
   873		    !ops->set_cur_state)
   874			return ERR_PTR(-EINVAL);
   875	
   876		if (type)
 > 877			cdev = thermal_cdev_get_zone_by_name(type);
   878	
   879		if (!IS_ERR_OR_NULL(cdev))
   880			return cdev;
   881	
   882		cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
   883		if (!cdev)
   884			return ERR_PTR(-ENOMEM);
   885	
   886		ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
   887		if (ret < 0)
   888			goto out_kfree_cdev;
   889		cdev->id = ret;
   890		id = ret;
   891	
   892		ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
   893		if (ret)
   894			goto out_ida_remove;
   895	
   896		cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
   897		if (!cdev->type) {
   898			ret = -ENOMEM;
   899			goto out_ida_remove;
   900		}
   901	
   902		mutex_init(&cdev->lock);
   903		INIT_LIST_HEAD(&cdev->thermal_instances);
   904		cdev->np = np;
   905		cdev->ops = ops;
   906		cdev->updated = false;
   907		cdev->device.class = &thermal_class;
   908		cdev->devdata = devdata;
   909		thermal_cooling_device_setup_sysfs(cdev);
   910		ret = device_register(&cdev->device);
   911		if (ret)
   912			goto out_kfree_type;
   913	
   914		/* Add 'this' new cdev to the global cdev list */
   915		mutex_lock(&thermal_list_lock);
   916		list_add(&cdev->node, &thermal_cdev_list);
   917		mutex_unlock(&thermal_list_lock);
   918	
   919		/* Update binding information for 'this' new cdev */
   920		bind_cdev(cdev);
   921	
   922		mutex_lock(&thermal_list_lock);
   923		list_for_each_entry(pos, &thermal_tz_list, node)
   924			if (atomic_cmpxchg(&pos->need_update, 1, 0))
   925				thermal_zone_device_update(pos,
   926							   THERMAL_EVENT_UNSPECIFIED);
   927		mutex_unlock(&thermal_list_lock);
   928	
   929		return cdev;
   930	
   931	out_kfree_type:
   932		thermal_cooling_device_destroy_sysfs(cdev);
   933		kfree(cdev->type);
   934		put_device(&cdev->device);
   935		cdev = NULL;
   936	out_ida_remove:
   937		ida_free(&thermal_cdev_ida, id);
   938	out_kfree_cdev:
   939		kfree(cdev);
   940		return ERR_PTR(ret);
   941	}
   942
  
kernel test robot Oct. 26, 2022, 7:10 p.m. UTC | #2
Hi Qibo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on rafael-pm/thermal]
[also build test WARNING on linus/master v6.1-rc2 next-20221026]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
patch link:    https://lore.kernel.org/r/20221026120321.735-1-huangqibo.tech%40gmail.com
patch subject: [PATCH] thermal/core: cooling device duplicate creation check
config: i386-randconfig-a013
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
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/b9ffa61b51bd8fb000c57f602e94908c46345283
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
        git checkout b9ffa61b51bd8fb000c57f602e94908c46345283
        # 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 drivers/thermal/

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

All warnings (new ones prefixed by >>):

   drivers/thermal/thermal_core.c:877:10: error: implicit declaration of function 'thermal_cdev_get_zone_by_name' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                   cdev = thermal_cdev_get_zone_by_name(type);
                          ^
   drivers/thermal/thermal_core.c:877:10: note: did you mean 'thermal_zone_get_zone_by_name'?
   include/linux/thermal.h:368:29: note: 'thermal_zone_get_zone_by_name' declared here
   struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
                               ^
>> drivers/thermal/thermal_core.c:877:8: warning: incompatible integer to pointer conversion assigning to 'struct thermal_cooling_device *' from 'int' [-Wint-conversion]
                   cdev = thermal_cdev_get_zone_by_name(type);
                        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/thermal/thermal_core.c:1444:32: error: conflicting types for 'thermal_cdev_get_zone_by_name'
   struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
                                  ^
   drivers/thermal/thermal_core.c:877:10: note: previous implicit declaration is here
                   cdev = thermal_cdev_get_zone_by_name(type);
                          ^
   1 warning and 2 errors generated.


vim +877 drivers/thermal/thermal_core.c

   846	
   847	/**
   848	 * __thermal_cooling_device_register() - register a new thermal cooling device
   849	 * @np:		a pointer to a device tree node.
   850	 * @type:	the thermal cooling device type.
   851	 * @devdata:	device private data.
   852	 * @ops:		standard thermal cooling devices callbacks.
   853	 *
   854	 * This interface function adds a new thermal cooling device (fan/processor/...)
   855	 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
   856	 * to all the thermal zone devices registered at the same time.
   857	 * It also gives the opportunity to link the cooling device to a device tree
   858	 * node, so that it can be bound to a thermal zone created out of device tree.
   859	 *
   860	 * Return: a pointer to the created struct thermal_cooling_device or an
   861	 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
   862	 */
   863	static struct thermal_cooling_device *
   864	__thermal_cooling_device_register(struct device_node *np,
   865					  const char *type, void *devdata,
   866					  const struct thermal_cooling_device_ops *ops)
   867	{
   868		struct thermal_cooling_device *cdev;
   869		struct thermal_zone_device *pos = NULL;
   870		int id, ret;
   871	
   872		if (!ops || !ops->get_max_state || !ops->get_cur_state ||
   873		    !ops->set_cur_state)
   874			return ERR_PTR(-EINVAL);
   875	
   876		if (type)
 > 877			cdev = thermal_cdev_get_zone_by_name(type);
   878	
   879		if (!IS_ERR_OR_NULL(cdev))
   880			return cdev;
   881	
   882		cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
   883		if (!cdev)
   884			return ERR_PTR(-ENOMEM);
   885	
   886		ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
   887		if (ret < 0)
   888			goto out_kfree_cdev;
   889		cdev->id = ret;
   890		id = ret;
   891	
   892		ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
   893		if (ret)
   894			goto out_ida_remove;
   895	
   896		cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
   897		if (!cdev->type) {
   898			ret = -ENOMEM;
   899			goto out_ida_remove;
   900		}
   901	
   902		mutex_init(&cdev->lock);
   903		INIT_LIST_HEAD(&cdev->thermal_instances);
   904		cdev->np = np;
   905		cdev->ops = ops;
   906		cdev->updated = false;
   907		cdev->device.class = &thermal_class;
   908		cdev->devdata = devdata;
   909		thermal_cooling_device_setup_sysfs(cdev);
   910		ret = device_register(&cdev->device);
   911		if (ret)
   912			goto out_kfree_type;
   913	
   914		/* Add 'this' new cdev to the global cdev list */
   915		mutex_lock(&thermal_list_lock);
   916		list_add(&cdev->node, &thermal_cdev_list);
   917		mutex_unlock(&thermal_list_lock);
   918	
   919		/* Update binding information for 'this' new cdev */
   920		bind_cdev(cdev);
   921	
   922		mutex_lock(&thermal_list_lock);
   923		list_for_each_entry(pos, &thermal_tz_list, node)
   924			if (atomic_cmpxchg(&pos->need_update, 1, 0))
   925				thermal_zone_device_update(pos,
   926							   THERMAL_EVENT_UNSPECIFIED);
   927		mutex_unlock(&thermal_list_lock);
   928	
   929		return cdev;
   930	
   931	out_kfree_type:
   932		thermal_cooling_device_destroy_sysfs(cdev);
   933		kfree(cdev->type);
   934		put_device(&cdev->device);
   935		cdev = NULL;
   936	out_ida_remove:
   937		ida_free(&thermal_cdev_ida, id);
   938	out_kfree_cdev:
   939		kfree(cdev);
   940		return ERR_PTR(ret);
   941	}
   942
  
kernel test robot Oct. 26, 2022, 9:32 p.m. UTC | #3
Hi Qibo,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on rafael-pm/thermal]
[also build test ERROR on linus/master v6.1-rc2 next-20221026]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
patch link:    https://lore.kernel.org/r/20221026120321.735-1-huangqibo.tech%40gmail.com
patch subject: [PATCH] thermal/core: cooling device duplicate creation check
config: mips-randconfig-r021-20221026
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 791a7ae1ba3efd6bca96338e10ffde557ba83920)
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
        # install mips cross compiling tool for clang build
        # apt-get install binutils-mips64el-linux-gnuabi64
        # https://github.com/intel-lab-lkp/linux/commit/b9ffa61b51bd8fb000c57f602e94908c46345283
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
        git checkout b9ffa61b51bd8fb000c57f602e94908c46345283
        # 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=mips 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/thermal/thermal_core.c:877:10: error: call to undeclared function 'thermal_cdev_get_zone_by_name'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                   cdev = thermal_cdev_get_zone_by_name(type);
                          ^
   drivers/thermal/thermal_core.c:877:10: note: did you mean 'thermal_zone_get_zone_by_name'?
   include/linux/thermal.h:368:29: note: 'thermal_zone_get_zone_by_name' declared here
   struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
                               ^
>> drivers/thermal/thermal_core.c:877:8: error: incompatible integer to pointer conversion assigning to 'struct thermal_cooling_device *' from 'int' [-Wint-conversion]
                   cdev = thermal_cdev_get_zone_by_name(type);
                        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/thermal/thermal_core.c:1444:32: error: conflicting types for 'thermal_cdev_get_zone_by_name'
   struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
                                  ^
   drivers/thermal/thermal_core.c:877:10: note: previous implicit declaration is here
                   cdev = thermal_cdev_get_zone_by_name(type);
                          ^
   3 errors generated.


vim +/thermal_cdev_get_zone_by_name +877 drivers/thermal/thermal_core.c

   846	
   847	/**
   848	 * __thermal_cooling_device_register() - register a new thermal cooling device
   849	 * @np:		a pointer to a device tree node.
   850	 * @type:	the thermal cooling device type.
   851	 * @devdata:	device private data.
   852	 * @ops:		standard thermal cooling devices callbacks.
   853	 *
   854	 * This interface function adds a new thermal cooling device (fan/processor/...)
   855	 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
   856	 * to all the thermal zone devices registered at the same time.
   857	 * It also gives the opportunity to link the cooling device to a device tree
   858	 * node, so that it can be bound to a thermal zone created out of device tree.
   859	 *
   860	 * Return: a pointer to the created struct thermal_cooling_device or an
   861	 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
   862	 */
   863	static struct thermal_cooling_device *
   864	__thermal_cooling_device_register(struct device_node *np,
   865					  const char *type, void *devdata,
   866					  const struct thermal_cooling_device_ops *ops)
   867	{
   868		struct thermal_cooling_device *cdev;
   869		struct thermal_zone_device *pos = NULL;
   870		int id, ret;
   871	
   872		if (!ops || !ops->get_max_state || !ops->get_cur_state ||
   873		    !ops->set_cur_state)
   874			return ERR_PTR(-EINVAL);
   875	
   876		if (type)
 > 877			cdev = thermal_cdev_get_zone_by_name(type);
   878	
   879		if (!IS_ERR_OR_NULL(cdev))
   880			return cdev;
   881	
   882		cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
   883		if (!cdev)
   884			return ERR_PTR(-ENOMEM);
   885	
   886		ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
   887		if (ret < 0)
   888			goto out_kfree_cdev;
   889		cdev->id = ret;
   890		id = ret;
   891	
   892		ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
   893		if (ret)
   894			goto out_ida_remove;
   895	
   896		cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
   897		if (!cdev->type) {
   898			ret = -ENOMEM;
   899			goto out_ida_remove;
   900		}
   901	
   902		mutex_init(&cdev->lock);
   903		INIT_LIST_HEAD(&cdev->thermal_instances);
   904		cdev->np = np;
   905		cdev->ops = ops;
   906		cdev->updated = false;
   907		cdev->device.class = &thermal_class;
   908		cdev->devdata = devdata;
   909		thermal_cooling_device_setup_sysfs(cdev);
   910		ret = device_register(&cdev->device);
   911		if (ret)
   912			goto out_kfree_type;
   913	
   914		/* Add 'this' new cdev to the global cdev list */
   915		mutex_lock(&thermal_list_lock);
   916		list_add(&cdev->node, &thermal_cdev_list);
   917		mutex_unlock(&thermal_list_lock);
   918	
   919		/* Update binding information for 'this' new cdev */
   920		bind_cdev(cdev);
   921	
   922		mutex_lock(&thermal_list_lock);
   923		list_for_each_entry(pos, &thermal_tz_list, node)
   924			if (atomic_cmpxchg(&pos->need_update, 1, 0))
   925				thermal_zone_device_update(pos,
   926							   THERMAL_EVENT_UNSPECIFIED);
   927		mutex_unlock(&thermal_list_lock);
   928	
   929		return cdev;
   930	
   931	out_kfree_type:
   932		thermal_cooling_device_destroy_sysfs(cdev);
   933		kfree(cdev->type);
   934		put_device(&cdev->device);
   935		cdev = NULL;
   936	out_ida_remove:
   937		ida_free(&thermal_cdev_ida, id);
   938	out_kfree_cdev:
   939		kfree(cdev);
   940		return ERR_PTR(ret);
   941	}
   942
  

Patch

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 117eeaf7dd24..092c7732a294 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -873,6 +873,12 @@  __thermal_cooling_device_register(struct device_node *np,
 	    !ops->set_cur_state)
 		return ERR_PTR(-EINVAL);
 
+	if (type)
+		cdev = thermal_cdev_get_zone_by_name(type);
+
+	if (!IS_ERR_OR_NULL(cdev))
+		return cdev;
+
 	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
 	if (!cdev)
 		return ERR_PTR(-ENOMEM);
@@ -1435,6 +1441,34 @@  struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name)
 }
 EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
 
+struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
+{
+	struct thermal_cooling_device *pos = NULL, *ref = ERR_PTR(-EINVAL);
+	unsigned int found = 0;
+
+	if (!name)
+		goto exit;
+
+	mutex_lock(&thermal_list_lock);
+	list_for_each_entry(pos, &thermal_cdev_list, node)
+		if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) {
+			found++;
+			ref = pos;
+		}
+	mutex_unlock(&thermal_list_lock);
+
+	/* nothing has been found, thus an error code for it */
+	if (found == 0)
+		ref = ERR_PTR(-ENODEV);
+	else if (found > 1)
+	/* Success only when an unique zone is found */
+		ref = ERR_PTR(-EEXIST);
+
+exit:
+	return ref;
+}
+EXPORT_SYMBOL_GPL(thermal_cdev_get_zone_by_name);
+
 static int thermal_pm_notify(struct notifier_block *nb,
 			     unsigned long mode, void *_unused)
 {