From: Bjorn Helgaas <helgaas@kernel.org>
To: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: "Rob Herring" <robh@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
"Jingoo Han" <jingoohan1@gmail.com>,
"Gustavo Pimentel" <gustavo.pimentel@synopsys.com>,
"Krzysztof Wilczyński" <kw@linux.com>,
"Serge Semin" <fancer.lancer@gmail.com>,
"Alexey Malahov" <Alexey.Malahov@baikalelectronics.ru>,
"Pavel Parkhomenko" <Pavel.Parkhomenko@baikalelectronics.ru>,
"Frank Li" <Frank.Li@nxp.com>,
"Manivannan Sadhasivam" <manivannan.sadhasivam@linaro.org>,
"Rob Herring" <robh+dt@kernel.org>,
linux-pci@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 17/17] PCI: dwc: Add Baikal-T1 PCIe controller support
Date: Wed, 15 Jun 2022 11:48:48 -0500 [thread overview]
Message-ID: <20220615164848.GA941930@bhelgaas> (raw)
In-Reply-To: <20220610085706.15741-18-Sergey.Semin@baikalelectronics.ru>
On Fri, Jun 10, 2022 at 11:57:05AM +0300, Serge Semin wrote:
> Baikal-T1 SoC is equipped with DWC PCIe v4.60a host controller. It can be
> trained to work up to Gen.3 speed over up to x4 lanes. The host controller
> is attached to the DW PCIe 3.0 PCS via the PIPE-4 interface, which in its
> turn is connected to the DWC 10G PHY. The whole system is supposed to be
> fed up with four clock sources: DBI peripheral clock, AXI application
> clocks and external PHY/core reference clock generating the 100MHz signal.
> In addition to that the platform provide a way to reset each part of the
> controller: sticky/non-sticky bits, host controller core, PIPE interface,
> PCS/PHY and Hot/Power reset signal. The driver also provides a way to
> handle the GPIO-based PERST# signal.
>
> Note due to the Baikal-T1 MMIO peculiarity we have to implement the DBI
> interface accessors which make sure the IO operations are dword-aligned.
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> +static int bt1_pcie_start_ltssm(struct dw_pcie *pci)
> +{
> + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> + u32 val;
> + int ret;
> +
> + /*
> + * Enable LTSSM and make sure it was able to establish both PHY and
> + * data links. This procedure shall work fine to reach 2.5 GT/s speed.
> + */
> + regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
> + BT1_CCU_PCIE_LTSSM_EN, BT1_CCU_PCIE_LTSSM_EN);
> +
> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_PMSC, val,
> + (val & BT1_CCU_PCIE_SMLH_LINKUP),
> + 1000, 1000000);
> + if (ret) {
> + dev_err(pci->dev, "LTSSM failed to set PHY link up\n");
> + return ret;
> + }
> +
> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_PMSC, val,
> + (val & BT1_CCU_PCIE_RDLH_LINKUP),
> + 1000, 1000000);
> + if (ret) {
> + dev_err(pci->dev, "LTSSM failed to set data link up\n");
> + return ret;
> + }
> +
> + /*
> + * Activate direct speed change after the link is established in an
> + * attempt to reach a higher bus performance (up to Gen.3 - 8.0 GT/s).
> + * This is required at least to get 8.0 GT/s speed.
> + */
> + val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> + val |= PORT_LOGIC_SPEED_CHANGE;
> + dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
> +
> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_PMSC, val,
> + BT1_CCU_PCIE_LTSSM_LINKUP(val),
> + 1000, 1000000);
> + if (ret)
> + dev_err(pci->dev, "LTSSM failed to get into L0 state\n");
> +
> + return ret;
> +}
> +
> +static void bt1_pcie_stop_ltssm(struct dw_pcie *pci)
> +{
> + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> +
> + regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
> + BT1_CCU_PCIE_LTSSM_EN, 0);
> +}
> +
> +struct dw_pcie_ops bt1_pcie_dw_ops = {
> + .read_dbi = bt1_pcie_read_dbi,
> + .write_dbi = bt1_pcie_write_dbi,
> + .write_dbi2 = bt1_pcie_write_dbi2,
> + .start_link = bt1_pcie_start_ltssm,
> + .stop_link = bt1_pcie_stop_ltssm,
> +};
Should be static and const. Please rename to "dw_pcie_ops" as most
drivers use. Please rename bt1_pcie_start_ltssm() and
bt1_pcie_stop_ltssm() to bt1_pcie_start_link() and
bt1_pcie_stop_link() for consistency with other drivers to make
maintenance easier.
> +static struct pci_ops bt1_pcie_ops = {
> + .map_bus = dw_pcie_own_conf_map_bus,
> + .read = pci_generic_config_read32,
> + .write = pci_generic_config_write32,
> +};
> +
> +static int bt1_pcie_get_res(struct bt1_pcie *btpci)
Can you name this something similar to what other drivers use? There
are a couple *_pcie_get_resources() functions (normally called from
*_pcie_probe()), but no *_get_res() yet.
> +{
> + struct device *dev = btpci->dw.dev;
> + int i, ret;
> +
> + /* DBI access is supposed to be performed by the dword-aligned IOs */
> + btpci->dw.pp.bridge->ops = &bt1_pcie_ops;
> +
> + /* AXI-interface is configured with 64-bit address bus width */
> + ret = dma_coerce_mask_and_coherent(&btpci->dw.pp.bridge->dev,
> + DMA_BIT_MASK(64));
Just to double-check since this is the first instance of
dma_coerce_mask_and_coherent() in drivers/pci -- I guess Baikal-T1 is
unique in needing this?
> + if (ret) {
> + ret = dma_set_mask_and_coherent(&btpci->dw.pp.bridge->dev,
> + DMA_BIT_MASK(32));
Also the first instance of dma_set_mask_and_coherent() in dwc-based
drivers, so double-checking here, too.
> + if (ret)
> + return ret;
> + }
> +
> + /* These CSRs are in MMIO so we won't check the regmap-methods status */
> + btpci->sys_regs =
> + syscon_regmap_lookup_by_phandle(dev->of_node, "baikal,bt1-syscon");
> + if (IS_ERR(btpci->sys_regs))
> + return dev_err_probe(dev, PTR_ERR(btpci->sys_regs),
> + "Failed to get syscon\n");
> +
> + /* Make sure all the required resources have been specified */
> + for (i = 0; i < BT1_PCIE_NUM_APP_CLKS; i++) {
> + if (!btpci->dw.app_clks[bt1_pcie_app_clks[i]].clk) {
> + dev_err(dev, "App clocks set is incomplete\n");
> + return -ENOENT;
> + }
> + }
> +
> + for (i = 0; i < BT1_PCIE_NUM_CORE_CLKS; i++) {
> + if (!btpci->dw.core_clks[bt1_pcie_core_clks[i]].clk) {
> + dev_err(dev, "Core clocks set is incomplete\n");
> + return -ENOENT;
> + }
> + }
> +
> + for (i = 0; i < BT1_PCIE_NUM_APP_RSTS; i++) {
> + if (!btpci->dw.app_rsts[bt1_pcie_app_rsts[i]].rstc) {
> + dev_err(dev, "App resets set is incomplete\n");
> + return -ENOENT;
> + }
> + }
> +
> + for (i = 0; i < BT1_PCIE_NUM_CORE_RSTS; i++) {
> + if (!btpci->dw.core_rsts[bt1_pcie_core_rsts[i]].rstc) {
> + dev_err(dev, "Core resets set is incomplete\n");
> + return -ENOENT;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void bt1_pcie_full_stop_bus(struct bt1_pcie *btpci, bool init)
Can you name this something similar to what other drivers use?
> +{
> + struct device *dev = btpci->dw.dev;
> + struct dw_pcie *pci = &btpci->dw;
> + int ret;
> +
> + /* Disable LTSSM for sure */
> + regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
> + BT1_CCU_PCIE_LTSSM_EN, 0);
> +
> + /*
> + * Application reset controls are trigger-based so de-assert the core
> + * resets only.
> + */
> + ret = reset_control_bulk_assert(DW_PCIE_NUM_CORE_RSTS, pci->core_rsts);
> + if (ret)
> + dev_err(dev, "Failed to assert core resets\n");
> +
> + /*
> + * Clocks are disabled by default at least in accordance with the clk
> + * enable counter value on init stage.
> + */
> + if (!init) {
> + clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> +
> + clk_bulk_disable_unprepare(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> + }
> +
> + /* The peripheral devices are unavailable anyway so reset them too */
> + gpiod_set_value_cansleep(pci->pe_rst, 1);
> +
> + /* Make sure the reset is settled */
> + usleep_range(1, 10);
Is this duration related to something in the PCIe spec? Or the DWC
spec? I'd really like to use named constants when possible, although
we have a ton of bare magic numbers currently.
Similar for the poll timeouts and the "state settled" sleep below.
> +}
> +
> +/*
> + * Implements the cold reset procedure in accordance with the reference manual
> + * and available PM signals.
> + */
> +static int bt1_pcie_cold_start_bus(struct bt1_pcie *btpci)
> +{
> + struct device *dev = btpci->dw.dev;
> + struct dw_pcie *pci = &btpci->dw;
> + u32 val;
> + int ret;
> +
> + /* First get out of the Power/Hot reset state */
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert PHY reset\n");
> + return ret;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert hot reset\n");
> + goto err_assert_pwr_rst;
> + }
> +
> + /* Wait for the PM-core to stop requesting the PHY reset */
> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> + !(val & BT1_CCU_PCIE_REQ_PHY_RST), 1, 1000);
> + if (ret) {
> + dev_err(dev, "Timed out waiting for PM to stop PHY resetting\n");
> + goto err_assert_hot_rst;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert PHY reset\n");
> + goto err_assert_hot_rst;
> + }
> +
> + /* Clocks can be now enabled, but the ref one is crucial at this stage */
> + ret = clk_bulk_prepare_enable(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> + if (ret) {
> + dev_err(dev, "Failed to enable app clocks\n");
> + goto err_assert_phy_rst;
> + }
> +
> + ret = clk_bulk_prepare_enable(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> + if (ret) {
> + dev_err(dev, "Failed to enable ref clocks\n");
> + goto err_disable_app_clk;
> + }
> +
> + /* Wait for the PM to stop requesting the controller core reset */
> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> + !(val & BT1_CCU_PCIE_REQ_CORE_RST), 1, 1000);
> + if (ret) {
> + dev_err(dev, "Timed out waiting for PM to stop core resetting\n");
> + goto err_disable_core_clk;
> + }
> +
> + /* PCS-PIPE interface and controller core can be now activated */
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert PIPE reset\n");
> + goto err_disable_core_clk;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert core reset\n");
> + goto err_assert_pipe_rst;
> + }
> +
> + /* It's recommended to reset the core and application logic together */
> + ret = reset_control_bulk_reset(DW_PCIE_NUM_APP_RSTS, pci->app_rsts);
> + if (ret) {
> + dev_err(dev, "Failed to reset app domain\n");
> + goto err_assert_core_rst;
> + }
> +
> + /* Sticky/Non-sticky CSR flags can be now unreset too */
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert sticky reset\n");
> + goto err_assert_core_rst;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_NON_STICKY_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert non-sticky reset\n");
> + goto err_assert_sticky_rst;
> + }
> +
> + /* Activate the PCIe bus peripheral devices */
> + gpiod_set_value_cansleep(pci->pe_rst, 0);
> +
> + /* Make sure the state is settled (LTSSM is still disabled though) */
> + usleep_range(1, 10);
> +
> + return 0;
> +
> +err_assert_sticky_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
> +
> +err_assert_core_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
> +
> +err_assert_pipe_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
> +
> +err_disable_core_clk:
> + clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> +
> +err_disable_app_clk:
> + clk_bulk_disable_unprepare(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> +
> +err_assert_phy_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
> +
> +err_assert_hot_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> +
> +err_assert_pwr_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> +
> + return ret;
> +}
> +
> +static int bt1_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> + int ret;
> +
> + ret = bt1_pcie_get_res(btpci);
> + if (ret)
> + return ret;
> +
> + bt1_pcie_full_stop_bus(btpci, true);
> +
> + return bt1_pcie_cold_start_bus(btpci);
Generally I think the get_res-type stuff happens elsewhere. I'm not
an expert in that, but this doesn't look much like other
*_pcie_host_init() functions, which mainly deal with enabling clocks,
reset assertion/deassertion, PHY init, interrupt enable, etc.
Maybe this is connected with your new common clocks/resets properties.
I'm certainly in favor of making as much of that common as is
practical! I hope we can take advantage of that and make more
consistency across the dwc-based drivers as well.
> +}
> +
> +static void bt1_pcie_host_deinit(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> +
> + bt1_pcie_full_stop_bus(btpci, false);
> +}
> +
> +struct dw_pcie_host_ops bt1_pcie_host_ops = {
> + .host_init = bt1_pcie_host_init,
> + .host_deinit = bt1_pcie_host_deinit,
> +};
> +
> +static struct bt1_pcie *bt1_pcie_create_data(struct platform_device *pdev)
> +{
> + struct bt1_pcie *btpci;
> +
> + btpci = devm_kzalloc(&pdev->dev, sizeof(*btpci), GFP_KERNEL);
> + if (!btpci)
> + return ERR_PTR(-ENOMEM);
> +
> + btpci->pdev = pdev;
> +
> + platform_set_drvdata(pdev, btpci);
> +
> + return btpci;
I don't think it's worth splitting this into a separate function. I
think it would be better to use the same structure as other dwc-based
drivers and keep this in bt1_pcie_probe().
> +}
> +
> +static int bt1_pcie_add_dw_port(struct bt1_pcie *btpci)
All other dwc-based drivers call dw_pcie_host_init() from either
*_pcie_probe() or *_add_pcie_port(). Please use a similar convention.
> +{
> + struct device *dev = &btpci->pdev->dev;
> + int ret;
> +
> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
Why do you need this when no other dwc-based drivers do? Is Baikal-T1
different in this respect?
> + if (ret)
> + return ret;
> +
> + btpci->dw.version = DW_PCIE_VER_460A;
> + btpci->dw.dev = dev;
> + btpci->dw.ops = &bt1_pcie_dw_ops;
> +
> + btpci->dw.pp.num_vectors = MAX_MSI_IRQS;
> + btpci->dw.pp.ops = &bt1_pcie_host_ops;
> +
> + dw_pcie_cap_set(&btpci->dw, REQ_RES);
> +
> + ret = dw_pcie_host_init(&btpci->dw.pp);
> + if (ret)
> + dev_err_probe(dev, ret, "Failed to initialize DWC PCIe host\n");
> +
> + return ret;
> +}
> +
> +static void bt1_pcie_del_dw_port(struct bt1_pcie *btpci)
Can you call dw_pcie_host_deinit() from the same place as other
drivers?
$ git grep -p dw_pcie_host_deinit drivers/pci/controller/dwc
> +{
> + dw_pcie_host_deinit(&btpci->dw.pp);
> +}
> +
> +static int bt1_pcie_probe(struct platform_device *pdev)
> +{
> + struct bt1_pcie *btpci;
> +
> + btpci = bt1_pcie_create_data(pdev);
> + if (IS_ERR(btpci))
> + return PTR_ERR(btpci);
> +
> + return bt1_pcie_add_dw_port(btpci);
> +}
> +
> +static int bt1_pcie_remove(struct platform_device *pdev)
> +{
> + struct bt1_pcie *btpci = platform_get_drvdata(pdev);
> +
> + bt1_pcie_del_dw_port(btpci);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id bt1_pcie_of_match[] = {
> + { .compatible = "baikal,bt1-pcie" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, bt1_pcie_of_match);
> +
> +static struct platform_driver bt1_pcie_driver = {
> + .probe = bt1_pcie_probe,
> + .remove = bt1_pcie_remove,
> + .driver = {
> + .name = "bt1-pcie",
> + .of_match_table = bt1_pcie_of_match,
> + },
> +};
> +module_platform_driver(bt1_pcie_driver);
> +
> +MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
> +MODULE_DESCRIPTION("Baikal-T1 PCIe driver");
> +MODULE_LICENSE("GPL");
> --
> 2.35.1
>
next prev parent reply other threads:[~2022-06-15 16:48 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-10 8:56 [PATCH v3 00/17] PCI: dwc: Add generic resources and Baikal-T1 support Serge Semin
2022-06-10 8:56 ` [PATCH v3 01/17] dt-bindings: PCI: dwc: Detach common RP/EP DT bindings Serge Semin
2022-06-10 8:56 ` [PATCH v3 02/17] dt-bindings: PCI: dwc: Remove bus node from the examples Serge Semin
2022-06-15 16:30 ` Rob Herring
2022-06-10 8:56 ` [PATCH v3 03/17] dt-bindings: PCI: dwc: Add phys/phy-names common properties Serge Semin
2022-06-10 8:56 ` [PATCH v3 04/17] dt-bindings: PCI: dwc: Add max-link-speed common property Serge Semin
2022-06-15 14:55 ` Rob Herring
2022-06-19 14:27 ` Serge Semin
2022-06-28 12:15 ` Serge Semin
2022-06-28 14:56 ` Rob Herring
2022-06-29 1:50 ` Serge Semin
2022-07-01 14:44 ` Rob Herring
2022-07-07 19:02 ` Serge Semin
2022-06-10 8:56 ` [PATCH v3 05/17] dt-bindings: PCI: dwc: Stop selecting generic bindings by default Serge Semin
2022-06-10 8:56 ` Serge Semin
2022-06-10 8:56 ` Serge Semin
2022-06-10 8:56 ` [PATCH v3 06/17] dt-bindings: PCI: dwc: Add max-functions EP property Serge Semin
2022-06-15 16:31 ` Rob Herring
2022-06-10 8:56 ` [PATCH v3 07/17] dt-bindings: PCI: dwc: Add interrupts/interrupt-names common properties Serge Semin
2022-06-15 15:32 ` Rob Herring
2022-06-19 16:37 ` Serge Semin
2022-06-28 12:18 ` Serge Semin
2022-07-07 19:25 ` Serge Semin
2022-06-10 8:56 ` [PATCH v3 08/17] dt-bindings: PCI: dwc: Add reg/reg-names " Serge Semin
2022-06-10 8:56 ` [PATCH v3 09/17] dt-bindings: PCI: dwc: Add clocks/resets " Serge Semin
2022-06-10 8:56 ` Serge Semin
2022-06-10 8:56 ` [PATCH v3 10/17] dt-bindings: PCI: dwc: Add dma-coherent property Serge Semin
2022-06-10 8:56 ` [PATCH v3 11/17] dt-bindings: PCI: dwc: Apply common schema to Rockchip DW PCIe nodes Serge Semin
2022-06-10 8:56 ` Serge Semin
2022-06-10 8:56 ` Serge Semin
2022-06-10 13:12 ` Rob Herring
2022-06-10 13:12 ` Rob Herring
2022-06-10 13:12 ` Rob Herring
2022-06-10 21:13 ` Serge Semin
2022-06-10 21:13 ` Serge Semin
2022-06-10 21:13 ` Serge Semin
2022-06-10 8:57 ` [PATCH v3 12/17] dt-bindings: PCI: dwc: Add Baikal-T1 PCIe Root Port bindings Serge Semin
2022-06-15 16:37 ` Rob Herring
2022-06-19 20:03 ` Serge Semin
2022-06-28 12:19 ` Serge Semin
2022-07-01 14:59 ` Rob Herring
2022-07-07 19:19 ` Serge Semin
2022-06-10 8:57 ` [PATCH v3 13/17] PCI: dwc: Introduce generic controller capabilities interface Serge Semin
2022-06-15 16:42 ` Rob Herring
2022-06-10 8:57 ` [PATCH v3 14/17] PCI: dwc: Introduce generic resources getter Serge Semin
2022-06-15 16:46 ` Rob Herring
2022-06-10 8:57 ` [PATCH v3 15/17] PCI: dwc: Combine iATU detection procedures Serge Semin
2022-06-15 16:47 ` Rob Herring
2022-06-10 8:57 ` [PATCH v3 16/17] PCI: dwc: Introduce generic platform clocks and resets Serge Semin
2022-06-10 8:57 ` [PATCH v3 17/17] PCI: dwc: Add Baikal-T1 PCIe controller support Serge Semin
2022-06-15 16:48 ` Bjorn Helgaas [this message]
2022-06-20 17:13 ` Serge Semin
2022-06-21 18:29 ` Bjorn Helgaas
2022-06-22 17:04 ` Serge Semin
2022-06-28 12:23 ` Serge Semin
2022-06-28 15:17 ` Bjorn Helgaas
2022-06-15 17:10 ` Rob Herring
2022-06-19 20:39 ` Serge Semin
2022-07-12 20:29 ` Rob Herring
2022-07-12 20:58 ` Serge Semin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220615164848.GA941930@bhelgaas \
--to=helgaas@kernel.org \
--cc=Alexey.Malahov@baikalelectronics.ru \
--cc=Frank.Li@nxp.com \
--cc=Pavel.Parkhomenko@baikalelectronics.ru \
--cc=Sergey.Semin@baikalelectronics.ru \
--cc=bhelgaas@google.com \
--cc=devicetree@vger.kernel.org \
--cc=fancer.lancer@gmail.com \
--cc=gustavo.pimentel@synopsys.com \
--cc=jingoohan1@gmail.com \
--cc=kw@linux.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=manivannan.sadhasivam@linaro.org \
--cc=robh+dt@kernel.org \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.