Skip to content

Commit

Permalink
net: dsa: bcm_sf2: Add support for optional reset controller line
Browse files Browse the repository at this point in the history
Grab an optional and exclusive reset controller line for the switch and
manage it during probe/remove functions accordingly. For 7278 devices we
change bcm_sf2_sw_rst() to use the reset controller line since the
WATCHDOG_CTRL register does not reset the switch contrary to stated
documentation.

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>
  • Loading branch information
Florian Fainelli authored and David S. Miller committed Nov 6, 2019
1 parent 9482d03 commit eee87e4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
19 changes: 19 additions & 0 deletions drivers/net/dsa/bcm_sf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,18 @@ static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
{
unsigned int timeout = 1000;
u32 reg;
int ret;

/* The watchdog reset does not work on 7278, we need to hit the
* "external" reset line through the reset controller.
*/
if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev)) {
ret = reset_control_assert(priv->rcdev);
if (ret)
return ret;

return reset_control_deassert(priv->rcdev);
}

reg = core_readl(priv, CORE_WATCHDOG_CTRL);
reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
Expand Down Expand Up @@ -1092,6 +1104,11 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
priv->core_reg_align = data->core_reg_align;
priv->num_cfp_rules = data->num_cfp_rules;

priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
"switch");
if (PTR_ERR(priv->rcdev) == -EPROBE_DEFER)
return PTR_ERR(priv->rcdev);

/* Auto-detection using standard registers will not work, so
* provide an indication of what kind of device we are for
* b53_common to work with
Expand Down Expand Up @@ -1224,6 +1241,8 @@ static int bcm_sf2_sw_remove(struct platform_device *pdev)
/* Disable all ports and interrupts */
bcm_sf2_sw_suspend(priv->dev->ds);
bcm_sf2_mdio_unregister(priv);
if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev))
reset_control_assert(priv->rcdev);

return 0;
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/dsa/bcm_sf2.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/if_vlan.h>
#include <linux/reset.h>

#include <net/dsa.h>

Expand Down Expand Up @@ -64,6 +65,8 @@ struct bcm_sf2_priv {
void __iomem *fcb;
void __iomem *acb;

struct reset_control *rcdev;

/* Register offsets indirection tables */
u32 type;
const u16 *reg_offsets;
Expand Down

0 comments on commit eee87e4

Please sign in to comment.