linux/drivers/base/power/runtime.c
David Brownell 979d5199fe [PATCH] root hub changes (lesser half)
This patch collects various small updates related to root hubs, to shrink
later patches which build on them.

  - For root hub suspend/resume support:
     * Make the existing usb_hcd_resume_root_hub() routine respect pmcore
       locking, exporting and using the dpm_runtime_resume() method.
     * Add a new usb_hcd_suspend_root_hub() to pair with that routine.
       (Essential to make OHCI autosuspend behave again...)
     * HC_SUSPENDED by itself only refers to the root hub's downstream ports.
       So let HCDs see root hub URBs unless the parent device is suspended.

  - Remove an assertion we no longer need (and now, also don't want).

  - Generic suspend/resume updates to work better with swsusp.
     * Ignore the FREEZE vs SUSPEND distinction for hardware; trying to
       use it breaks the swsusp snapshots it's supposed to help (sigh).
     * On resume, mark devices as resumed right away, but then
       do nothing else if the device is marked NOTATTACHED.

These changes shouldn't be very noticable by themselves.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

 drivers/base/power/runtime.c |    1
 drivers/usb/core/hcd.c       |   64 ++++++++++++++++++++++++++++++++++++++-----
 drivers/usb/core/hcd.h       |    1
 drivers/usb/core/hub.c       |   45 ++++++++++++++++++++++++------
 drivers/usb/core/usb.c       |   20 +++++++++----
 drivers/usb/core/usb.h       |    1
 6 files changed, 111 insertions(+), 21 deletions(-)
2005-10-28 16:47:40 -07:00

83 lines
1.7 KiB
C

/*
* drivers/base/power/runtime.c - Handling dynamic device power management.
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
*
*/
#include <linux/device.h>
#include "power.h"
static void runtime_resume(struct device * dev)
{
dev_dbg(dev, "resuming\n");
if (!dev->power.power_state.event)
return;
if (!resume_device(dev))
dev->power.power_state = PMSG_ON;
}
/**
* dpm_runtime_resume - Power one device back on.
* @dev: Device.
*
* Bring one device back to the on state by first powering it
* on, then restoring state. We only operate on devices that aren't
* already on.
* FIXME: We need to handle devices that are in an unknown state.
*/
void dpm_runtime_resume(struct device * dev)
{
down(&dpm_sem);
runtime_resume(dev);
up(&dpm_sem);
}
EXPORT_SYMBOL(dpm_runtime_resume);
/**
* dpm_runtime_suspend - Put one device in low-power state.
* @dev: Device.
* @state: State to enter.
*/
int dpm_runtime_suspend(struct device * dev, pm_message_t state)
{
int error = 0;
down(&dpm_sem);
if (dev->power.power_state.event == state.event)
goto Done;
if (dev->power.power_state.event)
runtime_resume(dev);
if (!(error = suspend_device(dev, state)))
dev->power.power_state = state;
Done:
up(&dpm_sem);
return error;
}
/**
* dpm_set_power_state - Update power_state field.
* @dev: Device.
* @state: Power state device is in.
*
* This is an update mechanism for drivers to notify the core
* what power state a device is in. Device probing code may not
* always be able to tell, but we need accurate information to
* work reliably.
*/
void dpm_set_power_state(struct device * dev, pm_message_t state)
{
down(&dpm_sem);
dev->power.power_state = state;
up(&dpm_sem);
}