Пример #1
0
static int ehci_octeon_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct resource *res_mem;
	int irq;
	int ret;

	if (usb_disabled())
		return -ENODEV;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "No irq assigned\n");
		return -ENODEV;
	}

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res_mem == NULL) {
		dev_err(&pdev->dev, "No register space assigned\n");
		return -ENODEV;
	}

	/*
	 * We can DMA from anywhere. But the descriptors must be in
	 * the lower 4GB.
	 */
	pdev->dev.dma_mask = &ehci_octeon_dma_mask;
	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (ret)
		return ret;

	hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
	if (!hcd)
		return -ENOMEM;

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

	hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem);
	if (IS_ERR(hcd->regs)) {
		ret = PTR_ERR(hcd->regs);
		goto err1;
	}

	ehci_octeon_start();

	ehci = hcd_to_ehci(hcd);

	/* Octeon EHCI matches CPU endianness. */
#ifdef __BIG_ENDIAN
	ehci->big_endian_mmio = 1;
#endif

	ehci->caps = hcd->regs;

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err2;
	}
	device_wakeup_enable(hcd->self.controller);

	platform_set_drvdata(pdev, hcd);

	return 0;
err2:
	ehci_octeon_stop();

err1:
	usb_put_hcd(hcd);
	return ret;
}
Пример #2
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval, irq;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;

	if (pdev->num_resources != 2) {
		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM
			|| pdev->resource[1].flags != IORESOURCE_IRQ) {
		printk(KERN_ERR "hcd probe: invalid resource type\n");
		return -ENODEV;
	}

	usb_host_ck = clk_get(0, "usb_hhc_ck");
	if (IS_ERR(usb_host_ck))
		return PTR_ERR(usb_host_ck);

	if (!cpu_is_omap1510())
		usb_dc_ck = clk_get(0, "usb_dc_ck");
	else
		usb_dc_ck = clk_get(0, "lb_ck");

	if (IS_ERR(usb_dc_ck)) {
		clk_put(usb_host_ck);
		return PTR_ERR(usb_dc_ck);
	}


	hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id);
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}
	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}

	hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start);

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

	host_initialized = 0;
	host_enabled = 1;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		retval = -ENXIO;
		goto err2;
	}
	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
	if (retval)
		goto err2;

	host_initialized = 1;

	if (!host_enabled)
		omap_ohci_clock_power(0);

	return 0;
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);
err0:
	clk_put(usb_dc_ck);
	clk_put(usb_host_ck);
	return retval;
}
int ehci_xls_probe_internal(const struct hc_driver *driver,
	struct platform_device *pdev)
{
	struct usb_hcd  *hcd;
	struct resource *res;
	int retval, irq;

	
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n",
				dev_name(&pdev->dev));
		return -ENODEV;
	}

	
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n",
				dev_name(&pdev->dev));
		return -ENODEV;
	}
	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err1;
	}

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

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
				driver->description)) {
		dev_dbg(&pdev->dev, "controller already in use\n");
		retval = -EBUSY;
		goto err2;
	}
	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);

	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto err3;
	}

	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (retval != 0)
		goto err4;
	return retval;

err4:
	iounmap(hcd->regs);
err3:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev),
			retval);
	return retval;
}
Пример #4
0
/**
 * ehci_hcd_xilinx_of_probe - Probe method for the USB host controller
 * @op:		pointer to the platform_device bound to the host controller
 *
 * This function requests resources and sets up appropriate properties for the
 * host controller. Because the Xilinx USB host controller can be configured
 * as HS only or HS/FS only, it checks the configuration in the device tree
 * entry, and sets an appropriate value for hcd->has_tt.
 */
static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op)
{
	struct device_node *dn = op->dev.of_node;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci;
	struct resource res;
	int irq;
	int rv;
	int *value;

	if (usb_disabled())
		return -ENODEV;

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

	rv = of_address_to_resource(dn, 0, &res);
	if (rv)
		return rv;

	hcd = usb_create_hcd(&ehci_xilinx_of_hc_driver, &op->dev,
				"XILINX-OF USB");
	if (!hcd)
		return -ENOMEM;

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

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
		rv = -EBUSY;
		goto err_rmr;
	}

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

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

	ehci = hcd_to_ehci(hcd);

	/* This core always has big-endian register interface and uses
	 * big-endian memory descriptors.
	 */
	ehci->big_endian_mmio = 1;
	ehci->big_endian_desc = 1;

	/* Check whether the FS support option is selected in the hardware.
	 */
	value = (int *)of_get_property(dn, "xlnx,support-usb-fs", NULL);
	if (value && (*value == 1)) {
		ehci_dbg(ehci, "USB host controller supports FS devices\n");
		hcd->has_tt = 1;
	} else {
		ehci_dbg(ehci,
			"USB host controller is HS only\n");
		hcd->has_tt = 0;
	}

	/* Debug registers are at the first 0x100 region
	 */
	ehci->caps = hcd->regs + 0x100;
	ehci->regs = hcd->regs + 0x100 +
		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));

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

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

	iounmap(hcd->regs);

err_ioremap:
err_irq:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_rmr:
	usb_put_hcd(hcd);

	return rv;
}
Пример #5
0
static int ehci_octeon_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct resource *res_mem;
	int irq;
	int ret;

	if (usb_disabled())
		return -ENODEV;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "No irq assigned\n");
		return -ENODEV;
	}

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res_mem == NULL) {
		dev_err(&pdev->dev, "No register space assigned\n");
		return -ENODEV;
	}

	/*
	 * We can DMA from anywhere. But the descriptors must be in
	 * the lower 4GB.
	 */
	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
	pdev->dev.dma_mask = &ehci_octeon_dma_mask;

	hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
	if (!hcd)
		return -ENOMEM;

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

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
				OCTEON_EHCI_HCD_NAME)) {
		dev_err(&pdev->dev, "request_mem_region failed\n");
		ret = -EBUSY;
		goto err1;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err2;
	}

	ehci_octeon_start();

	ehci = hcd_to_ehci(hcd);

	/* Octeon EHCI matches CPU endianness. */
#ifdef __BIG_ENDIAN
	ehci->big_endian_mmio = 1;
#endif

	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);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err3;
	}

	platform_set_drvdata(pdev, hcd);

	/* root ports should always stay powered */
	ehci_port_power(ehci, 1);

	return 0;
err3:
	ehci_octeon_stop();

	iounmap(hcd->regs);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);
	return ret;
}
Пример #6
0
static int xhci_mtk_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct xhci_hcd_mtk *mtk;
	const struct hc_driver *driver;
	struct xhci_hcd *xhci;
	struct resource *res;
	struct usb_hcd *hcd;
	struct phy *phy;
	int phy_num;
	int ret = -ENODEV;
	int irq;

	if (usb_disabled())
		return -ENODEV;

	driver = &xhci_mtk_hc_driver;
	mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
	if (!mtk)
		return -ENOMEM;

	mtk->dev = dev;
	mtk->vbus = devm_regulator_get(dev, "vbus");
	if (IS_ERR(mtk->vbus)) {
		dev_err(dev, "fail to get vbus\n");
		return PTR_ERR(mtk->vbus);
	}

	mtk->vusb33 = devm_regulator_get(dev, "vusb33");
	if (IS_ERR(mtk->vusb33)) {
		dev_err(dev, "fail to get vusb33\n");
		return PTR_ERR(mtk->vusb33);
	}

	mtk->sys_clk = devm_clk_get(dev, "sys_ck");
	if (IS_ERR(mtk->sys_clk)) {
		dev_err(dev, "fail to get sys_ck\n");
		return PTR_ERR(mtk->sys_clk);
	}

	mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");

	ret = usb_wakeup_of_property_parse(mtk, node);
	if (ret)
		return ret;

	mtk->num_phys = of_count_phandle_with_args(node,
			"phys", "#phy-cells");
	if (mtk->num_phys > 0) {
		mtk->phys = devm_kcalloc(dev, mtk->num_phys,
					sizeof(*mtk->phys), GFP_KERNEL);
		if (!mtk->phys)
			return -ENOMEM;
	} else {
		mtk->num_phys = 0;
	}
	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);
	device_enable_async_suspend(dev);

	ret = xhci_mtk_ldos_enable(mtk);
	if (ret)
		goto disable_pm;

	ret = xhci_mtk_clks_enable(mtk);
	if (ret)
		goto disable_ldos;

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

	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
	if (ret)
		goto disable_clk;

	if (!dev->dma_mask)
		dev->dma_mask = &dev->coherent_dma_mask;
	else
		dma_set_mask(dev, DMA_BIT_MASK(32));

	hcd = usb_create_hcd(driver, dev, dev_name(dev));
	if (!hcd) {
		ret = -ENOMEM;
		goto disable_clk;
	}

	/*
	 * USB 2.0 roothub is stored in the platform_device.
	 * Swap it with mtk HCD.
	 */
	mtk->hcd = platform_get_drvdata(pdev);
	platform_set_drvdata(pdev, mtk);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hcd->regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(hcd->regs)) {
		ret = PTR_ERR(hcd->regs);
		goto put_usb2_hcd;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	mtk->ippc_regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(mtk->ippc_regs)) {
		ret = PTR_ERR(mtk->ippc_regs);
		goto put_usb2_hcd;
	}

	for (phy_num = 0; phy_num < mtk->num_phys; phy_num++) {
		phy = devm_of_phy_get_by_index(dev, node, phy_num);
		if (IS_ERR(phy)) {
			ret = PTR_ERR(phy);
			goto put_usb2_hcd;
		}
		mtk->phys[phy_num] = phy;
	}

	ret = xhci_mtk_phy_init(mtk);
	if (ret)
		goto put_usb2_hcd;

	ret = xhci_mtk_phy_power_on(mtk);
	if (ret)
		goto exit_phys;

	device_init_wakeup(dev, true);

	xhci = hcd_to_xhci(hcd);
	xhci->main_hcd = hcd;
	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
			dev_name(dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto power_off_phys;
	}

	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
		xhci->shared_hcd->can_do_streams = 1;

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto dealloc_usb2_hcd;

	return 0;

