/* NOTICE: this function MUST be called under autosleep_lock (in autosleep.c) is locked!! */
int mtk_hibernate_via_autosleep(suspend_state_t *autosleep_state)
{
	int err = 0;
	hib_log("entering hibernation state(%d)\n", *autosleep_state);
	err = hibernate();
	if (err) {
		hib_warn
		    ("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
		/* enhanced error handling */
#ifdef CONFIG_TOI_ENHANCE
		if (toi_hibernate_fatalerror()) {
			kernel_power_off();
			kernel_halt();
			BUG();
		}
#endif
		if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
			kernel_power_off();
			kernel_halt();
			BUG();
		} else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
			hib_warn("hibernation failed: so changing state(%d->%d) err(%d)\n",
				 *autosleep_state, PM_SUSPEND_MEM, err);
			if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
				hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
			hibernate_recover();
			*autosleep_state = PM_SUSPEND_MEM;
			pm_wake_lock("IPOD_HIB_WAKELOCK");
			system_is_hibernating = false;
		} else {
			hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
			BUG();
		}
	} else {
		if (hybrid_sleep_mode()) {
			hib_warn("hybrid sleep mode so changing state(%d->%d)\n", *autosleep_state,
				 PM_SUSPEND_MEM);
			*autosleep_state = PM_SUSPEND_MEM;	/* continue suspend to ram if hybrid sleep mode */
		} else {
			hib_warn("hibernation succeeded: so changing state(%d->%d) err(%d)\n",
				 *autosleep_state, PM_SUSPEND_ON, err);
			hibernate_restore();
			*autosleep_state = PM_SUSPEND_ON;	/* if this is not set, it will recursively do hibernating!! */
		}
		hib_failed_cnt = 0;
		pm_wake_lock("IPOD_HIB_WAKELOCK");
		system_is_hibernating = false;
	}

	return err;
}
Esempio n. 2
0
void mag_init() {
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    __DMB();

    // configure mag
    i2c_shared_wait();
    i2c_shared_lock();
    i2c_polling_start(addr, false);
    i2c_polling_write(REG_IDA); // read the IDA register
    i2c_polling_start(addr, true);
    if (i2c_polling_read(false) != 'H')
        kernel_halt("Failed to identify magnetometer");
    i2c_polling_start(addr, false);
    i2c_polling_write(REG_CONFIGA);
    i2c_polling_write(0); // config a
    i2c_polling_write(0x40); // config b
    i2c_polling_stop();
    i2c_shared_unlock();

    // enable EXTI
    SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI12_PB;
    EXTI->RTSR |= (1 << PIN_DRDY);
    EXTI->IMR |= (1 << PIN_DRDY);
    util_enable_irq(EXTI15_10_IRQn, IRQ_PRI_HIGH);

    // jumpstart the async process
    if (!(GPIOB->IDR & (1 << PIN_DRDY))) {
        i2c_shared_wait();
        i2c_shared_lock();
        i2c_async_send(addr, read_cmd, sizeof(read_cmd), i2c_shared_done_unlock); // if DRDY is low, send a command
    } else {
        irq_exti1510(); // if DRDY is high, run its IRQ since EXTI looks for edges not levels
    }
}
Esempio n. 3
0
void assert_failed(const char *file, uint32_t line, const char *desc) {
	IRQ_OFF;
	kprintf("Kernel Assertion Failed: %s\n", desc);
	kprintf("File: %s\n", file);
	kprintf("Line: %d\n", line);
	kernel_halt();
}
Esempio n. 4
0
Result_t Handle_CAPI2_SYS_SoftResetSystem(RPC_Msg_t *pReqMsg, UInt32 param)
{
	Result_t result = RESULT_OK;
	SYS_ReqRep_t data;

	memset(&data, 0, sizeof(SYS_ReqRep_t));

	data.result = result;
	Send_SYS_RspForRequest(pReqMsg, MSG_SYS_SOFT_RESET_SYSTEM_RSP, &data);

	switch (param) {
	case SYS_HALT:                  /* 0x002 */
		kernel_halt();
		break;

	case SYS_POWER_OFF:             /* 0x003 */
		kernel_power_off();
		break;

	case SYS_RESTART:      /* 0x0001 or SYS_DOWN  */
	default:
		kernel_restart(NULL);
		break;
	}

	return result;
}
Esempio n. 5
0
static void mv_enter_standby(void)
{
	/* halt the system */
	kernel_halt();
	/* configure the Eth Phy to be in WoL mode */
	kw_wol_configure();

}
/* called by echo "disk" > /sys/power/state */
int mtk_hibernate(void)
{
	int err = 0;

	hib_log("entering hibernation\n");
	err = hibernate();
	if (err) {
		hib_warn
		    ("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
		/* enhanced error handling */
#ifdef CONFIG_TOI_ENHANCE
		if (toi_hibernate_fatalerror()) {
			kernel_power_off();
			kernel_halt();
			BUG();
		}
#endif
		if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
			kernel_power_off();
			kernel_halt();
			BUG();
		} else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
			hib_warn("hibernation failed, suspend to ram instead!\n");
			if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
				hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
			hibernate_recover();
			pm_wake_lock("IPOD_HIB_WAKELOCK");
			system_is_hibernating = false;
		} else {
			hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
			BUG();
		}
	} else {
		if (!hybrid_sleep_mode()) {
			hibernate_restore();
		}
		hib_failed_cnt = 0;
		pm_wake_lock("IPOD_HIB_WAKELOCK");
		system_is_hibernating = false;
	}

	return err;
}
static void panic_do(const int8_t *file, uint32_t line) {
    log_write("# FILE: %s:%d\n", file, line);
    log_write("# SYSTEM HALTED!\n");

    /* Disable interrupts */
    kernel_disable_interrupts();

    /* Halt by going into an infinite loop */
    for(;;);

    /* Just in case... */
    kernel_halt();
}
Esempio n. 8
0
/**
 * power_down - Shut the machine down for hibernation.
 *
 * Use the platform driver, if configured, to put the system into the sleep
 * state corresponding to hibernation, or try to power it off or reboot,
 * depending on the value of hibernation_mode.
 */
