* [PATCH V21/5] kexec: Fix make headers_check
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1412640584.git.geoff@infradead.org>
Remove the unneded declaration for a kexec_load() routine.
Fixes errors like these when running 'make headers_check':
include/uapi/linux/kexec.h: userspace cannot reference function or variable defined in the kernel
Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Paul Bolle <pebolle@tiscali.nl>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
---
include/uapi/linux/kexec.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 6925f5b..99048e5 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -55,12 +55,6 @@ struct kexec_segment {
size_t memsz;
};
-/* Load a new kernel image as described by the kexec_segment array
- * consisting of passed number of segments at the entry-point address.
- * The flags allow different useage types.
- */
-extern int kexec_load(void *, size_t, struct kexec_segment *,
- unsigned long int);
#endif /* __KERNEL__ */
#endif /* _UAPILINUX_KEXEC_H */
--
1.9.1
^ permalink raw reply related
* [PATCH V22/5] kexec: Simplify conditional
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1412640584.git.geoff@infradead.org>
Simplify the code around one of the conditionals in the kexec_load
syscall routine.
The original code was confusing with a redundant check on KEXEC_ON_CRASH
and comments outside of the conditional block. This change switches the
order of the conditional check, and cleans up the comments for the
conditional. There is no functional change to the code.
Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
---
kernel/kexec.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 2bee072..4b8356b 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1288,19 +1288,22 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
if (nr_segments > 0) {
unsigned long i;
- /* Loading another kernel to reboot into */
- if ((flags & KEXEC_ON_CRASH) == 0)
- result = kimage_alloc_init(&image, entry, nr_segments,
- segments, flags);
- /* Loading another kernel to switch to if this one crashes */
- else if (flags & KEXEC_ON_CRASH) {
- /* Free any current crash dump kernel before
+ if (flags & KEXEC_ON_CRASH) {
+ /*
+ * Loading another kernel to switch to if this one
+ * crashes. Free any current crash dump kernel before
* we corrupt it.
*/
+
kimage_free(xchg(&kexec_crash_image, NULL));
result = kimage_alloc_init(&image, entry, nr_segments,
segments, flags);
crash_map_reserved_pages();
+ } else {
+ /* Loading another kernel to reboot into. */
+
+ result = kimage_alloc_init(&image, entry, nr_segments,
+ segments, flags);
}
if (result)
goto out;
--
1.9.1
^ permalink raw reply related
* [PATCH V23/5] kexec: Add bit definitions for kimage entry flags
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1412640584.git.geoff@infradead.org>
Define new kexec preprocessor macros IND_*_BIT that define the bit position of
the kimage entry flags. Change the existing IND_* flag macros to be defined as
bit shifts of the corresponding IND_*_BIT macros. Also wrap all C language code
in kexec.h with #if !defined(__ASSEMBLY__) so assembly files can include kexec.h
to get the IND_* and IND_*_BIT macros.
Some CPU instruction sets have tests for bit position which are convenient in
implementing routines that operate on the kimage entry list. The addition of
these bit position macros in a common location will avoid duplicate definitions
and the chance that changes to the IND_* flags will not be propagated to
assembly files.
Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
---
include/linux/kexec.h | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 4b2a0e1..8c628ca 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -1,6 +1,18 @@
#ifndef LINUX_KEXEC_H
#define LINUX_KEXEC_H
+#define IND_DESTINATION_BIT 0
+#define IND_INDIRECTION_BIT 1
+#define IND_DONE_BIT 2
+#define IND_SOURCE_BIT 3
+
+#define IND_DESTINATION (1 << IND_DESTINATION_BIT)
+#define IND_INDIRECTION (1 << IND_INDIRECTION_BIT)
+#define IND_DONE (1 << IND_DONE_BIT)
+#define IND_SOURCE (1 << IND_SOURCE_BIT)
+
+#if !defined(__ASSEMBLY__)
+
#include <uapi/linux/kexec.h>
#ifdef CONFIG_KEXEC
@@ -64,10 +76,6 @@
*/
typedef unsigned long kimage_entry_t;
-#define IND_DESTINATION 0x1
-#define IND_INDIRECTION 0x2
-#define IND_DONE 0x4
-#define IND_SOURCE 0x8
struct kexec_segment {
/*
@@ -312,4 +320,7 @@ struct task_struct;
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
#endif /* CONFIG_KEXEC */
+
+#endif /* !defined(__ASSEBMLY__) */
+
#endif /* LINUX_KEXEC_H */
--
1.9.1
^ permalink raw reply related
* [PATCH V2 0/5] kexec: Minor fixups and enhancements
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1408731991.git.geoff@infradead.org>
Hi Andrew,
This series is basically a re-send of my kexec fix-up patches I sent out back
in August. Everyone who commented seemed to think these changes were OK, but
there doesn't seem to be a kexec maintainer to pick these up. Could you take
them through your mm tree?
Please let us know.
-Geoff
V2 changes:
o Collected various Acked-by's.
The following changes since commit bfe01a5ba2490f299e1d2d5508cbbbadd897bbe9:
Linux 3.17 (2014-10-05 12:23:04 -0700)
are available in the git repository at:
git://git.linaro.org/people/geoff.levand/linux-kexec.git for-kexec
for you to fetch changes up to adf97d602657c72f6ee59aefe5d51149159a3e99:
powerpc/kexec: Use global IND_FLAGS macro (2014-10-06 17:06:26 -0700)
----------------------------------------------------------------
Geoff Levand (5):
kexec: Fix make headers_check
kexec: Simplify conditional
kexec: Add bit definitions for kimage entry flags
kexec: Add IND_FLAGS macro
powerpc/kexec: Use global IND_FLAGS macro
arch/powerpc/kernel/machine_kexec_64.c | 2 --
include/linux/kexec.h | 20 ++++++++++++++++----
include/uapi/linux/kexec.h | 6 ------
kernel/kexec.c | 17 ++++++++++-------
4 files changed, 26 insertions(+), 19 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH V25/5] powerpc/kexec: Use global IND_FLAGS macro
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1412640584.git.geoff@infradead.org>
linux/kexec.h now defines an IND_FLAGS macro. Remove the local powerpc
definition and use the generic one.
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/kernel/machine_kexec_64.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 879b3aa..75652a32 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -96,8 +96,6 @@ int default_machine_kexec_prepare(struct kimage *image)
return 0;
}
-#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
-
static void copy_segments(unsigned long ind)
{
unsigned long entry;
--
1.9.1
^ permalink raw reply related
* [PATCH V24/5] kexec: Add IND_FLAGS macro
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1412640584.git.geoff@infradead.org>
Add a new kexec preprocessor macro IND_FLAGS, which is the bitwise OR of
all the possible kexec IND_ kimage_entry indirection flags.
Having this macro allows for simplified code in the prosessing of the
kexec kimage_entry items.
Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
---
include/linux/kexec.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 8c628ca..a4758f9 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -10,6 +10,7 @@
#define IND_INDIRECTION (1 << IND_INDIRECTION_BIT)
#define IND_DONE (1 << IND_DONE_BIT)
#define IND_SOURCE (1 << IND_SOURCE_BIT)
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
#if !defined(__ASSEMBLY__)
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v2 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: Scott Wood @ 2014-10-07 0:24 UTC (permalink / raw)
To: christophe leroy; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <542FC6CC.4000507@c-s.fr>
On Sat, 2014-10-04 at 12:07 +0200, christophe leroy wrote:
> The bindings for that driver are described in
> Documentation/devicetree/bindings/spi/fsl-spi.txt. But it seems that it
> doesn't describe anything related to those compatibles. The driver has a
> match on "fsl,fsl-spi" only,
I think you mean "fsl,spi", and that's a terrible compatible name.
> and for using it with CPM you have to add
> "fsl,cpm1-spi" or "fsl,cpm2-spi" to tell the driver that it is CPM
> (existing code below).
fsl-spi.txt doesn't describe CPM1/2 at all, but rather QE (CPM3) and
non-CPM.
-Scott
^ permalink raw reply
* Re: [PATCH 1/4] powerpc/powernv: Add OPAL check token call
From: Stewart Smith @ 2014-10-07 4:36 UTC (permalink / raw)
To: Michael Neuling, Benjamin Herrenschmidt, Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <1408423682-14297-1-git-send-email-mikey@neuling.org>
Michael Neuling <mikey@neuling.org> writes:
> Currently there is no way to generically check if an OPAL call exists or not
> from the host kernel.
>
> This adds an OPAL call opal_check_token() which tells you if the given token is
> present in OPAL or not.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
(checked the firmware code)
Reviewed-by: Stewart Smith <stewart@linux.vnet.ibm.com>
(although should we be checking if the call returns OPAL_PARAMETER?
The opal call will return that if booting on firmware without
OPAL_CHECK_TOKEN.. which granted, is pretty old firmware that I don't
*think* we had leave the lab... or at least not to too many places)
^ permalink raw reply
* [PATCH v3 1/7] ALSA: hda - Limit 40bit DMA for AMD HDMI controllers
From: Benjamin Herrenschmidt @ 2014-10-07 4:37 UTC (permalink / raw)
To: Alex Deucher, Bjorn Helgaas
Cc: linuxppc-dev, Dave Airlie, linux-pci, Anton Blanchard,
Yijing Wang, Takashi Iwai, Brian King
From: Takashi Iwai <tiwai@suse.de>
AMD/ATI HDMI controller chip models, we already have a filter to lower
to 32bit DMA, but the rest are supposed to be working with 64bit
although the hardware doesn't really work with 63bit but only with 40
or 48bit DMA. In this patch, we take 40bit DMA for safety for the
AMD/ATI controllers as the graphics drivers does.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org>
---
sound/pci/hda/hda_intel.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index aa302fb..99b367b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1482,6 +1482,7 @@ static int azx_first_init(struct azx *chip)
struct snd_card *card = chip->card;
int err;
unsigned short gcap;
+ unsigned int dma_bits = 64;
#if BITS_PER_LONG != 64
/* Fix up base address on ULI M5461 */
@@ -1518,9 +1519,14 @@ static int azx_first_init(struct azx *chip)
gcap = azx_readw(chip, GCAP);
dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
+ /* AMD devices support 40 or 48bit DMA, take the safe one */
+ if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
+ dma_bits = 40;
+
/* disable SB600 64bit support for safety */
if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
struct pci_dev *p_smbus;
+ dma_bits = 40;
p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
PCI_DEVICE_ID_ATI_SBX00_SMBUS,
NULL);
@@ -1550,9 +1556,11 @@ static int azx_first_init(struct azx *chip)
}
/* allow 64bit DMA address if supported by H/W */
- if ((gcap & AZX_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
- else {
+ if (!(gcap & AZX_GCAP_64OK))
+ dma_bits = 32;
+ if (!pci_set_dma_mask(pci, DMA_BIT_MASK(dma_bits))) {
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(dma_bits));
+ } else {
pci_set_dma_mask(pci, DMA_BIT_MASK(32));
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
}
^ permalink raw reply related
* [PATCH v3 7/7] powerpc/pci: Remove unused force_32bit_msi quirk
From: Benjamin Herrenschmidt @ 2014-10-07 4:38 UTC (permalink / raw)
To: Alex Deucher, Bjorn Helgaas
Cc: linuxppc-dev, Dave Airlie, linux-pci, Anton Blanchard,
Yijing Wang, Takashi Iwai, Brian King
This is now fully replaced with the generic "no_64bit_msi" one
that is set by the respective drivers directly.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/pci-bridge.h | 2 --
arch/powerpc/kernel/pci_64.c | 10 ----------
2 files changed, 12 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 4ca90a3..725247b 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -159,8 +159,6 @@ struct pci_dn {
int pci_ext_config_space; /* for pci devices */
- bool force_32bit_msi;
-
struct pci_dev *pcidev; /* back-pointer to the pci device */
#ifdef CONFIG_EEH
struct eeh_dev *edev; /* eeh device */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 155013d..b15194e 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -266,13 +266,3 @@ int pcibus_to_node(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibus_to_node);
#endif
-
-static void quirk_radeon_32bit_msi(struct pci_dev *dev)
-{
- struct pci_dn *pdn = pci_get_pdn(dev);
-
- if (pdn)
- pdn->force_32bit_msi = true;
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi);
^ permalink raw reply related
* [PATCH v3 4/7] sound/radeon: Add quirk for broken 64-bit MSI
From: Benjamin Herrenschmidt @ 2014-10-07 4:38 UTC (permalink / raw)
To: Alex Deucher, Bjorn Helgaas
Cc: linuxppc-dev, Dave Airlie, linux-pci, Anton Blanchard,
Yijing Wang, Takashi Iwai, Brian King
From: Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
A number of radeon cards have a HW limitation causing them to be
unable to generate the full 64-bit of address bits for MSIs. This
breaks MSIs on some platforms such as POWER machines.
We used to have a powerpc specific quirk to address that on a
single card, but this doesn't scale very well, this is better
put under control of the drivers who know precisely what a given
HW revision can do.
This moves the setting of the quirk flag to the audio driver.
While recent ASICs have that problem fixed, they don't seem to
be listed in the PCI IDs of the current driver, so let's quirk all
the ATI HDMI for now. The consequences are nil on x86 anyway.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org>
---
sound/pci/hda/hda_intel.c | 96 +++++++++++++++++++++++++++++++++--------------
sound/pci/hda/hda_priv.h | 1 +
2 files changed, 69 insertions(+), 28 deletions(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 99b367b..af38ed9 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1506,9 +1506,14 @@ static int azx_first_init(struct azx *chip)
return -ENXIO;
}
- if (chip->msi)
+ if (chip->msi) {
+ if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
+ dev_dbg(card->dev, "Disabling 64bit MSI\n");
+ pci->no_64bit_msi = true;
+ }
if (pci_enable_msi(pci) < 0)
chip->msi = 0;
+ }
if (azx_acquire_irq(chip, 0) < 0)
return -EBUSY;
@@ -2070,58 +2075,93 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x1022, 0x780d),
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
/* ATI HDMI */
- { PCI_DEVICE(0x1002, 0x793b),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x1314),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0x7919),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
+ { PCI_DEVICE(0x1002, 0x7969),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
+ { PCI_DEVICE(0x1002, 0x793b),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0x960f),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
+ { PCI_DEVICE(0x1002, 0x9646),
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0x970f),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa00),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa08),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa10),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa18),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa20),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa28),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa30),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa38),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa40),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa48),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa50),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa58),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa60),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa68),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa80),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa88),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa90),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaa98),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0x9902),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaaa0),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaaa8),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
{ PCI_DEVICE(0x1002, 0xaab0),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI |
+ AZX_DCAPS_NO_MSI64 },
/* VIA VT8251/VT8237A */
{ PCI_DEVICE(0x1106, 0x3288),
.driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h
index 949cd43..5016014 100644
--- a/sound/pci/hda/hda_priv.h
+++ b/sound/pci/hda/hda_priv.h
@@ -171,6 +171,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
+#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
/* HD Audio class code */
#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
^ permalink raw reply related
* Re: [PATCH] powerpc/powernv: Fallback to old HMI handling behavior for old firmware
From: Stewart Smith @ 2014-10-07 4:53 UTC (permalink / raw)
To: Mahesh J Salgaonkar, Michael Ellerman, linuxppc-dev,
Benjamin Herrenschmidt
Cc: Paul Mackerras
In-Reply-To: <20141006093358.1828.36741.stgit@mars>
Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> writes:
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>
> Recently we moved HMI handling into Linux kernel instead of taking
> HMI directly in OPAL. This new change is dependent on new OPAL call
> for HMI recovery which was introduced in newer firmware. While this new
> change works fine with latest OPAL firmware, we broke the HMI handling
> if we run newer kernel on old OPAL firmware that results in system hang.
>
> This patch fixes this issue by falling back to old HMI behavior on older
> OPAL firmware.
>
> This patch introduces a check for opal token OPAL_HANDLE_HMI to see
> if we are running on newer firmware or old firmware. On newer firmware
> this check would return OPAL_TOKEN_PRESENT, otherwise we are running on
> old firmware and fallback to old HMI behavior.
>
> This patch depends on opal check token patch posted at ppc-devel
> https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-August/120224.html
(just reviewed that patch before this one...)
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index b44eec3..2768cd3 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -194,6 +194,24 @@ static int __init opal_register_exception_handlers(void)
> * fwnmi area at 0x7000 to provide the glue space to OPAL
> */
> glue = 0x7000;
> +
> + /* Check if we are running on newer firmware that exports
> + * OPAL_HANDLE_HMI token. If yes, then don't ask opal to patch
> + * HMI interrupt and we catch it directly in Linux kernel.
> + *
> + * For older firmware we will fallback to old behavior and
> + * let OPAL patch the HMI vector and handle it inside OPAL
> + * firmware.
> + */
> + if (opal_check_token(OPAL_HANDLE_HMI) != OPAL_TOKEN_PRESENT) {
> + /* We are on old firmware. fallback to old behavior. */
> + pr_info("%s: Falling back to old HMI handling behavior.\n",
> + __func__);
> + opal_register_exception_handler(
> + OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
> + 0, glue);
> + glue += 128;
> + }
> opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0,
> glue);
So.. that all looks fine, but another note: why are we doing the
OPAL_SOFTPATCH_HANDLER and why is it all #if 0 out in skiboot?
for this patch:
Reviewed-by: Stewart Smith <stewart@linux.vnet.ibm.com>
^ permalink raw reply
* [PATCH v3 6/7] powerpc/pseries: Honor the generic "no_64bit_msi" flag
From: Benjamin Herrenschmidt @ 2014-10-07 4:38 UTC (permalink / raw)
To: Alex Deucher, Bjorn Helgaas
Cc: linuxppc-dev, Dave Airlie, linux-pci, Anton Blanchard,
Yijing Wang, Takashi Iwai, Brian King
Instead of the arch specific quirk which we are deprecating
and that drivers don't understand.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org>
---
arch/powerpc/platforms/pseries/msi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 18ff462..6fd96d8 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -429,7 +429,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
*/
again:
if (type == PCI_CAP_ID_MSI) {
- if (pdn->force_32bit_msi) {
+ if (pdev->no_64bit_msi) {
rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
if (rc < 0) {
/*
^ permalink raw reply related
* [PATCH v3 5/7] powerpc/powernv: Honor the generic "no_64bit_msi" flag
From: Benjamin Herrenschmidt @ 2014-10-07 4:38 UTC (permalink / raw)
To: Alex Deucher, Bjorn Helgaas
Cc: linuxppc-dev, Dave Airlie, linux-pci, Anton Blanchard,
Yijing Wang, Takashi Iwai, Brian King
Instead of the arch specific quirk which we are deprecating
and that drivers don't understand.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 3 +--
arch/powerpc/platforms/powernv/pci.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index df241b1..a188bb8 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1311,7 +1311,6 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
unsigned int is_64, struct msi_msg *msg)
{
struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev);
- struct pci_dn *pdn = pci_get_pdn(dev);
struct irq_data *idata;
struct irq_chip *ichip;
unsigned int xive_num = hwirq - phb->msi_base;
@@ -1327,7 +1326,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
return -ENXIO;
/* Force 32-bit MSI on some broken devices */
- if (pdn && pdn->force_32bit_msi)
+ if (dev->no_64bit_msi)
is_64 = 0;
/* Assign XIVE to PE */
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index b854b57..89c6608 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -50,9 +50,8 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
- struct pci_dn *pdn = pci_get_pdn(pdev);
- if (pdn && pdn->force_32bit_msi && !phb->msi32_support)
+ if (pdev->no_64bit_msi && !phb->msi32_support)
return -ENODEV;
return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV;
^ permalink raw reply related
* Re: [PATCH v2 1/3] powerpc/powernv: Enable Offline CPUs to enter deep idle states
From: Benjamin Herrenschmidt @ 2014-10-07 5:06 UTC (permalink / raw)
To: Shreyas B. Prabhu
Cc: Srivatsa S. Bhat, linux-pm, Rafael J. Wysocki, linux-kernel,
Paul Mackerras, Preeti U. Murthy, linuxppc-dev
In-Reply-To: <1412149560-2953-2-git-send-email-shreyas@linux.vnet.ibm.com>
On Wed, 2014-10-01 at 13:15 +0530, Shreyas B. Prabhu wrote:
> From: "Srivatsa S. Bhat" <srivatsa@mit.edu>
>
> The offline cpus
Arguably "cpus" here should be "secondary threads" to make the commit
message a bit more comprehensible. A few more nits below...
> should enter deep idle states so as to gain maximum
> powersavings when the entire core is offline. To do so the offline path
> must be made aware of the available deepest idle state. Hence probe the
> device tree for the possible idle states in powernv core code and
> expose the deepest idle state through flags.
>
> Since the device tree is probed by the cpuidle driver as well, move
> the parameters required to discover the idle states into an appropriate
> common place to both the driver and the powernv core code.
>
> Another point is that fastsleep idle state may require workarounds in
> the kernel to function properly. This workaround is introduced in the
> subsequent patches. However neither the cpuidle driver or the hotplug
> path need be bothered about this workaround.
>
> They will be taken care of by the core powernv code.
>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: linux-pm@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Signed-off-by: Srivatsa S. Bhat <srivatsa@mit.edu>
> Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
> [ Changelog modified by preeti@linux.vnet.ibm.com ]
> Signed-off-by: Preeti U. Murthy <preeti@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/opal.h | 4 +++
> arch/powerpc/platforms/powernv/powernv.h | 7 +++++
> arch/powerpc/platforms/powernv/setup.c | 51 ++++++++++++++++++++++++++++++++
> arch/powerpc/platforms/powernv/smp.c | 11 ++++++-
> drivers/cpuidle/cpuidle-powernv.c | 7 ++---
> 5 files changed, 75 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 86055e5..28b8342 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -772,6 +772,10 @@ extern struct kobject *opal_kobj;
> /* /ibm,opal */
> extern struct device_node *opal_node;
>
> +/* Flags used for idle state discovery from the device tree */
> +#define IDLE_INST_NAP 0x00010000 /* nap instruction can be used */
> +#define IDLE_INST_SLEEP 0x00020000 /* sleep instruction can be used */
Please provide a better explanation if what this is about, maybe a
commend describing the device-tree property. Also those macros have
names too likely to collide or be confused with other uses. Use
something a bit less ambiguous such as OPAL_PM_NAP_AVAILABLE,
OPAL_PM_SLEEP_ENABLED,...
Also put that in the part of opal.h that isn't the linux internal
implementation, but instead the "API" part. This will help when we
finally split the file.
> /* API functions */
> int64_t opal_invalid_call(void);
> int64_t opal_console_write(int64_t term_number, __be64 *length,
> diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h
> index 75501bf..31ece13 100644
> --- a/arch/powerpc/platforms/powernv/powernv.h
> +++ b/arch/powerpc/platforms/powernv/powernv.h
> @@ -23,6 +23,13 @@ static inline int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
> }
> #endif
>
> +/* Flags to indicate which of the CPU idle states are available for use */
> +
> +#define IDLE_USE_NAP (1UL << 0)
> +#define IDLE_USE_SLEEP (1UL << 1)
This somewhat duplicates the opal.h definitions, can't we just re-use
them ?
> +extern unsigned int pnv_get_supported_cpuidle_states(void);
> +
> extern void pnv_lpc_init(void);
>
> bool cpu_core_split_required(void);
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index 5a0e2dc..2dca1d8 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -282,6 +282,57 @@ static void __init pnv_setup_machdep_rtas(void)
> }
> #endif /* CONFIG_PPC_POWERNV_RTAS */
>
> +static unsigned int supported_cpuidle_states;
> +
> +unsigned int pnv_get_supported_cpuidle_states(void)
> +{
> + return supported_cpuidle_states;
> +}
Will this be used by a module ? Doesn't it need to be exported ? Also
keep the prefix pnv on the variable, I don't like globals with such a
confusing name.
> +static int __init pnv_probe_idle_states(void)
> +{
> + struct device_node *power_mgt;
> + struct property *prop;
> + int dt_idle_states;
> + u32 *flags;
> + int i;
> +
> + supported_cpuidle_states = 0;
> +
> + if (cpuidle_disable != IDLE_NO_OVERRIDE)
> + return 0;
> +
> + if (!firmware_has_feature(FW_FEATURE_OPALv3))
> + return 0;
> +
> + power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
> + if (!power_mgt) {
> + pr_warn("opal: PowerMgmt Node not found\n");
> + return 0;
> + }
> +
> + prop = of_find_property(power_mgt, "ibm,cpu-idle-state-flags", NULL);
> + if (!prop) {
> + pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
> + return 0;
> + }
> +
> + dt_idle_states = prop->length / sizeof(u32);
> + flags = (u32 *) prop->value;
> +
> + for (i = 0; i < dt_idle_states; i++) {
> + if (flags[i] & IDLE_INST_NAP)
> + supported_cpuidle_states |= IDLE_USE_NAP;
> +
> + if (flags[i] & IDLE_INST_SLEEP)
> + supported_cpuidle_states |= IDLE_USE_SLEEP;
> + }
> +
> + return 0;
> +}
> +
> +subsys_initcall(pnv_probe_idle_states);
> +
> static int __init pnv_probe(void)
> {
> unsigned long root = of_get_flat_dt_root();
> diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
> index 5fcfcf4..3ad31d2 100644
> --- a/arch/powerpc/platforms/powernv/smp.c
> +++ b/arch/powerpc/platforms/powernv/smp.c
> @@ -149,6 +149,7 @@ static int pnv_smp_cpu_disable(void)
> static void pnv_smp_cpu_kill_self(void)
> {
> unsigned int cpu;
> + unsigned long idle_states;
>
> /* Standard hot unplug procedure */
> local_irq_disable();
> @@ -159,13 +160,21 @@ static void pnv_smp_cpu_kill_self(void)
> generic_set_cpu_dead(cpu);
> smp_wmb();
>
> + idle_states = pnv_get_supported_cpuidle_states();
> +
> /* We don't want to take decrementer interrupts while we are offline,
> * so clear LPCR:PECE1. We keep PECE2 enabled.
> */
> mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
> while (!generic_check_cpu_restart(cpu)) {
> ppc64_runlatch_off();
> - power7_nap(1);
> +
> + /* If sleep is supported, go to sleep, instead of nap */
> + if (idle_states & IDLE_USE_SLEEP)
> + power7_sleep();
> + else
> + power7_nap(1);
> +
> ppc64_runlatch_on();
>
> /* Reenable IRQs briefly to clear the IPI that woke us */
> diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
> index a64be57..23d2743 100644
> --- a/drivers/cpuidle/cpuidle-powernv.c
> +++ b/drivers/cpuidle/cpuidle-powernv.c
> @@ -16,13 +16,12 @@
>
> #include <asm/machdep.h>
> #include <asm/firmware.h>
> +#include <asm/opal.h>
> #include <asm/runlatch.h>
>
> /* Flags and constants used in PowerNV platform */
>
> #define MAX_POWERNV_IDLE_STATES 8
> -#define IDLE_USE_INST_NAP 0x00010000 /* Use nap instruction */
> -#define IDLE_USE_INST_SLEEP 0x00020000 /* Use sleep instruction */
>
> struct cpuidle_driver powernv_idle_driver = {
> .name = "powernv_idle",
> @@ -185,7 +184,7 @@ static int powernv_add_idle_states(void)
> for (i = 0; i < dt_idle_states; i++) {
>
> flags = be32_to_cpu(idle_state_flags[i]);
> - if (flags & IDLE_USE_INST_NAP) {
> + if (flags & IDLE_INST_NAP) {
> /* Add NAP state */
> strcpy(powernv_states[nr_idle_states].name, "Nap");
> strcpy(powernv_states[nr_idle_states].desc, "Nap");
> @@ -196,7 +195,7 @@ static int powernv_add_idle_states(void)
> nr_idle_states++;
> }
>
> - if (flags & IDLE_USE_INST_SLEEP) {
> + if (flags & IDLE_INST_SLEEP) {
> /* Add FASTSLEEP state */
> strcpy(powernv_states[nr_idle_states].name, "FastSleep");
> strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
^ permalink raw reply
* Re: [PATCH v2 2/3] powerpc/kvm/book3s_hv: Enable CPUs to run guest after waking up from fast-sleep
From: Benjamin Herrenschmidt @ 2014-10-07 5:11 UTC (permalink / raw)
To: Shreyas B. Prabhu
Cc: Preeti U Murthy, linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1412149560-2953-3-git-send-email-shreyas@linux.vnet.ibm.com>
On Wed, 2014-10-01 at 13:15 +0530, Shreyas B. Prabhu wrote:
> When guests have to be launched, the secondary threads which are offline
> are woken up to run the guests. Today these threads wake up from nap
> and check if they have to run guests. Now that the offline secondary
> threads can go to fastsleep or going ahead a deeper idle state such as winkle,
> add this check in the wakeup from any of the deep idle states path as well.
>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: linuxppc-dev@lists.ozlabs.org
> Suggested-by: "Srivatsa S. Bhat" <srivatsa@mit.edu>
> Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
> [ Changelog added by <preeti@linux.vnet.ibm.com> ]
> Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
> ---
> arch/powerpc/kernel/exceptions-64s.S | 35 ++++++++++++++++-------------------
> 1 file changed, 16 insertions(+), 19 deletions(-)
>
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index 050f79a..c64f3cc0 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -100,25 +100,8 @@ system_reset_pSeries:
> SET_SCRATCH0(r13)
> #ifdef CONFIG_PPC_P7_NAP
> BEGIN_FTR_SECTION
> - /* Running native on arch 2.06 or later, check if we are
> - * waking up from nap. We only handle no state loss and
> - * supervisor state loss. We do -not- handle hypervisor
> - * state loss at this time.
> - */
> - mfspr r13,SPRN_SRR1
> - rlwinm. r13,r13,47-31,30,31
> - beq 9f
>
> - /* waking up from powersave (nap) state */
> - cmpwi cr1,r13,2
> - /* Total loss of HV state is fatal, we could try to use the
> - * PIR to locate a PACA, then use an emergency stack etc...
> - * OPAL v3 based powernv platforms have new idle states
> - * which fall in this catagory.
> - */
> - bgt cr1,8f
> GET_PACA(r13)
> -
> #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
> li r0,KVM_HWTHREAD_IN_KERNEL
> stb r0,HSTATE_HWTHREAD_STATE(r13)
> @@ -131,13 +114,27 @@ BEGIN_FTR_SECTION
> 1:
> #endif
So you moved the state loss check to after the KVM check ? Was this
reviewed by Paul ? Is that ok ? (Does this match what we have in
PowerKVM ?). Is it possible that we end up calling kvm_start_guest
after a HV state loss or do we know for sure that this won't happen
for a reason or another ? If that's the case, then that reason needs
to be clearly documented here in a comment.
> + /* Running native on arch 2.06 or later, check if we are
> + * waking up from nap. We only handle no state loss and
> + * supervisor state loss. We do -not- handle hypervisor
> + * state loss at this time.
> + */
> + mfspr r13,SPRN_SRR1
> + rlwinm. r13,r13,47-31,30,31
> + beq 9f
> +
> + /* waking up from powersave (nap) state */
> + cmpwi cr1,r13,2
> + GET_PACA(r13)
> +
> + bgt cr1,8f
> +
> beq cr1,2f
> b power7_wakeup_noloss
> 2: b power7_wakeup_loss
>
> /* Fast Sleep wakeup on PowerNV */
> -8: GET_PACA(r13)
> - b power7_wakeup_tb_loss
> +8: b power7_wakeup_tb_loss
>
> 9:
> END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
^ permalink raw reply
* Re: [PATCH v2 3/3] powerpc/powernv/cpuidle: Add workaround to enable fastsleep
From: Benjamin Herrenschmidt @ 2014-10-07 5:20 UTC (permalink / raw)
To: Shreyas B. Prabhu
Cc: linux-pm, Rafael J. Wysocki, linux-kernel, Paul Mackerras,
Preeti U Murthy, linuxppc-dev
In-Reply-To: <1412149560-2953-4-git-send-email-shreyas@linux.vnet.ibm.com>
On Wed, 2014-10-01 at 13:16 +0530, Shreyas B. Prabhu wrote:
> From: Preeti U Murthy <preeti@linux.vnet.ibm.com>
>
> Fast sleep is an idle state, where the core and the L1 and L2
> caches are brought down to a threshold voltage. This also means that
> the communication between L2 and L3 caches have to be fenced. However
> the current P8 chips have a bug wherein this fencing between L2 and
> L3 caches get delayed by a cpu cycle. This can delay L3 response to
> the other cpus if they request for data during this time. Thus they
> would fetch the same data from the memory which could lead to data
> corruption if L3 cache is not flushed.
>
> The cpu idle states save power at a core level and not at a thread level.
> Hence powersavings is based on the shallowest idle state that a thread
> of a core is in. The above issue in fastsleep will arise only when
> all the threads in a core either enter fastsleep or some of them enter
> any deeper idle states, with only a few being in fastsleep. This patch
> therefore implements a workaround this bug by ensuring
> that, each time a cpu goes to fastsleep, it checks if it is the last
> thread in the core to enter fastsleep. If so, it needs to make an opal
> call to get around the above mentioned fastsleep problem in the hardware
> before issuing the sleep instruction.
>
> Similarly when a thread in a core comes out of fastsleep, it needs
> to verify if its the first thread in the core to come out of fastsleep
> and issue the opal call to revert the changes made while entering
> fastsleep.
>
> For the same reason mentioned above we need to take care of offline threads
> as well since we allow them to enter fastsleep and with support for
> deep winkle soon coming in they can enter winkle as well. We therefore
> ensure that even offline threads make the above mentioned opal calls
> similarly, so that as long as the threads in a core are in and
> idle state >= fastsleep, we have the workaround in place. Whenever a
> thread comes out of either of these states, it needs to verify if the
> opal call has been made and if so it will revert it. For now this patch
> ensures that offline threads enter fastsleep.
>
> We need to be able to synchronize the cpus in a core which are entering
> and exiting fastsleep so as to ensure that the last thread in the core
> to enter fastsleep and the first to exit fastsleep *only* issue the opal
> call. To do so, we need a per-core lock and counter. The counter is
> required to keep track of the number of threads in a core which are in
> idle state >= fastsleep. To make the implementation of this simple, we
> introduce a per-cpu lock and counter and every thread always takes the
> primary thread's lock, modifies the primary thread's counter. This
> effectively makes them per-core entities.
>
> But the workaround is abstracted in the powernv core code and neither
> the hotplug path nor the cpuidle driver need to bother about it. All
> they need to know is if fastsleep, with error or no error is present as
> an idle state.
>
> Cc: linux-pm@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
> Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/machdep.h | 3 +
> arch/powerpc/include/asm/opal.h | 3 +
> arch/powerpc/include/asm/processor.h | 4 +-
> arch/powerpc/kernel/idle.c | 19 ++++
> arch/powerpc/kernel/idle_power7.S | 2 +-
> arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
> arch/powerpc/platforms/powernv/setup.c | 139 ++++++++++++++++++-------
> drivers/cpuidle/cpuidle-powernv.c | 8 +-
> 8 files changed, 140 insertions(+), 39 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
> index b125cea..f37014f 100644
> --- a/arch/powerpc/include/asm/machdep.h
> +++ b/arch/powerpc/include/asm/machdep.h
> @@ -298,6 +298,9 @@ struct machdep_calls {
> #ifdef CONFIG_MEMORY_HOTREMOVE
> int (*remove_memory)(u64, u64);
> #endif
> + /* Idle handlers */
> + void (*setup_idle)(void);
> + unsigned long (*power7_sleep)(void);
> };
Do we need that ppc_md hook ? Since we are going to use idle states in
the CPU unplug loop, I would think we should do the necessary
initializations at boot time regardless of whether the cpuidle driver
is loaded or not, so we probably don't need this, or am I missing
something ?
> extern void e500_idle(void);
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 28b8342..166d572 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -149,6 +149,7 @@ struct opal_sg_list {
> #define OPAL_DUMP_INFO2 94
> #define OPAL_PCI_EEH_FREEZE_SET 97
> #define OPAL_HANDLE_HMI 98
> +#define OPAL_CONFIG_IDLE_STATE 99
> #define OPAL_REGISTER_DUMP_REGION 101
> #define OPAL_UNREGISTER_DUMP_REGION 102
>
> @@ -775,6 +776,7 @@ extern struct device_node *opal_node;
> /* Flags used for idle state discovery from the device tree */
> #define IDLE_INST_NAP 0x00010000 /* nap instruction can be used */
> #define IDLE_INST_SLEEP 0x00020000 /* sleep instruction can be used */
> +#define IDLE_INST_SLEEP_ER1 0x00080000 /* Use sleep with work around*/
Usual comment about names.
> /* API functions */
> int64_t opal_invalid_call(void);
> @@ -975,6 +977,7 @@ extern int opal_handle_hmi_exception(struct pt_regs *regs);
>
> extern void opal_shutdown(void);
> extern int opal_resync_timebase(void);
> +int64_t opal_config_idle_state(uint64_t state, uint64_t enter);
>
> extern void opal_lpc_init(void);
>
> diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
> index dda7ac4..41953cd 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -451,8 +451,10 @@ extern unsigned long cpuidle_disable;
> enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
>
> extern int powersave_nap; /* set if nap mode can be used in idle loop */
> +extern void arch_setup_idle(void);
> extern void power7_nap(int check_irq);
> -extern void power7_sleep(void);
> +extern unsigned long power7_sleep(void);
> +extern unsigned long __power7_sleep(void);
> extern void flush_instruction_cache(void);
> extern void hard_reset_now(void);
> extern void poweroff_now(void);
> diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
> index d7216c9..1f268e0 100644
> --- a/arch/powerpc/kernel/idle.c
> +++ b/arch/powerpc/kernel/idle.c
> @@ -32,6 +32,9 @@
> #include <asm/machdep.h>
> #include <asm/runlatch.h>
> #include <asm/smp.h>
> +#include <asm/cputhreads.h>
> +#include <asm/firmware.h>
> +#include <asm/opal.h>
>
>
> unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
> @@ -78,6 +81,22 @@ void arch_cpu_idle(void)
> HMT_medium();
> ppc64_runlatch_on();
> }
> +void arch_setup_idle(void)
> +{
> + if (ppc_md.setup_idle)
> + ppc_md.setup_idle();
> +}
See comment about hook
> +unsigned long power7_sleep(void)
> +{
> + unsigned long ret;
> +
> + if (ppc_md.power7_sleep)
> + ret = ppc_md.power7_sleep();
> + else
> + ret = __power7_sleep();
> + return ret;
> +}
This is in the wrong place. In fact, it should probably be power8 and
not power7 and it should be somewhere in powernv, not in generic code.
We don't need the ppc_md. hook, we can just check if the workaround
is needed from the ppc_md code.
> int powersave_nap;
>
> diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
> index be05841..c3481c9 100644
> --- a/arch/powerpc/kernel/idle_power7.S
> +++ b/arch/powerpc/kernel/idle_power7.S
> @@ -129,7 +129,7 @@ _GLOBAL(power7_nap)
> b power7_powersave_common
> /* No return */
>
> -_GLOBAL(power7_sleep)
> +_GLOBAL(__power7_sleep)
> li r3,1
> li r4,1
> b power7_powersave_common
> diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
> index 2e6ce1b..8d1e724 100644
> --- a/arch/powerpc/platforms/powernv/opal-wrappers.S
> +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
> @@ -245,5 +245,6 @@ OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ);
> OPAL_CALL(opal_get_param, OPAL_GET_PARAM);
> OPAL_CALL(opal_set_param, OPAL_SET_PARAM);
> OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
> +OPAL_CALL(opal_config_idle_state, OPAL_CONFIG_IDLE_STATE);
> OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION);
> OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index 2dca1d8..9d9a898 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -36,9 +36,20 @@
> #include <asm/opal.h>
> #include <asm/kexec.h>
> #include <asm/smp.h>
> +#include <asm/cputhreads.h>
>
> #include "powernv.h"
>
> +/* Per-cpu structures to keep track of cpus of a core that
> + * are in idle states >= fastsleep so as to call opal for
> + * sleep setup when the entire core is ready to go to fastsleep.
> + *
> + * We need sometihng similar to a per-core lock. For now we
> + * achieve this by taking the lock of the primary thread in the core.
> + */
> +static DEFINE_PER_CPU(spinlock_t, fastsleep_override_lock);
> +static DEFINE_PER_CPU(int, fastsleep_cnt);
> +
> static void __init pnv_setup_arch(void)
> {
> set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
> @@ -254,35 +265,8 @@ static unsigned long pnv_memory_block_size(void)
> }
> #endif
>
> -static void __init pnv_setup_machdep_opal(void)
> -{
> - ppc_md.get_boot_time = opal_get_boot_time;
> - ppc_md.get_rtc_time = opal_get_rtc_time;
> - ppc_md.set_rtc_time = opal_set_rtc_time;
> - ppc_md.restart = pnv_restart;
> - ppc_md.power_off = pnv_power_off;
> - ppc_md.halt = pnv_halt;
> - ppc_md.machine_check_exception = opal_machine_check;
> - ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
> - ppc_md.hmi_exception_early = opal_hmi_exception_early;
> - ppc_md.handle_hmi_exception = opal_handle_hmi_exception;
> -}
> -
> -#ifdef CONFIG_PPC_POWERNV_RTAS
> -static void __init pnv_setup_machdep_rtas(void)
> -{
> - if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) {
> - ppc_md.get_boot_time = rtas_get_boot_time;
> - ppc_md.get_rtc_time = rtas_get_rtc_time;
> - ppc_md.set_rtc_time = rtas_set_rtc_time;
> - }
> - ppc_md.restart = rtas_restart;
> - ppc_md.power_off = rtas_power_off;
> - ppc_md.halt = rtas_halt;
> -}
> -#endif /* CONFIG_PPC_POWERNV_RTAS */
That patch is ugly because of moving the above. You should instead
change the previous patch to put pnv_probe_idle_states above the above
two functions so that this patch has a lot less impact and is more
reviewable.
> static unsigned int supported_cpuidle_states;
> +static int need_fastsleep_workaround;
bool ?
> unsigned int pnv_get_supported_cpuidle_states(void)
> {
> @@ -292,12 +276,13 @@ unsigned int pnv_get_supported_cpuidle_states(void)
> static int __init pnv_probe_idle_states(void)
> {
> struct device_node *power_mgt;
> - struct property *prop;
> int dt_idle_states;
> - u32 *flags;
Fix the previous one to use __be ? IE. Previous patch is endian broken
and this one fixes it. Don't do that.
> + const __be32 *idle_state_flags;
> + u32 len_flags, flags;
> int i;
>
> supported_cpuidle_states = 0;
> + need_fastsleep_workaround = 0;
>
> if (cpuidle_disable != IDLE_NO_OVERRIDE)
> return 0;
> @@ -311,21 +296,28 @@ static int __init pnv_probe_idle_states(void)
> return 0;
> }
>
> - prop = of_find_property(power_mgt, "ibm,cpu-idle-state-flags", NULL);
> - if (!prop) {
> + idle_state_flags = of_get_property(power_mgt,
> + "ibm,cpu-idle-state-flags", &len_flags);
> + if (!idle_state_flags) {
> pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
> return 0;
> }
>
> - dt_idle_states = prop->length / sizeof(u32);
> - flags = (u32 *) prop->value;
> + dt_idle_states = len_flags / sizeof(u32);
>
> for (i = 0; i < dt_idle_states; i++) {
> - if (flags[i] & IDLE_INST_NAP)
> +
> + flags = be32_to_cpu(idle_state_flags[i]);
> + if (flags & IDLE_INST_NAP)
> supported_cpuidle_states |= IDLE_USE_NAP;
>
> - if (flags[i] & IDLE_INST_SLEEP)
> + if (flags & IDLE_INST_SLEEP)
> supported_cpuidle_states |= IDLE_USE_SLEEP;
> +
> + if (flags & IDLE_INST_SLEEP_ER1) {
> + supported_cpuidle_states |= IDLE_USE_SLEEP;
> + need_fastsleep_workaround = 1;
> + }
> }
>
> return 0;
> @@ -333,6 +325,81 @@ static int __init pnv_probe_idle_states(void)
>
> subsys_initcall(pnv_probe_idle_states);
>
> +static void pnv_setup_idle(void)
> +{
> + int cpu;
> +
> + for_each_possible_cpu(cpu) {
> + spin_lock_init(&per_cpu(fastsleep_override_lock, cpu));
> + per_cpu(fastsleep_cnt, cpu) = threads_per_core;
> + }
> +}
That can be done from probe_idle_states no ?
That locking construct and counter per-core (not per-CPU really) should
probably be documented somewhere and to be safe we should probably
initialize the secondary threads counters to some crazy value like -1
and BUG_ON on it in the use case.
> +static void
> +pnv_apply_fastsleep_workaround(bool enter_fastsleep, int primary_thread)
> +{
> + if (enter_fastsleep) {
> + spin_lock(&per_cpu(fastsleep_override_lock, primary_thread));
> + if (--(per_cpu(fastsleep_cnt, primary_thread)) == 0)
> + opal_config_idle_state(1, 1);
> + spin_unlock(&per_cpu(fastsleep_override_lock, primary_thread));
> + } else {
> + spin_lock(&per_cpu(fastsleep_override_lock, primary_thread));
> + if ((per_cpu(fastsleep_cnt, primary_thread)) == 0)
> + opal_config_idle_state(1, 0);
> + per_cpu(fastsleep_cnt, primary_thread)++;
> + spin_unlock(&per_cpu(fastsleep_override_lock, primary_thread));
> + }
Make two separate functions, one for enter and one to exit. IE.
pnv_enter_sleep_workaround();
vs.
pnv_exit_sleep_workaround();
> +
> +static unsigned long pnv_power7_sleep(void)
> +{
> + int cpu, primary_thread;
> + unsigned long srr1;
> +
> + cpu = smp_processor_id();
> + primary_thread = cpu_first_thread_sibling(cpu);
> +
> + if (need_fastsleep_workaround) {
> + pnv_apply_fastsleep_workaround(1, primary_thread);
> + srr1 = __power7_sleep();
> + pnv_apply_fastsleep_workaround(0, primary_thread);
> + } else {
> + srr1 = __power7_sleep();
> + }
> + return srr1;
> +}
Just pnv_sleep() and you can remove the __ in power7_sleep
> +static void __init pnv_setup_machdep_opal(void)
> +{
> + ppc_md.get_boot_time = opal_get_boot_time;
> + ppc_md.get_rtc_time = opal_get_rtc_time;
> + ppc_md.set_rtc_time = opal_set_rtc_time;
> + ppc_md.restart = pnv_restart;
> + ppc_md.power_off = pnv_power_off;
> + ppc_md.halt = pnv_halt;
> + ppc_md.machine_check_exception = opal_machine_check;
> + ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
> + ppc_md.hmi_exception_early = opal_hmi_exception_early;
> + ppc_md.handle_hmi_exception = opal_handle_hmi_exception;
> + ppc_md.setup_idle = pnv_setup_idle;
> + ppc_md.power7_sleep = pnv_power7_sleep;
> +}
Just export pnv_sleep() and call it from the pnv cpuidle driver
directly.
> +#ifdef CONFIG_PPC_POWERNV_RTAS
> +static void __init pnv_setup_machdep_rtas(void)
> +{
> + if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) {
> + ppc_md.get_boot_time = rtas_get_boot_time;
> + ppc_md.get_rtc_time = rtas_get_rtc_time;
> + ppc_md.set_rtc_time = rtas_set_rtc_time;
> + }
> + ppc_md.restart = rtas_restart;
> + ppc_md.power_off = rtas_power_off;
> + ppc_md.halt = rtas_halt;
> +}
> +#endif /* CONFIG_PPC_POWERNV_RTAS */
> +
> static int __init pnv_probe(void)
> {
> unsigned long root = of_get_flat_dt_root();
> diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
> index 23d2743..8ad97a9 100644
> --- a/drivers/cpuidle/cpuidle-powernv.c
> +++ b/drivers/cpuidle/cpuidle-powernv.c
> @@ -18,6 +18,7 @@
> #include <asm/firmware.h>
> #include <asm/opal.h>
> #include <asm/runlatch.h>
> +#include <asm/processor.h>
>
> /* Flags and constants used in PowerNV platform */
>
> @@ -195,7 +196,8 @@ static int powernv_add_idle_states(void)
> nr_idle_states++;
> }
>
> - if (flags & IDLE_INST_SLEEP) {
> + if ((flags & IDLE_INST_SLEEP_ER1) ||
> + (flags & IDLE_INST_SLEEP)) {
> /* Add FASTSLEEP state */
> strcpy(powernv_states[nr_idle_states].name, "FastSleep");
> strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
> @@ -247,6 +249,10 @@ static int __init powernv_processor_idle_init(void)
>
> register_cpu_notifier(&setup_hotplug_notifier);
> printk(KERN_DEBUG "powernv_idle_driver registered\n");
> +
> + /* If any idle states require special
> + * initializations before cpuidle kicks in */
> + arch_setup_idle();
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH v2 1/5] powerpc/powernv: Add OPAL call to save and restore
From: Benjamin Herrenschmidt @ 2014-10-07 5:22 UTC (permalink / raw)
To: Shreyas B. Prabhu; +Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <1412149617-3178-2-git-send-email-shreyas@linux.vnet.ibm.com>
On Wed, 2014-10-01 at 13:16 +0530, Shreyas B. Prabhu wrote:
> PORE can be programmed to restore hypervisor registers when waking up
> from deep cpu idle states like winkle.
Tell us a bit more about what "PORE" is. IE, explain a tiny engine will
reconfigure the core and its ucode can be patched to provide some
registers with sane values.
> Add call to pass SPR address and value to OPAL, which in turn will
> program PORE to restore the register state.
Otherwise, Acke-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Suggested-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
> Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/opal.h | 2 ++
> arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
> 2 files changed, 3 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 166d572..d376020 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -150,6 +150,7 @@ struct opal_sg_list {
> #define OPAL_PCI_EEH_FREEZE_SET 97
> #define OPAL_HANDLE_HMI 98
> #define OPAL_CONFIG_IDLE_STATE 99
> +#define OPAL_SLW_SET_REG 100
> #define OPAL_REGISTER_DUMP_REGION 101
> #define OPAL_UNREGISTER_DUMP_REGION 102
>
> @@ -978,6 +979,7 @@ extern int opal_handle_hmi_exception(struct pt_regs *regs);
> extern void opal_shutdown(void);
> extern int opal_resync_timebase(void);
> int64_t opal_config_idle_state(uint64_t state, uint64_t enter);
> +int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
>
> extern void opal_lpc_init(void);
>
> diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
> index 8d1e724..12e5d46 100644
> --- a/arch/powerpc/platforms/powernv/opal-wrappers.S
> +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
> @@ -246,5 +246,6 @@ OPAL_CALL(opal_get_param, OPAL_GET_PARAM);
> OPAL_CALL(opal_set_param, OPAL_SET_PARAM);
> OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
> OPAL_CALL(opal_config_idle_state, OPAL_CONFIG_IDLE_STATE);
> +OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG);
> OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION);
> OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
^ permalink raw reply
* Re: [PATCH v2 2/5] powerpc: Adding macro for accessing Thread Switch Control Register
From: Benjamin Herrenschmidt @ 2014-10-07 5:22 UTC (permalink / raw)
To: Shreyas B. Prabhu; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1412149617-3178-3-git-send-email-shreyas@linux.vnet.ibm.com>
Just fold that one in the patch that uses that register
On Wed, 2014-10-01 at 13:16 +0530, Shreyas B. Prabhu wrote:
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: linuxppc-dev@lists.ozlabs.org
> Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/reg.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 0c05059..cb65a73 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -371,6 +371,7 @@
> #define SPRN_DBAT7L 0x23F /* Data BAT 7 Lower Register */
> #define SPRN_DBAT7U 0x23E /* Data BAT 7 Upper Register */
> #define SPRN_PPR 0x380 /* SMT Thread status Register */
> +#define SPRN_TSCR 0x399 /* Thread Switch Control Register */
>
> #define SPRN_DEC 0x016 /* Decrement Register */
> #define SPRN_DER 0x095 /* Debug Enable Regsiter */
^ permalink raw reply
* [PATCH 02/44] memory: emif: Use API function to determine poweroff capability
From: Guenter Roeck @ 2014-10-07 5:28 UTC (permalink / raw)
To: linux-kernel
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, linux-xtensa,
devel, linux-s390, lguest, linux-c6x-dev, linux-hexagon, linux-sh,
linux-acpi, xen-devel, Guenter Roeck, devicetree,
user-mode-linux-devel, linux-pm, adi-buildroot-devel, linux-m68k,
linux-am33-list, linux-tegra, openipmi-developer, linux-metag,
linux-arm-kernel, linux-parisc, linux-cris-kernel,
Santosh Shilimkar, linux-alpha, linuxppc-dev
In-Reply-To: <1412659726-29957-1-git-send-email-linux@roeck-us.net>
Use have_kernel_poweroff() to determine if the kernel is able
to power off the system.
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/memory/emif.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 04644e7..acd830a 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -1053,10 +1053,10 @@ static irqreturn_t emif_threaded_isr(int irq, void *dev_id)
dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n");
/* If we have Power OFF ability, use it, else try restarting */
- if (pm_power_off) {
+ if (have_kernel_poweroff()) {
kernel_power_off();
} else {
- WARN(1, "FIXME: NO pm_power_off!!! trying restart\n");
+ WARN(1, "FIXME: NO kernel poweroff capability!!! trying restart\n");
kernel_restart("SDRAM Over-temp Emergency restart");
}
return IRQ_HANDLED;
--
1.9.1
^ permalink raw reply related
* [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off
From: Guenter Roeck @ 2014-10-07 5:28 UTC (permalink / raw)
To: linux-kernel
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, Len Brown,
linux-xtensa, Pavel Machek, devel, linux-s390, lguest,
linux-c6x-dev, linux-hexagon, linux-sh, linux-acpi, xen-devel,
Guenter Roeck, devicetree, user-mode-linux-devel, linux-pm,
adi-buildroot-devel, linux-m68k, linux-am33-list, linux-tegra,
openipmi-developer, linux-metag, linux-arm-kernel, linux-parisc,
linux-cris-kernel, Rafael J. Wysocki, linux-alpha, linuxppc-dev
In-Reply-To: <1412659726-29957-1-git-send-email-linux@roeck-us.net>
Poweroff handlers may now be installed with register_poweroff_handler.
Use the new API function have_kernel_poweroff to determine if a poweroff
handler has been installed.
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Len Brown <len.brown@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
kernel/power/hibernate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index a9dfa79..20353c5 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -602,7 +602,7 @@ static void power_down(void)
case HIBERNATION_PLATFORM:
hibernation_platform_enter();
case HIBERNATION_SHUTDOWN:
- if (pm_power_off)
+ if (have_kernel_poweroff())
kernel_power_off();
break;
#ifdef CONFIG_SUSPEND
--
1.9.1
^ permalink raw reply related
* [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off
From: Guenter Roeck @ 2014-10-07 5:28 UTC (permalink / raw)
To: linux-kernel
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, linux-xtensa,
Greg Ungerer, devel, linux-s390, lguest, linux-c6x-dev,
linux-hexagon, linux-sh, linux-acpi, Geert Uytterhoeven,
xen-devel, Guenter Roeck, devicetree, user-mode-linux-devel,
linux-pm, adi-buildroot-devel, linux-m68k, linux-am33-list,
linux-tegra, openipmi-developer, linux-metag, linux-arm-kernel,
linux-parisc, linux-cris-kernel, linux-alpha, linuxppc-dev,
Joshua Thompson
In-Reply-To: <1412659726-29957-1-git-send-email-linux@roeck-us.net>
Replace mach_power_off with pm_power_off to simplify the subsequent
move of pm_power_off to generic code.
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Cc: Joshua Thompson <funaho@jurai.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
arch/m68k/emu/natfeat.c | 3 ++-
arch/m68k/include/asm/machdep.h | 1 -
arch/m68k/kernel/process.c | 5 +++--
arch/m68k/kernel/setup_mm.c | 1 -
arch/m68k/kernel/setup_no.c | 1 -
arch/m68k/mac/config.c | 3 ++-
6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
index 71b78ec..91e2ae7 100644
--- a/arch/m68k/emu/natfeat.c
+++ b/arch/m68k/emu/natfeat.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/pm.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/natfeat.h>
@@ -90,5 +91,5 @@ void __init nf_init(void)
pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
version & 0xffff);
- mach_power_off = nf_poweroff;
+ pm_power_off = nf_poweroff;
}
diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h
index 953ca21..f9fac51 100644
--- a/arch/m68k/include/asm/machdep.h
+++ b/arch/m68k/include/asm/machdep.h
@@ -24,7 +24,6 @@ extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
extern int (*mach_set_clock_mmss)(unsigned long);
extern void (*mach_reset)( void );
extern void (*mach_halt)( void );
-extern void (*mach_power_off)( void );
extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
extern void (*mach_hd_setup)(char *, int *);
extern long mach_max_dma_address;
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index c55ff71..afe3d6e 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -22,6 +22,7 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/user.h>
+#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
@@ -77,8 +78,8 @@ void machine_halt(void)
void machine_power_off(void)
{
- if (mach_power_off)
- mach_power_off();
+ if (pm_power_off)
+ pm_power_off();
for (;;);
}
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 5b8ec4d..002fea6 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -96,7 +96,6 @@ EXPORT_SYMBOL(mach_get_rtc_pll);
EXPORT_SYMBOL(mach_set_rtc_pll);
void (*mach_reset)( void );
void (*mach_halt)( void );
-void (*mach_power_off)( void );
long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
#ifdef CONFIG_HEARTBEAT
void (*mach_heartbeat) (int);
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index 88c27d9..1520156 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -55,7 +55,6 @@ int (*mach_hwclk) (int, struct rtc_time*);
/* machine dependent reboot functions */
void (*mach_reset)(void);
void (*mach_halt)(void);
-void (*mach_power_off)(void);
#ifdef CONFIG_M68000
#if defined(CONFIG_M68328)
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index a471eab..677913ff 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -16,6 +16,7 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/interrupt.h>
+#include <linux/pm.h>
/* keyb */
#include <linux/random.h>
#include <linux/delay.h>
@@ -159,7 +160,7 @@ void __init config_mac(void)
mach_set_clock_mmss = mac_set_clock_mmss;
mach_reset = mac_reset;
mach_halt = mac_poweroff;
- mach_power_off = mac_poweroff;
+ pm_power_off = mac_poweroff;
mach_max_dma_address = 0xffffffff;
#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
mach_beep = mac_mksound;
--
1.9.1
^ permalink raw reply related
* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
From: Guenter Roeck @ 2014-10-07 5:28 UTC (permalink / raw)
To: linux-kernel
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, linux-xtensa,
Mark Rutland, devel, linux-s390, lguest, linux-c6x-dev,
linux-hexagon, linux-sh, linux-acpi, Pawel Moll, xen-devel,
Guenter Roeck, devicetree, user-mode-linux-devel, linux-pm,
adi-buildroot-devel, linux-m68k, linux-am33-list, linux-tegra,
openipmi-developer, linux-metag, linux-arm-kernel, linux-parisc,
linux-cris-kernel, Rob Herring, linux-alpha, linuxppc-dev
In-Reply-To: <1412659726-29957-1-git-send-email-linux@roeck-us.net>
Devicetree bindings are supposed to be operating system independent
and should thus not describe how a specific functionality is implemented
in Linux.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
Documentation/devicetree/bindings/mfd/as3722.txt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/mfd/as3722.txt b/Documentation/devicetree/bindings/mfd/as3722.txt
index 4f64b2a..0b2a609 100644
--- a/Documentation/devicetree/bindings/mfd/as3722.txt
+++ b/Documentation/devicetree/bindings/mfd/as3722.txt
@@ -122,8 +122,7 @@ Following are properties of regulator subnode.
Power-off:
=========
-AS3722 supports the system power off by turning off all its rail. This
-is provided through pm_power_off.
+AS3722 supports the system power off by turning off all its rails.
The device node should have the following properties to enable this
functionality
ams,system-power-controller: Boolean, to enable the power off functionality
--
1.9.1
^ permalink raw reply related
* [PATCH 01/44] kernel: Add support for poweroff handler call chain
From: Guenter Roeck @ 2014-10-07 5:28 UTC (permalink / raw)
To: linux-kernel
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, Heiko Stuebner,
Len Brown, linux-xtensa, Pavel Machek, devel, linux-s390, lguest,
linux-c6x-dev, linux-hexagon, linux-sh, Alexander Graf,
linux-acpi, Geert Uytterhoeven, xen-devel, Guenter Roeck,
devicetree, user-mode-linux-devel, linux-pm, adi-buildroot-devel,
linux-m68k, linux-am33-list, linux-tegra, openipmi-developer,
linux-metag, linux-arm-kernel, linux-parisc, linux-cris-kernel,
Rafael J. Wysocki, linux-alpha, Andrew Morton, Romain Perier,
linuxppc-dev
In-Reply-To: <1412659726-29957-1-git-send-email-linux@roeck-us.net>
Various drivers implement architecture and/or device specific means to
remove power from the system. For the most part, those drivers set the
global variable pm_power_off to point to a function within the driver.
This mechanism has a number of drawbacks. Typically only one scheme
to remove power is supported (at least if pm_power_off is used).
At least in theory there can be multiple means remove power, some of
which may be less desirable. For example, some mechanisms may only
power off the CPU or the CPU card, while another may power off the
entire system. Others may really just execute a restart sequence
or drop into the ROM monitor. Using pm_power_off can also be racy
if the function pointer is set from a driver built as module, as the
driver may be in the process of being unloaded when pm_power_off is
called. If there are multiple poweroff handlers in the system, removing
a module with such a handler may inadvertently reset the pointer to
pm_power_off to NULL, leaving the system with no means to remove power.
Introduce a system poweroff handler call chain to solve the described
problems. This call chain is expected to be executed from the
architecture specific machine_power_off() function. Drivers providing
system poweroff functionality are expected to register with this call chain.
By using the priority field in the notifier block, callers can control
poweroff handler execution sequence and thus ensure that the poweroff
handler with the optimal capabilities to remove power for a given system
is called first.
Cc: Andrew Morton <akpm@linux-foundation.org>
cc: Heiko Stuebner <heiko@sntech.de>
Cc: Romain Perier <romain.perier@gmail.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Len Brown <len.brown@intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Alexander Graf <agraf@suse.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
include/linux/pm.h | 13 +++
kernel/power/Makefile | 1 +
kernel/power/poweroff_handler.c | 172 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 186 insertions(+)
create mode 100644 kernel/power/poweroff_handler.c
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 72c0fe0..45271b5 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -34,6 +34,19 @@
extern void (*pm_power_off)(void);
extern void (*pm_power_off_prepare)(void);
+/*
+ * Callbacks to manage poweroff handlers
+ */
+
+struct notifier_block;
+
+extern int register_poweroff_handler(struct notifier_block *);
+extern int register_poweroff_handler_simple(void (*function)(void),
+ int priority);
+extern int unregister_poweroff_handler(struct notifier_block *);
+extern void do_kernel_poweroff(void);
+extern bool have_kernel_poweroff(void);
+
struct device; /* we have a circular dep with device.h */
#ifdef CONFIG_VT_CONSOLE_SLEEP
extern void pm_vt_switch_required(struct device *dev, bool required);
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 29472bf..4d9f0c7 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -2,6 +2,7 @@
ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG
obj-y += qos.o
+obj-y += poweroff_handler.o
obj-$(CONFIG_PM) += main.o
obj-$(CONFIG_VT_CONSOLE_SLEEP) += console.o
obj-$(CONFIG_FREEZER) += process.o
diff --git a/kernel/power/poweroff_handler.c b/kernel/power/poweroff_handler.c
new file mode 100644
index 0000000..ed99e5e
--- /dev/null
+++ b/kernel/power/poweroff_handler.c
@@ -0,0 +1,172 @@
+/*
+ * linux/kernel/power/poweroff_handler.c - Poweroff handling functions
+ *
+ * Copyright (c) 2014 Guenter Roeck
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "poweroff: " fmt
+
+#include <linux/ctype.h>
+#include <linux/export.h>
+#include <linux/kallsyms.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/*
+ * Notifier list for kernel code which wants to be called
+ * to power off the system.
+ */
+static ATOMIC_NOTIFIER_HEAD(poweroff_handler_list);
+
+/**
+ * register_poweroff_handler - Register function to be called to power off
+ * the system
+ * @nb: Info about handler function to be called
+ * @nb->priority: Handler priority. Handlers should follow the
+ * following guidelines for setting priorities.
+ * 0: Poweroff handler of last resort,
+ * with limited poweroff capabilities,
+ * such as poweroff handlers which
+ * do not really power off the system
+ * but loop forever or stop the CPU.
+ * 128: Default poweroff handler; use if no other
+ * poweroff handler is expected to be available,
+ * and/or if poweroff functionality is
+ * sufficient to power off the entire system
+ * 255: Highest priority poweroff handler, will
+ * preempt all other poweroff handlers
+ *
+ * Registers a function with code to be called to power off the
+ * system.
+ *
+ * Registered functions will be called from machine_power_off as last
+ * step of the poweroff sequence. Registered functions are expected
+ * to power off the system immediately. If more than one function is
+ * registered, the poweroff handler priority selects which function
+ * will be called first.
+ *
+ * Poweroff handlers may be registered from architecture code or from
+ * drivers. A typical use case would be a system where power off
+ * functionality is provided through a multi-function chip or through
+ * a programmable power controller. Multiple poweroff handlers may exist;
+ * for example, one poweroff handler might power off the entire system,
+ * while another only powers off the CPU card. In such cases, the
+ * poweroff handler which only powers off part of the hardware is
+ * expected to register with low priority to ensure that it only
+ * runs if no other means to power off the system are available.
+ *
+ * Currently always returns zero, as atomic_notifier_chain_register()
+ * always returns zero.
+ */
+int register_poweroff_handler(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&poweroff_handler_list, nb);
+}
+EXPORT_SYMBOL(register_poweroff_handler);
+
+/**
+ * unregister_poweroff_handler - Unregister previously registered
+ * poweroff handler
+ * @nb: Hook to be unregistered
+ *
+ * Unregisters a previously registered poweroff handler function.
+ *
+ * Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_poweroff_handler(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&poweroff_handler_list, nb);
+}
+EXPORT_SYMBOL(unregister_poweroff_handler);
+
+struct _poweroff_handler_data {
+ void (*handler)(void);
+ struct notifier_block poweroff_nb;
+};
+
+static int _poweroff_handler(struct notifier_block *this,
+ unsigned long _unused1, void *_unused2)
+{
+ struct _poweroff_handler_data *poh =
+ container_of(this, struct _poweroff_handler_data, poweroff_nb);
+
+ poh->handler();
+
+ return NOTIFY_DONE;
+}
+
+static struct _poweroff_handler_data poweroff_handler_data;
+
+/**
+ * register_poweroff_handler_simple - Register function to be called to power off
+ * the system
+ * @handler: Function to be called to power off the system
+ * @priority: Handler priority. For priority guidelines see
+ * register_poweroff_handler.
+ *
+ * This is a simplified version of register_poweroff_handler. It does not
+ * take a notifier as argument, but a function pointer. The function
+ * registers a poweroff handler with specified priority. Poweroff
+ * handlers registered with this function can not be unregistered,
+ * and only a single poweroff handler can be installed using it.
+ *
+ * This function must not be called from modules and is therefore
+ * not exported.
+ *
+ * Returns -EBUSY if a poweroff handler has already been registered
+ * using register_poweroff_handler_simple. Otherwise returns zero,
+ * since atomic_notifier_chain_register() currently always returns zero.
+ */
+int register_poweroff_handler_simple(void (*handler)(void), int priority)
+{
+ char symname[KSYM_NAME_LEN];
+
+ if (poweroff_handler_data.handler) {
+ lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
+ symname);
+ pr_warn("Poweroff function already registered (%s)", symname);
+ lookup_symbol_name((unsigned long)handler, symname);
+ pr_cont(", cannot register %s\n", symname);
+ return -EBUSY;
+ }
+
+ poweroff_handler_data.handler = handler;
+ poweroff_handler_data.poweroff_nb.notifier_call = _poweroff_handler;
+ poweroff_handler_data.poweroff_nb.priority = priority;
+
+ return register_poweroff_handler(&poweroff_handler_data.poweroff_nb);
+}
+
+/**
+ * do_kernel_poweroff - Execute kernel poweroff handler call chain
+ *
+ * Calls functions registered with register_poweroff_handler.
+ *
+ * Expected to be called from machine_power_off as last step of
+ * the poweroff sequence.
+ *
+ * Powers off the system immediately if a poweroff handler function
+ * has been registered. Otherwise does nothing.
+ */
+void do_kernel_poweroff(void)
+{
+ atomic_notifier_call_chain(&poweroff_handler_list, 0, NULL);
+}
+
+/**
+ * have_kernel_poweroff() - Check if kernel poweroff handler is available
+ *
+ * Returns true is a kernel poweroff handler is available, false otherwise.
+ */
+bool have_kernel_poweroff(void)
+{
+ return pm_power_off != NULL || poweroff_handler_list.head != NULL;
+}
+EXPORT_SYMBOL(have_kernel_poweroff);
--
1.9.1
^ permalink raw reply related
* [PATCH 00/44] kernel: Add support for poweroff handler call chain
From: Guenter Roeck @ 2014-10-07 5:28 UTC (permalink / raw)
To: linux-kernel
Cc: linux-m32r-ja, linux-mips, linux-sh, Linus Walleij, Will Deacon,
Paul Mackerras, Pavel Machek, Russell King, Aurelien Jacquiot,
James E.J. Bottomley, linux-acpi, Geert Uytterhoeven,
Catalin Marinas, xen-devel, Matt Turner, Guenter Roeck, Len Brown,
James Hogan, linux-pm, Julian Andres Klode, Rusty Russell,
adi-buildroot-devel, Thomas Gleixner, Richard Henderson,
linux-cris-kernel, Greg Kroah-Hartman, Rafael J. Wysocki,
Ralf Baechle, Richard Kuo, Jiri Kosina, Andrew Morton,
Mark Rutland, linux-ia64, Max Filippov, Greg Ungerer,
Jean Delvare, Hans-Christian Egtvedt, linux-s390, Jesper Nilsson,
linux-c6x-dev, Dmitry Eremin-Solenikov, linux-hexagon,
Helge Deller, Konrad Rzeszutek Wilk, Alexander Graf, Len Brown,
linux-xtensa, Corey Minyard, linux-m68k, Boris Ostrovsky,
linux-metag, linux-arm-kernel, Chris Zankel, Jonas Bonn,
Rob Herring, Santosh Shilimkar, David Vrabel, Martin Schwidefsky,
Koichi Yasutake, linux-efi, Heiko Carstens, Maciej W. Rozycki,
Guan Xuetao, Lennox Wu, Hirokazu Takata, Haavard Skinnemoen,
Fenghua Yu, Pawel Moll, Jeff Dike, Tony Luck, Ivan Kokshaysky,
openipmi-developer, Matt Fleming, linux-parisc, Sebastian Reichel,
Vineet Gupta, linux-alpha, Romain Perier, David S. Miller,
Steven Miao, David Howells, H. Peter Anvin, Lee Jones, devel,
lguest, Samuel Ortiz, Richard Weinberger, Ingo Molnar,
Mark Salter, devicetree, user-mode-linux-devel, Chen Liqin,
Chris Metcalf, Mikael Starvik, linux-am33-list, linux-tegra,
Michal Simek, linuxppc-dev, David Woodhouse, Joshua Thompson
Various drivers implement architecture and/or device specific means to
remove power from the system. For the most part, those drivers set the
global variable pm_power_off to point to a function within the driver.
This mechanism has a number of drawbacks. Typically only one means
to remove power is supported (at least if pm_power_off is used).
At least in theory there can be multiple means to remove power, some of
which may be less desirable. For example, one mechanism might power off the
entire system through an I/O port or gpio pin, while another might power off
a board by disabling its power controller. Other mechanisms may really just
execute a restart sequence or drop into the ROM monitor, or put the CPU into
sleep mode. Using pm_power_off can also be racy if the function pointer is
set from a driver built as module, as the driver may be in the process of
being unloaded when pm_power_off is called. If there are multiple poweroff
handlers in the system, removing a module with such a handler may
inadvertently reset the pointer to pm_power_off to NULL, leaving the system
with no means to remove power.
Introduce a system poweroff handler call chain to solve the described
problems. This call chain is expected to be executed from the architecture
specific machine_power_off() function. Drivers providing system poweroff
functionality are expected to register with this call chain. By using the
priority field in the notifier block, callers can control poweroff handler
execution sequence and thus ensure that the poweroff handler with the
optimal capabilities to remove power for a given system is called first.
Patch 01/44 implements the poweroff handler API.
Patches 02/44 to 04/44 are cleanup patches to prepare for the move of
pm_power_off to a common location.
Patches 05/44 to 07/44 remove references to pm_power_off from devicetree
bindings descriptions.
Patch 08/44 moves the pm_power_off variable from architecture code to
kernel/reboot.c.
Patches 09/44 to 30/44 convert various drivers to register with the kernel
poweroff handler instead of setting pm_power_off directly.
Patches 31/44 to 42/44 do the same for architecture code.
Patch 43/44 replaces a direct call to pm_power_off from a hwmon driver
with a call to kernel_power_off. This patch is part of the series for
completeness, but will find its way upstream through the hwmon subsystem.
Patch 44/44 removes pm_power_off.
For the most part, the individual patches include explanations why specific
priorities were chosen, at least if the selected priority is not the default
priority. Subsystem and architecture maintainers are encouraged to have a look
at the selected priorities and suggest improvements.
I ran the final code through my normal build and qemu tests. Results
are available at http://server.roeck-us.net:8010/builders in the
'poweroff-handler' column. In addition I build several additional
configurations for various architectures.
The series is available in branch poweroff-handler of my repository at
git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git.
It is based on 3.17, with the pending restart handler patches applied.
I got a number of Acks from architecture maintainers as response to the RFC.
I did not add those since the architecture code changed, and I did not think
it was appropriate to retain the Acks.
A note on timing: My original plan was to submit this series after 3.18-rc1
was released. However, since the commit window will remain open for three
weeks, and the series is, for all practical purposes, ready for review,
I decided to submit it now. I plan to rebase it to 3.18-rc1 once available
and send another version, hopefully including valuable feedback.
Important changes since RFC:
- Move API to new file kernel/power/poweroff_handler.c.
- Move pm_power_off pointer to kernel/power/poweroff_handler.c. Call
pm_power_off from do_kernel_poweroff, and only call do_kernel_poweroff
from architecture code instead of calling both pm_power_off and
do_kernel_poweroff.
- Provide additional API function register_poweroff_handler_simple
to simplify conversion of architecture code.
- Provide additional API function have_kernel_poweroff to check if
a poweroff handler was installed.
- Convert all drivers and architecture code to use the new API.
- Remove pm_power_off as last patch of the series.
Cc: Alexander Graf <agraf@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chen Liqin <liqin.linux@gmail.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: Corey Minyard <minyard@acm.org>
Cc: David Howells <dhowells@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Jean Delvare <jdelvare@suse.de>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Joshua Thompson <funaho@jurai.org>
Cc: Julian Andres Klode <jak@jak-linux.org>
Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Len Brown <len.brown@intel.com>
Cc: Lennox Wu <lennox.wu@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Marc Dietrich <marvin24@gmx.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Salter <msalter@redhat.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Matt Fleming <matt.fleming@intel.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Richard Weinberger <richard@nod.at>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Romain Perier <romain.perier@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Will Deacon <will.deacon@arm.com>
----------------------------------------------------------------
Guenter Roeck (44):
kernel: Add support for poweroff handler call chain
memory: emif: Use API function to determine poweroff capability
hibernate: Call have_kernel_poweroff instead of checking pm_power_off
m68k: Replace mach_power_off with pm_power_off
mfd: as3722: Drop reference to pm_power_off from devicetree bindings
gpio-poweroff: Drop reference to pm_power_off from devicetree bindings
qnap-poweroff: Drop reference to pm_power_off from devicetree bindings
kernel: Move pm_power_off to common code
mfd: palmas: Register with kernel poweroff handler
mfd: axp20x: Register with kernel poweroff handler
mfd: retu: Register with kernel poweroff handler
mfd: ab8500-sysctrl: Register with kernel poweroff handler
mfd: max8907: Register with kernel poweroff handler
mfd: tps80031: Register with kernel poweroff handler
mfd: dm355evm_msp: Register with kernel poweroff handler
mfd: tps6586x: Register with kernel poweroff handler
mfd: tps65910: Register with kernel poweroff handler
mfd: twl4030-power: Register with kernel poweroff handler
ipmi: Register with kernel poweroff handler
power/reset: restart-poweroff: Register with kernel poweroff handler
power/reset: gpio-poweroff: Register with kernel poweroff handler
power/reset: as3722-poweroff: Register with kernel poweroff handler
power/reset: qnap-poweroff: Register with kernel poweroff handler
power/reset: msm-powroff: Register with kernel poweroff handler
power/reset: vexpress-poweroff: Register with kernel poweroff handler
x86: iris: Register with kernel poweroff handler
x86: apm: Register with kernel poweroff handler
x86: olpc: Register xo1 poweroff handler with kernel poweroff handler
staging: nvec: Register with kernel poweroff handler
acpi: Register poweroff handler with kernel poweroff handler
arm: Register with kernel poweroff handler
arm64: psci: Register with kernel poweroff handler
avr32: atngw100: Register with kernel poweroff handler
ia64: Register with kernel poweroff handler
m68k: Register with kernel poweroff handler
mips: Register with kernel poweroff handler
sh: Register with kernel poweroff handler
x86: lguest: Register with kernel poweroff handler
x86: ce4100: Register with kernel poweroff handler
x86: intel-mid: Drop registration of dummy poweroff handlers
x86: pmc_atom: Register poweroff handler with kernel poweroff handler
efi: Register poweroff handler with kernel poweroff handler
hwmon: (ab8500) Call kernel_power_off instead of pm_power_off
kernel: Remove pm_power_off
.../devicetree/bindings/gpio/gpio-poweroff.txt | 10 +-
Documentation/devicetree/bindings/mfd/as3722.txt | 3 +-
.../bindings/power_supply/qnap-poweroff.txt | 4 +-
arch/alpha/kernel/process.c | 9 +-
arch/arc/kernel/reset.c | 5 +-
arch/arm/kernel/process.c | 5 +-
arch/arm/kernel/psci.c | 2 +-
arch/arm/mach-at91/board-gsia18s.c | 2 +-
arch/arm/mach-at91/setup.c | 4 +-
arch/arm/mach-bcm/board_bcm2835.c | 2 +-
arch/arm/mach-cns3xxx/cns3420vb.c | 2 +-
arch/arm/mach-cns3xxx/core.c | 2 +-
arch/arm/mach-highbank/highbank.c | 2 +-
arch/arm/mach-imx/mach-mx31moboard.c | 2 +-
arch/arm/mach-iop32x/em7210.c | 2 +-
arch/arm/mach-iop32x/glantank.c | 2 +-
arch/arm/mach-iop32x/iq31244.c | 2 +-
arch/arm/mach-iop32x/n2100.c | 2 +-
arch/arm/mach-ixp4xx/dsmg600-setup.c | 2 +-
arch/arm/mach-ixp4xx/nas100d-setup.c | 2 +-
arch/arm/mach-ixp4xx/nslu2-setup.c | 2 +-
arch/arm/mach-omap2/board-omap3touchbook.c | 2 +-
arch/arm/mach-orion5x/board-mss2.c | 2 +-
arch/arm/mach-orion5x/dns323-setup.c | 6 +-
arch/arm/mach-orion5x/kurobox_pro-setup.c | 2 +-
arch/arm/mach-orion5x/ls-chl-setup.c | 2 +-
arch/arm/mach-orion5x/ls_hgl-setup.c | 2 +-
arch/arm/mach-orion5x/lsmini-setup.c | 2 +-
arch/arm/mach-orion5x/mv2120-setup.c | 2 +-
arch/arm/mach-orion5x/net2big-setup.c | 2 +-
arch/arm/mach-orion5x/terastation_pro2-setup.c | 2 +-
arch/arm/mach-orion5x/ts209-setup.c | 2 +-
arch/arm/mach-orion5x/ts409-setup.c | 2 +-
arch/arm/mach-pxa/corgi.c | 2 +-
arch/arm/mach-pxa/mioa701.c | 2 +-
arch/arm/mach-pxa/poodle.c | 2 +-
arch/arm/mach-pxa/spitz.c | 2 +-
arch/arm/mach-pxa/tosa.c | 2 +-
arch/arm/mach-pxa/viper.c | 2 +-
arch/arm/mach-pxa/z2.c | 6 +-
arch/arm/mach-pxa/zeus.c | 6 +-
arch/arm/mach-s3c24xx/mach-gta02.c | 2 +-
arch/arm/mach-s3c24xx/mach-jive.c | 2 +-
arch/arm/mach-s3c24xx/mach-vr1000.c | 2 +-
arch/arm/mach-s3c64xx/mach-smartq.c | 2 +-
arch/arm/mach-sa1100/generic.c | 2 +-
arch/arm/mach-sa1100/simpad.c | 2 +-
arch/arm/mach-u300/regulator.c | 2 +-
arch/arm/mach-vt8500/vt8500.c | 2 +-
arch/arm/xen/enlighten.c | 2 +-
arch/arm64/kernel/process.c | 5 +-
arch/arm64/kernel/psci.c | 2 +-
arch/avr32/boards/atngw100/mrmt.c | 2 +-
arch/avr32/kernel/process.c | 6 +-
arch/blackfin/kernel/process.c | 3 -
arch/blackfin/kernel/reboot.c | 2 +
arch/c6x/kernel/process.c | 9 +-
arch/cris/kernel/process.c | 4 +-
arch/frv/kernel/process.c | 5 +-
arch/hexagon/kernel/reset.c | 5 +-
arch/ia64/kernel/process.c | 5 +-
arch/ia64/sn/kernel/setup.c | 4 +-
arch/m32r/kernel/process.c | 8 +-
arch/m68k/emu/natfeat.c | 3 +-
arch/m68k/include/asm/machdep.h | 1 -
arch/m68k/kernel/process.c | 7 +-
arch/m68k/kernel/setup_mm.c | 1 -
arch/m68k/kernel/setup_no.c | 1 -
arch/m68k/mac/config.c | 3 +-
arch/metag/kernel/process.c | 6 +-
arch/microblaze/kernel/process.c | 3 -
arch/microblaze/kernel/reset.c | 1 +
arch/mips/alchemy/board-gpr.c | 2 +-
arch/mips/alchemy/board-mtx1.c | 2 +-
arch/mips/alchemy/board-xxs1500.c | 2 +-
arch/mips/alchemy/devboards/platform.c | 17 +-
arch/mips/ar7/setup.c | 2 +-
arch/mips/ath79/setup.c | 2 +-
arch/mips/bcm47xx/setup.c | 2 +-
arch/mips/bcm63xx/setup.c | 2 +-
arch/mips/cobalt/setup.c | 2 +-
arch/mips/dec/setup.c | 2 +-
arch/mips/emma/markeins/setup.c | 2 +-
arch/mips/jz4740/reset.c | 2 +-
arch/mips/kernel/reset.c | 6 +-
arch/mips/lantiq/falcon/reset.c | 2 +-
arch/mips/lantiq/xway/reset.c | 2 +-
arch/mips/lasat/reset.c | 2 +-
arch/mips/loongson/common/reset.c | 2 +-
arch/mips/loongson1/common/reset.c | 2 +-
arch/mips/mti-malta/malta-reset.c | 2 +-
arch/mips/mti-sead3/sead3-reset.c | 2 +-
arch/mips/netlogic/xlp/setup.c | 2 +-
arch/mips/netlogic/xlr/setup.c | 2 +-
arch/mips/pmcs-msp71xx/msp_setup.c | 2 +-
arch/mips/pnx833x/common/setup.c | 2 +-
arch/mips/ralink/reset.c | 2 +-
arch/mips/rb532/setup.c | 2 +-
arch/mips/sgi-ip22/ip22-reset.c | 2 +-
arch/mips/sgi-ip27/ip27-reset.c | 2 +-
arch/mips/sgi-ip32/ip32-reset.c | 2 +-
arch/mips/sibyte/common/cfe.c | 2 +-
arch/mips/sni/setup.c | 2 +-
arch/mips/txx9/generic/setup.c | 2 +-
arch/mips/vr41xx/common/pmu.c | 2 +-
arch/mn10300/kernel/process.c | 8 +-
arch/openrisc/kernel/process.c | 8 +-
arch/parisc/kernel/process.c | 8 +-
arch/powerpc/kernel/setup-common.c | 6 +-
arch/s390/kernel/setup.c | 8 +-
arch/score/kernel/process.c | 8 +-
arch/sh/boards/board-sh7785lcr.c | 2 +-
arch/sh/boards/board-urquell.c | 2 +-
arch/sh/boards/mach-highlander/setup.c | 2 +-
arch/sh/boards/mach-landisk/setup.c | 2 +-
arch/sh/boards/mach-r2d/setup.c | 2 +-
arch/sh/boards/mach-sdk7786/setup.c | 2 +-
arch/sh/kernel/reboot.c | 6 +-
arch/sparc/kernel/process_32.c | 10 +-
arch/sparc/kernel/reboot.c | 8 +-
arch/tile/kernel/reboot.c | 7 +-
arch/um/kernel/reboot.c | 2 -
arch/unicore32/kernel/process.c | 9 +-
arch/x86/kernel/apm_32.c | 20 ++-
arch/x86/kernel/pmc_atom.c | 20 ++-
arch/x86/kernel/reboot.c | 11 +-
arch/x86/lguest/boot.c | 2 +-
arch/x86/platform/ce4100/ce4100.c | 2 +-
arch/x86/platform/intel-mid/intel-mid.c | 5 -
arch/x86/platform/intel-mid/mfld.c | 5 -
arch/x86/platform/iris/iris.c | 25 ++-
arch/x86/platform/olpc/olpc-xo1-pm.c | 20 ++-
arch/x86/xen/enlighten.c | 3 +-
arch/xtensa/kernel/process.c | 4 -
drivers/acpi/sleep.c | 15 +-
drivers/char/ipmi/ipmi_poweroff.c | 30 ++--
drivers/firmware/efi/reboot.c | 23 ++-
drivers/hwmon/ab8500.c | 5 +-
drivers/memory/emif.c | 4 +-
drivers/mfd/ab8500-sysctrl.c | 26 ++--
drivers/mfd/axp20x.c | 30 ++--
drivers/mfd/dm355evm_msp.c | 18 ++-
drivers/mfd/max8907.c | 24 ++-
drivers/mfd/palmas.c | 30 ++--
drivers/mfd/retu-mfd.c | 33 ++--
drivers/mfd/tps6586x.c | 31 +++-
drivers/mfd/tps65910.c | 27 ++--
drivers/mfd/tps80031.c | 30 ++--
drivers/mfd/twl4030-power.c | 25 ++-
drivers/parisc/power.c | 3 +-
drivers/power/reset/as3722-poweroff.c | 36 +++--
drivers/power/reset/gpio-poweroff.c | 36 ++---
drivers/power/reset/msm-poweroff.c | 13 +-
drivers/power/reset/qnap-poweroff.c | 28 ++--
drivers/power/reset/restart-poweroff.c | 25 ++-
drivers/power/reset/vexpress-poweroff.c | 19 ++-
drivers/staging/nvec/nvec.c | 24 +--
drivers/staging/nvec/nvec.h | 2 +
include/linux/i2c/twl.h | 1 -
include/linux/mfd/axp20x.h | 1 +
include/linux/mfd/max8907.h | 2 +
include/linux/mfd/palmas.h | 3 +
include/linux/mfd/tps65910.h | 3 +
include/linux/mfd/tps80031.h | 2 +
include/linux/pm.h | 14 +-
kernel/power/Makefile | 1 +
kernel/power/hibernate.c | 2 +-
kernel/power/poweroff_handler.c | 173 +++++++++++++++++++++
kernel/reboot.c | 4 +-
169 files changed, 794 insertions(+), 475 deletions(-)
create mode 100644 kernel/power/poweroff_handler.c
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox