]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
powerpc/rtas: add rtas_activate_firmware()
authorNathan Lynch <nathanl@linux.ibm.com>
Mon, 7 Dec 2020 21:51:37 +0000 (15:51 -0600)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 8 Dec 2020 10:40:55 +0000 (21:40 +1100)
Provide a documented wrapper function for the ibm,activate-firmware
service, which must be called after a partition migration or
hibernation.

If the function is absent or the call fails, the OS will continue to
run normally with the current firmware, so there is no need to perform
any recovery. Just log it and continue.

Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20201207215200.1785968-6-nathanl@linux.ibm.com
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/rtas.c

index b43165fc6c2aec0de441219ef30f2bb8719de839..fdefe6a974eb13a7678adbd1e6a38a4d546943ef 100644 (file)
@@ -247,6 +247,7 @@ extern void __noreturn rtas_restart(char *cmd);
 extern void rtas_power_off(void);
 extern void __noreturn rtas_halt(void);
 extern void rtas_os_term(char *str);
+void rtas_activate_firmware(void);
 extern int rtas_get_sensor(int sensor, int index, int *state);
 extern int rtas_get_sensor_fast(int sensor, int index, int *state);
 extern int rtas_get_power_level(int powerdomain, int *level);
index 8a618a3c4beb5a4b003963086b2388ef742a24e4..3a740ae933f8f6a4597290e03bea8f166a846e0b 100644 (file)
@@ -798,6 +798,36 @@ void rtas_os_term(char *str)
                printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
 }
 
+/**
+ * rtas_activate_firmware() - Activate a new version of firmware.
+ *
+ * Activate a new version of partition firmware. The OS must call this
+ * after resuming from a partition hibernation or migration in order
+ * to maintain the ability to perform live firmware updates. It's not
+ * catastrophic for this method to be absent or to fail; just log the
+ * condition in that case.
+ *
+ * Context: This function may sleep.
+ */
+void rtas_activate_firmware(void)
+{
+       int token;
+       int fwrc;
+
+       token = rtas_token("ibm,activate-firmware");
+       if (token == RTAS_UNKNOWN_SERVICE) {
+               pr_notice("ibm,activate-firmware method unavailable\n");
+               return;
+       }
+
+       do {
+               fwrc = rtas_call(token, 0, 1, NULL);
+       } while (rtas_busy_delay(fwrc));
+
+       if (fwrc)
+               pr_err("ibm,activate-firmware failed (%i)\n", fwrc);
+}
+
 static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
 #ifdef CONFIG_PPC_PSERIES
 static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done)