]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'stmmac_pm'
authorDavid S. Miller <davem@davemloft.net>
Thu, 16 Jan 2014 23:24:00 +0000 (15:24 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 16 Jan 2014 23:24:00 +0000 (15:24 -0800)
Srinivas Kandagatla says:

====================
net: stmmac PM related fixes.

During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
partly broken. I had to re-arrange the code to do PM correctly. There were lot
of things I did not like personally and some bits did not work in the first
place. I thought this is the nice opportunity to clean the mess up.

Here is what I did:
 any
1> Test PM suspend freeze via pm_test
It did not work for following reasons.
 - If the power to gmac is removed when it enters in low power state.
stmmac_resume could not cope up with such behaviour, it was expecting the ip
register contents to be still same as before entering low power, This
assumption is wrong. So I started to add some code to do Hardware
initialization, thats when I started to re-arrange the code. stmmac_open
contains both resource and memory allocations and hardware initialization. I
had to separate these two things in two different functions.

These two patches do that
  net: stmmac: move dma allocation to new function
  net: stmmac: move hardware setup for stmmac_open to new function

And rest of the other patches are fixing the loose ends, things like mdio
reset, which might be necessary in cases likes hibernation(I did not test).

In hibernation cases the driver was just unregistering with subsystems and
releasing resources which I did not like and its not necessary to do this as
part of PM. So using the same stmmac_suspend/resume made more sense for
hibernation cases than using stmmac_open/release.
Also fixed a NULL pointer dereference bug too.

2> Test WOL via PM_SUSPEND_FREEZE
Did get an wakeup interrupt, but could not wakeup a freeze system.
So I had to add pm_wakeup_event to the driver.
net: stmmac: notify the PM core of a wakeup event. patch.

Also few patches like
  net: stmmac: make stmmac_mdio_reset non-static
  net: stmmac: restore pinstate in pm resume.
helps the resume function to reset the phy and put back the pins in default
state.

Changes since RFC:
- Rebased to net-next on Dave's suggestion.

All these patches are Acked by Peppe.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
include/linux/stmmac.h

index 92be6b3fe547ef700a24044a18cac48b1982459b..73709e9ddcd119e1bc5dc6a4763c0cb2405e3c1a 100644 (file)
@@ -105,19 +105,19 @@ struct stmmac_priv {
        unsigned int default_addend;
        u32 adv_ts;
        int use_riwt;
+       int irq_wake;
        spinlock_t ptp_lock;
 };
 
 int stmmac_mdio_unregister(struct net_device *ndev);
 int stmmac_mdio_register(struct net_device *ndev);
+int stmmac_mdio_reset(struct mii_bus *mii);
 void stmmac_set_ethtool_ops(struct net_device *netdev);
 extern const struct stmmac_desc_ops enh_desc_ops;
 extern const struct stmmac_desc_ops ndesc_ops;
 extern const struct stmmac_hwtimestamp stmmac_ptp;
 int stmmac_ptp_register(struct stmmac_priv *priv);
 void stmmac_ptp_unregister(struct stmmac_priv *priv);
-int stmmac_freeze(struct net_device *ndev);
-int stmmac_restore(struct net_device *ndev);
 int stmmac_resume(struct net_device *ndev);
 int stmmac_suspend(struct net_device *ndev);
 int stmmac_dvr_remove(struct net_device *ndev);
index ecdc8ab50425d60214cae1829efdb6b09ca9bfe1..cddcf76f11f9f514f4c4289cec6fa98b315c078c 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/prefetch.h>
+#include <linux/pinctrl/consumer.h>
 #ifdef CONFIG_STMMAC_DEBUG_FS
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -776,6 +777,7 @@ static int stmmac_init_phy(struct net_device *dev)
        char phy_id_fmt[MII_BUS_ID_SIZE + 3];
        char bus_id[MII_BUS_ID_SIZE];
        int interface = priv->plat->interface;
+       int max_speed = priv->plat->max_speed;
        priv->oldlink = 0;
        priv->speed = 0;
        priv->oldduplex = -1;
@@ -800,7 +802,8 @@ static int stmmac_init_phy(struct net_device *dev)
 
        /* Stop Advertising 1000BASE Capability if interface is not GMII */
        if ((interface == PHY_INTERFACE_MODE_MII) ||
-           (interface == PHY_INTERFACE_MODE_RMII))
+           (interface == PHY_INTERFACE_MODE_RMII) ||
+               (max_speed < 1000 &&  max_speed > 0))
                phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
                                         SUPPORTED_1000baseT_Full);
 
