Thread (27 messages) flat view 27 messages, 6 authors, 2012-07-31
STALE5156d

Revision v1 of 12 in this series.

Revisions (12)
  1. v1 [diff vs current]
  2. v1 [diff vs current]
  3. v1 current
  4. v1 [diff vs current]
  5. v1 [diff vs current]
  6. v1 [diff vs current]
  7. v2 [diff vs current]
  8. v2 [diff vs current]
  9. v2 [diff vs current]
  10. v2 [diff vs current]
  11. v2 [diff vs current]
  12. v2 [diff vs current]

[PATCH 3/6] mv643xx.c: Add basic device tree support.

From: Amar Nath <hidden>
Date: 2012-07-30 16:19:32

Hi Ian,

On Mon, Jul 30, 2012 at 8:45 PM, Ian Molton [off-list ref]wrote:
quoted hunk ↗ jump to hunk
This patch adds basic device tree support to the mv643xx ethernet driver.

It should be enough for most current users of the device, and should allow
a fairly painless migration once proper support for clk devices is
available
to those platforms.

Signed-off-by: Ian Molton <redacted>
---
 drivers/net/ethernet/marvell/mv643xx_eth.c |  111
++++++++++++++++++++++++----
 1 file changed, 97 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c
b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 92497eb..579692f 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -48,6 +48,9 @@
 #include <linux/ethtool.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -2601,11 +2604,11 @@ static void infer_hw_params(struct
