diff options
Diffstat (limited to 'drivers/base/power')
-rw-r--r-- | drivers/base/power/clock_ops.c | 40 | ||||
-rw-r--r-- | drivers/base/power/domain.c | 33 | ||||
-rw-r--r-- | drivers/base/power/opp.c | 2 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 10 | ||||
-rw-r--r-- | drivers/base/power/sysfs.c | 2 |
5 files changed, 48 insertions, 39 deletions
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index a846b2f95cfb..2c18d584066d 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -19,7 +19,7 @@ struct pm_clk_data { struct list_head clock_list; - struct mutex lock; + spinlock_t lock; }; enum pce_status { @@ -73,9 +73,9 @@ int pm_clk_add(struct device *dev, const char *con_id) } } - mutex_lock(&pcd->lock); + spin_lock_irq(&pcd->lock); list_add_tail(&ce->node, &pcd->clock_list); - mutex_unlock(&pcd->lock); + spin_unlock_irq(&pcd->lock); return 0; } @@ -83,8 +83,8 @@ int pm_clk_add(struct device *dev, const char *con_id) * __pm_clk_remove - Destroy PM clock entry. * @ce: PM clock entry to destroy. * - * This routine must be called under the mutex protecting the PM list of clocks - * corresponding the the @ce's device. + * This routine must be called under the spinlock protecting the PM list of + * clocks corresponding the the @ce's device. */ static void __pm_clk_remove(struct pm_clock_entry *ce) { @@ -123,7 +123,7 @@ void pm_clk_remove(struct device *dev, const char *con_id) if (!pcd) return; - mutex_lock(&pcd->lock); + spin_lock_irq(&pcd->lock); list_for_each_entry(ce, &pcd->clock_list, node) { if (!con_id && !ce->con_id) { @@ -137,7 +137,7 @@ void pm_clk_remove(struct device *dev, const char *con_id) } } - mutex_unlock(&pcd->lock); + spin_unlock_irq(&pcd->lock); } /** @@ -158,7 +158,7 @@ int pm_clk_init(struct device *dev) } INIT_LIST_HEAD(&pcd->clock_list); - mutex_init(&pcd->lock); + spin_lock_init(&pcd->lock); dev->power.subsys_data = pcd; return 0; } @@ -181,12 +181,12 @@ void pm_clk_destroy(struct device *dev) dev->power.subsys_data = NULL; - mutex_lock(&pcd->lock); + spin_lock_irq(&pcd->lock); list_for_each_entry_safe_reverse(ce, c, &pcd->clock_list, node) __pm_clk_remove(ce); - mutex_unlock(&pcd->lock); + spin_unlock_irq(&pcd->lock); kfree(pcd); } @@ -220,13 +220,14 @@ int pm_clk_suspend(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); if (!pcd) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry_reverse(ce, &pcd->clock_list, node) { if (ce->status == PCE_STATUS_NONE) @@ -238,7 +239,7 @@ int pm_clk_suspend(struct device *dev) } } - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } @@ -251,13 +252,14 @@ int pm_clk_resume(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); if (!pcd) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry(ce, &pcd->clock_list, node) { if (ce->status == PCE_STATUS_NONE) @@ -269,7 +271,7 @@ int pm_clk_resume(struct device *dev) } } - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } @@ -344,6 +346,7 @@ int pm_clk_suspend(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); @@ -351,12 +354,12 @@ int pm_clk_suspend(struct device *dev) if (!pcd || !dev->driver) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry_reverse(ce, &pcd->clock_list, node) clk_disable(ce->clk); - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } @@ -369,6 +372,7 @@ int pm_clk_resume(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); @@ -376,12 +380,12 @@ int pm_clk_resume(struct device *dev) if (!pcd || !dev->driver) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry(ce, &pcd->clock_list, node) clk_enable(ce->clk); - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index be8714aa9dd6..1c374579407c 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -80,7 +80,6 @@ static void genpd_set_active(struct generic_pm_domain *genpd) int pm_genpd_poweron(struct generic_pm_domain *genpd) { struct generic_pm_domain *parent = genpd->parent; - DEFINE_WAIT(wait); int ret = 0; start: @@ -112,7 +111,7 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd) } if (genpd->power_on) { - int ret = genpd->power_on(genpd); + ret = genpd->power_on(genpd); if (ret) goto out; } @@ -461,6 +460,21 @@ static int pm_genpd_runtime_resume(struct device *dev) return 0; } +/** + * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. + */ +void pm_genpd_poweroff_unused(void) +{ + struct generic_pm_domain *genpd; + + mutex_lock(&gpd_list_lock); + + list_for_each_entry(genpd, &gpd_list, gpd_list_node) + genpd_queue_power_off_work(genpd); + + mutex_unlock(&gpd_list_lock); +} + #else static inline void genpd_power_off_work_fn(struct work_struct *work) {} @@ -1256,18 +1270,3 @@ void pm_genpd_init(struct generic_pm_domain *genpd, list_add(&genpd->gpd_list_node, &gpd_list); mutex_unlock(&gpd_list_lock); } - -/** - * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. - */ -void pm_genpd_poweroff_unused(void) -{ - struct generic_pm_domain *genpd; - - mutex_lock(&gpd_list_lock); - - list_for_each_entry(genpd, &gpd_list, gpd_list_node) - genpd_queue_power_off_work(genpd); - - mutex_unlock(&gpd_list_lock); -} diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 5cc12322ef32..b23de185cb04 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -453,7 +453,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) static int opp_set_availability(struct device *dev, unsigned long freq, bool availability_req) { - struct device_opp *tmp_dev_opp, *dev_opp = NULL; + struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV); struct opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); int r = 0; diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 8dc247c974af..acb3f83b8079 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -226,11 +226,17 @@ static int rpm_idle(struct device *dev, int rpmflags) callback = NULL; if (callback) { - spin_unlock_irq(&dev->power.lock); + if (dev->power.irq_safe) + spin_unlock(&dev->power.lock); + else + spin_unlock_irq(&dev->power.lock); callback(dev); - spin_lock_irq(&dev->power.lock); + if (dev->power.irq_safe) + spin_lock(&dev->power.lock); + else + spin_lock_irq(&dev->power.lock); } dev->power.idle_notification = false; diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 942d6a7c9ae1..17b7934f31cb 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -5,7 +5,7 @@ #include <linux/device.h> #include <linux/string.h> #include <linux/pm_runtime.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/jiffies.h> #include "power.h" |