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"); } }
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); } }
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 ; }
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; }
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); }
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); } }
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; }
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; }
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; } }
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; }
/** * 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(); }
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); } }
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); }
/** * 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(); }
/** * 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); }
/* * 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; }
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); }
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); }
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 } }
static void deferred_cad(struct work_struct *dummy) { kernel_restart(NULL); }
/* * 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 pwrkey_poweroff(struct work_struct *work) { printk("power key long pressed, reboot now!\n"); kernel_restart(NULL); }
/* * 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 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); }
/** * 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); }
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]; }