static int __init sgi_button_devinit(void) { if (ip22_is_fullhouse()) return 0; /* */ return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0)); }
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; }
void __init sgihpc_init(void) { /* ioremap can't fail */ hpc3c0 = (struct hpc3_regs *) ioremap(HPC3_CHIP0_BASE, sizeof(struct hpc3_regs)); hpc3c1 = (struct hpc3_regs *) ioremap(HPC3_CHIP1_BASE, sizeof(struct hpc3_regs)); /* IOC lives in PBUS PIO channel 6 */ sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6]; hpc3c0->pbus_piocfg[6][0] |= HPC3_PIOCFG_DS16; if (ip22_is_fullhouse()) { /* Full House comes with INT2 which lives in PBUS PIO * channel 4 */ sgint = (struct sgint_regs *)hpc3c0->pbus_extregs[4]; system_type = "SGI Indigo2"; } else { /* Guiness comes with INT3 which is part of IOC */ sgint = &sgioc->int3; system_type = "SGI Indy"; } sgi_ioc_reset = (SGIOC_RESET_PPORT | SGIOC_RESET_KBDMOUSE | SGIOC_RESET_EISA | SGIOC_RESET_ISDN | SGIOC_RESET_LC0OFF); sgi_ioc_write = (SGIOC_WRITE_EASEL | SGIOC_WRITE_NTHRESH | SGIOC_WRITE_TPSPEED | SGIOC_WRITE_EPSEL | SGIOC_WRITE_U0AMODE | SGIOC_WRITE_U1AMODE); sgioc->reset = sgi_ioc_reset; sgioc->write = sgi_ioc_write; }
/* * Read specified register from main NVRAM */ unsigned short ip22_nvram_read(int reg) { if (ip22_is_fullhouse()) /* IP22 (Indigo2 aka FullHouse) stores env variables into * 93CS56 Microwire Bus EEPROM 2048 Bit (128x16) */ return ip22_eeprom_read(&hpc3c0->eeprom, reg); else { unsigned short tmp; /* IP24 (Indy aka Guiness) uses DS1386 8K version */ reg <<= 1; tmp = hpc3c0->bbram[reg++] & 0xff; return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff); } }
unsigned short ip22_nvram_read(int reg) { if (ip22_is_fullhouse()) /* */ return ip22_eeprom_read(&hpc3c0->eeprom, reg); else { unsigned short tmp; /* */ reg <<= 1; tmp = hpc3c0->bbram[reg++] & 0xff; return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff); } }
/* * Here we need to calibrate the cycle counter to at least be close. */ __init void plat_time_init(void) { unsigned long r4k_ticks[3]; unsigned long r4k_tick; /* * Figure out the r4k offset, the algorithm is very simple and works in * _all_ cases as long as the 8254 counter register itself works ok (as * an interrupt driving timer it does not because of bug, this is why * we are using the onchip r4k counter/compare register to serve this * purpose, but for r4k_offset calculation it will work ok for us). * There are other very complicated ways of performing this calculation * but this one works just fine so I am not going to futz around. ;-) */ printk(KERN_INFO "Calibrating system timer... "); dosample(); /* Prime cache. */ dosample(); /* Prime cache. */ /* Zero is NOT an option. */ do { r4k_ticks[0] = dosample(); } while (!r4k_ticks[0]); do { r4k_ticks[1] = dosample(); } while (!r4k_ticks[1]); if (r4k_ticks[0] != r4k_ticks[1]) { printk("warning: timer counts differ, retrying... "); r4k_ticks[2] = dosample(); if (r4k_ticks[2] == r4k_ticks[0] || r4k_ticks[2] == r4k_ticks[1]) r4k_tick = r4k_ticks[2]; else { printk("disagreement, using average... "); r4k_tick = (r4k_ticks[0] + r4k_ticks[1] + r4k_ticks[2]) / 3; } } else r4k_tick = r4k_ticks[0]; printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick, (int) (r4k_tick / (500000 / HZ)), (int) (r4k_tick % (500000 / HZ))); mips_hpt_frequency = r4k_tick * HZ; if (ip22_is_fullhouse()) setup_pit_timer(); }
/* * Create a platform device for the GPI port that receives the * image data from the embedded camera. */ static int __init sgiwd93_devinit(void) { int res; sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0; sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext; res = platform_device_register(&sgiwd93_0_device); if (res) return res; if (!ip22_is_fullhouse()) return 0; sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1; sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext; return platform_device_register(&sgiwd93_1_device); }
/* * 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); }
static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs) { unsigned int buttons; buttons = sgioc->panel; sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR; if (sgint->istat1 & SGINT_ISTAT1_PWR) { /* Wait until interrupt goes away */ disable_irq(SGI_PANEL_IRQ); init_timer(&debounce_timer); debounce_timer.function = debounce; debounce_timer.expires = jiffies + 5; add_timer(&debounce_timer); } /* Power button was pressed * ioc.ps page 22: "The Panel Register is called Power Control by Full * House. Only lowest 2 bits are used. Guiness uses upper four bits * for volume control". This is not true, all bits are pulled high * on fullhouse */ if (ip22_is_fullhouse() || !(buttons & SGIOC_PANEL_POWERINTR)) { power_button(); return IRQ_HANDLED; } /* TODO: mute/unmute */ /* Volume up button was pressed */ if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { init_timer(&volume_timer); volume_timer.function = volume_up_button; volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } /* Volume down button was pressed */ if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { init_timer(&volume_timer); volume_timer.function = volume_down_button; volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } return IRQ_HANDLED; }
void __init arch_init_irq(void) { int i; /* Init local mask --> irq tables. */ for (i = 0; i < 256; i++) { if (i & 0x80) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7; } else if (i & 0x40) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6; } else if (i & 0x20) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5; } else if (i & 0x10) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4; } else if (i & 0x08) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3; } else if (i & 0x04) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2; } else if (i & 0x02) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1; } else if (i & 0x01) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0; } else { lc0msk_to_irqnr[i] = 0; lc1msk_to_irqnr[i] = 0; lc2msk_to_irqnr[i] = 0; lc3msk_to_irqnr[i] = 0; } } /* Mask out all interrupts. */ sgint->imask0 = 0; sgint->imask1 = 0; sgint->cmeimask0 = 0; sgint->cmeimask1 = 0; /* init CPU irqs */ mips_cpu_irq_init(); for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { struct irq_chip *handler; if (i < SGINT_LOCAL1) handler = &ip22_local0_irq_type; else if (i < SGINT_LOCAL2) handler = &ip22_local1_irq_type; else if (i < SGINT_LOCAL3) handler = &ip22_local2_irq_type; else handler = &ip22_local3_irq_type; set_irq_chip_and_handler(i, handler, handle_level_irq); } /* vector handler. this register the IRQ as non-sharable */ setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade); setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade); setup_irq(SGI_BUSERR_IRQ, &buserr); /* cascade in cascade. i love Indy ;-) */ setup_irq(SGI_MAP_0_IRQ, &map0_cascade); #ifdef USE_LIO3_IRQ setup_irq(SGI_MAP_1_IRQ, &map1_cascade); #endif #ifdef CONFIG_EISA if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */ ip22_eisa_init(); #endif }
void __init sgimc_init(void) { u32 tmp; /* ioremap can't fail */ sgimc = (struct sgimc_regs *) ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); printk(KERN_INFO "MC: SGI memory controller Revision %d\n", (int) sgimc->systemid & SGIMC_SYSID_MASKREV); /* Place the MC into a known state. This must be done before * interrupts are first enabled etc. */ /* Step 0: Make sure we turn off the watchdog in case it's * still running (which might be the case after a * soft reboot). */ tmp = sgimc->cpuctrl0; tmp &= ~SGIMC_CCTRL0_WDOG; sgimc->cpuctrl0 = tmp; /* Step 1: The CPU/GIO error status registers will not latch * up a new error status until the register has been * cleared by the cpu. These status registers are * cleared by writing any value to them. */ sgimc->cstat = sgimc->gstat = 0; /* Step 2: Enable all parity checking in cpu control register * zero. */ /* don't touch parity settings for IP28 */ tmp = sgimc->cpuctrl0; #ifndef CONFIG_SGI_IP28 tmp |= SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM; #endif tmp |= SGIMC_CCTRL0_R4KNOCHKPARR; sgimc->cpuctrl0 = tmp; /* Step 3: Setup the MC write buffer depth, this is controlled * in cpu control register 1 in the lower 4 bits. */ tmp = sgimc->cpuctrl1; tmp &= ~0xf; tmp |= 0xd; sgimc->cpuctrl1 = tmp; /* Step 4: Initialize the RPSS divider register to run as fast * as it can correctly operate. The register is laid * out as follows: * * ---------------------------------------- * | RESERVED | INCREMENT | DIVIDER | * ---------------------------------------- * 31 16 15 8 7 0 * * DIVIDER determines how often a 'tick' happens, * INCREMENT determines by how the RPSS increment * registers value increases at each 'tick'. Thus, * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 */ sgimc->divider = 0x101; /* Step 5: Initialize GIO64 arbitrator configuration register. * * NOTE: HPC init code in sgihpc_init() must run before us because * we need to know Guiness vs. FullHouse and the board * revision on this machine. You have been warned. */ /* First the basic invariants across all GIO64 implementations. */ tmp = sgimc->giopar & SGIMC_GIOPAR_GFX64; /* keep gfx 64bit settings */ tmp |= SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */ tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */ if (ip22_is_fullhouse()) { /* Fullhouse specific settings. */ if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) { tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */ tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */ tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */ tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */ } else { tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */ tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */ tmp |= SGIMC_GIOPAR_PLINEEXP1; tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */ } } else { /* Guiness specific settings. */ tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */ } sgimc->giopar = tmp; /* poof */ probe_memory(); }
void __init init_IRQ(void) { int i; /* Init local mask --> irq tables. */ for (i = 0; i < 256; i++) { if (i & 0x80) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7; } else if (i & 0x40) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6; } else if (i & 0x20) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5; } else if (i & 0x10) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4; } else if (i & 0x08) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3; } else if (i & 0x04) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2; } else if (i & 0x02) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1; } else if (i & 0x01) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0; } else { lc0msk_to_irqnr[i] = 0; lc1msk_to_irqnr[i] = 0; lc2msk_to_irqnr[i] = 0; lc3msk_to_irqnr[i] = 0; } } /* Mask out all interrupts. */ sgint->imask0 = 0; sgint->imask1 = 0; sgint->cmeimask0 = 0; sgint->cmeimask1 = 0; set_except_vector(0, indyIRQ); init_generic_irq(); /* init CPU irqs */ mips_cpu_irq_init(SGINT_CPU); for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { hw_irq_controller *handler; if (i < SGINT_LOCAL1) handler = &ip22_local0_irq_type; else if (i < SGINT_LOCAL2) handler = &ip22_local1_irq_type; else if (i < SGINT_LOCAL3) handler = &ip22_local2_irq_type; else handler = &ip22_local3_irq_type; irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; irq_desc[i].handler = handler; } /* vector handler. this register the IRQ as non-sharable */ setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade); setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade); setup_irq(SGI_BUSERR_IRQ, &buserr); /* cascade in cascade. i love Indy ;-) */ setup_irq(SGI_MAP_0_IRQ, &map0_cascade); #ifdef USE_LIO3_IRQ setup_irq(SGI_MAP_1_IRQ, &map1_cascade); #endif #ifdef CONFIG_EISA if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */ ip22_eisa_init (); #endif }
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; }
void __init arch_init_irq(void) { int i; for (i = 0; i < 256; i++) { if (i & 0x80) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7; } else if (i & 0x40) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6; } else if (i & 0x20) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5; } else if (i & 0x10) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4; } else if (i & 0x08) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3; } else if (i & 0x04) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2; } else if (i & 0x02) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1; } else if (i & 0x01) { lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0; lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0; lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0; lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0; } else { lc0msk_to_irqnr[i] = 0; lc1msk_to_irqnr[i] = 0; lc2msk_to_irqnr[i] = 0; lc3msk_to_irqnr[i] = 0; } } sgint->imask0 = 0; sgint->imask1 = 0; sgint->cmeimask0 = 0; sgint->cmeimask1 = 0; mips_cpu_irq_init(); for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { struct irq_chip *handler; if (i < SGINT_LOCAL1) handler = &ip22_local0_irq_type; else if (i < SGINT_LOCAL2) handler = &ip22_local1_irq_type; else if (i < SGINT_LOCAL3) handler = &ip22_local2_irq_type; else handler = &ip22_local3_irq_type; irq_set_chip_and_handler(i, handler, handle_level_irq); } setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade); setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade); setup_irq(SGI_BUSERR_IRQ, &buserr); setup_irq(SGI_MAP_0_IRQ, &map0_cascade); #ifdef USE_LIO3_IRQ setup_irq(SGI_MAP_1_IRQ, &map1_cascade); #endif #ifdef CONFIG_EISA if (ip22_is_fullhouse()) ip22_eisa_init(); #endif }