Пример #1
0
static int prepare_processes(void)
{
	int error;

	pm_prepare_console();
	sys_sync();
	disable_nonboot_cpus();

	if (freeze_processes()) {
		error = -EBUSY;
		goto thaw;
	}

	if (pm_disk_mode == PM_DISK_PLATFORM) {
		if (pm_ops && pm_ops->prepare) {
			if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
				goto thaw;
		}
	}

	/* Free memory before shutting down devices. */
	free_some_memory();
	return 0;
thaw:
	thaw_processes();
	enable_nonboot_cpus();
	pm_restore_console();
	return error;
}
Пример #2
0
/**
 *	suspend_enter - enter the desired system sleep state.
 *	@state:		state to enter
 *
 *	This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state)
{
	int error;

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			return error;
	}

	error = dpm_suspend_noirq(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "PM: Some devices failed to power down\n");
		goto Platfrom_finish;
	}

	if (suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Power_up_devices;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	error = sysdev_suspend(PMSG_SUSPEND);
	if (!error) {
		if (!suspend_test(TEST_CORE) && pm_check_wakeup_events()) {
			error = suspend_ops->enter(state);
			events_check_enabled = false;
		}
		sysdev_resume();
	}

	arch_suspend_enable_irqs();
	BUG_ON(irqs_disabled());

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_wake:
	if (suspend_ops->wake)
		suspend_ops->wake();

 Power_up_devices:
	dpm_resume_noirq(PMSG_RESUME);

 Platfrom_finish:
	if (suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #3
0
static inline int snapshot_restore(int platform_suspend)
{
	int error;

	mutex_lock(&pm_mutex);
	pm_prepare_console();
	if (platform_suspend) {
		error = platform_prepare();
		if (error)
			goto Finish;
	}
	suspend_console();
	error = device_suspend(PMSG_PRETHAW);
	if (error)
		goto Resume_devices;

	error = disable_nonboot_cpus();
	if (!error)
		error = swsusp_resume();

	enable_nonboot_cpus();
 Resume_devices:
	if (platform_suspend)
		platform_finish();

	device_resume();
	resume_console();
 Finish:
	pm_restore_console();
	mutex_unlock(&pm_mutex);
	return error;
}
Пример #4
0
static int prepare_processes(void)
{
	int error = 0;

	pm_prepare_console();

	error = disable_nonboot_cpus();
	if (error)
		goto enable_cpus;

	if (freeze_processes()) {
		error = -EBUSY;
		goto thaw;
	}

	if (pm_disk_mode == PM_DISK_TESTPROC) {
		printk("swsusp debug: Waiting for 5 seconds.\n");
		mdelay(5000);
		goto thaw;
	}

	/* Free memory before shutting down devices. */
	if (!(error = swsusp_shrink_memory()))
		return 0;
thaw:
	thaw_processes();
enable_cpus:
	enable_nonboot_cpus();
	pm_restore_console();
	return error;
}
Пример #5
0
/**
 *	suspend_devices_and_enter - suspend devices and enter the desired system sleep
 *			  state.
 *	@state:		  state to enter
 */
