162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * DWC PCIe RC driver for Toshiba Visconti ARM SoC
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2021 Toshiba Electronic Device & Storage Corporation
662306a36Sopenharmony_ci * Copyright (C) 2021 TOSHIBA CORPORATION
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/clk.h>
1262306a36Sopenharmony_ci#include <linux/delay.h>
1362306a36Sopenharmony_ci#include <linux/gpio.h>
1462306a36Sopenharmony_ci#include <linux/interrupt.h>
1562306a36Sopenharmony_ci#include <linux/init.h>
1662306a36Sopenharmony_ci#include <linux/iopoll.h>
1762306a36Sopenharmony_ci#include <linux/kernel.h>
1862306a36Sopenharmony_ci#include <linux/of_platform.h>
1962306a36Sopenharmony_ci#include <linux/pci.h>
2062306a36Sopenharmony_ci#include <linux/platform_device.h>
2162306a36Sopenharmony_ci#include <linux/resource.h>
2262306a36Sopenharmony_ci#include <linux/types.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include "pcie-designware.h"
2562306a36Sopenharmony_ci#include "../../pci.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistruct visconti_pcie {
2862306a36Sopenharmony_ci	struct dw_pcie pci;
2962306a36Sopenharmony_ci	void __iomem *ulreg_base;
3062306a36Sopenharmony_ci	void __iomem *smu_base;
3162306a36Sopenharmony_ci	void __iomem *mpu_base;
3262306a36Sopenharmony_ci	struct clk *refclk;
3362306a36Sopenharmony_ci	struct clk *coreclk;
3462306a36Sopenharmony_ci	struct clk *auxclk;
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define PCIE_UL_REG_S_PCIE_MODE		0x00F4
3862306a36Sopenharmony_ci#define  PCIE_UL_REG_S_PCIE_MODE_EP	0x00
3962306a36Sopenharmony_ci#define  PCIE_UL_REG_S_PCIE_MODE_RC	0x04
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define PCIE_UL_REG_S_PERSTN_CTRL	0x00F8
4262306a36Sopenharmony_ci#define  PCIE_UL_IOM_PCIE_PERSTN_I_EN	BIT(3)
4362306a36Sopenharmony_ci#define  PCIE_UL_DIRECT_PERSTN_EN	BIT(2)
4462306a36Sopenharmony_ci#define  PCIE_UL_PERSTN_OUT		BIT(1)
4562306a36Sopenharmony_ci#define  PCIE_UL_DIRECT_PERSTN		BIT(0)
4662306a36Sopenharmony_ci#define  PCIE_UL_REG_S_PERSTN_CTRL_INIT	(PCIE_UL_IOM_PCIE_PERSTN_I_EN | \
4762306a36Sopenharmony_ci					 PCIE_UL_DIRECT_PERSTN_EN | \
4862306a36Sopenharmony_ci					 PCIE_UL_DIRECT_PERSTN)
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define PCIE_UL_REG_S_PHY_INIT_02	0x0104
5162306a36Sopenharmony_ci#define  PCIE_UL_PHY0_SRAM_EXT_LD_DONE	BIT(0)
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#define PCIE_UL_REG_S_PHY_INIT_03	0x0108
5462306a36Sopenharmony_ci#define  PCIE_UL_PHY0_SRAM_INIT_DONE	BIT(0)
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define PCIE_UL_REG_S_INT_EVENT_MASK1	0x0138
5762306a36Sopenharmony_ci#define  PCIE_UL_CFG_PME_INT		BIT(0)
5862306a36Sopenharmony_ci#define  PCIE_UL_CFG_LINK_EQ_REQ_INT	BIT(1)
5962306a36Sopenharmony_ci#define  PCIE_UL_EDMA_INT0		BIT(2)
6062306a36Sopenharmony_ci#define  PCIE_UL_EDMA_INT1		BIT(3)
6162306a36Sopenharmony_ci#define  PCIE_UL_EDMA_INT2		BIT(4)
6262306a36Sopenharmony_ci#define  PCIE_UL_EDMA_INT3		BIT(5)
6362306a36Sopenharmony_ci#define  PCIE_UL_S_INT_EVENT_MASK1_ALL  (PCIE_UL_CFG_PME_INT | \
6462306a36Sopenharmony_ci					 PCIE_UL_CFG_LINK_EQ_REQ_INT | \
6562306a36Sopenharmony_ci					 PCIE_UL_EDMA_INT0 | \
6662306a36Sopenharmony_ci					 PCIE_UL_EDMA_INT1 | \
6762306a36Sopenharmony_ci					 PCIE_UL_EDMA_INT2 | \
6862306a36Sopenharmony_ci					 PCIE_UL_EDMA_INT3)
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#define PCIE_UL_REG_S_SB_MON		0x0198
7162306a36Sopenharmony_ci#define PCIE_UL_REG_S_SIG_MON		0x019C
7262306a36Sopenharmony_ci#define  PCIE_UL_CORE_RST_N_MON		BIT(0)
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#define PCIE_UL_REG_V_SII_DBG_00	0x0844
7562306a36Sopenharmony_ci#define PCIE_UL_REG_V_SII_GEN_CTRL_01	0x0860
7662306a36Sopenharmony_ci#define  PCIE_UL_APP_LTSSM_ENABLE	BIT(0)
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define PCIE_UL_REG_V_PHY_ST_00		0x0864
7962306a36Sopenharmony_ci#define  PCIE_UL_SMLH_LINK_UP		BIT(0)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define PCIE_UL_REG_V_PHY_ST_02		0x0868
8262306a36Sopenharmony_ci#define  PCIE_UL_S_DETECT_ACT		0x01
8362306a36Sopenharmony_ci#define  PCIE_UL_S_L0			0x11
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define PISMU_CKON_PCIE			0x0038
8662306a36Sopenharmony_ci#define  PISMU_CKON_PCIE_AUX_CLK	BIT(1)
8762306a36Sopenharmony_ci#define  PISMU_CKON_PCIE_MSTR_ACLK	BIT(0)
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define PISMU_RSOFF_PCIE		0x0538
9062306a36Sopenharmony_ci#define  PISMU_RSOFF_PCIE_ULREG_RST_N	BIT(1)
9162306a36Sopenharmony_ci#define  PISMU_RSOFF_PCIE_PWR_UP_RST_N	BIT(0)
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci#define PCIE_MPU_REG_MP_EN		0x0
9462306a36Sopenharmony_ci#define  MPU_MP_EN_DISABLE		BIT(0)
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/* Access registers in PCIe ulreg */
9762306a36Sopenharmony_cistatic void visconti_ulreg_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	writel_relaxed(val, pcie->ulreg_base + reg);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic u32 visconti_ulreg_readl(struct visconti_pcie *pcie, u32 reg)
10362306a36Sopenharmony_ci{
10462306a36Sopenharmony_ci	return readl_relaxed(pcie->ulreg_base + reg);
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/* Access registers in PCIe smu */
10862306a36Sopenharmony_cistatic void visconti_smu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
10962306a36Sopenharmony_ci{
11062306a36Sopenharmony_ci	writel_relaxed(val, pcie->smu_base + reg);
11162306a36Sopenharmony_ci}
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/* Access registers in PCIe mpu */
11462306a36Sopenharmony_cistatic void visconti_mpu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci	writel_relaxed(val, pcie->mpu_base + reg);
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_cistatic u32 visconti_mpu_readl(struct visconti_pcie *pcie, u32 reg)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	return readl_relaxed(pcie->mpu_base + reg);
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic int visconti_pcie_link_up(struct dw_pcie *pci)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
12762306a36Sopenharmony_ci	void __iomem *addr = pcie->ulreg_base;
12862306a36Sopenharmony_ci	u32 val = readl_relaxed(addr + PCIE_UL_REG_V_PHY_ST_02);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	return !!(val & PCIE_UL_S_L0);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic int visconti_pcie_start_link(struct dw_pcie *pci)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
13662306a36Sopenharmony_ci	void __iomem *addr = pcie->ulreg_base;
13762306a36Sopenharmony_ci	u32 val;
13862306a36Sopenharmony_ci	int ret;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, PCIE_UL_APP_LTSSM_ENABLE,
14162306a36Sopenharmony_ci			      PCIE_UL_REG_V_SII_GEN_CTRL_01);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	ret = readl_relaxed_poll_timeout(addr + PCIE_UL_REG_V_PHY_ST_02,
14462306a36Sopenharmony_ci					 val, (val & PCIE_UL_S_L0),
14562306a36Sopenharmony_ci					 90000, 100000);
14662306a36Sopenharmony_ci	if (ret)
14762306a36Sopenharmony_ci		return ret;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, PCIE_UL_S_INT_EVENT_MASK1_ALL,
15062306a36Sopenharmony_ci			      PCIE_UL_REG_S_INT_EVENT_MASK1);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	if (dw_pcie_link_up(pci)) {
15362306a36Sopenharmony_ci		val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
15462306a36Sopenharmony_ci		visconti_mpu_writel(pcie, val & ~MPU_MP_EN_DISABLE,
15562306a36Sopenharmony_ci				    PCIE_MPU_REG_MP_EN);
15662306a36Sopenharmony_ci	}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	return 0;
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_cistatic void visconti_pcie_stop_link(struct dw_pcie *pci)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
16462306a36Sopenharmony_ci	u32 val;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	val = visconti_ulreg_readl(pcie, PCIE_UL_REG_V_SII_GEN_CTRL_01);
16762306a36Sopenharmony_ci	val &= ~PCIE_UL_APP_LTSSM_ENABLE;
16862306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_V_SII_GEN_CTRL_01);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
17162306a36Sopenharmony_ci	visconti_mpu_writel(pcie, val | MPU_MP_EN_DISABLE, PCIE_MPU_REG_MP_EN);
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci/*
17562306a36Sopenharmony_ci * In this SoC specification, the CPU bus outputs the offset value from
17662306a36Sopenharmony_ci * 0x40000000 to the PCIe bus, so 0x40000000 is subtracted from the CPU
17762306a36Sopenharmony_ci * bus address. This 0x40000000 is also based on io_base from DT.
17862306a36Sopenharmony_ci */
17962306a36Sopenharmony_cistatic u64 visconti_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	struct dw_pcie_rp *pp = &pci->pp;
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	return cpu_addr & ~pp->io_base;
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistatic const struct dw_pcie_ops dw_pcie_ops = {
18762306a36Sopenharmony_ci	.cpu_addr_fixup = visconti_pcie_cpu_addr_fixup,
18862306a36Sopenharmony_ci	.link_up = visconti_pcie_link_up,
18962306a36Sopenharmony_ci	.start_link = visconti_pcie_start_link,
19062306a36Sopenharmony_ci	.stop_link = visconti_pcie_stop_link,
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistatic int visconti_pcie_host_init(struct dw_pcie_rp *pp)
19462306a36Sopenharmony_ci{
19562306a36Sopenharmony_ci	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
19662306a36Sopenharmony_ci	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
19762306a36Sopenharmony_ci	void __iomem *addr;
19862306a36Sopenharmony_ci	int err;
19962306a36Sopenharmony_ci	u32 val;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	visconti_smu_writel(pcie,
20262306a36Sopenharmony_ci			    PISMU_CKON_PCIE_AUX_CLK | PISMU_CKON_PCIE_MSTR_ACLK,
20362306a36Sopenharmony_ci			    PISMU_CKON_PCIE);
20462306a36Sopenharmony_ci	ndelay(250);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_ULREG_RST_N,
20762306a36Sopenharmony_ci			    PISMU_RSOFF_PCIE);
20862306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, PCIE_UL_REG_S_PCIE_MODE_RC,
20962306a36Sopenharmony_ci			      PCIE_UL_REG_S_PCIE_MODE);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	val = PCIE_UL_REG_S_PERSTN_CTRL_INIT;
21262306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
21362306a36Sopenharmony_ci	udelay(100);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	val |= PCIE_UL_PERSTN_OUT;
21662306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
21762306a36Sopenharmony_ci	udelay(100);
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_PWR_UP_RST_N,
22062306a36Sopenharmony_ci			    PISMU_RSOFF_PCIE);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	addr = pcie->ulreg_base + PCIE_UL_REG_S_PHY_INIT_03;
22362306a36Sopenharmony_ci	err = readl_relaxed_poll_timeout(addr, val,
22462306a36Sopenharmony_ci					 (val & PCIE_UL_PHY0_SRAM_INIT_DONE),
22562306a36Sopenharmony_ci					 100, 1000);
22662306a36Sopenharmony_ci	if (err)
22762306a36Sopenharmony_ci		return err;
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	visconti_ulreg_writel(pcie, PCIE_UL_PHY0_SRAM_EXT_LD_DONE,
23062306a36Sopenharmony_ci			      PCIE_UL_REG_S_PHY_INIT_02);
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	addr = pcie->ulreg_base + PCIE_UL_REG_S_SIG_MON;
23362306a36Sopenharmony_ci	return readl_relaxed_poll_timeout(addr, val,
23462306a36Sopenharmony_ci					  (val & PCIE_UL_CORE_RST_N_MON), 100,
23562306a36Sopenharmony_ci					  1000);
23662306a36Sopenharmony_ci}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cistatic const struct dw_pcie_host_ops visconti_pcie_host_ops = {
23962306a36Sopenharmony_ci	.host_init = visconti_pcie_host_init,
24062306a36Sopenharmony_ci};
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_cistatic int visconti_get_resources(struct platform_device *pdev,
24362306a36Sopenharmony_ci				  struct visconti_pcie *pcie)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	pcie->ulreg_base = devm_platform_ioremap_resource_byname(pdev, "ulreg");
24862306a36Sopenharmony_ci	if (IS_ERR(pcie->ulreg_base))
24962306a36Sopenharmony_ci		return PTR_ERR(pcie->ulreg_base);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	pcie->smu_base = devm_platform_ioremap_resource_byname(pdev, "smu");
25262306a36Sopenharmony_ci	if (IS_ERR(pcie->smu_base))
25362306a36Sopenharmony_ci		return PTR_ERR(pcie->smu_base);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	pcie->mpu_base = devm_platform_ioremap_resource_byname(pdev, "mpu");
25662306a36Sopenharmony_ci	if (IS_ERR(pcie->mpu_base))
25762306a36Sopenharmony_ci		return PTR_ERR(pcie->mpu_base);
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	pcie->refclk = devm_clk_get(dev, "ref");
26062306a36Sopenharmony_ci	if (IS_ERR(pcie->refclk))
26162306a36Sopenharmony_ci		return dev_err_probe(dev, PTR_ERR(pcie->refclk),
26262306a36Sopenharmony_ci				     "Failed to get ref clock\n");
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	pcie->coreclk = devm_clk_get(dev, "core");
26562306a36Sopenharmony_ci	if (IS_ERR(pcie->coreclk))
26662306a36Sopenharmony_ci		return dev_err_probe(dev, PTR_ERR(pcie->coreclk),
26762306a36Sopenharmony_ci				     "Failed to get core clock\n");
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	pcie->auxclk = devm_clk_get(dev, "aux");
27062306a36Sopenharmony_ci	if (IS_ERR(pcie->auxclk))
27162306a36Sopenharmony_ci		return dev_err_probe(dev, PTR_ERR(pcie->auxclk),
27262306a36Sopenharmony_ci				     "Failed to get aux clock\n");
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	return 0;
27562306a36Sopenharmony_ci}
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_cistatic int visconti_add_pcie_port(struct visconti_pcie *pcie,
27862306a36Sopenharmony_ci				  struct platform_device *pdev)
27962306a36Sopenharmony_ci{
28062306a36Sopenharmony_ci	struct dw_pcie *pci = &pcie->pci;
28162306a36Sopenharmony_ci	struct dw_pcie_rp *pp = &pci->pp;
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	pp->irq = platform_get_irq_byname(pdev, "intr");
28462306a36Sopenharmony_ci	if (pp->irq < 0)
28562306a36Sopenharmony_ci		return pp->irq;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	pp->ops = &visconti_pcie_host_ops;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	return dw_pcie_host_init(pp);
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic int visconti_pcie_probe(struct platform_device *pdev)
29362306a36Sopenharmony_ci{
29462306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
29562306a36Sopenharmony_ci	struct visconti_pcie *pcie;
29662306a36Sopenharmony_ci	struct dw_pcie *pci;
29762306a36Sopenharmony_ci	int ret;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
30062306a36Sopenharmony_ci	if (!pcie)
30162306a36Sopenharmony_ci		return -ENOMEM;
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	pci = &pcie->pci;
30462306a36Sopenharmony_ci	pci->dev = dev;
30562306a36Sopenharmony_ci	pci->ops = &dw_pcie_ops;
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	ret = visconti_get_resources(pdev, pcie);
30862306a36Sopenharmony_ci	if (ret)
30962306a36Sopenharmony_ci		return ret;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	platform_set_drvdata(pdev, pcie);
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	return visconti_add_pcie_port(pcie, pdev);
31462306a36Sopenharmony_ci}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistatic const struct of_device_id visconti_pcie_match[] = {
31762306a36Sopenharmony_ci	{ .compatible = "toshiba,visconti-pcie" },
31862306a36Sopenharmony_ci	{},
31962306a36Sopenharmony_ci};
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_cistatic struct platform_driver visconti_pcie_driver = {
32262306a36Sopenharmony_ci	.probe = visconti_pcie_probe,
32362306a36Sopenharmony_ci	.driver = {
32462306a36Sopenharmony_ci		.name = "visconti-pcie",
32562306a36Sopenharmony_ci		.of_match_table = visconti_pcie_match,
32662306a36Sopenharmony_ci		.suppress_bind_attrs = true,
32762306a36Sopenharmony_ci	},
32862306a36Sopenharmony_ci};
32962306a36Sopenharmony_cibuiltin_platform_driver(visconti_pcie_driver);
330