Beispiel #1
0
/* Probe for registered devices */
static int __devinit aes3_rx_of_probe(struct of_device *ofdev, const struct of_device_id *match)
{
  struct resource r_mem_struct    = {};
  struct resource r_irq_struct[2] = {};
  struct resource *addressRange   = &r_mem_struct;
  struct resource *irq            = r_irq_struct;
  struct resource *meter_irq      = &r_irq_struct[0];
  struct resource *aes_irq        = &r_irq_struct[1];
  struct platform_device *pdev    = to_platform_device(&ofdev->dev);
  const char *name = ofdev->node->name;
  int rc = 0;

  /* Obtain the resources for this instance */
  rc = of_address_to_resource(ofdev->node, 0, addressRange);
  if(rc) {
    printk(KERN_ERR "%s : No address found in device tree\n", name);
    return(rc);
  }

  rc = of_irq_to_resource(ofdev->node, 0, meter_irq);
  if(rc == NO_IRQ) {
    printk(KERN_ERR "%s : No metering IRQ found in device tree\n", name);
    return(rc);
  }

  rc = of_irq_to_resource(ofdev->node, 1, aes_irq);
  if(rc == NO_IRQ) {
    printk(KERN_ERR "%s : No channel IRQ found in device tree\n", name);
    return(rc);
  }

  /* Dispatch to the generic function */
  return(aes3_rx_probe(name, pdev, addressRange, irq, NULL, NULL, NULL));
}
static inline int mscan_get_config(unsigned long *addr, unsigned int *irq)
{
#if defined(CONFIG_PPC_MERGE) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)
	/* Use Open Firmware device tree */
	struct device_node *np = NULL;
	unsigned int i;
	int ret;

	for (i = 0; i < RTCAN_MSCAN_DEVS; i++) {
		struct resource r[2] = {};

		np = of_find_compatible_node(np, NULL, "fsl,mpc5200-mscan");
		if (np == NULL)
			np = of_find_compatible_node(np, NULL, "mpc5200-mscan");
		if (np == NULL)
			break;
		ret = of_address_to_resource(np, 0, &r[0]);
		if (ret)
			return ret;
		of_irq_to_resource(np, 0, &r[1]);
		addr[i] = r[0].start;
		irq[i] = r[1].start;
		rtcan_mscan_count++;
	}
#else
	addr[0] = MSCAN_CAN1_ADDR;
	irq[0] = MSCAN_CAN1_IRQ;
	addr[1] = MSCAN_CAN2_ADDR;
	irq[1] = MSCAN_CAN2_IRQ;
	rtcan_mscan_count = 2;
#endif
	return 0;
}
Beispiel #3
0
/* Probe for registered devices */
static int __devinit mailbox_of_probe(struct of_device *ofdev, const struct of_device_id *match)
{
  struct resource r_mem_struct = {};
  struct resource r_irq_struct = {};
  struct resource *addressRange = &r_mem_struct;
  struct resource *irq          = &r_irq_struct;
  struct platform_device *pdev  = to_platform_device(&ofdev->dev);
  const char *name = dev_name(&ofdev->dev);
  int rc = 0;

  /* Obtain the resources for this instance */
  rc = of_address_to_resource(ofdev->node, 0, addressRange);
  if(rc) {
    dev_warn(&ofdev->dev, "Invalid address\n");
    return(rc);
  }

  rc = of_irq_to_resource(ofdev->node, 0, irq);
  if(rc == NO_IRQ) {
    /* No IRQ was defined; null the resource pointer to indicate polled mode */
    irq = NULL;
    return(rc);
  }

  /* Dispatch to the generic function */
  return(mailbox_probe(name, pdev, addressRange, irq));
}
static int __devinit xilinx_iic_of_probe(struct platform_device *ofdev, const struct of_device_id *match)
{
	u32 ten_bit_addr, gpo_width;
	struct resource r_irq_struct;
	struct resource r_mem_struct;

	struct resource *r_irq = &r_irq_struct;	/* Interrupt resources */
	struct resource *r_mem = &r_mem_struct;	/* IO mem resources */
	int rc = 0;

	printk(KERN_INFO "Device Tree Probing \'%s\'\n",
                        ofdev->dev.of_node->name);

	/* Get iospace for the device */
	rc = of_address_to_resource(ofdev->dev.of_node, 0, r_mem);
	if(rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		return rc;
	}

	/* Get IRQ for the device */
	rc = of_irq_to_resource(ofdev->dev.of_node, 0, r_irq);
	if(!rc) {
		dev_warn(&ofdev->dev, "no IRQ found.\n");
		return rc;
	}

	ten_bit_addr = get_u32(ofdev, "xlnx,ten-bit-adr");
	gpo_width = get_u32(ofdev, "xlnx,gpo-width");

        return xilinx_iic_setup(&ofdev->dev, ofdev->dev.of_node, r_mem, r_irq, ten_bit_addr, gpo_width);
}
Beispiel #5
0
static int __devinit xps2_of_probe(struct of_device *ofdev, const struct of_device_id *match)
{
	struct resource r_irq_struct;
	struct resource r_mem_struct;
	struct resource *r_irq = &r_irq_struct;	/* Interrupt resources */
	struct resource *r_mem = &r_mem_struct;	/* IO mem resources */
	int rc = 0;
	const unsigned int *id;

	printk(KERN_INFO "Device Tree Probing \'%s\'\n",
                        ofdev->node->name);

	/* Get iospace for the device */
	rc = of_address_to_resource(ofdev->node, 0, r_mem);
	if(rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		return rc;
	}

	/* Get IRQ for the device */
	rc = of_irq_to_resource(ofdev->node, 0, r_irq);
	if(rc == NO_IRQ) {
		dev_warn(&ofdev->dev, "no IRQ found.\n");
		return rc;
	}

	id = of_get_property(ofdev->node, "port-number", NULL);
        return xps2_setup(&ofdev->dev, id ? *id : -1, r_mem, r_irq);
}
static inline int mscan_get_config(unsigned long *addr, unsigned int *irq)
{
	/* Use Open Firmware device tree */
	struct device_node *np = NULL;
	unsigned int i;
	int ret;

	for (i = 0; i < RTCAN_MSCAN_DEVS; i++) {
		struct resource r[2] = {};

		np = of_find_compatible_node(np, NULL, "fsl,mpc5200-mscan");
		if (np == NULL)
			np = of_find_compatible_node(np, NULL, "mpc5200-mscan");
		if (np == NULL)
			break;
		ret = of_address_to_resource(np, 0, &r[0]);
		if (ret)
			return ret;
		of_irq_to_resource(np, 0, &r[1]);
		addr[i] = r[0].start;
		irq[i] = r[1].start;
		rtcan_mscan_count++;
	}
	return 0;
}
static int wsa_map_irq(struct wsa_resource *wsa_res, int irq)
{
	if (wsa_res == NULL) {
		pr_err("%s: wsa_res is NULL\n", __func__);
		return -EINVAL;
	}
	return of_irq_to_resource(wsa_res->dev->of_node, irq, NULL);
}
Beispiel #8
0
int of_irq_count(struct device_node *dev)
{
	int nr = 0;

	while (of_irq_to_resource(dev, nr, NULL))
		nr++;

	return nr;
}
/**
 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
 * @dev: pointer to device tree node
 * @res: array of resources to fill in
 * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
 *
 * Returns the size of the filled in table (up to @nr_irqs).
 */
