Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp1546395rdb; Thu, 7 Dec 2023 02:08:53 -0800 (PST) X-Google-Smtp-Source: AGHT+IFCozVUzF3f2uE93YGO5xrls93HH5RQawttLw8s7D+vIaAbW3Am4ulVMH+urzXZ2f3PaM5R X-Received: by 2002:a92:bf0c:0:b0:35d:537d:5eba with SMTP id z12-20020a92bf0c000000b0035d537d5ebamr2695171ilh.24.1701943733512; Thu, 07 Dec 2023 02:08:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701943733; cv=none; d=google.com; s=arc-20160816; b=seB/suvc4I49nCff4j9CA+jHk3nz5M5/Bwd6v2SiSvaBL4DdRLiL+9YObHhJRz8D4i wxV/Pdgsud38aLiSas+7BEqjEI6y8eD73Eo9PVm7onNg64auFjBNLl/I9YREMvTHCk9j mK57Ef3UOGYO/pX1y98tMUvW56dW6Qred7y1ZRZKyLXPJbiDpRFWy6haiK3HKE9S1CD6 ztD6KaujF26wZCQmBB175CyX/HSJH78RlcTVYz9nXsrFICRmbgTApriLTYDt7nIRGbIH kzcdvzN4bHSC6Gx86JXhMEi1qzW8DFiyzTXE3jpC90cILUHe10fVWTF8Zmef70EdxDNF IfZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=9wLSZuNVuzPX7Shn+26HExweZjNyGSAHyxZvcrfaoj4=; fh=aSACCieQPg0+0okhGpmrdwfCZqhWBU8E+vAT/jR9hiE=; b=fe92t7BlQJ1SYURuTsvJ6YQOW8nCvk+jtEsb3ErnPJP6iKf1ww5Z9cafquy1dIITit 8V7GC7G+RGvvcx1cD9sZf4NQD58n2hFgj5QksXgMyvKNJAuthvlsHP6/AKmI+ieFFMKn Fvw+WSX+7kh7emSENtH3cM8CQYaL5Qrd1vJECbxMSZzsPKT75PLU2rMhmlezkMhjgor4 EMKVNAgjSLwU0ubglTBnsam8sKKVNUQyFpw2S9b6y2uaPtCUKKqQYZ6jQMW1lkBd9b0g i0UkTj+dO9QH8Hyb6hhXEw3AoF85Qc8O9ApSrANqZtbrCH0SBx4yWuvk8ip2CxoKzDE6 r2Iw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=LPPnoCwQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from pete.vger.email (pete.vger.email. [2620:137:e000::3:6]) by mx.google.com with ESMTPS id o9-20020a634e49000000b005b834096959si913743pgl.851.2023.12.07.02.08.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Dec 2023 02:08:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) client-ip=2620:137:e000::3:6; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=LPPnoCwQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 1FC6480C5C89; Thu, 7 Dec 2023 02:08:50 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379111AbjLGKII (ORCPT + 99 others); Thu, 7 Dec 2023 05:08:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379076AbjLGKIC (ORCPT ); Thu, 7 Dec 2023 05:08:02 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A70C133 for ; Thu, 7 Dec 2023 02:08:08 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 01AEEC433C9; Thu, 7 Dec 2023 10:08:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1701943687; bh=+TtWj3u6F3zGN0JIXvl73oCLKKxPXp04JKwR9ZXgj3M=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=LPPnoCwQQoWgHzBERudad0ncb3tnicMaEM1xQeqYyAMaMSeNXmNv5+N2ZGa6k2C/u fzwsvVRg4OcGLQw4HeVW/9YxXMauLsodfn2ww6y9Z8oNrgRVSfXZSBYyRhffOPKuUq WWWPpTNzmsmF60dK43Bme7ISlTk30HraApCZoLMs= Date: Thu, 7 Dec 2023 11:08:03 +0100 From: Greg Kroah-Hartman To: Stanley Chang Cc: Vinod Koul , Johan Hovold , Kishon Vijay Abraham I , Geert Uytterhoeven , Rob Herring , Jinjie Ruan , Alan Stern , Roy Luo , Flavio Suligoi , Ricardo =?iso-8859-1?Q?Ca=F1uelo?= , Heikki Krogerus , linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-usb@vger.kernel.org Subject: Re: [PATCH v3 RESEND 4/4] usb: core: add phy notify connect and disconnect Message-ID: <2023120730-mouth-jolt-0170@gregkh> References: <20231207074022.14116-1-stanley_chang@realtek.com> <20231207074022.14116-4-stanley_chang@realtek.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20231207074022.14116-4-stanley_chang@realtek.com> X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Thu, 07 Dec 2023 02:08:50 -0800 (PST) On Thu, Dec 07, 2023 at 03:38:07PM +0800, Stanley Chang wrote: > In Realtek SoC, the parameter of usb phy is designed to can dynamic > tuning base on port status. Therefore, add a notify callback of generic > phy driver when usb device connect and disconnect change. > > The Realtek phy driver is designed to dynamically adjust disconnection > level and calibrate phy parameters. When the device connected bit changes > and when the disconnected bit changes, do connection change notification: > > Check if portstatus is USB_PORT_STAT_CONNECTION and portchange is > USB_PORT_STAT_C_CONNECTION. > 1. The device is connected, the driver lowers the disconnection level and > calibrates the phy parameters. > 2. The device disconnects, the driver increases the disconnect level and > calibrates the phy parameters. > > Generic phy driver in usb core framework does not support device connect > and disconnect notifications. Therefore, we add an api to notify phy > the connection changes. > > 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. > > Signed-off-by: Stanley Chang > --- > v2 to v3: > No change > v1 to v2 change: > rebase the driver to remove the part of usb phy notify API > --- > drivers/usb/core/hcd.c | 14 +++++-- > drivers/usb/core/hub.c | 29 +++++++++++++ > drivers/usb/core/phy.c | 94 ++++++++++++++++++++++++++++++++++++++++++ > drivers/usb/core/phy.h | 3 ++ > 4 files changed, 136 insertions(+), 4 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 87480a6e6d93..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 > @@ -622,6 +623,34 @@ static int hub_ext_port_status(struct usb_hub *hub, int port1, int type, > ret = 0; > } > mutex_unlock(&hub->status_mutex); > + > + /* > + * There is no need to lock status_mutex here, because status_mutex > + * protects hub->status, and the phy driver only checks the port > + * status without changing the status. > + */ > + if (!ret) { > + struct usb_device *hdev = hub->hdev; > + > + /* > + * 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); > + 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); > + } > + } > + > return ret; > } > > 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; How can phy_roothub ever be NULL? > + > + head = &phy_roothub->list; > + > + list_for_each_entry(roothub_entry, head, list) { > + err = phy_notify_connect(roothub_entry->phy, port); > + if (err) > + return err; > + } > You walk a list with no locking at all? That does not seem right at all. Also, this is a new function that is exported with no documentation? Please fix. thanks, greg k-h