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>