Re: [PATCH v2 2/5] PCI: spacemit-k1: Add multiple PHY handles support
From: Alex Elder
Date: Tue Jun 09 2026 - 12:44:34 EST
On 5/16/26 8:48 PM, Inochi Amaoto wrote:
The PCIe controller on Spacemit K3 may use multiple PHYs at the
same time. The feature is not support by the current driver.
So extend the PHY definition to support multiple PHY handles.
Signed-off-by: Inochi Amaoto <inochiama@xxxxxxxxx>
---
drivers/pci/controller/dwc/pcie-spacemit-k1.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-spacemit-k1.c b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
index 1b519d49dcc0..7f6f1df31cd8 100644
--- a/drivers/pci/controller/dwc/pcie-spacemit-k1.c
+++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
@@ -51,7 +51,8 @@
struct k1_pcie {
struct dw_pcie pci;
- struct phy *phy;
+ struct phy **phy;
I haven't looked further at this series yet, but do you have
any interest in making this a flexible array of pointers
(counted_by(phy_count))?
+ int phy_count;
void __iomem *link;
struct regmap *pmu; /* Errors ignored; MMIO-backed regmap */
u32 pmu_off;
@@ -171,7 +172,7 @@ static int k1_pcie_init(struct dw_pcie_rp *pp)
*/
regmap_set_bits(k1->pmu, reset_ctrl, DEVICE_TYPE_RC | PCIE_AUX_PWR_DET);
- ret = phy_init(k1->phy);
+ ret = phy_init(k1->phy[0]);
If you're going to have an array you should probably put in place
a loop to initialize all phy_count elements of the array here
(as is done for phy_exit(), below).
if (ret) {
k1_pcie_disable_resources(k1);
@@ -191,12 +192,14 @@ static void k1_pcie_deinit(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct k1_pcie *k1 = to_k1_pcie(pci);
+ int i;
/* Assert fundamental reset (drive PERST# low) */
regmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL,
PCIE_RC_PERST);
- phy_exit(k1->phy);
+ for (i = 0; i < k1->phy_count; i++)
+ phy_exit(k1->phy[i]);
k1_pcie_disable_resources(k1);
}
@@ -277,7 +280,12 @@ static int k1_pcie_parse_port(struct k1_pcie *k1)
if (IS_ERR(phy))
return PTR_ERR(phy);
Andy said something different about this.
But it seems to me you are intentionally allocating an
*array* of PHY pointers, which happens to have only one entry.
But your objective is that you want to allocate an array of
them so you can support more than just one PHY, right?
- k1->phy = phy;
+ k1->phy = devm_kmalloc_array(dev, 1, sizeof(*k1->phy), GFP_KERNEL);
Probably should use the kzalloc variant.
+ if (!k1->phy)
+ return -ENOMEM;
+
+ k1->phy[0] = phy;
I think what's wrong is the above assignment.
If you are truly allocating an array of PHY *pointers*,
then you need to also allocate the phy structure that
each entry in the array points to.
The above assignment is erroneously assigning the first entry in the
array to point to the array, and not a new entry.
-Alex
+ k1->phy_count = 1;
return 0;
}