aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig64
-rw-r--r--arch/sparc/kernel/Makefile1
-rw-r--r--arch/sparc/kernel/cpu.c4
-rw-r--r--arch/sparc/kernel/ioport.c2
-rw-r--r--arch/sparc/kernel/led.c139
-rw-r--r--arch/sparc/kernel/pcic.c6
-rw-r--r--arch/sparc/kernel/process.c35
-rw-r--r--arch/sparc/kernel/setup.c2
-rw-r--r--arch/sparc/kernel/sunos_ioctl.c1
-rw-r--r--arch/sparc/kernel/time.c6
-rw-r--r--arch/sparc/lib/atomic32.c34
-rw-r--r--arch/sparc/lib/bitext.c1
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc/mm/generic.c15
-rw-r--r--arch/sparc/mm/srmmu.c2
15 files changed, 212 insertions, 102 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index aba05394d30a..3cfb8be3ff6d 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -25,62 +25,6 @@ source "init/Kconfig"
25 25
26menu "General machine setup" 26menu "General machine setup"
27 27
28config VT
29 bool
30 select INPUT
31 default y
32 ---help---
33 If you say Y here, you will get support for terminal devices with
34 display and keyboard devices. These are called "virtual" because you
35 can run several virtual terminals (also called virtual consoles) on
36 one physical terminal. This is rather useful, for example one
37 virtual terminal can collect system messages and warnings, another
38 one can be used for a text-mode user session, and a third could run
39 an X session, all in parallel. Switching between virtual terminals
40 is done with certain key combinations, usually Alt-<function key>.
41
42 The setterm command ("man setterm") can be used to change the
43 properties (such as colors or beeping) of a virtual terminal. The
44 man page console_codes(4) ("man console_codes") contains the special
45 character sequences that can be used to change those properties
46 directly. The fonts used on virtual terminals can be changed with
47 the setfont ("man setfont") command and the key bindings are defined
48 with the loadkeys ("man loadkeys") command.
49
50 You need at least one virtual terminal device in order to make use
51 of your keyboard and monitor. Therefore, only people configuring an
52 embedded system would want to say N here in order to save some
53 memory; the only way to log into such a system is then via a serial
54 or network connection.
55
56 If unsure, say Y, or else you won't be able to do much with your new
57 shiny Linux system :-)
58
59config VT_CONSOLE
60 bool
61 default y
62 ---help---
63 The system console is the device which receives all kernel messages
64 and warnings and which allows logins in single user mode. If you
65 answer Y here, a virtual terminal (the device used to interact with
66 a physical terminal) can be used as system console. This is the most
67 common mode of operations, so you should say Y here unless you want
68 the kernel messages be output only to a serial port (in which case
69 you should say Y to "Console on serial port", below).
70
71 If you do say Y here, by default the currently visible virtual
72 terminal (/dev/tty0) will be used as system console. You can change
73 that with a kernel command line option such as "console=tty3" which
74 would use the third virtual terminal as system console. (Try "man
75 bootparam" or see the documentation of your boot loader (lilo or
76 loadlin) about how to pass options to the kernel at boot time.)
77
78 If unsure, say Y.
79
80config HW_CONSOLE
81 bool
82 default y
83
84config SMP 28config SMP
85 bool "Symmetric multi-processing support (does not work on sun4/sun4c)" 29 bool "Symmetric multi-processing support (does not work on sun4/sun4c)"
86 depends on BROKEN 30 depends on BROKEN
@@ -257,6 +201,14 @@ config SUN_OPENPROMFS
257 Only choose N if you know in advance that you will not need to modify 201 Only choose N if you know in advance that you will not need to modify
258 OpenPROM settings on the running system. 202 OpenPROM settings on the running system.
259 203
204config SPARC_LED
205 tristate "Sun4m LED driver"
206 help
207 This driver toggles the front-panel LED on sun4m systems
208 in a user-specifyable manner. It's state can be probed
209 by reading /proc/led and it's blinking mode can be changed
210 via writes to /proc/led
211
260source "fs/Kconfig.binfmt" 212source "fs/Kconfig.binfmt"
261 213
262config SUNOS_EMUL 214config SUNOS_EMUL
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 3d22ba2af01c..1b83e21841b5 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SUN_AUXIO) += auxio.o
21obj-$(CONFIG_PCI) += ebus.o 21obj-$(CONFIG_PCI) += ebus.o
22obj-$(CONFIG_SUN_PM) += apc.o pmc.o 22obj-$(CONFIG_SUN_PM) += apc.o pmc.o
23obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o 23obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
24obj-$(CONFIG_SPARC_LED) += led.o
24 25
25ifdef CONFIG_SUNOS_EMUL 26ifdef CONFIG_SUNOS_EMUL
26obj-y += sys_sunos.o sunos_ioctl.o 27obj-y += sys_sunos.o sunos_ioctl.o
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 6a4ebc62193e..d7bfc61d2879 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -75,7 +75,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
75 { 9, 3, "Fujitsu or Weitek on-chip FPU"}, 75 { 9, 3, "Fujitsu or Weitek on-chip FPU"},
76}; 76};
77 77
78#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) 78#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
79 79
80struct cpu_iu_info linux_sparc_chips[] = { 80struct cpu_iu_info linux_sparc_chips[] = {
81 /* Sun4/100, 4/200, SLC */ 81 /* Sun4/100, 4/200, SLC */
@@ -120,7 +120,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
120 { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"}, 120 { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"},
121}; 121};
122 122
123#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) 123#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
124 124
125char *sparc_cpu_type; 125char *sparc_cpu_type;
126char *sparc_fpu_type; 126char *sparc_fpu_type;
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index d0f2bd227c4c..d39c9f206271 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -252,7 +252,7 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
252 } 252 }
253 253
254 order = get_order(len_total); 254 order = get_order(len_total);
255 if ((va = __get_free_pages(GFP_KERNEL, order)) == 0) 255 if ((va = __get_free_pages(GFP_KERNEL|__GFP_COMP, order)) == 0)
256 goto err_nopages; 256 goto err_nopages;
257 257
258 if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) 258 if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL)
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
new file mode 100644
index 000000000000..2a3afca453c9
--- /dev/null
+++ b/arch/sparc/kernel/led.c
@@ -0,0 +1,139 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/init.h>
4#include <linux/proc_fs.h>
5#include <linux/string.h>
6
7#include <asm/auxio.h>
8
9#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */
10
11static inline void led_toggle(void)
12{
13 unsigned char val = get_auxio();
14 unsigned char on, off;
15
16 if (val & AUXIO_LED) {
17 on = 0;
18 off = AUXIO_LED;
19 } else {
20 on = AUXIO_LED;
21 off = 0;
22 }
23
24 set_auxio(on, off);
25}
26
27static struct timer_list led_blink_timer;
28
29static void led_blink(unsigned long timeout)
30{
31 led_toggle();
32
33 /* reschedule */
34 if (!timeout) { /* blink according to load */
35 led_blink_timer.expires = jiffies +
36 ((1 + (avenrun[0] >> FSHIFT)) * HZ);
37 led_blink_timer.data = 0;
38 } else { /* blink at user specified interval */
39 led_blink_timer.expires = jiffies + (timeout * HZ);
40 led_blink_timer.data = timeout;
41 }
42 add_timer(&led_blink_timer);
43}
44
45static int led_read_proc(char *buf, char **start, off_t offset, int count,
46 int *eof, void *data)
47{
48 int len = 0;
49
50 if (get_auxio() & AUXIO_LED)
51 len = sprintf(buf, "on\n");
52 else
53 len = sprintf(buf, "off\n");
54
55 return len;
56}
57
58static int led_write_proc(struct file *file, const char *buffer,
59 unsigned long count, void *data)
60{
61 char *buf = NULL;
62
63 if (count > LED_MAX_LENGTH)
64 count = LED_MAX_LENGTH;
65
66 buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL);
67 if (!buf)
68 return -ENOMEM;
69
70 if (copy_from_user(buf, buffer, count)) {
71 kfree(buf);
72 return -EFAULT;
73 }
74
75 buf[count] = '\0';
76
77 /* work around \n when echo'ing into proc */
78 if (buf[count - 1] == '\n')
79 buf[count - 1] = '\0';
80
81 /* before we change anything we want to stop any running timers,
82 * otherwise calls such as on will have no persistent effect
83 */
84 del_timer_sync(&led_blink_timer);
85
86 if (!strcmp(buf, "on")) {
87 auxio_set_led(AUXIO_LED_ON);
88 } else if (!strcmp(buf, "toggle")) {
89 led_toggle();
90 } else if ((*buf > '0') && (*buf <= '9')) {
91 led_blink(simple_strtoul(buf, NULL, 10));
92 } else if (!strcmp(buf, "load")) {
93 led_blink(0);
94 } else {
95 auxio_set_led(AUXIO_LED_OFF);
96 }
97
98 kfree(buf);
99
100 return count;
101}
102
103static struct proc_dir_entry *led;
104
105#define LED_VERSION "0.1"
106
107static int __init led_init(void)
108{
109 init_timer(&led_blink_timer);
110 led_blink_timer.function = led_blink;
111
112 led = create_proc_entry("led", 0, NULL);
113 if (!led)
114 return -ENOMEM;
115
116 led->read_proc = led_read_proc; /* reader function */
117 led->write_proc = led_write_proc; /* writer function */
118 led->owner = THIS_MODULE;
119
120 printk(KERN_INFO
121 "led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
122 LED_VERSION);
123
124 return 0;
125}
126
127static void __exit led_exit(void)
128{
129 remove_proc_entry("led", NULL);
130 del_timer_sync(&led_blink_timer);
131}
132
133module_init(led_init);
134module_exit(led_exit);
135
136MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>");
137MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems.");
138MODULE_LICENSE("GPL");
139MODULE_VERSION(LED_VERSION);
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 36a40697b8d6..cccfc12802ed 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -143,7 +143,7 @@ static struct pcic_ca2irq pcic_i_jk[] = {
143 * as several PROMs may be installed on the same physical board. 143 * as several PROMs may be installed on the same physical board.
144 */ 144 */
145#define SN2L_INIT(name, map) \ 145#define SN2L_INIT(name, map) \
146 { name, map, sizeof(map)/sizeof(struct pcic_ca2irq) } 146 { name, map, ARRAY_SIZE(map) }
147 147
148static struct pcic_sn2list pcic_known_sysnames[] = { 148static struct pcic_sn2list pcic_known_sysnames[] = {
149 SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */ 149 SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
@@ -497,8 +497,8 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
497 * CheerIO makes a similar conversion. 497 * CheerIO makes a similar conversion.
498 * See ebus.c for details. 498 * See ebus.c for details.
499 * 499 *
500 * Note that check_region()/request_region() 500 * Note that request_region()
501 * work for these devices. 501 * works for these devices.
502 * 502 *
503 * XXX Neat trick, but it's a *bad* idea 503 * XXX Neat trick, but it's a *bad* idea
504 * to shit into regions like that. 504 * to shit into regions like that.
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 29e72b57d4fd..ea8647411462 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -67,13 +67,6 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
67struct task_struct *last_task_used_math = NULL; 67struct task_struct *last_task_used_math = NULL;
68struct thread_info *current_set[NR_CPUS]; 68struct thread_info *current_set[NR_CPUS];
69 69
70/*
71 * default_idle is new in 2.5. XXX Review, currently stolen from sparc64.
72 */
73void default_idle(void)
74{
75}
76
77#ifndef CONFIG_SMP 70#ifndef CONFIG_SMP
78 71
79#define SUN4C_FAULT_HIGH 100 72#define SUN4C_FAULT_HIGH 100
@@ -92,12 +85,11 @@ void cpu_idle(void)
92 static unsigned long fps; 85 static unsigned long fps;
93 unsigned long now; 86 unsigned long now;
94 unsigned long faults; 87 unsigned long faults;
95 unsigned long flags;
96 88
97 extern unsigned long sun4c_kernel_faults; 89 extern unsigned long sun4c_kernel_faults;
98 extern void sun4c_grow_kernel_ring(void); 90 extern void sun4c_grow_kernel_ring(void);
99 91
100 local_irq_save(flags); 92 local_irq_disable();
101 now = jiffies; 93 now = jiffies;
102 count -= (now - last_jiffies); 94 count -= (now - last_jiffies);
103 last_jiffies = now; 95 last_jiffies = now;
@@ -113,14 +105,19 @@ void cpu_idle(void)
113 sun4c_grow_kernel_ring(); 105 sun4c_grow_kernel_ring();
114 } 106 }
115 } 107 }
116 local_irq_restore(flags); 108 local_irq_enable();
117 } 109 }
118 110
119 while((!need_resched()) && pm_idle) { 111 if (pm_idle) {
120 (*pm_idle)(); 112 while (!need_resched())
113 (*pm_idle)();
114 } else {
115 while (!need_resched())
116 cpu_relax();
121 } 117 }
122 118 preempt_enable_no_resched();
123 schedule(); 119 schedule();
120 preempt_disable();
124 check_pgt_cache(); 121 check_pgt_cache();
125 } 122 }
126} 123}
@@ -130,13 +127,15 @@ void cpu_idle(void)
130/* This is being executed in task 0 'user space'. */ 127/* This is being executed in task 0 'user space'. */
131void cpu_idle(void) 128void cpu_idle(void)
132{ 129{
130 set_thread_flag(TIF_POLLING_NRFLAG);
133 /* endless idle loop with no priority at all */ 131 /* endless idle loop with no priority at all */
134 while(1) { 132 while(1) {
135 if(need_resched()) { 133 while (!need_resched())
136 schedule(); 134 cpu_relax();
137 check_pgt_cache(); 135 preempt_enable_no_resched();
138 } 136 schedule();
139 barrier(); /* or else gcc optimizes... */ 137 preempt_disable();
138 check_pgt_cache();
140 } 139 }
141} 140}
142 141
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 53c192a4982f..3509e4305532 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -249,8 +249,6 @@ struct tt_entry *sparc_ttable;
249 249
250struct pt_regs fake_swapper_regs; 250struct pt_regs fake_swapper_regs;
251 251
252extern void paging_init(void);
253
254void __init setup_arch(char **cmdline_p) 252void __init setup_arch(char **cmdline_p)
255{ 253{
256 int i; 254 int i;
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
index df1c0b31a930..a6ba3d26222c 100644
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ b/arch/sparc/kernel/sunos_ioctl.c
@@ -23,7 +23,6 @@
23#include <linux/smp_lock.h> 23#include <linux/smp_lock.h>
24#include <linux/syscalls.h> 24#include <linux/syscalls.h>
25#include <linux/file.h> 25#include <linux/file.h>
26#include <asm/kbio.h>
27 26
28#if 0 27#if 0
29extern char sunkbd_type; 28extern char sunkbd_type;
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index bc015e980341..24814d58f9e1 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -45,10 +45,6 @@
45 45
46extern unsigned long wall_jiffies; 46extern unsigned long wall_jiffies;
47 47
48u64 jiffies_64 = INITIAL_JIFFIES;
49
50EXPORT_SYMBOL(jiffies_64);
51
52DEFINE_SPINLOCK(rtc_lock); 48DEFINE_SPINLOCK(rtc_lock);
53enum sparc_clock_type sp_clock_typ; 49enum sparc_clock_type sp_clock_typ;
54DEFINE_SPINLOCK(mostek_lock); 50DEFINE_SPINLOCK(mostek_lock);
@@ -457,7 +453,7 @@ void __init time_init(void)
457 sbus_time_init(); 453 sbus_time_init();
458} 454}
459 455
460extern __inline__ unsigned long do_gettimeoffset(void) 456static inline unsigned long do_gettimeoffset(void)
461{ 457{
462 return (*master_l10_counter >> 10) & 0x1fffff; 458 return (*master_l10_counter >> 10) & 0x1fffff;
463} 459}
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 2e64e8c3e8e5..cb3cf0f22822 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -37,17 +37,43 @@ int __atomic_add_return(int i, atomic_t *v)
37 spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 37 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
38 return ret; 38 return ret;
39} 39}
40EXPORT_SYMBOL(__atomic_add_return);
40 41
41void atomic_set(atomic_t *v, int i) 42int atomic_cmpxchg(atomic_t *v, int old, int new)
42{ 43{
44 int ret;
43 unsigned long flags; 45 unsigned long flags;
46
44 spin_lock_irqsave(ATOMIC_HASH(v), flags); 47 spin_lock_irqsave(ATOMIC_HASH(v), flags);
48 ret = v->counter;
49 if (likely(ret == old))
50 v->counter = new;
45 51
46 v->counter = i; 52 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
53 return ret;
54}
55
56int atomic_add_unless(atomic_t *v, int a, int u)
57{
58 int ret;
59 unsigned long flags;
47 60
61 spin_lock_irqsave(ATOMIC_HASH(v), flags);
62 ret = v->counter;
63 if (ret != u)
64 v->counter += a;
48 spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 65 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
66 return ret != u;
49} 67}
50 68
51EXPORT_SYMBOL(__atomic_add_return); 69static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
52EXPORT_SYMBOL(atomic_set); 70/* Atomic operations are already serializing */
71void atomic_set(atomic_t *v, int i)
72{
73 unsigned long flags;
53 74
75 spin_lock_irqsave(ATOMIC_HASH(v), flags);
76 v->counter = i;
77 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
78}
79EXPORT_SYMBOL(atomic_set);
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c
index 94b05e8c906c..2e168d16547f 100644
--- a/arch/sparc/lib/bitext.c
+++ b/arch/sparc/lib/bitext.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/smp_lock.h> 12#include <linux/smp_lock.h>
13#include <linux/string.h>
13#include <linux/bitops.h> 14#include <linux/bitops.h>
14 15
15#include <asm/bitext.h> 16#include <asm/bitext.h>
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 2bbd53f3cafb..9eeed3347df3 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -33,8 +33,6 @@
33#include <asm/kdebug.h> 33#include <asm/kdebug.h>
34#include <asm/uaccess.h> 34#include <asm/uaccess.h>
35 35
36#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
37
38extern int prom_node_root; 36extern int prom_node_root;
39 37
40/* At boot time we determine these two values necessary for setting 38/* At boot time we determine these two values necessary for setting
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
index 20ccb957fb77..2cb0728cee05 100644
--- a/arch/sparc/mm/generic.c
+++ b/arch/sparc/mm/generic.c
@@ -32,9 +32,7 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigne
32 if (end > PMD_SIZE) 32 if (end > PMD_SIZE)
33 end = PMD_SIZE; 33 end = PMD_SIZE;
34 do { 34 do {
35 pte_t oldpage = *pte; 35 set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space));
36 pte_clear(mm, address, pte);
37 set_pte(pte, mk_pte_io(offset, prot, space));
38 address += PAGE_SIZE; 36 address += PAGE_SIZE;
39 offset += PAGE_SIZE; 37 offset += PAGE_SIZE;
40 pte++; 38 pte++;
@@ -63,7 +61,7 @@ static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned
63} 61}
64 62
65int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, 63int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
66 unsigned long pfn, unsigned long size, pgprot_t prot) 64 unsigned long pfn, unsigned long size, pgprot_t prot)
67{ 65{
68 int error = 0; 66 int error = 0;
69 pgd_t * dir; 67 pgd_t * dir;
@@ -73,14 +71,18 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
73 int space = GET_IOSPACE(pfn); 71 int space = GET_IOSPACE(pfn);
74 unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; 72 unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
75 73
74 /* See comment in mm/memory.c remap_pfn_range */
75 vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
76 vma->vm_pgoff = (offset >> PAGE_SHIFT) |
77 ((unsigned long)space << 28UL);
78
76 prot = __pgprot(pg_iobits); 79 prot = __pgprot(pg_iobits);
77 offset -= from; 80 offset -= from;
78 dir = pgd_offset(mm, from); 81 dir = pgd_offset(mm, from);
79 flush_cache_range(vma, beg, end); 82 flush_cache_range(vma, beg, end);
80 83
81 spin_lock(&mm->page_table_lock);
82 while (from < end) { 84 while (from < end) {
83 pmd_t *pmd = pmd_alloc(current->mm, dir, from); 85 pmd_t *pmd = pmd_alloc(mm, dir, from);
84 error = -ENOMEM; 86 error = -ENOMEM;
85 if (!pmd) 87 if (!pmd)
86 break; 88 break;
@@ -90,7 +92,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
90 from = (from + PGDIR_SIZE) & PGDIR_MASK; 92 from = (from + PGDIR_SIZE) & PGDIR_MASK;
91 dir++; 93 dir++;
92 } 94 }
93 spin_unlock(&mm->page_table_lock);
94 95
95 flush_tlb_range(vma, beg, end); 96 flush_tlb_range(vma, beg, end);
96 return error; 97 return error;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index c89a803cbc20..c664b962987c 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -260,7 +260,7 @@ static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot)
260{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); } 260{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); }
261 261
262/* to find an entry in a top-level page table... */ 262/* to find an entry in a top-level page table... */
263extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address) 263static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
264{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); } 264{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); }
265 265
266/* Find an entry in the second-level page table.. */ 266/* Find an entry in the second-level page table.. */