int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
		int nr_irqs)
{
	int i;

	for (i = 0; i < nr_irqs; i++, res++)
		if (!of_irq_to_resource(dev, i, res))
			break;

	return i;
}
Beispiel #10
0
static int __init fsl_i2c_of_init(void)
{
	struct device_node *np;
	unsigned int i;
	struct platform_device *i2c_dev;
	int ret;

	for (np = NULL, i = 0;
	     (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
	     i++) {
		struct resource r[2];
		struct fsl_i2c_platform_data i2c_data;
		const unsigned char *flags = NULL;

		memset(&r, 0, sizeof(r));
		memset(&i2c_data, 0, sizeof(i2c_data));

		ret = of_address_to_resource(np, 0, &r[0]);
		if (ret)
			goto err;

		of_irq_to_resource(np, 0, &r[1]);

		i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
		if (IS_ERR(i2c_dev)) {
			ret = PTR_ERR(i2c_dev);
			goto err;
		}

		i2c_data.device_flags = 0;
		flags = of_get_property(np, "dfsrr", NULL);
		if (flags)
			i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;

		flags = of_get_property(np, "fsl5200-clocking", NULL);
		if (flags)
			i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;

		ret =
		    platform_device_add_data(i2c_dev, &i2c_data,
					     sizeof(struct
						    fsl_i2c_platform_data));
		if (ret)
			goto unreg;
	}

	return 0;

unreg:
	platform_device_unregister(i2c_dev);
err:
	return ret;
}
static int __devinit xilinx_spi_of_probe(struct of_device *ofdev,
	const struct of_device_id *match)
{
	struct spi_master *master;
	struct xspi_platform_data *pdata;
	struct resource r_mem;
	struct resource r_irq;
	int rc = 0;
	const u32 *prop;
	int len;

	rc = of_address_to_resource(ofdev->node, 0, &r_mem);
	if (rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		return rc;
	}

	rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
	if (rc == NO_IRQ) {
		dev_warn(&ofdev->dev, "no IRQ found\n");
		return -ENODEV;
	}

	ofdev->dev.platform_data =
		kzalloc(sizeof(struct xspi_platform_data), GFP_KERNEL);
	pdata = ofdev->dev.platform_data;
	if (!pdata)
		return -ENOMEM;

	/* number of slave select bits is required */
	prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
	if (!prop || len < sizeof(*prop)) {
		dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
		return -EINVAL;
	}
	pdata->num_chipselect = *prop;
	pdata->bits_per_word = 8;
	master = xilinx_spi_init(&ofdev->dev, &r_mem, r_irq.start, -1);
	if (!master)
		return -ENODEV;

	dev_set_drvdata(&ofdev->dev, master);

	/* Add any subnodes on the SPI bus */
	of_register_spi_devices(master, ofdev->node);

	return 0;
}
static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
{
	const u32 *data;
	int len, id, irq;

	data = of_get_property(np, "reg", &len);
	if (!data || len != 4)
		return;

	id = *data;
	bus->phy_mask &= ~(1 << id);

	irq = of_irq_to_resource(np, 0, NULL);
	if (irq != NO_IRQ)
		bus->irq[id] = irq;
}
static int do_pd_setup(struct fs_enet_private *fep)
{
	struct of_device *ofdev = to_of_device(fep->dev);

	fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
	if (fep->interrupt == NO_IRQ)
		return -EINVAL;

	fep->scc.sccp = of_iomap(ofdev->node, 0);
	if (!fep->scc.sccp)
		return -EINVAL;

	fep->scc.ep = of_iomap(ofdev->node, 1);
	if (!fep->scc.ep) {
		iounmap(fep->scc.sccp);
		return -EINVAL;
	}

	return 0;
}
Beispiel #14
0
static int do_pd_setup(struct fs_enet_private *fep)
{
	struct of_device *ofdev = to_of_device(fep->dev);
	struct fs_platform_info *fpi = fep->fpi;
	int ret = -EINVAL;

	fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
	if (fep->interrupt == NO_IRQ)
		goto out;

	fep->fcc.fccp = of_iomap(ofdev->node, 0);
	if (!fep->fcc.fccp)
		goto out;

	fep->fcc.ep = of_iomap(ofdev->node, 1);
	if (!fep->fcc.ep)
		goto out_fccp;

	fep->fcc.fcccp = of_iomap(ofdev->node, 2);
	if (!fep->fcc.fcccp)
		goto out_ep;

	fep->fcc.mem = (void __iomem *)cpm2_immr;
	fpi->dpram_offset = cpm_dpalloc(128, 8);
	if (IS_ERR_VALUE(fpi->dpram_offset)) {
		ret = fpi->dpram_offset;
		goto out_fcccp;
	}

	return 0;

out_fcccp:
	iounmap(fep->fcc.fcccp);
out_ep:
	iounmap(fep->fcc.ep);
out_fccp:
	iounmap(fep->fcc.fccp);
out:
	return ret;
}
static int __devinit xps2_of_probe(struct platform_device *ofdev)
{
	struct resource r_irq; 
	struct resource r_mem; 
	struct xps2data *drvdata;
	struct serio *serio;
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
			ofdev->dev.of_node->name);

	
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}

	
	if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) {
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	if (!drvdata) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}

	dev_set_drvdata(dev, drvdata);

	spin_lock_init(&drvdata->lock);
	drvdata->irq = r_irq.start;

	phys_addr = r_mem.start;
	remap_size = resource_size(&r_mem);
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
		goto failed1;
	}

	
	drvdata->base_address = ioremap(phys_addr, remap_size);
	if (drvdata->base_address == NULL) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
		goto failed2;
	}

	
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);

	serio = &drvdata->serio;
	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
	snprintf(serio->phys, sizeof(serio->phys),
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

	serio_register_port(serio);

	return 0;		

failed2:
	release_mem_region(phys_addr, remap_size);
failed1:
	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return error;
}
Beispiel #16
0
/*
 * Probe routine for each detected JobR subsystem. It assumes that
 * property detection was picked up externally.
 */
