aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci/pci-ar724x.c
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2013-02-03 05:00:16 -0500
committerJohn Crispin <blogic@openwrt.org>2013-02-16 19:25:39 -0500
commit8b66d461187ff61c5755001af7296e6edde48423 (patch)
treeee07c7274d2c31e083418ac9e9f497ae97f73664 /arch/mips/pci/pci-ar724x.c
parent34b134aebda89888b6985b7a3139e9cbdf209236 (diff)
MIPS: pci-ar724x: use per-controller IRQ base
Change to the code to use per-controller IRQ base. This is needed for multiple PCI controller support. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/4915/ Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/pci/pci-ar724x.c')
-rw-r--r--arch/mips/pci/pci-ar724x.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
index d0d707de6c6c..0440d8800f8a 100644
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -34,6 +34,7 @@ struct ar724x_pci_controller {
34 void __iomem *ctrl_base; 34 void __iomem *ctrl_base;
35 35
36 int irq; 36 int irq;
37 int irq_base;
37 38
38 bool link_up; 39 bool link_up;
39 bool bar0_is_cached; 40 bool bar0_is_cached;
@@ -205,7 +206,7 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
205 __raw_readl(base + AR724X_PCI_REG_INT_MASK); 206 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
206 207
207 if (pending & AR724X_PCI_INT_DEV0) 208 if (pending & AR724X_PCI_INT_DEV0)
208 generic_handle_irq(ATH79_PCI_IRQ(0)); 209 generic_handle_irq(apc->irq_base + 0);
209 210
210 else 211 else
211 spurious_interrupt(); 212 spurious_interrupt();
@@ -215,13 +216,15 @@ static void ar724x_pci_irq_unmask(struct irq_data *d)
215{ 216{
216 struct ar724x_pci_controller *apc; 217 struct ar724x_pci_controller *apc;
217 void __iomem *base; 218 void __iomem *base;
219 int offset;
218 u32 t; 220 u32 t;
219 221
220 apc = irq_data_get_irq_chip_data(d); 222 apc = irq_data_get_irq_chip_data(d);
221 base = apc->ctrl_base; 223 base = apc->ctrl_base;
224 offset = apc->irq_base - d->irq;
222 225
223 switch (d->irq) { 226 switch (offset) {
224 case ATH79_PCI_IRQ(0): 227 case 0:
225 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); 228 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
226 __raw_writel(t | AR724X_PCI_INT_DEV0, 229 __raw_writel(t | AR724X_PCI_INT_DEV0,
227 base + AR724X_PCI_REG_INT_MASK); 230 base + AR724X_PCI_REG_INT_MASK);
@@ -234,13 +237,15 @@ static void ar724x_pci_irq_mask(struct irq_data *d)
234{ 237{
235 struct ar724x_pci_controller *apc; 238 struct ar724x_pci_controller *apc;
236 void __iomem *base; 239 void __iomem *base;
240 int offset;
237 u32 t; 241 u32 t;
238 242
239 apc = irq_data_get_irq_chip_data(d); 243 apc = irq_data_get_irq_chip_data(d);
240 base = apc->ctrl_base; 244 base = apc->ctrl_base;
245 offset = apc->irq_base - d->irq;
241 246
242 switch (d->irq) { 247 switch (offset) {
243 case ATH79_PCI_IRQ(0): 248 case 0:
244 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); 249 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
245 __raw_writel(t & ~AR724X_PCI_INT_DEV0, 250 __raw_writel(t & ~AR724X_PCI_INT_DEV0,
246 base + AR724X_PCI_REG_INT_MASK); 251 base + AR724X_PCI_REG_INT_MASK);
@@ -264,7 +269,8 @@ static struct irq_chip ar724x_pci_irq_chip = {
264 .irq_mask_ack = ar724x_pci_irq_mask, 269 .irq_mask_ack = ar724x_pci_irq_mask,
265}; 270};
266 271
267static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc) 272static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
273 int id)
268{ 274{
269 void __iomem *base; 275 void __iomem *base;
270 int i; 276 int i;
@@ -274,10 +280,10 @@ static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc)
274 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); 280 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
275 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); 281 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
276 282
277 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); 283 apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
278 284
279 for (i = ATH79_PCI_IRQ_BASE; 285 for (i = apc->irq_base;
280 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) { 286 i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
281 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, 287 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
282 handle_level_irq); 288 handle_level_irq);
283 irq_set_chip_data(i, apc); 289 irq_set_chip_data(i, apc);
@@ -291,6 +297,11 @@ static int ar724x_pci_probe(struct platform_device *pdev)
291{ 297{
292 struct ar724x_pci_controller *apc; 298 struct ar724x_pci_controller *apc;
293 struct resource *res; 299 struct resource *res;
300 int id;
301
302 id = pdev->id;
303 if (id == -1)
304 id = 0;
294 305
295 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller), 306 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
296 GFP_KERNEL); 307 GFP_KERNEL);
@@ -347,7 +358,7 @@ static int ar724x_pci_probe(struct platform_device *pdev)
347 if (!apc->link_up) 358 if (!apc->link_up)
348 dev_warn(&pdev->dev, "PCIe link is down\n"); 359 dev_warn(&pdev->dev, "PCIe link is down\n");
349 360
350 ar724x_pci_irq_init(apc); 361 ar724x_pci_irq_init(apc, id);
351 362
352 register_pci_controller(&apc->pci_controller); 363 register_pci_controller(&apc->pci_controller);
353 364