OSDN Git Service

extcon: add possibility to get extcon device by OF node
authorAndrzej Hajda <a.hajda@samsung.com>
Tue, 27 Feb 2018 12:22:07 +0000 (13:22 +0100)
committerChanwoo Choi <cw00.choi@samsung.com>
Thu, 8 Mar 2018 01:34:44 +0000 (10:34 +0900)
Since extcon property is not allowed in DT, extcon subsystem requires
another way to get extcon device. Lets try the simplest approach - get
edev by of_node.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
drivers/extcon/extcon.c
include/linux/extcon.h

index cb38c27..8bff5fd 100644 (file)
@@ -1336,6 +1336,28 @@ void extcon_dev_unregister(struct extcon_dev *edev)
 EXPORT_SYMBOL_GPL(extcon_dev_unregister);
 
 #ifdef CONFIG_OF
+
+/*
+ * extcon_find_edev_by_node - Find the extcon device from devicetree.
+ * @node       : OF node identifying edev
+ *
+ * Return the pointer of extcon device if success or ERR_PTR(err) if fail.
+ */
+struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
+{
+       struct extcon_dev *edev;
+
+       mutex_lock(&extcon_dev_list_lock);
+       list_for_each_entry(edev, &extcon_dev_list, entry)
+               if (edev->dev.parent && edev->dev.parent->of_node == node)
+                       goto out;
+       edev = ERR_PTR(-EPROBE_DEFER);
+out:
+       mutex_unlock(&extcon_dev_list_lock);
+
+       return edev;
+}
+
 /*
  * extcon_get_edev_by_phandle - Get the extcon device from devicetree.
  * @dev                : the instance to the given device
@@ -1363,25 +1385,27 @@ struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)
                return ERR_PTR(-ENODEV);
        }
 
-       mutex_lock(&extcon_dev_list_lock);
-       list_for_each_entry(edev, &extcon_dev_list, entry) {
-               if (edev->dev.parent && edev->dev.parent->of_node == node) {
-                       mutex_unlock(&extcon_dev_list_lock);
-                       of_node_put(node);
-                       return edev;
-               }
-       }
-       mutex_unlock(&extcon_dev_list_lock);
+       edev = extcon_find_edev_by_node(node);
        of_node_put(node);
 
-       return ERR_PTR(-EPROBE_DEFER);
+       return edev;
 }
+
 #else
+
+struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
 struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)
 {
        return ERR_PTR(-ENOSYS);
 }
+
 #endif /* CONFIG_OF */
+
+EXPORT_SYMBOL_GPL(extcon_find_edev_by_node);
 EXPORT_SYMBOL_GPL(extcon_get_edev_by_phandle);
 
 /**
index 6d94e82..7f033b1 100644 (file)
@@ -230,6 +230,7 @@ extern void devm_extcon_unregister_notifier_all(struct device *dev,
  * Following APIs get the extcon_dev from devicetree or by through extcon name.
  */
 extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
+extern struct extcon_dev *extcon_find_edev_by_node(struct device_node *node);
 extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
                                                     int index);
 
@@ -283,6 +284,11 @@ static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
        return ERR_PTR(-ENODEV);
 }
 
+static inline struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
                                int index)
 {