int suspend_devices_and_enter(suspend_state_t state)
{
	int error;

	if (!pm_ops)
		return -ENOSYS;

	if (pm_ops->set_target) {
		error = pm_ops->set_target(state);
		if (error)
			return error;
	}
	suspend_console();
	error = device_suspend(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "Some devices failed to suspend\n");
		goto Resume_console;
	}
	if (pm_ops->prepare) {
		error = pm_ops->prepare(state);
		if (error)
			goto Resume_devices;
	}
	error = disable_nonboot_cpus();
	if (!error)
		suspend_enter(state);

	enable_nonboot_cpus();
	pm_finish(state);
 Resume_devices:
	device_resume();
 Resume_console:
	resume_console();
	return error;
}
Пример #6
0
static int suspend_enter(suspend_state_t state, bool *wakeup)
{
	int error;

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			goto Platform_finish;
	}

	error = dpm_suspend_end(PMSG_SUSPEND);
	if (error) {
		pr_debug(KERN_ERR "PM: Some devices failed to power down\n");
		goto Platform_finish;
	}

	if (suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Platform_wake;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	error = syscore_suspend();
	if (!error) {
		*wakeup = pm_wakeup_pending();
		if (!(suspend_test(TEST_CORE) || *wakeup)) {
			error = suspend_ops->enter(state);
			events_check_enabled = false;
		}
		syscore_resume();
	}

	arch_suspend_enable_irqs();
	BUG_ON(irqs_disabled());

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_wake:
	if (suspend_ops->wake)
		suspend_ops->wake();

	dpm_resume_start(PMSG_RESUME);

 Platform_finish:
	if (suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #7
0
/**
 *	suspend_enter - enter the desired system sleep state.
 *	@state:		state to enter
 *
 *	This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state)
{
	int error;

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			return error;
	}

	error = dpm_suspend_noirq(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "PM: Some devices failed to power down\n");
		goto Platfrom_finish;
	}

	if (suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Power_up_devices;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	error = sysdev_suspend(PMSG_SUSPEND);
	if (!error) {
		//Check there is no NIRQ1 wakeup event before going in suspend
		if (!suspend_test(TEST_CORE) && !(omap_readl(0x4A10019C)&0x80000000) )
			error = suspend_ops->enter(state);
		sysdev_resume();
	}

	arch_suspend_enable_irqs();
	BUG_ON(irqs_disabled());

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_wake:
	if (suspend_ops->wake)
		suspend_ops->wake();

 Power_up_devices:
	dpm_resume_noirq(PMSG_RESUME);

 Platfrom_finish:
	if (suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #8
0
/**
 *	suspend_devices_and_enter - suspend devices and enter the desired system
 *				    sleep state.
 *	@state:		  state to enter
 */
int suspend_devices_and_enter(suspend_state_t state)
{
	int error, ftrace_save;

	if (!suspend_ops)
		return -ENOSYS;

	if (suspend_ops->begin) {
		error = suspend_ops->begin(state);
		if (error)
			goto Close;
	}
	suspend_console();
	ftrace_save = __ftrace_enabled_save();
	suspend_test_start();
	error = device_suspend(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "PM: Some devices failed to suspend\n");
		goto Recover_platform;
	}
	suspend_test_finish("suspend devices");
	if (suspend_test(TEST_DEVICES))
		goto Recover_platform;

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			goto Resume_devices;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Finish;

	error = disable_nonboot_cpus();
	if (!error && !suspend_test(TEST_CPUS))
		suspend_enter(state);

	enable_nonboot_cpus();
 Finish:
	if (suspend_ops->finish)
		suspend_ops->finish();
 Resume_devices:
	suspend_test_start();
	device_resume(PMSG_RESUME);
	suspend_test_finish("resume devices");
	__ftrace_enabled_restore(ftrace_save);
	resume_console();
 Close:
	if (suspend_ops->end)
		suspend_ops->end();
	return error;

 Recover_platform:
	if (suspend_ops->recover)
		suspend_ops->recover();
	goto Resume_devices;
}
Пример #9
0
/**
 *	suspend_enter - enter the desired system sleep state.
 *	@state:		state to enter
 *
 *	This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state)
{
	int error;

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			goto Platform_finish;
	}

	error = dpm_suspend_noirq(PMSG_SUSPEND);
	if (error) {
;
		goto Platform_finish;
	}

	if (suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Platform_wake;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;


	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Platform_wake;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	error = syscore_suspend();
	if (!error) {
		if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) {
			error = suspend_ops->enter(state);
			events_check_enabled = false;
		}
		syscore_resume();
	}

	arch_suspend_enable_irqs();
	BUG_ON(irqs_disabled());

 Platform_wake:
	if (suspend_ops->wake)
		suspend_ops->wake();

	dpm_resume_noirq(PMSG_RESUME);

 Platform_finish:
	if (suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #10
0
int hibernation_platform_enter(void)
{
	int error;

	if (!hibernation_ops)
		return -ENOSYS;

	/*
	 * We have cancelled the power transition by running
	 * hibernation_ops->finish() before saving the image, so we should let
	 * the firmware know that we're going to enter the sleep state after all
	 */
	error = hibernation_ops->begin();
	if (error)
		goto Close;

	suspend_console();
	error = device_suspend(PMSG_HIBERNATE);
	if (error) {
		if (hibernation_ops->recover)
			hibernation_ops->recover();
		goto Resume_devices;
	}

	error = hibernation_ops->prepare();
	if (error)
		goto Resume_devices;

	error = disable_nonboot_cpus();
	if (error)
		goto Finish;

	device_pm_lock();
	local_irq_disable();
	error = device_power_down(PMSG_HIBERNATE);
	if (!error) {
		hibernation_ops->enter();
		/* We should never get here */
		while (1);
	}
	local_irq_enable();
	device_pm_unlock();

	/*
	 * We don't need to reenable the nonboot CPUs or resume consoles, since
	 * the system is going to be halted anyway.
	 */
 Finish:
	hibernation_ops->finish();
 Resume_devices:
	device_resume(PMSG_RESTORE);
	resume_console();
 Close:
	hibernation_ops->end();
	return error;
}
Пример #11
0
static void ambench_apbread(void)
{
	u64					raw_counter = 0;
	u64					amba_counter = 0;
	unsigned long				flags;

	disable_nonboot_cpus();
	local_irq_save(flags);

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		raw_counter++;
	} while(__raw_readl((const volatile void *)TIMER1_STATUS_REG));

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		amba_counter++;
	} while(amba_readl(TIMER1_STATUS_REG));
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);

	local_irq_restore(flags);
	enable_nonboot_cpus();

