From 62ef2a96fe7e66b8b5c4e756a8454146adee1817 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 16 Jul 2026 15:25:32 +0200 Subject: [PATCH 1/7] PCI/pwrctrl: tc9563: Take i2c adapter module reference The i2c subsystem currently blocks during adapter deregistration whenever there are consumers holding a reference. Switch to using of_get_i2c_adapter_by_node() which also takes a reference to the adapter module so that an attempt to unload the module while in use fails gracefully instead of blocking uninterruptibly. Signed-off-by: Johan Hovold Signed-off-by: Bjorn Helgaas Reviewed-by: Bartosz Golaszewski Reviewed-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260716132532.1565340-1-johan@kernel.org --- drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c index 488e1ec34a7f..83ae9f256b69 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c @@ -549,7 +549,7 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "Failed to read i2c-parent property\n"); i2c_node = of_parse_phandle(dev->of_node, "i2c-parent", 0); - tc9563->adapter = of_find_i2c_adapter_by_node(i2c_node); + tc9563->adapter = of_get_i2c_adapter_by_node(i2c_node); of_node_put(i2c_node); if (!tc9563->adapter) return dev_err_probe(dev, -EPROBE_DEFER, "Failed to find I2C adapter\n"); @@ -557,7 +557,7 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) tc9563->client = i2c_new_dummy_device(tc9563->adapter, addr); if (IS_ERR(tc9563->client)) { dev_err(dev, "Failed to create I2C client\n"); - put_device(&tc9563->adapter->dev); + i2c_put_adapter(tc9563->adapter); return PTR_ERR(tc9563->client); } @@ -625,7 +625,7 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) tc9563_pwrctrl_power_off(&tc9563->pwrctrl); remove_i2c: i2c_unregister_device(tc9563->client); - put_device(&tc9563->adapter->dev); + i2c_put_adapter(tc9563->adapter); return ret; } @@ -637,7 +637,7 @@ static void tc9563_pwrctrl_remove(struct platform_device *pdev) tc9563_pwrctrl_power_off(&tc9563->pwrctrl); i2c_unregister_device(tc9563->client); - put_device(&tc9563->adapter->dev); + i2c_put_adapter(tc9563->adapter); } static const struct of_device_id tc9563_pwrctrl_of_match[] = { From 9a089144d0b388f94a1b2f8104f18a87181126b3 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 25 Jul 2026 10:59:13 +0200 Subject: [PATCH 2/7] dt-bindings: PCI: toshiba,tc9563: Restrict Tx Amplitude, DFE and N_FTS to USP, DSP1 and DSP2 TC9563 switch allows configuring Tx Amplitude, DFE and N_FTS settings only to USP, DSP1 and DSP2 ports. These settings don't apply to DSP3 or the integrated Ethernet MAC Endpoint. Restrict these properties and move 'toshiba,tx-amplitude-microvolt' to DSP2 in the example to conform to the binding. Fixes: 26f3ac884835 ("dt-bindings: PCI: Add binding for Toshiba TC9563 PCIe switch") Signed-off-by: Manivannan Sadhasivam [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas Acked-by: Alex Elder Link: https://patch.msgid.link/20260725-tc9563-fix-v1-1-ec4286e31331@oss.qualcomm.com --- .../bindings/pci/toshiba,tc9563.yaml | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml index b3ad05d90201..f084830c6d0c 100644 --- a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml +++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml @@ -54,7 +54,7 @@ properties: - description: I2C slave address patternProperties: - "^pcie@[1-3],0$": + "^pcie@[1-2],0$": description: child nodes describing the internal downstream ports of the tc9563 switch. @@ -64,6 +64,21 @@ patternProperties: - $ref: /schemas/pci/pci-pci-bridge.yaml# unevaluatedProperties: false + "^pcie@[3],0$": + description: + child node describing the internal downstream port connected to the + integrated Ethernet MAC endpoint of the tc9563 switch. + type: object + $ref: /schemas/pci/pci-pci-bridge.yaml# + properties: + n-fts: false + patternProperties: + "^ethernet@0,[0-1]$": + type: object + properties: + n-fts: false + unevaluatedProperties: false + $defs: tc9563-node: type: object @@ -154,6 +169,8 @@ examples: device_type = "pci"; ranges; bus-range = <0x04 0xff>; + + toshiba,tx-amplitude-microvolt = <10>; }; pcie@3,0 { @@ -165,8 +182,6 @@ examples: ranges; bus-range = <0x05 0xff>; - toshiba,tx-amplitude-microvolt = <10>; - ethernet@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; }; From 6e5e6c2194b2acbded5b12ed80590d215b786d29 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 25 Jul 2026 10:59:14 +0200 Subject: [PATCH 3/7] PCI/pwrctrl: tc9563: Fix parsing the integrated Ethernet MAC Endpoint node DSP3 has an integrated Ethernet MAC Endpoint which has its own set of config registers for configuring settings such as ASPM. The Endpoint device has two physical functions and those two functions share the same settings. Parse the Endpoint node under DSP3 instead of parsing both functions. The existing parsing logic also has one OOB issue as parsing both functions will result in accessing past the tc9563_pwrctrl->cfg array. Fixes: 4c9c7be47310 ("PCI: pwrctrl: Add power control driver for TC9563") Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Elder Reviewed-by: Bartosz Golaszewski Link: https://patch.msgid.link/20260725-tc9563-fix-v1-2-ec4286e31331@oss.qualcomm.com --- drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c index 83ae9f256b69..3ee1b4d19a4d 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c @@ -596,12 +596,18 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) ret = tc9563_pwrctrl_parse_device_dt(tc9563, child, port); if (ret) break; - /* Embedded ethernet device are under DSP3 */ + + /* + * The integrated Ethernet MAC Endpoint under DSP3 is a single + * device whose functions share the same config registers. + */ if (port == TC9563_DSP3) { - for_each_child_of_node_scoped(child, child1) { - port++; + struct device_node *eth __free(device_node) = + of_get_next_available_child(child, NULL); + + if (eth) { ret = tc9563_pwrctrl_parse_device_dt(tc9563, - child1, port); + eth, TC9563_ETHERNET); if (ret) break; } From e41bbfc4c109f2db741eef5cd0ac55600930c449 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 25 Jul 2026 10:59:15 +0200 Subject: [PATCH 4/7] PCI/pwrctrl: tc9563: Power off only the external ports in tc9563_pwrctrl_disable_port() TC9563 supports powering off only the external facing ports like DSP1 and DSP2. It is not recommended to power off USP and DSP3 as they have fixed ports/endpoint connected. Fix tc9563_pwrctrl_disable_port() to power off only DSP1 and DSP2. Fixes: 4c9c7be47310 ("PCI: pwrctrl: Add power control driver for TC9563") Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Elder Reviewed-by: Bartosz Golaszewski Link: https://patch.msgid.link/20260725-tc9563-fix-v1-3-ec4286e31331@oss.qualcomm.com --- drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c index 3ee1b4d19a4d..c1cb867ea47e 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c @@ -241,12 +241,18 @@ static int tc9563_pwrctrl_disable_port(struct tc9563_pwrctrl *tc9563, if (!cfg->disable_port) return 0; - if (port == TC9563_DSP1) { + switch (port) { + case TC9563_DSP1: seq = dsp1_pwroff_seq; len = ARRAY_SIZE(dsp1_pwroff_seq); - } else { + break; + case TC9563_DSP2: seq = dsp2_pwroff_seq; len = ARRAY_SIZE(dsp2_pwroff_seq); + break; + default: + /* Only external downstream ports DSP1/DSP2 can be powered off */ + return 0; } ret = tc9563_pwrctrl_i2c_bulk_write(tc9563->client, seq, len); From b859b9366b44e48461724c19dd42cd4a05b6f49c Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 25 Jul 2026 10:59:16 +0200 Subject: [PATCH 5/7] PCI/pwrctrl: tc9563: Skip Tx amplitude and DFE tuning for DSP3 DSP3 doesn't support tuning Tx amplitude and DFE settings. Skip the setting if DT has passed the tuning properties. There is no need to error out the whole driver because of it. Fixes: 4c9c7be47310 ("PCI: pwrctrl: Add power control driver for TC9563") Signed-off-by: Manivannan Sadhasivam [bhelgaas: squash https://lore.kernel.org/all/oefxm7olagbd3dby2npgly7ausiz3g6cvls5igaxdzvlbr3wrv@rjlfebi2p36j] Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Elder Reviewed-by: Bartosz Golaszewski Link: https://patch.msgid.link/20260725-tc9563-fix-v1-4-ec4286e31331@oss.qualcomm.com --- drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c index c1cb867ea47e..d7c5cc406d10 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c @@ -308,6 +308,7 @@ static int tc9563_pwrctrl_set_l0s_l1_entry_delay(struct tc9563_pwrctrl *tc9563, static int tc9563_pwrctrl_set_tx_amplitude(struct tc9563_pwrctrl *tc9563, enum tc9563_pwrctrl_ports port) { + struct device *dev = tc9563->pwrctrl.dev; u32 amp = tc9563->cfg[port].tx_amp; int port_access; @@ -327,6 +328,9 @@ static int tc9563_pwrctrl_set_tx_amplitude(struct tc9563_pwrctrl *tc9563, case TC9563_DSP2: port_access = 0x8; break; + case TC9563_DSP3: + dev_dbg(dev, "Tx amplitude tuning not supported for DSP3\n"); + return 0; default: return -EINVAL; } @@ -345,6 +349,7 @@ static int tc9563_pwrctrl_disable_dfe(struct tc9563_pwrctrl *tc9563, enum tc9563_pwrctrl_ports port) { struct tc9563_pwrctrl_cfg *cfg = &tc9563->cfg[port]; + struct device *dev = tc9563->pwrctrl.dev; int port_access, lane_access = 0x3; u32 phy_rate = 0x21; @@ -363,6 +368,9 @@ static int tc9563_pwrctrl_disable_dfe(struct tc9563_pwrctrl *tc9563, port_access = 0x8; lane_access = 0x1; break; + case TC9563_DSP3: + dev_dbg(dev, "DFE tuning not supported for DSP3\n"); + return 0; default: return -EINVAL; } @@ -393,11 +401,17 @@ static int tc9563_pwrctrl_set_nfts(struct tc9563_pwrctrl *tc9563, {TC9563_NFTS_2_5_GT, nfts[0]}, {TC9563_NFTS_5_GT, nfts[1]}, }; + struct device *dev = tc9563->pwrctrl.dev; int ret; if (!nfts[0]) return 0; + if (port == TC9563_VDSP) { + dev_dbg(dev, "N_FTS tuning not supported for VDSP\n"); + return 0; + } + ret = tc9563_pwrctrl_i2c_write(tc9563->client, TC9563_PORT_SELECT, BIT(port)); if (ret) From b7f273a4627505839720d633ffc66c89f46f9eee Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 25 Jul 2026 10:59:17 +0200 Subject: [PATCH 6/7] PCI/pwrctrl: tc9563: Rename DSP3 to VDSP TC9563 Reference Manual calls DSP3 as VDSP (Virtual Downstream Port). Name it as such to avoid ambiguity. Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Elder Reviewed-by: Bartosz Golaszewski Link: https://patch.msgid.link/20260725-tc9563-fix-v1-5-ec4286e31331@oss.qualcomm.com --- drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c index d7c5cc406d10..86187f1c4a75 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c @@ -80,7 +80,7 @@ enum tc9563_pwrctrl_ports { TC9563_USP, TC9563_DSP1, TC9563_DSP2, - TC9563_DSP3, + TC9563_VDSP, TC9563_ETHERNET, TC9563_MAX }; @@ -328,8 +328,8 @@ static int tc9563_pwrctrl_set_tx_amplitude(struct tc9563_pwrctrl *tc9563, case TC9563_DSP2: port_access = 0x8; break; - case TC9563_DSP3: - dev_dbg(dev, "Tx amplitude tuning not supported for DSP3\n"); + case TC9563_VDSP: + dev_dbg(dev, "Tx amplitude tuning not supported for VDSP\n"); return 0; default: return -EINVAL; @@ -368,8 +368,8 @@ static int tc9563_pwrctrl_disable_dfe(struct tc9563_pwrctrl *tc9563, port_access = 0x8; lane_access = 0x1; break; - case TC9563_DSP3: - dev_dbg(dev, "DFE tuning not supported for DSP3\n"); + case TC9563_VDSP: + dev_dbg(dev, "DFE tuning not supported for VDSP\n"); return 0; default: return -EINVAL; @@ -618,10 +618,10 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) break; /* - * The integrated Ethernet MAC Endpoint under DSP3 is a single + * The integrated Ethernet MAC Endpoint under VDSP is a single * device whose functions share the same config registers. */ - if (port == TC9563_DSP3) { + if (port == TC9563_VDSP) { struct device_node *eth __free(device_node) = of_get_next_available_child(child, NULL); From b9851611bad7cb227c93c1401dca48995a815d94 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 25 Jul 2026 10:59:18 +0200 Subject: [PATCH 7/7] PCI/pwrctrl: tc9563: Move Integrated MAC Endpoint out of 'tc9563_pwrctrl_ports' enum 'tc9563_pwrctrl_ports' is supposed to list only the internal ports of the switch. But it currently lists the integrated MAC Endpoint as well, which is wrong. Move it to a separate 'ep_cfg' struct and also configure/parse the ports and the MAC Endpoint separately. Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Reviewed-by: Alex Elder Reviewed-by: Bartosz Golaszewski Link: https://patch.msgid.link/20260725-tc9563-fix-v1-6-ec4286e31331@oss.qualcomm.com --- drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 104 ++++++++++++++--------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c index 86187f1c4a75..db744fbfc09a 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c @@ -81,7 +81,6 @@ enum tc9563_pwrctrl_ports { TC9563_DSP1, TC9563_DSP2, TC9563_VDSP, - TC9563_ETHERNET, TC9563_MAX }; @@ -109,6 +108,7 @@ struct tc9563_pwrctrl { struct pci_pwrctrl pwrctrl; struct regulator_bulk_data supplies[TC9563_PWRCTL_MAX_SUPPLY]; struct tc9563_pwrctrl_cfg cfg[TC9563_MAX]; + struct tc9563_pwrctrl_cfg ep_cfg; struct gpio_desc *reset_gpio; struct i2c_adapter *adapter; struct i2c_client *client; @@ -263,9 +263,31 @@ static int tc9563_pwrctrl_disable_port(struct tc9563_pwrctrl *tc9563, ARRAY_SIZE(common_pwroff_seq)); } -static int tc9563_pwrctrl_set_l0s_l1_entry_delay(struct tc9563_pwrctrl *tc9563, - enum tc9563_pwrctrl_ports port, - bool is_l1, u32 ns) +static int tc9563_pwrctrl_set_port_l0s_l1_entry_delay(struct tc9563_pwrctrl *tc9563, + enum tc9563_pwrctrl_ports port, + bool is_l1, u32 ns) +{ + u32 units; + int ret; + + if (ns < TC9563_L0S_L1_DELAY_UNIT_NS) + return 0; + + /* convert to units of 256ns */ + units = ns / TC9563_L0S_L1_DELAY_UNIT_NS; + + ret = tc9563_pwrctrl_i2c_write(tc9563->client, TC9563_PORT_SELECT, + BIT(port)); + if (ret) + return ret; + + return tc9563_pwrctrl_i2c_write(tc9563->client, + is_l1 ? TC9563_PORT_L1_DELAY : TC9563_PORT_L0S_DELAY, + units); +} + +static int tc9563_pwrctrl_set_eth_l0s_l1_entry_delay(struct tc9563_pwrctrl *tc9563, + bool is_l1, u32 ns) { u32 rd_val, units; int ret; @@ -276,33 +298,20 @@ static int tc9563_pwrctrl_set_l0s_l1_entry_delay(struct tc9563_pwrctrl *tc9563, /* convert to units of 256ns */ units = ns / TC9563_L0S_L1_DELAY_UNIT_NS; - if (port == TC9563_ETHERNET) { - ret = tc9563_pwrctrl_i2c_read(tc9563->client, - TC9563_EMBEDDED_ETH_DELAY, - &rd_val); - if (ret) - return ret; - - if (is_l1) - rd_val = u32_replace_bits(rd_val, units, - TC9563_ETH_L1_DELAY_MASK); - else - rd_val = u32_replace_bits(rd_val, units, - TC9563_ETH_L0S_DELAY_MASK); - - return tc9563_pwrctrl_i2c_write(tc9563->client, - TC9563_EMBEDDED_ETH_DELAY, - rd_val); - } - - ret = tc9563_pwrctrl_i2c_write(tc9563->client, TC9563_PORT_SELECT, - BIT(port)); + ret = tc9563_pwrctrl_i2c_read(tc9563->client, TC9563_EMBEDDED_ETH_DELAY, + &rd_val); if (ret) return ret; - return tc9563_pwrctrl_i2c_write(tc9563->client, - is_l1 ? TC9563_PORT_L1_DELAY : TC9563_PORT_L0S_DELAY, - units); + if (is_l1) + rd_val = u32_replace_bits(rd_val, units, + TC9563_ETH_L1_DELAY_MASK); + else + rd_val = u32_replace_bits(rd_val, units, + TC9563_ETH_L0S_DELAY_MASK); + + return tc9563_pwrctrl_i2c_write(tc9563->client, TC9563_EMBEDDED_ETH_DELAY, + rd_val); } static int tc9563_pwrctrl_set_tx_amplitude(struct tc9563_pwrctrl *tc9563, @@ -436,11 +445,9 @@ static int tc9563_pwrctrl_assert_deassert_reset(struct tc9563_pwrctrl *tc9563, return tc9563_pwrctrl_i2c_write(tc9563->client, TC9563_RESET_GPIO, val); } -static int tc9563_pwrctrl_parse_device_dt(struct tc9563_pwrctrl *tc9563, - struct device_node *node, - enum tc9563_pwrctrl_ports port) +static int tc9563_pwrctrl_parse_device_dt(struct device_node *node, + struct tc9563_pwrctrl_cfg *cfg) { - struct tc9563_pwrctrl_cfg *cfg = &tc9563->cfg[port]; int ret; /* Disable port if the status of the port is disabled. */ @@ -511,13 +518,13 @@ static int tc9563_pwrctrl_power_on(struct pci_pwrctrl *pwrctrl) goto power_off; } - ret = tc9563_pwrctrl_set_l0s_l1_entry_delay(tc9563, i, false, cfg->l0s_delay); + ret = tc9563_pwrctrl_set_port_l0s_l1_entry_delay(tc9563, i, false, cfg->l0s_delay); if (ret) { dev_err(dev, "Setting L0s entry delay failed\n"); goto power_off; } - ret = tc9563_pwrctrl_set_l0s_l1_entry_delay(tc9563, i, true, cfg->l1_delay); + ret = tc9563_pwrctrl_set_port_l0s_l1_entry_delay(tc9563, i, true, cfg->l1_delay); if (ret) { dev_err(dev, "Setting L1 entry delay failed\n"); goto power_off; @@ -542,6 +549,21 @@ static int tc9563_pwrctrl_power_on(struct pci_pwrctrl *pwrctrl) } } + /* Configure the integrated Ethernet MAC endpoint */ + ret = tc9563_pwrctrl_set_eth_l0s_l1_entry_delay(tc9563, false, + tc9563->ep_cfg.l0s_delay); + if (ret) { + dev_err(dev, "Setting Ethernet L0s entry delay failed\n"); + goto power_off; + } + + ret = tc9563_pwrctrl_set_eth_l0s_l1_entry_delay(tc9563, true, + tc9563->ep_cfg.l1_delay); + if (ret) { + dev_err(dev, "Setting Ethernet L1 entry delay failed\n"); + goto power_off; + } + ret = tc9563_pwrctrl_assert_deassert_reset(tc9563, true); if (!ret) return 0; @@ -599,8 +621,7 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) pci_pwrctrl_init(&tc9563->pwrctrl, dev); - port = TC9563_USP; - ret = tc9563_pwrctrl_parse_device_dt(tc9563, node, port); + ret = tc9563_pwrctrl_parse_device_dt(node, &tc9563->cfg[TC9563_USP]); if (ret) { dev_err(dev, "failed to parse device tree properties: %d\n", ret); goto remove_i2c; @@ -611,9 +632,12 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) * The first node represents DSP1, the second node represents DSP2, * and so on. */ + port = TC9563_USP; for_each_child_of_node_scoped(node, child) { - port++; - ret = tc9563_pwrctrl_parse_device_dt(tc9563, child, port); + if (++port >= TC9563_MAX) + break; + + ret = tc9563_pwrctrl_parse_device_dt(child, &tc9563->cfg[port]); if (ret) break; @@ -626,8 +650,8 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) of_get_next_available_child(child, NULL); if (eth) { - ret = tc9563_pwrctrl_parse_device_dt(tc9563, - eth, TC9563_ETHERNET); + ret = tc9563_pwrctrl_parse_device_dt(eth, + &tc9563->ep_cfg); if (ret) break; }