Commit 22f902df authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'i2c-for-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c fix from Wolfram Sang:
 "An i2c driver fix"

* tag 'i2c-for-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr
parents 1dd28064 b4680332
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -32,7 +31,6 @@ struct i2c_pnx_mif { ...@@ -32,7 +31,6 @@ struct i2c_pnx_mif {
int ret; /* Return value */ int ret; /* Return value */
int mode; /* Interface mode */ int mode; /* Interface mode */
struct completion complete; /* I/O completion */ struct completion complete; /* I/O completion */
struct timer_list timer; /* Timeout */
u8 * buf; /* Data buffer */ u8 * buf; /* Data buffer */
int len; /* Length of data buffer */ int len; /* Length of data buffer */
int order; /* RX Bytes to order via TX */ int order; /* RX Bytes to order via TX */
...@@ -117,24 +115,6 @@ static inline int wait_reset(struct i2c_pnx_algo_data *data) ...@@ -117,24 +115,6 @@ static inline int wait_reset(struct i2c_pnx_algo_data *data)
return (timeout <= 0); return (timeout <= 0);
} }
static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
{
struct timer_list *timer = &alg_data->mif.timer;
unsigned long expires = msecs_to_jiffies(alg_data->timeout);
if (expires <= 1)
expires = 2;
del_timer_sync(timer);
dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
jiffies, expires);
timer->expires = jiffies + expires;
add_timer(timer);
}
/** /**
* i2c_pnx_start - start a device * i2c_pnx_start - start a device
* @slave_addr: slave address * @slave_addr: slave address
...@@ -259,8 +239,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) ...@@ -259,8 +239,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
~(mcntrl_afie | mcntrl_naie | mcntrl_drmie), ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
I2C_REG_CTL(alg_data)); I2C_REG_CTL(alg_data));
del_timer_sync(&alg_data->mif.timer);
dev_dbg(&alg_data->adapter.dev, dev_dbg(&alg_data->adapter.dev,
"%s(): Waking up xfer routine.\n", "%s(): Waking up xfer routine.\n",
__func__); __func__);
...@@ -276,8 +254,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) ...@@ -276,8 +254,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
~(mcntrl_afie | mcntrl_naie | mcntrl_drmie), ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
I2C_REG_CTL(alg_data)); I2C_REG_CTL(alg_data));
/* Stop timer. */
del_timer_sync(&alg_data->mif.timer);
dev_dbg(&alg_data->adapter.dev, dev_dbg(&alg_data->adapter.dev,
"%s(): Waking up xfer routine after zero-xfer.\n", "%s(): Waking up xfer routine after zero-xfer.\n",
__func__); __func__);
...@@ -364,8 +340,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) ...@@ -364,8 +340,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
mcntrl_drmie | mcntrl_daie); mcntrl_drmie | mcntrl_daie);
iowrite32(ctl, I2C_REG_CTL(alg_data)); iowrite32(ctl, I2C_REG_CTL(alg_data));
/* Kill timer. */
del_timer_sync(&alg_data->mif.timer);
complete(&alg_data->mif.complete); complete(&alg_data->mif.complete);
} }
} }
...@@ -400,8 +374,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) ...@@ -400,8 +374,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
mcntrl_drmie); mcntrl_drmie);
iowrite32(ctl, I2C_REG_CTL(alg_data)); iowrite32(ctl, I2C_REG_CTL(alg_data));
/* Stop timer, to prevent timeout. */
del_timer_sync(&alg_data->mif.timer);
complete(&alg_data->mif.complete); complete(&alg_data->mif.complete);
} else if (stat & mstatus_nai) { } else if (stat & mstatus_nai) {
/* Slave did not acknowledge, generate a STOP */ /* Slave did not acknowledge, generate a STOP */
...@@ -419,8 +391,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) ...@@ -419,8 +391,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
/* Our return value. */ /* Our return value. */
alg_data->mif.ret = -EIO; alg_data->mif.ret = -EIO;
/* Stop timer, to prevent timeout. */
del_timer_sync(&alg_data->mif.timer);
complete(&alg_data->mif.complete); complete(&alg_data->mif.complete);
} else { } else {
/* /*
...@@ -453,9 +423,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) ...@@ -453,9 +423,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void i2c_pnx_timeout(struct timer_list *t) static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data)
{ {
struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer);
u32 ctl; u32 ctl;
dev_err(&alg_data->adapter.dev, dev_err(&alg_data->adapter.dev,
...@@ -472,7 +441,6 @@ static void i2c_pnx_timeout(struct timer_list *t) ...@@ -472,7 +441,6 @@ static void i2c_pnx_timeout(struct timer_list *t)
iowrite32(ctl, I2C_REG_CTL(alg_data)); iowrite32(ctl, I2C_REG_CTL(alg_data));
wait_reset(alg_data); wait_reset(alg_data);
alg_data->mif.ret = -EIO; alg_data->mif.ret = -EIO;
complete(&alg_data->mif.complete);
} }
static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
...@@ -514,6 +482,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -514,6 +482,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
struct i2c_msg *pmsg; struct i2c_msg *pmsg;
int rc = 0, completed = 0, i; int rc = 0, completed = 0, i;
struct i2c_pnx_algo_data *alg_data = adap->algo_data; struct i2c_pnx_algo_data *alg_data = adap->algo_data;
unsigned long time_left;
u32 stat; u32 stat;
dev_dbg(&alg_data->adapter.dev, dev_dbg(&alg_data->adapter.dev,
...@@ -548,7 +517,6 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -548,7 +517,6 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
__func__, alg_data->mif.mode, alg_data->mif.len); __func__, alg_data->mif.mode, alg_data->mif.len);
i2c_pnx_arm_timer(alg_data);
/* initialize the completion var */ /* initialize the completion var */
init_completion(&alg_data->mif.complete); init_completion(&alg_data->mif.complete);
...@@ -564,7 +532,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -564,7 +532,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
break; break;
/* Wait for completion */ /* Wait for completion */
wait_for_completion(&alg_data->mif.complete); time_left = wait_for_completion_timeout(&alg_data->mif.complete,
alg_data->timeout);
if (time_left == 0)
i2c_pnx_timeout(alg_data);
if (!(rc = alg_data->mif.ret)) if (!(rc = alg_data->mif.ret))
completed++; completed++;
...@@ -653,7 +624,10 @@ static int i2c_pnx_probe(struct platform_device *pdev) ...@@ -653,7 +624,10 @@ static int i2c_pnx_probe(struct platform_device *pdev)
alg_data->adapter.algo_data = alg_data; alg_data->adapter.algo_data = alg_data;
alg_data->adapter.nr = pdev->id; alg_data->adapter.nr = pdev->id;
alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT; alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT);
if (alg_data->timeout <= 1)
alg_data->timeout = 2;
#ifdef CONFIG_OF #ifdef CONFIG_OF
alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node); alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
...@@ -673,8 +647,6 @@ static int i2c_pnx_probe(struct platform_device *pdev) ...@@ -673,8 +647,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
if (IS_ERR(alg_data->clk)) if (IS_ERR(alg_data->clk))
return PTR_ERR(alg_data->clk); return PTR_ERR(alg_data->clk);
timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0);
snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name), snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
"%s", pdev->name); "%s", pdev->name);
......
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