static void power_down(void)
{
#ifdef CONFIG_SUSPEND
	int error;
#endif

	switch (hibernation_mode) {
	case HIBERNATION_REBOOT:
		kernel_restart(NULL);
		break;
	case HIBERNATION_PLATFORM:
		hibernation_platform_enter();
	case HIBERNATION_SHUTDOWN:
		if (pm_power_off)
			kernel_power_off();
		break;
#ifdef CONFIG_SUSPEND
	case HIBERNATION_SUSPEND:
		error = suspend_devices_and_enter(PM_SUSPEND_MEM);
		if (error) {
			if (hibernation_ops)
				hibernation_mode = HIBERNATION_PLATFORM;
			else
				hibernation_mode = HIBERNATION_SHUTDOWN;
			power_down();
		}
		/*
		 * Restore swap signature.
		 */
		error = swsusp_unmark();
		if (error)
			printk(KERN_ERR "PM: Swap will be unusable! "
			                "Try swapon -a.\n");
		return;
#endif
	}
	kernel_halt();
	/*
	 * Valid image is on the disk, if we continue we risk serious data
	 * corruption after resume.
	 */
	printk(KERN_CRIT "PM: Please power down manually\n");
	while (1)
		cpu_relax();
}
Esempio n. 9
0
/**
 * power_down - Shut the machine down for hibernation.
 *
 * Use the platform driver, if configured, to put the system into the sleep
 * state corresponding to hibernation, or try to power it off or reboot,
 * depending on the value of hibernation_mode.
 */
static void power_down(void)
{
#ifdef CONFIG_SUSPEND
	int error;

	if (hibernation_mode == HIBERNATION_SUSPEND) {
		error = suspend_devices_and_enter(PM_SUSPEND_MEM);
		if (error) {
			hibernation_mode = hibernation_ops ?
						HIBERNATION_PLATFORM :
						HIBERNATION_SHUTDOWN;
		} else {
			/* Restore swap signature. */
			error = swsusp_unmark();
			if (error)
				pr_err("Swap will be unusable! Try swapon -a.\n");

			return;
		}
	}
#endif

	switch (hibernation_mode) {
	case HIBERNATION_REBOOT:
		kernel_restart(NULL);
		break;
	case HIBERNATION_PLATFORM:
		hibernation_platform_enter();
		/* Fall through */
	case HIBERNATION_SHUTDOWN:
		if (pm_power_off)
			kernel_power_off();
		break;
	}
	kernel_halt();
	/*
	 * Valid image is on the disk, if we continue we risk serious data
	 * corruption after resume.
	 */
	pr_crit("Power down manually\n");
	while (1)
		cpu_relax();
}
// NOTICE: this function MUST be called under autosleep_lock (in autosleep.c) is locked!!
int mtk_hibernate_via_autosleep(suspend_state_t *autosleep_state)
{
    int err = 0;
    hib_log("entering hibernation state(%d)\n", *autosleep_state);
    err = hibernate();
    if (err) {
        hib_warn("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
            kernel_power_off();
            kernel_halt();
            BUG();
        } else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
            hib_warn("hibernation failed: so changing state(%d->%d) err(%d)\n", *autosleep_state, PM_SUSPEND_MEM, err);
            if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
                hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
            // userspace recover if hibernation failed
            usr_recover_func(NULL);
            *autosleep_state = PM_SUSPEND_MEM;
            system_is_hibernating = false;
         } else {
            hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
            BUG();
        }
    } else {
        if (hybrid_sleep_mode()) {
            hib_warn("hybrid sleep mode so changing state(%d->%d)\n", *autosleep_state, PM_SUSPEND_MEM);
            *autosleep_state = PM_SUSPEND_MEM; //continue suspend to ram if hybrid sleep mode
        } else {
            hib_warn("hibernation succeeded: so changing state(%d->%d) err(%d) \n", *autosleep_state, PM_SUSPEND_ON, err);
            hib_warn("start trigger ipod\n");
            //usr_bootanim_start(NULL);
            //schedule_delayed_work(&usr_restore_work, HZ*0.05);
            usr_restore_func(NULL);
            *autosleep_state = PM_SUSPEND_ON; // if this is not set, it will recursively do hibernating!!
        }
        hib_failed_cnt = 0;
        pm_wake_lock("IPOD_HIB_WAKELOCK");
        system_is_hibernating = false;
    }

    return err;
}
Esempio n. 11
0
/**
 * power_down - Shut the machine down for hibernation.
 *
 * Use the platform driver, if configured, to put the system into the sleep
 * state corresponding to hibernation, or try to power it off or reboot,
 * depending on the value of hibernation_mode.
 */
