diff options
author | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> | 2014-02-17 19:12:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-18 17:21:34 -0500 |
commit | b356e978e92fccd17a3e4620a4821bdbfb706c1a (patch) | |
tree | 07289470e765e7e97ac07e25ee6649beddac38e2 /drivers/net/ethernet/renesas | |
parent | e8f08ee0ad86012a2e9ac3a6cc318b058dd4d47c (diff) |
sh_eth: add device tree support
Add support of the device tree probing for the Renesas SH-Mobile SoCs
documenting the device tree binding as necessary.
This work is loosely based on the original patch by Nobuhiro Iwamatsu
<nobuhiro.iwamatsu.yj@renesas.com>.
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/renesas')
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 88b40b514cb2..b1e6554f44bc 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* SuperH Ethernet device driver | 1 | /* SuperH Ethernet device driver |
2 | * | 2 | * |
3 | * Copyright (C) 2006-2012 Nobuhiro Iwamatsu | 3 | * Copyright (C) 2006-2012 Nobuhiro Iwamatsu |
4 | * Copyright (C) 2008-2013 Renesas Solutions Corp. | 4 | * Copyright (C) 2008-2014 Renesas Solutions Corp. |
5 | * Copyright (C) 2013 Cogent Embedded, Inc. | 5 | * Copyright (C) 2013-2014 Cogent Embedded, Inc. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms and conditions of the GNU General Public License, | 8 | * under the terms and conditions of the GNU General Public License, |
@@ -27,6 +27,10 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/mdio-bitbang.h> | 28 | #include <linux/mdio-bitbang.h> |
29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <linux/of_irq.h> | ||
33 | #include <linux/of_net.h> | ||
30 | #include <linux/phy.h> | 34 | #include <linux/phy.h> |
31 | #include <linux/cache.h> | 35 | #include <linux/cache.h> |
32 | #include <linux/io.h> | 36 | #include <linux/io.h> |
@@ -2710,6 +2714,54 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = { | |||
2710 | .ndo_change_mtu = eth_change_mtu, | 2714 | .ndo_change_mtu = eth_change_mtu, |
2711 | }; | 2715 | }; |
2712 | 2716 | ||
2717 | #ifdef CONFIG_OF | ||
2718 | static struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) | ||
2719 | { | ||
2720 | struct device_node *np = dev->of_node; | ||
2721 | struct sh_eth_plat_data *pdata; | ||
2722 | struct device_node *phy; | ||
2723 | const char *mac_addr; | ||
2724 | |||
2725 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
2726 | if (!pdata) | ||
2727 | return NULL; | ||
2728 | |||
2729 | pdata->phy_interface = of_get_phy_mode(np); | ||
2730 | |||
2731 | phy = of_parse_phandle(np, "phy-handle", 0); | ||
2732 | if (of_property_read_u32(phy, "reg", &pdata->phy)) | ||
2733 | return NULL; | ||
2734 | pdata->phy_irq = irq_of_parse_and_map(phy, 0); | ||
2735 | |||
2736 | mac_addr = of_get_mac_address(np); | ||
2737 | if (mac_addr) | ||
2738 | memcpy(pdata->mac_addr, mac_addr, ETH_ALEN); | ||
2739 | |||
2740 | pdata->no_ether_link = | ||
2741 | of_property_read_bool(np, "renesas,no-ether-link"); | ||
2742 | pdata->ether_link_active_low = | ||
2743 | of_property_read_bool(np, "renesas,ether-link-active-low"); | ||
2744 | |||
2745 | return pdata; | ||
2746 | } | ||
2747 | |||
2748 | static const struct of_device_id sh_eth_match_table[] = { | ||
2749 | { .compatible = "renesas,gether-r8a7740", .data = &r8a7740_data }, | ||
2750 | { .compatible = "renesas,ether-r8a7778", .data = &r8a777x_data }, | ||
2751 | { .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data }, | ||
2752 | { .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data }, | ||
2753 | { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data }, | ||
2754 | { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data }, | ||
2755 | { } | ||
2756 | }; | ||
2757 | MODULE_DEVICE_TABLE(of, sh_eth_match_table); | ||
2758 | #else | ||
2759 | static inline struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) | ||
2760 | { | ||
2761 | return NULL; | ||
2762 | } | ||
2763 | #endif | ||
2764 | |||
2713 | static int sh_eth_drv_probe(struct platform_device *pdev) | 2765 | static int sh_eth_drv_probe(struct platform_device *pdev) |
2714 | { | 2766 | { |
2715 | int ret, devno = 0; | 2767 | int ret, devno = 0; |
@@ -2763,6 +2815,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
2763 | pm_runtime_enable(&pdev->dev); | 2815 | pm_runtime_enable(&pdev->dev); |
2764 | pm_runtime_resume(&pdev->dev); | 2816 | pm_runtime_resume(&pdev->dev); |
2765 | 2817 | ||
2818 | if (pdev->dev.of_node) | ||
2819 | pd = sh_eth_parse_dt(&pdev->dev); | ||
2766 | if (!pd) { | 2820 | if (!pd) { |
2767 | dev_err(&pdev->dev, "no platform data\n"); | 2821 | dev_err(&pdev->dev, "no platform data\n"); |
2768 | ret = -EINVAL; | 2822 | ret = -EINVAL; |
@@ -2778,7 +2832,15 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
2778 | mdp->ether_link_active_low = pd->ether_link_active_low; | 2832 | mdp->ether_link_active_low = pd->ether_link_active_low; |
2779 | 2833 | ||
2780 | /* set cpu data */ | 2834 | /* set cpu data */ |
2781 | mdp->cd = (struct sh_eth_cpu_data *)id->driver_data; | 2835 | if (id) { |
2836 | mdp->cd = (struct sh_eth_cpu_data *)id->driver_data; | ||
2837 | } else { | ||
2838 | const struct of_device_id *match; | ||
2839 | |||
2840 | match = of_match_device(of_match_ptr(sh_eth_match_table), | ||
2841 | &pdev->dev); | ||
2842 | mdp->cd = (struct sh_eth_cpu_data *)match->data; | ||
2843 | } | ||
2782 | mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type); | 2844 | mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type); |
2783 | sh_eth_set_default_cpu_data(mdp->cd); | 2845 | sh_eth_set_default_cpu_data(mdp->cd); |
2784 | 2846 | ||
@@ -2920,6 +2982,7 @@ static struct platform_driver sh_eth_driver = { | |||
2920 | .driver = { | 2982 | .driver = { |
2921 | .name = CARDNAME, | 2983 | .name = CARDNAME, |
2922 | .pm = SH_ETH_PM_OPS, | 2984 | .pm = SH_ETH_PM_OPS, |
2985 | .of_match_table = of_match_ptr(sh_eth_match_table), | ||
2923 | }, | 2986 | }, |
2924 | }; | 2987 | }; |
2925 | 2988 | ||