static int ip22_gio_id(unsigned long addr, u32 *res) { u8 tmp8; u8 tmp16; u32 tmp32; u8 *ptr8; u16 *ptr16; u32 *ptr32; ptr32 = (void *)CKSEG1ADDR(addr); if (!get_dbe(tmp32, ptr32)) { /* * We got no DBE, but this doesn't mean anything. * If GIO is pipelined (which can't be disabled * for GFX slot) we don't get a DBE, but we see * the transfer size as data. So we do an 8bit * and a 16bit access and check whether the common * data matches */ ptr8 = (void *)CKSEG1ADDR(addr + 3); get_dbe(tmp8, ptr8); ptr16 = (void *)CKSEG1ADDR(addr + 2); get_dbe(tmp16, ptr16); if (tmp8 == (tmp16 & 0xff) && tmp8 == (tmp32 & 0xff) && tmp16 == (tmp32 & 0xffff)) { *res = tmp32; return 1; } } return 0; /* nothing here */ }
static int config_access(int devfn, int where, int size, u32 *ptr, bool write) { unsigned long flags; int func = PCI_FUNC(devfn); int dev = PCI_SLOT(devfn); u32 value = 0; int err = 0; u32 addr; if (((dev != 0) && (dev != 3)) || (func > 2)) return PCIBIOS_DEVICE_NOT_FOUND; /* Select Configuration access */ local_irq_save(flags); ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); mb(); addr = (u32) configspace + (1 << (13 + dev)) + (func << 8) + where; if (size == 1) addr ^= 0x3; else if (size == 2) addr ^= 0x2; if (write) { value = *ptr; if (size == 1) err = put_dbe(value, (u8 *) addr); else if (size == 2) err = put_dbe(value, (u16 *) addr); else if (size == 4) err = put_dbe(value, (u32 *) addr); } else { if (size == 1) err = get_dbe(value, (u8 *) addr); else if (size == 2) err = get_dbe(value, (u16 *) addr); else if (size == 4) err = get_dbe(value, (u32 *) addr); if (err) *ptr = 0xffffffff; else *ptr = value; } /* Select Memory access */ ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, 0); local_irq_restore(flags); return (err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL); }
static inline uint ms02nv_probe_one(ulong addr) { ms02nv_uint *ms02nv_diagp; ms02nv_uint *ms02nv_magicp; uint ms02nv_diag; uint ms02nv_magic; size_t size; int err; /* * The firmware writes MS02NV_ID at MS02NV_MAGIC and also * a diagnostic status at MS02NV_DIAG. */ ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG)); ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC)); err = get_dbe(ms02nv_magic, ms02nv_magicp); if (err) return 0; if (ms02nv_magic != MS02NV_ID) return 0; ms02nv_diag = *ms02nv_diagp; size = (ms02nv_diag & MS02NV_DIAG_SIZE_MASK) << MS02NV_DIAG_SIZE_SHIFT; if (size > MS02NV_CSR) size = MS02NV_CSR; return size; }
int __init ip22_gio_init(void) { unsigned int pbdma __maybe_unused; int ret; ret = device_register(&gio_bus); 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()) { /* 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/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); return ret; }
int osl_busprobe(uint32 *val, uint32 addr) { #ifdef mips return get_dbe(*val, (uint32 *)addr); #else *val = readl((uint32 *)(uintptr)addr); return 0; #endif }
static int ip22_is_gr2(unsigned long addr) { u32 tmp; u32 *ptr; /* HQ2 only allows 32bit accesses */ ptr = (void *)CKSEG1ADDR(addr + HQ2_MYSTERY_OFFS); if (!get_dbe(tmp, ptr)) { if (tmp == 0xdeadbeef) return 1; } return 0; }
static int amazon_pci_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data) { unsigned long flags; u32 pci_addr; u32 val; int ret; /* Amazon support slot from 0 to 15 */ /* devfn 0 & 0x20 is itself */ if ((bus->number != 0) || (devfn > 0x7f) || (devfn == 0) || (devfn == 0x20)) return 1; local_irq_save(flags); pci_addr = AMAZON_PCI_CFG_BASE | bus->number << AMAZON_PCI_CFG_BUSNUM_SHF | devfn << AMAZON_PCI_CFG_FUNNUM_SHF | (where & ~0x3); if (access_type == PCI_ACCESS_WRITE) { #ifdef CONFIG_SWAP_IO_SPACE val = swab32(*data); #endif ret = put_dbe(val, (u32 *)pci_addr); } else { ret = get_dbe(val, (u32 *)pci_addr); #ifdef CONFIG_SWAP_IO_SPACE *data = swab32(val); #else *data = val; #endif } amazon_writel(amazon_readl(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE); amazon_writel(amazon_readl(STATUS_COMMAND_ADDR), STATUS_COMMAND_ADDR); amazon_writel(amazon_readl(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE); mb(); local_irq_restore(flags); if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ)) return 1; return ret; }
/* * Create a platform device for the GPI port that receives the * image data from the embedded camera. */ static int __init sgiseeq_devinit(void) { unsigned int tmp; int res, i; eth0_pd.hpc = hpc3c0; eth0_pd.irq = SGI_ENET_IRQ; #define EADDR_NVOFS 250 for (i = 0; i < 3; i++) { unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); eth0_pd.mac[2 * i] = tmp >> 8; eth0_pd.mac[2 * i + 1] = tmp & 0xff; } res = platform_device_register(ð0_device); if (res) return res; /* Second HPC is missing? */ if (!ip22_is_fullhouse() || get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1])) return 0; sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 | SGIMC_GIOPAR_HPC264; hpc3c1->pbus_piocfg[0][0] = 0x3ffff; /* interrupt/config register on Challenge S Mezz board */ hpc3c1->pbus_extregs[0][0] = 0x30; eth1_pd.hpc = hpc3c1; eth1_pd.irq = SGI_GIO_0_IRQ; #define EADDR_NVOFS 250 for (i = 0; i < 3; i++) { unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom, EADDR_NVOFS / 2 + i); eth1_pd.mac[2 * i] = tmp >> 8; eth1_pd.mac[2 * i + 1] = tmp & 0xff; } return platform_device_register(ð1_device); }
/* * Probing for TURBOchannel modules */ static void __init tc_probe(unsigned long startaddr, unsigned long size, int slots) { int i, slot, err; long offset; unsigned char pattern[4]; unsigned char *module; for (slot = 0; slot < slots; slot++) { module = (char *)(startaddr + slot * size); offset = OLDCARD; err = 0; err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0); err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1); err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2); err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3); if (err) continue; if (pattern[0] != 0x55 || pattern[1] != 0x00 || pattern[2] != 0xaa || pattern[3] != 0xff) { offset = NEWCARD; err = 0; err |= get_dbe(pattern[0], module + TC_PATTERN0); err |= get_dbe(pattern[1], module + TC_PATTERN1); err |= get_dbe(pattern[2], module + TC_PATTERN2); err |= get_dbe(pattern[3], module + TC_PATTERN3); if (err) continue; } if (pattern[0] != 0x55 || pattern[1] != 0x00 || pattern[2] != 0xaa || pattern[3] != 0xff) continue; tc_bus[slot].base_addr = (unsigned long)module; for(i = 0; i < 8; i++) { tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i]; tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i]; tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i]; } tc_bus[slot].firmware[8] = 0; tc_bus[slot].vendor[8] = 0; tc_bus[slot].name[8] = 0; /* * Looks unneccesary, but we may change * TC? in the future */ switch (slot) { case 0: tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0]; break; case 1: tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1]; break; case 2: tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2]; break; /* * Yuck! DS5000/200 onboard devices */ case 5: tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5]; break; case 6: tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6]; break; default: tc_bus[slot].interrupt = -1; break; } } }
int tc_preadb(u8 *valp, void __iomem *addr) { return get_dbe(*valp, (u8 *)addr); }
static int __init vino_init(void) { unsigned long rev; dma_addr_t dma; int i, ret = 0; /* VINO is Indy specific beast */ if (ip22_is_fullhouse()) return -ENODEV; /* * VINO is in the EISA address space, so the sysid register will tell * us if the EISA_PRESENT pin on MC has been pulled low. * * If EISA_PRESENT is not set we definitely don't have a VINO equiped * system. */ if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { printk(KERN_ERR "VINO not found\n"); return -ENODEV; } vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); if (!vino) return -EIO; /* Okay, once we know that VINO is present we'll read its revision * safe way. One never knows... */ if (get_dbe(rev, &(vino->rev_id))) { printk(KERN_ERR "VINO: failed to read revision register\n"); ret = -ENODEV; goto out_unmap; } if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) { printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev); ret = -ENODEV; goto out_unmap; } printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev)); Vino = (struct vino_video *) kmalloc(sizeof(struct vino_video), GFP_KERNEL); if (!Vino) { ret = -ENOMEM; goto out_unmap; } memset(Vino, 0, sizeof(struct vino_video)); Vino->dummy_desc = get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!Vino->dummy_desc) { ret = -ENOMEM; goto out_free_vino; } Vino->dummy_dma.cpu = pci_alloc_consistent(NULL, 4 * sizeof(dma_addr_t), &Vino->dummy_dma.dma); if (!Vino->dummy_dma.cpu) { ret = -ENOMEM; goto out_free_dummy_desc; } dma = pci_map_single(NULL, (void *)Vino->dummy_desc, PAGE_SIZE, PCI_DMA_FROMDEVICE); for (i = 0; i < 4; i++) Vino->dummy_dma.cpu[i] = dma; vino->control = 0; /* prevent VINO from throwing spurious interrupts */ vino->a.next_4_desc = Vino->dummy_dma.dma; vino->b.next_4_desc = Vino->dummy_dma.dma; udelay(5); vino->intr_status = 0; /* set threshold level */ vino->a.fifo_thres = threshold_a; vino->b.fifo_thres = threshold_b; spin_lock_init(&Vino->vino_lock); spin_lock_init(&Vino->input_lock); init_channel_data(&Vino->chA, VINO_CHAN_A); init_channel_data(&Vino->chB, VINO_CHAN_B); if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) { printk(KERN_ERR "VINO: request irq%02d failed\n", SGI_VINO_IRQ); ret = -EAGAIN; goto out_unmap_dummy_desc; } ret = vino_i2c_add_bus(); if (ret) { printk(KERN_ERR "VINO: I2C bus registration failed\n"); goto out_free_irq; } if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) { printk("%s, chnl %d: device registration failed.\n", Vino->chA.vdev.name, Vino->chA.chan); ret = -EINVAL; goto out_i2c_del_bus; } if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) { printk("%s, chnl %d: device registration failed.\n", Vino->chB.vdev.name, Vino->chB.chan); ret = -EINVAL; goto out_unregister_vdev; } #if defined(CONFIG_KMOD) && defined (MODULE) request_module("saa7191"); request_module("indycam"); #endif return 0; out_unregister_vdev: video_unregister_device(&Vino->chA.vdev); out_i2c_del_bus: vino_i2c_del_bus(); out_free_irq: free_irq(SGI_VINO_IRQ, NULL); out_unmap_dummy_desc: pci_unmap_single(NULL, Vino->dummy_dma.dma, PAGE_SIZE, PCI_DMA_FROMDEVICE); pci_free_consistent(NULL, 4 * sizeof(dma_addr_t), (void *)Vino->dummy_dma.cpu, Vino->dummy_dma.dma); out_free_dummy_desc: free_page(Vino->dummy_desc); out_free_vino: kfree(Vino); out_unmap: iounmap(vino); return ret; }