All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards
@ 2009-08-30 19:36 Anton Vorontsov
  2009-08-30 19:37 ` [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation Anton Vorontsov
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-30 19:36 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

On Fri, Aug 28, 2009 at 12:38:51AM -0500, Kumar Gala wrote:
> >This patch adds suspend/resume support for MPC8540-compatible and
> >MPC8569 CPUs.
[...] 
> I'd also like to get Scott's Ack on this and the device tree patches
> before accepting them.

Heh, I didn't notice that the PMC bindings for 85xx describe devdisr
registers (and thus sleep = <> properties).

So here are updated patches that should comply with the bindings.
Plus,

- It appears that 86xx PMCs registers-compatible with 85xx, so we
  can support both. Thus move 85xx/suspend.c to sysdev/fsl_pmc.c;
- New patch that adds suspend/resume for MPC8610HPCD;
- New patch that adds suspend/resume for 83xx QE boards;
- Some fixes in "Make qe_reset() code path safe for repeated
  invocation" patch.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation
  2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
@ 2009-08-30 19:37 ` Anton Vorontsov
  2009-08-31  0:36   ` Tabi Timur-B04825
  2009-08-30 19:37 ` [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support Anton Vorontsov
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-30 19:37 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

For MPC8569 CPUs we'll need to reset QE after each suspend, so make
qe_reset() code path suitable for repeated invocation, that is:

- Don't initialize rheap structures if already initialized;
- Don't allocate muram for SDMA if already allocated, just reinitialize
  registers with previously allocated muram offset;
- Remove __init attributes from qe_reset() and cpm_muram_init();

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/include/asm/qe.h    |    2 +-
 arch/powerpc/sysdev/cpm_common.c |    5 ++++-
 arch/powerpc/sysdev/qe_lib/qe.c  |   12 +++++++-----
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index e8232bb..2f44754 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -87,7 +87,7 @@ extern spinlock_t cmxgcr_lock;
 
 /* Export QE common operations */
 #ifdef CONFIG_QUICC_ENGINE
-extern void __init qe_reset(void);
+extern void qe_reset(void);
 #else
 static inline void qe_reset(void) {}
 #endif
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index e4b6d66..9de72c9 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -72,7 +72,7 @@ static phys_addr_t muram_pbase;
 /* Max address size we deal with */
 #define OF_MAX_ADDR_CELLS	4
 
-int __init cpm_muram_init(void)
+int cpm_muram_init(void)
 {
 	struct device_node *np;
 	struct resource r;
@@ -81,6 +81,9 @@ int __init cpm_muram_init(void)
 	int i = 0;
 	int ret = 0;
 
+	if (muram_pbase)
+		return 0;
+
 	spin_lock_init(&cpm_muram_lock);
 	/* initialize the info header */
 	rh_init(&cpm_muram_info, 1,
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index b06564f..4eaf2a9 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -91,7 +91,7 @@ phys_addr_t get_qe_base(void)
 
 EXPORT_SYMBOL(get_qe_base);
 
-void __init qe_reset(void)
+void qe_reset(void)
 {
 	if (qe_immr == NULL)
 		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
@@ -317,16 +317,18 @@ EXPORT_SYMBOL(qe_put_snum);
 static int qe_sdma_init(void)
 {
 	struct sdma __iomem *sdma = &qe_immr->sdma;
-	unsigned long sdma_buf_offset;
+	static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
 
 	if (!sdma)
 		return -ENODEV;
 
 	/* allocate 2 internal temporary buffers (512 bytes size each) for
 	 * the SDMA */
- 	sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
-	if (IS_ERR_VALUE(sdma_buf_offset))
-		return -ENOMEM;
+	if (IS_ERR_VALUE(sdma_buf_offset)) {
+		sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
+		if (IS_ERR_VALUE(sdma_buf_offset))
+			return -ENOMEM;
+	}
 
 	out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
  	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
  2009-08-30 19:37 ` [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation Anton Vorontsov
@ 2009-08-30 19:37 ` Anton Vorontsov
  2009-08-31  0:38   ` Tabi Timur-B04825
  2009-09-14 17:28   ` Scott Wood
  2009-08-30 19:37 ` [PATCH 3/5] powerpc/85xx: Add power management support for MPC85xxMDS boards Anton Vorontsov
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-30 19:37 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

This patch adds suspend/resume support for MPC8540, MPC8569 and
MPC8641D-compatible CPUs.

MPC8540 and MPC8641D-compatible PMCs are trivial: we just write
the SLP bit into the PM control and status register.

MPC8569 is a bit trickier, QE turns off during suspend, thus on
resume we must reload QE microcode and reset QE.

So far we don't support Deep Sleep mode as found in newer MPC85xx
CPUs (i.e. MPC8536). It can be relatively easy implemented though,
and for it we reserve 'mem' suspend type.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/Kconfig          |   11 +++-
 arch/powerpc/sysdev/Makefile  |    1 +
 arch/powerpc/sysdev/fsl_pmc.c |  124 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 135 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/sysdev/fsl_pmc.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d00131c..a0743a7 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -212,7 +212,8 @@ config ARCH_HIBERNATION_POSSIBLE
 
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
-	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
+	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
+		   PPC_85xx || PPC_86xx
 
 config PPC_DCR_NATIVE
 	bool
@@ -642,6 +643,14 @@ config FSL_PCI
 	select PPC_INDIRECT_PCI
 	select PCI_QUIRKS
 
+config FSL_PMC
+	bool
+	default y
+	depends on SUSPEND && (PPC_85xx || PPC_86xx)
+	help
+	  Freescale MPC85xx/MPC86xx power management controller support
+	  (suspend/resume). For MPC83xx see platforms/83xx/suspend.c
+
 config 4xx_SOC
 	bool
 
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 9d4b174..5642924 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_U3_DART)		+= dart_iommu.o
 obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
 obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_FSL_PCI)		+= fsl_pci.o $(fsl-msi-obj-y)
+obj-$(CONFIG_FSL_PMC)		+= fsl_pmc.o
 obj-$(CONFIG_FSL_LBC)		+= fsl_lbc.o
 obj-$(CONFIG_FSL_GTM)		+= fsl_gtm.o
 obj-$(CONFIG_MPC8xxx_GPIO)	+= mpc8xxx_gpio.o
diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c
new file mode 100644
index 0000000..843c284
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_pmc.c
@@ -0,0 +1,124 @@
+/*
+ * Suspend/resume support
+ *
+ * Copyright © 2009  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/suspend.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/firmware.h>
+#include <asm/qe.h>
+
+struct pmc_regs {
+	__be32 devdisr;
+	__be32 devdisr2;
+	__be32 :32;
+	__be32 :32;
+	__be32 pmcsr;
+#define PMCSR_SLP	(1 << 17)
+};
+
+struct pmc_data {
+	unsigned int flags;
+#define PMC_NEED_QE_RELOAD (1 << 0)
+
+	const char *fw_name;
+};
+
+static struct device *pmc_dev;
+static struct pmc_regs __iomem *pmc_regs;
+static const struct pmc_data *pmc_data;
+static struct qe_firmware *pmc_qefw;
+
+static int pmc_suspend_enter(suspend_state_t state)
+{
+	setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
+	/* At this point, the CPU is asleep. */
+
+	/* For 86xx we need to clear the bit on resume, 85xx don't care. */
+	clrbits32(&pmc_regs->pmcsr, PMCSR_SLP);
+
+	if (pmc_qefw) {
+		int ret;
+
+		ret = qe_upload_firmware(pmc_qefw);
+		if (ret)
+			dev_err(pmc_dev, "could not upload firmware\n");
+
+		qe_reset();
+	}
+	return 0;
+}
+
+static int pmc_suspend_valid(suspend_state_t state)
+{
+	if (state != PM_SUSPEND_STANDBY)
+		return 0;
+
+	if (pmc_data && pmc_data->flags & PMC_NEED_QE_RELOAD && !pmc_qefw) {
+		const struct firmware *fw;
+		int ret;
+
+		ret = request_firmware(&fw, pmc_data->fw_name, pmc_dev);
+		if (ret) {
+			dev_err(pmc_dev, "could not request firmware %s\n",
+				pmc_data->fw_name);
+			return 0;
+		}
+
+		pmc_qefw = (struct qe_firmware *)fw->data;
+	}
+
+	return 1;
+}
+
+static struct platform_suspend_ops pmc_suspend_ops = {
+	.valid = pmc_suspend_valid,
+	.enter = pmc_suspend_enter,
+};
+
+static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id)
+{
+	pmc_regs = of_iomap(ofdev->node, 0);
+	if (!pmc_regs)
+		return -ENOMEM;
+
+	pmc_dev = &ofdev->dev;
+	pmc_data = id->data;
+	suspend_set_ops(&pmc_suspend_ops);
+	return 0;
+}
+
+static struct pmc_data mpc8569_pmc_data = {
+	.flags = PMC_NEED_QE_RELOAD,
+	.fw_name = "fsl_qe_ucode_8569.bin",
+};
+
+static const struct of_device_id pmc_ids[] = {
+	{ .compatible = "fsl,mpc8569-pmc", .data = &mpc8569_pmc_data, },
+	{ .compatible = "fsl,mpc8548-pmc", },
+	{ .compatible = "fsl,mpc8641d-pmc", },
+	{ },
+};
+
+static struct of_platform_driver pmc_driver = {
+	.driver.name = "fsl-pmc",
+	.match_table = pmc_ids,
+	.probe = pmc_probe,
+};
+
+static int __init pmc_init(void)
+{
+	return of_register_platform_driver(&pmc_driver);
+}
+device_initcall(pmc_init);
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/5] powerpc/85xx: Add power management support for MPC85xxMDS boards
  2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
  2009-08-30 19:37 ` [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation Anton Vorontsov
  2009-08-30 19:37 ` [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support Anton Vorontsov
@ 2009-08-30 19:37 ` Anton Vorontsov
  2009-08-30 19:37 ` [PATCH 4/5] powerpc/86xx: Add power management support for MPC8610HPCD boards Anton Vorontsov
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-30 19:37 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

- Add power management controller nodes;
- Add interrupts for RTC nodes, the RTC interrupt may be used as a
  wakeup source;
- Add sleep properties and sleep-nexus nodes.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc8568mds.dts      |  119 +++++++++++++++++++----------
 arch/powerpc/boot/dts/mpc8569mds.dts      |  111 ++++++++++++++++++---------
 arch/powerpc/platforms/85xx/mpc85xx_mds.c |    1 +
 3 files changed, 153 insertions(+), 78 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 00c2bbd..6d892ba 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -40,6 +40,8 @@
 			i-cache-line-size = <32>;	// 32 bytes
 			d-cache-size = <0x8000>;		// L1, 32K
 			i-cache-size = <0x8000>;		// L1, 32K
+			sleep = <&pmc 0x00008000	// core
+				 &pmc 0x00004000>;	// timebase
 			timebase-frequency = <0>;
 			bus-frequency = <0>;
 			clock-frequency = <0>;
@@ -94,31 +96,41 @@
 			interrupts = <16 2>;
 		};
 
-		i2c@3000 {
+		i2c-sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000004>;
+			ranges;
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <3 1>;
+					interrupt-parent = <&mpic>;
+				};
 			};
-		};
 
-		i2c@3100 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
+			i2c@3100 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <1>;
+				compatible = "fsl-i2c";
+				reg = <0x3100 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
+			};
 		};
 
 		dma@21300 {
@@ -128,6 +140,8 @@
 			reg = <0x21300 0x4>;
 			ranges = <0x0 0x21100 0x200>;
 			cell-index = <0>;
+			sleep = <&pmc 0x00000400>;
+
 			dma-channel@0 {
 				compatible = "fsl,mpc8568-dma-channel",
 						"fsl,eloplus-dma-channel";
@@ -176,6 +190,7 @@
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0x00000080>;
 
 			mdio@520 {
 				#address-cells = <1>;
@@ -228,6 +243,7 @@
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy3>;
+			sleep = <&pmc 0x00000040>;
 
 			mdio@520 {
 				#address-cells = <1>;
@@ -242,30 +258,47 @@
 			};
 		};
 
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
+		duart-sleep-nexus {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000002>;
+			ranges;
+
+			serial0: serial@4500 {
+				cell-index = <0>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4500 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
+
+			serial1: serial@4600 {
+				cell-index = <1>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4600 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
 		};
 
-		global-utilities@e0000 {	//global utilities block
-			compatible = "fsl,mpc8548-guts";
+		global-utilities@e0000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8568-guts", "fsl,mpc8548-guts";
 			reg = <0xe0000 0x1000>;
+			ranges = <0 0xe0000 0x1000>;
 			fsl,has-rstcr;
-		};
 
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
+			pmc: power@70 {
+				compatible = "fsl,mpc8568-pmc",
+					     "fsl,mpc8548-pmc";
+				reg = <0x70 0x20>;
+			};
 		};
 
 		crypto@30000 {
@@ -277,6 +310,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0xfe>;
 			fsl,descriptor-types-mask = <0x12b0ebf>;
+			sleep = <&pmc 0x01000000>;
 		};
 
 		mpic: pic@40000 {
@@ -376,6 +410,7 @@
 		compatible = "fsl,qe";
 		ranges = <0x0 0xe0080000 0x40000>;
 		reg = <0xe0080000 0x480>;
+		sleep = <&pmc 0x00000800>;
 		brg-frequency = <0>;
 		bus-frequency = <396000000>;
 		fsl,qe-num-riscs = <2>;
@@ -509,6 +544,7 @@
 		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x0 0xe2000000 0x0 0x800000>;
+		sleep = <&pmc 0x80000000>;
 		clock-frequency = <66666666>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -534,6 +570,7 @@
 		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
 			  0x1000000 0x0 0x0 0xe2800000 0x0 0x800000>;
+		sleep = <&pmc 0x20000000>;
 		clock-frequency = <33333333>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -570,5 +607,7 @@
 			      55 2 /* msg2_tx   */
 			      56 2 /* msg2_rx   */>;
 		interrupt-parent = <&mpic>;
+		sleep = <&pmc 0x00080000   /* controller */
+			 &pmc 0x00040000>; /* message unit */
 	};
 };
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
index 880f896..b35e62c 100644
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -41,6 +41,8 @@
 			i-cache-line-size = <32>;	// 32 bytes
 			d-cache-size = <0x8000>;		// L1, 32K
 			i-cache-size = <0x8000>;		// L1, 32K
+			sleep = <&pmc 0x00008000	// core
+				 &pmc 0x00004000>;	// timebase
 			timebase-frequency = <0>;
 			bus-frequency = <0>;
 			clock-frequency = <0>;
@@ -59,6 +61,7 @@
 		reg = <0xe0005000 0x1000>;
 		interrupts = <19 2>;
 		interrupt-parent = <&mpic>;
+		sleep = <&pmc 0x08000000>;
 
 		ranges = <0x0 0x0 0xfe000000 0x02000000
 			  0x1 0x0 0xf8000000 0x00008000
@@ -158,51 +161,69 @@
 			interrupts = <18 2>;
 		};
 
-		i2c@3000 {
+		i2c-sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000004>;
+			ranges;
+
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <3 1>;
+					interrupt-parent = <&mpic>;
+				};
+			};
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
+			i2c@3100 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <1>;
+				compatible = "fsl-i2c";
+				reg = <0x3100 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
 			};
 		};
 
-		i2c@3100 {
+		duart-sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000002>;
+			ranges;
 
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
+			serial0: serial@4500 {
+				cell-index = <0>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4500 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
 
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
+			serial1: serial@4600 {
+				cell-index = <1>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4600 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
 		};
 
 		L2: l2-cache-controller@20000 {
@@ -260,6 +281,7 @@
 			reg = <0x2e000 0x1000>;
 			interrupts = <72 0x8>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00200000>;
 			/* Filled in by U-Boot */
 			clock-frequency = <0>;
 			status = "disabled";
@@ -276,6 +298,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0xbfe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
+			sleep = <&pmc 0x01000000>;
 		};
 
 		mpic: pic@40000 {
@@ -304,9 +327,18 @@
 		};
 
 		global-utilities@e0000 {
-			compatible = "fsl,mpc8569-guts";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8569-guts", "fsl,mpc8548-guts";
 			reg = <0xe0000 0x1000>;
+			ranges = <0 0xe0000 0x1000>;
 			fsl,has-rstcr;
+
+			pmc: power@70 {
+				compatible = "fsl,mpc8569-pmc",
+					     "fsl,mpc8548-pmc";
+				reg = <0x70 0x20>;
+			};
 		};
 
 		par_io@e0100 {
@@ -422,6 +454,7 @@
 		compatible = "fsl,qe";
 		ranges = <0x0 0xe0080000 0x40000>;
 		reg = <0xe0080000 0x480>;
+		sleep = <&pmc 0x00000800>;
 		brg-frequency = <0>;
 		bus-frequency = <0>;
 		fsl,qe-num-riscs = <4>;
@@ -680,6 +713,7 @@
 		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
 			  0x1000000 0x0 0x00000000 0xe2800000 0x0 0x00800000>;
+		sleep = <&pmc 0x20000000>;
 		clock-frequency = <33333333>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
@@ -710,5 +744,6 @@
 			      55 2 /* msg2_tx   */
 			      56 2 /* msg2_rx   */>;
 		interrupt-parent = <&mpic>;
+		sleep = <&pmc 0x00080000>;
 	};
 };
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 20a61d0..995ddad 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -300,6 +300,7 @@ static struct of_device_id mpc85xx_ids[] = {
 	{ .compatible = "fsl,qe", },
 	{ .compatible = "gianfar", },
 	{ .compatible = "fsl,rapidio-delta", },
+	{ .compatible = "fsl,mpc8548-guts", },
 	{},
 };
 
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/5] powerpc/86xx: Add power management support for MPC8610HPCD boards
  2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
                   ` (2 preceding siblings ...)
  2009-08-30 19:37 ` [PATCH 3/5] powerpc/85xx: Add power management support for MPC85xxMDS boards Anton Vorontsov
@ 2009-08-30 19:37 ` Anton Vorontsov
  2009-08-30 19:37 ` [PATCH 5/5] powerpc/83xx: Add power management support for MPC83xx QE boards Anton Vorontsov
  2009-09-14 15:33 ` [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
  5 siblings, 0 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-30 19:37 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

This patch adds needed nodes and properties to support suspend/resume
on the MPC8610HPCD boards.

There is a dedicated switch (SW9) that is used to wake up the boards.
By default the SW9 button is routed to IRQ8, but could be re-routed
(via PIXIS) to sreset.

With 'no_console_suspend' kernel command line argument specified, the
board is also able to wakeup upon serial port input.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 Documentation/powerpc/dts-bindings/fsl/board.txt |    4 ++
 arch/powerpc/boot/dts/mpc8610_hpcd.dts           |   26 ++++++++++++
 arch/powerpc/platforms/86xx/mpc8610_hpcd.c       |   48 ++++++++++++++++++++--
 3 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/Documentation/powerpc/dts-bindings/fsl/board.txt b/Documentation/powerpc/dts-bindings/fsl/board.txt
index e8b5bc2..39e9415 100644
--- a/Documentation/powerpc/dts-bindings/fsl/board.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/board.txt
@@ -20,12 +20,16 @@ Required properities:
 - compatible : should be "fsl,fpga-pixis".
 - reg : should contain the address and the length of the FPPGA register
   set.
+- interrupt-parent: should specify phandle for the interrupt controller.
+- interrupts : should specify event (wakeup) IRQ.
 
 Example (MPC8610HPCD):
 
 	board-control@e8000000 {
 		compatible = "fsl,fpga-pixis";
 		reg = <0xe8000000 32>;
+		interrupt-parent = <&mpic>;
+		interrupts = <8 8>;
 	};
 
 * Freescale BCSR GPIO banks
diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
index f468d21..9535ce6 100644
--- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
@@ -35,6 +35,8 @@
 			i-cache-line-size = <32>;
 			d-cache-size = <32768>;		// L1
 			i-cache-size = <32768>;		// L1
+			sleep = <&pmc 0x00008000 0	// core
+				 &pmc 0x00004000 0>;	// timebase
 			timebase-frequency = <0>;	// From uboot
 			bus-frequency = <0>;		// From uboot
 			clock-frequency = <0>;		// From uboot
@@ -60,6 +62,7 @@
 			  5 0 0xe8480000 0x00008000
 			  6 0 0xe84c0000 0x00008000
 			  3 0 0xe8000000 0x00000020>;
+		sleep = <&pmc 0x08000000 0>;
 
 		flash@0,0 {
 			compatible = "cfi-flash";
@@ -105,6 +108,8 @@
 			compatible = "fsl,fpga-pixis";
 			reg = <3 0 0x20>;
 			ranges = <0 3 0 0x20>;
+			interrupt-parent = <&mpic>;
+			interrupts = <8 8>;
 
 			sdcsr_pio: gpio-controller@a {
 				#gpio-cells = <2>;
@@ -163,6 +168,7 @@
 			reg = <0x3100 0x100>;
 			interrupts = <43 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00000004 0>;
 			dfsrr;
 		};
 
@@ -174,6 +180,7 @@
 			clock-frequency = <0>;
 			interrupts = <42 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00000002 0>;
 		};
 
 		serial1: serial@4600 {
@@ -184,6 +191,7 @@
 			clock-frequency = <0>;
 			interrupts = <42 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00000008 0>;
 		};
 
 		spi@7000 {
@@ -196,6 +204,7 @@
 			interrupt-parent = <&mpic>;
 			mode = "cpu";
 			gpios = <&sdcsr_pio 7 0>;
+			sleep = <&pmc 0x00000800 0>;
 
 			mmc-slot@0 {
 				compatible = "fsl,mpc8610hpcd-mmc-slot",
@@ -213,6 +222,7 @@
 			reg = <0x2c000 100>;
 			interrupts = <72 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x04000000 0>;
 		};
 
 		mpic: interrupt-controller@40000 {
@@ -241,9 +251,18 @@
 		};
 
 		global-utilities@e0000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			compatible = "fsl,mpc8610-guts";
 			reg = <0xe0000 0x1000>;
+			ranges = <0 0xe0000 0x1000>;
 			fsl,has-rstcr;
+
+			pmc: power@70 {
+				compatible = "fsl,mpc8610-pmc",
+					     "fsl,mpc8641d-pmc";
+				reg = <0x70 0x20>;
+			};
 		};
 
 		wdt@e4000 {
@@ -262,6 +281,7 @@
 			fsl,playback-dma = <&dma00>;
 			fsl,capture-dma = <&dma01>;
 			fsl,fifo-depth = <8>;
+			sleep = <&pmc 0 0x08000000>;
 		};
 
 		ssi@16100 {
@@ -271,6 +291,7 @@
 			interrupt-parent = <&mpic>;
 			interrupts = <63 2>;
 			fsl,fifo-depth = <8>;
+			sleep = <&pmc 0 0x04000000>;
 		};
 
 		dma@21300 {
@@ -280,6 +301,7 @@
 			cell-index = <0>;
 			reg = <0x21300 0x4>; /* DMA general status register */
 			ranges = <0x0 0x21100 0x200>;
+			sleep = <&pmc 0x00000400 0>;
 
 			dma00: dma-channel@0 {
 				compatible = "fsl,mpc8610-dma-channel",
@@ -322,6 +344,7 @@
 			cell-index = <1>;
 			reg = <0xc300 0x4>; /* DMA general status register */
 			ranges = <0x0 0xc100 0x200>;
+			sleep = <&pmc 0x00000200 0>;
 
 			dma-channel@0 {
 				compatible = "fsl,mpc8610-dma-channel",
@@ -369,6 +392,7 @@
 		bus-range = <0 0>;
 		ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 			  0x01000000 0x0 0x00000000 0xe1000000 0x0 0x00100000>;
+		sleep = <&pmc 0x80000000 0>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <24 2>;
@@ -398,6 +422,7 @@
 		bus-range = <1 3>;
 		ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
 			  0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>;
+		sleep = <&pmc 0x40000000 0>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <26 2>;
@@ -474,6 +499,7 @@
 				 0x0000 0 0 4 &mpic 7 1>;
 		interrupt-parent = <&mpic>;
 		interrupts = <25 2>;
+		sleep = <&pmc 0x20000000 0>;
 		clock-frequency = <33333333>;
 	};
 };
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 627908a..5abe137 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -19,6 +19,7 @@
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
@@ -41,10 +42,46 @@
 
 #include "mpc86xx.h"
 
+static struct device_node *pixis_node;
 static unsigned char *pixis_bdcfg0, *pixis_arch;
 
+#ifdef CONFIG_SUSPEND
+static irqreturn_t mpc8610_sw9_irq(int irq, void *data)
+{
+	pr_debug("%s: PIXIS' event (sw9/wakeup) IRQ handled\n", __func__);
+	return IRQ_HANDLED;
+}
+
+static void __init mpc8610_suspend_init(void)
+{
+	int irq;
+	int ret;
+
+	if (!pixis_node)
+		return;
+
+	irq = irq_of_parse_and_map(pixis_node, 0);
+	if (!irq) {
+		pr_err("%s: can't map pixis event IRQ.\n", __func__);
+		return;
+	}
+
+	ret = request_irq(irq, mpc8610_sw9_irq, 0, "sw9/wakeup", NULL);
+	if (ret) {
+		pr_err("%s: can't request pixis event IRQ: %d\n",
+		       __func__, ret);
+		irq_dispose_mapping(irq);
+	}
+
+	enable_irq_wake(irq);
+}
+#else
+static inline void mpc8610_suspend_init(void) { }
+#endif /* CONFIG_SUSPEND */
+
 static struct of_device_id __initdata mpc8610_ids[] = {
 	{ .compatible = "fsl,mpc8610-immr", },
+	{ .compatible = "fsl,mpc8610-guts", },
 	{ .compatible = "simple-bus", },
 	{ .compatible = "gianfar", },
 	{}
@@ -55,6 +92,9 @@ static int __init mpc8610_declare_of_platform_devices(void)
 	/* Firstly, register PIXIS GPIOs. */
 	simple_gpiochip_init("fsl,fpga-pixis-gpio-bank");
 
+	/* Enable wakeup on PIXIS' event IRQ. */
+	mpc8610_suspend_init();
+
 	/* Without this call, the SSI device driver won't get probed. */
 	of_platform_bus_probe(NULL, mpc8610_ids, NULL);
 
@@ -250,10 +290,10 @@ static void __init mpc86xx_hpcd_setup_arch(void)
 	diu_ops.set_sysfs_monitor_port	= mpc8610hpcd_set_sysfs_monitor_port;
 #endif
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
-	if (np) {
-		of_address_to_resource(np, 0, &r);
-		of_node_put(np);
+	pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
+	if (pixis_node) {
+		of_address_to_resource(pixis_node, 0, &r);
+		of_node_put(pixis_node);
 		pixis = ioremap(r.start, 32);
 		if (!pixis) {
 			printk(KERN_ERR "Err: can't map FPGA cfg register!\n");
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/5] powerpc/83xx: Add power management support for MPC83xx QE boards
  2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
                   ` (3 preceding siblings ...)
  2009-08-30 19:37 ` [PATCH 4/5] powerpc/86xx: Add power management support for MPC8610HPCD boards Anton Vorontsov
@ 2009-08-30 19:37 ` Anton Vorontsov
  2009-09-14 15:33 ` [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
  5 siblings, 0 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-30 19:37 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

Simply add power management controller nodes and sleep properties.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/kmeter1.dts     |    7 +++++++
 arch/powerpc/boot/dts/mpc832x_mds.dts |    9 +++++++++
 arch/powerpc/boot/dts/mpc832x_rdb.dts |    9 +++++++++
 arch/powerpc/boot/dts/mpc836x_mds.dts |    9 +++++++++
 arch/powerpc/boot/dts/mpc836x_rdk.dts |    9 +++++++++
 5 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/kmeter1.dts b/arch/powerpc/boot/dts/kmeter1.dts
index 167044f..65b8b4f 100644
--- a/arch/powerpc/boot/dts/kmeter1.dts
+++ b/arch/powerpc/boot/dts/kmeter1.dts
@@ -59,6 +59,13 @@
 		reg = <0xe0000000 0x00000200>;
 		bus-frequency = <0>;	/* Filled in by U-Boot */
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8360-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 436c9c6..05ad8c9 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -79,6 +79,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8323-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -163,6 +170,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x4c>;
 			fsl,descriptor-types-mask = <0x0122003f>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic: pic@700 {
@@ -428,5 +436,6 @@
 		       0xe0008300 0x8>;		/* config space access registers */
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
+		sleep = <&pmc 0x00010000>;
 	};
 };
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 9a0952f..f4fadb2 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -62,6 +62,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8323-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -141,6 +148,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x4c>;
 			fsl,descriptor-types-mask = <0x0122003f>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic:pic@700 {
@@ -360,5 +368,6 @@
 		       0xe0008300 0x8>;		/* config space access registers */
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
+		sleep = <&pmc 0x00010000>;
 	};
 };
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 39ff4c8..45cfa1c 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -99,6 +99,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8360-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -194,6 +201,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x7e>;
 			fsl,descriptor-types-mask = <0x01010ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic: pic@700 {
@@ -470,5 +478,6 @@
 		       0xe0008300 0x8>;		/* config space access registers */
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
+		sleep = <&pmc 0x00010000>;
 	};
 };
diff --git a/arch/powerpc/boot/dts/mpc836x_rdk.dts b/arch/powerpc/boot/dts/mpc836x_rdk.dts
index 6315d6f..bdf4459 100644
--- a/arch/powerpc/boot/dts/mpc836x_rdk.dts
+++ b/arch/powerpc/boot/dts/mpc836x_rdk.dts
@@ -71,6 +71,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8360-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -161,6 +168,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x7e>;
 			fsl,descriptor-types-mask = <0x01010ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic: interrupt-controller@700 {
@@ -455,6 +463,7 @@
 				 0xa800 0 0 2 &ipic 20 8
 				 0xa800 0 0 3 &ipic 21 8
 				 0xa800 0 0 4 &ipic 18 8>;
+		sleep = <&pmc 0x00010000>;
 		/* filled by u-boot */
 		bus-range = <0 0>;
 		clock-frequency = <0>;
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* RE: [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation
  2009-08-30 19:37 ` [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation Anton Vorontsov
@ 2009-08-31  0:36   ` Tabi Timur-B04825
  2009-08-31 18:47     ` Anton Vorontsov
  0 siblings, 1 reply; 16+ messages in thread
From: Tabi Timur-B04825 @ 2009-08-31  0:36 UTC (permalink / raw)
  To: Anton Vorontsov, Kumar Gala; +Cc: Wood Scott-B07421, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 3335 bytes --]

Is the need to reinitialize the QE after resume something that is unique to the 8569, or would it apply to the 8360 and 8323 also?


-----Original Message-----
From: Anton Vorontsov [mailto:avorontsov@ru.mvista.com]
Sent: Sun 8/30/2009 2:37 PM
To: Kumar Gala
Cc: Tabi Timur-B04825; Wood Scott-B07421; linuxppc-dev@ozlabs.org
Subject: [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation
 
For MPC8569 CPUs we'll need to reset QE after each suspend, so make
qe_reset() code path suitable for repeated invocation, that is:

- Don't initialize rheap structures if already initialized;
- Don't allocate muram for SDMA if already allocated, just reinitialize
  registers with previously allocated muram offset;
- Remove __init attributes from qe_reset() and cpm_muram_init();

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/include/asm/qe.h    |    2 +-
 arch/powerpc/sysdev/cpm_common.c |    5 ++++-
 arch/powerpc/sysdev/qe_lib/qe.c  |   12 +++++++-----
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index e8232bb..2f44754 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -87,7 +87,7 @@ extern spinlock_t cmxgcr_lock;
 
 /* Export QE common operations */
 #ifdef CONFIG_QUICC_ENGINE
-extern void __init qe_reset(void);
+extern void qe_reset(void);
 #else
 static inline void qe_reset(void) {}
 #endif
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index e4b6d66..9de72c9 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -72,7 +72,7 @@ static phys_addr_t muram_pbase;
 /* Max address size we deal with */
 #define OF_MAX_ADDR_CELLS	4
 
-int __init cpm_muram_init(void)
+int cpm_muram_init(void)
 {
 	struct device_node *np;
 	struct resource r;
@@ -81,6 +81,9 @@ int __init cpm_muram_init(void)
 	int i = 0;
 	int ret = 0;
 
+	if (muram_pbase)
+		return 0;
+
 	spin_lock_init(&cpm_muram_lock);
 	/* initialize the info header */
 	rh_init(&cpm_muram_info, 1,
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index b06564f..4eaf2a9 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -91,7 +91,7 @@ phys_addr_t get_qe_base(void)
 
 EXPORT_SYMBOL(get_qe_base);
 
-void __init qe_reset(void)
+void qe_reset(void)
 {
 	if (qe_immr == NULL)
 		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
@@ -317,16 +317,18 @@ EXPORT_SYMBOL(qe_put_snum);
 static int qe_sdma_init(void)
 {
 	struct sdma __iomem *sdma = &qe_immr->sdma;
-	unsigned long sdma_buf_offset;
+	static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
 
 	if (!sdma)
 		return -ENODEV;
 
 	/* allocate 2 internal temporary buffers (512 bytes size each) for
 	 * the SDMA */
- 	sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
-	if (IS_ERR_VALUE(sdma_buf_offset))
-		return -ENOMEM;
+	if (IS_ERR_VALUE(sdma_buf_offset)) {
+		sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
+		if (IS_ERR_VALUE(sdma_buf_offset))
+			return -ENOMEM;
+	}
 
 	out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
  	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
-- 
1.6.3.3




[-- Attachment #2: Type: text/html, Size: 5835 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* RE: [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-08-30 19:37 ` [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support Anton Vorontsov
@ 2009-08-31  0:38   ` Tabi Timur-B04825
  2009-08-31 18:47     ` Anton Vorontsov
  2009-09-14 17:28   ` Scott Wood
  1 sibling, 1 reply; 16+ messages in thread
From: Tabi Timur-B04825 @ 2009-08-31  0:38 UTC (permalink / raw)
  To: Anton Vorontsov, Kumar Gala; +Cc: Wood Scott-B07421, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 810 bytes --]


What about the 8610?

-----Original Message-----
From: Anton Vorontsov [mailto:avorontsov@ru.mvista.com]
Sent: Sun 8/30/2009 2:37 PM
To: Kumar Gala
Cc: Tabi Timur-B04825; Wood Scott-B07421; linuxppc-dev@ozlabs.org
Subject: [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support
 
This patch adds suspend/resume support for MPC8540, MPC8569 and
MPC8641D-compatible CPUs.

MPC8540 and MPC8641D-compatible PMCs are trivial: we just write
the SLP bit into the PM control and status register.

MPC8569 is a bit trickier, QE turns off during suspend, thus on
resume we must reload QE microcode and reset QE.

So far we don't support Deep Sleep mode as found in newer MPC85xx
CPUs (i.e. MPC8536). It can be relatively easy implemented though,
and for it we reserve 'mem' suspend type.




[-- Attachment #2: Type: text/html, Size: 1359 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation
  2009-08-31  0:36   ` Tabi Timur-B04825
@ 2009-08-31 18:47     ` Anton Vorontsov
  0 siblings, 0 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-31 18:47 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: Wood Scott-B07421, linuxppc-dev

On Sun, Aug 30, 2009 at 05:36:28PM -0700, Tabi Timur-B04825 wrote:
> Is the need to reinitialize the QE after resume something that
> is unique to the 8569, or would it apply to the 8360 and 8323 also?

8569 is unique in this regard, though I'm not sure if that's by design
or because of some errata.

Just as 8569 is unique that it needs QE microcode loaded externally
since the CPU doesn't have any ROM where the microcode can be stored.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-08-31  0:38   ` Tabi Timur-B04825
@ 2009-08-31 18:47     ` Anton Vorontsov
  0 siblings, 0 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-08-31 18:47 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: Wood Scott-B07421, linuxppc-dev

On Sun, Aug 30, 2009 at 05:38:05PM -0700, Tabi Timur-B04825 wrote:
> 
> What about the 8610?

Yes, it is supported. The bindings decribe that 8641d should
be used as a base match, so 8610-pmc is 8641d-compatible.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards
  2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
                   ` (4 preceding siblings ...)
  2009-08-30 19:37 ` [PATCH 5/5] powerpc/83xx: Add power management support for MPC83xx QE boards Anton Vorontsov
@ 2009-09-14 15:33 ` Anton Vorontsov
  2009-09-14 17:33   ` Scott Wood
  5 siblings, 1 reply; 16+ messages in thread
From: Anton Vorontsov @ 2009-09-14 15:33 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev, Timur Tabi

On Sun, Aug 30, 2009 at 11:36:25PM +0400, Anton Vorontsov wrote:
> On Fri, Aug 28, 2009 at 12:38:51AM -0500, Kumar Gala wrote:
> > >This patch adds suspend/resume support for MPC8540-compatible and
> > >MPC8569 CPUs.
> [...] 
> > I'd also like to get Scott's Ack on this and the device tree patches
> > before accepting them.
> 
> Heh, I didn't notice that the PMC bindings for 85xx describe devdisr
> registers (and thus sleep = <> properties).
> 
> So here are updated patches that should comply with the bindings.
> Plus,
> 
> - It appears that 86xx PMCs registers-compatible with 85xx, so we
>   can support both. Thus move 85xx/suspend.c to sysdev/fsl_pmc.c;
> - New patch that adds suspend/resume for MPC8610HPCD;
> - New patch that adds suspend/resume for 83xx QE boards;
> - Some fixes in "Make qe_reset() code path safe for repeated
>   invocation" patch.

Kumar,

Is there any issues with the patches? Can you merge them for 2.6.32?

Thanks!

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-08-30 19:37 ` [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support Anton Vorontsov
  2009-08-31  0:38   ` Tabi Timur-B04825
@ 2009-09-14 17:28   ` Scott Wood
  2009-09-14 20:20     ` [PATCH v3 " Anton Vorontsov
  1 sibling, 1 reply; 16+ messages in thread
From: Scott Wood @ 2009-09-14 17:28 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev, Timur Tabi

On Sun, Aug 30, 2009 at 11:37:18PM +0400, Anton Vorontsov wrote:
> This patch adds suspend/resume support for MPC8540, MPC8569 and
> MPC8641D-compatible CPUs.
> 
> MPC8540 and MPC8641D-compatible PMCs are trivial: we just write
> the SLP bit into the PM control and status register.
> 
> MPC8569 is a bit trickier, QE turns off during suspend, thus on
> resume we must reload QE microcode and reset QE.
> 
> So far we don't support Deep Sleep mode as found in newer MPC85xx
> CPUs (i.e. MPC8536). It can be relatively easy implemented though,
> and for it we reserve 'mem' suspend type.

We've got some code floating around here for that; it's just been falling
through the cracks as far as getting a chance to clean up and push
upstream.  Hopefully it'll happen soon.

> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
>  arch/powerpc/Kconfig          |   11 +++-
>  arch/powerpc/sysdev/Makefile  |    1 +
>  arch/powerpc/sysdev/fsl_pmc.c |  124 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 135 insertions(+), 1 deletions(-)
>  create mode 100644 arch/powerpc/sysdev/fsl_pmc.c
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index d00131c..a0743a7 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -212,7 +212,8 @@ config ARCH_HIBERNATION_POSSIBLE
>  
>  config ARCH_SUSPEND_POSSIBLE
>  	def_bool y
> -	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
> +	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
> +		   PPC_85xx || PPC_86xx

This isn't directed at this patch, but why do we need this list?  Can't
each platform figure out for itself whether it can actually register that
suspend_ops struct, just like any other driver?

>  config PPC_DCR_NATIVE
>  	bool
> @@ -642,6 +643,14 @@ config FSL_PCI
>  	select PPC_INDIRECT_PCI
>  	select PCI_QUIRKS
>  
> +config FSL_PMC
> +	bool
> +	default y
> +	depends on SUSPEND && (PPC_85xx || PPC_86xx)
> +	help
> +	  Freescale MPC85xx/MPC86xx power management controller support
> +	  (suspend/resume). For MPC83xx see platforms/83xx/suspend.c

I wish we had a better name for 85xx+86xx than "FSL". :-(

> +static int pmc_suspend_enter(suspend_state_t state)
> +{
> +	setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
> +	/* At this point, the CPU is asleep. */

I'm not sure that we're guaranteed that the sleep has taken effect
immediately -- we may need to do a loop waiting for it to clear (on
85xx), probably with some delays to give the bus a chance to become idle.

I'm not sure how much of that is necessary under certain conditions,
versus just paranoia, though.  Something like what you have here worked
well enough for us in testing -- but having that clear immediately after
makes me nervous.  At least a read-back seems appropriate (which I
suppose the clbits32 does, but I'd prefer something more explicit).

> +	/* For 86xx we need to clear the bit on resume, 85xx don't care. */
> +	clrbits32(&pmc_regs->pmcsr, PMCSR_SLP);

Hmm, how does this work?  Does it only enter sleep mode on the rising
edge of that bit?

The 8610 manual says that that bit should only be set as part of a
sequence also involving the use of MSR[POW] (section 23.5.1.4).

> +	if (pmc_qefw) {
> +		int ret;
> +
> +		ret = qe_upload_firmware(pmc_qefw);
> +		if (ret)
> +			dev_err(pmc_dev, "could not upload firmware\n");
> +
> +		qe_reset();
> +	}

Does this really belong here, or should the QE subsystem have a device
struct with suspend/resume ops?

-Scott

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards
  2009-09-14 15:33 ` [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
@ 2009-09-14 17:33   ` Scott Wood
  0 siblings, 0 replies; 16+ messages in thread
From: Scott Wood @ 2009-09-14 17:33 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev, Timur Tabi

On Mon, Sep 14, 2009 at 07:33:49PM +0400, Anton Vorontsov wrote:
> On Sun, Aug 30, 2009 at 11:36:25PM +0400, Anton Vorontsov wrote:
> > On Fri, Aug 28, 2009 at 12:38:51AM -0500, Kumar Gala wrote:
> > > >This patch adds suspend/resume support for MPC8540-compatible and
> > > >MPC8569 CPUs.
> > [...] 
> > > I'd also like to get Scott's Ack on this and the device tree patches
> > > before accepting them.

ACK the device tree stuff.

-Scott

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-09-14 17:28   ` Scott Wood
@ 2009-09-14 20:20     ` Anton Vorontsov
  2009-09-14 20:45       ` Scott Wood
  0 siblings, 1 reply; 16+ messages in thread
From: Anton Vorontsov @ 2009-09-14 20:20 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Timur Tabi

This patch adds suspend/resume support for MPC8540, MPC8569 and
MPC8641D-compatible CPUs.

MPC8540 and MPC8641D-compatible PMCs are trivial: we just write
the SLP bit into the PM control and status register.

MPC8569 is a bit trickier, QE turns off during suspend, thus on
resume we must reload QE microcode and reset QE.

So far we don't support Deep Sleep mode as found in newer MPC85xx
CPUs (i.e. MPC8536). It can be relatively easy implemented though,
and for it we reserve 'mem' suspend type.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---

On Mon, Sep 14, 2009 at 12:28:11PM -0500, Scott Wood wrote:
[...]
> > So far we don't support Deep Sleep mode as found in newer MPC85xx
> > CPUs (i.e. MPC8536). It can be relatively easy implemented though,
> > and for it we reserve 'mem' suspend type.
> 
> We've got some code floating around here for that; it's just been falling
> through the cracks as far as getting a chance to clean up and push
> upstream.  Hopefully it'll happen soon.

Nice.

[...]
> > +++ b/arch/powerpc/Kconfig
> > @@ -212,7 +212,8 @@ config ARCH_HIBERNATION_POSSIBLE
> >  
> >  config ARCH_SUSPEND_POSSIBLE
> >  	def_bool y
> > -	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
> > +	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
> > +		   PPC_85xx || PPC_86xx
> 
> This isn't directed at this patch, but why do we need this list?  Can't
> each platform figure out for itself whether it can actually register that
> suspend_ops struct, just like any other driver?

Good question. Disabling PM also makes some drivers less
tested, since there are a lot of #ifdef CONFIG_PM in the
drivers.

Though in this patch I'm just following current practice, if
a cleanup patch for all platforms is desired, I can readily
implement it.

[...]
> > +config FSL_PMC
> > +	bool
> > +	default y
> > +	depends on SUSPEND && (PPC_85xx || PPC_86xx)
> > +	help
> > +	  Freescale MPC85xx/MPC86xx power management controller support
> > +	  (suspend/resume). For MPC83xx see platforms/83xx/suspend.c
> 
> I wish we had a better name for 85xx+86xx than "FSL". :-(

Ditto. It took me quite some time to pick the name, couldn't find
anything better.

> > +static int pmc_suspend_enter(suspend_state_t state)
> > +{
> > +	setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
> > +	/* At this point, the CPU is asleep. */
> 
> I'm not sure that we're guaranteed that the sleep has taken effect
> immediately -- we may need to do a loop waiting for it to clear (on
> 85xx), probably with some delays to give the bus a chance to become idle.

Brilliant idea, thanks!

But it works vice versa: upon write, the code flow stops immediately
(on 85xx and 86xx), so there wouldn't any point in trying to readback
the pmcsr. But upon resume, on 86xx (and most probably on 85xx,
though we don't see it), the SLP bit doesn't clear immediately, we
have to wait for it. This eliminates the need for clearing the bit
for 86xx (i.e. the clearing operation worked as a small delay).

> I'm not sure how much of that is necessary under certain conditions,
> versus just paranoia, though.
> 
> Something like what you have here worked
> well enough for us in testing -- but having that clear immediately after
> makes me nervous.  At least a read-back seems appropriate (which I
> suppose the clbits32 does, but I'd prefer something more explicit).
> 
> > +	/* For 86xx we need to clear the bit on resume, 85xx don't care. */
> > +	clrbits32(&pmc_regs->pmcsr, PMCSR_SLP);
> 
> Hmm, how does this work?  Does it only enter sleep mode on the rising
> edge of that bit?

No, it appears it is the same as in 85xx, the bit clears by itself,
but we must wait for it. So your idea about looping and reading the
register actually eliminates the need for clrbits32(). Without the
clrbit32 (aka delay) or proper looping we would let device drivers
to resume too early, and things, obviously, didn't work.

> The 8610 manual says that that bit should only be set as part of a
> sequence also involving the use of MSR[POW] (section 23.5.1.4).

Well, 23.4.1.12 says:

| Sleep status
| 0 The device is not attempting to reach sleep mode.
| 1 The device is attempting to enter sleep mode because
| POWMGTCSR[SLP] is set, or HID0[SLEEP] and MSR[POW] in
                         ^^
| the e600 core are set. The core has halted fetching, snooping
| to the L1 and L2 caches is disabled, ....

The same in 85xx specs.

I can confirm this on real hw, after setting the SLP bit, the 8610
actually goes into sleep mode, no code flow happens until a wakeup
event. So playing with MSR[POW] doesn't seem to be necessary. The
same for 85xx.

> > +	if (pmc_qefw) {
> > +		int ret;
> > +
> > +		ret = qe_upload_firmware(pmc_qefw);
> > +		if (ret)
> > +			dev_err(pmc_dev, "could not upload firmware\n");
> > +
> > +		qe_reset();
> > +	}
> 
> Does this really belong here, or should the QE subsystem have a device
> struct with suspend/resume ops?

This exact snippet could be moved to the "qe" device driver, yes.
But I didn't bother because fsl_pmc have to request the QE firmware.

You can't request the firmware in the qe driver's ->suspend()
routine necause the firmware may be on e.g. NFS filesystem or USB
stick (implies having QE Ethernet or QE USB fully functional).

We can solve that by implementing ppc_md.suspend_prepare() (must
be called from userspace context), there we could request the
firmware. Then QE device driver would reload it in its resume()
callback. Needless to say that it makes things a bit more
complicated to follow.

The current code vanishes without QE anyway. But if you insist,
I can do the suspend_prepare() thing, although I'd prefer it as
a cleanup patch for 2.6.33, since it would touch more code,
specifically I'm concerned about ppc generic files.

How about this patch?

Thanks!

 arch/powerpc/Kconfig          |   11 +++-
 arch/powerpc/sysdev/Makefile  |    1 +
 arch/powerpc/sysdev/fsl_pmc.c |  131 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/sysdev/fsl_pmc.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d00131c..a0743a7 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -212,7 +212,8 @@ config ARCH_HIBERNATION_POSSIBLE
 
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
-	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
+	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
+		   PPC_85xx || PPC_86xx
 
 config PPC_DCR_NATIVE
 	bool
@@ -642,6 +643,14 @@ config FSL_PCI
 	select PPC_INDIRECT_PCI
 	select PCI_QUIRKS
 
+config FSL_PMC
+	bool
+	default y
+	depends on SUSPEND && (PPC_85xx || PPC_86xx)
+	help
+	  Freescale MPC85xx/MPC86xx power management controller support
+	  (suspend/resume). For MPC83xx see platforms/83xx/suspend.c
+
 config 4xx_SOC
 	bool
 
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 9d4b174..5642924 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_U3_DART)		+= dart_iommu.o
 obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
 obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_FSL_PCI)		+= fsl_pci.o $(fsl-msi-obj-y)
+obj-$(CONFIG_FSL_PMC)		+= fsl_pmc.o
 obj-$(CONFIG_FSL_LBC)		+= fsl_lbc.o
 obj-$(CONFIG_FSL_GTM)		+= fsl_gtm.o
 obj-$(CONFIG_MPC8xxx_GPIO)	+= mpc8xxx_gpio.o
diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c
new file mode 100644
index 0000000..916a21a
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_pmc.c
@@ -0,0 +1,131 @@
+/*
+ * Suspend/resume support
+ *
+ * Copyright © 2009  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/suspend.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/firmware.h>
+#include <asm/qe.h>
+
+struct pmc_regs {
+	__be32 devdisr;
+	__be32 devdisr2;
+	__be32 :32;
+	__be32 :32;
+	__be32 pmcsr;
+#define PMCSR_SLP	(1 << 17)
+};
+
+struct pmc_data {
+	unsigned int flags;
+#define PMC_NEED_QE_RELOAD (1 << 0)
+
+	const char *fw_name;
+};
+
+static struct device *pmc_dev;
+static struct pmc_regs __iomem *pmc_regs;
+static const struct pmc_data *pmc_data;
+static struct qe_firmware *pmc_qefw;
+
+static int pmc_suspend_enter(suspend_state_t state)
+{
+	int ret;
+
+	setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
+	/* At this point, the CPU is asleep. */
+
+	/* Upon resume, wait for SLP bit to be clear. */
+	ret = spin_event_timeout((in_be32(&pmc_regs->pmcsr) & PMCSR_SLP) == 0,
+				 10000, 10) ? 0 : -ETIMEDOUT;
+	if (ret)
+		dev_err(pmc_dev, "tired waiting for SLP bit to clear\n");
+
+	if (pmc_qefw) {
+		int ret;
+
+		ret = qe_upload_firmware(pmc_qefw);
+		if (ret)
+			dev_err(pmc_dev, "could not upload firmware\n");
+
+		qe_reset();
+	}
+	return ret;
+}
+
+static int pmc_suspend_valid(suspend_state_t state)
+{
+	if (state != PM_SUSPEND_STANDBY)
+		return 0;
+
+	if (pmc_data && pmc_data->flags & PMC_NEED_QE_RELOAD && !pmc_qefw) {
+		const struct firmware *fw;
+		int ret;
+
+		ret = request_firmware(&fw, pmc_data->fw_name, pmc_dev);
+		if (ret) {
+			dev_err(pmc_dev, "could not request firmware %s\n",
+				pmc_data->fw_name);
+			return 0;
+		}
+
+		pmc_qefw = (struct qe_firmware *)fw->data;
+	}
+
+	return 1;
+}
+
+static struct platform_suspend_ops pmc_suspend_ops = {
+	.valid = pmc_suspend_valid,
+	.enter = pmc_suspend_enter,
+};
+
+static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id)
+{
+	pmc_regs = of_iomap(ofdev->node, 0);
+	if (!pmc_regs)
+		return -ENOMEM;
+
+	pmc_dev = &ofdev->dev;
+	pmc_data = id->data;
+	suspend_set_ops(&pmc_suspend_ops);
+	return 0;
+}
+
+static struct pmc_data mpc8569_pmc_data = {
+	.flags = PMC_NEED_QE_RELOAD,
+	.fw_name = "fsl_qe_ucode_8569.bin",
+};
+
+static const struct of_device_id pmc_ids[] = {
+	{ .compatible = "fsl,mpc8569-pmc", .data = &mpc8569_pmc_data, },
+	{ .compatible = "fsl,mpc8548-pmc", },
+	{ .compatible = "fsl,mpc8641d-pmc", },
+	{ },
+};
+
+static struct of_platform_driver pmc_driver = {
+	.driver.name = "fsl-pmc",
+	.match_table = pmc_ids,
+	.probe = pmc_probe,
+};
+
+static int __init pmc_init(void)
+{
+	return of_register_platform_driver(&pmc_driver);
+}
+device_initcall(pmc_init);
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-09-14 20:20     ` [PATCH v3 " Anton Vorontsov
@ 2009-09-14 20:45       ` Scott Wood
  2009-09-14 21:47         ` Anton Vorontsov
  0 siblings, 1 reply; 16+ messages in thread
From: Scott Wood @ 2009-09-14 20:45 UTC (permalink / raw)
  To: avorontsov; +Cc: linuxppc-dev, Timur Tabi

Anton Vorontsov wrote:
> This patch adds suspend/resume support for MPC8540, MPC8569 and
> MPC8641D-compatible CPUs.
> 
> MPC8540 and MPC8641D-compatible PMCs are trivial: we just write
> the SLP bit into the PM control and status register.
> 
> MPC8569 is a bit trickier, QE turns off during suspend, thus on
> resume we must reload QE microcode and reset QE.
> 
> So far we don't support Deep Sleep mode as found in newer MPC85xx
> CPUs (i.e. MPC8536). It can be relatively easy implemented though,
> and for it we reserve 'mem' suspend type.
> 
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>

Acked-by: Scott Wood <scottwood@freescale.com>

>> I'm not sure that we're guaranteed that the sleep has taken effect
>> immediately -- we may need to do a loop waiting for it to clear (on
>> 85xx), probably with some delays to give the bus a chance to become idle.
> 
> Brilliant idea, thanks!
> 
> But it works vice versa: upon write, the code flow stops immediately
> (on 85xx and 86xx),

That's what I've observed as well; the question is whether it's always 
guaranteed to be immediate.

>> The 8610 manual says that that bit should only be set as part of a
>> sequence also involving the use of MSR[POW] (section 23.5.1.4).
> 
> Well, 23.4.1.12 says:
> 
> | Sleep status
> | 0 The device is not attempting to reach sleep mode.
> | 1 The device is attempting to enter sleep mode because
> | POWMGTCSR[SLP] is set, or HID0[SLEEP] and MSR[POW] in
>                          ^^
> | the e600 core are set. The core has halted fetching, snooping
> | to the L1 and L2 caches is disabled, ....
> 
> The same in 85xx specs.
> 
> I can confirm this on real hw, after setting the SLP bit, the 8610
> actually goes into sleep mode, no code flow happens until a wakeup
> event. So playing with MSR[POW] doesn't seem to be necessary. The
> same for 85xx.

OK, looks like section 23.5.1.4 is just bogus.

> This exact snippet could be moved to the "qe" device driver, yes.
> But I didn't bother because fsl_pmc have to request the QE firmware.
> 
> You can't request the firmware in the qe driver's ->suspend()
> routine necause the firmware may be on e.g. NFS filesystem or USB
> stick (implies having QE Ethernet or QE USB fully functional).

Is there any way for software to read out the current firmware from the 
device, or is it write-only?

> We can solve that by implementing ppc_md.suspend_prepare() (must
> be called from userspace context), there we could request the
> firmware. Then QE device driver would reload it in its resume()
> callback. Needless to say that it makes things a bit more
> complicated to follow.
> 
> The current code vanishes without QE anyway. But if you insist,
> I can do the suspend_prepare() thing, although I'd prefer it as
> a cleanup patch for 2.6.33, since it would touch more code,
> specifically I'm concerned about ppc generic files.

I don't insist, it just struck me as odd.

-Scott

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 2/5] powerpc/85xx/86xx: Add suspend/resume support
  2009-09-14 20:45       ` Scott Wood
@ 2009-09-14 21:47         ` Anton Vorontsov
  0 siblings, 0 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-09-14 21:47 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Timur Tabi

On Mon, Sep 14, 2009 at 03:45:10PM -0500, Scott Wood wrote:
[...]
> >You can't request the firmware in the qe driver's ->suspend()
> >routine necause the firmware may be on e.g. NFS filesystem or USB
> >stick (implies having QE Ethernet or QE USB fully functional).
> 
> Is there any way for software to read out the current firmware from
> the device, or is it write-only?

Hm, I didn't look into iram stuff that much, but seemingly I can
read it back and save. In the end, it's just a ram that we access
in a weird way... Let me try it.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2009-09-14 21:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-30 19:36 [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
2009-08-30 19:37 ` [PATCH 1/5] powerpc/qe: Make qe_reset() code path safe for repeated invocation Anton Vorontsov
2009-08-31  0:36   ` Tabi Timur-B04825
2009-08-31 18:47     ` Anton Vorontsov
2009-08-30 19:37 ` [PATCH 2/5] powerpc/85xx/86xx: Add suspend/resume support Anton Vorontsov
2009-08-31  0:38   ` Tabi Timur-B04825
2009-08-31 18:47     ` Anton Vorontsov
2009-09-14 17:28   ` Scott Wood
2009-09-14 20:20     ` [PATCH v3 " Anton Vorontsov
2009-09-14 20:45       ` Scott Wood
2009-09-14 21:47         ` Anton Vorontsov
2009-08-30 19:37 ` [PATCH 3/5] powerpc/85xx: Add power management support for MPC85xxMDS boards Anton Vorontsov
2009-08-30 19:37 ` [PATCH 4/5] powerpc/86xx: Add power management support for MPC8610HPCD boards Anton Vorontsov
2009-08-30 19:37 ` [PATCH 5/5] powerpc/83xx: Add power management support for MPC83xx QE boards Anton Vorontsov
2009-09-14 15:33 ` [PATCH v2 0/5] Suspend/resume support for some 83xx/85xx/86xx boards Anton Vorontsov
2009-09-14 17:33   ` Scott Wood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.