@@ -994,66 +997,6 @@ static int init_dma_desc_rings(struct net_device *dev)
                pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__,
                         txsize, rxsize, bfsize);
 
-       if (priv->extend_desc) {
-               priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
-                                                  sizeof(struct
-                                                         dma_extended_desc),
-                                                  &priv->dma_rx_phy,
-                                                  GFP_KERNEL);
-               if (!priv->dma_erx)
-                       goto err_dma;
-
-               priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
-                                                  sizeof(struct
-                                                         dma_extended_desc),
-                                                  &priv->dma_tx_phy,
-                                                  GFP_KERNEL);
-               if (!priv->dma_etx) {
-                       dma_free_coherent(priv->device, priv->dma_rx_size *
-                                       sizeof(struct dma_extended_desc),
-                                       priv->dma_erx, priv->dma_rx_phy);
-                       goto err_dma;
-               }
-       } else {
-               priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
-                                                 sizeof(struct dma_desc),
-                                                 &priv->dma_rx_phy,
-                                                 GFP_KERNEL);
-               if (!priv->dma_rx)
-                       goto err_dma;
-
-               priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
-                                                 sizeof(struct dma_desc),
-                                                 &priv->dma_tx_phy,
-                                                 GFP_KERNEL);
-               if (!priv->dma_tx) {
-                       dma_free_coherent(priv->device, priv->dma_rx_size *
-                                       sizeof(struct dma_desc),
-                                       priv->dma_rx, priv->dma_rx_phy);
-                       goto err_dma;
-               }
-       }
-
-       priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
-                                           GFP_KERNEL);
-       if (!priv->rx_skbuff_dma)
-               goto err_rx_skbuff_dma;
-
-       priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
-                                       GFP_KERNEL);
-       if (!priv->rx_skbuff)
-               goto err_rx_skbuff;
-
-       priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
-                                           GFP_KERNEL);
-       if (!priv->tx_skbuff_dma)
-               goto err_tx_skbuff_dma;
-
-       priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
-                                       GFP_KERNEL);
-       if (!priv->tx_skbuff)
-               goto err_tx_skbuff;
-
        if (netif_msg_probe(priv)) {
                pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__,
                         (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy);
@@ -1121,30 +1064,6 @@ static int init_dma_desc_rings(struct net_device *dev)
 err_init_rx_buffers:
        while (--i >= 0)
                stmmac_free_rx_buffers(priv, i);
-       kfree(priv->tx_skbuff);
-err_tx_skbuff:
-       kfree(priv->tx_skbuff_dma);
-err_tx_skbuff_dma:
-       kfree(priv->rx_skbuff);
-err_rx_skbuff:
-       kfree(priv->rx_skbuff_dma);
-err_rx_skbuff_dma:
-       if (priv->extend_desc) {
-               dma_free_coherent(priv->device, priv->dma_tx_size *
-                                 sizeof(struct dma_extended_desc),
-                                 priv->dma_etx, priv->dma_tx_phy);
-               dma_free_coherent(priv->device, priv->dma_rx_size *
-                                 sizeof(struct dma_extended_desc),
-                                 priv->dma_erx, priv->dma_rx_phy);
-       } else {
-               dma_free_coherent(priv->device,
-                               priv->dma_tx_size * sizeof(struct dma_desc),
-                               priv->dma_tx, priv->dma_tx_phy);
-               dma_free_coherent(priv->device,
-                               priv->dma_rx_size * sizeof(struct dma_desc),
-                               priv->dma_rx, priv->dma_rx_phy);
-       }
-err_dma:
        return ret;
 }
 
