From 958585f58f675a3c2855c7d91b6fdd2875552d0b Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sun, 27 Jul 2008 14:41:54 +0800 Subject: [PATCH] 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: Michael Hennerich Signed-off-by: Bryan Wu Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-bfin-twi.c | 35 +++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 48d084bdf7c8..3c855ff2992f 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -49,6 +49,8 @@ struct bfin_twi_iface { struct i2c_msg *pmsg; int msg_num; int cur_msg; + u16 saved_clkdiv; + u16 saved_control; void __iomem *regs_base; }; @@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap) I2C_FUNC_I2C; } - static struct i2c_algorithm bfin_twi_algorithm = { .master_xfer = bfin_twi_master_xfer, .smbus_xfer = bfin_twi_smbus_xfer, .functionality = bfin_twi_functionality, }; - -static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state) +static int i2c_bfin_twi_suspend(struct platform_device *pdev, 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 */ - write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA); - SSYNC(); + write_CONTROL(iface, iface->saved_control & ~TWI_ENA); 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 */ - write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); - SSYNC(); + int rc = request_irq(iface->irq, bfin_twi_interrupt_entry, + IRQF_DISABLED, pdev->name, iface); + 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; } -- 2.20.1