dealloc_usb2_hcd:
	usb_remove_hcd(hcd);

put_usb3_hcd:
	xhci_mtk_sch_exit(mtk);
	usb_put_hcd(xhci->shared_hcd);

power_off_phys:
	xhci_mtk_phy_power_off(mtk);
	device_init_wakeup(dev, false);

exit_phys:
	xhci_mtk_phy_exit(mtk);

put_usb2_hcd:
	usb_put_hcd(hcd);

disable_clk:
	xhci_mtk_clks_disable(mtk);

disable_ldos:
	xhci_mtk_ldos_disable(mtk);

disable_pm:
	pm_runtime_put_sync(dev);
	pm_runtime_disable(dev);
	return ret;
}
static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
{
    struct usb_hcd *hcd ;
    struct spear_ehci *ehci;
    struct resource *res;
    struct clk *usbh_clk;
    const struct hc_driver *driver = &ehci_spear_hc_driver;
    int *pdata = pdev->dev.platform_data;
    int irq, retval;
    char clk_name[20] = "usbh_clk";

    if (pdata == NULL)
        return -EFAULT;

    if (usb_disabled())
        return -ENODEV;

    irq = platform_get_irq(pdev, 0);
    if (irq < 0) {
        retval = irq;
        goto fail_irq_get;
    }

    if (*pdata >= 0)
        sprintf(clk_name, "usbh.%01d_clk", *pdata);

    usbh_clk = clk_get(NULL, clk_name);
    if (IS_ERR(usbh_clk)) {
        dev_err(&pdev->dev, "Error getting interface clock\n");
        retval = PTR_ERR(usbh_clk);
        goto fail_get_usbh_clk;
    }

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

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res) {
        retval = -ENODEV;
        goto fail_request_resource;
    }

    hcd->rsrc_start = res->start;
    hcd->rsrc_len = resource_size(res);
    if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
                            driver->description)) {
        retval = -EBUSY;
        goto fail_request_resource;
    }

    hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
    if (hcd->regs == NULL) {
        dev_dbg(&pdev->dev, "error mapping memory\n");
        retval = -ENOMEM;
        goto fail_ioremap;
    }

    ehci = (struct spear_ehci *)hcd_to_ehci(hcd);
    ehci->clk = usbh_clk;

    spear_start_ehci(ehci);
    retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
    if (retval)
        goto fail_add_hcd;

    return retval;

fail_add_hcd:
    spear_stop_ehci(ehci);
    iounmap(hcd->regs);
fail_ioremap:
    release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
fail_request_resource:
    usb_put_hcd(hcd);
fail_create_hcd:
    clk_put(usbh_clk);
fail_get_usbh_clk:
fail_irq_get:
    dev_err(&pdev->dev, "init fail, %d\n", retval);

    return retval ;
}
Пример #8
0
int usb_ehci_ar9130_probe(struct hc_driver *driver,
        struct usb_hcd **hcd_out,
        struct platform_device *pdev)
{
    struct usb_hcd *hcd;
    int ret;
    struct ehci_hcd *ehci;

    ar9130_debug_dev("No of Resources %d \n",pdev->num_resources);

    /* Verify the Host Mode of the Driver */
    if (pdev->resource[1].flags != IORESOURCE_IRQ) {
        printk ("resource[1] is not IORESOURCE_IRQ");
        ret = -ENOMEM;
    }

    hcd = usb_create_hcd(driver,&pdev->dev,pdev->dev.bus_id);
    if(!hcd){
        ret = -ENOMEM;
        goto err;
    }
    hcd->rsrc_start = pdev->resource[0].start;
    hcd->rsrc_len   = pdev->resource[0].end - pdev->resource[0].start + 1;

    if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
                driver->description)) {
        dev_dbg(&pdev->dev, "controller already in use\n");
        ret = -EBUSY;
        goto err1;
    }

    hcd->regs = ioremap(hcd->rsrc_start,hcd->rsrc_len);
    if(hcd->regs == NULL){
        dev_dbg(&pdev->dev,"error mapping memory \n");
        ret = -EFAULT;
        goto err2;
    }

    /* EHCI Register offset 0x100 - Info from ChipIdea */
    ehci =hcd_to_ehci(hcd);
    ehci->caps = hcd->regs + 0x100;     /* Device/Host Capa Reg*/
    ehci->regs = hcd->regs + 0x140;     /* Device/Host Oper Reg*/

    ar9130_debug_dev("hcd->regs %p \n",hcd->regs);
    ar9130_debug_dev("Host Capability Reg %p \n",ehci->caps);
    ar9130_debug_dev("Host Operational Reg %p \n",ehci->regs);

	/* Added 5_29_07 */
	ar9130_reg_rmw_set(AR9130_RESET,AR9130_RESET_USBSUS_OVRIDE);
	mdelay(10);
	

	ar9130_reg_wr(AR9130_RESET,((ar9130_reg_rd(AR9130_RESET) & ~(AR9130_RESET_USB_HOST)) |
							   AR9130_RESET_USBSUS_OVRIDE));

    mdelay(10);

	ar9130_reg_wr(AR9130_RESET,((ar9130_reg_rd(AR9130_RESET) & ~(AR9130_RESET_USB_PHY)) |
							   AR9130_RESET_USBSUS_OVRIDE));

    mdelay(10);

    printk("Port Status %x \n",readl(&ehci->regs->port_status[0])); // 26thFeb
    ret = usb_add_hcd(hcd,pdev->resource[1].start,SA_INTERRUPT | SA_SHIRQ);

	
    if(ret != 0){
        goto err3;
    }
    return ret;

err3:
    iounmap(hcd->regs);
err2:
    release_mem_region(hcd->rsrc_start,hcd->rsrc_len);
err1:
    usb_put_hcd(hcd);
err:
    dev_err(&pdev->dev,"init %s fail, %d \n",pdev->dev.bus_id,ret);
    return ret;
}
Пример #9
0
int usb_otg_ar9130_probe(struct hc_driver *driver)
{
    struct ar9130_otg *ar9130_otg;
    struct usb_hcd *hcd;
    struct ehci_hcd *ehci;
    struct device *dev;
    int ret;

    ar9130_otg = ar9130_get_otg();
    if (ar9130_otg == NULL) {
        return -EINVAL;
    }
    dev = ar9130_otg->dev;

    hcd = usb_create_hcd(driver, dev, dev->bus_id);
    if(!hcd){
        ret = -ENOMEM;
        goto err;
    }
    hcd->rsrc_start = 0;
    hcd->rsrc_len   = 0;

    hcd->regs = ar9130_otg->reg_base;
    if(hcd->regs == NULL){
        dev_dbg(dev,"error mapping memory \n");
        ret = -EFAULT;
        goto err1;
    }

    /* EHCI Register offset 0x100 - Info from ChipIdea */
    ehci = hcd_to_ehci(hcd);
    ehci->caps = hcd->regs + 0x100;     /* Device/Host Capa Reg*/
    ehci->regs = hcd->regs + 0x140;     /* Device/Host Oper Reg*/

    ar9130_otg->ehci = ehci; /* Temp To Test HNP */

    printk("hcd->regs %p, %p \n", hcd, hcd->regs);
    printk("Host Capability Reg %p \n",ehci->caps);
    printk("Host Operational Reg %p \n",ehci->regs);

    ehci->transceiver = &ar9130_otg->otg;

    printk ("usb_add_hcd\n");
    ret = usb_add_hcd(hcd, 0, 0);
    if(ret != 0){
        goto err1;
    }
    dev_set_drvdata(dev, hcd);

    ehci_hc_ar9130_driver.irq = ehci_irq;
    ret = ar9130_start_hc(ehci, dev);
    if (ret != 0) {
        goto err1;
    }

    return ret;

err1:
    usb_put_hcd(hcd);
err:
    dev_err(dev,"init %s fail, %d \n", dev->bus_id, ret);
    return ret;
}
Пример #10
0
static int __devinit uhci_hcd_grlib_probe(struct platform_device *op)
{
	struct device_node *dn = op->dev.of_node;
	struct usb_hcd *hcd;
	struct uhci_hcd	*uhci = NULL;
	struct resource res;
	int irq;
	int rv;

	if (usb_disabled())
		return -ENODEV;

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

	rv = of_address_to_resource(dn, 0, &res);
	if (rv)
		return rv;

	/* usb_create_hcd requires dma_mask != NULL */
	op->dev.dma_mask = &op->dev.coherent_dma_mask;
	hcd = usb_create_hcd(&uhci_grlib_hc_driver, &op->dev,
			"GRUSBHC UHCI USB");
	if (!hcd)
		return -ENOMEM;

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

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
		rv = -EBUSY;
		goto err_rmr;
	}

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

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

	uhci = hcd_to_uhci(hcd);

	uhci->regs = hcd->regs;

	rv = usb_add_hcd(hcd, irq, 0);
	if (rv)
		goto err_uhci;

	return 0;

