static int zynq_rpmsg_deinitialize(struct platform_device *pdev)
{
	unregister_virtio_device(&(zynq_rpmsg_p->virtio_dev));

	put_device(&(zynq_rpmsg_p->mid_dev));

	dma_release_declared_memory(&pdev->dev);

	clear_ipi_handler(zynq_rpmsg_p->vring0);

	return 0;
}
static int zynqmp_r5_remoteproc_remove(struct platform_device *pdev)
{
	struct zynqmp_r5_rproc_pdata *local = platform_get_drvdata(pdev);

	dev_info(&pdev->dev, "%s\n", __func__);

	rproc_del(local->rproc);
	rproc_put(local->rproc);

	dma_release_declared_memory(&pdev->dev);

	return 0;
}
Exemple #3
0
static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
{
	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
	struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
					struct sh_mobile_ceu_dev, ici);

	soc_camera_host_unregister(soc_host);
	pm_runtime_disable(&pdev->dev);
	free_irq(pcdev->irq, pcdev);
	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
		dma_release_declared_memory(&pdev->dev);
	iounmap(pcdev->base);
	kfree(pcdev);
	return 0;
}
static int ehci_hcd_hlwd_remove(struct of_device *op)
{
	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);

	dev_set_drvdata(&op->dev, NULL);

	dev_dbg(&op->dev, "stopping " DRV_MODULE_NAME " USB Controller\n");

	usb_remove_hcd(hcd);
	iounmap(hcd->regs);
	irq_dispose_mapping(hcd->irq);
	dma_release_declared_memory(&op->dev);
	usb_put_hcd(hcd);

	return 0;
}
Exemple #5
0
static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
{
	struct usb_hcd *hcd = platform_get_drvdata(dev);
	struct tmio_hcd *tmio = hcd_to_tmio(hcd);
	const struct mfd_cell *cell = mfd_get_cell(dev);

	usb_remove_hcd(hcd);
	tmio_stop_hc(dev);
	if (cell->disable)
		cell->disable(dev);
	dma_release_declared_memory(&dev->dev);
	iounmap(hcd->regs);
	iounmap(tmio->ccr);
	usb_put_hcd(hcd);

	return 0;
}
static void sram_deinit(struct usb_hcd *hcd)
{
	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);

	if (!hcd->has_sram)
		return;
	dma_release_declared_memory(&pdev->dev);
	pci_release_region(pdev, 1);

	/* If host is suspended, SRAM backup memory should be freed */
	if (ehci->sram_swap) {
		vfree(ehci->sram_swap);
		ehci->sram_swap = NULL;
	}

}
static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);
	struct resource	*mem;

	usb_remove_hcd(hcd);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
	dma_release_declared_memory(&pdev->dev);
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (mem)
		release_mem_region(mem->start, resource_size(mem));

	/* mask interrupts and disable power */

	sm501_modify_reg(pdev->dev.parent, SM501_IRQ_MASK, 0, 1 << 6);
	sm501_unit_power(pdev->dev.parent, SM501_GATE_USB_HOST, 0);

	return 0;
}
static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
{
    const struct mfd_cell *cell = mfd_get_cell(dev);
    struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
    struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1);
    struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2);
    int irq = platform_get_irq(dev, 0);
    struct tmio_hcd *tmio;
    struct ohci_hcd *ohci;
    struct usb_hcd *hcd;
    int ret;

    if (usb_disabled())
        return -ENODEV;

    if (!cell)
        return -EINVAL;

    hcd = usb_create_hcd(&ohci_tmio_hc_driver, &dev->dev, dev_name(&dev->dev));
    if (!hcd) {
        ret = -ENOMEM;
        goto err_usb_create_hcd;
    }

    hcd->rsrc_start = regs->start;
    hcd->rsrc_len = resource_size(regs);

    tmio = hcd_to_tmio(hcd);

    spin_lock_init(&tmio->lock);

    tmio->ccr = ioremap(config->start, resource_size(config));
    if (!tmio->ccr) {
        ret = -ENOMEM;
        goto err_ioremap_ccr;
    }

    hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
    if (!hcd->regs) {
        ret = -ENOMEM;
        goto err_ioremap_regs;
    }

    if (!dma_declare_coherent_memory(&dev->dev, sram->start,
                                     sram->start,
                                     resource_size(sram),
                                     DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) {
        ret = -EBUSY;
        goto err_dma_declare;
    }

    if (cell->enable) {
        ret = cell->enable(dev);
        if (ret)
            goto err_enable;
    }

    tmio_start_hc(dev);
    ohci = hcd_to_ohci(hcd);
    ohci_hcd_init(ohci);

    ret = usb_add_hcd(hcd, irq, 0);
    if (ret)
        goto err_add_hcd;

    if (ret == 0)
        return ret;

    usb_remove_hcd(hcd);

err_add_hcd:
    tmio_stop_hc(dev);
    if (cell->disable)
        cell->disable(dev);
err_enable:
    dma_release_declared_memory(&dev->dev);
err_dma_declare:
    iounmap(hcd->regs);
err_ioremap_regs:
    iounmap(tmio->ccr);
err_ioremap_ccr:
    usb_put_hcd(hcd);
err_usb_create_hcd:

    return ret;
}
static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
{
	const struct hc_driver *driver = &ohci_sm501_hc_driver;
	struct device *dev = &pdev->dev;
	struct resource	*res, *mem;
	int retval, irq;
	struct usb_hcd *hcd = NULL;

	irq = retval = platform_get_irq(pdev, 0);
	if (retval < 0)
		goto err0;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (mem == NULL) {
		dev_err(dev, "no resource definition for memory\n");
		retval = -ENOENT;
		goto err0;
	}

	if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
		dev_err(dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err0;
	}

	/* The sm501 chip is equipped with local memory that may be used
	 * by on-chip devices such as the video controller and the usb host.
	 * This driver uses dma_declare_coherent_memory() to make sure
	 * usb allocations with dma_alloc_coherent() allocate from
	 * this local memory. The dma_handle returned by dma_alloc_coherent()
	 * will be an offset starting from 0 for the first local memory byte.
	 *
	 * So as long as data is allocated using dma_alloc_coherent() all is
	 * fine. This is however not always the case - buffers may be allocated
	 * using kmalloc() - so the usb core needs to be told that it must copy
	 * data into our local memory if the buffers happen to be placed in
	 * regular memory. The HCD_LOCAL_MEM flag does just that.
	 */

	if (!dma_declare_coherent_memory(dev, mem->start,
					 mem->start - mem->parent->start,
					 resource_size(mem),
					 DMA_MEMORY_MAP |
					 DMA_MEMORY_EXCLUSIVE)) {
		dev_err(dev, "cannot declare coherent memory\n");
		retval = -ENXIO;
		goto err1;
	}

	/* allocate, reserve and remap resources for registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "no resource definition for registers\n");
		retval = -ENOENT;
		goto err2;
	}

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err2;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,	pdev->name)) {
		dev_err(dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err3;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (hcd->regs == NULL) {
		dev_err(dev, "cannot remap registers\n");
		retval = -ENXIO;
		goto err4;
	}

	ohci_hcd_init(hcd_to_ohci(hcd));

	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (retval)
		goto err5;

	/* enable power and unmask interrupts */

	sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
	sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0);

	return 0;