static void power_down(void)
{
	switch (hibernation_mode) {
	case HIBERNATION_REBOOT:
		kernel_restart(NULL);
		break;
	case HIBERNATION_PLATFORM:
		hibernation_platform_enter();
	case HIBERNATION_SHUTDOWN:
		kernel_power_off();
		break;
	}
	kernel_halt();
	/*
	 * Valid image is on the disk, if we continue we risk serious data
	 * corruption after resume.
	 */
	printk(KERN_CRIT "PM: Please power down manually\n");
	while(1);
}
Esempio n. 12
0
void mpu_reset(AccelFS new_accel_fs, GyroFS new_gyro_fs, uint8_t new_dlpf, uint8_t new_samplerate_div) {
    accel_fs = new_accel_fs;
    gyro_fs = new_gyro_fs;
    dlpf = new_dlpf;
    samplerate_div = new_samplerate_div;

    writereg(REG_PWR_MGMT_1, 1 << 7); // reset MPU
    sched_sleep(100);
    writereg(REG_PWR_MGMT_1, 3); // clock source is z gyro
    writereg(REG_PWR_MGMT_2, 0);
    writereg(REG_USER_CTRL, (1 << 4)); // disable I2C interface

    if (readreg(REG_WHO_AM_I) != 0x68) // check WHO_AM_I register
        kernel_halt("MPU failed to read WHO_AM_I");

    writereg(REG_SMPLRT_DIV, samplerate_div); // set sample rate divisor
    writereg(REG_CONFIG, dlpf); // set DLPF
    writereg(REG_GYRO_CONFIG, (int)gyro_fs << 3); // set gyro FS_SEL
    writereg(REG_ACCEL_CONFIG, (int)accel_fs << 3); // set accel FS_SEL
    writereg(REG_INT_PIN_CFG, (1 << 5) | (1 << 4)); // turn on LATCH_INT and INT_RD_CLEAR
    writereg(REG_INT_ENABLE, (1 << 0)); // turn on DATA_RDY_EN
}
Esempio n. 13
0
static void warn_irq_w(struct work_struct *w)
{
	struct mmi_factory_info *info = container_of(w,
						     struct mmi_factory_info,
						     warn_irq_work.work);
	int warn_line = gpio_get_value(info->list[KP_WARN_INDEX].gpio);
	int reset_info = RESET_EXTRA_RESET_KUNPOW_REASON;

	if (!warn_line) {
		pr_info("HW User Reset!\n");
		pr_info("2 sec to Reset.\n");

#ifdef CONFIG_QPNP_POWER_ON
		/* trigger wdog if resin key pressed */
		if (qpnp_pon_key_status & QPNP_PON_KEY_RESIN_BIT) {
			pr_info("User triggered watchdog reset(Pwr + VolDn)\n");
			msm_trigger_wdog_bite();
			return;
		}
#endif
		/* Configure hardware reset before halt
		 * The new KUNGKOW circuit will not disconnect the battery if
		 * usb/dc is connected. But because the kernel is halted, a
		 * watchdog reset will be reported instead of hardware reset.
		 * In this case, we need to clear the KUNPOW reset bit to let
		 * BL detect it as a hardware reset.
		 * A pmic hard reset is necessary to report the powerup reason
		 * to BL correctly.
		 */
		if (usr_rst_sw_dis_flg <= 0) {
			qpnp_pon_store_extra_reset_info(reset_info, 0);
			qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET);
			kernel_halt();
		} else
			pr_info("SW HALT Disabled!\n");

		return;
	}
}
Esempio n. 14
0
static void jz4740_rtc_power_off(void)
{
	struct jz4740_rtc *rtc = dev_get_drvdata(dev_for_power_off);
	unsigned long rtc_rate;
	unsigned long wakeup_filter_ticks;
	unsigned long reset_counter_ticks;

	clk_prepare_enable(rtc->clk);

	rtc_rate = clk_get_rate(rtc->clk);

	/*
	 * Set minimum wakeup pin assertion time: 100 ms.
	 * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
	 */
	wakeup_filter_ticks =
		(rtc->min_wakeup_pin_assert_time * rtc_rate) / 1000;
	if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
		wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
	else
		wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
	jz4740_rtc_reg_write(rtc,
			     JZ_REG_RTC_WAKEUP_FILTER, wakeup_filter_ticks);

	/*
	 * Set reset pin low-level assertion time after wakeup: 60 ms.
	 * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
	 */
	reset_counter_ticks = (rtc->reset_pin_assert_time * rtc_rate) / 1000;
	if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
		reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
	else
		reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK;
	jz4740_rtc_reg_write(rtc,
			     JZ_REG_RTC_RESET_COUNTER, reset_counter_ticks);

	jz4740_rtc_poweroff(dev_for_power_off);
	kernel_halt();
}
Esempio n. 15
0
static void power_down(suspend_disk_method_t mode)
{
	int error = 0;

	switch(mode) {
	case PM_DISK_PLATFORM:
		kernel_power_off_prepare();
		error = pm_ops->enter(PM_SUSPEND_DISK);
		break;
	case PM_DISK_SHUTDOWN:
		kernel_power_off();
		break;
	case PM_DISK_REBOOT:
		kernel_restart(NULL);
		break;
	}
	kernel_halt();
	/* Valid image is on the disk, if we continue we risk serious data corruption
	   after resume. */
	printk(KERN_CRIT "Please power me down manually\n");
	while(1);
}
// called by echo "disk" > /sys/power/state
int mtk_hibernate(void)
{
    int err = 0;

    hib_log("entering hibernation\n");
    err = hibernate();
    if (err) {
        hib_warn("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
            kernel_power_off();
            kernel_halt();
            BUG();
        } else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
            hib_warn("hibernation failed, suspend to ram instead!\n");
            if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
                hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
            // userspace recover if hibernation failed
            usr_recover_func(NULL);
            system_is_hibernating = false;
        } else {
            hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
            BUG();
        }
    } else {
        if (!hybrid_sleep_mode()) {
            hib_warn("start trigger ipod\n");
            //schedule_delayed_work(&usr_bootanim_start_work, HZ*1.0);
            //schedule_delayed_work(&usr_restore_work, HZ*0.05);
            //usr_bootanim_start(NULL);
            usr_restore_func(NULL);
        }
        hib_failed_cnt = 0;
        pm_wake_lock("IPOD_HIB_WAKELOCK");
        system_is_hibernating = false;
    }

    return err;
}
static void usr_reset_warning_work(struct work_struct *work)
{
	kernel_halt();
}
Esempio n. 18
0
/*
 * Reboot system call: for obvious reasons only root may call it,
 * and even root needs to set up some magic numbers in the registers
 * so that some mistake won't make this reboot the whole machine.
 * You can also set the meaning of the ctrl-alt-del-key here.
 *
 * reboot doesn't sync: do that yourself before calling this.
 */
asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg)
{
    char buffer[256];

    /* We only trust the superuser with rebooting the system. */
    if (!capable(CAP_SYS_BOOT))
        return -EPERM;

    /* For safety, we require "magic" arguments. */
    if (magic1 != LINUX_REBOOT_MAGIC1 ||
            (magic2 != LINUX_REBOOT_MAGIC2 &&
             magic2 != LINUX_REBOOT_MAGIC2A &&
             magic2 != LINUX_REBOOT_MAGIC2B &&
             magic2 != LINUX_REBOOT_MAGIC2C))
        return -EINVAL;

    lock_kernel();
    switch (cmd) {
    case LINUX_REBOOT_CMD_RESTART:
        kernel_restart(NULL);
        break;

    case LINUX_REBOOT_CMD_CAD_ON:
        C_A_D = 1;
        break;

    case LINUX_REBOOT_CMD_CAD_OFF:
        C_A_D = 0;
        break;

    case LINUX_REBOOT_CMD_HALT:
        kernel_halt();
        unlock_kernel();
        do_exit(0);
        break;

    case LINUX_REBOOT_CMD_POWER_OFF:
        kernel_power_off();
        unlock_kernel();
        do_exit(0);
        break;

    case LINUX_REBOOT_CMD_RESTART2:
        if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
            unlock_kernel();
            return -EFAULT;
        }
        buffer[sizeof(buffer) - 1] = '\0';

        kernel_restart(buffer);
        break;

    case LINUX_REBOOT_CMD_KEXEC:
        kernel_kexec();
        unlock_kernel();
        return -EINVAL;

#ifdef CONFIG_SOFTWARE_SUSPEND
    case LINUX_REBOOT_CMD_SW_SUSPEND:
    {
        int ret = software_suspend();
        unlock_kernel();
        return ret;
    }
#endif

    default:
        unlock_kernel();
        return -EINVAL;
    }
    unlock_kernel();
    return 0;
}
Esempio n. 19
0
/*
 * Reboot system call: for obvious reasons only root may call it,
 * and even root needs to set up some magic numbers in the registers
 * so that some mistake won't make this reboot the whole machine.
 * You can also set the meaning of the ctrl-alt-del-key here.
 *
 * reboot doesn't sync: do that yourself before calling this.
 */
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
		void __user *, arg)
{
	struct pid_namespace *pid_ns = task_active_pid_ns(current);
	char buffer[256];
	int ret = 0;

	/* We only trust the superuser with rebooting the system. */
	if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
		return -EPERM;

	/* For safety, we require "magic" arguments. */
	if (magic1 != LINUX_REBOOT_MAGIC1 ||
			(magic2 != LINUX_REBOOT_MAGIC2 &&
			magic2 != LINUX_REBOOT_MAGIC2A &&
			magic2 != LINUX_REBOOT_MAGIC2B &&
			magic2 != LINUX_REBOOT_MAGIC2C))
		return -EINVAL;

	/*
	 * If pid namespaces are enabled and the current task is in a child
	 * pid_namespace, the command is handled by reboot_pid_ns() which will
	 * call do_exit().
	 */
	ret = reboot_pid_ns(pid_ns, cmd);
	if (ret)
		return ret;

	/* Instead of trying to make the power_off code look like
	 * halt when pm_power_off is not set do it the easy way.
	 */
	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
		cmd = LINUX_REBOOT_CMD_HALT;

	mutex_lock(&reboot_mutex);
	switch (cmd) {
	case LINUX_REBOOT_CMD_RESTART:
		kernel_restart(NULL);
		break;

	case LINUX_REBOOT_CMD_CAD_ON:
		C_A_D = 1;
		break;

	case LINUX_REBOOT_CMD_CAD_OFF:
		C_A_D = 0;
		break;

	case LINUX_REBOOT_CMD_HALT:
		kernel_halt();
		do_exit(0);
		panic("cannot halt");

	case LINUX_REBOOT_CMD_POWER_OFF:
		kernel_power_off();
		do_exit(0);
		break;

	case LINUX_REBOOT_CMD_RESTART2:
		ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);
		if (ret < 0) {
			ret = -EFAULT;
			break;
		}
		buffer[sizeof(buffer) - 1] = '\0';

		kernel_restart(buffer);
		break;

#ifdef CONFIG_KEXEC_CORE
	case LINUX_REBOOT_CMD_KEXEC:
		ret = kernel_kexec();
		break;
#endif

#ifdef CONFIG_HIBERNATION
	case LINUX_REBOOT_CMD_SW_SUSPEND:
		ret = hibernate();
		break;
#endif

	default:
		ret = -EINVAL;
		break;
	}
	mutex_unlock(&reboot_mutex);
	return ret;
}
static uint32_t _halt(void) {
    kernel_halt();
    return 0;
}
Esempio n. 21
0
/*
 * Reboot system call: for obvious reasons only root may call it,
 * and even root needs to set up some magic numbers in the registers
 * so that some mistake won't make this reboot the whole machine.
 * You can also set the meaning of the ctrl-alt-del-key here.
 *
 * reboot doesn't sync: do that yourself before calling this.
 */
asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg)
{
	char buffer[256];

	/* We only trust the superuser with rebooting the system. */
	if (!capable(CAP_SYS_BOOT))
		return -EPERM;

	/* For safety, we require "magic" arguments. */
	if (magic1 != LINUX_REBOOT_MAGIC1 ||
	    (magic2 != LINUX_REBOOT_MAGIC2 &&
	                magic2 != LINUX_REBOOT_MAGIC2A &&
			magic2 != LINUX_REBOOT_MAGIC2B &&
	                magic2 != LINUX_REBOOT_MAGIC2C))
		return -EINVAL;

	/* Instead of trying to make the power_off code look like
	 * halt when pm_power_off is not set do it the easy way.
	 */
	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
		cmd = LINUX_REBOOT_CMD_HALT;

	lock_kernel();
	switch (cmd) {
	case LINUX_REBOOT_CMD_RESTART:
		kernel_restart(NULL);
		break;

	case LINUX_REBOOT_CMD_CAD_ON:
		C_A_D = 1;
		break;

	case LINUX_REBOOT_CMD_CAD_OFF:
		C_A_D = 0;
		break;

	case LINUX_REBOOT_CMD_HALT:
		kernel_halt();
		unlock_kernel();
		do_exit(0);
		break;

	case LINUX_REBOOT_CMD_POWER_OFF:
		kernel_power_off();
		unlock_kernel();
		do_exit(0);
		break;

	case LINUX_REBOOT_CMD_RESTART2:
		if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
			unlock_kernel();
			return -EFAULT;
		}
		buffer[sizeof(buffer) - 1] = '\0';

		kernel_restart(buffer);
		break;

	case LINUX_REBOOT_CMD_KEXEC:
		kernel_kexec();
		unlock_kernel();
		return -EINVAL;

#ifdef CONFIG_HIBERNATION
	case LINUX_REBOOT_CMD_SW_SUSPEND:
		{
			int ret = hibernate();
			unlock_kernel();
			return ret;
		}
#endif

	default:
		unlock_kernel();
		return -EINVAL;
	}
	unlock_kernel();
	return 0;
}
static void __toi_power_down(int method)
{
	int error;

	toi_cond_pause(1, test_action_state(TOI_REBOOT) ? "Ready to reboot." :
			"Powering down.");

	if (test_result_state(TOI_ABORTED))
		goto out;

	if (test_action_state(TOI_REBOOT))
		kernel_restart(NULL);

	switch (method) {
	case 0:
		break;
	case 3:
		/*
		 * Re-read the overwritten part of pageset2 to make post-resume
		 * faster.
		 */
		if (read_pageset2(1))
			panic("Attempt to reload pagedir 2 failed. "
					"Try rebooting.");

		pm_prepare_console();

		error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
		if (!error) {
			pm_restore_gfp_mask();
			error = suspend_devices_and_enter(PM_SUSPEND_MEM);
			pm_restrict_gfp_mask();
			if (!error)
				did_suspend_to_both = 1;
		}
		pm_notifier_call_chain(PM_POST_SUSPEND);
		pm_restore_console();

        // jonathan.jmchen: FIXME, Create API to add another wakeup source to power down,
        // if system is idle after xxx (e.g., 5 min) without user interaction!!

		/* Success - we're now post-resume-from-ram */
		if (did_suspend_to_both)
			return;

		/* Failed to suspend to ram - do normal power off */
		break;
	case 4:
		/*
		 * If succeeds, doesn't return. If fails, do a simple
		 * powerdown.
		 */
		hibernation_platform_enter();
		break;
	case 5:
		/* Historic entry only now */
		break;
	}

	if (method && method != 5)
		toi_cond_pause(1,
			"Falling back to alternate power off method.");

	if (test_result_state(TOI_ABORTED))
		goto out;

	kernel_power_off();
	kernel_halt();
	toi_cond_pause(1, "Powerdown failed.");
	while (1)
		cpu_relax();

out:
	if (read_pageset2(1))
		panic("Attempt to reload pagedir 2 failed. Try rebooting.");
	return;
}