summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2014-01-26 16:05:35 +0000
committerWolfram Sang <wsa@the-dreams.de>2014-01-26 22:48:34 +0100
commitbc8120f17ae87da0850b4e6a806ad88ffd01ca64 (patch)
treee41afe3176a871a1b7d347c10217430d19bb6dc8 /drivers/i2c
parent770540f029ba65a2658b5204d850565ab7f61f1b (diff)
downloadlinux-bc8120f17ae87da0850b4e6a806ad88ffd01ca64.tar.bz2
i2c: rcar: use devm_clk_get to ensure clock is properly ref-counted
The current i2c-rcar driver does clk_get() without a corresponding clk_put(). Add the clk to the driver private data and then get it with the devm functions so that it is released when the driver is unbound. Note, we do not call clk_prepare_enable() at this point due to the very possible magic that is being done by the pm_runtime system underneath the driver. Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-rcar.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index fd4cd7f6b3ef..57169d23aa3b 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -110,6 +110,7 @@ struct rcar_i2c_priv {
void __iomem *io;
struct i2c_adapter adap;
struct i2c_msg *msg;
+ struct clk *clk;
spinlock_t lock;
wait_queue_head_t wait;
@@ -226,18 +227,12 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
u32 bus_speed,
struct device *dev)
{
- struct clk *clkp = clk_get(dev, NULL);
u32 scgd, cdf;
u32 round, ick;
u32 scl;
u32 cdf_width;
unsigned long rate;
- if (IS_ERR(clkp)) {
- dev_err(dev, "couldn't get clock\n");
- return PTR_ERR(clkp);
- }
-
switch (priv->devtype) {
case I2C_RCAR_GEN1:
cdf_width = 2;
@@ -265,7 +260,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
* clkp : peripheral_clk
* F[] : integer up-valuation
*/
- rate = clk_get_rate(clkp);
+ rate = clk_get_rate(priv->clk);
cdf = rate / 20000000;
if (cdf >= 1 << cdf_width) {
dev_err(dev, "Input clock %lu too high\n", rate);
@@ -307,7 +302,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
scgd_find:
dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n",
- scl, bus_speed, clk_get_rate(clkp), round, cdf, scgd);
+ scl, bus_speed, clk_get_rate(priv->clk), round, cdf, scgd);
/*
* keep icccr value
@@ -663,6 +658,12 @@ static int rcar_i2c_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "cannot get clock\n");
+ return PTR_ERR(priv->clk);
+ }
+
bus_speed = 100000; /* default 100 kHz */
ret = of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed);
if (ret < 0 && pdata && pdata->bus_speed)