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