diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-30 09:30:50 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-30 09:30:50 +0400 |
commit | 213d61386ee8a0a704d99922dbdb99f9c233d630 (patch) | |
tree | 0a50a83b55c6664725394b25f84ecc5d3e15f308 | |
parent | 5f0c5f73e5efaee2928c4cabcf48b03f6ba99fc8 (diff) | |
parent | fa5f4adf3a1594d55d730ba68c10afa1edebf58a (diff) | |
download | linux-213d61386ee8a0a704d99922dbdb99f9c233d630.tar.xz |
Merge branch 'am335x'
Markus Pargmann says:
====================
net: cpsw: Support for am335x chip MACIDs
This series adds support to the cpsw driver to read the MACIDs of the am335x
chip and use them as fallback. These addresses are only used if there are no
mac addresses in the devicetree, for example set by a bootloader.
====================
Acked-by: Mugunthan V N <mugunthanvnm@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/cpsw.txt | 6 | ||||
-rw-r--r-- | arch/arm/boot/dts/am33xx.dtsi | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 45 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.h | 1 |
5 files changed, 57 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt index ae2b8b7f9c38..33fe8462edf4 100644 --- a/Documentation/devicetree/bindings/net/cpsw.txt +++ b/Documentation/devicetree/bindings/net/cpsw.txt @@ -24,15 +24,17 @@ Optional properties: - ti,hwmods : Must be "cpgmac0" - no_bd_ram : Must be 0 or 1 - dual_emac : Specifies Switch to act as Dual EMAC +- syscon : Phandle to the system control device node, which is + the control module device of the am33x Slave Properties: Required properties: - phy_id : Specifies slave phy id - phy-mode : See ethernet.txt file in the same directory -- mac-address : See ethernet.txt file in the same directory Optional properties: - dual_emac_res_vlan : Specifies VID to be used to segregate the ports +- mac-address : See ethernet.txt file in the same directory Note: "ti,hwmods" field is used to fetch the base address and irq resources from TI, omap hwmod data base during device registration. @@ -57,6 +59,7 @@ Examples: active_slave = <0>; cpts_clock_mult = <0x80000000>; cpts_clock_shift = <29>; + syscon = <&cm>; cpsw_emac0: slave@0 { phy_id = <&davinci_mdio>, <0>; phy-mode = "rgmii-txid"; @@ -85,6 +88,7 @@ Examples: active_slave = <0>; cpts_clock_mult = <0x80000000>; cpts_clock_shift = <29>; + syscon = <&cm>; cpsw_emac0: slave@0 { phy_id = <&davinci_mdio>, <0>; phy-mode = "rgmii-txid"; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 3a0a161342ba..13e44b0f5adc 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -132,6 +132,11 @@ }; }; + cm: syscon@44e10000 { + compatible = "ti,am33xx-controlmodule", "syscon"; + reg = <0x44e10000 0x800>; + }; + intc: interrupt-controller@48200000 { compatible = "ti,omap2-intc"; interrupt-controller; @@ -696,6 +701,7 @@ */ interrupts = <40 41 42 43>; ranges; + syscon = <&cm>; status = "disabled"; davinci_mdio: mdio@4a101000 { diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index 1769700a6070..5d8cb7956113 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -62,6 +62,8 @@ config TI_CPSW select TI_DAVINCI_CPDMA select TI_DAVINCI_MDIO select TI_CPSW_PHY_SEL + select MFD_SYSCON + select REGMAP ---help--- This driver supports TI's CPSW Ethernet Switch. diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 45ba50e4eaec..ab167dc49ce4 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -33,6 +33,8 @@ #include <linux/of_net.h> #include <linux/of_device.h> #include <linux/if_vlan.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> #include <linux/pinctrl/consumer.h> @@ -1876,6 +1878,36 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, slave->port_vlan = data->dual_emac_res_vlan; } +#define AM33XX_CTRL_MAC_LO_REG(id) (0x630 + 0x8 * id) +#define AM33XX_CTRL_MAC_HI_REG(id) (0x630 + 0x8 * id + 0x4) + +static int cpsw_am33xx_cm_get_macid(struct device *dev, int slave, + u8 *mac_addr) +{ + u32 macid_lo; + u32 macid_hi; + struct regmap *syscon; + + syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); + if (IS_ERR(syscon)) { + if (PTR_ERR(syscon) == -ENODEV) + return 0; + return PTR_ERR(syscon); + } + + regmap_read(syscon, AM33XX_CTRL_MAC_LO_REG(slave), &macid_lo); + regmap_read(syscon, AM33XX_CTRL_MAC_HI_REG(slave), &macid_hi); + + mac_addr[5] = (macid_lo >> 8) & 0xff; + mac_addr[4] = macid_lo & 0xff; + mac_addr[3] = (macid_hi >> 24) & 0xff; + mac_addr[2] = (macid_hi >> 16) & 0xff; + mac_addr[1] = (macid_hi >> 8) & 0xff; + mac_addr[0] = macid_hi & 0xff; + + return 0; +} + static int cpsw_probe_dt(struct cpsw_platform_data *data, struct platform_device *pdev) { @@ -1981,15 +2013,23 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, mdio = of_find_device_by_node(mdio_node); of_node_put(mdio_node); if (!mdio) { - pr_err("Missing mdio platform device\n"); + dev_err(&pdev->dev, "Missing mdio platform device\n"); return -EINVAL; } snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), PHY_ID_FMT, mdio->name, phyid); mac_addr = of_get_mac_address(slave_node); - if (mac_addr) + if (mac_addr) { memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); + } else { + if (of_machine_is_compatible("ti,am33xx")) { + ret = cpsw_am33xx_cm_get_macid(&pdev->dev, i, + slave_data->mac_addr); + if (ret) + return ret; + } + } slave_data->phy_if = of_get_phy_mode(slave_node); if (slave_data->phy_if < 0) { @@ -2123,6 +2163,7 @@ static int cpsw_probe(struct platform_device *pdev) priv->irq_enabled = true; if (!priv->cpts) { dev_err(&pdev->dev, "error allocating cpts\n"); + ret = -ENOMEM; goto clean_ndev_ret; } diff --git a/drivers/net/ethernet/ti/cpsw.h b/drivers/net/ethernet/ti/cpsw.h index 574f49da693f..1b710674630c 100644 --- a/drivers/net/ethernet/ti/cpsw.h +++ b/drivers/net/ethernet/ti/cpsw.h @@ -15,6 +15,7 @@ #define __CPSW_H__ #include <linux/if_ether.h> +#include <linux/phy.h> struct cpsw_slave_data { char phy_id[MII_BUS_ID_SIZE]; |