aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-2.6.27/boc01/014-090209-pm-wakeup.patch
blob: 3acbf40c32c439be0bab4131abcf00da9e0a22ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
Index: linux-2.6.27/arch/powerpc/platforms/83xx/Kconfig
===================================================================
--- linux-2.6.27.orig/arch/powerpc/platforms/83xx/Kconfig	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27/arch/powerpc/platforms/83xx/Kconfig	2009-01-23 10:54:03.000000000 +0100
@@ -104,6 +104,13 @@
 
 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	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27/arch/powerpc/platforms/83xx/Makefile	2009-01-23 10:54:03.000000000 +0100
@@ -14,3 +14,4 @@
 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	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.27/arch/powerpc/platforms/83xx/wakeup-it.c	2009-01-23 10:49:09.000000000 +0100
@@ -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);