Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bed2b42d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

PM / Runtime: Allow helpers to be called by early platform drivers



Runtime PM helper functions, like pm_runtime_get_sync(), cannot be
called by early platform device drivers, because the devices' power
management locks are not initialized at that time.  This is quite
inconvenient, so modify early_platform_add_devices() to initialize
the devices power management locks as appropriate and make sure that
they won't be initialized more than once if an early platform
device is going to be used as a regular one later.

Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
parent e91c11b1
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>


#include "base.h"
#include "base.h"
#include "power/power.h"


#define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
#define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
				 driver))
				 driver))
@@ -948,6 +949,7 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
		dev = &devs[i]->dev;
		dev = &devs[i]->dev;


		if (!dev->devres_head.next) {
		if (!dev->devres_head.next) {
			pm_runtime_early_init(dev);
			INIT_LIST_HEAD(&dev->devres_head);
			INIT_LIST_HEAD(&dev->devres_head);
			list_add_tail(&dev->devres_head,
			list_add_tail(&dev->devres_head,
				      &early_platform_device_list);
				      &early_platform_device_list);
+16 −2
Original line number Original line Diff line number Diff line
@@ -2,17 +2,31 @@


static inline void device_pm_init_common(struct device *dev)
static inline void device_pm_init_common(struct device *dev)
{
{
	if (!dev->power.early_init) {
		spin_lock_init(&dev->power.lock);
		spin_lock_init(&dev->power.lock);
		dev->power.power_state = PMSG_INVALID;
		dev->power.power_state = PMSG_INVALID;
		dev->power.early_init = true;
	}
}
}


#ifdef CONFIG_PM_RUNTIME
#ifdef CONFIG_PM_RUNTIME


static inline void pm_runtime_early_init(struct device *dev)
{
	dev->power.disable_depth = 1;
	device_pm_init_common(dev);
}

extern void pm_runtime_init(struct device *dev);
extern void pm_runtime_init(struct device *dev);
extern void pm_runtime_remove(struct device *dev);
extern void pm_runtime_remove(struct device *dev);


#else /* !CONFIG_PM_RUNTIME */
#else /* !CONFIG_PM_RUNTIME */


static inline void pm_runtime_early_init(struct device *dev)
{
	device_pm_init_common(dev);
}

static inline void pm_runtime_init(struct device *dev) {}
static inline void pm_runtime_init(struct device *dev) {}
static inline void pm_runtime_remove(struct device *dev) {}
static inline void pm_runtime_remove(struct device *dev) {}


+1 −0
Original line number Original line Diff line number Diff line
@@ -510,6 +510,7 @@ struct dev_pm_info {
	bool			is_prepared:1;	/* Owned by the PM core */
	bool			is_prepared:1;	/* Owned by the PM core */
	bool			is_suspended:1;	/* Ditto */
	bool			is_suspended:1;	/* Ditto */
	bool			ignore_children:1;
	bool			ignore_children:1;
	bool			early_init:1;	/* Owned by the PM core */
	spinlock_t		lock;
	spinlock_t		lock;
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM_SLEEP
	struct list_head	entry;
	struct list_head	entry;