int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
		  int ring)
{
	struct device *ctrldev, *jrdev;
	struct platform_device *jr_pdev;
	struct caam_drv_private *ctrlpriv;
	struct caam_drv_private_jr *jrpriv;
	int error;
	/* FIXME: perhaps "struct resource *" for OF and non? */
	u32 *jroffset, *irqres;
#ifndef CONFIG_OF
	char *rname, rinst;
#endif

	ctrldev = &pdev->dev;
	ctrlpriv = dev_get_drvdata(ctrldev);

	jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
			 GFP_KERNEL);
	if (jrpriv == NULL) {
		dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
			ring);
		return -ENOMEM;
	}
	jrpriv->parentdev = ctrldev; /* point back to parent */
	jrpriv->ridx = ring; /* save ring identity relative to detection */

	/*
	 * Derive a pointer to the detected JobRs regs
	 * Driver has already iomapped the entire space, we just
	 * need to add in the offset to this JobR. Don't know if I
	 * like this long-term, but it'll run
	 */
#ifdef CONFIG_OF
	jroffset = (u32 *)of_get_property(np, "reg", NULL);
#else
	rname = kmalloc(strlen(JR_MEMRES_NAME_ROOT) + 1, 0);
	if (rname == NULL) {
		dev_err(ctrldev, "can't alloc resource detection buffer %d\n",
			ring);
		kfree(jrpriv);
		return -ENOMEM;
	}
	rname[0] = 0;
	rinst = '0' + ring;
	strcat(rname, JR_MEMRES_NAME_ROOT);
	strncat(rname, &rinst, 1);
	jroffset = (u32 *)platform_get_resource_byname(pdev, IORESOURCE_MEM,
						       rname);
	kfree(rname);
#endif
	jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
							 + *jroffset);

	/* Build a local dev for each detected queue */
#ifdef CONFIG_OF
	jr_pdev = of_platform_device_create(np, NULL, ctrldev);
#else
	jr_pdev = platform_device_register_data(ctrldev, "caam_jr", ring,
						jrpriv,
					sizeof(struct caam_drv_private_jr));
#endif
	if (jr_pdev == NULL) {
		kfree(jrpriv);
		return -EINVAL;
	}
	jrdev = &jr_pdev->dev;
	dev_set_drvdata(jrdev, jrpriv);
	ctrlpriv->jrdev[ring] = jrdev;

	/* Identify the interrupt */
#ifdef CONFIG_OF
	jrpriv->irq = of_irq_to_resource(np, 0, NULL);
#else
	rname = kmalloc(strlen(JR_IRQRES_NAME_ROOT) + 1, 0);
	if (rname == NULL) {
		dev_err(ctrldev, "can't alloc resource detection buffer %d\n",
			ring);
		kfree(jrpriv);
		return -ENOMEM;
	}
	rname[0] = 0;
	strcat(rname, JR_IRQRES_NAME_ROOT);
	strncat(rname, &rinst, 1);
	irqres = (u32 *)platform_get_resource_byname(pdev, IORESOURCE_IRQ,
						     rname);
	jrpriv->irq = *irqres;
	kfree(rname);
#endif

	/* Now do the platform independent part */
	error = caam_jr_init(jrdev); /* now turn on hardware */
	if (error) {
		kfree(jrpriv);
		return error;
	}

	return error;
}
Beispiel #17
0
static int cpm_uart_init_port(struct device_node *np,
                              struct uart_cpm_port *pinfo)
{
	const u32 *data;
	void __iomem *mem, *pram;
	int len;
	int ret;
	int i;

	data = of_get_property(np, "clock", NULL);
	if (data) {
		struct clk *clk = clk_get(NULL, (const char*)data);
		if (!IS_ERR(clk))
			pinfo->clk = clk;
	}
	if (!pinfo->clk) {
		data = of_get_property(np, "fsl,cpm-brg", &len);
		if (!data || len != 4) {
			printk(KERN_ERR "CPM UART %s has no/invalid "
			                "fsl,cpm-brg property.\n", np->name);
			return -EINVAL;
		}
		pinfo->brg = *data;
	}