err5:
	iounmap(hcd->regs);
err4:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err3:
	usb_put_hcd(hcd);
err2:
	dma_release_declared_memory(dev);
err1:
	release_mem_region(mem->start, resource_size(mem));
err0:
	return retval;
}
Exemple #10
0
static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
{
	const struct hc_driver *driver = &ohci_sm501_hc_driver;
	struct device *dev = &pdev->dev;
	struct resource	*res, *mem;
	int retval, irq;
	struct usb_hcd *hcd = NULL;

	irq = retval = platform_get_irq(pdev, 0);
	if (retval < 0)
		goto err0;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (mem == NULL) {
		dev_err(dev, "no resource definition for memory\n");
		retval = -ENOENT;
		goto err0;
	}

	if (!request_mem_region(mem->start, mem->end - mem->start + 1,
				pdev->name)) {
		dev_err(dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err0;
	}

	

	if (!dma_declare_coherent_memory(dev, mem->start,
					 mem->start - mem->parent->start,
					 (mem->end - mem->start) + 1,
					 DMA_MEMORY_MAP |
					 DMA_MEMORY_EXCLUSIVE)) {
		dev_err(dev, "cannot declare coherent memory\n");
		retval = -ENXIO;
		goto err1;
	}

	
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "no resource definition for registers\n");
		retval = -ENOENT;
		goto err2;
	}

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err2;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = res->end - res->start + 1;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,	pdev->name)) {
		dev_err(dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err3;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (hcd->regs == NULL) {
		dev_err(dev, "cannot remap registers\n");
		retval = -ENXIO;
		goto err4;
	}

	ohci_hcd_init(hcd_to_ohci(hcd));

	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval)
		goto err4;

	

	sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
	sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0);

	return 0;
