static ssize_t hsic_autosuspend_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int retval; int org_req; if (size > HSIC_ENABLE_SIZE) { dev_dbg(dev, "Invalid, size = %d\n", size); return -EINVAL; } if (sscanf(buf, "%d", &org_req) != 1) { dev_dbg(dev, "Invalid, value\n"); return -EINVAL; } mutex_lock(&hsic.hsic_mutex); hsic.autosuspend_enable = org_req; if (hsic.modem_dev != NULL) { if (hsic.autosuspend_enable == 0) { dev_dbg(dev, "Modem dev autosuspend disable\n"); usb_disable_autosuspend(hsic.modem_dev); } else { dev_dbg(dev, "Enable auto suspend\n"); usb_enable_autosuspend(hsic.modem_dev); hsic_wakeup_irq_init(); } } if (hsic.rh_dev != NULL) { if (hsic.autosuspend_enable == 0) { dev_dbg(dev, "port autosuspend disable\n"); usb_disable_autosuspend(hsic.rh_dev); } else { dev_dbg(dev, "port Enable auto suspend\n"); usb_enable_autosuspend(hsic.rh_dev); } } mutex_unlock(&hsic.hsic_mutex); return size; }
/* the root hub will call this callback when device added/removed */ void hsic_notify(struct usb_device *udev, unsigned action) { int retval; struct pci_dev *pdev = to_pci_dev(udev->bus->controller); printk(KERN_ERR "pdev device ID: %d, portnum: %d", pdev->device, udev->portnum); /* Ignore and only valid for HSIC. Filter out * the USB devices added by other USB2 host driver */ if (pdev->device != USH_PCI_ID) return; /* Ignore USB devices on external hub */ if (udev->parent && udev->parent->parent) return; switch (action) { case USB_DEVICE_ADD: pr_debug("Notify HSIC add device\n"); /* Root hub */ if (!udev->parent) { if (udev->speed == USB_SPEED_HIGH) { pr_debug("%s rh device set\n", __func__); hsic.rh_dev = udev; pr_debug("%s Disable autosuspend\n", __func__); pm_runtime_set_autosuspend_delay(&udev->dev, hsic.bus_inactivityDuration); usb_disable_autosuspend(udev); } } else { if (udev->portnum != HSIC_USH_PORT) { pr_debug("%s ignore ush ports except port5\n", __func__); pr_debug("%s ush ports %d\n", __func__, udev->portnum); break; } /* Modem devices */ hsic.modem_dev = udev; pm_runtime_set_autosuspend_delay (&udev->dev, hsic.port_inactivityDuration); if (hsic.remoteWakeup_enable) { pr_debug("%s Modem dev remote wakeup enabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 1); device_set_wakeup_capable (&hsic.rh_dev->dev, 1); } else { pr_debug("%s Modem dev remote wakeup disabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 0); device_set_wakeup_capable (&hsic.rh_dev->dev, 0); } usb_disable_autosuspend(hsic.modem_dev); usb_disable_autosuspend(hsic.rh_dev); #if 0 if (hsic.autosuspend_enable) { pr_debug("%s----> enable autosuspend\n", __func__); usb_enable_autosuspend(udev->parent); hsic_wakeup_irq_init(); } if (hsic.autosuspend_enable == 0) { pr_debug("%s Modem dev autosuspend disable\n", __func__); usb_disable_autosuspend(hsic.modem_dev); } #endif } break; case USB_DEVICE_REMOVE: pr_debug("Notify HSIC delete device\n"); /* Root hub */ if (udev->speed != USB_SPEED_HIGH) { pr_debug("%s ignore ss port\n", __func__); break; } if (!udev->parent) { pr_debug("%s rh_dev deleted\n", __func__); hsic.rh_dev = NULL; } else { /* Modem devices */ pr_debug("%s----> modem dev deleted\n", __func__); hsic.modem_dev = NULL; usb_disable_autosuspend(hsic.rh_dev); } break; case MODEM_WORK_FLUSH: if (udev == hsic.modem_dev) { pr_debug("Notify MODEM work flush\n"); synchronize_irq(gpio_to_irq(hsic.aux_gpio)); flush_work(&hsic.hsic_aux); } break; default: pr_debug("Notify action not supported\n"); break ; } return; }
static void hsicdev_add(struct usb_device *udev) { pr_debug("Notify HSIC add device\n"); if (is_ush_hsic(udev) == 0) { pr_debug("Not a USH HSIC device\n"); return; } /* Root hub */ if (!udev->parent) { if (udev->speed == USB_SPEED_HIGH) { pr_debug("%s rh device set\n", __func__); hsic.rh_dev = udev; pr_debug("%s Disable autosuspend\n", __func__); pm_runtime_set_autosuspend_delay(&udev->dev, hsic.bus_inactivityDuration); usb_disable_autosuspend(udev); hsic.autosuspend_enable = 0; } } else { if (udev->portnum != HSIC_USH_PORT) { pr_debug("%s ignore ush ports %d\n", __func__, udev->portnum); return; } /* Modem devices */ hsic.port_disconnect = 0; hsic.modem_dev = udev; pm_runtime_set_autosuspend_delay (&udev->dev, hsic.port_inactivityDuration); if (hsic.remoteWakeup_enable) { pr_debug("%s Modem dev remote wakeup enabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 1); device_set_wakeup_capable (&hsic.rh_dev->dev, 1); } else { pr_debug("%s Modem dev remote wakeup disabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 0); device_set_wakeup_capable (&hsic.rh_dev->dev, 0); } hsic.autosuspend_enable = HSIC_AUTOSUSPEND; if (hsic.autosuspend_enable) { pr_debug("%s----> enable autosuspend\n", __func__); usb_enable_autosuspend(hsic.modem_dev); usb_enable_autosuspend(hsic.rh_dev); hsic_wakeup_irq_init(); } if (hsic.autosuspend_enable == 0) { pr_debug("%s Modem dev autosuspend disable\n", __func__); usb_disable_autosuspend(hsic.modem_dev); usb_disable_autosuspend(hsic.rh_dev); } } }