コード例 #1
0
ファイル: ll_temac_main.c プロジェクト: jay-caoj/linux-3.9.6
/**
 * temac_dcr_setup - If the DMA is DCR based, then setup the address and
 * I/O  functions
 */
static int temac_dcr_setup(struct temac_local *lp, struct platform_device *op,
                           struct device_node *np)
{
    unsigned int dcrs;

    /* setup the dcr address mapping if it's in the device tree */

    dcrs = dcr_resource_start(np, 0);
    if (dcrs != 0) {
        lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
        lp->dma_in = temac_dma_dcr_in;
        lp->dma_out = temac_dma_dcr_out;
        dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
        return 0;
    }
    /* no DCR in the device tree, indicate a failure */
    return -1;
}
コード例 #2
0
ファイル: nwpserial.c プロジェクト: 12rafael/jellytimekernel
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;
}
コード例 #3
0
static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
{
	struct ppc4xx_pciex_port *port;
	const u32 *pval;
	int portno;
	unsigned int dcrs;
	const char *val;

	/* First, proceed to core initialization as we assume there's
	 * only one PCIe core in the system
	 */
	if (ppc4xx_pciex_check_core_init(np))
		return;

	/* Get the port number from the device-tree */
	pval = of_get_property(np, "port", NULL);
	if (pval == NULL) {
		printk(KERN_ERR "PCIE: Can't find port number for %s\n",
		       np->full_name);
		return;
	}
	portno = *pval;
	if (portno >= ppc4xx_pciex_port_count) {
		printk(KERN_ERR "PCIE: port number out of range for %s\n",
		       np->full_name);
		return;
	}
	port = &ppc4xx_pciex_ports[portno];
	port->index = portno;

	/*
	 * Check if device is enabled
	 */
	if (!of_device_is_available(np)) {
		printk(KERN_INFO "PCIE%d: Port disabled via device-tree\n", port->index);
		return;
	}

	port->node = of_node_get(np);
	pval = of_get_property(np, "sdr-base", NULL);
	if (pval == NULL) {
		printk(KERN_ERR "PCIE: missing sdr-base for %s\n",
		       np->full_name);
		return;
	}
	port->sdr_base = *pval;

	/* Check if device_type property is set to "pci" or "pci-endpoint".
	 * Resulting from this setup this PCIe port will be configured
	 * as root-complex or as endpoint.
	 */
	val = of_get_property(port->node, "device_type", NULL);
	if (!strcmp(val, "pci-endpoint")) {
		port->endpoint = 1;
	} else if (!strcmp(val, "pci")) {
		port->endpoint = 0;
	} else {
		printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n",
		       np->full_name);
		return;
	}

	/* Fetch config space registers address */
	if (of_address_to_resource(np, 0, &port->cfg_space)) {
		printk(KERN_ERR "%s: Can't get PCI-E config space !",
		       np->full_name);
		return;
	}
	/* Fetch host bridge internal registers address */
	if (of_address_to_resource(np, 1, &port->utl_regs)) {
		printk(KERN_ERR "%s: Can't get UTL register base !",
		       np->full_name);
		return;
	}

	/* Map DCRs */
	dcrs = dcr_resource_start(np, 0);
	if (dcrs == 0) {
		printk(KERN_ERR "%s: Can't get DCR register base !",
		       np->full_name);
		return;
	}
	port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));

	/* Initialize the port specific registers */
	if (ppc4xx_pciex_port_init(port)) {
		printk(KERN_WARNING "PCIE%d: Port init failed\n", port->index);
		return;
	}

	/* Setup the linux hose data structure */
	ppc4xx_pciex_port_setup_hose(port);
}
コード例 #4
0
ファイル: nwpserial.c プロジェクト: 12rafael/jellytimekernel
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;
}
コード例 #5
0
ファイル: osif.c プロジェクト: EPiCS/reconos_v2
///
/// 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;
}