err4:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err3:
	usb_put_hcd(hcd);
err2:
	dma_release_declared_memory(dev);
err1:
	release_mem_region(mem->start, mem->end - mem->start + 1);
err0:
	return retval;
}
static int zynqmp_r5_remoteproc_probe(struct platform_device *pdev)
{
	const unsigned char *prop;
	struct resource *res;
	int ret = 0;
	int method = 0;
	struct zynqmp_r5_rproc_pdata *local;

	local = devm_kzalloc(&pdev->dev, sizeof(struct zynqmp_r5_rproc_pdata),
				 GFP_KERNEL);
	if (!local)
		return -ENOMEM;

	platform_set_drvdata(pdev, local);

	/* Declare vring for firmware */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vring0");
	if (!res) {
		dev_err(&pdev->dev, "invalid address for vring0\n");
		return -ENXIO;
	}

	/* FIXME: it may need to extend to 64/48 bit */
	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
		goto dma_mask_fault;
	}

	prop = of_get_property(pdev->dev.of_node, "core_conf", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default core_conf used: lock-step\n");
		prop = "lock-step";
	}

	dev_info(&pdev->dev, "RPU core_conf: %s\n", prop);
	if (!strcmp(prop, "split0")) {
		local->rpu_mode = SPLIT;
		local->rpu_id = 0;
	} else if (!strcmp(prop, "split1")) {
		local->rpu_mode = SPLIT;
		local->rpu_id = 1;
	} else if (!strcmp(prop, "lock-step")) {
		local->rpu_mode = LOCK_STEP;
		local->rpu_id = 0;
	} else {
		dev_err(&pdev->dev, "Invalid core_conf mode provided - %s , %d\n",
			prop, local->rpu_mode);
		goto dma_mask_fault;
	}

	prop = of_get_property(pdev->dev.of_node, "method", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default method used: smc\n");
		prop = "smc";
	}

	dev_info(&pdev->dev, "IPI/RPU control method: %s\n", prop);
	if (!strcmp(prop, "direct")) {
		method = HW;
		local->ipi_ops = &ipi_hw_ops;
		local->rpu_ops = &rpu_hw_ops;
	} else if (!strcmp(prop, "hvc")) {
		method = HVC;
		local->ipi_ops = &ipi_hvc_ops;
		local->rpu_ops = &rpu_hvc_ops;
	} else if (!strcmp(prop, "smc")) {
		method = SMC;
		local->ipi_ops = &ipi_smc_ops;
		local->rpu_ops = &rpu_smc_ops;
	} else {
		dev_err(&pdev->dev, "Invalid method provided - %s\n",
			prop);
		goto dma_mask_fault;
	}

	/* Handle direct hardware access */
	/* (TODO: remove once RPU and IPI drivers are ready ) */
	if (method == HW) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"rpu_base");
		local->rpu_base = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(local->rpu_base)) {
			dev_err(&pdev->dev, "Unable to map RPU I/O memory\n");
			ret = PTR_ERR(local->rpu_base);
			goto dma_mask_fault;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"apb_base");
		local->crl_apb_base = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(local->crl_apb_base)) {
			dev_err(&pdev->dev, "Unable to map CRL_APB I/O memory\n");
			ret = PTR_ERR(local->crl_apb_base);
			goto dma_mask_fault;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipi");
		local->ipi_base = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(local->ipi_base)) {
			pr_err("%s: Unable to map IPI\n", __func__);
			ret = PTR_ERR(local->ipi_base);
			goto dma_mask_fault;
		}
	}

	prop = of_get_property(pdev->dev.of_node, "bootmem", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default bootmem property used: tcm\n");
		prop = "tcm";
	}

	dev_info(&pdev->dev, "RPU bootmem: %s\n", prop);
	if (!strcmp(prop, "tcm")) {
		local->bootmem = TCM;
	} else if (!strcmp(prop, "ocm")) {
		local->bootmem = OCM;
	} else {
		dev_err(&pdev->dev, "Invalid R5 bootmem property - %s\n",
			prop);
		goto dma_mask_fault;
	}

	/* IPI IRQ */
	local->vring0 = platform_get_irq(pdev, 0);
	if (local->vring0 < 0) {
		ret = local->vring0;
		dev_err(&pdev->dev, "unable to find IPI IRQ\n");
		goto dma_mask_fault;
	}
	ret = devm_request_irq(&pdev->dev, local->vring0,
		r5_remoteproc_interrupt, 0, dev_name(&pdev->dev),
		&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "IRQ %d already allocated\n",
			local->vring0);
		goto dma_mask_fault;
	}
	dev_dbg(&pdev->dev, "vring0 irq: %d\n", local->vring0);

	ret = of_property_read_u32(pdev->dev.of_node, "ipi_dest_mask",
		&local->ipi_dest_mask);
	if (ret < 0) {
		dev_warn(&pdev->dev, "default ipi_dest_mask used: 0x100\n");
		local->ipi_dest_mask = 0x100;
	}
	dev_info(&pdev->dev, "ipi_dest_mask: 0x%x\n", local->ipi_dest_mask);

	/* Module param firmware first */
	prop = of_get_property(pdev->dev.of_node, "firmware", NULL);
	if (firmware)
		prop = firmware;
	else if (!prop)
		prop = DEFAULT_FIRMWARE_NAME;

	if (prop) {
		dev_dbg(&pdev->dev, "Using firmware: %s\n", prop);
		local->rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
			&zynqmp_r5_rproc_ops, prop, sizeof(struct rproc));
		if (!local->rproc) {
			dev_err(&pdev->dev, "rproc allocation failed\n");
			goto rproc_fault;
		}

		ret = rproc_add(local->rproc);
		if (ret) {
			dev_err(&pdev->dev, "rproc registration failed\n");
			goto rproc_fault;
		}
	} else {
		ret = -ENODEV;
	}

	return ret;

