int pm_suspend_disk(void) { int error; if ((error = prepare())) return error; pr_debug("PM: Attempting to suspend to disk.\n"); if (pm_disk_mode == PM_DISK_FIRMWARE) return pm_ops->enter(PM_SUSPEND_DISK); pr_debug("PM: snapshotting memory.\n"); in_suspend = 1; if ((error = swsusp_suspend())) goto Done; if (in_suspend) { pr_debug("PM: writing image.\n"); error = swsusp_write(); if (!error) power_down(pm_disk_mode); } else pr_debug("PM: Image restored successfully.\n"); swsusp_free(); Done: finish(); return error; }
int pm_suspend_disk(void) { int error; error = prepare_processes(); if (error) return error; if (pm_disk_mode == PM_DISK_TESTPROC) return 0; suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) { resume_console(); printk("Some devices failed to suspend\n"); goto Thaw; } if (pm_disk_mode == PM_DISK_TEST) { printk("swsusp debug: Waiting for 5 seconds.\n"); mdelay(5000); goto Done; } pr_debug("PM: snapshotting memory.\n"); in_suspend = 1; if ((error = swsusp_suspend())) goto Done; if (in_suspend) { device_resume(); resume_console(); pr_debug("PM: writing image.\n"); error = swsusp_write(); if (!error) power_down(pm_disk_mode); else { swsusp_free(); goto Thaw; } } else { pr_debug("PM: Image restored successfully.\n"); } swsusp_free(); Done: device_resume(); resume_console(); Thaw: unprepare_processes(); return error; }
int pm_suspend_disk(void) { int error; error = prepare_processes(); if (error) return error; error = device_suspend(PMSG_FREEZE); if (error) { printk("Some devices failed to suspend\n"); unprepare_processes(); return error; } pr_debug("PM: snapshotting memory.\n"); in_suspend = 1; if ((error = swsusp_suspend())) goto Done; if (in_suspend) { pr_debug("PM: writing image.\n"); error = swsusp_write(); if (!error) power_down(pm_disk_mode); else { /* swsusp_write can not fail in device_resume, no need to do second device_resume */ swsusp_free(); unprepare_processes(); return error; } } else pr_debug("PM: Image restored successfully.\n"); swsusp_free(); Done: device_resume(); unprepare_processes(); return error; }
static inline int snapshot_suspend(int platform_suspend) { int error; mutex_lock(&pm_mutex); /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (error) goto Finish; if (platform_suspend) { error = platform_prepare(); if (error) goto Finish; } suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) goto Resume_devices; error = disable_nonboot_cpus(); if (!error) { in_suspend = 1; error = swsusp_suspend(); } enable_nonboot_cpus(); Resume_devices: if (platform_suspend) platform_finish(); device_resume(); resume_console(); Finish: mutex_unlock(&pm_mutex); return error; }
int pm_suspend_disk(void) { int error; error = prepare_processes(); if (error) return error; if (pm_disk_mode == PM_DISK_TESTPROC) { printk("swsusp debug: Waiting for 5 seconds.\n"); mdelay(5000); goto Thaw; } /* Allocate memory management structures */ error = create_basic_memory_bitmaps(); if (error) goto Thaw; /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (error) goto Finish; error = platform_prepare(); if (error) goto Finish; suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) { printk(KERN_ERR "PM: Some devices failed to suspend\n"); goto Resume_devices; } error = disable_nonboot_cpus(); if (error) goto Enable_cpus; if (pm_disk_mode == PM_DISK_TEST) { printk("swsusp debug: Waiting for 5 seconds.\n"); mdelay(5000); goto Enable_cpus; } pr_debug("PM: snapshotting memory.\n"); in_suspend = 1; error = swsusp_suspend(); if (error) goto Enable_cpus; if (in_suspend) { enable_nonboot_cpus(); platform_finish(); device_resume(); resume_console(); pr_debug("PM: writing image.\n"); error = swsusp_write(); if (!error) power_down(pm_disk_mode); else { swsusp_free(); goto Finish; } } else { pr_debug("PM: Image restored successfully.\n"); } swsusp_free(); Enable_cpus: enable_nonboot_cpus(); Resume_devices: platform_finish(); device_resume(); resume_console(); Finish: free_basic_memory_bitmaps(); Thaw: unprepare_processes(); return error; }
static int snapshot_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int error = 0; struct snapshot_data *data; loff_t offset, avail; if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR) return -ENOTTY; if (!capable(CAP_SYS_ADMIN)) return -EPERM; data = filp->private_data; switch (cmd) { case SNAPSHOT_FREEZE: if (data->frozen) break; down(&pm_sem); disable_nonboot_cpus(); if (freeze_processes()) { thaw_processes(); enable_nonboot_cpus(); error = -EBUSY; } up(&pm_sem); if (!error) data->frozen = 1; break; case SNAPSHOT_UNFREEZE: if (!data->frozen) break; down(&pm_sem); thaw_processes(); enable_nonboot_cpus(); up(&pm_sem); data->frozen = 0; break; case SNAPSHOT_ATOMIC_SNAPSHOT: if (data->mode != O_RDONLY || !data->frozen || data->ready) { error = -EPERM; break; } down(&pm_sem); /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (!error) { error = device_suspend(PMSG_FREEZE); if (!error) { in_suspend = 1; error = swsusp_suspend(); device_resume(); } } up(&pm_sem); if (!error) error = put_user(in_suspend, (unsigned int __user *)arg); if (!error) data->ready = 1; break; case SNAPSHOT_ATOMIC_RESTORE: if (data->mode != O_WRONLY || !data->frozen || !snapshot_image_loaded(&data->handle)) { error = -EPERM; break; } down(&pm_sem); pm_prepare_console(); error = device_suspend(PMSG_FREEZE); if (!error) { error = swsusp_resume(); device_resume(); } pm_restore_console(); up(&pm_sem); break; case SNAPSHOT_FREE: swsusp_free(); memset(&data->handle, 0, sizeof(struct snapshot_handle)); data->ready = 0; break; case SNAPSHOT_SET_IMAGE_SIZE: image_size = arg; break; case SNAPSHOT_AVAIL_SWAP: avail = count_swap_pages(data->swap, 1); avail <<= PAGE_SHIFT; error = put_user(avail, (loff_t __user *)arg); break; case SNAPSHOT_GET_SWAP_PAGE: if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { error = -ENODEV; break; } if (!data->bitmap) { data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0)); if (!data->bitmap) { error = -ENOMEM; break; } } offset = alloc_swap_page(data->swap, data->bitmap); if (offset) { offset <<= PAGE_SHIFT; error = put_user(offset, (loff_t __user *)arg); } else { error = -ENOSPC; } break; case SNAPSHOT_FREE_SWAP_PAGES: if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { error = -ENODEV; break; } free_all_swap_pages(data->swap, data->bitmap); free_bitmap(data->bitmap); data->bitmap = NULL; break; case SNAPSHOT_SET_SWAP_FILE: if (!data->bitmap) { /* * User space encodes device types as two-byte values, * so we need to recode them */ if (old_decode_dev(arg)) { data->swap = swap_type_of(old_decode_dev(arg)); if (data->swap < 0) error = -ENODEV; } else { data->swap = -1; error = -EINVAL; } } else { error = -EPERM; } break; case SNAPSHOT_S2RAM: if (!data->frozen) { error = -EPERM; break; } if (down_trylock(&pm_sem)) { error = -EBUSY; break; } if (pm_ops->prepare) { error = pm_ops->prepare(PM_SUSPEND_MEM); if (error) goto OutS3; } /* Put devices to sleep */ error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Failed to suspend some devices.\n"); } else { /* Enter S3, system is already frozen */ suspend_enter(PM_SUSPEND_MEM); /* Wake up devices */ device_resume(); } if (pm_ops->finish) pm_ops->finish(PM_SUSPEND_MEM); OutS3: up(&pm_sem); break; default: error = -ENOTTY; } return error; }