	data = of_get_property(np, "fsl,cpm-command", &len);
	if (!data || len != 4) {
		printk(KERN_ERR "CPM UART %s has no/invalid "
		                "fsl,cpm-command property.\n", np->name);
		return -EINVAL;
	}
	pinfo->command = *data;

	mem = of_iomap(np, 0);
	if (!mem)
		return -ENOMEM;

	if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") ||
	    of_device_is_compatible(np, "fsl,cpm2-scc-uart")) {
		pinfo->sccp = mem;
		pinfo->sccup = pram = cpm_uart_map_pram(pinfo, np);
	} else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") ||
	           of_device_is_compatible(np, "fsl,cpm2-smc-uart")) {
		pinfo->flags |= FLAG_SMC;
		pinfo->smcp = mem;
		pinfo->smcup = pram = cpm_uart_map_pram(pinfo, np);
	} else {
		ret = -ENODEV;
		goto out_mem;
	}

	if (!pram) {
		ret = -ENOMEM;
		goto out_mem;
	}

	pinfo->tx_nrfifos = TX_NUM_FIFO;
	pinfo->tx_fifosize = TX_BUF_SIZE;
	pinfo->rx_nrfifos = RX_NUM_FIFO;
	pinfo->rx_fifosize = RX_BUF_SIZE;

	pinfo->port.uartclk = ppc_proc_freq;
	pinfo->port.mapbase = (unsigned long)mem;
	pinfo->port.type = PORT_CPM;
	pinfo->port.ops = &cpm_uart_pops,
	pinfo->port.iotype = UPIO_MEM;
	pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize;
	spin_lock_init(&pinfo->port.lock);

	pinfo->port.irq = of_irq_to_resource(np, 0, NULL);
	if (pinfo->port.irq == NO_IRQ) {
		ret = -EINVAL;
		goto out_pram;
	}

	for (i = 0; i < NUM_GPIOS; i++)
		pinfo->gpios[i] = of_get_gpio(np, i);

	return cpm_uart_request_port(&pinfo->port);

out_pram:
	cpm_uart_unmap_pram(pinfo, pram);
out_mem:
	iounmap(mem);
	return ret;
}
static int wcd9xxx_map_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq)
{
	return of_irq_to_resource(wcd9xxx_res->dev->of_node, irq, NULL);
}
Beispiel #19
0
static int __init cpm_uart_of_init(void)
{
	struct device_node *np;
	unsigned int i;
	struct platform_device *cpm_uart_dev;
	int ret;

	for (np = NULL, i = 0;
	     (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
	     i++) {
		struct resource r[3];
		struct fs_uart_platform_info cpm_uart_data;
		const int *id;
		const char *model;

		memset(r, 0, sizeof(r));
		memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));

		ret = of_address_to_resource(np, 0, &r[0]);
		if (ret)
			goto err;

		r[0].name = scc_regs;

		ret = of_address_to_resource(np, 1, &r[1]);
		if (ret)
			goto err;
		r[1].name = scc_pram;

		of_irq_to_resource(np, 0, &r[2]);

		cpm_uart_dev =
		    platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);

		if (IS_ERR(cpm_uart_dev)) {
			ret = PTR_ERR(cpm_uart_dev);
			goto err;
		}

		id = of_get_property(np, "device-id", NULL);
		cpm_uart_data.fs_no = *id;

		model = of_get_property(np, "model", NULL);
		strcpy(cpm_uart_data.fs_type, model);

		cpm_uart_data.uart_clk = ppc_proc_freq;

		cpm_uart_data.tx_num_fifo = 4;
		cpm_uart_data.tx_buf_size = 32;
		cpm_uart_data.rx_num_fifo = 4;
		cpm_uart_data.rx_buf_size = 32;
		cpm_uart_data.clk_rx = *((u32 *)of_get_property(np,
						"rx-clock", NULL));
		cpm_uart_data.clk_tx = *((u32 *)of_get_property(np,
						"tx-clock", NULL));

		ret =
		    platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
					     sizeof(struct
						    fs_uart_platform_info));
		if (ret)
			goto unreg;
	}

	return 0;

unreg:
	platform_device_unregister(cpm_uart_dev);
