Commit 51bc2b7f authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/msi'

- Convert tegra to MSI domains (Marc Zyngier)

- Use rcar controller address as MSI doorbell instead of allocating a page
  (Marc Zyngier)

- Convert rcar to MSI domains (Marc Zyngier)

- Use xilinx port structure as MSI doorbell instead of allocating a page
  (Marc Zyngier)

- Convert xilinx to MSI domains (Marc Zyngier)

- Remove unused Hyper-V msi_controller structure (Marc Zyngier)

- Remove unused PCI core msi_controller support (Marc Zyngier)

- Remove struct msi_controller (Marc Zyngier)

- Remove unused default_teardown_msi_irqs() (Marc Zyngier)

- Let host bridges declare their reliance on MSI domains (Marc Zyngier)

- Make pci_host_common_probe() declare its reliance on MSI domains (Marc
  Zyngier)

- Advertise mediatek lack of built-in MSI handling (Thomas Gleixner)

- Document ways of ending up with NO_MSI (Marc Zyngier)

- Refactor HT advertising of NO_MSI flag (Marc Zyngier)

* remotes/lorenzo/pci/msi:
  PCI: Refactor HT advertising of NO_MSI flag
  PCI/MSI: Document the various ways of ending up with NO_MSI
  PCI: mediatek: Advertise lack of built-in MSI handling
  PCI/MSI: Make pci_host_common_probe() declare its reliance on MSI domains
  PCI/MSI: Let PCI host bridges declare their reliance on MSI domains
  PCI/MSI: Kill default_teardown_msi_irqs()
  PCI/MSI: Kill msi_controller structure
  PCI/MSI: Drop use of msi_controller from core code
  PCI: hv: Drop msi_controller structure
  PCI: xilinx: Convert to MSI domains
  PCI: xilinx: Don't allocate extra memory for the MSI capture address
  PCI: rcar: Convert to MSI domains
  PCI: rcar: Don't allocate extra memory for the MSI capture address
  PCI: tegra: Convert to MSI domains
parents 4772ade2 557853f4
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ config PCI_TEGRA
	bool "NVIDIA Tegra PCIe controller"
	depends on ARCH_TEGRA || COMPILE_TEST
	depends on PCI_MSI_IRQ_DOMAIN
	select PCI_MSI_ARCH_FALLBACKS
	help
	  Say Y here if you want support for the PCIe host controller found
	  on NVIDIA Tegra SoCs.
@@ -59,7 +58,6 @@ config PCIE_RCAR_HOST
	bool "Renesas R-Car PCIe host controller"
	depends on ARCH_RENESAS || COMPILE_TEST
	depends on PCI_MSI_IRQ_DOMAIN
	select PCI_MSI_ARCH_FALLBACKS
	help
	  Say Y here if you want PCIe controller support on R-Car SoCs in host
	  mode.
@@ -88,7 +86,7 @@ config PCI_HOST_GENERIC
config PCIE_XILINX
	bool "Xilinx AXI PCIe host bridge support"
	depends on OF || COMPILE_TEST
	select PCI_MSI_ARCH_FALLBACKS
	depends on PCI_MSI_IRQ_DOMAIN
	help
	  Say 'Y' here if you want kernel to support the Xilinx AXI PCIe
	  Host Bridge driver.
+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ int pci_host_common_probe(struct platform_device *pdev)

	bridge->sysdata = cfg;
	bridge->ops = (struct pci_ops *)&ops->pci_ops;
	bridge->msi_domain = true;

	return pci_host_probe(bridge);
}
+0 −4
Original line number Diff line number Diff line
@@ -473,7 +473,6 @@ struct hv_pcibus_device {
	struct list_head dr_list;

	struct msi_domain_info msi_info;
	struct msi_controller msi_chip;
	struct irq_domain *irq_domain;

	spinlock_t retarget_msi_interrupt_lock;
@@ -1866,9 +1865,6 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)
	if (!hbus->pci_bus)
		return -ENODEV;

	hbus->pci_bus->msi = &hbus->msi_chip;
	hbus->pci_bus->msi->dev = &hbus->hdev->device;

	pci_lock_rescan_remove();
	pci_scan_child_bus(hbus->pci_bus);
	hv_pci_assign_numa_node(hbus);
+191 −158
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -78,23 +79,8 @@
#define AFI_MSI_FPCI_BAR_ST	0x64
#define AFI_MSI_AXI_BAR_ST	0x68

