aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/armksyms.c2
-rw-r--r--arch/arm/kernel/arthur.c2
-rw-r--r--arch/arm/kernel/atags.c83
-rw-r--r--arch/arm/kernel/ecard.c13
-rw-r--r--arch/arm/kernel/ecard.h13
-rw-r--r--arch/arm/kernel/init_task.c1
-rw-r--r--arch/arm/kernel/stacktrace.c34
7 files changed, 93 insertions, 55 deletions
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index f73d62e8ab60..688b7b1ee416 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -179,3 +179,5 @@ EXPORT_SYMBOL(_find_next_zero_bit_be);
179EXPORT_SYMBOL(_find_first_bit_be); 179EXPORT_SYMBOL(_find_first_bit_be);
180EXPORT_SYMBOL(_find_next_bit_be); 180EXPORT_SYMBOL(_find_next_bit_be);
181#endif 181#endif
182
183EXPORT_SYMBOL(copy_page);
diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
index 0ee2e9819631..321c5291d05f 100644
--- a/arch/arm/kernel/arthur.c
+++ b/arch/arm/kernel/arthur.c
@@ -90,3 +90,5 @@ static void __exit arthur_exit(void)
90 90
91module_init(arthur_init); 91module_init(arthur_init);
92module_exit(arthur_exit); 92module_exit(arthur_exit);
93
94MODULE_LICENSE("GPL");
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
index 64c420805e6f..42a1a1415fa6 100644
--- a/arch/arm/kernel/atags.c
+++ b/arch/arm/kernel/atags.c
@@ -1,5 +1,4 @@
1#include <linux/slab.h> 1#include <linux/slab.h>
2#include <linux/kexec.h>
3#include <linux/proc_fs.h> 2#include <linux/proc_fs.h>
4#include <asm/setup.h> 3#include <asm/setup.h>
5#include <asm/types.h> 4#include <asm/types.h>
@@ -7,9 +6,8 @@
7 6
8struct buffer { 7struct buffer {
9 size_t size; 8 size_t size;
10 char *data; 9 char data[];
11}; 10};
12static struct buffer tags_buffer;
13 11
14static int 12static int
15read_buffer(char* page, char** start, off_t off, int count, 13read_buffer(char* page, char** start, off_t off, int count,
@@ -29,58 +27,57 @@ read_buffer(char* page, char** start, off_t off, int count,
29 return count; 27 return count;
30} 28}
31 29
32 30#define BOOT_PARAMS_SIZE 1536
33static int 31static char __initdata atags_copy[BOOT_PARAMS_SIZE];
34create_proc_entries(void)
35{
36 struct proc_dir_entry* tags_entry;
37
38 tags_entry = create_proc_read_entry("atags", 0400, NULL, read_buffer, &tags_buffer);
39 if (!tags_entry)
40 return -ENOMEM;
41
42 return 0;
43}
44
45
46static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE];
47static char __initdata *atags_copy;
48 32
49void __init save_atags(const struct tag *tags) 33void __init save_atags(const struct tag *tags)
50{ 34{
51 atags_copy = atags_copy_buf; 35 memcpy(atags_copy, tags, sizeof(atags_copy));
52 memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE);
53} 36}
54 37
55
56static int __init init_atags_procfs(void) 38static int __init init_atags_procfs(void)
57{ 39{
58 struct tag *tag; 40 /*
59 int error; 41 * This cannot go into save_atags() because kmalloc and proc don't work
42 * yet when it is called.
43 */
44 struct proc_dir_entry *tags_entry;
45 struct tag *tag = (struct tag *)atags_copy;
46 struct buffer *b;
47 size_t size;
60 48
61 if (!atags_copy) { 49 if (tag->hdr.tag != ATAG_CORE) {
62 printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n"); 50 printk(KERN_INFO "No ATAGs?");
63 return -EIO; 51 return -EINVAL;
64 } 52 }
65 53
66 for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag)) 54 for (; tag->hdr.size; tag = tag_next(tag))
67 ; 55 ;
68 56
69 tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr); 57 /* include the terminating ATAG_NONE */
70 tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL); 58 size = (char *)tag - atags_copy + sizeof(struct tag_header);
71 if (tags_buffer.data == NULL)
72 return -ENOMEM;
73 memcpy(tags_buffer.data, atags_copy, tags_buffer.size);
74
75 error = create_proc_entries();
76 if (error) {
77 printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
78 kfree(tags_buffer.data);
79 tags_buffer.size = 0;
80 tags_buffer.data = NULL;
81 }
82 59
83 return error; 60 WARN_ON(tag->hdr.tag != ATAG_NONE);
84} 61
62 b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
63 if (!b)
64 goto nomem;
85 65
66 b->size = size;
67 memcpy(b->data, atags_copy, size);
68
69 tags_entry = create_proc_read_entry("atags", 0400,
70 NULL, read_buffer, b);
71
72 if (!tags_entry)
73 goto nomem;
74
75 return 0;
76
77nomem:
78 kfree(b);
79 printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
80
81 return -ENOMEM;
82}
86arch_initcall(init_atags_procfs); 83arch_initcall(init_atags_procfs);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index a53c0aba5c14..8bfd299bfe77 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -680,7 +680,7 @@ static int __init ecard_probeirqhw(void)
680#define IO_EC_MEMC8_BASE 0 680#define IO_EC_MEMC8_BASE 0
681#endif 681#endif
682 682
683unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) 683static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
684{ 684{
685 unsigned long address = 0; 685 unsigned long address = 0;
686 int slot = ec->slot_no; 686 int slot = ec->slot_no;
@@ -1002,7 +1002,7 @@ ecard_probe(int slot, card_type_t type)
1002 } 1002 }
1003 1003
1004 rc = -ENODEV; 1004 rc = -ENODEV;
1005 if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0) 1005 if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0)
1006 goto nodev; 1006 goto nodev;
1007 1007
1008 cid.r_zero = 1; 1008 cid.r_zero = 1;
@@ -1141,10 +1141,10 @@ static int ecard_drv_probe(struct device *dev)
1141 1141
1142 id = ecard_match_device(drv->id_table, ec); 1142 id = ecard_match_device(drv->id_table, ec);
1143 1143
1144 ecard_claim(ec); 1144 ec->claimed = 1;
1145 ret = drv->probe(ec, id); 1145 ret = drv->probe(ec, id);
1146 if (ret) 1146 if (ret)
1147 ecard_release(ec); 1147 ec->claimed = 0;
1148 return ret; 1148 return ret;
1149} 1149}
1150 1150
@@ -1154,7 +1154,7 @@ static int ecard_drv_remove(struct device *dev)
1154 struct ecard_driver *drv = ECARD_DRV(dev->driver); 1154 struct ecard_driver *drv = ECARD_DRV(dev->driver);
1155 1155
1156 drv->remove(ec); 1156 drv->remove(ec);
1157 ecard_release(ec); 1157 ec->claimed = 0;
1158 1158
1159 /* 1159 /*
1160 * Restore the default operations. We ensure that the 1160 * Restore the default operations. We ensure that the
@@ -1182,7 +1182,7 @@ static void ecard_drv_shutdown(struct device *dev)
1182 if (dev->driver) { 1182 if (dev->driver) {
1183 if (drv->shutdown) 1183 if (drv->shutdown)
1184 drv->shutdown(ec); 1184 drv->shutdown(ec);
1185 ecard_release(ec); 1185 ec->claimed = 0;
1186 } 1186 }
1187 1187
1188 /* 1188 /*
@@ -1239,7 +1239,6 @@ static int ecard_bus_init(void)
1239postcore_initcall(ecard_bus_init); 1239postcore_initcall(ecard_bus_init);
1240 1240
1241EXPORT_SYMBOL(ecard_readchunk); 1241EXPORT_SYMBOL(ecard_readchunk);
1242EXPORT_SYMBOL(__ecard_address);
1243EXPORT_SYMBOL(ecard_register_driver); 1242EXPORT_SYMBOL(ecard_register_driver);
1244EXPORT_SYMBOL(ecard_remove_driver); 1243EXPORT_SYMBOL(ecard_remove_driver);
1245EXPORT_SYMBOL(ecard_bus_type); 1244EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h
index d7c2dacf935d..4642d436be2a 100644
--- a/arch/arm/kernel/ecard.h
+++ b/arch/arm/kernel/ecard.h
@@ -54,3 +54,16 @@ struct ex_chunk_dir {
54#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16)) 54#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
55#define c_start(x) ((x)->r_start) 55#define c_start(x) ((x)->r_start)
56}; 56};
57
58typedef enum ecard_type { /* Cards address space */
59 ECARD_IOC,
60 ECARD_MEMC,
61 ECARD_EASI
62} card_type_t;
63
64typedef enum { /* Speed for ECARD_IOC space */
65 ECARD_SLOW = 0,
66 ECARD_MEDIUM = 1,
67 ECARD_FAST = 2,
68 ECARD_SYNC = 3
69} card_speed_t;
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index bd4ef53bc6b9..8b8c9d38a761 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -13,7 +13,6 @@
13#include <asm/pgtable.h> 13#include <asm/pgtable.h>
14 14
15static struct fs_struct init_fs = INIT_FS; 15static struct fs_struct init_fs = INIT_FS;
16static struct files_struct init_files = INIT_FILES;
17static struct signal_struct init_signals = INIT_SIGNALS(init_signals); 16static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
18static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); 17static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
19struct mm_struct init_mm = INIT_MM(init_mm); 18struct mm_struct init_mm = INIT_MM(init_mm);
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index ae31deb2d065..90e0c35ae60d 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -36,6 +36,7 @@ EXPORT_SYMBOL(walk_stackframe);
36#ifdef CONFIG_STACKTRACE 36#ifdef CONFIG_STACKTRACE
37struct stack_trace_data { 37struct stack_trace_data {
38 struct stack_trace *trace; 38 struct stack_trace *trace;
39 unsigned int no_sched_functions;
39 unsigned int skip; 40 unsigned int skip;
40}; 41};
41 42
@@ -43,27 +44,52 @@ static int save_trace(struct stackframe *frame, void *d)
43{ 44{
44 struct stack_trace_data *data = d; 45 struct stack_trace_data *data = d;
45 struct stack_trace *trace = data->trace; 46 struct stack_trace *trace = data->trace;
47 unsigned long addr = frame->lr;
46 48
49 if (data->no_sched_functions && in_sched_functions(addr))
50 return 0;
47 if (data->skip) { 51 if (data->skip) {
48 data->skip--; 52 data->skip--;
49 return 0; 53 return 0;
50 } 54 }
51 55
52 trace->entries[trace->nr_entries++] = frame->lr; 56 trace->entries[trace->nr_entries++] = addr;
53 57
54 return trace->nr_entries >= trace->max_entries; 58 return trace->nr_entries >= trace->max_entries;
55} 59}
56 60
57void save_stack_trace(struct stack_trace *trace) 61void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
58{ 62{
59 struct stack_trace_data data; 63 struct stack_trace_data data;
60 unsigned long fp, base; 64 unsigned long fp, base;
61 65
62 data.trace = trace; 66 data.trace = trace;
63 data.skip = trace->skip; 67 data.skip = trace->skip;
64 base = (unsigned long)task_stack_page(current); 68 base = (unsigned long)task_stack_page(tsk);
65 asm("mov %0, fp" : "=r" (fp)); 69
70 if (tsk != current) {
71#ifdef CONFIG_SMP
72 /*
73 * What guarantees do we have here that 'tsk'
74 * is not running on another CPU?
75 */
76 BUG();
77#else
78 data.no_sched_functions = 1;
79 fp = thread_saved_fp(tsk);
80#endif
81 } else {
82 data.no_sched_functions = 0;
83 asm("mov %0, fp" : "=r" (fp));
84 }
66 85
67 walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data); 86 walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
87 if (trace->nr_entries < trace->max_entries)
88 trace->entries[trace->nr_entries++] = ULONG_MAX;
89}
90
91void save_stack_trace(struct stack_trace *trace)
92{
93 save_stack_trace_tsk(current, trace);
68} 94}
69#endif 95#endif