diff options
Diffstat (limited to 'arch/mips/sgi-ip22/ip22-gio.c')
-rw-r--r-- | arch/mips/sgi-ip22/ip22-gio.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c index ab0e379dc7e0..8e52446286ca 100644 --- a/arch/mips/sgi-ip22/ip22-gio.c +++ b/arch/mips/sgi-ip22/ip22-gio.c | |||
@@ -19,6 +19,9 @@ static struct { | |||
19 | } gio_name_table[] = { | 19 | } gio_name_table[] = { |
20 | { .name = "SGI Impact", .id = 0x10 }, | 20 | { .name = "SGI Impact", .id = 0x10 }, |
21 | { .name = "Phobos G160", .id = 0x35 }, | 21 | { .name = "Phobos G160", .id = 0x35 }, |
22 | { .name = "Phobos G130", .id = 0x36 }, | ||
23 | { .name = "Phobos G100", .id = 0x37 }, | ||
24 | { .name = "Set Engineering GFE", .id = 0x38 }, | ||
22 | /* fake IDs */ | 25 | /* fake IDs */ |
23 | { .name = "SGI Newport", .id = 0x7e }, | 26 | { .name = "SGI Newport", .id = 0x7e }, |
24 | { .name = "SGI GR2/GR3", .id = 0x7f }, | 27 | { .name = "SGI GR2/GR3", .id = 0x7f }, |
@@ -293,7 +296,16 @@ static int ip22_gio_id(unsigned long addr, u32 *res) | |||
293 | * data matches | 296 | * data matches |
294 | */ | 297 | */ |
295 | ptr8 = (void *)CKSEG1ADDR(addr + 3); | 298 | ptr8 = (void *)CKSEG1ADDR(addr + 3); |
296 | get_dbe(tmp8, ptr8); | 299 | if (get_dbe(tmp8, ptr8)) { |
300 | /* | ||
301 | * 32bit access worked, but 8bit doesn't | ||
302 | * so we don't see phantom reads on | ||
303 | * a pipelined bus, but a real card which | ||
304 | * doesn't support 8 bit reads | ||
305 | */ | ||
306 | *res = tmp32; | ||
307 | return 1; | ||
308 | } | ||
297 | ptr16 = (void *)CKSEG1ADDR(addr + 2); | 309 | ptr16 = (void *)CKSEG1ADDR(addr + 2); |
298 | get_dbe(tmp16, ptr16); | 310 | get_dbe(tmp16, ptr16); |
299 | if (tmp8 == (tmp16 & 0xff) && | 311 | if (tmp8 == (tmp16 & 0xff) && |
@@ -324,7 +336,7 @@ static int ip22_is_gr2(unsigned long addr) | |||
324 | } | 336 | } |
325 | 337 | ||
326 | 338 | ||
327 | static void ip22_check_gio(int slotno, unsigned long addr) | 339 | static void ip22_check_gio(int slotno, unsigned long addr, int irq) |
328 | { | 340 | { |
329 | const char *name = "Unknown"; | 341 | const char *name = "Unknown"; |
330 | struct gio_device *gio_dev; | 342 | struct gio_device *gio_dev; |
@@ -338,9 +350,9 @@ static void ip22_check_gio(int slotno, unsigned long addr) | |||
338 | else { | 350 | else { |
339 | if (!ip22_gio_id(addr, &tmp)) { | 351 | if (!ip22_gio_id(addr, &tmp)) { |
340 | /* | 352 | /* |
341 | * no GIO signature at start address of slot, but | 353 | * no GIO signature at start address of slot |
342 | * Newport doesn't have one, so let's check usea | 354 | * since Newport doesn't have one, we check if |
343 | * status register | 355 | * user status register is readable |
344 | */ | 356 | */ |
345 | if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp)) | 357 | if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp)) |
346 | tmp = 0x7e; | 358 | tmp = 0x7e; |
@@ -369,6 +381,7 @@ static void ip22_check_gio(int slotno, unsigned long addr) | |||
369 | gio_dev->resource.start = addr; | 381 | gio_dev->resource.start = addr; |
370 | gio_dev->resource.end = addr + 0x3fffff; | 382 | gio_dev->resource.end = addr + 0x3fffff; |
371 | gio_dev->resource.flags = IORESOURCE_MEM; | 383 | gio_dev->resource.flags = IORESOURCE_MEM; |
384 | gio_dev->irq = irq; | ||
372 | dev_set_name(&gio_dev->dev, "%d", slotno); | 385 | dev_set_name(&gio_dev->dev, "%d", slotno); |
373 | gio_device_register(gio_dev); | 386 | gio_device_register(gio_dev); |
374 | } else | 387 | } else |
@@ -408,16 +421,17 @@ int __init ip22_gio_init(void) | |||
408 | request_resource(&iomem_resource, &gio_bus_resource); | 421 | request_resource(&iomem_resource, &gio_bus_resource); |
409 | printk(KERN_INFO "GIO: Probing bus...\n"); | 422 | printk(KERN_INFO "GIO: Probing bus...\n"); |
410 | 423 | ||
411 | if (ip22_is_fullhouse() || | 424 | if (ip22_is_fullhouse()) { |
412 | !get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) { | 425 | /* Indigo2 */ |
413 | /* Indigo2 and ChallengeS */ | 426 | ip22_check_gio(0, GIO_SLOT_GFX_BASE, SGI_GIO_1_IRQ); |
414 | ip22_check_gio(0, GIO_SLOT_GFX_BASE); | 427 | ip22_check_gio(1, GIO_SLOT_EXP0_BASE, SGI_GIO_1_IRQ); |
415 | ip22_check_gio(1, GIO_SLOT_EXP0_BASE); | ||
416 | } else { | 428 | } else { |
417 | /* Indy */ | 429 | /* Indy/Challenge S */ |
418 | ip22_check_gio(0, GIO_SLOT_GFX_BASE); | 430 | if (get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) |
419 | ip22_check_gio(1, GIO_SLOT_EXP0_BASE); | 431 | ip22_check_gio(0, GIO_SLOT_GFX_BASE, |
420 | ip22_check_gio(2, GIO_SLOT_EXP1_BASE); | 432 | SGI_GIO_0_IRQ); |
433 | ip22_check_gio(1, GIO_SLOT_EXP0_BASE, SGI_GIOEXP0_IRQ); | ||
434 | ip22_check_gio(2, GIO_SLOT_EXP1_BASE, SGI_GIOEXP1_IRQ); | ||
421 | } | 435 | } |
422 | } else | 436 | } else |
423 | device_unregister(&gio_bus); | 437 | device_unregister(&gio_bus); |