From nobody Thu Sep 24 14:25:57 2026 Received: from mail-pj2-f19.google.com (mail-pj2-f19.google.com [74.125.227.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EEF63803F7 for ; Wed, 23 Sep 2026 02:34:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130844; cv=none; b=UrVZJFpFFYceqi6vdw4cvr2jlZ9BSCxYQZYvIGcqIKPIB01dVxJQ1tjnBILfXosu0O9Znt+8e8gdg7W0LQqtwFWEUoSLkADwuhCwa5eB0wgHtl5h2+uBxLbvcIcwknZ/RsEQJKD9qe6vQfuwoOVNK0x/xcF0h6AOHYDYzbwxnAU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130844; c=relaxed/simple; bh=NINNbjPJn/WUw0YRVDeoPVp/IxOxirFTB3dkvBGrbro=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=beGYh2t9LU6htBN2OyL667kqSTRRS4xZSMtQkX/rjIYibut+At2bebLZjmX2Yc7P4xT0ST8jLX2wNeUPSc5SrubG6smVXCAVhvf2mFXVsA6Ku23BeA4X0XAMIWofCINb4ZjZeG/p5Lg4apMH4JGsQtbcpQBmXiKZG7n1H0KmoJY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XrjxhybO; arc=none smtp.client-ip=74.125.227.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XrjxhybO" Received: by mail-pj2-f19.google.com with SMTP id d9443c01a7336-2db18fe433fso2160875ad.2 for ; Tue, 22 Sep 2026 19:34:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790130843; x=1790735643; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=igoxe3cxGkJq4SLiQXpcx4KeGIWifNJAVf3ouJtaOBU=; b=XrjxhybOANBUzo/zf3D5we5VtNyGhCC3Kad47Cui2VscThPKMhmKqDwebCovaYy20H OOwqNIQ37Egy8/wlbYYdHss+Dtcp/dZAE5m7y5uOei1DzoALkFL0XKpMjMtuu7pknOu5 8+Su1rLo8G9J2TSaS00SSwIfawiTJOni8zT+bmIG0XE9SMLCVk0ojVMwipEwi7P/InbP K77Au5iVHH0i4tTS9RwiPfk+tc3odqQk40de+FFXxbds+s9NvJx0QvCSabLajgoOEo4s n2Yl1hMmaDI5tr1agZpx2/rOPAlk9VWwO7S9LlKIWg+fL/bcRiihXIhEaEI5l0oQr37k //Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790130843; x=1790735643; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=igoxe3cxGkJq4SLiQXpcx4KeGIWifNJAVf3ouJtaOBU=; b=R04lSJ0xmEjkmX40+ij1dWhtY6B9SHacL0m2BpldBRGiGNnjy2mi3TfDktaulHpts/ 66ROiVyN1rjJkptkTHfV0zhw9re2EgobtVnMZtKO7qijMjRfLcFmTjb3AskvSxs69uiv uWOaYtudMtTNHIU/HDrk7ahKaTHF2hEw49CgWYXOLEs9da4hdRu8vA38XYbZXJniVVAM J6fkQ+7NRF704E7xvpYrRhjOqb9/oWRWGcERegFcZEkjNeZmX7Bd0KC6NtJ9U9EHz/lj tCoeSFFYPs6sU55oF7sKflL5mLJ3wwJsHPetwrEqO5THu09ZwslBJo+gEpzB/SNKEDy+ OW2w== X-Forwarded-Encrypted: i=1; AKwUvBx7kf/Ag8lK7rP3JJ5+c0MVYbzYEcPl6Sy2TVEmsHJZqu35AUHI1C15IsHSmuo8ukQyNjPCnzOwuEsWhAk=@vger.kernel.org X-Gm-Message-State: AFuF++m8OIPKRDminLEwNt8r6T0Tkv+bpM1WnX7pPt5X7zWLcu0c2Usi h+p58grY+YSY1uY4IT8YTf58GMKkPIThT3vR7xLeQyJW0OHvxZtYg0me X-Gm-Gg: AYBFou1hZv1QcKQTtIUuH9ci0enKcSNuH6y747Ff0nN+Hrc4AF0bLgC+AzkfGCfkTTD Xu6KbXU3yJrcWvOXLfH2cNCTfZDTDPnumS6kf2f/eazBN09Nx2Z8og234NHGztxi1lD0PtI9OFZ 49D0zT7eAMSBsexsE970ZjZ85Dh/klLC0VhY3WXnKT56AQ759V/pkgSYjo5PPpFk9zcPzsv2JhS iX1Q2ip8BboqPEVV6aNIhk73SBnEfq9ghU93MFerb9SW6hMV8/O1ord2CsDqoRNYES2L4fDs/ky DFwaeacu0JaL/rzMX7cq/6YMzB0LPShfZ1ICquTQH1TjPa6280DBJeJEAEQYW/8rtYDG+pDgMQG eCCQJqQuItvjjdZFIhO8Yrq+5eEcAAaASZmej6TCrkMTWWq6nPquAqCHVMx4WzWVCsKREY7hoCI il5TCOVYOiyWd1jrfatAS40/8gjcGMdUXs1WbhpwiO457eXJxVkrfjscWx7j+fJwVhDSAxF6jkD Ka3/iA= X-Received: by 2002:a17:903:1b4c:b0:2db:2427:97d5 with SMTP id d9443c01a7336-2df69d3704dmr11204435ad.4.1790130842671; Tue, 22 Sep 2026 19:34:02 -0700 (PDT) Received: from localhost ([2001:19f0:8000:3e6e:5400:6ff:fe38:3d01]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2df6a5f79aesm3182785ad.74.2026.09.22.19.34.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 19:34:02 -0700 (PDT) From: Inochi Amaoto To: Jonathan Corbet , Shuah Khan , Randy Dunlap , Vinod Koul , Neil Armstrong , Manivannan Sadhasivam , Rhys Tumelty , Inochi Amaoto Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, Yixun Lan , Longbin Li , Andy Shevchenko Subject: [PATCH v3 1/5] phy: core: Add common helper to add phy phandle device link Date: Wed, 23 Sep 2026 10:32:59 +0800 Message-ID: <20260923023304.78428-2-inochiama@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923023304.78428-1-inochiama@gmail.com> References: <20260923023304.78428-1-inochiama@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" It is very common for adding a device link for phy phandle for device managed phy helper functions. So add a common helper for future reuse. Signed-off-by: Inochi Amaoto Reviewed-by: Andy Shevchenko --- drivers/phy/phy-core.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 21aaf2f76e53..7be649f14797 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -606,6 +606,27 @@ int phy_validate(struct phy *phy, enum phy_mode mode, = int submode, } EXPORT_SYMBOL_GPL(phy_validate); =20 +/** + * phy_add_device_link() - Associate the phy with the device + * @dev: the device consuming the PHY + * @phy: the PHY supplied to @dev + * + * Add a device link with @dev as the consumer and @phy as the + * PHY supplier. + */ +static void phy_add_device_link(struct device *dev, struct phy *phy) +{ + struct device_link *link; + + if (!phy) + return; + + link =3D device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); + if (!link) + dev_dbg(dev, "failed to create device link to %s\n", + dev_name(phy->dev.parent)); +} + /** * _of_phy_get() - lookup and obtain a reference to a phy by phandle * @np: device_node for which to get the phy @@ -784,7 +805,6 @@ struct phy *phy_get(struct device *dev, const char *str= ing) { int index =3D 0; struct phy *phy; - struct device_link *link; =20 if (dev->of_node) { if (string) @@ -808,10 +828,7 @@ struct phy *phy_get(struct device *dev, const char *st= ring) =20 get_device(&phy->dev); =20 - link =3D device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); - if (!link) - dev_dbg(dev, "failed to create device link to %s\n", - dev_name(phy->dev.parent)); + phy_add_device_link(dev, phy); =20 return phy; } @@ -885,7 +902,6 @@ struct phy *devm_of_phy_get(struct device *dev, struct = device_node *np, const char *con_id) { struct phy **ptr, *phy; - struct device_link *link; =20 ptr =3D devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) @@ -900,10 +916,7 @@ struct phy *devm_of_phy_get(struct device *dev, struct= device_node *np, return phy; } =20 - link =3D device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); - if (!link) - dev_dbg(dev, "failed to create device link to %s\n", - dev_name(phy->dev.parent)); + phy_add_device_link(dev, phy); =20 return phy; } @@ -955,7 +968,6 @@ struct phy *devm_of_phy_get_by_index(struct device *dev= , struct device_node *np, int index) { struct phy **ptr, *phy; - struct device_link *link; =20 ptr =3D devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) @@ -977,10 +989,7 @@ struct phy *devm_of_phy_get_by_index(struct device *de= v, struct device_node *np, *ptr =3D phy; devres_add(dev, ptr); =20 - link =3D device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); - if (!link) - dev_dbg(dev, "failed to create device link to %s\n", - dev_name(phy->dev.parent)); + phy_add_device_link(dev, phy); =20 return phy; } --=20 2.55.0 From nobody Thu Sep 24 14:25:57 2026 Received: from mail-pj2-f42.google.com (mail-pj2-f42.google.com [74.125.227.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70A2A3815D9 for ; Wed, 23 Sep 2026 02:34:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130849; cv=none; b=kfnrY432ytkLbu6fEVDBm3abTzV12DuOZdnt9nqj+di/B+xd994IMHBuhrKzqPugoSPtHGZMYDynOBEmX1UvjHj0qD9SINP3Fpw6yYhsMhax5rhFCEs/pJFvlFOcZ8P9PRpbK459/Wu37+hHWyqzWljNnqoNX5kHuAmv+w6isBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130849; c=relaxed/simple; bh=/5Y2a7OHDrZ6jahngk9hKXSydFbk7n3qDMauoI5sWJo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=obQ3aK0+f5GR0Jpr26lcfy1OFEyH1MQkv8pXupV7Eiy0fRI0h97yUkFYQahChceCcqWPOnGBC7pKiuvT/UUWA9mnjUfDq6dLIudo0d+zhDt+avXo3f8IaIJXAQEGRCV2KLVxQVREATknhCB1nOTzJwKu0g1YZWsSncr+bPNzsfw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NNSUqtry; arc=none smtp.client-ip=74.125.227.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NNSUqtry" Received: by mail-pj2-f42.google.com with SMTP id 98e67ed59e1d1-398cb5615deso368312a91.3 for ; Tue, 22 Sep 2026 19:34:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790130847; x=1790735647; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OPE7PSkJ4NrPw8zuJEf70/v8WMud7mVFynWgRXYCG4A=; b=NNSUqtry4UjppRpEcwQNyJcu9BJpCH7o73Mms3GzsFbCdVlWMwX66mfzX2zeoLW1Dc nF9+0boWG9NnR6jyejGBmQmS6pbwZAyXgRLEc+E5tRWEi++2PfMfvcW5Q9D84crtf/0p 4Sz5/unm3MXgM7ovaqqFLdpOvNnoBgAcJ2iDxQCk3sflaUkFKB0uuKsWcFTGzxjWk0KX elADIaly82fm4LXrHppfXPqny8XO5B1Hy9F2jq9cN/WuWqZGz/nCoEXm7VG9TEDZZZxA OydBwarDYSXqYiJFkz6ECGduYvLmADOWbhf6XyX+FHkv1nj5xBmjDm8jrppQyjd4wl2z GEhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790130847; x=1790735647; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OPE7PSkJ4NrPw8zuJEf70/v8WMud7mVFynWgRXYCG4A=; b=EE4LEmJSMb0kb6tW4YPt1vWdZCIozIGS9SR9Mbwek1h6YSP7ozmaYxUjAT4myA/bsH MJH6tYfLGwCum5ihtGb4Zr7J8mg13AaTzrSnd4blHnEsXlsrCXGSCbFiIHEyo+IHTSq0 vVxYL6SqkvwK0VqGCvexEw71kocbupd3X0huUe+VzeA4mET1qU28D0+VQVfwrWtjT2ZF +w7H4qCnt2fXDNolnrBU9T23g7rPv6QHPK53T7VdtKxFW1ypXX8W5lGxEin5NAk3jgrD zrgD15XG9eg5WZS2mgfro3DFh1cEUd0ipdobCq8/s+jFOHJKQLVbX7cbcyFVmdAvGnmZ jwuw== X-Forwarded-Encrypted: i=1; AKwUvBxKX/dSUaECJhHHrzgis6PmmCu2DJ16nyvdzqc36fRlggWvI6w7TYQ8tEH1CXEIiuSOjnLEUW0s5HynhKE=@vger.kernel.org X-Gm-Message-State: AFuF++lXpisfeQggtgjtAiip6J29zpuHTyvS2BxTKMIjtSiEPJYUGBfG CKX8h/nQX+efBNmd8M5KbD/rIgLQHLNsvnBo9K6aluTQPj8KA40e5yAd X-Gm-Gg: AYBFou1Hu8IrI2mreVczMIMT5JNsyfstxZq4huizcw2gb2ljpf305uO+P89JCCAgNYr ofh5pV/WlDRiM8Ko5WFrDNOd1EH/BN7R82EnuctACCCpUYyApBJDAPTaQMU0plfugQ3R6HRzVCo A6f41boFfrQHBYaK6j5kB4V51KgKOLCIW+fIYbAu9PkSveCeEhLjL/UgVWM7jeSyyyR544OGjTq WqESFwb0e+qla9PJA+bE3Cv1wSIXhmNb5+xbebl7iWE3FsLCofXScCZpJznHk4THdblUKqOxt+o oZkCY5jgrJhamI3bWzWuq+xXdlHe/+j+GsQUXjy4Phm9ROWz14RlMgnnO3T6KP2StNVJGb3ZUME 0iAjjG1Yvk2GT8Cc4eouRs2zRRX/PJJ6mvjoJAXYxEPPVfR869dSrff6CQSPX/6Ymz/1d/05FgI CMJmE93Vgyj+ukWRgI6PWkSwSd+IHTszKGZK57RHXaCEB8DJ8n+g0WgM05orlIrW/KZ0tDc/Dt/ DyKODc= X-Received: by 2002:a17:90b:2d4c:b0:39e:6d82:dca with SMTP id 98e67ed59e1d1-3a07e56dc06mr1100081a91.30.1790130846753; Tue, 22 Sep 2026 19:34:06 -0700 (PDT) Received: from localhost ([2001:19f0:8000:3e6e:5400:6ff:fe38:3d01]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3a07ddae723sm2076574a91.5.2026.09.22.19.34.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 19:34:06 -0700 (PDT) From: Inochi Amaoto To: Jonathan Corbet , Shuah Khan , Randy Dunlap , Vinod Koul , Neil Armstrong , Manivannan Sadhasivam , Rhys Tumelty , Inochi Amaoto Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, Yixun Lan , Longbin Li , Andy Shevchenko Subject: [PATCH v3 2/5] phy: core: Add common helper for get phy phandle by index Date: Wed, 23 Sep 2026 10:33:00 +0800 Message-ID: <20260923023304.78428-3-inochiama@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923023304.78428-1-inochiama@gmail.com> References: <20260923023304.78428-1-inochiama@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Two phy helpers use index to get phy phandle of a device node, add a common function for the future reuse. Signed-off-by: Inochi Amaoto Reviewed-by: Andy Shevchenko --- drivers/phy/phy-core.c | 51 +++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 7be649f14797..8fbaea003b90 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -682,33 +682,49 @@ static struct phy *_of_phy_get(struct device_node *np= , int index) return phy; } =20 +/** + * of_phy_get_by_index() - lookup and obtain a reference to a phy using a + * device_node by index. + * @np: device_node for which to get the phy + * @index: index of the phy from device's point of view + * + * Returns: the phy device, after getting a refcount to it; or + * -ENODEV if there is no such phy. The caller is responsible for + * calling of_phy_put() to release that count. + */ +static struct phy *of_phy_get_by_index(struct device_node *np, int index) +{ + struct phy *phy; + + phy =3D _of_phy_get(np, index); + if (IS_ERR(phy)) + return phy; + + if (!try_module_get(phy->ops->owner)) + return ERR_PTR(-EPROBE_DEFER); + + get_device(&phy->dev); + + return phy; +} + /** * of_phy_get() - lookup and obtain a reference to a phy using a device_no= de. * @np: device_node for which to get the phy * @con_id: name of the phy from device's point of view * - * Returns the phy driver, after getting a refcount to it; or + * Returns: the phy device, after getting a refcount to it; or * -ENODEV if there is no such phy. The caller is responsible for * calling of_phy_put() to release that count. */ struct phy *of_phy_get(struct device_node *np, const char *con_id) { - struct phy *phy =3D NULL; int index =3D 0; =20 if (con_id) index =3D of_property_match_string(np, "phy-names", con_id); =20 - phy =3D _of_phy_get(np, index); - if (IS_ERR(phy)) - return phy; - - if (!try_module_get(phy->ops->owner)) - return ERR_PTR(-EPROBE_DEFER); - - get_device(&phy->dev); - - return phy; + return of_phy_get_by_index(np, index); } EXPORT_SYMBOL_GPL(of_phy_get); =20 @@ -958,7 +974,7 @@ EXPORT_SYMBOL_GPL(devm_of_phy_optional_get); * @np: node containing the phy * @index: index of the phy * - * Gets the phy using _of_phy_get(), then gets a refcount to it, + * Gets the phy using of_phy_get_by_index(), then gets a refcount to it, * and associates a device with it using devres. On driver detach, * release function is invoked on the devres data, * then, devres data is freed. @@ -973,19 +989,12 @@ struct phy *devm_of_phy_get_by_index(struct device *d= ev, struct device_node *np, if (!ptr) return ERR_PTR(-ENOMEM); =20 - phy =3D _of_phy_get(np, index); + phy =3D of_phy_get_by_index(np, index); if (IS_ERR(phy)) { devres_free(ptr); return phy; } =20 - if (!try_module_get(phy->ops->owner)) { - devres_free(ptr); - return ERR_PTR(-EPROBE_DEFER); - } - - get_device(&phy->dev); - *ptr =3D phy; devres_add(dev, ptr); =20 --=20 2.55.0 From nobody Thu Sep 24 14:25:57 2026 Received: from mail-pj2-f42.google.com (mail-pj2-f42.google.com [74.125.227.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70A0D3803F7 for ; Wed, 23 Sep 2026 02:34:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130857; cv=none; b=eZ3QTBglyxS2z5G9bIk9PAPSHv7ZuQQIvlv/JXqiHcK+KTaVwzooDd7rpw3EYaZtcYuSyZrX8BHEIzQX5xjNd8lyh3sIKu0avG5U7sr65YcjHMQZLNDyWYFq3w0CXZzO55+hIbi0xNb1aLWkozoXGbRh/F79pqj7ZuXnhBHOItM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130857; c=relaxed/simple; bh=OZgQEFvU5+/DbzdlPy5+1h2N0KFyrBwZO9/fwi7cA5E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CHMKX6RUXwb0KHI8KJMzrTSjUhsp5j3GiRueFsijGOBhRZicAxTsWGYFNhXF4m34yuRR22hJVoumLl4Olj/7RPn9uR++pIt66iVfM3rW9TvDL5LvehFj6QsUXVV6AkFNa9+zfeLW+uzado68pFNCfIjGs4kP7/l8i9yIouGGQM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LejNsAu0; arc=none smtp.client-ip=74.125.227.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LejNsAu0" Received: by mail-pj2-f42.google.com with SMTP id 98e67ed59e1d1-398cb5615deso368352a91.3 for ; Tue, 22 Sep 2026 19:34:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790130851; x=1790735651; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=RVt+Q6vf6BkSb3Obq200XC2a8MA/3pBxsRhoBaJSQWk=; b=LejNsAu0bHcxGBmFXiVqpZiaaycgMkbO9xa9ig1duD0g9GLD/yK6MHhbHezrzxncx6 cyxmcM4pxPT0c42xQIxdKNbTaQ52YOP1bCE/ERu3M390e7Hbhxhcin9YhufNj62DG/kw OYdnkWNtVJqdXoQITX1l8pk0OJf9HzN35QMB0xijbRJ+noUrJ4UWZdKs+QrG7SvJNcfe NOzGNh2hOUnZy3DfDKEMA9wccqJYnHsZTUpyoQbeyHk9VHcZ3SFsac9176dtn8HHwinC LBNcdhNtzcVa4ZMhBuEUYD9t2L9KpVSLVZ7J1L6mRWyIR4s1uM+GhlXZaYA6ViAdrEk/ 4v8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790130851; x=1790735651; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=RVt+Q6vf6BkSb3Obq200XC2a8MA/3pBxsRhoBaJSQWk=; b=06nP/W1Anx6Pz1d/dlWixDd8o0+sOE8hQtvrw6lN3y9it97U6s/jBZztg8p4a2PA4W H6yL+60tN2Y2X5+/Q1PaDJMg20UCRIpCJK5YkV0aJYI5JWwyZbcDRjk0qJs7F1mAerhd s/LwQRI0iUaQ8cTpixzaoNo7K+TltcS6PmVGdsxrrpfhLyW4ohdGUL+dVktl1RW/Z37D g2fT7WPZwxzdvmV8N7sO0msDJlhFVEfBBmRkEbIL7yIcZeDnAboUQtfX3UxOWfOqeD/z 10BtxRWDxc/5RqkQSEEgMRC1+U+gFunAaAkx6Eu7KWiPst2jX3T0EiwtnRnuTw5inrup w7ng== X-Forwarded-Encrypted: i=1; AKwUvBzefFfsgtNMTv+S3v+X8/qKsQaCTNg1FLf0MXI6/s/gDnvuEOX99culs660pXHGj112ENVFs9AEDercm58=@vger.kernel.org X-Gm-Message-State: AFuF++k66ezUBMS5qb3fGO5GJw1UqEoOKj4vDS42nlylC3oq3mK4mqhI fOUr4UQyZ0Q+Rvni+2R6mVhMuW06lvfNm7g/rxDpVQuRqwQQ9yx/iOII X-Gm-Gg: AYBFou2+0UZFbKtkhNqaI8RkJQoyCjh5/DvbcL1Jx2VWJzsN5+f/nOq+j5kJKOkS8+w RTFQk90xGSmgQSgOD+bfhHe6KOUwd+BaGGmjgoA6QgsEK7xWmLaGS8SX295cnDWJgjCSTqFKYfD q6iGI9zt/uVIbIOSeMBmbkKKhSrMDNlvUVxLYejwymNi5L4oxoqYcBxTSSFbM4Dl6c1ajnZ5E5F CtMQRml0ieyT0MfsAWiTASSoDmg8eNxQpnAUnYdncmIEuCqgccMMYgJ1RC9wumD3wrUIvbMUzri W9eZ5UXRqN+LAAWQvuPiG2pXagUDgpzWt53r6hDgZdC8gRRS9kVa3etcfcpQGbSCivGFnGCfymm ucIRc5j1LizZru5Zala69zn7BikfdFg9PoS9YItY71U1d7iajErUSz/UYNeXXmUA2zqBTM+5Yrw ZHLs23ddm6gVoa6/uGf37p6FsJTt34k7UpxDUnlfzNf2teEfbV/1Ifanb3OKmXXKZRApgXn8nPf KfFnbs= X-Received: by 2002:a17:90a:d005:b0:39e:4d7b:b247 with SMTP id 98e67ed59e1d1-3a07e53be0dmr1115661a91.19.1790130850809; Tue, 22 Sep 2026 19:34:10 -0700 (PDT) Received: from localhost ([2001:19f0:8000:3e6e:5400:6ff:fe38:3d01]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3a07dbf69f0sm2075572a91.8.2026.09.22.19.34.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 19:34:10 -0700 (PDT) From: Inochi Amaoto To: Jonathan Corbet , Shuah Khan , Randy Dunlap , Vinod Koul , Neil Armstrong , Manivannan Sadhasivam , Rhys Tumelty , Inochi Amaoto Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, Yixun Lan , Longbin Li Subject: [PATCH v3 3/5] phy: core: Add phy bulk data helper functions Date: Wed, 23 Sep 2026 10:33:01 +0800 Message-ID: <20260923023304.78428-4-inochiama@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923023304.78428-1-inochiama@gmail.com> References: <20260923023304.78428-1-inochiama@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add several helper functions that allow drivers to get several phy consumers in one operation. If any of the phy cannot be acquired then any phys that were got will be put before returning to the caller. This can relieve the driver owners' life who needs to handle many phys, as well as each phy error reporting. Signed-off-by: Inochi Amaoto --- drivers/phy/phy-core.c | 253 ++++++++++++++++++++++++++++++++++++++++ include/linux/phy/phy.h | 55 +++++++++ 2 files changed, 308 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 8fbaea003b90..5b76c006575b 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1004,6 +1004,259 @@ struct phy *devm_of_phy_get_by_index(struct device = *dev, struct device_node *np, } EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index); =20 +/** + * of_phy_get_count() - Get the number of phys of a device node + * @np: device_node for which to get the phy + * + * Return: the phy count if successful, %0 if no phy handle is found, + * negative error value if error occurs. + */ +static int of_phy_get_count(const struct device_node *np) +{ + int count; + + count =3D of_count_phandle_with_args(np, "phys", "#phy-cells"); + + if (count =3D=3D -ENOENT) + return 0; + + return count; +} + +/** + * phy_bulk_put() - release a set of PHYs + * @dev: device that acquired the PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data with PHYs set + * + * Releases the PHY references in reverse order and clears the PHY pointer= in + * each entry. The caller owns the phys array and is responsible for freei= ng it + * if necessary. + */ +static void phy_bulk_put(struct device *dev, unsigned int num_phys, + struct phy_bulk_data *phys) +{ + while (num_phys--) { + if (!IS_ERR_OR_NULL(phys[num_phys].phy)) + phy_put(dev, phys[num_phys].phy); + phys[num_phys].phy =3D NULL; + } +} + +/** + * of_phy_bulk_put() - release a set of PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data with PHYs set + * + * Releases the PHY references in reverse order and clears the PHY pointer= in + * each entry. The caller owns the phys array and is responsible for freei= ng it + * if necessary. + */ +static void of_phy_bulk_put(unsigned int num_phys, struct phy_bulk_data *p= hys) +{ + while (num_phys--) { + of_phy_put(phys[num_phys].phy); + phys[num_phys].phy =3D NULL; + } +} + +static int of_phy_bulk_get_by_index(struct device_node *np, + unsigned int num_phys, + struct phy_bulk_data *phys) +{ + unsigned int i; + int ret; + + for (i =3D 0; i < num_phys; i++) { + phys[i].id =3D NULL; + phys[i].phy =3D NULL; + } + + for (i =3D 0; i < num_phys; i++) { + of_property_read_string_index(np, "phy-names", i, &phys[i].id); + + phys[i].phy =3D of_phy_get_by_index(np, i); + + ret =3D PTR_ERR_OR_ZERO(phys[i].phy); + if (ret) { + phys[i].phy =3D NULL; + goto err; + } + } + + return 0; + +err: + of_phy_bulk_put(i, phys); + + return ret; +} + +/** + * of_phy_bulk_get_all() - obtain all PHYs from a device node + * @np: device node containing the PHY references + * @phys: pointer to store the allocated array of struct phy_bulk_data + * + * Gets every PHY referenced by the phys property in index order. PHY name= s are + * read from phy-names when present. + * + * Return: the number of PHYs on success, %0 if no PHYs are found, or a + * negative error code otherwise + */ +static int of_phy_bulk_get_all(struct device_node *np, + struct phy_bulk_data **phys) +{ + struct phy_bulk_data *phy_bulk; + int num_phys; + int ret; + + num_phys =3D of_phy_get_count(np); + if (num_phys <=3D 0) + return num_phys; + + phy_bulk =3D kmalloc_objs(*phy_bulk, num_phys); + if (!phy_bulk) + return -ENOMEM; + + ret =3D of_phy_bulk_get_by_index(np, num_phys, phy_bulk); + if (ret) { + kfree(phy_bulk); + return ret; + } + + *phys =3D phy_bulk; + + return num_phys; +} + +/** + * phy_bulk_put_all() - release and free PHYs + * @dev: device that acquired the PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data to release and free + */ +static void phy_bulk_put_all(struct device *dev, unsigned int num_phys, + struct phy_bulk_data *phys) +{ + if (IS_ERR_OR_NULL(phys)) + return; + + phy_bulk_put(dev, num_phys, phys); + kfree(phys); +} + +/** + * phy_bulk_init() - initialize multiple PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data to initialize + * + * Initializes the PHYs in array order. If an initialization fails, all PH= Ys + * initialized by this call are exited in reverse order. + * + * Return: %0 if successful, a negative error code otherwise + */ +int phy_bulk_init(unsigned int num_phys, struct phy_bulk_data *phys) +{ + unsigned int i; + int ret; + + for (i =3D 0; i < num_phys; i++) { + ret =3D phy_init(phys[i].phy); + if (ret) + goto err; + } + + return 0; + +err: + while (i--) + phy_exit(phys[i].phy); + + return ret; +} +EXPORT_SYMBOL_GPL(phy_bulk_init); + +/** + * phy_bulk_exit() - exit multiple PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data to exit + * + * Exits the PHYs in reverse array order. All PHYs are processed even if an + * error occurs. + * + * Return: %0 if successful, the first negative error code otherwise + */ +int phy_bulk_exit(unsigned int num_phys, struct phy_bulk_data *phys) +{ + int ret =3D 0; + int err; + + while (num_phys--) { + err =3D phy_exit(phys[num_phys].phy); + if (err && !ret) + ret =3D err; + } + + return ret; +} +EXPORT_SYMBOL_GPL(phy_bulk_exit); + +/** + * phy_bulk_power_on() - power on multiple PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data to power on + * + * Powers on the PHYs in array order. If a power-on operation fails, all P= HYs + * powered on by this call are powered off in reverse order. + * + * Return: %0 if successful, a negative error code otherwise + */ +int phy_bulk_power_on(unsigned int num_phys, struct phy_bulk_data *phys) +{ + unsigned int i; + int ret; + + for (i =3D 0; i < num_phys; i++) { + ret =3D phy_power_on(phys[i].phy); + if (ret) + goto err; + } + + return 0; + +err: + while (i--) + phy_power_off(phys[i].phy); + + return ret; +} +EXPORT_SYMBOL_GPL(phy_bulk_power_on); + +/** + * phy_bulk_power_off() - power off multiple PHYs + * @num_phys: number of entries in the phys array + * @phys: array of struct phy_bulk_data to power off + * + * Powers off the PHYs in reverse array order. All PHYs are processed even= if + * an error occurs. + * + * Return: %0 if successful, the first negative error code otherwise + */ +int phy_bulk_power_off(unsigned int num_phys, struct phy_bulk_data *phys) +{ + int ret =3D 0; + int err; + + while (num_phys--) { + err =3D phy_power_off(phys[num_phys].phy); + if (err && !ret) + ret =3D err; + } + + return ret; +} +EXPORT_SYMBOL_GPL(phy_bulk_power_off); + /** * phy_create() - create a new phy * @dev: device that is creating the new phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index ea47975e288a..77d9d74682b7 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -81,6 +81,18 @@ union phy_configure_opts { struct phy_configure_opts_hdmi hdmi; }; =20 +/** + * struct phy_bulk_data - Data used for bulk phy operations. + * + * @id: phy consumer ID + */ +struct phy_bulk_data { + const char *id; + + /* private: Internal use */ + struct phy *phy; +}; + /** * struct phy_ops - set of function pointers for performing phy operations * @init: operation to be performed for initializing phy @@ -309,6 +321,12 @@ void devm_of_phy_provider_unregister(struct device *de= v, struct phy_provider *phy_provider); int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev= _id); void phy_remove_lookup(struct phy *phy, const char *con_id, const char *de= v_id); + +int phy_bulk_init(unsigned int num_phys, struct phy_bulk_data *phys); +int phy_bulk_exit(unsigned int num_phys, struct phy_bulk_data *phys); +int phy_bulk_power_on(unsigned int num_phys, struct phy_bulk_data *phys); +int phy_bulk_power_off(unsigned int num_phys, struct phy_bulk_data *phys); + #else static inline int phy_pm_runtime_get(struct phy *phy) { @@ -493,6 +511,43 @@ static inline struct phy *devm_of_phy_get_by_index(str= uct device *dev, return ERR_PTR(-ENOSYS); } =20 +static inline int phy_bulk_check_disabled(unsigned int num_phys, + struct phy_bulk_data *phys) +{ + if (!phys) + return 0; + + for (unsigned int i =3D 0; i < num_phys; i++) + if (phys[i].phy) + return -EOPNOTSUPP; + + return 0; +} + +static inline int phy_bulk_init(unsigned int num_phys, + struct phy_bulk_data *phys) +{ + return phy_bulk_check_disabled(num_phys, phys); +} + +static inline int phy_bulk_exit(unsigned int num_phys, + struct phy_bulk_data *phys) +{ + return phy_bulk_check_disabled(num_phys, phys); +} + +static inline int phy_bulk_power_on(unsigned int num_phys, + struct phy_bulk_data *phys) +{ + return phy_bulk_check_disabled(num_phys, phys); +} + +static inline int phy_bulk_power_off(unsigned int num_phys, + struct phy_bulk_data *phys) +{ + return phy_bulk_check_disabled(num_phys, phys); +} + static inline void of_phy_put(struct phy *phy) { } --=20 2.55.0 From nobody Thu Sep 24 14:25:57 2026 Received: from mail-pj2-f17.google.com (mail-pj2-f17.google.com [74.125.227.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32E3923A561 for ; Wed, 23 Sep 2026 02:34:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130861; cv=none; b=Ak6TkBSB4WQUtYLFEcKAegib+LyOwiz6ToTTpdQXvfG196svyUeMZKmymlEOinCcrZw4P99RAHS/au0GDoUrytOwD73+c+KRfbpPGPsSLTDWDW6Wq2NIvrTcQcymQmGpIdfpEaqQ1WYA9aCWvxR7TuC+QcgPzlIOIliKJ5ixjTs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130861; c=relaxed/simple; bh=0BuC+m4001jm0LtxJ5Aoc4IuhuJTdWNW08Zgoc6YibU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vg5/g4VfA2R2aie/5R7sEE4bAcOEC40yslRggQNJ4rPSEpJFfFfv7r1aC8sQUolRm85KuqgTXDTsiOZq0WHgW84ge6RSAC+xCGqBibMYBNhUpjRTayRYU+WizNC9VkgKo2khrlDXUgBl+swvZGdyPkOPTidGs0MPkKIWdXEzEqE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bmjZuh0j; arc=none smtp.client-ip=74.125.227.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bmjZuh0j" Received: by mail-pj2-f17.google.com with SMTP id d9443c01a7336-2db1ca06a25so1989275ad.2 for ; Tue, 22 Sep 2026 19:34:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790130856; x=1790735656; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=F23PT++YfQdFZCmgLsj0Bh4dPpOhTY0Wr6NJKb8T5Wo=; b=bmjZuh0jt+TFqGLbVBiCV/awZ5YzQmLOatlQ1C47cLT2CuR1MJXReu2K/PKhwwa6mw 2d3mpnCthtYT4HmTyEF+OZ8+p+wT2/KRc9vxf0GulhDGqG1ELZamlmkgVKhLgVwwjl8Z eYYsvxHog3p9qHx/5vy1Olzfd7JOUbXj7g7DKRpR8W+rHX6MQr6mzmskybxBMmczbFX5 VaP8bbZsy3zkzwrjO1boKv1AscdwHq2lBqgESP7YLUatekEQFloW8cN9P+9eXCtyEvxK scBzSL3z8YjUDtDt2SQtidqmBN5OQaDxg/SPbNaJd4joHf5cEnPMB7lnEx+ygpI0253G xE9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790130856; x=1790735656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=F23PT++YfQdFZCmgLsj0Bh4dPpOhTY0Wr6NJKb8T5Wo=; b=CD7p9X1AcxZJmmyCBKLK5dKx1a1XqDqUX59M+WPfUKp7mYbTI1i6Jus0vHFLPDvd02 Wga1FCB2Mq7JSpwLGwsLhMEDdkjWgMaoCCZ6CSjGpbLRwwUug7fgG16yl7OhssC4g/2q rairx0mnbUHOyAwK2J3XHcZNnl9LCmkrMkFVywMRDvTNrZGBPdLRmlhZJo1lJ6waeD6f PvJaZvoEEuKTnJZ1xmtxC+GLUX3zVHfN7H+H1jOhQAfEf3n2f/shUL/UVySxgu5akbrH uacxU9xoSSaeaIxRo7jkoAgvX4W+hMGpOqs9yXPxtKKO6FxFI6SlJXfZ32LYYDjLQACp ndEw== X-Forwarded-Encrypted: i=1; AKwUvBw+Zhx0Ma+4Xw8gsh1CraKq/0JpBRCDly/0dw8FF9Aq440+EK8om97BExWvO6/nSGu9j1vrGCvL0/KN54w=@vger.kernel.org X-Gm-Message-State: AFuF++mmwlMHLkqtyWpZx4xxP6ulxcqfe8NbknxeyKEI1kGirgPpXOFq Dj6J0eDb6XHfiYgB8Thswba67d/kCcKQbRHu/M8lVZuJJrp1506UHkeO X-Gm-Gg: AYBFou3q0jX1s44LfJGxCoivYy5jLkRIH0DWIbArPr3RTy0dTaKmiIjhnCHMMEyIAvE HUirFGw79Mi29WLugwTHyn0lvWJD+ZK0fmveFWD7/zWvQiwBXmTU33MHEpPAh2VsCm4wmtA/LY1 yijeKANBkmwTZioPvJFoQSqLHcM4IZk+BhWN1BPlqU9iMQZuypiHUyiKE4mJTva9kgYgPFOdtBI tmOmpF2Z62ODvhJA3JPx0aruFQLjJVGLlJKZ2xi0/kyN8TZ9jUBkAVmlI5DmqJYt7QCGIpvCZs+ DpLVAQSBHL38eZ9IOfVH/tkoVRGCeEVfuJ2bbZ9dAceRETNGYTm5t6brk9zQe0xo7aJi9aH05Ds 8ZY2P/LfXRPGoBx0+GhVtKoMRvqKSj+YTmn6KE4y8KsMcw9zyqcvD1guJg5xPfsu83TFDMJK5ro xEztd4p70mLhFReqQKM8HJT+NQxoV3l9gbfQU5+pGMikAgGOEz8NrD+36XkRndn8QKeidn X-Received: by 2002:a17:902:e741:b0:2dd:c053:e0fa with SMTP id d9443c01a7336-2df69e017bdmr10714565ad.41.1790130855762; Tue, 22 Sep 2026 19:34:15 -0700 (PDT) Received: from localhost ([2001:19f0:8000:3e6e:5400:6ff:fe38:3d01]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2df6a5c16f6sm3133945ad.35.2026.09.22.19.34.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 19:34:15 -0700 (PDT) From: Inochi Amaoto To: Jonathan Corbet , Shuah Khan , Randy Dunlap , Vinod Koul , Neil Armstrong , Manivannan Sadhasivam , Rhys Tumelty , Inochi Amaoto Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, Yixun Lan , Longbin Li Subject: [PATCH v3 4/5] phy: core: Add managed phy bulk data helper functions Date: Wed, 23 Sep 2026 10:33:02 +0800 Message-ID: <20260923023304.78428-5-inochiama@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923023304.78428-1-inochiama@gmail.com> References: <20260923023304.78428-1-inochiama@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add device managed variants of the phy bulk helper functions. So the driver can benefit from automatically managed phy handles. Signed-off-by: Inochi Amaoto --- drivers/phy/phy-core.c | 73 +++++++++++++++++++++++++++++++++++++++++ include/linux/phy/phy.h | 19 +++++++++++ 2 files changed, 92 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 5b76c006575b..a588fba33313 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1145,6 +1145,79 @@ static void phy_bulk_put_all(struct device *dev, uns= igned int num_phys, kfree(phys); } =20 +struct phy_bulk_devres { + struct phy_bulk_data *phys; + unsigned int num_phys; +}; + +static void devm_phy_bulk_release_all(struct device *dev, void *res) +{ + struct phy_bulk_devres *devres =3D res; + + phy_bulk_put_all(dev, devres->num_phys, devres->phys); +} + +/** + * devm_phy_bulk_get_all() - managed lookup of all PHYs requested by a dev= ice + * @dev: device that requests the PHYs + * @phys: pointer to store the allocated array of struct phy_bulk_data + * + * The function calls devm_of_phy_bulk_get_all() directly, but sets the + * @np parameter to dev_of_node(dev). + * + * Return: the number of PHYs on success, %0 if no PHYs are found, or a + * negative error code otherwise + */ +int devm_phy_bulk_get_all(struct device *dev, struct phy_bulk_data **phys) +{ + return devm_of_phy_bulk_get_all(dev, dev_of_node(dev), phys); +} +EXPORT_SYMBOL_GPL(devm_phy_bulk_get_all); + +/** + * devm_of_phy_bulk_get_all() - managed lookup of all PHYs from a device n= ode + * @dev: device that requests the PHYs + * @np: device node containing the PHY references + * @phys: pointer to store the allocated array of struct phy_bulk_data + * + * Gets all PHYs from the specified device node, associates the allocated = array + * and PHY references with @dev, and creates a device link for each PHY. T= hey + * are automatically released on driver detach. + * + * Return: the number of PHYs on success, %0 if no PHYs are found, or a + * negative error code otherwise + */ +int devm_of_phy_bulk_get_all(struct device *dev, struct device_node *np, + struct phy_bulk_data **phys) +{ + struct phy_bulk_devres *devres; + int ret; + + *phys =3D NULL; + + if (!np) + return 0; + + devres =3D devres_alloc(devm_phy_bulk_release_all, sizeof(*devres), + GFP_KERNEL); + if (!devres) + return -ENOMEM; + + ret =3D of_phy_bulk_get_all(np, &devres->phys); + if (ret > 0) { + for (int i =3D 0; i < ret; i++) + phy_add_device_link(dev, devres->phys[i].phy); + *phys =3D devres->phys; + devres->num_phys =3D ret; + devres_add(dev, devres); + } else { + devres_free(devres); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_of_phy_bulk_get_all); + /** * phy_bulk_init() - initialize multiple PHYs * @num_phys: number of entries in the phys array diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 77d9d74682b7..e60e42eb7e0b 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -322,6 +322,9 @@ void devm_of_phy_provider_unregister(struct device *dev, int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev= _id); void phy_remove_lookup(struct phy *phy, const char *con_id, const char *de= v_id); =20 +int devm_phy_bulk_get_all(struct device *dev, struct phy_bulk_data **phys); +int devm_of_phy_bulk_get_all(struct device *dev, struct device_node *np, + struct phy_bulk_data **phys); int phy_bulk_init(unsigned int num_phys, struct phy_bulk_data *phys); int phy_bulk_exit(unsigned int num_phys, struct phy_bulk_data *phys); int phy_bulk_power_on(unsigned int num_phys, struct phy_bulk_data *phys); @@ -511,6 +514,22 @@ static inline struct phy *devm_of_phy_get_by_index(str= uct device *dev, return ERR_PTR(-ENOSYS); } =20 +static inline int devm_of_phy_bulk_get_all(struct device *dev, + struct device_node *np, + struct phy_bulk_data **phys) +{ + if (phys) + *phys =3D NULL; + + return 0; +} + +static inline int devm_phy_bulk_get_all(struct device *dev, + struct phy_bulk_data **phys) +{ + return devm_of_phy_bulk_get_all(dev, dev_of_node(dev), phys); +} + static inline int phy_bulk_check_disabled(unsigned int num_phys, struct phy_bulk_data *phys) { --=20 2.55.0 From nobody Thu Sep 24 14:25:57 2026 Received: from mail-pz2-f12.google.com (mail-pz2-f12.google.com [74.125.228.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 637323806B6 for ; Wed, 23 Sep 2026 02:34:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130862; cv=none; b=NG2Axe7nZrqSHQzxcd3tjy80h7dmklHpG/ZFnVf/EKUdEFUPu9CiQMWPv4JTG5HCDnqyP+JwCuV+kbe27Hln8EeAHLd7FKPwkp4r9VdmShlBYkgfl9bZO7lwrslIkkiBX/WfgtZKZRm8eK25ek1opMEjWwfxCpm7axb9S5cACfc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790130862; c=relaxed/simple; bh=KAHvlzNsX2RSyag5xWzRHXQ55ITbwrvDX57hYu6PuRw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ae51DdWgJcuE9xNr8BRRJikVSyQB/AKUe53tzDL/T9PVz7zzYyjYTBWyV40EyHbxyPpURe4FKC5WxYn5IASA2vv4Um6lnJX+N0qEBbxB5heEalwCbfmpzMNY62EvEXMH7rb9jA8meodPD3U69EUHR9voJ/w0hEnRt4nzZ9wHg2g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=k8MkN9VM; arc=none smtp.client-ip=74.125.228.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="k8MkN9VM" Received: by mail-pz2-f12.google.com with SMTP id 41be03b00d2f7-cc1cea4ae2cso372856a12.0 for ; Tue, 22 Sep 2026 19:34:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790130860; x=1790735660; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=xnrcjxk0kzIW2dBkRTKNaLCxSo8UzYbysB1rR/EfFJo=; b=k8MkN9VMrRU9sPd9dtcMWT0cF4KpSTEZQyWhl1CC2eG0KRCQvOfuMPs4HiASEB0yEA LwFsqsEYOdap3mxGXGFCQ2TM7bkEpsqPBrev+EpcyC4RDOaxF86BT/OPu3H0psYnuA8G tmud/Dqy4ZW02HxvEhQejRbukiuvTYBh6VnijTOfQDZ/sSIi3JRSStHdoqXBWYFvOe7u SFj28cvc9xghEqBqYULCC22OxCB2JehDz24CV/ARJjP8FW/Gkcy6XRt5B4eG7CkG26c7 ERuJpBr/cW1KSM/TEv77aUFS1EMqn5YMXidTOPd/lXUFLesbWU/+EDvoJAycAoQFQU2r xTOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790130860; x=1790735660; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=xnrcjxk0kzIW2dBkRTKNaLCxSo8UzYbysB1rR/EfFJo=; b=IqbW/meRkH/C6IrXTxk+qAdaz5akqdWSJ/lxbYxAv+p3pGg7TZ3kvI1w7pSWS6u+O6 QvWPyPT088yNlNQYiOb/w2O4s3Uj6/6wfj7ywBFCKhBitKbRy/jsjqgqktmxzZ6KiQja WxO+gPhJaGfGE9gIz7QgjfbHYyTi/ElkGeDVD26Cd8eQ0AEO38feaygKIp4sGYwMXLvN hjDjTWFPpKQ10bRvB+ad49UpFsB58UUQdfSXVBQeZE5RHvDTgqSHGouI3YwfEomPNn2X 9Gvba39r6KCAlay7rbNHeA3y5cLevVwFDnQLJGtudGxcEPQHQJPkKbu9vlXWLWcQ/orO ++Iw== X-Forwarded-Encrypted: i=1; AKwUvBy0K3WL7dMRCs3HqkEq2Ao9bx2k9unWyQWeP9bH1pIwofAJrq7OXacD6C5uF4jqPVsLKuguGlIl7PEHAqc=@vger.kernel.org X-Gm-Message-State: AFuF++mRB6U7COjtqsV58foaTljuUcdfEfQkjW3DiluYxbaVULuEIQ21 TX3DDQyFZSrxzBcMJesYpF1GT4B1zurZjwkO8+o/U62oNuc/VNhfR/5A X-Gm-Gg: AYBFou3smDL1zsFgIBD68JJSIewx/erAoakg9LbFjc946wBl6fg+U5XoVkclC2Vk+Zd wHZnOE+gFdVJTXbcKctiA0vFHzbtjt5uW/Ouf2EZoCvPmgj51aXoKGXH3RwANH1Z6z1cIVen5Oc NuiLIQAESbzKlqVJx8SB3fzHT2BZA96IIQfTGkXwJ55PEFZij9jCjLbhzX/mj+P2YI07rhv+wk2 GONbQvW9RRddDcWUurnRmuND0hId8ayvNegGrrT9RdCiHXnpfowO+981I1EQ9GxB+UCSZjaXMBq Ck1DZdB5XPI1rgF0KiYWckcUgAgl8s8YvsOWhJIa6xMhgFQLcL4pd6R7qz+O5tL1cK0rPDcJRTw tLkxYcUFeL8bDWa8jvcY14cF08Tv5+t5wDMgTMxuz5zAG5sLvin1i/7xmSe9MuEodeVxR2Vhocw fm8W3W8/ALBgC8lKPCi/y1YJ0gJxE1qas1uqPcsQVGVxXJz1ILmubnmyQWMOho3bPqDLlQ X-Received: by 2002:a05:6a20:3c9f:b0:3dd:a196:53a8 with SMTP id adf61e73a8af0-3ddf82fd72emr1311152637.74.1790130859652; Tue, 22 Sep 2026 19:34:19 -0700 (PDT) Received: from localhost ([2001:19f0:8000:3e6e:5400:6ff:fe38:3d01]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc75f3d5ce8sm316506a12.17.2026.09.22.19.34.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 19:34:19 -0700 (PDT) From: Inochi Amaoto To: Jonathan Corbet , Shuah Khan , Randy Dunlap , Vinod Koul , Neil Armstrong , Manivannan Sadhasivam , Rhys Tumelty , Inochi Amaoto Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, Yixun Lan , Longbin Li Subject: [PATCH v3 5/5] doc: phy: Document some bulk helper functions Date: Wed, 23 Sep 2026 10:33:03 +0800 Message-ID: <20260923023304.78428-6-inochiama@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923023304.78428-1-inochiama@gmail.com> References: <20260923023304.78428-1-inochiama@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Document all newly added bulk helper function, it can be used to manage a set of PHYs automatically. This is useful when the driver want to simplify the management of multiple PHYs. Signed-off-by: Inochi Amaoto --- Documentation/driver-api/phy/phy.rst | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Documentation/driver-api/phy/phy.rst b/Documentation/driver-ap= i/phy/phy.rst index 0865c2e94eec..c5d3d7cc1a74 100644 --- a/Documentation/driver-api/phy/phy.rst +++ b/Documentation/driver-api/phy/phy.rst @@ -114,6 +114,10 @@ it. This framework provides the following APIs to get = a reference to the PHY. struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, int index); + int devm_phy_bulk_get_all(struct device *dev, + struct phy_bulk_data **phys); + int devm_of_phy_bulk_get_all(struct device *dev, struct device_node *np, + struct phy_bulk_data **phys); =20 phy_get, devm_phy_get and devm_phy_optional_get can be used to get the PHY. In the case of dt boot, the string arguments @@ -129,6 +133,13 @@ Some generic drivers, such as ehci, may use multiple p= hys. In this case, devm_of_phy_get or devm_of_phy_get_by_index can be used to get a phy reference based on name or index. =20 +When a controller needs every PHY listed in a device node's ``phys`` prope= rty, +devm_phy_bulk_get_all() obtains them from the controller's device node. +devm_of_phy_bulk_get_all() does the same for an explicitly supplied device +node. On success, these functions return the number of PHYs and store an a= rray +of ``struct phy_bulk_data`` in ``*phys``. The PHY references and array are +managed by devres and are released when the device is detached. + It should be noted that NULL is a valid phy reference. All phy consumer calls on the NULL phy become NOPs. That is the release calls, the phy_init() and phy_exit() calls, and phy_power_on() and @@ -149,6 +160,19 @@ The general order of calls should be:: phy_exit() [[of_]phy_put()] =20 +For a set of PHYs acquired with devm_phy_bulk_get_all() or +devm_of_phy_bulk_get_all(), the corresponding order is:: + + devm_[of_]phy_bulk_get_all() + phy_bulk_init() + phy_bulk_power_on() + ... + phy_bulk_power_off() + phy_bulk_exit() + +The bulk get-all APIs release the PHY references and the array automatical= ly +when the device is detached. + Some PHY drivers may not implement :c:func:`phy_init` or :c:func:`phy_powe= r_on`, but controllers should always call these functions to be compatible with o= ther PHYs. Some PHYs may require :c:func:`phy_set_mode `, whi= le @@ -221,3 +245,8 @@ DeviceTree Binding =20 The documentation for PHY dt binding can be found @ Documentation/devicetree/bindings/phy/phy-bindings.txt + +Missing Bulk Helpers +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Currently, Only a few bulk helper functions are added as they have users. +Function not upstreamed can be found at https://lore.kernel.org/linux-phy/= 20260904083709.425893-1-inochiama@gmail.com/ --=20 2.55.0