fixes for UEFI and improved upstream fix for PHY shutdown lockups
This commit is contained in:
parent
d98cfa77d6
commit
1457c7c78e
@ -1,5 +1,6 @@
|
||||
a64-olinuxino
|
||||
amarula_a64_relic
|
||||
apple_m1
|
||||
bananapi_m2_plus_h5
|
||||
bananapi_m64
|
||||
beelink_gs1
|
||||
@ -35,6 +36,7 @@ nanopi-m4-rk3399
|
||||
nanopi_neo2
|
||||
nanopi-neo4-rk3399
|
||||
nanopi_neo_plus2
|
||||
nanopi_r1s_h5
|
||||
nanopi-r2s-rk3328
|
||||
nanopi-r4s-rk3399
|
||||
odroid-c2
|
||||
|
@ -1,233 +0,0 @@
|
||||
From patchwork Tue Apr 6 15:10:59 2021
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Patchwork-Submitter: Icenowy Zheng <icenowy@aosc.io>
|
||||
X-Patchwork-Id: 1462876
|
||||
Return-Path: <u-boot-bounces@lists.denx.de>
|
||||
X-Original-To: incoming@patchwork.ozlabs.org
|
||||
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
|
||||
Authentication-Results: ozlabs.org;
|
||||
spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
|
||||
(client-ip=85.214.62.61; helo=phobos.denx.de;
|
||||
envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
|
||||
Authentication-Results: ozlabs.org;
|
||||
dkim=fail reason="signature verification failed" (1024-bit key;
|
||||
unprotected) header.d=mymailcheap.com header.i=@mymailcheap.com
|
||||
header.a=rsa-sha256 header.s=default header.b=unszVtqT;
|
||||
dkim=fail reason="signature verification failed" (1024-bit key;
|
||||
unprotected) header.d=aosc.io header.i=@aosc.io header.a=rsa-sha256
|
||||
header.s=default header.b=mWwYCh9A;
|
||||
dkim-atps=neutral
|
||||
Received: from phobos.denx.de (phobos.denx.de [85.214.62.61])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||
key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest
|
||||
SHA256)
|
||||
(No client certificate requested)
|
||||
by ozlabs.org (Postfix) with ESMTPS id 4FF9wc3GdNz9sW1
|
||||
for <incoming@patchwork.ozlabs.org>; Wed, 7 Apr 2021 01:11:42 +1000 (AEST)
|
||||
Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
|
||||
by phobos.denx.de (Postfix) with ESMTP id C1F9C8040A;
|
||||
Tue, 6 Apr 2021 17:11:32 +0200 (CEST)
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dmarc=none (p=none dis=none) header.from=aosc.io
|
||||
Authentication-Results: phobos.denx.de;
|
||||
spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dkim=fail reason="signature verification failed" (1024-bit key;
|
||||
unprotected) header.d=mymailcheap.com header.i=@mymailcheap.com
|
||||
header.b="unszVtqT";
|
||||
dkim=fail reason="signature verification failed" (1024-bit key;
|
||||
unprotected) header.d=aosc.io header.i=@aosc.io header.b="mWwYCh9A";
|
||||
dkim-atps=neutral
|
||||
Received: by phobos.denx.de (Postfix, from userid 109)
|
||||
id E4F22805B4; Tue, 6 Apr 2021 17:11:30 +0200 (CEST)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,
|
||||
DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE autolearn=ham
|
||||
autolearn_force=no version=3.4.2
|
||||
Received: from relay3.mymailcheap.com (relay3.mymailcheap.com
|
||||
[217.182.66.161])
|
||||
(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by phobos.denx.de (Postfix) with ESMTPS id 2FC4A8039D
|
||||
for <u-boot@lists.denx.de>; Tue, 6 Apr 2021 17:11:27 +0200 (CEST)
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dmarc=none (p=none dis=none) header.from=aosc.io
|
||||
Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=icenowy@aosc.io
|
||||
Received: from filter2.mymailcheap.com (filter2.mymailcheap.com
|
||||
[91.134.140.82])
|
||||
by relay3.mymailcheap.com (Postfix) with ESMTPS id A6AC13ECDF;
|
||||
Tue, 6 Apr 2021 17:11:26 +0200 (CEST)
|
||||
Received: from localhost (localhost [127.0.0.1])
|
||||
by filter2.mymailcheap.com (Postfix) with ESMTP id 88D512A915;
|
||||
Tue, 6 Apr 2021 17:11:26 +0200 (CEST)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mymailcheap.com;
|
||||
s=default; t=1617721886;
|
||||
bh=qb5gt5o7M9qjdJd67A3WHGZp/76w4s4FS6+u1VuEh/o=;
|
||||
h=From:To:Cc:Subject:Date:From;
|
||||
b=unszVtqTnO9MGZVbgLH5H0cMo3VfQ+g5377blmOUcrtzMSqNbDD5SM25MUhlTUKiB
|
||||
hTFq4L53gszBYfRPfh7Z5XgNVERULL5Zx0+WnVjZ7kUIp/wS3IQqxe81ChoFEsLTr8
|
||||
22UB9NN3OSVkuN/jRAzX+lKpugVGBHwOCjZBZukQ=
|
||||
Received: from filter2.mymailcheap.com ([127.0.0.1])
|
||||
by localhost (filter2.mymailcheap.com [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP id V9lVOgo6gApH; Tue, 6 Apr 2021 17:11:25 +0200 (CEST)
|
||||
Received: from mail20.mymailcheap.com (mail20.mymailcheap.com [51.83.111.147])
|
||||
(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by filter2.mymailcheap.com (Postfix) with ESMTPS;
|
||||
Tue, 6 Apr 2021 17:11:25 +0200 (CEST)
|
||||
Received: from [213.133.102.83] (ml.mymailcheap.com [213.133.102.83])
|
||||
by mail20.mymailcheap.com (Postfix) with ESMTP id C9EA3400B6;
|
||||
Tue, 6 Apr 2021 15:11:24 +0000 (UTC)
|
||||
Authentication-Results: mail20.mymailcheap.com; dkim=pass (1024-bit key;
|
||||
unprotected) header.d=aosc.io header.i=@aosc.io header.b="mWwYCh9A";
|
||||
dkim-atps=neutral
|
||||
AI-Spam-Status: Not processed
|
||||
Received: from ice-e5v2.lan (unknown [59.41.163.135])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||
key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest
|
||||
SHA256) (No client certificate requested)
|
||||
by mail20.mymailcheap.com (Postfix) with ESMTPSA id 251F840C16;
|
||||
Tue, 6 Apr 2021 15:11:10 +0000 (UTC)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=aosc.io; s=default;
|
||||
t=1617721874; bh=qb5gt5o7M9qjdJd67A3WHGZp/76w4s4FS6+u1VuEh/o=;
|
||||
h=From:To:Cc:Subject:Date:From;
|
||||
b=mWwYCh9AM8eRWm9hiEqirytotj/G/C1p9r2fd0zUxPhS0UQH+kw6L3RWZnsfmXAYq
|
||||
HmYFiM3ktIfwevqQw89tOi8c2ktb49iYOyHXkfi8hTZl1dNsJDS94uyzBiHYY+U7x5
|
||||
P0aTRRaL5C8ua2c1GedoPx06nrARO/KMEFy39rxI=
|
||||
From: Icenowy Zheng <icenowy@aosc.io>
|
||||
To: Simon Glass <sjg@chromium.org>, Kever Yang <kever.yang@rock-chips.com>,
|
||||
Frank Wang <frank.wang@rock-chips.com>,
|
||||
Jagan Teki <jagan@amarulasolutions.com>
|
||||
Cc: u-boot@lists.denx.de,
|
||||
Icenowy Zheng <icenowy@aosc.io>
|
||||
Subject: [PATCH] phy: rockchip: inno-usb2: fix hang when multiple controllers
|
||||
exit
|
||||
Date: Tue, 6 Apr 2021 23:10:59 +0800
|
||||
Message-Id: <20210406151059.1187379-1-icenowy@aosc.io>
|
||||
X-Mailer: git-send-email 2.30.2
|
||||
MIME-Version: 1.0
|
||||
X-Rspamd-Server: mail20.mymailcheap.com
|
||||
X-Spamd-Result: default: False [4.90 / 20.00]; RCVD_VIA_SMTP_AUTH(0.00)[];
|
||||
ARC_NA(0.00)[]; R_DKIM_ALLOW(0.00)[aosc.io:s=default];
|
||||
RECEIVED_SPAMHAUS_PBL(0.00)[59.41.163.135:received];
|
||||
FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[];
|
||||
R_MISSING_CHARSET(2.50)[]; TO_MATCH_ENVRCPT_ALL(0.00)[];
|
||||
MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[aosc.io];
|
||||
BROKEN_CONTENT_TYPE(1.50)[]; R_SPF_SOFTFAIL(0.00)[~all];
|
||||
RCPT_COUNT_FIVE(0.00)[6]; ML_SERVERS(-3.10)[213.133.102.83];
|
||||
DKIM_TRACE(0.00)[aosc.io:+]; MID_CONTAINS_FROM(1.00)[];
|
||||
RCVD_NO_TLS_LAST(0.10)[]; FROM_EQ_ENVFROM(0.00)[];
|
||||
MIME_TRACE(0.00)[0:+];
|
||||
ASN(0.00)[asn:24940, ipnet:213.133.96.0/19, country:DE];
|
||||
RCVD_COUNT_TWO(0.00)[2];
|
||||
HFILTER_HELO_BAREIP(3.00)[213.133.102.83,1]
|
||||
X-Rspamd-Queue-Id: C9EA3400B6
|
||||
X-BeenThere: u-boot@lists.denx.de
|
||||
X-Mailman-Version: 2.1.34
|
||||
Precedence: list
|
||||
List-Id: U-Boot discussion <u-boot.lists.denx.de>
|
||||
List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
|
||||
<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
|
||||
List-Archive: <https://lists.denx.de/pipermail/u-boot/>
|
||||
List-Post: <mailto:u-boot@lists.denx.de>
|
||||
List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
|
||||
List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
|
||||
<mailto:u-boot-request@lists.denx.de?subject=subscribe>
|
||||
Errors-To: u-boot-bounces@lists.denx.de
|
||||
Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
|
||||
X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de
|
||||
X-Virus-Status: Clean
|
||||
|
||||
The OHCI and EHCI controllers are both bound to the same PHY. They will
|
||||
both do init and power_on operations when the controller is brought up
|
||||
and both do power_off and exit when the controller is stopped. However,
|
||||
the PHY uclass of U-Boot is not as sane as we thought -- they won't
|
||||
maintain a status mark for PHYs, and thus the functions of the PHYs
|
||||
could be called for multiple times. Calling init/power_on for multiple
|
||||
times have no severe problems, however calling power_off/exit for
|
||||
multiple times have a problem -- the first exit call will stop the PHY
|
||||
clock, and power_off/exit calls after it still trying to write to PHY
|
||||
registers. The write operation to PHY registers will fail because clock
|
||||
is already stopped.
|
||||
|
||||
Adapt the count mechanism from phy-sun4i-usb to both init/exit and
|
||||
power_on/power_off functions to phy-rockchip-inno-usb2 to fix this
|
||||
problem. With this stopping USB controllers (manually or before booting
|
||||
a kernel) will work.
|
||||
|
||||
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
|
||||
Fixes: ac97a9ece14e ("phy: rockchip: Add Rockchip USB2PHY driver")
|
||||
---
|
||||
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 21 +++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
|
||||
index 62b8ba3a4a..be9cc99d90 100644
|
||||
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
|
||||
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
|
||||
@@ -62,6 +62,8 @@ struct rockchip_usb2phy {
|
||||
void *reg_base;
|
||||
struct clk phyclk;
|
||||
const struct rockchip_usb2phy_cfg *phy_cfg;
|
||||
+ int init_count;
|
||||
+ int power_on_count;
|
||||
};
|
||||
|
||||
static inline int property_enable(void *reg_base,
|
||||
@@ -92,6 +94,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
|
||||
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
||||
const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
|
||||
|
||||
+ priv->power_on_count++;
|
||||
+ if (priv->power_on_count != 1)
|
||||
+ return 0;
|
||||
+
|
||||
property_enable(priv->reg_base, &port_cfg->phy_sus, false);
|
||||
|
||||
/* waiting for the utmi_clk to become stable */
|
||||
@@ -106,6 +112,10 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
|
||||
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
||||
const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
|
||||
|
||||
+ priv->power_on_count--;
|
||||
+ if (priv->power_on_count != 0)
|
||||
+ return 0;
|
||||
+
|
||||
property_enable(priv->reg_base, &port_cfg->phy_sus, true);
|
||||
|
||||
return 0;
|
||||
@@ -118,6 +128,10 @@ static int rockchip_usb2phy_init(struct phy *phy)
|
||||
const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
|
||||
int ret;
|
||||
|
||||
+ priv->init_count++;
|
||||
+ if (priv->init_count != 1)
|
||||
+ return 0;
|
||||
+
|
||||
ret = clk_enable(&priv->phyclk);
|
||||
if (ret) {
|
||||
dev_err(phy->dev, "failed to enable phyclk (ret=%d)\n", ret);
|
||||
@@ -140,6 +154,10 @@ static int rockchip_usb2phy_exit(struct phy *phy)
|
||||
struct udevice *parent = dev_get_parent(phy->dev);
|
||||
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
||||
|
||||
+ priv->init_count--;
|
||||
+ if (priv->init_count != 0)
|
||||
+ return 0;
|
||||
+
|
||||
clk_disable(&priv->phyclk);
|
||||
|
||||
return 0;
|
||||
@@ -212,6 +230,9 @@ static int rockchip_usb2phy_probe(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ priv->power_on_count = 0;
|
||||
+ priv->init_count = 0;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Name: uboot-tools
|
||||
Version: 2022.01
|
||||
Release: 0.2%{?candidate:.%{candidate}}%{?dist}
|
||||
Release: 0.3%{?candidate:.%{candidate}}%{?dist}
|
||||
Summary: U-Boot utilities
|
||||
License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+
|
||||
URL: http://www.denx.de/wiki/U-Boot
|
||||
@ -17,14 +17,15 @@ Source2: aarch64-boards
|
||||
Patch1: uefi-distro-load-FDT-from-any-partition-on-boot-device.patch
|
||||
|
||||
# Board fixes and enablement
|
||||
Patch2: v2-console-usb-kbd-Limit-poll-frequency-to-improve-performance.patch
|
||||
# RPi - uses RPI firmware device tree for HAT support
|
||||
Patch2: rpi-Enable-using-the-DT-provided-by-the-Raspberry-Pi.patch
|
||||
Patch3: rpi-fallback-to-max-clock-for-mmc.patch
|
||||
Patch4: rpi-bcm2835_sdhost-firmware-managed-clock.patch
|
||||
Patch3: rpi-Enable-using-the-DT-provided-by-the-Raspberry-Pi.patch
|
||||
Patch4: rpi-fallback-to-max-clock-for-mmc.patch
|
||||
Patch5: rpi-bcm2835_sdhost-firmware-managed-clock.patch
|
||||
# Rockchips improvements
|
||||
Patch5: phy-rockchip-inno-usb2-fix-hang-when-multiple-controllers-exit.patch
|
||||
Patch6: dts-rockchip-rk3399-enable-emmc-phy-for-spl.patch
|
||||
Patch7: 0001-Revert-spi-spi-uclass-Add-support-to-manually-reloca.patch
|
||||
Patch6: v3-phy-Track-power-on-and-init-counts-in-uclass.patch
|
||||
Patch7: dts-rockchip-rk3399-enable-emmc-phy-for-spl.patch
|
||||
Patch8: 0001-Revert-spi-spi-uclass-Add-support-to-manually-reloca.patch
|
||||
|
||||
BuildRequires: bc
|
||||
BuildRequires: dtc
|
||||
@ -250,6 +251,9 @@ cp -p board/warp7/README builds/docs/README.warp7
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Jan 05 2022 Peter Robinson <pbrobinson@fedoraproject.org> - 2022.01-0.3.rc4
|
||||
- Upstream fixes for PHY and UEFI
|
||||
|
||||
* Mon Dec 20 2021 Peter Robinson <pbrobinson@fedoraproject.org> - 2022.01-0.2.rc4
|
||||
- Update to 2022.01 RC4
|
||||
|
||||
|
@ -0,0 +1,178 @@
|
||||
From patchwork Wed Dec 22 22:51:26 2021
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Patchwork-Submitter: Thomas Watson <twatson52@icloud.com>
|
||||
X-Patchwork-Id: 1572368
|
||||
X-Patchwork-Delegate: marek.vasut@gmail.com
|
||||
Return-Path: <u-boot-bounces@lists.denx.de>
|
||||
X-Original-To: incoming@patchwork.ozlabs.org
|
||||
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
|
||||
Authentication-Results: bilbo.ozlabs.org;
|
||||
dkim=pass (2048-bit key;
|
||||
unprotected) header.d=icloud.com header.i=@icloud.com header.a=rsa-sha256
|
||||
header.s=1a1hai header.b=SkTQ1vLj;
|
||||
dkim-atps=neutral
|
||||
Authentication-Results: ozlabs.org;
|
||||
spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
|
||||
(client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;
|
||||
envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
|
||||
Received: from phobos.denx.de (phobos.denx.de
|
||||
[IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||
key-exchange X25519 server-signature RSA-PSS (4096 bits))
|
||||
(No client certificate requested)
|
||||
by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JK8Mc4B31z9s0r
|
||||
for <incoming@patchwork.ozlabs.org>; Thu, 23 Dec 2021 10:16:10 +1100 (AEDT)
|
||||
Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
|
||||
by phobos.denx.de (Postfix) with ESMTP id D051D830C3;
|
||||
Thu, 23 Dec 2021 00:15:59 +0100 (CET)
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dmarc=pass (p=quarantine dis=none) header.from=icloud.com
|
||||
Authentication-Results: phobos.denx.de;
|
||||
spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dkim=pass (2048-bit key;
|
||||
unprotected) header.d=icloud.com header.i=@icloud.com header.b="SkTQ1vLj";
|
||||
dkim-atps=neutral
|
||||
Received: by phobos.denx.de (Postfix, from userid 109)
|
||||
id 0DA67830F5; Wed, 22 Dec 2021 23:52:26 +0100 (CET)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,
|
||||
DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT,
|
||||
FREEMAIL_FROM,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=ham
|
||||
autolearn_force=no version=3.4.2
|
||||
Received: from st43p00im-ztbu10073601.me.com (st43p00im-ztbu10073601.me.com
|
||||
[17.58.63.184])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by phobos.denx.de (Postfix) with ESMTPS id 1598D830C2
|
||||
for <u-boot@lists.denx.de>; Wed, 22 Dec 2021 23:52:23 +0100 (CET)
|
||||
Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none)
|
||||
header.from=icloud.com
|
||||
Authentication-Results: phobos.denx.de;
|
||||
spf=pass smtp.mailfrom=twatson52@icloud.com
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com;
|
||||
s=1a1hai; t=1640213541;
|
||||
bh=9Gu/RsbBH8Lwy0caxjtXwguQwc3tOXLqzye8cafMd78=;
|
||||
h=From:To:Subject:Date:Message-Id:MIME-Version;
|
||||
b=SkTQ1vLjDZUB4S3pQ+QOuMAQs7y78hvdCVG59JmuiBtL/pLL9IskzfDYEEVxmBQ8j
|
||||
QIbZXSdaHlAH3tL3ajaqL0+IJp7J/yQ5/wpmmTsRMBdk0xcgSGilBCve35DMoKYFu1
|
||||
YSaXYI8GDtaBL5R9EGZAW6SekyeIWfyy03PQpawqJpTlqUNZuLdrr9mGRF/q2fbSHd
|
||||
Fr4qzePCKzk3GsUhdfkh8hEDS4lOGVAPa3K2mGEpK6K/+Gv3rCckgYrV5IAJQ8YpdP
|
||||
SCmRL3N03P5wkt5WiYasawJW4pcx92J2RXtyikC9fc6p67bGXkUJA+8dOtxlOyBY8E
|
||||
8TrKBWY9cvKTw==
|
||||
Received: from jacobs-p52.memphis.edu
|
||||
(99-122-90-201.lightspeed.mmphtn.sbcglobal.net [99.122.90.201])
|
||||
by st43p00im-ztbu10073601.me.com (Postfix) with ESMTPSA id 283205A0974;
|
||||
Wed, 22 Dec 2021 22:52:21 +0000 (UTC)
|
||||
From: Thomas Watson <twatson52@icloud.com>
|
||||
To: u-boot@lists.denx.de
|
||||
Cc: Thomas Watson <twatson52@icloud.com>,
|
||||
Marek Vasut <marex@denx.de>
|
||||
Subject: [PATCH v2] console: usb: kbd: Limit poll frequency to improve
|
||||
performance
|
||||
Date: Wed, 22 Dec 2021 16:51:26 -0600
|
||||
Message-Id: <20211222225124.7154-1-twatson52@icloud.com>
|
||||
X-Mailer: git-send-email 2.31.1
|
||||
MIME-Version: 1.0
|
||||
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.425, 18.0.790
|
||||
definitions=2021-12-22_02:2021-12-22,
|
||||
2021-12-22 signatures=0
|
||||
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0
|
||||
malwarescore=0
|
||||
phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0
|
||||
mlxlogscore=934 adultscore=0 classifier=spam adjust=0 reason=mlx
|
||||
scancount=1 engine=8.0.1-2009150000 definitions=main-2112220119
|
||||
X-Mailman-Approved-At: Thu, 23 Dec 2021 00:15:58 +0100
|
||||
X-BeenThere: u-boot@lists.denx.de
|
||||
X-Mailman-Version: 2.1.38
|
||||
Precedence: list
|
||||
List-Id: U-Boot discussion <u-boot.lists.denx.de>
|
||||
List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
|
||||
<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
|
||||
List-Archive: <https://lists.denx.de/pipermail/u-boot/>
|
||||
List-Post: <mailto:u-boot@lists.denx.de>
|
||||
List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
|
||||
List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
|
||||
<mailto:u-boot-request@lists.denx.de?subject=subscribe>
|
||||
Errors-To: u-boot-bounces@lists.denx.de
|
||||
Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
|
||||
X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de
|
||||
X-Virus-Status: Clean
|
||||
|
||||
Using the XHCI driver, the function `usb_kbd_poll_for_event` takes
|
||||
30-40ms to run. The exact time is dependent on the polling interval the
|
||||
keyboard requests in its descriptor, and likely cannot be significantly
|
||||
reduced without major rework to the XHCI driver.
|
||||
|
||||
The U-Boot EFI console service sets a timer to poll the keyboard every 5
|
||||
microseconds, and this timer is checked every time a block is read off
|
||||
disk. The net effect is that, on my system, loading a ~40MiB kernel and
|
||||
initrd takes about 62 seconds with a slower keyboard and 53 seconds
|
||||
with a faster one, with the vast majority of the time spent polling the
|
||||
keyboard.
|
||||
|
||||
To solve this problem, this patch adds a 20ms delay between consecutive
|
||||
calls to `usb_kbd_poll_for_event`. This is sufficient to reduce the
|
||||
total loading time to under half a second for both keyboards, and does
|
||||
not impact the perceived keystroke latency.
|
||||
|
||||
Signed-off-by: Thomas Watson <twatson52@icloud.com>
|
||||
---
|
||||
This revision wraps the comment at 80 characters and also should not
|
||||
have been corrupted by my e-mail client.
|
||||
|
||||
common/usb_kbd.c | 20 +++++++++++++++-----
|
||||
1 file changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
|
||||
index afad260d3d..5408c821b4 100644
|
||||
--- a/common/usb_kbd.c
|
||||
+++ b/common/usb_kbd.c
|
||||
@@ -118,7 +118,7 @@ struct usb_kbd_pdata {
|
||||
extern int __maybe_unused net_busy_flag;
|
||||
|
||||
/* The period of time between two calls of usb_kbd_testc(). */
|
||||
-static unsigned long __maybe_unused kbd_testc_tms;
|
||||
+static unsigned long kbd_testc_tms;
|
||||
|
||||
/* Puts character in the queue and sets up the in and out pointer. */
|
||||
static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c)
|
||||
@@ -394,21 +394,31 @@ static int usb_kbd_testc(struct stdio_dev *sdev)
|
||||
struct usb_device *usb_kbd_dev;
|
||||
struct usb_kbd_pdata *data;
|
||||
|
||||
+ /*
|
||||
+ * Polling the keyboard for an event can take dozens of milliseconds.
|
||||
+ * Add a delay between polls to avoid blocking activity which polls
|
||||
+ * rapidly, like the UEFI console timer.
|
||||
+ */
|
||||
+ unsigned long poll_delay = CONFIG_SYS_HZ / 50;
|
||||
+
|
||||
#ifdef CONFIG_CMD_NET
|
||||
/*
|
||||
* If net_busy_flag is 1, NET transfer is running,
|
||||
* then we check key-pressed every second (first check may be
|
||||
* less than 1 second) to improve TFTP booting performance.
|
||||
*/
|
||||
- if (net_busy_flag && (get_timer(kbd_testc_tms) < CONFIG_SYS_HZ))
|
||||
- return 0;
|
||||
- kbd_testc_tms = get_timer(0);
|
||||
+ if (net_busy_flag)
|
||||
+ poll_delay = CONFIG_SYS_HZ;
|
||||
#endif
|
||||
+
|
||||
dev = stdio_get_by_name(sdev->name);
|
||||
usb_kbd_dev = (struct usb_device *)dev->priv;
|
||||
data = usb_kbd_dev->privptr;
|
||||
|
||||
- usb_kbd_poll_for_event(usb_kbd_dev);
|
||||
+ if (get_timer(kbd_testc_tms) >= poll_delay) {
|
||||
+ usb_kbd_poll_for_event(usb_kbd_dev);
|
||||
+ kbd_testc_tms = get_timer(0);
|
||||
+ }
|
||||
|
||||
return !(data->usb_in_pointer == data->usb_out_pointer);
|
||||
}
|
556
v3-phy-Track-power-on-and-init-counts-in-uclass.patch
Normal file
556
v3-phy-Track-power-on-and-init-counts-in-uclass.patch
Normal file
@ -0,0 +1,556 @@
|
||||
From patchwork Thu Dec 30 19:36:51 2021
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Patchwork-Submitter: Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
||||
X-Patchwork-Id: 1574229
|
||||
Return-Path: <u-boot-bounces@lists.denx.de>
|
||||
X-Original-To: incoming@patchwork.ozlabs.org
|
||||
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
|
||||
Authentication-Results: bilbo.ozlabs.org;
|
||||
dkim=pass (2048-bit key;
|
||||
unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256
|
||||
header.s=20210112 header.b=cK81Bg2I;
|
||||
dkim-atps=neutral
|
||||
Authentication-Results: ozlabs.org;
|
||||
spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
|
||||
(client-ip=85.214.62.61; helo=phobos.denx.de;
|
||||
envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
|
||||
Received: from phobos.denx.de (phobos.denx.de [85.214.62.61])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||
key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest
|
||||
SHA256)
|
||||
(No client certificate requested)
|
||||
by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JPz7X0bFyz9s0r
|
||||
for <incoming@patchwork.ozlabs.org>; Fri, 31 Dec 2021 06:37:26 +1100 (AEDT)
|
||||
Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
|
||||
by phobos.denx.de (Postfix) with ESMTP id 0F0B2804C8;
|
||||
Thu, 30 Dec 2021 20:37:18 +0100 (CET)
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dmarc=pass (p=none dis=none) header.from=gmail.com
|
||||
Authentication-Results: phobos.denx.de;
|
||||
spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dkim=pass (2048-bit key;
|
||||
unprotected) header.d=gmail.com header.i=@gmail.com header.b="cK81Bg2I";
|
||||
dkim-atps=neutral
|
||||
Received: by phobos.denx.de (Postfix, from userid 109)
|
||||
id AEDBD811BB; Thu, 30 Dec 2021 20:37:16 +0100 (CET)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,
|
||||
DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE,
|
||||
SPF_PASS autolearn=ham autolearn_force=no version=3.4.2
|
||||
Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com
|
||||
[IPv6:2a00:1450:4864:20::52d])
|
||||
(using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))
|
||||
(No client certificate requested)
|
||||
by phobos.denx.de (Postfix) with ESMTPS id DFF2E81184
|
||||
for <u-boot@lists.denx.de>; Thu, 30 Dec 2021 20:37:12 +0100 (CET)
|
||||
Authentication-Results: phobos.denx.de;
|
||||
dmarc=pass (p=none dis=none) header.from=gmail.com
|
||||
Authentication-Results: phobos.denx.de;
|
||||
spf=pass smtp.mailfrom=alpernebiyasak@gmail.com
|
||||
Received: by mail-ed1-x52d.google.com with SMTP id x15so101755439edv.1
|
||||
for <u-boot@lists.denx.de>; Thu, 30 Dec 2021 11:37:12 -0800 (PST)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
|
||||
h=from:to:cc:subject:date:message-id:mime-version
|
||||
:content-transfer-encoding;
|
||||
bh=o95ZU+qnz+og5Dat/q/VTF9YYww8PBCzA+ABZSXXolA=;
|
||||
b=cK81Bg2IxzE3JOMrYmY71vV4AwQM5u4QfMs8UyJlfcZ1/+ES5KYKqOqFfpKFnoHmhj
|
||||
dExR4ZG55QcIoQvX2QjSsh5m4oqpvqaJRCHmG8MNFscusyVvJvZidSC4A6MsKFm/xDhO
|
||||
6trpXrffdaK4mrMLrlpNwtX4zvGFrQ8BfwsRN6vkYzissuXrMEHMB8gnY2z9FMvnQepB
|
||||
suI6C2oVprB/tyo+iFw6q9vnxnFxbNMaU6Kbevqekv1lG4k2bAKTTcgLTUETQ8fbYtPt
|
||||
8f1NCTBCNS2fRO0fx1tGhK9Ymw8hLuO8f0Bzrj+ZixtmYiR9QRbZU/OYM/dvO0SVCQAo
|
||||
6/cA==
|
||||
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
|
||||
d=1e100.net; s=20210112;
|
||||
h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version
|
||||
:content-transfer-encoding;
|
||||
bh=o95ZU+qnz+og5Dat/q/VTF9YYww8PBCzA+ABZSXXolA=;
|
||||
b=2fadn4WWHwuQAEwrV9KPDpx5of4g6aU2eu41AiBB7973C1mGKZc9wITb6nQTG1VesX
|
||||
2N/LdQdgK6TKFXUcJnujd8Kh2+aTbmxK5aa4CT48DOc+FjvNWln6+GW3Cu2NYVuM1P+P
|
||||
AC8aeVMpezmVLZMnUFgc46wf/9vd/U0SG6I5Iv3/89f4IjiajTPgp2yZZSSBPmK0QQoJ
|
||||
y+w0KYKeICH1Q/IiYUvQjgEvWY3DdK6si2QT+UO9I0xo+gkK3CwaEpVIVQ6HC75FEPLZ
|
||||
HRLoHTUYGCu30AZsXToNOOR/eX5cjyzON64fUyBqO69BiI43Hh9x8usz+VdI8B2LcOT+
|
||||
7WuQ==
|
||||
X-Gm-Message-State: AOAM533kWmvGofl0Ku1us2MhhVDF3yCz3i6FyVMhb7qhAA3dYLiAjW43
|
||||
WXFRC/b1oHVMXZDbmQz2s6c0KYDb8KI=
|
||||
X-Google-Smtp-Source:
|
||||
ABdhPJwyxnfOXQuo28I9zKzDtG6KUXF845MW0EPlPCt/upF5MoMLbHxEazYxf+uas6Ce8af3fcfE5g==
|
||||
X-Received: by 2002:a50:d74e:: with SMTP id
|
||||
i14mr31016125edj.243.1640893032437;
|
||||
Thu, 30 Dec 2021 11:37:12 -0800 (PST)
|
||||
Received: from localhost.localdomain ([178.233.26.119])
|
||||
by smtp.gmail.com with ESMTPSA id y13sm9836432edq.77.2021.12.30.11.37.09
|
||||
(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
|
||||
Thu, 30 Dec 2021 11:37:11 -0800 (PST)
|
||||
From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
||||
To: u-boot@lists.denx.de
|
||||
Cc: Frank Wang <frank.wang@rock-chips.com>,
|
||||
Andre Przywara <andre.przywara@arm.com>, Tom Rini <trini@konsulko.com>,
|
||||
Simon Glass <sjg@chromium.org>, Neil Armstrong <narmstrong@baylibre.com>,
|
||||
Grant Likely <grant.likely@arm.com>,
|
||||
Joe Hershberger <joe.hershberger@ni.com>,
|
||||
Peter Robinson <pbrobinson@gmail.com>,
|
||||
Jagan Teki <jagan@amarulasolutions.com>,
|
||||
Patrick Delaunay <patrick.delaunay@foss.st.com>,
|
||||
Grant Likely <grant.likely@secretlab.ca>, Icenowy Zheng <icenowy@aosc.io>,
|
||||
Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
||||
Subject: [PATCH v3] phy: Track power-on and init counts in uclass
|
||||
Date: Thu, 30 Dec 2021 22:36:51 +0300
|
||||
Message-Id: <20211230193652.33514-1-alpernebiyasak@gmail.com>
|
||||
X-Mailer: git-send-email 2.34.1
|
||||
MIME-Version: 1.0
|
||||
X-BeenThere: u-boot@lists.denx.de
|
||||
X-Mailman-Version: 2.1.38
|
||||
Precedence: list
|
||||
List-Id: U-Boot discussion <u-boot.lists.denx.de>
|
||||
List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
|
||||
<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
|
||||
List-Archive: <https://lists.denx.de/pipermail/u-boot/>
|
||||
List-Post: <mailto:u-boot@lists.denx.de>
|
||||
List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
|
||||
List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
|
||||
<mailto:u-boot-request@lists.denx.de?subject=subscribe>
|
||||
Errors-To: u-boot-bounces@lists.denx.de
|
||||
Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
|
||||
X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de
|
||||
X-Virus-Status: Clean
|
||||
|
||||
On boards using the RK3399 SoC, the USB OHCI and EHCI controllers share
|
||||
the same PHY device instance. While these controllers are being stopped
|
||||
they both attempt to power-off and deinitialize it, but trying to
|
||||
power-off the deinitialized PHY device results in a hang. This usually
|
||||
happens just before booting an OS, and can be explicitly triggered by
|
||||
running "usb start; usb stop" in the U-Boot shell.
|
||||
|
||||
Implement a uclass-wide counting mechanism for PHY initialization and
|
||||
power state change requests, so that we don't power-off/deinitialize a
|
||||
PHY instance until all of its users want it done. The Allwinner A10 USB
|
||||
PHY driver does this counting in-driver, remove those parts in favour of
|
||||
this in-uclass implementation.
|
||||
|
||||
The sandbox PHY operations test needs some changes since the uclass will
|
||||
no longer call into the drivers for actions matching its tracked state
|
||||
(e.g. powering-off a powered-off PHY). Update that test, and add a new
|
||||
one which simulates multiple users of a single PHY.
|
||||
|
||||
The major complication here is that PHY handles aren't deduplicated per
|
||||
instance, so the obvious idea of putting the counts in the PHY handles
|
||||
don't immediately work. It seems possible to bind a child udevice per
|
||||
PHY instance to the PHY provider and deduplicate the handles in each
|
||||
child's uclass-private areas, like in the CLK framework. An alternative
|
||||
approach could be to use those bound child udevices themselves as the
|
||||
PHY handles. Instead, to avoid the architectural changes those would
|
||||
require, this patch solves things by dynamically allocating a list of
|
||||
structs (one per instance) in the provider's uclass-private area.
|
||||
|
||||
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
||||
Reviewed-by: Simon Glass <sjg@chromium.org>
|
||||
---
|
||||
|
||||
Changes in v3:
|
||||
- Add tag: "Reviewed-by: Simon Glass <sjg@chromium.org>"
|
||||
- Add comment for phy_counts struct
|
||||
|
||||
v2: https://patchwork.ozlabs.org/project/uboot/patch/20211224130549.20276-1-alpernebiyasak@gmail.com/
|
||||
|
||||
Changes in v2:
|
||||
- Rename {phy_,}id_priv -> {phy_,}counts
|
||||
- Split phy_get_uclass_priv -> phy_{alloc,get}_counts
|
||||
- Allocate counts (or return error) in generic_phy_get_by_*()
|
||||
- Remove now-unnecessary null checks for counts of valid phy handles
|
||||
|
||||
v1: https://patchwork.ozlabs.org/project/uboot/patch/20211210200124.19226-1-alpernebiyasak@gmail.com/
|
||||
|
||||
drivers/phy/allwinner/phy-sun4i-usb.c | 9 --
|
||||
drivers/phy/phy-uclass.c | 137 ++++++++++++++++++++++++++
|
||||
test/dm/phy.c | 83 +++++++++++++++-
|
||||
3 files changed, 215 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
|
||||
index ab2a5d17fcff..86c589a65fd3 100644
|
||||
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
|
||||
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
|
||||
@@ -125,7 +125,6 @@ struct sun4i_usb_phy_info {
|
||||
|
||||
struct sun4i_usb_phy_plat {
|
||||
void __iomem *pmu;
|
||||
- int power_on_count;
|
||||
int gpio_vbus;
|
||||
int gpio_vbus_det;
|
||||
int gpio_id_det;
|
||||
@@ -225,10 +224,6 @@ static int sun4i_usb_phy_power_on(struct phy *phy)
|
||||
initial_usb_scan_delay = 0;
|
||||
}
|
||||
|
||||
- usb_phy->power_on_count++;
|
||||
- if (usb_phy->power_on_count != 1)
|
||||
- return 0;
|
||||
-
|
||||
if (usb_phy->gpio_vbus >= 0)
|
||||
gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_UP);
|
||||
|
||||
@@ -240,10 +235,6 @@ static int sun4i_usb_phy_power_off(struct phy *phy)
|
||||
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
|
||||
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
|
||||
|
||||
- usb_phy->power_on_count--;
|
||||
- if (usb_phy->power_on_count != 0)
|
||||
- return 0;
|
||||
-
|
||||
if (usb_phy->gpio_vbus >= 0)
|
||||
gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_DISABLE);
|
||||
|
||||
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
|
||||
index 59683a080cd7..cec46c2c4103 100644
|
||||
--- a/drivers/phy/phy-uclass.c
|
||||
+++ b/drivers/phy/phy-uclass.c
|
||||
@@ -11,12 +11,96 @@
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/devres.h>
|
||||
#include <generic-phy.h>
|
||||
+#include <linux/list.h>
|
||||
+
|
||||
+/**
|
||||
+ * struct phy_counts - Init and power-on counts of a single PHY port
|
||||
+ *
|
||||
+ * This structure is used to keep track of PHY initialization and power
|
||||
+ * state change requests, so that we don't power off and deinitialize a
|
||||
+ * PHY instance until all of its users want it done. Otherwise, multiple
|
||||
+ * consumers using the same PHY port can cause problems (e.g. one might
|
||||
+ * call power_off() after another's exit() and hang indefinitely).
|
||||
+ *
|
||||
+ * @id: The PHY ID within a PHY provider
|
||||
+ * @power_on_count: Times generic_phy_power_on() was called for this ID
|
||||
+ * without a matching generic_phy_power_off() afterwards
|
||||
+ * @init_count: Times generic_phy_init() was called for this ID
|
||||
+ * without a matching generic_phy_exit() afterwards
|
||||
+ * @list: Handle for a linked list of these structures corresponding to
|
||||
+ * ports of the same PHY provider
|
||||
+ */
|
||||
+struct phy_counts {
|
||||
+ unsigned long id;
|
||||
+ int power_on_count;
|
||||
+ int init_count;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
|
||||
static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
|
||||
{
|
||||
return (struct phy_ops *)dev->driver->ops;
|
||||
}
|
||||
|
||||
+static struct phy_counts *phy_get_counts(struct phy *phy)
|
||||
+{
|
||||
+ struct list_head *uc_priv;
|
||||
+ struct phy_counts *counts;
|
||||
+
|
||||
+ if (!generic_phy_valid(phy))
|
||||
+ return NULL;
|
||||
+
|
||||
+ uc_priv = dev_get_uclass_priv(phy->dev);
|
||||
+ list_for_each_entry(counts, uc_priv, list)
|
||||
+ if (counts->id == phy->id)
|
||||
+ return counts;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int phy_alloc_counts(struct phy *phy)
|
||||
+{
|
||||
+ struct list_head *uc_priv;
|
||||
+ struct phy_counts *counts;
|
||||
+
|
||||
+ if (!generic_phy_valid(phy))
|
||||
+ return 0;
|
||||
+ if (phy_get_counts(phy))
|
||||
+ return 0;
|
||||
+
|
||||
+ uc_priv = dev_get_uclass_priv(phy->dev);
|
||||
+ counts = kzalloc(sizeof(*counts), GFP_KERNEL);
|
||||
+ if (!counts)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ counts->id = phy->id;
|
||||
+ counts->power_on_count = 0;
|
||||
+ counts->init_count = 0;
|
||||
+ list_add(&counts->list, uc_priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int phy_uclass_pre_probe(struct udevice *dev)
|
||||
+{
|
||||
+ struct list_head *uc_priv = dev_get_uclass_priv(dev);
|
||||
+
|
||||
+ INIT_LIST_HEAD(uc_priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int phy_uclass_pre_remove(struct udevice *dev)
|
||||
+{
|
||||
+ struct list_head *uc_priv = dev_get_uclass_priv(dev);
|
||||
+ struct phy_counts *counts, *next;
|
||||
+
|
||||
+ list_for_each_entry_safe(counts, next, uc_priv, list)
|
||||
+ kfree(counts);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int generic_phy_xlate_offs_flags(struct phy *phy,
|
||||
struct ofnode_phandle_args *args)
|
||||
{
|
||||
@@ -88,6 +172,12 @@ int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy)
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ ret = phy_alloc_counts(phy);
|
||||
+ if (ret) {
|
||||
+ debug("phy_alloc_counts() failed: %d\n", ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@@ -118,6 +208,7 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
|
||||
|
||||
int generic_phy_init(struct phy *phy)
|
||||
{
|
||||
+ struct phy_counts *counts;
|
||||
struct phy_ops const *ops;
|
||||
int ret;
|
||||
|
||||
@@ -126,10 +217,19 @@ int generic_phy_init(struct phy *phy)
|
||||
ops = phy_dev_ops(phy->dev);
|
||||
if (!ops->init)
|
||||
return 0;
|
||||
+
|
||||
+ counts = phy_get_counts(phy);
|
||||
+ if (counts->init_count > 0) {
|
||||
+ counts->init_count++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ret = ops->init(phy);
|
||||
if (ret)
|
||||
dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
|
||||
phy->dev->name, ret);
|
||||
+ else
|
||||
+ counts->init_count = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -154,6 +254,7 @@ int generic_phy_reset(struct phy *phy)
|
||||
|
||||
int generic_phy_exit(struct phy *phy)
|
||||
{
|
||||
+ struct phy_counts *counts;
|
||||
struct phy_ops const *ops;
|
||||
int ret;
|
||||
|
||||
@@ -162,16 +263,28 @@ int generic_phy_exit(struct phy *phy)
|
||||
ops = phy_dev_ops(phy->dev);
|
||||
if (!ops->exit)
|
||||
return 0;
|
||||
+
|
||||
+ counts = phy_get_counts(phy);
|
||||
+ if (counts->init_count == 0)
|
||||
+ return 0;
|
||||
+ if (counts->init_count > 1) {
|
||||
+ counts->init_count--;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ret = ops->exit(phy);
|
||||
if (ret)
|
||||
dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n",
|
||||
phy->dev->name, ret);
|
||||
+ else
|
||||
+ counts->init_count = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int generic_phy_power_on(struct phy *phy)
|
||||
{
|
||||
+ struct phy_counts *counts;
|
||||
struct phy_ops const *ops;
|
||||
int ret;
|
||||
|
||||
@@ -180,16 +293,26 @@ int generic_phy_power_on(struct phy *phy)
|
||||
ops = phy_dev_ops(phy->dev);
|
||||
if (!ops->power_on)
|
||||
return 0;
|
||||
+
|
||||
+ counts = phy_get_counts(phy);
|
||||
+ if (counts->power_on_count > 0) {
|
||||
+ counts->power_on_count++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ret = ops->power_on(phy);
|
||||
if (ret)
|
||||
dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",
|
||||
phy->dev->name, ret);
|
||||
+ else
|
||||
+ counts->power_on_count = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int generic_phy_power_off(struct phy *phy)
|
||||
{
|
||||
+ struct phy_counts *counts;
|
||||
struct phy_ops const *ops;
|
||||
int ret;
|
||||
|
||||
@@ -198,10 +321,21 @@ int generic_phy_power_off(struct phy *phy)
|
||||
ops = phy_dev_ops(phy->dev);
|
||||
if (!ops->power_off)
|
||||
return 0;
|
||||
+
|
||||
+ counts = phy_get_counts(phy);
|
||||
+ if (counts->power_on_count == 0)
|
||||
+ return 0;
|
||||
+ if (counts->power_on_count > 1) {
|
||||
+ counts->power_on_count--;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ret = ops->power_off(phy);
|
||||
if (ret)
|
||||
dev_err(phy->dev, "PHY: Failed to power off %s: %d.\n",
|
||||
phy->dev->name, ret);
|
||||
+ else
|
||||
+ counts->power_on_count = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -316,4 +450,7 @@ int generic_phy_power_off_bulk(struct phy_bulk *bulk)
|
||||
UCLASS_DRIVER(phy) = {
|
||||
.id = UCLASS_PHY,
|
||||
.name = "phy",
|
||||
+ .pre_probe = phy_uclass_pre_probe,
|
||||
+ .pre_remove = phy_uclass_pre_remove,
|
||||
+ .per_device_auto = sizeof(struct list_head),
|
||||
};
|
||||
diff --git a/test/dm/phy.c b/test/dm/phy.c
|
||||
index ecbd47bf12fd..df4c73fc701f 100644
|
||||
--- a/test/dm/phy.c
|
||||
+++ b/test/dm/phy.c
|
||||
@@ -79,12 +79,15 @@ static int dm_test_phy_ops(struct unit_test_state *uts)
|
||||
ut_assertok(generic_phy_power_off(&phy1));
|
||||
|
||||
/*
|
||||
- * test operations after exit().
|
||||
- * The sandbox phy driver does not allow it.
|
||||
+ * Test power_on() failure after exit().
|
||||
+ * The sandbox phy driver does not allow power-on/off after
|
||||
+ * exit, but the uclass counts power-on/init calls and skips
|
||||
+ * calling the driver's ops when e.g. powering off an already
|
||||
+ * powered-off phy.
|
||||
*/
|
||||
ut_assertok(generic_phy_exit(&phy1));
|
||||
ut_assert(generic_phy_power_on(&phy1) != 0);
|
||||
- ut_assert(generic_phy_power_off(&phy1) != 0);
|
||||
+ ut_assertok(generic_phy_power_off(&phy1));
|
||||
|
||||
/*
|
||||
* test normal operations again (after re-init)
|
||||
@@ -99,6 +102,17 @@ static int dm_test_phy_ops(struct unit_test_state *uts)
|
||||
*/
|
||||
ut_assertok(generic_phy_reset(&phy1));
|
||||
|
||||
+ /*
|
||||
+ * Test power_off() failure after exit().
|
||||
+ * For this we need to call exit() while the phy is powered-on,
|
||||
+ * so that the uclass actually calls the driver's power-off()
|
||||
+ * and reports the resulting failure.
|
||||
+ */
|
||||
+ ut_assertok(generic_phy_power_on(&phy1));
|
||||
+ ut_assertok(generic_phy_exit(&phy1));
|
||||
+ ut_assert(generic_phy_power_off(&phy1) != 0);
|
||||
+ ut_assertok(generic_phy_power_on(&phy1));
|
||||
+
|
||||
/* PHY2 has a known problem with power off */
|
||||
ut_assertok(generic_phy_init(&phy2));
|
||||
ut_assertok(generic_phy_power_on(&phy2));
|
||||
@@ -106,8 +120,8 @@ static int dm_test_phy_ops(struct unit_test_state *uts)
|
||||
|
||||
/* PHY3 has a known problem with power off and power on */
|
||||
ut_assertok(generic_phy_init(&phy3));
|
||||
- ut_asserteq(-EIO, generic_phy_power_off(&phy3));
|
||||
- ut_asserteq(-EIO, generic_phy_power_off(&phy3));
|
||||
+ ut_asserteq(-EIO, generic_phy_power_on(&phy3));
|
||||
+ ut_assertok(generic_phy_power_off(&phy3));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -145,3 +159,62 @@ static int dm_test_phy_bulk(struct unit_test_state *uts)
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_phy_bulk, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
+
|
||||
+static int dm_test_phy_multi_exit(struct unit_test_state *uts)
|
||||
+{
|
||||
+ struct phy phy1_method1;
|
||||
+ struct phy phy1_method2;
|
||||
+ struct phy phy1_method3;
|
||||
+ struct udevice *parent;
|
||||
+
|
||||
+ /* Get the same phy instance in 3 different ways. */
|
||||
+ ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
|
||||
+ "gen_phy_user", &parent));
|
||||
+ ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1));
|
||||
+ ut_asserteq(0, phy1_method1.id);
|
||||
+ ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method2));
|
||||
+ ut_asserteq(0, phy1_method2.id);
|
||||
+ ut_asserteq_ptr(phy1_method1.dev, phy1_method1.dev);
|
||||
+
|
||||
+ ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
|
||||
+ "gen_phy_user1", &parent));
|
||||
+ ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method3));
|
||||
+ ut_asserteq(0, phy1_method3.id);
|
||||
+ ut_asserteq_ptr(phy1_method1.dev, phy1_method3.dev);
|
||||
+
|
||||
+ /*
|
||||
+ * Test using the same PHY from different handles.
|
||||
+ * In non-test code these could be in different drivers.
|
||||
+ */
|
||||
+
|
||||
+ /*
|
||||
+ * These must only call the driver's ops at the first init()
|
||||
+ * and power_on().
|
||||
+ */
|
||||
+ ut_assertok(generic_phy_init(&phy1_method1));
|
||||
+ ut_assertok(generic_phy_init(&phy1_method2));
|
||||
+ ut_assertok(generic_phy_power_on(&phy1_method1));
|
||||
+ ut_assertok(generic_phy_power_on(&phy1_method2));
|
||||
+ ut_assertok(generic_phy_init(&phy1_method3));
|
||||
+ ut_assertok(generic_phy_power_on(&phy1_method3));
|
||||
+
|
||||
+ /*
|
||||
+ * These must not call the driver's ops as other handles still
|
||||
+ * want the PHY powered-on and initialized.
|
||||
+ */
|
||||
+ ut_assertok(generic_phy_power_off(&phy1_method3));
|
||||
+ ut_assertok(generic_phy_exit(&phy1_method3));
|
||||
+
|
||||
+ /*
|
||||
+ * We would get an error here if the generic_phy_exit() above
|
||||
+ * actually called the driver's exit(), as the sandbox driver
|
||||
+ * doesn't allow power-off() after exit().
|
||||
+ */
|
||||
+ ut_assertok(generic_phy_power_off(&phy1_method1));
|
||||
+ ut_assertok(generic_phy_power_off(&phy1_method2));
|
||||
+ ut_assertok(generic_phy_exit(&phy1_method1));
|
||||
+ ut_assertok(generic_phy_exit(&phy1_method2));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+DM_TEST(dm_test_phy_multi_exit, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
Loading…
Reference in New Issue
Block a user