Ejemplo n.º 1
0
static void modem_sw_fatal_fn(struct work_struct *work)
{
	uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
	uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
					SMSM_SYSTEM_PWRDWN_USR;
	uint32_t modem_state;

	pr_err("Watchdog bite received from modem SW!\n");

	modem_state = smsm_get_state(SMSM_MODEM_STATE);

	if (modem_state & panic_smsm_states) {

		pr_err("Modem SMSM state changed to SMSM_RESET.\n"
			"Probable err_fatal on the modem. "
			"Calling subsystem restart...\n");
		subsystem_restart("modem");

	} else if (modem_state & reset_smsm_states) {

		pr_err("%s: User-invoked system reset/powerdown. "
			"Resetting the SoC now.\n",
			__func__);
		kernel_restart(NULL);
	} else {
		/* TODO: Bus unlock code/sequence goes _here_ */
		subsystem_restart("modem");
	}
}
Ejemplo n.º 2
0
static void modem_fatal_fn(struct work_struct *work)
{
	u32 modem_state;
	u32 panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
	u32 reset_smsm_states = SMSM_SYSTEM_REBOOT_USR | SMSM_SYSTEM_PWRDWN_USR;
	struct modem_data *drv;

	drv = container_of(work, struct modem_data, fatal_work);

	pr_err("Watchdog bite received from modem!\n");

	modem_state = smsm_get_state(SMSM_MODEM_STATE);
	pr_err("Modem SMSM state = 0x%x!\n", modem_state);

	if (modem_state == 0 || modem_state & panic_smsm_states) {
		subsystem_restart_dev(drv->subsys);
		enable_irq(drv->irq);
	} else if (modem_state & reset_smsm_states) {
		pr_err("User-invoked system reset/powerdown.");
		kernel_restart(NULL);
	} else {
		unsigned long timeout = msecs_to_jiffies(6000);

		pr_err("Modem AHB locked up. Trying to free up modem!\n");

		writel_relaxed(0x3, drv->cbase + MSS_MODEM_RESET);
		/*
		 * If we are still alive (allowing for the 5 second
		 * delayed-panic-reboot), the modem is either still wedged or
		 * SMSM didn't come through. Force panic in that case.
		 */
		schedule_delayed_work(&drv->unlock_work, timeout);
	}
}
Ejemplo n.º 3
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;
}
/* 
 *  Write by the user to low/high the gpio 8
 */
