arm: tegra: comms: Enable autopm for RAW-IP network driver.
Michael Hsu [Sat, 12 Nov 2011 20:49:07 +0000 (12:49 -0800)]
Autoresume usb interface before tx and autosuspend after tx
completes.  Also mark last busy time to prevent autosuspend
until some idle time has occurred.

Reviewed-on: http://git-master/r/63993
(cherry picked from commit cfbe77e471d96feda7efd3d8e3f35114a7a32bf7)

Change-Id: I4f419ea29aad6a06b786e6ffb8b17b2016c6e21d
Reviewed-on: http://git-master/r/66528
Reviewed-by: Michael Hsu <mhsu@nvidia.com>
Tested-by: Michael Hsu <mhsu@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com>

Rebase-Id: R76d1761a632abc1d05563016f046d60c7b68853a

drivers/net/usb/raw_ip_net.c

index ff550a5..899278b 100755 (executable)
@@ -417,12 +417,14 @@ static netdev_tx_t baseband_usb_netdev_start_xmit(
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
                pr_err("usb_alloc_urb() failed\n");
+               kfree_skb(skb);
                return -ENOMEM;
        }
        buf = kzalloc(skb->len - 14, GFP_ATOMIC);
        if (!buf) {
                pr_err("usb buffer kzalloc() failed\n");
                usb_free_urb(urb);
+               kfree_skb(skb);
                return -ENOMEM;
        }
        err = skb_copy_bits(skb, 14, buf, skb->len - 14);
@@ -430,6 +432,7 @@ static netdev_tx_t baseband_usb_netdev_start_xmit(
                pr_err("skb_copy_bits() failed - %d\n", err);
                kfree(buf);
                usb_free_urb(urb);
+               kfree_skb(skb);
                return err;
        }
        usb_fill_bulk_urb(urb, usb->usb.device, usb->usb.pipe.bulk.out,
@@ -438,11 +441,24 @@ static netdev_tx_t baseband_usb_netdev_start_xmit(
                usb);
        urb->transfer_flags = URB_ZERO_PACKET;
 
+       /* autoresume before tx */
+       err = usb_autopm_get_interface(usb->usb.interface);
+       if (err < 0) {
+               pr_err("%s: usb_autopm_get_interface(%p) failed %d\n",
+                       __func__, usb->usb.interface, err);
+               kfree(urb->transfer_buffer);
+               usb_free_urb(urb);
+               kfree_skb(skb);
+               return err;
+       }
+
        /* submit tx urb */
+       usb_mark_last_busy(usb->usb.device);
        usb->usb.tx_urb = urb;
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
                pr_err("usb_submit_urb() failed - err %d\n", err);
+               usb_autopm_put_interface(usb->usb.interface);
                usb->usb.tx_urb = (struct urb *) 0;
                kfree(urb->transfer_buffer);
                usb_free_urb(urb);
@@ -616,6 +632,9 @@ static void usb_net_raw_ip_tx_urb_comp(struct urb *urb)
        usb_free_urb(urb);
        usb->usb.tx_urb = (struct urb *) 0;
 
+       /* autosuspend after tx completed */
+       usb_autopm_put_interface_async(usb->usb.interface);
+
        pr_debug("usb_net_raw_ip_tx_urb_comp }\n");
 }