Hi Ian,<br><br><div class="gmail_quote">On Mon, Jul 30, 2012 at 8:45 PM, Ian Molton <span dir="ltr"><<a href="mailto:ian.molton@codethink.co.uk" target="_blank">ian.molton@codethink.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


This patch adds basic device tree support to the mv643xx ethernet driver.<br>
<br>
It should be enough for most current users of the device, and should allow<br>
a fairly painless migration once proper support for clk devices is available<br>
to those platforms.<br>
<br>
Signed-off-by: Ian Molton <<a href="mailto:ian.molton@codethink.co.uk" target="_blank">ian.molton@codethink.co.uk</a>><br>
---<br>
 drivers/net/ethernet/marvell/mv643xx_eth.c |  111 ++++++++++++++++++++++++----<br>
 1 file changed, 97 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c<br>
index 92497eb..579692f 100644<br>
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c<br>
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c<br>
@@ -48,6 +48,9 @@<br>
 #include <linux/ethtool.h><br>
 #include <linux/platform_device.h><br>
 #include <linux/module.h><br>
+#include <linux/of.h><br>
+#include <linux/of_platform.h><br>
+#include <linux/of_irq.h><br>
 #include <linux/kernel.h><br>
 #include <linux/spinlock.h><br>
 #include <linux/workqueue.h><br>
@@ -2601,11 +2604,11 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)<br>
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)<br>
 {<br>
        static int mv643xx_eth_version_printed;<br>
-       struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;<br>
+       struct mv643xx_eth_shared_platform_data *pd;<br>
        struct mv643xx_eth_shared_private *msp;<br>
        const struct mbus_dram_target_info *dram;<br>
        struct resource *res;<br>
-       int ret;<br>
+       int ret, irq = -1;<br>
<br>
        if (!mv643xx_eth_version_printed++)<br>
                pr_notice("MV-643xx 10/100/1000 ethernet driver version %s\n",<br>
@@ -2625,6 +2628,23 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)<br>
        if (msp->base == NULL)<br>
                goto out_free;<br>
<br>
+       if (pdev->dev.of_node) {<br>
+               struct device_node *np = NULL;<br>
+<br>
+               /* when all users of this driver use FDT, we can remove this */<br>
+               pd = kzalloc(sizeof(*pd), GFP_ATOMIC);<br>
+               if (!pd) {<br>
+                       dev_dbg(&pdev->dev, "Could not allocate platform data\n");<br>
+                       goto out_free;<br>
+               }<br>
+<br>
+               np = of_parse_phandle(pdev->dev.of_node, "shared_smi", 0);<br>
+               if (np)<br>
+                       pd->shared_smi = of_find_device_by_node(np);<br>
+<br>
+       } else {<br>
+               pd = pdev->dev.platform_data;<br>
+       }<br>
        /*<br>
         * Set up and register SMI bus.<br>
         */<br>
@@ -2654,15 +2674,22 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)<br>
        /*<br>
         * Check whether the error interrupt is hooked up.<br>
         */<br>
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);<br>
-       if (res != NULL) {<br>
+       if (pdev->dev.of_node) {<br>
+               irq = irq_of_parse_and_map(pdev->dev.of_node, 0);<br>
+       } else {<br>
+               res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);<br>
+               if (res)<br>
+                       irq = res->start;<br>
+       }<br>
+<br>
+       if (irq != -1) {<br>
                int err;<br>
<br>
-               err = request_irq(res->start, mv643xx_eth_err_irq,<br>
+               err = request_irq(irq, mv643xx_eth_err_irq,<br>
                                  IRQF_SHARED, "mv643xx_eth", msp);<br>
                if (!err) {<br>
                        writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);<br>
-                       msp->err_interrupt = res->start;<br>
+                       msp->err_interrupt = irq;<br>
                }<br>
        }<br>
<br>
@@ -2675,6 +2702,10 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)<br>
<br>
        msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?<br>
                                        pd->tx_csum_limit : 9 * 1024;<br>
+<br>
+       if (pdev->dev.of_node)<br>
+               kfree(pd);  /* If we created a fake pd, free it now */<br>
+<br>
        infer_hw_params(msp);<br>
<br>
        platform_set_drvdata(pdev, msp);<br>
@@ -2708,12 +2739,21 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev)<br>
        return 0;<br>
 }<br>
<br>
+#ifdef CONFIG_OF<br>
+static struct of_device_id mv_mdio_dt_ids[] __devinitdata = {<br>
+       { .compatible = "marvell,mdio-mv643xx", },<br>
+       {},<br>
+};<br>
+MODULE_DEVICE_TABLE(of, mv_mdio_dt_ids);<br>
+#endif<br>
+<br>
 static struct platform_driver mv643xx_eth_shared_driver = {<br>
        .probe          = mv643xx_eth_shared_probe,<br>
        .remove         = mv643xx_eth_shared_remove,<br>
        .driver = {<br>
                .name   = MV643XX_ETH_SHARED_NAME,<br>
                .owner  = THIS_MODULE,<br>
+               .of_match_table = of_match_ptr(mv_mdio_dt_ids),<br>
        },<br>
 };<br>
<br>
@@ -2873,7 +2913,31 @@ static int mv643xx_eth_probe(struct platform_device *pdev)<br>
        struct resource *res;<br>
        int err;<br>
