Merge tag 'topic/drm-misc-2015-07-23' of git://anongit.freedesktop.org/drm-intel...
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_main.c
index 2c5ce2baca8712790d51096a53868b84466f7dde..50f7a7a26821c7a40cb73294a4844406ea9caee5 100644 (file)
@@ -52,6 +52,7 @@
 #include "stmmac_ptp.h"
 #include "stmmac.h"
 #include <linux/reset.h>
+#include <linux/of_mdio.h>
 
 #define STMMAC_ALIGN(x)        L1_CACHE_ALIGN(x)
 
@@ -816,18 +817,25 @@ static int stmmac_init_phy(struct net_device *dev)
        priv->speed = 0;
        priv->oldduplex = -1;
 
-       if (priv->plat->phy_bus_name)
-               snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
-                        priv->plat->phy_bus_name, priv->plat->bus_id);
-       else
-               snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
-                        priv->plat->bus_id);
+       if (priv->plat->phy_node) {
+               phydev = of_phy_connect(dev, priv->plat->phy_node,
+                                       &stmmac_adjust_link, 0, interface);
+       } else {
+               if (priv->plat->phy_bus_name)
+                       snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
+                                priv->plat->phy_bus_name, priv->plat->bus_id);
+               else
+                       snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
+                                priv->plat->bus_id);
 
-       snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-                priv->plat->phy_addr);
-       pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
+               snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+                        priv->plat->phy_addr);
+               pr_debug("stmmac_init_phy:  trying to attach to %s\n",
+                        phy_id_fmt);
 
-       phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
+               phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
+                                    interface);
+       }
 
        if (IS_ERR(phydev)) {
                pr_err("%s: Could not attach to PHY\n", dev->name);
@@ -848,7 +856,7 @@ static int stmmac_init_phy(struct net_device *dev)
         * device as well.
         * Note: phydev->phy_id is the result of reading the UID PHY registers.
         */
-       if (phydev->phy_id == 0) {
+       if (!priv->plat->phy_node && phydev->phy_id == 0) {
                phy_disconnect(phydev);
                return -ENODEV;
        }
@@ -975,13 +983,11 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
 {
        struct sk_buff *skb;
 
-       skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
-                                flags);
+       skb = __netdev_alloc_skb_ip_align(priv->dev, priv->dma_buf_sz, flags);
        if (!skb) {
                pr_err("%s: Rx init fails; skb is NULL\n", __func__);
                return -ENOMEM;
        }
-       skb_reserve(skb, NET_IP_ALIGN);
        priv->rx_skbuff[i] = skb;
        priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
                                                priv->dma_buf_sz,
@@ -1189,41 +1195,41 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv)
                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);
+               priv->dma_erx = dma_zalloc_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);
+               priv->dma_etx = dma_zalloc_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);
+                                         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);
+               priv->dma_rx = dma_zalloc_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);
+               priv->dma_tx = dma_zalloc_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);
+                                         sizeof(struct dma_desc),
+                                         priv->dma_rx, priv->dma_rx_phy);
                        goto err_dma;
                }
        }
@@ -2800,16 +2806,15 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
  * stmmac_dvr_probe
  * @device: device pointer
  * @plat_dat: platform data pointer
- * @addr: iobase memory address
+ * @res: stmmac resource pointer
  * Description: this is the main probe function used to
  * call the alloc_etherdev, allocate the priv structure.
  * Return:
- * on success the new private structure is returned, otherwise the error
- * pointer.
+ * returns 0 on success, otherwise errno.
  */
-struct stmmac_priv *stmmac_dvr_probe(struct device *device,
-                                    struct plat_stmmacenet_data *plat_dat,
-                                    void __iomem *addr)
+int stmmac_dvr_probe(struct device *device,
+                    struct plat_stmmacenet_data *plat_dat,
+                    struct stmmac_resources *res)
 {
        int ret = 0;
        struct net_device *ndev = NULL;
@@ -2817,7 +2822,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
 
        ndev = alloc_etherdev(sizeof(struct stmmac_priv));
        if (!ndev)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        SET_NETDEV_DEV(ndev, device);
 
@@ -2828,8 +2833,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
        stmmac_set_ethtool_ops(ndev);
        priv->pause = pause;
        priv->plat = plat_dat;
-       priv->ioaddr = addr;
-       priv->dev->base_addr = (unsigned long)addr;
+       priv->ioaddr = res->addr;
+       priv->dev->base_addr = (unsigned long)res->addr;
+
+       priv->dev->irq = res->irq;
+       priv->wol_irq = res->wol_irq;
+       priv->lpi_irq = res->lpi_irq;
+
+       if (res->mac)
+               memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
+
+       dev_set_drvdata(device, priv);
 
        /* Verify driver arguments */
        stmmac_verify_args();
@@ -2944,7 +2958,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
                }
        }
 
-       return priv;
+       return 0;
 
 error_mdio_register:
        unregister_netdev(ndev);
@@ -2957,7 +2971,7 @@ error_pclk_get:
 error_clk_get:
        free_netdev(ndev);
 
-       return ERR_PTR(ret);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(stmmac_dvr_probe);