1 /* $Id: ebus.c,v 1.44 1999/09/05 09:28:09 ecd Exp $
2 * ebus.c: PCI to EBus bridge device.
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/init.h>
12 #include <linux/malloc.h>
13 #include <linux/string.h>
15 #include <asm/system.h>
19 #include <asm/oplib.h>
23 struct linux_ebus
*ebus_chain
= 0;
25 extern void prom_ebus_ranges_init(struct linux_ebus
*);
26 extern void prom_ebus_intmap_init(struct linux_ebus
*);
28 #ifdef CONFIG_SUN_OPENPROMIO
29 extern int openprom_init(void);
31 #ifdef CONFIG_SUN_AUXIO
32 extern void auxio_probe(void);
34 #ifdef CONFIG_OBP_FLASH
35 extern int flash_init(void);
38 extern int envctrl_init(void);
41 static inline void *ebus_alloc(size_t size
)
45 mem
= kmalloc(size
, GFP_ATOMIC
);
47 panic(__FUNCTION__
": out of memory");
48 memset((char *)mem
, 0, size
);
52 void __init
ebus_intmap_match(struct linux_ebus
*ebus
,
53 struct linux_prom_registers
*reg
,
56 unsigned int hi
, lo
, irq
;
59 if (!ebus
->num_ebus_intmap
)
62 hi
= reg
->which_io
& ebus
->ebus_intmask
.phys_hi
;
63 lo
= reg
->phys_addr
& ebus
->ebus_intmask
.phys_lo
;
64 irq
= *interrupt
& ebus
->ebus_intmask
.interrupt
;
65 for (i
= 0; i
< ebus
->num_ebus_intmap
; i
++) {
66 if ((ebus
->ebus_intmap
[i
].phys_hi
== hi
) &&
67 (ebus
->ebus_intmap
[i
].phys_lo
== lo
) &&
68 (ebus
->ebus_intmap
[i
].interrupt
== irq
)) {
69 *interrupt
= ebus
->ebus_intmap
[i
].cinterrupt
;
74 prom_printf("ebus: IRQ [%08x.%08x.%08x] not found in interrupt-map\n",
75 reg
->which_io
, reg
->phys_addr
, *interrupt
);
79 void __init
fill_ebus_child(int node
, struct linux_prom_registers
*preg
,
80 struct linux_ebus_child
*dev
, int non_standard_regs
)
82 int regs
[PROMREG_MAX
];
83 int irqs
[PROMREG_MAX
];
86 dev
->prom_node
= node
;
87 prom_getstring(node
, "name", dev
->prom_name
, sizeof(dev
->prom_name
));
88 printk(" (%s)", dev
->prom_name
);
90 len
= prom_getproperty(node
, "reg", (void *)regs
, sizeof(regs
));
91 dev
->num_addrs
= len
/ sizeof(regs
[0]);
93 if (non_standard_regs
) {
94 /* This is to handle reg properties which are not
95 * in the parent relative format. One example are
96 * children of the i2c device on CompactPCI systems.
98 * So, for such devices we just record the property
99 * raw in the child resources.
101 for (i
= 0; i
< dev
->num_addrs
; i
++)
102 dev
->resource
[i
].start
= regs
[i
];
104 for (i
= 0; i
< dev
->num_addrs
; i
++) {
106 if (rnum
>= dev
->parent
->num_addrs
) {
107 prom_printf("UGH: property for %s was %d, need < %d\n",
108 dev
->prom_name
, len
, dev
->parent
->num_addrs
);
111 dev
->resource
[i
].start
= dev
->parent
->resource
[i
].start
;
112 dev
->resource
[i
].end
= dev
->parent
->resource
[i
].end
;
113 dev
->resource
[i
].flags
= IORESOURCE_MEM
;
114 dev
->resource
[i
].name
= dev
->prom_name
;
118 len
= prom_getproperty(node
, "interrupts", (char *)&irqs
, sizeof(irqs
));
119 if ((len
== -1) || (len
== 0)) {
122 * Oh, well, some PROMs don't export interrupts
123 * property to children of EBus devices...
125 * Be smart about PS/2 keyboard and mouse.
127 if (!strcmp(dev
->parent
->prom_name
, "8042")) {
128 if (!strcmp(dev
->prom_name
, "kb_ps2")) {
130 dev
->irqs
[0] = dev
->parent
->irqs
[0];
133 dev
->irqs
[0] = dev
->parent
->irqs
[1];
137 dev
->num_irqs
= len
/ sizeof(irqs
[0]);
138 for (i
= 0; i
< dev
->num_irqs
; i
++) {
139 struct pci_pbm_info
*pbm
= dev
->bus
->parent
;
140 struct pci_controller_info
*p
= pbm
->parent
;
142 ebus_intmap_match(dev
->bus
, preg
, &irqs
[i
]);
143 dev
->irqs
[i
] = p
->irq_build(p
, dev
->bus
->self
, irqs
[i
]);
148 static int __init
child_regs_nonstandard(struct linux_ebus_device
*dev
)
150 if (!strcmp(dev
->prom_name
, "i2c"))
155 void __init
fill_ebus_device(int node
, struct linux_ebus_device
*dev
)
157 struct linux_prom_registers regs
[PROMREG_MAX
];
158 struct linux_ebus_child
*child
;
159 int irqs
[PROMINTR_MAX
];
162 dev
->prom_node
= node
;
163 prom_getstring(node
, "name", dev
->prom_name
, sizeof(dev
->prom_name
));
164 printk(" [%s", dev
->prom_name
);
166 len
= prom_getproperty(node
, "reg", (void *)regs
, sizeof(regs
));
167 if (len
% sizeof(struct linux_prom_registers
)) {
168 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
170 (int)sizeof(struct linux_prom_registers
));
173 dev
->num_addrs
= len
/ sizeof(struct linux_prom_registers
);
175 for (i
= 0; i
< dev
->num_addrs
; i
++) {
176 n
= (regs
[i
].which_io
- 0x10) >> 2;
178 dev
->resource
[i
].start
= dev
->bus
->self
->resource
[n
].start
;
179 dev
->resource
[i
].start
+= (unsigned long)regs
[i
].phys_addr
;
180 dev
->resource
[i
].end
=
181 (dev
->resource
[i
].start
+ (unsigned long)regs
[i
].reg_size
- 1UL);
182 dev
->resource
[i
].flags
= IORESOURCE_MEM
;
183 dev
->resource
[i
].name
= dev
->prom_name
;
184 request_resource(&dev
->bus
->self
->resource
[n
],
188 len
= prom_getproperty(node
, "interrupts", (char *)&irqs
, sizeof(irqs
));
189 if ((len
== -1) || (len
== 0)) {
192 dev
->num_irqs
= len
/ sizeof(irqs
[0]);
193 for (i
= 0; i
< dev
->num_irqs
; i
++) {
194 struct pci_pbm_info
*pbm
= dev
->bus
->parent
;
195 struct pci_controller_info
*p
= pbm
->parent
;
197 ebus_intmap_match(dev
->bus
, ®s
[0], &irqs
[i
]);
198 dev
->irqs
[i
] = p
->irq_build(p
, dev
->bus
->self
, irqs
[i
]);
202 if ((node
= prom_getchild(node
))) {
204 dev
->children
= ebus_alloc(sizeof(struct linux_ebus_child
));
206 child
= dev
->children
;
209 child
->bus
= dev
->bus
;
210 fill_ebus_child(node
, ®s
[0],
211 child
, child_regs_nonstandard(dev
));
213 while ((node
= prom_getsibling(node
))) {
214 child
->next
= ebus_alloc(sizeof(struct linux_ebus_child
));
219 child
->bus
= dev
->bus
;
220 fill_ebus_child(node
, ®s
[0],
221 child
, child_regs_nonstandard(dev
));
227 extern void clock_probe(void);
228 extern void power_init(void);
230 void __init
ebus_init(void)
232 struct pci_pbm_info
*pbm
;
233 struct linux_ebus_device
*dev
;
234 struct linux_ebus
*ebus
;
235 struct pci_dev
*pdev
;
236 struct pcidev_cookie
*cookie
;
237 unsigned short pci_command
;
244 pdev
= pci_find_device(PCI_VENDOR_ID_SUN
, PCI_DEVICE_ID_SUN_EBUS
, 0);
246 printk("ebus: No EBus's found.\n");
250 cookie
= pdev
->sysdata
;
251 ebusnd
= cookie
->prom_node
;
253 ebus_chain
= ebus
= ebus_alloc(sizeof(struct linux_ebus
));
257 /* SUNW,pci-qfe uses four empty ebuses on it.
258 I think we should not consider them here,
259 as they have half of the properties this
260 code expects and once we do PCI hot-plug,
261 we'd have to tweak with the ebus_chain
262 in the runtime after initialization. -jj */
263 if (!prom_getchild (ebusnd
)) {
264 pdev
= pci_find_device(PCI_VENDOR_ID_SUN
,
265 PCI_DEVICE_ID_SUN_EBUS
, pdev
);
267 if (ebus
== ebus_chain
) {
269 printk("ebus: No EBus's found.\n");
275 cookie
= pdev
->sysdata
;
276 ebusnd
= cookie
->prom_node
;
279 printk("ebus%d:", num_ebus
);
281 prom_getstring(ebusnd
, "name", ebus
->prom_name
, sizeof(ebus
->prom_name
));
282 ebus
->index
= num_ebus
;
283 ebus
->prom_node
= ebusnd
;
285 ebus
->parent
= pbm
= cookie
->pbm
;
287 /* Enable BUS Master. */
288 pci_read_config_word(pdev
, PCI_COMMAND
, &pci_command
);
289 pci_command
|= PCI_COMMAND_MASTER
;
290 pci_write_config_word(pdev
, PCI_COMMAND
, pci_command
);
292 /* Set reasonable cache line size and latency timer values. */
293 pci_write_config_byte(pdev
, PCI_LATENCY_TIMER
, 64);
295 /* NOTE: Cache line size is in 32-bit word units. */
296 pci_write_config_byte(pdev
, PCI_CACHE_LINE_SIZE
, 64/sizeof(u32
));
298 prom_ebus_ranges_init(ebus
);
299 prom_ebus_intmap_init(ebus
);
301 nd
= prom_getchild(ebusnd
);
305 ebus
->devices
= ebus_alloc(sizeof(struct linux_ebus_device
));
311 fill_ebus_device(nd
, dev
);
313 while ((nd
= prom_getsibling(nd
))) {
314 dev
->next
= ebus_alloc(sizeof(struct linux_ebus_device
));
320 fill_ebus_device(nd
, dev
);
326 pdev
= pci_find_device(PCI_VENDOR_ID_SUN
,
327 PCI_DEVICE_ID_SUN_EBUS
, pdev
);
331 cookie
= pdev
->sysdata
;
332 ebusnd
= cookie
->prom_node
;
334 ebus
->next
= ebus_alloc(sizeof(struct linux_ebus
));
340 #ifdef CONFIG_SUN_OPENPROMIO
343 #ifdef CONFIG_SUN_BPP
346 #ifdef CONFIG_SUN_AUXIO
349 #ifdef CONFIG_ENVCTRL
352 #ifdef CONFIG_OBP_FLASH