diff options
author | Michael Hsu <mhsu@nvidia.com> | 2011-11-12 12:49:07 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:50:20 -0800 |
commit | ced29868819d5259801b4344fa7e909fe0adb28e (patch) | |
tree | 683098afca85202122d3aaf9cad6fdb9059743d6 /drivers/net/usb | |
parent | 0657258dfaaa1382175ac56b4c4ffaea52fc05f0 (diff) |
arm: tegra: comms: Enable autopm for RAW-IP network driver.
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
Diffstat (limited to 'drivers/net/usb')
-rwxr-xr-x | drivers/net/usb/raw_ip_net.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/net/usb/raw_ip_net.c b/drivers/net/usb/raw_ip_net.c index ff550a5703f7..899278b1d2eb 100755 --- a/drivers/net/usb/raw_ip_net.c +++ b/drivers/net/usb/raw_ip_net.c @@ -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"); } |