Skip to content

Commit

Permalink
PM / clock_ops: fix up clk prepare/unprepare count
Browse files Browse the repository at this point in the history
The drivers/base/power/clock_ops.c file is causing warnings from
the clock driver (as shown below) due to failing to do a clk_prepare()
call before enabling a clock. It also fails to check the balance of
prepare/unprepare as __pm_clk_remove() do clk_disable_unprepare() call.

This bug has probably been in since commit b247649 ("clk: introduce
the common clock framework") as the warning was part of the original
commit. It is strange that it has not been noticed (although this has
also been coupled with a failure for certain SH builds to not build the
necessary glue to use this method of controlling the clocks).

In summary, this is probably needed in several stable branches but need
advice on which ones.

On the Renesas Lager board, this causes numerous warnings of the following
and even worse the clock system will not enable clocks, causing drivers
that are in development to fail to work:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:883 __clk_enable+0x2c/0xa0()

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Ian Molton <ian.molton@codethink.co.uk>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Ben Dooks authored and Rafael J. Wysocki committed Jan 15, 2014
1 parent 7e22e91 commit 8a6720e
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions drivers/base/power/clock_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
if (IS_ERR(ce->clk)) {
ce->status = PCE_STATUS_ERROR;
} else {
clk_prepare(ce->clk);
ce->status = PCE_STATUS_ACQUIRED;
dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
}
Expand Down Expand Up @@ -99,10 +100,12 @@ static void __pm_clk_remove(struct pm_clock_entry *ce)

if (ce->status < PCE_STATUS_ERROR) {
if (ce->status == PCE_STATUS_ENABLED)
clk_disable_unprepare(ce->clk);
clk_disable(ce->clk);

if (ce->status >= PCE_STATUS_ACQUIRED)
if (ce->status >= PCE_STATUS_ACQUIRED) {
clk_unprepare(ce->clk);
clk_put(ce->clk);
}
}

kfree(ce->con_id);
Expand Down

0 comments on commit 8a6720e

Please sign in to comment.