f3c64524185c8666b38e55dfd1ababfaa9d51be2
[openwrt.git] / target / linux / ar71xx / files / arch / mips / ar71xx / pci.c
1 /*
2  *  Atheros AR71xx PCI setup code
3  *
4  *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6  *
7  *  Parts of this file are based on Atheros' 2.6.15 BSP
8  *
9  *  This program is free software; you can redistribute it and/or modify it
10  *  under the terms of the GNU General Public License version 2 as published
11  *  by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15
16 #include <asm/traps.h>
17
18 #include <asm/mach-ar71xx/ar71xx.h>
19 #include <asm/mach-ar71xx/pci.h>
20
21 unsigned ar71xx_pci_nr_irqs __initdata;
22 struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata;
23
24 int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev);
25
26 static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup)
27 {
28         int err = 0;
29
30         err = ar71xx_pci_be_handler(is_fixup);
31
32         return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
33 }
34
35 int pcibios_plat_dev_init(struct pci_dev *dev)
36 {
37         if (ar71xx_pci_plat_dev_init)
38                 return ar71xx_pci_plat_dev_init(dev);
39
40         return 0;
41 }
42
43 int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
44 {
45         int ret = 0;
46
47         switch (ar71xx_soc) {
48         case AR71XX_SOC_AR7130:
49         case AR71XX_SOC_AR7141:
50         case AR71XX_SOC_AR7161:
51                 ret = ar71xx_pcibios_map_irq(dev, slot, pin);
52                 break;
53
54         case AR71XX_SOC_AR7240:
55         case AR71XX_SOC_AR7241:
56         case AR71XX_SOC_AR7242:
57         case AR71XX_SOC_AR9342:
58         case AR71XX_SOC_AR9344:
59                 ret = ar724x_pcibios_map_irq(dev, slot, pin);
60                 break;
61
62         default:
63                 break;
64         }
65
66         return ret;
67 }
68
69 int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map)
70 {
71         u32 t;
72         int ret = 0;
73
74         switch (ar71xx_soc) {
75         case AR71XX_SOC_AR7130:
76         case AR71XX_SOC_AR7141:
77         case AR71XX_SOC_AR7161:
78                 board_be_handler = ar71xx_be_handler;
79                 ret = ar71xx_pcibios_init();
80                 break;
81
82         case AR71XX_SOC_AR7240:
83         case AR71XX_SOC_AR7241:
84         case AR71XX_SOC_AR7242:
85                 ret = ar724x_pcibios_init(AR71XX_CPU_IRQ_IP2);
86                 break;
87
88         case AR71XX_SOC_AR9342:
89         case AR71XX_SOC_AR9344:
90                 t = ar71xx_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
91                 if (t & AR934X_BOOTSTRAP_PCIE_RC) {
92                         ret = ar724x_pcibios_init(AR934X_IP2_IRQ_PCIE);
93                         break;
94                 }
95
96                 /* fall through */
97         default:
98                 return 0;
99         }
100
101         ar71xx_pci_nr_irqs = nr_irqs;
102         ar71xx_pci_irq_map = map;
103
104         return ret;
105 }