err_uhci:
	iounmap(hcd->regs);
err_ioremap:
	irq_dispose_mapping(irq);
err_irq:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_rmr:
	usb_put_hcd(hcd);

	return rv;
}
Пример #11
0
static int host_start(struct ci_hdrc *ci)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct ehci_ci_priv *priv;
	int ret;

	if (usb_disabled())
		return -ENODEV;

	hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev));
	if (!hcd)
		return -ENOMEM;

	dev_set_drvdata(ci->dev, ci);
	hcd->rsrc_start = ci->hw_bank.phys;
	hcd->rsrc_len = ci->hw_bank.size;
	hcd->regs = ci->hw_bank.abs;
	hcd->has_tt = 1;

	hcd->power_budget = ci->platdata->power_budget;
	hcd->tpl_support = ci->platdata->tpl_support;
	if (ci->phy)
		hcd->phy = ci->phy;
	else
		hcd->usb_phy = ci->usb_phy;

	ehci = hcd_to_ehci(hcd);
	ehci->caps = ci->hw_bank.cap;
	ehci->has_hostpc = ci->hw_bank.lpm;
	ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
	ehci->imx28_write_fix = ci->imx28_write_fix;

	priv = (struct ehci_ci_priv *)ehci->priv;
	priv->reg_vbus = NULL;

	if (ci->platdata->reg_vbus)
		priv->reg_vbus = ci->platdata->reg_vbus;

	ret = usb_add_hcd(hcd, 0, 0);
	if (ret) {
		goto put_hcd;
	} else {
		struct usb_otg *otg = &ci->otg;

		ci->hcd = hcd;

		if (ci_otg_is_fsm_mode(ci)) {
			otg->host = &hcd->self;
			hcd->self.otg_port = 1;
		}
	}

	if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);

	return ret;

put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Пример #12
0
static int ehci_rkhsic_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct resource *res;
	struct device *dev = &pdev->dev;
	struct rkehci_platform_data *pldata;
	int ret;
	int retval = 0;
	static u64 usb_dmamask = 0xffffffffUL;
	struct device_node *node = pdev->dev.of_node;
	struct rkehci_pdata_id *p;
	const struct of_device_id *match =
		of_match_device(of_match_ptr( rk_hsic_of_match ), &pdev->dev);

	dev_dbg(&pdev->dev, "ehci_rkhsic proble\n");

	if (match){
		p = (struct rkehci_pdata_id *)match->data;
	}else{
		dev_err(dev, "ehci_rkhsic match failed\n");
		return -EINVAL;
	}

	dev->platform_data = p->pdata;
	pldata = dev->platform_data;
	pldata->dev = dev;

	if (!node) {
		dev_err(dev, "device node not found\n");
		return -EINVAL;
	}

	dev->dma_mask = &usb_dmamask;

	retval = device_create_file(dev, &dev_attr_ehci_rkhsic_power);
	retval = device_create_file(dev, &dev_attr_hsic_debug_ehci);
	hcd = usb_create_hcd(&rk_hsic_driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return  -ENOMEM;
	}
	
	if(pldata->hw_init)
		pldata->hw_init();

	if(pldata->clock_init){
		pldata->clock_init(pldata);
		pldata->clock_enable(pldata, 1);
	}
	
	if(pldata->soft_reset)
		pldata->soft_reset();

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get memory resource\n");
		ret = -ENODEV;
		goto put_hcd;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = devm_ioremap_resource(dev, res);

	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto put_hcd;
	}
	
	hcd->irq = platform_get_irq(pdev, 0);
	if (hcd->irq < 0) {
		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
		ret = hcd->irq;
		goto put_hcd;
	}
	
	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;
	ehci->regs = hcd->regs + 0x10;
	printk("%s %p %p\n", __func__, ehci->caps, ehci->regs);
    
	dbg_hcs_params(ehci, "reset");
	dbg_hcc_params(ehci, "reset");

	ehci->hcs_params = readl(&ehci->caps->hcs_params);

	ret = usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add USB HCD\n");
		goto put_hcd;
	}
	
	g_hsic_ehci = ehci;
	ehci_rkhsic_port_power(ehci, 1);
	writel_relaxed(1 ,hcd->regs +0xb0);
	writel_relaxed(0x1d4d ,hcd->regs +0x90);
	writel_relaxed(0x4 ,hcd->regs +0xa0);
	dsb();


	printk("%s ok\n", __func__);

	return 0;

put_hcd:
	if(pldata->clock_enable)
		pldata->clock_enable(pldata, 0);
	usb_put_hcd(hcd);

	return ret;
}
Пример #13
0
/**
 * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 */
static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
				  struct platform_device *dev)
{
	struct usb_hcd *hcd = NULL;
	int retval;

	s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
	s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

	hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
	if (hcd == NULL)
		return -ENOMEM;

	hcd->rsrc_start = dev->resource[0].start;
	hcd->rsrc_len	= resource_size(&dev->resource[0]);

	printk("gjl usb_hcd_s3c2410_probe here 000!\n");

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

	printk("gjl usb_hcd_s3c2410_probe here 11111!\n");

	clk = clk_get(&dev->dev, "usb-host");
	if (IS_ERR(clk)) {
		dev_err(&dev->dev, "cannot get usb-host clock\n");
		retval = PTR_ERR(clk);
		goto err_mem;
	}

	usb_clk = clk_get(&dev->dev, "usb-bus-host");
	if (IS_ERR(usb_clk)) {
		dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
		retval = PTR_ERR(usb_clk);
		goto err_clk;
	}
// gjl
	otg_clk = clk_get(&dev->dev, "otg");
	if (IS_ERR(otg_clk)) {
		dev_err(&dev->dev, "cannot get otg clock\n");
		retval = -ENOENT;
		goto err_otg;
	}
	s3c2410_start_hc(dev, hcd);

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&dev->dev, "ioremap failed\n");
		retval = -ENOMEM;
		goto err_ioremap;
	}

	ohci_hcd_init(hcd_to_ohci(hcd));

	retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
	if (retval != 0)
		goto err_ioremap;

	return 0;

 err_ioremap:
	s3c2410_stop_hc(dev);
	iounmap(hcd->regs);
	clk_put(usb_clk);

err_otg:  // gjl 
	clk_put(otg_clk);
 
err_clk:
	clk_put(clk);

err_mem:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);

