Example #1
0
static ssize_t store_ehci_power(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct usb_hcd *hcd = bus_to_hcd(dev_get_drvdata(dev));
	int power_on;
	int retval;

	if (sscanf(buf, "%d", &power_on) != 1)
		return -EINVAL;

	device_lock(dev);
	if (power_on == 0 && s5pv210_hcd != NULL) {
		printk(KERN_DEBUG "%s: EHCI turns off\n", __func__);
		usb_remove_hcd(hcd);
		s5pv210_stop_ehc();
		s5pv210_hcd = NULL;
		/*HSIC IPC control the ACTIVE_STATE*/
                #ifdef CONFIG_SAMSUNG_PHONE_SVNET
		mc_control_active_state(0);
                #endif
	} else if (power_on == 1) {
		printk(KERN_DEBUG "%s: EHCI turns on\n", __func__);
		if (s5pv210_hcd != NULL) {
			usb_remove_hcd(hcd);
			/*HSIC IPC control the ACTIVE_STATE*/
                        #ifdef CONFIG_SAMSUNG_PHONE_SVNET
			mc_control_active_state(0);
                        #endif
		}
		s5pv210_start_ehc();

#if defined(CONFIG_ARCH_S5PV310)
		writel(0x03C00000, hcd->regs + 0x90);
#endif

		retval = usb_add_hcd(hcd, IRQ_UHOST,
				IRQF_DISABLED | IRQF_SHARED);
		if (retval < 0) {
			dev_err(dev, "Power On Fail\n");
			goto exit;
		}
		/*HSIC IPC control the ACTIVE_STATE*/
                #ifdef CONFIG_SAMSUNG_PHONE_SVNET
		mc_control_active_state(1);
                #endif

		s5pv210_hcd = hcd;
	}
exit:
	device_unlock(dev);
	return count;
}
Example #2
0
static int ehci_hcd_s5pv210_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);

	usb_remove_hcd(hcd);
	iounmap(hcd->regs);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
	s5pv210_stop_ehc();
	clk_put(usb_clk);
	platform_set_drvdata(pdev, NULL);

	return 0;
}
Example #3
0
static int ehci_hcd_s5pv210_drv_suspend(
    struct platform_device *pdev,
    pm_message_t message
) {
    struct usb_hcd *hcd = platform_get_drvdata(pdev);
    struct ehci_hcd *ehci = hcd_to_ehci(hcd);
    unsigned long flags;
    int rc = 0;

    if (time_before(jiffies, ehci->next_statechange))
        msleep(10);

    /* Root hub was already suspended. Disable irq emission and
     * mark HW unaccessible, bail out if RH has been resumed. Use
     * the spinlock to properly synchronize with possible pending
     * RH suspend or resume activity.
     *
     * This is still racy as hcd->state is manipulated outside of
     * any locks =P But that will be a different fix.
     */

    spin_lock_irqsave(&ehci->lock, flags);
    if (hcd->state != HC_STATE_SUSPENDED) {
        rc = -EINVAL;
        goto bail;
    }

    ehci_writel(ehci, 0, &ehci->regs->intr_enable);
    (void)ehci_readl(ehci, &ehci->regs->intr_enable);

    /* make sure snapshot being resumed re-enumerates everything */
    if (message.event == PM_EVENT_PRETHAW) {
        ehci_halt(ehci);
        ehci_reset(ehci);
    }

    clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

    s5pv210_stop_ehc();
bail:
    spin_unlock_irqrestore(&ehci->lock, flags);

    return rc;
}
Example #4
0
static int s5pv210_ehci_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct usb_hcd *hcd = platform_get_drvdata(pdev);
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	unsigned long flags;
	int rc = 0;

	if (s5pv210_hcd == NULL) {
		dev_info(dev, "Nothing to do for the device (power off)\n");
		usb_host_phy_power_off();
		return 0;
	}

	if (time_before(jiffies, ehci->next_statechange))
		msleep(10);

	/* Root hub was already suspended. Disable irq emission and
	 * mark HW unaccessible, bail out if RH has been resumed. Use
	 * the spinlock to properly synchronize with possible pending
	 * RH suspend or resume activity.
	 *
	 * This is still racy as hcd->state is manipulated outside of
	 * any locks =P But that will be a different fix.
	 */

	spin_lock_irqsave(&ehci->lock, flags);
	if (hcd->state != HC_STATE_SUSPENDED && hcd->state != HC_STATE_HALT) {
		spin_unlock_irqrestore(&ehci->lock, flags);
		return -EINVAL;
	}
	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
	(void)ehci_readl(ehci, &ehci->regs->intr_enable);

	/* make sure snapshot being resumed re-enumerates everything */
	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

	spin_unlock_irqrestore(&ehci->lock, flags);
	s5pv210_stop_ehc();
	usb_host_phy_power_off();

	return rc;
}
Example #5
0
static int ehci_hcd_s5pv210_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);

	s5pv210_hcd = NULL;
	remove_ehci_sys_file(hcd_to_ehci(hcd));