#define AFI_MSI_VEC0		0x6c
#define AFI_MSI_VEC1		0x70
#define AFI_MSI_VEC2		0x74
#define AFI_MSI_VEC3		0x78
#define AFI_MSI_VEC4		0x7c
#define AFI_MSI_VEC5		0x80
#define AFI_MSI_VEC6		0x84
#define AFI_MSI_VEC7		0x88

#define AFI_MSI_EN_VEC0		0x8c
#define AFI_MSI_EN_VEC1		0x90
#define AFI_MSI_EN_VEC2		0x94
#define AFI_MSI_EN_VEC3		0x98
#define AFI_MSI_EN_VEC4		0x9c
#define AFI_MSI_EN_VEC5		0xa0
#define AFI_MSI_EN_VEC6		0xa4
#define AFI_MSI_EN_VEC7		0xa8
#define AFI_MSI_VEC(x)		(0x6c + ((x) * 4))
#define AFI_MSI_EN_VEC(x)	(0x8c + ((x) * 4))

#define AFI_CONFIGURATION		0xac
#define  AFI_CONFIGURATION_EN_FPCI		(1 << 0)
@@ -280,10 +266,10 @@
#define LINK_RETRAIN_TIMEOUT 100000 /* in usec */

struct tegra_msi {
	struct msi_controller chip;
	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
	struct irq_domain *domain;
	struct mutex lock;
	struct mutex map_lock;
	spinlock_t mask_lock;
	void *virt;
	dma_addr_t phys;
	int irq;
@@ -333,11 +319,6 @@ struct tegra_pcie_soc {
	} ectl;
};

static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
{
	return container_of(chip, struct tegra_msi, chip);
}

struct tegra_pcie {
	struct device *dev;

@@ -372,6 +353,11 @@ struct tegra_pcie {
	struct dentry *debugfs;
};

static inline struct tegra_pcie *msi_to_pcie(struct tegra_msi *msi)
{
	return container_of(msi, struct tegra_pcie, msi);
}

struct tegra_pcie_port {
	struct tegra_pcie *pcie;
	struct device_node *np;
@@ -1432,7 +1418,6 @@ static void tegra_pcie_phys_put(struct tegra_pcie *pcie)
	}
}


static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
{
	struct device *dev = pcie->dev;
@@ -1509,6 +1494,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
phys_put:
	if (soc->program_uphy)
		tegra_pcie_phys_put(pcie);

	return err;
}

@@ -1551,161 +1537,227 @@ static void tegra_pcie_pme_turnoff(struct tegra_pcie_port *port)
	afi_writel(pcie, val, AFI_PCIE_PME);
}

static int tegra_msi_alloc(struct tegra_msi *chip)
static void tegra_pcie_msi_irq(struct irq_desc *desc)
{
	int msi;

	mutex_lock(&chip->lock);

	msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR);
	if (msi < INT_PCI_MSI_NR)
		set_bit(msi, chip->used);
	else
		msi = -ENOSPC;

	mutex_unlock(&chip->lock);

	return msi;
}

static void tegra_msi_free(struct tegra_msi *chip, unsigned long irq)
{
	struct device *dev = chip->chip.dev;

	mutex_lock(&chip->lock);

	if (!test_bit(irq, chip->used))
		dev_err(dev, "trying to free unused MSI#%lu\n", irq);
	else
		clear_bit(irq, chip->used);

	mutex_unlock(&chip->lock);
}

static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
{
	struct tegra_pcie *pcie = data;
	struct device *dev = pcie->dev;
	struct tegra_pcie *pcie = irq_desc_get_handler_data(desc);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct tegra_msi *msi = &pcie->msi;
	unsigned int i, processed = 0;
	struct device *dev = pcie->dev;
	unsigned int i;

	chained_irq_enter(chip, desc);

	for (i = 0; i < 8; i++) {
		unsigned long reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
		unsigned long reg = afi_readl(pcie, AFI_MSI_VEC(i));

		while (reg) {
			unsigned int offset = find_first_bit(&reg, 32);
			unsigned int index = i * 32 + offset;
			unsigned int irq;

			/* clear the interrupt */
			afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);

			irq = irq_find_mapping(msi->domain, index);
			irq = irq_find_mapping(msi->domain->parent, index);
			if (irq) {
				if (test_bit(index, msi->used))
				generic_handle_irq(irq);
				else
					dev_info(dev, "unhandled MSI\n");
			} else {
				/*
				 * that's weird who triggered this?
				 * just clear it
				 */
				dev_info(dev, "unexpected MSI\n");
				afi_writel(pcie, BIT(index % 32), AFI_MSI_VEC(index));
			}

			/* see if there's any more pending in this vector */
			reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
			reg = afi_readl(pcie, AFI_MSI_VEC(i));
		}
	}

			processed++;
	chained_irq_exit(chip, desc);
}