@@ -1180,6 +1099,85 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv)
        }
 }
 
+static int alloc_dma_desc_resources(struct stmmac_priv *priv)
+{
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int rxsize = priv->dma_rx_size;
+       int ret = -ENOMEM;
+
+       priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
+                                           GFP_KERNEL);
+       if (!priv->rx_skbuff_dma)
+               return -ENOMEM;
+
+       priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
+                                       GFP_KERNEL);
+       if (!priv->rx_skbuff)
+               goto err_rx_skbuff;
+
+       priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
+                                           GFP_KERNEL);
+       if (!priv->tx_skbuff_dma)
+               goto err_tx_skbuff_dma;
+
+       priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
+                                       GFP_KERNEL);
+       if (!priv->tx_skbuff)
+               goto err_tx_skbuff;
+
+       if (priv->extend_desc) {
+               priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
+                                                  sizeof(struct
+                                                         dma_extended_desc),
+                                                  &priv->dma_rx_phy,
+                                                  GFP_KERNEL);
+               if (!priv->dma_erx)
+                       goto err_dma;
+
+               priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
+                                                  sizeof(struct
+                                                         dma_extended_desc),
+                                                  &priv->dma_tx_phy,
+                                                  GFP_KERNEL);
+               if (!priv->dma_etx) {
+                       dma_free_coherent(priv->device, priv->dma_rx_size *
+                                       sizeof(struct dma_extended_desc),
+                                       priv->dma_erx, priv->dma_rx_phy);
+                       goto err_dma;
+               }
+       } else {
+               priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
+                                                 sizeof(struct dma_desc),
+                                                 &priv->dma_rx_phy,
+                                                 GFP_KERNEL);
+               if (!priv->dma_rx)
+                       goto err_dma;
+
+               priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
+                                                 sizeof(struct dma_desc),
+                                                 &priv->dma_tx_phy,
+                                                 GFP_KERNEL);
+               if (!priv->dma_tx) {
+                       dma_free_coherent(priv->device, priv->dma_rx_size *
+                                       sizeof(struct dma_desc),
+                                       priv->dma_rx, priv->dma_rx_phy);
+                       goto err_dma;
+               }
+       }
+
+       return 0;
+
+err_dma:
+       kfree(priv->tx_skbuff);
+err_tx_skbuff:
+       kfree(priv->tx_skbuff_dma);
+err_tx_skbuff_dma:
+       kfree(priv->rx_skbuff);
+err_rx_skbuff:
+       kfree(priv->rx_skbuff_dma);
+       return ret;
+}
+
 static void free_dma_desc_resources(struct stmmac_priv *priv)
 {
        /* Release the DMA TX/RX socket buffers */
@@ -1588,6 +1586,86 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
        add_timer(&priv->txtimer);
 }
 