ssize_t
ota_proc_write(struct file *filp, const char __user *buff,
  unsigned long len, void *data)
{
	char k_buf[MAX_LEN] = "\0";
	int count = min(MAX_LEN, (int)len) ;
	int retval ;
	if(copy_from_user( k_buf, buff, count))
	{
		printk(KERN_ERR "Ant -- ota switch, copy from user failed!\n");
		return -1 ;
	} else {
		printk(KERN_ERR "Ant -- ota switch, user write %s\n", k_buf);
		retval = count ;
	}
	if(strncmp(k_buf, "start", 5) == 0)
	{
		ota = 1 ;
	}
	else if(strncmp(k_buf, "reboot", 6) == 0)
	{
		kernel_restart(NULL) ;
	} else {
		// do nothing
	}
	return retval ;
}
Ejemplo n.º 5
0
static int autoreboot_thread(void *data)
{
	unsigned int autoreboot_cycle;

	autoreboot_cycle = get_random_secs(10, AUTOREBOOT_CYCLE);

	pr_at_info("%s: Enter into autoreboot_thread\n", __func__);

	/* Only allow to start the autoreboot test when normally boot:
	 * This allows users to dump out the previous kernel log
	 * from /proc/last_kmsg when RAM_CONSOLE is enabled.
	 */
	pr_at_info("%s: Sleep %d ms for reboot\n", __func__, autoreboot_cycle);
	msleep_interruptible(autoreboot_cycle);

	pr_at_info("%s: Sync all changes to disk\n", __func__);
	/* Sync the changes from cache to disk */
	sys_sync();

	/* Tell uboot to start a normal reboot to avoid it come to
	 * the charging mode when a USB is inserted
	 */
	pr_at_info("%s: Should start a normal reboot\n", __func__);

	pr_at_info("%s: Stop suspend just before sending out restart command\n", __func__);
#ifdef CONFIG_AUTOSUSPEND_TEST
	wake_lock(&autotest_wake_lock);
#endif
	pr_at_info("%s: Send out the restart command ...\n", __func__);

	kernel_restart(NULL);

	return 0;
}
Ejemplo n.º 6
0
static void wisky_boot_charge_restart(void)
{
	gpio_request(KEY_SHUTDOWN_PIN, "poweronpin");
	gpio_direction_output(KEY_SHUTDOWN_PIN, GPIO_HIGH);
	gpio_set_value(KEY_SHUTDOWN_PIN,GPIO_HIGH);
	kernel_restart(NULL);	
}
Ejemplo n.º 7
0
static void magic_reboot_wq_handler(struct work_struct *w)
{
    /* Keep trying until it works, although the inital delay set
     * waiting for MMC to come up should be sufficient */
    if (access_osip_record(osip_invalidate, (void *)magic_target))
        schedule_delayed_work(&magic_reboot_wq, msecs_to_jiffies(100));
    else {
        pr_info("Rebooting on behalf of magic key press\n");
        sys_sync();
        kernel_restart(NULL);
    }
}
Ejemplo n.º 8
0
static irqreturn_t twl6030_hotdie_interrupt(int irq, void *di)
{
	pr_emerg("%s: TWL overheat detected.\n"\
		 "Shutting down to avoid device malfunction...", __func__);
	if (pm_power_off) {
		kernel_power_off();
	} else {
		WARN(1, "FIXME: NO pm_power_off!!! trying restart\n");
		kernel_restart(NULL);
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 9
0
static int __orderly_reboot(void)
{
	int ret;

	ret = run_cmd(reboot_cmd);

	if (ret) {
		pr_warn("Failed to start orderly reboot: forcing the issue\n");
		emergency_sync();
		kernel_restart(NULL);
	}

	return ret;
}
 static kal_uint32 charging_set_platform_reset(void *data)
 {
     kal_uint32 status = STATUS_OK;
     
#if defined(CONFIG_POWER_EXT) || defined(CONFIG_MTK_FPGA)    
#else 
     battery_log(BAT_LOG_CRTI, "charging_set_platform_reset\n");
  
  	kernel_restart("battery service reboot system");
     //arch_reset(0,NULL);
#endif
         
     return status;
 }
Ejemplo n.º 11
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);

	if (!warn_line) {
		pr_info("HW User Reset!\n");
		pr_info("2 sec to Reset.\n");
		kernel_restart(NULL);
		return;
	}
}
Ejemplo n.º 12
0
static irqreturn_t omap_tshut_irq_handler(int irq, void *data)
{
	struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;

	/* Need to handle thermal mgmt in bootloader
	 * to avoid restart again at kernel level
	 */
	if (temp_sensor->is_efuse_valid) {
		pr_emerg("%s: Thermal shutdown reached rebooting device\n",
			__func__);
		kernel_restart(NULL);
	} else {
		pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__);
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 13
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();
}
Ejemplo n.º 14
0
static void modem_fatal_fn(struct work_struct *work)
{
	uint32_t modem_state;
	uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
	uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
					SMSM_SYSTEM_PWRDWN_USR;

	pr_err("%s: Watchdog bite received from modem!\n", MODULE_NAME);

	modem_state = smsm_get_state(SMSM_MODEM_STATE);
	pr_err("%s: Modem SMSM state = 0x%x!", MODULE_NAME, modem_state);

	if (modem_state == 0 || modem_state & panic_smsm_states) {

		subsystem_restart("modem");
		enable_irq(MARM_WDOG_EXPIRED);

	} else if (modem_state & reset_smsm_states) {

		pr_err("%s: User-invoked system reset/powerdown.",
			MODULE_NAME);
		kernel_restart(NULL);

	} else {

		int ret;
		void *hwio_modem_reset_addr =
				ioremap_nocache(MODEM_HWIO_MSS_RESET_ADDR, 8);

		pr_err("%s: Modem AHB locked up.\n", MODULE_NAME);
		pr_err("%s: Trying to free up modem!\n", MODULE_NAME);

		writel_relaxed(0x3, hwio_modem_reset_addr);

		/* If we are still alive after 6 seconds (allowing for
		 * the 5-second-delayed-panic-reboot), modem is either
		 * still wedged or SMSM didn't come through. Force panic
		 * in that case.
		*/
		ret = schedule_delayed_work(&modem_unlock_timeout_work,
					msecs_to_jiffies(6000));

		iounmap(hwio_modem_reset_addr);
	}
}
Ejemplo n.º 15
0
static void bq27410_battery_update_work(struct work_struct *work)
{
	struct file *filp;
	int retval;
	unsigned long len = sizeof(g_filename);
	struct bq27410_device_info *di = container_of(work, struct bq27410_device_info, work.work); 

	retval = update_get_flen(g_filename);
	if(retval == 0){
		printk("bq27410_battery_update_work:update_get_flen error.\n");
		return;
	}

	mutex_lock(&g_bq27410_mutex);
	retval = bq27410_update_flash_data(filp, g_filename, len, NULL);
	mutex_unlock(&g_bq27410_mutex);

	if(retval == 0)
	{
	#if UPDATE_FIRMWARE_RESTART
		printk("bq27410_battery_update_work ,update success,restart the system.\n");
		virtual_battery_enable = 0;
		//after update firmware ,restart the system.
		sys_sync();
		msleep(200);
		kernel_restart(NULL);

		return;
	#else
		printk("bq27410_battery_update_work ,update success.\n");
	#endif
	}
	else{
		printk("bq27410_battery_update_work:update failed.\n");
		return;
	}

	bq27410_write_batt_insert(g_client);
	msleep(2000);
	bq27410_write_batt_insert(g_client);
	
	INIT_DELAYED_WORK(&bq27410_di->work, bq27410_battery_work);
	schedule_delayed_work(&bq27410_di->work, bq27410_di->interval);
}
Ejemplo n.º 16
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();
}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
/*
 * This thread starts and then immediately goes to sleep. When it is woken
 * up, it carries out the instructions left in uptime_expiration_action. If
 * no action was specified it simply goes back to sleep.
 */
