Hi! Here's my current round of type-safety patches (which paves way to really fix stuff up). Patrick, could you commit it to linux-pm tree? [At this point it is still possible to split it into nice pieces, but I'd like to get it into some visible place so that drivers can be converted.] Andrew, would you take plain patches if Patrick is not responsive? Look into amd8111e.c part for a proof that this is really needed. Pavel --- clean/arch/i386/kernel/apm.c 2004-10-01 00:29:59.000000000 +0200 +++ linux-delme/arch/i386/kernel/apm.c 2004-11-14 23:51:55.000000000 +0100 @@ -1201,8 +1201,8 @@ printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); } - device_suspend(3); - device_power_down(3); + device_suspend(PMSG_SUSPEND); + device_power_down(PMSG_SUSPEND); /* serialize with the timer interrupt */ write_seqlock_irq(&xtime_lock); @@ -1255,7 +1255,7 @@ { int err; - device_power_down(3); + device_power_down(PMSG_SUSPEND); /* serialize with the timer interrupt */ write_seqlock_irq(&xtime_lock); /* If needed, notify drivers here */ --- clean/drivers/base/power/power.h 2004-08-15 19:14:55.000000000 +0200 +++ linux-delme/drivers/base/power/power.h 2004-11-14 23:51:55.000000000 +0100 @@ -66,14 +66,14 @@ /* * suspend.c */ -extern int suspend_device(struct device *, u32); +extern int suspend_device(struct device *, pm_message_t); /* * runtime.c */ -extern int dpm_runtime_suspend(struct device *, u32); +extern int dpm_runtime_suspend(struct device *, pm_message_t); extern void dpm_runtime_resume(struct device *); #else /* CONFIG_PM */ @@ -88,7 +88,7 @@ } -static inline int dpm_runtime_suspend(struct device * dev, u32 state) +static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) { return 0; } --- clean/drivers/base/power/resume.c 2004-08-15 19:14:55.000000000 +0200 +++ linux-delme/drivers/base/power/resume.c 2004-11-14 23:51:55.000000000 +0100 @@ -36,7 +36,7 @@ struct device * dev = to_device(entry); list_del_init(entry); - if (!dev->power.prev_state) + if (dev->power.prev_state == PMSG_ON) resume_device(dev); list_add_tail(entry, &dpm_active); --- clean/drivers/base/power/runtime.c 2004-08-15 19:14:55.000000000 +0200 +++ linux-delme/drivers/base/power/runtime.c 2004-11-14 23:51:55.000000000 +0100 @@ -13,10 +13,10 @@ static void runtime_resume(struct device * dev) { dev_dbg(dev, "resuming\n"); - if (!dev->power.power_state) + if (dev->power.power_state == PMSG_ON) return; if (!resume_device(dev)) - dev->power.power_state = 0; + dev->power.power_state = PMSG_ON; } @@ -44,7 +44,7 @@ * @state: State to enter. */ -int dpm_runtime_suspend(struct device * dev, u32 state) +int dpm_runtime_suspend(struct device * dev, pm_message_t state) { int error = 0; @@ -52,7 +52,7 @@ if (dev->power.power_state == state) goto Done; - if (dev->power.power_state) + if (dev->power.power_state != PMSG_ON) runtime_resume(dev); if (!(error = suspend_device(dev, state))) @@ -73,7 +73,7 @@ * always be able to tell, but we need accurate information to * work reliably. */ -void dpm_set_power_state(struct device * dev, u32 state) +void dpm_set_power_state(struct device * dev, pm_message_t state) { down(&dpm_sem); dev->power.power_state = state; --- clean/drivers/base/power/shutdown.c 2004-08-15 19:14:55.000000000 +0200 +++ linux-delme/drivers/base/power/shutdown.c 2004-11-14 23:51:55.000000000 +0100 @@ -29,7 +29,8 @@ dev->driver->shutdown(dev); return 0; } - return dpm_runtime_suspend(dev, dev->detach_state); + /* FIXME */ + return dpm_runtime_suspend(dev, PMSG_FREEZE); } --- clean/drivers/base/power/suspend.c 2004-08-15 19:14:55.000000000 +0200 +++ linux-delme/drivers/base/power/suspend.c 2004-11-14 23:51:55.000000000 +0100 @@ -11,7 +11,7 @@ #include <linux/device.h> #include "power.h" -extern int sysdev_suspend(u32 state); +extern int sysdev_suspend(pm_message_t state); /* * The entries in the dpm_active list are in a depth first order, simply @@ -35,7 +35,7 @@ * @state: Power state device is entering. */ -int suspend_device(struct device * dev, u32 state) +int suspend_device(struct device * dev, pm_message_t state) { int error = 0; @@ -43,7 +43,7 @@ dev->power.prev_state = dev->power.power_state; - if (dev->bus && dev->bus->suspend && !dev->power.power_state) + if (dev->bus && dev->bus->suspend && (dev->power.power_state == PMSG_ON)) error = dev->bus->suspend(dev, state); return error; @@ -70,7 +70,7 @@ * */ -int device_suspend(u32 state) +int device_suspend(pm_message_t state) { int error = 0; @@ -112,7 +112,7 @@ * done, power down system devices. */ -int device_power_down(u32 state) +int device_power_down(pm_message_t state) { int error = 0; struct device * dev; --- clean/drivers/net/3c59x.c 2004-10-19 14:16:28.000000000 +0200 +++ linux-delme/drivers/net/3c59x.c 2004-11-14 23:51:55.000000000 +0100 @@ -1550,7 +1550,7 @@ int i; if (VORTEX_PCI(vp) && vp->enable_wol) { - pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ + pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ pci_restore_state(VORTEX_PCI(vp), vp->power_state); } @@ -2942,7 +2942,7 @@ /* The kernel core really should have pci_get_power_state() */ if(state != 0) - pci_set_power_state(VORTEX_PCI(vp), 0); + pci_set_power_state(VORTEX_PCI(vp), PCI_D0); err = vortex_do_ioctl(dev, rq, cmd); if(state != 0) pci_set_power_state(VORTEX_PCI(vp), state); @@ -3141,7 +3141,7 @@ /* Change the power state to D3; RxEnable doesn't take effect. */ pci_enable_wake(VORTEX_PCI(vp), 0, 1); - pci_set_power_state(VORTEX_PCI(vp), 3); + pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); } @@ -3164,7 +3164,7 @@ unregister_netdev(dev); if (VORTEX_PCI(vp) && vp->enable_wol) { - pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ + pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ if (vp->pm_state_valid) pci_restore_state(VORTEX_PCI(vp), vp->power_state); } --- clean/drivers/net/8139cp.c 2004-10-01 00:30:15.000000000 +0200 +++ linux-delme/drivers/net/8139cp.c 2004-11-14 23:51:55.000000000 +0100 @@ -1623,7 +1623,7 @@ static void cp_set_d3_state (struct cp_private *cp) { pci_enable_wake (cp->pdev, 0, 1); /* Enable PME# generation */ - pci_set_power_state (cp->pdev, 3); + pci_set_power_state (cp->pdev, PCI_D3hot); } static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1813,7 +1813,7 @@ BUG(); unregister_netdev(dev); iounmap(cp->regs); - if (cp->wol_enabled) pci_set_power_state (pdev, 0); + if (cp->wol_enabled) pci_set_power_state (pdev, PCI_D0); pci_release_regions(pdev); pci_clear_mwi(pdev); pci_disable_device(pdev); @@ -1863,7 +1863,7 @@ netif_device_attach (dev); if (cp->pdev && cp->wol_enabled) { - pci_set_power_state (cp->pdev, 0); + pci_set_power_state (cp->pdev, PCI_D0); pci_restore_state (cp->pdev, cp->power_state); } --- clean/drivers/net/amd8111e.c 2004-10-01 00:30:15.000000000 +0200 +++ linux-delme/drivers/net/amd8111e.c 2004-11-14 23:51:55.000000000 +0100 @@ -1865,17 +1865,17 @@ if(lp->options & OPTION_WAKE_PHY_ENABLE) amd8111e_enable_link_change(lp); - pci_enable_wake(pci_dev, 3, 1); - pci_enable_wake(pci_dev, 4, 1); /* D3 cold */ + pci_enable_wake(pci_dev, PCI_D3hot, 1); + pci_enable_wake(pci_dev, PCI_D3cold, 1); } else{ - pci_enable_wake(pci_dev, 3, 0); - pci_enable_wake(pci_dev, 4, 0); /* 4 == D3 cold */ + pci_enable_wake(pci_dev, PCI_D3hot, 0); + pci_enable_wake(pci_dev, PCI_D3cold, 0); } pci_save_state(pci_dev, lp->pm_state); - pci_set_power_state(pci_dev, 3); + pci_set_power_state(pci_dev, PCI_D3hot); return 0; } @@ -1887,11 +1887,11 @@ if (!netif_running(dev)) return 0; - pci_set_power_state(pci_dev, 0); + pci_set_power_state(pci_dev, PCI_D0); pci_restore_state(pci_dev, lp->pm_state); - pci_enable_wake(pci_dev, 3, 0); - pci_enable_wake(pci_dev, 4, 0); /* D3 cold */ + pci_enable_wake(pci_dev, PCI_D3hot, 0); + pci_enable_wake(pci_dev, PCI_D3cold, 0); netif_device_attach(dev); --- clean/drivers/net/e100.c 2004-10-01 00:30:15.000000000 +0200 +++ linux-delme/drivers/net/e100.c 2004-11-14 23:51:55.000000000 +0100 @@ -2313,7 +2313,7 @@ pci_save_state(pdev, nic->pm_state); pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic))); pci_disable_device(pdev); - pci_set_power_state(pdev, state); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } @@ -2323,7 +2323,7 @@ struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - pci_set_power_state(pdev, 0); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev, nic->pm_state); e100_hw_init(nic); --- clean/drivers/net/eepro100.c 2004-10-01 00:30:15.000000000 +0200 +++ linux-delme/drivers/net/eepro100.c 2004-11-14 23:51:55.000000000 +0100 @@ -155,16 +155,6 @@ #define RUN_AT(x) (jiffies + (x)) -/* ACPI power states don't universally work (yet) */ -#ifndef CONFIG_PM -#undef pci_set_power_state -#define pci_set_power_state null_set_power_state -static inline int null_set_power_state(struct pci_dev *dev, int state) -{ - return 0; -} -#endif /* CONFIG_PM */ - #define netdevice_start(dev) #define netdevice_stop(dev) #define netif_set_tx_timeout(dev, tf, tm) \ @@ -1015,7 +1005,7 @@ if (netif_msg_ifup(sp)) printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq); - pci_set_power_state(sp->pdev, 0); + pci_set_power_state(sp->pdev, PCI_D0); /* Set up the Tx queue early.. */ sp->cur_tx = 0; @@ -1964,7 +1954,7 @@ if (netif_msg_ifdown(sp)) printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i); - pci_set_power_state(sp->pdev, 2); + pci_set_power_state(sp->pdev, PCI_D2); return 0; } @@ -2103,7 +2093,7 @@ access from the timeout handler. They are currently serialized only with MDIO access from the timer routine. 2000/05/09 SAW */ - saved_acpi = pci_set_power_state(sp->pdev, 0); + saved_acpi = pci_set_power_state(sp->pdev, PCI_D0); t = del_timer_sync(&sp->timer); data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); if (t) @@ -2114,7 +2104,7 @@ case SIOCSMIIREG: /* Write MII PHY register. */ if (!capable(CAP_NET_ADMIN)) return -EPERM; - saved_acpi = pci_set_power_state(sp->pdev, 0); + saved_acpi = pci_set_power_state(sp->pdev, PCI_D0); t = del_timer_sync(&sp->timer); mdio_write(dev, data->phy_id, data->reg_num, data->val_in); if (t) --- clean/drivers/net/pci-skeleton.c 2004-08-15 19:14:58.000000000 +0200 +++ linux-delme/drivers/net/pci-skeleton.c 2004-11-14 23:51:55.000000000 +0100 @@ -1922,7 +1922,7 @@ spin_unlock_irqrestore (&tp->lock, flags); pci_save_state (pdev, tp->pci_state); - pci_set_power_state (pdev, 3); + pci_set_power_state (pdev, PCI_D3hot); return 0; } @@ -1935,7 +1935,7 @@ if (!netif_running(dev)) return 0; - pci_set_power_state (pdev, 0); + pci_set_power_state (pdev, PCI_D0); pci_restore_state (pdev, tp->pci_state); netif_device_attach (dev); netdrv_hw_start (dev); --- clean/drivers/net/sis900.c 2004-10-01 00:30:15.000000000 +0200 +++ linux-delme/drivers/net/sis900.c 2004-11-14 23:51:55.000000000 +0100 @@ -2212,7 +2212,7 @@ /* Stop the chip's Tx and Rx Status Machine */ outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr); - pci_set_power_state(pci_dev, 3); + pci_set_power_state(pci_dev, PCI_D3hot); pci_save_state(pci_dev, sis_priv->pci_state); return 0; @@ -2227,7 +2227,7 @@ if(!netif_running(net_dev)) return 0; pci_restore_state(pci_dev, sis_priv->pci_state); - pci_set_power_state(pci_dev, 0); + pci_set_power_state(pci_dev, PCI_D0); sis900_init_rxfilter(net_dev); --- clean/drivers/net/starfire.c 2004-08-15 19:14:58.000000000 +0200 +++ linux-delme/drivers/net/starfire.c 2004-11-14 23:51:55.000000000 +0100 @@ -2186,7 +2186,7 @@ unregister_netdev(dev); /* XXX: add wakeup code -- requires firmware for MagicPacket */ - pci_set_power_state(pdev, 3); /* go to sleep in D3 mode */ + pci_set_power_state(pdev, PCI_D3hot); /* go to sleep in D3 mode */ pci_disable_device(pdev); iounmap((char *)dev->base_addr); --- clean/drivers/net/typhoon.c 2004-10-01 00:30:16.000000000 +0200 +++ linux-delme/drivers/net/typhoon.c 2004-11-14 23:51:55.000000000 +0100 @@ -1884,7 +1884,7 @@ pci_enable_wake(tp->pdev, state, 1); pci_disable_device(pdev); - return pci_set_power_state(pdev, state); + return pci_set_power_state(pdev, pci_choose_state(pdev, state)); } static int @@ -1893,7 +1893,7 @@ struct pci_dev *pdev = tp->pdev; void __iomem *ioaddr = tp->ioaddr; - pci_set_power_state(pdev, 0); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev, tp->pci_state); /* Post 2.x.x versions of the Sleep Image require a reset before @@ -2541,7 +2541,7 @@ struct typhoon *tp = (struct typhoon *) (dev->priv); unregister_netdev(dev); - pci_set_power_state(pdev, 0); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev, tp->pci_state); typhoon_reset(tp->ioaddr, NoWait); iounmap(tp->ioaddr); --- clean/drivers/net/via-velocity.c 2004-10-19 14:16:28.000000000 +0200 +++ linux-delme/drivers/net/via-velocity.c 2004-11-14 23:51:55.000000000 +0100 @@ -804,7 +804,7 @@ /* and leave the chip powered down */ - pci_set_power_state(pdev, 3); + pci_set_power_state(pdev, PCI_D3hot); #ifdef CONFIG_PM { unsigned long flags; @@ -1742,7 +1742,7 @@ goto err_free_rd_ring; /* Ensure chip is running */ - pci_set_power_state(vptr->pdev, 0); + pci_set_power_state(vptr->pdev, PCI_D0); velocity_init_registers(vptr, VELOCITY_INIT_COLD); @@ -1750,7 +1750,7 @@ dev->name, dev); if (ret < 0) { /* Power down the chip */ - pci_set_power_state(vptr->pdev, 3); + pci_set_power_state(vptr->pdev, PCI_D3hot); goto err_free_td_ring; } @@ -1868,7 +1868,7 @@ free_irq(dev->irq, dev); /* Power down the chip */ - pci_set_power_state(vptr->pdev, 3); + pci_set_power_state(vptr->pdev, PCI_D3hot); /* Free the resources */ velocity_free_td_ring(vptr); @@ -2194,8 +2194,8 @@ /* If we are asked for information and the device is power saving then we need to bring the device back up to talk to it */ - if(!netif_running(dev)) - pci_set_power_state(vptr->pdev, 0); + if (!netif_running(dev)) + pci_set_power_state(vptr->pdev, PCI_D0); switch (cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ @@ -2207,8 +2207,8 @@ default: ret = -EOPNOTSUPP; } - if(!netif_running(dev)) - pci_set_power_state(vptr->pdev, 3); + if (!netif_running(dev)) + pci_set_power_state(vptr->pdev, PCI_D3hot); return ret; @@ -2818,8 +2818,8 @@ static int velocity_ethtool_up(struct net_device *dev) { struct velocity_info *vptr = dev->priv; - if(!netif_running(dev)) - pci_set_power_state(vptr->pdev, 0); + if (!netif_running(dev)) + pci_set_power_state(vptr->pdev, PCI_D0); return 0; } @@ -2834,8 +2834,8 @@ static void velocity_ethtool_down(struct net_device *dev) { struct velocity_info *vptr = dev->priv; - if(!netif_running(dev)) - pci_set_power_state(vptr->pdev, 3); + if (!netif_running(dev)) + pci_set_power_state(vptr->pdev, PCI_D3hot); } static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) @@ -3229,15 +3229,15 @@ velocity_shutdown(vptr); velocity_set_wol(vptr); pci_enable_wake(pdev, 3, 1); - pci_set_power_state(pdev, 3); + pci_set_power_state(pdev, PCI_D3hot); } else { velocity_save_context(vptr, &vptr->context); velocity_shutdown(vptr); pci_disable_device(pdev); - pci_set_power_state(pdev, state); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); } #else - pci_set_power_state(pdev, state); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); #endif spin_unlock_irqrestore(&vptr->lock, flags); return 0; @@ -3252,7 +3252,7 @@ if(!netif_running(vptr->dev)) return 0; - pci_set_power_state(pdev, 0); + pci_set_power_state(pdev, PCI_D0); pci_enable_wake(pdev, 0, 0); pci_restore_state(pdev, vptr->pci_state); --- clean/drivers/pci/pci.c 2004-10-01 00:30:16.000000000 +0200 +++ linux-delme/drivers/pci/pci.c 2004-11-14 23:51:55.000000000 +0100 @@ -229,7 +229,7 @@ /** * pci_set_power_state - Set the power state of a PCI device * @dev: PCI device to be suspended - * @state: Power state we're entering + * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering * * Transition a device to a new power state, using the Power Management * Capabilities in the device's config space. @@ -300,6 +300,30 @@ } /** + * pci_choose_state - Choose the power state of a PCI device + * @dev: PCI device to be suspended + * @state: target sleep state for the whole system + * + * Returns PCI power state suitable for given device and given system + * message. + */ + +pci_power_t pci_choose_state(struct pci_dev *dev, u32 state) +{ + if (!pci_find_capability(dev, PCI_CAP_ID_PM)) + return PCI_D0; + + switch (state) { + case 0: return PCI_D0; + case 2: return PCI_D2; + case 3: return PCI_D3hot; + default: BUG(); + } +} + +EXPORT_SYMBOL(pci_choose_state); + +/** * pci_save_state - save the PCI configuration space of a device before suspending * @dev: - PCI device that we're dealing with * @buffer: - buffer to hold config space context @@ -365,7 +389,7 @@ { int err; - pci_set_power_state(dev, 0); + pci_set_power_state(dev, PCI_D0); if ((err = pcibios_enable_device(dev, bars)) < 0) return err; return 0; --- clean/drivers/usb/core/hcd-pci.c 2004-10-01 00:30:19.000000000 +0200 +++ linux-delme/drivers/usb/core/hcd-pci.c 2004-11-14 23:51:55.000000000 +0100 @@ -355,8 +355,8 @@ hcd->state = USB_STATE_RESUMING; if (has_pci_pm) - pci_set_power_state (dev, 0); - dev->dev.power.power_state = 0; + pci_set_power_state (dev, PCI_D0); + dev->dev.power.power_state = PMSG_ON; retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd); if (retval < 0) { --- clean/drivers/usb/host/ohci-hub.c 2004-10-19 14:16:28.000000000 +0200 +++ linux-delme/drivers/usb/host/ohci-hub.c 2004-11-14 23:51:55.000000000 +0100 @@ -76,7 +76,7 @@ struct usb_device *root = hcd_to_bus (&ohci->hcd)->root_hub; int status = 0; - if (root->dev.power.power_state != 0) + if (root->dev.power.power_state != PMSG_ON) return 0; if (time_before (jiffies, ohci->next_statechange)) return -EAGAIN; --- clean/include/linux/pm.h 2004-10-01 00:30:30.000000000 +0200 +++ linux-delme/include/linux/pm.h 2004-11-14 23:51:56.000000000 +0100 @@ -229,10 +229,34 @@ struct device; +typedef u32 __bitwise pm_message_t; + +/* + * There are 4 important states driver can be in: + * ON -- driver is working + * FREEZE -- stop operations and apply whatever policy is applicable to a suspended driver + * of that class, freeze queues for block like IDE does, drop packets for + * ethernet, etc... stop DMA engine too etc... so a consistent image can be + * saved; but do not power any hardware down. + * SUSPEND - like FREEZE, but hardware is doing as much powersaving as possible. Roughly + * pci D3. + * + * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3 (SUSPEND). + * We'll need to fix the drivers. So yes, putting 3 to all diferent defines is intentional, + * and will go away as soon as drivers are fixed. Also note that typedef is neccessary, + * we'll probably want to switch to + * typedef struct pm_message_t { int event; int flags; } pm_message_t + * or something similar soon. + */ + +#define PMSG_FREEZE ((__force pm_message_t) 3) +#define PMSG_SUSPEND ((__force pm_message_t) 3) +#define PMSG_ON ((__force pm_message_t) 0) + struct dev_pm_info { - u32 power_state; + pm_message_t power_state; #ifdef CONFIG_PM - u32 prev_state; + pm_message_t prev_state; u8 * saved_state; atomic_t pm_users; struct device * pm_parent; @@ -242,8 +266,8 @@ extern void device_pm_set_parent(struct device * dev, struct device * parent); -extern int device_suspend(u32 state); -extern int device_power_down(u32 state); +extern int device_suspend(pm_message_t state); +extern int device_power_down(pm_message_t state); extern void device_power_up(void); extern void device_resume(void); --- clean/kernel/power/disk.c 2004-10-01 00:30:32.000000000 +0200 +++ linux-delme/kernel/power/disk.c 2004-11-14 23:51:56.000000000 +0100 @@ -49,7 +49,7 @@ local_irq_save(flags); switch(mode) { case PM_DISK_PLATFORM: - device_power_down(PM_SUSPEND_DISK); + device_power_down(PMSG_SUSPEND); error = pm_ops->enter(PM_SUSPEND_DISK); break; case PM_DISK_SHUTDOWN: @@ -102,6 +102,7 @@ static void finish(void) { + sysdev_resume(); device_resume(); platform_finish(); enable_nonboot_cpus(); @@ -133,8 +134,12 @@ free_some_memory(); disable_nonboot_cpus(); - if ((error = device_suspend(PM_SUSPEND_DISK))) + if ((error = device_suspend(PMSG_FREEZE))) { + printk("Some devices failed to suspend\n"); goto Finish; + } + + sysdev_suspend(PMSG_FREEZE); return 0; Finish: --- clean/kernel/power/main.c 2004-10-01 00:30:32.000000000 +0200 +++ linux-delme/kernel/power/main.c 2004-11-14 23:51:56.000000000 +0100 @@ -65,7 +65,7 @@ goto Thaw; } - if ((error = device_suspend(state))) + if ((error = device_suspend(PMSG_SUSPEND))) goto Finish; return 0; Finish: @@ -78,13 +78,14 @@ } -static int suspend_enter(u32 state) +static int suspend_enter(suspend_state_t state) { int error = 0; unsigned long flags; local_irq_save(flags); - if ((error = device_power_down(state))) + + if ((error = device_power_down(PMSG_SUSPEND))) goto Done; error = pm_ops->enter(state); device_power_up(); -- People were complaining that M$ turns users into beta-testers... ...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!