git: 3753988c5d22 - main - LinuxKPI: pm: add SET_SYSTEM_SLEEP_PM_OPS() and device_can_wakeup()

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Fri, 07 Jun 2024 23:48:58 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=3753988c5d22393fbdefb6aa16b5a5a699d05642

commit 3753988c5d22393fbdefb6aa16b5a5a699d05642
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2024-04-06 21:15:16 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2024-06-07 22:57:04 +0000

    LinuxKPI: pm: add SET_SYSTEM_SLEEP_PM_OPS() and device_can_wakeup()
    
    Add the SET_SYSTEM_SLEEP_PM_OPS() by factoring some other macro code
    out in order to set the suspend/resume functions when the struct is
    already given.  Such is the case in iwlwifi d3.
    
    Also add an initial implementation of device_can_wakeup().  Though
    this is likely all we need we have no way of setting the flag for it
    yet so leave a pr_debug() and a comment there as well.  Until we want
    to support WoWLAN this is likely not needed for wireless.
    Doing it the proper way checking a bool in 'struct dev_pm_info' would
    change 'struct device' and with that 'struct pci_dev' and break the
    KBI.  In favour of mergeability this version does not implement the
    full functionality yet.
    
    Both help to make an updated iwlwifi d3 compile.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
    Differential Revision: https://reviews.freebsd.org/D45358
---
 sys/compat/linuxkpi/common/include/linux/pm.h | 30 +++++++++++++++------------
 sys/compat/linuxkpi/common/src/linux_compat.c | 18 ++++++++++++++++
 2 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/pm.h b/sys/compat/linuxkpi/common/include/linux/pm.h
index 871c7b587864..c8d943027909 100644
--- a/sys/compat/linuxkpi/common/include/linux/pm.h
+++ b/sys/compat/linuxkpi/common/include/linux/pm.h
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2020 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
  *
  * This software was developed by Björn Zeeb under sponsorship from
  * the FreeBSD Foundation.
@@ -58,25 +58,26 @@ struct dev_pm_info {
     IS_ENABLED(CONFIG_PM_SLEEP) ? (_p) : NULL
 
 #ifdef CONFIG_PM_SLEEP
+#define	__SET_PM_OPS(_suspendfunc, _resumefunc)			\
+	.suspend	= _suspendfunc,				\
+	.resume		= _resumefunc,				\
+	.freeze		= _suspendfunc,				\
+	.thaw		= _resumefunc,				\
+	.poweroff	= _suspendfunc,				\
+	.restore	= _resumefunc,				\
+
 #define	SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc)	\
 const struct dev_pm_ops _name = {				\
-	.suspend	= _suspendfunc,		\
-	.resume		= _resumefunc,		\
-	.freeze		= _suspendfunc,		\
-	.thaw		= _resumefunc,		\
-	.poweroff	= _suspendfunc,		\
-	.restore	= _resumefunc,		\
+	__SET_PM_OPS(_suspendfunc, _resumefunc)			\
 }
 
 #define	DEFINE_SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
 const struct dev_pm_ops _name = {				\
-	.suspend	= _suspendfunc,		\
-	.resume		= _resumefunc,		\
-	.freeze		= _suspendfunc,		\
-	.thaw		= _resumefunc,		\
-	.poweroff	= _suspendfunc,		\
-	.restore	= _resumefunc,		\
+	__SET_PM_OPS(_suspendfunc, _resumefunc)			\
 }
+
+#define	SET_SYSTEM_SLEEP_PM_OPS(_suspendfunc, _resumefunc)	\
+	__SET_PM_OPS(_suspendfunc, _resumefunc)
 #else
 #define	SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc)	\
 const struct dev_pm_ops _name = {				\
@@ -86,6 +87,9 @@ const struct dev_pm_ops _name = {				\
 }
 #endif
 
+bool linuxkpi_device_can_wakeup(struct device *);
+#define	device_can_wakeup(_dev)		linuxkpi_device_can_wakeup(_dev)
+
 static inline void
 pm_wakeup_event(struct device *dev __unused, unsigned int x __unused)
 {
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
index 4c639c1f8459..90d03d480089 100644
--- a/sys/compat/linuxkpi/common/src/linux_compat.c
+++ b/sys/compat/linuxkpi/common/src/linux_compat.c
@@ -2597,6 +2597,24 @@ io_mapping_create_wc(resource_size_t base, unsigned long size)
 	return (io_mapping_init_wc(mapping, base, size));
 }
 
+/* We likely want a linuxkpi_device.c at some point. */
+bool
+device_can_wakeup(struct device *dev)
+{
+
+	if (dev == NULL)
+		return (false);
+	/*
+	 * XXX-BZ iwlwifi queries it as part of enabling WoWLAN.
+	 * Normally this would be based on a bool in dev->power.XXX.
+	 * Check such as PCI PCIM_PCAP_*PME.  We have no way to enable this yet.
+	 * We may get away by directly calling into bsddev for as long as
+	 * we can assume PCI only avoiding changing struct device breaking KBI.
+	 */
+	pr_debug("%s:%d: not enabled; see comment.\n", __func__, __LINE__);
+	return (false);
+}
+
 #if defined(__i386__) || defined(__amd64__)
 bool linux_cpu_has_clflush;
 struct cpuinfo_x86 boot_cpu_data;