From: Chaoyi Chen <[email protected]> Add default DRM AUX HPD bridge device when register DisplayPort altmode. That makes it redundant for each Type-C driver to implement a similar registration process in embedded scenarios.
Signed-off-by: Chaoyi Chen <[email protected]> --- Changes in v6: - Fix depend in Kconfig. Changes in v5: - Remove the calls related to `drm_aux_hpd_bridge_notify()`. - Place the helper functions in the same compilation unit. - Add more comments about parent device. drivers/usb/typec/Kconfig | 2 ++ drivers/usb/typec/class.c | 26 ++++++++++++++++++++++++++ include/linux/usb/typec_altmode.h | 2 ++ 3 files changed, 30 insertions(+) diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index 2f80c2792dbd..a6730fbb576b 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -2,6 +2,8 @@ menuconfig TYPEC tristate "USB Type-C Support" + depends on DRM || DRM=n + select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE && OF help USB Type-C Specification defines a cable and connector for USB where only one type of plug is supported on both ends, i.e. there will not diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 67a533e35150..e9d7772d1a8f 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -8,14 +8,18 @@ #include <linux/module.h> #include <linux/mutex.h> +#include <linux/of.h> #include <linux/property.h> #include <linux/slab.h> #include <linux/string_choices.h> #include <linux/usb/pd_vdo.h> +#include <linux/usb/typec_dp.h> #include <linux/usb/typec_mux.h> #include <linux/usb/typec_retimer.h> #include <linux/usb.h> +#include <drm/bridge/aux-bridge.h> + #include "bus.h" #include "class.h" #include "pd.h" @@ -538,6 +542,21 @@ const struct device_type typec_altmode_dev_type = { .release = typec_altmode_release, }; +static void dp_altmode_hpd_device_register(struct typec_altmode *alt) +{ + if (alt->svid != USB_TYPEC_DP_SID) + return; + + /* + * alt->dev.parent->parent : USB-C controller device + * alt->dev.parent : USB-C connector device + */ + alt->hpd_dev = drm_dp_hpd_bridge_register(alt->dev.parent->parent, + to_of_node(alt->dev.parent->fwnode)); + if (IS_ERR(alt->hpd_dev)) + alt->hpd_dev = NULL; +} + static struct typec_altmode * typec_register_altmode(struct device *parent, const struct typec_altmode_desc *desc) @@ -600,6 +619,13 @@ typec_register_altmode(struct device *parent, return ERR_PTR(ret); } + /* + * It is too late to register the HPD device when the DisplayPort + * altmode device becomes ready. If the current altmode is DP, + * register a static HPD device. + */ + dp_altmode_hpd_device_register(&alt->adev); + return &alt->adev; } diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h index b3c0866ea70f..acb0af1b9d5d 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -21,6 +21,7 @@ struct typec_altmode_ops; * @desc: Optional human readable description of the mode * @ops: Operations vector from the driver * @cable_ops: Cable operations vector from the driver. + * @hpd_dev: HPD device for DisplayPort */ struct typec_altmode { struct device dev; @@ -32,6 +33,7 @@ struct typec_altmode { char *desc; const struct typec_altmode_ops *ops; const struct typec_cable_ops *cable_ops; + struct device *hpd_dev; }; #define to_typec_altmode(d) container_of(d, struct typec_altmode, dev) -- 2.49.0