rproc_fault:
	rproc_put(local->rproc);

dma_mask_fault:
	dma_release_declared_memory(&pdev->dev);

err_exit:
	return 0;
}
static int zynqmp_r5_remoteproc_probe(struct platform_device *pdev)
{
	const unsigned char *prop;
	struct resource *res;
	int ret = 0;
	int method = 0;
	char *rproc_firmware = 0;
	struct zynqmp_r5_rproc_pdata *local;

	local = devm_kzalloc(&pdev->dev, sizeof(struct zynqmp_r5_rproc_pdata),
				 GFP_KERNEL);
	if (!local)
		return -ENOMEM;

	platform_set_drvdata(pdev, local);

	/* FIXME: it may need to extend to 64/48 bit */
	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
		goto dma_mask_fault;
	}

	prop = of_get_property(pdev->dev.of_node, "core_conf", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default core_conf used: lock-step\n");
		prop = "lock-step";
	}

	dev_info(&pdev->dev, "RPU core_conf: %s\n", prop);
	if (!strcmp(prop, "split0")) {
		local->rpu_mode = SPLIT;
		local->rpu_id = 0;
	} else if (!strcmp(prop, "split1")) {
		local->rpu_mode = SPLIT;
		local->rpu_id = 1;
	} else if (!strcmp(prop, "lock-step")) {
		local->rpu_mode = LOCK_STEP;
		local->rpu_id = 0;
	} else {
		dev_err(&pdev->dev, "Invalid core_conf mode provided - %s , %d\n",
			prop, local->rpu_mode);
		ret = -EINVAL;
		goto dma_mask_fault;
	}

	prop = of_get_property(pdev->dev.of_node, "method", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default method used: smc\n");
		prop = "direct";
	}

	dev_info(&pdev->dev, "IPI/RPU control method: %s\n", prop);
	if (!strcmp(prop, "direct")) {
		method = HW;
		local->ipi_ops = &ipi_hw_ops;
		local->rpu_ops = &rpu_hw_ops;
	} else if (!strcmp(prop, "hvc")) {
		method = HVC;
		local->ipi_ops = &ipi_hvc_ops;
		local->rpu_ops = &rpu_hvc_ops;
	} else if (!strcmp(prop, "smc")) {
		method = SMC;
		local->ipi_ops = &ipi_smc_ops;
		local->rpu_ops = &rpu_smc_ops;
	} else {
		dev_err(&pdev->dev, "Invalid method provided - %s\n",
			prop);
		ret = -EINVAL;
		goto dma_mask_fault;
	}

	/* Handle direct hardware access */
	/* (TODO: remove once RPU and IPI drivers are ready ) */
	if (method == HW) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"rpu_base");
		local->rpu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		if (IS_ERR(local->rpu_base)) {
			dev_err(&pdev->dev, "Unable to map RPU I/O memory\n");
			ret = PTR_ERR(local->rpu_base);
			goto dma_mask_fault;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"apb_base");
		local->crl_apb_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		if (IS_ERR(local->crl_apb_base)) {
			dev_err(&pdev->dev, "Unable to map CRL_APB I/O memory\n");
			ret = PTR_ERR(local->crl_apb_base);
			goto dma_mask_fault;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipi");
		local->ipi_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		if (IS_ERR(local->ipi_base)) {
			pr_err("%s: Unable to map IPI\n", __func__);
			ret = PTR_ERR(local->ipi_base);
			goto dma_mask_fault;
		}
	}

	/* IPI IRQ */
	local->vring0 = platform_get_irq(pdev, 0);
	if (local->vring0 < 0) {
		ret = local->vring0;
		dev_err(&pdev->dev, "unable to find IPI IRQ\n");
		goto dma_mask_fault;
	}
	ret = devm_request_irq(&pdev->dev, local->vring0,
		r5_remoteproc_interrupt, IRQF_SHARED, dev_name(&pdev->dev),
		&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "IRQ %d already allocated\n",
			local->vring0);
		goto dma_mask_fault;
	}
	dev_dbg(&pdev->dev, "vring0 irq: %d\n", local->vring0);

	if (local->rpu_id == 0) {
		local->ipi_dest_mask = RPU_0_IPI_MASK;
		rproc_firmware = firmware;
	} else {
		local->ipi_dest_mask = RPU_1_IPI_MASK;
		rproc_firmware = firmware1;
	}

	dev_dbg(&pdev->dev, "Using firmware: %s\n", rproc_firmware);
	local->rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
		&zynqmp_r5_rproc_ops, rproc_firmware, sizeof(struct rproc));
	if (!local->rproc) {
		dev_err(&pdev->dev, "rproc allocation failed\n");
		goto rproc_fault;
	}

	zynqmp_r5_rproc_init(local->rproc);
	ret = rproc_add(local->rproc);
	if (ret) {
		dev_err(&pdev->dev, "rproc registration failed\n");
		goto rproc_fault;
	}

	return ret;