+/**
+ * stmmac_hw_setup: setup mac in a usable state.
+ *  @dev : pointer to the device structure.
+ *  Description:
+ *  This function sets up the ip in a usable state.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_hw_setup(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int ret;
+
+       ret = init_dma_desc_rings(dev);
+       if (ret < 0) {
+               pr_err("%s: DMA descriptors initialization failed\n", __func__);
+               return ret;
+       }
+       /* DMA initialization and SW reset */
+       ret = stmmac_init_dma_engine(priv);
+       if (ret < 0) {
+               pr_err("%s: DMA engine initialization failed\n", __func__);
+               return ret;
+       }
+
+       /* Copy the MAC addr into the HW  */
+       priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
+
+       /* If required, perform hw setup of the bus. */
+       if (priv->plat->bus_setup)
+               priv->plat->bus_setup(priv->ioaddr);
+
+       /* Initialize the MAC Core */
+       priv->hw->mac->core_init(priv->ioaddr);
+
+       /* Enable the MAC Rx/Tx */
+       stmmac_set_mac(priv->ioaddr, true);
+
+       /* Set the HW DMA mode and the COE */
+       stmmac_dma_operation_mode(priv);
+
+       stmmac_mmc_setup(priv);
+
+       ret = stmmac_init_ptp(priv);
+       if (ret)
+               pr_warn("%s: failed PTP initialisation\n", __func__);
+
+#ifdef CONFIG_STMMAC_DEBUG_FS
+       ret = stmmac_init_fs(dev);
+       if (ret < 0)
+               pr_warn("%s: failed debugFS registration\n", __func__);
+#endif
+       /* Start the ball rolling... */
+       pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
+       priv->hw->dma->start_tx(priv->ioaddr);
+       priv->hw->dma->start_rx(priv->ioaddr);
+
+       /* Dump DMA/MAC registers */
+       if (netif_msg_hw(priv)) {
+               priv->hw->mac->dump_regs(priv->ioaddr);
+               priv->hw->dma->dump_regs(priv->ioaddr);
+       }
+       priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
+
+       priv->eee_enabled = stmmac_eee_init(priv);
+
+       stmmac_init_tx_coalesce(priv);
+
+       if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
+               priv->rx_riwt = MAX_DMA_RIWT;
+               priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
+       }
+
+       if (priv->pcs && priv->hw->mac->ctrl_ane)
+               priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
+
+       return 0;
+}
+
 /**
  *  stmmac_open - open entry point of the driver
  *  @dev : pointer to the device structure.
@@ -1616,33 +1694,29 @@ static int stmmac_open(struct net_device *dev)
                }
        }
 
+       /* Extra statistics */
+       memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
+       priv->xstats.threshold = tc;
+
        /* Create and initialize the TX/RX descriptors chains. */
        priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
        priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
        priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
 
-       ret = init_dma_desc_rings(dev);
+       alloc_dma_desc_resources(priv);
        if (ret < 0) {
-               pr_err("%s: DMA descriptors initialization failed\n", __func__);
+               pr_err("%s: DMA descriptors allocation failed\n", __func__);
                goto dma_desc_error;
        }
 
-       /* DMA initialization and SW reset */
-       ret = stmmac_init_dma_engine(priv);
+       ret = stmmac_hw_setup(dev);
        if (ret < 0) {
-               pr_err("%s: DMA engine initialization failed\n", __func__);
+               pr_err("%s: Hw setup failed\n", __func__);
                goto init_error;
        }
 
-       /* Copy the MAC addr into the HW  */
-       priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
-
-       /* If required, perform hw setup of the bus. */
-       if (priv->plat->bus_setup)
-               priv->plat->bus_setup(priv->ioaddr);
-
-       /* Initialize the MAC Core */
-       priv->hw->mac->core_init(priv->ioaddr);
+       if (priv->phydev)
+               phy_start(priv->phydev);
 
        /* Request the IRQ lines */
        ret = request_irq(dev->irq, stmmac_interrupt,
@@ -1675,55 +1749,6 @@ static int stmmac_open(struct net_device *dev)
                }
        }
 
