[PATCH 1/3] Powerpc/4xx: Add suspend and idle support

Victor Gallardo vgallardo at apm.com
Sat Oct 9 04:32:19 EST 2010


On Fri, Oct 8, 2010 at 6:46 AM, Josh Boyer <jwboyer at linux.vnet.ibm.com> wrote:
> On Thu, Oct 07, 2010 at 12:07:16PM -0700, Victor Gallardo wrote:
>
> I hit send too soon on my earlier response.  My apologies.
>
>>--- /dev/null
>>+++ b/arch/powerpc/sysdev/ppc4xx_cpm.c
>>@@ -0,0 +1,339 @@
>>+/*
>>+ * PowerPC 4xx Clock and Power Management
>>+ *
>>+ * Copyright (C) 2010, Applied Micro Circuits Corporation
>>+ * Victor Gallardo (vgallardo at apm.com)
>>+ *
>>+ * Based on arch/powerpc/platforms/44x/idle.c:
>>+ * Jerone Young <jyoung5 at us.ibm.com>
>>+ * Copyright 2008 IBM Corp.
>>+ *
>>+ * Based on arch/powerpc/sysdev/fsl_pmc.c:
>>+ * Anton Vorontsov <avorontsov at ru.mvista.com>
>>+ * Copyright 2009  MontaVista Software, Inc.
>>+ *
>>+ * See file CREDITS for list of people who contributed to this
>>+ * project.
>>+ *
>>+ * 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.
>>+ *
>>+ * This program is distributed in the hope that it will be useful,
>>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>+ * GNU General Public License for more details.
>>+ *
>>+ * You should have received a copy of the GNU General Public License
>>+ * along with this program; if not, write to the Free Software
>>+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>>+ * MA 02111-1307 USA
>>+ */
>>+
>>+#include <linux/kernel.h>
>>+#include <linux/of_platform.h>
>>+#include <linux/sysfs.h>
>>+#include <linux/cpu.h>
>>+#include <linux/suspend.h>
>>+#include <asm/dcr.h>
>>+#include <asm/dcr-native.h>
>>+#include <asm/machdep.h>
>>+
>>+#define CPM_ER        0
>>+#define CPM_FR        1
>>+#define CPM_SR        2
>>+
>>+#define CPM_IDLE_WAIT 0
>>+#define CPM_IDLE_DOZE 1
>>+
>>+struct cpm {
>>+      dcr_host_t      dcr_host;
>>+      unsigned int    dcr_offset[3];
>>+      unsigned int    powersave_off;
>>+      unsigned int    unused;
>>+      unsigned int    idle_doze;
>>+      unsigned int    standby;
>>+      unsigned int    suspend;
>>+};
>>+
>>+static struct cpm cpm;
>>+
>>+struct cpm_idle_mode {
>>+      unsigned int enabled;
>>+      const char  *name;
>>+};
>>+
>>+static struct cpm_idle_mode idle_mode[] = {
>>+      [CPM_IDLE_WAIT] = { 1, "wait" }, /* default */
>>+      [CPM_IDLE_DOZE] = { 0, "doze" },
>>+};
>>+
>>+static void cpm_set(unsigned int cpm_reg, unsigned int mask)
>>+{
>>+      unsigned int value;
>>+
>>+      value = dcr_read(cpm.dcr_host, cpm.dcr_offset[cpm_reg]);
>>+      value |= mask;
>>+      dcr_write(cpm.dcr_host, cpm.dcr_offset[cpm_reg], value);
>>+}
>
> This doesn't seem to do any sort of verification that the class 2 and
> class 3 devices actually got disabled.  Or at least I don't see where we
> verify anything in the SR.
>
> Maybe in practice it doesn't matter, but we should add a comment that say
> we just expect them to eventually go off when they can.
>
Yes, you are correct. I will add a comment here.

>>+
>>+static void cpm_idle_wait(void)
>>+{
>>+      unsigned long msr_save;
>>+
>>+      /* save off initial state */
>>+      msr_save = mfmsr();
>>+      /* sync required when CPM0_ER[CPU] is set */
>>+      mb();
>>+      /* set wait state MSR */
>>+      mtmsr(msr_save|MSR_WE|MSR_EE|MSR_CE|MSR_DE);
>>+      isync();
>>+      /* return to initial state */
>>+      mtmsr(msr_save);
>>+      isync();
>>+}
>>+
>>+static void cpm_idle_sleep(unsigned int mask)
>>+{
>>+      unsigned int er_save;
>>+
>>+      /* update CPM_ER state */
>>+      er_save = dcr_read(cpm.dcr_host, cpm.dcr_offset[CPM_ER]);
>>+      dcr_write(cpm.dcr_host, cpm.dcr_offset[CPM_ER],
>>+                er_save | mask);
>>+
>>+      /* go to wait state */
>>+      cpm_idle_wait();
>>+
>>+      /* restore CPM_ER state */
>>+      dcr_write(cpm.dcr_host, cpm.dcr_offset[CPM_ER], er_save);
>>+}
>
> For my clarification, the CPU is a class 2 device and we expect that the
> logic between the CPU and the CPM allows us to do the write to make it
> sleep, but not actually sleep until we set the idle state?
>

Yes, you are correct again. I will add another comment here to a little
more clear.

> josh
>


More information about the Linuxppc-dev mailing list