rproc_fault:
	rproc_put(local->rproc);

dma_mask_fault:
	dma_release_declared_memory(&pdev->dev);

	return ret;
}
Exemple #13
0
static int mb_remoteproc_probe(struct platform_device *pdev)
{
	const unsigned char *prop;
	struct platform_device *bram_pdev;
	struct device_node *bram_dev;
	struct resource *res; /* IO mem resources */
	int ret = 0;
	int count = 0;
	struct mb_rproc_pdata *local;

	local = devm_kzalloc(&pdev->dev, sizeof(*local), GFP_KERNEL);
	if (!local)
		return -ENOMEM;

	platform_set_drvdata(pdev, local);

	/* Declare memory for firmware */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "invalid address\n");
		return -ENODEV;
	}

	local->mem_start = res->start;
	local->mem_end = res->end;

	/* Alloc phys addr from 0 to max_addr for firmware */
	ret = dma_declare_coherent_memory(&pdev->dev, local->mem_start,
		local->mem_start, local->mem_end - local->mem_start + 1,
		DMA_MEMORY_IO);
	if (!ret) {
		dev_err(&pdev->dev, "dma_declare_coherent_memory failed\n");
		return -ENOMEM;
	}

	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
		goto dma_mask_fault;
	}

	/* Alloc IRQ based on DTS to be sure that no other driver will use it */
	while (1) {
		int irq;
		/* Allocating shared IRQs will ensure that any module will
		 * use these IRQs */
		irq = platform_get_irq(pdev, count++);
		if (irq == -ENXIO || irq == -EINVAL)
			break;
		ret = devm_request_irq(&pdev->dev, irq, mb_remoteproc_interrupt,
				       0, dev_name(&pdev->dev), &pdev->dev);
		if (ret) {
			dev_err(&pdev->dev, "IRQ %d already allocated\n", irq);
			goto dma_mask_fault;
		}

		dev_info(&pdev->dev, "%d: Alloc irq: %d\n", count, irq);
	}

	/* Find out reset gpio and keep microblaze in reset */
	local->reset_gpio = of_get_named_gpio(pdev->dev.of_node, "reset", 0);
	if (local->reset_gpio < 0) {
		dev_err(&pdev->dev, "reset-gpio property not found\n");
		ret = local->reset_gpio;
		goto dma_mask_fault;
	}
	ret = devm_gpio_request_one(&pdev->dev, local->reset_gpio,
				    GPIOF_OUT_INIT_HIGH, "mb_reset");
	if (ret) {
		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
		goto dma_mask_fault;
	}

	/* Find out reset gpio and keep microblaze in reset */
	local->mb_debug_gpio = of_get_named_gpio(pdev->dev.of_node, "debug", 0);
	if (local->mb_debug_gpio < 0) {
		dev_err(&pdev->dev, "mb-debug-gpio property not found\n");
		ret = local->mb_debug_gpio;
		goto dma_mask_fault;
	}
	ret = devm_gpio_request_one(&pdev->dev, local->mb_debug_gpio,
				    GPIOF_OUT_INIT_LOW, "mb_debug");
	if (ret) {
		dev_err(&pdev->dev, "Please specify gpio debug pin\n");
		goto dma_mask_fault;
	}

	/* IPI number for getting irq from firmware */
	local->ipi = of_get_named_gpio(pdev->dev.of_node, "ipino", 0);
	if (local->ipi < 0) {
		dev_err(&pdev->dev, "ipi-gpio property not found\n");
		ret = local->ipi;
		goto dma_mask_fault;
	}
	ret = devm_gpio_request_one(&pdev->dev, local->ipi, GPIOF_IN, "mb_ipi");
	if (ret) {
		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
		goto dma_mask_fault;
	}
	ret = devm_request_irq(&pdev->dev, gpio_to_irq(local->ipi),
			       ipi_kick, IRQF_SHARED|IRQF_TRIGGER_RISING,
			       dev_name(&pdev->dev), local);
	if (ret) {
		dev_err(&pdev->dev, "IRQ %d already allocated\n", local->ipi);
		goto dma_mask_fault;
	}

	/* Find out vring0 pin */
	local->vring0 = of_get_named_gpio(pdev->dev.of_node, "vring0", 0);
	if (local->vring0 < 0) {
		dev_err(&pdev->dev, "reset-gpio property not found\n");
		ret = local->vring0;
		goto dma_mask_fault;
	}
	ret = devm_gpio_request_one(&pdev->dev, local->vring0,
				    GPIOF_DIR_OUT, "mb_vring0");
	if (ret) {
		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
		goto dma_mask_fault;
	}

	/* Find out vring1 pin */
	local->vring1 = of_get_named_gpio(pdev->dev.of_node, "vring1", 0);
	if (local->vring1 < 0) {
		dev_err(&pdev->dev, "reset-gpio property not found\n");
		ret = local->vring1;
		goto dma_mask_fault;
	}
	ret = devm_gpio_request_one(&pdev->dev, local->vring1,
				    GPIOF_DIR_OUT, "mb_vring1");
	if (ret) {
		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
		goto dma_mask_fault;
	}

	/* Allocate bram device */
	bram_dev = of_parse_phandle(pdev->dev.of_node, "bram", 0);
	if (!bram_dev) {
		dev_err(&pdev->dev, "Please specify bram connection\n");
		ret = -ENODEV;
		goto dma_mask_fault;
	}
	bram_pdev = of_find_device_by_node(bram_dev);
	if (!bram_pdev) {
		dev_err(&pdev->dev, "BRAM device hasn't found\n");
		ret = -ENODEV;
		goto dma_mask_fault;
	}
	res = platform_get_resource(bram_pdev, IORESOURCE_MEM, 0);
	local->vbase = devm_ioremap_resource(&pdev->dev, res);
	if (!local->vbase) {
		ret = -ENODEV;
		goto dma_mask_fault;
	}

	/* Load simple bootloader to bram */
	local->bootloader = of_get_property(pdev->dev.of_node,
					    "bram-firmware", NULL);
	if (!local->bootloader) {
		dev_err(&pdev->dev, "Please specify BRAM firmware\n");
		ret = -ENODEV;
		goto dma_mask_fault;
	}

	dev_info(&pdev->dev, "Using microblaze BRAM bootloader: %s\n",
		 local->bootloader);

	/* Module param firmware first */
	if (firmware)
		prop = firmware;
	else
		prop = of_get_property(pdev->dev.of_node, "firmware", NULL);

	if (prop) {
		dev_info(&pdev->dev, "Using firmware: %s\n", prop);
		local->rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
				&mb_rproc_ops, prop, sizeof(struct rproc));
		if (!local->rproc) {
			dev_err(&pdev->dev, "rproc allocation failed\n");
			ret = -ENODEV;
			goto dma_mask_fault;
		}

		ret = rproc_add(local->rproc);
		if (ret) {
			dev_err(&pdev->dev, "rproc registration failed\n");
			rproc_put(local->rproc);
			goto dma_mask_fault;
		}
		return 0;
	} else {
		ret = -ENODEV;
	}