err:
	return ret;
}
Beispiel #20
0
static int __init mv64x60_eth_device_setup(struct device_node *np, int id)
{
	struct resource r[1];
	struct mv643xx_eth_platform_data pdata;
	struct platform_device *pdev;
	struct device_node *phy;
	const u8 *mac_addr;
	const int *prop;
	const phandle *ph;
	int err;

	/* only register the shared platform device the first time through */
	if (id == 0 && (err = eth_register_shared_pdev(np)))
		return err;;

	memset(r, 0, sizeof(r));
	of_irq_to_resource(np, 0, &r[0]);

	memset(&pdata, 0, sizeof(pdata));

	prop = of_get_property(np, "block-index", NULL);
	if (!prop)
		return -ENODEV;
	pdata.port_number = *prop;

	mac_addr = of_get_mac_address(np);
	if (mac_addr)
		memcpy(pdata.mac_addr, mac_addr, 6);

	prop = of_get_property(np, "speed", NULL);
	if (prop)
		pdata.speed = *prop;

	prop = of_get_property(np, "tx_queue_size", NULL);
	if (prop)
		pdata.tx_queue_size = *prop;

	prop = of_get_property(np, "rx_queue_size", NULL);
	if (prop)
		pdata.rx_queue_size = *prop;

	prop = of_get_property(np, "tx_sram_addr", NULL);
	if (prop)
		pdata.tx_sram_addr = *prop;

	prop = of_get_property(np, "tx_sram_size", NULL);
	if (prop)
		pdata.tx_sram_size = *prop;

	prop = of_get_property(np, "rx_sram_addr", NULL);
	if (prop)
		pdata.rx_sram_addr = *prop;

	prop = of_get_property(np, "rx_sram_size", NULL);
	if (prop)
		pdata.rx_sram_size = *prop;

	ph = of_get_property(np, "phy", NULL);
	if (!ph)
		return -ENODEV;

	phy = of_find_node_by_phandle(*ph);
	if (phy == NULL)
		return -ENODEV;

	prop = of_get_property(phy, "reg", NULL);
	if (prop) {
		pdata.force_phy_addr = 1;
		pdata.phy_addr = *prop;
	}

	of_node_put(phy);

	pdev = platform_device_alloc(MV643XX_ETH_NAME, pdata.port_number);
	if (!pdev)
		return -ENOMEM;

	err = platform_device_add_resources(pdev, r, 1);
	if (err)
		goto error;

	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
	if (err)
		goto error;

	err = platform_device_add(pdev);
	if (err)
		goto error;

	return 0;

error:
	platform_device_put(pdev);
	return err;
}
/*####modified for marvell-bg2*/
static int drv_get_dts_for_gpu(void)
{
    struct device_node *np;
    struct resource res;
    int rc = 0;
    u32 value;

    /* get the gpu3d information */
    np = of_find_compatible_node(NULL, NULL, "marvell,berlin-gpu3d");
    if (!np)
    {
        printk("gpu error: of_find_compatible_node for berlin-gpu3d failed!\n");
        goto err_exit;
    }

    /* get the reg section */
    rc = of_address_to_resource(np, 0, &res);
    if (rc)
    {
        printk("gpu warning: of_address_to_resource for berlin-gpu3d failed!\n");
    }
    else
    {
        registerMemBase = res.start;
        registerMemSize = resource_size(&res);
    }

    /* get the interrupt section */
    rc = of_irq_to_resource(np, 0, &res);
    if (!rc)
    {
        printk("gpu warning: of_irq_to_resource for berlin-gpu3d failed, rc=%d!\n", rc);
    }
    else
    {
        irqLine = rc;
    }

    /* get the nonsecure-mem-base section */
    rc = of_property_read_u32(np, "marvell,nonsecure-mem-base", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for nonsecure-mem-base failed!\n");
    }
    else
    {
        contiguousBase = value;
    }

    /* get the nonsecure-mem-size section */
    rc = of_property_read_u32(np, "marvell,nonsecure-mem-size", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for nonsecure-mem-size failed!\n");
    }
    else
    {
        contiguousSize = value;
    }

    /* get the phy-mem-size section */
    rc = of_property_read_u32(np, "marvell,phy-mem-size", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for phy-mem-size failed!\n");
    }
    else
    {
        physSize = value;
    }

    /* get the 3D clock registers and corresponding bitfields */
    rc = of_property_read_u32(np, "marvell,core-clock-register", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for 3D core-clock-register failed!\n");
        coreClkRegister3D = 0;
    }
    else
    {
        coreClkRegister3D = value;
    }

    rc = of_property_read_u32(np, "marvell,sys-clock-register", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for 3D sys-clock-register failed!\n");
        sysClkRegister3D = 0;
    }
    else
    {
        sysClkRegister3D = value;
    }

    rc = of_property_read_u32(np, "marvell,core-clock-bitfield", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for 3D core-clock-bitfield failed!\n");
        coreClkBitfield3D = 0;
    }
    else
    {
        coreClkBitfield3D = value;
    }

    rc = of_property_read_u32(np, "marvell,sys-clock-bitfield", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for 3D sys-clock-bitfield failed!\n");
        sysClkBitfield3D = 0;
    }
    else
    {
        sysClkBitfield3D = value;
    }

    of_node_put(np);

    /* get the gpu2d information */
    np = of_find_compatible_node(NULL, NULL, "marvell,berlin-gpu2d");
    if (!np)
    {
        /* no 2d gpu, just goto exit */
        goto err_exit;
    }

    /* get the reg section */
    rc = of_address_to_resource(np, 0, &res);
    if (rc)
    {
        printk("gpu warning: of_address_to_resource for berlin-gpu2d failed!\n");
    }
    else
    {
        registerMemBase2D = res.start;
        registerMemSize2D = resource_size(&res);
    }

    /* get the interrupt section */
    rc = of_irq_to_resource(np, 0, &res);
    if (!rc)
    {
        printk("gpu warning: of_irq_to_resource for berlin-gpu2d failed!\n");
    }
    else
    {
        irqLine2D = rc;
    }

    /* get 2D core clock register and corresponding bitfield */
    rc = of_property_read_u32(np, "marvell,core-clock-register", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for 2D core-clock-register failed!\n");
        coreClkRegister2D = 0;
    }
    else
    {
        coreClkRegister2D = value;
    }

    rc = of_property_read_u32(np, "marvell,core-clock-bitfield", &value);
    if (rc)
    {
        printk("gpu warning: of_property_read_u32 for 2D core-clock-bitfield failed!\n");
        coreClkBitfield2D = 0;
    }
    else
    {
        coreClkBitfield2D = value;
    }

    of_node_put(np);

    return 0;

err_exit:
    return -1;
}
Beispiel #22
0
static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
{
	struct resource r[5];
	struct mpsc_pdata pdata;
	struct platform_device *pdev;
	const unsigned int *prop;
	const phandle *ph;
	struct device_node *sdma, *brg;
	int err;
	int port_number;

	/* only register the shared platform device the first time through */
	if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
		return err;

	memset(r, 0, sizeof(r));

	err = of_address_to_resource(np, 0, &r[0]);
	if (err)
		return err;

	of_irq_to_resource(np, 0, &r[4]);

	ph = of_get_property(np, "sdma", NULL);
	sdma = of_find_node_by_phandle(*ph);
	if (!sdma)
		return -ENODEV;

	of_irq_to_resource(sdma, 0, &r[3]);
	err = of_address_to_resource(sdma, 0, &r[1]);
	of_node_put(sdma);
	if (err)
		return err;

	ph = of_get_property(np, "brg", NULL);
	brg = of_find_node_by_phandle(*ph);
	if (!brg)
		return -ENODEV;

	err = of_address_to_resource(brg, 0, &r[2]);
	of_node_put(brg);
	if (err)
		return err;

	prop = of_get_property(np, "block-index", NULL);
	if (!prop)
		return -ENODEV;
	port_number = *(int *)prop;

	memset(&pdata, 0, sizeof(pdata));

	pdata.cache_mgmt = 1; /* All current revs need this set */

	prop = of_get_property(np, "max_idle", NULL);
	if (prop)
		pdata.max_idle = *prop;

	prop = of_get_property(brg, "current-speed", NULL);
	if (prop)
		pdata.default_baud = *prop;

	/* Default is 8 bits, no parity, no flow control */
	pdata.default_bits = 8;
	pdata.default_parity = 'n';
	pdata.default_flow = 'n';

	prop = of_get_property(np, "chr_1", NULL);
	if (prop)
		pdata.chr_1_val = *prop;

	prop = of_get_property(np, "chr_2", NULL);
	if (prop)
		pdata.chr_2_val = *prop;

	prop = of_get_property(np, "chr_10", NULL);
	if (prop)
		pdata.chr_10_val = *prop;

	prop = of_get_property(np, "mpcr", NULL);
	if (prop)
		pdata.mpcr_val = *prop;

	prop = of_get_property(brg, "bcr", NULL);
	if (prop)
		pdata.bcr_val = *prop;

	pdata.brg_can_tune = 1; /* All current revs need this set */

	prop = of_get_property(brg, "clock-src", NULL);
	if (prop)
		pdata.brg_clk_src = *prop;

	prop = of_get_property(brg, "clock-frequency", NULL);
	if (prop)
		pdata.brg_clk_freq = *prop;

	pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
	if (!pdev)
		return -ENOMEM;

	err = platform_device_add_resources(pdev, r, 5);
	if (err)
		goto error;

	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
	if (err)
		goto error;

	err = platform_device_add(pdev);
	if (err)
		goto error;

	return 0;

error:
	platform_device_put(pdev);
	return err;
}
Beispiel #23
0
/*
 * Create mv64x60_i2c platform devices
 */
