Simplify driver error paths by adding devm_typec_switch_register() which will unregister the typec switch when the parent device is unbound. Cc: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: <linux-usb@xxxxxxxxxxxxxxx> Cc: Pin-yen Lin <treapking@xxxxxxxxxxxx> Signed-off-by: Stephen Boyd <swboyd@xxxxxxxxxxxx> --- drivers/usb/typec/mux.c | 27 +++++++++++++++++++++++++++ include/linux/usb/typec_mux.h | 9 +++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 65c60eb56428..3531ab03bac4 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -235,6 +235,33 @@ void typec_switch_unregister(struct typec_switch_dev *sw_dev) } EXPORT_SYMBOL_GPL(typec_switch_unregister); +static void devm_typec_switch_unregister(struct device *dev, void *switch_dev) +{ + typec_switch_unregister(*(struct typec_switch_dev **)switch_dev); +} + +struct typec_switch_dev * +devm_typec_switch_register(struct device *parent, + const struct typec_switch_desc *desc) +{ + struct typec_switch_dev **ptr, *switch_dev; + + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + switch_dev = typec_switch_register(parent ,desc); + if (!IS_ERR(switch_dev)) { + *ptr = switch_dev; + devres_add(parent, ptr); + } else { + devres_free(ptr); + } + + return switch_dev; +} +EXPORT_SYMBOL_GPL(devm_typec_switch_register); + void typec_switch_set_drvdata(struct typec_switch_dev *sw_dev, void *data) { dev_set_drvdata(&sw_dev->dev, data); diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index c6f49756530d..fe7a05dd71c8 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -34,6 +34,9 @@ int typec_switch_set(struct typec_switch *sw, struct typec_switch_dev * typec_switch_register(struct device *parent, const struct typec_switch_desc *desc); +struct typec_switch_dev * +devm_typec_switch_register(struct device *parent, + const struct typec_switch_desc *desc); void typec_switch_unregister(struct typec_switch_dev *sw); void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data); @@ -59,6 +62,12 @@ typec_switch_register(struct device *parent, { return ERR_PTR(-EOPNOTSUPP); } +static inline struct typec_switch_dev * +devm_typec_switch_register(struct device *parent, + const struct typec_switch_desc *desc) +{ + return typec_switch_register(parent, desc); +} static inline void typec_switch_unregister(struct typec_switch_dev *sw) {} static inline void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data) {} -- https://chromeos.dev