static int uptime_worker(void *unused)
{
	set_current_state(TASK_INTERRUPTIBLE);

	while (!kthread_should_stop()) {
		schedule();

		if (kthread_should_stop())
			break;

		if (uptime_expiration_action == uptime_reboot) {
			printk(KERN_CRIT "Uptime: restarting machine\n");
			kernel_restart(NULL);
		}

		set_current_state(TASK_INTERRUPTIBLE);
	}
	__set_current_state(TASK_RUNNING);

	return 0;
}
Ejemplo n.º 19
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);
}
Ejemplo n.º 20
0
static int bq27410_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data)
{
	int ret = 0;
	char update_file[100];
	memset(update_file, 0, 100);

	if(copy_from_user(&update_file, buff, len))	
	{		
		return -EFAULT;	
	}

	update_file[len-1] = 0;
	ret = update_get_flen(update_file);
	if(ret == 0){
		printk("bq27410_update_write:update_get_flen error.\n");
		return -EFAULT;
	}

	mutex_lock(&g_bq27410_mutex);

	printk("update file: %d-[%s].\n", len, update_file);
	ret = bq27410_update_flash_data(filp, update_file, len, data);
	mutex_unlock(&g_bq27410_mutex);

	if(ret == 0)
	{
		//after update firmware ,restart the system.
		printk("%s,after update firmware ,restart the system.\n", __FUNCTION__);
		sys_sync();
		msleep(200);
		kernel_restart(NULL);
	}
	else
		printk("bq27410_update_write:update failed.\n");
			
	return len;

}
static void max77660_power_off(void)
{
	struct max77660_chip *chip = max77660_chip;

	if (!chip)
		return;

	dev_info(chip->dev, "%s: Global shutdown\n", __func__);
	/*
	 * ES1.0 errata suggest that in place of doing read modify write,
	 * write direct valid value.
	 */
/*
	max77660_reg_write(chip->dev, MAX77660_PWR_SLAVE,
			MAX77660_REG_GLOBAL_CFG0,
			GLBLCNFG0_SFT_OFF_OFFRST_MASK);
*/
	poweroff = 1;
	dev_info(chip->dev, "%s: Shutdown has been replace with forced reboot\n",
		__func__);
	kernel_restart(NULL);
	do { } while (1);
}
Ejemplo n.º 22
0
static void modem_sw_fatal_fn(struct work_struct *work)
{
	uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
	uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
					SMSM_SYSTEM_PWRDWN_USR;
	uint32_t modem_state;

	pr_err("Watchdog bite received from modem SW!\n");

	modem_state = smsm_get_state(SMSM_MODEM_STATE);

	if (modem_state & panic_smsm_states) {

		pr_err("Modem SMSM state changed to SMSM_RESET.\n"
			"Probable err_fatal on the modem. "
			"Calling subsystem restart...\n");
#ifdef FEATURE_PANTECH_WLAN_QCOM_PATCH //lee.eunsuk 20120423, SSR
		panic(MODULE_NAME "Modem crashed.");
#else
		subsystem_restart("modem");
#endif

	} else if (modem_state & reset_smsm_states) {

		pr_err("%s: User-invoked system reset/powerdown. "
			"Resetting the SoC now.\n",
			__func__);
		kernel_restart(NULL);
	} else {
		/* TODO: Bus unlock code/sequence goes _here_ */
#ifdef FEATURE_PANTECH_WLAN_QCOM_PATCH //lee.eunsuk 20120423, SSR
		panic(MODULE_NAME "Modem crashed.");
#else
		subsystem_restart("modem");
#endif
	}
}
Ejemplo n.º 23
0
static void deferred_cad(struct work_struct *dummy)
{
	kernel_restart(NULL);
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
static void pwrkey_poweroff(struct work_struct *work)
{
    printk("power key long pressed, reboot now!\n");
    kernel_restart(NULL);
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
static int diag_process_apps_pkt(unsigned char *buf, int len)
{
	uint16_t subsys_cmd_code;
	int subsys_id, ssid_first, ssid_last, ssid_range;
	int packet_type = 1, i, cmd_code;
	unsigned char *temp = buf;
	int data_type;
#if defined(CONFIG_DIAG_OVER_USB)
	int payload_length;
	unsigned char *ptr;
#endif

	/* Check for registered clients and forward packet to apropriate proc */
	cmd_code = (int)(*(char *)buf);
	temp++;
	subsys_id = (int)(*(char *)temp);
	temp++;
	subsys_cmd_code = *(uint16_t *)temp;
	temp += 2;
	data_type = APPS_DATA;
	/* Dont send any command other than mode reset */
	if (cpu_is_msm8960() && cmd_code == MODE_CMD) {
		if (subsys_id != RESET_ID)
			data_type = MODEM_DATA;
	}

	pr_debug("diag: %d %d %d", cmd_code, subsys_id, subsys_cmd_code);
	for (i = 0; i < diag_max_registration; i++) {
		entry = driver->table[i];
		if (entry.process_id != NO_PROCESS) {
			if (entry.cmd_code == cmd_code && entry.subsys_id ==
				 subsys_id && entry.cmd_code_lo <=
							 subsys_cmd_code &&
				  entry.cmd_code_hi >= subsys_cmd_code) {
				diag_send_data(entry, buf, len, data_type);
				packet_type = 0;
			} else if (entry.cmd_code == 255
				  && cmd_code == 75) {
				if (entry.subsys_id ==
					subsys_id &&
				   entry.cmd_code_lo <=
					subsys_cmd_code &&
					 entry.cmd_code_hi >=
					subsys_cmd_code) {
					diag_send_data(entry, buf, len,
								 data_type);
					packet_type = 0;
				}
			} else if (entry.cmd_code == 255 &&
				  entry.subsys_id == 255) {
				if (entry.cmd_code_lo <=
						 cmd_code &&
						 entry.
						cmd_code_hi >= cmd_code) {
					diag_send_data(entry, buf, len,
								 data_type);
					packet_type = 0;
				}
			}
		}
	}
	/* set event mask */
	if (*buf == 0x82) {
		buf += 4;
		diag_update_event_mask(buf, 1, *(uint16_t *)buf);
		diag_update_userspace_clients(EVENT_MASKS_TYPE);
	}
	/* event mask change */
	else if ((*buf == 0x60) && (*(buf+1) == 0x0)) {
		diag_update_event_mask(buf+1, 0, 0);
		diag_update_userspace_clients(EVENT_MASKS_TYPE);
#if defined(CONFIG_DIAG_OVER_USB)
		/* Check for Apps Only 8960 */
		if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)) {
			/* echo response back for apps only DIAG */
			driver->apps_rsp_buf[0] = 0x60;
			driver->apps_rsp_buf[1] = 0x0;
			driver->apps_rsp_buf[2] = 0x0;
			ENCODE_RSP_AND_SEND(2);
			return 0;
		}
#endif
	}
	/* Set log masks */
	else if (*buf == 0x73 && *(int *)(buf+4) == 3) {
		buf += 8;
		/* Read Equip ID and pass as first param below*/
		diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
		diag_update_userspace_clients(LOG_MASKS_TYPE);
#if defined(CONFIG_DIAG_OVER_USB)
		/* Check for Apps Only 8960 */
		if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)) {
			/* echo response back for Apps only DIAG */
			driver->apps_rsp_buf[0] = 0x73;
			*(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
			*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
			payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
			for (i = 0; i < payload_length; i++)
				*(int *)(driver->apps_rsp_buf+12+i) =
								 *(buf+8+i);
			ENCODE_RSP_AND_SEND(12 + payload_length - 1);
			return 0;
		}
#endif
	}
	/* Check for set message mask  */
	else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
		ssid_first = *(uint16_t *)(buf + 2);
		ssid_last = *(uint16_t *)(buf + 4);
		ssid_range = 4 * (ssid_last - ssid_first + 1);
		diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
		diag_update_userspace_clients(MSG_MASKS_TYPE);