static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
{
	struct resource r[2];
	struct platform_device *pdev;
	struct mv64xxx_i2c_pdata pdata;
	const unsigned int *prop;
	int err;

	memset(r, 0, sizeof(r));

	err = of_address_to_resource(np, 0, &r[0]);
	if (err)
		return err;

	of_irq_to_resource(np, 0, &r[1]);

	memset(&pdata, 0, sizeof(pdata));

	prop = of_get_property(np, "freq_m", NULL);
	if (!prop)
		return -ENODEV;
	pdata.freq_m = *prop;

	prop = of_get_property(np, "freq_n", NULL);
	if (!prop)
		return -ENODEV;
	pdata.freq_n = *prop;

	prop = of_get_property(np, "timeout", NULL);
	if (prop)
		pdata.timeout = *prop;
	else
		pdata.timeout = 1000;	/* 1 second */

	prop = of_get_property(np, "retries", NULL);
	if (prop)
		pdata.retries = *prop;
	else
		pdata.retries = 1;

	pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
	if (!pdev)
		return -ENOMEM;

	err = platform_device_add_resources(pdev, r, 2);
	if (err)
		goto error;

	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
	if (err)
		goto error;

	err = platform_device_add(pdev);
	if (err)
		goto error;

	return 0;

error:
	platform_device_put(pdev);
	return err;
}
Beispiel #24
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;
}
/* The probe function for a single message register block.
 */
static __devinit int mpic_msgr_probe(struct platform_device *dev)
{
	void __iomem *msgr_block_addr;
	int block_number;
	struct resource rsrc;
	unsigned int i;
	unsigned int irq_index;
	struct device_node *np = dev->dev.of_node;
	unsigned int receive_mask;
	const unsigned int *prop;

	if (!np) {
		dev_err(&dev->dev, "Device OF-Node is NULL");
		return -EFAULT;
	}

	/* Allocate the message register array upon the first device
	 * registered.
	 */
	if (!mpic_msgrs) {
		mpic_msgr_count = mpic_msgr_number_of_registers();
		dev_info(&dev->dev, "Found %d message registers\n",
				mpic_msgr_count);

		mpic_msgrs = kzalloc(sizeof(struct mpic_msgr) * mpic_msgr_count,
							 GFP_KERNEL);
		if (!mpic_msgrs) {
			dev_err(&dev->dev,
				"No memory for message register blocks\n");
			return -ENOMEM;
		}
	}
	dev_info(&dev->dev, "Of-device full name %s\n", np->full_name);

	/* IO map the message register block. */
	of_address_to_resource(np, 0, &rsrc);
	msgr_block_addr = ioremap(rsrc.start, rsrc.end - rsrc.start);
	if (!msgr_block_addr) {
		dev_err(&dev->dev, "Failed to iomap MPIC message registers");
		return -EFAULT;
	}

	/* Ensure the block has a defined order. */
	block_number = mpic_msgr_block_number(np);
	if (block_number < 0) {
		dev_err(&dev->dev,
			"Failed to find message register block alias\n");
		return -ENODEV;
	}
	dev_info(&dev->dev, "Setting up message register block %d\n",
			block_number);

	/* Grab the receive mask which specifies what registers can receive
	 * interrupts.
	 */
	prop = of_get_property(np, "mpic-msgr-receive-mask", NULL);
	receive_mask = (prop) ? *prop : 0xF;

	/* Build up the appropriate message register data structures. */
	for (i = 0, irq_index = 0; i < MPIC_MSGR_REGISTERS_PER_BLOCK; ++i) {
		struct mpic_msgr *msgr;
		unsigned int reg_number;

		msgr = kzalloc(sizeof(struct mpic_msgr), GFP_KERNEL);
		if (!msgr) {
			dev_err(&dev->dev, "No memory for message register\n");
			return -ENOMEM;
		}

		reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i;
		msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE;
		msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET);
		msgr->in_use = MSGR_FREE;
		msgr->num = i;
		raw_spin_lock_init(&msgr->lock);

		if (receive_mask & (1 << i)) {
			struct resource irq;

			if (of_irq_to_resource(np, irq_index, &irq) == NO_IRQ) {
				dev_err(&dev->dev,
						"Missing interrupt specifier");
				kfree(msgr);
				return -EFAULT;
			}
			msgr->irq = irq.start;
			irq_index += 1;
		} else {
			msgr->irq = NO_IRQ;
		}

		mpic_msgrs[reg_number] = msgr;
		mpic_msgr_disable(msgr);
		dev_info(&dev->dev, "Register %d initialized: irq %d\n",
				reg_number, msgr->irq);

	}

	return 0;
}
Beispiel #26
0
/**
 * xps2_of_probe - probe method for the PS/2 device.
 * @of_dev:	pointer to OF device structure
 * @match:	pointer to the structure used for matching a device
 *
 * This function probes the PS/2 device in the device tree.
 * It initializes the driver data structure and the hardware.
 * It returns 0, if the driver is bound to the PS/2 device, or a negative
 * value if there is an error.
 */
