From 42f59967a091d012b358a532766fe4d53c6d3ba3 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 17 Jul 2012 00:34:24 +0000 Subject: [PATCH] net: ethernet: davinci_emac: add OF support add OF support for the davinci_emac driver. Signed-off-by: Heiko Schocher Acked-by: Sekhar Nori Signed-off-by: Anatolij Gustschin Cc: netdev@vger.kernel.org Cc: davinci-linux-open-source@linux.davincidsp.com Cc: linux-arm-kernel@lists.infradead.org Cc: devicetree-discuss@lists.ozlabs.org Cc: Grant Likely Cc: Sekhar Nori Cc: Wolfgang Denk Cc: Anatoly Sivov Cc: David Miller Signed-off-by: David S. Miller --- .../devicetree/bindings/net/davinci_emac.txt | 41 +++++++++ drivers/net/ethernet/ti/davinci_emac.c | 89 ++++++++++++++++++- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/net/davinci_emac.txt diff --git a/Documentation/devicetree/bindings/net/davinci_emac.txt b/Documentation/devicetree/bindings/net/davinci_emac.txt new file mode 100644 index 000000000000..48b259e29e87 --- /dev/null +++ b/Documentation/devicetree/bindings/net/davinci_emac.txt @@ -0,0 +1,41 @@ +* Texas Instruments Davinci EMAC + +This file provides information, what the device node +for the davinci_emac interface contains. + +Required properties: +- compatible: "ti,davinci-dm6467-emac"; +- reg: Offset and length of the register set for the device +- ti,davinci-ctrl-reg-offset: offset to control register +- ti,davinci-ctrl-mod-reg-offset: offset to control module register +- ti,davinci-ctrl-ram-offset: offset to control module ram +- ti,davinci-ctrl-ram-size: size of control module ram +- ti,davinci-rmii-en: use RMII +- ti,davinci-no-bd-ram: has the emac controller BD RAM +- phy-handle: Contains a phandle to an Ethernet PHY. + if not, davinci_emac driver defaults to 100/FULL +- interrupts: interrupt mapping for the davinci emac interrupts sources: + 4 sources: + +Optional properties: +- local-mac-address : 6 bytes, mac address + +Example (enbw_cmc board): + eth0: emac@1e20000 { + compatible = "ti,davinci-dm6467-emac"; + reg = <0x220000 0x4000>; + ti,davinci-ctrl-reg-offset = <0x3000>; + ti,davinci-ctrl-mod-reg-offset = <0x2000>; + ti,davinci-ctrl-ram-offset = <0>; + ti,davinci-ctrl-ram-size = <0x2000>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <33 + 34 + 35 + 36 + >; + interrupt-parent = <&intc>; + }; diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index ab0bbb78699a..b298ab071e3d 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -58,6 +58,12 @@ #include #include #include +#include +#include +#include +#include + +#include #include #include @@ -339,6 +345,9 @@ struct emac_priv { u32 rx_addr_type; atomic_t cur_tx; const char *phy_id; +#ifdef CONFIG_OF + struct device_node *phy_node; +#endif struct phy_device *phydev; spinlock_t lock; /*platform specific members*/ @@ -1760,6 +1769,77 @@ static const struct net_device_ops emac_netdev_ops = { #endif }; +#ifdef CONFIG_OF +static struct emac_platform_data + *davinci_emac_of_get_pdata(struct platform_device *pdev, + struct emac_priv *priv) +{ + struct device_node *np; + struct emac_platform_data *pdata = NULL; + const u8 *mac_addr; + u32 data; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + goto nodata; + } + + np = pdev->dev.of_node; + if (!np) + goto nodata; + else + pdata->version = EMAC_VERSION_2; + + if (!is_valid_ether_addr(pdata->mac_addr)) { + mac_addr = of_get_mac_address(np); + if (mac_addr) + memcpy(pdata->mac_addr, mac_addr, ETH_ALEN); + } + + ret = of_property_read_u32(np, "ti,davinci-ctrl-reg-offset", &data); + if (!ret) + pdata->ctrl_reg_offset = data; + + ret = of_property_read_u32(np, "ti,davinci-ctrl-mod-reg-offset", + &data); + if (!ret) + pdata->ctrl_mod_reg_offset = data; + + ret = of_property_read_u32(np, "ti,davinci-ctrl-ram-offset", &data); + if (!ret) + pdata->ctrl_ram_offset = data; + + ret = of_property_read_u32(np, "ti,davinci-ctrl-ram-size", &data); + if (!ret) + pdata->ctrl_ram_size = data; + + ret = of_property_read_u32(np, "ti,davinci-rmii-en", &data); + if (!ret) + pdata->rmii_en = data; + + ret = of_property_read_u32(np, "ti,davinci-no-bd-ram", &data); + if (!ret) + pdata->no_bd_ram = data; + + priv->phy_node = of_parse_phandle(np, "phy-handle", 0); + if (!priv->phy_node) + pdata->phy_id = ""; + + pdev->dev.platform_data = pdata; +nodata: + return pdata; +} +#else +static struct emac_platform_data + *davinci_emac_of_get_pdata(struct platform_device *pdev, + struct emac_priv *priv) +{ + return pdev->dev.platform_data; +} +#endif /** * davinci_emac_probe - EMAC device probe * @pdev: The DaVinci EMAC device that we are removing @@ -1802,7 +1882,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) spin_lock_init(&priv->lock); - pdata = pdev->dev.platform_data; + pdata = davinci_emac_of_get_pdata(pdev, priv); if (!pdata) { dev_err(&pdev->dev, "no platform data\n"); rc = -ENODEV; @@ -2013,12 +2093,19 @@ static const struct dev_pm_ops davinci_emac_pm_ops = { .resume = davinci_emac_resume, }; +static const struct of_device_id davinci_emac_of_match[] = { + {.compatible = "ti,davinci-dm6467-emac", }, + {}, +}; +MODULE_DEVICE_TABLE(of, davinci_emac_of_match); + /* davinci_emac_driver: EMAC platform driver structure */ static struct platform_driver davinci_emac_driver = { .driver = { .name = "davinci_emac", .owner = THIS_MODULE, .pm = &davinci_emac_pm_ops, + .of_match_table = of_match_ptr(davinci_emac_of_match), }, .probe = davinci_emac_probe, .remove = __devexit_p(davinci_emac_remove), -- 2.39.5