diff options
Diffstat (limited to 'drivers/base/power/runtime.c')
| -rw-r--r-- | drivers/base/power/runtime.c | 37 | 
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 38556f6cc22..5a01ecef4af 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -51,8 +51,6 @@ static int __pm_runtime_idle(struct device *dev)  {  	int retval = 0; -	dev_dbg(dev, "__pm_runtime_idle()!\n"); -  	if (dev->power.runtime_error)  		retval = -EINVAL;  	else if (dev->power.idle_notification) @@ -93,8 +91,6 @@ static int __pm_runtime_idle(struct device *dev)  	wake_up_all(&dev->power.wait_queue);   out: -	dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval); -  	return retval;  } @@ -189,6 +185,7 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)  	}  	dev->power.runtime_status = RPM_SUSPENDING; +	dev->power.deferred_resume = false;  	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) {  		spin_unlock_irq(&dev->power.lock); @@ -204,7 +201,6 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)  	if (retval) {  		dev->power.runtime_status = RPM_ACTIVE;  		pm_runtime_cancel_pending(dev); -		dev->power.deferred_resume = false;  		if (retval == -EAGAIN || retval == -EBUSY) {  			notify = true; @@ -221,7 +217,6 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)  	wake_up_all(&dev->power.wait_queue);  	if (dev->power.deferred_resume) { -		dev->power.deferred_resume = false;  		__pm_runtime_resume(dev, false);  		retval = -EAGAIN;  		goto out; @@ -332,11 +327,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)  		 * necessary.  		 */  		parent = dev->parent; -		spin_unlock_irq(&dev->power.lock); +		spin_unlock(&dev->power.lock);  		pm_runtime_get_noresume(parent); -		spin_lock_irq(&parent->power.lock); +		spin_lock(&parent->power.lock);  		/*  		 * We can resume if the parent's run-time PM is disabled or it  		 * is set to ignore children. @@ -347,9 +342,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)  			if (parent->power.runtime_status != RPM_ACTIVE)  				retval = -EBUSY;  		} -		spin_unlock_irq(&parent->power.lock); +		spin_unlock(&parent->power.lock); -		spin_lock_irq(&dev->power.lock); +		spin_lock(&dev->power.lock);  		if (retval)  			goto out;  		goto repeat; @@ -630,6 +625,8 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)  		goto out;  	dev->power.timer_expires = jiffies + msecs_to_jiffies(delay); +	if (!dev->power.timer_expires) +		dev->power.timer_expires = 1;  	mod_timer(&dev->power.suspend_timer, dev->power.timer_expires);   out: @@ -663,13 +660,17 @@ static int __pm_request_resume(struct device *dev)  	pm_runtime_deactivate_timer(dev); +	if (dev->power.runtime_status == RPM_SUSPENDING) { +		dev->power.deferred_resume = true; +		return retval; +	}  	if (dev->power.request_pending) {  		/* If non-resume request is pending, we can overtake it. */  		dev->power.request = retval ? RPM_REQ_NONE : RPM_REQ_RESUME;  		return retval; -	} else if (retval) { -		return retval;  	} +	if (retval) +		return retval;  	dev->power.request = RPM_REQ_RESUME;  	dev->power.request_pending = true; @@ -781,7 +782,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)  	}  	if (parent) { -		spin_lock_irq(&parent->power.lock); +		spin_lock_nested(&parent->power.lock, SINGLE_DEPTH_NESTING);  		/*  		 * It is invalid to put an active child under a parent that is @@ -790,14 +791,12 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)  		 */  		if (!parent->power.disable_depth  		    && !parent->power.ignore_children -		    && parent->power.runtime_status != RPM_ACTIVE) { +		    && parent->power.runtime_status != RPM_ACTIVE)  			error = -EBUSY; -		} else { -			if (dev->power.runtime_status == RPM_SUSPENDED) -				atomic_inc(&parent->power.child_count); -		} +		else if (dev->power.runtime_status == RPM_SUSPENDED) +			atomic_inc(&parent->power.child_count); -		spin_unlock_irq(&parent->power.lock); +		spin_unlock(&parent->power.lock);  		if (error)  			goto out;  |