Esempio n. 1
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;
}
Esempio n. 2
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;
}