On 03/08/2013 01:38:47 AM, Wang Dongsheng wrote:
The driver provides a way to wake up the system by the MPIC timer.

For example,
echo 5 > /sys/devices/system/mpic/timer_wakeup
echo standby > /sys/power/state

After 5 seconds the MPIC timer will generate an interrupt to wake up
the system.

Signed-off-by: Wang Dongsheng <dongsheng.w...@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.z...@freescale.com>
Signed-off-by: Li Yang <le...@freescale.com>

Does this work with deep sleep (echo mem > /sys/power/state on mpc8536, p1022, etc) or just regular sleep?

---
 arch/powerpc/platforms/Kconfig              |    9 ++
 arch/powerpc/sysdev/Makefile                |    1 +
arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c | 185 +++++++++++++++++++++++++++
 3 files changed, 195 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c

diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 5af04fa..487c37f 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -99,6 +99,15 @@ config MPIC_TIMER
          only tested on fsl chip, but it can potentially support
          other global timers complying to Open-PIC standard.

+config FSL_MPIC_TIMER_WAKEUP
+       tristate "Freescale MPIC global timer wakeup driver"
+       depends on FSL_SOC &&  MPIC_TIMER
+       default n
+       help
+         This is only for freescale powerpc platform.

This sentence is redundant... It already says "Freescale MPIC" in the name and depends on "FSL_SOC && MPIC_TIMER".

+static irqreturn_t fsl_mpic_timer_irq(int irq, void *dev_id)
+{
+       struct fsl_mpic_timer_wakeup *wakeup = dev_id;
+
+       schedule_work(&wakeup->free_work);
+       return IRQ_HANDLED;
+}

return wakeup->timer ? IRQ_HANDLED : IRQ_NONE;

+
+static ssize_t fsl_timer_wakeup_show(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct timeval interval;
+       int val = 0;
+
+       mutex_lock(&sysfs_lock);
+       if (fsl_wakeup->timer) {
+               mpic_get_remain_time(fsl_wakeup->timer, &interval);
+               val = interval.tv_sec + 1;
+       }
+       mutex_unlock(&sysfs_lock);
+
+       return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t fsl_timer_wakeup_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf,
+                               size_t count)
+{
+       struct timeval interval;
+       int ret;
+
+       interval.tv_usec = 0;
+       if (kstrtol(buf, 0, &interval.tv_sec))
+               return -EINVAL;

I don't think the buffer will NUL-terminated...  Ordinarily there'll be
an LF terminator, but you can't rely on that (many other sysfs attributes
seem to, though...).

+       mutex_lock(&sysfs_lock);
+
+       if (fsl_wakeup->timer && !interval.tv_sec) {
+               disable_irq_wake(fsl_wakeup->timer->irq);
+               mpic_free_timer(fsl_wakeup->timer);
+               fsl_wakeup->timer = NULL;
+               mutex_unlock(&sysfs_lock);
+
+               return count;
+       }
+
+       if (fsl_wakeup->timer) {
+               mutex_unlock(&sysfs_lock);
+               return -EBUSY;
+       }

So to change an already-set timer you have to set it to zero and then to
what you want?  Why not just do:

        if (fsl_wakeup->timer) {
                disable_irq_wake(...);
                mpic_free_timer(...);
                fsl_wakeup_timer = NULL;
        }

        if (!interval.tv_sec) {
                mutex_unlock(&sysfs_lock);
                return count;
        }

+       ret = subsys_system_register(&mpic_subsys, NULL);
+       if (ret)
+               goto err;

Maybe arch/powerpc/sysdev/mpic.c should be doing this?

+
+       for (i = 0; mpic_attributes[i]; i++) {
+               ret = device_create_file(mpic_subsys.dev_root,
+                                       mpic_attributes[i]);
+               if (ret)
+                       goto err2;
+       }

Is this code ever going to register more than one?

-Scott
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to