Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ben Dooks and committed by
Wolfram Sang
bc8120f1 770540f0

+9 -8
+9 -8
drivers/i2c/busses/i2c-rcar.c
··· 110 110 void __iomem *io; 111 111 struct i2c_adapter adap; 112 112 struct i2c_msg *msg; 113 + struct clk *clk; 113 114 114 115 spinlock_t lock; 115 116 wait_queue_head_t wait; ··· 227 226 u32 bus_speed, 228 227 struct device *dev) 229 228 { 230 - struct clk *clkp = clk_get(dev, NULL); 231 229 u32 scgd, cdf; 232 230 u32 round, ick; 233 231 u32 scl; 234 232 u32 cdf_width; 235 233 unsigned long rate; 236 - 237 - if (IS_ERR(clkp)) { 238 - dev_err(dev, "couldn't get clock\n"); 239 - return PTR_ERR(clkp); 240 - } 241 234 242 235 switch (priv->devtype) { 243 236 case I2C_RCAR_GEN1: ··· 260 265 * clkp : peripheral_clk 261 266 * F[] : integer up-valuation 262 267 */ 263 - rate = clk_get_rate(clkp); 268 + rate = clk_get_rate(priv->clk); 264 269 cdf = rate / 20000000; 265 270 if (cdf >= 1 << cdf_width) { 266 271 dev_err(dev, "Input clock %lu too high\n", rate); ··· 302 307 303 308 scgd_find: 304 309 dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", 305 - scl, bus_speed, clk_get_rate(clkp), round, cdf, scgd); 310 + scl, bus_speed, clk_get_rate(priv->clk), round, cdf, scgd); 306 311 307 312 /* 308 313 * keep icccr value ··· 656 661 if (!priv) { 657 662 dev_err(dev, "no mem for private data\n"); 658 663 return -ENOMEM; 664 + } 665 + 666 + priv->clk = devm_clk_get(dev, NULL); 667 + if (IS_ERR(priv->clk)) { 668 + dev_err(dev, "cannot get clock\n"); 669 + return PTR_ERR(priv->clk); 659 670 } 660 671 661 672 bus_speed = 100000; /* default 100 kHz */