switch (action) { case SYS_RESTART:
val = SMC_KEY(rest);
shutdown_flag = 0; break; case SYS_POWER_OFF:
val = SMC_KEY(offw);
shutdown_flag = 1; break; default: return NOTIFY_DONE;
}
dev_info(reboot->dev, "Preparing for reboot (%p4ch)\n", &val);
/* On the Mac Mini, this will turn off the LED for power off */ if (apple_smc_write_u32(reboot->smc, SMC_KEY(MBSE), val) < 0)
dev_err(reboot->dev, "Failed to issue MBSE = %p4ch (reboot_prepare)\n", &val);
/* Set the boot_stage to 0, which means we're doing a clean shutdown/reboot. */ if (reboot->nvm.boot_stage &&
nvmem_cell_set_u8(reboot->nvm.boot_stage, BOOT_STAGE_SHUTDOWN) < 0)
dev_err(reboot->dev, "Failed to write boot_stage\n");
/* * Set the PMU flag to actually reboot into the off state. * Without this, the device will just reboot. We make it optional in case it is no longer * necessary on newer hardware.
*/ if (reboot->nvm.shutdown_flag &&
nvmem_cell_set_u8(reboot->nvm.shutdown_flag, shutdown_flag) < 0)
dev_err(reboot->dev, "Failed to write shutdown_flag\n");
return NOTIFY_OK;
}
staticvoid macsmc_power_init_error_counts(struct macsmc_reboot *reboot)
{ int boot_error_count, panic_count;
if (!reboot->nvm.boot_error_count || !reboot->nvm.panic_count) return;
boot_error_count = nvmem_cell_get_u8(reboot->nvm.boot_error_count); if (boot_error_count < 0) {
dev_err(reboot->dev, "Failed to read boot_error_count (%d)\n", boot_error_count); return;
}
panic_count = nvmem_cell_get_u8(reboot->nvm.panic_count); if (panic_count < 0) {
dev_err(reboot->dev, "Failed to read panic_count (%d)\n", panic_count); return;
}
reboot = devm_kzalloc(&pdev->dev, sizeof(*reboot), GFP_KERNEL); if (!reboot) return -ENOMEM;
reboot->dev = &pdev->dev;
reboot->smc = smc;
platform_set_drvdata(pdev, reboot);
for (i = 0; i < ARRAY_SIZE(nvmem_names); i++) { struct nvmem_cell *cell;
cell = devm_nvmem_cell_get(&pdev->dev,
nvmem_names[i]); if (IS_ERR(cell)) { if (PTR_ERR(cell) == -EPROBE_DEFER) return -EPROBE_DEFER;
dev_warn(&pdev->dev, "Missing NVMEM cell %s (%ld)\n",
nvmem_names[i], PTR_ERR(cell)); /* Non fatal, we'll deal with it */
cell = NULL;
}
reboot->nvm_cells[i] = cell;
}
/* Set the boot_stage to indicate we're running the OS kernel */ if (reboot->nvm.boot_stage &&
nvmem_cell_set_u8(reboot->nvm.boot_stage, BOOT_STAGE_KERNEL_STARTED) < 0)
dev_err(reboot->dev, "Failed to write boot_stage\n");
/* Display and clear the error counts */
macsmc_power_init_error_counts(reboot);
ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF_PREPARE,
SYS_OFF_PRIO_HIGH, macsmc_prepare_atomic, reboot); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register power-off prepare handler\n");
ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_HIGH,
macsmc_power_off, reboot); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register power-off handler\n");
ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART_PREPARE,
SYS_OFF_PRIO_HIGH, macsmc_prepare_atomic, reboot); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register restart prepare handler\n");
ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
macsmc_restart, reboot); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register restart handler\n");
ret = devm_register_reboot_notifier(&pdev->dev, &reboot->reboot_notify); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register reboot notifier\n");
dev_info(&pdev->dev, "Handling reboot and poweroff requests via SMC\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.