aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-02-20 14:13:30 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-02-20 14:13:30 -0500
commit5a84d159061d914c8dd4aa372ac6e9529c2be453 (patch)
tree9b08af78085334af44414adafe0096276f8fe0ff /arch/arm
parente80a0e6e7ccdf64575d4384cb4172860422f5b81 (diff)
parent7d477a04a619e90ee08724e8f2d8803c6bdfcef8 (diff)
Merge ARM fixes
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig40
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/common/rtctime.c2
-rw-r--r--arch/arm/common/sharpsl_pm.c2
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/apm.c672
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/isa.c2
-rw-r--r--arch/arm/kernel/setup.c6
-rw-r--r--arch/arm/kernel/time.c10
-rw-r--r--arch/arm/kernel/vmlinux.lds.S2
-rw-r--r--arch/arm/mach-at91/clock.c2
-rw-r--r--arch/arm/mach-at91/gpio.c48
-rw-r--r--arch/arm/mach-imx/time.c2
-rw-r--r--arch/arm/mach-iop13xx/setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/common.c2
-rw-r--r--arch/arm/mach-netx/time.c2
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c2
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c2
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c2
-rw-r--r--arch/arm/mach-pxa/time.c2
-rw-r--r--arch/arm/mach-sa1100/jornada720.c6
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig1
24 files changed, 83 insertions, 733 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2c32c8702cfd..4409561ea32c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -9,6 +9,7 @@ config ARM
9 bool 9 bool
10 default y 10 default y
11 select RTC_LIB 11 select RTC_LIB
12 select SYS_SUPPORTS_APM_EMULATION
12 help 13 help
13 The ARM series is a line of low-power-consumption RISC chip designs 14 The ARM series is a line of low-power-consumption RISC chip designs
14 licensed by ARM Ltd and targeted at embedded applications and 15 licensed by ARM Ltd and targeted at embedded applications and
@@ -17,6 +18,9 @@ config ARM
17 Europe. There is an ARM Linux project with a web page at 18 Europe. There is an ARM Linux project with a web page at
18 <http://www.arm.linux.org.uk/>. 19 <http://www.arm.linux.org.uk/>.
19 20
21config SYS_SUPPORTS_APM_EMULATION
22 bool
23
20config GENERIC_TIME 24config GENERIC_TIME
21 bool 25 bool
22 default n 26 default n
@@ -25,6 +29,10 @@ config MMU
25 bool 29 bool
26 default y 30 default y
27 31
32config NO_IOPORT
33 bool
34 default n
35
28config EISA 36config EISA
29 bool 37 bool
30 ---help--- 38 ---help---
@@ -96,6 +104,10 @@ config GENERIC_BUST_SPINLOCK
96config ARCH_MAY_HAVE_PC_FDC 104config ARCH_MAY_HAVE_PC_FDC
97 bool 105 bool
98 106
107config ZONE_DMA
108 bool
109 default y
110
99config GENERIC_ISA_DMA 111config GENERIC_ISA_DMA
100 bool 112 bool
101 113
@@ -301,6 +313,7 @@ config ARCH_RPC
301 select TIMER_ACORN 313 select TIMER_ACORN
302 select ARCH_MAY_HAVE_PC_FDC 314 select ARCH_MAY_HAVE_PC_FDC
303 select ISA_DMA_API 315 select ISA_DMA_API
316 select NO_IOPORT
304 help 317 help
305 On the Acorn Risc-PC, Linux can support the internal IDE disk and 318 On the Acorn Risc-PC, Linux can support the internal IDE disk and
306 CD-ROM interface, serial and parallel port, and the floppy drive. 319 CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -414,7 +427,7 @@ source arch/arm/mm/Kconfig
414 427
415config IWMMXT 428config IWMMXT
416 bool "Enable iWMMXt support" 429 bool "Enable iWMMXt support"
417 depends CPU_XSCALE || CPU_XSC3 430 depends on CPU_XSCALE || CPU_XSC3
418 default y if PXA27x 431 default y if PXA27x
419 help 432 help
420 Enable support for iWMMXt context switching at run time if 433 Enable support for iWMMXt context switching at run time if
@@ -892,31 +905,6 @@ menu "Power management options"
892 905
893source "kernel/power/Kconfig" 906source "kernel/power/Kconfig"
894 907
895config APM
896 tristate "Advanced Power Management Emulation"
897 ---help---
898 APM is a BIOS specification for saving power using several different
899 techniques. This is mostly useful for battery powered laptops with
900 APM compliant BIOSes. If you say Y here, the system time will be
901 reset after a RESUME operation, the /proc/apm device will provide
902 battery status information, and user-space programs will receive
903 notification of APM "events" (e.g. battery status change).
904
905 In order to use APM, you will need supporting software. For location
906 and more information, read <file:Documentation/pm.txt> and the
907 Battery Powered Linux mini-HOWTO, available from
908 <http://www.tldp.org/docs.html#howto>.
909
910 This driver does not spin down disk drives (see the hdparm(8)
911 manpage ("man 8 hdparm") for that), and it doesn't turn off
912 VESA-compliant "green" monitors.
913
914 Generally, if you don't have a battery in your machine, there isn't
915 much point in using this driver and you should say N. If you get
916 random kernel OOPSes or reboots that don't seem to be related to
917 anything, try disabling/enabling this option (or disabling/enabling
918 APM in your BIOS).
919
920endmenu 908endmenu
921 909
922source "net/Kconfig" 910source "net/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1320418b5d6f..ab9f2d4bd04e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -124,7 +124,7 @@ endif
124 machine-$(CONFIG_ARCH_H720X) := h720x 124 machine-$(CONFIG_ARCH_H720X) := h720x
125 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 125 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
126 machine-$(CONFIG_ARCH_REALVIEW) := realview 126 machine-$(CONFIG_ARCH_REALVIEW) := realview
127 machine-$(CONFIG_ARCH_AT91) := at91rm9200 127 machine-$(CONFIG_ARCH_AT91) := at91
128 machine-$(CONFIG_ARCH_EP93XX) := ep93xx 128 machine-$(CONFIG_ARCH_EP93XX) := ep93xx
129 machine-$(CONFIG_ARCH_PNX4008) := pnx4008 129 machine-$(CONFIG_ARCH_PNX4008) := pnx4008
130 machine-$(CONFIG_ARCH_NETX) := netx 130 machine-$(CONFIG_ARCH_NETX) := netx
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index 4e5445cfb0ea..bf1075e1f571 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -329,7 +329,7 @@ static int rtc_fasync(int fd, struct file *file, int on)
329 return fasync_helper(fd, file, on, &rtc_async_queue); 329 return fasync_helper(fd, file, on, &rtc_async_queue);
330} 330}
331 331
332static struct file_operations rtc_fops = { 332static const struct file_operations rtc_fops = {
333 .owner = THIS_MODULE, 333 .owner = THIS_MODULE,
334 .llseek = no_llseek, 334 .llseek = no_llseek,
335 .read = rtc_read, 335 .read = rtc_read,
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index b3599743093b..a9bc5b52218f 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -23,11 +23,11 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/leds.h> 25#include <linux/leds.h>
26#include <linux/apm-emulation.h>
26 27
27#include <asm/hardware.h> 28#include <asm/hardware.h>
28#include <asm/mach-types.h> 29#include <asm/mach-types.h>
29#include <asm/irq.h> 30#include <asm/irq.h>
30#include <asm/apm.h>
31#include <asm/arch/pm.h> 31#include <asm/arch/pm.h>
32#include <asm/arch/pxa-regs.h> 32#include <asm/arch/pxa-regs.h>
33#include <asm/arch/sharpsl.h> 33#include <asm/arch/sharpsl.h>
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index d5002889773e..bb28087bf818 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,7 +10,6 @@ obj-y := compat.o entry-armv.o entry-common.o irq.o \
10 process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ 10 process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
11 time.o traps.o 11 time.o traps.o
12 12
13obj-$(CONFIG_APM) += apm.o
14obj-$(CONFIG_ISA_DMA_API) += dma.o 13obj-$(CONFIG_ISA_DMA_API) += dma.o
15obj-$(CONFIG_ARCH_ACORN) += ecard.o 14obj-$(CONFIG_ARCH_ACORN) += ecard.o
16obj-$(CONFIG_FIQ) += fiq.o 15obj-$(CONFIG_FIQ) += fiq.o
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
deleted file mode 100644
index 2c37b70b17ab..000000000000
--- a/arch/arm/kernel/apm.c
+++ /dev/null
@@ -1,672 +0,0 @@
1/*
2 * bios-less APM driver for ARM Linux
3 * Jamey Hicks <jamey@crl.dec.com>
4 * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com)
5 *
6 * APM 1.2 Reference:
7 * Intel Corporation, Microsoft Corporation. Advanced Power Management
8 * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
9 *
10 * [This document is available from Microsoft at:
11 * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
12 */
13#include <linux/module.h>
14#include <linux/poll.h>
15#include <linux/slab.h>
16#include <linux/proc_fs.h>
17#include <linux/miscdevice.h>
18#include <linux/apm_bios.h>
19#include <linux/capability.h>
20#include <linux/sched.h>
21#include <linux/pm.h>
22#include <linux/device.h>
23#include <linux/kernel.h>
24#include <linux/list.h>
25#include <linux/init.h>
26#include <linux/completion.h>
27#include <linux/kthread.h>
28#include <linux/delay.h>
29
30#include <asm/apm.h> /* apm_power_info */
31#include <asm/system.h>
32
33/*
34 * The apm_bios device is one of the misc char devices.
35 * This is its minor number.
36 */
37#define APM_MINOR_DEV 134
38
39/*
40 * See Documentation/Config.help for the configuration options.
41 *
42 * Various options can be changed at boot time as follows:
43 * (We allow underscores for compatibility with the modules code)
44 * apm=on/off enable/disable APM
45 */
46
47/*
48 * Maximum number of events stored
49 */
50#define APM_MAX_EVENTS 16
51
52struct apm_queue {
53 unsigned int event_head;
54 unsigned int event_tail;
55 apm_event_t events[APM_MAX_EVENTS];
56};
57
58/*
59 * The per-file APM data
60 */
61struct apm_user {
62 struct list_head list;
63
64 unsigned int suser: 1;
65 unsigned int writer: 1;
66 unsigned int reader: 1;
67
68 int suspend_result;
69 unsigned int suspend_state;
70#define SUSPEND_NONE 0 /* no suspend pending */
71#define SUSPEND_PENDING 1 /* suspend pending read */
72#define SUSPEND_READ 2 /* suspend read, pending ack */
73#define SUSPEND_ACKED 3 /* suspend acked */
74#define SUSPEND_WAIT 4 /* waiting for suspend */
75#define SUSPEND_DONE 5 /* suspend completed */
76
77 struct apm_queue queue;
78};
79
80/*
81 * Local variables
82 */
83static int suspends_pending;
84static int apm_disabled;
85static struct task_struct *kapmd_tsk;
86
87static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
88static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
89
90/*
91 * This is a list of everyone who has opened /dev/apm_bios
92 */
93static DECLARE_RWSEM(user_list_lock);
94static LIST_HEAD(apm_user_list);
95
96/*
97 * kapmd info. kapmd provides us a process context to handle
98 * "APM" events within - specifically necessary if we're going
99 * to be suspending the system.
100 */
101static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
102static DEFINE_SPINLOCK(kapmd_queue_lock);
103static struct apm_queue kapmd_queue;
104
105static DEFINE_MUTEX(state_lock);
106
107static const char driver_version[] = "1.13"; /* no spaces */
108
109
110
111/*
112 * Compatibility cruft until the IPAQ people move over to the new
113 * interface.
114 */
115static void __apm_get_power_status(struct apm_power_info *info)
116{
117}
118
119/*
120 * This allows machines to provide their own "apm get power status" function.
121 */
122void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status;
123EXPORT_SYMBOL(apm_get_power_status);
124
125
126/*
127 * APM event queue management.
128 */
129static inline int queue_empty(struct apm_queue *q)
130{
131 return q->event_head == q->event_tail;
132}
133
134static inline apm_event_t queue_get_event(struct apm_queue *q)
135{
136 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
137 return q->events[q->event_tail];
138}
139
140static void queue_add_event(struct apm_queue *q, apm_event_t event)
141{
142 q->event_head = (q->event_head + 1) % APM_MAX_EVENTS;
143 if (q->event_head == q->event_tail) {
144 static int notified;
145
146 if (notified++ == 0)
147 printk(KERN_ERR "apm: an event queue overflowed\n");
148 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
149 }
150 q->events[q->event_head] = event;
151}
152
153static void queue_event(apm_event_t event)
154{
155 struct apm_user *as;
156
157 down_read(&user_list_lock);
158 list_for_each_entry(as, &apm_user_list, list) {
159 if (as->reader)
160 queue_add_event(&as->queue, event);
161 }
162 up_read(&user_list_lock);
163 wake_up_interruptible(&apm_waitqueue);
164}
165
166/*
167 * queue_suspend_event - queue an APM suspend event.
168 *
169 * Check that we're in a state where we can suspend. If not,
170 * return -EBUSY. Otherwise, queue an event to all "writer"
171 * users. If there are no "writer" users, return '1' to
172 * indicate that we can immediately suspend.
173 */
174static int queue_suspend_event(apm_event_t event, struct apm_user *sender)
175{
176 struct apm_user *as;
177 int ret = 1;
178
179 mutex_lock(&state_lock);
180 down_read(&user_list_lock);
181
182 /*
183 * If a thread is still processing, we can't suspend, so reject
184 * the request.
185 */
186 list_for_each_entry(as, &apm_user_list, list) {
187 if (as != sender && as->reader && as->writer && as->suser &&
188 as->suspend_state != SUSPEND_NONE) {
189 ret = -EBUSY;
190 goto out;
191 }
192 }
193
194 list_for_each_entry(as, &apm_user_list, list) {
195 if (as != sender && as->reader && as->writer && as->suser) {
196 as->suspend_state = SUSPEND_PENDING;
197 suspends_pending++;
198 queue_add_event(&as->queue, event);
199 ret = 0;
200 }
201 }
202 out:
203 up_read(&user_list_lock);
204 mutex_unlock(&state_lock);
205 wake_up_interruptible(&apm_waitqueue);
206 return ret;
207}
208
209static void apm_suspend(void)
210{
211 struct apm_user *as;
212 int err = pm_suspend(PM_SUSPEND_MEM);
213
214 /*
215 * Anyone on the APM queues will think we're still suspended.
216 * Send a message so everyone knows we're now awake again.
217 */
218 queue_event(APM_NORMAL_RESUME);
219
220 /*
221 * Finally, wake up anyone who is sleeping on the suspend.
222 */
223 mutex_lock(&state_lock);
224 down_read(&user_list_lock);
225 list_for_each_entry(as, &apm_user_list, list) {
226 if (as->suspend_state == SUSPEND_WAIT ||
227 as->suspend_state == SUSPEND_ACKED) {
228 as->suspend_result = err;
229 as->suspend_state = SUSPEND_DONE;
230 }
231 }
232 up_read(&user_list_lock);
233 mutex_unlock(&state_lock);
234
235 wake_up(&apm_suspend_waitqueue);
236}
237
238static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
239{
240 struct apm_user *as = fp->private_data;
241 apm_event_t event;
242 int i = count, ret = 0;
243
244 if (count < sizeof(apm_event_t))
245 return -EINVAL;
246
247 if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK)
248 return -EAGAIN;
249
250 wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue));
251
252 while ((i >= sizeof(event)) && !queue_empty(&as->queue)) {
253 event = queue_get_event(&as->queue);
254
255 ret = -EFAULT;
256 if (copy_to_user(buf, &event, sizeof(event)))
257 break;
258
259 mutex_lock(&state_lock);
260 if (as->suspend_state == SUSPEND_PENDING &&
261 (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND))
262 as->suspend_state = SUSPEND_READ;
263 mutex_unlock(&state_lock);
264
265 buf += sizeof(event);
266 i -= sizeof(event);
267 }
268
269 if (i < count)
270 ret = count - i;
271
272 return ret;
273}
274
275static unsigned int apm_poll(struct file *fp, poll_table * wait)
276{
277 struct apm_user *as = fp->private_data;
278
279 poll_wait(fp, &apm_waitqueue, wait);
280 return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM;
281}
282
283/*
284 * apm_ioctl - handle APM ioctl
285 *
286 * APM_IOC_SUSPEND
287 * This IOCTL is overloaded, and performs two functions. It is used to:
288 * - initiate a suspend
289 * - acknowledge a suspend read from /dev/apm_bios.
290 * Only when everyone who has opened /dev/apm_bios with write permission
291 * has acknowledge does the actual suspend happen.
292 */
293static int
294apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
295{
296 struct apm_user *as = filp->private_data;
297 unsigned long flags;
298 int err = -EINVAL;
299
300 if (!as->suser || !as->writer)
301 return -EPERM;
302
303 switch (cmd) {
304 case APM_IOC_SUSPEND:
305 mutex_lock(&state_lock);
306
307 as->suspend_result = -EINTR;
308
309 if (as->suspend_state == SUSPEND_READ) {
310 int pending;
311
312 /*
313 * If we read a suspend command from /dev/apm_bios,
314 * then the corresponding APM_IOC_SUSPEND ioctl is
315 * interpreted as an acknowledge.
316 */
317 as->suspend_state = SUSPEND_ACKED;
318 suspends_pending--;
319 pending = suspends_pending == 0;
320 mutex_unlock(&state_lock);
321
322 /*
323 * If there are no further acknowledges required,
324 * suspend the system.
325 */
326 if (pending)
327 apm_suspend();
328
329 /*
330 * Wait for the suspend/resume to complete. If there
331 * are pending acknowledges, we wait here for them.
332 *
333 * Note: we need to ensure that the PM subsystem does
334 * not kick us out of the wait when it suspends the
335 * threads.
336 */
337 flags = current->flags;
338 current->flags |= PF_NOFREEZE;
339
340 wait_event(apm_suspend_waitqueue,
341 as->suspend_state == SUSPEND_DONE);
342 } else {
343 as->suspend_state = SUSPEND_WAIT;
344 mutex_unlock(&state_lock);
345
346 /*
347 * Otherwise it is a request to suspend the system.
348 * Queue an event for all readers, and expect an
349 * acknowledge from all writers who haven't already
350 * acknowledged.
351 */
352 err = queue_suspend_event(APM_USER_SUSPEND, as);
353 if (err < 0) {
354 /*
355 * Avoid taking the lock here - this
356 * should be fine.
357 */
358 as->suspend_state = SUSPEND_NONE;
359 break;
360 }
361
362 if (err > 0)
363 apm_suspend();
364
365 /*
366 * Wait for the suspend/resume to complete. If there
367 * are pending acknowledges, we wait here for them.
368 *
369 * Note: we need to ensure that the PM subsystem does
370 * not kick us out of the wait when it suspends the
371 * threads.
372 */
373 flags = current->flags;
374 current->flags |= PF_NOFREEZE;
375
376 wait_event_interruptible(apm_suspend_waitqueue,
377 as->suspend_state == SUSPEND_DONE);
378 }
379
380 current->flags = flags;
381
382 mutex_lock(&state_lock);
383 err = as->suspend_result;
384 as->suspend_state = SUSPEND_NONE;
385 mutex_unlock(&state_lock);
386 break;
387 }
388
389 return err;
390}
391
392static int apm_release(struct inode * inode, struct file * filp)
393{
394 struct apm_user *as = filp->private_data;
395 int pending = 0;
396
397 filp->private_data = NULL;
398
399 down_write(&user_list_lock);
400 list_del(&as->list);
401 up_write(&user_list_lock);
402
403 /*
404 * We are now unhooked from the chain. As far as new
405 * events are concerned, we no longer exist. However, we
406 * need to balance suspends_pending, which means the
407 * possibility of sleeping.
408 */
409 mutex_lock(&state_lock);
410 if (as->suspend_state != SUSPEND_NONE) {
411 suspends_pending -= 1;
412 pending = suspends_pending == 0;
413 }
414 mutex_unlock(&state_lock);
415 if (pending)
416 apm_suspend();
417
418 kfree(as);
419 return 0;
420}
421
422static int apm_open(struct inode * inode, struct file * filp)
423{
424 struct apm_user *as;
425
426 as = kzalloc(sizeof(*as), GFP_KERNEL);
427 if (as) {
428 /*
429 * XXX - this is a tiny bit broken, when we consider BSD
430 * process accounting. If the device is opened by root, we
431 * instantly flag that we used superuser privs. Who knows,
432 * we might close the device immediately without doing a
433 * privileged operation -- cevans
434 */
435 as->suser = capable(CAP_SYS_ADMIN);
436 as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
437 as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
438
439 down_write(&user_list_lock);
440 list_add(&as->list, &apm_user_list);
441 up_write(&user_list_lock);
442
443 filp->private_data = as;
444 }
445
446 return as ? 0 : -ENOMEM;
447}
448
449static struct file_operations apm_bios_fops = {
450 .owner = THIS_MODULE,
451 .read = apm_read,
452 .poll = apm_poll,
453 .ioctl = apm_ioctl,
454 .open = apm_open,
455 .release = apm_release,
456};
457
458static struct miscdevice apm_device = {
459 .minor = APM_MINOR_DEV,
460 .name = "apm_bios",
461 .fops = &apm_bios_fops
462};
463
464
465#ifdef CONFIG_PROC_FS
466/*
467 * Arguments, with symbols from linux/apm_bios.h.
468 *
469 * 0) Linux driver version (this will change if format changes)
470 * 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
471 * 2) APM flags from APM Installation Check (0x00):
472 * bit 0: APM_16_BIT_SUPPORT
473 * bit 1: APM_32_BIT_SUPPORT
474 * bit 2: APM_IDLE_SLOWS_CLOCK
475 * bit 3: APM_BIOS_DISABLED
476 * bit 4: APM_BIOS_DISENGAGED
477 * 3) AC line status
478 * 0x00: Off-line
479 * 0x01: On-line
480 * 0x02: On backup power (BIOS >= 1.1 only)
481 * 0xff: Unknown
482 * 4) Battery status
483 * 0x00: High
484 * 0x01: Low
485 * 0x02: Critical
486 * 0x03: Charging
487 * 0x04: Selected battery not present (BIOS >= 1.2 only)
488 * 0xff: Unknown
489 * 5) Battery flag
490 * bit 0: High
491 * bit 1: Low
492 * bit 2: Critical
493 * bit 3: Charging
494 * bit 7: No system battery
495 * 0xff: Unknown
496 * 6) Remaining battery life (percentage of charge):
497 * 0-100: valid
498 * -1: Unknown
499 * 7) Remaining battery life (time units):
500 * Number of remaining minutes or seconds
501 * -1: Unknown
502 * 8) min = minutes; sec = seconds
503 */
504static int apm_get_info(char *buf, char **start, off_t fpos, int length)
505{
506 struct apm_power_info info;
507 char *units;
508 int ret;
509
510 info.ac_line_status = 0xff;
511 info.battery_status = 0xff;
512 info.battery_flag = 0xff;
513 info.battery_life = -1;
514 info.time = -1;
515 info.units = -1;
516
517 if (apm_get_power_status)
518 apm_get_power_status(&info);
519
520 switch (info.units) {
521 default: units = "?"; break;
522 case 0: units = "min"; break;
523 case 1: units = "sec"; break;
524 }
525
526 ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
527 driver_version, APM_32_BIT_SUPPORT,
528 info.ac_line_status, info.battery_status,
529 info.battery_flag, info.battery_life,
530 info.time, units);
531
532 return ret;
533}
534#endif
535
536static int kapmd(void *arg)
537{
538 do {
539 apm_event_t event;
540 int ret;
541
542 wait_event_interruptible(kapmd_wait,
543 !queue_empty(&kapmd_queue) || kthread_should_stop());
544
545 if (kthread_should_stop())
546 break;
547
548 spin_lock_irq(&kapmd_queue_lock);
549 event = 0;
550 if (!queue_empty(&kapmd_queue))
551 event = queue_get_event(&kapmd_queue);
552 spin_unlock_irq(&kapmd_queue_lock);
553
554 switch (event) {
555 case 0:
556 break;
557
558 case APM_LOW_BATTERY:
559 case APM_POWER_STATUS_CHANGE:
560 queue_event(event);
561 break;
562
563 case APM_USER_SUSPEND:
564 case APM_SYS_SUSPEND:
565 ret = queue_suspend_event(event, NULL);
566 if (ret < 0) {
567 /*
568 * We were busy. Try again in 50ms.
569 */
570 queue_add_event(&kapmd_queue, event);
571 msleep(50);
572 }
573 if (ret > 0)
574 apm_suspend();
575 break;
576
577 case APM_CRITICAL_SUSPEND:
578 apm_suspend();
579 break;
580 }
581 } while (1);
582
583 return 0;
584}
585
586static int __init apm_init(void)
587{
588 int ret;
589
590 if (apm_disabled) {
591 printk(KERN_NOTICE "apm: disabled on user request.\n");
592 return -ENODEV;
593 }
594
595 kapmd_tsk = kthread_create(kapmd, NULL, "kapmd");
596 if (IS_ERR(kapmd_tsk)) {
597 ret = PTR_ERR(kapmd_tsk);
598 kapmd_tsk = NULL;
599 return ret;
600 }
601 kapmd_tsk->flags |= PF_NOFREEZE;
602 wake_up_process(kapmd_tsk);
603
604#ifdef CONFIG_PROC_FS
605 create_proc_info_entry("apm", 0, NULL, apm_get_info);
606#endif
607
608 ret = misc_register(&apm_device);
609 if (ret != 0) {
610 remove_proc_entry("apm", NULL);
611 kthread_stop(kapmd_tsk);
612 }
613
614 return ret;
615}
616
617static void __exit apm_exit(void)
618{
619 misc_deregister(&apm_device);
620 remove_proc_entry("apm", NULL);
621
622 kthread_stop(kapmd_tsk);
623}
624
625module_init(apm_init);
626module_exit(apm_exit);
627
628MODULE_AUTHOR("Stephen Rothwell");
629MODULE_DESCRIPTION("Advanced Power Management");
630MODULE_LICENSE("GPL");
631
632#ifndef MODULE
633static int __init apm_setup(char *str)
634{
635 while ((str != NULL) && (*str != '\0')) {
636 if (strncmp(str, "off", 3) == 0)
637 apm_disabled = 1;
638 if (strncmp(str, "on", 2) == 0)
639 apm_disabled = 0;
640 str = strchr(str, ',');
641 if (str != NULL)
642 str += strspn(str, ", \t");
643 }
644 return 1;
645}
646
647__setup("apm=", apm_setup);
648#endif
649
650/**
651 * apm_queue_event - queue an APM event for kapmd
652 * @event: APM event
653 *
654 * Queue an APM event for kapmd to process and ultimately take the
655 * appropriate action. Only a subset of events are handled:
656 * %APM_LOW_BATTERY
657 * %APM_POWER_STATUS_CHANGE
658 * %APM_USER_SUSPEND
659 * %APM_SYS_SUSPEND
660 * %APM_CRITICAL_SUSPEND
661 */
662void apm_queue_event(apm_event_t event)
663{
664 unsigned long flags;
665
666 spin_lock_irqsave(&kapmd_queue_lock, flags);
667 queue_add_event(&kapmd_queue, event);
668 spin_unlock_irqrestore(&kapmd_queue_lock, flags);
669
670 wake_up_interruptible(&kapmd_wait);
671}
672EXPORT_SYMBOL(apm_queue_event);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index ec01f08f5642..e101846ab7dd 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -159,8 +159,7 @@ void __init init_IRQ(void)
159 int irq; 159 int irq;
160 160
161 for (irq = 0; irq < NR_IRQS; irq++) 161 for (irq = 0; irq < NR_IRQS; irq++)
162 irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_DELAYED_DISABLE | 162 irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
163 IRQ_NOPROBE;
164 163
165#ifdef CONFIG_SMP 164#ifdef CONFIG_SMP
166 bad_irq_desc.affinity = CPU_MASK_ALL; 165 bad_irq_desc.affinity = CPU_MASK_ALL;
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 54bbd9fe255c..50a30bc91872 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -70,5 +70,5 @@ register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int por
70 isa_membase = membase; 70 isa_membase = membase;
71 isa_portbase = portbase; 71 isa_portbase = portbase;
72 isa_portshift = portshift; 72 isa_portshift = portshift;
73 isa_sysctl_header = register_sysctl_table(ctl_bus, 0); 73 isa_sysctl_header = register_sysctl_table(ctl_bus);
74} 74}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 243aea458057..03e37af315d7 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -109,7 +109,7 @@ unsigned long phys_initrd_size __initdata = 0;
109static struct meminfo meminfo __initdata = { 0, }; 109static struct meminfo meminfo __initdata = { 0, };
110static const char *cpu_name; 110static const char *cpu_name;
111static const char *machine_name; 111static const char *machine_name;
112static char command_line[COMMAND_LINE_SIZE]; 112static char __initdata command_line[COMMAND_LINE_SIZE];
113 113
114static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; 114static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
115static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; 115static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -806,8 +806,8 @@ void __init setup_arch(char **cmdline_p)
806 init_mm.end_data = (unsigned long) &_edata; 806 init_mm.end_data = (unsigned long) &_edata;
807 init_mm.brk = (unsigned long) &_end; 807 init_mm.brk = (unsigned long) &_end;
808 808
809 memcpy(saved_command_line, from, COMMAND_LINE_SIZE); 809 memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
810 saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; 810 boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
811 parse_cmdline(cmdline_p, from); 811 parse_cmdline(cmdline_p, from);
812 paging_init(&meminfo, mdesc); 812 paging_init(&meminfo, mdesc);
813 request_standard_resources(&meminfo, mdesc); 813 request_standard_resources(&meminfo, mdesc);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 3825acd6687d..f61decb89ba2 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -80,16 +80,6 @@ static unsigned long dummy_gettimeoffset(void)
80#endif 80#endif
81 81
82/* 82/*
83 * Scheduler clock - returns current time in nanosec units.
84 * This is the default implementation. Sub-architecture
85 * implementations can override this.
86 */
87unsigned long long __attribute__((weak)) sched_clock(void)
88{
89 return (unsigned long long)jiffies * (1000000000 / HZ);
90}
91
92/*
93 * An implementation of printk_clock() independent from 83 * An implementation of printk_clock() independent from
94 * sched_clock(). This avoids non-bootable kernels when 84 * sched_clock(). This avoids non-bootable kernels when
95 * printk_clock is enabled. 85 * printk_clock is enabled.
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a8fa75ea07a9..b929a60f7547 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -53,10 +53,12 @@ SECTIONS
53 __security_initcall_start = .; 53 __security_initcall_start = .;
54 *(.security_initcall.init) 54 *(.security_initcall.init)
55 __security_initcall_end = .; 55 __security_initcall_end = .;
56#ifdef CONFIG_BLK_DEV_INITRD
56 . = ALIGN(32); 57 . = ALIGN(32);
57 __initramfs_start = .; 58 __initramfs_start = .;
58 usr/built-in.o(.init.ramfs) 59 usr/built-in.o(.init.ramfs)
59 __initramfs_end = .; 60 __initramfs_end = .;
61#endif
60 . = ALIGN(64); 62 . = ALIGN(64);
61 __per_cpu_start = .; 63 __per_cpu_start = .;
62 *(.data.percpu) 64 *(.data.percpu)
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index f6cb74806043..06c9a0507d0d 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -407,7 +407,7 @@ static int at91_clk_open(struct inode *inode, struct file *file)
407 return single_open(file, at91_clk_show, NULL); 407 return single_open(file, at91_clk_show, NULL);
408} 408}
409 409
410static struct file_operations at91_clk_operations = { 410static const struct file_operations at91_clk_operations = {
411 .open = at91_clk_open, 411 .open = at91_clk_open,
412 .read = seq_read, 412 .read = seq_read,
413 .llseek = seq_lseek, 413 .llseek = seq_lseek,
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 9b7495cd555d..7b87f3f101b7 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -65,6 +65,24 @@ static inline unsigned pin_to_mask(unsigned pin)
65 65
66 66
67/* 67/*
68 * mux the pin to the "GPIO" peripheral role.
69 */
70int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup)
71{
72 void __iomem *pio = pin_to_controller(pin);
73 unsigned mask = pin_to_mask(pin);
74
75 if (!pio)
76 return -EINVAL;
77 __raw_writel(mask, pio + PIO_IDR);
78 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
79 __raw_writel(mask, pio + PIO_PER);
80 return 0;
81}
82EXPORT_SYMBOL(at91_set_GPIO_periph);
83
84
85/*
68 * mux the pin to the "A" internal peripheral role. 86 * mux the pin to the "A" internal peripheral role.
69 */ 87 */
70int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) 88int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup)
@@ -181,6 +199,36 @@ EXPORT_SYMBOL(at91_set_multi_drive);
181 199
182/*--------------------------------------------------------------------------*/ 200/*--------------------------------------------------------------------------*/
183 201
202/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been
203 * called, and maybe at91_set_multi_drive() for putout pins.
204 */
205
206int gpio_direction_input(unsigned pin)
207{
208 void __iomem *pio = pin_to_controller(pin);
209 unsigned mask = pin_to_mask(pin);
210
211 if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
212 return -EINVAL;
213 __raw_writel(mask, pio + PIO_OER);
214 return 0;
215}
216EXPORT_SYMBOL(gpio_direction_input);
217
218int gpio_direction_output(unsigned pin)
219{
220 void __iomem *pio = pin_to_controller(pin);
221 unsigned mask = pin_to_mask(pin);
222
223 if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
224 return -EINVAL;
225 __raw_writel(mask, pio + PIO_OER);
226 return 0;
227}
228EXPORT_SYMBOL(gpio_direction_output);
229
230/*--------------------------------------------------------------------------*/
231
184/* 232/*
185 * assuming the pin is muxed as a gpio output, set its value. 233 * assuming the pin is muxed as a gpio output, set its value.
186 */ 234 */
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 40039b2a90b3..2703a730baf7 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -87,7 +87,7 @@ static struct clocksource clocksource_imx = {
87 .read = imx_get_cycles, 87 .read = imx_get_cycles,
88 .mask = 0xFFFFFFFF, 88 .mask = 0xFFFFFFFF,
89 .shift = 20, 89 .shift = 20,
90 .is_continuous = 1, 90 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
91}; 91};
92 92
93static int __init imx_clocksource_init(void) 93static int __init imx_clocksource_init(void)
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
index 5fbeb28d04bb..9a46bcd5f18e 100644
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -24,6 +24,7 @@
24#include <asm/mach/map.h> 24#include <asm/mach/map.h>
25#include <asm/hardware.h> 25#include <asm/hardware.h>
26#include <asm/irq.h> 26#include <asm/irq.h>
27#include <asm/io.h>
27 28
28#define IOP13XX_UART_XTAL 33334000 29#define IOP13XX_UART_XTAL 33334000
29#define IOP13XX_SETUP_DEBUG 0 30#define IOP13XX_SETUP_DEBUG 0
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 2ec9a9e9a04d..45068c3d8dcc 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -395,7 +395,7 @@ static struct clocksource clocksource_ixp4xx = {
395 .read = ixp4xx_get_cycles, 395 .read = ixp4xx_get_cycles,
396 .mask = CLOCKSOURCE_MASK(32), 396 .mask = CLOCKSOURCE_MASK(32),
397 .shift = 20, 397 .shift = 20,
398 .is_continuous = 1, 398 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
399}; 399};
400 400
401unsigned long ixp4xx_timer_freq = FREQ; 401unsigned long ixp4xx_timer_freq = FREQ;
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 5773b55ef4a6..7e132fcccd47 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -62,7 +62,7 @@ static struct clocksource clocksource_netx = {
62 .read = netx_get_cycles, 62 .read = netx_get_cycles,
63 .mask = CLOCKSOURCE_MASK(32), 63 .mask = CLOCKSOURCE_MASK(32),
64 .shift = 20, 64 .shift = 20,
65 .is_continuous = 1, 65 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
66}; 66};
67 67
68/* 68/*
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index 4c3de4008a43..165017de8d0d 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -16,7 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <asm/apm.h> 19#include <asm/apm-emulation.h>
20#include <asm/irq.h> 20#include <asm/irq.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/hardware.h> 22#include <asm/hardware.h>
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index db6e8f56a75f..b1d8cfca245a 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -23,7 +23,7 @@
23 23
24#include <asm/hardware.h> 24#include <asm/hardware.h>
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26#include <asm/apm.h> 26#include <asm/apm-emulation.h>
27#include <asm/arch/pm.h> 27#include <asm/arch/pm.h>
28#include <asm/arch/pxa-regs.h> 28#include <asm/arch/pxa-regs.h>
29#include <asm/arch/sharpsl.h> 29#include <asm/arch/sharpsl.h>
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 40be833079c7..b97d543d9364 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -16,7 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <asm/apm.h> 19#include <asm/apm-emulation.h>
20#include <asm/irq.h> 20#include <asm/irq.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/hardware.h> 22#include <asm/hardware.h>
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index ee2beb400414..fc3b82a740a0 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -112,7 +112,7 @@ static struct clocksource clocksource_pxa = {
112 .read = pxa_get_cycles, 112 .read = pxa_get_cycles,
113 .mask = CLOCKSOURCE_MASK(32), 113 .mask = CLOCKSOURCE_MASK(32),
114 .shift = 20, 114 .shift = 20,
115 .is_continuous = 1, 115 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
116}; 116};
117 117
118static void __init pxa_timer_init(void) 118static void __init pxa_timer_init(void)
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 54ecdaa373d6..64067cd58d36 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -231,12 +231,6 @@ static struct platform_device *devices[] __initdata = {
231 &s1d13xxxfb_device, 231 &s1d13xxxfb_device,
232}; 232};
233 233
234/* a stub for now, we theoretically cannot suspend without a flashboard */
235int pm_suspend(suspend_state_t state)
236{
237 return -1;
238}
239
240static int __init jornada720_init(void) 234static int __init jornada720_init(void)
241{ 235{
242 int ret = -ENODEV; 236 int ret = -ENODEV;
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 4b277199d0e8..e684e9b38216 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -525,7 +525,7 @@ config CPU_BIG_ENDIAN
525 of your chipset/board/processor. 525 of your chipset/board/processor.
526 526
527config CPU_HIGH_VECTOR 527config CPU_HIGH_VECTOR
528 depends !MMU && CPU_CP15 && !CPU_ARM740T 528 depends on !MMU && CPU_CP15 && !CPU_ARM740T
529 bool "Select the High exception vector" 529 bool "Select the High exception vector"
530 default n 530 default n
531 help 531 help
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index e22343160634..860869528f4c 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -8,6 +8,7 @@ config PLAT_S3C24XX
8 bool 8 bool
9 depends on ARCH_S3C2410 9 depends on ARCH_S3C2410
10 default y if ARCH_S3C2410 10 default y if ARCH_S3C2410
11 select NO_IOPORT
11 help 12 help
12 Base platform code for any Samsung S3C device 13 Base platform code for any Samsung S3C device
13 14