Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72df68ca authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Len Brown
Browse files

Hibernation: Move low level resume to disk.c



Move the low level restore code to kernel/power/disk.c , since the
corresponding low level hibernation code is already there.

Make restore fail if device_power_down(PMSG_PRETHAW) returns an
error.

Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Acked-by: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 2ed43b63
Loading
Loading
Loading
Loading
+48 −1
Original line number Diff line number Diff line
@@ -274,6 +274,53 @@ int hibernation_snapshot(int platform_mode)
	return error;
}

/**
 *	resume_target_kernel - prepare devices that need to be suspended with
 *	interrupts off, restore the contents of highmem that have not been
 *	restored yet from the image and run the low level code that will restore
 *	the remaining contents of memory and switch to the just restored target
 *	kernel.
 */

static int resume_target_kernel(void)
{
	int error;

	local_irq_disable();
	error = device_power_down(PMSG_PRETHAW);
	if (error) {
		printk(KERN_ERR "Some devices failed to power down, "
			"aborting resume\n");
		goto Enable_irqs;
	}
	/* We'll ignore saved state, but this gets preempt count (etc) right */
	save_processor_state();
	error = restore_highmem();
	if (!error) {
		error = swsusp_arch_resume();
		/*
		 * The code below is only ever reached in case of a failure.
		 * Otherwise execution continues at place where
		 * swsusp_arch_suspend() was called
		 */
		BUG_ON(!error);
		/* This call to restore_highmem() undos the previous one */
		restore_highmem();
	}
	/*
	 * The only reason why swsusp_arch_resume() can fail is memory being
	 * very tight, so we have to free it as soon as we can to avoid
	 * subsequent failures
	 */
	swsusp_free();
	restore_processor_state();
	touch_softlockup_watchdog();
	device_power_up();
 Enable_irqs:
	local_irq_enable();
	return error;
}

/**
 *	hibernation_restore - quiesce devices and restore the hibernation
 *	snapshot image.  If successful, control returns in hibernation_snaphot()
@@ -297,7 +344,7 @@ int hibernation_restore(int platform_mode)
	if (!error) {
		error = disable_nonboot_cpus();
		if (!error)
			error = swsusp_resume();
			error = resume_target_kernel();
		enable_nonboot_cpus();
	}
	platform_restore_cleanup(platform_mode);
+0 −1
Original line number Diff line number Diff line
@@ -152,7 +152,6 @@ extern int swsusp_swap_in_use(void);
extern int swsusp_check(void);
extern int swsusp_shrink_memory(void);
extern void swsusp_free(void);
extern int swsusp_resume(void);
extern int swsusp_read(unsigned int *flags_p);
extern int swsusp_write(unsigned int flags);
extern void swsusp_close(void);
+0 −35
Original line number Diff line number Diff line
@@ -261,38 +261,3 @@ int swsusp_shrink_memory(void)

	return 0;
}

int swsusp_resume(void)
{
	int error;

	local_irq_disable();
	/* NOTE:  device_power_down() is just a suspend() with irqs off;
	 * it has no special "power things down" semantics
	 */
	if (device_power_down(PMSG_PRETHAW))
		printk(KERN_ERR "Some devices failed to power down, very bad\n");
	/* We'll ignore saved state, but this gets preempt count (etc) right */
	save_processor_state();
	error = restore_highmem();
	if (!error) {
		error = swsusp_arch_resume();
		/* The code below is only ever reached in case of a failure.
		 * Otherwise execution continues at place where
		 * swsusp_arch_suspend() was called
        	 */
		BUG_ON(!error);
		/* This call to restore_highmem() undos the previous one */
		restore_highmem();
	}
	/* The only reason why swsusp_arch_resume() can fail is memory being
	 * very tight, so we have to free it as soon as we can to avoid
	 * subsequent failures
	 */
	swsusp_free();
	restore_processor_state();
	touch_softlockup_watchdog();
	device_power_up();
	local_irq_enable();
	return error;
}