-       /* Enable the MAC Rx/Tx */
-       stmmac_set_mac(priv->ioaddr, true);
-
-       /* Set the HW DMA mode and the COE */
-       stmmac_dma_operation_mode(priv);
-
-       /* Extra statistics */
-       memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
-       priv->xstats.threshold = tc;
-
-       stmmac_mmc_setup(priv);
-
-       ret = stmmac_init_ptp(priv);
-       if (ret)
-               pr_warn("%s: failed PTP initialisation\n", __func__);
-
-#ifdef CONFIG_STMMAC_DEBUG_FS
-       ret = stmmac_init_fs(dev);
-       if (ret < 0)
-               pr_warn("%s: failed debugFS registration\n", __func__);
-#endif
-       /* Start the ball rolling... */
-       pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
-       priv->hw->dma->start_tx(priv->ioaddr);
-       priv->hw->dma->start_rx(priv->ioaddr);
-
-       /* Dump DMA/MAC registers */
-       if (netif_msg_hw(priv)) {
-               priv->hw->mac->dump_regs(priv->ioaddr);
-               priv->hw->dma->dump_regs(priv->ioaddr);
-       }
-
-       if (priv->phydev)
-               phy_start(priv->phydev);
-
-       priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
-
-       priv->eee_enabled = stmmac_eee_init(priv);
-
-       stmmac_init_tx_coalesce(priv);
-
-       if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
-               priv->rx_riwt = MAX_DMA_RIWT;
-               priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
-       }
-
-       if (priv->pcs && priv->hw->mac->ctrl_ane)
-               priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
-
        napi_enable(&priv->napi);
        netif_start_queue(dev);
 
@@ -2295,6 +2320,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
        struct net_device *dev = (struct net_device *)dev_id;
        struct stmmac_priv *priv = netdev_priv(dev);
 
+       if (priv->irq_wake)
+               pm_wakeup_event(priv->device, 0);
+
        if (unlikely(!dev)) {
                pr_err("%s: invalid dev pointer\n", __func__);
                return IRQ_NONE;
@@ -2836,10 +2864,12 @@ int stmmac_suspend(struct net_device *ndev)
        stmmac_clear_descriptors(priv);
 
        /* Enable Power down mode by programming the PMT regs */
-       if (device_may_wakeup(priv->device))
+       if (device_may_wakeup(priv->device)) {
                priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
-       else {
+               priv->irq_wake = 1;
+       } else {
                stmmac_set_mac(priv->ioaddr, false);
+               pinctrl_pm_select_sleep_state(priv->device);
                /* Disable clock in case of PWM is off */
                clk_disable_unprepare(priv->stmmac_clk);
        }
@@ -2863,18 +2893,21 @@ int stmmac_resume(struct net_device *ndev)
         * this bit because it can generate problems while resuming
         * from another devices (e.g. serial console).
         */
-       if (device_may_wakeup(priv->device))
+       if (device_may_wakeup(priv->device)) {
                priv->hw->mac->pmt(priv->ioaddr, 0);
-       else
+               priv->irq_wake = 0;
+       } else {
+               pinctrl_pm_select_default_state(priv->device);
                /* enable the clk prevously disabled */
                clk_prepare_enable(priv->stmmac_clk);
+               /* reset the phy so that it's ready */
+               if (priv->mii)
+                       stmmac_mdio_reset(priv->mii);
+       }
 
        netif_device_attach(ndev);
 
-       /* Enable the MAC and DMA */
-       stmmac_set_mac(priv->ioaddr, true);
-       priv->hw->dma->start_tx(priv->ioaddr);
-       priv->hw->dma->start_rx(priv->ioaddr);
+       stmmac_hw_setup(ndev);
 
        napi_enable(&priv->napi);
 
@@ -2887,22 +2920,6 @@ int stmmac_resume(struct net_device *ndev)
 
        return 0;
 }
-
-int stmmac_freeze(struct net_device *ndev)
-{
-       if (!ndev || !netif_running(ndev))
-               return 0;
-
-       return stmmac_release(ndev);
-}
-
-int stmmac_restore(struct net_device *ndev)
-{
-       if (!ndev || !netif_running(ndev))
-               return 0;
-
-       return stmmac_open(ndev);
-}
 #endif /* CONFIG_PM */
 
 /* Driver can be configured w/ and w/ both PCI and Platf drivers
index fe7bc9903867640179ffde86d57f81b6c18a745e..a468eb10782361e31fd0b0af5ce6be33d68a2578 100644 (file)
@@ -128,7 +128,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
  * @bus: points to the mii_bus structure
  * Description: reset the MII bus
  */
-static int stmmac_mdio_reset(struct mii_bus *bus)
+int stmmac_mdio_reset(struct mii_bus *bus)
 {
 #if defined(CONFIG_STMMAC_PLATFORM)
        struct net_device *ndev = bus->priv;
@@ -166,7 +166,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
                        udelay(data->delays[1]);
                        gpio_set_value(reset_gpio, active_low ? 1 : 0);
                        udelay(data->delays[2]);
-                       gpio_free(reset_gpio);
                }
        }
 #endif
