diff options
author | David S. Miller <davem@davemloft.net> | 2015-01-30 20:42:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-30 20:42:07 -0500 |
commit | 055470d2a7ad47dfb479308d713993173f1c6876 (patch) | |
tree | a474f07c34c34cfa63a1b18ab83bd03a57ab3239 | |
parent | 4c72c53be5e3c8cf319a020ea671ab0fc32ec96f (diff) | |
parent | f276c0ce5d9256bb87e65f88ddea28a6a5eafdb2 (diff) |
Merge branch 'cpsw_macid'
Tony Lindgren says:
====================
Changes to cpsw and davinci_emac for getting MAC address
Here are a few patches to add common code for cpsw and davinci_emac for
getting the MAC address. Looks like we can also now add code to get the
MAC address on 3517 but in a slightly different way.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/arm/boot/dts/am3517.dtsi | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw-common.c | 53 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 35 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/davinci_emac.c | 56 |
6 files changed, 116 insertions, 34 deletions
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi index 5a452fdd7c5d..c90724bded10 100644 --- a/arch/arm/boot/dts/am3517.dtsi +++ b/arch/arm/boot/dts/am3517.dtsi | |||
@@ -31,6 +31,7 @@ | |||
31 | status = "disabled"; | 31 | status = "disabled"; |
32 | reg = <0x5c000000 0x30000>; | 32 | reg = <0x5c000000 0x30000>; |
33 | interrupts = <67 68 69 70>; | 33 | interrupts = <67 68 69 70>; |
34 | syscon = <&omap3_scm_general>; | ||
34 | ti,davinci-ctrl-reg-offset = <0x10000>; | 35 | ti,davinci-ctrl-reg-offset = <0x10000>; |
35 | ti,davinci-ctrl-mod-reg-offset = <0>; | 36 | ti,davinci-ctrl-mod-reg-offset = <0>; |
36 | ti,davinci-ctrl-ram-offset = <0x20000>; | 37 | ti,davinci-ctrl-ram-offset = <0x20000>; |
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile index 0a9813bc0451..5475cf60fa2d 100644 --- a/drivers/net/ethernet/ti/Makefile +++ b/drivers/net/ethernet/ti/Makefile | |||
@@ -2,6 +2,9 @@ | |||
2 | # Makefile for the TI network device drivers. | 2 | # Makefile for the TI network device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_TI_CPSW) += cpsw-common.o | ||
6 | obj-$(CONFIG_TI_DAVINCI_EMAC) += cpsw-common.o | ||
7 | |||
5 | obj-$(CONFIG_TLAN) += tlan.o | 8 | obj-$(CONFIG_TLAN) += tlan.o |
6 | obj-$(CONFIG_CPMAC) += cpmac.o | 9 | obj-$(CONFIG_CPMAC) += cpmac.o |
7 | obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o | 10 | obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o |
diff --git a/drivers/net/ethernet/ti/cpsw-common.c b/drivers/net/ethernet/ti/cpsw-common.c new file mode 100644 index 000000000000..763ada18ad3d --- /dev/null +++ b/drivers/net/ethernet/ti/cpsw-common.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2 of the License, or | ||
5 | * (at your option) any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_device.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/mfd/syscon.h> | ||
19 | |||
20 | #define AM33XX_CTRL_MAC_LO_REG(offset, id) ((offset) + 0x8 * (id)) | ||
21 | #define AM33XX_CTRL_MAC_HI_REG(offset, id) ((offset) + 0x8 * (id) + 0x4) | ||
22 | |||
23 | int cpsw_am33xx_cm_get_macid(struct device *dev, u16 offset, int slave, | ||
24 | u8 *mac_addr) | ||
25 | { | ||
26 | u32 macid_lo; | ||
27 | u32 macid_hi; | ||
28 | struct regmap *syscon; | ||
29 | |||
30 | syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); | ||
31 | if (IS_ERR(syscon)) { | ||
32 | if (PTR_ERR(syscon) == -ENODEV) | ||
33 | return 0; | ||
34 | return PTR_ERR(syscon); | ||
35 | } | ||
36 | |||
37 | regmap_read(syscon, AM33XX_CTRL_MAC_LO_REG(offset, slave), | ||
38 | &macid_lo); | ||
39 | regmap_read(syscon, AM33XX_CTRL_MAC_HI_REG(offset, slave), | ||
40 | &macid_hi); | ||
41 | |||
42 | mac_addr[5] = (macid_lo >> 8) & 0xff; | ||
43 | mac_addr[4] = macid_lo & 0xff; | ||
44 | mac_addr[3] = (macid_hi >> 24) & 0xff; | ||
45 | mac_addr[2] = (macid_hi >> 16) & 0xff; | ||
46 | mac_addr[1] = (macid_hi >> 8) & 0xff; | ||
47 | mac_addr[0] = macid_hi & 0xff; | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | EXPORT_SYMBOL_GPL(cpsw_am33xx_cm_get_macid); | ||
52 | |||
53 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 2b9d404f8586..7d8dd0d2182e 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -33,8 +33,6 @@ | |||
33 | #include <linux/of_net.h> | 33 | #include <linux/of_net.h> |
34 | #include <linux/of_device.h> | 34 | #include <linux/of_device.h> |
35 | #include <linux/if_vlan.h> | 35 | #include <linux/if_vlan.h> |
36 | #include <linux/mfd/syscon.h> | ||
37 | #include <linux/regmap.h> | ||
38 | 36 | ||
39 | #include <linux/pinctrl/consumer.h> | 37 | #include <linux/pinctrl/consumer.h> |
40 | 38 | ||
@@ -1936,36 +1934,6 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, | |||
1936 | slave->port_vlan = data->dual_emac_res_vlan; | 1934 | slave->port_vlan = data->dual_emac_res_vlan; |
1937 | } | 1935 | } |
1938 | 1936 | ||
1939 | #define AM33XX_CTRL_MAC_LO_REG(id) (0x630 + 0x8 * id) | ||
1940 | #define AM33XX_CTRL_MAC_HI_REG(id) (0x630 + 0x8 * id + 0x4) | ||
1941 | |||
1942 | static int cpsw_am33xx_cm_get_macid(struct device *dev, int slave, | ||
1943 | u8 *mac_addr) | ||
1944 | { | ||
1945 | u32 macid_lo; | ||
1946 | u32 macid_hi; | ||
1947 | struct regmap *syscon; | ||
1948 | |||
1949 | syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); | ||
1950 | if (IS_ERR(syscon)) { | ||
1951 | if (PTR_ERR(syscon) == -ENODEV) | ||
1952 | return 0; | ||
1953 | return PTR_ERR(syscon); | ||
1954 | } | ||
1955 | |||
1956 | regmap_read(syscon, AM33XX_CTRL_MAC_LO_REG(slave), &macid_lo); | ||
1957 | regmap_read(syscon, AM33XX_CTRL_MAC_HI_REG(slave), &macid_hi); | ||
1958 | |||
1959 | mac_addr[5] = (macid_lo >> 8) & 0xff; | ||
1960 | mac_addr[4] = macid_lo & 0xff; | ||
1961 | mac_addr[3] = (macid_hi >> 24) & 0xff; | ||
1962 | mac_addr[2] = (macid_hi >> 16) & 0xff; | ||
1963 | mac_addr[1] = (macid_hi >> 8) & 0xff; | ||
1964 | mac_addr[0] = macid_hi & 0xff; | ||
1965 | |||
1966 | return 0; | ||
1967 | } | ||
1968 | |||
1969 | static int cpsw_probe_dt(struct cpsw_platform_data *data, | 1937 | static int cpsw_probe_dt(struct cpsw_platform_data *data, |
1970 | struct platform_device *pdev) | 1938 | struct platform_device *pdev) |
1971 | { | 1939 | { |
@@ -2090,7 +2058,8 @@ no_phy_slave: | |||
2090 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); | 2058 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); |
2091 | } else { | 2059 | } else { |
2092 | if (of_machine_is_compatible("ti,am33xx")) { | 2060 | if (of_machine_is_compatible("ti,am33xx")) { |
2093 | ret = cpsw_am33xx_cm_get_macid(&pdev->dev, i, | 2061 | ret = cpsw_am33xx_cm_get_macid(&pdev->dev, |
2062 | 0x630, i, | ||
2094 | slave_data->mac_addr); | 2063 | slave_data->mac_addr); |
2095 | if (ret) | 2064 | if (ret) |
2096 | return ret; | 2065 | return ret; |
diff --git a/drivers/net/ethernet/ti/cpsw.h b/drivers/net/ethernet/ti/cpsw.h index 1b710674630c..ca90efafd156 100644 --- a/drivers/net/ethernet/ti/cpsw.h +++ b/drivers/net/ethernet/ti/cpsw.h | |||
@@ -41,5 +41,7 @@ struct cpsw_platform_data { | |||
41 | }; | 41 | }; |
42 | 42 | ||
43 | void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave); | 43 | void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave); |
44 | int cpsw_am33xx_cm_get_macid(struct device *dev, u16 offset, int slave, | ||
45 | u8 *mac_addr); | ||
44 | 46 | ||
45 | #endif /* __CPSW_H__ */ | 47 | #endif /* __CPSW_H__ */ |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 5fae4354722c..aeebc0a7bf47 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/dma-mapping.h> | 52 | #include <linux/dma-mapping.h> |
53 | #include <linux/clk.h> | 53 | #include <linux/clk.h> |
54 | #include <linux/platform_device.h> | 54 | #include <linux/platform_device.h> |
55 | #include <linux/regmap.h> | ||
55 | #include <linux/semaphore.h> | 56 | #include <linux/semaphore.h> |
56 | #include <linux/phy.h> | 57 | #include <linux/phy.h> |
57 | #include <linux/bitops.h> | 58 | #include <linux/bitops.h> |
@@ -65,10 +66,12 @@ | |||
65 | #include <linux/of_mdio.h> | 66 | #include <linux/of_mdio.h> |
66 | #include <linux/of_irq.h> | 67 | #include <linux/of_irq.h> |
67 | #include <linux/of_net.h> | 68 | #include <linux/of_net.h> |
69 | #include <linux/mfd/syscon.h> | ||
68 | 70 | ||
69 | #include <asm/irq.h> | 71 | #include <asm/irq.h> |
70 | #include <asm/page.h> | 72 | #include <asm/page.h> |
71 | 73 | ||
74 | #include "cpsw.h" | ||
72 | #include "davinci_cpdma.h" | 75 | #include "davinci_cpdma.h" |
73 | 76 | ||
74 | static int debug_level; | 77 | static int debug_level; |
@@ -1838,7 +1841,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) | |||
1838 | if (!is_valid_ether_addr(pdata->mac_addr)) { | 1841 | if (!is_valid_ether_addr(pdata->mac_addr)) { |
1839 | mac_addr = of_get_mac_address(np); | 1842 | mac_addr = of_get_mac_address(np); |
1840 | if (mac_addr) | 1843 | if (mac_addr) |
1841 | memcpy(pdata->mac_addr, mac_addr, ETH_ALEN); | 1844 | ether_addr_copy(pdata->mac_addr, mac_addr); |
1842 | } | 1845 | } |
1843 | 1846 | ||
1844 | of_property_read_u32(np, "ti,davinci-ctrl-reg-offset", | 1847 | of_property_read_u32(np, "ti,davinci-ctrl-reg-offset", |
@@ -1879,6 +1882,53 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) | |||
1879 | return pdata; | 1882 | return pdata; |
1880 | } | 1883 | } |
1881 | 1884 | ||
1885 | static int davinci_emac_3517_get_macid(struct device *dev, u16 offset, | ||
1886 | int slave, u8 *mac_addr) | ||
1887 | { | ||
1888 | u32 macid_lsb; | ||
1889 | u32 macid_msb; | ||
1890 | struct regmap *syscon; | ||
1891 | |||
1892 | syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); | ||
1893 | if (IS_ERR(syscon)) { | ||
1894 | if (PTR_ERR(syscon) == -ENODEV) | ||
1895 | return 0; | ||
1896 | return PTR_ERR(syscon); | ||
1897 | } | ||
1898 | |||
1899 | regmap_read(syscon, offset, &macid_lsb); | ||
1900 | regmap_read(syscon, offset + 4, &macid_msb); | ||
1901 | |||
1902 | mac_addr[0] = (macid_msb >> 16) & 0xff; | ||
1903 | mac_addr[1] = (macid_msb >> 8) & 0xff; | ||
1904 | mac_addr[2] = macid_msb & 0xff; | ||
1905 | mac_addr[3] = (macid_lsb >> 16) & 0xff; | ||
1906 | mac_addr[4] = (macid_lsb >> 8) & 0xff; | ||
1907 | mac_addr[5] = macid_lsb & 0xff; | ||
1908 | |||
1909 | return 0; | ||
1910 | } | ||
1911 | |||
1912 | static int davinci_emac_try_get_mac(struct platform_device *pdev, | ||
1913 | int instance, u8 *mac_addr) | ||
1914 | { | ||
1915 | int error = -EINVAL; | ||
1916 | |||
1917 | if (!pdev->dev.of_node) | ||
1918 | return error; | ||
1919 | |||
1920 | if (of_device_is_compatible(pdev->dev.of_node, "ti,am3517-emac")) | ||
1921 | error = davinci_emac_3517_get_macid(&pdev->dev, 0x110, | ||
1922 | 0, mac_addr); | ||
1923 | else if (of_device_is_compatible(pdev->dev.of_node, | ||
1924 | "ti,dm816-emac")) | ||
1925 | error = cpsw_am33xx_cm_get_macid(&pdev->dev, 0x30, | ||
1926 | instance, | ||
1927 | mac_addr); | ||
1928 | |||
1929 | return error; | ||
1930 | } | ||
1931 | |||
1882 | /** | 1932 | /** |
1883 | * davinci_emac_probe - EMAC device probe | 1933 | * davinci_emac_probe - EMAC device probe |
1884 | * @pdev: The DaVinci EMAC device that we are removing | 1934 | * @pdev: The DaVinci EMAC device that we are removing |
@@ -2009,6 +2059,10 @@ static int davinci_emac_probe(struct platform_device *pdev) | |||
2009 | } | 2059 | } |
2010 | ndev->irq = res->start; | 2060 | ndev->irq = res->start; |
2011 | 2061 | ||
2062 | rc = davinci_emac_try_get_mac(pdev, res_ctrl ? 0 : 1, priv->mac_addr); | ||
2063 | if (!rc) | ||
2064 | ether_addr_copy(ndev->dev_addr, priv->mac_addr); | ||
2065 | |||
2012 | if (!is_valid_ether_addr(priv->mac_addr)) { | 2066 | if (!is_valid_ether_addr(priv->mac_addr)) { |
2013 | /* Use random MAC if none passed */ | 2067 | /* Use random MAC if none passed */ |
2014 | eth_hw_addr_random(ndev); | 2068 | eth_hw_addr_random(ndev); |