err_put:
	usb_put_hcd(hcd);
	return retval;
}
Пример #14
0
/**
 * usb_hcd_pci_probe - initialize PCI-based HCDs
 * @dev: USB Host Controller being probed
 * @id: pci hotplug id connecting controller to HCD framework
 * Context: !in_interrupt()
 *
 * Allocates basic PCI resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct hc_driver	*driver;
	struct usb_hcd		*hcd;
	int			retval;

	if (usb_disabled())
		return -ENODEV;

	if (!id)
		return -EINVAL;
	driver = (struct hc_driver *)id->driver_data;
	if (!driver)
		return -EINVAL;

	if (pci_enable_device(dev) < 0)
		return -ENODEV;
	dev->current_state = PCI_D0;

	if (!dev->irq) {
		dev_err(&dev->dev,
			"Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
			pci_name(dev));
		retval = -ENODEV;
		goto err1;
	}

	hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err1;
	}

	if (driver->flags & HCD_MEMORY) {
		/* EHCI, OHCI */
		hcd->rsrc_start = pci_resource_start(dev, 0);
		hcd->rsrc_len = pci_resource_len(dev, 0);
		if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
				driver->description)) {
			dev_dbg(&dev->dev, "controller already in use\n");
			retval = -EBUSY;
			goto err2;
		}
		hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
		if (hcd->regs == NULL) {
			dev_dbg(&dev->dev, "error mapping memory\n");
			retval = -EFAULT;
			goto err3;
		}

	} else {
		/* UHCI */
		int	region;

		for (region = 0; region < PCI_ROM_RESOURCE; region++) {
			if (!(pci_resource_flags(dev, region) &
					IORESOURCE_IO))
				continue;

			hcd->rsrc_start = pci_resource_start(dev, region);
			hcd->rsrc_len = pci_resource_len(dev, region);
			if (request_region(hcd->rsrc_start, hcd->rsrc_len,
					driver->description))
				break;
		}
		if (region == PCI_ROM_RESOURCE) {
			dev_dbg(&dev->dev, "no i/o regions available\n");
			retval = -EBUSY;
			goto err1;
		}
	}

	pci_set_master(dev);

	retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval != 0)
		goto err4;
	return retval;

 err4:
	if (driver->flags & HCD_MEMORY) {
		iounmap(hcd->regs);
 err3:
		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	} else
		release_region(hcd->rsrc_start, hcd->rsrc_len);
 err2:
	usb_put_hcd(hcd);
 err1:
	pci_disable_device(dev);
	dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
	return retval;
}
Пример #15
0
/**
 * usb_hcd_msp_probe - initialize PMC MSP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 */
int usb_hcd_msp_probe(const struct hc_driver *driver,
			  struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd;
	struct resource *res;
	struct ehci_hcd		*ehci ;

	hcd = usb_create_hcd(driver, &dev->dev, "pmcmsp");
	if (!hcd)
		return -ENOMEM;

	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		pr_debug("No IOMEM resource info for %s.\n", dev->name);
		retval = -ENOMEM;
		goto err1;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, dev->name)) {
		retval = -EBUSY;
		goto err1;
	}
	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		pr_debug("ioremap failed");
		retval = -ENOMEM;
		goto err2;
	}

	res = platform_get_resource(dev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(&dev->dev, "No IRQ resource info for %s.\n", dev->name);
		retval = -ENOMEM;
		goto err3;
	}

	/* Map non-EHCI register spaces */
	retval = usb_hcd_msp_map_regs(to_mspusb_device(dev));
	if (retval != 0)
		goto err3;

	ehci = hcd_to_ehci(hcd);
	ehci->big_endian_mmio = 1;
	ehci->big_endian_desc = 1;


	retval = usb_add_hcd(hcd, res->start, IRQF_SHARED);
	if (retval == 0)
		return 0;

	usb_remove_hcd(hcd);
err3:
	iounmap(hcd->regs);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);

	return retval;
}
Пример #16
0
static int ixp4xx_ehci_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	const struct hc_driver *driver = &ixp4xx_ehci_hc_driver;
	struct resource *res;
	int irq;
	int retval;

	if (usb_disabled())
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no IRQ. Check %s setup!\n",
			dev_name(&pdev->dev));
		return -ENODEV;
	}
	irq = res->start;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no register addr. Check %s setup!\n",
			dev_name(&pdev->dev));
		retval = -ENODEV;
		goto fail_request_resource;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = res->end - res->start + 1;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
				driver->description)) {
		dev_dbg(&pdev->dev, "controller already in use\n");
		retval = -EBUSY;
		goto fail_request_resource;
	}

	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto fail_ioremap;
	}

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

	return retval;

fail_add_hcd:
	iounmap(hcd->regs);
fail_ioremap:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
fail_request_resource:
	usb_put_hcd(hcd);
fail_create_hcd:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	return retval;
}
Пример #17
0
/*
 * We need to register our own PCI probe function (instead of the USB core's
 * function) in order to create a second roothub under xHCI.
 */
static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
    int retval;
    struct xhci_hcd *xhci;
    struct hc_driver *driver;
    struct usb_hcd *hcd;

    driver = (struct hc_driver *)id->driver_data;

    /* Prevent runtime suspending between USB-2 and USB-3 initialization */
    pm_runtime_get_noresume(&dev->dev);

    /* Register the USB 2.0 roothub.
     * FIXME: USB core must know to register the USB 2.0 roothub first.
     * This is sort of silly, because we could just set the HCD driver flags
     * to say USB 2.0, but I'm not sure what the implications would be in
     * the other parts of the HCD code.
     */
    retval = usb_hcd_pci_probe(dev, id);

    if (retval)
        goto put_runtime_pm;

    /* USB 2.0 roothub is stored in the PCI device now. */
    hcd = dev_get_drvdata(&dev->dev);
    xhci = hcd_to_xhci(hcd);
    xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,
                       pci_name(dev), hcd);
    if (!xhci->shared_hcd) {
        retval = -ENOMEM;
        goto dealloc_usb2_hcd;
    }

    /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset)
     * is called by usb_add_hcd().
     */
    *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

    retval = usb_add_hcd(xhci->shared_hcd, dev->irq,
                         IRQF_SHARED);
    if (retval)
        goto put_usb3_hcd;
    /* Roothub already marked as USB 3.0 speed */

    if (!(xhci->quirks & XHCI_BROKEN_STREAMS) &&
            HCC_MAX_PSA(xhci->hcc_params) >= 4)
        xhci->shared_hcd->can_do_streams = 1;

    /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */
    pm_runtime_put_noidle(&dev->dev);

    return 0;

put_usb3_hcd:
    usb_put_hcd(xhci->shared_hcd);
dealloc_usb2_hcd:
    usb_hcd_pci_remove(dev);
put_runtime_pm:
    pm_runtime_put_noidle(&dev->dev);
    return retval;
}
Пример #18
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval, irq;
	struct usb_hcd *hcd = 0;

	if (pdev->num_resources != 2) {
		dev_err(&pdev->dev, "invalid num_resources: %i\n",
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM
			|| pdev->resource[1].flags != IORESOURCE_IRQ) {
		dev_err(&pdev->dev, "invalid resource type\n");
		return -ENODEV;
	}

	usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
	if (IS_ERR(usb_host_ck))
		return PTR_ERR(usb_host_ck);

	if (!cpu_is_omap15xx())
		usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
	else
		usb_dc_ck = clk_get(&pdev->dev, "lb_ck");

	if (IS_ERR(usb_dc_ck)) {
		clk_put(usb_host_ck);
		return PTR_ERR(usb_dc_ck);
	}


	hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}
	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
		retval = -ENOMEM;
		goto err2;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		retval = -ENXIO;
		goto err3;
	}
	retval = usb_add_hcd(hcd, irq, 0);
	if (retval)
		goto err3;

	device_wakeup_enable(hcd->self.controller);
	return 0;
err3:
	iounmap(hcd->regs);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);
err0:
	clk_put(usb_dc_ck);
	clk_put(usb_host_ck);
	return retval;
}
Пример #19
0
static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;
	const struct hc_driver *driver = &ohci_pnx4008_hc_driver;
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;

	int ret = 0, irq;

	dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name);
	if (usb_disabled()) {
		err("USB is disabled");
		ret = -ENODEV;
		goto out;
	}

	if (pdev->num_resources != 2
	    || pdev->resource[0].flags != IORESOURCE_MEM
	    || pdev->resource[1].flags != IORESOURCE_IRQ) {
		err("Invalid resource configuration");
		ret = -ENODEV;
		goto out;
	}

	/* Enable AHB slave USB clock, needed for further USB clock control */
	__raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL);

	ret = i2c_add_driver(&isp1301_driver);
	if (ret < 0) {
		err("failed to add ISP1301 driver");
		goto out;
	}
	i2c_adap = i2c_get_adapter(2);
	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE);
	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c);
	i2c_put_adapter(i2c_adap);
	if (!isp1301_i2c_client) {
		err("failed to connect I2C to ISP1301 USB Transceiver");
		ret = -ENODEV;
		goto out_i2c_driver;
	}

	isp1301_configure();

	/* Enable USB PLL */
	usb_clk = clk_get(&pdev->dev, "ck_pll5");
	if (IS_ERR(usb_clk)) {
		err("failed to acquire USB PLL");
		ret = PTR_ERR(usb_clk);
		goto out1;
	}

	ret = clk_enable(usb_clk);
	if (ret < 0) {
		err("failed to start USB PLL");
		goto out2;
	}

	ret = clk_set_rate(usb_clk, 48000);
	if (ret < 0) {
		err("failed to set USB clock rate");
		goto out3;
	}

	__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);

	/* Set to enable all needed USB clocks */
	__raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL);

	while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
	       USB_CLOCK_MASK) ;

	hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		err("Failed to allocate HC buffer");
		ret = -ENOMEM;
		goto out3;
	}

	/* Set all USB bits in the Start Enable register */
	pnx4008_set_usb_bits();

	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		ret =  -ENOMEM;
		goto out4;
	}
	hcd->regs = (void __iomem *)pdev->resource[0].start;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = -ENXIO;
		goto out4;
	}

	pnx4008_start_hc();
	platform_set_drvdata(pdev, hcd);
	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);

	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
	if (ret == 0)
		return ret;

	pnx4008_stop_hc();
