PCI: dra7xx: Iterate over INTx status bits
[linux-2.6-block.git] / drivers / pci / dwc / pci-dra7xx.c
index e77a4ceed74c62392527eac2bec565f849a8ab20..8bf7c2714db6c6f79b056c10154faf0e93eb6ee6 100644 (file)
@@ -110,7 +110,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
        writel(value, pcie->base + offset);
 }
 
-static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
 {
        return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
 }
@@ -226,6 +226,7 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
 
 static const struct irq_domain_ops intx_domain_ops = {
        .map = dra7xx_pcie_intx_map,
+       .xlate = pci_irqd_intx_xlate,
 };
 
 static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
@@ -256,7 +257,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
        struct dra7xx_pcie *dra7xx = arg;
        struct dw_pcie *pci = dra7xx->pci;
        struct pcie_port *pp = &pci->pp;
-       u32 reg;
+       unsigned long reg;
+       u32 virq, bit;
 
        reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
 
@@ -268,8 +270,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
        case INTB:
        case INTC:
        case INTD:
-               generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
-                                                   ffs(reg)));
+               for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
+                       virq = irq_find_mapping(dra7xx->irq_domain, bit);
+                       if (virq)
+                               generic_handle_irq(virq);
+               }
                break;
        }
 
@@ -337,15 +342,6 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
-{
-       u32 reg;
-
-       reg = PCI_BASE_ADDRESS_0 + (4 * bar);
-       dw_pcie_writel_dbi2(pci, reg, 0x0);
-       dw_pcie_writel_dbi(pci, reg, 0x0);
-}
-
 static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -470,6 +466,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
        if (!pci->dbi_base)
                return -ENOMEM;
 
+       pp->ops = &dra7xx_pcie_host_ops;
+
        ret = dw_pcie_host_init(pp);
        if (ret) {
                dev_err(dev, "failed to initialize host\n");
@@ -599,7 +597,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
        void __iomem *base;
        struct resource *res;
        struct dw_pcie *pci;
-       struct pcie_port *pp;
        struct dra7xx_pcie *dra7xx;
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
@@ -627,9 +624,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
        pci->dev = dev;
        pci->ops = &dw_pcie_ops;
 
-       pp = &pci->pp;
-       pp->ops = &dra7xx_pcie_host_ops;
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(dev, "missing IRQ resource: %d\n", irq);
@@ -705,6 +699,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
 
        switch (mode) {
        case DW_PCIE_RC_TYPE:
+               if (!IS_ENABLED(CONFIG_PCI_DRA7XX_HOST)) {
+                       ret = -ENODEV;
+                       goto err_gpio;
+               }
+
                dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
                                   DEVICE_TYPE_RC);
                ret = dra7xx_add_pcie_port(dra7xx, pdev);
@@ -712,6 +711,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
                        goto err_gpio;
                break;
        case DW_PCIE_EP_TYPE:
+               if (!IS_ENABLED(CONFIG_PCI_DRA7XX_EP)) {
+                       ret = -ENODEV;
+                       goto err_gpio;
+               }
+
                dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
                                   DEVICE_TYPE_EP);
 
@@ -810,7 +814,7 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
 }
 #endif
 
-void dra7xx_pcie_shutdown(struct platform_device *pdev)
+static void dra7xx_pcie_shutdown(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);