static void bcm_hsotgctrl_delayed_wakeup_handler(struct work_struct *work) { struct bcm_hsotgctrl_drv_data *bcm_hsotgctrl_handle = container_of(work, struct bcm_hsotgctrl_drv_data, wakeup_work.work); if (NULL == local_hsotgctrl_handle) return; if (bcm_hsotgctrl_handle != local_hsotgctrl_handle) { dev_warn(local_hsotgctrl_handle->dev, "Invalid HSOTGCTRL wakeup handler"); return; } dev_info(bcm_hsotgctrl_handle->dev, "Do HSOTGCTRL wakeup\n"); /* Enable OTG AHB clock */ bcm_hsotgctrl_en_clock(true); /* Use the PHY-core wakeup sequence */ bcm_hsotgctrl_wakeup_core(); bcm_hsotgctrl_en_clock(false); }
static ssize_t bcmpmu_otg_xceiv_wake_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_gadget *gadget; ssize_t result = 0; unsigned int val; struct bcmpmu_otg_xceiv_data *xceiv_data = dev_get_drvdata(dev); int error; gadget = xceiv_data->otg_xceiver.xceiver.gadget; result = sscanf(buf, "%02x\n", &val); if (result != 1) { result = -EINVAL; } else if (val == 0) { dev_warn(xceiv_data->dev, "Illegal value\n"); } else { dev_info(xceiv_data->dev, "Waking up host\n"); /* Bring core out of suspend */ bcm_hsotgctrl_wakeup_core(); error = usb_gadget_wakeup(gadget); if (error) dev_err(xceiv_data->dev, "Failed to issue wakeup\n"); } return result < 0 ? result : count; }
int bcm_hsotgctrl_phy_deinit(void) { struct bcm_hsotgctrl_drv_data *bcm_hsotgctrl_handle = local_hsotgctrl_handle; if (NULL == local_hsotgctrl_handle) return -ENODEV; if (!bcm_hsotgctrl_handle->dev) return -EIO; if (bcm_hsotgctrl_handle->irq_enabled) { /* We are shutting down USB so ensure wake IRQ * is disabled */ disable_irq(bcm_hsotgctrl_handle->hsotgctrl_irq); bcm_hsotgctrl_handle->irq_enabled = false; } if (work_pending(&bcm_hsotgctrl_handle->wakeup_work.work)) { /* Cancel scheduled work */ cancel_delayed_work(&bcm_hsotgctrl_handle-> wakeup_work); /* Make sure work queue is flushed */ flush_workqueue(bcm_hsotgctrl_handle-> bcm_hsotgctrl_work_queue); } /* Disable wakeup condition */ bcm_hsotgctrl_phy_wakeup_condition(false); /* Stay disconnected */ bcm_hsotgctrl_wakeup_core(); bcm_hsotgctrl_phy_set_non_driving(true); /* Disable pad, internal PLL etc. */ bcm_hsotgctrl_set_phy_off(true); /* Enable software control of PHY-PM */ bcm_hsotgctrl_set_soft_ldo_pwrdn(true); /* Isolate PHY */ bcm_hsotgctrl_set_phy_iso(true); /* Power down ALDO */ bcm_hsotgctrl_set_aldo_pdn(false); /* Clear PHY reference clock request */ bcm_hsotgctrl_set_phy_clk_request(false); /* Clear Vbus valid state */ bcm_hsotgctrl_phy_set_vbus_stat(false); /* Disable the OTG core AHB clock */ bcm_hsotgctrl_en_clock(false); return 0; }