static int __init ts102_uctrl_init(void) { struct uctrl_driver *driver = &drv; int len, i; struct linux_prom_irqs tmp_irq[2]; unsigned int vaddr[2] = { 0, 0 }; int tmpnode, uctrlnode = prom_getchild(prom_root_node); int err; tmpnode = prom_searchsiblings(uctrlnode, "obio"); if (tmpnode) uctrlnode = prom_getchild(tmpnode); uctrlnode = prom_searchsiblings(uctrlnode, "uctrl"); if (!uctrlnode) return -ENODEV; /* the prom mapped it for us */ len = prom_getproperty(uctrlnode, "address", (void *) vaddr, sizeof(vaddr)); driver->regs = (struct uctrl_regs *)vaddr[0]; len = prom_getproperty(uctrlnode, "intr", (char *) tmp_irq, sizeof(tmp_irq)); /* Flush device */ READUCTLDATA(len); if(!driver->irq) driver->irq = tmp_irq[0].pri; err = request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver); if (err) { printk("%s: unable to register irq %d\n", __FUNCTION__, driver->irq); return err; } if (misc_register(&uctrl_dev)) { printk("%s: unable to get misc minor %d\n", __FUNCTION__, uctrl_dev.minor); free_irq(driver->irq, driver); return -ENODEV; } driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK; printk("uctrl: 0x%p (irq %d)\n", driver->regs, driver->irq); uctrl_get_event_status(); uctrl_get_external_status(); return 0; }
static void uctrl_do_txn(struct uctrl_txn *txn) { struct uctrl_driver *driver = &drv; int stat, incnt, outcnt, bytecnt, intr; u32 byte; stat = driver->regs->uctrl_stat; intr = driver->regs->uctrl_intr; driver->regs->uctrl_stat = stat; dprintk(("interrupt stat 0x%x int 0x%x\n", stat, intr)); incnt = txn->inbits; outcnt = txn->outbits; byte = (txn->opcode << 8); WRITEUCTLDATA(byte); bytecnt = 0; while (incnt > 0) { byte = (txn->inbuf[bytecnt] << 8); WRITEUCTLDATA(byte); incnt--; bytecnt++; } /* Get the ack */ READUCTLDATA(byte); dprintk(("ack was %x\n", (byte >> 8))); bytecnt = 0; while (outcnt > 0) { READUCTLDATA(byte); txn->outbuf[bytecnt] = (byte >> 8); dprintk(("set byte to %02x\n", byte)); outcnt--; bytecnt++; } }