diff options
author | Jon Loeliger <jdl@freescale.com> | 2006-08-18 15:30:35 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-08-23 01:51:18 -0400 |
commit | 343832734fac000d2d276ccc41955daded1265f5 (patch) | |
tree | 7450a712261fe7ffc02d92cb5fca2adec1ac43de /arch/powerpc/platforms/86xx | |
parent | 2654d6385f6cad00cfb8f5087aeb10d0ed781e74 (diff) |
[POWERPC] Rewrite the PPC 86xx IRQ handling to use Flat Device Tree
IRQ setup now comes from the Flat Device Tree and use the new generic
IRQ code. Fixed the fsl_soc.c IRQ OF interrupt node parsing.
Removed some unused MPC86xx macro definition.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
(cherry picked from 919fede6edab94cccb3ca8c1c0b32fa62c9369a5 commit)
Diffstat (limited to 'arch/powerpc/platforms/86xx')
-rw-r--r-- | arch/powerpc/platforms/86xx/mpc8641_hpcn.h | 32 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 324 |
2 files changed, 176 insertions, 180 deletions
diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 5d2bcf78cef7..41e554c4af94 100644 --- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h | |||
@@ -16,38 +16,6 @@ | |||
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | 18 | ||
19 | /* PCI interrupt controller */ | ||
20 | #define PIRQA 3 | ||
21 | #define PIRQB 4 | ||
22 | #define PIRQC 5 | ||
23 | #define PIRQD 6 | ||
24 | #define PIRQ7 7 | ||
25 | #define PIRQE 9 | ||
26 | #define PIRQF 10 | ||
27 | #define PIRQG 11 | ||
28 | #define PIRQH 12 | ||
29 | |||
30 | /* PCI-Express memory map */ | ||
31 | #define MPC86XX_PCIE_LOWER_IO 0x00000000 | ||
32 | #define MPC86XX_PCIE_UPPER_IO 0x00ffffff | ||
33 | |||
34 | #define MPC86XX_PCIE_LOWER_MEM 0x80000000 | ||
35 | #define MPC86XX_PCIE_UPPER_MEM 0x9fffffff | ||
36 | |||
37 | #define MPC86XX_PCIE_IO_BASE 0xe2000000 | ||
38 | #define MPC86XX_PCIE_MEM_OFFSET 0x00000000 | ||
39 | |||
40 | #define MPC86XX_PCIE_IO_SIZE 0x01000000 | ||
41 | |||
42 | #define PCIE1_CFG_ADDR_OFFSET (0x8000) | ||
43 | #define PCIE1_CFG_DATA_OFFSET (0x8004) | ||
44 | |||
45 | #define PCIE2_CFG_ADDR_OFFSET (0x9000) | ||
46 | #define PCIE2_CFG_DATA_OFFSET (0x9004) | ||
47 | |||
48 | #define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET | ||
49 | #define MPC86xx_PCIE_SIZE (0x1000) | ||
50 | |||
51 | #define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */ | 19 | #define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */ |
52 | 20 | ||
53 | #endif /* __MPC8641_HPCN_H__ */ | 21 | #endif /* __MPC8641_HPCN_H__ */ |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index ebae73eb0063..146da3001c67 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -37,6 +37,14 @@ | |||
37 | #include "mpc86xx.h" | 37 | #include "mpc86xx.h" |
38 | #include "mpc8641_hpcn.h" | 38 | #include "mpc8641_hpcn.h" |
39 | 39 | ||
40 | #undef DEBUG | ||
41 | |||
42 | #ifdef DEBUG | ||
43 | #define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0) | ||
44 | #else | ||
45 | #define DBG(fmt...) do { } while(0) | ||
46 | #endif | ||
47 | |||
40 | #ifndef CONFIG_PCI | 48 | #ifndef CONFIG_PCI |
41 | unsigned long isa_io_base = 0; | 49 | unsigned long isa_io_base = 0; |
42 | unsigned long isa_mem_base = 0; | 50 | unsigned long isa_mem_base = 0; |
@@ -44,205 +52,215 @@ unsigned long pci_dram_offset = 0; | |||
44 | #endif | 52 | #endif |
45 | 53 | ||
46 | 54 | ||
47 | /* | 55 | static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc, |
48 | * Internal interrupts are all Level Sensitive, and Positive Polarity | 56 | struct pt_regs *regs) |
49 | */ | 57 | { |
50 | 58 | unsigned int cascade_irq = i8259_irq(regs); | |
51 | static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = { | 59 | if (cascade_irq != NO_IRQ) |
52 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: Reserved */ | 60 | generic_handle_irq(cascade_irq, regs); |
53 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: MCM */ | 61 | desc->chip->eoi(irq); |
54 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ | 62 | } |
55 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ | ||
56 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ | ||
57 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ | ||
58 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ | ||
59 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ | ||
60 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCIE1 */ | ||
61 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: PCIE2 */ | ||
62 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: Reserved */ | ||
63 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: Reserved */ | ||
64 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: DUART2 */ | ||
65 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 1 Transmit */ | ||
66 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 1 Receive */ | ||
67 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: TSEC 3 transmit */ | ||
68 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: TSEC 3 receive */ | ||
69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: TSEC 3 error */ | ||
70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 1 Receive/Transmit Error */ | ||
71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 2 Transmit */ | ||
72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 2 Receive */ | ||
73 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: TSEC 4 transmit */ | ||
74 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: TSEC 4 receive */ | ||
75 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: TSEC 4 error */ | ||
76 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 2 Receive/Transmit Error */ | ||
77 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Unused */ | ||
78 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART1 */ | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ | ||
80 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ | ||
81 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ | ||
82 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: Unused */ | ||
83 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ | ||
84 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32: SRIO error/write-port unit */ | ||
85 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33: SRIO outbound doorbell */ | ||
86 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34: SRIO inbound doorbell */ | ||
87 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35: Unused */ | ||
88 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36: Unused */ | ||
89 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37: SRIO outbound message unit 1 */ | ||
90 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38: SRIO inbound message unit 1 */ | ||
91 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39: SRIO outbound message unit 2 */ | ||
92 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40: SRIO inbound message unit 2 */ | ||
93 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41: Unused */ | ||
94 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42: Unused */ | ||
95 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43: Unused */ | ||
96 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44: Unused */ | ||
97 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45: Unused */ | ||
98 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46: Unused */ | ||
99 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 47: Unused */ | ||
100 | 0x0, /* External 0: */ | ||
101 | 0x0, /* External 1: */ | ||
102 | 0x0, /* External 2: */ | ||
103 | 0x0, /* External 3: */ | ||
104 | 0x0, /* External 4: */ | ||
105 | 0x0, /* External 5: */ | ||
106 | 0x0, /* External 6: */ | ||
107 | 0x0, /* External 7: */ | ||
108 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: Pixis FPGA */ | ||
109 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: ULI 8259 INTR Cascade */ | ||
110 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 10: Quad ETH PHY */ | ||
111 | 0x0, /* External 11: */ | ||
112 | 0x0, | ||
113 | 0x0, | ||
114 | 0x0, | ||
115 | 0x0, | ||
116 | }; | ||
117 | |||
118 | 63 | ||
119 | void __init | 64 | void __init |
120 | mpc86xx_hpcn_init_irq(void) | 65 | mpc86xx_hpcn_init_irq(void) |
121 | { | 66 | { |
122 | struct mpic *mpic1; | 67 | struct mpic *mpic1; |
68 | struct device_node *np, *cascade_node = NULL; | ||
69 | int cascade_irq; | ||
123 | phys_addr_t openpic_paddr; | 70 | phys_addr_t openpic_paddr; |
124 | 71 | ||
72 | np = of_find_node_by_type(NULL, "open-pic"); | ||
73 | if (np == NULL) | ||
74 | return; | ||
75 | |||
125 | /* Determine the Physical Address of the OpenPIC regs */ | 76 | /* Determine the Physical Address of the OpenPIC regs */ |
126 | openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET; | 77 | openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET; |
127 | 78 | ||
128 | /* Alloc mpic structure and per isu has 16 INT entries. */ | 79 | /* Alloc mpic structure and per isu has 16 INT entries. */ |
129 | mpic1 = mpic_alloc(openpic_paddr, | 80 | mpic1 = mpic_alloc(np, openpic_paddr, |
130 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | 81 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
131 | 16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250, | 82 | 16, NR_IRQS - 4, |
132 | mpc86xx_hpcn_openpic_initsenses, | ||
133 | sizeof(mpc86xx_hpcn_openpic_initsenses), | ||
134 | " MPIC "); | 83 | " MPIC "); |
135 | BUG_ON(mpic1 == NULL); | 84 | BUG_ON(mpic1 == NULL); |
136 | 85 | ||
86 | mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10000); | ||
87 | |||
137 | /* 48 Internal Interrupts */ | 88 | /* 48 Internal Interrupts */ |
138 | mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200); | 89 | mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10200); |
139 | mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400); | 90 | mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10400); |
140 | mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600); | 91 | mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10600); |
141 | 92 | ||
142 | /* 16 External interrupts */ | 93 | /* 16 External interrupts |
143 | mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000); | 94 | * Moving them from [0 - 15] to [64 - 79] |
95 | */ | ||
96 | mpic_assign_isu(mpic1, 4, openpic_paddr + 0x10000); | ||
144 | 97 | ||
145 | mpic_init(mpic1); | 98 | mpic_init(mpic1); |
146 | 99 | ||
147 | #ifdef CONFIG_PCI | 100 | #ifdef CONFIG_PCI |
148 | mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL); | 101 | /* Initialize i8259 controller */ |
149 | i8259_init(0, I8259_OFFSET); | 102 | for_each_node_by_type(np, "interrupt-controller") |
150 | #endif | 103 | if (device_is_compatible(np, "chrp,iic")) { |
151 | } | 104 | cascade_node = np; |
105 | break; | ||
106 | } | ||
107 | if (cascade_node == NULL) { | ||
108 | printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n"); | ||
109 | return; | ||
110 | } | ||
152 | 111 | ||
112 | cascade_irq = irq_of_parse_and_map(cascade_node, 0); | ||
113 | if (cascade_irq == NO_IRQ) { | ||
114 | printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt"); | ||
115 | return; | ||
116 | } | ||
117 | DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq); | ||
153 | 118 | ||
119 | i8259_init(cascade_node, 0); | ||
120 | set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); | ||
121 | #endif | ||
122 | } | ||
154 | 123 | ||
155 | #ifdef CONFIG_PCI | 124 | #ifdef CONFIG_PCI |
156 | /* | ||
157 | * interrupt routing | ||
158 | */ | ||
159 | 125 | ||
160 | int | 126 | enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH}; |
161 | mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | 127 | const unsigned char uli1575_irq_route_table[16] = { |
128 | 0, /* 0: Reserved */ | ||
129 | 0x8, /* 1: 0b1000 */ | ||
130 | 0, /* 2: Reserved */ | ||
131 | 0x2, /* 3: 0b0010 */ | ||
132 | 0x4, /* 4: 0b0100 */ | ||
133 | 0x5, /* 5: 0b0101 */ | ||
134 | 0x7, /* 6: 0b0111 */ | ||
135 | 0x6, /* 7: 0b0110 */ | ||
136 | 0, /* 8: Reserved */ | ||
137 | 0x1, /* 9: 0b0001 */ | ||
138 | 0x3, /* 10: 0b0011 */ | ||
139 | 0x9, /* 11: 0b1001 */ | ||
140 | 0xb, /* 12: 0b1011 */ | ||
141 | 0, /* 13: Reserved */ | ||
142 | 0xd, /* 14, 0b1101 */ | ||
143 | 0xf, /* 15, 0b1111 */ | ||
144 | }; | ||
145 | |||
146 | static int __devinit | ||
147 | get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) | ||
162 | { | 148 | { |
163 | static char pci_irq_table[][4] = { | 149 | struct of_irq oirq; |
164 | /* | 150 | u32 laddr[3]; |
165 | * PCI IDSEL/INTPIN->INTLINE | 151 | struct device_node *hosenode = hose ? hose->arch_data : NULL; |
166 | * A B C D | 152 | |
167 | */ | 153 | if (!hosenode) return -EINVAL; |
168 | {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 17 -- PCI Slot 1 */ | 154 | |
169 | {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 18 -- PCI Slot 2 */ | 155 | laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); |
170 | {0, 0, 0, 0}, /* IDSEL 19 */ | 156 | laddr[1] = laddr[2] = 0; |
171 | {0, 0, 0, 0}, /* IDSEL 20 */ | 157 | of_irq_map_raw(hosenode, &pin, laddr, &oirq); |
172 | {0, 0, 0, 0}, /* IDSEL 21 */ | 158 | DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n", |
173 | {0, 0, 0, 0}, /* IDSEL 22 */ | 159 | laddr[0], slot, pin, oirq.specifier[0]); |
174 | {0, 0, 0, 0}, /* IDSEL 23 */ | 160 | return oirq.specifier[0]; |
175 | {0, 0, 0, 0}, /* IDSEL 24 */ | ||
176 | {0, 0, 0, 0}, /* IDSEL 25 */ | ||
177 | {PIRQD, PIRQA, PIRQB, PIRQC}, /* IDSEL 26 -- PCI Bridge*/ | ||
178 | {PIRQC, 0, 0, 0}, /* IDSEL 27 -- LAN */ | ||
179 | {PIRQE, PIRQF, PIRQH, PIRQ7}, /* IDSEL 28 -- USB 1.1 */ | ||
180 | {PIRQE, PIRQF, PIRQG, 0}, /* IDSEL 29 -- Audio & Modem */ | ||
181 | {PIRQH, 0, 0, 0}, /* IDSEL 30 -- LPC & PMU*/ | ||
182 | {PIRQD, 0, 0, 0}, /* IDSEL 31 -- ATA */ | ||
183 | }; | ||
184 | |||
185 | const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4; | ||
186 | return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; | ||
187 | } | 161 | } |
188 | 162 | ||
189 | static void __devinit quirk_ali1575(struct pci_dev *dev) | 163 | static void __devinit quirk_uli1575(struct pci_dev *dev) |
190 | { | 164 | { |
191 | unsigned short temp; | 165 | unsigned short temp; |
166 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
167 | unsigned char irq2pin[16]; | ||
168 | unsigned long pirq_map_word = 0; | ||
169 | u32 irq; | ||
170 | int i; | ||
192 | 171 | ||
193 | /* | 172 | /* |
194 | * ALI1575 interrupts route table setup: | 173 | * ULI1575 interrupts route setup |
174 | */ | ||
175 | memset(irq2pin, 0, 16); /* Initialize default value 0 */ | ||
176 | |||
177 | /* | ||
178 | * PIRQA -> PIRQD mapping read from OF-tree | ||
179 | * | ||
180 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
181 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
182 | */ | ||
183 | for (i = 0; i < 4; i++){ | ||
184 | irq = get_pci_irq_from_of(hose, 17, i + 1); | ||
185 | if (irq > 0 && irq < 16) | ||
186 | irq2pin[irq] = PIRQA + i; | ||
187 | else | ||
188 | printk(KERN_WARNING "ULI1575 device" | ||
189 | "(slot %d, pin %d) irq %d is invalid.\n", | ||
190 | 17, i, irq); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * PIRQE -> PIRQF mapping set manually | ||
195 | * | 195 | * |
196 | * IRQ pin IRQ# | 196 | * IRQ pin IRQ# |
197 | * PIRQA ---- 3 | ||
198 | * PIRQB ---- 4 | ||
199 | * PIRQC ---- 5 | ||
200 | * PIRQD ---- 6 | ||
201 | * PIRQE ---- 9 | 197 | * PIRQE ---- 9 |
202 | * PIRQF ---- 10 | 198 | * PIRQF ---- 10 |
203 | * PIRQG ---- 11 | 199 | * PIRQG ---- 11 |
204 | * PIRQH ---- 12 | 200 | * PIRQH ---- 12 |
205 | * | ||
206 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
207 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
208 | */ | 201 | */ |
209 | pci_write_config_dword(dev, 0x48, 0xb9317542); | 202 | for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i; |
203 | |||
204 | /* Set IRQ-PIRQ Mapping to ULI1575 */ | ||
205 | for (i = 0; i < 16; i++) | ||
206 | if (irq2pin[i]) | ||
207 | pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) | ||
208 | << ((irq2pin[i] - PIRQA) * 4); | ||
210 | 209 | ||
211 | /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ | 210 | /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ |
212 | pci_write_config_byte(dev, 0x86, 0x0c); | 211 | DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n", |
212 | pirq_map_word); | ||
213 | pci_write_config_dword(dev, 0x48, pirq_map_word); | ||
213 | 214 | ||
214 | /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ | 215 | #define ULI1575_SET_DEV_IRQ(slot, pin, reg) \ |
215 | pci_write_config_byte(dev, 0x87, 0x0d); | 216 | do { \ |
217 | int irq; \ | ||
218 | irq = get_pci_irq_from_of(hose, slot, pin); \ | ||
219 | if (irq > 0 && irq < 16) \ | ||
220 | pci_write_config_byte(dev, reg, irq2pin[irq]); \ | ||
221 | else \ | ||
222 | printk(KERN_WARNING "ULI1575 device" \ | ||
223 | "(slot %d, pin %d) irq %d is invalid.\n", \ | ||
224 | slot, pin, irq); \ | ||
225 | } while(0) | ||
216 | 226 | ||
217 | /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ | 227 | /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ |
218 | pci_write_config_byte(dev, 0x88, 0x0f); | 228 | ULI1575_SET_DEV_IRQ(28, 1, 0x86); |
219 | 229 | ||
220 | /* USB 2.0 controller, interrupt: PIRQ7 */ | 230 | /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ |
221 | pci_write_config_byte(dev, 0x74, 0x06); | 231 | ULI1575_SET_DEV_IRQ(28, 2, 0x87); |
222 | 232 | ||
223 | /* Audio controller, interrupt: PIRQE */ | 233 | /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ |
224 | pci_write_config_byte(dev, 0x8a, 0x0c); | 234 | ULI1575_SET_DEV_IRQ(28, 3, 0x88); |
225 | 235 | ||
226 | /* Modem controller, interrupt: PIRQF */ | 236 | /* USB 2.0 controller, slot 28, pin 4 */ |
227 | pci_write_config_byte(dev, 0x8b, 0x0d); | 237 | irq = get_pci_irq_from_of(hose, 28, 4); |
238 | if (irq >= 0 && irq <=15) | ||
239 | pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); | ||
228 | 240 | ||
229 | /* HD audio controller, interrupt: PIRQG */ | 241 | /* Audio controller, slot 29, pin 1 */ |
230 | pci_write_config_byte(dev, 0x8c, 0x0e); | 242 | ULI1575_SET_DEV_IRQ(29, 1, 0x8a); |
231 | 243 | ||
232 | /* Serial ATA interrupt: PIRQD */ | 244 | /* Modem controller, slot 29, pin 2 */ |
233 | pci_write_config_byte(dev, 0x8d, 0x0b); | 245 | ULI1575_SET_DEV_IRQ(29, 2, 0x8b); |
234 | 246 | ||
235 | /* SMB interrupt: PIRQH */ | 247 | /* HD audio controller, slot 29, pin 3 */ |
236 | pci_write_config_byte(dev, 0x8e, 0x0f); | 248 | ULI1575_SET_DEV_IRQ(29, 3, 0x8c); |
237 | 249 | ||
238 | /* PMU ACPI SCI interrupt: PIRQH */ | 250 | /* SMB interrupt: slot 30, pin 1 */ |
239 | pci_write_config_byte(dev, 0x8f, 0x0f); | 251 | ULI1575_SET_DEV_IRQ(30, 1, 0x8e); |
252 | |||
253 | /* PMU ACPI SCI interrupt: slot 30, pin 2 */ | ||
254 | ULI1575_SET_DEV_IRQ(30, 2, 0x8f); | ||
255 | |||
256 | /* Serial ATA interrupt: slot 31, pin 1 */ | ||
257 | ULI1575_SET_DEV_IRQ(31, 1, 0x8d); | ||
240 | 258 | ||
241 | /* Primary PATA IDE IRQ: 14 | 259 | /* Primary PATA IDE IRQ: 14 |
242 | * Secondary PATA IDE IRQ: 15 | 260 | * Secondary PATA IDE IRQ: 15 |
243 | */ | 261 | */ |
244 | pci_write_config_byte(dev, 0x44, 0x3d); | 262 | pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]); |
245 | pci_write_config_byte(dev, 0x75, 0x0f); | 263 | pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); |
246 | 264 | ||
247 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | 265 | /* Set IRQ14 and IRQ15 to legacy IRQs */ |
248 | pci_read_config_word(dev, 0x46, &temp); | 266 | pci_read_config_word(dev, 0x46, &temp); |
@@ -264,6 +282,8 @@ static void __devinit quirk_ali1575(struct pci_dev *dev) | |||
264 | */ | 282 | */ |
265 | outb(0xfa, 0x4d0); | 283 | outb(0xfa, 0x4d0); |
266 | outb(0x1e, 0x4d1); | 284 | outb(0x1e, 0x4d1); |
285 | |||
286 | #undef ULI1575_SET_DEV_IRQ | ||
267 | } | 287 | } |
268 | 288 | ||
269 | static void __devinit quirk_uli5288(struct pci_dev *dev) | 289 | static void __devinit quirk_uli5288(struct pci_dev *dev) |
@@ -306,7 +326,7 @@ static void __devinit early_uli5249(struct pci_dev *dev) | |||
306 | dev->class |= 0x1; | 326 | dev->class |= 0x1; |
307 | } | 327 | } |
308 | 328 | ||
309 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); | 329 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); |
310 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | 330 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); |
311 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | 331 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); |
312 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | 332 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); |
@@ -337,8 +357,6 @@ mpc86xx_hpcn_setup_arch(void) | |||
337 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | 357 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) |
338 | add_bridge(np); | 358 | add_bridge(np); |
339 | 359 | ||
340 | ppc_md.pci_swizzle = common_swizzle; | ||
341 | ppc_md.pci_map_irq = mpc86xx_map_irq; | ||
342 | ppc_md.pci_exclude_device = mpc86xx_exclude_device; | 360 | ppc_md.pci_exclude_device = mpc86xx_exclude_device; |
343 | #endif | 361 | #endif |
344 | 362 | ||
@@ -377,6 +395,15 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) | |||
377 | } | 395 | } |
378 | 396 | ||
379 | 397 | ||
398 | void __init mpc86xx_hpcn_pcibios_fixup(void) | ||
399 | { | ||
400 | struct pci_dev *dev = NULL; | ||
401 | |||
402 | for_each_pci_dev(dev) | ||
403 | pci_read_irq_line(dev); | ||
404 | } | ||
405 | |||
406 | |||
380 | /* | 407 | /* |
381 | * Called very early, device-tree isn't unflattened | 408 | * Called very early, device-tree isn't unflattened |
382 | */ | 409 | */ |
@@ -431,6 +458,7 @@ define_machine(mpc86xx_hpcn) { | |||
431 | .setup_arch = mpc86xx_hpcn_setup_arch, | 458 | .setup_arch = mpc86xx_hpcn_setup_arch, |
432 | .init_IRQ = mpc86xx_hpcn_init_irq, | 459 | .init_IRQ = mpc86xx_hpcn_init_irq, |
433 | .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, | 460 | .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, |
461 | .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup, | ||
434 | .get_irq = mpic_get_irq, | 462 | .get_irq = mpic_get_irq, |
435 | .restart = mpc86xx_restart, | 463 | .restart = mpc86xx_restart, |
436 | .time_init = mpc86xx_time_init, | 464 | .time_init = mpc86xx_time_init, |