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

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.comSigned-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 2d52dabb
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -376,6 +377,15 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg, ...@@ -376,6 +377,15 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
mcp251x_spi_trans(spi, 4); 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 #ifdef CONFIG_GPIOLIB
enum { enum {
MCP251X_GPIO_TX0RTS = 0, /* inputs */ MCP251X_GPIO_TX0RTS = 0, /* inputs */
...@@ -709,7 +719,8 @@ static void mcp251x_hw_sleep(struct spi_device *spi) ...@@ -709,7 +719,8 @@ static void mcp251x_hw_sleep(struct spi_device *spi)
/* May only be called when device is sleeping! */ /* May only be called when device is sleeping! */
static int mcp251x_hw_wake(struct spi_device *spi) 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 */ /* Force wakeup interrupt to wake device, but don't execute IST */
disable_irq(spi->irq); disable_irq(spi->irq);
...@@ -722,14 +733,12 @@ static int mcp251x_hw_wake(struct spi_device *spi) ...@@ -722,14 +733,12 @@ static int mcp251x_hw_wake(struct spi_device *spi)
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_CONF); mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_CONF);
/* Wait for the device to enter config mode */ /* Wait for the device to enter config mode */
timeout = jiffies + HZ; ret = mcp251x_read_stat_poll_timeout(spi, value, value == CANCTRL_REQOP_CONF,
while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) != MCP251X_OST_DELAY_MS * 1000,
CANCTRL_REQOP_CONF) { USEC_PER_SEC);
schedule(); if (ret) {
if (time_after(jiffies, timeout)) {
dev_err(&spi->dev, "MCP251x didn't enter in config mode\n"); dev_err(&spi->dev, "MCP251x didn't enter in config mode\n");
return -EBUSY; return ret;
}
} }
/* Disable and clear pending interrupts */ /* Disable and clear pending interrupts */
...@@ -784,7 +793,8 @@ static int mcp251x_do_set_mode(struct net_device *net, enum can_mode mode) ...@@ -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) static int mcp251x_set_normal_mode(struct spi_device *spi)
{ {
struct mcp251x_priv *priv = spi_get_drvdata(spi); struct mcp251x_priv *priv = spi_get_drvdata(spi);
unsigned long timeout; u8 value;
int ret;
/* Enable interrupts */ /* Enable interrupts */
mcp251x_write_reg(spi, CANINTE, mcp251x_write_reg(spi, CANINTE,
...@@ -802,13 +812,12 @@ static int mcp251x_set_normal_mode(struct spi_device *spi) ...@@ -802,13 +812,12 @@ static int mcp251x_set_normal_mode(struct spi_device *spi)
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL); mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
/* Wait for the device to enter normal mode */ /* Wait for the device to enter normal mode */
timeout = jiffies + HZ; ret = mcp251x_read_stat_poll_timeout(spi, value, value == 0,
while (mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) { MCP251X_OST_DELAY_MS * 1000,
schedule(); USEC_PER_SEC);
if (time_after(jiffies, timeout)) { if (ret) {
dev_err(&spi->dev, "MCP251x didn't enter in normal mode\n"); dev_err(&spi->dev, "MCP251x didn't enter in normal mode\n");
return -EBUSY; return ret;
}
} }
} }
priv->can.state = CAN_STATE_ERROR_ACTIVE; priv->can.state = CAN_STATE_ERROR_ACTIVE;
...@@ -852,7 +861,7 @@ static int mcp251x_setup(struct net_device *net, struct spi_device *spi) ...@@ -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) static int mcp251x_hw_reset(struct spi_device *spi)
{ {
struct mcp251x_priv *priv = spi_get_drvdata(spi); struct mcp251x_priv *priv = spi_get_drvdata(spi);
unsigned long timeout; u8 value;
int ret; int ret;
/* Wait for oscillator startup timer after power up */ /* Wait for oscillator startup timer after power up */
...@@ -867,19 +876,12 @@ static int mcp251x_hw_reset(struct spi_device *spi) ...@@ -867,19 +876,12 @@ static int mcp251x_hw_reset(struct spi_device *spi)
mdelay(MCP251X_OST_DELAY_MS); mdelay(MCP251X_OST_DELAY_MS);
/* Wait for reset to finish */ /* Wait for reset to finish */
timeout = jiffies + HZ; ret = mcp251x_read_stat_poll_timeout(spi, value, value == CANCTRL_REQOP_CONF,
while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) != MCP251X_OST_DELAY_MS * 1000,
CANCTRL_REQOP_CONF) { USEC_PER_SEC);
usleep_range(MCP251X_OST_DELAY_MS * 1000, if (ret)
MCP251X_OST_DELAY_MS * 1000 * 2); dev_err(&spi->dev, "MCP251x didn't enter in conf mode after reset\n");
return ret;
if (time_after(jiffies, timeout)) {
dev_err(&spi->dev,
"MCP251x didn't enter in conf mode after reset\n");
return -EBUSY;
}
}
return 0;
} }
static int mcp251x_hw_probe(struct spi_device *spi) static int mcp251x_hw_probe(struct spi_device *spi)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment