From patchwork Tue Nov 7 06:33:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?U3RhbmxleSBDaGFuZ1vmmIzogrLlvrdd?= X-Patchwork-Id: 13447945 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7520617F0 for ; Tue, 7 Nov 2023 06:37:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=none Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 766B2119; Mon, 6 Nov 2023 22:37:27 -0800 (PST) X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 3A76ZJYm84026363, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/2.95/5.92) with ESMTPS id 3A76ZJYm84026363 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Nov 2023 14:35:19 +0800 Received: from RTEXMBS01.realtek.com.tw (172.21.6.94) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Tue, 7 Nov 2023 14:35:19 +0800 Received: from RTEXH36505.realtek.com.tw (172.21.6.25) by RTEXMBS01.realtek.com.tw (172.21.6.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Tue, 7 Nov 2023 14:35:19 +0800 Received: from localhost.localdomain (172.21.252.101) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server id 15.1.2375.32 via Frontend Transport; Tue, 7 Nov 2023 14:35:19 +0800 From: Stanley Chang To: Greg Kroah-Hartman CC: Stanley Chang , Vinod Koul , Johan Hovold , Kishon Vijay Abraham I , Rob Herring , Jinjie Ruan , "Alan Stern" , Yang Yingliang , =?utf-8?q?Ricardo_Ca=C3=B1uelo?= , Roy Luo , Heikki Krogerus , Ray Chi , , , Subject: [PATCH v1 1/4] phy: core: add notify_connect and notify_disconnect callback Date: Tue, 7 Nov 2023 14:33:44 +0800 Message-ID: <20231107063518.27824-1-stanley_chang@realtek.com> X-Mailer: git-send-email 2.42.0 Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-KSE-ServerInfo: RTEXMBS01.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-ServerInfo: RTEXH36505.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback In Realtek SoC, the parameter of usb phy is designed to can dynamic tuning base on port status. Therefore, add a notify callback of phy driver when usb connection/disconnection change. Signed-off-by: Stanley Chang --- drivers/phy/phy-core.c | 47 +++++++++++++++++++++++++++++++++++++++++ include/linux/phy/phy.h | 18 ++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 96a0b1e111f3..a84ad4896b7f 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -489,6 +489,53 @@ int phy_calibrate(struct phy *phy) } EXPORT_SYMBOL_GPL(phy_calibrate); +/** + * phy_notify_connect() - phy connect notify + * @phy: the phy returned by phy_get() + * @port: the port index for connect + * + * If phy need the 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 notify + * @phy: the phy returned by phy_get() + * @port: the port index for disconnect + * + * If phy need the get disconnection 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() diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index f6d607ef0e80..cf98cb29ddaa 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -122,6 +122,8 @@ struct phy_ops { union phy_configure_opts *opts); int (*reset)(struct phy *phy); int (*calibrate)(struct phy *phy); + int (*connect)(struct phy *phy, int port); + int (*disconnect)(struct phy *phy, int port); void (*release)(struct phy *phy); struct module *owner; }; @@ -243,6 +245,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 +400,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) { From patchwork Tue Nov 7 06:33:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?U3RhbmxleSBDaGFuZ1vmmIzogrLlvrdd?= X-Patchwork-Id: 13447943 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A71B218E for ; Tue, 7 Nov 2023 06:37:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=none Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F15AE8; Mon, 6 Nov 2023 22:37:27 -0800 (PST) X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 3A76ZbPR24026412, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/2.95/5.92) with ESMTPS id 3A76ZbPR24026412 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Nov 2023 14:35:37 +0800 Received: from RTEXDAG02.realtek.com.tw (172.21.6.101) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Tue, 7 Nov 2023 14:35:38 +0800 Received: from RTEXH36505.realtek.com.tw (172.21.6.25) by RTEXDAG02.realtek.com.tw (172.21.6.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Tue, 7 Nov 2023 14:35:37 +0800 Received: from localhost.localdomain (172.21.252.101) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server id 15.1.2375.32 via Frontend Transport; Tue, 7 Nov 2023 14:35:37 +0800 From: Stanley Chang To: Greg Kroah-Hartman CC: Stanley Chang , Vinod Koul , Johan Hovold , Kishon Vijay Abraham I , Jinjie Ruan , Rob Herring , "Alan Stern" , Yang Yingliang , Flavio Suligoi , "Heikki Krogerus" , Roy Luo , "Ray Chi" , =?utf-8?q?Ricar?= =?utf-8?q?do_Ca=C3=B1uelo?= , , , Subject: [PATCH v1 2/4] phy: realtek: usb2: Remove the legacy usb phy implementation Date: Tue, 7 Nov 2023 14:33:45 +0800 Message-ID: <20231107063518.27824-2-stanley_chang@realtek.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231107063518.27824-1-stanley_chang@realtek.com> References: <20231107063518.27824-1-stanley_chang@realtek.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-KSE-ServerInfo: RTEXDAG02.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback Remove the port status notification on legacy USB PHY. Use the generic PHY to notify the usb device connect and disconnect. To avoid using these PHYs would require describing the very same PHY using both the generic "phy" property and the deprecated "usb-phy" property. Signed-off-by: Stanley Chang --- drivers/phy/realtek/phy-rtk-usb2.c | 58 ++++++++++++------------------ 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/drivers/phy/realtek/phy-rtk-usb2.c b/drivers/phy/realtek/phy-rtk-usb2.c index 0a6426285c67..9cd2329fd7ca 100644 --- a/drivers/phy/realtek/phy-rtk-usb2.c +++ b/drivers/phy/realtek/phy-rtk-usb2.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include /* GUSB2PHYACCn register */ #define PHY_NEW_REG_REQ BIT(25) @@ -115,7 +113,6 @@ struct phy_parameter { }; struct rtk_phy { - struct usb_phy phy; struct device *dev; struct phy_cfg *phy_cfg; @@ -669,18 +666,9 @@ static int rtk_phy_exit(struct phy *phy) return 0; } -static const struct phy_ops ops = { - .init = rtk_phy_init, - .exit = rtk_phy_exit, - .owner = THIS_MODULE, -}; - -static void rtk_phy_toggle(struct usb_phy *usb2_phy, bool connect, int port) +static void rtk_phy_toggle(struct rtk_phy *rtk_phy, bool connect, int port) { int index = port; - struct rtk_phy *rtk_phy = NULL; - - rtk_phy = dev_get_drvdata(usb2_phy->dev); if (index > rtk_phy->num_phy) { dev_err(rtk_phy->dev, "%s: The port=%d is not in usb phy (num_phy=%d)\n", @@ -691,22 +679,34 @@ static void rtk_phy_toggle(struct usb_phy *usb2_phy, bool connect, int port) do_rtk_phy_toggle(rtk_phy, index, connect); } -static int rtk_phy_notify_port_status(struct usb_phy *x, int port, - u16 portstatus, u16 portchange) +static int rtk_phy_connect(struct phy *phy, int port) { - bool connect = false; + struct rtk_phy *rtk_phy = phy_get_drvdata(phy); + + dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port); + rtk_phy_toggle(rtk_phy, true, port); - pr_debug("%s port=%d portstatus=0x%x portchange=0x%x\n", - __func__, port, (int)portstatus, (int)portchange); - if (portstatus & USB_PORT_STAT_CONNECTION) - connect = true; + return 0; +} + +static int rtk_phy_disconnect(struct phy *phy, int port) +{ + struct rtk_phy *rtk_phy = phy_get_drvdata(phy); - if (portchange & USB_PORT_STAT_C_CONNECTION) - rtk_phy_toggle(x, connect, port); + dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port); + rtk_phy_toggle(rtk_phy, false, port); return 0; } +static const struct phy_ops ops = { + .init = rtk_phy_init, + .exit = rtk_phy_exit, + .connect = rtk_phy_connect, + .disconnect = rtk_phy_disconnect, + .owner = THIS_MODULE, +}; + #ifdef CONFIG_DEBUG_FS static struct dentry *create_phy_debug_root(void) { @@ -856,8 +856,6 @@ static inline void create_debug_files(struct rtk_phy *rtk_phy) debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy, &rtk_usb2_parameter_fops); - - return; } static inline void remove_debug_files(struct rtk_phy *rtk_phy) @@ -1024,10 +1022,6 @@ static int rtk_usb2phy_probe(struct platform_device *pdev) return -ENOMEM; rtk_phy->dev = &pdev->dev; - rtk_phy->phy.dev = rtk_phy->dev; - rtk_phy->phy.label = "rtk-usb2phy"; - rtk_phy->phy.notify_port_status = rtk_phy_notify_port_status; - rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL); memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg)); @@ -1051,10 +1045,6 @@ static int rtk_usb2phy_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - ret = usb_add_phy_dev(&rtk_phy->phy); - if (ret) - goto err; - create_debug_files(rtk_phy); err: @@ -1066,8 +1056,6 @@ static void rtk_usb2phy_remove(struct platform_device *pdev) struct rtk_phy *rtk_phy = platform_get_drvdata(pdev); remove_debug_files(rtk_phy); - - usb_remove_phy(&rtk_phy->phy); } static const struct phy_cfg rtd1295_phy_cfg = { @@ -1221,7 +1209,7 @@ static const struct phy_cfg rtd1312c_phy_cfg = { static const struct phy_cfg rtd1619b_phy_cfg = { .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE, .page0 = { [0] = {0xe0, 0xa3}, - [4] = {0xe4, 0x88}, + [4] = {0xe4, 0xa8}, [5] = {0xe5, 0x4f}, [6] = {0xe6, 0x02}, }, .page1_size = 8, From patchwork Tue Nov 7 06:33:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?U3RhbmxleSBDaGFuZ1vmmIzogrLlvrdd?= X-Patchwork-Id: 13447944 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4CF0A41 for ; Tue, 7 Nov 2023 06:37:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=none Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7054610D; Mon, 6 Nov 2023 22:37:27 -0800 (PST) X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 3A76ZulZ64026563, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/2.95/5.92) with ESMTPS id 3A76ZulZ64026563 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Nov 2023 14:35:56 +0800 Received: from RTEXMBS05.realtek.com.tw (172.21.6.98) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Tue, 7 Nov 2023 14:35:56 +0800 Received: from RTEXH36505.realtek.com.tw (172.21.6.25) by RTEXMBS05.realtek.com.tw (172.21.6.98) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Tue, 7 Nov 2023 14:35:55 +0800 Received: from localhost.localdomain (172.21.252.101) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server id 15.1.2375.32 via Frontend Transport; Tue, 7 Nov 2023 14:35:55 +0800 From: Stanley Chang To: Greg Kroah-Hartman CC: Stanley Chang , Vinod Koul , Johan Hovold , Kishon Vijay Abraham I , Rob Herring , Jinjie Ruan , "Alan Stern" , Yang Yingliang , =?utf-8?q?Ricardo_Ca=C3=B1uelo?= , Ray Chi , Roy Luo , , , Subject: [PATCH v1 3/4] phy: realtek: usb3: Remove the legacy usb phy implementation Date: Tue, 7 Nov 2023 14:33:46 +0800 Message-ID: <20231107063518.27824-3-stanley_chang@realtek.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231107063518.27824-1-stanley_chang@realtek.com> References: <20231107063518.27824-1-stanley_chang@realtek.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-KSE-ServerInfo: RTEXMBS05.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback Same as phy-rtk-usb2.c Remove the port status notification on legacy USB PHY. Use the generic PHY to notify the usb device connect and disconnect. To avoid using these PHYs would require describing the very same PHY using both the generic "phy" property and the deprecated "usb-phy" property. Signed-off-by: Stanley Chang --- drivers/phy/realtek/phy-rtk-usb3.c | 56 ++++++++++++------------------ 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/drivers/phy/realtek/phy-rtk-usb3.c b/drivers/phy/realtek/phy-rtk-usb3.c index 67446a85e968..d992a21243e1 100644 --- a/drivers/phy/realtek/phy-rtk-usb3.c +++ b/drivers/phy/realtek/phy-rtk-usb3.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #define USB_MDIO_CTRL_PHY_BUSY BIT(7) #define USB_MDIO_CTRL_PHY_WRITE BIT(0) @@ -85,7 +83,6 @@ struct phy_parameter { }; struct rtk_phy { - struct usb_phy phy; struct device *dev; struct phy_cfg *phy_cfg; @@ -303,18 +300,9 @@ static int rtk_phy_exit(struct phy *phy) return 0; } -static const struct phy_ops ops = { - .init = rtk_phy_init, - .exit = rtk_phy_exit, - .owner = THIS_MODULE, -}; - -static void rtk_phy_toggle(struct usb_phy *usb3_phy, bool connect, int port) +static void rtk_phy_toggle(struct rtk_phy *rtk_phy, bool connect, int port) { int index = port; - struct rtk_phy *rtk_phy = NULL; - - rtk_phy = dev_get_drvdata(usb3_phy->dev); if (index > rtk_phy->num_phy) { dev_err(rtk_phy->dev, "%s: The port=%d is not in usb phy (num_phy=%d)\n", @@ -325,22 +313,34 @@ static void rtk_phy_toggle(struct usb_phy *usb3_phy, bool connect, int port) do_rtk_usb3_phy_toggle(rtk_phy, index, connect); } -static int rtk_phy_notify_port_status(struct usb_phy *x, int port, - u16 portstatus, u16 portchange) +static int rtk_phy_connect(struct phy *phy, int port) { - bool connect = false; + struct rtk_phy *rtk_phy = phy_get_drvdata(phy); + + dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port); + rtk_phy_toggle(rtk_phy, true, port); + + return 0; +} - pr_debug("%s port=%d portstatus=0x%x portchange=0x%x\n", - __func__, port, (int)portstatus, (int)portchange); - if (portstatus & USB_PORT_STAT_CONNECTION) - connect = true; +static int rtk_phy_disconnect(struct phy *phy, int port) +{ + struct rtk_phy *rtk_phy = phy_get_drvdata(phy); - if (portchange & USB_PORT_STAT_C_CONNECTION) - rtk_phy_toggle(x, connect, port); + dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port); + rtk_phy_toggle(rtk_phy, false, port); return 0; } +static const struct phy_ops ops = { + .init = rtk_phy_init, + .exit = rtk_phy_exit, + .connect = rtk_phy_connect, + .disconnect = rtk_phy_disconnect, + .owner = THIS_MODULE, +}; + #ifdef CONFIG_DEBUG_FS static struct dentry *create_phy_debug_root(void) { @@ -419,8 +419,6 @@ static inline void create_debug_files(struct rtk_phy *rtk_phy) debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy, &rtk_usb3_parameter_fops); - - return; } static inline void remove_debug_files(struct rtk_phy *rtk_phy) @@ -578,10 +576,6 @@ static int rtk_usb3phy_probe(struct platform_device *pdev) return -ENOMEM; rtk_phy->dev = &pdev->dev; - rtk_phy->phy.dev = rtk_phy->dev; - rtk_phy->phy.label = "rtk-usb3phy"; - rtk_phy->phy.notify_port_status = rtk_phy_notify_port_status; - rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL); memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg)); @@ -604,10 +598,6 @@ static int rtk_usb3phy_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - ret = usb_add_phy_dev(&rtk_phy->phy); - if (ret) - goto err; - create_debug_files(rtk_phy); err: @@ -619,8 +609,6 @@ static void rtk_usb3phy_remove(struct platform_device *pdev) struct rtk_phy *rtk_phy = platform_get_drvdata(pdev); remove_debug_files(rtk_phy); - - usb_remove_phy(&rtk_phy->phy); } static const struct phy_cfg rtd1295_phy_cfg = { From patchwork Tue Nov 7 06:33:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?U3RhbmxleSBDaGFuZ1vmmIzogrLlvrdd?= X-Patchwork-Id: 13447946 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8F3E1C15 for ; Tue, 7 Nov 2023 06:37:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=none Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71C6910F; Mon, 6 Nov 2023 22:37:27 -0800 (PST) X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 3A76aE2u94026654, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/2.95/5.92) with ESMTPS id 3A76aE2u94026654 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Nov 2023 14:36:14 +0800 Received: from RTEXMBS02.realtek.com.tw (172.21.6.95) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Tue, 7 Nov 2023 14:36:15 +0800 Received: from RTEXH36505.realtek.com.tw (172.21.6.25) by RTEXMBS02.realtek.com.tw (172.21.6.95) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Tue, 7 Nov 2023 14:36:14 +0800 Received: from localhost.localdomain (172.21.252.101) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server id 15.1.2375.32 via Frontend Transport; Tue, 7 Nov 2023 14:36:14 +0800 From: Stanley Chang To: Greg Kroah-Hartman CC: Stanley Chang , Vinod Koul , Johan Hovold , Kishon Vijay Abraham I , Jinjie Ruan , Rob Herring , "Alan Stern" , Yang Yingliang , Roy Luo , Heikki Krogerus , =?utf-8?q?Ricardo_Ca?= =?utf-8?q?=C3=B1uelo?= , Ray Chi , , , Subject: [PATCH v1 4/4] usb: core: add phy notify connect and disconnect Date: Tue, 7 Nov 2023 14:33:47 +0800 Message-ID: <20231107063518.27824-4-stanley_chang@realtek.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231107063518.27824-1-stanley_chang@realtek.com> References: <20231107063518.27824-1-stanley_chang@realtek.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-KSE-ServerInfo: RTEXMBS02.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-ServerInfo: RTEXH36505.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback Recently added Realtek PHY driver depends on new port status Notification mechanism built on the deprecated USB PHY implementation. It's broken by design. Therefore, USB port status notifications on legacy USB PHYs should be removed. New mechanism for connect and disconnect USB devices using to replace it on generic phy. Additionally, the generic phy only specifies primary_hcd in the original design. Added specific "usb2-phy" on primary_hcd and "usb3-phy" on shared_hcd. In Realtek SoC, the parameter of usb phy is designed to can dynamic tuning base on device connect and disconnect. Therefore, add a notify callback of generic phy driver when usb device connection change. Check if portstatus is USB_PORT_STAT_CONNECTION and portchange is USB_PORT_STAT_C_CONNECTION. 1. The device is connected, notify phy driver to calibrates the phy parameters. 2. The device disconnects, also notify driver to calibrates the phy parameters. Signed-off-by: Stanley Chang --- drivers/usb/core/hcd.c | 14 ++++-- drivers/usb/core/hub.c | 16 ++++--- drivers/usb/core/phy.c | 94 +++++++++++++++++++++++++++++++++++++++++ drivers/usb/core/phy.h | 3 ++ include/linux/usb/phy.h | 13 ------ 5 files changed, 118 insertions(+), 22 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 12b6dfeaf658..992284461ad8 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2794,10 +2794,16 @@ int usb_add_hcd(struct usb_hcd *hcd, struct usb_device *rhdev; struct usb_hcd *shared_hcd; - if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); - if (IS_ERR(hcd->phy_roothub)) - return PTR_ERR(hcd->phy_roothub); + if (!hcd->skip_phy_initialization) { + if (usb_hcd_is_primary_hcd(hcd)) { + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); + if (IS_ERR(hcd->phy_roothub)) + return PTR_ERR(hcd->phy_roothub); + } else { + hcd->phy_roothub = usb_phy_roothub_alloc_usb3_phy(hcd->self.sysdev); + if (IS_ERR(hcd->phy_roothub)) + return PTR_ERR(hcd->phy_roothub); + } retval = usb_phy_roothub_init(hcd->phy_roothub); if (retval) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b4584a0cd484..65c0454ee70a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -37,6 +37,7 @@ #include #include "hub.h" +#include "phy.h" #include "otg_productlist.h" #define USB_VENDOR_GENESYS_LOGIC 0x05e3 @@ -632,16 +633,21 @@ static int hub_ext_port_status(struct usb_hub *hub, int port1, int type, struct usb_device *hdev = hub->hdev; /* - * Only roothub will be notified of port state changes, + * Only roothub will be notified of connection changes, * since the USB PHY only cares about changes at the next * level. */ if (is_root_hub(hdev)) { struct usb_hcd *hcd = bus_to_hcd(hdev->bus); - - if (hcd->usb_phy) - usb_phy_notify_port_status(hcd->usb_phy, - port1 - 1, *status, *change); + bool connect; + bool connect_change; + + connect_change = *change & USB_PORT_STAT_C_CONNECTION; + connect = *status & USB_PORT_STAT_CONNECTION; + if (connect_change && connect) + usb_phy_roothub_notify_connect(hcd->phy_roothub, port1 - 1); + else if (connect_change) + usb_phy_roothub_notify_disconnect(hcd->phy_roothub, port1 - 1); } } diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index fb1588e7c282..26585fc1ec32 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -19,6 +19,29 @@ struct usb_phy_roothub { struct list_head list; }; +static int usb_phy_roothub_add_phy_by_name(struct device *dev, const char *name, + struct list_head *list) +{ + struct usb_phy_roothub *roothub_entry; + struct phy *phy; + + phy = devm_of_phy_get(dev, dev->of_node, name); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return -ENOMEM; + + INIT_LIST_HEAD(&roothub_entry->list); + + roothub_entry->phy = phy; + + list_add_tail(&roothub_entry->list, list); + + return 0; +} + static int usb_phy_roothub_add_phy(struct device *dev, int index, struct list_head *list) { @@ -65,6 +88,9 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) INIT_LIST_HEAD(&phy_roothub->list); + if (!usb_phy_roothub_add_phy_by_name(dev, "usb2-phy", &phy_roothub->list)) + return phy_roothub; + for (i = 0; i < num_phys; i++) { err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); if (err) @@ -75,6 +101,32 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) } EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc); +struct usb_phy_roothub *usb_phy_roothub_alloc_usb3_phy(struct device *dev) +{ + struct usb_phy_roothub *phy_roothub; + int num_phys; + + if (!IS_ENABLED(CONFIG_GENERIC_PHY)) + return NULL; + + num_phys = of_count_phandle_with_args(dev->of_node, "phys", + "#phy-cells"); + if (num_phys <= 0) + return NULL; + + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); + if (!phy_roothub) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&phy_roothub->list); + + if (!usb_phy_roothub_add_phy_by_name(dev, "usb3-phy", &phy_roothub->list)) + return phy_roothub; + + return NULL; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc_usb3_phy); + int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub) { struct usb_phy_roothub *roothub_entry; @@ -172,6 +224,48 @@ int usb_phy_roothub_calibrate(struct usb_phy_roothub *phy_roothub) } EXPORT_SYMBOL_GPL(usb_phy_roothub_calibrate); +int usb_phy_roothub_notify_connect(struct usb_phy_roothub *phy_roothub, int port) +{ + struct usb_phy_roothub *roothub_entry; + struct list_head *head; + int err; + + if (!phy_roothub) + return 0; + + head = &phy_roothub->list; + + list_for_each_entry(roothub_entry, head, list) { + err = phy_notify_connect(roothub_entry->phy, port); + if (err) + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_notify_connect); + +int usb_phy_roothub_notify_disconnect(struct usb_phy_roothub *phy_roothub, int port) +{ + struct usb_phy_roothub *roothub_entry; + struct list_head *head; + int err; + + if (!phy_roothub) + return 0; + + head = &phy_roothub->list; + + list_for_each_entry(roothub_entry, head, list) { + err = phy_notify_disconnect(roothub_entry->phy, port); + if (err) + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_notify_disconnect); + int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub) { struct usb_phy_roothub *roothub_entry; diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 20a267cd986b..88b49c0ea6b5 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -12,6 +12,7 @@ struct device; struct usb_phy_roothub; struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); +struct usb_phy_roothub *usb_phy_roothub_alloc_usb3_phy(struct device *dev); int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); @@ -19,6 +20,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub, enum phy_mode mode); int usb_phy_roothub_calibrate(struct usb_phy_roothub *phy_roothub); +int usb_phy_roothub_notify_connect(struct usb_phy_roothub *phy_roothub, int port); +int usb_phy_roothub_notify_disconnect(struct usb_phy_roothub *phy_roothub, int port); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub); diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index b513749582d7..e4de6bc1f69b 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -144,10 +144,6 @@ struct usb_phy { */ int (*set_wakeup)(struct usb_phy *x, bool enabled); - /* notify phy port status change */ - int (*notify_port_status)(struct usb_phy *x, int port, - u16 portstatus, u16 portchange); - /* notify phy connect status change */ int (*notify_connect)(struct usb_phy *x, enum usb_device_speed speed); @@ -320,15 +316,6 @@ usb_phy_set_wakeup(struct usb_phy *x, bool enabled) return 0; } -static inline int -usb_phy_notify_port_status(struct usb_phy *x, int port, u16 portstatus, u16 portchange) -{ - if (x && x->notify_port_status) - return x->notify_port_status(x, port, portstatus, portchange); - else - return 0; -} - static inline int usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) {