#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL)
	raw_counter *= get_apb_bus_freq_hz();
#else
	raw_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
#endif
	do_div(raw_counter, APBREAD_RELOAD_NUM);
#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL)
	amba_counter *= get_apb_bus_freq_hz();
#else
	amba_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
#endif
	do_div(amba_counter, APBREAD_RELOAD_NUM);
	pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n",
		cpu_architecture(), raw_counter);
	pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n",
		cpu_architecture(), amba_counter);
}
Пример #12
0
/**
 *	kernel_power_off - power_off the system
 *
 *	Shutdown everything and perform a clean system power_off.
 */
void kernel_power_off(void)
{
	kernel_shutdown_prepare(SYSTEM_POWER_OFF);
	if (pm_power_off_prepare)
		pm_power_off_prepare();
	disable_nonboot_cpus();
	sysdev_shutdown();
	printk(KERN_EMERG "Power down.\n");
	machine_power_off();
}
Пример #13
0
/**
 *	suspend_enter - enter the desired system sleep state.
 *	@state:		state to enter
 *
 *	This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state)
{
	int error;

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			return error;
	}

	error = dpm_suspend_noirq(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "PM: Some devices failed to power down\n");
		goto Platfrom_finish;
	}

	if (suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Power_up_devices;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	error = _suspend_enter(state);
#ifdef CONFIG_QUICK_WAKEUP
		while (!error && !quickwakeup_execute()) {
			if (has_wake_lock(WAKE_LOCK_SUSPEND))
				break;
			error = _suspend_enter(state);
		}
#endif

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_wake:
	if (suspend_ops->wake)
		suspend_ops->wake();

 Power_up_devices:
	dpm_resume_noirq(PMSG_RESUME);

 Platfrom_finish:
	if (suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #14
0
int hibernation_snapshot(int platform_mode)
{
	int error;

	/* Free memory before shutting down devices. */
	error = swsusp_shrink_memory();
	if (error)
		return error;

	error = platform_begin(platform_mode);
	if (error)
		goto Close;

	suspend_console();
	error = device_suspend(PMSG_FREEZE);
	if (error)
		goto Recover_platform;

	if (hibernation_test(TEST_DEVICES))
		goto Recover_platform;

	error = platform_pre_snapshot(platform_mode);
	if (error || hibernation_test(TEST_PLATFORM))
		goto Finish;

	error = disable_nonboot_cpus();
	if (!error) {
		if (hibernation_test(TEST_CPUS))
			goto Enable_cpus;

		if (hibernation_testmode(HIBERNATION_TEST))
			goto Enable_cpus;

		error = create_image(platform_mode);
		/* Control returns here after successful restore */
	}
 Enable_cpus:
	enable_nonboot_cpus();
 Finish:
	platform_finish(platform_mode);
 Resume_devices:
	device_resume(in_suspend ?
		(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
	resume_console();
 Close:
	platform_end(platform_mode);
	return error;

 Recover_platform:
	platform_recover(platform_mode);
	goto Resume_devices;
}
static int suspend_prepare(suspend_state_t state)
{
	int error = 0;
	unsigned int free_pages;

	if (!pm_ops || !pm_ops->enter)
		return -EPERM;

	pm_prepare_console();

	disable_nonboot_cpus();

	if (num_online_cpus() != 1) {
		error = -EPERM;
		goto Enable_cpu;
	}

	if (freeze_processes()) {
		error = -EAGAIN;
		goto Thaw;
	}

	if ((free_pages = nr_free_pages()) < FREE_PAGE_NUMBER) {
		pr_debug("PM: free some memory\n");
		shrink_all_memory(FREE_PAGE_NUMBER - free_pages);
		if (nr_free_pages() < FREE_PAGE_NUMBER) {
			error = -ENOMEM;
			printk(KERN_ERR "PM: No enough memory\n");
			goto Thaw;
		}
	}

	if (pm_ops->prepare) {
		if ((error = pm_ops->prepare(state)))
			goto Thaw;
	}

	if ((error = device_suspend(PMSG_SUSPEND))) {
		printk(KERN_ERR "Some devices failed to suspend\n");
		goto Finish;
	}
	return 0;
 Finish:
	if (pm_ops->finish)
		pm_ops->finish(state);
 Thaw:
	thaw_processes();
 Enable_cpu:
	enable_nonboot_cpus();
	pm_restore_console();
	return error;
}
Пример #16
0
static int suspend_prepare(suspend_state_t state)
{
	int error;
	unsigned int free_pages;

	if (!pm_ops || !pm_ops->enter)
		return -EPERM;

	pm_prepare_console();

	if (freeze_processes()) {
		error = -EAGAIN;
		goto Thaw;
	}

	if ((free_pages = global_page_state(NR_FREE_PAGES))
			< FREE_PAGE_NUMBER) {
		pr_debug("PM: free some memory\n");
		shrink_all_memory(FREE_PAGE_NUMBER - free_pages);
		if (nr_free_pages() < FREE_PAGE_NUMBER) {
			error = -ENOMEM;
			printk(KERN_ERR "PM: No enough memory\n");
			goto Thaw;
		}
	}

	if (pm_ops->prepare) {
		if ((error = pm_ops->prepare(state)))
			goto Thaw;
	}

	suspend_console();
	error = device_suspend(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "Some devices failed to suspend\n");
		goto Resume_devices;
	}
	error = disable_nonboot_cpus();
	if (!error)
		return 0;

	enable_nonboot_cpus();
 Resume_devices:
	pm_finish(state);
	device_resume();
	resume_console();
 Thaw:
	thaw_processes();
	pm_restore_console();
	return error;
}
Пример #17
0
static void ambench_apbread(void)
{
	u64					raw_counter = 0;
	u64					amba_counter = 0;
	unsigned long				flags;

	disable_nonboot_cpus();
	local_irq_save(flags);

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		raw_counter++;
	} while(__raw_readl(TIMER1_STATUS_REG));

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		amba_counter++;
	} while(amba_readl(TIMER1_STATUS_REG));
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);

	local_irq_restore(flags);
	enable_nonboot_cpus();

	raw_counter *= get_apb_bus_freq_hz();
	do_div(raw_counter, APBREAD_RELOAD_NUM);
	amba_counter *= get_apb_bus_freq_hz();
	do_div(amba_counter, APBREAD_RELOAD_NUM);
	pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n",
		cpu_architecture(), raw_counter);
	pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n",
		cpu_architecture(), amba_counter);
}
Пример #18
0
int hibernation_snapshot(int platform_mode)
{
	int error;

	/* Free memory before shutting down devices. */
	error = swsusp_shrink_memory();
	if (error)
		return error;

	error = platform_start(platform_mode);
	if (error)
		return error;

	suspend_console();
	error = device_suspend(PMSG_FREEZE);
	if (error)
		goto Resume_console;

	error = platform_pre_snapshot(platform_mode);
	if (error)
		goto Resume_devices;

	error = disable_nonboot_cpus();
	if (!error) {
		if (hibernation_mode != HIBERNATION_TEST) {
			in_suspend = 1;
			error = create_image(platform_mode);
			/* Control returns here after successful restore */
		} else {
			printk("swsusp debug: Waiting for 5 seconds.\n");
			mdelay(5000);
		}
	}
	enable_nonboot_cpus();
 Resume_devices:
	platform_finish(platform_mode);
	device_resume();
 Resume_console:
	resume_console();
	return error;
}
Пример #19
0
void machine_crash_shutdown(struct pt_regs *regs)
{
	unsigned long msecs;

	local_irq_disable();
	disable_nonboot_cpus();

	atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
	smp_call_function(machine_crash_nonpanic_core, NULL, false);
	msecs = 1000; /* Wait at most a second for the other cpus to stop */
	while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
		mdelay(1);
		msecs--;
	}
	if (atomic_read(&waiting_for_crash_ipi) > 0)
		pr_warn("Non-crashing CPUs did not react to IPI\n");

	crash_save_cpu(regs, smp_processor_id());
	machine_kexec_mask_interrupts();

	pr_info("Loading crashdump kernel...\n");
}
Пример #20
0
int hibernation_restore(int platform_mode)
{
	int error;

	pm_prepare_console();
	suspend_console();
	error = device_suspend(PMSG_PRETHAW);
	if (error)
		goto Finish;

	error = platform_pre_restore(platform_mode);
	if (!error) {
		error = disable_nonboot_cpus();
		if (!error)
			error = swsusp_resume();
		enable_nonboot_cpus();
	}
	platform_restore_cleanup(platform_mode);
	device_resume();
 Finish:
	resume_console();
	pm_restore_console();
	return error;
}
Пример #21
0
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;
}
Пример #22
0
int hibernation_restore(int platform_mode)
{
	int error;

	pm_prepare_console();
	suspend_console();
	error = device_suspend(PMSG_QUIESCE);
	if (error)
		goto Finish;

	error = platform_pre_restore(platform_mode);
	if (!error) {
		error = disable_nonboot_cpus();
		if (!error)
			error = resume_target_kernel();
		enable_nonboot_cpus();
	}
	platform_restore_cleanup(platform_mode);
	device_resume(PMSG_RECOVER);
 Finish:
	resume_console();
	pm_restore_console();
	return error;
}
Пример #23
0
/**
 * hibernation_platform_enter - Power off the system using the platform driver.
 */
