Commit 8139046a authored by Vaibhav Jain's avatar Vaibhav Jain Committed by Michael Ellerman
Browse files

powerpc/powernv: Make possible for user to force a full ipl cec reboot



Ever since fast reboot is enabled by default in opal,
opal_cec_reboot() will use fast-reset instead of full IPL to perform
system reboot. This leaves the user with no direct way to force a full
IPL reboot except changing an nvram setting that persistently disables
fast-reset for all subsequent reboots.

This patch provides a more direct way for the user to force a one-shot
full IPL reboot by passing the command line argument 'full' to the
reboot command. So the user will be able to tweak the reboot behavior
via:

  $ sudo reboot full	# Force a full ipl reboot skipping fast-reset

  or
  $ sudo reboot  	# default reboot path (usually fast-reset)

The reboot command passes the un-parsed command argument to the kernel
via the 'Reboot' syscall which is then passed on to the arch function
pnv_restart(). The patch updates pnv_restart() to handle this cmd-arg
and issues opal_cec_reboot2 with OPAL_REBOOT_FULL_IPL to force a full
IPL reset.

Signed-off-by: default avatarVaibhav Jain <vaibhav@linux.ibm.com>
Acked-by: default avatarAndrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent db6711b7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1050,6 +1050,7 @@ enum OpalSysCooling {
enum {
	OPAL_REBOOT_NORMAL		= 0,
	OPAL_REBOOT_PLATFORM_ERROR	= 1,
	OPAL_REBOOT_FULL_IPL		= 2,
};

/* Argument to OPAL_PCI_TCE_KILL */
+30 −6
Original line number Diff line number Diff line
@@ -219,17 +219,41 @@ static void pnv_prepare_going_down(void)

static void  __noreturn pnv_restart(char *cmd)
{
	long rc = OPAL_BUSY;
	long rc;

	pnv_prepare_going_down();

	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
	do {
		if (!cmd)
			rc = opal_cec_reboot();
		if (rc == OPAL_BUSY_EVENT)
			opal_poll_events(NULL);
		else if (strcmp(cmd, "full") == 0)
			rc = opal_cec_reboot2(OPAL_REBOOT_FULL_IPL, NULL);
		else
			rc = OPAL_UNSUPPORTED;

		if (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
			/* Opal is busy wait for some time and retry */
			opal_poll_events(NULL);
			mdelay(10);

		} else	if (cmd && rc) {
			/* Unknown error while issuing reboot */
			if (rc == OPAL_UNSUPPORTED)
				pr_err("Unsupported '%s' reboot.\n", cmd);
			else
				pr_err("Unable to issue '%s' reboot. Err=%ld\n",
				       cmd, rc);
			pr_info("Forcing a cec-reboot\n");
			cmd = NULL;
			rc = OPAL_BUSY;

		} else if (rc != OPAL_SUCCESS) {
			/* Unknown error while issuing cec-reboot */
			pr_err("Unable to reboot. Err=%ld\n", rc);
		}

	} while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT);

	for (;;)
		opal_poll_events(NULL);
}