out4:
	pnx4008_unset_usb_bits();
	usb_put_hcd(hcd);
out3:
	clk_disable(usb_clk);
out2:
	clk_put(usb_clk);
out1:
	i2c_unregister_device(isp1301_i2c_client);
	isp1301_i2c_client = NULL;
out_i2c_driver:
	i2c_del_driver(&isp1301_driver);
out:
	return ret;
}
Пример #20
0
static int ehci_oxnas_drv_probe(struct platform_device *ofdev)
{
	struct device_node *np = ofdev->dev.of_node;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct resource res;
	struct oxnas_hcd *oxnas;
	int irq, err;
	struct reset_control *rstc;

	if (usb_disabled())
		return -ENODEV;

	if (!ofdev->dev.dma_mask)
		ofdev->dev.dma_mask = &ofdev->dev.coherent_dma_mask;
	if (!ofdev->dev.coherent_dma_mask)
		ofdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

	hcd = usb_create_hcd(&oxnas_hc_driver,	&ofdev->dev,
					dev_name(&ofdev->dev));
	if (!hcd)
		return -ENOMEM;

	err = of_address_to_resource(np, 0, &res);
	if (err)
		goto err_res;

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

	hcd->regs = devm_ioremap_resource(&ofdev->dev, &res);
	if (IS_ERR(hcd->regs)) {
		dev_err(&ofdev->dev, "devm_ioremap_resource failed\n");
		err = PTR_ERR(hcd->regs);
		goto err_ioremap;
	}

	oxnas = (struct oxnas_hcd *)hcd_to_ehci(hcd)->priv;

	oxnas->use_pllb = of_property_read_bool(np, "plxtech,ehci_use_pllb");
	oxnas->use_phya = of_property_read_bool(np, "plxtech,ehci_use_phya");

	oxnas->clk = of_clk_get_by_name(np, "usb");
	if (IS_ERR(oxnas->clk)) {
		err = PTR_ERR(oxnas->clk);
		goto err_clk;
	}

	if (oxnas->use_pllb) {
		oxnas->refsrc = of_clk_get_by_name(np, "refsrc");
		if (IS_ERR(oxnas->refsrc)) {
			err = PTR_ERR(oxnas->refsrc);
			goto err_refsrc;
		}
		oxnas->phyref = of_clk_get_by_name(np, "phyref");
		if (IS_ERR(oxnas->refsrc)) {
			err = PTR_ERR(oxnas->refsrc);
			goto err_phyref;
		}

	} else {
		oxnas->refsrc = NULL;
		oxnas->phyref = NULL;
	}

	rstc = devm_reset_control_get(&ofdev->dev, "host");
	if (IS_ERR(rstc)) {
		err = PTR_ERR(rstc);
		goto err_rst;
	}
	oxnas->rst_host = rstc;

	rstc = devm_reset_control_get(&ofdev->dev, "phya");
	if (IS_ERR(rstc)) {
		err = PTR_ERR(rstc);
		goto err_rst;
	}
	oxnas->rst_phya = rstc;

	rstc = devm_reset_control_get(&ofdev->dev, "phyb");
	if (IS_ERR(rstc)) {
		err = PTR_ERR(rstc);
		goto err_rst;
	}
	oxnas->rst_phyb = rstc;

	irq = irq_of_parse_and_map(np, 0);
	if (!irq) {
		dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
		err = -EBUSY;
		goto err_irq;
	}

	hcd->has_tt = 1;
	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;

	start_oxnas_usb_ehci(oxnas);

	err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
	if (err)
		goto err_hcd;

	return 0;

err_hcd:
	stop_oxnas_usb_ehci(oxnas);
err_irq:
err_rst:
	if (oxnas->phyref)
		clk_put(oxnas->phyref);
err_phyref:
	if (oxnas->refsrc)
		clk_put(oxnas->refsrc);
err_refsrc:
	clk_put(oxnas->clk);
err_clk:
err_ioremap:
err_res:
	usb_put_hcd(hcd);

	return err;
}
static int sw_ohci_hcd_probe(struct platform_device *pdev)
{
	int ret;
	struct usb_hcd *hcd = NULL;
	struct sw_hci_hcd *sw_ohci = NULL;

	if(pdev == NULL){
	    DMSG_PANIC("ERR: Argment is invaild\n");
	    return -1;
    }

    /* if usb is disabled, can not probe */
    if (usb_disabled()){
        DMSG_PANIC("ERR: usb hcd is disabled\n");
        return -ENODEV;
    }

	sw_ohci = pdev->dev.platform_data;
	if(!sw_ohci){
		DMSG_PANIC("ERR: sw_ohci is null\n");
		ret = -ENOMEM;
		goto ERR1;
	}

	sw_ohci->pdev = pdev;
	g_sw_ohci[sw_ohci->usbc_no] = sw_ohci;

	DMSG_INFO("[%s%d]: probe, pdev->name: %s, pdev->id: %d, sw_ohci: 0x%p\n",
		      ohci_name, sw_ohci->usbc_no, pdev->name, pdev->id, sw_ohci);

	/* get io resource */
	sw_get_io_resource(pdev, sw_ohci);
	sw_ohci->ohci_base 			= sw_ohci->usb_vbase + SW_USB_OHCI_BASE_OFFSET;
	sw_ohci->ohci_reg_length 	= SW_USB_OHCI_LEN;

    /*creat a usb_hcd for the ohci controller*/
	hcd = usb_create_hcd(&sw_ohci_hc_driver, &pdev->dev, ohci_name);
	if(!hcd){
        DMSG_PANIC("ERR: usb_ohci_create_hcd failed\n");
        ret = -ENOMEM;
		goto ERR2;
	}

  	hcd->rsrc_start = (u32)sw_ohci->ohci_base;
	hcd->rsrc_len 	= sw_ohci->ohci_reg_length;
	hcd->regs 		= sw_ohci->ohci_base;
	sw_ohci->hcd    = hcd;

	/* ochi start to work */
	sw_start_ohc(sw_ohci);
    printk("[%s %d]:reg(0xf1c20060) = %x\n", __func__, __LINE__, *(u32 *)0xf1c20060);
    ohci_hcd_init(hcd_to_ohci(hcd));

    ret = usb_add_hcd(hcd, sw_ohci->irq_no, IRQF_DISABLED | IRQF_SHARED);
    if(ret != 0){
        DMSG_PANIC("ERR: usb_add_hcd failed\n");
        ret = -ENOMEM;
        goto ERR3;
    }

    platform_set_drvdata(pdev, hcd);

#ifdef  SW_USB_OHCI_DEBUG
    DMSG_INFO("[%s]: probe, clock: 0x60(0x%x), 0xcc(0x%x); usb: 0x800(0x%x), dram:(0x%x, 0x%x)\n",
              sw_ohci->hci_name,
              (u32)USBC_Readl(sw_ohci->clock_vbase + 0x60),
              (u32)USBC_Readl(sw_ohci->clock_vbase + 0xcc),
              (u32)USBC_Readl(sw_ohci->usb_vbase + 0x800),
              (u32)USBC_Readl(sw_ohci->sdram_vbase + SW_SDRAM_REG_HPCR_USB1),
              (u32)USBC_Readl(sw_ohci->sdram_vbase + SW_SDRAM_REG_HPCR_USB2));
#endif

	device_enable_async_suspend(&pdev->dev);
	sw_ohci->probe = 1;

    /* Disable ohci, when driver probe */
    if(sw_ohci->host_init_state == 0){
        if(ohci_first_probe[sw_ohci->usbc_no]){
            sw_usb_disable_ohci(sw_ohci->usbc_no);
            ohci_first_probe[sw_ohci->usbc_no]--;
        }
    }

    return 0;

ERR3:
	usb_put_hcd(hcd);

ERR2:
	sw_ohci->hcd = NULL;
	g_sw_ohci[sw_ohci->usbc_no] = NULL;

ERR1:

    return ret;
}
static int ehci_hcd_stm_probe(struct platform_device *pdev)
{
	int retval = 0;
	struct usb_hcd *hcd;
        struct ehci_hcd *ehci;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct platform_device *stm_usb_pdev;

	dgb_print("\n");
	hcd = usb_create_hcd(&ehci_stm_hc_driver, dev, dev->bus_id);
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}

	stm_usb_pdev = to_platform_device(pdev->dev.parent);

	res = platform_get_resource(stm_usb_pdev, IORESOURCE_MEM, 0);
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = res->end - res->start;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		pr_debug("request_mem_region failed");
		retval = -EBUSY;
		goto err1;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		pr_debug("ioremap failed");
		retval = -ENOMEM;
		goto err2;
	}

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

	/* cache this readonly data; minimize device reads */
	ehci->hcs_params = readl(&ehci->caps->hcs_params);

