Commit 958585f5 authored by Michael Hennerich's avatar Michael Hennerich Committed by Ben Dooks

i2c: Blackfin I2C Driver: Functional power management support

PM_SUSPEND_MEM: Blackfin does not maintain register state through
Hibernate. Save and restore peripheral base initialization during
PM transitions.
Signed-off-by: default avatarMichael Hennerich <michael.hennerich@analog.com>
Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent 31321b76
...@@ -49,6 +49,8 @@ struct bfin_twi_iface { ...@@ -49,6 +49,8 @@ struct bfin_twi_iface {
struct i2c_msg *pmsg; struct i2c_msg *pmsg;
int msg_num; int msg_num;
int cur_msg; int cur_msg;
u16 saved_clkdiv;
u16 saved_control;
void __iomem *regs_base; void __iomem *regs_base;
}; };
...@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap) ...@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap)
I2C_FUNC_I2C; I2C_FUNC_I2C;
} }
static struct i2c_algorithm bfin_twi_algorithm = { static struct i2c_algorithm bfin_twi_algorithm = {
.master_xfer = bfin_twi_master_xfer, .master_xfer = bfin_twi_master_xfer,
.smbus_xfer = bfin_twi_smbus_xfer, .smbus_xfer = bfin_twi_smbus_xfer,
.functionality = bfin_twi_functionality, .functionality = bfin_twi_functionality,
}; };
static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)
static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
{ {
struct bfin_twi_iface *iface = platform_get_drvdata(dev); struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
iface->saved_clkdiv = read_CLKDIV(iface);
iface->saved_control = read_CONTROL(iface);
free_irq(iface->irq, iface);
/* Disable TWI */ /* Disable TWI */
write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA); write_CONTROL(iface, iface->saved_control & ~TWI_ENA);
SSYNC();
return 0; return 0;
} }
static int i2c_bfin_twi_resume(struct platform_device *dev) static int i2c_bfin_twi_resume(struct platform_device *pdev)
{ {
struct bfin_twi_iface *iface = platform_get_drvdata(dev); struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
/* Enable TWI */ int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); IRQF_DISABLED, pdev->name, iface);
SSYNC(); if (rc) {
dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
return -ENODEV;
}
/* Resume TWI interface clock as specified */
write_CLKDIV(iface, iface->saved_clkdiv);
/* Resume TWI */
write_CONTROL(iface, iface->saved_control);
return 0; return 0;
} }
......
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