Hi, Philipp, On 09.05.2025 13:51, Philipp Zabel wrote: > Hi Claudiu, > > On Mi, 2025-04-30 at 13:32 +0300, Claudiu wrote: >> From: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx> >> >> The Renesas RZ/G3S features a PCIe IP that complies with the PCI Express >> Base Specification 4.0 and supports speeds of up to 5 GT/s. It functions >> only as a root complex, with a single-lane (x1) configuration. The >> controller includes Type 1 configuration registers, as well as IP >> specific registers (called AXI registers) required for various adjustments. >> >> Other Renesas RZ SoCs (e.g., RZ/G3E, RZ/V2H) share the same AXI registers >> but have both Root Complex and Endpoint capabilities. As a result, the PCIe >> host driver can be reused for these variants with minimal adjustments. >> >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx> >> --- >> MAINTAINERS | 8 + >> drivers/pci/controller/Kconfig | 7 + >> drivers/pci/controller/Makefile | 1 + >> drivers/pci/controller/pcie-rzg3s-host.c | 1561 ++++++++++++++++++++++ >> 4 files changed, 1577 insertions(+) >> create mode 100644 drivers/pci/controller/pcie-rzg3s-host.c >> > [...] >> diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c >> new file mode 100644 >> index 000000000000..c3bce0acd57e >> --- /dev/null >> +++ b/drivers/pci/controller/pcie-rzg3s-host.c >> @@ -0,0 +1,1561 @@ > [...] >> +static int rzg3s_pcie_resets_bulk_set(int (*action)(int num, struct reset_control_bulk_data *rstcs), >> + struct reset_control **resets, u8 num_resets) >> +{ >> + struct reset_control_bulk_data *data __free(kfree) = >> + kcalloc(num_resets, sizeof(*data), GFP_KERNEL); >> + >> + if (!data) >> + return -ENOMEM; >> + >> + for (u8 i = 0; i < num_resets; i++) >> + data[i].rstc = resets[i]; >> + >> + return action(num_resets, data); >> +} > > What is the purpose of this? Can't you just store struct > reset_control_bulk_data in struct rzg3s_pcie_host and call > reset_control_bulk_assert/deassert() directly? Yes, I can. I was trying to avoid storing also the reset_control_bulk_data in struct rzg3s_pcie_host since all that is needed can be retrieved from the already parsed in probe cfg_resets and power_resets. > >> +static int >> +rzg3s_pcie_resets_init(struct device *dev, struct reset_control ***resets, >> + struct reset_control *(*action)(struct device *dev, const char *id), >> + const char * const *reset_names, u8 num_resets) >> +{ >> + *resets = devm_kcalloc(dev, num_resets, sizeof(struct reset_control *), GFP_KERNEL); >> + if (!*resets) >> + return -ENOMEM; >> + >> + for (u8 i = 0; i < num_resets; i++) { >> + (*resets)[i] = action(dev, reset_names[i]); >> + if (IS_ERR((*resets)[i])) >> + return PTR_ERR((*resets)[i]); >> + } >> + >> + return 0; >> +} > > Why not use devm_reset_control_bulk_get_exclusive() directly? I wasn't able to find a bulk_get_exclusive_deasserted() kind of API. This IP needs particular sequence for configuration. First, after power on, the following resets need to be de-asserted: const char * const power_resets[] = { "aresetn", "rst_cfg_b", "rst_load_b", }; then, after proper values are written into the configuration registers, the rest of the resets need to be de-asserted: const char * const cfg_resets[] = { "rst_b", "rst_ps_b", "rst_gp_b", "rst_rsm_b", }; So I was trying to get and de-assert the power_resets in probe and just get the cfg_resets in the 1st step of the initialization, and later to de-assert the cfg_resets as well. Now, after you pointed it out, maybe you are proposing to just get_exclusive everything in one shot and then to de-assert what is needed at proper moments with generic reset control APIs? Thank you for your review, Claudiu