aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhayeswang <hayeswang@realtek.com>2014-10-17 04:55:08 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-17 23:46:35 -0400
commit6cc69f2a404dea8641d6cf97c0fbe8d24579e259 (patch)
tree8f02af17a0087a6a936c751a06ca3773416d46f9
parentd8f00d27105a1553a13d4a96c3eb4544f70ca908 (diff)
r8152: return -EBUSY for runtime suspend
Remove calling cancel_delayed_work_sync() for runtime suspend, because it would cause dead lock. Instead, return -EBUSY to avoid the device enters suspending if the net is running and the delayed work is pending or running. The delayed work would try to wake up the device later, so the suspending is not necessary. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/usb/r8152.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 864159eb744e..e3d84c322e4e 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3189,31 +3189,39 @@ static void r8153_init(struct r8152 *tp)
3189static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) 3189static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
3190{ 3190{
3191 struct r8152 *tp = usb_get_intfdata(intf); 3191 struct r8152 *tp = usb_get_intfdata(intf);
3192 struct net_device *netdev = tp->netdev;
3193 int ret = 0;
3192 3194
3193 mutex_lock(&tp->control); 3195 mutex_lock(&tp->control);
3194 3196
3195 if (PMSG_IS_AUTO(message)) 3197 if (PMSG_IS_AUTO(message)) {
3198 if (netif_running(netdev) && work_busy(&tp->schedule.work)) {
3199 ret = -EBUSY;
3200 goto out1;
3201 }
3202
3196 set_bit(SELECTIVE_SUSPEND, &tp->flags); 3203 set_bit(SELECTIVE_SUSPEND, &tp->flags);
3197 else 3204 } else {
3198 netif_device_detach(tp->netdev); 3205 netif_device_detach(netdev);
3206 }
3199 3207
3200 if (netif_running(tp->netdev)) { 3208 if (netif_running(netdev)) {
3201 clear_bit(WORK_ENABLE, &tp->flags); 3209 clear_bit(WORK_ENABLE, &tp->flags);
3202 usb_kill_urb(tp->intr_urb); 3210 usb_kill_urb(tp->intr_urb);
3203 cancel_delayed_work_sync(&tp->schedule);
3204 tasklet_disable(&tp->tl); 3211 tasklet_disable(&tp->tl);
3205 if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { 3212 if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
3206 rtl_stop_rx(tp); 3213 rtl_stop_rx(tp);
3207 rtl_runtime_suspend_enable(tp, true); 3214 rtl_runtime_suspend_enable(tp, true);
3208 } else { 3215 } else {
3216 cancel_delayed_work_sync(&tp->schedule);
3209 tp->rtl_ops.down(tp); 3217 tp->rtl_ops.down(tp);
3210 } 3218 }
3211 tasklet_enable(&tp->tl); 3219 tasklet_enable(&tp->tl);
3212 } 3220 }
3213 3221out1:
3214 mutex_unlock(&tp->control); 3222 mutex_unlock(&tp->control);
3215 3223
3216 return 0; 3224 return ret;
3217} 3225}
3218 3226
3219static int rtl8152_resume(struct usb_interface *intf) 3227static int rtl8152_resume(struct usb_interface *intf)