Skip to content

Commit e4fbce7

Browse files
rjwysockidavem330
authored andcommitted
r8169: Fix runtime power management
I noticed that one of the post-2.6.36 patches broke runtime PM of the r8169 on my MSI Wind test machine in such a way that the link was not brought up after reconnecting the network cable. In the process of debugging the issue I realized that we only should invoke the runtime PM functions in rtl8169_check_link_status() when link change is reported and if we do so, the problem goes away. Moreover, this allows rtl8169_runtime_idle() to be simplified quite a bit. Signed-off-by: Rafael J. Wysocki <[email protected]> Acked-by: Francois Romieu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6934d33 commit e4fbce7

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

drivers/net/r8169.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
744744
mdio_write(ioaddr, MII_BMCR, val & 0xffff);
745745
}
746746

747-
static void rtl8169_check_link_status(struct net_device *dev,
747+
static void __rtl8169_check_link_status(struct net_device *dev,
748748
struct rtl8169_private *tp,
749-
void __iomem *ioaddr)
749+
void __iomem *ioaddr,
750+
bool pm)
750751
{
751752
unsigned long flags;
752753

753754
spin_lock_irqsave(&tp->lock, flags);
754755
if (tp->link_ok(ioaddr)) {
755756
/* This is to cancel a scheduled suspend if there's one. */
756-
pm_request_resume(&tp->pci_dev->dev);
757+
if (pm)
758+
pm_request_resume(&tp->pci_dev->dev);
757759
netif_carrier_on(dev);
758760
netif_info(tp, ifup, dev, "link up\n");
759761
} else {
760762
netif_carrier_off(dev);
761763
netif_info(tp, ifdown, dev, "link down\n");
762-
pm_schedule_suspend(&tp->pci_dev->dev, 100);
764+
if (pm)
765+
pm_schedule_suspend(&tp->pci_dev->dev, 100);
763766
}
764767
spin_unlock_irqrestore(&tp->lock, flags);
765768
}
766769

770+
static void rtl8169_check_link_status(struct net_device *dev,
771+
struct rtl8169_private *tp,
772+
void __iomem *ioaddr)
773+
{
774+
__rtl8169_check_link_status(dev, tp, ioaddr, false);
775+
}
776+
767777
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
768778

769779
static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
@@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
46004610
}
46014611

46024612
if (status & LinkChg)
4603-
rtl8169_check_link_status(dev, tp, ioaddr);
4613+
__rtl8169_check_link_status(dev, tp, ioaddr, true);
46044614

46054615
/* We need to see the lastest version of tp->intr_mask to
46064616
* avoid ignoring an MSI interrupt and having to wait for
@@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device)
48904900
struct net_device *dev = pci_get_drvdata(pdev);
48914901
struct rtl8169_private *tp = netdev_priv(dev);
48924902

4893-
if (!tp->TxDescArray)
4894-
return 0;
4895-
4896-
rtl8169_check_link_status(dev, tp, tp->mmio_addr);
4897-
return -EBUSY;
4903+
return tp->TxDescArray ? -EBUSY : 0;
48984904
}
48994905

49004906
static const struct dev_pm_ops rtl8169_pm_ops = {

0 commit comments

Comments
 (0)