diff options
author | hayeswang <hayeswang@realtek.com> | 2014-02-18 08:49:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-18 16:40:02 -0500 |
commit | 9a4be1bd04d6df0cb1a1a0fe49430b27152bb98f (patch) | |
tree | 39405f3d31abdadb948a5811e783bc85ad545682 | |
parent | 21ff2e8976b1be23eb0125ee83eb807ad40fb226 (diff) |
r8152: support runtime suspend
Support runtime suspend for RTL8152 and RTL8153.
Move tx_bottom() from tasklet to delayed_work. That avoids to
transmit tx packets after calling autosuspend.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/r8152.c | 181 |
1 files changed, 158 insertions, 23 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 5d520bee6c0c..f303549b416a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -445,6 +445,7 @@ enum rtl8152_flags { | |||
445 | RTL8152_SET_RX_MODE, | 445 | RTL8152_SET_RX_MODE, |
446 | WORK_ENABLE, | 446 | WORK_ENABLE, |
447 | RTL8152_LINK_CHG, | 447 | RTL8152_LINK_CHG, |
448 | SELECTIVE_SUSPEND, | ||
448 | PHY_RESET, | 449 | PHY_RESET, |
449 | }; | 450 | }; |
450 | 451 | ||
@@ -877,11 +878,21 @@ static u16 sram_read(struct r8152 *tp, u16 addr) | |||
877 | static int read_mii_word(struct net_device *netdev, int phy_id, int reg) | 878 | static int read_mii_word(struct net_device *netdev, int phy_id, int reg) |
878 | { | 879 | { |
879 | struct r8152 *tp = netdev_priv(netdev); | 880 | struct r8152 *tp = netdev_priv(netdev); |
881 | int ret; | ||
880 | 882 | ||
881 | if (phy_id != R8152_PHY_ID) | 883 | if (phy_id != R8152_PHY_ID) |
882 | return -EINVAL; | 884 | return -EINVAL; |
883 | 885 | ||
884 | return r8152_mdio_read(tp, reg); | 886 | ret = usb_autopm_get_interface(tp->intf); |
887 | if (ret < 0) | ||
888 | goto out; | ||
889 | |||
890 | ret = r8152_mdio_read(tp, reg); | ||
891 | |||
892 | usb_autopm_put_interface(tp->intf); | ||
893 | |||
894 | out: | ||
895 | return ret; | ||
885 | } | 896 | } |
886 | 897 | ||
887 | static | 898 | static |
@@ -892,7 +903,12 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) | |||
892 | if (phy_id != R8152_PHY_ID) | 903 | if (phy_id != R8152_PHY_ID) |
893 | return; | 904 | return; |
894 | 905 | ||
906 | if (usb_autopm_get_interface(tp->intf) < 0) | ||
907 | return; | ||
908 | |||
895 | r8152_mdio_write(tp, reg, val); | 909 | r8152_mdio_write(tp, reg, val); |
910 | |||
911 | usb_autopm_put_interface(tp->intf); | ||
896 | } | 912 | } |
897 | 913 | ||
898 | static | 914 | static |
@@ -978,6 +994,8 @@ static void read_bulk_callback(struct urb *urb) | |||
978 | if (!netif_carrier_ok(netdev)) | 994 | if (!netif_carrier_ok(netdev)) |
979 | return; | 995 | return; |
980 | 996 | ||
997 | usb_mark_last_busy(tp->udev); | ||
998 | |||
981 | switch (status) { | 999 | switch (status) { |
982 | case 0: | 1000 | case 0: |
983 | if (urb->actual_length < ETH_ZLEN) | 1001 | if (urb->actual_length < ETH_ZLEN) |
@@ -1045,6 +1063,8 @@ static void write_bulk_callback(struct urb *urb) | |||
1045 | list_add_tail(&agg->list, &tp->tx_free); | 1063 | list_add_tail(&agg->list, &tp->tx_free); |
1046 | spin_unlock_irqrestore(&tp->tx_lock, flags); | 1064 | spin_unlock_irqrestore(&tp->tx_lock, flags); |
1047 | 1065 | ||
1066 | usb_autopm_put_interface_async(tp->intf); | ||
1067 | |||
1048 | if (!netif_carrier_ok(tp->netdev)) | 1068 | if (!netif_carrier_ok(tp->netdev)) |
1049 | return; | 1069 | return; |
1050 | 1070 | ||
@@ -1055,7 +1075,7 @@ static void write_bulk_callback(struct urb *urb) | |||
1055 | return; | 1075 | return; |
1056 | 1076 | ||
1057 | if (!skb_queue_empty(&tp->tx_queue)) | 1077 | if (!skb_queue_empty(&tp->tx_queue)) |
1058 | tasklet_schedule(&tp->tl); | 1078 | schedule_delayed_work(&tp->schedule, 0); |
1059 | } | 1079 | } |
1060 | 1080 | ||
1061 | static void intr_callback(struct urb *urb) | 1081 | static void intr_callback(struct urb *urb) |
@@ -1313,7 +1333,7 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) | |||
1313 | { | 1333 | { |
1314 | struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; | 1334 | struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; |
1315 | unsigned long flags; | 1335 | unsigned long flags; |
1316 | int remain; | 1336 | int remain, ret; |
1317 | u8 *tx_data; | 1337 | u8 *tx_data; |
1318 | 1338 | ||
1319 | __skb_queue_head_init(&skb_head); | 1339 | __skb_queue_head_init(&skb_head); |
@@ -1361,19 +1381,28 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) | |||
1361 | spin_unlock_irqrestore(&tx_queue->lock, flags); | 1381 | spin_unlock_irqrestore(&tx_queue->lock, flags); |
1362 | } | 1382 | } |
1363 | 1383 | ||
1364 | netif_tx_lock(tp->netdev); | 1384 | netif_tx_lock_bh(tp->netdev); |
1365 | 1385 | ||
1366 | if (netif_queue_stopped(tp->netdev) && | 1386 | if (netif_queue_stopped(tp->netdev) && |
1367 | skb_queue_len(&tp->tx_queue) < tp->tx_qlen) | 1387 | skb_queue_len(&tp->tx_queue) < tp->tx_qlen) |
1368 | netif_wake_queue(tp->netdev); | 1388 | netif_wake_queue(tp->netdev); |
1369 | 1389 | ||
1370 | netif_tx_unlock(tp->netdev); | 1390 | netif_tx_unlock_bh(tp->netdev); |
1391 | |||
1392 | ret = usb_autopm_get_interface(tp->intf); | ||
1393 | if (ret < 0) | ||
1394 | goto out_tx_fill; | ||
1371 | 1395 | ||
1372 | usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), | 1396 | usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), |
1373 | agg->head, (int)(tx_data - (u8 *)agg->head), | 1397 | agg->head, (int)(tx_data - (u8 *)agg->head), |
1374 | (usb_complete_t)write_bulk_callback, agg); | 1398 | (usb_complete_t)write_bulk_callback, agg); |
1375 | 1399 | ||
1376 | return usb_submit_urb(agg->urb, GFP_ATOMIC); | 1400 | ret = usb_submit_urb(agg->urb, GFP_KERNEL); |
1401 | if (ret < 0) | ||
1402 | usb_autopm_put_interface(tp->intf); | ||
1403 | |||
1404 | out_tx_fill: | ||
1405 | return ret; | ||
1377 | } | 1406 | } |
1378 | 1407 | ||
1379 | static void rx_bottom(struct r8152 *tp) | 1408 | static void rx_bottom(struct r8152 *tp) |
@@ -1511,7 +1540,6 @@ static void bottom_half(unsigned long data) | |||
1511 | return; | 1540 | return; |
1512 | 1541 | ||
1513 | rx_bottom(tp); | 1542 | rx_bottom(tp); |
1514 | tx_bottom(tp); | ||
1515 | } | 1543 | } |
1516 | 1544 | ||
1517 | static | 1545 | static |
@@ -1621,7 +1649,7 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, | |||
1621 | netif_stop_queue(netdev); | 1649 | netif_stop_queue(netdev); |
1622 | 1650 | ||
1623 | if (!list_empty(&tp->tx_free)) | 1651 | if (!list_empty(&tp->tx_free)) |
1624 | tasklet_schedule(&tp->tl); | 1652 | schedule_delayed_work(&tp->schedule, 0); |
1625 | 1653 | ||
1626 | return NETDEV_TX_OK; | 1654 | return NETDEV_TX_OK; |
1627 | } | 1655 | } |
@@ -1876,6 +1904,25 @@ static void __rtl_set_wol(struct r8152 *tp, u32 wolopts) | |||
1876 | device_set_wakeup_enable(&tp->udev->dev, false); | 1904 | device_set_wakeup_enable(&tp->udev->dev, false); |
1877 | } | 1905 | } |
1878 | 1906 | ||
1907 | static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable) | ||
1908 | { | ||
1909 | if (enable) { | ||
1910 | u32 ocp_data; | ||
1911 | |||
1912 | __rtl_set_wol(tp, WAKE_ANY); | ||
1913 | |||
1914 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); | ||
1915 | |||
1916 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); | ||
1917 | ocp_data |= LINK_OFF_WAKE_EN; | ||
1918 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); | ||
1919 | |||
1920 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); | ||
1921 | } else { | ||
1922 | __rtl_set_wol(tp, tp->saved_wolopts); | ||
1923 | } | ||
1924 | } | ||
1925 | |||
1879 | static void rtl_phy_reset(struct r8152 *tp) | 1926 | static void rtl_phy_reset(struct r8152 *tp) |
1880 | { | 1927 | { |
1881 | u16 data; | 1928 | u16 data; |
@@ -2467,6 +2514,9 @@ static void rtl_work_func_t(struct work_struct *work) | |||
2467 | { | 2514 | { |
2468 | struct r8152 *tp = container_of(work, struct r8152, schedule.work); | 2515 | struct r8152 *tp = container_of(work, struct r8152, schedule.work); |
2469 | 2516 | ||
2517 | if (usb_autopm_get_interface(tp->intf) < 0) | ||
2518 | return; | ||
2519 | |||
2470 | if (!test_bit(WORK_ENABLE, &tp->flags)) | 2520 | if (!test_bit(WORK_ENABLE, &tp->flags)) |
2471 | goto out1; | 2521 | goto out1; |
2472 | 2522 | ||
@@ -2479,12 +2529,14 @@ static void rtl_work_func_t(struct work_struct *work) | |||
2479 | if (test_bit(RTL8152_SET_RX_MODE, &tp->flags)) | 2529 | if (test_bit(RTL8152_SET_RX_MODE, &tp->flags)) |
2480 | _rtl8152_set_rx_mode(tp->netdev); | 2530 | _rtl8152_set_rx_mode(tp->netdev); |
2481 | 2531 | ||
2532 | if (tp->speed & LINK_STATUS) | ||
2533 | tx_bottom(tp); | ||
2482 | 2534 | ||
2483 | if (test_bit(PHY_RESET, &tp->flags)) | 2535 | if (test_bit(PHY_RESET, &tp->flags)) |
2484 | rtl_phy_reset(tp); | 2536 | rtl_phy_reset(tp); |
2485 | 2537 | ||
2486 | out1: | 2538 | out1: |
2487 | return; | 2539 | usb_autopm_put_interface(tp->intf); |
2488 | } | 2540 | } |
2489 | 2541 | ||
2490 | static int rtl8152_open(struct net_device *netdev) | 2542 | static int rtl8152_open(struct net_device *netdev) |
@@ -2496,6 +2548,21 @@ static int rtl8152_open(struct net_device *netdev) | |||
2496 | if (res) | 2548 | if (res) |
2497 | goto out; | 2549 | goto out; |
2498 | 2550 | ||
2551 | res = usb_autopm_get_interface(tp->intf); | ||
2552 | if (res < 0) { | ||
2553 | free_all_mem(tp); | ||
2554 | goto out; | ||
2555 | } | ||
2556 | |||
2557 | /* The WORK_ENABLE may be set when autoresume occurs */ | ||
2558 | if (test_bit(WORK_ENABLE, &tp->flags)) { | ||
2559 | clear_bit(WORK_ENABLE, &tp->flags); | ||
2560 | usb_kill_urb(tp->intr_urb); | ||
2561 | cancel_delayed_work_sync(&tp->schedule); | ||
2562 | if (tp->speed & LINK_STATUS) | ||
2563 | tp->rtl_ops.disable(tp); | ||
2564 | } | ||
2565 | |||
2499 | tp->rtl_ops.up(tp); | 2566 | tp->rtl_ops.up(tp); |
2500 | 2567 | ||
2501 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | 2568 | rtl8152_set_speed(tp, AUTONEG_ENABLE, |
@@ -2514,6 +2581,7 @@ static int rtl8152_open(struct net_device *netdev) | |||
2514 | free_all_mem(tp); | 2581 | free_all_mem(tp); |
2515 | } | 2582 | } |
2516 | 2583 | ||
2584 | usb_autopm_put_interface(tp->intf); | ||
2517 | 2585 | ||
2518 | out: | 2586 | out: |
2519 | return res; | 2587 | return res; |
@@ -2528,9 +2596,26 @@ static int rtl8152_close(struct net_device *netdev) | |||
2528 | usb_kill_urb(tp->intr_urb); | 2596 | usb_kill_urb(tp->intr_urb); |
2529 | cancel_delayed_work_sync(&tp->schedule); | 2597 | cancel_delayed_work_sync(&tp->schedule); |
2530 | netif_stop_queue(netdev); | 2598 | netif_stop_queue(netdev); |
2531 | tasklet_disable(&tp->tl); | 2599 | |
2532 | tp->rtl_ops.down(tp); | 2600 | res = usb_autopm_get_interface(tp->intf); |
2533 | tasklet_enable(&tp->tl); | 2601 | if (res < 0) { |
2602 | rtl_drop_queued_tx(tp); | ||
2603 | } else { | ||
2604 | /* | ||
2605 | * The autosuspend may have been enabled and wouldn't | ||
2606 | * be disable when autoresume occurs, because the | ||
2607 | * netif_running() would be false. | ||
2608 | */ | ||
2609 | if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { | ||
2610 | rtl_runtime_suspend_enable(tp, false); | ||
2611 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
2612 | } | ||
2613 | |||
2614 | tasklet_disable(&tp->tl); | ||
2615 | tp->rtl_ops.down(tp); | ||
2616 | tasklet_enable(&tp->tl); | ||
2617 | usb_autopm_put_interface(tp->intf); | ||
2618 | } | ||
2534 | 2619 | ||
2535 | free_all_mem(tp); | 2620 | free_all_mem(tp); |
2536 | 2621 | ||
@@ -2684,15 +2769,22 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) | |||
2684 | { | 2769 | { |
2685 | struct r8152 *tp = usb_get_intfdata(intf); | 2770 | struct r8152 *tp = usb_get_intfdata(intf); |
2686 | 2771 | ||
2687 | netif_device_detach(tp->netdev); | 2772 | if (PMSG_IS_AUTO(message)) |
2773 | set_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
2774 | else | ||
2775 | netif_device_detach(tp->netdev); | ||
2688 | 2776 | ||
2689 | if (netif_running(tp->netdev)) { | 2777 | if (netif_running(tp->netdev)) { |
2690 | clear_bit(WORK_ENABLE, &tp->flags); | 2778 | clear_bit(WORK_ENABLE, &tp->flags); |
2691 | usb_kill_urb(tp->intr_urb); | 2779 | usb_kill_urb(tp->intr_urb); |
2692 | cancel_delayed_work_sync(&tp->schedule); | 2780 | cancel_delayed_work_sync(&tp->schedule); |
2693 | tasklet_disable(&tp->tl); | 2781 | if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { |
2694 | tp->rtl_ops.down(tp); | 2782 | rtl_runtime_suspend_enable(tp, true); |
2695 | tasklet_enable(&tp->tl); | 2783 | } else { |
2784 | tasklet_disable(&tp->tl); | ||
2785 | tp->rtl_ops.down(tp); | ||
2786 | tasklet_enable(&tp->tl); | ||
2787 | } | ||
2696 | } | 2788 | } |
2697 | 2789 | ||
2698 | return 0; | 2790 | return 0; |
@@ -2702,13 +2794,23 @@ static int rtl8152_resume(struct usb_interface *intf) | |||
2702 | { | 2794 | { |
2703 | struct r8152 *tp = usb_get_intfdata(intf); | 2795 | struct r8152 *tp = usb_get_intfdata(intf); |
2704 | 2796 | ||
2705 | tp->rtl_ops.init(tp); | 2797 | if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) { |
2706 | netif_device_attach(tp->netdev); | 2798 | tp->rtl_ops.init(tp); |
2799 | netif_device_attach(tp->netdev); | ||
2800 | } | ||
2801 | |||
2707 | if (netif_running(tp->netdev)) { | 2802 | if (netif_running(tp->netdev)) { |
2708 | tp->rtl_ops.up(tp); | 2803 | if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { |
2709 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | 2804 | rtl_runtime_suspend_enable(tp, false); |
2805 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | ||
2806 | if (tp->speed & LINK_STATUS) | ||
2807 | tp->rtl_ops.disable(tp); | ||
2808 | } else { | ||
2809 | tp->rtl_ops.up(tp); | ||
2810 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
2710 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | 2811 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, |
2711 | DUPLEX_FULL); | 2812 | DUPLEX_FULL); |
2813 | } | ||
2712 | tp->speed = 0; | 2814 | tp->speed = 0; |
2713 | netif_carrier_off(tp->netdev); | 2815 | netif_carrier_off(tp->netdev); |
2714 | set_bit(WORK_ENABLE, &tp->flags); | 2816 | set_bit(WORK_ENABLE, &tp->flags); |
@@ -2722,18 +2824,31 @@ static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2722 | { | 2824 | { |
2723 | struct r8152 *tp = netdev_priv(dev); | 2825 | struct r8152 *tp = netdev_priv(dev); |
2724 | 2826 | ||
2827 | if (usb_autopm_get_interface(tp->intf) < 0) | ||
2828 | return; | ||
2829 | |||
2725 | wol->supported = WAKE_ANY; | 2830 | wol->supported = WAKE_ANY; |
2726 | wol->wolopts = __rtl_get_wol(tp); | 2831 | wol->wolopts = __rtl_get_wol(tp); |
2832 | |||
2833 | usb_autopm_put_interface(tp->intf); | ||
2727 | } | 2834 | } |
2728 | 2835 | ||
2729 | static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2836 | static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2730 | { | 2837 | { |
2731 | struct r8152 *tp = netdev_priv(dev); | 2838 | struct r8152 *tp = netdev_priv(dev); |
2839 | int ret; | ||
2840 | |||
2841 | ret = usb_autopm_get_interface(tp->intf); | ||
2842 | if (ret < 0) | ||
2843 | goto out_set_wol; | ||
2732 | 2844 | ||
2733 | __rtl_set_wol(tp, wol->wolopts); | 2845 | __rtl_set_wol(tp, wol->wolopts); |
2734 | tp->saved_wolopts = wol->wolopts & WAKE_ANY; | 2846 | tp->saved_wolopts = wol->wolopts & WAKE_ANY; |
2735 | 2847 | ||
2736 | return 0; | 2848 | usb_autopm_put_interface(tp->intf); |
2849 | |||
2850 | out_set_wol: | ||
2851 | return ret; | ||
2737 | } | 2852 | } |
2738 | 2853 | ||
2739 | static void rtl8152_get_drvinfo(struct net_device *netdev, | 2854 | static void rtl8152_get_drvinfo(struct net_device *netdev, |
@@ -2760,8 +2875,18 @@ int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) | |||
2760 | static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 2875 | static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
2761 | { | 2876 | { |
2762 | struct r8152 *tp = netdev_priv(dev); | 2877 | struct r8152 *tp = netdev_priv(dev); |
2878 | int ret; | ||
2879 | |||
2880 | ret = usb_autopm_get_interface(tp->intf); | ||
2881 | if (ret < 0) | ||
2882 | goto out; | ||
2763 | 2883 | ||
2764 | return rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex); | 2884 | ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex); |
2885 | |||
2886 | usb_autopm_put_interface(tp->intf); | ||
2887 | |||
2888 | out: | ||
2889 | return ret; | ||
2765 | } | 2890 | } |
2766 | 2891 | ||
2767 | static struct ethtool_ops ops = { | 2892 | static struct ethtool_ops ops = { |
@@ -2777,7 +2902,11 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | |||
2777 | { | 2902 | { |
2778 | struct r8152 *tp = netdev_priv(netdev); | 2903 | struct r8152 *tp = netdev_priv(netdev); |
2779 | struct mii_ioctl_data *data = if_mii(rq); | 2904 | struct mii_ioctl_data *data = if_mii(rq); |
2780 | int res = 0; | 2905 | int res; |
2906 | |||
2907 | res = usb_autopm_get_interface(tp->intf); | ||
2908 | if (res < 0) | ||
2909 | goto out; | ||
2781 | 2910 | ||
2782 | switch (cmd) { | 2911 | switch (cmd) { |
2783 | case SIOCGMIIPHY: | 2912 | case SIOCGMIIPHY: |
@@ -2800,6 +2929,9 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | |||
2800 | res = -EOPNOTSUPP; | 2929 | res = -EOPNOTSUPP; |
2801 | } | 2930 | } |
2802 | 2931 | ||
2932 | usb_autopm_put_interface(tp->intf); | ||
2933 | |||
2934 | out: | ||
2803 | return res; | 2935 | return res; |
2804 | } | 2936 | } |
2805 | 2937 | ||
@@ -2962,6 +3094,8 @@ static int rtl8152_probe(struct usb_interface *intf, | |||
2962 | tp->mii.phy_id = R8152_PHY_ID; | 3094 | tp->mii.phy_id = R8152_PHY_ID; |
2963 | tp->mii.supports_gmii = 0; | 3095 | tp->mii.supports_gmii = 0; |
2964 | 3096 | ||
3097 | intf->needs_remote_wakeup = 1; | ||
3098 | |||
2965 | r8152b_get_version(tp); | 3099 | r8152b_get_version(tp); |
2966 | tp->rtl_ops.init(tp); | 3100 | tp->rtl_ops.init(tp); |
2967 | set_ethernet_addr(tp); | 3101 | set_ethernet_addr(tp); |
@@ -3023,6 +3157,7 @@ static struct usb_driver rtl8152_driver = { | |||
3023 | .suspend = rtl8152_suspend, | 3157 | .suspend = rtl8152_suspend, |
3024 | .resume = rtl8152_resume, | 3158 | .resume = rtl8152_resume, |
3025 | .reset_resume = rtl8152_resume, | 3159 | .reset_resume = rtl8152_resume, |
3160 | .supports_autosuspend = 1, | ||
3026 | }; | 3161 | }; |
3027 | 3162 | ||
3028 | module_usb_driver(rtl8152_driver); | 3163 | module_usb_driver(rtl8152_driver); |