--- zzzz-none-000/linux-3.10.107/arch/mips/sgi-ip22/ip22-gio.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/mips/sgi-ip22/ip22-gio.c 2021-02-04 17:41:59.000000000 +0000 @@ -19,13 +19,22 @@ } gio_name_table[] = { { .name = "SGI Impact", .id = 0x10 }, { .name = "Phobos G160", .id = 0x35 }, + { .name = "Phobos G130", .id = 0x36 }, + { .name = "Phobos G100", .id = 0x37 }, + { .name = "Set Engineering GFE", .id = 0x38 }, /* fake IDs */ { .name = "SGI Newport", .id = 0x7e }, { .name = "SGI GR2/GR3", .id = 0x7f }, }; +static void gio_bus_release(struct device *dev) +{ + kfree(dev); +} + static struct device gio_bus = { .init_name = "gio", + .release = &gio_bus_release, }; /** @@ -143,28 +152,6 @@ return 0; } -static int gio_device_suspend(struct device *dev, pm_message_t state) -{ - struct gio_device *gio_dev = to_gio_device(dev); - struct gio_driver *drv = to_gio_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(gio_dev, state); - return error; -} - -static int gio_device_resume(struct device *dev) -{ - struct gio_device *gio_dev = to_gio_device(dev); - struct gio_driver *drv = to_gio_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(gio_dev); - return error; -} - static void gio_device_shutdown(struct device *dev) { struct gio_device *gio_dev = to_gio_device(dev); @@ -293,7 +280,16 @@ * data matches */ ptr8 = (void *)CKSEG1ADDR(addr + 3); - get_dbe(tmp8, ptr8); + if (get_dbe(tmp8, ptr8)) { + /* + * 32bit access worked, but 8bit doesn't + * so we don't see phantom reads on + * a pipelined bus, but a real card which + * doesn't support 8 bit reads + */ + *res = tmp32; + return 1; + } ptr16 = (void *)CKSEG1ADDR(addr + 2); get_dbe(tmp16, ptr16); if (tmp8 == (tmp16 & 0xff) && @@ -324,7 +320,7 @@ } -static void ip22_check_gio(int slotno, unsigned long addr) +static void ip22_check_gio(int slotno, unsigned long addr, int irq) { const char *name = "Unknown"; struct gio_device *gio_dev; @@ -338,9 +334,9 @@ else { if (!ip22_gio_id(addr, &tmp)) { /* - * no GIO signature at start address of slot, but - * Newport doesn't have one, so let's check usea - * status register + * no GIO signature at start address of slot + * since Newport doesn't have one, we check if + * user status register is readable */ if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp)) tmp = 0x7e; @@ -369,6 +365,7 @@ gio_dev->resource.start = addr; gio_dev->resource.end = addr + 0x3fffff; gio_dev->resource.flags = IORESOURCE_MEM; + gio_dev->irq = irq; dev_set_name(&gio_dev->dev, "%d", slotno); gio_device_register(gio_dev); } else @@ -381,8 +378,6 @@ .match = gio_bus_match, .probe = gio_device_probe, .remove = gio_device_remove, - .suspend = gio_device_suspend, - .resume = gio_device_resume, .shutdown = gio_device_shutdown, .uevent = gio_device_uevent, }; @@ -400,24 +395,27 @@ int ret; ret = device_register(&gio_bus); - if (ret) + if (ret) { + put_device(&gio_bus); return ret; + } ret = bus_register(&gio_bus_type); if (!ret) { request_resource(&iomem_resource, &gio_bus_resource); printk(KERN_INFO "GIO: Probing bus...\n"); - if (ip22_is_fullhouse() || - !get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) { - /* Indigo2 and ChallengeS */ - ip22_check_gio(0, GIO_SLOT_GFX_BASE); - ip22_check_gio(1, GIO_SLOT_EXP0_BASE); + if (ip22_is_fullhouse()) { + /* Indigo2 */ + ip22_check_gio(0, GIO_SLOT_GFX_BASE, SGI_GIO_1_IRQ); + ip22_check_gio(1, GIO_SLOT_EXP0_BASE, SGI_GIO_1_IRQ); } else { - /* Indy */ - ip22_check_gio(0, GIO_SLOT_GFX_BASE); - ip22_check_gio(1, GIO_SLOT_EXP0_BASE); - ip22_check_gio(2, GIO_SLOT_EXP1_BASE); + /* Indy/Challenge S */ + if (get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) + ip22_check_gio(0, GIO_SLOT_GFX_BASE, + SGI_GIO_0_IRQ); + ip22_check_gio(1, GIO_SLOT_EXP0_BASE, SGI_GIOEXP0_IRQ); + ip22_check_gio(2, GIO_SLOT_EXP1_BASE, SGI_GIOEXP1_IRQ); } } else device_unregister(&gio_bus);