Commit cdf49fff authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'clean-up-ocelot_reset-routine'

Colin Foster says:

====================
clean up ocelot_reset() routine

ocelot_reset() will soon be exported to a common library to be used by
the ocelot_ext system. This will make error values from regmap calls
possible, so they must be checked. Additionally, readx_poll_timeout()
can be substituted for the custom loop, as a simple cleanup.

I don't have hardware to verify this set directly, but there shouldn't
be any functional changes.
====================

Link: https://lore.kernel.org/r/20220917175127.161504-1-colin.foster@in-advantage.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d294ad82 fa1d90b0
Loading
Loading
Loading
Loading
+33 −13
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,27 +195,43 @@ 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);
	err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
	if (err)
		return err;

	do {
		msleep(1);
		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
				  &val);
	} while (val && --retries);
	err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
	if (err)
		return err;

	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);
	err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
	if (err)
		return err;

	return 0;
	return regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
}

/* Watermark encode