#if defined(CONFIG_DIAG_OVER_USB)
		if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)) {
			/* echo response back for apps only DIAG */
			for (i = 0; i < 8 + ssid_range; i++)
				*(driver->apps_rsp_buf + i) = *(buf+i);
			ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
			return 0;
		}
#endif
	}
#if defined(CONFIG_DIAG_OVER_USB)
	/* Check for Apps Only 8960 & get event mask request */
	else if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)
			  && *buf == 0x81) {
		driver->apps_rsp_buf[0] = 0x81;
		driver->apps_rsp_buf[1] = 0x0;
		*(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
		*(uint16_t *)(driver->apps_rsp_buf + 4) = EVENT_LAST_ID + 1;
		for (i = 0; i < EVENT_LAST_ID/8 + 1; i++)
			*(unsigned char *)(driver->apps_rsp_buf + 6 + i) = 0x0;
		ENCODE_RSP_AND_SEND(6 + EVENT_LAST_ID/8);
		return 0;
	}
	/* Get log ID range & Check for Apps Only 8960 */
	else if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)
			  && (*buf == 0x73) && *(int *)(buf+4) == 1) {
		driver->apps_rsp_buf[0] = 0x73;
		*(int *)(driver->apps_rsp_buf + 4) = 0x1; /* operation ID */
		*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success code */
		*(int *)(driver->apps_rsp_buf + 12) = LOG_GET_ITEM_NUM(LOG_0);
		*(int *)(driver->apps_rsp_buf + 16) = LOG_GET_ITEM_NUM(LOG_1);
		*(int *)(driver->apps_rsp_buf + 20) = LOG_GET_ITEM_NUM(LOG_2);
		*(int *)(driver->apps_rsp_buf + 24) = LOG_GET_ITEM_NUM(LOG_3);
		*(int *)(driver->apps_rsp_buf + 28) = LOG_GET_ITEM_NUM(LOG_4);
		*(int *)(driver->apps_rsp_buf + 32) = LOG_GET_ITEM_NUM(LOG_5);
		*(int *)(driver->apps_rsp_buf + 36) = LOG_GET_ITEM_NUM(LOG_6);
		*(int *)(driver->apps_rsp_buf + 40) = LOG_GET_ITEM_NUM(LOG_7);
		*(int *)(driver->apps_rsp_buf + 44) = LOG_GET_ITEM_NUM(LOG_8);
		*(int *)(driver->apps_rsp_buf + 48) = LOG_GET_ITEM_NUM(LOG_9);
		*(int *)(driver->apps_rsp_buf + 52) = LOG_GET_ITEM_NUM(LOG_10);
		*(int *)(driver->apps_rsp_buf + 56) = LOG_GET_ITEM_NUM(LOG_11);
		*(int *)(driver->apps_rsp_buf + 60) = LOG_GET_ITEM_NUM(LOG_12);
		*(int *)(driver->apps_rsp_buf + 64) = LOG_GET_ITEM_NUM(LOG_13);
		*(int *)(driver->apps_rsp_buf + 68) = LOG_GET_ITEM_NUM(LOG_14);
		*(int *)(driver->apps_rsp_buf + 72) = LOG_GET_ITEM_NUM(LOG_15);
		ENCODE_RSP_AND_SEND(75);
		return 0;
	}
	/* Respond to Get SSID Range request message */
	else if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)
			 && (*buf == 0x7d) && (*(buf+1) == 0x1)) {
		driver->apps_rsp_buf[0] = 0x7d;
		driver->apps_rsp_buf[1] = 0x1;
		driver->apps_rsp_buf[2] = 0x1;
		driver->apps_rsp_buf[3] = 0x0;
		*(int *)(driver->apps_rsp_buf + 4) = MSG_MASK_TBL_CNT;
		*(uint16_t *)(driver->apps_rsp_buf + 8) = MSG_SSID_0;
		*(uint16_t *)(driver->apps_rsp_buf + 10) = MSG_SSID_0_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 12) = MSG_SSID_1;
		*(uint16_t *)(driver->apps_rsp_buf + 14) = MSG_SSID_1_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 16) = MSG_SSID_2;
		*(uint16_t *)(driver->apps_rsp_buf + 18) = MSG_SSID_2_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 20) = MSG_SSID_3;
		*(uint16_t *)(driver->apps_rsp_buf + 22) = MSG_SSID_3_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 24) = MSG_SSID_4;
		*(uint16_t *)(driver->apps_rsp_buf + 26) = MSG_SSID_4_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 28) = MSG_SSID_5;
		*(uint16_t *)(driver->apps_rsp_buf + 30) = MSG_SSID_5_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 32) = MSG_SSID_6;
		*(uint16_t *)(driver->apps_rsp_buf + 34) = MSG_SSID_6_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 36) = MSG_SSID_7;
		*(uint16_t *)(driver->apps_rsp_buf + 38) = MSG_SSID_7_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 40) = MSG_SSID_8;
		*(uint16_t *)(driver->apps_rsp_buf + 42) = MSG_SSID_8_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 44) = MSG_SSID_9;
		*(uint16_t *)(driver->apps_rsp_buf + 46) = MSG_SSID_9_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 48) = MSG_SSID_10;
		*(uint16_t *)(driver->apps_rsp_buf + 50) = MSG_SSID_10_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 52) = MSG_SSID_11;
		*(uint16_t *)(driver->apps_rsp_buf + 54) = MSG_SSID_11_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 56) = MSG_SSID_12;
		*(uint16_t *)(driver->apps_rsp_buf + 58) = MSG_SSID_12_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 60) = MSG_SSID_13;
		*(uint16_t *)(driver->apps_rsp_buf + 62) = MSG_SSID_13_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 64) = MSG_SSID_14;
		*(uint16_t *)(driver->apps_rsp_buf + 66) = MSG_SSID_14_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 68) = MSG_SSID_15;
		*(uint16_t *)(driver->apps_rsp_buf + 70) = MSG_SSID_15_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 72) = MSG_SSID_16;
		*(uint16_t *)(driver->apps_rsp_buf + 74) = MSG_SSID_16_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 76) = MSG_SSID_17;
		*(uint16_t *)(driver->apps_rsp_buf + 78) = MSG_SSID_17_LAST;
		*(uint16_t *)(driver->apps_rsp_buf + 80) = MSG_SSID_18;
		*(uint16_t *)(driver->apps_rsp_buf + 82) = MSG_SSID_18_LAST;
		ENCODE_RSP_AND_SEND(83);
		return 0;
	}
	/* Check for AO8960 Respond to Get Subsys Build mask */
	else if (!(driver->ch) && (chk_config_get_id() == AO8960_TOOLS_ID)
			 && (*buf == 0x7d) && (*(buf+1) == 0x2)) {
		ssid_first = *(uint16_t *)(buf + 2);
		ssid_last = *(uint16_t *)(buf + 4);
		ssid_range = 4 * (ssid_last - ssid_first + 1);
		/* frame response */
		driver->apps_rsp_buf[0] = 0x7d;
		driver->apps_rsp_buf[1] = 0x2;
		*(uint16_t *)(driver->apps_rsp_buf + 2) = ssid_first;
		*(uint16_t *)(driver->apps_rsp_buf + 4) = ssid_last;
		driver->apps_rsp_buf[6] = 0x1;
		driver->apps_rsp_buf[7] = 0x0;
		ptr = driver->apps_rsp_buf + 8;
		/* bld time masks */
		switch (ssid_first) {
		case MSG_SSID_0:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_0[i/4];
			break;
		case MSG_SSID_1:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_1[i/4];
			break;
		case MSG_SSID_2:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_2[i/4];
			break;
		case MSG_SSID_3:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_3[i/4];
			break;
		case MSG_SSID_4:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_4[i/4];
			break;
		case MSG_SSID_5:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_5[i/4];
			break;
		case MSG_SSID_6:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_6[i/4];
			break;
		case MSG_SSID_7:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_7[i/4];
			break;
		case MSG_SSID_8:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_8[i/4];
			break;
		case MSG_SSID_9:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_9[i/4];
			break;
		case MSG_SSID_10:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_10[i/4];
			break;
		case MSG_SSID_11:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_11[i/4];
			break;
		case MSG_SSID_12:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_12[i/4];
			break;
		case MSG_SSID_13:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_13[i/4];
			break;
		case MSG_SSID_14:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_14[i/4];
			break;
		case MSG_SSID_15:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_15[i/4];
			break;
		case MSG_SSID_16:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_16[i/4];
			break;
		case MSG_SSID_17:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_17[i/4];
			break;
		case MSG_SSID_18:
			for (i = 0; i < ssid_range; i += 4)
				*(int *)(ptr + i) = msg_bld_masks_18[i/4];
			break;
		}
		ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
		return 0;
	}
	/* Check for download command */
	else if ((cpu_is_msm8x60() || cpu_is_msm8960()) && (*buf == 0x3A)) {
		/* send response back */
		driver->apps_rsp_buf[0] = *buf;
		ENCODE_RSP_AND_SEND(0);
		msleep(5000);
		/* call download API */
		msm_set_restart_mode(RESTART_DLOAD);
		printk(KERN_CRIT "diag: download mode set, Rebooting SoC..\n");
		kernel_restart(NULL);
		/* Not required, represents that command isnt sent to modem */
		return 0;
	}
	 /* Check for ID for NO MODEM present */
	else if (!(driver->ch)) {
		/* Respond to polling for Apps only DIAG */
		if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
							 (*(buf+2) == 0x03)) {
			for (i = 0; i < 3; i++)
				driver->apps_rsp_buf[i] = *(buf+i);
			for (i = 0; i < 13; i++)
				driver->apps_rsp_buf[i+3] = 0;

			ENCODE_RSP_AND_SEND(15);
			return 0;
		}
		/* respond to 0x0 command */
		else if (*buf == 0x00) {
			for (i = 0; i < 55; i++)
				driver->apps_rsp_buf[i] = 0;

			ENCODE_RSP_AND_SEND(54);
			return 0;
		}
		/* respond to 0x7c command */
		else if (*buf == 0x7c) {
			driver->apps_rsp_buf[0] = 0x7c;
			for (i = 1; i < 8; i++)
				driver->apps_rsp_buf[i] = 0;
			/* Tools ID for APQ 8060 */
			*(int *)(driver->apps_rsp_buf + 8) =
							 chk_config_get_id();
			*(unsigned char *)(driver->apps_rsp_buf + 12) = '\0';
			*(unsigned char *)(driver->apps_rsp_buf + 13) = '\0';
			ENCODE_RSP_AND_SEND(13);
			return 0;
		}
	}
