Commit 21bb08cd authored by Colin Foster's avatar Colin Foster Committed by Jakub Kicinski
Browse files

net: mscc: ocelot: utilize readx_poll_timeout() for chip reset



Clean up the reset code by utilizing readx_poll_timeout instead of a custom
loop.

Signed-off-by: default avatarColin Foster <colin.foster@in-advantage.com>
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent d294ad82
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 */
#include <linux/dsa/ocelot.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_net.h>
#include <linux/netdevice.h>
@@ -25,6 +26,9 @@
#define VSC7514_VCAP_POLICER_BASE			128
#define VSC7514_VCAP_POLICER_MAX			191

#define MEM_INIT_SLEEP_US				1000
#define MEM_INIT_TIMEOUT_US				100000

static const u32 *ocelot_regmap[TARGET_MAX] = {
	[ANA] = vsc7514_ana_regmap,
	[QS] = vsc7514_qs_regmap,
@@ -191,22 +195,32 @@ static const struct of_device_id mscc_ocelot_match[] = {
};
MODULE_DEVICE_TABLE(of, mscc_ocelot_match);

static int ocelot_mem_init_status(struct ocelot *ocelot)
{
	unsigned int val;
	int err;

	err = regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
				&val);

	return err ?: val;
}

static int ocelot_reset(struct ocelot *ocelot)
{
	int retries = 100;
	int err;
	u32 val;

	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);

	do {
		msleep(1);
		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
				  &val);
	} while (val && --retries);

	if (!retries)
		return -ETIMEDOUT;
	/* MEM_INIT is a self-clearing bit. Wait for it to be cleared (should be
	 * 100us) before enabling the switch core.
	 */
	err = readx_poll_timeout(ocelot_mem_init_status, ocelot, val, !val,
				 MEM_INIT_SLEEP_US, MEM_INIT_TIMEOUT_US);
	if (err)
		return err;

	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);