misc: tegra-baseband: take wakelock after remote wakeup
Neil Patel [Thu, 10 Oct 2013 00:31:19 +0000 (20:31 -0400)]
Take a wakelock after a remote wakeup event occurs. This is done to
help ensure we do not suspend before the upper layers can handle
incoming data.

Bug 1362837
Bug 1430974

Change-Id: I7dc4ee43e4443e9ac0635eac179427c2348238c8
Signed-off-by: Neil Patel <neilp@nvidia.com>
Reviewed-on: http://git-master/r/289962
Reviewed-by: Steve Lin <stlin@nvidia.com>
Reviewed-by: Gray Lei <glei@nvidia.com>
Reviewed-on: http://git-master/r/349729
Reviewed-by: Martin Chi <mchi@nvidia.com>
Tested-by: Martin Chi <mchi@nvidia.com>
Reviewed-on: http://git-master/r/351586
GVS: Gerrit_Virtual_Submit

drivers/misc/tegra-baseband/tegra_usb_modem_power.c
include/linux/platform_data/tegra_usb_modem_power.h

index f3e142e..28f5202 100644 (file)
@@ -441,6 +441,27 @@ static int mdm_request_wakeable_irq(struct tegra_usb_modem *modem,
        return ret;
 }
 
+static void tegra_usb_modem_post_remote_wakeup(void)
+{
+       struct device *dev;
+       struct tegra_usb_modem *modem;
+
+       dev = bus_find_device_by_name(&platform_bus_type, NULL,
+                                       "MDM");
+       if (!dev) {
+               pr_warn("%s unable to find device name\n", __func__);
+               return;
+       }
+
+       modem = dev_get_drvdata(dev);
+
+       mutex_lock(&modem->lock);
+       wake_lock_timeout(&modem->wake_lock, WAKELOCK_TIMEOUT_FOR_REMOTE_WAKE);
+       mutex_unlock(&modem->lock);
+
+       return;
+}
+
 /* load USB host controller */
 static struct platform_device *tegra_usb_host_register(
                                const struct tegra_usb_modem *modem)
@@ -706,6 +727,10 @@ static struct device_attribute *edp_attributes[] = {
        NULL
 };
 
+static struct tegra_usb_phy_platform_ops tegra_usb_modem_platform_ops = {
+       .post_remote_wakeup = tegra_usb_modem_post_remote_wakeup,
+};
+
 static int mdm_init(struct tegra_usb_modem *modem, struct platform_device *pdev)
 {
        struct tegra_usb_modem_power_platform_data *pdata =
@@ -821,8 +846,12 @@ static int mdm_init(struct tegra_usb_modem *modem, struct platform_device *pdev)
                        dev_err(&pdev->dev, "request wake irq error\n");
                        goto error;
                }
+       } else {
+               modem->pdata->tegra_ehci_pdata->ops =
+                                               &tegra_usb_modem_platform_ops;
        }
 
+
        if (gpio_is_valid(pdata->boot_gpio)) {
                /* request boot irq from platform data */
                ret = mdm_request_wakeable_irq(modem,
index be47529..4b891c8 100644 (file)
@@ -49,7 +49,7 @@ struct tegra_usb_modem_power_platform_data {
        int autosuspend_delay;          /* autosuspend delay in milliseconds */
        int short_autosuspend_delay;    /* short autosuspend delay in ms */
        const struct platform_device *tegra_ehci_device; /* USB host device */
-       const struct tegra_usb_platform_data *tegra_ehci_pdata;
+       struct tegra_usb_platform_data *tegra_ehci_pdata;
        struct edp_client *modem_boot_edp_client;
        char *edp_manager_name;
        unsigned int i_breach_ppm;