summaryrefslogtreecommitdiff
path: root/drivers/parisc/power.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-11-01 10:21:07 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2023-11-01 10:21:07 -1000
commitf00593e09968ed6dfcd10aebb13f470fbe3343b4 (patch)
treecc9fc1ea0072ed8aca1c8e3b6f04d2b338f3203b /drivers/parisc/power.c
parent979ff1e5af8a46f75a69ffa86209f8650547f42f (diff)
parent8a32aa17c1cd48df1ddaa78e45abcb8c7a2220d6 (diff)
Merge tag 'parisc-for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc updates from Helge Deller: "Usual fixes and updates: - Add up to 12 nops after TLB inserts for PA8x00 CPUs as the specification requires (Dave Anglin) - Simplify the parisc smp_prepare_boot_cpu() code (Russell King) - Use 64-bit little-endian values in SBA IOMMU PDIR table for AGP Since there is upcoming support for booting a 64-bit kernel on QEMU, some corner cases were fixed and improvements added: - Fix 64-bit kernel crash in STI (graphics console) font setup code which miscalculated the font start address as it gets signed vs unsigned offsets wrong - Support building an uncompressed Linux kernel - Add support for soft power-off in qemu" * tag 'parisc-for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: fbdev: stifb: Make the STI next font pointer a 32-bit signed offset parisc: Show default CPU PSW.W setting as reported by PDC parisc/pdc: Add width field to struct pdc_model parisc: Add nop instructions after TLB inserts parisc: simplify smp_prepare_boot_cpu() parisc/agp: Use 64-bit LE values in SBA IOMMU PDIR table parisc/firmware: Use PDC constants for narrow/wide firmware parisc: Move parisc_narrow_firmware variable to header file parisc/power: Trivial whitespace cleanups and license update parisc/power: Add power soft-off when running on qemu parisc: Allow building uncompressed Linux kernel parisc: Add some missing PDC functions and constants parisc: sba-iommu: Fix comment when calculating IOC number
Diffstat (limited to 'drivers/parisc/power.c')
-rw-r--r--drivers/parisc/power.c67
1 files changed, 28 insertions, 39 deletions
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index 6f5e5f0230d3..539d8920c202 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -1,38 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
- * linux/drivers/parisc/power.c
- * HP PARISC soft power switch support driver
- *
- * Copyright (c) 2001-2007 Helge Deller <deller@gmx.de>
- * All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL").
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * HP PARISC soft power switch driver
*
+ * Copyright (c) 2001-2023 Helge Deller <deller@gmx.de>
*
* HINT:
* Support of the soft power switch button may be enabled or disabled at
* runtime through the "/proc/sys/kernel/power" procfs entry.
- */
+ */
#include <linux/module.h>
#include <linux/init.h>
@@ -62,12 +37,12 @@
#define MFCPU_X(rDiagReg, t_ch, t_th, code) \
(DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )
-
+
#define MTCPU(dr, gr) MFCPU_X(dr, gr, 0, 0x12) /* move value of gr to dr[dr] */
#define MFCPU_C(dr, gr) MFCPU_X(dr, gr, 0, 0x30) /* for dr0 and dr8 only ! */
#define MFCPU_T(dr, gr) MFCPU_X(dr, 0, gr, 0xa0) /* all dr except dr0 and dr8 */
-
-#define __getDIAG(dr) ( { \
+
+#define __getDIAG(dr) ( { \
register unsigned long __res asm("r28");\
__asm__ __volatile__ ( \
".word %1" : "=&r" (__res) : "i" (MFCPU_T(dr,28) ) \
@@ -85,7 +60,7 @@ static void process_shutdown(void)
printk(KERN_ALERT KTHREAD_NAME ": Shutdown requested...\n");
shutdown_timer++;
-
+
/* wait until the button was pressed for 1 second */
if (shutdown_timer == (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC)) {
static const char msg[] = "Shutting down...";
@@ -135,7 +110,7 @@ static int kpowerswd(void *param)
button_not_pressed = (gsc_readl(soft_power_reg) & 0x1);
} else {
/*
- * On gecko style machines (e.g. 712/xx and 715/xx)
+ * On gecko style machines (e.g. 712/xx and 715/xx)
* the power switch status is stored in Bit 0 ("the highest bit")
* of CPU diagnose register 25.
* Warning: Some machines never reset the DIAG flag, even if
@@ -161,7 +136,7 @@ static int kpowerswd(void *param)
/*
- * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2)
+ * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2)
*/
#if 0
static void powerfail_interrupt(int code, void *x)
@@ -197,6 +172,14 @@ static struct notifier_block parisc_panic_block = {
.priority = INT_MAX,
};
+/* qemu soft power-off function */
+static int qemu_power_off(struct sys_off_data *data)
+{
+ /* this turns the system off via SeaBIOS */
+ *(int *)data->cb_data = 0;
+ pdc_soft_power_button(1);
+ return NOTIFY_DONE;
+}
static int __init power_init(void)
{
@@ -214,19 +197,25 @@ static int __init power_init(void)
ret = pdc_soft_power_button(1);
if (ret != PDC_OK)
soft_power_reg = -1UL;
-
+
switch (soft_power_reg) {
case 0: printk(KERN_INFO DRIVER_NAME ": Gecko-style soft power switch enabled.\n");
break;
-
+
case -1UL: printk(KERN_INFO DRIVER_NAME ": Soft power switch support not available.\n");
return -ENODEV;
-
+
default: printk(KERN_INFO DRIVER_NAME ": Soft power switch at 0x%08lx enabled.\n",
soft_power_reg);
}
- power_task = kthread_run(kpowerswd, (void*)soft_power_reg, KTHREAD_NAME);
+ power_task = NULL;
+ if (running_on_qemu && soft_power_reg)
+ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
+ qemu_power_off, (void *)soft_power_reg);
+ else
+ power_task = kthread_run(kpowerswd, (void*)soft_power_reg,
+ KTHREAD_NAME);
if (IS_ERR(power_task)) {
printk(KERN_ERR DRIVER_NAME ": thread creation failed. Driver not loaded.\n");
pdc_soft_power_button(0);