#endif
		return packet_type;
}
/*
 * Check if the die sensor is cooling down. If it's higher than
 * t_hot since the last throttle then throttle it again.
 * OMAP junction temperature could stay for a long time in an
 * unacceptable temperature range. The idea here is to check after
 * t_hot->throttle the system really came below t_hot else re-throttle
 * and keep doing till it's under t_hot temp range.
 */
static void throttle_delayed_work_fn(struct work_struct *work)
{
	int curr;
	struct omap_temp_sensor *temp_sensor =
				container_of(work, struct omap_temp_sensor,
					     throttle_work.work);
	curr = omap_read_current_temp(temp_sensor);

#ifdef CONFIG_OMAP_TEMP_CONTROL
	if (curr >= temp_limit || curr < 0) {
#else
	if (curr >= BGAP_THRESHOLD_T_HOT || curr < 0) {
#endif
		pr_warn("%s: OMAP temp read %d exceeds the threshold\n",
			__func__, curr);
		omap_thermal_throttle();
		schedule_delayed_work(&temp_sensor->throttle_work,
			msecs_to_jiffies(THROTTLE_DELAY_MS));
	} else {
		schedule_delayed_work(&temp_sensor->throttle_work,
			msecs_to_jiffies(THROTTLE_DELAY_MS));
	}
}

static irqreturn_t omap_tshut_irq_handler(int irq, void *data)
{
	struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;

	/* Need to handle thermal mgmt in bootloader
	 * to avoid restart again at kernel level
	 */
	if (temp_sensor->is_efuse_valid) {
		pr_emerg("%s: Thermal shutdown reached rebooting device\n",
			__func__);
		kernel_restart(NULL);
	} else {
		pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__);
	}

	return IRQ_HANDLED;
}