static int __devinit xps2_of_probe(struct platform_device *ofdev)
{
	struct resource r_irq; /* Interrupt resources */
	struct resource r_mem; /* IO mem resources */
	struct xps2data *drvdata;
	struct serio *serio;
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
			ofdev->dev.of_node->name);

	/* Get iospace for the device */
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}

	/* Get IRQ for the device */
	if (of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq) == NO_IRQ) {
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	if (!drvdata) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}

	dev_set_drvdata(dev, drvdata);

	spin_lock_init(&drvdata->lock);
	drvdata->irq = r_irq.start;

	phys_addr = r_mem.start;
	remap_size = resource_size(&r_mem);
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
		goto failed1;
	}

	/* Fill in configuration data and add them to the list */
	drvdata->base_address = ioremap(phys_addr, remap_size);
	if (drvdata->base_address == NULL) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
		goto failed2;
	}

	/* Disable all the interrupts, just in case */
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	/* Reset the PS2 device and abort any current transaction, to make sure
	 * we have the PS2 in a good state */
	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);

	serio = &drvdata->serio;
	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
	snprintf(serio->phys, sizeof(serio->phys),
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

	serio_register_port(serio);

	return 0;		/* success */

failed2:
	release_mem_region(phys_addr, remap_size);
failed1:
	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return error;
}
Beispiel #27
0
static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
				   struct spi_board_info *board_infos,
				   unsigned int num_board_infos,
				   void (*cs_control)(struct spi_device *dev,
						      bool on))
{
	struct device_node *np;
	unsigned int i = 0;

	for_each_compatible_node(np, type, compatible) {
		int ret;
		unsigned int j;
		const void *prop;
		struct resource res[2];
		struct platform_device *pdev;
		struct fsl_spi_platform_data pdata = {
			.cs_control = cs_control,
		};

		memset(res, 0, sizeof(res));

		pdata.sysclk = sysclk;

		prop = of_get_property(np, "reg", NULL);
		if (!prop)
			goto err;
		pdata.bus_num = *(u32 *)prop;

		prop = of_get_property(np, "cell-index", NULL);
		if (prop)
			i = *(u32 *)prop;

		prop = of_get_property(np, "mode", NULL);
		if (prop && !strcmp(prop, "cpu-qe"))
			pdata.qe_mode = 1;

		for (j = 0; j < num_board_infos; j++) {
			if (board_infos[j].bus_num == pdata.bus_num)
				pdata.max_chipselect++;
		}

		if (!pdata.max_chipselect)
			continue;

		ret = of_address_to_resource(np, 0, &res[0]);
		if (ret)
			goto err;

		ret = of_irq_to_resource(np, 0, &res[1]);
		if (ret == NO_IRQ)
			goto err;

		pdev = platform_device_alloc("mpc83xx_spi", i);
		if (!pdev)
			goto err;

		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
		if (ret)
			goto unreg;

		ret = platform_device_add_resources(pdev, res,
						    ARRAY_SIZE(res));
		if (ret)
			goto unreg;

		ret = platform_device_add(pdev);
		if (ret)
			goto unreg;

		goto next;
unreg:
		platform_device_del(pdev);
err:
		pr_err("%s: registration failed\n", np->full_name);
next:
		i++;
	}
static int __devinit pata_of_platform_probe(struct of_device *ofdev,
					    const struct of_device_id *match)
{
	int ret;
	struct device_node *dn = ofdev->dev.of_node;
	struct resource io_res;
	struct resource ctl_res;
	struct resource irq_res;
	unsigned int reg_shift = 0;
	int pio_mode = 0;
	int pio_mask;
	const u32 *prop;

	ret = of_address_to_resource(dn, 0, &io_res);
	if (ret) {
		dev_err(&ofdev->dev, "can't get IO address from "
			"device tree\n");
		return -EINVAL;
	}

	if (of_device_is_compatible(dn, "electra-ide")) {
		/* Altstatus is really at offset 0x3f6 from the primary window
		 * on electra-ide. Adjust ctl_res and io_res accordingly.
		 */
		ctl_res = io_res;
		ctl_res.start = ctl_res.start+0x3f6;
		io_res.end = ctl_res.start-1;
	} else {
		ret = of_address_to_resource(dn, 1, &ctl_res);
		if (ret) {
			dev_err(&ofdev->dev, "can't get CTL address from "
				"device tree\n");
			return -EINVAL;
		}
	}

	ret = of_irq_to_resource(dn, 0, &irq_res);
	if (ret == NO_IRQ)
		irq_res.start = irq_res.end = 0;
	else
		irq_res.flags = 0;

	prop = of_get_property(dn, "reg-shift", NULL);
	if (prop)
		reg_shift = *prop;

	prop = of_get_property(dn, "pio-mode", NULL);
	if (prop) {
		pio_mode = *prop;
		if (pio_mode > 6) {
			dev_err(&ofdev->dev, "invalid pio-mode\n");
			return -EINVAL;
		}
	} else {
		dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n");
	}

	pio_mask = 1 << pio_mode;
	pio_mask |= (1 << pio_mode) - 1;

	return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res,
				     reg_shift, pio_mask);
}
Beispiel #29
0
/*
 * Probe routine for each detected JobR subsystem. It assumes that
 * property detection was picked up externally.
 */
