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

Commit ff06d611 authored by Alexander Shiyan's avatar Alexander Shiyan Committed by Marc Kleine-Budde
Browse files

can: mcp251x: Improve mcp251x_hw_reset()



The MCP251x utilizes an oscillator startup timer (OST), which holds the
chip in reset, to insure that the oscillator has stabilized before the
internal state machine begins to operate. The OST maintains reset for
the first 128 OSC clock cycles after power up or reset.
So, this patch removes unnecessary loops and reduce delay for power on
and reset to the safe value.

Signed-off-by: default avatarAlexander Shiyan <shc_work@mail.ru>
Tested-by: default avatarAlexander Shiyan <shc_work@mail.ru>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 31473c28
Loading
Loading
Loading
Loading
+16 −19
Original line number Diff line number Diff line
@@ -214,6 +214,8 @@

#define TX_ECHO_SKB_MAX	1

#define MCP251X_OST_DELAY_MS	(5)

#define DEVICE_NAME "mcp251x"

static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
@@ -624,28 +626,24 @@ static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
static int mcp251x_hw_reset(struct spi_device *spi)
{
	struct mcp251x_priv *priv = spi_get_drvdata(spi);
	u8 reg;
	int ret;
	unsigned long timeout;

	/* Wait for oscillator startup timer after power up */
	mdelay(MCP251X_OST_DELAY_MS);

	priv->spi_tx_buf[0] = INSTRUCTION_RESET;
	ret = spi_write(spi, priv->spi_tx_buf, 1);
	if (ret) {
		dev_err(&spi->dev, "reset failed: ret = %d\n", ret);
		return -EIO;
	}
	ret = mcp251x_spi_trans(spi, 1);
	if (ret)
		return ret;

	/* Wait for oscillator startup timer after reset */
	mdelay(MCP251X_OST_DELAY_MS);
	
	reg = mcp251x_read_reg(spi, CANSTAT);
	if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
		return -ENODEV;

	/* Wait for reset to finish */
	timeout = jiffies + HZ;
	mdelay(10);
	while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK)
	       != CANCTRL_REQOP_CONF) {
		schedule();
		if (time_after(jiffies, timeout)) {
			dev_err(&spi->dev, "MCP251x didn't"
				" enter in conf mode after reset\n");
			return -EBUSY;
		}
	}
	return 0;
}

@@ -776,7 +774,6 @@ static void mcp251x_restart_work_handler(struct work_struct *ws)

	mutex_lock(&priv->mcp_lock);
	if (priv->after_suspend) {
		mdelay(10);
		mcp251x_hw_reset(spi);
		mcp251x_setup(net, priv, spi);
		if (priv->after_suspend & AFTER_SUSPEND_RESTART) {