diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2017-01-08 00:01:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-08 22:01:22 -0500 |
commit | a4c61b92b3a4cbda35bb0251a5063a68f0861b2c (patch) | |
tree | da293a8457b7a372f3fd97845272996359329f3c | |
parent | a2cd64f30140c5aebd9359f66c00c19d5c6bece6 (diff) |
net: dsa: bcm_sf2: Do not clobber b53_switch_ops
We make the bcm_sf2 driver override ds->ops which points to
b53_switch_ops since b53_switch_alloc() did the assignent. This is all
well and good until a second b53 switch comes in, and ends up using the
bcm_sf2 operations. Make a proper local copy, substitute the ds->ops
pointer and then override the operations.
Fixes: f458995b9ad8 ("net: dsa: bcm_sf2: Utilize core B53 driver when possible")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/dsa/bcm_sf2.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 9ec33b51a0ed..2f9f910c0e40 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c | |||
@@ -982,6 +982,7 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) | |||
982 | const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; | 982 | const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; |
983 | struct device_node *dn = pdev->dev.of_node; | 983 | struct device_node *dn = pdev->dev.of_node; |
984 | struct b53_platform_data *pdata; | 984 | struct b53_platform_data *pdata; |
985 | struct dsa_switch_ops *ops; | ||
985 | struct bcm_sf2_priv *priv; | 986 | struct bcm_sf2_priv *priv; |
986 | struct b53_device *dev; | 987 | struct b53_device *dev; |
987 | struct dsa_switch *ds; | 988 | struct dsa_switch *ds; |
@@ -995,6 +996,10 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) | |||
995 | if (!priv) | 996 | if (!priv) |
996 | return -ENOMEM; | 997 | return -ENOMEM; |
997 | 998 | ||
999 | ops = devm_kzalloc(&pdev->dev, sizeof(*ops), GFP_KERNEL); | ||
1000 | if (!ops) | ||
1001 | return -ENOMEM; | ||
1002 | |||
998 | dev = b53_switch_alloc(&pdev->dev, &bcm_sf2_io_ops, priv); | 1003 | dev = b53_switch_alloc(&pdev->dev, &bcm_sf2_io_ops, priv); |
999 | if (!dev) | 1004 | if (!dev) |
1000 | return -ENOMEM; | 1005 | return -ENOMEM; |
@@ -1014,6 +1019,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) | |||
1014 | ds = dev->ds; | 1019 | ds = dev->ds; |
1015 | 1020 | ||
1016 | /* Override the parts that are non-standard wrt. normal b53 devices */ | 1021 | /* Override the parts that are non-standard wrt. normal b53 devices */ |
1022 | memcpy(ops, ds->ops, sizeof(*ops)); | ||
1023 | ds->ops = ops; | ||
1017 | ds->ops->get_tag_protocol = bcm_sf2_sw_get_tag_protocol; | 1024 | ds->ops->get_tag_protocol = bcm_sf2_sw_get_tag_protocol; |
1018 | ds->ops->setup = bcm_sf2_sw_setup; | 1025 | ds->ops->setup = bcm_sf2_sw_setup; |
1019 | ds->ops->get_phy_flags = bcm_sf2_sw_get_phy_flags; | 1026 | ds->ops->get_phy_flags = bcm_sf2_sw_get_phy_flags; |