dma_mask_fault:
	dma_release_declared_memory(&pdev->dev);

	return ret;
}
Exemple #14
0
static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
{
	struct sh_mobile_ceu_dev *pcdev;
	struct resource *res;
	void __iomem *base;
	unsigned int irq;
	int err = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!res || !irq) {
		dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
		err = -ENODEV;
		goto exit;
	}

	pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
	if (!pcdev) {
		dev_err(&pdev->dev, "Could not allocate pcdev\n");
		err = -ENOMEM;
		goto exit;
	}

	INIT_LIST_HEAD(&pcdev->capture);
	spin_lock_init(&pcdev->lock);

	pcdev->pdata = pdev->dev.platform_data;
	if (!pcdev->pdata) {
		err = -EINVAL;
		dev_err(&pdev->dev, "CEU platform data not set.\n");
		goto exit_kfree;
	}

	base = ioremap_nocache(res->start, resource_size(res));
	if (!base) {
		err = -ENXIO;
		dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
		goto exit_kfree;
	}

	pcdev->irq = irq;
	pcdev->base = base;
	pcdev->video_limit = 0; 

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res) {
		err = dma_declare_coherent_memory(&pdev->dev, res->start,
						  res->start,
						  resource_size(res),
						  DMA_MEMORY_MAP |
						  DMA_MEMORY_EXCLUSIVE);
		if (!err) {
			dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
			err = -ENXIO;
			goto exit_iounmap;
		}

		pcdev->video_limit = resource_size(res);
	}

	
	err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
			  dev_name(&pdev->dev), pcdev);
	if (err) {
		dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
		goto exit_release_mem;
	}

	pm_suspend_ignore_children(&pdev->dev, true);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_resume(&pdev->dev);

	pcdev->ici.priv = pcdev;
	pcdev->ici.v4l2_dev.dev = &pdev->dev;
	pcdev->ici.nr = pdev->id;
	pcdev->ici.drv_name = dev_name(&pdev->dev);
	pcdev->ici.ops = &sh_mobile_ceu_host_ops;

	err = soc_camera_host_register(&pcdev->ici);
	if (err)
		goto exit_free_clk;

	return 0;

