diff mbox series

[v2,2/3] usb: roles: Add API to register notifiers

Message ID 20191211155032.167032-2-paul@crapouillou.net (mailing list archive)
State New, archived
Headers show
Series [v2,1/3] dt-bindings: power/supply: Document generic USB charger | expand

Commit Message

Paul Cercueil Dec. 11, 2019, 3:50 p.m. UTC
Add usb_role_switch_notifier_register() and
usb_role_switch_notifier_unregister().

The registered notifiers will be called when the USB role is changed.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---

Notes:
    v2: New patch

 drivers/usb/roles/class.c | 24 +++++++++++++++++++++++-
 include/linux/usb/role.h  | 20 ++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index 8273126ffdf4..9b122b504b98 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -10,6 +10,7 @@ 
 #include <linux/usb/role.h>
 #include <linux/property.h>
 #include <linux/device.h>
+#include <linux/notifier.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -19,6 +20,7 @@  static struct class *role_class;
 struct usb_role_switch {
 	struct device dev;
 	struct mutex lock; /* device lock*/
+	struct blocking_notifier_head notifier_chain;
 	enum usb_role role;
 
 	/* From descriptor */
@@ -49,8 +51,11 @@  int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role)
 	mutex_lock(&sw->lock);
 
 	ret = sw->set(sw->dev.parent, role);
-	if (!ret)
+	if (!ret) {
 		sw->role = role;
+		ret = blocking_notifier_call_chain(&sw->notifier_chain,
+						   (long)role, sw);
+	}
 
 	mutex_unlock(&sw->lock);
 
@@ -85,6 +90,22 @@  enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
 
+int
+usb_role_switch_register_notifier(struct usb_role_switch *sw,
+				  struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&sw->notifier_chain, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_register_notifier);
+
+int
+usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+				    struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&sw->notifier_chain, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_unregister_notifier);
+
 static void *usb_role_switch_match(struct device_connection *con, int ep,
 				   void *data)
 {
@@ -317,6 +338,7 @@  usb_role_switch_register(struct device *parent,
 		return ERR_PTR(-ENOMEM);
 
 	mutex_init(&sw->lock);
+	BLOCKING_INIT_NOTIFIER_HEAD(&sw->notifier_chain);
 
 	sw->allow_userspace_control = desc->allow_userspace_control;
 	sw->usb2_port = desc->usb2_port;
diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h
index efac3af83d6b..5f67d42cd28d 100644
--- a/include/linux/usb/role.h
+++ b/include/linux/usb/role.h
@@ -6,6 +6,7 @@ 
 #include <linux/device.h>
 
 struct usb_role_switch;
+struct notifier_block;
 
 enum usb_role {
 	USB_ROLE_NONE,
@@ -50,6 +51,11 @@  struct usb_role_switch *usb_role_switch_get(struct device *dev);
 struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *node);
 void usb_role_switch_put(struct usb_role_switch *sw);
 
+int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+				      struct notifier_block *nb);
+int usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+					struct notifier_block *nb);
+
 struct usb_role_switch *
 usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode);
 
@@ -82,6 +88,20 @@  fwnode_usb_role_switch_get(struct fwnode_handle *node)
 
 static inline void usb_role_switch_put(struct usb_role_switch *sw) { }
 
+static inline int
+usb_role_switch_register_notifier(struct usb_role_switch *sw,
+				  struct notifier_block *nb)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline int
+usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+				    struct notifier_block *nb)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline struct usb_role_switch *
 usb_role_switch_register(struct device *parent,
 			 const struct usb_role_switch_desc *desc)