phy: core: add notify_connect and notify_disconnect callback
authorStanley Chang <stanley_chang@realtek.com>
Wed, 13 Dec 2023 03:10:06 +0000 (11:10 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 28 Jan 2024 01:36:14 +0000 (17:36 -0800)
In Realtek SoC, the parameter of usb phy is designed to be able to
do dynamic tuning based in the port status. Therefore, add a notify
callback of phy driver when usb connection/disconnection change.

Signed-off-by: Stanley Chang <stanley_chang@realtek.com>
Link: https://lore.kernel.org/r/20231213031203.4911-1-stanley_chang@realtek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/phy/phy-core.c
include/linux/phy/phy.h

index d9be6a4..2e8b07e 100644 (file)
@@ -489,6 +489,53 @@ int phy_calibrate(struct phy *phy)
 }
 EXPORT_SYMBOL_GPL(phy_calibrate);
 
+/**
+ * phy_notify_connect() - phy connect notification
+ * @phy: the phy returned by phy_get()
+ * @port: the port index for connect
+ *
+ * If the phy needs to get connection status, the callback can be used.
+ * Returns: %0 if successful, a negative error code otherwise
+ */
+int phy_notify_connect(struct phy *phy, int port)
+{
+       int ret;
+
+       if (!phy || !phy->ops->connect)
+               return 0;
+
+       mutex_lock(&phy->mutex);
+       ret = phy->ops->connect(phy, port);
+       mutex_unlock(&phy->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_notify_connect);
+
+/**
+ * phy_notify_disconnect() - phy disconnect notification
+ * @phy: the phy returned by phy_get()
+ * @port: the port index for disconnect
+ *
+ * If the phy needs to get connection status, the callback can be used.
+ *
+ * Returns: %0 if successful, a negative error code otherwise
+ */
+int phy_notify_disconnect(struct phy *phy, int port)
+{
+       int ret;
+
+       if (!phy || !phy->ops->disconnect)
+               return 0;
+
+       mutex_lock(&phy->mutex);
+       ret = phy->ops->disconnect(phy, port);
+       mutex_unlock(&phy->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_notify_disconnect);
+
 /**
  * phy_configure() - Changes the phy parameters
  * @phy: the phy returned by phy_get()
index f6d607e..aa76609 100644 (file)
@@ -122,6 +122,11 @@ struct phy_ops {
                            union phy_configure_opts *opts);
        int     (*reset)(struct phy *phy);
        int     (*calibrate)(struct phy *phy);
+
+       /* notify phy connect status change */
+       int     (*connect)(struct phy *phy, int port);
+       int     (*disconnect)(struct phy *phy, int port);
+
        void    (*release)(struct phy *phy);
        struct module *owner;
 };
@@ -243,6 +248,8 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
 }
 int phy_reset(struct phy *phy);
 int phy_calibrate(struct phy *phy);
+int phy_notify_connect(struct phy *phy, int port);
+int phy_notify_disconnect(struct phy *phy, int port);
 static inline int phy_get_bus_width(struct phy *phy)
 {
        return phy->attrs.bus_width;
@@ -396,6 +403,20 @@ static inline int phy_calibrate(struct phy *phy)
        return -ENOSYS;
 }
 
+static inline int phy_notify_connect(struct phy *phy, int index)
+{
+       if (!phy)
+               return 0;
+       return -ENOSYS;
+}
+
+static inline int phy_notify_disconnect(struct phy *phy, int index)
+{
+       if (!phy)
+               return 0;
+       return -ENOSYS;
+}
+
 static inline int phy_configure(struct phy *phy,
                                union phy_configure_opts *opts)
 {