diff options
author | David S. Miller <davem@davemloft.net> | 2017-06-16 11:37:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-16 11:37:13 -0400 |
commit | 61f73d1ea4c68544b959228ead7ef5c021791b14 (patch) | |
tree | 12f9199896a4413b366ca7082bb01deec4562a21 /drivers | |
parent | 54144b4825ea7790cbc32a0f75a1103a97907646 (diff) | |
parent | bd8829822204debbb2dd38a5b052ef7663e618cc (diff) |
Merge branch 'r8152-adjust-runtime-suspend-resume'
Hayes Wang says:
====================
r8152: adjust runtime suspend/resume
v2:
For #1, replace GFP_KERNEL with GFP_NOIO for usb_submit_urb().
v1:
Improve the flow about runtime suspend/resume and make the code
easy to read.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/usb/r8152.c | 111 |
1 files changed, 66 insertions, 45 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 3a29072dc622..8bc4573e0cd4 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -4289,6 +4289,61 @@ static bool delay_autosuspend(struct r8152 *tp) | |||
4289 | return false; | 4289 | return false; |
4290 | } | 4290 | } |
4291 | 4291 | ||
4292 | static int rtl8152_runtime_resume(struct r8152 *tp) | ||
4293 | { | ||
4294 | struct net_device *netdev = tp->netdev; | ||
4295 | |||
4296 | if (netif_running(netdev) && netdev->flags & IFF_UP) { | ||
4297 | struct napi_struct *napi = &tp->napi; | ||
4298 | |||
4299 | tp->rtl_ops.autosuspend_en(tp, false); | ||
4300 | napi_disable(napi); | ||
4301 | set_bit(WORK_ENABLE, &tp->flags); | ||
4302 | |||
4303 | if (netif_carrier_ok(netdev)) { | ||
4304 | if (rtl8152_get_speed(tp) & LINK_STATUS) { | ||
4305 | rtl_start_rx(tp); | ||
4306 | } else { | ||
4307 | netif_carrier_off(netdev); | ||
4308 | tp->rtl_ops.disable(tp); | ||
4309 | netif_info(tp, link, netdev, "linking down\n"); | ||
4310 | } | ||
4311 | } | ||
4312 | |||
4313 | napi_enable(napi); | ||
4314 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
4315 | smp_mb__after_atomic(); | ||
4316 | |||
4317 | if (!list_empty(&tp->rx_done)) | ||
4318 | napi_schedule(&tp->napi); | ||
4319 | |||
4320 | usb_submit_urb(tp->intr_urb, GFP_NOIO); | ||
4321 | } else { | ||
4322 | if (netdev->flags & IFF_UP) | ||
4323 | tp->rtl_ops.autosuspend_en(tp, false); | ||
4324 | |||
4325 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
4326 | } | ||
4327 | |||
4328 | return 0; | ||
4329 | } | ||
4330 | |||
4331 | static int rtl8152_system_resume(struct r8152 *tp) | ||
4332 | { | ||
4333 | struct net_device *netdev = tp->netdev; | ||
4334 | |||
4335 | netif_device_attach(netdev); | ||
4336 | |||
4337 | if (netif_running(netdev) && netdev->flags & IFF_UP) { | ||
4338 | tp->rtl_ops.up(tp); | ||
4339 | netif_carrier_off(netdev); | ||
4340 | set_bit(WORK_ENABLE, &tp->flags); | ||
4341 | usb_submit_urb(tp->intr_urb, GFP_NOIO); | ||
4342 | } | ||
4343 | |||
4344 | return 0; | ||
4345 | } | ||
4346 | |||
4292 | static int rtl8152_runtime_suspend(struct r8152 *tp) | 4347 | static int rtl8152_runtime_suspend(struct r8152 *tp) |
4293 | { | 4348 | { |
4294 | struct net_device *netdev = tp->netdev; | 4349 | struct net_device *netdev = tp->netdev; |
@@ -4300,13 +4355,6 @@ static int rtl8152_runtime_suspend(struct r8152 *tp) | |||
4300 | if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { | 4355 | if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { |
4301 | u32 rcr = 0; | 4356 | u32 rcr = 0; |
4302 | 4357 | ||
4303 | if (delay_autosuspend(tp)) { | ||
4304 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
4305 | smp_mb__after_atomic(); | ||
4306 | ret = -EBUSY; | ||
4307 | goto out1; | ||
4308 | } | ||
4309 | |||
4310 | if (netif_carrier_ok(netdev)) { | 4358 | if (netif_carrier_ok(netdev)) { |
4311 | u32 ocp_data; | 4359 | u32 ocp_data; |
4312 | 4360 | ||
@@ -4340,6 +4388,11 @@ static int rtl8152_runtime_suspend(struct r8152 *tp) | |||
4340 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); | 4388 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); |
4341 | napi_enable(napi); | 4389 | napi_enable(napi); |
4342 | } | 4390 | } |
4391 | |||
4392 | if (delay_autosuspend(tp)) { | ||
4393 | rtl8152_runtime_resume(tp); | ||
4394 | ret = -EBUSY; | ||
4395 | } | ||
4343 | } | 4396 | } |
4344 | 4397 | ||
4345 | out1: | 4398 | out1: |
@@ -4387,50 +4440,18 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) | |||
4387 | static int rtl8152_resume(struct usb_interface *intf) | 4440 | static int rtl8152_resume(struct usb_interface *intf) |
4388 | { | 4441 | { |
4389 | struct r8152 *tp = usb_get_intfdata(intf); | 4442 | struct r8152 *tp = usb_get_intfdata(intf); |
4390 | struct net_device *netdev = tp->netdev; | 4443 | int ret; |
4391 | 4444 | ||
4392 | mutex_lock(&tp->control); | 4445 | mutex_lock(&tp->control); |
4393 | 4446 | ||
4394 | if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) | 4447 | if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) |
4395 | netif_device_attach(netdev); | 4448 | ret = rtl8152_runtime_resume(tp); |
4396 | 4449 | else | |
4397 | if (netif_running(netdev) && netdev->flags & IFF_UP) { | 4450 | ret = rtl8152_system_resume(tp); |
4398 | if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { | ||
4399 | struct napi_struct *napi = &tp->napi; | ||
4400 | |||
4401 | tp->rtl_ops.autosuspend_en(tp, false); | ||
4402 | napi_disable(napi); | ||
4403 | set_bit(WORK_ENABLE, &tp->flags); | ||
4404 | if (netif_carrier_ok(netdev)) { | ||
4405 | if (rtl8152_get_speed(tp) & LINK_STATUS) { | ||
4406 | rtl_start_rx(tp); | ||
4407 | } else { | ||
4408 | netif_carrier_off(netdev); | ||
4409 | tp->rtl_ops.disable(tp); | ||
4410 | netif_info(tp, link, netdev, | ||
4411 | "linking down\n"); | ||
4412 | } | ||
4413 | } | ||
4414 | napi_enable(napi); | ||
4415 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
4416 | smp_mb__after_atomic(); | ||
4417 | if (!list_empty(&tp->rx_done)) | ||
4418 | napi_schedule(&tp->napi); | ||
4419 | } else { | ||
4420 | tp->rtl_ops.up(tp); | ||
4421 | netif_carrier_off(netdev); | ||
4422 | set_bit(WORK_ENABLE, &tp->flags); | ||
4423 | } | ||
4424 | usb_submit_urb(tp->intr_urb, GFP_KERNEL); | ||
4425 | } else if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { | ||
4426 | if (netdev->flags & IFF_UP) | ||
4427 | tp->rtl_ops.autosuspend_en(tp, false); | ||
4428 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
4429 | } | ||
4430 | 4451 | ||
4431 | mutex_unlock(&tp->control); | 4452 | mutex_unlock(&tp->control); |
4432 | 4453 | ||
4433 | return 0; | 4454 | return ret; |
4434 | } | 4455 | } |
4435 | 4456 | ||
4436 | static int rtl8152_reset_resume(struct usb_interface *intf) | 4457 | static int rtl8152_reset_resume(struct usb_interface *intf) |