===================================================================
@@ -17,11 +17,6 @@
#ifdef CONFIG_PM
-struct pm_clk_data {
- struct list_head clock_list;
- struct mutex lock;
-};
-
enum pce_status {
PCE_STATUS_NONE = 0,
PCE_STATUS_ACQUIRED,
@@ -36,11 +31,6 @@ struct pm_clock_entry {
enum pce_status status;
};
-static struct pm_clk_data *__to_pcd(struct device *dev)
-{
- return dev ? dev->power.subsys_data : NULL;
-}
-
/**
* pm_clk_add - Start using a device clock for power management.
* @dev: Device whose clock is going to be used for power management.
@@ -51,10 +41,10 @@ static struct pm_clk_data *__to_pcd(stru
*/
int pm_clk_add(struct device *dev, const char *con_id)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce;
- if (!pcd)
+ if (!psd)
return -EINVAL;
ce = kzalloc(sizeof(*ce), GFP_KERNEL);
@@ -73,9 +63,9 @@ int pm_clk_add(struct device *dev, const
}
}
- mutex_lock(&pcd->lock);
- list_add_tail(&ce->node, &pcd->clock_list);
- mutex_unlock(&pcd->lock);
+ mutex_lock(&psd->lock);
+ list_add_tail(&ce->node, &psd->clock_list);
+ mutex_unlock(&psd->lock);
return 0;
}
@@ -117,15 +107,15 @@ static void __pm_clk_remove(struct pm_cl
*/
void pm_clk_remove(struct device *dev, const char *con_id)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce;
- if (!pcd)
+ if (!psd)
return;
- mutex_lock(&pcd->lock);
+ mutex_lock(&psd->lock);
- list_for_each_entry(ce, &pcd->clock_list, node) {
+ list_for_each_entry(ce, &psd->clock_list, node) {
if (!con_id && !ce->con_id) {
__pm_clk_remove(ce);
break;
@@ -137,29 +127,45 @@ void pm_clk_remove(struct device *dev, c
}
}
- mutex_unlock(&pcd->lock);
+ mutex_unlock(&psd->lock);
}
/**
* pm_clk_init - Initialize a device's list of power management clocks.
* @dev: Device to initialize the list of PM clocks for.
*
- * Allocate a struct pm_clk_data object, initialize its lock member and
- * make the @dev's power.subsys_data field point to it.
+ * Initialize the lock and clock_list members of the device's pm_subsys_data
+ * object.
*/
-int pm_clk_init(struct device *dev)
+void pm_clk_init(struct device *dev)
{
- struct pm_clk_data *pcd;
+ struct pm_subsys_data *psd = dev_to_psd(dev);
+
+ if (!psd)
+ return;
- pcd = kzalloc(sizeof(*pcd), GFP_KERNEL);
- if (!pcd) {
+ INIT_LIST_HEAD(&psd->clock_list);
+ mutex_init(&psd->lock);
+}
+
+/**
+ * pm_clk_create - Create and initialize a device's list of PM clocks.
+ * @dev: Device to create and initialize the list of PM clocks for.
+ *
+ * Allocate a struct pm_subsys_data object, initialize its lock and clock_list
+ * members and make the @dev's power.subsys_data field point to it.
+ */
+int pm_clk_create(struct device *dev)
+{
+ struct pm_subsys_data *psd;
+
+ psd = kzalloc(sizeof(*psd), GFP_KERNEL);
+ if (!psd) {
dev_err(dev, "Not enough memory for PM clock data.\n");
return -ENOMEM;
}
-
- INIT_LIST_HEAD(&pcd->clock_list);
- mutex_init(&pcd->lock);
- dev->power.subsys_data = pcd;
+ dev->power.subsys_data = psd;
+ pm_clk_init(dev);
return 0;
}
@@ -168,27 +174,27 @@ int pm_clk_init(struct device *dev)
* @dev: Device to destroy the list of PM clocks for.
*
* Clear the @dev's power.subsys_data field, remove the list of clock entries
- * from the struct pm_clk_data object pointed to by it before and free
+ * from the struct pm_subsys_data object pointed to by it before and free
* that object.
*/
void pm_clk_destroy(struct device *dev)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce, *c;
- if (!pcd)
+ if (!psd)
return;
dev->power.subsys_data = NULL;
- mutex_lock(&pcd->lock);
+ mutex_lock(&psd->lock);
- list_for_each_entry_safe_reverse(ce, c, &pcd->clock_list, node)
+ list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node)
__pm_clk_remove(ce);
- mutex_unlock(&pcd->lock);
+ mutex_unlock(&psd->lock);
- kfree(pcd);
+ kfree(psd);
}
#endif /* CONFIG_PM */
@@ -218,17 +224,17 @@ static void pm_clk_acquire(struct device
*/
int pm_clk_suspend(struct device *dev)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce;
dev_dbg(dev, "%s()\n", __func__);
- if (!pcd)
+ if (!psd)
return 0;
- mutex_lock(&pcd->lock);
+ mutex_lock(&psd->lock);
- list_for_each_entry_reverse(ce, &pcd->clock_list, node) {
+ list_for_each_entry_reverse(ce, &psd->clock_list, node) {
if (ce->status == PCE_STATUS_NONE)
pm_clk_acquire(dev, ce);
@@ -238,7 +244,7 @@ int pm_clk_suspend(struct device *dev)
}
}
- mutex_unlock(&pcd->lock);
+ mutex_unlock(&psd->lock);
return 0;
}
@@ -249,17 +255,17 @@ int pm_clk_suspend(struct device *dev)
*/
int pm_clk_resume(struct device *dev)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce;
dev_dbg(dev, "%s()\n", __func__);
- if (!pcd)
+ if (!psd)
return 0;
- mutex_lock(&pcd->lock);
+ mutex_lock(&psd->lock);
- list_for_each_entry(ce, &pcd->clock_list, node) {
+ list_for_each_entry(ce, &psd->clock_list, node) {
if (ce->status == PCE_STATUS_NONE)
pm_clk_acquire(dev, ce);
@@ -269,7 +275,7 @@ int pm_clk_resume(struct device *dev)
}
}
- mutex_unlock(&pcd->lock);
+ mutex_unlock(&psd->lock);
return 0;
}
@@ -307,7 +313,7 @@ static int pm_clk_notify(struct notifier
if (dev->pm_domain)
break;
- error = pm_clk_init(dev);
+ error = pm_clk_create(dev);
if (error)
break;
@@ -342,21 +348,21 @@ static int pm_clk_notify(struct notifier
*/
int pm_clk_suspend(struct device *dev)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce;
dev_dbg(dev, "%s()\n", __func__);
/* If there is no driver, the clocks are already disabled. */
- if (!pcd || !dev->driver)
+ if (!psd || !dev->driver)
return 0;
- mutex_lock(&pcd->lock);
+ mutex_lock(&psd->lock);
- list_for_each_entry_reverse(ce, &pcd->clock_list, node)
+ list_for_each_entry_reverse(ce, &psd->clock_list, node)
clk_disable(ce->clk);
- mutex_unlock(&pcd->lock);
+ mutex_unlock(&psd->lock);
return 0;
}
@@ -367,21 +373,21 @@ int pm_clk_suspend(struct device *dev)
*/
int pm_clk_resume(struct device *dev)
{
- struct pm_clk_data *pcd = __to_pcd(dev);
+ struct pm_subsys_data *psd = dev_to_psd(dev);
struct pm_clock_entry *ce;
dev_dbg(dev, "%s()\n", __func__);
/* If there is no driver, the clocks should remain disabled. */
- if (!pcd || !dev->driver)
+ if (!psd || !dev->driver)
return 0;
- mutex_lock(&pcd->lock);
+ mutex_lock(&psd->lock);
- list_for_each_entry(ce, &pcd->clock_list, node)
+ list_for_each_entry(ce, &psd->clock_list, node)
clk_enable(ce->clk);
- mutex_unlock(&pcd->lock);
+ mutex_unlock(&psd->lock);
return 0;
}
===================================================================
@@ -636,6 +636,11 @@ static inline void set_dev_node(struct d
}
#endif
+static inline struct pm_subsys_data *dev_to_psd(struct device *dev)
+{
+ return dev ? dev->power.subsys_data : NULL;
+}
+
static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
{
return dev->kobj.uevent_suppress;
===================================================================
@@ -24,6 +24,7 @@
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/completion.h>
@@ -421,6 +422,13 @@ enum rpm_request {
struct wakeup_source;
+struct pm_subsys_data {
+ struct mutex lock;
+#ifdef CONFIG_PM_CLK
+ struct list_head clock_list;
+#endif
+};
+
struct dev_pm_info {
pm_message_t power_state;
unsigned int can_wakeup:1;
@@ -462,7 +470,7 @@ struct dev_pm_info {
unsigned long suspended_jiffies;
unsigned long accounting_timestamp;
#endif
- void *subsys_data; /* Owned by the subsystem. */
+ struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */
};
extern void update_pm_runtime_accounting(struct device *dev);
===================================================================
@@ -115,7 +115,7 @@ void sh7372_add_device_to_domain(struct
struct device *dev = &pdev->dev;
if (!dev->power.subsys_data) {
- pm_clk_init(dev);
+ pm_clk_create(dev);
pm_clk_add(dev, NULL);
}
pm_genpd_add_device(&sh7372_pd->genpd, dev);
===================================================================
@@ -258,14 +258,18 @@ struct pm_clk_notifier_block {
};
#ifdef CONFIG_PM_CLK
-extern int pm_clk_init(struct device *dev);
+extern void pm_clk_init(struct device *dev);
+extern int pm_clk_create(struct device *dev);
extern void pm_clk_destroy(struct device *dev);
extern int pm_clk_add(struct device *dev, const char *con_id);
extern void pm_clk_remove(struct device *dev, const char *con_id);
extern int pm_clk_suspend(struct device *dev);
extern int pm_clk_resume(struct device *dev);
#else
-static inline int pm_clk_init(struct device *dev)
+static inline void pm_clk_init(struct device *dev)
+{
+}
+static inline int pm_clk_create(struct device *dev)
{
return -EINVAL;
}