static void tegra_msi_top_irq_ack(struct irq_data *d)
{
	irq_chip_ack_parent(d);
}

	return processed > 0 ? IRQ_HANDLED : IRQ_NONE;
static void tegra_msi_top_irq_mask(struct irq_data *d)
{
	pci_msi_mask_irq(d);
	irq_chip_mask_parent(d);
}

static int tegra_msi_setup_irq(struct msi_controller *chip,
			       struct pci_dev *pdev, struct msi_desc *desc)
static void tegra_msi_top_irq_unmask(struct irq_data *d)
{
	struct tegra_msi *msi = to_tegra_msi(chip);
	struct msi_msg msg;
	unsigned int irq;
	int hwirq;
	pci_msi_unmask_irq(d);
	irq_chip_unmask_parent(d);
}

	hwirq = tegra_msi_alloc(msi);
	if (hwirq < 0)
		return hwirq;
static struct irq_chip tegra_msi_top_chip = {
	.name		= "Tegra PCIe MSI",
	.irq_ack	= tegra_msi_top_irq_ack,
	.irq_mask	= tegra_msi_top_irq_mask,
	.irq_unmask	= tegra_msi_top_irq_unmask,
};

	irq = irq_create_mapping(msi->domain, hwirq);
	if (!irq) {
		tegra_msi_free(msi, hwirq);
		return -EINVAL;
static void tegra_msi_irq_ack(struct irq_data *d)
{
	struct tegra_msi *msi = irq_data_get_irq_chip_data(d);
	struct tegra_pcie *pcie = msi_to_pcie(msi);
	unsigned int index = d->hwirq / 32;

	/* clear the interrupt */
	afi_writel(pcie, BIT(d->hwirq % 32), AFI_MSI_VEC(index));
}

	irq_set_msi_desc(irq, desc);
static void tegra_msi_irq_mask(struct irq_data *d)
{
	struct tegra_msi *msi = irq_data_get_irq_chip_data(d);
	struct tegra_pcie *pcie = msi_to_pcie(msi);
	unsigned int index = d->hwirq / 32;
	unsigned long flags;
	u32 value;

	msg.address_lo = lower_32_bits(msi->phys);
	msg.address_hi = upper_32_bits(msi->phys);
	msg.data = hwirq;
	spin_lock_irqsave(&msi->mask_lock, flags);
	value = afi_readl(pcie, AFI_MSI_EN_VEC(index));
	value &= ~BIT(d->hwirq % 32);
	afi_writel(pcie, value, AFI_MSI_EN_VEC(index));
	spin_unlock_irqrestore(&msi->mask_lock, flags);
}

	pci_write_msi_msg(irq, &msg);
static void tegra_msi_irq_unmask(struct irq_data *d)
{
	struct tegra_msi *msi = irq_data_get_irq_chip_data(d);
	struct tegra_pcie *pcie = msi_to_pcie(msi);
	unsigned int index = d->hwirq / 32;
	unsigned long flags;
	u32 value;

	return 0;
	spin_lock_irqsave(&msi->mask_lock, flags);
	value = afi_readl(pcie, AFI_MSI_EN_VEC(index));
	value |= BIT(d->hwirq % 32);
	afi_writel(pcie, value, AFI_MSI_EN_VEC(index));
	spin_unlock_irqrestore(&msi->mask_lock, flags);
}

static void tegra_msi_teardown_irq(struct msi_controller *chip,
				   unsigned int irq)
static int tegra_msi_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
{
	struct tegra_msi *msi = to_tegra_msi(chip);
	struct irq_data *d = irq_get_irq_data(irq);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	return -EINVAL;
}

	irq_dispose_mapping(irq);
	tegra_msi_free(msi, hwirq);
static void tegra_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
{
	struct tegra_msi *msi = irq_data_get_irq_chip_data(data);

	msg->address_lo = lower_32_bits(msi->phys);
	msg->address_hi = upper_32_bits(msi->phys);
	msg->data = data->hwirq;
}

static struct irq_chip tegra_msi_irq_chip = {
	.name = "Tegra PCIe MSI",
	.irq_enable = pci_msi_unmask_irq,
	.irq_disable = pci_msi_mask_irq,
	.irq_mask = pci_msi_mask_irq,
	.irq_unmask = pci_msi_unmask_irq,
static struct irq_chip tegra_msi_bottom_chip = {
	.name			= "Tegra MSI",
	.irq_ack		= tegra_msi_irq_ack,
	.irq_mask		= tegra_msi_irq_mask,
	.irq_unmask		= tegra_msi_irq_unmask,
	.irq_set_affinity 	= tegra_msi_set_affinity,
	.irq_compose_msi_msg	= tegra_compose_msi_msg,
};

static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,
			 irq_hw_number_t hwirq)
static int tegra_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
				  unsigned int nr_irqs, void *args)
{
	irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);
	irq_set_chip_data(irq, domain->host_data);
	struct tegra_msi *msi = domain->host_data;
	unsigned int i;
	int hwirq;

	mutex_lock(&msi->map_lock);

	hwirq = bitmap_find_free_region(msi->used, INT_PCI_MSI_NR, order_base_2(nr_irqs));

	mutex_unlock(&msi->map_lock);

	if (hwirq < 0)
		return -ENOSPC;

	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_info(domain, virq + i, hwirq + i,
				    &tegra_msi_bottom_chip, domain->host_data,
				    handle_edge_irq, NULL, NULL);

	tegra_cpuidle_pcie_irqs_in_use();

	return 0;
}

