Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 978d6a90 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull PCI fixes from Bjorn Helgaas:
 "These are more fixes I'd like to have in v4.4.  Several for the Altera
  driver added for v4.4, and one for an MSI domain problem that affects
  several arm64 platforms:

  MSI:
   - Only use the generic MSI layer when domain is hierarchical (Marc
     Zyngier)

  Altera host bridge driver:
   - Fix loop in tlp_read_packet() (Dan Carpenter)
   - Fix Requester ID for config accesses (Ley Foon Tan)
   - Check TLP completion status (Ley Foon Tan)
   - Fix error when INTx is 4 (Ley Foon Tan)"

* tag 'pci-v4.4-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  PCI: altera: Fix error when INTx is 4
  PCI: altera: Check TLP completion status
  PCI: altera: Fix Requester ID for config accesses
  PCI: altera: Fix loop in tlp_read_packet()
  PCI/MSI: Only use the generic MSI layer when domain is hierarchical
parents aa536855 99496bd2
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -55,8 +55,10 @@
#define TLP_CFG_DW2(bus, devfn, offset)	\
				(((bus) << 24) | ((devfn) << 16) | (offset))
#define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))
#define TLP_COMP_STATUS(s)		(((s) >> 12) & 7)
#define TLP_HDR_SIZE			3
#define TLP_LOOP			500
#define RP_DEVFN			0

#define INTX_NUM			4

@@ -166,34 +168,41 @@ static bool altera_pcie_valid_config(struct altera_pcie *pcie,

static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
{
	u8 loop;
	int i;
	bool sop = 0;
	u32 ctrl;
	u32 reg0, reg1;
	u32 comp_status = 1;

	/*
	 * Minimum 2 loops to read TLP headers and 1 loop to read data
	 * payload.
	 */
	for (loop = 0; loop < TLP_LOOP; loop++) {
	for (i = 0; i < TLP_LOOP; i++) {
		ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
		if ((ctrl & RP_RXCPL_SOP) || (ctrl & RP_RXCPL_EOP) || sop) {
			reg0 = cra_readl(pcie, RP_RXCPL_REG0);
			reg1 = cra_readl(pcie, RP_RXCPL_REG1);

			if (ctrl & RP_RXCPL_SOP)
			if (ctrl & RP_RXCPL_SOP) {
				sop = true;
				comp_status = TLP_COMP_STATUS(reg1);
			}

			if (ctrl & RP_RXCPL_EOP) {
				if (comp_status)
					return PCIBIOS_DEVICE_NOT_FOUND;

				if (value)
					*value = reg0;

				return PCIBIOS_SUCCESSFUL;
			}
		}
		udelay(5);
	}

	return -ENOENT;
	return PCIBIOS_DEVICE_NOT_FOUND;
}

static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers,
@@ -233,7 +242,7 @@ static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
	else
		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);

	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN),
					TLP_READ_TAG, byte_en);
	headers[2] = TLP_CFG_DW2(bus, devfn, where);

@@ -253,7 +262,7 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
	else
		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);

	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN),
					TLP_WRITE_TAG, byte_en);
	headers[2] = TLP_CFG_DW2(bus, devfn, where);

@@ -458,7 +467,7 @@ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
	struct device_node *node = dev->of_node;

	/* Setup INTx */
	pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
	pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM + 1,
					&intx_domain_ops, pcie);
	if (!pcie->irq_domain) {
		dev_err(dev, "Failed to get a INTx IRQ domain\n");
+2 −2
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
	struct irq_domain *domain;

	domain = pci_msi_get_domain(dev);
	if (domain)
	if (domain && irq_domain_is_hierarchy(domain))
		return pci_msi_domain_alloc_irqs(domain, dev, nvec, type);

	return arch_setup_msi_irqs(dev, nvec, type);
@@ -65,7 +65,7 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
	struct irq_domain *domain;

	domain = pci_msi_get_domain(dev);
	if (domain)
	if (domain && irq_domain_is_hierarchy(domain))
		pci_msi_domain_free_irqs(domain, dev);
	else
		arch_teardown_msi_irqs(dev);