mv643xx_eth_shared_private *msp)
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 {
        static int mv643xx_eth_version_printed;
-       struct mv643xx_eth_shared_platform_data *pd =
pdev->dev.platform_data;
+       struct mv643xx_eth_shared_platform_data *pd;
        struct mv643xx_eth_shared_private *msp;
        const struct mbus_dram_target_info *dram;
        struct resource *res;
-       int ret;
+       int ret, irq = -1;

        if (!mv643xx_eth_version_printed++)
                pr_notice("MV-643xx 10/100/1000 ethernet driver version
%s\n",
@@ -2625,6 +2628,23 @@ static int mv643xx_eth_shared_probe(struct
platform_device *pdev)
        if (msp->base == NULL)
                goto out_free;

+       if (pdev->dev.of_node) {
+               struct device_node *np = NULL;
+
+               /* when all users of this driver use FDT, we can remove
this */
+               pd = kzalloc(sizeof(*pd), GFP_ATOMIC);
+               if (!pd) {
+                       dev_dbg(&pdev->dev, "Could not allocate platform
data\n");
+                       goto out_free;
+               }
+
+               np = of_parse_phandle(pdev->dev.of_node, "shared_smi", 0);
+               if (np)
+                       pd->shared_smi = of_find_device_by_node(np);
+
+       } else {
+               pd = pdev->dev.platform_data;
+       }
        /*
         * Set up and register SMI bus.
         */
@@ -2654,15 +2674,22 @@ static int mv643xx_eth_shared_probe(struct
platform_device *pdev)
        /*
         * Check whether the error interrupt is hooked up.
         */
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (res != NULL) {
+       if (pdev->dev.of_node) {
+               irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+       } else {
+               res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+               if (res)
+                       irq = res->start;
+       }
+
+       if (irq != -1) {
                int err;

-               err = request_irq(res->start, mv643xx_eth_err_irq,
+               err = request_irq(irq, mv643xx_eth_err_irq,
                                  IRQF_SHARED, "mv643xx_eth", msp);
                if (!err) {
                        writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);
-                       msp->err_interrupt = res->start;
+                       msp->err_interrupt = irq;
                }
        }
@@ -2675,6 +2702,10 @@ static int mv643xx_eth_shared_probe(struct
platform_device *pdev)

        msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
                                        pd->tx_csum_limit : 9 * 1024;
+
+       if (pdev->dev.of_node)
+               kfree(pd);  /* If we created a fake pd, free it now */
+
        infer_hw_params(msp);

        platform_set_drvdata(pdev, msp);
@@ -2708,12 +2739,21 @@ static int mv643xx_eth_shared_remove(struct
platform_device *pdev)
        return 0;
 }

+#ifdef CONFIG_OF
+static struct of_device_id mv_mdio_dt_ids[] __devinitdata = {
+       { .compatible = "marvell,mdio-mv643xx", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mv_mdio_dt_ids);
+#endif
+
 static struct platform_driver mv643xx_eth_shared_driver = {
        .probe          = mv643xx_eth_shared_probe,
        .remove         = mv643xx_eth_shared_remove,
        .driver = {
                .name   = MV643XX_ETH_SHARED_NAME,
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(mv_mdio_dt_ids),
        },
 };
@@ -2873,7 +2913,31 @@ static int mv643xx_eth_probe(struct platform_device
*pdev)
        struct resource *res;
        int err;

-       pd = pdev->dev.platform_data;
+       if (pdev->dev.of_node) {
+               struct device_node *np = NULL;
+
+               /* when all users of this driver use FDT, we can remove
this */
+               pd = kzalloc(sizeof(*pd), GFP_ATOMIC);
+               if (!pd) {
+                       dev_dbg(&pdev->dev, "Could not allocate platform
data\n");
+                       return -ENOMEM;
+               }
+
+               of_property_read_u32(pdev->dev.of_node,
+                       "port_number", &pd->port_number);
+               of_property_read_u32(pdev->dev.of_node,
+                       "phy_addr", &pd->phy_addr);
+               np = of_parse_phandle(pdev->dev.of_node, "mdio", 0);
+               if (np) {
+                       pd->shared = of_find_device_by_node(np);
+               } else {
+                       kfree(pd);
+                       return -ENODEV;
+               }
+       } else {
+               pd = pdev->dev.platform_data;
+       }
+
        if (pd == NULL) {
                dev_err(&pdev->dev, "no mv643xx_eth_platform_data\n");
                return -ENODEV;
Can this check for pd be moved in the else part above as well, as for the
pd allocation with kzalloc,
we have already made a check for memory allocation failure?


quoted hunk ↗ jump to hunk
@@ -2881,12 +2945,15 @@ static int mv643xx_eth_probe(struct
platform_device *pdev)

        if (pd->shared == NULL) {
                dev_err(&pdev->dev, "no
mv643xx_eth_platform_data->shared\n");
-               return -ENODEV;
+               err = -ENODEV;
+               goto out_free_pd;
        }

        dev = alloc_etherdev_mq(sizeof(struct mv643xx_eth_private), 8);
-       if (!dev)
-               return -ENOMEM;
+       if (!dev) {
+               err = -ENOMEM;
+               goto out_free_pd;
+       }

        mp = netdev_priv(dev);
        platform_set_drvdata(pdev, mp);
@@ -2923,6 +2990,8 @@ static int mv643xx_eth_probe(struct platform_device
*pdev)

        init_pscr(mp, pd->speed, pd->duplex);

+       if (pdev->dev.of_node)
+               kfree(pd); /* If we created a fake pd, free it now */

        mib_counters_clear(mp);
@@ -2942,10 +3011,13 @@ static int mv643xx_eth_probe(struct
platform_device *pdev)
        mp->rx_oom.data = (unsigned long)mp;
        mp->rx_oom.function = oom_timer_wrapper;

-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       BUG_ON(!res);
-       dev->irq = res->start;
+       if (pdev->dev.of_node) {
+               dev->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+       } else {
+               res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+               BUG_ON(!res);
+               dev->irq = res->start;
+       }

        dev->netdev_ops = &mv643xx_eth_netdev_ops;
@@ -2991,6 +3063,8 @@ out:
        }
 #endif
        free_netdev(dev);
+out_free_pd:
+       kfree(pd);

        return err;
 }
@@ -3030,6 +3104,14 @@ static void mv643xx_eth_shutdown(struct
platform_device *pdev)
                port_reset(mp);
 }

+#ifdef CONFIG_OF
+static struct of_device_id mv_eth_dt_ids[] __devinitdata = {
+       { .compatible = "marvell,mv643xx", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mv_eth_dt_ids);
+#endif
+
 static struct platform_driver mv643xx_eth_driver = {
        .probe          = mv643xx_eth_probe,
        .remove         = mv643xx_eth_remove,
@@ -3037,6 +3119,7 @@ static struct platform_driver mv643xx_eth_driver = {
        .driver = {
                .name   = MV643XX_ETH_NAME,
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(mv_eth_dt_ids),
        },
 };

--
1.7.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Regards,
-Amar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120730/a2bd46ae/attachment-0001.html>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help