aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ixp4xx/patches-2.6.23/017-nas100d_auto_power_on.patch
blob: 232dd9a8c570cdd06fb5760a45e98efc61514b72 (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
---
 arch/arm/mach-ixp4xx/nas100d-power.c  |   68 ++++++++++++++++++++++++++++++++--
 include/asm-arm/arch-ixp4xx/nas100d.h |   18 +++++----
 2 files changed, 75 insertions(+), 11 deletions(-)

Index: linux-2.6.22-rc5-armeb/arch/arm/mach-ixp4xx/nas100d-power.c
===================================================================
--- linux-2.6.22-rc5-armeb.orig/arch/arm/mach-ixp4xx/nas100d-power.c
+++ linux-2.6.22-rc5-armeb/arch/arm/mach-ixp4xx/nas100d-power.c
@@ -21,15 +21,60 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/reboot.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
 
 #include <asm/mach-types.h>
 
-static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
+extern void ctrl_alt_del(void);
+
+/* This is used to make sure the power-button pusher is serious.  The button
+ * must be held until the value of this counter reaches zero.
+ */
+static volatile int power_button_countdown;
+
+/* Must hold the button down for at least this many counts to be processed */
+#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
+
+static void nas100d_power_handler(unsigned long data);
+static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler, 0, 0);
+
+static void nas100d_power_handler(unsigned long data)
 {
-	/* Signal init to do the ctrlaltdel action, this will bypass init if
-	 * it hasn't started and do a kernel_restart.
+	/* This routine is called twice per second to check the
+	 * state of the power button.
 	 */
-	ctrl_alt_del();
+
+	if (*IXP4XX_GPIO_GPINR & NAS100D_PB_BM) {
+
+		/* IO Pin is 1 (button pushed) */
+		if (power_button_countdown > 0) {
+			power_button_countdown--;
+		}
+
+	} else {
+
+		/* Done on button release, to allow for auto-power-on mods. */
+		if (power_button_countdown == 0) {
+			/* Signal init to do the ctrlaltdel action, this will bypass
+			 * init if it hasn't started and do a kernel_restart.
+			 */
+			ctrl_alt_del();
+
+			/* Change the state of the power LED to "blink" */
+			gpio_line_set(NAS100D_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
+		} else {
+			power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+		}
+	}
+
+	mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
+{
+	/* This is the paper-clip reset, it shuts the machine down directly. */
+	machine_power_off();
 
 	return IRQ_HANDLED;
 }
@@ -50,6 +95,19 @@
 		return -EIO;
 	}
 
+	/* The power button on the Iomega NAS100d is on GPIO 14, but
+	 * it cannot handle interrupts on that GPIO line.  So we'll
+	 * have to poll it with a kernel timer.
+	 */
+
+	/* Make sure that the power button GPIO is set up as an input */
+	gpio_line_config(NAS100D_PB_GPIO, IXP4XX_GPIO_IN);
+
+	/* Set the initial value for the power button IRQ handler */
+	power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+
+	mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
+
 	return 0;
 }
 
@@ -58,6 +116,8 @@
 	if (!(machine_is_nas100d()))
 		return;
 
+	del_timer_sync(&nas100d_power_timer);
+
 	free_irq(NAS100D_RB_IRQ, NULL);
 }
 
Index: linux-2.6.22-rc5-armeb/include/asm-arm/arch-ixp4xx/nas100d.h
===================================================================
--- linux-2.6.22-rc5-armeb.orig/include/asm-arm/arch-ixp4xx/nas100d.h
+++ linux-2.6.22-rc5-armeb/include/asm-arm/arch-ixp4xx/nas100d.h
@@ -39,14 +39,18 @@
 /* Buttons */
 
 #define NAS100D_PB_GPIO         14
+#define NAS100D_PB_BM           (1L << NAS100D_PB_GPIO)
+
 #define NAS100D_RB_GPIO         4
-#define NAS100D_PO_GPIO         12   /* power off */
 
-#define NAS100D_PB_IRQ          IRQ_IXP4XX_GPIO14
 #define NAS100D_RB_IRQ          IRQ_IXP4XX_GPIO4
 
-/*
-#define NAS100D_PB_BM           (1L << NAS100D_PB_GPIO)
-#define NAS100D_PO_BM           (1L << NAS100D_PO_GPIO)
-#define NAS100D_RB_BM           (1L << NAS100D_RB_GPIO)
-*/
+#define NAS100D_PO_GPIO         12   /* power off */
+
+/* LEDs */
+
+#define NAS100D_LED_PWR_GPIO	15
+#define NAS100D_LED_PWR_BM	(1L << NAS100D_LED_PWR_GPIO)
+
+#define NAS100D_LED_WLAN_GPIO	0
+#define NAS100D_LED_WLAN_BM	(1L << NAS100D_LED_WLAN_GPIO)