lkml.org 
[lkml]   [2005]   [Mar]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: 2.6.11-rc4-mm1: something is wrong with swsusp powerdown
    Hi!

    > btw, suspend is a bit messy. The disk spins down. Then up. Then down
    > again. And:

    Here's preview patch to make disk not do stupid yo-yo. Please do not
    apply (it will probably not apply cleanly anyway).

    I can fix disk going yo-yo without switching pm_message_t to struct,
    but will have to back parts of that later. Do you want patch?
    Pavel

    --- clean/drivers/base/power/resume.c 2004-12-25 13:34:59.000000000 +0100
    +++ linux/drivers/base/power/resume.c 2005-02-28 15:38:51.000000000 +0100
    @@ -41,7 +41,7 @@
    list_add_tail(entry, &dpm_active);

    up(&dpm_list_sem);
    - if (!dev->power.prev_state)
    + if (!dev->power.prev_state EVENT)
    resume_device(dev);
    down(&dpm_list_sem);
    put_device(dev);
    --- clean/drivers/base/power/runtime.c 2005-01-12 11:07:39.000000000 +0100
    +++ linux/drivers/base/power/runtime.c 2005-02-28 15:42:10.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 EVENT)
    return;
    if (!resume_device(dev))
    - dev->power.power_state = 0;
    + dev->power.power_state = PMSG_ON;
    }


    @@ -49,10 +49,10 @@
    int error = 0;

    down(&dpm_sem);
    - if (dev->power.power_state == state)
    + if (dev->power.power_state EVENT == state EVENT)
    goto Done;

    - if (dev->power.power_state)
    + if (dev->power.power_state EVENT)
    runtime_resume(dev);

    if (!(error = suspend_device(dev, state)))
    --- clean/drivers/base/power/shutdown.c 2004-08-15 19:14:55.000000000 +0200
    +++ linux/drivers/base/power/shutdown.c 2005-01-12 10:57:23.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 2005-01-12 11:07:39.000000000 +0100
    +++ linux/drivers/base/power/suspend.c 2005-02-28 21:30:13.000000000 +0100
    @@ -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 EVENT))
    error = dev->bus->suspend(dev, state);

    return error;
    @@ -134,6 +134,8 @@
    Done:
    return error;
    Error:
    + printk(KERN_ERR "Could not power down device %s: "
    + "error %d\n", kobject_name(&dev->kobj), error);
    dpm_power_up();
    goto Done;
    }
    --- clean/drivers/base/power/sysfs.c 2004-08-15 19:14:55.000000000 +0200
    +++ linux/drivers/base/power/sysfs.c 2005-02-28 15:43:57.000000000 +0100
    @@ -26,19 +26,20 @@

    static ssize_t state_show(struct device * dev, char * buf)
    {
    - return sprintf(buf, "%u\n", dev->power.power_state);
    + return sprintf(buf, "%u\n", dev->power.power_state EVENT);
    }

    static ssize_t state_store(struct device * dev, const char * buf, size_t n)
    {
    - u32 state;
    + pm_message_t state;
    char * rest;
    int error = 0;

    - state = simple_strtoul(buf, &rest, 10);
    + state EVENT = simple_strtoul(buf, &rest, 10);
    +// state.flags = PFL_RUNTIME;
    if (*rest)
    return -EINVAL;
    - if (state)
    + if (state EVENT)
    error = dpm_runtime_suspend(dev, state);
    else
    dpm_runtime_resume(dev);
    --- clean/drivers/ide/ide-disk.c 2005-02-14 14:12:21.000000000 +0100
    +++ linux/drivers/ide/ide-disk.c 2005-02-14 22:34:43.000000000 +0100
    @@ -872,7 +872,7 @@
    {
    switch (rq->pm->pm_step) {
    case idedisk_pm_flush_cache: /* Suspend step 1 (flush cache) complete */
    - if (rq->pm->pm_state == 4)
    + if (rq->pm->pm_state == EVENT_FREEZE)
    rq->pm->pm_step = ide_pm_state_completed;
    else
    rq->pm->pm_step = idedisk_pm_standby;
    @@ -1155,8 +1155,7 @@
    return;
    }

    - printk("Shutdown: %s\n", drive->name);
    - dev->bus->suspend(dev, PM_SUSPEND_STANDBY);
    + dev->bus->suspend(dev, PMSG_SUSPEND);
    }

    /*
    --- clean/drivers/ide/ide.c 2005-02-28 00:50:42.000000000 +0100
    +++ linux/drivers/ide/ide.c 2005-02-28 15:48:21.000000000 +0100
    @@ -1398,7 +1398,7 @@
    rq.special = &args;
    rq.pm = &rqpm;
    rqpm.pm_step = ide_pm_state_start_suspend;
    - rqpm.pm_state = state;
    + rqpm.pm_state = state EVENT;

    return ide_do_drive_cmd(drive, &rq, ide_wait);
    }
    @@ -1417,7 +1417,7 @@
    rq.special = &args;
    rq.pm = &rqpm;
    rqpm.pm_step = ide_pm_state_start_resume;
    - rqpm.pm_state = 0;
    + rqpm.pm_state = EVENT_ON;

    return ide_do_drive_cmd(drive, &rq, ide_head_wait);
    }
    --- clean/drivers/pci/pci.c 2005-02-28 00:50:43.000000000 +0100
    +++ linux/drivers/pci/pci.c 2005-02-28 15:54:24.000000000 +0100
    @@ -312,22 +312,27 @@
    /**
    * 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
    + * @state: target sleep state for the whole system. This is the value
    + * that is passed to suspend() function.
    *
    * Returns PCI power state suitable for given device and given system
    * message.
    */

    -pci_power_t pci_choose_state(struct pci_dev *dev, u32 state)
    +pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t 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();
    + switch (state EVENT) {
    + case EVENT_ON:
    + case EVENT_FREEZE:
    + return PCI_D0;
    + case EVENT_SUSPEND:
    + return PCI_D3hot;
    + default:
    + printk("They asked me for state %d\n", state EVENT);
    + BUG();
    }
    return PCI_D0;
    }
    --- clean/drivers/usb/core/usb.c 2005-01-22 21:24:52.000000000 +0100
    +++ linux/drivers/usb/core/usb.c 2005-02-28 16:01:01.000000000 +0100
    @@ -1364,7 +1364,7 @@
    driver = to_usb_driver(dev->driver);

    /* there's only one USB suspend state */
    - if (intf->dev.power.power_state)
    + if (intf->dev.power.power_state EVENT)
    return 0;

    if (driver->suspend)
    --- clean/drivers/usb/host/ehci-dbg.c 2005-01-12 11:07:40.000000000 +0100
    +++ linux/drivers/usb/host/ehci-dbg.c 2005-02-14 22:35:42.000000000 +0100
    @@ -641,7 +641,7 @@

    spin_lock_irqsave (&ehci->lock, flags);

    - if (bus->controller->power.power_state) {
    + if (bus->controller->power.power_state.event) {
    size = scnprintf (next, size,
    "bus %s, device %s (driver " DRIVER_VERSION ")\n"
    "SUSPENDED (no register access)\n",
    --- clean/drivers/usb/host/ohci-dbg.c 2005-01-12 11:07:40.000000000 +0100
    +++ linux/drivers/usb/host/ohci-dbg.c 2005-02-14 22:35:42.000000000 +0100
    @@ -625,7 +625,7 @@
    hcd->self.controller->bus_id,
    hcd_name);

    - if (bus->controller->power.power_state) {
    + if (bus->controller->power.power_state.event) {
    size -= scnprintf (next, size,
    "SUSPENDED (no register access)\n");
    goto done;
    --- clean/drivers/video/aty/atyfb_base.c 2005-02-28 00:50:43.000000000 +0100
    +++ linux/drivers/video/aty/atyfb_base.c 2005-02-28 00:50:54.000000000 +0100
    @@ -2070,12 +2070,12 @@
    struct fb_info *info = pci_get_drvdata(pdev);
    struct atyfb_par *par = (struct atyfb_par *) info->par;

    - if (pdev->dev.power.power_state == 0)
    + if (pdev->dev.power.power_state.event == EVENT_ON)
    return 0;

    acquire_console_sem();

    - if (pdev->dev.power.power_state == 2)
    + if (pdev->dev.power.power_state.event == 2)
    aty_power_mgmt(0, par);
    par->asleep = 0;

    @@ -2091,7 +2091,7 @@

    release_console_sem();

    - pdev->dev.power.power_state = 0;
    + pdev->dev.power.power_state = PMSG_ON;

    return 0;
    }
    --- clean/drivers/video/aty/radeon_pm.c 2005-02-28 00:50:43.000000000 +0100
    +++ linux/drivers/video/aty/radeon_pm.c 2005-02-28 16:06:12.000000000 +0100
    @@ -2501,31 +2501,25 @@
    }


    -static/*extern*/ int susdisking = 0;
    -
    -int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state)
    +int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
    {
    struct fb_info *info = pci_get_drvdata(pdev);
    struct radeonfb_info *rinfo = info->par;
    int i;

    - if (state == pdev->dev.power.power_state)
    + if (state EVENT == pdev->dev.power.power_state EVENT)
    return 0;

    printk(KERN_DEBUG "radeonfb (%s): suspending to state: %d...\n",
    - pci_name(pdev), state);
    + pci_name(pdev), state EVENT);

    /* For suspend-to-disk, we cheat here. We don't suspend anything and
    * let fbcon continue drawing until we are all set. That shouldn't
    * really cause any problem at this point, provided that the wakeup
    * code knows that any state in memory may not match the HW
    */
    - if (state != PM_SUSPEND_MEM)
    - goto done;
    - if (susdisking) {
    - printk("suspending to disk but state = %d\n", state);
    + if (state EVENT == EVENT_FREEZE)
    goto done;
    - }

    acquire_console_sem();

    @@ -2596,7 +2590,7 @@
    struct radeonfb_info *rinfo = info->par;
    int rc = 0;

    - if (pdev->dev.power.power_state == 0)
    + if (pdev->dev.power.power_state EVENT == EVENT_ON)
    return 0;

    if (rinfo->no_schedule) {
    @@ -2606,7 +2600,7 @@
    acquire_console_sem();

    printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
    - pci_name(pdev), pdev->dev.power.power_state);
    + pci_name(pdev), pdev->dev.power.power_state EVENT);


    if (pci_enable_device(pdev)) {
    @@ -2617,7 +2611,7 @@
    }
    pci_set_master(pdev);

    - if (pdev->dev.power.power_state == PM_SUSPEND_MEM) {
    + if (pdev->dev.power.power_state EVENT == EVENT_SUSPEND) {
    /* Wakeup chip. Check from config space if we were powered off
    * (todo: additionally, check CLK_PIN_CNTL too)
    */
    @@ -2663,7 +2657,7 @@
    else if (rinfo->dynclk == 0)
    radeon_pm_disable_dynamic_mode(rinfo);

    - pdev->dev.power.power_state = 0;
    + pdev->dev.power.power_state = PMSG_ON;

    bail:
    release_console_sem();
    --- clean/drivers/video/i810/i810_main.c 2005-01-22 21:24:52.000000000 +0100
    +++ linux/drivers/video/i810/i810_main.c 2005-01-30 23:53:29.000000000 +0100
    @@ -1492,18 +1492,18 @@
    /***********************************************************************
    * Power Management *
    ***********************************************************************/
    -static int i810fb_suspend(struct pci_dev *dev, u32 state)
    +static int i810fb_suspend(struct pci_dev *dev, pm_message_t state)
    {
    struct fb_info *info = pci_get_drvdata(dev);
    struct i810fb_par *par = (struct i810fb_par *) info->par;
    int blank = 0, prev_state = par->cur_state;

    - if (state == prev_state)
    + if (state.event == prev_state)
    return 0;

    - par->cur_state = state;
    + par->cur_state = state.event;

    - switch (state) {
    + switch (state.event) {
    case 1:
    blank = VESA_VSYNC_SUSPEND;
    break;
    --- clean/include/linux/pm.h 2005-01-12 11:07:40.000000000 +0100
    +++ linux/include/linux/pm.h 2005-02-28 18:08:20.000000000 +0100
    @@ -195,7 +195,11 @@

    struct device;

    -typedef u32 __bitwise pm_message_t;
    +#if 1
    +typedef struct pm_message {
    + int event;
    + int flags;
    +} pm_message_t;

    /*
    * There are 4 important states driver can be in:
    @@ -215,9 +219,32 @@
    * 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)
    +#define EVENT_ON 0
    +#define EVENT_FREEZE 1
    +#define EVENT_SUSPEND 2
    +
    +#define PFL_RUNTIME 1
    +
    +#define PMSG_FREEZE ({struct pm_message m; m.event = EVENT_FREEZE; m.flags = 0; m; })
    +#define PMSG_SUSPEND ({struct pm_message m; m.event = EVENT_SUSPEND; m.flags = 0; m; })
    +#define PMSG_ON ({struct pm_message m; m.event = EVENT_ON; m.flags = 0; m; })
    +#define EVENT .event
    +#else
    +
    +typedef u32 pm_message_t;
    +
    +#define EVENT_ON 0
    +#define EVENT_FREEZE 2
    +#define EVENT_SUSPEND 3
    +
    +#define PFL_RUNTIME 1
    +
    +#define PMSG_FREEZE EVENT_FREEZE
    +#define PMSG_SUSPEND EVENT_SUSPEND
    +#define PMSG_ON EVENT_ON
    +#define EVENT
    +#endif
    +

    struct dev_pm_info {
    pm_message_t power_state;
    --- clean/kernel/power/main.c 2005-02-03 22:27:26.000000000 +0100
    +++ linux/kernel/power/main.c 2005-02-28 01:16:02.000000000 +0100
    @@ -65,8 +65,10 @@
    goto Thaw;
    }

    - if ((error = device_suspend(PMSG_SUSPEND)))
    + if ((error = device_suspend(PMSG_SUSPEND))) {
    + printk(KERN_ERR "Some devices failed to suspend\n");
    goto Finish;
    + }
    return 0;
    Finish:
    if (pm_ops->finish)
    @@ -85,8 +87,10 @@

    local_irq_save(flags);

    - if ((error = device_power_down(PMSG_SUSPEND)))
    + if ((error = device_power_down(PMSG_SUSPEND))) {
    + printk(KERN_ERR "Some devices failed to power down\n");
    goto Done;
    + }
    error = pm_ops->enter(state);
    device_power_up();
    Done:
    --- clean/kernel/sys.c 2005-01-12 11:07:40.000000000 +0100
    +++ linux/kernel/sys.c 2005-01-12 11:12:10.000000000 +0100
    @@ -402,6 +402,7 @@
    case LINUX_REBOOT_CMD_HALT:
    notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
    system_state = SYSTEM_HALT;
    + device_suspend(PMSG_SUSPEND);
    device_shutdown();
    printk(KERN_EMERG "System halted.\n");
    machine_halt();
    @@ -412,6 +413,7 @@
    case LINUX_REBOOT_CMD_POWER_OFF:
    notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
    system_state = SYSTEM_POWER_OFF;
    + device_suspend(PMSG_SUSPEND);
    device_shutdown();
    printk(KERN_EMERG "Power down.\n");
    machine_power_off();
    @@ -428,6 +430,7 @@

    notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
    system_state = SYSTEM_RESTART;
    + device_suspend(PMSG_FREEZE);
    device_shutdown();
    printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
    machine_restart(buffer);

    --
    People were complaining that M$ turns users into beta-testers...
    ...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:10    [W:0.045 / U:59.624 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site