mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
i2c don NOT suspend when system enter sleep
This commit is contained in:
@@ -85,7 +85,7 @@ struct rk2818_i2c_data {
|
||||
unsigned int msg_num;
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
struct notifier_block freq_transition;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
static void rk2818_i2c_init_hw(struct rk2818_i2c_data *i2c);
|
||||
@@ -230,19 +230,22 @@ static int rk2818_wait_event(struct rk2818_i2c_data *i2c,
|
||||
enum rk2818_event mr_event)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(unlikely(irqs_disabled()))
|
||||
unsigned long flags;
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
{
|
||||
dev_err(i2c->dev, "irqs are disabled on this system!\n");
|
||||
return -EIO;
|
||||
}
|
||||
spin_lock_irq(&i2c->cmd_lock);
|
||||
if(unlikely(irqs_disabled()))
|
||||
{
|
||||
dev_err(i2c->dev, "irqs are disabled on this system!\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&i2c->cmd_lock,flags);
|
||||
i2c->cmd_err = RK2818_ERROR_NONE;
|
||||
i2c->cmd_event = mr_event;
|
||||
|
||||
init_completion(&i2c->cmd_complete);
|
||||
|
||||
spin_unlock_irq(&i2c->cmd_lock);
|
||||
spin_unlock_irqrestore(&i2c->cmd_lock,flags);
|
||||
|
||||
rk2818_i2c_enable_irqs(i2c);
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
@@ -461,6 +464,17 @@ exit:
|
||||
{
|
||||
dev_err(i2c->dev, "<error>rk2818_i2c_stop timeout\n");
|
||||
}
|
||||
|
||||
//not I2C code,add by sxj,used for extend gpio intrrupt,set SCL and SDA pin.
|
||||
if(msg->flags & I2C_M_RD)
|
||||
{
|
||||
#if defined (CONFIG_IOEXTEND_TCA6424)
|
||||
if (pdata && pdata->reseti2cpin) {
|
||||
pdata->reseti2cpin();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -473,9 +487,10 @@ static int rk2818_i2c_xfer(struct i2c_adapter *adap,
|
||||
int i;
|
||||
struct rk2818_i2c_data *i2c = (struct rk2818_i2c_data *)adap->algo_data;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
|
||||
/*
|
||||
if(i2c->suspended ==1)
|
||||
return -EIO;
|
||||
*/
|
||||
if(msgs[0].scl_rate <= 400000 && msgs[0].scl_rate > 0)
|
||||
i2c->scl_rate = msgs[0].scl_rate;
|
||||
else
|
||||
@@ -516,7 +531,17 @@ static const struct i2c_algorithm rk2818_i2c_algorithm = {
|
||||
.functionality = rk2818_i2c_func,
|
||||
};
|
||||
|
||||
|
||||
int i2c_suspended(struct i2c_adapter *adap)
|
||||
{
|
||||
struct rk2818_i2c_data *i2c = (struct rk2818_i2c_data *)adap->algo_data;
|
||||
if(adap->nr > 1)
|
||||
return 1;
|
||||
if(i2c == NULL)
|
||||
return 1;
|
||||
return i2c->suspended;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_suspended);
|
||||
|
||||
static void rk2818_i2c_init_hw(struct rk2818_i2c_data *i2c)
|
||||
{
|
||||
unsigned long lcmr = 0x00000000;
|
||||
@@ -735,6 +760,7 @@ static int rk2818_i2c_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int rk2818_i2c_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct rk2818_i2c_data *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
6
drivers/i2c/i2c-core.c
Normal file → Executable file
6
drivers/i2c/i2c-core.c
Normal file → Executable file
@@ -1091,8 +1091,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
(msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_RK2818
|
||||
if (!(i2c_suspended(adap)) && (in_atomic() || irqs_disabled())) {
|
||||
#else
|
||||
if (in_atomic() || irqs_disabled()) {
|
||||
#endif
|
||||
|
||||
ret = mutex_trylock(&adap->bus_lock);
|
||||
if (!ret)
|
||||
/* I2C activity is ongoing. */
|
||||
|
||||
1
include/linux/i2c.h
Normal file → Executable file
1
include/linux/i2c.h
Normal file → Executable file
@@ -62,6 +62,7 @@ extern int i2c_master_reg8_send(struct i2c_client *client, const char reg, const
|
||||
extern int i2c_master_reg8_recv(struct i2c_client *client, const char reg, char *buf, int count, int scl_rate);
|
||||
extern int i2c_master_reg16_send(struct i2c_client *client, const short regs, const short *buf, int count, int scl_rate);
|
||||
extern int i2c_master_reg16_recv(struct i2c_client *client, const short regs, short *buf, int count, int scl_rate);
|
||||
extern int i2c_suspended(struct i2c_adapter *adap);
|
||||
#endif
|
||||
|
||||
extern int i2c_master_send(struct i2c_client *client, const char *buf,
|
||||
|
||||
Reference in New Issue
Block a user