Commit 74fa565b authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Marc Kleine-Budde
Browse files

can: mcp251x: Use readx_poll_timeout() helper



We may use special helper macro to poll IO till condition or timeout occurs.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200217161038.25009-1-andriy.shevchenko@linux.intel.com


Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 2d52dabb
Loading
Loading
Loading
Loading
+33 −31
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
@@ -376,6 +377,15 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
	mcp251x_spi_trans(spi, 4);
}

static u8 mcp251x_read_stat(struct spi_device *spi)
{
	return mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK;
}

#define mcp251x_read_stat_poll_timeout(addr, val, cond, delay_us, timeout_us) \
	readx_poll_timeout(mcp251x_read_stat, addr, val, cond, \
			   delay_us, timeout_us)

#ifdef CONFIG_GPIOLIB
enum {
	MCP251X_GPIO_TX0RTS = 0,		/* inputs */
@@ -709,7 +719,8 @@ static void mcp251x_hw_sleep(struct spi_device *spi)
/* May only be called when device is sleeping! */
static int mcp251x_hw_wake(struct spi_device *spi)
{
	unsigned long timeout;
	u8 value;
	int ret;

	/* Force wakeup interrupt to wake device, but don't execute IST */
	disable_irq(spi->irq);
@@ -722,14 +733,12 @@ static int mcp251x_hw_wake(struct spi_device *spi)
	mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_CONF);

	/* Wait for the device to enter config mode */
	timeout = jiffies + HZ;
	while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) !=
			CANCTRL_REQOP_CONF) {
		schedule();
		if (time_after(jiffies, timeout)) {
	ret = mcp251x_read_stat_poll_timeout(spi, value, value == CANCTRL_REQOP_CONF,
					     MCP251X_OST_DELAY_MS * 1000,
					     USEC_PER_SEC);
	if (ret) {
		dev_err(&spi->dev, "MCP251x didn't enter in config mode\n");
			return -EBUSY;
		}
		return ret;
	}

	/* Disable and clear pending interrupts */
@@ -784,7 +793,8 @@ static int mcp251x_do_set_mode(struct net_device *net, enum can_mode mode)
static int mcp251x_set_normal_mode(struct spi_device *spi)
{
	struct mcp251x_priv *priv = spi_get_drvdata(spi);
	unsigned long timeout;
	u8 value;
	int ret;

	/* Enable interrupts */
	mcp251x_write_reg(spi, CANINTE,
@@ -802,13 +812,12 @@ static int mcp251x_set_normal_mode(struct spi_device *spi)
		mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);

		/* Wait for the device to enter normal mode */
		timeout = jiffies + HZ;
		while (mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) {
			schedule();
			if (time_after(jiffies, timeout)) {
		ret = mcp251x_read_stat_poll_timeout(spi, value, value == 0,
						     MCP251X_OST_DELAY_MS * 1000,
						     USEC_PER_SEC);
		if (ret) {
			dev_err(&spi->dev, "MCP251x didn't enter in normal mode\n");
				return -EBUSY;
			}
			return ret;
		}
	}
	priv->can.state = CAN_STATE_ERROR_ACTIVE;
@@ -852,7 +861,7 @@ static int mcp251x_setup(struct net_device *net, struct spi_device *spi)
static int mcp251x_hw_reset(struct spi_device *spi)
{
	struct mcp251x_priv *priv = spi_get_drvdata(spi);
	unsigned long timeout;
	u8 value;
	int ret;

	/* Wait for oscillator startup timer after power up */
@@ -867,19 +876,12 @@ static int mcp251x_hw_reset(struct spi_device *spi)
	mdelay(MCP251X_OST_DELAY_MS);

	/* Wait for reset to finish */
	timeout = jiffies + HZ;
	while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) !=
	       CANCTRL_REQOP_CONF) {
		usleep_range(MCP251X_OST_DELAY_MS * 1000,
			     MCP251X_OST_DELAY_MS * 1000 * 2);

		if (time_after(jiffies, timeout)) {
			dev_err(&spi->dev,
				"MCP251x didn't enter in conf mode after reset\n");
			return -EBUSY;
		}
	}
	return 0;
	ret = mcp251x_read_stat_poll_timeout(spi, value, value == CANCTRL_REQOP_CONF,
					     MCP251X_OST_DELAY_MS * 1000,
					     USEC_PER_SEC);
	if (ret)
		dev_err(&spi->dev, "MCP251x didn't enter in conf mode after reset\n");
	return ret;
}

static int mcp251x_hw_probe(struct spi_device *spi)