static const struct irq_domain_ops msi_domain_ops = {
	.map = tegra_msi_map,
static void tegra_msi_domain_free(struct irq_domain *domain, unsigned int virq,
				  unsigned int nr_irqs)
{
	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
	struct tegra_msi *msi = domain->host_data;

	mutex_lock(&msi->map_lock);

	bitmap_release_region(msi->used, d->hwirq, order_base_2(nr_irqs));

	mutex_unlock(&msi->map_lock);
}

static const struct irq_domain_ops tegra_msi_domain_ops = {
	.alloc = tegra_msi_domain_alloc,
	.free = tegra_msi_domain_free,
};

static struct msi_domain_info tegra_msi_info = {
	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
		   MSI_FLAG_PCI_MSIX),
	.chip	= &tegra_msi_top_chip,
};

static int tegra_allocate_domains(struct tegra_msi *msi)
{
	struct tegra_pcie *pcie = msi_to_pcie(msi);
	struct fwnode_handle *fwnode = dev_fwnode(pcie->dev);
	struct irq_domain *parent;

	parent = irq_domain_create_linear(fwnode, INT_PCI_MSI_NR,
					  &tegra_msi_domain_ops, msi);
	if (!parent) {
		dev_err(pcie->dev, "failed to create IRQ domain\n");
		return -ENOMEM;
	}
	irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);

	msi->domain = pci_msi_create_irq_domain(fwnode, &tegra_msi_info, parent);
	if (!msi->domain) {
		dev_err(pcie->dev, "failed to create MSI domain\n");
		irq_domain_remove(parent);
		return -ENOMEM;
	}

	return 0;
}

static void tegra_free_domains(struct tegra_msi *msi)
{
	struct irq_domain *parent = msi->domain->parent;

	irq_domain_remove(msi->domain);
	irq_domain_remove(parent);
}

