Merge branch 'pm-clk'

* pm-clk:
  PM / clock_ops: report clock errors from clk_enable()
  PM / clock_ops: check return of clk_enable() in pm_clk_resume()
  PM / clock_ops: fix up clk prepare/unprepare count
This commit is contained in:
Rafael J. Wysocki 2014-01-17 01:56:56 +01:00
commit 380062bd66

View File

@ -32,6 +32,21 @@ struct pm_clock_entry {
enum pce_status status; enum pce_status status;
}; };
/**
* pm_clk_enable - Enable a clock, reporting any errors
* @dev: The device for the given clock
* @clk: The clock being enabled.
*/
static inline int __pm_clk_enable(struct device *dev, struct clk *clk)
{
int ret = clk_enable(clk);
if (ret)
dev_err(dev, "%s: failed to enable clk %p, error %d\n",
__func__, clk, ret);
return ret;
}
/** /**
* pm_clk_acquire - Acquire a device clock. * pm_clk_acquire - Acquire a device clock.
* @dev: Device whose clock is to be acquired. * @dev: Device whose clock is to be acquired.
@ -43,6 +58,7 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
if (IS_ERR(ce->clk)) { if (IS_ERR(ce->clk)) {
ce->status = PCE_STATUS_ERROR; ce->status = PCE_STATUS_ERROR;
} else { } else {
clk_prepare(ce->clk);
ce->status = PCE_STATUS_ACQUIRED; ce->status = PCE_STATUS_ACQUIRED;
dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
} }
@ -99,11 +115,13 @@ static void __pm_clk_remove(struct pm_clock_entry *ce)
if (ce->status < PCE_STATUS_ERROR) { if (ce->status < PCE_STATUS_ERROR) {
if (ce->status == PCE_STATUS_ENABLED) 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); clk_put(ce->clk);
} }
}
kfree(ce->con_id); kfree(ce->con_id);
kfree(ce); kfree(ce);
@ -249,6 +267,7 @@ int pm_clk_resume(struct device *dev)
struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce; struct pm_clock_entry *ce;
unsigned long flags; unsigned long flags;
int ret;
dev_dbg(dev, "%s()\n", __func__); dev_dbg(dev, "%s()\n", __func__);
@ -259,7 +278,8 @@ int pm_clk_resume(struct device *dev)
list_for_each_entry(ce, &psd->clock_list, node) { list_for_each_entry(ce, &psd->clock_list, node) {
if (ce->status < PCE_STATUS_ERROR) { if (ce->status < PCE_STATUS_ERROR) {
clk_enable(ce->clk); ret = __pm_clk_enable(dev, ce->clk);
if (!ret)
ce->status = PCE_STATUS_ENABLED; ce->status = PCE_STATUS_ENABLED;
} }
} }
@ -376,7 +396,7 @@ int pm_clk_resume(struct device *dev)
spin_lock_irqsave(&psd->lock, flags); spin_lock_irqsave(&psd->lock, flags);
list_for_each_entry(ce, &psd->clock_list, node) list_for_each_entry(ce, &psd->clock_list, node)
clk_enable(ce->clk); __pm_clk_enable(dev, ce->clk);
spin_unlock_irqrestore(&psd->lock, flags); spin_unlock_irqrestore(&psd->lock, flags);