int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
		  int ring)
{
	struct device *ctrldev, *jrdev;
	struct platform_device *jr_pdev;
	struct caam_drv_private *ctrlpriv;
	struct caam_drv_private_jr *jrpriv;
	u32 *jroffset;
	int error;

	ctrldev = &pdev->dev;
	ctrlpriv = dev_get_drvdata(ctrldev);

	jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
			 GFP_KERNEL);
	if (jrpriv == NULL) {
		dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
			ring);
		return -ENOMEM;
	}
	jrpriv->parentdev = ctrldev; /* point back to parent */
	jrpriv->ridx = ring; /* save ring identity relative to detection */

	/*
	 * Derive a pointer to the detected JobRs regs
	 * Driver has already iomapped the entire space, we just
	 * need to add in the offset to this JobR. Don't know if I
	 * like this long-term, but it'll run
	 */
	jroffset = (u32 *)of_get_property(np, "reg", NULL);
	jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
							 + *jroffset);

	/* Build a local dev for each detected queue */
	jr_pdev = of_platform_device_create(np, NULL, ctrldev);
	if (jr_pdev == NULL) {
		kfree(jrpriv);
		return -EINVAL;
	}
	jrdev = &jr_pdev->dev;
	dev_set_drvdata(jrdev, jrpriv);
	ctrlpriv->jrdev[ring] = jrdev;

	if (sizeof(dma_addr_t) == sizeof(u64))
		if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring"))
			dma_set_mask(jrdev, DMA_BIT_MASK(40));
		else
			dma_set_mask(jrdev, DMA_BIT_MASK(36));
	else
		dma_set_mask(jrdev, DMA_BIT_MASK(32));

	/* Identify the interrupt */
	jrpriv->irq = of_irq_to_resource(np, 0, NULL);

	/* Now do the platform independent part */
	error = caam_jr_init(jrdev); /* now turn on hardware */
	if (error) {
		kfree(jrpriv);
		return error;
	}

	return error;
}
static int __init xilinx_spi_of_probe(struct of_device *ofdev,
					const struct of_device_id *match)
{
	struct spi_master *master;
	struct xilinx_spi *xspi;
	struct resource r_irq_struct;
	struct resource r_mem_struct;

	struct resource *r_irq = &r_irq_struct;
	struct resource *r_mem = &r_mem_struct;
	int rc = 0;
	const u32 *prop;
	int len;

	/* Get resources(memory, IRQ) associated with the device */
	master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi));

	if (master == NULL) {
		return -ENOMEM;
	}

	dev_set_drvdata(&ofdev->dev, master);

	rc = of_address_to_resource(ofdev->node, 0, r_mem);
	if (rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		goto put_master;
	}

	rc = of_irq_to_resource(ofdev->node, 0, r_irq);
	if (rc == NO_IRQ) {
		dev_warn(&ofdev->dev, "no IRQ found\n");
		goto put_master;
	}

	xspi = spi_master_get_devdata(master);
	xspi->bitbang.master = spi_master_get(master);
	xspi->bitbang.chipselect = xilinx_spi_chipselect;
	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
	xspi->bitbang.master->setup = xilinx_spi_setup;
	init_completion(&xspi->done);

	xspi->irq = r_irq->start;

	if (!request_mem_region(r_mem->start,
			r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) {
		rc = -ENXIO;
		dev_warn(&ofdev->dev, "memory request failure\n");
		goto put_master;
	}

	xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1);
	if (xspi->regs == NULL) {
		rc = -ENOMEM;
		dev_warn(&ofdev->dev, "ioremap failure\n");
		goto put_master;
	}
	xspi->irq = r_irq->start;

	/* dynamic bus assignment */
	master->bus_num = -1;

	/* number of slave select bits is required */
	prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
	if (!prop || len < sizeof(*prop)) {
		dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
		goto put_master;
	}
	master->num_chipselect = *prop;

	/* SPI controller initializations */
	xspi_init_hw(xspi->regs);

	/* Register for SPI Interrupt */
	rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
	if (rc != 0) {
		dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq);
		goto unmap_io;
	}

	rc = spi_bitbang_start(&xspi->bitbang);
	if (rc != 0) {
		dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n");
		goto free_irq;
	}

	dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
			(unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq);

	/* Add any subnodes on the SPI bus */
	of_register_spi_devices(master, ofdev->node);

	return rc;

free_irq:
	free_irq(xspi->irq, xspi);
unmap_io:
	iounmap(xspi->regs);
put_master:
	spi_master_put(master);
	return rc;
}