/*
 * Fix the reset port issue on a load-unload-load sequence
 */
	ehci->has_reset_port_bug = 1,
	res = platform_get_resource(stm_usb_pdev, IORESOURCE_IRQ, 0);
	retval = usb_add_hcd(hcd, res->start, 0);
	if (retval == 0) {
#ifdef CONFIG_PM
		hcd->self.root_hub->do_remote_wakeup = 0;
		hcd->self.root_hub->persist_enabled = 0;
		hcd->self.root_hub->autosuspend_disabled = 1;
		hcd->self.root_hub->autoresume_disabled = 1;
#endif
		return retval;
	}
	iounmap(hcd->regs);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);
err0:
	return retval;
}
static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct tilegx_usb_platform_data *pdata = pdev->dev.platform_data;
	pte_t pte = { 0 };
	int my_cpu = smp_processor_id();
	int ret;

	if (usb_disabled())
		return -ENODEV;

	/*
	 * Try to initialize our GXIO context; if we can't, the device
	 * doesn't exist.
	 */
	if (gxio_usb_host_init(&pdata->usb_ctx, pdata->dev_index, 1) != 0)
		return -ENXIO;

	hcd = usb_create_hcd(&ehci_tilegx_hc_driver, &pdev->dev,
			     dev_name(&pdev->dev));
	if (!hcd) {
          ret = -ENOMEM;
          goto err_hcd;
        }

	/*
	 * We don't use rsrc_start to map in our registers, but seems like
	 * we ought to set it to something, so we use the register VA.
	 */
	hcd->rsrc_start =
		(ulong) gxio_usb_host_get_reg_start(&pdata->usb_ctx);
	hcd->rsrc_len = gxio_usb_host_get_reg_len(&pdata->usb_ctx);
	hcd->regs = gxio_usb_host_get_reg_start(&pdata->usb_ctx);

	tilegx_start_ehc();

	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;
	ehci->regs =
		hcd->regs + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase));
	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = readl(&ehci->caps->hcs_params);

	/* Create our IRQs and register them. */
	pdata->irq = create_irq();
	if (pdata->irq < 0) {
		ret = -ENXIO;
		goto err_no_irq;
	}

	tile_irq_activate(pdata->irq, TILE_IRQ_PERCPU);

	/* Configure interrupts. */
	ret = gxio_usb_host_cfg_interrupt(&pdata->usb_ctx,
					  cpu_x(my_cpu), cpu_y(my_cpu),
					  KERNEL_PL, pdata->irq);
	if (ret) {
		ret = -ENXIO;
		goto err_have_irq;
	}

	/* Register all of our memory. */
	pte = pte_set_home(pte, PAGE_HOME_HASH);
	ret = gxio_usb_host_register_client_memory(&pdata->usb_ctx, pte, 0);
	if (ret) {
		ret = -ENXIO;
		goto err_have_irq;
	}

	ret = usb_add_hcd(hcd, pdata->irq, IRQF_SHARED);
	if (ret == 0) {
		platform_set_drvdata(pdev, hcd);
		return ret;
	}

err_have_irq:
	destroy_irq(pdata->irq);
err_no_irq:
	tilegx_stop_ehc();
	usb_put_hcd(hcd);
err_hcd:
	gxio_usb_host_destroy(&pdata->usb_ctx);
	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;
	}


	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;
	}

	
	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;

	

	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;
}
Пример #25
0
static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
{
	struct mfd_cell *cell = dev->dev.platform_data;
	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->dev.bus_id);
	if (!hcd) {
		ret = -ENOMEM;
		goto err_usb_create_hcd;
	}

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

	tmio = hcd_to_tmio(hcd);

	spin_lock_init(&tmio->lock);

	tmio->ccr = ioremap(config->start, config->end - config->start + 1);
	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,
				sram->end - sram->start + 1,
				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, IRQF_DISABLED);
	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;
}
Пример #26
0
static int xhci_plat_probe(struct platform_device *pdev)
{
	const struct hc_driver	*driver;
	struct xhci_hcd		*xhci;
	struct resource         *res;
	struct usb_hcd		*hcd;
	int			ret;
	int			irq;

	if (usb_disabled())
		return -ENODEV;

	driver = &xhci_plat_xhci_driver;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

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

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
				driver->description)) {
		dev_dbg(&pdev->dev, "controller already in use\n");
		ret = -EBUSY;
		goto put_hcd;
	}

	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		ret = -EFAULT;
		goto release_mem_region;
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto unmap_registers;

	/* USB 2.0 roothub is stored in the platform_device now. */
	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);
	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
			dev_name(&pdev->dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto dealloc_usb2_hcd;
	}

	/*
	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
	 * is called by usb_add_hcd().
	 */
	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	phy = usb_get_transceiver();
	if (phy && phy->otg) {
		dev_dbg(&pdev->dev, "%s otg support available\n", __func__);
		hcd->driver->stop(hcd);
		ret = otg_set_host(phy->otg, &hcd->self);
		if (ret) {
			dev_err(&pdev->dev, "%s otg_set_host failed\n",
				__func__);
			usb_put_transceiver(phy);
			goto put_usb3_hcd;
		}
	}

	return 0;

put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);

dealloc_usb2_hcd:
	usb_remove_hcd(hcd);

unmap_registers:
	iounmap(hcd->regs);

release_mem_region:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);

