Ejemplo n.º 1
0
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));
}
Ejemplo n.º 2
0
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));
}
Ejemplo n.º 3
0
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));
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
///
/// 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;
}