index 38bd1f4fbe33bae915e878c4e4c333e993b66de8..6d0bf222623a56a174c35e8a06ed8e5d6d6d3074 100644 (file)
@@ -42,6 +42,10 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
        *mac = of_get_mac_address(np);
        plat->interface = of_get_phy_mode(np);
 
+       /* Get max speed of operation from device tree */
+       if (of_property_read_u32(np, "max-speed", &plat->max_speed))
+               plat->max_speed = -1;
+
        plat->bus_id = of_alias_get_id(np, "ethernet");
        if (plat->bus_id < 0)
                plat->bus_id = 0;
@@ -206,56 +210,36 @@ static int stmmac_pltfr_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_PM
 static int stmmac_pltfr_suspend(struct device *dev)
-{
-       struct net_device *ndev = dev_get_drvdata(dev);
-
-       return stmmac_suspend(ndev);
-}
-
-static int stmmac_pltfr_resume(struct device *dev)
-{
-       struct net_device *ndev = dev_get_drvdata(dev);
-
-       return stmmac_resume(ndev);
-}
-
-static int stmmac_pltfr_freeze(struct device *dev)
 {
        int ret;
-       struct plat_stmmacenet_data *plat_dat = dev_get_platdata(dev);
        struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
        struct platform_device *pdev = to_platform_device(dev);
 
-       ret = stmmac_freeze(ndev);
-       if (plat_dat->exit)
-               plat_dat->exit(pdev);
+       ret = stmmac_suspend(ndev);
+       if (priv->plat->exit)
+               priv->plat->exit(pdev);
 
        return ret;
 }
 
-static int stmmac_pltfr_restore(struct device *dev)
+static int stmmac_pltfr_resume(struct device *dev)
 {
-       struct plat_stmmacenet_data *plat_dat = dev_get_platdata(dev);
        struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
        struct platform_device *pdev = to_platform_device(dev);
 
-       if (plat_dat->init)
-               plat_dat->init(pdev);
+       if (priv->plat->init)
+               priv->plat->init(pdev);
 
-       return stmmac_restore(ndev);
+       return stmmac_resume(ndev);
 }
 
-static const struct dev_pm_ops stmmac_pltfr_pm_ops = {
-       .suspend = stmmac_pltfr_suspend,
-       .resume = stmmac_pltfr_resume,
-       .freeze = stmmac_pltfr_freeze,
-       .thaw = stmmac_pltfr_restore,
-       .restore = stmmac_pltfr_restore,
-};
-#else
-static const struct dev_pm_ops stmmac_pltfr_pm_ops;
 #endif /* CONFIG_PM */
 
+static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
+                       stmmac_pltfr_suspend, stmmac_pltfr_resume);
+
 static const struct of_device_id stmmac_dt_ids[] = {
        { .compatible = "st,spear600-gmac"},
        { .compatible = "snps,dwmac-3.610"},
index bb5deb0feb6bc2190212d53ea290947287a4007a..33ace712e7e818e7409732d77d9ea4583b7a78ad 100644 (file)
@@ -110,6 +110,7 @@ struct plat_stmmacenet_data {
        int force_sf_dma_mode;
        int force_thresh_dma_mode;
        int riwt_off;
+       int max_speed;
        void (*fix_mac_speed)(void *priv, unsigned int speed);
        void (*bus_setup)(void __iomem *ioaddr);
        int (*init)(struct platform_device *pdev);