Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbe4d0d6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bcm_sf2'



Florian Fainelli says:

====================
net: dsa: bcm_sf2: misc bugfixes

This patch series contains two bug fixes:

- first patch fixes an issue on the error path of the driver where we could
  have left some of our registers mapped

- second patch enforces the use of a software reset of the switch to guarantee
  the HW is in a consistent state prior to software initialization
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a620a6bc 33f84614
Loading
Loading
Loading
Loading
+33 −25
Original line number Diff line number Diff line
@@ -377,6 +377,29 @@ static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
{
	unsigned int timeout = 1000;
	u32 reg;

	reg = core_readl(priv, CORE_WATCHDOG_CTRL);
	reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
	core_writel(priv, reg, CORE_WATCHDOG_CTRL);

	do {
		reg = core_readl(priv, CORE_WATCHDOG_CTRL);
		if (!(reg & SOFTWARE_RESET))
			break;

		usleep_range(1000, 2000);
	} while (timeout-- > 0);

	if (timeout == 0)
		return -ETIMEDOUT;

	return 0;
}

static int bcm_sf2_sw_setup(struct dsa_switch *ds)
{
	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
@@ -404,11 +427,18 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
		*base = of_iomap(dn, i);
		if (*base == NULL) {
			pr_err("unable to find register: %s\n", reg_names[i]);
			return -ENODEV;
			ret = -ENOMEM;
			goto out_unmap;
		}
		base++;
	}

	ret = bcm_sf2_sw_rst(priv);
	if (ret) {
		pr_err("unable to software reset switch: %d\n", ret);
		goto out_unmap;
	}

	/* Disable all interrupts and request them */
	intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
	intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
@@ -484,6 +514,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
out_unmap:
	base = &priv->core;
	for (i = 0; i < BCM_SF2_REGS_NUM; i++) {
		if (*base)
			iounmap(*base);
		base++;
	}
@@ -733,29 +764,6 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
	return 0;
}

static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
{
	unsigned int timeout = 1000;
	u32 reg;

	reg = core_readl(priv, CORE_WATCHDOG_CTRL);
	reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
	core_writel(priv, reg, CORE_WATCHDOG_CTRL);

	do {
		reg = core_readl(priv, CORE_WATCHDOG_CTRL);
		if (!(reg & SOFTWARE_RESET))
			break;

		usleep_range(1000, 2000);
	} while (timeout-- > 0);

	if (timeout == 0)
		return -ETIMEDOUT;

	return 0;
}

static int bcm_sf2_sw_resume(struct dsa_switch *ds)
{
	struct bcm_sf2_priv *priv = ds_to_priv(ds);