On Mon, Mar 28, 2011 at 4:41 AM, Ben Dooks <ben-linux@xxxxxxxxx> wrote: > On Sun, Mar 27, 2011 at 04:32:43PM -0400, Amit Daniel Kachhap wrote: >> This patch adds PM runtime management support in the I2C driver. >> The functionality of the driver is not modified much but some extra I2C >> states are added for PM runtime. The runtime suspend keeps the interrupt >> for the I2C interface disabled. > > ok, whilst this looks ok, it's too late for the current merge window, > so will go into the -next for the next kernel > Hi Ben, I do not see this patch in your i2c-next branch. Could you please merge this patch in the next merge window. Thanks, Amit Daniel >> Signed-off-by: Amit Daniel Kachhap <amit.kachhap@xxxxxxxxxx> >> --- >> drivers/i2c/busses/i2c-s3c2410.c | 61 +++++++++++++++++++++++++++++++++----- >> 1 files changed, 53 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c >> index 6c00c10..8ebe621 100644 >> --- a/drivers/i2c/busses/i2c-s3c2410.c >> +++ b/drivers/i2c/busses/i2c-s3c2410.c >> @@ -35,6 +35,7 @@ >> #include <linux/cpufreq.h> >> #include <linux/slab.h> >> #include <linux/io.h> >> +#include <linux/pm_runtime.h> >> >> #include <asm/irq.h> >> >> @@ -48,7 +49,9 @@ enum s3c24xx_i2c_state { >> STATE_START, >> STATE_READ, >> STATE_WRITE, >> - STATE_STOP >> + STATE_STOP, >> + STATE_STANDBY, >> + STATE_SUSPEND >> }; >> >> enum s3c24xx_i2c_type { >> @@ -59,7 +62,6 @@ enum s3c24xx_i2c_type { >> struct s3c24xx_i2c { >> spinlock_t lock; >> wait_queue_head_t wait; >> - unsigned int suspended:1; >> >> struct i2c_msg *msg; >> unsigned int msg_num; >> @@ -400,8 +402,13 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) >> i2c->msg++; >> } >> } >> + break; >> >> + default: >> + dev_err(i2c->dev, "%s: called with invalid state\n", __func__); >> + goto out; >> break; >> + >> } >> >> /* acknowlegde the IRQ and get back on with the work */ >> @@ -485,7 +492,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, >> int spins = 20; >> int ret; >> >> - if (i2c->suspended) >> + if (i2c->state == STATE_SUSPEND) >> return -EIO; >> >> ret = s3c24xx_i2c_set_master(i2c); >> @@ -555,12 +562,14 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, >> int ret; >> >> clk_enable(i2c->clk); >> + pm_runtime_get_sync(i2c->dev); >> >> for (retry = 0; retry < adap->retries; retry++) { >> >> ret = s3c24xx_i2c_doxfer(i2c, msgs, num); >> >> if (ret != -EAGAIN) { >> + pm_runtime_put_sync(i2c->dev); >> clk_disable(i2c->clk); >> return ret; >> } >> @@ -570,6 +579,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, >> udelay(100); >> } >> >> + pm_runtime_put_sync(i2c->dev); >> clk_disable(i2c->clk); >> return -EREMOTEIO; >> } >> @@ -912,10 +922,14 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) >> goto err_cpufreq; >> } >> >> + /*Set Initial I2C state*/ >> + i2c->state = STATE_STANDBY; >> + >> platform_set_drvdata(pdev, i2c); >> >> dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev)); >> clk_disable(i2c->clk); >> + pm_runtime_enable(&pdev->dev); >> return 0; >> >> err_cpufreq: >> @@ -956,6 +970,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) >> >> clk_disable(i2c->clk); >> clk_put(i2c->clk); >> + pm_runtime_disable(&pdev->dev); >> >> iounmap(i2c->regs); >> >> @@ -972,9 +987,9 @@ static int s3c24xx_i2c_suspend_noirq(struct device *dev) >> struct platform_device *pdev = to_platform_device(dev); >> struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); >> >> - i2c->suspended = 1; >> - >> + i2c->state = STATE_SUSPEND; >> return 0; >> + >> } >> >> static int s3c24xx_i2c_resume(struct device *dev) >> @@ -982,17 +997,47 @@ static int s3c24xx_i2c_resume(struct device *dev) >> struct platform_device *pdev = to_platform_device(dev); >> struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); >> >> - i2c->suspended = 0; >> clk_enable(i2c->clk); >> s3c24xx_i2c_init(i2c); >> + i2c->state = STATE_STANDBY; >> clk_disable(i2c->clk); >> >> return 0; >> } >> >> +static int s3c_i2c_runtime_suspend(struct device *dev) >> +{ >> + struct platform_device *pdev = to_platform_device(dev); >> + struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); >> + >> + i2c->state = STATE_STANDBY; >> + s3c24xx_i2c_disable_irq(i2c); >> + s3c24xx_i2c_disable_ack(i2c); >> + >> + return 0; >> +} >> + >> +static int s3c_i2c_runtime_resume(struct device *dev) >> +{ >> + struct platform_device *pdev = to_platform_device(dev); >> + struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); >> + >> + if (i2c->state != STATE_STANDBY) >> + return 0; >> + >> + /*No major activity in runtime resume because all the registers are >> + re-initialised for each i2c transfer, so just changing the state*/ >> + i2c->state = STATE_IDLE; >> + >> + return 0; >> +} >> + >> + >> static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = { >> - .suspend_noirq = s3c24xx_i2c_suspend_noirq, >> - .resume = s3c24xx_i2c_resume, >> + .suspend_noirq = s3c24xx_i2c_suspend_noirq, >> + .resume = s3c24xx_i2c_resume, >> + .runtime_suspend = s3c_i2c_runtime_suspend, >> + .runtime_resume = s3c_i2c_runtime_resume, >> }; >> >> #define S3C24XX_DEV_PM_OPS (&s3c24xx_i2c_dev_pm_ops) >> -- >> 1.7.1 >> >> >> _______________________________________________ >> linux-arm-kernel mailing list >> linux-arm-kernel@xxxxxxxxxxxxxxxxxxx >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > > -- > Ben Dooks, ben@xxxxxxxxx, http://www.fluff.org/ben/ > > Large Hadron Colada: A large Pina Colada that makes the universe disappear. > > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html