mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 07:50:04 +00:00
PCI updates for v4.4:
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) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWaE7hAAoJEFmIoMA60/r8ttwQAI7sv6+hLB+xSv8j43Xlh/wr M58VLpLHhsh0c5bhViIfTj3m56QPb1FqxzD1jD8NB29twPzf/j96UUUFHXZH5Amm kVdFVzslgpfBusGJeedL0Nei4R9TCVCaQv1BKODcLGGUZx1f29mlYLmgSVz7n3V0 oihjN4R352yjsH0goTHxsSHjnwR7mdzKmK6lWFAFgujQK3+eJ8WE+qniP0Rh5IWS voqQBE7N9vXzTqrBbEJYS1KZFUn7gBkkVPo1xFtniIHXZoT23in2Cg17eUQdMymN 6oXzzgiHkcJizuFhcxhtf7KitEbJk+6YWXxH03u5onDZQQNpJpcz17Us+vK3G4bb hdCMzOnZ2HAZgNP8W9yGdTB9Px9d6l1Kt3py3Nb9xJemMtl2IWVnxbRk/uu2ddF+ 83eX074U0lZqb8vAkR64EByKi8q+126BV5e+P7t3YgqJ1nA3luvk+bZsEiBFOePb hCNSSR2sP6mtYnVW0T3YPnZYJkrM3N28+JrZtP75szLjBNj3vmX2ani/dEJLAlkR UA6EoBiyJQvFyoZ2/pRb3dDYuNWoSP4yEAcZYwUFHmfs8AdF87Jl3BGH7HHW4C+8 sendp2WisODovdUa9/QKA0VX9VAStlzTIy5g+smMgZ340yp1Bl4HHxnZhN2kSR/P RZVNePtY/5DX60andYLb =3jiK -----END PGP SIGNATURE----- Merge tag 'pci-v4.4-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci 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
This commit is contained in:
commit
978d6a9041
@ -55,8 +55,10 @@
|
|||||||
#define TLP_CFG_DW2(bus, devfn, offset) \
|
#define TLP_CFG_DW2(bus, devfn, offset) \
|
||||||
(((bus) << 24) | ((devfn) << 16) | (offset))
|
(((bus) << 24) | ((devfn) << 16) | (offset))
|
||||||
#define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
|
#define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
|
||||||
|
#define TLP_COMP_STATUS(s) (((s) >> 12) & 7)
|
||||||
#define TLP_HDR_SIZE 3
|
#define TLP_HDR_SIZE 3
|
||||||
#define TLP_LOOP 500
|
#define TLP_LOOP 500
|
||||||
|
#define RP_DEVFN 0
|
||||||
|
|
||||||
#define INTX_NUM 4
|
#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)
|
static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
|
||||||
{
|
{
|
||||||
u8 loop;
|
int i;
|
||||||
bool sop = 0;
|
bool sop = 0;
|
||||||
u32 ctrl;
|
u32 ctrl;
|
||||||
u32 reg0, reg1;
|
u32 reg0, reg1;
|
||||||
|
u32 comp_status = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Minimum 2 loops to read TLP headers and 1 loop to read data
|
* Minimum 2 loops to read TLP headers and 1 loop to read data
|
||||||
* payload.
|
* payload.
|
||||||
*/
|
*/
|
||||||
for (loop = 0; loop < TLP_LOOP; loop++) {
|
for (i = 0; i < TLP_LOOP; i++) {
|
||||||
ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
|
ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
|
||||||
if ((ctrl & RP_RXCPL_SOP) || (ctrl & RP_RXCPL_EOP) || sop) {
|
if ((ctrl & RP_RXCPL_SOP) || (ctrl & RP_RXCPL_EOP) || sop) {
|
||||||
reg0 = cra_readl(pcie, RP_RXCPL_REG0);
|
reg0 = cra_readl(pcie, RP_RXCPL_REG0);
|
||||||
reg1 = cra_readl(pcie, RP_RXCPL_REG1);
|
reg1 = cra_readl(pcie, RP_RXCPL_REG1);
|
||||||
|
|
||||||
if (ctrl & RP_RXCPL_SOP)
|
if (ctrl & RP_RXCPL_SOP) {
|
||||||
sop = true;
|
sop = true;
|
||||||
|
comp_status = TLP_COMP_STATUS(reg1);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctrl & RP_RXCPL_EOP) {
|
if (ctrl & RP_RXCPL_EOP) {
|
||||||
|
if (comp_status)
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
*value = reg0;
|
*value = reg0;
|
||||||
|
|
||||||
return PCIBIOS_SUCCESSFUL;
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
udelay(5);
|
udelay(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOENT;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers,
|
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
|
else
|
||||||
headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
|
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);
|
TLP_READ_TAG, byte_en);
|
||||||
headers[2] = TLP_CFG_DW2(bus, devfn, where);
|
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
|
else
|
||||||
headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
|
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);
|
TLP_WRITE_TAG, byte_en);
|
||||||
headers[2] = TLP_CFG_DW2(bus, devfn, where);
|
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;
|
struct device_node *node = dev->of_node;
|
||||||
|
|
||||||
/* Setup INTx */
|
/* 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);
|
&intx_domain_ops, pcie);
|
||||||
if (!pcie->irq_domain) {
|
if (!pcie->irq_domain) {
|
||||||
dev_err(dev, "Failed to get a INTx IRQ domain\n");
|
dev_err(dev, "Failed to get a INTx IRQ domain\n");
|
||||||
|
@ -54,7 +54,7 @@ static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
|||||||
struct irq_domain *domain;
|
struct irq_domain *domain;
|
||||||
|
|
||||||
domain = pci_msi_get_domain(dev);
|
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 pci_msi_domain_alloc_irqs(domain, dev, nvec, type);
|
||||||
|
|
||||||
return arch_setup_msi_irqs(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;
|
struct irq_domain *domain;
|
||||||
|
|
||||||
domain = pci_msi_get_domain(dev);
|
domain = pci_msi_get_domain(dev);
|
||||||
if (domain)
|
if (domain && irq_domain_is_hierarchy(domain))
|
||||||
pci_msi_domain_free_irqs(domain, dev);
|
pci_msi_domain_free_irqs(domain, dev);
|
||||||
else
|
else
|
||||||
arch_teardown_msi_irqs(dev);
|
arch_teardown_msi_irqs(dev);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user