1*151f3d29SChristian Bruel // SPDX-License-Identifier: GPL-2.0-only 2*151f3d29SChristian Bruel /* 3*151f3d29SChristian Bruel * STMicroelectronics STM32MP25 PCIe endpoint driver. 4*151f3d29SChristian Bruel * 5*151f3d29SChristian Bruel * Copyright (C) 2025 STMicroelectronics 6*151f3d29SChristian Bruel * Author: Christian Bruel <christian.bruel@foss.st.com> 7*151f3d29SChristian Bruel */ 8*151f3d29SChristian Bruel 9*151f3d29SChristian Bruel #include <linux/clk.h> 10*151f3d29SChristian Bruel #include <linux/mfd/syscon.h> 11*151f3d29SChristian Bruel #include <linux/of_platform.h> 12*151f3d29SChristian Bruel #include <linux/of_gpio.h> 13*151f3d29SChristian Bruel #include <linux/phy/phy.h> 14*151f3d29SChristian Bruel #include <linux/platform_device.h> 15*151f3d29SChristian Bruel #include <linux/pm_runtime.h> 16*151f3d29SChristian Bruel #include <linux/regmap.h> 17*151f3d29SChristian Bruel #include <linux/reset.h> 18*151f3d29SChristian Bruel #include "pcie-designware.h" 19*151f3d29SChristian Bruel #include "pcie-stm32.h" 20*151f3d29SChristian Bruel 21*151f3d29SChristian Bruel struct stm32_pcie { 22*151f3d29SChristian Bruel struct dw_pcie pci; 23*151f3d29SChristian Bruel struct regmap *regmap; 24*151f3d29SChristian Bruel struct reset_control *rst; 25*151f3d29SChristian Bruel struct phy *phy; 26*151f3d29SChristian Bruel struct clk *clk; 27*151f3d29SChristian Bruel struct gpio_desc *perst_gpio; 28*151f3d29SChristian Bruel unsigned int perst_irq; 29*151f3d29SChristian Bruel }; 30*151f3d29SChristian Bruel 31*151f3d29SChristian Bruel static void stm32_pcie_ep_init(struct dw_pcie_ep *ep) 32*151f3d29SChristian Bruel { 33*151f3d29SChristian Bruel struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 34*151f3d29SChristian Bruel enum pci_barno bar; 35*151f3d29SChristian Bruel 36*151f3d29SChristian Bruel for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) 37*151f3d29SChristian Bruel dw_pcie_ep_reset_bar(pci, bar); 38*151f3d29SChristian Bruel } 39*151f3d29SChristian Bruel 40*151f3d29SChristian Bruel static int stm32_pcie_enable_link(struct dw_pcie *pci) 41*151f3d29SChristian Bruel { 42*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 43*151f3d29SChristian Bruel 44*151f3d29SChristian Bruel regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, 45*151f3d29SChristian Bruel STM32MP25_PCIECR_LTSSM_EN, 46*151f3d29SChristian Bruel STM32MP25_PCIECR_LTSSM_EN); 47*151f3d29SChristian Bruel 48*151f3d29SChristian Bruel return dw_pcie_wait_for_link(pci); 49*151f3d29SChristian Bruel } 50*151f3d29SChristian Bruel 51*151f3d29SChristian Bruel static void stm32_pcie_disable_link(struct dw_pcie *pci) 52*151f3d29SChristian Bruel { 53*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 54*151f3d29SChristian Bruel 55*151f3d29SChristian Bruel regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, STM32MP25_PCIECR_LTSSM_EN, 0); 56*151f3d29SChristian Bruel } 57*151f3d29SChristian Bruel 58*151f3d29SChristian Bruel static int stm32_pcie_start_link(struct dw_pcie *pci) 59*151f3d29SChristian Bruel { 60*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 61*151f3d29SChristian Bruel int ret; 62*151f3d29SChristian Bruel 63*151f3d29SChristian Bruel dev_dbg(pci->dev, "Enable link\n"); 64*151f3d29SChristian Bruel 65*151f3d29SChristian Bruel ret = stm32_pcie_enable_link(pci); 66*151f3d29SChristian Bruel if (ret) { 67*151f3d29SChristian Bruel dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret); 68*151f3d29SChristian Bruel return ret; 69*151f3d29SChristian Bruel } 70*151f3d29SChristian Bruel 71*151f3d29SChristian Bruel enable_irq(stm32_pcie->perst_irq); 72*151f3d29SChristian Bruel 73*151f3d29SChristian Bruel return 0; 74*151f3d29SChristian Bruel } 75*151f3d29SChristian Bruel 76*151f3d29SChristian Bruel static void stm32_pcie_stop_link(struct dw_pcie *pci) 77*151f3d29SChristian Bruel { 78*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 79*151f3d29SChristian Bruel 80*151f3d29SChristian Bruel dev_dbg(pci->dev, "Disable link\n"); 81*151f3d29SChristian Bruel 82*151f3d29SChristian Bruel disable_irq(stm32_pcie->perst_irq); 83*151f3d29SChristian Bruel 84*151f3d29SChristian Bruel stm32_pcie_disable_link(pci); 85*151f3d29SChristian Bruel } 86*151f3d29SChristian Bruel 87*151f3d29SChristian Bruel static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 88*151f3d29SChristian Bruel unsigned int type, u16 interrupt_num) 89*151f3d29SChristian Bruel { 90*151f3d29SChristian Bruel struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 91*151f3d29SChristian Bruel 92*151f3d29SChristian Bruel switch (type) { 93*151f3d29SChristian Bruel case PCI_IRQ_INTX: 94*151f3d29SChristian Bruel return dw_pcie_ep_raise_intx_irq(ep, func_no); 95*151f3d29SChristian Bruel case PCI_IRQ_MSI: 96*151f3d29SChristian Bruel return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 97*151f3d29SChristian Bruel default: 98*151f3d29SChristian Bruel dev_err(pci->dev, "UNKNOWN IRQ type\n"); 99*151f3d29SChristian Bruel return -EINVAL; 100*151f3d29SChristian Bruel } 101*151f3d29SChristian Bruel } 102*151f3d29SChristian Bruel 103*151f3d29SChristian Bruel static const struct pci_epc_features stm32_pcie_epc_features = { 104*151f3d29SChristian Bruel .msi_capable = true, 105*151f3d29SChristian Bruel .align = SZ_64K, 106*151f3d29SChristian Bruel }; 107*151f3d29SChristian Bruel 108*151f3d29SChristian Bruel static const struct pci_epc_features* 109*151f3d29SChristian Bruel stm32_pcie_get_features(struct dw_pcie_ep *ep) 110*151f3d29SChristian Bruel { 111*151f3d29SChristian Bruel return &stm32_pcie_epc_features; 112*151f3d29SChristian Bruel } 113*151f3d29SChristian Bruel 114*151f3d29SChristian Bruel static const struct dw_pcie_ep_ops stm32_pcie_ep_ops = { 115*151f3d29SChristian Bruel .init = stm32_pcie_ep_init, 116*151f3d29SChristian Bruel .raise_irq = stm32_pcie_raise_irq, 117*151f3d29SChristian Bruel .get_features = stm32_pcie_get_features, 118*151f3d29SChristian Bruel }; 119*151f3d29SChristian Bruel 120*151f3d29SChristian Bruel static const struct dw_pcie_ops dw_pcie_ops = { 121*151f3d29SChristian Bruel .start_link = stm32_pcie_start_link, 122*151f3d29SChristian Bruel .stop_link = stm32_pcie_stop_link, 123*151f3d29SChristian Bruel }; 124*151f3d29SChristian Bruel 125*151f3d29SChristian Bruel static int stm32_pcie_enable_resources(struct stm32_pcie *stm32_pcie) 126*151f3d29SChristian Bruel { 127*151f3d29SChristian Bruel int ret; 128*151f3d29SChristian Bruel 129*151f3d29SChristian Bruel ret = phy_init(stm32_pcie->phy); 130*151f3d29SChristian Bruel if (ret) 131*151f3d29SChristian Bruel return ret; 132*151f3d29SChristian Bruel 133*151f3d29SChristian Bruel ret = clk_prepare_enable(stm32_pcie->clk); 134*151f3d29SChristian Bruel if (ret) 135*151f3d29SChristian Bruel phy_exit(stm32_pcie->phy); 136*151f3d29SChristian Bruel 137*151f3d29SChristian Bruel return ret; 138*151f3d29SChristian Bruel } 139*151f3d29SChristian Bruel 140*151f3d29SChristian Bruel static void stm32_pcie_disable_resources(struct stm32_pcie *stm32_pcie) 141*151f3d29SChristian Bruel { 142*151f3d29SChristian Bruel clk_disable_unprepare(stm32_pcie->clk); 143*151f3d29SChristian Bruel 144*151f3d29SChristian Bruel phy_exit(stm32_pcie->phy); 145*151f3d29SChristian Bruel } 146*151f3d29SChristian Bruel 147*151f3d29SChristian Bruel static void stm32_pcie_perst_assert(struct dw_pcie *pci) 148*151f3d29SChristian Bruel { 149*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 150*151f3d29SChristian Bruel struct dw_pcie_ep *ep = &stm32_pcie->pci.ep; 151*151f3d29SChristian Bruel struct device *dev = pci->dev; 152*151f3d29SChristian Bruel 153*151f3d29SChristian Bruel dev_dbg(dev, "PERST asserted by host\n"); 154*151f3d29SChristian Bruel 155*151f3d29SChristian Bruel pci_epc_deinit_notify(ep->epc); 156*151f3d29SChristian Bruel 157*151f3d29SChristian Bruel stm32_pcie_disable_resources(stm32_pcie); 158*151f3d29SChristian Bruel 159*151f3d29SChristian Bruel pm_runtime_put_sync(dev); 160*151f3d29SChristian Bruel } 161*151f3d29SChristian Bruel 162*151f3d29SChristian Bruel static void stm32_pcie_perst_deassert(struct dw_pcie *pci) 163*151f3d29SChristian Bruel { 164*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 165*151f3d29SChristian Bruel struct device *dev = pci->dev; 166*151f3d29SChristian Bruel struct dw_pcie_ep *ep = &pci->ep; 167*151f3d29SChristian Bruel int ret; 168*151f3d29SChristian Bruel 169*151f3d29SChristian Bruel dev_dbg(dev, "PERST de-asserted by host\n"); 170*151f3d29SChristian Bruel 171*151f3d29SChristian Bruel ret = pm_runtime_resume_and_get(dev); 172*151f3d29SChristian Bruel if (ret < 0) { 173*151f3d29SChristian Bruel dev_err(dev, "Failed to resume runtime PM: %d\n", ret); 174*151f3d29SChristian Bruel return; 175*151f3d29SChristian Bruel } 176*151f3d29SChristian Bruel 177*151f3d29SChristian Bruel ret = stm32_pcie_enable_resources(stm32_pcie); 178*151f3d29SChristian Bruel if (ret) { 179*151f3d29SChristian Bruel dev_err(dev, "Failed to enable resources: %d\n", ret); 180*151f3d29SChristian Bruel goto err_pm_put_sync; 181*151f3d29SChristian Bruel } 182*151f3d29SChristian Bruel 183*151f3d29SChristian Bruel /* 184*151f3d29SChristian Bruel * Reprogram the configuration space registers here because the DBI 185*151f3d29SChristian Bruel * registers were reset by the PHY RCC during phy_init(). 186*151f3d29SChristian Bruel */ 187*151f3d29SChristian Bruel ret = dw_pcie_ep_init_registers(ep); 188*151f3d29SChristian Bruel if (ret) { 189*151f3d29SChristian Bruel dev_err(dev, "Failed to complete initialization: %d\n", ret); 190*151f3d29SChristian Bruel goto err_disable_resources; 191*151f3d29SChristian Bruel } 192*151f3d29SChristian Bruel 193*151f3d29SChristian Bruel pci_epc_init_notify(ep->epc); 194*151f3d29SChristian Bruel 195*151f3d29SChristian Bruel return; 196*151f3d29SChristian Bruel 197*151f3d29SChristian Bruel err_disable_resources: 198*151f3d29SChristian Bruel stm32_pcie_disable_resources(stm32_pcie); 199*151f3d29SChristian Bruel 200*151f3d29SChristian Bruel err_pm_put_sync: 201*151f3d29SChristian Bruel pm_runtime_put_sync(dev); 202*151f3d29SChristian Bruel } 203*151f3d29SChristian Bruel 204*151f3d29SChristian Bruel static irqreturn_t stm32_pcie_ep_perst_irq_thread(int irq, void *data) 205*151f3d29SChristian Bruel { 206*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = data; 207*151f3d29SChristian Bruel struct dw_pcie *pci = &stm32_pcie->pci; 208*151f3d29SChristian Bruel u32 perst; 209*151f3d29SChristian Bruel 210*151f3d29SChristian Bruel perst = gpiod_get_value(stm32_pcie->perst_gpio); 211*151f3d29SChristian Bruel if (perst) 212*151f3d29SChristian Bruel stm32_pcie_perst_assert(pci); 213*151f3d29SChristian Bruel else 214*151f3d29SChristian Bruel stm32_pcie_perst_deassert(pci); 215*151f3d29SChristian Bruel 216*151f3d29SChristian Bruel irq_set_irq_type(gpiod_to_irq(stm32_pcie->perst_gpio), 217*151f3d29SChristian Bruel (perst ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW)); 218*151f3d29SChristian Bruel 219*151f3d29SChristian Bruel return IRQ_HANDLED; 220*151f3d29SChristian Bruel } 221*151f3d29SChristian Bruel 222*151f3d29SChristian Bruel static int stm32_add_pcie_ep(struct stm32_pcie *stm32_pcie, 223*151f3d29SChristian Bruel struct platform_device *pdev) 224*151f3d29SChristian Bruel { 225*151f3d29SChristian Bruel struct dw_pcie_ep *ep = &stm32_pcie->pci.ep; 226*151f3d29SChristian Bruel struct device *dev = &pdev->dev; 227*151f3d29SChristian Bruel int ret; 228*151f3d29SChristian Bruel 229*151f3d29SChristian Bruel ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, 230*151f3d29SChristian Bruel STM32MP25_PCIECR_TYPE_MASK, 231*151f3d29SChristian Bruel STM32MP25_PCIECR_EP); 232*151f3d29SChristian Bruel if (ret) 233*151f3d29SChristian Bruel return ret; 234*151f3d29SChristian Bruel 235*151f3d29SChristian Bruel reset_control_assert(stm32_pcie->rst); 236*151f3d29SChristian Bruel reset_control_deassert(stm32_pcie->rst); 237*151f3d29SChristian Bruel 238*151f3d29SChristian Bruel ep->ops = &stm32_pcie_ep_ops; 239*151f3d29SChristian Bruel 240*151f3d29SChristian Bruel ret = dw_pcie_ep_init(ep); 241*151f3d29SChristian Bruel if (ret) { 242*151f3d29SChristian Bruel dev_err(dev, "Failed to initialize ep: %d\n", ret); 243*151f3d29SChristian Bruel return ret; 244*151f3d29SChristian Bruel } 245*151f3d29SChristian Bruel 246*151f3d29SChristian Bruel ret = stm32_pcie_enable_resources(stm32_pcie); 247*151f3d29SChristian Bruel if (ret) { 248*151f3d29SChristian Bruel dev_err(dev, "Failed to enable resources: %d\n", ret); 249*151f3d29SChristian Bruel dw_pcie_ep_deinit(ep); 250*151f3d29SChristian Bruel return ret; 251*151f3d29SChristian Bruel } 252*151f3d29SChristian Bruel 253*151f3d29SChristian Bruel return 0; 254*151f3d29SChristian Bruel } 255*151f3d29SChristian Bruel 256*151f3d29SChristian Bruel static int stm32_pcie_probe(struct platform_device *pdev) 257*151f3d29SChristian Bruel { 258*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie; 259*151f3d29SChristian Bruel struct device *dev = &pdev->dev; 260*151f3d29SChristian Bruel int ret; 261*151f3d29SChristian Bruel 262*151f3d29SChristian Bruel stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL); 263*151f3d29SChristian Bruel if (!stm32_pcie) 264*151f3d29SChristian Bruel return -ENOMEM; 265*151f3d29SChristian Bruel 266*151f3d29SChristian Bruel stm32_pcie->pci.dev = dev; 267*151f3d29SChristian Bruel stm32_pcie->pci.ops = &dw_pcie_ops; 268*151f3d29SChristian Bruel 269*151f3d29SChristian Bruel stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg"); 270*151f3d29SChristian Bruel if (IS_ERR(stm32_pcie->regmap)) 271*151f3d29SChristian Bruel return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap), 272*151f3d29SChristian Bruel "No syscfg specified\n"); 273*151f3d29SChristian Bruel 274*151f3d29SChristian Bruel stm32_pcie->phy = devm_phy_get(dev, NULL); 275*151f3d29SChristian Bruel if (IS_ERR(stm32_pcie->phy)) 276*151f3d29SChristian Bruel return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy), 277*151f3d29SChristian Bruel "failed to get pcie-phy\n"); 278*151f3d29SChristian Bruel 279*151f3d29SChristian Bruel stm32_pcie->clk = devm_clk_get(dev, NULL); 280*151f3d29SChristian Bruel if (IS_ERR(stm32_pcie->clk)) 281*151f3d29SChristian Bruel return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk), 282*151f3d29SChristian Bruel "Failed to get PCIe clock source\n"); 283*151f3d29SChristian Bruel 284*151f3d29SChristian Bruel stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL); 285*151f3d29SChristian Bruel if (IS_ERR(stm32_pcie->rst)) 286*151f3d29SChristian Bruel return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst), 287*151f3d29SChristian Bruel "Failed to get PCIe reset\n"); 288*151f3d29SChristian Bruel 289*151f3d29SChristian Bruel stm32_pcie->perst_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN); 290*151f3d29SChristian Bruel if (IS_ERR(stm32_pcie->perst_gpio)) 291*151f3d29SChristian Bruel return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio), 292*151f3d29SChristian Bruel "Failed to get reset GPIO\n"); 293*151f3d29SChristian Bruel 294*151f3d29SChristian Bruel ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE); 295*151f3d29SChristian Bruel if (ret) 296*151f3d29SChristian Bruel return ret; 297*151f3d29SChristian Bruel 298*151f3d29SChristian Bruel platform_set_drvdata(pdev, stm32_pcie); 299*151f3d29SChristian Bruel 300*151f3d29SChristian Bruel pm_runtime_get_noresume(dev); 301*151f3d29SChristian Bruel 302*151f3d29SChristian Bruel ret = devm_pm_runtime_enable(dev); 303*151f3d29SChristian Bruel if (ret < 0) { 304*151f3d29SChristian Bruel pm_runtime_put_noidle(&pdev->dev); 305*151f3d29SChristian Bruel return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); 306*151f3d29SChristian Bruel } 307*151f3d29SChristian Bruel 308*151f3d29SChristian Bruel stm32_pcie->perst_irq = gpiod_to_irq(stm32_pcie->perst_gpio); 309*151f3d29SChristian Bruel 310*151f3d29SChristian Bruel /* Will be enabled in start_link when device is initialized. */ 311*151f3d29SChristian Bruel irq_set_status_flags(stm32_pcie->perst_irq, IRQ_NOAUTOEN); 312*151f3d29SChristian Bruel 313*151f3d29SChristian Bruel ret = devm_request_threaded_irq(dev, stm32_pcie->perst_irq, NULL, 314*151f3d29SChristian Bruel stm32_pcie_ep_perst_irq_thread, 315*151f3d29SChristian Bruel IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 316*151f3d29SChristian Bruel "perst_irq", stm32_pcie); 317*151f3d29SChristian Bruel if (ret) { 318*151f3d29SChristian Bruel pm_runtime_put_noidle(&pdev->dev); 319*151f3d29SChristian Bruel return dev_err_probe(dev, ret, "Failed to request PERST IRQ\n"); 320*151f3d29SChristian Bruel } 321*151f3d29SChristian Bruel 322*151f3d29SChristian Bruel ret = stm32_add_pcie_ep(stm32_pcie, pdev); 323*151f3d29SChristian Bruel if (ret) 324*151f3d29SChristian Bruel pm_runtime_put_noidle(&pdev->dev); 325*151f3d29SChristian Bruel 326*151f3d29SChristian Bruel return ret; 327*151f3d29SChristian Bruel } 328*151f3d29SChristian Bruel 329*151f3d29SChristian Bruel static void stm32_pcie_remove(struct platform_device *pdev) 330*151f3d29SChristian Bruel { 331*151f3d29SChristian Bruel struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev); 332*151f3d29SChristian Bruel struct dw_pcie *pci = &stm32_pcie->pci; 333*151f3d29SChristian Bruel struct dw_pcie_ep *ep = &pci->ep; 334*151f3d29SChristian Bruel 335*151f3d29SChristian Bruel dw_pcie_stop_link(pci); 336*151f3d29SChristian Bruel 337*151f3d29SChristian Bruel pci_epc_deinit_notify(ep->epc); 338*151f3d29SChristian Bruel dw_pcie_ep_deinit(ep); 339*151f3d29SChristian Bruel 340*151f3d29SChristian Bruel stm32_pcie_disable_resources(stm32_pcie); 341*151f3d29SChristian Bruel 342*151f3d29SChristian Bruel pm_runtime_put_sync(&pdev->dev); 343*151f3d29SChristian Bruel } 344*151f3d29SChristian Bruel 345*151f3d29SChristian Bruel static const struct of_device_id stm32_pcie_ep_of_match[] = { 346*151f3d29SChristian Bruel { .compatible = "st,stm32mp25-pcie-ep" }, 347*151f3d29SChristian Bruel {}, 348*151f3d29SChristian Bruel }; 349*151f3d29SChristian Bruel 350*151f3d29SChristian Bruel static struct platform_driver stm32_pcie_ep_driver = { 351*151f3d29SChristian Bruel .probe = stm32_pcie_probe, 352*151f3d29SChristian Bruel .remove = stm32_pcie_remove, 353*151f3d29SChristian Bruel .driver = { 354*151f3d29SChristian Bruel .name = "stm32-ep-pcie", 355*151f3d29SChristian Bruel .of_match_table = stm32_pcie_ep_of_match, 356*151f3d29SChristian Bruel }, 357*151f3d29SChristian Bruel }; 358*151f3d29SChristian Bruel 359*151f3d29SChristian Bruel module_platform_driver(stm32_pcie_ep_driver); 360*151f3d29SChristian Bruel 361*151f3d29SChristian Bruel MODULE_AUTHOR("Christian Bruel <christian.bruel@foss.st.com>"); 362*151f3d29SChristian Bruel MODULE_DESCRIPTION("STM32MP25 PCIe Endpoint Controller driver"); 363*151f3d29SChristian Bruel MODULE_LICENSE("GPL"); 364*151f3d29SChristian Bruel MODULE_DEVICE_TABLE(of, stm32_pcie_ep_of_match); 365