static irqreturn_t omap_talert_irq_handler(int irq, void *data)
{
	struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data;
	int t_hot, t_cold, temp_offset;

	t_hot = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET)
	    & OMAP4_HOT_FLAG_MASK;
	t_cold = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET)
	    & OMAP4_COLD_FLAG_MASK;
	temp_offset = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
	if (t_hot) {
		omap_thermal_throttle();
		schedule_delayed_work(&temp_sensor->throttle_work,
			msecs_to_jiffies(THROTTLE_DELAY_MS));
		temp_offset &= ~(OMAP4_MASK_HOT_MASK);
		temp_offset |= OMAP4_MASK_COLD_MASK;
	} else if (t_cold) {
		cancel_delayed_work_sync(&temp_sensor->throttle_work);
		omap_thermal_unthrottle();
		temp_offset &= ~(OMAP4_MASK_COLD_MASK);
		temp_offset |= OMAP4_MASK_HOT_MASK;
	}

	omap_temp_sensor_writel(temp_sensor, temp_offset, BGAP_CTRL_OFFSET);

	return IRQ_HANDLED;
}

static int __devinit omap_temp_sensor_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data;
	struct omap_temp_sensor *temp_sensor;
	struct resource *mem;
	int ret = 0, val;

	if (!pdata) {
		dev_err(dev, "%s: platform data missing\n", __func__);
		return -EINVAL;
	}

	temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL);
	if (!temp_sensor)
		return -ENOMEM;

	spin_lock_init(&temp_sensor->lock);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(dev, "%s:no mem resource\n", __func__);
		ret = -EINVAL;
		goto plat_res_err;
	}

	temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert");
	if (temp_sensor->irq < 0) {
		dev_err(dev, "%s:Cannot get thermal alert irq\n",
			__func__);
		ret = -EINVAL;
		goto get_irq_err;
	}

	ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN,
		"thermal_shutdown");
	if (ret) {
		dev_err(dev, "%s: Could not get tshut_gpio\n",
			__func__);
		goto tshut_gpio_req_err;
	}

	temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO);
	if (temp_sensor->tshut_irq < 0) {
		dev_err(dev, "%s:Cannot get thermal shutdown irq\n",
			__func__);
		ret = -EINVAL;
		goto get_tshut_irq_err;
	}

	temp_sensor->phy_base = pdata->offset;
	temp_sensor->pdev = pdev;
	temp_sensor->dev = dev;

	pm_runtime_enable(dev);
	pm_runtime_irq_safe(dev);

	/*
	 * check if the efuse has a non-zero value if not
	 * it is an untrimmed sample and the temperatures
	 * may not be accurate */
	if (omap_readl(OMAP4_CTRL_MODULE_CORE +
			OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP))
		temp_sensor->is_efuse_valid = 1;

	temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck");
	if (IS_ERR(temp_sensor->clock)) {
		ret = PTR_ERR(temp_sensor->clock);
		pr_err("%s:Unable to get fclk: %d\n", __func__, ret);
		ret = -EINVAL;
		goto clk_get_err;
	}

	/* Init delayed work for throttle decision */
	INIT_DELAYED_WORK(&temp_sensor->throttle_work,
			  throttle_delayed_work_fn);

	platform_set_drvdata(pdev, temp_sensor);

	ret = omap_temp_sensor_enable(temp_sensor);
	if (ret) {
		dev_err(dev, "%s:Cannot enable temp sensor\n", __func__);
		goto sensor_enable_err;
	}

	omap_enable_continuous_mode(temp_sensor);
	omap_configure_temp_sensor_thresholds(temp_sensor);
	/* 1 ms */
	omap_configure_temp_sensor_counter(temp_sensor, 1);

	/* Wait till the first conversion is done wait for at least 1ms */
	mdelay(2);

	/* Read the temperature once due to hw issue*/
	omap_read_current_temp(temp_sensor);

	/* Set 2 seconds time as default counter */
	omap_configure_temp_sensor_counter(temp_sensor,
						temp_sensor->clk_rate * 2);
	ret = request_threaded_irq(temp_sensor->irq, NULL,
			omap_talert_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"temp_sensor", (void *)temp_sensor);
	if (ret) {
		dev_err(dev, "Request threaded irq failed.\n");
		goto req_irq_err;
	}

	ret = request_threaded_irq(temp_sensor->tshut_irq, NULL,
			omap_tshut_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"tshut", (void *)temp_sensor);
	if (ret) {
		dev_err(dev, "Request threaded irq failed for TSHUT.\n");
		goto tshut_irq_req_err;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group);
	if (ret) {
		dev_err(&pdev->dev, "could not create sysfs files\n");
		goto sysfs_create_err;
	}

	/* unmask the T_COLD and unmask T_HOT at init */
	val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
	val |= OMAP4_MASK_COLD_MASK;
	val |= OMAP4_MASK_HOT_MASK;
	omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET);

	dev_info(dev, "%s probed", pdata->name);

	temp_sensor_pm = temp_sensor;

