diff options
Diffstat (limited to 'packages/linux/linux-2.6.27/boc01/014-090115-pm-wakeup.patch')
-rw-r--r-- | packages/linux/linux-2.6.27/boc01/014-090115-pm-wakeup.patch | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/packages/linux/linux-2.6.27/boc01/014-090115-pm-wakeup.patch b/packages/linux/linux-2.6.27/boc01/014-090115-pm-wakeup.patch new file mode 100644 index 0000000000..536a788ffc --- /dev/null +++ b/packages/linux/linux-2.6.27/boc01/014-090115-pm-wakeup.patch @@ -0,0 +1,195 @@ +Index: linux-2.6.27/arch/powerpc/platforms/83xx/Kconfig +=================================================================== +--- linux-2.6.27.orig/arch/powerpc/platforms/83xx/Kconfig ++++ linux-2.6.27/arch/powerpc/platforms/83xx/Kconfig +@@ -104,6 +104,13 @@ config ASP834x + + endif + ++ ++config WAKEUP_IT ++ tristate "83xx interrupt for PM wakeup" ++ help ++ This enables a driver to be used as a wakeup source . ++ ++ + # used for usb + config PPC_MPC831x + bool +Index: linux-2.6.27/arch/powerpc/platforms/83xx/Makefile +=================================================================== +--- linux-2.6.27.orig/arch/powerpc/platforms/83xx/Makefile ++++ linux-2.6.27/arch/powerpc/platforms/83xx/Makefile +@@ -14,3 +14,4 @@ obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds + obj-$(CONFIG_SBC834x) += sbc834x.o + obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o + obj-$(CONFIG_ASP834x) += asp834x.o ++obj-$(CONFIG_WAKEUP_IT) += wakeup-it.o +Index: linux-2.6.27/arch/powerpc/platforms/83xx/wakeup-it.c +=================================================================== +--- /dev/null ++++ linux-2.6.27/arch/powerpc/platforms/83xx/wakeup-it.c +@@ -0,0 +1,163 @@ ++/* ++ * This support a driver to be used as a wakeup source on the MPC8313. ++ * ++ * Copyright (c) 2008 Cenosys ++ * ++ * Alexandre Coffignal <alexandre.coffignal@censoys.com> ++ * Sylvain Giroudon <sylvain.giroudon@goobie.fr> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/interrupt.h> ++#include <linux/of_platform.h> ++#include <linux/reboot.h> ++#include <linux/irq.h> ++ ++#include <sysdev/fsl_soc.h> ++ ++#define DRIVER_NAME "wakeup-it" ++ ++char suspend = 0; ++ ++static char *wakeup_irq_ids[] = { ++ "capsense", ++ "rfid", ++}; ++ ++struct wakeup_priv { ++ int nirq; ++ int irq[ARRAY_SIZE(wakeup_irq_ids)]; ++ spinlock_t lock; ++}; ++ ++struct wakeup_irq_desc { ++ char *name; ++ int index; ++}; ++ ++static irqreturn_t wakeup(int irq, void *dev_id) ++{ ++ //printk(KERN_INFO "===== WAKEUP INTERRUPT %d !!\n", irq); ++ ++ if ( suspend ) ++ kernel_restart(NULL); ++ return IRQ_HANDLED ; ++} ++ ++ ++static void wakeup_free(struct wakeup_priv *priv) ++{ ++ int i; ++ ++ for (i = 0; i < priv->nirq; i++) { ++ free_irq(priv->irq[i], priv); ++ } ++ ++ kfree(priv); ++} ++ ++ ++static int __devinit wakeup_probe(struct of_device *dev, const struct of_device_id *match) ++{ ++ struct device_node *np = dev->node; ++ struct resource res; ++ int ret = 0; ++ struct wakeup_priv *priv; ++ int i; ++ ++ priv = kmalloc(sizeof(struct wakeup_priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->nirq = 0; ++ spin_lock_init(&priv->lock); ++ dev_set_drvdata(&dev->dev, priv); ++ ++ ret = of_address_to_resource(np, 0, &res); ++ if (ret) ++ goto out; ++ ++ for (i = 0; i < ARRAY_SIZE(wakeup_irq_ids); i++) { ++ char *id = wakeup_irq_ids[i]; ++ char it_name[32]; ++ int it_num; ++ ++ it_num = irq_of_parse_and_map(np, i); ++ if ( it_num == NO_IRQ ) { ++ dev_err(&dev->dev, DRIVER_NAME ": interrupt #%d (%s) does not exist in device tree.\n", i, id); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ set_irq_type(it_num, IRQ_TYPE_EDGE_FALLING); ++ ++ snprintf(it_name, sizeof(it_name), DRIVER_NAME ":%s", id); ++ ++ ret = request_irq(it_num, wakeup, 0, it_name, priv); ++ if ( ret ) { ++ printk(KERN_WARNING DRIVER_NAME ": cannot request interrupt %d (%s)\n", it_num, id); ++ goto out; ++ } ++ ++ printk(KERN_INFO DRIVER_NAME ": accepting wakeup event from %s (%d)\n", id, it_num); ++ ++ priv->irq[priv->nirq++] = it_num; ++ } ++ ++ return 0; ++ ++out: ++ wakeup_free(priv); ++ return ret; ++} ++ ++static int __devexit wakeup_remove(struct of_device *dev) ++{ ++ struct wakeup_priv *priv = dev_get_drvdata(&dev->dev); ++ wakeup_free(priv); ++ return 0; ++} ++ ++static struct of_device_id wakeup_match[] = { ++ { ++ .compatible = "fsl,wakeup-it", ++ }, ++ {}, ++}; ++ ++static int wakeup_suspend(struct of_device * dev, pm_message_t state) ++{ ++ int ret = 0; ++ printk(KERN_INFO DRIVER_NAME ": suspend\n"); ++ suspend=1; ++ return ret; ++} ++ ++ ++static struct of_platform_driver wakeup_driver = { ++ .name = DRIVER_NAME, ++ .match_table = wakeup_match, ++ .probe = wakeup_probe, ++ .suspend = wakeup_suspend, ++ .remove = __devexit_p(wakeup_remove) ++ ++}; ++ ++static int __init wakeup_init(void) ++{ ++ return of_register_platform_driver(&wakeup_driver); ++} ++ ++static void __exit wakeup_exit(void) ++{ ++ of_unregister_platform_driver(&wakeup_driver); ++} ++ ++module_init(wakeup_init); ++module_exit(wakeup_exit); |