put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Пример #27
0
static int whc_probe(struct umc_dev *umc)
{
	int ret;
	struct usb_hcd *usb_hcd;
	struct wusbhc *wusbhc;
	struct whc *whc;
	struct device *dev = &umc->dev;

	usb_hcd = usb_create_hcd(&whc_hc_driver, dev, "whci");
	if (usb_hcd == NULL) {
		dev_err(dev, "unable to create hcd\n");
		return -ENOMEM;
	}

	usb_hcd->wireless = 1;
	usb_hcd->self.sg_tablesize = 2048; /* somewhat arbitrary */

	wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	whc = wusbhc_to_whc(wusbhc);
	whc->umc = umc;

	ret = whc_init(whc);
	if (ret)
		goto error;

	wusbhc->dev = dev;
	wusbhc->uwb_rc = uwb_rc_get_by_grandpa(umc->dev.parent);
	if (!wusbhc->uwb_rc) {
		ret = -ENODEV;
		dev_err(dev, "cannot get radio controller\n");
		goto error;
	}

	if (whc->n_devices > USB_MAXCHILDREN) {
		dev_warn(dev, "USB_MAXCHILDREN too low for WUSB adapter (%u ports)\n",
			 whc->n_devices);
		wusbhc->ports_max = USB_MAXCHILDREN;
	} else
		wusbhc->ports_max = whc->n_devices;
	wusbhc->mmcies_max      = whc->n_mmc_ies;
	wusbhc->start           = whc_wusbhc_start;
	wusbhc->stop            = whc_wusbhc_stop;
	wusbhc->mmcie_add       = whc_mmcie_add;
	wusbhc->mmcie_rm        = whc_mmcie_rm;
	wusbhc->dev_info_set    = whc_dev_info_set;
	wusbhc->bwa_set         = whc_bwa_set;
	wusbhc->set_num_dnts    = whc_set_num_dnts;
	wusbhc->set_ptk         = whc_set_ptk;
	wusbhc->set_gtk         = whc_set_gtk;

	ret = wusbhc_create(wusbhc);
	if (ret)
		goto error_wusbhc_create;

	ret = usb_add_hcd(usb_hcd, whc->umc->irq, IRQF_SHARED);
	if (ret) {
		dev_err(dev, "cannot add HCD: %d\n", ret);
		goto error_usb_add_hcd;
	}

	ret = wusbhc_b_create(wusbhc);
	if (ret) {
		dev_err(dev, "WUSBHC phase B setup failed: %d\n", ret);
		goto error_wusbhc_b_create;
	}

	whc_dbg_init(whc);

	return 0;

error_wusbhc_b_create:
	usb_remove_hcd(usb_hcd);
error_usb_add_hcd:
	wusbhc_destroy(wusbhc);
error_wusbhc_create:
	uwb_rc_put(wusbhc->uwb_rc);
error:
	whc_clean_up(whc);
	if (usb_hcd)
		usb_put_hcd(usb_hcd);
	return ret;
}
Пример #28
0
static int ehci_msm2_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	struct msm_hcd *mhcd;
	struct pinctrl_state *set_state;
	const struct msm_usb_host_platform_data *pdata;
	char pdev_name[PDEV_NAME_LEN];
	int ret;

	dev_dbg(&pdev->dev, "ehci_msm2 probe\n");

	/*
	 * Fail probe in case of uicc till userspace activates driver through
	 * sysfs entry.
	 */
	if (!uicc_card_present && pdev->dev.of_node && of_property_read_bool(
				pdev->dev.of_node, "qcom,usb2-enable-uicc"))
		return -ENODEV;

	hcd = usb_create_hcd(&ehci_msm2_hc_driver, &pdev->dev,
				dev_name(&pdev->dev));
	if (!hcd) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return  -ENOMEM;
	}

	mhcd = hcd_to_mhcd(hcd);
	mhcd->dev = &pdev->dev;

	mhcd->xo_clk = clk_get(&pdev->dev, "xo");
	if (IS_ERR(mhcd->xo_clk)) {
		ret = PTR_ERR(mhcd->xo_clk);
		mhcd->xo_clk = NULL;
		if (ret == -EPROBE_DEFER)
			goto put_hcd;
	}

	ret = msm_ehci_init_clocks(mhcd, 1);
	if (ret)
		goto xo_put;

	if (pdev->dev.of_node) {
		dev_dbg(&pdev->dev, "device tree enabled\n");
		pdev->dev.platform_data = ehci_msm2_dt_to_pdata(pdev);
	}

	if (!pdev->dev.platform_data)
		dev_dbg(&pdev->dev, "No platform data given\n");

	pdata = pdev->dev.platform_data;

	if (!pdev->dev.dma_mask)
		pdev->dev.dma_mask = &ehci_msm_dma_mask;
	if (!pdev->dev.coherent_dma_mask)
		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

	hcd_to_bus(hcd)->skip_resume = true;

	hcd->irq = platform_get_irq(pdev, 0);
	if (hcd->irq < 0) {
		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
		ret = hcd->irq;
		goto deinit_clocks;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get memory resource\n");
		ret = -ENODEV;
		goto deinit_clocks;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto deinit_clocks;
	}


	spin_lock_init(&mhcd->wakeup_lock);

	mhcd->async_irq = platform_get_irq_byname(pdev, "async_irq");
	if (mhcd->async_irq < 0) {
		dev_dbg(&pdev->dev, "platform_get_irq for async_int failed\n");
		mhcd->async_irq = 0;
	} else {
		ret = request_irq(mhcd->async_irq, msm_async_irq,
				IRQF_TRIGGER_RISING, "msm_ehci_host", mhcd);
		if (ret) {
			dev_err(&pdev->dev, "request irq failed (ASYNC INT)\n");
			goto unmap;
		}
		disable_irq(mhcd->async_irq);
	}

	snprintf(pdev_name, PDEV_NAME_LEN, "%s.%d", pdev->name, pdev->id);
	if (mhcd->xo_clk)
		ret = clk_prepare_enable(mhcd->xo_clk);
	if (ret) {
		dev_err(&pdev->dev, "%s failed to vote for TCXO %d\n",
								__func__, ret);
		goto free_xo_handle;
	}

	/* Get pinctrl if target uses pinctrl */
	mhcd->hsusb_pinctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(mhcd->hsusb_pinctrl)) {
		if (of_property_read_bool(pdev->dev.of_node, "pinctrl-names")) {
			dev_err(&pdev->dev, "Error encountered while getting pinctrl");
			ret = PTR_ERR(mhcd->hsusb_pinctrl);
			goto devote_xo_handle;
		}
		pr_debug("Target does not use pinctrl\n");
		mhcd->hsusb_pinctrl = NULL;
	}

	if (mhcd->hsusb_pinctrl) {
		set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl,
				"ehci_active");
		if (IS_ERR(set_state)) {
			pr_err("cannot get hsusb pinctrl active state\n");
			ret = PTR_ERR(set_state);
			goto devote_xo_handle;
		}
		ret = pinctrl_select_state(mhcd->hsusb_pinctrl, set_state);
		if (ret) {
			pr_err("cannot set hsusb pinctrl active state\n");
			goto devote_xo_handle;
		}
	}

	if (pdata && gpio_is_valid(pdata->resume_gpio)) {
		mhcd->resume_gpio = pdata->resume_gpio;
		ret = devm_gpio_request(&pdev->dev, mhcd->resume_gpio,
							"hsusb_resume");
		if (ret) {
			dev_err(&pdev->dev,
				"resume gpio(%d) request failed:%d\n",
				mhcd->resume_gpio, ret);
			mhcd->resume_gpio = -EINVAL;
		} else {
			/* to override ehci_bus_resume from ehci-hcd library */
			ehci_bus_resume_func = ehci_msm2_hc_driver.bus_resume;
			ehci_msm2_hc_driver.bus_resume =
				msm_ehci_bus_resume_with_gpio;
		}
	}

	if (pdata && gpio_is_valid(pdata->ext_hub_reset_gpio)) {
		ret = devm_gpio_request(&pdev->dev, pdata->ext_hub_reset_gpio,
							"hsusb_reset");
		if (ret) {
			dev_err(&pdev->dev,
				"reset gpio(%d) request failed:%d\n",
				pdata->ext_hub_reset_gpio, ret);
			goto pinctrl_sleep;
		} else {
			/* reset external hub */
			gpio_direction_output(pdata->ext_hub_reset_gpio, 0);
			/*
			 * Hub reset should be asserted for minimum 5microsec
			 * before deasserting.
			 */
			usleep_range(5, 1000);
			gpio_direction_output(pdata->ext_hub_reset_gpio, 1);
		}
	}

	spin_lock_init(&mhcd->wakeup_lock);

	ret = msm_ehci_init_vddcx(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize VDDCX\n");
		ret = -ENODEV;
		goto pinctrl_sleep;
	}

	ret = msm_ehci_config_vddcx(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "hsusb vddcx configuration failed\n");
		goto deinit_vddcx;
	}

	ret = msm_ehci_ldo_init(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "hsusb vreg configuration failed\n");
		goto deinit_vddcx;
	}

	ret = msm_ehci_ldo_enable(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "hsusb vreg enable failed\n");
		goto deinit_ldo;
	}

	ret = msm_ehci_init_vbus(mhcd, 1);
	if (ret)
		goto disable_ldo;

	hcd->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
	if (IS_ERR(hcd->phy)) {
		if (PTR_ERR(hcd->phy) == -EPROBE_DEFER) {
			dev_dbg(&pdev->dev, "usb-phy not probed yet\n");
			ret = -EPROBE_DEFER;
			goto vbus_deinit;
		}
		hcd->phy = NULL;
	}

	if (hcd->phy) {
		usb_phy_init(hcd->phy);
		/* Set Host mode flag */
		hcd->phy->flags |= PHY_HOST_MODE;
	} else if (pdata && pdata->use_sec_phy) {
		mhcd->usb_phy_ctrl_reg = USB_PHY_CTRL2;
	} else {
		mhcd->usb_phy_ctrl_reg = USB_PHY_CTRL;
	}

	ret = msm_hsusb_reset(mhcd);
	if (ret) {
		dev_err(&pdev->dev, "hsusb PHY initialization failed\n");
		goto vbus_deinit;
	}

	ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
	if (ret) {
		dev_err(&pdev->dev, "unable to register HCD\n");
		goto vbus_deinit;
	}

	mhcd->bus_scale_table = msm_bus_cl_get_pdata(pdev);
	if (!mhcd->bus_scale_table) {
		dev_dbg(&pdev->dev, "bus scaling is disabled\n");
	} else {
		mhcd->bus_perf_client =
			msm_bus_scale_register_client(mhcd->bus_scale_table);
		ret = msm_bus_scale_client_update_request(
						mhcd->bus_perf_client, 1);
		if (ret)
			dev_err(&pdev->dev, "Failed to vote for bus scaling\n");
	}

	pdata = mhcd->dev->platform_data;
	if (pdata && (!pdata->dock_connect_irq ||
				!irq_read_line(pdata->dock_connect_irq)))
		msm_ehci_vbus_power(mhcd, 1);

	/* For peripherals directly conneted to downstream port of root hub
	 * and require to drive suspend and resume by controller driver instead
	 * of root hub.
	 */
	if (pdata)
		mhcd->ehci.no_selective_suspend = pdata->no_selective_suspend;

	mhcd->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq");
	if (mhcd->wakeup_irq > 0) {
		dev_dbg(&pdev->dev, "wakeup irq:%d\n", mhcd->wakeup_irq);

		irq_set_status_flags(mhcd->wakeup_irq, IRQ_NOAUTOEN);
		ret = request_irq(mhcd->wakeup_irq, msm_hsusb_wakeup_irq,
				IRQF_TRIGGER_HIGH,
				"msm_hsusb_wakeup", mhcd);
		if (ret) {
			dev_err(&pdev->dev, "request_irq(%d) failed:%d\n",
					mhcd->wakeup_irq, ret);
			mhcd->wakeup_irq = 0;
		}
	} else {
		mhcd->wakeup_irq = 0;
	}

	device_init_wakeup(&pdev->dev, 1);
	wakeup_source_init(&mhcd->ws, dev_name(&pdev->dev));
	pm_stay_awake(mhcd->dev);
	INIT_WORK(&mhcd->phy_susp_fail_work, msm_ehci_phy_susp_fail_work);
	/*
	 * This pdev->dev is assigned parent of root-hub by USB core,
	 * hence, runtime framework automatically calls this driver's
	 * runtime APIs based on root-hub's state.
	 */
	/* configure pmic_gpio_irq for D+ change */
	if (pdata && pdata->pmic_gpio_dp_irq)
		mhcd->pmic_gpio_dp_irq = pdata->pmic_gpio_dp_irq;
	if (mhcd->pmic_gpio_dp_irq) {
		ret = request_threaded_irq(mhcd->pmic_gpio_dp_irq, NULL,
				msm_ehci_host_wakeup_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"msm_ehci_host_wakeup", mhcd);
		if (!ret) {
			disable_irq_nosync(mhcd->pmic_gpio_dp_irq);
		} else {
			dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
					mhcd->pmic_gpio_dp_irq, ret);
			mhcd->pmic_gpio_dp_irq = 0;
		}
	}

	if (pdata && pdata->pm_qos_latency)
		pm_qos_add_request(&mhcd->pm_qos_req_dma,
			PM_QOS_CPU_DMA_LATENCY, pdata->pm_qos_latency + 1);

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	if (ehci_debugfs_init(mhcd) < 0)
		dev_err(mhcd->dev, "%s: debugfs init failed\n", __func__);

	return 0;