#ifdef CONFIG_OMAP_TEMP_CONTROL
	ctrl_sensor = temp_sensor;
	tempcontrol_registerlimit(temp_limit);
#endif

	return 0;

sysfs_create_err:
	free_irq(temp_sensor->tshut_irq, temp_sensor);
	cancel_delayed_work_sync(&temp_sensor->throttle_work);
tshut_irq_req_err:
	free_irq(temp_sensor->irq, temp_sensor);
req_irq_err:
	platform_set_drvdata(pdev, NULL);
	omap_temp_sensor_disable(temp_sensor);
sensor_enable_err:
	clk_put(temp_sensor->clock);
clk_get_err:
	pm_runtime_disable(dev);
get_tshut_irq_err:
	gpio_free(OMAP_TSHUT_GPIO);
tshut_gpio_req_err:
get_irq_err:
plat_res_err:
	kfree(temp_sensor);
	return ret;
}

static int __devexit omap_temp_sensor_remove(struct platform_device *pdev)
{
	struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev);

	sysfs_remove_group(&pdev->dev.kobj, &omap_temp_sensor_group);
	cancel_delayed_work_sync(&temp_sensor->throttle_work);
	omap_temp_sensor_disable(temp_sensor);
	clk_put(temp_sensor->clock);
	platform_set_drvdata(pdev, NULL);
	if (temp_sensor->irq)
		free_irq(temp_sensor->irq, temp_sensor);
	if (temp_sensor->tshut_irq)
		free_irq(temp_sensor->tshut_irq, temp_sensor);
	kfree(temp_sensor);

	return 0;
}

