static struct class_compat *switch_class;
 #endif /* CONFIG_ANDROID && !defined(CONFIG_ANDROID_SWITCH) */
 
+static LIST_HEAD(extcon_dev_list);
+static DEFINE_MUTEX(extcon_dev_list_lock);
+
 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
 {
  * the name of extcon device (envp[0]) and the state output (envp[1]).
  * Tizen uses this format for extcon device to get events from ports.
  * Android uses this format as well.
+ *
+ * Note that notifier provides the which bits are changes in the state
+ * variable with "val" to the callback.
  */
 void extcon_set_state(struct extcon_dev *edev, u32 state)
 {
        char *envp[3];
        int env_offset = 0;
        int length;
+       u32 old_state = edev->state;
 
        if (edev->state != state) {
                edev->state = state;
 
+               raw_notifier_call_chain(&edev->nh, old_state ^ edev->state,
+                                       edev);
+
                prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
                if (prop_buf) {
                        length = name_show(edev->dev, NULL, prop_buf);
 }
 EXPORT_SYMBOL_GPL(extcon_set_state);
 
+/**
+ * extcon_get_extcon_dev() - Get the extcon device instance from the name
+ * @extcon_name:       The extcon name provided with extcon_dev_register()
+ */
+struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
+{
+       struct extcon_dev *sd;
+
+       mutex_lock(&extcon_dev_list_lock);
+       list_for_each_entry(sd, &extcon_dev_list, entry) {
+               if (!strcmp(sd->name, extcon_name))
+                       goto out;
+       }
+       sd = NULL;
+out:
+       mutex_unlock(&extcon_dev_list_lock);
+       return sd;
+}
+EXPORT_SYMBOL_GPL(extcon_get_extcon_dev);
+
+/**
+ * extcon_register_notifier() - Register a notifee to get notified by
+ *                           any attach status changes from the extcon.
+ * @edev:      the extcon device.
+ * @nb:                a notifier block to be registered.
+ */
+int extcon_register_notifier(struct extcon_dev *edev,
+                       struct notifier_block *nb)
+{
+       return raw_notifier_chain_register(&edev->nh, nb);
+}
+EXPORT_SYMBOL_GPL(extcon_register_notifier);
+
+/**
+ * extcon_unregister_notifier() - Unregister a notifee from the extcon device.
+ * @edev:      the extcon device.
+ * @nb:                a registered notifier block to be unregistered.
+ */
+int extcon_unregister_notifier(struct extcon_dev *edev,
+                       struct notifier_block *nb)
+{
+       return raw_notifier_chain_unregister(&edev->nh, nb);
+}
+EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
+
 static struct device_attribute extcon_attrs[] = {
        __ATTR_RO(state),
        __ATTR_RO(name),
 
 static void extcon_cleanup(struct extcon_dev *edev, bool skip)
 {
+       mutex_lock(&extcon_dev_list_lock);
+       list_del(&edev->entry);
+       mutex_unlock(&extcon_dev_list_lock);
+
        if (!skip && get_device(edev->dev)) {
                device_unregister(edev->dev);
                put_device(edev->dev);
                                               dev);
 #endif /* CONFIG_ANDROID && !defined(CONFIG_ANDROID_SWITCH) */
 
+       RAW_INIT_NOTIFIER_HEAD(&edev->nh);
+
        dev_set_drvdata(edev->dev, edev);
        edev->state = 0;
+
+       mutex_lock(&extcon_dev_list_lock);
+       list_add(&edev->entry, &extcon_dev_list);
+       mutex_unlock(&extcon_dev_list_lock);
+
        return 0;
 
 err_dev:
 
 #ifndef __LINUX_EXTCON_H__
 #define __LINUX_EXTCON_H__
 
+#include <linux/notifier.h>
 /**
  * struct extcon_dev - An extcon device represents one external connector.
  * @name       The name of this extcon device. Parent device name is used
  * @dev                Device of this extcon. Do not provide at register-time.
  * @state      Attach/detach state of this extcon. Do not provide at
  *             register-time
+ * @nh Notifier for the state change events from this extcon
+ * @entry      To support list of extcon devices so that uses can search
+ *             for extcon devices based on the extcon name.
  *
  * In most cases, users only need to provide "User initializing data" of
  * this struct when registering an extcon. In some exceptional cases,
        /* --- Internal data. Please do not set. --- */
        struct device   *dev;
        u32             state;
+       struct raw_notifier_head nh;
+       struct list_head entry;
 };
 
 #if IS_ENABLED(CONFIG_EXTCON)
+
+/*
+ * Following APIs are for notifiers or configurations.
+ * Notifiers are the external port and connection devices.
+ */
 extern int extcon_dev_register(struct extcon_dev *edev, struct device *dev);
 extern void extcon_dev_unregister(struct extcon_dev *edev);
+extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
 
 static inline u32 extcon_get_state(struct extcon_dev *edev)
 {
 }
 
 extern void extcon_set_state(struct extcon_dev *edev, u32 state);
+
+/*
+ * Following APIs are to monitor every action of a notifier.
+ * Registerer gets notified for every external port of a connection device.
+ */
+extern int extcon_register_notifier(struct extcon_dev *edev,
+                                   struct notifier_block *nb);
+extern int extcon_unregister_notifier(struct extcon_dev *edev,
+                                     struct notifier_block *nb);
 #else /* CONFIG_EXTCON */
 static inline int extcon_dev_register(struct extcon_dev *edev,
                                      struct device *dev)
 }
 
 static inline void extcon_set_state(struct extcon_dev *edev, u32 state) { }
+static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
+{
+       return NULL;
+}
+
+static inline int extcon_register_notifier(struct extcon_dev *edev,
+                                          struct notifier_block *nb)
+{
+       return 0;
+}
+
+static inline int extcon_unregister_notifier(struct extcon_dev *edev,
+                                            struct notifier_block *nb)
+{
+       return 0;
+}
+
 #endif /* CONFIG_EXTCON */
 #endif /* __LINUX_EXTCON_H__ */