aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/isa.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/isa.c')
-rw-r--r--arch/sparc64/kernel/isa.c68
1 files changed, 24 insertions, 44 deletions
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index 8c8c5a491ad6..2693f2de549c 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -72,19 +72,30 @@ static struct {
72static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev, 72static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev,
73 struct sparc_isa_bridge *isa_br, 73 struct sparc_isa_bridge *isa_br,
74 int *interrupt, 74 int *interrupt,
75 struct linux_prom_registers *pregs) 75 struct linux_prom_registers *reg)
76{ 76{
77 struct linux_prom_ebus_intmap *imap;
78 struct linux_prom_ebus_intmap *imask;
77 unsigned int hi, lo, irq; 79 unsigned int hi, lo, irq;
78 int i; 80 int i, len, n_imap;
79 81
80 hi = pregs->which_io & isa_br->isa_intmask.phys_hi; 82 imap = of_get_property(isa_br->prom_node, "interrupt-map", &len);
81 lo = pregs->phys_addr & isa_br->isa_intmask.phys_lo; 83 if (!imap)
82 irq = *interrupt & isa_br->isa_intmask.interrupt; 84 return 0;
83 for (i = 0; i < isa_br->num_isa_intmap; i++) { 85 n_imap = len / sizeof(imap[0]);
84 if ((isa_br->isa_intmap[i].phys_hi == hi) && 86
85 (isa_br->isa_intmap[i].phys_lo == lo) && 87 imask = of_get_property(isa_br->prom_node, "interrupt-map-mask", NULL);
86 (isa_br->isa_intmap[i].interrupt == irq)) { 88 if (!imask)
87 *interrupt = isa_br->isa_intmap[i].cinterrupt; 89 return 0;
90
91 hi = reg->which_io & imask->phys_hi;
92 lo = reg->phys_addr & imask->phys_lo;
93 irq = *interrupt & imask->interrupt;
94 for (i = 0; i < n_imap; i++) {
95 if ((imap[i].phys_hi == hi) &&
96 (imap[i].phys_lo == lo) &&
97 (imap[i].interrupt == irq)) {
98 *interrupt = imap[i].cinterrupt;
88 return 0; 99 return 0;
89 } 100 }
90 } 101 }
@@ -105,7 +116,8 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
105 struct pci_pbm_info *pbm; 116 struct pci_pbm_info *pbm;
106 int i; 117 int i;
107 118
108 if (isa_dev->bus->num_isa_intmap) { 119 if (of_find_property(isa_dev->bus->prom_node,
120 "interrupt-map", NULL)) {
109 if (!isa_dev_get_irq_using_imap(isa_dev, 121 if (!isa_dev_get_irq_using_imap(isa_dev,
110 isa_dev->bus, 122 isa_dev->bus,
111 &irq_prop, 123 &irq_prop,
@@ -218,36 +230,6 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
218 } 230 }
219} 231}
220 232
221static void __init get_bridge_props(struct sparc_isa_bridge *isa_br)
222{
223 struct device_node *dp = isa_br->prom_node;
224 void *pval;
225 int len;
226
227 pval = of_get_property(dp, "ranges", &len);
228 if (pval) {
229 memcpy(isa_br->isa_ranges, pval, len);
230 isa_br->num_isa_ranges =
231 len / sizeof(struct linux_prom_isa_ranges);
232 } else {
233 isa_br->num_isa_ranges = 0;
234 }
235
236 pval = of_get_property(dp, "interrupt-map", &len);
237 if (pval) {
238 memcpy(isa_br->isa_intmap, pval, len);
239 isa_br->num_isa_intmap =
240 (len / sizeof(struct linux_prom_isa_intmap));
241 } else {
242 isa_br->num_isa_intmap = 0;
243 }
244
245 pval = of_get_property(dp, "interrupt-map-mask", &len);
246 if (pval)
247 memcpy(&isa_br->isa_intmask, pval,
248 sizeof(isa_br->isa_intmask));
249}
250
251void __init isa_init(void) 233void __init isa_init(void)
252{ 234{
253 struct pci_dev *pdev; 235 struct pci_dev *pdev;
@@ -288,8 +270,6 @@ void __init isa_init(void)
288 isa_br->index = index++; 270 isa_br->index = index++;
289 isa_br->prom_node = pdev_cookie->prom_node; 271 isa_br->prom_node = pdev_cookie->prom_node;
290 272
291 get_bridge_props(isa_br);
292
293 printk("isa%d:", isa_br->index); 273 printk("isa%d:", isa_br->index);
294 274
295 isa_fill_devices(isa_br); 275 isa_fill_devices(isa_br);