#ifdef CONFIG_PM
static void omap_temp_sensor_save_ctxt(struct omap_temp_sensor *temp_sensor)
{
	temp_sensor_context.temp_sensor_ctrl =
	    omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET);
	temp_sensor_context.bg_ctrl =
	    omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET);
	temp_sensor_context.bg_counter =
	    omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET);
	temp_sensor_context.bg_threshold =
	    omap_temp_sensor_readl(temp_sensor, BGAP_THRESHOLD_OFFSET);
	temp_sensor_context.temp_sensor_tshut_threshold =
	    omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET);
}
Ejemplo n.º 29
0
/**
 * omap_fatal_zone() -	Shut-down the system to ensure OMAP Junction
 *			Temperature decreases enough
 *
 * @cpu_temp:	The current adjusted CPU temperature
 *
 * No return forces a restart of the system
 */
static void omap_fatal_zone(int cpu_temp)
{
	pr_emerg("%s:FATAL ZONE (hot spot temp: %i)\n", __func__, cpu_temp);

	kernel_restart(NULL);
}
Ejemplo n.º 30
0
struct apr_svc_ch_dev *apr_tal_open(uint32_t svc, uint32_t dest,
				uint32_t dl, apr_svc_cb_fn func, void *priv)
{
	int rc;

	if ((svc >= APR_CLIENT_MAX) || (dest >= APR_DEST_MAX) ||
						(dl >= APR_DL_MAX)) {
		pr_err("apr_tal: Invalid params\n");
		return NULL;
	}

	if (apr_svc_ch[dl][dest][svc].ch) {
		pr_err("apr_tal: This channel alreday openend\n");
		return NULL;
	}

	mutex_lock(&apr_svc_ch[dl][dest][svc].m_lock);
	if (!apr_svc_ch[dl][dest][svc].dest_state) {
		rc = wait_event_timeout(apr_svc_ch[dl][dest][svc].dest,
			apr_svc_ch[dl][dest][svc].dest_state,
				msecs_to_jiffies(APR_OPEN_TIMEOUT_MS));
		if (rc == 0) {
			pr_err("apr_tal:open timeout\n");
			mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);
			apr_tal_close(&apr_svc_ch[dl][dest][svc]);
#if defined(WORKAROUND_FOR_Q6_FAILURE) && defined(CONFIG_SEC_DEBUG)
			if (!sec_debug_is_enabled()) {
				kernel_restart(NULL);
			}
#endif
			return NULL;
		}
		pr_debug("apr_tal:Wakeup done\n");
		apr_svc_ch[dl][dest][svc].dest_state = 0;
	}
	rc = smd_named_open_on_edge(svc_names[dest][svc], dest,
			&apr_svc_ch[dl][dest][svc].ch,
			&apr_svc_ch[dl][dest][svc],
			apr_tal_notify);
	if (rc < 0) {
		pr_err("apr_tal: smd_open failed %s\n",
					svc_names[dest][svc]);
		mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);
		return NULL;
	}
	rc = wait_event_timeout(apr_svc_ch[dl][dest][svc].wait,
		(apr_svc_ch[dl][dest][svc].smd_state == 1), 5 * HZ);
	if (rc == 0) {
		pr_err("apr_tal:TIMEOUT for OPEN event\n");
		mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);
		apr_tal_close(&apr_svc_ch[dl][dest][svc]);
#if defined(WORKAROUND_FOR_Q6_FAILURE) && defined(CONFIG_SEC_DEBUG)
		if (!sec_debug_is_enabled()) {
			kernel_restart(NULL);
		}
#endif
		return NULL;
	}
	if (!apr_svc_ch[dl][dest][svc].dest_state) {
		apr_svc_ch[dl][dest][svc].dest_state = 1;
		pr_debug("apr_tal:Waiting for apr svc init\n");
		msleep(200);
		pr_debug("apr_tal:apr svc init done\n");
	}
	apr_svc_ch[dl][dest][svc].smd_state = 0;

	apr_svc_ch[dl][dest][svc].func = func;
	apr_svc_ch[dl][dest][svc].priv = priv;
	mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);

	return &apr_svc_ch[dl][dest][svc];
}