static int intel_mid_ehci_driver_register(struct pci_driver *host_driver) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_transceiver(); if (otg == NULL || host_driver == NULL) return -EINVAL; iotg = otg_to_mid_xceiv(otg); iotg->start_host = ehci_mid_start_host; iotg->stop_host = ehci_mid_stop_host; iotg->runtime_suspend_host = ehci_mid_runtime_suspend_host; iotg->runtime_resume_host = ehci_mid_runtime_resume_host; iotg->suspend_host = ehci_mid_suspend_host; iotg->suspend_noirq_host = ehci_mid_suspend_noirq_host; iotg->resume_host = ehci_mid_resume_host; iotg->resume_noirq_host = ehci_mid_resume_noirq_host; #ifdef CONFIG_USB_SUSPEND wake_lock_init(&iotg->wake_lock, WAKE_LOCK_SUSPEND, "ehci_wake_lock"); #endif /* notify host driver is registered */ atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HOSTADD, iotg); usb_put_transceiver(otg); return 0; }
static void intel_mid_ehci_driver_unregister(struct pci_driver *host_driver) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_transceiver(); if (otg == NULL) return ; iotg = otg_to_mid_xceiv(otg); iotg->start_host = NULL; iotg->stop_host = NULL; iotg->runtime_suspend_host = NULL; iotg->runtime_resume_host = NULL; #ifdef CONFIG_USB_SUSPEND wake_lock_destroy(&iotg->wake_lock); #endif /* notify host driver is unregistered */ atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HOSTREMOVE, iotg); usb_put_transceiver(otg); }
static int intel_mid_ehci_driver_register(struct pci_driver *host_driver) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_phy(USB_PHY_TYPE_USB2); if (otg == NULL || host_driver == NULL) return -EINVAL; iotg = otg_to_mid_xceiv(otg); iotg->start_host = ehci_mid_start_host; iotg->stop_host = ehci_mid_stop_host; iotg->runtime_suspend_host = ehci_mid_runtime_suspend_host; iotg->runtime_resume_host = ehci_mid_runtime_resume_host; iotg->suspend_host = ehci_mid_suspend_host; iotg->suspend_noirq_host = ehci_mid_suspend_noirq_host; iotg->resume_host = ehci_mid_resume_host; iotg->resume_noirq_host = ehci_mid_resume_noirq_host; /* notify host driver is registered */ atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HOSTADD, iotg); usb_put_phy(otg); return 0; }
/* the root hub will call this callback when device added/removed */ static void otg_notify(struct usb_device *udev, unsigned action) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; /* Ignore root hub add/remove event */ if (!udev->parent) { pr_debug("%s Ignore root hub otg_notify\n", __func__); return; } /* Ignore USB devices on external hub */ if (udev->parent && udev->parent->parent) return; otg = usb_get_transceiver(); if (otg == NULL) { printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__); return; } iotg = otg_to_mid_xceiv(otg); switch (action) { case USB_DEVICE_ADD: pr_debug("Notify OTG HNP add device\n"); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_CONNECT, iotg); break; case USB_DEVICE_REMOVE: pr_debug("Notify OTG HNP delete device\n"); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_DISCONN, iotg); break; case USB_OTG_TESTDEV: pr_debug("Notify OTG test device\n"); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_TEST, iotg); break; case USB_OTG_TESTDEV_VBUSOFF: pr_debug("Notify OTG test device, Vbusoff mode\n"); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_TEST_VBUS_OFF, iotg); break; default: usb_put_transceiver(otg); return ; } usb_put_transceiver(otg); return; }
static int usb_otg_resume(struct usb_hcd *hcd) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_transceiver(); if (otg == NULL) { printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__); return -EINVAL; } iotg = otg_to_mid_xceiv(otg); dev_dbg(otg->dev, "%s OTG HNP update resume\n", __func__); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HRESUME, iotg); usb_put_transceiver(otg); return 0; }
static int usb_otg_suspend(struct usb_hcd *hcd) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_transceiver(); if (otg == NULL) { printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__); return -EINVAL; } iotg = otg_to_mid_xceiv(otg); printk(KERN_INFO "%s OTG HNP update suspend\n", __func__); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HSUSPEND, iotg); usb_put_transceiver(otg); return 0; }
static int usb_otg_suspend(struct usb_hcd *hcd) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_phy(USB_PHY_TYPE_USB2); if (otg == NULL) { pr_err("%s: failed to get otg transceiver\n", __func__); return -EINVAL; } iotg = otg_to_mid_xceiv(otg); pr_info("%s: OTG HNP update suspend\n", __func__); atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HSUSPEND, iotg); usb_put_phy(otg); return 0; }
static void intel_mid_ehci_driver_unregister(struct pci_driver *host_driver) { struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; otg = usb_get_phy(USB_PHY_TYPE_USB2); if (otg == NULL) return; iotg = otg_to_mid_xceiv(otg); iotg->start_host = NULL; iotg->stop_host = NULL; iotg->runtime_suspend_host = NULL; iotg->runtime_resume_host = NULL; /* notify host driver is unregistered */ atomic_notifier_call_chain(&iotg->iotg_notifier, MID_OTG_NOTIFY_HOSTREMOVE, iotg); usb_put_phy(otg); }
static int ehci_mid_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct hc_driver *driver; struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; struct intel_mid_otg_pdata *otg_pdata; struct usb_hcd *hcd; struct ehci_hcd *ehci; int irq; int retval; pr_debug("initializing Intel MID USB OTG Host Controller\n"); /* we need not call pci_enable_dev since otg transceiver already take * the control of this device and this probe actaully gets called by * otg transceiver driver with HNP protocol. */ irq = pdev->irq; if (!id) return -EINVAL; driver = (struct hc_driver *)id->driver_data; if (!driver) return -EINVAL; hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err1; } ehci = hcd_to_ehci(hcd); /* this will be called in ehci_bus_suspend and ehci_bus_resume */ ehci->otg_suspend = usb_otg_suspend; ehci->otg_resume = usb_otg_resume; /* this will be called by root hub code */ hcd->otg_notify = otg_notify; otg = usb_get_transceiver(); if (otg == NULL) { printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__); retval = -EINVAL; goto err1; } iotg = otg_to_mid_xceiv(otg); hcd->regs = iotg->base; hcd->rsrc_start = pci_resource_start(pdev, 0); hcd->rsrc_len = pci_resource_len(pdev, 0); if (hcd->regs == NULL) { dev_dbg(&pdev->dev, "error mapping memory\n"); retval = -EFAULT; goto err2; } otg_pdata = pdev->dev.platform_data; if (otg_pdata == NULL) { dev_err(&pdev->dev, "Failed to get OTG platform data.\n"); retval = -ENODEV; goto err2; } hcd->power_budget = otg_pdata->power_budget; /* Mandatorily set the controller as remote-wakeup enabled */ device_set_wakeup_enable(&pdev->dev, true); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err2; retval = otg_set_host(otg->otg, &hcd->self); if (!otg->otg->default_a) hcd->self.is_b_host = 1; usb_put_transceiver(otg); return retval; err2: usb_put_hcd(hcd); err1: dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); return retval; }