int hibernation_platform_enter(void)
{
	int error;

	if (!hibernation_ops)
		return -ENOSYS;

	/*
	 * We have cancelled the power transition by running
	 * hibernation_ops->finish() before saving the image, so we should let
	 * the firmware know that we're going to enter the sleep state after all
	 */
	error = hibernation_ops->begin();
	if (error)
		goto Close;

	entering_platform_hibernation = true;
	suspend_console();
	error = dpm_suspend_start(PMSG_HIBERNATE);
	if (error) {
		if (hibernation_ops->recover)
			hibernation_ops->recover();
		goto Resume_devices;
	}

	error = dpm_suspend_end(PMSG_HIBERNATE);
	if (error)
		goto Resume_devices;

	error = hibernation_ops->prepare();
	if (error)
		goto Platform_finish;

	error = disable_nonboot_cpus();
	if (error)
		goto Enable_cpus;

	local_irq_disable();
	syscore_suspend();
	if (pm_wakeup_pending()) {
		error = -EAGAIN;
		goto Power_up;
	}

	hibernation_ops->enter();
	/* We should never get here */
	while (1);

 Power_up:
	syscore_resume();
	local_irq_enable();

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_finish:
	hibernation_ops->finish();

	dpm_resume_start(PMSG_RESTORE);

 Resume_devices:
	entering_platform_hibernation = false;
	dpm_resume_end(PMSG_RESTORE);
	resume_console();

 Close:
	hibernation_ops->end();

	return error;
}
Пример #24
0
int __weak hibernate_resume_nonboot_cpu_disable(void)
{
	return disable_nonboot_cpus();
}
Пример #25
0
/**
 * create_image - Create a hibernation image.
 * @platform_mode: Whether or not to use the platform driver.
 *
 * Execute device drivers' "late" and "noirq" freeze callbacks, create a
 * hibernation image and run the drivers' "noirq" and "early" thaw callbacks.
 *
 * Control reappears in this routine after the subsequent restore.
 */
