/**
 * usb_hcd_pxa27x_probe - initialize pxa27x-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_pxa27x_probe (const struct hc_driver *driver,
			  struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd;

	if (dev->resource[1].flags != IORESOURCE_IRQ) {
		pr_debug ("resource[1] is not IORESOURCE_IRQ");
		return -ENOMEM;
	}

	hcd = usb_create_hcd (driver, &dev->dev, "pxa27x");
	if (!hcd)
		return -ENOMEM;
	hcd->rsrc_start = dev->resource[0].start;
	hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;

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

	pxa27x_start_hc(dev);

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm( PMM_PERPORT_MODE );

	/* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */
	if (pxa27x_ohci_set_port_power(1) < 0)
		printk(KERN_ERR "Setting port 1 power failed.\n");

	if (pxa27x_ohci_clear_port_power(2) < 0)
		printk(KERN_ERR "Setting port 2 power failed.\n");

	if (pxa27x_ohci_clear_port_power(3) < 0)
		printk(KERN_ERR "Setting port 3 power failed.\n");

	ohci_hcd_init(hcd_to_ohci(hcd));

	retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
	if (retval == 0)
		return retval;

	pxa27x_stop_hc(dev);
	iounmap(hcd->regs);
 err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 err1:
	usb_put_hcd(hcd);
	return retval;
}
Beispiel #2
0
/**
 * usb_hcd_pxa27x_probe - initialize pxa27x-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_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd;
	struct pxaohci_platform_data *inf;

	inf = pdev->dev.platform_data;

	if (!inf)
		return -ENODEV;

	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
		pr_debug ("resource[1] is not IORESOURCE_IRQ");
		return -ENOMEM;
	}

	hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
	if (!hcd)
		return -ENOMEM;
	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)) {
		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;
	}

	if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
		pr_debug("pxa27x_start_hc failed");
		goto err3;
	}

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm(inf->port_mode);

	ohci_hcd_init(hcd_to_ohci(hcd));

	retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
	if (retval == 0)
		return retval;

	pxa27x_stop_hc(&pdev->dev);
 err3:
	iounmap(hcd->regs);
 err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 err1:
	usb_put_hcd(hcd);
	return retval;
}
Beispiel #3
0
static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
	struct pxaohci_platform_data *inf = dev->platform_data;
	int status;

	if (time_before(jiffies, ohci->ohci.next_statechange))
		msleep(5);
	ohci->ohci.next_statechange = jiffies;

	if ((status = pxa27x_start_hc(ohci, dev)) < 0)
		return status;

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm(ohci, inf->port_mode);

	ohci_finish_controller_resume(hcd);
	return 0;
}
Beispiel #4
0
static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
	struct pxaohci_platform_data *inf = dev_get_platdata(dev);
	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
	int status;

	if (time_before(jiffies, ohci->next_statechange))
		msleep(5);
	ohci->next_statechange = jiffies;

	status = pxa27x_start_hc(pxa_ohci, dev);
	if (status < 0)
		return status;

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);

	ohci_resume(hcd, false);
	return 0;
}
Beispiel #5
0
/**
 * usb_hcd_pxa27x_probe - initialize pxa27x-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_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
{
	int retval, irq;
	struct usb_hcd *hcd;
	struct pxaohci_platform_data *inf;
	struct pxa27x_ohci *ohci;
	struct resource *r;
	struct clk *usb_clk;

	inf = pdev->dev.platform_data;

	if (!inf)
		return -ENODEV;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		pr_err("no resource of IORESOURCE_IRQ");
		return -ENXIO;
	}

	usb_clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(usb_clk))
		return PTR_ERR(usb_clk);

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

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		pr_err("no resource of IORESOURCE_MEM");
		retval = -ENXIO;
		goto err1;
	}

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

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

	/* initialize "struct pxa27x_ohci" */
	ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
	ohci->dev = &pdev->dev;
	ohci->clk = usb_clk;
	ohci->mmio_base = (void __iomem *)hcd->regs;

	if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
		pr_debug("pxa27x_start_hc failed");
		goto err3;
	}

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm(ohci, inf->port_mode);

	if (inf->power_budget)
		hcd->power_budget = inf->power_budget;

	ohci_hcd_init(hcd_to_ohci(hcd));

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

	pxa27x_stop_hc(ohci, &pdev->dev);
 err3:
	iounmap(hcd->regs);
 err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 err1:
	usb_put_hcd(hcd);
 err0:
	clk_put(usb_clk);
	return retval;
}
Beispiel #6
0
/**
 * usb_hcd_pxa27x_probe - initialize pxa27x-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_pxa27x_probe (const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	unsigned int *addr = NULL;

	if (!request_mem_region(dev->resource[0].start,
				dev->resource[0].end
				- dev->resource[0].start + 1, hcd_name)) {
		pr_debug("request_mem_region failed");
		return -EBUSY;
	}

	pxa27x_start_hc(dev);

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm( PMM_PERPORT_MODE );

	/* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */
	if (pxa27x_ohci_set_port_power(1) < 0)
		printk(KERN_ERR "Setting port 1 power failed.\n");

	if (pxa27x_ohci_clear_port_power(2) < 0)
		printk(KERN_ERR "Setting port 2 power failed.\n");

	if (pxa27x_ohci_clear_port_power(3) < 0)
		printk(KERN_ERR "Setting port 3 power failed.\n");

	addr = ioremap(dev->resource[0].start,
		       dev->resource[0].end - dev->resource[0].start + 1);
	if (!addr) {
		pr_debug("ioremap failed");
		retval = -ENOMEM;
		goto err1;
	}

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		pr_debug ("hcd_alloc failed");
		retval = -ENOMEM;
		goto err1;
	}

	if(dev->resource[1].flags != IORESOURCE_IRQ){
		pr_debug ("resource[1] is not IORESOURCE_IRQ");
		retval = -ENOMEM;
		goto err1;
	}

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = dev->resource[1].start;
	hcd->regs = addr;
	hcd->self.controller = &dev->dev;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		pr_debug ("pool alloc fail");
		goto err1;
	}

	retval = request_irq (hcd->irq, usb_hcd_irq, SA_INTERRUPT,
			      hcd->description, hcd);
	if (retval != 0) {
		pr_debug("request_irq(%d) failed with retval %d\n",hcd->irq,retval);
		retval = -EBUSY;
		goto err2;
	}

	pr_debug ("%s (pxa27x) at 0x%p, irq %d",
	     hcd->description, hcd->regs, hcd->irq);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = "pxa27x";
	hcd->product_desc = "PXA27x OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);

	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) {
		usb_hcd_pxa27x_remove(hcd, dev);
		return retval;
	}

	*hcd_out = hcd;
	return 0;

 err2:
	hcd_buffer_destroy (hcd);
	if (hcd)
		driver->hcd_free(hcd);
 err1:
	pxa27x_stop_hc(dev);
	release_mem_region(dev->resource[0].start,
				dev->resource[0].end
			   - dev->resource[0].start + 1);
	return retval;
}
Beispiel #7
0
/**
 * ohci_hcd_pxa27x_probe - initialize pxa27x-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 ohci_hcd_pxa27x_probe(struct platform_device *pdev)
{
	int retval, irq;
	struct usb_hcd *hcd;
	struct pxaohci_platform_data *inf;
	struct pxa27x_ohci *pxa_ohci;
	struct ohci_hcd *ohci;
	struct resource *r;
	struct clk *usb_clk;
	unsigned int i;

	retval = ohci_pxa_of_init(pdev);
	if (retval)
		return retval;

	inf = dev_get_platdata(&pdev->dev);

	if (!inf)
		return -ENODEV;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		pr_err("no resource of IORESOURCE_IRQ");
		return irq;
	}

	usb_clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(usb_clk))
		return PTR_ERR(usb_clk);

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

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hcd->regs = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(hcd->regs)) {
		retval = PTR_ERR(hcd->regs);
		goto err;
	}
	hcd->rsrc_start = r->start;
	hcd->rsrc_len = resource_size(r);

	/* initialize "struct pxa27x_ohci" */
	pxa_ohci = to_pxa27x_ohci(hcd);
	pxa_ohci->clk = usb_clk;
	pxa_ohci->mmio_base = (void __iomem *)hcd->regs;

	for (i = 0; i < 3; ++i) {
		char name[6];

		if (!(inf->flags & (ENABLE_PORT1 << i)))
			continue;

		sprintf(name, "vbus%u", i + 1);
		pxa_ohci->vbus[i] = devm_regulator_get(&pdev->dev, name);
	}

	retval = pxa27x_start_hc(pxa_ohci, &pdev->dev);
	if (retval < 0) {
		pr_debug("pxa27x_start_hc failed");
		goto err;
	}

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);

	if (inf->power_budget)
		hcd->power_budget = inf->power_budget;

	/* The value of NDP in roothub_a is incorrect on this hardware */
	ohci = hcd_to_ohci(hcd);
	ohci->num_ports = 3;

	retval = usb_add_hcd(hcd, irq, 0);
	if (retval == 0) {
		device_wakeup_enable(hcd->self.controller);
		return retval;
	}

	pxa27x_stop_hc(pxa_ohci, &pdev->dev);
 err:
	usb_put_hcd(hcd);
	return retval;
}