exit_free_clk:
	pm_runtime_disable(&pdev->dev);
	free_irq(pcdev->irq, pcdev);
exit_release_mem:
	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
		dma_release_declared_memory(&pdev->dev);
exit_iounmap:
	iounmap(base);
exit_kfree:
	kfree(pcdev);
exit:
	return err;
}
static int __devinit
ehci_hcd_hlwd_probe(struct of_device *op, const struct of_device_id *match)
{
	struct device_node *dn = op->node;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci = NULL;
	struct resource res;
	dma_addr_t coherent_mem_addr;
	size_t coherent_mem_size;
	int irq;
	int error = -ENODEV;

	if (usb_disabled())
		goto out;

	if (starlet_get_ipc_flavour() != STARLET_IPC_MINI)
		goto out;

	dev_dbg(&op->dev, "initializing " DRV_MODULE_NAME " USB Controller\n");

	error = of_address_to_resource(dn, 0, &res);
	if (error)
		goto out;

	hcd = usb_create_hcd(&ehci_hlwd_hc_driver, &op->dev, DRV_MODULE_NAME);
	if (!hcd) {
		error = -ENOMEM;
		goto out;
	}

	hcd->rsrc_start = res.start;
	hcd->rsrc_len = resource_size(&res);

	error = of_address_to_resource(dn, 1, &res);
	if (error) {
		/* satisfy coherent memory allocations from mem1 or mem2 */
		dev_warn(&op->dev, "using normal memory\n");
	} else {
		coherent_mem_addr = res.start;
		coherent_mem_size = res.end - res.start + 1;
		if (!dma_declare_coherent_memory(&op->dev, coherent_mem_addr,
						 coherent_mem_addr,
						 coherent_mem_size,
						 DMA_MEMORY_MAP |
						 DMA_MEMORY_EXCLUSIVE)) {
			dev_err(&op->dev, "error declaring %u bytes of"
				" coherent memory at 0x%p\n",
				coherent_mem_size, (void *)coherent_mem_addr);
			error = -EBUSY;
			goto err_decl_coherent;
		}
	}

	irq = irq_of_parse_and_map(dn, 0);
	if (irq == NO_IRQ) {
		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
		error = -EBUSY;
		goto err_irq;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		printk(KERN_ERR __FILE__ ": ioremap failed\n");
		error = -EBUSY;
		goto err_ioremap;
	}

	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;
	ehci->regs = hcd->regs +
			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));

	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);

	error = usb_add_hcd(hcd, irq, 0);
	if (error == 0)
		return 0;

	iounmap(hcd->regs);
err_ioremap:
	irq_dispose_mapping(irq);
err_irq:
	dma_release_declared_memory(&op->dev);
err_decl_coherent:
	usb_put_hcd(hcd);
out:
	return error;
}