Hi John,

On 03-10-2019 01:16, John Stultz wrote:
From: Yu Chen <cheny...@huawei.com>

This patch adds notifier for drivers want to be informed of the usb role
switch.

I do not see any patches in this series actually using this new
notifier.

Maybe it is best to drop this patch until we actually have in-kernel
users of this new API show up ?

Regards,

Hans



Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Rob Herring <robh...@kernel.org>
Cc: Mark Rutland <mark.rutl...@arm.com>
Cc: Heikki Krogerus <heikki.kroge...@linux.intel.com>
Cc: Suzuki K Poulose <suzuki.poul...@arm.com>
Cc: Chunfeng Yun <chunfeng....@mediatek.com>
Cc: Yu Chen <cheny...@huawei.com>
Cc: Felipe Balbi <ba...@kernel.org>
Cc: Hans de Goede <hdego...@redhat.com>
Cc: Andy Shevchenko <andy.shevche...@gmail.com>
Cc: Jun Li <lijun.ker...@gmail.com>
Cc: Valentin Schneider <valentin.schnei...@arm.com>
Cc: linux-...@vger.kernel.org
Cc: devicet...@vger.kernel.org
Suggested-by: Heikki Krogerus <heikki.kroge...@linux.intel.com>
Signed-off-by: Yu Chen <cheny...@huawei.com>
Signed-off-by: John Stultz <john.stu...@linaro.org>
---
  drivers/usb/roles/class.c | 35 ++++++++++++++++++++++++++++++++++-
  include/linux/usb/role.h  | 16 ++++++++++++++++
  2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index 94b4e7db2b94..418e762d5d72 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -20,6 +20,7 @@ struct usb_role_switch {
        struct device dev;
        struct mutex lock; /* device lock*/
        enum usb_role role;
+       struct blocking_notifier_head nh;
/* From descriptor */
        struct device *usb2_port;
@@ -49,8 +50,10 @@ 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;
+               blocking_notifier_call_chain(&sw->nh, role, NULL);
+       }
mutex_unlock(&sw->lock); @@ -58,6 +61,35 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role)
  }
  EXPORT_SYMBOL_GPL(usb_role_switch_set_role);
+int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+                                     struct notifier_block *nb)
+{
+       int ret = blocking_notifier_chain_register(&sw->nh, nb);
+       enum usb_role role;
+
+       if (ret)
+               return ret;
+
+       /* Initialize the notifier that was just registered */
+       mutex_lock(&sw->lock);
+       if (sw->get)
+               role = sw->get(sw->dev.parent);
+       else
+               role = sw->role;
+       blocking_notifier_call_chain(&sw->nh, role, NULL);
+       mutex_unlock(&sw->lock);
+
+       return 0;
+}
+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->nh, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_unregister_notifier);
+
  /**
   * usb_role_switch_get_role - Get the USB role for a switch
   * @sw: USB role switch
@@ -296,6 +328,7 @@ usb_role_switch_register(struct device *parent,
                return ERR_PTR(-ENOMEM);
mutex_init(&sw->lock);
+       BLOCKING_INIT_NOTIFIER_HEAD(&sw->nh);
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 2d77f97df72d..8dbf7940b7da 100644
--- a/include/linux/usb/role.h
+++ b/include/linux/usb/role.h
@@ -54,6 +54,10 @@ struct usb_role_switch *
  usb_role_switch_register(struct device *parent,
                         const struct usb_role_switch_desc *desc);
  void usb_role_switch_unregister(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);
  #else
  static inline int usb_role_switch_set_role(struct usb_role_switch *sw,
                enum usb_role role)
@@ -87,6 +91,18 @@ usb_role_switch_register(struct device *parent,
  }
static inline void usb_role_switch_unregister(struct usb_role_switch *sw) { }
+
+static int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+                                            struct notifier_block *nb)
+{
+       return -ENODEV;
+}
+
+static int usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+                                              struct notifier_block *nb)
+{
+       return -ENODEV;
+}
  #endif
#endif /* __LINUX_USB_ROLE_H */


Reply via email to