static int create_image(int platform_mode)
{
	int error;

	error = dpm_suspend_end(PMSG_FREEZE);
	if (error) {
		pr_err("Some devices failed to power down, aborting hibernation\n");
		return error;
	}

	error = platform_pre_snapshot(platform_mode);
	if (error || hibernation_test(TEST_PLATFORM))
		goto Platform_finish;

	error = disable_nonboot_cpus();
	if (error || hibernation_test(TEST_CPUS))
		goto Enable_cpus;

	local_irq_disable();

	error = syscore_suspend();
	if (error) {
		pr_err("Some system devices failed to power down, aborting hibernation\n");
		goto Enable_irqs;
	}

	if (hibernation_test(TEST_CORE) || pm_wakeup_pending())
		goto Power_up;

	in_suspend = 1;
	save_processor_state();
	trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, true);
	error = swsusp_arch_suspend();
	/* Restore control flow magically appears here */
	restore_processor_state();
	trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false);
	if (error)
		pr_err("Error %d creating hibernation image\n", error);

	if (!in_suspend) {
		events_check_enabled = false;
		clear_free_pages();
	}

	platform_leave(platform_mode);

 Power_up:
	syscore_resume();

 Enable_irqs:
	local_irq_enable();

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_finish:
	platform_finish(platform_mode);

	dpm_resume_start(in_suspend ?
		(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);

	return error;
}
Пример #26
0
/**
 * suspend_enter - Make the system enter the given sleep state.
 * @state: System sleep state to enter.
 * @wakeup: Returns information that the sleep state should not be re-entered.
 *
 * This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state, bool *wakeup)
{
	int error;

	if (need_suspend_ops(state) && suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			goto Platform_finish;
	}

	error = dpm_suspend_end(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "PM: Some devices failed to power down\n");
		goto Platform_finish;
	}

	if (need_suspend_ops(state) && suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Platform_wake;
	}

	/*
	 * PM_SUSPEND_FREEZE equals
	 * frozen processes + suspended devices + idle processors.
	 * Thus we should invoke freeze_enter() soon after
	 * all the devices are suspended.
	 */
	if (state == PM_SUSPEND_FREEZE) {
		freeze_enter();
		goto Platform_wake;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	error = syscore_suspend();
	if (!error) {
		*wakeup = pm_wakeup_pending();
		if (!(suspend_test(TEST_CORE) || *wakeup)) {
			error = suspend_ops->enter(state);
			events_check_enabled = false;
		}
		syscore_resume();
	}

	arch_suspend_enable_irqs();
	BUG_ON(irqs_disabled());

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_wake:
	if (need_suspend_ops(state) && suspend_ops->wake)
		suspend_ops->wake();

	dpm_resume_start(PMSG_RESUME);

 Platform_finish:
	if (need_suspend_ops(state) && suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #27
0
/**
 * suspend_enter - Make the system enter the given sleep state.
 * @state: System sleep state to enter.
 * @wakeup: Returns information that the sleep state should not be re-entered.
 *
 * This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state, bool *wakeup)
{
	int error;

#ifdef CONFIG_SEC_GPIO_DVS
    /************************ Caution !!! ****************************/
    /* This function must be located in appropriate SLEEP position
     * in accordance with the specification of each BB vendor.
     */
    /************************ Caution !!! ****************************/
    gpio_dvs_check_sleepgpio();
#ifdef SECGPIO_SLEEP_DEBUGGING
    /************************ Caution !!! ****************************/
    /* This func. must be located in an appropriate position for GPIO SLEEP debugging
     * in accordance with the specification of each BB vendor, and 
     * the func. must be called after calling the function "gpio_dvs_check_sleepgpio"
     */
    /************************ Caution !!! ****************************/
    gpio_dvs_set_sleepgpio();
#endif
#endif

	if (suspend_ops->prepare) {
		error = suspend_ops->prepare();
		if (error)
			goto Platform_finish;
	}

	error = dpm_suspend_end(PMSG_SUSPEND);
	if (error) {
		printk(KERN_ERR "PM: Some devices failed to power down\n");
		goto Platform_finish;
	}

	if (suspend_ops->prepare_late) {
		error = suspend_ops->prepare_late();
		if (error)
			goto Platform_wake;
	}

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	error = disable_nonboot_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	error = syscore_suspend();
	if (!error) {
		*wakeup = pm_wakeup_pending();
		if (!(suspend_test(TEST_CORE) || *wakeup)) {
			error = suspend_ops->enter(state);
			events_check_enabled = false;
		}
		syscore_resume();
	}

	arch_suspend_enable_irqs();
	BUG_ON(irqs_disabled());

 Enable_cpus:
	enable_nonboot_cpus();

 Platform_wake:
	if (suspend_ops->wake)
		suspend_ops->wake();

	dpm_resume_start(PMSG_RESUME);

 Platform_finish:
	if (suspend_ops->finish)
		suspend_ops->finish();

	return error;
}
Пример #28
0
/* Main interface to do xen specific suspend/resume */
static int enter_state(u32 state)
{
    unsigned long flags;
    int error;
    unsigned long cr4;

    if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
        return -EINVAL;

    if ( !spin_trylock(&pm_lock) )
        return -EBUSY;

    BUG_ON(system_state != SYS_STATE_active);
    system_state = SYS_STATE_suspend;

    printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state);

    freeze_domains();

    acpi_dmar_reinstate();

    if ( (error = disable_nonboot_cpus()) )
    {
        system_state = SYS_STATE_resume;
        goto enable_cpu;
    }

    cpufreq_del_cpu(0);

    hvm_cpu_down();

    acpi_sleep_prepare(state);

    console_start_sync();
    printk("Entering ACPI S%d state.\n", state);

    local_irq_save(flags);
    spin_debug_disable();

    if ( (error = device_power_down()) )
    {
        printk(XENLOG_ERR "Some devices failed to power down.");
        system_state = SYS_STATE_resume;
        goto done;
    }

    ACPI_FLUSH_CPU_CACHE();

    switch ( state )
    {
    case ACPI_STATE_S3:
        do_suspend_lowlevel();
        system_reset_counter++;
        error = tboot_s3_resume();
        break;
    case ACPI_STATE_S5:
        acpi_enter_sleep_state(ACPI_STATE_S5);
        break;
    default:
        error = -EINVAL;
        break;
    }

    system_state = SYS_STATE_resume;

    /* Restore CR4 and EFER from cached values. */
    cr4 = read_cr4();
    write_cr4(cr4 & ~X86_CR4_MCE);
    write_efer(read_efer());

    device_power_up();

    mcheck_init(&boot_cpu_data, 0);
    write_cr4(cr4);

    printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state);

    if ( (state == ACPI_STATE_S3) && error )
        tboot_s3_error(error);

 done:
    spin_debug_enable();
    local_irq_restore(flags);
    console_end_sync();
    acpi_sleep_post(state);
    if ( hvm_cpu_up() )
        BUG();

 enable_cpu:
    cpufreq_add_cpu(0);
    microcode_resume_cpu(0);
    rcu_barrier();
    mtrr_aps_sync_begin();
    enable_nonboot_cpus();
    mtrr_aps_sync_end();
    adjust_vtd_irq_affinities();
    acpi_dmar_zap();
    thaw_domains();
    system_state = SYS_STATE_active;
    spin_unlock(&pm_lock);
    return error;
}
Пример #29
0
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 avail;
	sector_t offset;

	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;
		mutex_lock(&pm_mutex);
		if (freeze_processes()) {
			thaw_processes();
			error = -EBUSY;
		}
		mutex_unlock(&pm_mutex);
		if (!error)
			data->frozen = 1;
		break;

	case SNAPSHOT_UNFREEZE:
		if (!data->frozen || data->ready)
			break;
		mutex_lock(&pm_mutex);
		thaw_processes();
		mutex_unlock(&pm_mutex);
		data->frozen = 0;
		break;

	case SNAPSHOT_ATOMIC_SNAPSHOT:
		if (data->mode != O_RDONLY || !data->frozen  || data->ready) {
			error = -EPERM;
			break;
		}
		error = snapshot_suspend(data->platform_suspend);
		if (!error)
			error = put_user(in_suspend, (unsigned int __user *)arg);
		if (!error)
			data->ready = 1;
		break;

	case SNAPSHOT_ATOMIC_RESTORE:
		snapshot_write_finalize(&data->handle);
		if (data->mode != O_WRONLY || !data->frozen ||
		    !snapshot_image_loaded(&data->handle)) {
			error = -EPERM;
			break;
		}
		error = snapshot_restore(data->platform_suspend);
		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;
		}
		offset = alloc_swapdev_block(data->swap);
		if (offset) {
			offset <<= PAGE_SHIFT;
			error = put_user(offset, (sector_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);
		break;

	case SNAPSHOT_SET_SWAP_FILE:
		if (!swsusp_swap_in_use()) {
			/*
			 * 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),
							0, NULL);
				if (data->swap < 0)
					error = -ENODEV;
			} else {
				data->swap = -1;
				error = -EINVAL;
			}
		} else {
			error = -EPERM;
		}
		break;

	case SNAPSHOT_S2RAM:
		if (!pm_ops) {
			error = -ENOSYS;
			break;
		}

		if (!data->frozen) {
			error = -EPERM;
			break;
		}

		if (!mutex_trylock(&pm_mutex)) {
			error = -EBUSY;
			break;
		}

		if (pm_ops->prepare) {
			error = pm_ops->prepare(PM_SUSPEND_MEM);
			if (error)
				goto OutS3;
		}

		/* Put devices to sleep */
		suspend_console();
		error = device_suspend(PMSG_SUSPEND);
		if (error) {
			printk(KERN_ERR "Failed to suspend some devices.\n");
		} else {
			error = disable_nonboot_cpus();
			if (!error) {
				/* Enter S3, system is already frozen */
				suspend_enter(PM_SUSPEND_MEM);
				enable_nonboot_cpus();
			}
			/* Wake up devices */
			device_resume();
		}
		resume_console();
		if (pm_ops->finish)
			pm_ops->finish(PM_SUSPEND_MEM);

 OutS3:
		mutex_unlock(&pm_mutex);
		break;

	case SNAPSHOT_PMOPS:
		error = -EINVAL;

		switch (arg) {

		case PMOPS_PREPARE:
			if (hibernation_ops) {
				data->platform_suspend = 1;
				error = 0;
			} else {
				error = -ENOSYS;
			}
			break;

		case PMOPS_ENTER:
			if (data->platform_suspend) {
				kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
				error = hibernation_ops->enter();
			}
			break;

		case PMOPS_FINISH:
			if (data->platform_suspend)
				error = 0;

			break;

		default:
			printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);

		}
		break;

	case SNAPSHOT_SET_SWAP_AREA:
		if (swsusp_swap_in_use()) {
			error = -EPERM;
		} else {
			struct resume_swap_area swap_area;
			dev_t swdev;

			error = copy_from_user(&swap_area, (void __user *)arg,
					sizeof(struct resume_swap_area));
			if (error) {
				error = -EFAULT;
				break;
			}

			/*
			 * User space encodes device types as two-byte values,
			 * so we need to recode them
			 */
			swdev = old_decode_dev(swap_area.dev);
			if (swdev) {
				offset = swap_area.offset;
				data->swap = swap_type_of(swdev, offset, NULL);
				if (data->swap < 0)
					error = -ENODEV;
			} else {
				data->swap = -1;
				error = -EINVAL;
			}
		}
		break;

	default:
		error = -ENOTTY;

	}

	return error;
}
Пример #30
0
/*
 * Called by kexec, immediately prior to machine_kexec().
 *
 * This must completely disable all secondary CPUs; simply causing those CPUs
 * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
 * kexec'd kernel to use any and all RAM as it sees fit, without having to
 * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
 * functionality embodied in disable_nonboot_cpus() to achieve this.
 */
void machine_shutdown(void)
{
	disable_nonboot_cpus();
}