ARM: tegra: usb: add remote wakeup callback
Neil Patel [Fri, 11 Oct 2013 18:31:43 +0000 (14:31 -0400)]
Drivers can take actions based on remote wakeup events to prevent a
device or the bus from suspending before the incoming data is handled.

Bug 1362837
Bug 1430974

Change-Id: I55cf26663cbf00bd2eccc60f18aa95ab5777e604
Signed-off-by: Neil Patel <neilp@nvidia.com>
Reviewed-on: http://git-master/r/289968
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Steve Lin <stlin@nvidia.com>
Reviewed-by: Gray Lei <glei@nvidia.com>
Reviewed-on: http://git-master/r/349731
Reviewed-by: Martin Chi <mchi@nvidia.com>
Tested-by: Martin Chi <mchi@nvidia.com>
Reviewed-on: http://git-master/r/351588
GVS: Gerrit_Virtual_Submit

arch/arm/mach-tegra/tegra11x_usb_phy.c
include/linux/platform_data/tegra_usb.h

index f6bd2a5..945a10e 100644 (file)
@@ -1586,9 +1586,12 @@ static void uhsic_phy_restore_end(struct tegra_usb_phy *phy)
        int wait_time_us = FPR_WAIT_TIME_US; /* FPR should be set by this time */
        bool irq_disabled = false;
        struct tegra_usb_pmc_data *pmc = &pmc_data[phy->inst];
+       bool remote_wakeup_detected;
 
        DBG("%s(%d)\n", __func__, __LINE__);
 
+       remote_wakeup_detected = phy->pmc_remote_wakeup;
+
        /*
         * check whether we wake up from the remote wake detected before putting
         * controller in suspend in usb_phy_bringup_host_controller.
@@ -1666,6 +1669,9 @@ static void uhsic_phy_restore_end(struct tegra_usb_phy *phy)
                pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__);
                return;
        }
+       if (remote_wakeup_detected && phy->pdata->ops &&
+                                       phy->pdata->ops->post_remote_wakeup)
+               phy->pdata->ops->post_remote_wakeup();
 }
 
 static int uhsic_rail_enable(struct tegra_usb_phy *phy)
index 22cf378..b10ce69 100644 (file)
@@ -87,6 +87,7 @@ struct tegra_usb_phy_platform_ops {
        void (*post_suspend)(void);
        void (*pre_resume)(void);
        void (*post_resume)(void);
+       void (*post_remote_wakeup)(void);
        void (*pre_phy_off)(void);
        void (*post_phy_off)(void);
        void (*pre_phy_on)(void);