static int tegra_pcie_msi_setup(struct tegra_pcie *pcie)
{
	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
	struct platform_device *pdev = to_platform_device(pcie->dev);
	struct tegra_msi *msi = &pcie->msi;
	struct device *dev = pcie->dev;
	int err;

	mutex_init(&msi->lock);

	msi->chip.dev = dev;
	msi->chip.setup_irq = tegra_msi_setup_irq;
	msi->chip.teardown_irq = tegra_msi_teardown_irq;
	mutex_init(&msi->map_lock);
	spin_lock_init(&msi->mask_lock);

	msi->domain = irq_domain_add_linear(dev->of_node, INT_PCI_MSI_NR,
					    &msi_domain_ops, &msi->chip);
	if (!msi->domain) {
		dev_err(dev, "failed to create IRQ domain\n");
		return -ENOMEM;
	if (IS_ENABLED(CONFIG_PCI_MSI)) {
		err = tegra_allocate_domains(msi);
		if (err)
			return err;
	}

	err = platform_get_irq_byname(pdev, "msi");
@@ -1714,12 +1766,7 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie)

	msi->irq = err;

	err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
			  tegra_msi_irq_chip.name, pcie);
	if (err < 0) {
		dev_err(dev, "failed to request IRQ: %d\n", err);
		goto free_irq_domain;
	}
	irq_set_chained_handler_and_data(msi->irq, tegra_pcie_msi_irq, pcie);

	/* Though the PCIe controller can address >32-bit address space, to
	 * facilitate endpoints that support only 32-bit MSI target address,
@@ -1740,14 +1787,14 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie)
		goto free_irq;
	}

	host->msi = &msi->chip;

	return 0;

free_irq:
	free_irq(msi->irq, pcie);
	irq_set_chained_handler_and_data(msi->irq, NULL, NULL);
free_irq_domain:
	irq_domain_remove(msi->domain);
	if (IS_ENABLED(CONFIG_PCI_MSI))
		tegra_free_domains(msi);

	return err;
}

@@ -1755,22 +1802,18 @@ static void tegra_pcie_enable_msi(struct tegra_pcie *pcie)
{
	const struct tegra_pcie_soc *soc = pcie->soc;
	struct tegra_msi *msi = &pcie->msi;
	u32 reg;
	u32 reg, msi_state[INT_PCI_MSI_NR / 32];
	int i;

	afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST);
	afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST);
	/* this register is in 4K increments */
	afi_writel(pcie, 1, AFI_MSI_BAR_SZ);

	/* enable all MSI vectors */
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC0);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC1);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC2);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC3);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC4);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC5);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC6);
	afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC7);
	/* Restore the MSI allocation state */
	bitmap_to_arr32(msi_state, msi->used, INT_PCI_MSI_NR);
	for (i = 0; i < ARRAY_SIZE(msi_state); i++)
		afi_writel(pcie, msi_state[i], AFI_MSI_EN_VEC(i));

	/* and unmask the MSI interrupt */
	reg = afi_readl(pcie, AFI_INTR_MASK);
@@ -1786,16 +1829,16 @@ static void tegra_pcie_msi_teardown(struct tegra_pcie *pcie)
	dma_free_attrs(pcie->dev, PAGE_SIZE, msi->virt, msi->phys,
		       DMA_ATTR_NO_KERNEL_MAPPING);

	if (msi->irq > 0)
		free_irq(msi->irq, pcie);

	for (i = 0; i < INT_PCI_MSI_NR; i++) {
		irq = irq_find_mapping(msi->domain, i);
		if (irq > 0)
			irq_dispose_mapping(irq);
			irq_domain_free_irqs(irq, 1);
	}

	irq_domain_remove(msi->domain);
	irq_set_chained_handler_and_data(msi->irq, NULL, NULL);

	if (IS_ENABLED(CONFIG_PCI_MSI))
		tegra_free_domains(msi);
}

static int tegra_pcie_disable_msi(struct tegra_pcie *pcie)
@@ -1807,16 +1850,6 @@ static int tegra_pcie_disable_msi(struct tegra_pcie *pcie)
	value &= ~AFI_INTR_MASK_MSI_MASK;
	afi_writel(pcie, value, AFI_INTR_MASK);

	/* disable all MSI vectors */
	afi_writel(pcie, 0, AFI_MSI_EN_VEC0);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC1);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC2);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC3);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC4);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC5);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC6);
	afi_writel(pcie, 0, AFI_MSI_EN_VEC7);

	return 0;
}

+4 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ struct mtk_pcie_port;
 * struct mtk_pcie_soc - differentiate between host generations
 * @need_fix_class_id: whether this host's class ID needed to be fixed or not
 * @need_fix_device_id: whether this host's device ID needed to be fixed or not
 * @no_msi: Bridge has no MSI support, and relies on an external block
 * @device_id: device ID which this host need to be fixed
 * @ops: pointer to configuration access functions
 * @startup: pointer to controller setting functions
@@ -151,6 +152,7 @@ struct mtk_pcie_port;
struct mtk_pcie_soc {
	bool need_fix_class_id;
	bool need_fix_device_id;
	bool no_msi;
	unsigned int device_id;
	struct pci_ops *ops;
	int (*startup)(struct mtk_pcie_port *port);
@@ -1087,6 +1089,7 @@ static int mtk_pcie_probe(struct platform_device *pdev)

	host->ops = pcie->soc->ops;
	host->sysdata = pcie;
	host->msi_domain = pcie->soc->no_msi;

	err = pci_host_probe(host);
	if (err)
@@ -1176,6 +1179,7 @@ static const struct dev_pm_ops mtk_pcie_pm_ops = {
};

static const struct mtk_pcie_soc mtk_pcie_soc_v1 = {
	.no_msi = true,
	.ops = &mtk_pcie_ops,
	.startup = mtk_pcie_startup_port,
};
Loading