static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, unsigned int offset, unsigned int size) { phys_addr_t phys_addr = dcr_resource_start(mpic->node, 0); rb->dhost = dcr_map(mpic->node, phys_addr + offset, size); BUG_ON(!DCR_MAP_OK(rb->dhost)); }
static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, unsigned int offset, unsigned int size) { rb->dbase = mpic->dcr_base; rb->doff = offset; rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size); BUG_ON(!DCR_MAP_OK(rb->dhost)); }
static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, unsigned int offset, unsigned int size) { const u32 *dbasep; dbasep = get_property(mpic->of_node, "dcr-reg", NULL); rb->dhost = dcr_map(mpic->of_node, *dbasep + offset, size); BUG_ON(!DCR_MAP_OK(rb->dhost)); }
static int __init nwpserial_console_init(void) { struct nwpserial_port *up = NULL; struct device_node *dn; const char *name; int dcr_base; int dcr_len; int i; /* search for a free port */ for (i = 0; i < NWPSERIAL_NR; i++) if (nwpserial_ports[i].port.type == PORT_UNKNOWN) { up = &nwpserial_ports[i]; break; } if (up == NULL) return -1; name = of_get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) return -1; dn = of_find_node_by_path(name); if (!dn) return -1; spin_lock_init(&up->port.lock); up->port.ops = &nwpserial_pops; up->port.type = PORT_NWPSERIAL; up->port.fifosize = 16; dcr_base = dcr_resource_start(dn, 0); dcr_len = dcr_resource_len(dn, 0); up->port.iobase = dcr_base; up->dcr_host = dcr_map(dn, dcr_base, dcr_len); if (!DCR_MAP_OK(up->dcr_host)) { printk("Cannot map DCR resources for SERIAL"); return -1; } register_console(&nwpserial_console); return 0; }
int nwpserial_register_port(struct uart_port *port) { struct nwpserial_port *up = NULL; int ret = -1; int i; static int first = 1; int dcr_len; int dcr_base; struct device_node *dn; mutex_lock(&nwpserial_mutex); dn = to_of_device(port->dev)->dev.of_node; if (dn == NULL) goto out; /* get dcr base. */ dcr_base = dcr_resource_start(dn, 0); /* find matching entry */ for (i = 0; i < NWPSERIAL_NR; i++) if (nwpserial_ports[i].port.iobase == dcr_base) { up = &nwpserial_ports[i]; break; } /* we didn't find a mtching entry, search for a free port */ if (up == NULL) for (i = 0; i < NWPSERIAL_NR; i++) if (nwpserial_ports[i].port.type == PORT_UNKNOWN && nwpserial_ports[i].port.iobase == 0) { up = &nwpserial_ports[i]; break; } if (up == NULL) { ret = -EBUSY; goto out; } if (first) uart_register_driver(&nwpserial_reg); first = 0; up->port.membase = port->membase; up->port.irq = port->irq; up->port.uartclk = port->uartclk; up->port.fifosize = port->fifosize; up->port.regshift = port->regshift; up->port.iotype = port->iotype; up->port.flags = port->flags; up->port.mapbase = port->mapbase; up->port.private_data = port->private_data; if (port->dev) up->port.dev = port->dev; if (up->port.iobase != dcr_base) { up->port.ops = &nwpserial_pops; up->port.fifosize = 16; spin_lock_init(&up->port.lock); up->port.iobase = dcr_base; dcr_len = dcr_resource_len(dn, 0); up->dcr_host = dcr_map(dn, dcr_base, dcr_len); if (!DCR_MAP_OK(up->dcr_host)) { printk(KERN_ERR "Cannot map DCR resources for NWPSERIAL"); goto out; } } ret = uart_add_one_port(&nwpserial_reg, &up->port); if (ret == 0) ret = up->port.line; out: mutex_unlock(&nwpserial_mutex); return ret; }
/// /// Probe device parameters from OF device tree /// /// This also involves allocating the osif_dev structs for our devices, and /// initializing them. /// int __devinit osif_of_probe( struct of_device *ofdev, const struct of_device_id *match) { struct osif_dev *osif_inst; struct resource r_irq_struct; struct resource *r_irq = &r_irq_struct; int start; int result = 0; PDEBUG("of_probe %s\n", ofdev->node->full_name); if(!strcmp(ofdev->node->name,"tlb")){ start = dcr_resource_start(ofdev->node, 0); PDEBUG("Found TLB @ %u\n", start); reconos_tlb_dcrn = start; return 0; } PDEBUG("probing IRQ\n"); // lookup interrupt number result = of_irq_to_resource(ofdev->node, 0, r_irq); if(result == NO_IRQ) { printk( KERN_WARNING "osif: no IRQ found.\n"); goto fail; } PDEBUG("IRQ = %lu\n", (unsigned long)r_irq->start); // allocate device data (TODO: does this need to be thread-safe?) osif_inst = kmalloc(sizeof(struct osif_dev), GFP_KERNEL); if (!osif_inst) { result = -ENOMEM; goto fail; /* Make this more graceful */ } memset(osif_inst, 0, sizeof(struct osif_dev)); PDEBUG("probing DCR\n"); // lookup dcr base address start = dcr_resource_start(ofdev->node, 0); osif_inst->dcr_len = dcr_resource_len(ofdev->node, 0); osif_inst->dcr_host = dcr_map(ofdev->node, start, osif_inst->dcr_len); if (!DCR_MAP_OK(osif_inst->dcr_host)) { printk( KERN_ERR "osif: invalid dcr address\n" ); result = -ENODEV; goto fail1; } PDEBUG("DCR from %u, len %u\n", start, osif_inst->dcr_len); // register device data with device dev_set_drvdata(&ofdev->dev, osif_inst); /* Initialize device data */ osif_inst->slot_num = osif_counter++; // FIXME: can we extract this from ofdev? // request interrupt result = request_irq(r_irq->start, osif_interrupt, 0, "osif", osif_inst); if (result) { printk(KERN_WARNING "osif: can't get assigned IRQ %lu\n", (unsigned long)r_irq->start); goto fail2; } osif_inst->irq = r_irq->start; osif_inst->next_read = 0; init_waitqueue_head(&osif_inst->read_queue); osif_inst->irq_count = 0; init_MUTEX(&osif_inst->sem); osif_setup_cdev(osif_inst, osif_inst->slot_num); // FIXME minor number // TODO: add to some kind of list for later reference? // or is the reference via the filp->private_data (in open()) and // the dev_set_drvdata() enough? return 0; fail2: dcr_unmap(osif_inst->dcr_host, osif_inst->dcr_len); fail1: kfree(osif_inst); fail: return result; }