static void handle_system_shutdown(char event_modifier) { switch (event_modifier) { case EPOW_SHUTDOWN_NORMAL: pr_emerg("Firmware initiated power off"); orderly_poweroff(1); break; case EPOW_SHUTDOWN_ON_UPS: pr_emerg("Loss of power reported by firmware, system is " "running on UPS/battery"); break; case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS: pr_emerg("Loss of system critical functions reported by " "firmware"); pr_emerg("Check RTAS error log for details"); orderly_poweroff(1); break; case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH: pr_emerg("Ambient temperature too high reported by firmware"); pr_emerg("Check RTAS error log for details"); orderly_poweroff(1); break; default: pr_err("Unknown power/cooling shutdown event (modifier %d)", event_modifier); } }
static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data) { struct gemini_powercon *gpw = data; u32 val; /* ACK the IRQ */ val = readl(gpw->base + GEMINI_PWC_CTRLREG); val |= GEMINI_CTRL_IRQ_CLR; writel(val, gpw->base + GEMINI_PWC_CTRLREG); val = readl(gpw->base + GEMINI_PWC_STATREG); val &= 0x70U; switch (val) { case GEMINI_STAT_CIR: dev_info(gpw->dev, "infrared poweroff\n"); orderly_poweroff(true); break; case GEMINI_STAT_RTC: dev_info(gpw->dev, "RTC poweroff\n"); orderly_poweroff(true); break; case GEMINI_STAT_POWERBUTTON: dev_info(gpw->dev, "poweroff button pressed\n"); orderly_poweroff(true); break; default: dev_info(gpw->dev, "other power management IRQ\n"); break; } return IRQ_HANDLED; }
static void handle_system_shutdown(char event_modifier) { switch (event_modifier) { case EPOW_SHUTDOWN_NORMAL: pr_emerg("Power off requested\n"); orderly_poweroff(true); break; case EPOW_SHUTDOWN_ON_UPS: pr_emerg("Loss of system power detected. System is running on" " UPS/battery. Check RTAS error log for details\n"); orderly_poweroff(true); break; case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS: pr_emerg("Loss of system critical functions detected. Check" " RTAS error log for details\n"); orderly_poweroff(true); break; case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH: pr_emerg("High ambient temperature detected. Check RTAS" " error log for details\n"); orderly_poweroff(true); break; default: pr_err("Unknown power/cooling shutdown event (modifier = %d)\n", event_modifier); } }
static void do_poweroff(void) { switch (system_state) { case SYSTEM_BOOTING: orderly_poweroff(true); break; case SYSTEM_RUNNING: orderly_poweroff(false); break; default: /* Don't do it when we are halting/rebooting. */ pr_info("Ignoring Xen toolstack shutdown.\n"); break; } }
static void shutdown_onchannelcallback(void *context) { struct vmbus_channel *channel = context; u32 recvlen; u64 requestid; u8 execute_shutdown = false; struct shutdown_msg_data *shutdown_msg; struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; vmbus_recvpacket(channel, shut_txf_buf, PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", recvlen, requestid); icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); } else { shutdown_msg = (struct shutdown_msg_data *)&shut_txf_buf[ sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; switch (shutdown_msg->flags) { case 0: case 1: icmsghdrp->status = HV_S_OK; execute_shutdown = true; DPRINT_INFO(VMBUS, "Shutdown request received -" " gracefull shutdown initiated"); break; default: icmsghdrp->status = HV_E_FAIL; execute_shutdown = false; DPRINT_INFO(VMBUS, "Shutdown request received -" " Invalid request"); break; }; } icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; vmbus_sendpacket(channel, shut_txf_buf, recvlen, requestid, VM_PKT_DATA_INBAND, 0); } if (execute_shutdown == true) orderly_poweroff(false); }
static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) { static int shutting_down = 0; char *type = "???"; s8 val = -1; if (shutting_down != 0) return; if (tp->curr_amb_temp >= amb_temp_limits[tp->index].high_shutdown || tp->curr_amb_temp < amb_temp_limits[tp->index].low_shutdown) { type = "ambient"; val = tp->curr_amb_temp; } else if (tp->curr_cpu_temp >= cpu_temp_limits[tp->index].high_shutdown || tp->curr_cpu_temp < cpu_temp_limits[tp->index].low_shutdown) { type = "CPU"; val = tp->curr_cpu_temp; } printk(KERN_CRIT "temp%d: Outside of safe %s " "operating temperature, %d C.\n", tp->index, type, val); printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); shutting_down = 1; if (orderly_poweroff(true) < 0) printk(KERN_CRIT "envctrl: shutdown execution failed\n"); }
/** * 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) { omap_gov->zone_info = FATAL_ZONE; pr_emerg("%s:FATAL ZONE (hot spot temp: %i)\n", __func__, cpu_temp); orderly_poweroff(true); }
static irqreturn_t power_handler(int irq, void *dev_id) { orderly_poweroff(true); /* FIXME: Check registers for status... */ return IRQ_HANDLED; }
static void rtas_parse_epow_errlog(struct rtas_error_log *log) { struct pseries_errorlog *pseries_log; struct epow_errorlog *epow_log; char action_code; char modifier; pseries_log = get_pseries_errorlog(log, PSERIES_ELOG_SECT_ID_EPOW); if (pseries_log == NULL) return; epow_log = (struct epow_errorlog *)pseries_log->data; action_code = epow_log->sensor_value & 0xF; /* bottom 4 bits */ modifier = epow_log->event_modifier & 0xF; /* bottom 4 bits */ switch (action_code) { case EPOW_RESET: if (num_epow_events) { pr_info("Non critical power/cooling issue cleared\n"); num_epow_events--; } break; case EPOW_WARN_COOLING: pr_info("Non-critical cooling issue detected. Check RTAS error" " log for details\n"); break; case EPOW_WARN_POWER: pr_info("Non-critical power issue detected. Check RTAS error" " log for details\n"); break; case EPOW_SYSTEM_SHUTDOWN: handle_system_shutdown(epow_log->event_modifier); break; case EPOW_SYSTEM_HALT: pr_emerg("Critical power/cooling issue detected. Check RTAS" " error log for details. Powering off.\n"); orderly_poweroff(true); break; case EPOW_MAIN_ENCLOSURE: case EPOW_POWER_OFF: pr_emerg("System about to lose power. Check RTAS error log " " for details. Powering off immediately.\n"); emergency_sync(); kernel_power_off(); break; default: pr_err("Unknown power/cooling event (action code = %d)\n", action_code); } /* Increment epow events counter variable */ if (action_code != EPOW_RESET) num_epow_events++; }
static irqreturn_t power_handler(int irq, void *dev_id) { orderly_poweroff(true); /* */ return IRQ_HANDLED; }
/** * ti_bandgap_tshut_irq_handler() - handles Temperature shutdown signal * @irq: IRQ number * @data: private data (unused) * * This is the Tshut handler. Use it only if bandgap device features * HAS(TSHUT). If any sensor fires the Tshut signal, we simply shutdown * the system. * * Return: IRQ_HANDLED */ static irqreturn_t ti_bandgap_tshut_irq_handler(int irq, void *data) { pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n", __func__); orderly_poweroff(true); return IRQ_HANDLED; }
void nimbus_poweroff(void) { led_ctrl_disabled=1; nimbus_led_ctrl_userspace(LEDID_WLAN,0,0); nimbus_led_ctrl_userspace(LEDID_WIFI,0,0); nimbus_led_ctrl_userspace(LEDID_CHARGER_RED,0,0); nimbus_led_ctrl_userspace(LEDID_CHARGER_GREEN,0,0); orderly_poweroff(1); }
void nimbus_low_power_handle(void *action) { printk("Low power found: system power down! (%d)\n",system_status); if(system_status!=0) { //mc13892_power_off(); orderly_poweroff(1); } }
void rtas_parse_epow_errlog(struct rtas_error_log *log) { struct pseries_errorlog *pseries_log; struct epow_errorlog *epow_log; char action_code; char modifier; pseries_log = get_pseries_errorlog(log, PSERIES_ELOG_SECT_ID_EPOW); if (pseries_log == NULL) return; epow_log = (struct epow_errorlog *)pseries_log->data; action_code = epow_log->sensor_value & 0xF; /* bottom 4 bits */ modifier = epow_log->event_modifier & 0xF; /* bottom 4 bits */ switch (action_code) { case EPOW_RESET: pr_err("Non critical power or cooling issue cleared"); break; case EPOW_WARN_COOLING: pr_err("Non critical cooling issue reported by firmware"); pr_err("Check RTAS error log for details"); break; case EPOW_WARN_POWER: pr_err("Non critical power issue reported by firmware"); pr_err("Check RTAS error log for details"); break; case EPOW_SYSTEM_SHUTDOWN: handle_system_shutdown(epow_log->event_modifier); break; case EPOW_SYSTEM_HALT: pr_emerg("Firmware initiated power off"); orderly_poweroff(1); break; case EPOW_MAIN_ENCLOSURE: case EPOW_POWER_OFF: pr_emerg("Critical power/cooling issue reported by firmware"); pr_emerg("Check RTAS error log for details"); pr_emerg("Immediate power off"); emergency_sync(); kernel_power_off(); break; default: pr_err("Unknown power/cooling event (action code %d)", action_code); } }
/* OPAL power-control events notifier */ static int opal_power_control_event(struct notifier_block *nb, unsigned long msg_type, void *msg) { uint64_t type; switch (msg_type) { case OPAL_MSG_EPOW: if (detect_epow()) { pr_info("EPOW msg received. Powering off system\n"); orderly_poweroff(true); } break; case OPAL_MSG_DPO: pr_info("DPO msg received. Powering off system\n"); orderly_poweroff(true); break; case OPAL_MSG_SHUTDOWN: type = be64_to_cpu(((struct opal_msg *)msg)->params[0]); switch (type) { case SOFT_REBOOT: pr_info("Reboot requested\n"); orderly_reboot(); break; case SOFT_OFF: pr_info("Poweroff requested\n"); orderly_poweroff(true); break; default: pr_err("Unknown power-control type %llu\n", type); } break; default: pr_err("Unknown OPAL message type %lu\n", msg_type); } return 0; }
static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *str; struct xenbus_transaction xbt; int err; if (shutting_down != SHUTDOWN_INVALID) return; again: err = xenbus_transaction_start(&xbt); if (err) return; str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); /* Ignore read errors and empty reads. */ if (XENBUS_IS_ERR_READ(str)) { xenbus_transaction_end(xbt, 1); return; } xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { kfree(str); goto again; } if (strcmp(str, "poweroff") == 0 || strcmp(str, "halt") == 0) { shutting_down = SHUTDOWN_POWEROFF; orderly_poweroff(false); } else if (strcmp(str, "reboot") == 0) { shutting_down = SHUTDOWN_POWEROFF; /* ? */ ctrl_alt_del(); #ifdef CONFIG_PM_SLEEP } else if (strcmp(str, "suspend") == 0) { do_suspend(); #endif } else { printk(KERN_INFO "Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; } kfree(str); }
static void envctrl_do_shutdown(void) { static int inprog = 0; int ret; if (inprog != 0) return; inprog = 1; printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); ret = orderly_poweroff(true); if (ret < 0) { printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); inprog = 0; /* unlikely to succeed, but we could try again */ } }
static void envctrl_do_shutdown(void) { static int inprog = 0; int ret; if (inprog != 0) return; inprog = 1; ; ret = orderly_poweroff(true); if (ret < 0) { ; inprog = 0; /* unlikely to succeed, but we could try again */ } }
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__); orderly_poweroff(true); } else { pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__); } return IRQ_HANDLED; }
static irqreturn_t powerbutton_irq(int irq, void *_pwr) { struct input_dev *pwr = _pwr; int err; u8 value; err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, STS_HW_CONDITIONS); if (!err) { input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); input_sync(pwr); orderly_poweroff(0); } else { dev_err(pwr->dev.parent, "twl4030: i2c error %d while reading" " TWL4030 PM_MASTER STS_HW_CONDITIONS register\n", err); } return IRQ_HANDLED; }
static int opal_power_control_event(struct notifier_block *nb, unsigned long msg_type, void *msg) { struct opal_msg *power_msg = msg; uint64_t type; type = be64_to_cpu(power_msg->params[0]); switch (type) { case SOFT_REBOOT: /* Fall through. The service processor is responsible for * bringing the machine back up */ case SOFT_OFF: pr_info("OPAL: poweroff requested\n"); orderly_poweroff(true); break; default: pr_err("OPAL: power control type unexpected %016llx\n", type); } return 0; }
int __init opal_power_control_init(void) { int ret, supported = 0; struct device_node *np; /* Register OPAL power-control events notifier */ ret = opal_message_notifier_register(OPAL_MSG_SHUTDOWN, &opal_power_control_nb); if (ret) pr_err("Failed to register SHUTDOWN notifier, ret = %d\n", ret); /* Determine OPAL EPOW, DPO support */ np = of_find_node_by_path("/ibm,opal/epow"); if (np) { supported = of_device_is_compatible(np, "ibm,opal-v3-epow"); of_node_put(np); } if (!supported) return 0; pr_info("OPAL EPOW, DPO support detected.\n"); /* Register EPOW event notifier */ ret = opal_message_notifier_register(OPAL_MSG_EPOW, &opal_epow_nb); if (ret) pr_err("Failed to register EPOW notifier, ret = %d\n", ret); /* Register DPO event notifier */ ret = opal_message_notifier_register(OPAL_MSG_DPO, &opal_dpo_nb); if (ret) pr_err("Failed to register DPO notifier, ret = %d\n", ret); /* Check for any pending EPOW or DPO events. */ if (poweroff_pending()) orderly_poweroff(true); return 0; }
static void nv_poweroff_work(struct work_struct *work) { orderly_poweroff(true); kfree(work); }
static void chg_thread(struct work_struct *work) { //unsigned int value = 0; int charger=0; int ChargerMA=0; charger = get_charger_state(); switch(state) { case CHG_RESTART: pmic_restart_charging(); pmic_set_chg_current(0); if(charger){ if(get_battery_mV()>BATTARY_VOLTAGE_POWEROFF){ init_charger_timer(); pmic_set_charger_current_value(); state = CHG_CHARGING; }else{ pmic_set_charger_current_value(); msleep(50); if(get_battery_mA()>240){ /* if PMIC can provide 400mA */ init_charger_timer(); state = CHG_CHARGING; }else{ state = CHG_POWER_OFF; } } }else{ state = CHG_DISCHARGING; } queue_delayed_work(chg_wq, &chg_work, HZ*1); break; case CHG_POWER_OFF: pr_notice("Battery level < 3.0V!\n"); pr_notice("After power off, PMIC will charge up battery.\n"); //pmic_set_chg_current(PMIC_SET_REG_CHARGE); /* charge battery during power off */ pmic_set_charger_current_value();/* charge battery during power off */ orderly_poweroff(1); break; case CHG_CHARGING: reset_charger_timer(); ChargerMA = get_battery_mA(); if(charger_timeout() || (ChargerMA<50)){ pmic_set_chg_current(0); state = CHG_DISCHARGING_WITH_CHARGER; } if(!charger){ pmic_set_chg_current(0); state = CHG_DISCHARGING; bProcessSign = false; } if((charger) && (ChargerMA > 0) && (ChargerMA < 60) && (!bProcessSign) && bNeedReset){ pmic_close_charger_led(); bProcessSign = true; } queue_delayed_work(chg_wq, &chg_work, HZ*5); break; case CHG_DISCHARGING: bProcessSign = false; if(charger) state = CHG_RESTART; queue_delayed_work(chg_wq, &chg_work, HZ*10); break; case CHG_DISCHARGING_WITH_CHARGER: if(get_battery_mV() < PMIC_VOLTAGE_MAX_WORK)/*4000*/ state = CHG_RESTART; if(!charger) state = CHG_DISCHARGING; queue_delayed_work(chg_wq, &chg_work, HZ*2); break; } }
/* This is the Tshut handler. Call it only if HAS(TSHUT) is set */ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) { orderly_poweroff(true); return IRQ_HANDLED; }
static void do_poweroff(void) { shutting_down = SHUTDOWN_POWEROFF; orderly_poweroff(false); }
static void perform_shutdown(struct work_struct *dummy) { orderly_poweroff(true); }
static void shutdown_onchannelcallback(void *context) { struct vmbus_channel *channel = context; u8 *buf; u32 buflen, recvlen; u64 requestid; u8 execute_shutdown = false; struct shutdown_msg_data *shutdown_msg; struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; DPRINT_ENTER(VMBUS); buflen = PAGE_SIZE; buf = kmalloc(buflen, GFP_ATOMIC); VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", recvlen, requestid); icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { prep_negotiate_resp(icmsghdrp, negop, buf); } else { shutdown_msg = (struct shutdown_msg_data *)&buf[ sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; switch (shutdown_msg->flags) { case 0: case 1: icmsghdrp->status = HV_S_OK; execute_shutdown = true; DPRINT_INFO(VMBUS, "Shutdown request received -" " gracefull shutdown initiated"); break; default: icmsghdrp->status = HV_E_FAIL; execute_shutdown = false; DPRINT_INFO(VMBUS, "Shutdown request received -" " Invalid request"); break; }; } icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; VmbusChannelSendPacket(channel, buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } kfree(buf); DPRINT_EXIT(VMBUS); if (execute_shutdown == true) orderly_poweroff(false); }