aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2017-01-11 07:06:54 -0500
committerBjorn Helgaas <bhelgaas@google.com>2017-02-21 16:00:12 -0500
commitebe85a44aad47bb5f08c5cbd939eb5e40956c73b (patch)
tree493ceb728b091c60edadf8252b8d5b1d831b477f
parentab5fe4f4d31ee27df9b8d7720da710d955d55737 (diff)
PCI: dra7xx: Enable MSI and legacy interrupts simultaneously
pci-dra7xx driver had a bug in that if CONFIG_PCI_MSI config is enabled, it doesn't support legacy interrupt. Fix it here so that both MSI and legacy interrupts can be enabled simultaneously and the interrupt mechanism supported by the endpoint device will be used. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/dwc/pci-dra7xx.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index 587b18c38bcc..af330d723726 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -72,6 +72,7 @@ struct dra7xx_pcie {
72 int phy_count; /* DT phy-names count */ 72 int phy_count; /* DT phy-names count */
73 struct phy **phy; 73 struct phy **phy;
74 int link_gen; 74 int link_gen;
75 struct irq_domain *irq_domain;
75}; 76};
76 77
77#define to_dra7xx_pcie(x) container_of((x), struct dra7xx_pcie, pp) 78#define to_dra7xx_pcie(x) container_of((x), struct dra7xx_pcie, pp)
@@ -142,14 +143,8 @@ static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)
142 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN, INTERRUPTS); 143 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN, INTERRUPTS);
143 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, 144 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI,
144 ~LEG_EP_INTERRUPTS & ~MSI); 145 ~LEG_EP_INTERRUPTS & ~MSI);
145 146 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI,
146 if (IS_ENABLED(CONFIG_PCI_MSI)) 147 MSI | LEG_EP_INTERRUPTS);
147 dra7xx_pcie_writel(dra7xx,
148 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, MSI);
149 else
150 dra7xx_pcie_writel(dra7xx,
151 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI,
152 LEG_EP_INTERRUPTS);
153} 148}
154 149
155static void dra7xx_pcie_host_init(struct pcie_port *pp) 150static void dra7xx_pcie_host_init(struct pcie_port *pp)
@@ -164,8 +159,7 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
164 dw_pcie_setup_rc(pp); 159 dw_pcie_setup_rc(pp);
165 160
166 dra7xx_pcie_establish_link(dra7xx); 161 dra7xx_pcie_establish_link(dra7xx);
167 if (IS_ENABLED(CONFIG_PCI_MSI)) 162 dw_pcie_msi_init(pp);
168 dw_pcie_msi_init(pp);
169 dra7xx_pcie_enable_interrupts(dra7xx); 163 dra7xx_pcie_enable_interrupts(dra7xx);
170} 164}
171 165
@@ -190,6 +184,7 @@ static const struct irq_domain_ops intx_domain_ops = {
190static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) 184static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
191{ 185{
192 struct device *dev = pp->dev; 186 struct device *dev = pp->dev;
187 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
193 struct device_node *node = dev->of_node; 188 struct device_node *node = dev->of_node;
194 struct device_node *pcie_intc_node = of_get_next_child(node, NULL); 189 struct device_node *pcie_intc_node = of_get_next_child(node, NULL);
195 190
@@ -198,9 +193,9 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
198 return -ENODEV; 193 return -ENODEV;
199 } 194 }
200 195
201 pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, 196 dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, 4,
202 &intx_domain_ops, pp); 197 &intx_domain_ops, pp);
203 if (!pp->irq_domain) { 198 if (!dra7xx->irq_domain) {
204 dev_err(dev, "Failed to get a INTx IRQ domain\n"); 199 dev_err(dev, "Failed to get a INTx IRQ domain\n");
205 return -ENODEV; 200 return -ENODEV;
206 } 201 }
@@ -224,7 +219,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
224 case INTB: 219 case INTB:
225 case INTC: 220 case INTC:
226 case INTD: 221 case INTD:
227 generic_handle_irq(irq_find_mapping(pp->irq_domain, ffs(reg))); 222 generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
223 ffs(reg)));
228 break; 224 break;
229 } 225 }
230 226
@@ -310,11 +306,9 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
310 return ret; 306 return ret;
311 } 307 }
312 308
313 if (!IS_ENABLED(CONFIG_PCI_MSI)) { 309 ret = dra7xx_pcie_init_irq_domain(pp);
314 ret = dra7xx_pcie_init_irq_domain(pp); 310 if (ret < 0)
315 if (ret < 0) 311 return ret;
316 return ret;
317 }
318 312
319 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics"); 313 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics");
320 pp->dbi_base = devm_ioremap(dev, res->start, resource_size(res)); 314 pp->dbi_base = devm_ioremap(dev, res->start, resource_size(res));