<br>
-       pd = pdev->dev.platform_data;<br>
+       if (pdev->dev.of_node) {<br>
+               struct device_node *np = NULL;<br>
+<br>
+               /* when all users of this driver use FDT, we can remove this */<br>
+               pd = kzalloc(sizeof(*pd), GFP_ATOMIC);<br>
+               if (!pd) {<br>
+                       dev_dbg(&pdev->dev, "Could not allocate platform data\n");<br>
+                       return -ENOMEM;<br>
+               }<br>
+<br>
+               of_property_read_u32(pdev->dev.of_node,<br>
+                       "port_number", &pd->port_number);<br>
+               of_property_read_u32(pdev->dev.of_node,<br>
+                       "phy_addr", &pd->phy_addr);<br>
+               np = of_parse_phandle(pdev->dev.of_node, "mdio", 0);<br>
+               if (np) {<br>
+                       pd->shared = of_find_device_by_node(np);<br>
+               } else {<br>
+                       kfree(pd);<br>
+                       return -ENODEV;<br>
+               }<br>
+       } else {<br>
+               pd = pdev->dev.platform_data;<br>
+       }<br>
+<br>
        if (pd == NULL) {<br>
                dev_err(&pdev->dev, "no mv643xx_eth_platform_data\n");<br>
                return -ENODEV;<br></blockquote><div><div><br></div><div>Can this check for pd be moved in the else part above as well, as for the pd allocation with kzalloc, </div><div>we have already made a check for memory allocation failure?</div>


<div><br></div></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
@@ -2881,12 +2945,15 @@ static int mv643xx_eth_probe(struct platform_device *pdev)<br>
<br>
        if (pd->shared == NULL) {<br>
                dev_err(&pdev->dev, "no mv643xx_eth_platform_data->shared\n");<br>
-               return -ENODEV;<br>
+               err = -ENODEV;<br>
+               goto out_free_pd;<br>
        }<br>
<br>
        dev = alloc_etherdev_mq(sizeof(struct mv643xx_eth_private), 8);<br>
-       if (!dev)<br>
-               return -ENOMEM;<br>
+       if (!dev) {<br>
+               err = -ENOMEM;<br>
+               goto out_free_pd;<br>
+       }<br>
<br>
        mp = netdev_priv(dev);<br>
        platform_set_drvdata(pdev, mp);<br>
@@ -2923,6 +2990,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)<br>
<br>
        init_pscr(mp, pd->speed, pd->duplex);<br>
<br>
+       if (pdev->dev.of_node)<br>
+               kfree(pd); /* If we created a fake pd, free it now */<br>
<br>
        mib_counters_clear(mp);<br>
<br>
@@ -2942,10 +3011,13 @@ static int mv643xx_eth_probe(struct platform_device *pdev)<br>
        mp->rx_oom.data = (unsigned long)mp;<br>
        mp->rx_oom.function = oom_timer_wrapper;<br>
<br>
-<br>
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);<br>
-       BUG_ON(!res);<br>
-       dev->irq = res->start;<br>
+       if (pdev->dev.of_node) {<br>
+               dev->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);<br>
+       } else {<br>
+               res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);<br>
+               BUG_ON(!res);<br>
+               dev->irq = res->start;<br>
+       }<br>
<br>
        dev->netdev_ops = &mv643xx_eth_netdev_ops;<br>
<br>
@@ -2991,6 +3063,8 @@ out:<br>
        }<br>
 #endif<br>
        free_netdev(dev);<br>
+out_free_pd:<br>
+       kfree(pd);<br>
<br>
        return err;<br>
 }<br>
@@ -3030,6 +3104,14 @@ static void mv643xx_eth_shutdown(struct platform_device *pdev)<br>
                port_reset(mp);<br>
 }<br>
<br>
+#ifdef CONFIG_OF<br>
+static struct of_device_id mv_eth_dt_ids[] __devinitdata = {<br>
+       { .compatible = "marvell,mv643xx", },<br>
+       {},<br>
+};<br>
+MODULE_DEVICE_TABLE(of, mv_eth_dt_ids);<br>
+#endif<br>
+<br>
 static struct platform_driver mv643xx_eth_driver = {<br>
        .probe          = mv643xx_eth_probe,<br>
        .remove         = mv643xx_eth_remove,<br>
@@ -3037,6 +3119,7 @@ static struct platform_driver mv643xx_eth_driver = {<br>
        .driver = {<br>
                .name   = MV643XX_ETH_NAME,<br>
                .owner  = THIS_MODULE,<br>
+               .of_match_table = of_match_ptr(mv_eth_dt_ids),<br>
        },<br>
 };<br>
<span><font color="#888888"><br>
--<br>
1.7.9.5<br>
<br>
<br>
_______________________________________________<br>
linux-arm-kernel mailing list<br>
<a href="mailto:linux-arm-kernel@lists.infradead.org" target="_blank">linux-arm-kernel@lists.infradead.org</a><br>
<a href="http://lists.infradead.org/mailman/listinfo/linux-arm-kernel" target="_blank">http://lists.infradead.org/mailman/listinfo/linux-arm-kernel</a></font></span></blockquote><div><br></div><div><div><br>
Regards,</div><div>-Amar </div></div></div><br>