#ifdef CONFIG_USB_SUSPEND
	pm_runtime_disable(&pdev->dev);
#endif
	usb_remove_hcd(hcd);
	/*HSIC IPC control the ACTIVE_STATE*/
        #ifdef CONFIG_SAMSUNG_PHONE_SVNET
	mc_control_active_state(0);
        #endif
	iounmap(hcd->regs);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
	s5pv210_stop_ehc();
	platform_set_drvdata(pdev, NULL);

	return 0;
}
Example #6
0
void usb_host_hsic_power_off()
{
        int retval;
        struct regulator *usb_hsic_reg;

		 if (s5pv210_onoff_flag == 1) {
			 usb_remove_hcd(s5pv210_hcd);
			 s5pv210_stop_ehc();
			 s5pv210_onoff_flag = 0;
		 }

         usb_hsic_reg = regulator_get(NULL, "vhsic");
         if (IS_ERR(usb_hsic_reg)) {
                        retval = PTR_ERR(usb_hsic_reg);
                        //dev_err(, "No VHSIC_1.2V regualtor: %d\n",
                          //      retval);
                        usb_hsic_reg = NULL;
                }

        if (usb_hsic_reg)
                retval=regulator_disable(usb_hsic_reg);

}
Example #7
0
static int ehci_hcd_s5pv210_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd  *hcd = NULL;
	struct ehci_hcd *ehci = NULL;
	int retval = 0;

	if (usb_disabled())
		return -ENODEV;

	usb_host_phy_off();

	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
		dev_err(&pdev->dev, "resource[1] is not IORESOURCE_IRQ.\n");
		return -ENODEV;
	}

	hcd = usb_create_hcd(&ehci_s5pv210_hc_driver, &pdev->dev, "s5pv210");
	if (!hcd) {
		dev_err(&pdev->dev, "usb_create_hcd failed!\n");
		return -ENODEV;
	}
	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_err(&pdev->dev, "request_mem_region failed!\n");
		retval = -EBUSY;
		goto err1;
	}

	usb_clk = clk_get(&pdev->dev, "usbhost");
	if (IS_ERR(usb_clk)) {
		dev_err(&pdev->dev, "cannot get usb-host clock\n");
		retval = -ENODEV;
		goto err2;
	}

	s5pv210_start_ehc();

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed!\n");
		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 chip reads */
	ehci->hcs_params = readl(&ehci->caps->hcs_params);

	writel(0x00600040, hcd->regs + 0x94);

	retval = usb_add_hcd(hcd, pdev->resource[1].start,
				IRQF_DISABLED | IRQF_SHARED);

	if (retval == 0) {
		platform_set_drvdata(pdev, hcd);
		return retval;
	}

	s5pv210_stop_ehc();
	iounmap(hcd->regs);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	clk_put(usb_clk);
	usb_put_hcd(hcd);
	return retval;
}
Example #8
0
static int ehci_hcd_s5pv210_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd  *hcd = NULL;
	struct ehci_hcd *ehci = NULL;
	int retval = 0;

	if (usb_disabled())
		return -ENODEV;


	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
		dev_err(&pdev->dev, "resource[1] is not IORESOURCE_IRQ.\n");
		return -ENODEV;
	}

	hcd = usb_create_hcd(&ehci_s5pv210_hc_driver, &pdev->dev, "s5pv210");
	if (!hcd) {
		dev_err(&pdev->dev, "usb_create_hcd failed!\n");
		return -ENODEV;
	}
	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_err(&pdev->dev, "request_mem_region failed!\n");
		retval = -EBUSY;
		goto err1;
	}

	usb_host_phy_power_init(pdev);
	s5pv210_start_ehc();

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed!\n");
		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 chip reads */
	ehci->hcs_params = readl(&ehci->caps->hcs_params);

#if defined(CONFIG_ARCH_S5PV210) || defined(CONFIG_ARCH_S5P6450)
	writel(0x000F0000, hcd->regs + 0x90);
#endif

#if defined(CONFIG_ARCH_S5PV310)
	writel(0x03C00000, hcd->regs + 0x90);
#endif

	if (create_ehci_sys_file(ehci) < 0) {
			dev_err(&pdev->dev, "Failed to create ehci sysfs\n");
	}

	retval = usb_add_hcd(hcd, pdev->resource[1].start,
				IRQF_DISABLED | IRQF_SHARED);

	if (retval == 0) {
		platform_set_drvdata(pdev, hcd);
		s5pv210_hcd = hcd;

#ifdef CONFIG_USB_SUSPEND
		pm_runtime_set_active(&pdev->dev);
		pm_runtime_enable(&pdev->dev);
		pm_runtime_forbid(&pdev->dev);
#endif

		/*HSIC IPC control the ACTIVE_STATE*/
                #ifdef CONFIG_SAMSUNG_PHONE_SVNET
		mc_control_active_state(1);
                #endif
		return retval;
	}

	remove_ehci_sys_file(ehci);
	s5pv210_stop_ehc();
	iounmap(hcd->regs);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);
	return retval;
}