vbus_deinit:
	msm_ehci_init_vbus(mhcd, 0);
disable_ldo:
	msm_ehci_ldo_enable(mhcd, 0);
deinit_ldo:
	msm_ehci_ldo_init(mhcd, 0);
deinit_vddcx:
	msm_ehci_init_vddcx(mhcd, 0);
pinctrl_sleep:
	if (mhcd->hsusb_pinctrl) {
		set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl,
				"ehci_sleep");
		if (IS_ERR(set_state))
			pr_err("cannot get hsusb pinctrl sleep state\n");
		else
			pinctrl_select_state(mhcd->hsusb_pinctrl, set_state);
	}
devote_xo_handle:
	if (mhcd->xo_clk)
		clk_disable_unprepare(mhcd->xo_clk);
free_xo_handle:
	if (mhcd->xo_clk) {
		clk_put(mhcd->xo_clk);
		mhcd->xo_clk = NULL;
	}
	if (mhcd->async_irq)
		free_irq(mhcd->async_irq, mhcd);
unmap:
	iounmap(hcd->regs);
deinit_clocks:
	msm_ehci_init_clocks(mhcd, 0);
xo_put:
	if (mhcd->xo_clk)
		clk_put(mhcd->xo_clk);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Пример #29
0
/**
 * usb_hcd_fsl_probe - initialize FSL-based HCDs
 * @drvier: Driver to be used for this HCD
 * @pdev: USB Host Controller being probed
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 */
int usb_hcd_fsl_probe(const struct hc_driver *driver,
		      struct platform_device *pdev)
{
	struct fsl_usb2_platform_data *pdata;
	struct usb_hcd *hcd;
	struct resource *res;
	int irq;
	int retval;

	pr_debug("initializing FSL-SOC USB Controller\n");

	/* Need platform data for setup */
	pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev,
			"No platform data for %s.\n", dev_name(&pdev->dev));
		return -ENODEV;
	}

	/*
	 * This is a host mode driver, verify that we're supposed to be
	 * in host mode.
	 */
	if (!((pdata->operating_mode == FSL_USB2_DR_HOST) ||
	      (pdata->operating_mode == FSL_USB2_MPH_HOST) ||
	      (pdata->operating_mode == FSL_USB2_DR_OTG))) {
		dev_err(&pdev->dev,
			"Non Host Mode configured for %s. Wrong driver linked.\n",
			dev_name(&pdev->dev));
		return -ENODEV;
	}

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

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no IRQ. Check %s setup!\n",
			dev_name(&pdev->dev));
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	if (pdata->operating_mode != FSL_USB2_DR_OTG) {
		if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
					driver->description)) {
			dev_dbg(&pdev->dev, "controller already in use\n");
			retval = -EBUSY;
			goto err2;
		}
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);

	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto err3;
	}
	pdata->regs = hcd->regs;

	/*
	 * do platform specific init: check the clock, grab/config pins, etc.
	 */
	if (pdata->platform_init && pdata->platform_init(pdev)) {
		retval = -ENODEV;
		goto err3;
	}

	fsl_platform_set_host_mode(hcd);
	hcd->power_budget = pdata->power_budget;

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

	if (pdata->operating_mode == FSL_USB2_DR_OTG) {
		struct ehci_hcd *ehci = hcd_to_ehci(hcd);

		dbg("pdev=0x%p  hcd=0x%p  ehci=0x%p\n", pdev, hcd, ehci);

		ehci->transceiver = otg_get_transceiver();
		dbg("ehci->transceiver=0x%p\n", ehci->transceiver);

		if (!ehci->transceiver) {
			printk(KERN_ERR "can't find transceiver\n");
			retval = -ENODEV;
			goto err5;
		}

		retval = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self);
		if (retval)
			otg_put_transceiver(ehci->transceiver);
	} else if ((pdata->operating_mode == FSL_USB2_MPH_HOST) || \
			(pdata->operating_mode == FSL_USB2_DR_HOST))
		fsl_platform_set_vbus_power(pdata, 1);

	if (pdata->suspended) {
		pdata->suspended = 0;
		if (pdata->already_suspended)
			pdata->already_suspended = 0;
	}

	fsl_platform_set_ahb_burst(hcd);
	ehci_testmode_init(hcd_to_ehci(hcd));
	return retval;
err5:
	usb_remove_hcd(hcd);
err4:
	iounmap(hcd->regs);
err3:
	if (pdata->operating_mode != FSL_USB2_DR_OTG)
		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	if (pdata->platform_uninit)
		pdata->platform_uninit(pdata);
	return retval;
}
Пример #30
0
static int __init ehci_orion_drv_probe(struct platform_device *pdev)
{
    struct orion_ehci_data *pd = pdev->dev.platform_data;
    struct resource *res;
    struct usb_hcd *hcd;
    struct ehci_hcd *ehci;
    void __iomem *regs;
    int irq, err;

    if (usb_disabled())
        return -ENODEV;

    pr_debug("Initializing Orion-SoC USB Host Controller\n");

    irq = platform_get_irq(pdev, 0);
    if (irq <= 0) {
        dev_err(&pdev->dev,
                "Found HC with no IRQ. Check %s setup!\n",
                pdev->dev.bus_id);
        err = -ENODEV;
        goto err1;
    }

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res) {
        dev_err(&pdev->dev,
                "Found HC with no register addr. Check %s setup!\n",
                pdev->dev.bus_id);
        err = -ENODEV;
        goto err1;
    }

    if (!request_mem_region(res->start, res->end - res->start + 1,
                            ehci_orion_hc_driver.description)) {
        dev_dbg(&pdev->dev, "controller already in use\n");
        err = -EBUSY;
        goto err1;
    }

    regs = ioremap(res->start, res->end - res->start + 1);
    if (regs == NULL) {
        dev_dbg(&pdev->dev, "error mapping memory\n");
        err = -EFAULT;
        goto err2;
    }

    hcd = usb_create_hcd(&ehci_orion_hc_driver,
                         &pdev->dev, pdev->dev.bus_id);
    if (!hcd) {
        err = -ENOMEM;
        goto err3;
    }

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

    ehci = hcd_to_ehci(hcd);
    ehci->caps = hcd->regs + 0x100;
    ehci->regs = hcd->regs + 0x100 +
                 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
    ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
    hcd->has_tt = 1;
    ehci->sbrn = 0x20;

    /*
     * (Re-)program MBUS remapping windows if we are asked to.
     */
    if (pd != NULL && pd->dram != NULL)
        ehci_orion_conf_mbus_windows(hcd, pd->dram);

    /*
     * setup Orion USB controller
     */
    orion_usb_setup(hcd);

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

    return 0;

err4:
    usb_put_hcd(hcd);
err3:
    iounmap(regs);
err2:
    release_mem_region(res->start, res->end - res->start + 1);
err1:
    dev_err(&pdev->dev, "init %s fail, %d\n",
            pdev->dev.bus_id, err);

    return err;
}