@@ -220,7 +220,7 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
- (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \
+ FSL_SOC_BOOKE || PPC_86xx || PPC_PSERIES \
|| 44x || 40x
config PPC_DCR_NATIVE
@@ -694,7 +694,7 @@ config FSL_PCI
config FSL_PMC
bool
default y
- depends on SUSPEND && (PPC_85xx || PPC_86xx)
+ depends on SUSPEND && ((PPC_85xx && !PPC_E500MC) || PPC_86xx)
help
Freescale MPC85xx/MPC86xx power management controller support
(suspend/resume). For MPC83xx see platforms/83xx/suspend.c
@@ -124,6 +124,7 @@ struct ccsr_rcpm {
u8 res0038[4];
__be32 cwdtdsr; /* 0x003c - Core watchdog detect status register */
__be32 powmgtcsr; /* 0x0040 - Power Mangement Control & Status Register */
+#define RCPM_POWMGTCSR_SLP 0x00020000
u8 res0044[12];
__be32 ippdexpcr; /* 0x0050 - IP Powerdown Exception Control Register */
u8 res0054[16];
@@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE
select FSL_PCI if PCI
select SERIAL_8250_EXTENDED if SERIAL_8250
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
+ select FSL_CORENET_RCPM if SUSPEND && PPC_E500MC
default y
if FSL_SOC_BOOKE
@@ -33,3 +33,8 @@ config SCOM_DEBUGFS
config GE_FPGA
bool
default n
+
+config FSL_CORENET_RCPM
+ bool
+ help
+ This option enables support for RCPM (Run Control/Power Management).
@@ -18,6 +18,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o
obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
+obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
new file mode 100644
@@ -0,0 +1,101 @@
+/*
+ * RCPM(Run Control/Power Management) support
+ *
+ * Copyright 2012-2013 Freescale Semiconductor Inc.
+ *
+ * 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/types.h>
+#include <linux/errno.h>
+#include <linux/suspend.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/of_platform.h>
+
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/fsl_guts.h>
+
+static struct ccsr_rcpm __iomem *rcpm_regs;
+
+static int rcpm_suspend_enter(suspend_state_t state)
+{
+ int ret = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+
+ flush_dcache_L1();
+ flush_backside_L2_cache();
+
+ setbits32(&rcpm_regs->powmgtcsr, RCPM_POWMGTCSR_SLP);
+
+ /* At this point, the device is in sleep mode. */
+
+ /* Upon resume, wait for SLP bit to be clear. */
+ ret = spin_event_timeout(
+ (in_be32(&rcpm_regs->powmgtcsr) & RCPM_POWMGTCSR_SLP) == 0,
+ 10000, 10);
+ if (!ret) {
+ pr_err("%s: timeout waiting for SLP bit to be cleared\n",
+ __func__);
+ ret = -EINVAL;
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+
+ }
+ return ret;
+}
+
+static int rcpm_suspend_valid(suspend_state_t state)
+{
+ if (state == PM_SUSPEND_STANDBY)
+ return 1;
+ else
+ return 0;
+}
+
+static const struct platform_suspend_ops rcpm_suspend_ops = {
+ .valid = rcpm_suspend_valid,
+ .enter = rcpm_suspend_enter,
+};
+
+static int rcpm_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+
+ rcpm_regs = of_iomap(np, 0);
+ if (!rcpm_regs)
+ return -ENOMEM;
+
+ suspend_set_ops(&rcpm_suspend_ops);
+
+ dev_info(&pdev->dev, "Freescale RCPM driver\n");
+ return 0;
+}
+
+static const struct of_device_id rcpm_ids[] = {
+ { .compatible = "fsl,qoriq-rcpm-1.0", },
+ { },
+};
+
+static struct platform_driver rcpm_driver = {
+ .driver = {
+ .name = "fsl-rcpm",
+ .of_match_table = rcpm_ids,
+ },
+ .probe = rcpm_probe,
+};
+
+static int __init rcpm_init(void)
+{
+ return platform_driver_register(&rcpm_driver);
+}
+
+device_initcall(rcpm_init);