Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'r8152-pm-fixxes'

Takashi Iwai says:

====================
r8152: Fix a couple of PM problems

it seems that r8152 driver suffers from the deadlock at both runtime
and system PM. Formerly, it was seen more often at hibernation
resume, but now it's triggered more frequently, as reported in SUSE
Bugzilla:
https://bugzilla.suse.com/show_bug.cgi?id=1186194

While debugging the problem, I stumbled on a few obvious bugs and here
is the results with two patches for addressing the resume problem.

***

However, the story doesn't end here, unfortunately, and those patches
don't seem sufficing. The rest major problem is that the driver calls
napi_disable() and napi_enable() in the PM suspend callbacks. This
makes the system stalling at (runtime-)suspend. If we drop
napi_disable() and napi_enable() calls in the PM suspend callbacks, it
starts working (that was the result in Bugzilla comment 13):
https://bugzilla.suse.com/show_bug.cgi?id=1186194#c13

So, my patches aren't enough and we still need to investigate
further. It'd be appreciated if anyone can give a fix or a hint for
more debugging. The usage of napi_disable() at PM callbacks is unique
in this driver and looks rather suspicious to me; but I'm no expert in
this area so I might be wrong...
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+21 -11
+21 -11
drivers/net/usb/r8152.c
··· 1552 1552 rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, 1553 1553 u32 advertising); 1554 1554 1555 - static int rtl8152_set_mac_address(struct net_device *netdev, void *p) 1555 + static int __rtl8152_set_mac_address(struct net_device *netdev, void *p, 1556 + bool in_resume) 1556 1557 { 1557 1558 struct r8152 *tp = netdev_priv(netdev); 1558 1559 struct sockaddr *addr = p; ··· 1562 1561 if (!is_valid_ether_addr(addr->sa_data)) 1563 1562 goto out1; 1564 1563 1565 - ret = usb_autopm_get_interface(tp->intf); 1566 - if (ret < 0) 1567 - goto out1; 1564 + if (!in_resume) { 1565 + ret = usb_autopm_get_interface(tp->intf); 1566 + if (ret < 0) 1567 + goto out1; 1568 + } 1568 1569 1569 1570 mutex_lock(&tp->control); 1570 1571 ··· 1578 1575 1579 1576 mutex_unlock(&tp->control); 1580 1577 1581 - usb_autopm_put_interface(tp->intf); 1578 + if (!in_resume) 1579 + usb_autopm_put_interface(tp->intf); 1582 1580 out1: 1583 1581 return ret; 1582 + } 1583 + 1584 + static int rtl8152_set_mac_address(struct net_device *netdev, void *p) 1585 + { 1586 + return __rtl8152_set_mac_address(netdev, p, false); 1584 1587 } 1585 1588 1586 1589 /* Devices containing proper chips can support a persistent ··· 1707 1698 return ret; 1708 1699 } 1709 1700 1710 - static int set_ethernet_addr(struct r8152 *tp) 1701 + static int set_ethernet_addr(struct r8152 *tp, bool in_resume) 1711 1702 { 1712 1703 struct net_device *dev = tp->netdev; 1713 1704 struct sockaddr sa; ··· 1720 1711 if (tp->version == RTL_VER_01) 1721 1712 ether_addr_copy(dev->dev_addr, sa.sa_data); 1722 1713 else 1723 - ret = rtl8152_set_mac_address(dev, &sa); 1714 + ret = __rtl8152_set_mac_address(dev, &sa, in_resume); 1724 1715 1725 1716 return ret; 1726 1717 } ··· 6772 6763 tp->rtl_ops.down(tp); 6773 6764 6774 6765 mutex_unlock(&tp->control); 6775 - 6776 - usb_autopm_put_interface(tp->intf); 6777 6766 } 6767 + 6768 + if (!res) 6769 + usb_autopm_put_interface(tp->intf); 6778 6770 6779 6771 free_all_mem(tp); 6780 6772 ··· 8453 8443 clear_bit(SELECTIVE_SUSPEND, &tp->flags); 8454 8444 tp->rtl_ops.init(tp); 8455 8445 queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); 8456 - set_ethernet_addr(tp); 8446 + set_ethernet_addr(tp, true); 8457 8447 return rtl8152_resume(intf); 8458 8448 } 8459 8449 ··· 9654 9644 tp->rtl_fw.retry = true; 9655 9645 #endif 9656 9646 queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); 9657 - set_ethernet_addr(tp); 9647 + set_ethernet_addr(tp, false); 9658 9648 9659 9649 usb_set_intfdata(intf, tp); 9660 9650