From: Andrzej Hajda <a.hajda@samsung.com>
Date: Tue, 27 Feb 2018 13:22:07 +0100
Subject: extcon: add possibility to get extcon device by OF node
Git-commit: 370ed7a9b9176d68c7b13e6cef32efa6ac5b2d97
Patch-mainline: v4.17-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166
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>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
drivers/extcon/extcon.c | 44 ++++++++++++++++++++++++++++++++++----------
include/linux/extcon.h | 6 ++++++
2 files changed, 40 insertions(+), 10 deletions(-)
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -1342,6 +1342,28 @@ void extcon_dev_unregister(struct extcon
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 - instance to the given device
@@ -1369,25 +1391,27 @@ struct extcon_dev *extcon_get_edev_by_ph
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);
/**
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -187,6 +187,7 @@ extern int devm_extcon_dev_register(stru
extern void devm_extcon_dev_unregister(struct device *dev,
struct extcon_dev *edev);
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);
/*
* Following APIs control the memory of extcon device.
@@ -367,6 +368,11 @@ static inline struct extcon_dev *extcon_
return NULL;
}
+static inline struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
+{
+ return ERR_PTR(-ENODEV);
+}
+
static inline int extcon_register_notifier(struct extcon_dev *edev,
unsigned int id,
struct notifier_block *nb)