aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mscc/ocelot_board.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2018-10-08 09:48:31 +0200
committerJohannes Berg <johannes.berg@intel.com>2018-10-08 09:48:36 +0200
commit188de5dd80b2b7986e75821374efb67081049b6e (patch)
tree545bbc0fdb58f30c0175128e3b5a9c00c89e2020 /drivers/net/ethernet/mscc/ocelot_board.c
parentcfg80211: sort tracing properly (diff)
parentnet: vhost: remove bad code line (diff)
downloadlinux-dev-188de5dd80b2b7986e75821374efb67081049b6e.tar.xz
linux-dev-188de5dd80b2b7986e75821374efb67081049b6e.zip
Merge remote-tracking branch 'net-next/master' into mac80211-next
Merge net-next, which pulled in net, so I can merge a few more patches that would otherwise conflict. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot_board.c')
-rw-r--r--drivers/net/ethernet/mscc/ocelot_board.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index 3cdf63e35b53..953b32677383 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -6,9 +6,11 @@
*/
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/of_net.h>
#include <linux/netdevice.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
+#include <linux/mfd/syscon.h>
#include <linux/skbuff.h>
#include "ocelot.h"
@@ -168,6 +170,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct device_node *ports, *portnp;
struct ocelot *ocelot;
+ struct regmap *hsio;
u32 val;
struct {
@@ -179,7 +182,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
{ QSYS, "qsys" },
{ ANA, "ana" },
{ QS, "qs" },
- { HSIO, "hsio" },
};
if (!np && !pdev->dev.platform_data)
@@ -202,6 +204,14 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
ocelot->targets[res[i].id] = target;
}
+ hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
+ if (IS_ERR(hsio)) {
+ dev_err(&pdev->dev, "missing hsio syscon\n");
+ return PTR_ERR(hsio);
+ }
+
+ ocelot->targets[HSIO] = hsio;
+
err = ocelot_chip_init(ocelot);
if (err)
return err;
@@ -244,18 +254,12 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&ocelot->multicast);
ocelot_init(ocelot);
- ocelot_rmw(ocelot, HSIO_HW_CFG_DEV1G_4_MODE |
- HSIO_HW_CFG_DEV1G_6_MODE |
- HSIO_HW_CFG_DEV1G_9_MODE,
- HSIO_HW_CFG_DEV1G_4_MODE |
- HSIO_HW_CFG_DEV1G_6_MODE |
- HSIO_HW_CFG_DEV1G_9_MODE,
- HSIO_HW_CFG);
-
for_each_available_child_of_node(ports, portnp) {
struct device_node *phy_node;
struct phy_device *phy;
struct resource *res;
+ struct phy *serdes;
+ enum phy_mode phy_mode;
void __iomem *regs;
char res_name[8];
u32 port;
@@ -280,10 +284,45 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
continue;
err = ocelot_probe_port(ocelot, port, regs, phy);
- if (err) {
- dev_err(&pdev->dev, "failed to probe ports\n");
+ if (err)
+ return err;
+
+ err = of_get_phy_mode(portnp);
+ if (err < 0)
+ ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA;
+ else
+ ocelot->ports[port]->phy_mode = err;
+
+ switch (ocelot->ports[port]->phy_mode) {
+ case PHY_INTERFACE_MODE_NA:
+ continue;
+ case PHY_INTERFACE_MODE_SGMII:
+ phy_mode = PHY_MODE_SGMII;
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ phy_mode = PHY_MODE_QSGMII;
+ break;
+ default:
+ dev_err(ocelot->dev,
+ "invalid phy mode for port%d, (Q)SGMII only\n",
+ port);
+ return -EINVAL;
+ }
+
+ serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
+ if (IS_ERR(serdes)) {
+ err = PTR_ERR(serdes);
+ if (err == -EPROBE_DEFER)
+ dev_dbg(ocelot->dev, "deferring probe\n");
+ else
+ dev_err(ocelot->dev,
+ "missing SerDes phys for port%d\n",
+ port);
+
goto err_probe_ports;
}
+
+ ocelot->ports[port]->serdes = serdes;
}
register_netdevice_notifier(&ocelot_netdevice_nb);