Message ID | 20211124231028.696982-2-pmalani@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | usb: Use notifier for linking Type C ports. | expand |
On Wed, Nov 24, 2021 at 3:11 PM Prashant Malani <pmalani@chromium.org> wrote: > > Introduce a blocking notifier to be called when a new Type C port gets > registered with the connector class framework. > > Signed-off-by: Prashant Malani <pmalani@chromium.org> > --- > NOTE: typec_port_registration_register_notify() is a bit long, > so please let me know if you have any shorter suggestions for naming > this function. > > drivers/usb/typec/class.c | 30 ++++++++++++++++++++++++++++++ > include/linux/usb/typec.h | 13 +++++++++++++ > 2 files changed, 43 insertions(+) > > diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c > index aeef453aa658..14b82109b0f5 100644 > --- a/drivers/usb/typec/class.c > +++ b/drivers/usb/typec/class.c > @@ -16,6 +16,8 @@ > #include "bus.h" > #include "class.h" > > +static BLOCKING_NOTIFIER_HEAD(typec_port_registration_notifier); > + > static DEFINE_IDA(typec_index_ida); > > struct class typec_class = { > @@ -1979,6 +1981,32 @@ void typec_port_register_altmodes(struct typec_port *port, > } > EXPORT_SYMBOL_GPL(typec_port_register_altmodes); > > +/** > + * typec_port_registration_register_notify - Register a notifier for Type C port registration. > + * @nb: notifier block to signal > + * > + * This function allows callers to get a notification when a Type C port is registered with > + * the connector class. > + */ > +int typec_port_registration_register_notify(struct notifier_block *nb) > +{ > + return blocking_notifier_chain_register(&typec_port_registration_notifier, nb); > +} > +EXPORT_SYMBOL_GPL(typec_port_registration_register_notify); > + > +/** > + * typec_port_registration_unregister_notify - Unregister a notifier for Type C port registration. > + * @nb: notifier block to unregister > + * > + * This function allows callers to unregister notifiers which were previously registered using > + * typec_port_registration_register_notify(). > + */ > +int typec_port_registration_unregister_notify(struct notifier_block *nb) > +{ > + return blocking_notifier_chain_unregister(&typec_port_registration_notifier, nb); > +} > +EXPORT_SYMBOL_GPL(typec_port_registration_unregister_notify); > + > /** > * typec_register_port - Register a USB Type-C Port > * @parent: Parent device > @@ -2086,6 +2114,8 @@ struct typec_port *typec_register_port(struct device *parent, > if (ret) > dev_warn(&port->dev, "failed to create symlinks (%d)\n", ret); > > + blocking_notifier_call_chain(&typec_port_registration_notifier, 0, port); > + > return port; > } > EXPORT_SYMBOL_GPL(typec_register_port); > diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h > index e2e44bb1dad8..398317835f24 100644 > --- a/include/linux/usb/typec.h > +++ b/include/linux/usb/typec.h > @@ -3,6 +3,7 @@ > #ifndef __LINUX_USB_TYPEC_H > #define __LINUX_USB_TYPEC_H > > +#include <linux/notifier.h> > #include <linux/types.h> > > /* USB Type-C Specification releases */ > @@ -308,6 +309,8 @@ int typec_get_negotiated_svdm_version(struct typec_port *port); > #if IS_REACHABLE(CONFIG_TYPEC) > int typec_link_port(struct device *port); > void typec_unlink_port(struct device *port); > +int typec_port_registration_register_notify(struct notifier_block *nb); > +int typec_port_registration_unregister_notify(struct notifier_block *nb); > #else > static inline int typec_link_port(struct device *port) > { > @@ -315,6 +318,16 @@ static inline int typec_link_port(struct device *port) > } > > static inline void typec_unlink_port(struct device *port) { } > + > +int typec_port_registration_register_notify(struct notifier_block *nb) > +{ > + return 0; > +} > + > +int typec_port_registration_unregister_notify(struct notifier_block *nb) > +{ > + return 0; > +} > #endif Oops, looks like I forgot to static inline these.... Also, probably better to return -ENODEV for these calls? Sorry about that; I'll fix it up and send another version. Thanks,
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index aeef453aa658..14b82109b0f5 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -16,6 +16,8 @@ #include "bus.h" #include "class.h" +static BLOCKING_NOTIFIER_HEAD(typec_port_registration_notifier); + static DEFINE_IDA(typec_index_ida); struct class typec_class = { @@ -1979,6 +1981,32 @@ void typec_port_register_altmodes(struct typec_port *port, } EXPORT_SYMBOL_GPL(typec_port_register_altmodes); +/** + * typec_port_registration_register_notify - Register a notifier for Type C port registration. + * @nb: notifier block to signal + * + * This function allows callers to get a notification when a Type C port is registered with + * the connector class. + */ +int typec_port_registration_register_notify(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&typec_port_registration_notifier, nb); +} +EXPORT_SYMBOL_GPL(typec_port_registration_register_notify); + +/** + * typec_port_registration_unregister_notify - Unregister a notifier for Type C port registration. + * @nb: notifier block to unregister + * + * This function allows callers to unregister notifiers which were previously registered using + * typec_port_registration_register_notify(). + */ +int typec_port_registration_unregister_notify(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&typec_port_registration_notifier, nb); +} +EXPORT_SYMBOL_GPL(typec_port_registration_unregister_notify); + /** * typec_register_port - Register a USB Type-C Port * @parent: Parent device @@ -2086,6 +2114,8 @@ struct typec_port *typec_register_port(struct device *parent, if (ret) dev_warn(&port->dev, "failed to create symlinks (%d)\n", ret); + blocking_notifier_call_chain(&typec_port_registration_notifier, 0, port); + return port; } EXPORT_SYMBOL_GPL(typec_register_port); diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index e2e44bb1dad8..398317835f24 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -3,6 +3,7 @@ #ifndef __LINUX_USB_TYPEC_H #define __LINUX_USB_TYPEC_H +#include <linux/notifier.h> #include <linux/types.h> /* USB Type-C Specification releases */ @@ -308,6 +309,8 @@ int typec_get_negotiated_svdm_version(struct typec_port *port); #if IS_REACHABLE(CONFIG_TYPEC) int typec_link_port(struct device *port); void typec_unlink_port(struct device *port); +int typec_port_registration_register_notify(struct notifier_block *nb); +int typec_port_registration_unregister_notify(struct notifier_block *nb); #else static inline int typec_link_port(struct device *port) { @@ -315,6 +318,16 @@ static inline int typec_link_port(struct device *port) } static inline void typec_unlink_port(struct device *port) { } + +int typec_port_registration_register_notify(struct notifier_block *nb) +{ + return 0; +} + +int typec_port_registration_unregister_notify(struct notifier_block *nb) +{ + return 0; +} #endif #endif /* __LINUX_USB_TYPEC_H */
Introduce a blocking notifier to be called when a new Type C port gets registered with the connector class framework. Signed-off-by: Prashant Malani <pmalani@chromium.org> --- NOTE: typec_port_registration_register_notify() is a bit long, so please let me know if you have any shorter suggestions for naming this function. drivers/usb/typec/class.c | 30 ++++++++++++++++++++++++++++++ include/linux/usb/typec.h | 13 +++++++++++++ 2 files changed, 43 insertions(+)