From patchwork Sat May 2 09:35:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Wunderlich X-Patchwork-Id: 1281801 X-Patchwork-Delegate: marek.vasut@gmail.com Return-Path: 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=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=E5adLeZB; 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49F85n6LfYz9sPF for ; Sun, 3 May 2020 11:48:29 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6123181E71; Sun, 3 May 2020 03:47:46 +0200 (CEST) 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="E5adLeZB"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4FDA381D4A; Sat, 2 May 2020 11:35:50 +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,FREEMAIL_FROM,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) (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 844F681D30 for ; Sat, 2 May 2020 11:35:47 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=frank.wunderlich@gmail.com Received: by mail-wr1-x441.google.com with SMTP id k1so14708221wrx.4 for ; Sat, 02 May 2020 02:35:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=arfrrSMDKkPnI5WxEFQTo0qiqYh6+KtNeDTyxEK4fF8=; b=E5adLeZBuVDdvvYsbmVtA5xXMnh9kSjFf7AxRy3p1j6igRIrViaQzwf0C8ywxhX2uz Sm3zdqWwfsHI7Jb9XmiVOQhPi3j3M+CDxMTHgIvUMVPu3usnEQ4nOgbht8ooyn5bjyld nL9MCUTmw3aFtm75fPm4eplBsMReznW8Sh2tSWEFUN5T5OEEB0rSpgG51b6jX7b95J/H 5uA6873AABJq4XFCwBSiHxz9DGvtsvy/4jaUJ/VEJHre7GLMcaeSmv8aMWMGrdQv9Vfc 9ESGE3ySb6DfTDZod4Y6HA0I+IGfoFNOK/KkHfIPrbc6kuqCILqRD57sNt7ula59JLgl oHmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=arfrrSMDKkPnI5WxEFQTo0qiqYh6+KtNeDTyxEK4fF8=; b=ggNnAiUk092NhZEq9tpffKszYQgG4kJa61m61Ytd8DJk209ZEulR0DM90DmZlKNWWl 5T+ALTs2jT6Qqkmy7nF1RjTslbto98dKv5wj1bn/kZAYnTh016Ibc35NzwjZVUqRuuoZ 8PPo97W2D7vekELeqDW0WKyC6Mec9E4VymZhqf9cQJutU5O0eEDL65v0Qj0JF04lpf81 zcNJwTE7TW4MmVqtdZyGf8IrDd4NyLUOqtvz0KjRZko0Y7ZclfJKkn9dexmG06mmLuDJ WsDvT7jSdHLq3wWpo6pXLjsoOGr/ASZVyRCA4SmE7NBBzAbt1q5JZHf/2Fmj4Dsyw0Ji qn3g== X-Gm-Message-State: AGi0PuY+7LJ/5Rqsh+yJ+2fw/tupEvr3Bw5lkpLbdreiWo5dhsiz6dOG CDH1S6ii1qSkUq8kcHfwask= X-Google-Smtp-Source: APiQypKH+0s9bRZXi54VoDiW151WB9zxtDFYo5xqs6eFRnzLFeAPsQtY8i0HUAh3u9UNST3Vfqlzgg== X-Received: by 2002:adf:cd0a:: with SMTP id w10mr8264579wrm.404.1588412147110; Sat, 02 May 2020 02:35:47 -0700 (PDT) Received: from localhost.localdomain (fttx-pool-185.76.96.142.bambit.de. [185.76.96.142]) by smtp.gmail.com with ESMTPSA id l16sm8196681wrp.91.2020.05.02.02.35.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 02:35:46 -0700 (PDT) From: Frank Wunderlich X-Google-Original-From: Frank Wunderlich To: Simon Glass , Ryder Lee , Marek Vasut , Bin Meng Cc: Frank Wunderlich , Weijie Gao , GSS_MTK_Uboot_upstream , Jagan Teki , Stefan Roese , Neil Armstrong , Sam Shih , Chunfeng Yun , Jean-Jacques Hiblot , Alex Marginean , Patrick Delaunay , Lukasz Majewski , AKASHI Takahiro , Anatolij Gustschin , Ye Li , Fabio Estevam , Marcel Ziswiler , Heiko Schocher , Mark Kettenis , Adam Ford , u-boot@lists.denx.de, Masahiro Yamada , Vignesh Raghavendra Subject: [PATCH v8 03/14] phy: Add API for a bulk of phys Date: Sat, 2 May 2020 11:35:11 +0200 Message-Id: <20200502093522.3568-4-frank-w@public-files.de> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200502093522.3568-1-frank-w@public-files.de> References: <20200502093522.3568-1-frank-w@public-files.de> X-Mailman-Approved-At: Sun, 03 May 2020 03:47:25 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean From: Chunfeng Yun This patch adds a "bulk" API to the phy API in order to get/init/exit/power on/off a group of phys associated with a device. The bulk API will avoid adding a copy of the same code to manage a group of phys in drivers. Signed-off-by: Chunfeng Yun Signed-off-by: Frank Wunderlich Reviewed-by: Weijie Gao Reviewed-by: Jagan Teki --- v8: no changes v7: provide bulk init/exit/power on/off separately suggested by Jagan v6: add Reviewed-by Weijie v5: no changes v4: new patch --- drivers/phy/phy-uclass.c | 97 ++++++++++++++++++++++++++++++++++++++++ include/generic-phy.h | 92 +++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index e463b0b400..6ab78448af 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -6,6 +6,7 @@ #include #include +#include #include static inline struct phy_ops *phy_dev_ops(struct udevice *dev) @@ -167,6 +168,102 @@ int generic_phy_power_off(struct phy *phy) return ops->power_off ? ops->power_off(phy) : 0; } +int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk) +{ + int i, ret, count; + + bulk->count = 0; + + /* Return if no phy declared */ + if (!dev_read_prop(dev, "phys", NULL)) + return 0; + + count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); + if (count < 1) + return count; + + bulk->phys = devm_kcalloc(dev, count, sizeof(struct phy), GFP_KERNEL); + if (!bulk->phys) + return -ENOMEM; + + for (i = 0; i < count; i++) { + ret = generic_phy_get_by_index(dev, i, &bulk->phys[i]); + if (ret) { + pr_err("Failed to get PHY%d for %s\n", i, dev->name); + return ret; + } + bulk->count++; + } + + return 0; +} + +int generic_phy_init_bulk(struct phy_bulk *bulk) +{ + struct phy *phys = bulk->phys; + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = generic_phy_init(&phys[i]); + if (ret) { + pr_err("Can't init PHY%d\n", i); + goto phys_init_err; + } + } + + return 0; + +phys_init_err: + for (; i > 0; i--) + generic_phy_exit(&phys[i - 1]); + + return ret; +} + +int generic_phy_exit_bulk(struct phy_bulk *bulk) +{ + struct phy *phys = bulk->phys; + int i, ret = 0; + + for (i = 0; i < bulk->count; i++) + ret |= generic_phy_exit(&phys[i]); + + return ret; +} + +int generic_phy_power_on_bulk(struct phy_bulk *bulk) +{ + struct phy *phys = bulk->phys; + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = generic_phy_power_on(&phys[i]); + if (ret) { + pr_err("Can't power on PHY%d\n", i); + goto phys_poweron_err; + } + } + + return 0; + +phys_poweron_err: + for (; i > 0; i--) + generic_phy_power_off(&phys[i - 1]); + + return ret; +} + +int generic_phy_power_off_bulk(struct phy_bulk *bulk) +{ + struct phy *phys = bulk->phys; + int i, ret = 0; + + for (i = 0; i < bulk->count; i++) + ret |= generic_phy_power_off(&phys[i]); + + return ret; +} + UCLASS_DRIVER(phy) = { .id = UCLASS_PHY, .name = "phy", diff --git a/include/generic-phy.h b/include/generic-phy.h index 73537025c2..55629ae0b4 100644 --- a/include/generic-phy.h +++ b/include/generic-phy.h @@ -124,6 +124,23 @@ struct phy_ops { int (*power_off)(struct phy *phy); }; +/** + * struct phy_bulk - A handle to (allowing control of) a bulk of phys. + * + * Consumers provide storage for the phy bulk. The content of the structure is + * managed solely by the phy API. A phy bulk struct is initialized + * by "get"ing the phy bulk struct. + * The phy bulk struct is passed to all other bulk phy APIs to apply + * the API to all the phy in the bulk struct. + * + * @phys: An array of phy handles. + * @count: The number of phy handles in the phys array. + */ +struct phy_bulk { + struct phy *phys; + unsigned int count; +}; + #ifdef CONFIG_PHY /** @@ -250,6 +267,55 @@ int generic_phy_get_by_node(ofnode node, int index, struct phy *phy); int generic_phy_get_by_name(struct udevice *user, const char *phy_name, struct phy *phy); +/** + * generic_phy_get_bulk - Get all phys of a device. + * + * This looks up and gets all phys of the consumer device; each device is + * assumed to have n phys associated with it somehow, and this function finds + * and gets all of them in a separate structure. + * + * @dev: The consumer device. + * @bulk A pointer to a phy bulk struct to initialize. + * @return 0 if OK, or a negative error code. + */ +int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk); + +/** + * generic_phy_init_bulk() - Initialize all phys in a phy bulk struct. + * + * @bulk: A phy bulk struct that was previously successfully requested + * by generic_phy_get_bulk(). + * @return 0 if OK, or negative error code. + */ +int generic_phy_init_bulk(struct phy_bulk *bulk); + +/** + * generic_phy_exit_bulk() - de-initialize all phys in a phy bulk struct. + * + * @bulk: A phy bulk struct that was previously successfully requested + * by generic_phy_get_bulk(). + * @return 0 if OK, or negative error code. + */ +int generic_phy_exit_bulk(struct phy_bulk *bulk); + +/** + * generic_phy_power_on_bulk() - Power on all phys in a phy bulk struct. + * + * @bulk: A phy bulk struct that was previously successfully requested + * by generic_phy_get_bulk(). + * @return 0 if OK, or negative error code. + */ +int generic_phy_power_on_bulk(struct phy_bulk *bulk); + +/** + * generic_phy_power_off_bulk() - Power off all phys in a phy bulk struct. + * + * @bulk: A phy bulk struct that was previously successfully requested + * by generic_phy_get_bulk(). + * @return 0 if OK, or negative error code. + */ +int generic_phy_power_off_bulk(struct phy_bulk *bulk); + #else /* CONFIG_PHY */ static inline int generic_phy_init(struct phy *phy) @@ -289,6 +355,32 @@ static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_ return 0; } +static inline int +generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk) +{ + return 0; +} + +static inline int generic_phy_init_bulk(struct phy_bulk *bulk) +{ + return 0; +} + +static inline int generic_phy_exit_bulk(struct phy_bulk *bulk) +{ + return 0; +} + +static inline int generic_phy_power_on_bulk(struct phy_bulk *bulk) +{ + return 0; +} + +static inline int generic_phy_power_off_bulk(struct phy_bulk *bulk) +{ + return 0; +} + #endif /* CONFIG_PHY */ /**