1/* $Id: ebus.c,v 1.1.1.1 2008/10/15 03:26:19 james26_jang Exp $ 2 * ebus.c: PCI to EBus bridge device. 3 * 4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) 5 * Copyright (C) 1999 David S. Miller (davem@redhat.com) 6 */ 7 8#include <linux/config.h> 9#include <linux/kernel.h> 10#include <linux/types.h> 11#include <linux/init.h> 12#include <linux/slab.h> 13#include <linux/string.h> 14 15#include <asm/system.h> 16#include <asm/page.h> 17#include <asm/pbm.h> 18#include <asm/ebus.h> 19#include <asm/oplib.h> 20#include <asm/bpp.h> 21#include <asm/irq.h> 22 23struct linux_ebus *ebus_chain = 0; 24 25#ifdef CONFIG_SUN_AUXIO 26extern void auxio_probe(void); 27#endif 28 29static inline void *ebus_alloc(size_t size) 30{ 31 void *mem; 32 33 mem = kmalloc(size, GFP_ATOMIC); 34 if (!mem) 35 panic("ebus_alloc: out of memory"); 36 memset((char *)mem, 0, size); 37 return mem; 38} 39 40static void __init ebus_ranges_init(struct linux_ebus *ebus) 41{ 42 int success; 43 44 ebus->num_ebus_ranges = 0; 45 success = prom_getproperty(ebus->prom_node, "ranges", 46 (char *)ebus->ebus_ranges, 47 sizeof(ebus->ebus_ranges)); 48 if (success != -1) 49 ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges)); 50} 51 52static void __init ebus_intmap_init(struct linux_ebus *ebus) 53{ 54 int success; 55 56 ebus->num_ebus_intmap = 0; 57 success = prom_getproperty(ebus->prom_node, "interrupt-map", 58 (char *)ebus->ebus_intmap, 59 sizeof(ebus->ebus_intmap)); 60 if (success == -1) 61 return; 62 63 ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap)); 64 65 success = prom_getproperty(ebus->prom_node, "interrupt-map-mask", 66 (char *)&ebus->ebus_intmask, 67 sizeof(ebus->ebus_intmask)); 68 if (success == -1) { 69 prom_printf("ebus: can't get interrupt-map-mask\n"); 70 prom_halt(); 71 } 72} 73 74int __init ebus_intmap_match(struct linux_ebus *ebus, 75 struct linux_prom_registers *reg, 76 int *interrupt) 77{ 78 unsigned int hi, lo, irq; 79 int i; 80 81 if (!ebus->num_ebus_intmap) 82 return 0; 83 84 hi = reg->which_io & ebus->ebus_intmask.phys_hi; 85 lo = reg->phys_addr & ebus->ebus_intmask.phys_lo; 86 irq = *interrupt & ebus->ebus_intmask.interrupt; 87 for (i = 0; i < ebus->num_ebus_intmap; i++) { 88 if ((ebus->ebus_intmap[i].phys_hi == hi) && 89 (ebus->ebus_intmap[i].phys_lo == lo) && 90 (ebus->ebus_intmap[i].interrupt == irq)) { 91 *interrupt = ebus->ebus_intmap[i].cinterrupt; 92 return 0; 93 } 94 } 95 return -1; 96} 97 98void __init fill_ebus_child(int node, struct linux_prom_registers *preg, 99 struct linux_ebus_child *dev, int non_standard_regs) 100{ 101 int regs[PROMREG_MAX]; 102 int irqs[PROMREG_MAX]; 103 int i, len; 104 105 dev->prom_node = node; 106 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); 107 printk(" (%s)", dev->prom_name); 108 109 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 110 dev->num_addrs = len / sizeof(regs[0]); 111 112 if (non_standard_regs) { 113 /* This is to handle reg properties which are not 114 * in the parent relative format. One example are 115 * children of the i2c device on CompactPCI systems. 116 * 117 * So, for such devices we just record the property 118 * raw in the child resources. 119 */ 120 for (i = 0; i < dev->num_addrs; i++) 121 dev->resource[i].start = regs[i]; 122 } else { 123 for (i = 0; i < dev->num_addrs; i++) { 124 int rnum = regs[i]; 125 if (rnum >= dev->parent->num_addrs) { 126 prom_printf("UGH: property for %s was %d, need < %d\n", 127 dev->prom_name, len, dev->parent->num_addrs); 128 panic("fill_ebus_child"); 129 } 130 dev->resource[i].start = dev->parent->resource[i].start; 131 dev->resource[i].end = dev->parent->resource[i].end; 132 dev->resource[i].flags = IORESOURCE_MEM; 133 dev->resource[i].name = dev->prom_name; 134 } 135 } 136 137 for (i = 0; i < PROMINTR_MAX; i++) 138 dev->irqs[i] = PCI_IRQ_NONE; 139 140 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 141 if ((len == -1) || (len == 0)) { 142 dev->num_irqs = 0; 143 /* 144 * Oh, well, some PROMs don't export interrupts 145 * property to children of EBus devices... 146 * 147 * Be smart about PS/2 keyboard and mouse. 148 */ 149 if (!strcmp(dev->parent->prom_name, "8042")) { 150 if (!strcmp(dev->prom_name, "kb_ps2")) { 151 dev->num_irqs = 1; 152 dev->irqs[0] = dev->parent->irqs[0]; 153 } else { 154 dev->num_irqs = 1; 155 dev->irqs[0] = dev->parent->irqs[1]; 156 } 157 } 158 } else { 159 dev->num_irqs = len / sizeof(irqs[0]); 160 for (i = 0; i < dev->num_irqs; i++) { 161 struct pci_pbm_info *pbm = dev->bus->parent; 162 struct pci_controller_info *p = pbm->parent; 163 164 if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) { 165 dev->irqs[i] = p->irq_build(pbm, 166 dev->bus->self, 167 irqs[i]); 168 } else { 169 /* If we get a bogus interrupt property, just 170 * record the raw value instead of punting. 171 */ 172 dev->irqs[i] = irqs[i]; 173 } 174 } 175 } 176} 177 178static int __init child_regs_nonstandard(struct linux_ebus_device *dev) 179{ 180 if (!strcmp(dev->prom_name, "i2c")) 181 return 1; 182 return 0; 183} 184 185void __init fill_ebus_device(int node, struct linux_ebus_device *dev) 186{ 187 struct linux_prom_registers regs[PROMREG_MAX]; 188 struct linux_ebus_child *child; 189 int irqs[PROMINTR_MAX]; 190 int i, n, len; 191 192 dev->prom_node = node; 193 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); 194 printk(" [%s", dev->prom_name); 195 196 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 197 if (len == -1) { 198 dev->num_addrs = 0; 199 goto probe_interrupts; 200 } 201 202 if (len % sizeof(struct linux_prom_registers)) { 203 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", 204 dev->prom_name, len, 205 (int)sizeof(struct linux_prom_registers)); 206 prom_halt(); 207 } 208 dev->num_addrs = len / sizeof(struct linux_prom_registers); 209 210 for (i = 0; i < dev->num_addrs; i++) { 211 if (regs[i].which_io >= 0x10) 212 n = (regs[i].which_io - 0x10) >> 2; 213 else 214 n = regs[i].which_io; 215 216 dev->resource[i].start = dev->bus->self->resource[n].start; 217 dev->resource[i].start += (unsigned long)regs[i].phys_addr; 218 dev->resource[i].end = 219 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL); 220 dev->resource[i].flags = IORESOURCE_MEM; 221 dev->resource[i].name = dev->prom_name; 222 request_resource(&dev->bus->self->resource[n], 223 &dev->resource[i]); 224 } 225 226probe_interrupts: 227 for (i = 0; i < PROMINTR_MAX; i++) 228 dev->irqs[i] = PCI_IRQ_NONE; 229 230 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 231 if ((len == -1) || (len == 0)) { 232 dev->num_irqs = 0; 233 } else { 234 dev->num_irqs = len / sizeof(irqs[0]); 235 for (i = 0; i < dev->num_irqs; i++) { 236 struct pci_pbm_info *pbm = dev->bus->parent; 237 struct pci_controller_info *p = pbm->parent; 238 239 if (ebus_intmap_match(dev->bus, ®s[0], &irqs[i]) != -1) { 240 dev->irqs[i] = p->irq_build(pbm, 241 dev->bus->self, 242 irqs[i]); 243 } else { 244 /* If we get a bogus interrupt property, just 245 * record the raw value instead of punting. 246 */ 247 dev->irqs[i] = irqs[i]; 248 } 249 } 250 } 251 252 if ((node = prom_getchild(node))) { 253 printk(" ->"); 254 dev->children = ebus_alloc(sizeof(struct linux_ebus_child)); 255 256 child = dev->children; 257 child->next = 0; 258 child->parent = dev; 259 child->bus = dev->bus; 260 fill_ebus_child(node, ®s[0], 261 child, child_regs_nonstandard(dev)); 262 263 while ((node = prom_getsibling(node))) { 264 child->next = ebus_alloc(sizeof(struct linux_ebus_child)); 265 266 child = child->next; 267 child->next = 0; 268 child->parent = dev; 269 child->bus = dev->bus; 270 fill_ebus_child(node, ®s[0], 271 child, child_regs_nonstandard(dev)); 272 } 273 } 274 printk("]"); 275} 276 277static struct pci_dev *find_next_ebus(struct pci_dev *start, int *is_rio_p) 278{ 279 struct pci_dev *pdev = start; 280 281 do { 282 pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev); 283 if (pdev && 284 (pdev->device == PCI_DEVICE_ID_SUN_EBUS || 285 pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)) 286 break; 287 } while (pdev != NULL); 288 289 if (pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)) 290 *is_rio_p = 1; 291 else 292 *is_rio_p = 0; 293 294 return pdev; 295} 296 297void __init ebus_init(void) 298{ 299 struct pci_pbm_info *pbm; 300 struct linux_ebus_device *dev; 301 struct linux_ebus *ebus; 302 struct pci_dev *pdev; 303 struct pcidev_cookie *cookie; 304 int nd, ebusnd, is_rio; 305 int num_ebus = 0; 306 307 if (!pci_present()) 308 return; 309 310 pdev = find_next_ebus(NULL, &is_rio); 311 if (!pdev) { 312 printk("ebus: No EBus's found.\n"); 313 return; 314 } 315 316 cookie = pdev->sysdata; 317 ebusnd = cookie->prom_node; 318 319 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); 320 ebus->next = 0; 321 ebus->is_rio = is_rio; 322 323 while (ebusnd) { 324 /* SUNW,pci-qfe uses four empty ebuses on it. 325 I think we should not consider them here, 326 as they have half of the properties this 327 code expects and once we do PCI hot-plug, 328 we'd have to tweak with the ebus_chain 329 in the runtime after initialization. -jj */ 330 if (!prom_getchild (ebusnd)) { 331 pdev = find_next_ebus(pdev, &is_rio); 332 if (!pdev) { 333 if (ebus == ebus_chain) { 334 ebus_chain = NULL; 335 printk("ebus: No EBus's found.\n"); 336 return; 337 } 338 break; 339 } 340 ebus->is_rio = is_rio; 341 cookie = pdev->sysdata; 342 ebusnd = cookie->prom_node; 343 continue; 344 } 345 printk("ebus%d:", num_ebus); 346 347 prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name)); 348 ebus->index = num_ebus; 349 ebus->prom_node = ebusnd; 350 ebus->self = pdev; 351 ebus->parent = pbm = cookie->pbm; 352 353 ebus_ranges_init(ebus); 354 ebus_intmap_init(ebus); 355 356 nd = prom_getchild(ebusnd); 357 if (!nd) 358 goto next_ebus; 359 360 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); 361 362 dev = ebus->devices; 363 dev->next = 0; 364 dev->children = 0; 365 dev->bus = ebus; 366 fill_ebus_device(nd, dev); 367 368 while ((nd = prom_getsibling(nd))) { 369 dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); 370 371 dev = dev->next; 372 dev->next = 0; 373 dev->children = 0; 374 dev->bus = ebus; 375 fill_ebus_device(nd, dev); 376 } 377 378 next_ebus: 379 printk("\n"); 380 381 pdev = find_next_ebus(pdev, &is_rio); 382 if (!pdev) 383 break; 384 385 cookie = pdev->sysdata; 386 ebusnd = cookie->prom_node; 387 388 ebus->next = ebus_alloc(sizeof(struct linux_ebus)); 389 ebus = ebus->next; 390 ebus->next = 0; 391 ebus->is_rio = is_rio; 392 ++num_ebus; 393 } 394 395#ifdef CONFIG_SUN_AUXIO 396 auxio_probe(); 397#endif 398} 399