diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index e05a672db3e5..76d16713508f 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -31,10 +31,12 @@ #include #include #include +#include #define DEFAULT_TWI_CLK_HZ 100000 /* max 400 Kbits/s */ #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ #define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */ +#define AUTOSUSPEND_TIMEOUT 2000 /* AT91 TWI register definitions */ #define AT91_TWI_CR 0x0000 /* Control Register */ @@ -481,6 +483,10 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); + ret = pm_runtime_get_sync(dev->dev); + if (ret < 0) + goto out; + /* * The hardware can handle at most two messages concatenated by a * repeated start via it's internal address feature. @@ -488,18 +494,21 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) if (num > 2) { dev_err(dev->dev, "cannot handle more than two concatenated messages.\n"); - return 0; + ret = 0; + goto out; } else if (num == 2) { int internal_address = 0; int i; if (msg->flags & I2C_M_RD) { dev_err(dev->dev, "first transfer must be write.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } if (msg->len > 3) { dev_err(dev->dev, "first message size must be <= 3.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } /* 1st msg is put into the internal address, start with 2nd */ @@ -523,7 +532,12 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) ret = at91_do_twi_transfer(dev); - return (ret < 0) ? ret : num; + ret = (ret < 0) ? ret : num; +out: + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + + return ret; } static u32 at91_twi_func(struct i2c_adapter *adapter) @@ -795,11 +809,20 @@ static int at91_twi_probe(struct platform_device *pdev) dev->adapter.timeout = AT91_I2C_TIMEOUT; dev->adapter.dev.of_node = pdev->dev.of_node; + pm_runtime_set_autosuspend_delay(dev->dev, AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev->dev); + pm_runtime_set_active(dev->dev); + pm_runtime_enable(dev->dev); + rc = i2c_add_numbered_adapter(&dev->adapter); if (rc) { dev_err(dev->dev, "Adapter %s registration failed\n", dev->adapter.name); clk_disable_unprepare(dev->clk); + + pm_runtime_disable(dev->dev); + pm_runtime_set_suspended(dev->dev); + return rc; } @@ -814,6 +837,9 @@ static int at91_twi_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); clk_disable_unprepare(dev->clk); + pm_runtime_disable(dev->dev); + pm_runtime_set_suspended(dev->dev); + return 0; } @@ -823,7 +849,7 @@ static int at91_twi_runtime_suspend(struct device *dev) { struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); - clk_disable(twi_dev->clk); + clk_disable_unprepare(twi_dev->clk); return 0; } @@ -832,7 +858,7 @@ static int at91_twi_runtime_resume(struct device *dev) { struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); - return clk_enable(twi_dev->clk); + return clk_prepare_enable(twi_dev->clk); } static const struct dev_pm_ops at91_twi_pm = {