summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig2
-rw-r--r--drivers/acpi/sleep/main.c318
-rw-r--r--drivers/acpi/sleep/proc.c82
-rw-r--r--drivers/base/power/main.c2
-rw-r--r--drivers/base/power/power.h4
-rw-r--r--drivers/base/power/resume.c101
-rw-r--r--drivers/base/power/runtime.c12
-rw-r--r--drivers/base/power/suspend.c171
-rw-r--r--drivers/base/sys.c111
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/ide/ide-cd.c4
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide.c16
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c1
-rw-r--r--drivers/oprofile/buffer_sync.c4
-rw-r--r--drivers/oprofile/oprofile_files.c14
-rw-r--r--drivers/oprofile/oprofile_stats.c3
-rw-r--r--drivers/oprofile/oprofile_stats.h1
-rw-r--r--drivers/oprofile/oprofilefs.c12
-rw-r--r--drivers/pci/pci-driver.c31
20 files changed, 203 insertions, 692 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 99b9fa1f80e1..d9e1a83ab8ef 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -30,7 +30,7 @@ config ACPI
bool "Full ACPI Support"
depends on !X86_VISWS
depends on !IA64_HP_SIM
- depends on IA64 || (X86 && ACPI_HT)
+ depends on IA64 || (X86 || ACPI_HT)
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index ba7294275354..d3f29ce924ae 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -1,11 +1,11 @@
/*
* sleep.c - ACPI sleep support.
- *
- * Copyright (c) 2000-2003 Patrick Mochel
*
- * Portions are
- * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (c) 2000-2003 Patrick Mochel
+ * Copyright (c) 2003 Open Source Development Lab
+ *
+ * This file is released under the GPLv2.
+ *
*/
#include <linux/delay.h>
@@ -16,274 +16,151 @@
#include <acpi/acpi_drivers.h>
#include "sleep.h"
-#define _COMPONENT ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME ("sleep")
-
u8 sleep_states[ACPI_S_STATE_COUNT];
+static struct pm_ops acpi_pm_ops;
+
extern void do_suspend_lowlevel_s4bios(int);
extern void do_suspend_lowlevel(int);
-/**
- * acpi_system_restore_state - OS-specific restoration of state
- * @state: sleep state we're exiting
- *
- * Note that if we're coming back from S4, the memory image should have already
- * been loaded from the disk and is already in place. (Otherwise how else would we
- * be here?).
- */
-acpi_status
-acpi_system_restore_state (
- u32 state)
-{
- /* restore processor state
- * We should only be here if we're coming back from STR or STD.
- * And, in the case of the latter, the memory image should have already
- * been loaded from disk.
- */
- if (state > ACPI_STATE_S1)
- acpi_restore_state_mem();
-
- /* wait for power to come back */
- mdelay(10);
-
- /* turn all the devices back on */
- device_resume(RESUME_POWER_ON);
-
- /* enable interrupts once again */
- ACPI_ENABLE_IRQS();
-
- /* restore device context */
- device_resume(RESUME_RESTORE_STATE);
-
- if (dmi_broken & BROKEN_INIT_AFTER_S1) {
- printk("Broken toshiba laptop -> kicking interrupts\n");
- init_8259A(0);
- }
-
- return AE_OK;
-}
+static u32 acpi_suspend_states[] = {
+ [PM_SUSPEND_ON] = ACPI_STATE_S0,
+ [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
+ [PM_SUSPEND_MEM] = ACPI_STATE_S3,
+ [PM_SUSPEND_DISK] = ACPI_STATE_S4,
+};
/**
- * acpi_system_save_state - save OS specific state and power down devices
- * @state: sleep state we're entering.
+ * acpi_pm_prepare - Do preliminary suspend work.
+ * @state: suspend state we're entering.
*
- * This handles saving all context to memory, and possibly disk.
- * First, we call to the device driver layer to save device state.
- * Once we have that, we save whatevery processor and kernel state we
- * need to memory.
+ * Make sure we support the state. If we do, and we need it, set the
+ * firmware waking vector and do arch-specific nastiness to get the
+ * wakeup code to the waking vector.
*/
-acpi_status
-acpi_system_save_state(
- u32 state)
-{
- int error = 0;
- /* Send notification to devices that they will be suspended.
- * If any device or driver cannot make the transition, either up
- * or down, we'll get an error back.
- */
- error = device_suspend(state, SUSPEND_NOTIFY);
- if (error)
- return AE_ERROR;
-
- if (state < ACPI_STATE_S5) {
-
- /* Tell devices to stop I/O and actually save their state.
- * It is theoretically possible that something could fail,
- * so handle that gracefully..
- */
- error = device_suspend(state, SUSPEND_SAVE_STATE);
- if (error) {
- /* tell devices to restore state if they have
- * it saved and to start taking I/O requests.
- */
- device_resume(RESUME_RESTORE_STATE);
- return error;
- }
-
- /* flush caches */
- ACPI_FLUSH_CPU_CACHE();
-
- /* Do arch specific saving of state. */
- if (state > ACPI_STATE_S1) {
- error = acpi_save_state_mem();
+static int acpi_pm_prepare(u32 state)
+{
+ int error = 0;
+ u32 acpi_state = acpi_suspend_states[state];
- if (!error && (state == ACPI_STATE_S4))
- error = acpi_save_state_disk();
+ if (!sleep_states[acpi_state])
+ return -EPERM;
- if (error) {
- device_resume(RESUME_RESTORE_STATE);
- return error;
- }
- }
+ /* do we have a wakeup address for S2 and S3? */
+ /* Here, we support only S4BIOS, those we set the wakeup address */
+ /* S4OS is only supported for now via swsusp.. */
+ if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_DISK) {
+ if (!acpi_wakeup_address)
+ return -EFAULT;
+ acpi_set_firmware_waking_vector(
+ (acpi_physical_address) acpi_wakeup_address);
}
- /* disable interrupts
- * Note that acpi_suspend -- our caller -- will do this once we return.
- * But, we want it done early, so we don't get any suprises during
- * the device suspend sequence.
- */
- ACPI_DISABLE_IRQS();
+ ACPI_FLUSH_CPU_CACHE();
- /* Unconditionally turn off devices.
- * Obvious if we enter a sleep state.
- * If entering S5 (soft off), this should put devices in a
- * quiescent state.
- */
- error = device_suspend(state, SUSPEND_POWER_DOWN);
+ /* Do arch specific saving of state. */
+ if (state > PM_SUSPEND_STANDBY) {
+ if ((error = acpi_save_state_mem()))
+ goto Err;
+ }
- /* We're pretty screwed if we got an error from this.
- * We try to recover by simply calling our own restore_state
- * function; see above for definition.
- *
- * If it's S5 though, go through with it anyway..
- */
- if (error && state != ACPI_STATE_S5)
- acpi_system_restore_state(state);
+ acpi_enter_sleep_state_prep(acpi_state);
- return error ? AE_ERROR : AE_OK;
+ return 0;
+ Err:
+ acpi_set_firmware_waking_vector(0);
+ return error;
}
-/****************************************************************************
- *
- * FUNCTION: acpi_system_suspend
- *
- * PARAMETERS: %state: Sleep state to enter.
- *
- * RETURN: acpi_status, whether or not we successfully entered and
- * exited sleep.
- *
- * DESCRIPTION: Perform OS-specific action to enter sleep state.
- * This is the final step in going to sleep, per spec. If we
- * know we're coming back (i.e. not entering S5), we save the
- * processor flags. [ We'll have to save and restore them anyway,
- * so we use the arch-agnostic save_flags and restore_flags
- * here.] We then set the place to return to in arch-specific
- * globals using arch_set_return_point. Finally, we call the
- * ACPI function to write the proper values to I/O ports.
+/**
+ * acpi_pm_enter - Actually enter a sleep state.
+ * @state: State we're entering.
*
- ****************************************************************************/
+ * Flush caches and go to sleep. For STR or STD, we have to call
+ * arch-specific assembly, which in turn call acpi_enter_sleep_state().
+ * It's unfortunate, but it works. Please fix if you're feeling frisky.
+ */
-acpi_status
-acpi_system_suspend(
- u32 state)
+static int acpi_pm_enter(u32 state)
{
- acpi_status status = AE_ERROR;
- unsigned long flags = 0;
+ acpi_status status = AE_OK;
+ unsigned long flags = 0;
+ u32 acpi_state = acpi_suspend_states[state];
+ ACPI_FLUSH_CPU_CACHE();
local_irq_save(flags);
-
switch (state)
{
- case ACPI_STATE_S1:
+ case PM_SUSPEND_STANDBY:
barrier();
- status = acpi_enter_sleep_state(state);
+ status = acpi_enter_sleep_state(acpi_state);
break;
- case ACPI_STATE_S2:
- case ACPI_STATE_S3:
+ case PM_SUSPEND_MEM:
do_suspend_lowlevel(0);
break;
- case ACPI_STATE_S4:
- do_suspend_lowlevel_s4bios(0);
+ case PM_SUSPEND_DISK:
+ if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM)
+ status = acpi_enter_sleep_state(acpi_state);
+ else
+ do_suspend_lowlevel_s4bios(0);
break;
default:
- printk(KERN_WARNING PREFIX "don't know how to handle %d state.\n", state);
- break;
+ return -EINVAL;
}
local_irq_restore(flags);
printk(KERN_DEBUG "Back to C!\n");
- return status;
+ return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
/**
- * acpi_suspend - OS-agnostic system suspend/resume support (S? states)
- * @state: state we're entering
+ * acpi_pm_finish - Finish up suspend sequence.
+ * @state: State we're coming out of.
*
+ * This is called after we wake back up (or if entering the sleep state
+ * failed).
*/
-acpi_status
-acpi_suspend (
- u32 state)
-{
- acpi_status status;
-
- /* Suspend is hard to get right on SMP. */
- if (num_online_cpus() != 1)
- return AE_ERROR;
-
- /* get out if state is invalid */
- if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
- return AE_ERROR;
-
- /* Since we handle S4OS via a different path (swsusp), give up if no s4bios. */
- if (state == ACPI_STATE_S4 && !acpi_gbl_FACS->S4bios_f)
- return AE_ERROR;
-
- pm_prepare_console();
-
- /*
- * TBD: S1 can be done without device_suspend. Make a CONFIG_XX
- * to handle however when S1 failed without device_suspend.
- */
- if (freeze_processes()) {
- status = AE_ERROR;
- goto Done;
- }
-
- /* do we have a wakeup address for S2 and S3? */
- /* Here, we support only S4BIOS, those we set the wakeup address */
- /* S4OS is only supported for now via swsusp.. */
- if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3 || state == ACPI_STATE_S4) {
- if (!acpi_wakeup_address)
- return AE_ERROR;
- acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
- }
-
- status = acpi_system_save_state(state);
- if (!ACPI_SUCCESS(status))
- return status;
- acpi_enter_sleep_state_prep(state);
-
- /* disable interrupts and flush caches */
- ACPI_DISABLE_IRQS();
- ACPI_FLUSH_CPU_CACHE();
-
- /* perform OS-specific sleep actions */
- status = acpi_system_suspend(state);
-
- /* Even if we failed to go to sleep, all of the devices are in an suspended
- * mode. So, we run these unconditionaly to make sure we have a usable system
- * no matter what.
- */
+static int acpi_pm_finish(u32 state)
+{
acpi_leave_sleep_state(state);
- acpi_system_restore_state(state);
- /* make sure interrupts are enabled */
- ACPI_ENABLE_IRQS();
+ /* restore processor state
+ * We should only be here if we're coming back from STR or STD.
+ * And, in the case of the latter, the memory image should have already
+ * been loaded from disk.
+ */
+ if (state > ACPI_STATE_S1)
+ acpi_restore_state_mem();
/* reset firmware waking vector */
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
- Done:
- thaw_processes();
- pm_restore_console();
- return status;
+ if (dmi_broken & BROKEN_INIT_AFTER_S1) {
+ printk("Broken toshiba laptop -> kicking interrupts\n");
+ init_8259A(0);
+ }
+ return 0;
}
+
+static struct pm_ops acpi_pm_ops = {
+ .prepare = acpi_pm_prepare,
+ .enter = acpi_pm_enter,
+ .finish = acpi_pm_finish,
+};
+
static int __init acpi_sleep_init(void)
{
int i = 0;
- ACPI_FUNCTION_TRACE("acpi_system_add_fs");
-
if (acpi_disabled)
- return_VALUE(0);
+ return 0;
printk(KERN_INFO PREFIX "(supports");
for (i=0; i<ACPI_S_STATE_COUNT; i++) {
@@ -294,14 +171,19 @@ static int __init acpi_sleep_init(void)
sleep_states[i] = 1;
printk(" S%d", i);
}
- if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f) {
- sleep_states[i] = 1;
- printk(" S4bios");
+ if (i == ACPI_STATE_S4) {
+ if (acpi_gbl_FACS->S4bios_f) {
+ sleep_states[i] = 1;
+ printk(" S4bios");
+ acpi_pm_ops.pm_disk_mode = PM_DISK_FIRMWARE;
+ } else if (sleep_states[i])
+ acpi_pm_ops.pm_disk_mode = PM_DISK_PLATFORM;
}
}
printk(")\n");
- return_VALUE(0);
+ pm_set_ops(&acpi_pm_ops);
+ return 0;
}
late_initcall(acpi_sleep_init);
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 50f0bdfd0992..41cbde00b785 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -13,80 +13,12 @@
#include "sleep.h"
-#define ACPI_SYSTEM_FILE_SLEEP "sleep"
#define ACPI_SYSTEM_FILE_ALARM "alarm"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("sleep")
-static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
-{
- int i;
-
- ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
-
- for (i = 0; i <= ACPI_STATE_S5; i++) {
- if (sleep_states[i]) {
- seq_printf(seq,"S%d ", i);
- if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
- seq_printf(seq, "S4bios ");
- }
- }
-
- seq_puts(seq, "\n");
-
- return 0;
-}
-
-static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
-}
-
-static int
-acpi_system_write_sleep (
- struct file *file,
- const char *buffer,
- size_t count,
- loff_t *ppos)
-{
- acpi_status status = AE_ERROR;
- char state_string[12] = {'\0'};
- u32 state = 0;
-
- ACPI_FUNCTION_TRACE("acpi_system_write_sleep");
-
- if (count > sizeof(state_string) - 1)
- goto Done;
-
- if (copy_from_user(state_string, buffer, count))
- return_VALUE(-EFAULT);
-
- state_string[count] = '\0';
-
- state = simple_strtoul(state_string, NULL, 0);
-
- if (state < 1 || state > 4)
- goto Done;
-
- if (!sleep_states[state])
- goto Done;
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
- if (state == 4) {
- software_suspend();
- goto Done;
- }
-#endif
- status = acpi_suspend(state);
- Done:
- if (ACPI_FAILURE(status))
- return_VALUE(-EINVAL);
- else
- return_VALUE(count);
-}
-
static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{
u32 sec, min, hr;
@@ -362,14 +294,6 @@ end:
}
-static struct file_operations acpi_system_sleep_fops = {
- .open = acpi_system_sleep_open_fs,
- .read = seq_read,
- .write = acpi_system_write_sleep,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static struct file_operations acpi_system_alarm_fops = {
.open = acpi_system_alarm_open_fs,
.read = seq_read,
@@ -383,12 +307,6 @@ static int acpi_sleep_proc_init(void)
{
struct proc_dir_entry *entry = NULL;
- /* 'sleep' [R/W]*/
- entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
- S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
- if (entry)
- entry->proc_fops = &acpi_system_sleep_fops;
-
/* 'alarm' [R/W] */
entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 6f53840c6b39..611a69accdd0 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -25,7 +25,6 @@
#include "power.h"
LIST_HEAD(dpm_active);
-LIST_HEAD(dpm_suspended);
LIST_HEAD(dpm_off);
LIST_HEAD(dpm_off_irq);
@@ -76,6 +75,7 @@ int device_pm_add(struct device * dev)
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+ atomic_set(&dev->power.pm_users,0);
down(&dpm_sem);
list_add_tail(&dev->power.entry,&dpm_active);
device_pm_set_parent(dev,dev->parent);
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 8130b04ffe5f..fde72b37f938 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -31,7 +31,6 @@ extern struct semaphore dpm_sem;
* The PM lists.
*/
extern struct list_head dpm_active;
-extern struct list_head dpm_suspended;
extern struct list_head dpm_off;
extern struct list_head dpm_off_irq;
@@ -61,15 +60,12 @@ extern void dpm_sysfs_remove(struct device *);
*/
extern int dpm_resume(void);
extern void dpm_power_up(void);
-extern void dpm_power_up_irq(void);
-extern void power_up_device(struct device *);
extern int resume_device(struct device *);
/*
* suspend.c
*/
extern int suspend_device(struct device *, u32);
-extern int power_down_device(struct device *, u32);
/*
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 6c8653205128..9db84a9e41e3 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -12,7 +12,6 @@
#include "power.h"
extern int sysdev_resume(void);
-extern int sysdev_restore(void);
/**
@@ -23,59 +22,33 @@ extern int sysdev_restore(void);
int resume_device(struct device * dev)
{
- struct device_driver * drv = dev->driver;
-
- if (drv && drv->resume)
- return drv->resume(dev,RESUME_RESTORE_STATE);
+ if (dev->bus && dev->bus->resume)
+ return dev->bus->resume(dev);
return 0;
}
+
/**
- * dpm_resume - Restore all device state.
+ * device_resume - Restore state of each device in system.
*
- * Walk the dpm_suspended list and restore each device. As they are
- * resumed, move the devices to the dpm_active list.
+ * Walk the dpm_off list, remove each entry, resume the device,
+ * then add it to the dpm_active list.
*/
-int dpm_resume(void)
+void device_resume(void)
{
- while(!list_empty(&dpm_suspended)) {
- struct list_head * entry = dpm_suspended.next;
+ down(&dpm_sem);
+ while(!list_empty(&dpm_off)) {
+ struct list_head * entry = dpm_off.next;
struct device * dev = to_device(entry);
list_del_init(entry);
resume_device(dev);
list_add_tail(entry,&dpm_active);
}
- return 0;
-}
-
-
-/**
- * device_pm_resume - Restore state of each device in system.
- *
- * Restore system device state, then common device state. Finally,
- * release dpm_sem, as we're done with device PM.
- */
-
-void device_pm_resume(void)
-{
- sysdev_restore();
- dpm_resume();
up(&dpm_sem);
}
-
-/**
- * power_up_device - Power one device on.
- * @dev: Device.
- */
-
-void power_up_device(struct device * dev)
-{
- struct device_driver * drv = dev->driver;
- if (drv && drv->resume)
- drv->resume(dev,RESUME_POWER_ON);
-}
+EXPORT_SYMBOL(device_resume);
/**
@@ -89,65 +62,31 @@ void power_up_device(struct device * dev)
* Interrupts must be disabled when calling this.
*/
-void dpm_power_up_irq(void)
+void dpm_power_up(void)
{
while(!list_empty(&dpm_off_irq)) {
struct list_head * entry = dpm_off_irq.next;
list_del_init(entry);
- power_up_device(to_device(entry));
- list_add_tail(entry,&dpm_suspended);
- }
-}
-
-
-/**
- * dpm_power_up - Power on most devices.
- *
- * Walk the dpm_off list and power each device up. This is used
- * to power on devices that were able to power down with interrupts
- * enabled.
- */
-
-void dpm_power_up(void)
-{
- while (!list_empty(&dpm_off)) {
- struct list_head * entry = dpm_off.next;
- list_del_init(entry);
- power_up_device(to_device(entry));
- list_add_tail(entry,&dpm_suspended);
+ resume_device(to_device(entry));
+ list_add_tail(entry,&dpm_active);
}
}
/**
- * device_pm_power_up - Turn on all devices.
+ * device_pm_power_up - Turn on all devices that need special attention.
*
- * First, power on system devices, which must happen with interrupts
- * disbled. Then, power on devices that also require interrupts disabled.
- * Turn interrupts back on, and finally power up the rest of the normal
- * devices.
+ * Power on system devices then devices that required we shut them down
+ * with interrupts disabled.
+ * Called with interrupts disabled.
*/
-void device_pm_power_up(void)
+void device_power_up(void)
{
sysdev_resume();
- dpm_power_up_irq();
- local_irq_enable();
dpm_power_up();
}
-/**
- * device_resume - resume all the devices in the system
- * @level: stage of resume process we're at
- *
- * This function is deprecated, and should be replaced with appropriate
- * calls to device_pm_power_up() and device_pm_resume() above.
- */
+EXPORT_SYMBOL(device_power_up);
-void device_resume(u32 level)
-{
- printk("%s is deprecated. Called from:\n",__FUNCTION__);
- dump_stack();
-}
-EXPORT_SYMBOL(device_resume);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 4a4ac9f7764d..05ef979a3791 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -14,8 +14,6 @@ static void runtime_resume(struct device * dev)
{
if (!dev->power.power_state)
return;
-
- power_up_device(dev);
resume_device(dev);
}
@@ -55,19 +53,11 @@ int dpm_runtime_suspend(struct device * dev, u32 state)
if (dev->power.power_state)
dpm_runtime_resume(dev);
- error = suspend_device(dev,state);
- if (!error) {
- error = power_down_device(dev,state);
- if (error)
- goto ErrResume;
+ if (!(error = suspend_device(dev,state)))
dev->power.power_state = state;
- }
Done:
up(&dpm_sem);
return error;
- ErrResume:
- resume_device(dev);
- goto Done;
}
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index cf1f6c0b7b0e..6da8cdd69dce 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -11,7 +11,6 @@
#include <linux/device.h>
#include "power.h"
-extern int sysdev_save(u32 state);
extern int sysdev_suspend(u32 state);
/*
@@ -38,41 +37,43 @@ extern int sysdev_suspend(u32 state);
int suspend_device(struct device * dev, u32 state)
{
- struct device_driver * drv = dev->driver;
int error = 0;
- if (drv && drv->suspend)
- error = drv->suspend(dev,state,SUSPEND_SAVE_STATE);
+ if (dev->bus && dev->bus->suspend)
+ error = dev->bus->suspend(dev,state);
if (!error) {
list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_suspended);
+ list_add(&dev->power.entry,&dpm_off);
+ } else if (error == -EAGAIN) {
+ list_del(&dev->power.entry);
+ list_add(&dev->power.entry,&dpm_off_irq);
}
return error;
}
/**
- * device_pm_suspend - Save state and stop all devices in system.
+ * device_suspend - Save state and stop all devices in system.
* @state: Power state to put each device in.
*
* Walk the dpm_active list, call ->suspend() for each device, and move
- * it to dpm_suspended. If we hit a failure with any of the devices, call
- * dpm_resume() above to bring the suspended devices back to life.
+ * it to dpm_off.
+ * Check the return value for each. If it returns 0, then we move the
+ * the device to the dpm_off list. If it returns -EAGAIN, we move it to
+ * the dpm_off_irq list. If we get a different error, try and back out.
*
- * Have system devices save state last.
+ * If we hit a failure with any of the devices, call device_resume()
+ * above to bring the suspended devices back to life.
*
* Note this function leaves dpm_sem held to
* a) block other devices from registering.
* b) prevent other PM operations from happening after we've begun.
* c) make sure we're exclusive when we disable interrupts.
*
- * device_pm_resume() will release dpm_sem after restoring state to
- * all devices (as will this on error). You must call it once you've
- * called device_pm_suspend().
*/
-int device_pm_suspend(u32 state)
+int device_suspend(u32 state)
{
int error = 0;
@@ -83,153 +84,45 @@ int device_pm_suspend(u32 state)
if ((error = suspend_device(dev,state)))
goto Error;
}
-
- if ((error = sysdev_save(state)))
- goto Error;
Done:
+ up(&dpm_sem);
return error;
Error:
- dpm_resume();
- up(&dpm_sem);
+ device_resume();
goto Done;
}
-
-/**
- * power_down_device - Put one device in low power state.
- * @dev: Device.
- * @state: Power state to enter.
- */
-
-int power_down_device(struct device * dev, u32 state)
-{
- struct device_driver * drv = dev->driver;
- int error = 0;
-
- if (drv && drv->suspend)
- error = drv->suspend(dev,state,SUSPEND_POWER_DOWN);
- if (!error) {
- list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off);
- }
- return error;
-}
-
-
-/**
- * dpm_power_down - Put all devices in low power state.
- * @state: Power state to enter.
- *
- * Walk the dpm_suspended list (with interrupts enabled) and try
- * to power down each each. If any fail with -EAGAIN, they require
- * the call to be done with interrupts disabled. So, we move them to
- * the dpm_off_irq list.
- *
- * If the call succeeds, we move each device to the dpm_off list.
- */
-
-static int dpm_power_down(u32 state)
-{
- while(!list_empty(&dpm_suspended)) {
- struct list_head * entry = dpm_suspended.prev;
- int error;
- error = power_down_device(to_device(entry),state);
- if (error) {
- if (error == -EAGAIN) {
- list_del(entry);
- list_add(entry,&dpm_off_irq);
- continue;
- }
- return error;
- }
- }
- return 0;
-}
+EXPORT_SYMBOL(device_suspend);
/**
- * dpm_power_down_irq - Power down devices without interrupts.
- * @state: State to enter.
+ * device_power_down - Shut down special devices.
+ * @state: Power state to enter.
*
- * Walk the dpm_off_irq list (built by dpm_power_down) and power
- * down each device that requires the call to be made with interrupts
- * disabled.
+ * Walk the dpm_off_irq list, calling ->power_down() for each device that
+ * couldn't power down the device with interrupts enabled. When we're
+ * done, power down system devices.
*/
-static int dpm_power_down_irq(u32 state)
+int device_power_down(u32 state)
{
- struct device * dev;
int error = 0;
+ struct device * dev;
list_for_each_entry_reverse(dev,&dpm_off_irq,power.entry) {
- if ((error = power_down_device(dev,state)))
+ if ((error = suspend_device(dev,state)))
break;
- }
- return error;
-}
-
-
-/**
- * device_pm_power_down - Put all devices in low power state.
- * @state: Power state to enter.
- *
- * Walk the dpm_suspended list, calling ->power_down() for each device.
- * Check the return value for each. If it returns 0, then we move the
- * the device to the dpm_off list. If it returns -EAGAIN, we move it to
- * the dpm_off_irq list. If we get a different error, try and back out.
- *
- * dpm_irq_off is for devices that require interrupts to be disabled to
- * either to power down the device or power it back on.
- *
- * When we're done, we disable interrrupts (!!) and walk the dpm_off_irq
- * list to shut down the devices that need interrupts disabled.
- *
- * This function leaves interrupts disabled on exit, since powering down
- * devices should be the very last thing before the system is put into a
- * low-power state.
- *
- * device_pm_power_on() should be called to re-enable interrupts and power
- * the devices back on.
- */
-
-int device_pm_power_down(u32 state)
-{
- int error = 0;
-
- if ((error = dpm_power_down(state)))
- goto ErrorIRQOn;
- local_irq_disable();
- if ((error = dpm_power_down_irq(state)))
- goto ErrorIRQOff;
-
- sysdev_suspend(state);
+ }
+ if (error)
+ goto Error;
+ if ((error = sysdev_suspend(state)))
+ goto Error;
Done:
return error;
-
- ErrorIRQOff:
- dpm_power_up_irq();
- local_irq_enable();
- ErrorIRQOn:
+ Error:
dpm_power_up();
goto Done;
}
+EXPORT_SYMBOL(device_power_down);
-/**
- * device_suspend - suspend all devices on the device ree
- * @state: state we're entering
- * @level: Stage of suspend sequence we're in.
- *
- *
- * This function is deprecated. Calls should be replaced with
- * appropriate calls to device_pm_suspend() and device_pm_power_down().
- */
-
-int device_suspend(u32 state, u32 level)
-{
-
- printk("%s Called from:\n",__FUNCTION__);
- dump_stack();
- return -EFAULT;
-}
-EXPORT_SYMBOL(device_suspend);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index e306d2e26363..299b390e243b 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -283,61 +283,16 @@ void sysdev_shutdown(void)
/**
- * sysdev_save - Save system device state
- * @state: Power state we're entering.
- *
- * This is called when the system is going to sleep, but before interrupts
- * have been disabled. This allows system device drivers to allocate and
- * save device state, including sleeping during the process..
- */
-
-int sysdev_save(u32 state)
-{
- struct sysdev_class * cls;
-
- pr_debug("Saving System Device State\n");
-
- down_write(&system_subsys.rwsem);
-
- list_for_each_entry_reverse(cls,&system_subsys.kset.list,
- kset.kobj.entry) {
- struct sys_device * sysdev;
- pr_debug("Saving state for type '%s':\n",cls->kset.kobj.name);
-
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
- struct sysdev_driver * drv;
-
- pr_debug(" %s\n",sysdev->kobj.name);
-
- list_for_each_entry(drv,&global_drivers,entry) {
- if (drv->save)
- drv->save(sysdev,state);
- }
-
- list_for_each_entry(drv,&cls->drivers,entry) {
- if (drv->save)
- drv->save(sysdev,state);
- }
-
- if (cls->save)
- cls->save(sysdev,state);
- }
- }
- up_write(&system_subsys.rwsem);
- return 0;
-}
-
-
-/**
* sysdev_suspend - Suspend all system devices.
* @state: Power state to enter.
*
* We perform an almost identical operation as sys_device_shutdown()
- * above, though calling ->suspend() instead.
+ * above, though calling ->suspend() instead. Interrupts are disabled
+ * when this called. Devices are responsible for both saving state and
+ * quiescing or powering down the device.
*
- * Note: Interrupts are disabled when called, so we can't sleep when
- * trying to get the subsystem's rwsem. If that happens, print a nasty
- * warning and return an error.
+ * This is only called by the device PM core, so we let them handle
+ * all synchronization.
*/
int sysdev_suspend(u32 state)
@@ -346,11 +301,6 @@ int sysdev_suspend(u32 state)
pr_debug("Suspending System Devices\n");
- if (!down_write_trylock(&system_subsys.rwsem)) {
- printk("%s: Cannot acquire semaphore; Failing\n",__FUNCTION__);
- return -EFAULT;
- }
-
list_for_each_entry_reverse(cls,&system_subsys.kset.list,
kset.kobj.entry) {
struct sys_device * sysdev;
@@ -378,8 +328,6 @@ int sysdev_suspend(u32 state)
cls->suspend(sysdev,state);
}
}
- up_write(&system_subsys.rwsem);
-
return 0;
}
@@ -390,7 +338,7 @@ int sysdev_suspend(u32 state)
* Similar to sys_device_suspend(), but we iterate the list forwards
* to guarantee that parent devices are resumed before their children.
*
- * Note: Interrupts are disabled when called.
+ * Note: Interrupts are disabled when called.
*/
int sysdev_resume(void)
@@ -399,9 +347,6 @@ int sysdev_resume(void)
pr_debug("Resuming System Devices\n");
- if(!down_write_trylock(&system_subsys.rwsem))
- return -EFAULT;
-
list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) {
struct sys_device * sysdev;
@@ -429,50 +374,6 @@ int sysdev_resume(void)
}
}
- up_write(&system_subsys.rwsem);
- return 0;
-}
-
-
-/**
- * sysdev_restore - Restore system device state
- *
- * This is called during a suspend/resume cycle last, after interrupts
- * have been re-enabled. This is intended for auxillary drivers, etc,
- * that may sleep when restoring state.
- */
-
-int sysdev_restore(void)
-{
- struct sysdev_class * cls;
-
- down_write(&system_subsys.rwsem);
- pr_debug("Restoring System Device State\n");
-
- list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) {
- struct sys_device * sysdev;
-
- pr_debug("Restoring state for type '%s':\n",cls->kset.kobj.name);
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
- struct sysdev_driver * drv;
- pr_debug(" %s\n",sysdev->kobj.name);
-
- if (cls->restore)
- cls->restore(sysdev);
-
- list_for_each_entry(drv,&cls->drivers,entry) {
- if (drv->restore)
- drv->restore(sysdev);
- }
-
- list_for_each_entry(drv,&global_drivers,entry) {
- if (drv->restore)
- drv->restore(sysdev);
- }
- }
- }
-
- up_write(&system_subsys.rwsem);
return 0;
}
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d16c54b65102..60f1508b24ab 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -6,7 +6,7 @@ menu "Character devices"
config VT
bool "Virtual terminal" if EMBEDDED
- requires INPUT=y
+ select INPUT
default y
---help---
If you say Y here, you will get support for terminal devices with
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index cf0b5307a8de..4e7a197f6611 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3330,10 +3330,6 @@ static ide_driver_t ide_cdrom_driver = {
.drives = LIST_HEAD_INIT(ide_cdrom_driver.drives),
.start_power_step = ide_cdrom_start_power_step,
.complete_power_step = ide_cdrom_complete_power_step,
- .gen_driver = {
- .suspend = generic_ide_suspend,
- .resume = generic_ide_resume,
- }
};
static int idecd_open(struct inode * inode, struct file * file)
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 30865145af3e..1217e840ac02 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1732,10 +1732,6 @@ static ide_driver_t idedisk_driver = {
.drives = LIST_HEAD_INIT(idedisk_driver.drives),
.start_power_step = idedisk_start_power_step,
.complete_power_step = idedisk_complete_power_step,
- .gen_driver = {
- .suspend = generic_ide_suspend,
- .resume = generic_ide_resume,
- }
};
static int idedisk_open(struct inode *inode, struct file *filp)
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 5d19aa20abcd..dd0ad3ff074c 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1534,16 +1534,13 @@ int ata_attach(ide_drive_t *drive)
EXPORT_SYMBOL(ata_attach);
-int generic_ide_suspend(struct device *dev, u32 state, u32 level)
+static int generic_ide_suspend(struct device *dev, u32 state)
{
ide_drive_t *drive = dev->driver_data;
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
- if (level == dev->power_state || level != SUSPEND_SAVE_STATE)
- return 0;
-
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
@@ -1556,18 +1553,13 @@ int generic_ide_suspend(struct device *dev, u32 state, u32 level)
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
-EXPORT_SYMBOL(generic_ide_suspend);
-
-int generic_ide_resume(struct device *dev, u32 level)
+static int generic_ide_resume(struct device *dev)
{
ide_drive_t *drive = dev->driver_data;
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
- if (level == dev->power_state || level != RESUME_RESTORE_STATE)
- return 0;
-
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
@@ -1580,8 +1572,6 @@ int generic_ide_resume(struct device *dev, u32 level)
return ide_do_drive_cmd(drive, &rq, ide_head_wait);
}
-EXPORT_SYMBOL(generic_ide_resume);
-
int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
unsigned long arg)
{
@@ -2594,6 +2584,8 @@ EXPORT_SYMBOL(ide_probe);
struct bus_type ide_bus_type = {
.name = "ide",
+ .suspend = generic_ide_suspend,
+ .resume = generic_ide_resume,
};
/*
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 63ceffd78748..a73b16eefd58 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -647,7 +647,6 @@ static void __exit exit_sedlbauer_cs(void)
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) {
- del_timer(&dev_list->release);
if (dev_list->state & DEV_CONFIG)
sedlbauer_release(dev_list);
sedlbauer_detach(dev_list);
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index ad105b881410..2dac57b618a3 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -308,8 +308,10 @@ static void add_us_sample(struct mm_struct * mm, struct op_sample * s)
cookie = lookup_dcookie(mm, s->eip, &offset);
- if (!cookie)
+ if (!cookie) {
+ atomic_inc(&oprofile_stats.sample_lost_no_mapping);
return;
+ }
if (cookie != last_cookie) {
add_cookie_switch(cookie);
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
index 21ae41a54e90..b7466377afd4 100644
--- a/drivers/oprofile/oprofile_files.c
+++ b/drivers/oprofile/oprofile_files.c
@@ -19,6 +19,17 @@ unsigned long fs_cpu_buffer_size = 8192;
unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
+static ssize_t pointer_size_read(struct file * file, char * buf, size_t count, loff_t * offset)
+{
+ return oprofilefs_ulong_to_user((unsigned long)sizeof(void *), buf, count, offset);
+}
+
+
+static struct file_operations pointer_size_fops = {
+ .read = pointer_size_read,
+};
+
+
static ssize_t cpu_type_read(struct file * file, char * buf, size_t count, loff_t * offset)
{
return oprofilefs_str_to_user(oprofile_ops->cpu_type, buf, count, offset);
@@ -32,7 +43,7 @@ static struct file_operations cpu_type_fops = {
static ssize_t enable_read(struct file * file, char * buf, size_t count, loff_t * offset)
{
- return oprofilefs_ulong_to_user(&oprofile_started, buf, count, offset);
+ return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset);
}
@@ -85,6 +96,7 @@ void oprofile_create_files(struct super_block * sb, struct dentry * root)
oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
oprofilefs_create_ulong(sb, root, "cpu_buffer_size", &fs_cpu_buffer_size);
oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops);
+ oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops);
oprofile_create_stats_files(sb, root);
if (oprofile_ops->create_files)
oprofile_ops->create_files(sb, root);
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
index 5624c1e017e0..f01e1935072c 100644
--- a/drivers/oprofile/oprofile_stats.c
+++ b/drivers/oprofile/oprofile_stats.c
@@ -32,6 +32,7 @@ void oprofile_reset_stats(void)
}
atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
+ atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
atomic_set(&oprofile_stats.event_lost_overflow, 0);
}
@@ -70,6 +71,8 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root)
oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm",
&oprofile_stats.sample_lost_no_mm);
+ oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mapping",
+ &oprofile_stats.sample_lost_no_mapping);
oprofilefs_create_ro_atomic(sb, dir, "event_lost_overflow",
&oprofile_stats.event_lost_overflow);
}
diff --git a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h
index e3f67d5c0910..9f4d4d2046db 100644
--- a/drivers/oprofile/oprofile_stats.h
+++ b/drivers/oprofile/oprofile_stats.h
@@ -14,6 +14,7 @@
struct oprofile_stat_struct {
atomic_t sample_lost_no_mm;
+ atomic_t sample_lost_no_mapping;
atomic_t event_lost_overflow;
};
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index c82630ec1819..ed1efe61f6e3 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -69,7 +69,7 @@ ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_
#define TMPBUFSIZE 50
-ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count, loff_t * offset)
+ssize_t oprofilefs_ulong_to_user(unsigned long val, char * buf, size_t count, loff_t * offset)
{
char tmpbuf[TMPBUFSIZE];
size_t maxlen;
@@ -78,7 +78,7 @@ ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count,
return 0;
spin_lock(&oprofilefs_lock);
- maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", *val);
+ maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val);
spin_unlock(&oprofilefs_lock);
if (maxlen > TMPBUFSIZE)
maxlen = TMPBUFSIZE;
@@ -122,7 +122,8 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const * buf, size_t cou
static ssize_t ulong_read_file(struct file * file, char * buf, size_t count, loff_t * offset)
{
- return oprofilefs_ulong_to_user(file->private_data, buf, count, offset);
+ unsigned long * val = file->private_data;
+ return oprofilefs_ulong_to_user(*val, buf, count, offset);
}
@@ -212,9 +213,8 @@ int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root,
static ssize_t atomic_read_file(struct file * file, char * buf, size_t count, loff_t * offset)
{
- atomic_t * aval = file->private_data;
- unsigned long val = atomic_read(aval);
- return oprofilefs_ulong_to_user(&val, buf, count, offset);
+ atomic_t * val = file->private_data;
+ return oprofilefs_ulong_to_user(atomic_read(val), buf, count, offset);
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f0f3d80ce60d..640681c93bdc 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -158,32 +158,23 @@ static int pci_device_remove(struct device * dev)
return 0;
}
-static int pci_device_suspend(struct device * dev, u32 state, u32 level)
+static int pci_device_suspend(struct device * dev, u32 state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
- int error = 0;
+ struct pci_driver * drv = pci_dev->driver;
- if (pci_dev->driver) {
- if (level == SUSPEND_SAVE_STATE && pci_dev->driver->save_state)
- error = pci_dev->driver->save_state(pci_dev,state);
- else if (level == SUSPEND_POWER_DOWN && pci_dev->driver->suspend)
- error = pci_dev->driver->suspend(pci_dev,state);
- }
- return error;
+ if (drv && drv->suspend)
+ return drv->suspend(pci_dev,state);
+ return 0;
}
-static int pci_device_resume(struct device * dev, u32 level)
+static int pci_device_resume(struct device * dev)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
+ struct pci_driver * drv = pci_dev->driver;
- if (pci_dev->driver) {
- /* We may not call PCI drivers resume at
- RESUME_POWER_ON because interrupts are not yet
- working at that point. Calling resume at
- RESUME_RESTORE_STATE seems like solution. */
- if (level == RESUME_RESTORE_STATE && pci_dev->driver->resume)
- pci_dev->driver->resume(pci_dev);
- }
+ if (drv && drv->resume)
+ drv->resume(pci_dev);
return 0;
}
@@ -349,8 +340,6 @@ pci_register_driver(struct pci_driver *drv)
drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type;
drv->driver.probe = pci_device_probe;
- drv->driver.resume = pci_device_resume;
- drv->driver.suspend = pci_device_suspend;
drv->driver.remove = pci_device_remove;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
pci_init_dynids(&drv->dynids);
@@ -496,6 +485,8 @@ struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.hotplug = pci_hotplug,
+ .suspend = pci_device_suspend,
+ .resume = pci_device_resume,
};
static int __init pci_driver_init(void)