aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/parisc/hpux/fs.c2
-rw-r--r--arch/parisc/kernel/binfmt_elf32.c24
-rw-r--r--arch/parisc/kernel/cache.c48
-rw-r--r--arch/parisc/kernel/entry.S21
-rw-r--r--arch/parisc/kernel/hardware.c3
-rw-r--r--arch/parisc/kernel/irq.c151
-rw-r--r--arch/parisc/kernel/processor.c5
-rw-r--r--arch/parisc/kernel/signal.c5
-rw-r--r--arch/parisc/kernel/smp.c7
-rw-r--r--arch/parisc/kernel/sys_parisc.c45
-rw-r--r--arch/parisc/kernel/syscall_table.S4
-rw-r--r--arch/parisc/kernel/time.c208
-rw-r--r--arch/parisc/kernel/traps.c10
-rw-r--r--arch/parisc/mm/init.c23
-rw-r--r--arch/parisc/mm/ioremap.c2
-rw-r--r--drivers/char/agp/Kconfig10
-rw-r--r--drivers/char/agp/Makefile1
-rw-r--r--drivers/char/agp/parisc-agp.c416
-rw-r--r--drivers/parisc/iosapic.c5
-rw-r--r--drivers/parisc/lba_pci.c122
-rw-r--r--drivers/parisc/sba_iommu.c267
-rw-r--r--drivers/serial/8250_gsc.c4
-rw-r--r--drivers/serial/Kconfig9
-rw-r--r--fs/binfmt_som.c18
-rw-r--r--include/asm-parisc/agp.h25
-rw-r--r--include/asm-parisc/assembly.h6
-rw-r--r--include/asm-parisc/cacheflush.h30
-rw-r--r--include/asm-parisc/compat.h4
-rw-r--r--include/asm-parisc/dma.h7
-rw-r--r--include/asm-parisc/futex.h71
-rw-r--r--include/asm-parisc/io.h2
-rw-r--r--include/asm-parisc/iosapic.h53
-rw-r--r--include/asm-parisc/irq.h6
-rw-r--r--include/asm-parisc/mckinley.h9
-rw-r--r--include/asm-parisc/page.h22
-rw-r--r--include/asm-parisc/param.h10
-rw-r--r--include/asm-parisc/parisc-device.h5
-rw-r--r--include/asm-parisc/pci.h5
-rw-r--r--include/asm-parisc/prefetch.h39
-rw-r--r--include/asm-parisc/processor.h39
-rw-r--r--include/asm-parisc/ropes.h322
-rw-r--r--include/asm-parisc/serial.h16
-rw-r--r--include/asm-parisc/spinlock.h115
-rw-r--r--include/linux/debug_locks.h2
45 files changed, 1473 insertions, 727 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6dd0ea8f88e0..d2101237442e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -127,7 +127,7 @@ config PA11
127 127
128config PREFETCH 128config PREFETCH
129 def_bool y 129 def_bool y
130 depends on PA8X00 130 depends on PA8X00 || PA7200
131 131
132config 64BIT 132config 64BIT
133 bool "64-bit kernel" 133 bool "64-bit kernel"
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index 6e79dbf3f6bd..2d58b92b57e3 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -96,7 +96,7 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
96 put_user(namlen, &dirent->d_namlen); 96 put_user(namlen, &dirent->d_namlen);
97 copy_to_user(dirent->d_name, name, namlen); 97 copy_to_user(dirent->d_name, name, namlen);
98 put_user(0, dirent->d_name + namlen); 98 put_user(0, dirent->d_name + namlen);
99 ((char *) dirent) += reclen; 99 dirent = (void __user *)dirent + reclen;
100 buf->current_dir = dirent; 100 buf->current_dir = dirent;
101 buf->count -= reclen; 101 buf->count -= reclen;
102 return 0; 102 return 0;
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
index d1833f164bbe..1e64e7b88110 100644
--- a/arch/parisc/kernel/binfmt_elf32.c
+++ b/arch/parisc/kernel/binfmt_elf32.c
@@ -87,7 +87,7 @@ struct elf_prpsinfo32
87 */ 87 */
88 88
89#define SET_PERSONALITY(ex, ibcs2) \ 89#define SET_PERSONALITY(ex, ibcs2) \
90 current->personality = PER_LINUX32; \ 90 set_thread_flag(TIF_32BIT); \
91 current->thread.map_base = DEFAULT_MAP_BASE32; \ 91 current->thread.map_base = DEFAULT_MAP_BASE32; \
92 current->thread.task_size = DEFAULT_TASK_SIZE32 \ 92 current->thread.task_size = DEFAULT_TASK_SIZE32 \
93 93
@@ -102,25 +102,3 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
102} 102}
103 103
104#include "../../../fs/binfmt_elf.c" 104#include "../../../fs/binfmt_elf.c"
105
106/* Set up a separate execution domain for ELF32 binaries running
107 * on an ELF64 kernel */
108
109static struct exec_domain parisc32_exec_domain = {
110 .name = "Linux/ELF32",
111 .pers_low = PER_LINUX32,
112 .pers_high = PER_LINUX32,
113};
114
115static int __init parisc32_exec_init(void)
116{
117 /* steal the identity signal mappings from the default domain */
118 parisc32_exec_domain.signal_map = default_exec_domain.signal_map;
119 parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
120
121 register_exec_domain(&parisc32_exec_domain);
122
123 return 0;
124}
125
126__initcall(parisc32_exec_init);
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index bc7c4a4e26a1..0be51e92a2fc 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -35,15 +35,12 @@ int icache_stride __read_mostly;
35EXPORT_SYMBOL(dcache_stride); 35EXPORT_SYMBOL(dcache_stride);
36 36
37 37
38#if defined(CONFIG_SMP)
39/* On some machines (e.g. ones with the Merced bus), there can be 38/* On some machines (e.g. ones with the Merced bus), there can be
40 * only a single PxTLB broadcast at a time; this must be guaranteed 39 * only a single PxTLB broadcast at a time; this must be guaranteed
41 * by software. We put a spinlock around all TLB flushes to 40 * by software. We put a spinlock around all TLB flushes to
42 * ensure this. 41 * ensure this.
43 */ 42 */
44DEFINE_SPINLOCK(pa_tlb_lock); 43DEFINE_SPINLOCK(pa_tlb_lock);
45EXPORT_SYMBOL(pa_tlb_lock);
46#endif
47 44
48struct pdc_cache_info cache_info __read_mostly; 45struct pdc_cache_info cache_info __read_mostly;
49#ifndef CONFIG_PA20 46#ifndef CONFIG_PA20
@@ -91,7 +88,8 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
91 88
92 flush_kernel_dcache_page(page); 89 flush_kernel_dcache_page(page);
93 clear_bit(PG_dcache_dirty, &page->flags); 90 clear_bit(PG_dcache_dirty, &page->flags);
94 } 91 } else if (parisc_requires_coherency())
92 flush_kernel_dcache_page(page);
95} 93}
96 94
97void 95void
@@ -370,3 +368,45 @@ void parisc_setup_cache_timing(void)
370 368
371 printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); 369 printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
372} 370}
371
372extern void purge_kernel_dcache_page(unsigned long);
373extern void clear_user_page_asm(void *page, unsigned long vaddr);
374
375void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
376{
377 purge_kernel_dcache_page((unsigned long)page);
378 purge_tlb_start();
379 pdtlb_kernel(page);
380 purge_tlb_end();
381 clear_user_page_asm(page, vaddr);
382}
383EXPORT_SYMBOL(clear_user_page);
384
385void flush_kernel_dcache_page_addr(void *addr)
386{
387 flush_kernel_dcache_page_asm(addr);
388 purge_tlb_start();
389 pdtlb_kernel(addr);
390 purge_tlb_end();
391}
392EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
393
394void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
395 struct page *pg)
396{
397 /* no coherency needed (all in kmap/kunmap) */
398 copy_user_page_asm(vto, vfrom);
399 if (!parisc_requires_coherency())
400 flush_kernel_dcache_page_asm(vto);
401}
402EXPORT_SYMBOL(copy_user_page);
403
404#ifdef CONFIG_PA8X00
405
406void kunmap_parisc(void *addr)
407{
408 if (parisc_requires_coherency())
409 flush_kernel_dcache_page_addr(addr);
410}
411EXPORT_SYMBOL(kunmap_parisc);
412#endif
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 192357a3b9fe..340b5e8d67ba 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -30,6 +30,7 @@
30 30
31 31
32#include <asm/psw.h> 32#include <asm/psw.h>
33#include <asm/cache.h> /* for L1_CACHE_SHIFT */
33#include <asm/assembly.h> /* for LDREG/STREG defines */ 34#include <asm/assembly.h> /* for LDREG/STREG defines */
34#include <asm/pgtable.h> 35#include <asm/pgtable.h>
35#include <asm/signal.h> 36#include <asm/signal.h>
@@ -478,11 +479,7 @@
478 bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault 479 bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
479 DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ 480 DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
480 copy \pmd,%r9 481 copy \pmd,%r9
481#ifdef CONFIG_64BIT 482 SHLREG %r9,PxD_VALUE_SHIFT,\pmd
482 shld %r9,PxD_VALUE_SHIFT,\pmd
483#else
484 shlw %r9,PxD_VALUE_SHIFT,\pmd
485#endif
486 EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index 483 EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
487 DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */ 484 DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
488 shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd 485 shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
@@ -970,11 +967,7 @@ intr_return:
970 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount 967 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
971 ** irq_stat[] is defined using ____cacheline_aligned. 968 ** irq_stat[] is defined using ____cacheline_aligned.
972 */ 969 */
973#ifdef CONFIG_64BIT 970 SHLREG %r1,L1_CACHE_SHIFT,%r20
974 shld %r1, 6, %r20
975#else
976 shlw %r1, 5, %r20
977#endif
978 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ 971 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
979#endif /* CONFIG_SMP */ 972#endif /* CONFIG_SMP */
980 973
@@ -1076,7 +1069,7 @@ intr_do_preempt:
1076 BL preempt_schedule_irq, %r2 1069 BL preempt_schedule_irq, %r2
1077 nop 1070 nop
1078 1071
1079 b intr_restore /* ssm PSW_SM_I done by intr_restore */ 1072 b,n intr_restore /* ssm PSW_SM_I done by intr_restore */
1080#endif /* CONFIG_PREEMPT */ 1073#endif /* CONFIG_PREEMPT */
1081 1074
1082 .import do_signal,code 1075 .import do_signal,code
@@ -2115,11 +2108,7 @@ syscall_check_bh:
2115 ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */ 2108 ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
2116 2109
2117 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */ 2110 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
2118#ifdef CONFIG_64BIT 2111 SHLREG %r26,L1_CACHE_SHIFT,%r20
2119 shld %r26, 6, %r20
2120#else
2121 shlw %r26, 5, %r20
2122#endif
2123 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ 2112 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
2124#endif /* CONFIG_SMP */ 2113#endif /* CONFIG_SMP */
2125 2114
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
index 3058bffd8a2c..18ba4cb9159b 100644
--- a/arch/parisc/kernel/hardware.c
+++ b/arch/parisc/kernel/hardware.c
@@ -231,6 +231,7 @@ static struct hp_hardware hp_hardware_list[] __initdata = {
231 {HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"}, 231 {HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
232 {HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"}, 232 {HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
233 {HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"}, 233 {HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
234 {HPHW_NPROC,0x5EB,0x4,0x91,"Perf/Leone 875 W2+"},
234 {HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"}, 235 {HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
235 {HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"}, 236 {HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
236 {HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"}, 237 {HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
@@ -584,8 +585,10 @@ static struct hp_hardware hp_hardware_list[] __initdata = {
584 {HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"}, 585 {HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"},
585 {HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"}, 586 {HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"},
586 {HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"}, 587 {HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"},
588 {HPHW_FABRIC, 0x005, 0x000AA, 0x80, "Keystone DNA Central Agent"},
587 {HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"}, 589 {HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"},
588 {HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"}, 590 {HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"},
591 {HPHW_FABRIC, 0x005, 0x000AB, 0x00, "Keystone TOGO Fabric Crossbar"},
589 {HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"}, 592 {HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"},
590 {HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"}, 593 {HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"},
591 {HPHW_FIO, 0x004, 0x0004F, 0x0, "8-Port X.25 EISA-ACC (AMSO)"}, 594 {HPHW_FIO, 0x004, 0x0004F, 0x0, "8-Port X.25 EISA-ACC (AMSO)"},
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 5b8803cc3d69..9bdd0197ceb7 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -45,6 +45,17 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
45*/ 45*/
46static volatile unsigned long cpu_eiem = 0; 46static volatile unsigned long cpu_eiem = 0;
47 47
48/*
49** ack bitmap ... habitually set to 1, but reset to zero
50** between ->ack() and ->end() of the interrupt to prevent
51** re-interruption of a processing interrupt.
52*/
53static volatile unsigned long global_ack_eiem = ~0UL;
54/*
55** Local bitmap, same as above but for per-cpu interrupts
56*/
57static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
58
48static void cpu_disable_irq(unsigned int irq) 59static void cpu_disable_irq(unsigned int irq)
49{ 60{
50 unsigned long eirr_bit = EIEM_MASK(irq); 61 unsigned long eirr_bit = EIEM_MASK(irq);
@@ -62,13 +73,6 @@ static void cpu_enable_irq(unsigned int irq)
62 73
63 cpu_eiem |= eirr_bit; 74 cpu_eiem |= eirr_bit;
64 75
65 /* FIXME: while our interrupts aren't nested, we cannot reset
66 * the eiem mask if we're already in an interrupt. Once we
67 * implement nested interrupts, this can go away
68 */
69 if (!in_interrupt())
70 set_eiem(cpu_eiem);
71
72 /* This is just a simple NOP IPI. But what it does is cause 76 /* This is just a simple NOP IPI. But what it does is cause
73 * all the other CPUs to do a set_eiem(cpu_eiem) at the end 77 * all the other CPUs to do a set_eiem(cpu_eiem) at the end
74 * of the interrupt handler */ 78 * of the interrupt handler */
@@ -84,13 +88,45 @@ static unsigned int cpu_startup_irq(unsigned int irq)
84void no_ack_irq(unsigned int irq) { } 88void no_ack_irq(unsigned int irq) { }
85void no_end_irq(unsigned int irq) { } 89void no_end_irq(unsigned int irq) { }
86 90
91void cpu_ack_irq(unsigned int irq)
92{
93 unsigned long mask = EIEM_MASK(irq);
94 int cpu = smp_processor_id();
95
96 /* Clear in EIEM so we can no longer process */
97 if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
98 per_cpu(local_ack_eiem, cpu) &= ~mask;
99 else
100 global_ack_eiem &= ~mask;
101
102 /* disable the interrupt */
103 set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
104 /* and now ack it */
105 mtctl(mask, 23);
106}
107
108void cpu_end_irq(unsigned int irq)
109{
110 unsigned long mask = EIEM_MASK(irq);
111 int cpu = smp_processor_id();
112
113 /* set it in the eiems---it's no longer in process */
114 if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
115 per_cpu(local_ack_eiem, cpu) |= mask;
116 else
117 global_ack_eiem |= mask;
118
119 /* enable the interrupt */
120 set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
121}
122
87#ifdef CONFIG_SMP 123#ifdef CONFIG_SMP
88int cpu_check_affinity(unsigned int irq, cpumask_t *dest) 124int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
89{ 125{
90 int cpu_dest; 126 int cpu_dest;
91 127
92 /* timer and ipi have to always be received on all CPUs */ 128 /* timer and ipi have to always be received on all CPUs */
93 if (irq == TIMER_IRQ || irq == IPI_IRQ) { 129 if (CHECK_IRQ_PER_CPU(irq)) {
94 /* Bad linux design decision. The mask has already 130 /* Bad linux design decision. The mask has already
95 * been set; we must reset it */ 131 * been set; we must reset it */
96 irq_desc[irq].affinity = CPU_MASK_ALL; 132 irq_desc[irq].affinity = CPU_MASK_ALL;
@@ -119,8 +155,8 @@ static struct hw_interrupt_type cpu_interrupt_type = {
119 .shutdown = cpu_disable_irq, 155 .shutdown = cpu_disable_irq,
120 .enable = cpu_enable_irq, 156 .enable = cpu_enable_irq,
121 .disable = cpu_disable_irq, 157 .disable = cpu_disable_irq,
122 .ack = no_ack_irq, 158 .ack = cpu_ack_irq,
123 .end = no_end_irq, 159 .end = cpu_end_irq,
124#ifdef CONFIG_SMP 160#ifdef CONFIG_SMP
125 .set_affinity = cpu_set_affinity_irq, 161 .set_affinity = cpu_set_affinity_irq,
126#endif 162#endif
@@ -209,7 +245,7 @@ int show_interrupts(struct seq_file *p, void *v)
209** Then use that to get the Transaction address and data. 245** Then use that to get the Transaction address and data.
210*/ 246*/
211 247
212int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data) 248int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
213{ 249{
214 if (irq_desc[irq].action) 250 if (irq_desc[irq].action)
215 return -EBUSY; 251 return -EBUSY;
@@ -298,82 +334,69 @@ unsigned int txn_alloc_data(unsigned int virt_irq)
298 return virt_irq - CPU_IRQ_BASE; 334 return virt_irq - CPU_IRQ_BASE;
299} 335}
300 336
337static inline int eirr_to_irq(unsigned long eirr)
338{
339#ifdef CONFIG_64BIT
340 int bit = fls64(eirr);
341#else
342 int bit = fls(eirr);
343#endif
344 return (BITS_PER_LONG - bit) + TIMER_IRQ;
345}
346
301/* ONLY called from entry.S:intr_extint() */ 347/* ONLY called from entry.S:intr_extint() */
302void do_cpu_irq_mask(struct pt_regs *regs) 348void do_cpu_irq_mask(struct pt_regs *regs)
303{ 349{
304 unsigned long eirr_val; 350 unsigned long eirr_val;
305 351 int irq, cpu = smp_processor_id();
306 irq_enter();
307
308 /*
309 * Don't allow TIMER or IPI nested interrupts.
310 * Allowing any single interrupt to nest can lead to that CPU
311 * handling interrupts with all enabled interrupts unmasked.
312 */
313 set_eiem(0UL);
314
315 /* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
316 * 2) We loop here on EIRR contents in order to avoid
317 * nested interrupts or having to take another interrupt
318 * when we could have just handled it right away.
319 */
320 for (;;) {
321 unsigned long bit = (1UL << (BITS_PER_LONG - 1));
322 unsigned int irq;
323 eirr_val = mfctl(23) & cpu_eiem;
324 if (!eirr_val)
325 break;
326
327 mtctl(eirr_val, 23); /* reset bits we are going to process */
328
329 /* Work our way from MSb to LSb...same order we alloc EIRs */
330 for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
331#ifdef CONFIG_SMP 352#ifdef CONFIG_SMP
332 cpumask_t dest = irq_desc[irq].affinity; 353 cpumask_t dest;
333#endif 354#endif
334 if (!(bit & eirr_val))
335 continue;
336 355
337 /* clear bit in mask - can exit loop sooner */ 356 local_irq_disable();
338 eirr_val &= ~bit; 357 irq_enter();
339 358
340#ifdef CONFIG_SMP 359 eirr_val = mfctl(23) & cpu_eiem & global_ack_eiem &
341 /* FIXME: because generic set affinity mucks 360 per_cpu(local_ack_eiem, cpu);
342 * with the affinity before sending it to us 361 if (!eirr_val)
343 * we can get the situation where the affinity is 362 goto set_out;
344 * wrong for our CPU type interrupts */ 363 irq = eirr_to_irq(eirr_val);
345 if (irq != TIMER_IRQ && irq != IPI_IRQ &&
346 !cpu_isset(smp_processor_id(), dest)) {
347 int cpu = first_cpu(dest);
348
349 printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
350 irq, smp_processor_id(), cpu);
351 gsc_writel(irq + CPU_IRQ_BASE,
352 cpu_data[cpu].hpa);
353 continue;
354 }
355#endif
356 364
357 __do_IRQ(irq, regs); 365#ifdef CONFIG_SMP
358 } 366 dest = irq_desc[irq].affinity;
367 if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) &&
368 !cpu_isset(smp_processor_id(), dest)) {
369 int cpu = first_cpu(dest);
370
371 printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
372 irq, smp_processor_id(), cpu);
373 gsc_writel(irq + CPU_IRQ_BASE,
374 cpu_data[cpu].hpa);
375 goto set_out;
359 } 376 }
377#endif
378 __do_IRQ(irq, regs);
360 379
361 set_eiem(cpu_eiem); /* restore original mask */ 380 out:
362 irq_exit(); 381 irq_exit();
363} 382 return;
364 383
384 set_out:
385 set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
386 goto out;
387}
365 388
366static struct irqaction timer_action = { 389static struct irqaction timer_action = {
367 .handler = timer_interrupt, 390 .handler = timer_interrupt,
368 .name = "timer", 391 .name = "timer",
369 .flags = IRQF_DISABLED, 392 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU,
370}; 393};
371 394
372#ifdef CONFIG_SMP 395#ifdef CONFIG_SMP
373static struct irqaction ipi_action = { 396static struct irqaction ipi_action = {
374 .handler = ipi_interrupt, 397 .handler = ipi_interrupt,
375 .name = "IPI", 398 .name = "IPI",
376 .flags = IRQF_DISABLED, 399 .flags = IRQF_DISABLED | IRQF_PERCPU,
377}; 400};
378#endif 401#endif
379 402
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 99d7fca93104..fb81e5687e7c 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -143,8 +143,9 @@ static int __init processor_probe(struct parisc_device *dev)
143 p = &cpu_data[cpuid]; 143 p = &cpu_data[cpuid];
144 boot_cpu_data.cpu_count++; 144 boot_cpu_data.cpu_count++;
145 145
146 /* initialize counters */ 146 /* initialize counters - CPU 0 gets it_value set in time_init() */
147 memset(p, 0, sizeof(struct cpuinfo_parisc)); 147 if (cpuid)
148 memset(p, 0, sizeof(struct cpuinfo_parisc));
148 149
149 p->loops_per_jiffy = loops_per_jiffy; 150 p->loops_per_jiffy = loops_per_jiffy;
150 p->dev = dev; /* Save IODC data in case we need it */ 151 p->dev = dev; /* Save IODC data in case we need it */
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index bb83880c5ee3..ee6653edeb7a 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -26,7 +26,6 @@
26#include <linux/stddef.h> 26#include <linux/stddef.h>
27#include <linux/compat.h> 27#include <linux/compat.h>
28#include <linux/elf.h> 28#include <linux/elf.h>
29#include <linux/personality.h>
30#include <asm/ucontext.h> 29#include <asm/ucontext.h>
31#include <asm/rt_sigframe.h> 30#include <asm/rt_sigframe.h>
32#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -433,13 +432,13 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
433 if (in_syscall) { 432 if (in_syscall) {
434 regs->gr[31] = haddr; 433 regs->gr[31] = haddr;
435#ifdef __LP64__ 434#ifdef __LP64__
436 if (personality(current->personality) == PER_LINUX) 435 if (!test_thread_flag(TIF_32BIT))
437 sigframe_size |= 1; 436 sigframe_size |= 1;
438#endif 437#endif
439 } else { 438 } else {
440 unsigned long psw = USER_PSW; 439 unsigned long psw = USER_PSW;
441#ifdef __LP64__ 440#ifdef __LP64__
442 if (personality(current->personality) == PER_LINUX) 441 if (!test_thread_flag(TIF_32BIT))
443 psw |= PSW_W; 442 psw |= PSW_W;
444#endif 443#endif
445 444
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 98e40959a564..faad338f310e 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -262,6 +262,9 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
262 this_cpu, which); 262 this_cpu, which);
263 return IRQ_NONE; 263 return IRQ_NONE;
264 } /* Switch */ 264 } /* Switch */
265 /* let in any pending interrupts */
266 local_irq_enable();
267 local_irq_disable();
265 } /* while (ops) */ 268 } /* while (ops) */
266 } 269 }
267 return IRQ_HANDLED; 270 return IRQ_HANDLED;
@@ -430,8 +433,9 @@ smp_do_timer(struct pt_regs *regs)
430static void __init 433static void __init
431smp_cpu_init(int cpunum) 434smp_cpu_init(int cpunum)
432{ 435{
433 extern int init_per_cpu(int); /* arch/parisc/kernel/setup.c */ 436 extern int init_per_cpu(int); /* arch/parisc/kernel/processor.c */
434 extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */ 437 extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */
438 extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */
435 439
436 /* Set modes and Enable floating point coprocessor */ 440 /* Set modes and Enable floating point coprocessor */
437 (void) init_per_cpu(cpunum); 441 (void) init_per_cpu(cpunum);
@@ -457,6 +461,7 @@ smp_cpu_init(int cpunum)
457 enter_lazy_tlb(&init_mm, current); 461 enter_lazy_tlb(&init_mm, current);
458 462
459 init_IRQ(); /* make sure no IRQ's are enabled or pending */ 463 init_IRQ(); /* make sure no IRQ's are enabled or pending */
464 start_cpu_itimer();
460} 465}
461 466
462 467
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 8b5df98e2b31..1db5588ceacf 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -31,6 +31,8 @@
31#include <linux/shm.h> 31#include <linux/shm.h>
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33#include <linux/syscalls.h> 33#include <linux/syscalls.h>
34#include <linux/utsname.h>
35#include <linux/personality.h>
34 36
35int sys_pipe(int __user *fildes) 37int sys_pipe(int __user *fildes)
36{ 38{
@@ -248,3 +250,46 @@ asmlinkage int sys_free_hugepages(unsigned long addr)
248{ 250{
249 return -EINVAL; 251 return -EINVAL;
250} 252}
253
254long parisc_personality(unsigned long personality)
255{
256 long err;
257
258 if (personality(current->personality) == PER_LINUX32
259 && personality == PER_LINUX)
260 personality = PER_LINUX32;
261
262 err = sys_personality(personality);
263 if (err == PER_LINUX32)
264 err = PER_LINUX;
265
266 return err;
267}
268
269static inline int override_machine(char __user *mach) {
270#ifdef CONFIG_COMPAT
271 if (personality(current->personality) == PER_LINUX32) {
272 if (__put_user(0, mach + 6) ||
273 __put_user(0, mach + 7))
274 return -EFAULT;
275 }
276
277 return 0;
278#else /*!CONFIG_COMPAT*/
279 return 0;
280#endif /*CONFIG_COMPAT*/
281}
282
283long parisc_newuname(struct new_utsname __user *utsname)
284{
285 int err = 0;
286
287 down_read(&uts_sem);
288 if (copy_to_user(utsname, &system_utsname, sizeof(*utsname)))
289 err = -EFAULT;
290 up_read(&uts_sem);
291
292 err = override_machine(utsname->machine);
293
294 return (long)err;
295}
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index e27b432f90a8..701d66a596e8 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -132,7 +132,7 @@
132 ENTRY_SAME(socketpair) 132 ENTRY_SAME(socketpair)
133 ENTRY_SAME(setpgid) 133 ENTRY_SAME(setpgid)
134 ENTRY_SAME(send) 134 ENTRY_SAME(send)
135 ENTRY_SAME(newuname) 135 ENTRY_OURS(newuname)
136 ENTRY_SAME(umask) /* 60 */ 136 ENTRY_SAME(umask) /* 60 */
137 ENTRY_SAME(chroot) 137 ENTRY_SAME(chroot)
138 ENTRY_SAME(ustat) 138 ENTRY_SAME(ustat)
@@ -221,7 +221,7 @@
221 ENTRY_SAME(fchdir) 221 ENTRY_SAME(fchdir)
222 ENTRY_SAME(bdflush) 222 ENTRY_SAME(bdflush)
223 ENTRY_SAME(sysfs) /* 135 */ 223 ENTRY_SAME(sysfs) /* 135 */
224 ENTRY_SAME(personality) 224 ENTRY_OURS(personality)
225 ENTRY_SAME(ni_syscall) /* for afs_syscall */ 225 ENTRY_SAME(ni_syscall) /* for afs_syscall */
226 ENTRY_SAME(setfsuid) 226 ENTRY_SAME(setfsuid)
227 ENTRY_SAME(setfsgid) 227 ENTRY_SAME(setfsgid)
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index ab641d67f551..b3496b592a2d 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -32,8 +32,7 @@
32 32
33#include <linux/timex.h> 33#include <linux/timex.h>
34 34
35static long clocktick __read_mostly; /* timer cycles per tick */ 35static unsigned long clocktick __read_mostly; /* timer cycles per tick */
36static long halftick __read_mostly;
37 36
38#ifdef CONFIG_SMP 37#ifdef CONFIG_SMP
39extern void smp_do_timer(struct pt_regs *regs); 38extern void smp_do_timer(struct pt_regs *regs);
@@ -41,46 +40,106 @@ extern void smp_do_timer(struct pt_regs *regs);
41 40
42irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 41irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
43{ 42{
44 long now; 43 unsigned long now;
45 long next_tick; 44 unsigned long next_tick;
46 int nticks; 45 unsigned long cycles_elapsed;
47 int cpu = smp_processor_id(); 46 unsigned long cycles_remainder;
47 unsigned int cpu = smp_processor_id();
48
49 /* gcc can optimize for "read-only" case with a local clocktick */
50 unsigned long cpt = clocktick;
48 51
49 profile_tick(CPU_PROFILING, regs); 52 profile_tick(CPU_PROFILING, regs);
50 53
51 now = mfctl(16); 54 /* Initialize next_tick to the expected tick time. */
52 /* initialize next_tick to time at last clocktick */
53 next_tick = cpu_data[cpu].it_value; 55 next_tick = cpu_data[cpu].it_value;
54 56
55 /* since time passes between the interrupt and the mfctl() 57 /* Get current interval timer.
56 * above, it is never true that last_tick + clocktick == now. If we 58 * CR16 reads as 64 bits in CPU wide mode.
57 * never miss a clocktick, we could set next_tick = last_tick + clocktick 59 * CR16 reads as 32 bits in CPU narrow mode.
58 * but maybe we'll miss ticks, hence the loop.
59 *
60 * Variables are *signed*.
61 */ 60 */
61 now = mfctl(16);
62
63 cycles_elapsed = now - next_tick;
62 64
63 nticks = 0; 65 if ((cycles_elapsed >> 5) < cpt) {
64 while((next_tick - now) < halftick) { 66 /* use "cheap" math (add/subtract) instead
65 next_tick += clocktick; 67 * of the more expensive div/mul method
66 nticks++; 68 */
69 cycles_remainder = cycles_elapsed;
70 while (cycles_remainder > cpt) {
71 cycles_remainder -= cpt;
72 }
73 } else {
74 cycles_remainder = cycles_elapsed % cpt;
67 } 75 }
68 mtctl(next_tick, 16); 76
77 /* Can we differentiate between "early CR16" (aka Scenario 1) and
78 * "long delay" (aka Scenario 3)? I don't think so.
79 *
80 * We expected timer_interrupt to be delivered at least a few hundred
81 * cycles after the IT fires. But it's arbitrary how much time passes
82 * before we call it "late". I've picked one second.
83 */
84/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
85#if HZ == 1000
86 if (cycles_elapsed > (cpt << 10) )
87#elif HZ == 250
88 if (cycles_elapsed > (cpt << 8) )
89#elif HZ == 100
90 if (cycles_elapsed > (cpt << 7) )
91#else
92#warn WTF is HZ set to anyway?
93 if (cycles_elapsed > (HZ * cpt) )
94#endif
95 {
96 /* Scenario 3: very long delay? bad in any case */
97 printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
98 " cycles %lX rem %lX "
99 " next/now %lX/%lX\n",
100 cpu,
101 cycles_elapsed, cycles_remainder,
102 next_tick, now );
103 }
104
105 /* convert from "division remainder" to "remainder of clock tick" */
106 cycles_remainder = cpt - cycles_remainder;
107
108 /* Determine when (in CR16 cycles) next IT interrupt will fire.
109 * We want IT to fire modulo clocktick even if we miss/skip some.
110 * But those interrupts don't in fact get delivered that regularly.
111 */
112 next_tick = now + cycles_remainder;
113
69 cpu_data[cpu].it_value = next_tick; 114 cpu_data[cpu].it_value = next_tick;
70 115
71 while (nticks--) { 116 /* Skip one clocktick on purpose if we are likely to miss next_tick.
117 * We want to avoid the new next_tick being less than CR16.
118 * If that happened, itimer wouldn't fire until CR16 wrapped.
119 * We'll catch the tick we missed on the tick after that.
120 */
121 if (!(cycles_remainder >> 13))
122 next_tick += cpt;
123
124 /* Program the IT when to deliver the next interrupt. */
125 /* Only bottom 32-bits of next_tick are written to cr16. */
126 mtctl(next_tick, 16);
127
128
129 /* Done mucking with unreliable delivery of interrupts.
130 * Go do system house keeping.
131 */
72#ifdef CONFIG_SMP 132#ifdef CONFIG_SMP
73 smp_do_timer(regs); 133 smp_do_timer(regs);
74#else 134#else
75 update_process_times(user_mode(regs)); 135 update_process_times(user_mode(regs));
76#endif 136#endif
77 if (cpu == 0) { 137 if (cpu == 0) {
78 write_seqlock(&xtime_lock); 138 write_seqlock(&xtime_lock);
79 do_timer(1); 139 do_timer(regs);
80 write_sequnlock(&xtime_lock); 140 write_sequnlock(&xtime_lock);
81 }
82 } 141 }
83 142
84 /* check soft power switch status */ 143 /* check soft power switch status */
85 if (cpu == 0 && !atomic_read(&power_tasklet.count)) 144 if (cpu == 0 && !atomic_read(&power_tasklet.count))
86 tasklet_schedule(&power_tasklet); 145 tasklet_schedule(&power_tasklet);
@@ -106,14 +165,12 @@ unsigned long profile_pc(struct pt_regs *regs)
106EXPORT_SYMBOL(profile_pc); 165EXPORT_SYMBOL(profile_pc);
107 166
108 167
109/*** converted from ia64 ***/
110/* 168/*
111 * Return the number of micro-seconds that elapsed since the last 169 * Return the number of micro-seconds that elapsed since the last
112 * update to wall time (aka xtime). The xtime_lock 170 * update to wall time (aka xtime). The xtime_lock
113 * must be at least read-locked when calling this routine. 171 * must be at least read-locked when calling this routine.
114 */ 172 */
115static inline unsigned long 173static inline unsigned long gettimeoffset (void)
116gettimeoffset (void)
117{ 174{
118#ifndef CONFIG_SMP 175#ifndef CONFIG_SMP
119 /* 176 /*
@@ -121,21 +178,44 @@ gettimeoffset (void)
121 * Once parisc-linux learns the cr16 difference between processors, 178 * Once parisc-linux learns the cr16 difference between processors,
122 * this could be made to work. 179 * this could be made to work.
123 */ 180 */
124 long last_tick; 181 unsigned long now;
125 long elapsed_cycles; 182 unsigned long prev_tick;
126 183 unsigned long next_tick;
127 /* it_value is the intended time of the next tick */ 184 unsigned long elapsed_cycles;
128 last_tick = cpu_data[smp_processor_id()].it_value; 185 unsigned long usec;
129 186 unsigned long cpuid = smp_processor_id();
130 /* Subtract one tick and account for possible difference between 187 unsigned long cpt = clocktick;
131 * when we expected the tick and when it actually arrived. 188
132 * (aka wall vs real) 189 next_tick = cpu_data[cpuid].it_value;
133 */ 190 now = mfctl(16); /* Read the hardware interval timer. */
134 last_tick -= clocktick * (jiffies - wall_jiffies + 1); 191
135 elapsed_cycles = mfctl(16) - last_tick; 192 prev_tick = next_tick - cpt;
193
194 /* Assume Scenario 1: "now" is later than prev_tick. */
195 elapsed_cycles = now - prev_tick;
196
197/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
198#if HZ == 1000
199 if (elapsed_cycles > (cpt << 10) )
200#elif HZ == 250
201 if (elapsed_cycles > (cpt << 8) )
202#elif HZ == 100
203 if (elapsed_cycles > (cpt << 7) )
204#else
205#warn WTF is HZ set to anyway?
206 if (elapsed_cycles > (HZ * cpt) )
207#endif
208 {
209 /* Scenario 3: clock ticks are missing. */
210 printk (KERN_CRIT "gettimeoffset(CPU %ld): missing %ld ticks!"
211 " cycles %lX prev/now/next %lX/%lX/%lX clock %lX\n",
212 cpuid, elapsed_cycles / cpt,
213 elapsed_cycles, prev_tick, now, next_tick, cpt);
214 }
136 215
137 /* the precision of this math could be improved */ 216 /* FIXME: Can we improve the precision? Not with PAGE0. */
138 return elapsed_cycles / (PAGE0->mem_10msec / 10000); 217 usec = (elapsed_cycles * 10000) / PAGE0->mem_10msec;
218 return usec;
139#else 219#else
140 return 0; 220 return 0;
141#endif 221#endif
@@ -146,6 +226,7 @@ do_gettimeofday (struct timeval *tv)
146{ 226{
147 unsigned long flags, seq, usec, sec; 227 unsigned long flags, seq, usec, sec;
148 228
229 /* Hold xtime_lock and adjust timeval. */
149 do { 230 do {
150 seq = read_seqbegin_irqsave(&xtime_lock, flags); 231 seq = read_seqbegin_irqsave(&xtime_lock, flags);
151 usec = gettimeoffset(); 232 usec = gettimeoffset();
@@ -153,25 +234,13 @@ do_gettimeofday (struct timeval *tv)
153 usec += (xtime.tv_nsec / 1000); 234 usec += (xtime.tv_nsec / 1000);
154 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); 235 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
155 236
156 if (unlikely(usec > LONG_MAX)) { 237 /* Move adjusted usec's into sec's. */
157 /* This can happen if the gettimeoffset adjustment is
158 * negative and xtime.tv_nsec is smaller than the
159 * adjustment */
160 printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec);
161 usec += USEC_PER_SEC;
162 --sec;
163 /* This should never happen, it means the negative
164 * time adjustment was more than a second, so there's
165 * something seriously wrong */
166 BUG_ON(usec > LONG_MAX);
167 }
168
169
170 while (usec >= USEC_PER_SEC) { 238 while (usec >= USEC_PER_SEC) {
171 usec -= USEC_PER_SEC; 239 usec -= USEC_PER_SEC;
172 ++sec; 240 ++sec;
173 } 241 }
174 242
243 /* Return adjusted result. */
175 tv->tv_sec = sec; 244 tv->tv_sec = sec;
176 tv->tv_usec = usec; 245 tv->tv_usec = usec;
177} 246}
@@ -223,22 +292,23 @@ unsigned long long sched_clock(void)
223} 292}
224 293
225 294
295void __init start_cpu_itimer(void)
296{
297 unsigned int cpu = smp_processor_id();
298 unsigned long next_tick = mfctl(16) + clocktick;
299
300 mtctl(next_tick, 16); /* kick off Interval Timer (CR16) */
301
302 cpu_data[cpu].it_value = next_tick;
303}
304
226void __init time_init(void) 305void __init time_init(void)
227{ 306{
228 unsigned long next_tick;
229 static struct pdc_tod tod_data; 307 static struct pdc_tod tod_data;
230 308
231 clocktick = (100 * PAGE0->mem_10msec) / HZ; 309 clocktick = (100 * PAGE0->mem_10msec) / HZ;
232 halftick = clocktick / 2;
233 310
234 /* Setup clock interrupt timing */ 311 start_cpu_itimer(); /* get CPU 0 started */
235
236 next_tick = mfctl(16);
237 next_tick += clocktick;
238 cpu_data[smp_processor_id()].it_value = next_tick;
239
240 /* kick off Itimer (CR16) */
241 mtctl(next_tick, 16);
242 312
243 if(pdc_tod_read(&tod_data) == 0) { 313 if(pdc_tod_read(&tod_data) == 0) {
244 write_seqlock_irq(&xtime_lock); 314 write_seqlock_irq(&xtime_lock);
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 77b28cb8aca6..65cd6ca32fed 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -16,6 +16,7 @@
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/delay.h>
19#include <linux/mm.h> 20#include <linux/mm.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/smp.h> 22#include <linux/smp.h>
@@ -245,6 +246,15 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
245 current->comm, current->pid, str, err); 246 current->comm, current->pid, str, err);
246 show_regs(regs); 247 show_regs(regs);
247 248
249 if (in_interrupt())
250 panic("Fatal exception in interrupt");
251
252 if (panic_on_oops) {
253 printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
254 ssleep(5);
255 panic("Fatal exception");
256 }
257
248 /* Wot's wrong wif bein' racy? */ 258 /* Wot's wrong wif bein' racy? */
249 if (current->thread.flags & PARISC_KERNEL_DEATH) { 259 if (current->thread.flags & PARISC_KERNEL_DEATH) {
250 printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__); 260 printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 25ad28d63e88..0667f2b4f977 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -31,10 +31,7 @@
31 31
32DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 32DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
33 33
34extern char _text; /* start of kernel code, defined by linker */
35extern int data_start; 34extern int data_start;
36extern char _end; /* end of BSS, defined by linker */
37extern char __init_begin, __init_end;
38 35
39#ifdef CONFIG_DISCONTIGMEM 36#ifdef CONFIG_DISCONTIGMEM
40struct node_map_data node_data[MAX_NUMNODES] __read_mostly; 37struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
@@ -319,8 +316,8 @@ static void __init setup_bootmem(void)
319 316
320 reserve_bootmem_node(NODE_DATA(0), 0UL, 317 reserve_bootmem_node(NODE_DATA(0), 0UL,
321 (unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE)); 318 (unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE));
322 reserve_bootmem_node(NODE_DATA(0),__pa((unsigned long)&_text), 319 reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
323 (unsigned long)(&_end - &_text)); 320 (unsigned long)(_end - _text));
324 reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT), 321 reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
325 ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT)); 322 ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT));
326 323
@@ -355,8 +352,8 @@ static void __init setup_bootmem(void)
355#endif 352#endif
356 353
357 data_resource.start = virt_to_phys(&data_start); 354 data_resource.start = virt_to_phys(&data_start);
358 data_resource.end = virt_to_phys(&_end)-1; 355 data_resource.end = virt_to_phys(_end) - 1;
359 code_resource.start = virt_to_phys(&_text); 356 code_resource.start = virt_to_phys(_text);
360 code_resource.end = virt_to_phys(&data_start)-1; 357 code_resource.end = virt_to_phys(&data_start)-1;
361 358
362 /* We don't know which region the kernel will be in, so try 359 /* We don't know which region the kernel will be in, so try
@@ -385,12 +382,12 @@ void free_initmem(void)
385 */ 382 */
386 local_irq_disable(); 383 local_irq_disable();
387 384
388 memset(&__init_begin, 0x00, 385 memset(__init_begin, 0x00,
389 (unsigned long)&__init_end - (unsigned long)&__init_begin); 386 (unsigned long)__init_end - (unsigned long)__init_begin);
390 387
391 flush_data_cache(); 388 flush_data_cache();
392 asm volatile("sync" : : ); 389 asm volatile("sync" : : );
393 flush_icache_range((unsigned long)&__init_begin, (unsigned long)&__init_end); 390 flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end);
394 asm volatile("sync" : : ); 391 asm volatile("sync" : : );
395 392
396 local_irq_enable(); 393 local_irq_enable();
@@ -398,8 +395,8 @@ void free_initmem(void)
398 395
399 /* align __init_begin and __init_end to page size, 396 /* align __init_begin and __init_end to page size,
400 ignoring linker script where we might have tried to save RAM */ 397 ignoring linker script where we might have tried to save RAM */
401 init_begin = PAGE_ALIGN((unsigned long)(&__init_begin)); 398 init_begin = PAGE_ALIGN((unsigned long)(__init_begin));
402 init_end = PAGE_ALIGN((unsigned long)(&__init_end)); 399 init_end = PAGE_ALIGN((unsigned long)(__init_end));
403 for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) { 400 for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
404 ClearPageReserved(virt_to_page(addr)); 401 ClearPageReserved(virt_to_page(addr));
405 init_page_count(virt_to_page(addr)); 402 init_page_count(virt_to_page(addr));
@@ -578,7 +575,7 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_padd
578 extern const unsigned long fault_vector_20; 575 extern const unsigned long fault_vector_20;
579 extern void * const linux_gateway_page; 576 extern void * const linux_gateway_page;
580 577
581 ro_start = __pa((unsigned long)&_text); 578 ro_start = __pa((unsigned long)_text);
582 ro_end = __pa((unsigned long)&data_start); 579 ro_end = __pa((unsigned long)&data_start);
583 fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK; 580 fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
584 gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK; 581 gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 27384567a1d0..47a1d2ac9419 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -188,7 +188,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
188} 188}
189EXPORT_SYMBOL(__ioremap); 189EXPORT_SYMBOL(__ioremap);
190 190
191void iounmap(void __iomem *addr) 191void iounmap(const volatile void __iomem *addr)
192{ 192{
193 if (addr > high_memory) 193 if (addr > high_memory)
194 return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); 194 return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 22f8cf218cc6..c603bf291580 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,6 +1,6 @@
1config AGP 1config AGP
2 tristate "/dev/agpgart (AGP Support)" 2 tristate "/dev/agpgart (AGP Support)"
3 depends on ALPHA || IA64 || PPC || X86 3 depends on ALPHA || IA64 || PARISC || PPC || X86
4 depends on PCI 4 depends on PCI
5 ---help--- 5 ---help---
6 AGP (Accelerated Graphics Port) is a bus system mainly used to 6 AGP (Accelerated Graphics Port) is a bus system mainly used to
@@ -122,6 +122,14 @@ config AGP_HP_ZX1
122 This option gives you AGP GART support for the HP ZX1 chipset 122 This option gives you AGP GART support for the HP ZX1 chipset
123 for IA64 processors. 123 for IA64 processors.
124 124
125config AGP_PARISC
126 tristate "HP Quicksilver AGP support"
127 depends on AGP && PARISC && 64BIT
128 help
129 This option gives you AGP GART support for the HP Quicksilver
130 AGP bus adapter on HP PA-RISC machines (Ok, just on the C8000
131 workstation...)
132
125config AGP_ALPHA_CORE 133config AGP_ALPHA_CORE
126 tristate "Alpha AGP support" 134 tristate "Alpha AGP support"
127 depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL) 135 depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL)
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index d33a22f2fa0b..3e581603d0a8 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_AGP_AMD64) += amd64-agp.o
8obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o 8obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o
9obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o 9obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o
10obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o 10obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
11obj-$(CONFIG_AGP_PARISC) += parisc-agp.o
11obj-$(CONFIG_AGP_I460) += i460-agp.o 12obj-$(CONFIG_AGP_I460) += i460-agp.o
12obj-$(CONFIG_AGP_INTEL) += intel-agp.o 13obj-$(CONFIG_AGP_INTEL) += intel-agp.o
13obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o 14obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
new file mode 100644
index 000000000000..17c50b0f83f0
--- /dev/null
+++ b/drivers/char/agp/parisc-agp.c
@@ -0,0 +1,416 @@
1/*
2 * HP Quicksilver AGP GART routines
3 *
4 * Copyright (c) 2006, Kyle McMartin <kyle@parisc-linux.org>
5 *
6 * Based on drivers/char/agpgart/hp-agp.c which is
7 * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
8 * Bjorn Helgaas <bjorn.helgaas@hp.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/pci.h>
18#include <linux/init.h>
19#include <linux/klist.h>
20#include <linux/agp_backend.h>
21
22#include <asm-parisc/parisc-device.h>
23#include <asm-parisc/ropes.h>
24
25#include "agp.h"
26
27#define DRVNAME "quicksilver"
28#define DRVPFX DRVNAME ": "
29
30#ifndef log2
31#define log2(x) ffz(~(x))
32#endif
33
34#define AGP8X_MODE_BIT 3
35#define AGP8X_MODE (1 << AGP8X_MODE_BIT)
36
37static struct _parisc_agp_info {
38 void __iomem *ioc_regs;
39 void __iomem *lba_regs;
40
41 int lba_cap_offset;
42
43 u64 *gatt;
44 u64 gatt_entries;
45
46 u64 gart_base;
47 u64 gart_size;
48
49 int io_page_size;
50 int io_pages_per_kpage;
51} parisc_agp_info;
52
53static struct gatt_mask parisc_agp_masks[] =
54{
55 {
56 .mask = SBA_PDIR_VALID_BIT,
57 .type = 0
58 }
59};
60
61static struct aper_size_info_fixed parisc_agp_sizes[] =
62{
63 {0, 0, 0}, /* filled in by parisc_agp_fetch_size() */
64};
65
66static int
67parisc_agp_fetch_size(void)
68{
69 int size;
70
71 size = parisc_agp_info.gart_size / MB(1);
72 parisc_agp_sizes[0].size = size;
73 agp_bridge->current_size = (void *) &parisc_agp_sizes[0];
74
75 return size;
76}
77
78static int
79parisc_agp_configure(void)
80{
81 struct _parisc_agp_info *info = &parisc_agp_info;
82
83 agp_bridge->gart_bus_addr = info->gart_base;
84 agp_bridge->capndx = info->lba_cap_offset;
85 agp_bridge->mode = readl(info->lba_regs+info->lba_cap_offset+PCI_AGP_STATUS);
86
87 return 0;
88}
89
90static void
91parisc_agp_tlbflush(struct agp_memory *mem)
92{
93 struct _parisc_agp_info *info = &parisc_agp_info;
94
95 writeq(info->gart_base | log2(info->gart_size), info->ioc_regs+IOC_PCOM);
96 readq(info->ioc_regs+IOC_PCOM); /* flush */
97}
98
99static int
100parisc_agp_create_gatt_table(struct agp_bridge_data *bridge)
101{
102 struct _parisc_agp_info *info = &parisc_agp_info;
103 int i;
104
105 for (i = 0; i < info->gatt_entries; i++) {
106 info->gatt[i] = (unsigned long)agp_bridge->scratch_page;
107 }
108
109 return 0;
110}
111
112static int
113parisc_agp_free_gatt_table(struct agp_bridge_data *bridge)
114{
115 struct _parisc_agp_info *info = &parisc_agp_info;
116
117 info->gatt[0] = SBA_AGPGART_COOKIE;
118
119 return 0;
120}
121
122static int
123parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
124{
125 struct _parisc_agp_info *info = &parisc_agp_info;
126 int i, k;
127 off_t j, io_pg_start;
128 int io_pg_count;
129
130 if (type != 0 || mem->type != 0) {
131 return -EINVAL;
132 }
133
134 io_pg_start = info->io_pages_per_kpage * pg_start;
135 io_pg_count = info->io_pages_per_kpage * mem->page_count;
136 if ((io_pg_start + io_pg_count) > info->gatt_entries) {
137 return -EINVAL;
138 }
139
140 j = io_pg_start;
141 while (j < (io_pg_start + io_pg_count)) {
142 if (info->gatt[j])
143 return -EBUSY;
144 j++;
145 }
146
147 if (mem->is_flushed == FALSE) {
148 global_cache_flush();
149 mem->is_flushed = TRUE;
150 }
151
152 for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
153 unsigned long paddr;
154
155 paddr = mem->memory[i];
156 for (k = 0;
157 k < info->io_pages_per_kpage;
158 k++, j++, paddr += info->io_page_size) {
159 info->gatt[j] =
160 agp_bridge->driver->mask_memory(agp_bridge,
161 paddr, type);
162 }
163 }
164
165 agp_bridge->driver->tlb_flush(mem);
166
167 return 0;
168}
169
170static int
171parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
172{
173 struct _parisc_agp_info *info = &parisc_agp_info;
174 int i, io_pg_start, io_pg_count;
175
176 if (type != 0 || mem->type != 0) {
177 return -EINVAL;
178 }
179
180 io_pg_start = info->io_pages_per_kpage * pg_start;
181 io_pg_count = info->io_pages_per_kpage * mem->page_count;
182 for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
183 info->gatt[i] = agp_bridge->scratch_page;
184 }
185
186 agp_bridge->driver->tlb_flush(mem);
187 return 0;
188}
189
190static unsigned long
191parisc_agp_mask_memory(struct agp_bridge_data *bridge,
192 unsigned long addr, int type)
193{
194 return SBA_PDIR_VALID_BIT | addr;
195}
196
197static void
198parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
199{
200 struct _parisc_agp_info *info = &parisc_agp_info;
201 u32 command;
202
203 command = readl(info->lba_regs + info->lba_cap_offset + PCI_AGP_STATUS);
204
205 command = agp_collect_device_status(bridge, mode, command);
206 command |= 0x00000100;
207
208 writel(command, info->lba_regs + info->lba_cap_offset + PCI_AGP_COMMAND);
209
210 agp_device_command(command, (mode & AGP8X_MODE) != 0);
211}
212
213struct agp_bridge_driver parisc_agp_driver = {
214 .owner = THIS_MODULE,
215 .size_type = FIXED_APER_SIZE,
216 .configure = parisc_agp_configure,
217 .fetch_size = parisc_agp_fetch_size,
218 .tlb_flush = parisc_agp_tlbflush,
219 .mask_memory = parisc_agp_mask_memory,
220 .masks = parisc_agp_masks,
221 .agp_enable = parisc_agp_enable,
222 .cache_flush = global_cache_flush,
223 .create_gatt_table = parisc_agp_create_gatt_table,
224 .free_gatt_table = parisc_agp_free_gatt_table,
225 .insert_memory = parisc_agp_insert_memory,
226 .remove_memory = parisc_agp_remove_memory,
227 .alloc_by_type = agp_generic_alloc_by_type,
228 .free_by_type = agp_generic_free_by_type,
229 .agp_alloc_page = agp_generic_alloc_page,
230 .agp_destroy_page = agp_generic_destroy_page,
231 .cant_use_aperture = 1,
232};
233
234static int __init
235agp_ioc_init(void __iomem *ioc_regs)
236{
237 struct _parisc_agp_info *info = &parisc_agp_info;
238 u64 *iova_base, *io_pdir, io_tlb_ps;
239 int io_tlb_shift;
240
241 printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n");
242
243 info->ioc_regs = ioc_regs;
244
245 io_tlb_ps = readq(info->ioc_regs+IOC_TCNFG);
246 switch (io_tlb_ps) {
247 case 0: io_tlb_shift = 12; break;
248 case 1: io_tlb_shift = 13; break;
249 case 2: io_tlb_shift = 14; break;
250 case 3: io_tlb_shift = 16; break;
251 default:
252 printk(KERN_ERR DRVPFX "Invalid IOTLB page size "
253 "configuration 0x%llx\n", io_tlb_ps);
254 info->gatt = NULL;
255 info->gatt_entries = 0;
256 return -ENODEV;
257 }
258 info->io_page_size = 1 << io_tlb_shift;
259 info->io_pages_per_kpage = PAGE_SIZE / info->io_page_size;
260
261 iova_base = readq(info->ioc_regs+IOC_IBASE) & ~0x1;
262 info->gart_base = iova_base + PLUTO_IOVA_SIZE - PLUTO_GART_SIZE;
263
264 info->gart_size = PLUTO_GART_SIZE;
265 info->gatt_entries = info->gart_size / info->io_page_size;
266
267 io_pdir = phys_to_virt(readq(info->ioc_regs+IOC_PDIR_BASE));
268 info->gatt = &io_pdir[(PLUTO_IOVA_SIZE/2) >> PAGE_SHIFT];
269
270 if (info->gatt[0] != SBA_AGPGART_COOKIE) {
271 info->gatt = NULL;
272 info->gatt_entries = 0;
273 printk(KERN_ERR DRVPFX "No reserved IO PDIR entry found; "
274 "GART disabled\n");
275 return -ENODEV;
276 }
277
278 return 0;
279}
280
281static int
282lba_find_capability(int cap)
283{
284 struct _parisc_agp_info *info = &parisc_agp_info;
285 u16 status;
286 u8 pos, id;
287 int ttl = 48;
288
289 status = readw(info->lba_regs + PCI_STATUS);
290 if (!(status & PCI_STATUS_CAP_LIST))
291 return 0;
292 pos = readb(info->lba_regs + PCI_CAPABILITY_LIST);
293 while (ttl-- && pos >= 0x40) {
294 pos &= ~3;
295 id = readb(info->lba_regs + pos + PCI_CAP_LIST_ID);
296 if (id == 0xff)
297 break;
298 if (id == cap)
299 return pos;
300 pos = readb(info->lba_regs + pos + PCI_CAP_LIST_NEXT);
301 }
302 return 0;
303}
304
305static int __init
306agp_lba_init(void __iomem *lba_hpa)
307{
308 struct _parisc_agp_info *info = &parisc_agp_info;
309 int cap;
310
311 info->lba_regs = lba_hpa;
312 info->lba_cap_offset = lba_find_capability(PCI_CAP_ID_AGP);
313
314 cap = readl(lba_hpa + info->lba_cap_offset) & 0xff;
315 if (cap != PCI_CAP_ID_AGP) {
316 printk(KERN_ERR DRVPFX "Invalid capability ID 0x%02x at 0x%x\n",
317 cap, info->lba_cap_offset);
318 return -ENODEV;
319 }
320
321 return 0;
322}
323
324static int __init
325parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
326{
327 struct pci_dev *fake_bridge_dev = NULL;
328 struct agp_bridge_data *bridge;
329 int error = 0;
330
331 fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
332 if (!fake_bridge_dev) {
333 error = -ENOMEM;
334 goto fail;
335 }
336
337 error = agp_ioc_init(ioc_hpa);
338 if (error)
339 goto fail;
340
341 error = agp_lba_init(lba_hpa);
342 if (error)
343 goto fail;
344
345 bridge = agp_alloc_bridge();
346 if (!bridge) {
347 error = -ENOMEM;
348 goto fail;
349 }
350 bridge->driver = &parisc_agp_driver;
351
352 fake_bridge_dev->vendor = PCI_VENDOR_ID_HP;
353 fake_bridge_dev->device = PCI_DEVICE_ID_HP_PCIX_LBA;
354 bridge->dev = fake_bridge_dev;
355
356 error = agp_add_bridge(bridge);
357
358fail:
359 return error;
360}
361
362static struct device *next_device(struct klist_iter *i) {
363 struct klist_node * n = klist_next(i);
364 return n ? container_of(n, struct device, knode_parent) : NULL;
365}
366
367static int
368parisc_agp_init(void)
369{
370 extern struct sba_device *sba_list;
371
372 int err = -1;
373 struct parisc_device *sba = NULL, *lba = NULL;
374 struct lba_device *lbadev = NULL;
375 struct device *dev = NULL;
376 struct klist_iter i;
377
378 if (!sba_list)
379 goto out;
380
381 /* Find our parent Pluto */
382 sba = sba_list->dev;
383 if (!IS_PLUTO(sba)) {
384 printk(KERN_INFO DRVPFX "No Pluto found, so no AGPGART for you.\n");
385 goto out;
386 }
387
388 /* Now search our Pluto for our precious AGP device... */
389 klist_iter_init(&sba->dev.klist_children, &i);
390 while ((dev = next_device(&i))) {
391 struct parisc_device *padev = to_parisc_device(dev);
392 if (IS_QUICKSILVER(padev))
393 lba = padev;
394 }
395 klist_iter_exit(&i);
396
397 if (!lba) {
398 printk(KERN_INFO DRVPFX "No AGP devices found.\n");
399 goto out;
400 }
401
402 lbadev = parisc_get_drvdata(lba);
403
404 /* w00t, let's go find our cookies... */
405 parisc_agp_setup(sba_list->ioc[0].ioc_hpa, lbadev->hba.base_addr);
406
407 return 0;
408
409out:
410 return err;
411}
412
413module_init(parisc_agp_init);
414
415MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
416MODULE_LICENSE("GPL");
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 1fbda77cefc2..c2949b4367e5 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -146,7 +146,7 @@
146#include <asm/superio.h> 146#include <asm/superio.h>
147#endif 147#endif
148 148
149#include <asm/iosapic.h> 149#include <asm/ropes.h>
150#include "./iosapic_private.h" 150#include "./iosapic_private.h"
151 151
152#define MODULE_NAME "iosapic" 152#define MODULE_NAME "iosapic"
@@ -692,6 +692,7 @@ static void iosapic_end_irq(unsigned int irq)
692 DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq, 692 DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
693 vi->eoi_addr, vi->eoi_data); 693 vi->eoi_addr, vi->eoi_data);
694 iosapic_eoi(vi->eoi_addr, vi->eoi_data); 694 iosapic_eoi(vi->eoi_addr, vi->eoi_data);
695 cpu_end_irq(irq);
695} 696}
696 697
697static unsigned int iosapic_startup_irq(unsigned int irq) 698static unsigned int iosapic_startup_irq(unsigned int irq)
@@ -728,7 +729,7 @@ static struct hw_interrupt_type iosapic_interrupt_type = {
728 .shutdown = iosapic_disable_irq, 729 .shutdown = iosapic_disable_irq,
729 .enable = iosapic_enable_irq, 730 .enable = iosapic_enable_irq,
730 .disable = iosapic_disable_irq, 731 .disable = iosapic_disable_irq,
731 .ack = no_ack_irq, 732 .ack = cpu_ack_irq,
732 .end = iosapic_end_irq, 733 .end = iosapic_end_irq,
733#ifdef CONFIG_SMP 734#ifdef CONFIG_SMP
734 .set_affinity = iosapic_set_affinity_irq, 735 .set_affinity = iosapic_set_affinity_irq,
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 3fe4a77fa16a..ba6769934c77 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -46,9 +46,9 @@
46#include <asm/page.h> 46#include <asm/page.h>
47#include <asm/system.h> 47#include <asm/system.h>
48 48
49#include <asm/ropes.h>
49#include <asm/hardware.h> /* for register_parisc_driver() stuff */ 50#include <asm/hardware.h> /* for register_parisc_driver() stuff */
50#include <asm/parisc-device.h> 51#include <asm/parisc-device.h>
51#include <asm/iosapic.h> /* for iosapic_register() */
52#include <asm/io.h> /* read/write stuff */ 52#include <asm/io.h> /* read/write stuff */
53 53
54#undef DEBUG_LBA /* general stuff */ 54#undef DEBUG_LBA /* general stuff */
@@ -100,113 +100,10 @@
100 100
101#define MODULE_NAME "LBA" 101#define MODULE_NAME "LBA"
102 102
103#define LBA_FUNC_ID 0x0000 /* function id */
104#define LBA_FCLASS 0x0008 /* function class, bist, header, rev... */
105#define LBA_CAPABLE 0x0030 /* capabilities register */
106
107#define LBA_PCI_CFG_ADDR 0x0040 /* poke CFG address here */
108#define LBA_PCI_CFG_DATA 0x0048 /* read or write data here */
109
110#define LBA_PMC_MTLT 0x0050 /* Firmware sets this - read only. */
111#define LBA_FW_SCRATCH 0x0058 /* Firmware writes the PCI bus number here. */
112#define LBA_ERROR_ADDR 0x0070 /* On error, address gets logged here */
113
114#define LBA_ARB_MASK 0x0080 /* bit 0 enable arbitration. PAT/PDC enables */
115#define LBA_ARB_PRI 0x0088 /* firmware sets this. */
116#define LBA_ARB_MODE 0x0090 /* firmware sets this. */
117#define LBA_ARB_MTLT 0x0098 /* firmware sets this. */
118
119#define LBA_MOD_ID 0x0100 /* Module ID. PDC_PAT_CELL reports 4 */
120
121#define LBA_STAT_CTL 0x0108 /* Status & Control */
122#define LBA_BUS_RESET 0x01 /* Deassert PCI Bus Reset Signal */
123#define CLEAR_ERRLOG 0x10 /* "Clear Error Log" cmd */
124#define CLEAR_ERRLOG_ENABLE 0x20 /* "Clear Error Log" Enable */
125#define HF_ENABLE 0x40 /* enable HF mode (default is -1 mode) */
126
127#define LBA_LMMIO_BASE 0x0200 /* < 4GB I/O address range */
128#define LBA_LMMIO_MASK 0x0208
129
130#define LBA_GMMIO_BASE 0x0210 /* > 4GB I/O address range */
131#define LBA_GMMIO_MASK 0x0218
132
133#define LBA_WLMMIO_BASE 0x0220 /* All < 4GB ranges under the same *SBA* */
134#define LBA_WLMMIO_MASK 0x0228
135
136#define LBA_WGMMIO_BASE 0x0230 /* All > 4GB ranges under the same *SBA* */
137#define LBA_WGMMIO_MASK 0x0238
138
139#define LBA_IOS_BASE 0x0240 /* I/O port space for this LBA */
140#define LBA_IOS_MASK 0x0248
141
142#define LBA_ELMMIO_BASE 0x0250 /* Extra LMMIO range */
143#define LBA_ELMMIO_MASK 0x0258
144
145#define LBA_EIOS_BASE 0x0260 /* Extra I/O port space */
146#define LBA_EIOS_MASK 0x0268
147
148#define LBA_GLOBAL_MASK 0x0270 /* Mercury only: Global Address Mask */
149#define LBA_DMA_CTL 0x0278 /* firmware sets this */
150
151#define LBA_IBASE 0x0300 /* SBA DMA support */
152#define LBA_IMASK 0x0308
153
154/* FIXME: ignore DMA Hint stuff until we can measure performance */
155#define LBA_HINT_CFG 0x0310
156#define LBA_HINT_BASE 0x0380 /* 14 registers at every 8 bytes. */
157
158#define LBA_BUS_MODE 0x0620
159
160/* ERROR regs are needed for config cycle kluges */
161#define LBA_ERROR_CONFIG 0x0680
162#define LBA_SMART_MODE 0x20
163#define LBA_ERROR_STATUS 0x0688
164#define LBA_ROPE_CTL 0x06A0
165
166#define LBA_IOSAPIC_BASE 0x800 /* Offset of IRQ logic */
167
168/* non-postable I/O port space, densely packed */ 103/* non-postable I/O port space, densely packed */
169#define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL) 104#define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL)
170static void __iomem *astro_iop_base __read_mostly; 105static void __iomem *astro_iop_base __read_mostly;
171 106
172#define ELROY_HVERS 0x782
173#define MERCURY_HVERS 0x783
174#define QUICKSILVER_HVERS 0x784
175
176static inline int IS_ELROY(struct parisc_device *d)
177{
178 return (d->id.hversion == ELROY_HVERS);
179}
180
181static inline int IS_MERCURY(struct parisc_device *d)
182{
183 return (d->id.hversion == MERCURY_HVERS);
184}
185
186static inline int IS_QUICKSILVER(struct parisc_device *d)
187{
188 return (d->id.hversion == QUICKSILVER_HVERS);
189}
190
191
192/*
193** lba_device: Per instance Elroy data structure
194*/
195struct lba_device {
196 struct pci_hba_data hba;
197
198 spinlock_t lba_lock;
199 void *iosapic_obj;
200
201#ifdef CONFIG_64BIT
202 void __iomem * iop_base; /* PA_VIEW - for IO port accessor funcs */
203#endif
204
205 int flags; /* state/functionality enabled */
206 int hw_rev; /* HW revision of chip */
207};
208
209
210static u32 lba_t32; 107static u32 lba_t32;
211 108
212/* lba flags */ 109/* lba flags */
@@ -1542,8 +1439,8 @@ lba_driver_probe(struct parisc_device *dev)
1542 default: version = "TR4+"; 1439 default: version = "TR4+";
1543 } 1440 }
1544 1441
1545 printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n", 1442 printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
1546 MODULE_NAME, version, func_class & 0xf, dev->hpa.start); 1443 version, func_class & 0xf, dev->hpa.start);
1547 1444
1548 if (func_class < 2) { 1445 if (func_class < 2) {
1549 printk(KERN_WARNING "Can't support LBA older than " 1446 printk(KERN_WARNING "Can't support LBA older than "
@@ -1563,14 +1460,18 @@ lba_driver_probe(struct parisc_device *dev)
1563 } 1460 }
1564 1461
1565 } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { 1462 } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
1463 int major, minor;
1464
1566 func_class &= 0xff; 1465 func_class &= 0xff;
1567 version = kmalloc(6, GFP_KERNEL); 1466 major = func_class >> 4, minor = func_class & 0xf;
1568 snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf)); 1467
1569 /* We could use one printk for both Elroy and Mercury, 1468 /* We could use one printk for both Elroy and Mercury,
1570 * but for the mask for func_class. 1469 * but for the mask for func_class.
1571 */ 1470 */
1572 printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n", 1471 printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
1573 MODULE_NAME, version, func_class & 0xff, dev->hpa.start); 1472 IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
1473 minor, func_class, dev->hpa.start);
1474
1574 cfg_ops = &mercury_cfg_ops; 1475 cfg_ops = &mercury_cfg_ops;
1575 } else { 1476 } else {
1576 printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start); 1477 printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
@@ -1600,6 +1501,7 @@ lba_driver_probe(struct parisc_device *dev)
1600 lba_dev->hba.dev = dev; 1501 lba_dev->hba.dev = dev;
1601 lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */ 1502 lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */
1602 lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */ 1503 lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */
1504 parisc_set_drvdata(dev, lba_dev);
1603 1505
1604 /* ------------ Second : initialize common stuff ---------- */ 1506 /* ------------ Second : initialize common stuff ---------- */
1605 pci_bios = &lba_bios_ops; 1507 pci_bios = &lba_bios_ops;
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 8b4732815511..294c1117098d 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -38,22 +38,15 @@
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/seq_file.h> 39#include <linux/seq_file.h>
40 40
41#include <asm/ropes.h>
42#include <asm/mckinley.h> /* for proc_mckinley_root */
41#include <asm/runway.h> /* for proc_runway_root */ 43#include <asm/runway.h> /* for proc_runway_root */
42#include <asm/pdc.h> /* for PDC_MODEL_* */ 44#include <asm/pdc.h> /* for PDC_MODEL_* */
43#include <asm/pdcpat.h> /* for is_pdc_pat() */ 45#include <asm/pdcpat.h> /* for is_pdc_pat() */
44#include <asm/parisc-device.h> 46#include <asm/parisc-device.h>
45 47
46
47/* declared in arch/parisc/kernel/setup.c */
48extern struct proc_dir_entry * proc_mckinley_root;
49
50#define MODULE_NAME "SBA" 48#define MODULE_NAME "SBA"
51 49
52#ifdef CONFIG_PROC_FS
53/* depends on proc fs support. But costs CPU performance */
54#undef SBA_COLLECT_STATS
55#endif
56
57/* 50/*
58** The number of debug flags is a clue - this code is fragile. 51** The number of debug flags is a clue - this code is fragile.
59** Don't even think about messing with it unless you have 52** Don't even think about messing with it unless you have
@@ -92,202 +85,12 @@ extern struct proc_dir_entry * proc_mckinley_root;
92#define DBG_RES(x...) 85#define DBG_RES(x...)
93#endif 86#endif
94 87
95#if defined(CONFIG_64BIT)
96/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
97#define ZX1_SUPPORT
98#endif
99
100#define SBA_INLINE __inline__ 88#define SBA_INLINE __inline__
101 89
102
103/*
104** The number of pdir entries to "free" before issueing
105** a read to PCOM register to flush out PCOM writes.
106** Interacts with allocation granularity (ie 4 or 8 entries
107** allocated and free'd/purged at a time might make this
108** less interesting).
109*/
110#define DELAYED_RESOURCE_CNT 16
111
112#define DEFAULT_DMA_HINT_REG 0 90#define DEFAULT_DMA_HINT_REG 0
113 91
114#define ASTRO_RUNWAY_PORT 0x582 92struct sba_device *sba_list;
115#define IKE_MERCED_PORT 0x803 93EXPORT_SYMBOL_GPL(sba_list);
116#define REO_MERCED_PORT 0x804
117#define REOG_MERCED_PORT 0x805
118#define PLUTO_MCKINLEY_PORT 0x880
119
120#define SBA_FUNC_ID 0x0000 /* function id */
121#define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */
122
123#define IS_ASTRO(id) ((id)->hversion == ASTRO_RUNWAY_PORT)
124#define IS_IKE(id) ((id)->hversion == IKE_MERCED_PORT)
125#define IS_PLUTO(id) ((id)->hversion == PLUTO_MCKINLEY_PORT)
126
127#define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */
128
129#define ASTRO_IOC_OFFSET (32 * SBA_FUNC_SIZE)
130#define PLUTO_IOC_OFFSET (1 * SBA_FUNC_SIZE)
131/* Ike's IOC's occupy functions 2 and 3 */
132#define IKE_IOC_OFFSET(p) ((p+2) * SBA_FUNC_SIZE)
133
134#define IOC_CTRL 0x8 /* IOC_CTRL offset */
135#define IOC_CTRL_TC (1 << 0) /* TOC Enable */
136#define IOC_CTRL_CE (1 << 1) /* Coalesce Enable */
137#define IOC_CTRL_DE (1 << 2) /* Dillon Enable */
138#define IOC_CTRL_RM (1 << 8) /* Real Mode */
139#define IOC_CTRL_NC (1 << 9) /* Non Coherent Mode */
140#define IOC_CTRL_D4 (1 << 11) /* Disable 4-byte coalescing */
141#define IOC_CTRL_DD (1 << 13) /* Disable distr. LMMIO range coalescing */
142
143#define MAX_IOC 2 /* per Ike. Pluto/Astro only have 1. */
144
145#define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */
146
147
148/*
149** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
150** Firmware programs this stuff. Don't touch it.
151*/
152#define LMMIO_DIRECT0_BASE 0x300
153#define LMMIO_DIRECT0_MASK 0x308
154#define LMMIO_DIRECT0_ROUTE 0x310
155
156#define LMMIO_DIST_BASE 0x360
157#define LMMIO_DIST_MASK 0x368
158#define LMMIO_DIST_ROUTE 0x370
159
160#define IOS_DIST_BASE 0x390
161#define IOS_DIST_MASK 0x398
162#define IOS_DIST_ROUTE 0x3A0
163
164#define IOS_DIRECT_BASE 0x3C0
165#define IOS_DIRECT_MASK 0x3C8
166#define IOS_DIRECT_ROUTE 0x3D0
167
168/*
169** Offsets into I/O TLB (Function 2 and 3 on Ike)
170*/
171#define ROPE0_CTL 0x200 /* "regbus pci0" */
172#define ROPE1_CTL 0x208
173#define ROPE2_CTL 0x210
174#define ROPE3_CTL 0x218
175#define ROPE4_CTL 0x220
176#define ROPE5_CTL 0x228
177#define ROPE6_CTL 0x230
178#define ROPE7_CTL 0x238
179
180#define IOC_ROPE0_CFG 0x500 /* pluto only */
181#define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */
182
183
184
185#define HF_ENABLE 0x40
186
187
188#define IOC_IBASE 0x300 /* IO TLB */
189#define IOC_IMASK 0x308
190#define IOC_PCOM 0x310
191#define IOC_TCNFG 0x318
192#define IOC_PDIR_BASE 0x320
193
194/* AGP GART driver looks for this */
195#define SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
196
197
198/*
199** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
200** It's safer (avoid memory corruption) to keep DMA page mappings
201** equivalently sized to VM PAGE_SIZE.
202**
203** We really can't avoid generating a new mapping for each
204** page since the Virtual Coherence Index has to be generated
205** and updated for each page.
206**
207** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
208*/
209#define IOVP_SIZE PAGE_SIZE
210#define IOVP_SHIFT PAGE_SHIFT
211#define IOVP_MASK PAGE_MASK
212
213#define SBA_PERF_CFG 0x708 /* Performance Counter stuff */
214#define SBA_PERF_MASK1 0x718
215#define SBA_PERF_MASK2 0x730
216
217
218/*
219** Offsets into PCI Performance Counters (functions 12 and 13)
220** Controlled by PERF registers in function 2 & 3 respectively.
221*/
222#define SBA_PERF_CNT1 0x200
223#define SBA_PERF_CNT2 0x208
224#define SBA_PERF_CNT3 0x210
225
226
227struct ioc {
228 void __iomem *ioc_hpa; /* I/O MMU base address */
229 char *res_map; /* resource map, bit == pdir entry */
230 u64 *pdir_base; /* physical base address */
231 unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */
232 unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */
233#ifdef ZX1_SUPPORT
234 unsigned long iovp_mask; /* help convert IOVA to IOVP */
235#endif
236 unsigned long *res_hint; /* next avail IOVP - circular search */
237 spinlock_t res_lock;
238 unsigned int res_bitshift; /* from the LEFT! */
239 unsigned int res_size; /* size of resource map in bytes */
240#ifdef SBA_HINT_SUPPORT
241/* FIXME : DMA HINTs not used */
242 unsigned long hint_mask_pdir; /* bits used for DMA hints */
243 unsigned int hint_shift_pdir;
244#endif
245#if DELAYED_RESOURCE_CNT > 0
246 int saved_cnt;
247 struct sba_dma_pair {
248 dma_addr_t iova;
249 size_t size;
250 } saved[DELAYED_RESOURCE_CNT];
251#endif
252
253#ifdef SBA_COLLECT_STATS
254#define SBA_SEARCH_SAMPLE 0x100
255 unsigned long avg_search[SBA_SEARCH_SAMPLE];
256 unsigned long avg_idx; /* current index into avg_search */
257 unsigned long used_pages;
258 unsigned long msingle_calls;
259 unsigned long msingle_pages;
260 unsigned long msg_calls;
261 unsigned long msg_pages;
262 unsigned long usingle_calls;
263 unsigned long usingle_pages;
264 unsigned long usg_calls;
265 unsigned long usg_pages;
266#endif
267
268 /* STUFF We don't need in performance path */
269 unsigned int pdir_size; /* in bytes, determined by IOV Space size */
270};
271
272struct sba_device {
273 struct sba_device *next; /* list of SBA's in system */
274 struct parisc_device *dev; /* dev found in bus walk */
275 struct parisc_device_id *iodc; /* data about dev from firmware */
276 const char *name;
277 void __iomem *sba_hpa; /* base address */
278 spinlock_t sba_lock;
279 unsigned int flags; /* state/functionality enabled */
280 unsigned int hw_rev; /* HW revision of chip */
281
282 struct resource chip_resv; /* MMIO reserved for chip */
283 struct resource iommu_resv; /* MMIO reserved for iommu */
284
285 unsigned int num_ioc; /* number of on-board IOC's */
286 struct ioc ioc[MAX_IOC];
287};
288
289
290static struct sba_device *sba_list;
291 94
292static unsigned long ioc_needs_fdc = 0; 95static unsigned long ioc_needs_fdc = 0;
293 96
@@ -300,8 +103,14 @@ static unsigned long piranha_bad_128k = 0;
300/* Looks nice and keeps the compiler happy */ 103/* Looks nice and keeps the compiler happy */
301#define SBA_DEV(d) ((struct sba_device *) (d)) 104#define SBA_DEV(d) ((struct sba_device *) (d))
302 105
106#ifdef CONFIG_AGP_PARISC
107#define SBA_AGP_SUPPORT
108#endif /*CONFIG_AGP_PARISC*/
109
303#ifdef SBA_AGP_SUPPORT 110#ifdef SBA_AGP_SUPPORT
304static int reserve_sba_gart = 1; 111static int sba_reserve_agpgart = 1;
112module_param(sba_reserve_agpgart, int, 1);
113MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART");
305#endif 114#endif
306 115
307#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1)) 116#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
@@ -741,7 +550,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
741 asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); 550 asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
742 pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */ 551 pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */
743 552
744 pa |= 0x8000000000000000ULL; /* set "valid" bit */ 553 pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */
745 *pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */ 554 *pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */
746 555
747 /* 556 /*
@@ -1498,6 +1307,10 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
1498 WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); 1307 WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
1499 1308
1500#ifdef SBA_AGP_SUPPORT 1309#ifdef SBA_AGP_SUPPORT
1310{
1311 struct klist_iter i;
1312 struct device *dev = NULL;
1313
1501 /* 1314 /*
1502 ** If an AGP device is present, only use half of the IOV space 1315 ** If an AGP device is present, only use half of the IOV space
1503 ** for PCI DMA. Unfortunately we can't know ahead of time 1316 ** for PCI DMA. Unfortunately we can't know ahead of time
@@ -1506,20 +1319,22 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
1506 ** We program the next pdir index after we stop w/ a key for 1319 ** We program the next pdir index after we stop w/ a key for
1507 ** the GART code to handshake on. 1320 ** the GART code to handshake on.
1508 */ 1321 */
1509 device=NULL; 1322 klist_iter_init(&sba->dev.klist_children, &i);
1510 for (lba = sba->child; lba; lba = lba->sibling) { 1323 while (dev = next_device(&i)) {
1324 struct parisc_device *lba = to_parisc_device(dev);
1511 if (IS_QUICKSILVER(lba)) 1325 if (IS_QUICKSILVER(lba))
1512 break; 1326 agp_found = 1;
1513 } 1327 }
1328 klist_iter_exit(&sba->dev.klist_children, &i);
1514 1329
1515 if (lba) { 1330 if (agp_found && sba_reserve_agpgart) {
1516 DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__); 1331 printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
1332 __FUNCTION__, (iova_space_size/2) >> 20);
1517 ioc->pdir_size /= 2; 1333 ioc->pdir_size /= 2;
1518 ((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE; 1334 ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE;
1519 } else {
1520 DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__);
1521 } 1335 }
1522#endif /* 0 */ 1336}
1337#endif /*SBA_AGP_SUPPORT*/
1523 1338
1524} 1339}
1525 1340
@@ -1701,7 +1516,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
1701 } 1516 }
1702#endif 1517#endif
1703 1518
1704 if (!IS_PLUTO(sba_dev->iodc)) { 1519 if (!IS_PLUTO(sba_dev->dev)) {
1705 ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL); 1520 ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
1706 DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->", 1521 DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
1707 __FUNCTION__, sba_dev->sba_hpa, ioc_ctl); 1522 __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
@@ -1718,9 +1533,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
1718#endif 1533#endif
1719 } /* if !PLUTO */ 1534 } /* if !PLUTO */
1720 1535
1721 if (IS_ASTRO(sba_dev->iodc)) { 1536 if (IS_ASTRO(sba_dev->dev)) {
1722 int err; 1537 int err;
1723 /* PAT_PDC (L-class) also reports the same goofy base */
1724 sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET); 1538 sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET);
1725 num_ioc = 1; 1539 num_ioc = 1;
1726 1540
@@ -1730,13 +1544,9 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
1730 err = request_resource(&iomem_resource, &(sba_dev->chip_resv)); 1544 err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
1731 BUG_ON(err < 0); 1545 BUG_ON(err < 0);
1732 1546
1733 } else if (IS_PLUTO(sba_dev->iodc)) { 1547 } else if (IS_PLUTO(sba_dev->dev)) {
1734 int err; 1548 int err;
1735 1549
1736 /* We use a negative value for IOC HPA so it gets
1737 * corrected when we add it with IKE's IOC offset.
1738 * Doesnt look clean, but fewer code.
1739 */
1740 sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET); 1550 sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET);
1741 num_ioc = 1; 1551 num_ioc = 1;
1742 1552
@@ -1752,14 +1562,14 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
1752 err = request_resource(&iomem_resource, &(sba_dev->iommu_resv)); 1562 err = request_resource(&iomem_resource, &(sba_dev->iommu_resv));
1753 WARN_ON(err < 0); 1563 WARN_ON(err < 0);
1754 } else { 1564 } else {
1755 /* IS_IKE (ie N-class, L3000, L1500) */ 1565 /* IKE, REO */
1756 sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0)); 1566 sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0));
1757 sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1)); 1567 sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1));
1758 num_ioc = 2; 1568 num_ioc = 2;
1759 1569
1760 /* TODO - LOOKUP Ike/Stretch chipset mem map */ 1570 /* TODO - LOOKUP Ike/Stretch chipset mem map */
1761 } 1571 }
1762 /* XXX: What about Reo? */ 1572 /* XXX: What about Reo Grande? */
1763 1573
1764 sba_dev->num_ioc = num_ioc; 1574 sba_dev->num_ioc = num_ioc;
1765 for (i = 0; i < num_ioc; i++) { 1575 for (i = 0; i < num_ioc; i++) {
@@ -1774,7 +1584,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
1774 * Overrides bit 1 in DMA Hint Sets. 1584 * Overrides bit 1 in DMA Hint Sets.
1775 * Improves netperf UDP_STREAM by ~10% for bcm5701. 1585 * Improves netperf UDP_STREAM by ~10% for bcm5701.
1776 */ 1586 */
1777 if (IS_PLUTO(sba_dev->iodc)) { 1587 if (IS_PLUTO(sba_dev->dev)) {
1778 void __iomem *rope_cfg; 1588 void __iomem *rope_cfg;
1779 unsigned long cfg_val; 1589 unsigned long cfg_val;
1780 1590
@@ -1803,7 +1613,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
1803 READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400) 1613 READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400)
1804 ); 1614 );
1805 1615
1806 if (IS_PLUTO(sba_dev->iodc)) { 1616 if (IS_PLUTO(sba_dev->dev)) {
1807 sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i); 1617 sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
1808 } else { 1618 } else {
1809 sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i); 1619 sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
@@ -2067,7 +1877,7 @@ sba_driver_callback(struct parisc_device *dev)
2067 /* Read HW Rev First */ 1877 /* Read HW Rev First */
2068 func_class = READ_REG(sba_addr + SBA_FCLASS); 1878 func_class = READ_REG(sba_addr + SBA_FCLASS);
2069 1879
2070 if (IS_ASTRO(&dev->id)) { 1880 if (IS_ASTRO(dev)) {
2071 unsigned long fclass; 1881 unsigned long fclass;
2072 static char astro_rev[]="Astro ?.?"; 1882 static char astro_rev[]="Astro ?.?";
2073 1883
@@ -2078,11 +1888,11 @@ sba_driver_callback(struct parisc_device *dev)
2078 astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3); 1888 astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
2079 version = astro_rev; 1889 version = astro_rev;
2080 1890
2081 } else if (IS_IKE(&dev->id)) { 1891 } else if (IS_IKE(dev)) {
2082 static char ike_rev[] = "Ike rev ?"; 1892 static char ike_rev[] = "Ike rev ?";
2083 ike_rev[8] = '0' + (char) (func_class & 0xff); 1893 ike_rev[8] = '0' + (char) (func_class & 0xff);
2084 version = ike_rev; 1894 version = ike_rev;
2085 } else if (IS_PLUTO(&dev->id)) { 1895 } else if (IS_PLUTO(dev)) {
2086 static char pluto_rev[]="Pluto ?.?"; 1896 static char pluto_rev[]="Pluto ?.?";
2087 pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4); 1897 pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4);
2088 pluto_rev[8] = '0' + (char) (func_class & 0x0f); 1898 pluto_rev[8] = '0' + (char) (func_class & 0x0f);
@@ -2097,7 +1907,7 @@ sba_driver_callback(struct parisc_device *dev)
2097 global_ioc_cnt = count_parisc_driver(&sba_driver); 1907 global_ioc_cnt = count_parisc_driver(&sba_driver);
2098 1908
2099 /* Astro and Pluto have one IOC per SBA */ 1909 /* Astro and Pluto have one IOC per SBA */
2100 if ((!IS_ASTRO(&dev->id)) || (!IS_PLUTO(&dev->id))) 1910 if ((!IS_ASTRO(dev)) || (!IS_PLUTO(dev)))
2101 global_ioc_cnt *= 2; 1911 global_ioc_cnt *= 2;
2102 } 1912 }
2103 1913
@@ -2117,7 +1927,6 @@ sba_driver_callback(struct parisc_device *dev)
2117 1927
2118 sba_dev->dev = dev; 1928 sba_dev->dev = dev;
2119 sba_dev->hw_rev = func_class; 1929 sba_dev->hw_rev = func_class;
2120 sba_dev->iodc = &dev->id;
2121 sba_dev->name = dev->name; 1930 sba_dev->name = dev->name;
2122 sba_dev->sba_hpa = sba_addr; 1931 sba_dev->sba_hpa = sba_addr;
2123 1932
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 1ebe6b585d2d..c5d0addfda4f 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -22,7 +22,6 @@
22#include <asm/hardware.h> 22#include <asm/hardware.h>
23#include <asm/parisc-device.h> 23#include <asm/parisc-device.h>
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/serial.h> /* for LASI_BASE_BAUD */
26 25
27#include "8250.h" 26#include "8250.h"
28 27
@@ -54,7 +53,8 @@ serial_init_chip(struct parisc_device *dev)
54 53
55 memset(&port, 0, sizeof(port)); 54 memset(&port, 0, sizeof(port));
56 port.iotype = UPIO_MEM; 55 port.iotype = UPIO_MEM;
57 port.uartclk = LASI_BASE_BAUD * 16; 56 /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */
57 port.uartclk = 7272727;
58 port.mapbase = address; 58 port.mapbase = address;
59 port.membase = ioremap_nocache(address, 16); 59 port.membase = ioremap_nocache(address, 16);
60 port.irq = dev->irq; 60 port.irq = dev->irq;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 653098bc2dd5..8edee745888a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -556,10 +556,11 @@ config SERIAL_MUX
556 default y 556 default y
557 ---help--- 557 ---help---
558 Saying Y here will enable the hardware MUX serial driver for 558 Saying Y here will enable the hardware MUX serial driver for
559 the Nova and K class systems. The hardware MUX is not 8250/16550 559 the Nova, K class systems and D class with a 'remote control card'.
560 compatible therefore the /dev/ttyB0 device is shared between the 560 The hardware MUX is not 8250/16550 compatible therefore the
561 Serial MUX and the PDC software console. The following steps 561 /dev/ttyB0 device is shared between the Serial MUX and the PDC
562 need to be completed to use the Serial MUX: 562 software console. The following steps need to be completed to use
563 the Serial MUX:
563 564
564 1. create the device entry (mknod /dev/ttyB0 c 11 0) 565 1. create the device entry (mknod /dev/ttyB0 c 11 0)
565 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0 566 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 32b5d625ce9c..5bcdaaf4eae0 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -29,6 +29,7 @@
29#include <linux/personality.h> 29#include <linux/personality.h>
30#include <linux/init.h> 30#include <linux/init.h>
31 31
32#include <asm/a.out.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include <asm/pgtable.h> 34#include <asm/pgtable.h>
34 35
@@ -194,6 +195,7 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
194 unsigned long som_entry; 195 unsigned long som_entry;
195 struct som_hdr *som_ex; 196 struct som_hdr *som_ex;
196 struct som_exec_auxhdr *hpuxhdr; 197 struct som_exec_auxhdr *hpuxhdr;
198 struct files_struct *files;
197 199
198 /* Get the exec-header */ 200 /* Get the exec-header */
199 som_ex = (struct som_hdr *) bprm->buf; 201 som_ex = (struct som_hdr *) bprm->buf;
@@ -208,15 +210,27 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
208 size = som_ex->aux_header_size; 210 size = som_ex->aux_header_size;
209 if (size > SOM_PAGESIZE) 211 if (size > SOM_PAGESIZE)
210 goto out; 212 goto out;
211 hpuxhdr = (struct som_exec_auxhdr *) kmalloc(size, GFP_KERNEL); 213 hpuxhdr = kmalloc(size, GFP_KERNEL);
212 if (!hpuxhdr) 214 if (!hpuxhdr)
213 goto out; 215 goto out;
214 216
215 retval = kernel_read(bprm->file, som_ex->aux_header_location, 217 retval = kernel_read(bprm->file, som_ex->aux_header_location,
216 (char *) hpuxhdr, size); 218 (char *) hpuxhdr, size);
219 if (retval != size) {
220 if (retval >= 0)
221 retval = -EIO;
222 goto out_free;
223 }
224
225 files = current->files; /* Refcounted so ok */
226 retval = unshare_files();
217 if (retval < 0) 227 if (retval < 0)
218 goto out_free; 228 goto out_free;
219#error "Fix security hole before enabling me" 229 if (files == current->files) {
230 put_files_struct(files);
231 files = NULL;
232 }
233
220 retval = get_unused_fd(); 234 retval = get_unused_fd();
221 if (retval < 0) 235 if (retval < 0)
222 goto out_free; 236 goto out_free;
diff --git a/include/asm-parisc/agp.h b/include/asm-parisc/agp.h
new file mode 100644
index 000000000000..9f61d4eb6c01
--- /dev/null
+++ b/include/asm-parisc/agp.h
@@ -0,0 +1,25 @@
1#ifndef _ASM_PARISC_AGP_H
2#define _ASM_PARISC_AGP_H
3
4/*
5 * PARISC specific AGP definitions.
6 * Copyright (c) 2006 Kyle McMartin <kyle@parisc-linux.org>
7 *
8 */
9
10#define map_page_into_agp(page) /* nothing */
11#define unmap_page_from_agp(page) /* nothing */
12#define flush_agp_mappings() /* nothing */
13#define flush_agp_cache() mb()
14
15/* Convert a physical address to an address suitable for the GART. */
16#define phys_to_gart(x) (x)
17#define gart_to_phys(x) (x)
18
19/* GATT allocation. Returns/accepts GATT kernel virtual address. */
20#define alloc_gatt_pages(order) \
21 ((char *)__get_free_pages(GFP_KERNEL, (order)))
22#define free_gatt_pages(table, order) \
23 free_pages((unsigned long)(table), (order))
24
25#endif /* _ASM_PARISC_AGP_H */
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
index 1a7bfe699e0c..5a1e0e8b1c32 100644
--- a/include/asm-parisc/assembly.h
+++ b/include/asm-parisc/assembly.h
@@ -29,7 +29,8 @@
29#define LDREGX ldd,s 29#define LDREGX ldd,s
30#define LDREGM ldd,mb 30#define LDREGM ldd,mb
31#define STREGM std,ma 31#define STREGM std,ma
32#define SHRREG shrd 32#define SHRREG shrd
33#define SHLREG shld
33#define RP_OFFSET 16 34#define RP_OFFSET 16
34#define FRAME_SIZE 128 35#define FRAME_SIZE 128
35#define CALLEE_REG_FRAME_SIZE 144 36#define CALLEE_REG_FRAME_SIZE 144
@@ -39,7 +40,8 @@
39#define LDREGX ldwx,s 40#define LDREGX ldwx,s
40#define LDREGM ldwm 41#define LDREGM ldwm
41#define STREGM stwm 42#define STREGM stwm
42#define SHRREG shr 43#define SHRREG shr
44#define SHLREG shlw
43#define RP_OFFSET 20 45#define RP_OFFSET 20
44#define FRAME_SIZE 64 46#define FRAME_SIZE 64
45#define CALLEE_REG_FRAME_SIZE 128 47#define CALLEE_REG_FRAME_SIZE 128
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index 0b459cdfbd6f..2bc41f2e0271 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -191,16 +191,38 @@ flush_anon_page(struct page *page, unsigned long vmaddr)
191} 191}
192#define ARCH_HAS_FLUSH_ANON_PAGE 192#define ARCH_HAS_FLUSH_ANON_PAGE
193 193
194static inline void 194#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
195flush_kernel_dcache_page(struct page *page) 195void flush_kernel_dcache_page_addr(void *addr);
196static inline void flush_kernel_dcache_page(struct page *page)
196{ 197{
197 flush_kernel_dcache_page_asm(page_address(page)); 198 flush_kernel_dcache_page_addr(page_address(page));
198} 199}
199#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
200 200
201#ifdef CONFIG_DEBUG_RODATA 201#ifdef CONFIG_DEBUG_RODATA
202void mark_rodata_ro(void); 202void mark_rodata_ro(void);
203#endif 203#endif
204 204
205#ifdef CONFIG_PA8X00
206/* Only pa8800, pa8900 needs this */
207#define ARCH_HAS_KMAP
208
209void kunmap_parisc(void *addr);
210
211static inline void *kmap(struct page *page)
212{
213 might_sleep();
214 return page_address(page);
215}
216
217#define kunmap(page) kunmap_parisc(page_address(page))
218
219#define kmap_atomic(page, idx) page_address(page)
220
221#define kunmap_atomic(addr, idx) kunmap_parisc(addr)
222
223#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn))
224#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
225#endif
226
205#endif /* _PARISC_CACHEFLUSH_H */ 227#endif /* _PARISC_CACHEFLUSH_H */
206 228
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
index 71b4eeea205a..fe8579023531 100644
--- a/include/asm-parisc/compat.h
+++ b/include/asm-parisc/compat.h
@@ -5,7 +5,7 @@
5 */ 5 */
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/personality.h> 8#include <linux/thread_info.h>
9 9
10#define COMPAT_USER_HZ 100 10#define COMPAT_USER_HZ 100
11 11
@@ -152,7 +152,7 @@ static __inline__ void __user *compat_alloc_user_space(long len)
152 152
153static inline int __is_compat_task(struct task_struct *t) 153static inline int __is_compat_task(struct task_struct *t)
154{ 154{
155 return personality(t->personality) == PER_LINUX32; 155 return test_ti_thread_flag(t->thread_info, TIF_32BIT);
156} 156}
157 157
158static inline int is_compat_task(void) 158static inline int is_compat_task(void)
diff --git a/include/asm-parisc/dma.h b/include/asm-parisc/dma.h
index 9979c3cb3745..da2cf373e31c 100644
--- a/include/asm-parisc/dma.h
+++ b/include/asm-parisc/dma.h
@@ -72,18 +72,13 @@
72#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ 72#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
73#define DMA2_EXT_MODE_REG (0x400 | DMA2_MODE_REG) 73#define DMA2_EXT_MODE_REG (0x400 | DMA2_MODE_REG)
74 74
75extern spinlock_t dma_spin_lock;
76
77static __inline__ unsigned long claim_dma_lock(void) 75static __inline__ unsigned long claim_dma_lock(void)
78{ 76{
79 unsigned long flags; 77 return 0;
80 spin_lock_irqsave(&dma_spin_lock, flags);
81 return flags;
82} 78}
83 79
84static __inline__ void release_dma_lock(unsigned long flags) 80static __inline__ void release_dma_lock(unsigned long flags)
85{ 81{
86 spin_unlock_irqrestore(&dma_spin_lock, flags);
87} 82}
88 83
89 84
diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h
index 6a332a9f099c..d84bbb283fd1 100644
--- a/include/asm-parisc/futex.h
+++ b/include/asm-parisc/futex.h
@@ -1,6 +1,71 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_PARISC_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_PARISC_FUTEX_H
3 3
4#include <asm-generic/futex.h> 4#ifdef __KERNEL__
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52/* Non-atomic version */
53static inline int
54futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
55{
56 int err = 0;
57 int uval;
58
59 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
60 return -EFAULT;
61
62 err = get_user(uval, uaddr);
63 if (err) return -EFAULT;
64 if (uval == oldval)
65 err = put_user(newval, uaddr);
66 if (err) return -EFAULT;
67 return uval;
68}
69
70#endif
6#endif 71#endif
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index b9eb245b8874..c1963ce19dd2 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -134,7 +134,7 @@ extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
134} 134}
135#define ioremap_nocache(off, sz) ioremap((off), (sz)) 135#define ioremap_nocache(off, sz) ioremap((off), (sz))
136 136
137extern void iounmap(void __iomem *addr); 137extern void iounmap(const volatile void __iomem *addr);
138 138
139static inline unsigned char __raw_readb(const volatile void __iomem *addr) 139static inline unsigned char __raw_readb(const volatile void __iomem *addr)
140{ 140{
diff --git a/include/asm-parisc/iosapic.h b/include/asm-parisc/iosapic.h
deleted file mode 100644
index 613390e6805c..000000000000
--- a/include/asm-parisc/iosapic.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2** This file is private to iosapic driver.
3** If stuff needs to be used by another driver, move it to a common file.
4**
5** WARNING: fields most data structures here are ordered to make sure
6** they pack nicely for 64-bit compilation. (ie sizeof(long) == 8)
7*/
8
9
10/*
11** I/O SAPIC init function
12** Caller knows where an I/O SAPIC is. LBA has an integrated I/O SAPIC.
13** Call setup as part of per instance initialization.
14** (ie *not* init_module() function unless only one is present.)
15** fixup_irq is to initialize PCI IRQ line support and
16** virtualize pcidev->irq value. To be called by pci_fixup_bus().
17*/
18extern void *iosapic_register(unsigned long hpa);
19extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev);
20
21
22#ifdef __IA64__
23/*
24** PA: PIB (Processor Interrupt Block) is handled by Runway bus adapter.
25** and is hardcoded to 0xfeeNNNN0 where NNNN is id_eid field.
26**
27** IA64: PIB is handled by "Local SAPIC" (integrated in the processor).
28*/
29struct local_sapic_info {
30 struct local_sapic_info *lsi_next; /* point to next CPU info */
31 int *lsi_cpu_id; /* point to logical CPU id */
32 unsigned long *lsi_id_eid; /* point to IA-64 CPU id */
33 int *lsi_status; /* point to CPU status */
34 void *lsi_private; /* point to special info */
35};
36
37/*
38** "root" data structure which ties everything together.
39** Should always be able to start with sapic_root and locate
40** the desired information.
41*/
42struct sapic_info {
43 struct sapic_info *si_next; /* info is per cell */
44 int si_cellid; /* cell id */
45 unsigned int si_status; /* status */
46 char *si_pib_base; /* intr blk base address */
47 local_sapic_info_t *si_local_info;
48 io_sapic_info_t *si_io_info;
49 extint_info_t *si_extint_info;/* External Intr info */
50};
51
52#endif /* IA64 */
53
diff --git a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
index 5cae260615a2..399c81981ed5 100644
--- a/include/asm-parisc/irq.h
+++ b/include/asm-parisc/irq.h
@@ -31,7 +31,7 @@ static __inline__ int irq_canonicalize(int irq)
31 return (irq == 2) ? 9 : irq; 31 return (irq == 2) ? 9 : irq;
32} 32}
33 33
34struct hw_interrupt_type; 34struct irq_chip;
35 35
36/* 36/*
37 * Some useful "we don't have to do anything here" handlers. Should 37 * Some useful "we don't have to do anything here" handlers. Should
@@ -39,6 +39,8 @@ struct hw_interrupt_type;
39 */ 39 */
40void no_ack_irq(unsigned int irq); 40void no_ack_irq(unsigned int irq);
41void no_end_irq(unsigned int irq); 41void no_end_irq(unsigned int irq);
42void cpu_ack_irq(unsigned int irq);
43void cpu_end_irq(unsigned int irq);
42 44
43extern int txn_alloc_irq(unsigned int nbits); 45extern int txn_alloc_irq(unsigned int nbits);
44extern int txn_claim_irq(int); 46extern int txn_claim_irq(int);
@@ -46,7 +48,7 @@ extern unsigned int txn_alloc_data(unsigned int);
46extern unsigned long txn_alloc_addr(unsigned int); 48extern unsigned long txn_alloc_addr(unsigned int);
47extern unsigned long txn_affinity_addr(unsigned int irq, int cpu); 49extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
48 50
49extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *); 51extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *);
50extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest); 52extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest);
51 53
52/* soft power switch support (power.c) */ 54/* soft power switch support (power.c) */
diff --git a/include/asm-parisc/mckinley.h b/include/asm-parisc/mckinley.h
new file mode 100644
index 000000000000..d1ea6f12915e
--- /dev/null
+++ b/include/asm-parisc/mckinley.h
@@ -0,0 +1,9 @@
1#ifndef ASM_PARISC_MCKINLEY_H
2#define ASM_PARISC_MCKINLEY_H
3#ifdef __KERNEL__
4
5/* declared in arch/parisc/kernel/setup.c */
6extern struct proc_dir_entry * proc_mckinley_root;
7
8#endif /*__KERNEL__*/
9#endif /*ASM_PARISC_MCKINLEY_H*/
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index 57d6d82756dd..3567208191e3 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -26,24 +26,10 @@
26 26
27struct page; 27struct page;
28 28
29extern void purge_kernel_dcache_page(unsigned long); 29void copy_user_page_asm(void *to, void *from);
30extern void copy_user_page_asm(void *to, void *from); 30void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
31extern void clear_user_page_asm(void *page, unsigned long vaddr); 31 struct page *pg);
32 32void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
33static inline void
34copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg)
35{
36 copy_user_page_asm(vto, vfrom);
37 flush_kernel_dcache_page_asm(vto);
38 /* XXX: ppc flushes icache too, should we? */
39}
40
41static inline void
42clear_user_page(void *page, unsigned long vaddr, struct page *pg)
43{
44 purge_kernel_dcache_page((unsigned long)page);
45 clear_user_page_asm(page, vaddr);
46}
47 33
48/* 34/*
49 * These are used to make use of C type-checking.. 35 * These are used to make use of C type-checking..
diff --git a/include/asm-parisc/param.h b/include/asm-parisc/param.h
index 07cb9b93cfe2..32e03d877858 100644
--- a/include/asm-parisc/param.h
+++ b/include/asm-parisc/param.h
@@ -2,13 +2,9 @@
2#define _ASMPARISC_PARAM_H 2#define _ASMPARISC_PARAM_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5# ifdef CONFIG_PA20 5#define HZ CONFIG_HZ
6# define HZ 1000 /* Faster machines */ 6#define USER_HZ 100 /* some user API use "ticks" */
7# else 7#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
8# define HZ 100 /* Internal kernel timer frequency */
9# endif
10# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
11# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
12#endif 8#endif
13 9
14#ifndef HZ 10#ifndef HZ
diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
index 1d247e32a608..e12624d8941d 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/include/asm-parisc/parisc-device.h
@@ -1,3 +1,6 @@
1#ifndef _ASM_PARISC_PARISC_DEVICE_H_
2#define _ASM_PARISC_PARISC_DEVICE_H_
3
1#include <linux/device.h> 4#include <linux/device.h>
2 5
3struct parisc_device { 6struct parisc_device {
@@ -57,3 +60,5 @@ parisc_get_drvdata(struct parisc_device *d)
57} 60}
58 61
59extern struct bus_type parisc_bus_type; 62extern struct bus_type parisc_bus_type;
63
64#endif /*_ASM_PARISC_PARISC_DEVICE_H_*/
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 8b631f47eb25..7b8ad118d2fe 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -293,4 +293,9 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
293 /* We don't need to penalize isa irq's */ 293 /* We don't need to penalize isa irq's */
294} 294}
295 295
296static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
297{
298 return channel ? 15 : 14;
299}
300
296#endif /* __ASM_PARISC_PCI_H */ 301#endif /* __ASM_PARISC_PCI_H */
diff --git a/include/asm-parisc/prefetch.h b/include/asm-parisc/prefetch.h
new file mode 100644
index 000000000000..5d021726fa33
--- /dev/null
+++ b/include/asm-parisc/prefetch.h
@@ -0,0 +1,39 @@
1/*
2 * include/asm-parisc/prefetch.h
3 *
4 * PA 2.0 defines data prefetch instructions on page 6-11 of the Kane book.
5 * In addition, many implementations do hardware prefetching of both
6 * instructions and data.
7 *
8 * PA7300LC (page 14-4 of the ERS) also implements prefetching by a load
9 * to gr0 but not in a way that Linux can use. If the load would cause an
10 * interruption (eg due to prefetching 0), it is suppressed on PA2.0
11 * processors, but not on 7300LC.
12 *
13 */
14
15#ifndef __ASM_PARISC_PREFETCH_H
16#define __ASM_PARISC_PREFETCH_H
17
18#ifndef __ASSEMBLY__
19#ifdef CONFIG_PREFETCH
20
21#define ARCH_HAS_PREFETCH
22extern inline void prefetch(const void *addr)
23{
24 __asm__("ldw 0(%0), %%r0" : : "r" (addr));
25}
26
27/* LDD is a PA2.0 addition. */
28#ifdef CONFIG_PA20
29#define ARCH_HAS_PREFETCHW
30extern inline void prefetchw(const void *addr)
31{
32 __asm__("ldd 0(%0), %%r0" : : "r" (addr));
33}
34#endif /* CONFIG_PA20 */
35
36#endif /* CONFIG_PREFETCH */
37#endif /* __ASSEMBLY__ */
38
39#endif /* __ASM_PARISC_PROCESSOR_H */
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index b73626f040da..fd7866dc8c83 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -9,6 +9,8 @@
9#define __ASM_PARISC_PROCESSOR_H 9#define __ASM_PARISC_PROCESSOR_H
10 10
11#ifndef __ASSEMBLY__ 11#ifndef __ASSEMBLY__
12#include <asm/prefetch.h> /* lockdep.h needs <linux/prefetch.h> */
13
12#include <linux/threads.h> 14#include <linux/threads.h>
13#include <linux/spinlock_types.h> 15#include <linux/spinlock_types.h>
14 16
@@ -276,7 +278,7 @@ on downward growing arches, it looks like this:
276 */ 278 */
277 279
278#ifdef __LP64__ 280#ifdef __LP64__
279#define USER_WIDE_MODE (personality(current->personality) == PER_LINUX) 281#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
280#else 282#else
281#define USER_WIDE_MODE 0 283#define USER_WIDE_MODE 0
282#endif 284#endif
@@ -328,33 +330,20 @@ extern unsigned long get_wchan(struct task_struct *p);
328#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0]) 330#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
329#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30]) 331#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30])
330 332
333#define cpu_relax() barrier()
331 334
332/* 335/* Used as a macro to identify the combined VIPT/PIPT cached
333 * PA 2.0 defines data prefetch instructions on page 6-11 of the Kane book. 336 * CPUs which require a guarantee of coherency (no inequivalent
334 * In addition, many implementations do hardware prefetching of both 337 * aliases with different data, whether clean or not) to operate */
335 * instructions and data. 338static inline int parisc_requires_coherency(void)
336 *
337 * PA7300LC (page 14-4 of the ERS) also implements prefetching by a load
338 * to gr0 but not in a way that Linux can use. If the load would cause an
339 * interruption (eg due to prefetching 0), it is suppressed on PA2.0
340 * processors, but not on 7300LC.
341 */
342#ifdef CONFIG_PREFETCH
343#define ARCH_HAS_PREFETCH
344#define ARCH_HAS_PREFETCHW
345
346extern inline void prefetch(const void *addr)
347{
348 __asm__("ldw 0(%0), %%r0" : : "r" (addr));
349}
350
351extern inline void prefetchw(const void *addr)
352{ 339{
353 __asm__("ldd 0(%0), %%r0" : : "r" (addr)); 340#ifdef CONFIG_PA8X00
354} 341 /* FIXME: also pa8900 - when we see one */
342 return boot_cpu_data.cpu_type == mako;
343#else
344 return 0;
355#endif 345#endif
356 346}
357#define cpu_relax() barrier()
358 347
359#endif /* __ASSEMBLY__ */ 348#endif /* __ASSEMBLY__ */
360 349
diff --git a/include/asm-parisc/ropes.h b/include/asm-parisc/ropes.h
new file mode 100644
index 000000000000..5542dd00472b
--- /dev/null
+++ b/include/asm-parisc/ropes.h
@@ -0,0 +1,322 @@
1#ifndef _ASM_PARISC_ROPES_H_
2#define _ASM_PARISC_ROPES_H_
3
4#include <asm-parisc/parisc-device.h>
5
6#ifdef CONFIG_64BIT
7/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
8#define ZX1_SUPPORT
9#endif
10
11#ifdef CONFIG_PROC_FS
12/* depends on proc fs support. But costs CPU performance */
13#undef SBA_COLLECT_STATS
14#endif
15
16/*
17** The number of pdir entries to "free" before issueing
18** a read to PCOM register to flush out PCOM writes.
19** Interacts with allocation granularity (ie 4 or 8 entries
20** allocated and free'd/purged at a time might make this
21** less interesting).
22*/
23#define DELAYED_RESOURCE_CNT 16
24
25#define MAX_IOC 2 /* per Ike. Pluto/Astro only have 1. */
26#define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */
27
28struct ioc {
29 void __iomem *ioc_hpa; /* I/O MMU base address */
30 char *res_map; /* resource map, bit == pdir entry */
31 u64 *pdir_base; /* physical base address */
32 unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */
33 unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */
34#ifdef ZX1_SUPPORT
35 unsigned long iovp_mask; /* help convert IOVA to IOVP */
36#endif
37 unsigned long *res_hint; /* next avail IOVP - circular search */
38 spinlock_t res_lock;
39 unsigned int res_bitshift; /* from the LEFT! */
40 unsigned int res_size; /* size of resource map in bytes */
41#ifdef SBA_HINT_SUPPORT
42/* FIXME : DMA HINTs not used */
43 unsigned long hint_mask_pdir; /* bits used for DMA hints */
44 unsigned int hint_shift_pdir;
45#endif
46#if DELAYED_RESOURCE_CNT > 0
47 int saved_cnt;
48 struct sba_dma_pair {
49 dma_addr_t iova;
50 size_t size;
51 } saved[DELAYED_RESOURCE_CNT];
52#endif
53
54#ifdef SBA_COLLECT_STATS
55#define SBA_SEARCH_SAMPLE 0x100
56 unsigned long avg_search[SBA_SEARCH_SAMPLE];
57 unsigned long avg_idx; /* current index into avg_search */
58 unsigned long used_pages;
59 unsigned long msingle_calls;
60 unsigned long msingle_pages;
61 unsigned long msg_calls;
62 unsigned long msg_pages;
63 unsigned long usingle_calls;
64 unsigned long usingle_pages;
65 unsigned long usg_calls;
66 unsigned long usg_pages;
67#endif
68 /* STUFF We don't need in performance path */
69 unsigned int pdir_size; /* in bytes, determined by IOV Space size */
70};
71
72struct sba_device {
73 struct sba_device *next; /* list of SBA's in system */
74 struct parisc_device *dev; /* dev found in bus walk */
75 const char *name;
76 void __iomem *sba_hpa; /* base address */
77 spinlock_t sba_lock;
78 unsigned int flags; /* state/functionality enabled */
79 unsigned int hw_rev; /* HW revision of chip */
80
81 struct resource chip_resv; /* MMIO reserved for chip */
82 struct resource iommu_resv; /* MMIO reserved for iommu */
83
84 unsigned int num_ioc; /* number of on-board IOC's */
85 struct ioc ioc[MAX_IOC];
86};
87
88#define ASTRO_RUNWAY_PORT 0x582
89#define IKE_MERCED_PORT 0x803
90#define REO_MERCED_PORT 0x804
91#define REOG_MERCED_PORT 0x805
92#define PLUTO_MCKINLEY_PORT 0x880
93
94static inline int IS_ASTRO(struct parisc_device *d) {
95 return d->id.hversion == ASTRO_RUNWAY_PORT;
96}
97
98static inline int IS_IKE(struct parisc_device *d) {
99 return d->id.hversion == IKE_MERCED_PORT;
100}
101
102static inline int IS_PLUTO(struct parisc_device *d) {
103 return d->id.hversion == PLUTO_MCKINLEY_PORT;
104}
105
106#define PLUTO_IOVA_BASE (1UL*1024*1024*1024) /* 1GB */
107#define PLUTO_IOVA_SIZE (1UL*1024*1024*1024) /* 1GB */
108#define PLUTO_GART_SIZE (PLUTO_IOVA_SIZE / 2)
109
110#define SBA_PDIR_VALID_BIT 0x8000000000000000ULL
111
112#define SBA_AGPGART_COOKIE 0x0000badbadc0ffeeULL
113
114#define SBA_FUNC_ID 0x0000 /* function id */
115#define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */
116
117#define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */
118
119#define ASTRO_IOC_OFFSET (32 * SBA_FUNC_SIZE)
120#define PLUTO_IOC_OFFSET (1 * SBA_FUNC_SIZE)
121/* Ike's IOC's occupy functions 2 and 3 */
122#define IKE_IOC_OFFSET(p) ((p+2) * SBA_FUNC_SIZE)
123
124#define IOC_CTRL 0x8 /* IOC_CTRL offset */
125#define IOC_CTRL_TC (1 << 0) /* TOC Enable */
126#define IOC_CTRL_CE (1 << 1) /* Coalesce Enable */
127#define IOC_CTRL_DE (1 << 2) /* Dillon Enable */
128#define IOC_CTRL_RM (1 << 8) /* Real Mode */
129#define IOC_CTRL_NC (1 << 9) /* Non Coherent Mode */
130#define IOC_CTRL_D4 (1 << 11) /* Disable 4-byte coalescing */
131#define IOC_CTRL_DD (1 << 13) /* Disable distr. LMMIO range coalescing */
132
133/*
134** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
135** Firmware programs this stuff. Don't touch it.
136*/
137#define LMMIO_DIRECT0_BASE 0x300
138#define LMMIO_DIRECT0_MASK 0x308
139#define LMMIO_DIRECT0_ROUTE 0x310
140
141#define LMMIO_DIST_BASE 0x360
142#define LMMIO_DIST_MASK 0x368
143#define LMMIO_DIST_ROUTE 0x370
144
145#define IOS_DIST_BASE 0x390
146#define IOS_DIST_MASK 0x398
147#define IOS_DIST_ROUTE 0x3A0
148
149#define IOS_DIRECT_BASE 0x3C0
150#define IOS_DIRECT_MASK 0x3C8
151#define IOS_DIRECT_ROUTE 0x3D0
152
153/*
154** Offsets into I/O TLB (Function 2 and 3 on Ike)
155*/
156#define ROPE0_CTL 0x200 /* "regbus pci0" */
157#define ROPE1_CTL 0x208
158#define ROPE2_CTL 0x210
159#define ROPE3_CTL 0x218
160#define ROPE4_CTL 0x220
161#define ROPE5_CTL 0x228
162#define ROPE6_CTL 0x230
163#define ROPE7_CTL 0x238
164
165#define IOC_ROPE0_CFG 0x500 /* pluto only */
166#define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */
167
168#define HF_ENABLE 0x40
169
170#define IOC_IBASE 0x300 /* IO TLB */
171#define IOC_IMASK 0x308
172#define IOC_PCOM 0x310
173#define IOC_TCNFG 0x318
174#define IOC_PDIR_BASE 0x320
175
176/*
177** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
178** It's safer (avoid memory corruption) to keep DMA page mappings
179** equivalently sized to VM PAGE_SIZE.
180**
181** We really can't avoid generating a new mapping for each
182** page since the Virtual Coherence Index has to be generated
183** and updated for each page.
184**
185** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
186*/
187#define IOVP_SIZE PAGE_SIZE
188#define IOVP_SHIFT PAGE_SHIFT
189#define IOVP_MASK PAGE_MASK
190
191#define SBA_PERF_CFG 0x708 /* Performance Counter stuff */
192#define SBA_PERF_MASK1 0x718
193#define SBA_PERF_MASK2 0x730
194
195/*
196** Offsets into PCI Performance Counters (functions 12 and 13)
197** Controlled by PERF registers in function 2 & 3 respectively.
198*/
199#define SBA_PERF_CNT1 0x200
200#define SBA_PERF_CNT2 0x208
201#define SBA_PERF_CNT3 0x210
202
203/*
204** lba_device: Per instance Elroy data structure
205*/
206struct lba_device {
207 struct pci_hba_data hba;
208
209 spinlock_t lba_lock;
210 void *iosapic_obj;
211
212#ifdef CONFIG_64BIT
213 void __iomem *iop_base; /* PA_VIEW - for IO port accessor funcs */
214#endif
215
216 int flags; /* state/functionality enabled */
217 int hw_rev; /* HW revision of chip */
218};
219
220#define ELROY_HVERS 0x782
221#define MERCURY_HVERS 0x783
222#define QUICKSILVER_HVERS 0x784
223
224static inline int IS_ELROY(struct parisc_device *d) {
225 return (d->id.hversion == ELROY_HVERS);
226}
227
228static inline int IS_MERCURY(struct parisc_device *d) {
229 return (d->id.hversion == MERCURY_HVERS);
230}
231
232static inline int IS_QUICKSILVER(struct parisc_device *d) {
233 return (d->id.hversion == QUICKSILVER_HVERS);
234}
235
236static inline int agp_mode_mercury(void __iomem *hpa) {
237 u64 bus_mode;
238
239 bus_mode = readl(hpa + 0x0620);
240 if (bus_mode & 1)
241 return 1;
242
243 return 0;
244}
245
246/*
247** I/O SAPIC init function
248** Caller knows where an I/O SAPIC is. LBA has an integrated I/O SAPIC.
249** Call setup as part of per instance initialization.
250** (ie *not* init_module() function unless only one is present.)
251** fixup_irq is to initialize PCI IRQ line support and
252** virtualize pcidev->irq value. To be called by pci_fixup_bus().
253*/
254extern void *iosapic_register(unsigned long hpa);
255extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev);
256
257#define LBA_FUNC_ID 0x0000 /* function id */
258#define LBA_FCLASS 0x0008 /* function class, bist, header, rev... */
259#define LBA_CAPABLE 0x0030 /* capabilities register */
260
261#define LBA_PCI_CFG_ADDR 0x0040 /* poke CFG address here */
262#define LBA_PCI_CFG_DATA 0x0048 /* read or write data here */
263
264#define LBA_PMC_MTLT 0x0050 /* Firmware sets this - read only. */
265#define LBA_FW_SCRATCH 0x0058 /* Firmware writes the PCI bus number here. */
266#define LBA_ERROR_ADDR 0x0070 /* On error, address gets logged here */
267
268#define LBA_ARB_MASK 0x0080 /* bit 0 enable arbitration. PAT/PDC enables */
269#define LBA_ARB_PRI 0x0088 /* firmware sets this. */
270#define LBA_ARB_MODE 0x0090 /* firmware sets this. */
271#define LBA_ARB_MTLT 0x0098 /* firmware sets this. */
272
273#define LBA_MOD_ID 0x0100 /* Module ID. PDC_PAT_CELL reports 4 */
274
275#define LBA_STAT_CTL 0x0108 /* Status & Control */
276#define LBA_BUS_RESET 0x01 /* Deassert PCI Bus Reset Signal */
277#define CLEAR_ERRLOG 0x10 /* "Clear Error Log" cmd */
278#define CLEAR_ERRLOG_ENABLE 0x20 /* "Clear Error Log" Enable */
279#define HF_ENABLE 0x40 /* enable HF mode (default is -1 mode) */
280
281#define LBA_LMMIO_BASE 0x0200 /* < 4GB I/O address range */
282#define LBA_LMMIO_MASK 0x0208
283
284#define LBA_GMMIO_BASE 0x0210 /* > 4GB I/O address range */
285#define LBA_GMMIO_MASK 0x0218
286
287#define LBA_WLMMIO_BASE 0x0220 /* All < 4GB ranges under the same *SBA* */
288#define LBA_WLMMIO_MASK 0x0228
289
290#define LBA_WGMMIO_BASE 0x0230 /* All > 4GB ranges under the same *SBA* */
291#define LBA_WGMMIO_MASK 0x0238
292
293#define LBA_IOS_BASE 0x0240 /* I/O port space for this LBA */
294#define LBA_IOS_MASK 0x0248
295
296#define LBA_ELMMIO_BASE 0x0250 /* Extra LMMIO range */
297#define LBA_ELMMIO_MASK 0x0258
298
299#define LBA_EIOS_BASE 0x0260 /* Extra I/O port space */
300#define LBA_EIOS_MASK 0x0268
301
302#define LBA_GLOBAL_MASK 0x0270 /* Mercury only: Global Address Mask */
303#define LBA_DMA_CTL 0x0278 /* firmware sets this */
304
305#define LBA_IBASE 0x0300 /* SBA DMA support */
306#define LBA_IMASK 0x0308
307
308/* FIXME: ignore DMA Hint stuff until we can measure performance */
309#define LBA_HINT_CFG 0x0310
310#define LBA_HINT_BASE 0x0380 /* 14 registers at every 8 bytes. */
311
312#define LBA_BUS_MODE 0x0620
313
314/* ERROR regs are needed for config cycle kluges */
315#define LBA_ERROR_CONFIG 0x0680
316#define LBA_SMART_MODE 0x20
317#define LBA_ERROR_STATUS 0x0688
318#define LBA_ROPE_CTL 0x06A0
319
320#define LBA_IOSAPIC_BASE 0x800 /* Offset of IRQ logic */
321
322#endif /*_ASM_PARISC_ROPES_H_*/
diff --git a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h
index 82fd820d684f..d7e3cc60dbc3 100644
--- a/include/asm-parisc/serial.h
+++ b/include/asm-parisc/serial.h
@@ -3,20 +3,8 @@
3 */ 3 */
4 4
5/* 5/*
6 * This assumes you have a 7.272727 MHz clock for your UART. 6 * This is used for 16550-compatible UARTs
7 * The documentation implies a 40Mhz clock, and elsewhere a 7Mhz clock
8 * Clarified: 7.2727MHz on LASI. Not yet clarified for DINO
9 */ 7 */
8#define BASE_BAUD ( 1843200 / 16 )
10 9
11#define LASI_BASE_BAUD ( 7272727 / 16 )
12#define BASE_BAUD LASI_BASE_BAUD
13
14/*
15 * We don't use the ISA probing code, so these entries are just to reserve
16 * space. Some example (maximal) configurations:
17 * - 712 w/ additional Lasi & RJ16 ports: 4
18 * - J5k w/ PCI serial cards: 2 + 4 * card ~= 34
19 * A500 w/ PCI serial cards: 5 + 4 * card ~= 17
20 */
21
22#define SERIAL_PORT_DFNS 10#define SERIAL_PORT_DFNS
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index e1825530365d..f3d2090a18dc 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -56,50 +56,79 @@ static inline int __raw_spin_trylock(raw_spinlock_t *x)
56} 56}
57 57
58/* 58/*
59 * Read-write spinlocks, allowing multiple readers 59 * Read-write spinlocks, allowing multiple readers but only one writer.
60 * but only one writer. 60 * Linux rwlocks are unfair to writers; they can be starved for an indefinite
61 * time by readers. With care, they can also be taken in interrupt context.
62 *
63 * In the PA-RISC implementation, we have a spinlock and a counter.
64 * Readers use the lock to serialise their access to the counter (which
65 * records how many readers currently hold the lock).
66 * Writers hold the spinlock, preventing any readers or other writers from
67 * grabbing the rwlock.
61 */ 68 */
62 69
63#define __raw_read_trylock(lock) generic__raw_read_trylock(lock) 70/* Note that we have to ensure interrupts are disabled in case we're
64 71 * interrupted by some other code that wants to grab the same read lock */
65/* read_lock, read_unlock are pretty straightforward. Of course it somehow
66 * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
67
68static __inline__ void __raw_read_lock(raw_rwlock_t *rw) 72static __inline__ void __raw_read_lock(raw_rwlock_t *rw)
69{ 73{
70 __raw_spin_lock(&rw->lock); 74 unsigned long flags;
71 75 local_irq_save(flags);
76 __raw_spin_lock_flags(&rw->lock, flags);
72 rw->counter++; 77 rw->counter++;
73
74 __raw_spin_unlock(&rw->lock); 78 __raw_spin_unlock(&rw->lock);
79 local_irq_restore(flags);
75} 80}
76 81
82/* Note that we have to ensure interrupts are disabled in case we're
83 * interrupted by some other code that wants to grab the same read lock */
77static __inline__ void __raw_read_unlock(raw_rwlock_t *rw) 84static __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
78{ 85{
79 __raw_spin_lock(&rw->lock); 86 unsigned long flags;
80 87 local_irq_save(flags);
88 __raw_spin_lock_flags(&rw->lock, flags);
81 rw->counter--; 89 rw->counter--;
82
83 __raw_spin_unlock(&rw->lock); 90 __raw_spin_unlock(&rw->lock);
91 local_irq_restore(flags);
84} 92}
85 93
86/* write_lock is less trivial. We optimistically grab the lock and check 94/* Note that we have to ensure interrupts are disabled in case we're
87 * if we surprised any readers. If so we release the lock and wait till 95 * interrupted by some other code that wants to grab the same read lock */
88 * they're all gone before trying again 96static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
89 * 97{
90 * Also note that we don't use the _irqsave / _irqrestore suffixes here. 98 unsigned long flags;
91 * If we're called with interrupts enabled and we've got readers (or other 99 retry:
92 * writers) in interrupt handlers someone fucked up and we'd dead-lock 100 local_irq_save(flags);
93 * sooner or later anyway. prumpf */ 101 if (__raw_spin_trylock(&rw->lock)) {
102 rw->counter++;
103 __raw_spin_unlock(&rw->lock);
104 local_irq_restore(flags);
105 return 1;
106 }
94 107
95static __inline__ void __raw_write_lock(raw_rwlock_t *rw) 108 local_irq_restore(flags);
109 /* If write-locked, we fail to acquire the lock */
110 if (rw->counter < 0)
111 return 0;
112
113 /* Wait until we have a realistic chance at the lock */
114 while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0)
115 cpu_relax();
116
117 goto retry;
118}
119
120/* Note that we have to ensure interrupts are disabled in case we're
121 * interrupted by some other code that wants to read_trylock() this lock */
122static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
96{ 123{
124 unsigned long flags;
97retry: 125retry:
98 __raw_spin_lock(&rw->lock); 126 local_irq_save(flags);
127 __raw_spin_lock_flags(&rw->lock, flags);
99 128
100 if(rw->counter != 0) { 129 if (rw->counter != 0) {
101 /* this basically never happens */
102 __raw_spin_unlock(&rw->lock); 130 __raw_spin_unlock(&rw->lock);
131 local_irq_restore(flags);
103 132
104 while (rw->counter != 0) 133 while (rw->counter != 0)
105 cpu_relax(); 134 cpu_relax();
@@ -107,31 +136,37 @@ retry:
107 goto retry; 136 goto retry;
108 } 137 }
109 138
110 /* got it. now leave without unlocking */ 139 rw->counter = -1; /* mark as write-locked */
111 rw->counter = -1; /* remember we are locked */ 140 mb();
141 local_irq_restore(flags);
112} 142}
113 143
114/* write_unlock is absolutely trivial - we don't have to wait for anything */ 144static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
115
116static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
117{ 145{
118 rw->counter = 0; 146 rw->counter = 0;
119 __raw_spin_unlock(&rw->lock); 147 __raw_spin_unlock(&rw->lock);
120} 148}
121 149
122static __inline__ int __raw_write_trylock(raw_rwlock_t *rw) 150/* Note that we have to ensure interrupts are disabled in case we're
151 * interrupted by some other code that wants to read_trylock() this lock */
152static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
123{ 153{
124 __raw_spin_lock(&rw->lock); 154 unsigned long flags;
125 if (rw->counter != 0) { 155 int result = 0;
126 /* this basically never happens */ 156
127 __raw_spin_unlock(&rw->lock); 157 local_irq_save(flags);
128 158 if (__raw_spin_trylock(&rw->lock)) {
129 return 0; 159 if (rw->counter == 0) {
160 rw->counter = -1;
161 result = 1;
162 } else {
163 /* Read-locked. Oh well. */
164 __raw_spin_unlock(&rw->lock);
165 }
130 } 166 }
167 local_irq_restore(flags);
131 168
132 /* got it. now leave without unlocking */ 169 return result;
133 rw->counter = -1; /* remember we are locked */
134 return 1;
135} 170}
136 171
137/* 172/*
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h
index 88dafa246d87..952bee79a8f3 100644
--- a/include/linux/debug_locks.h
+++ b/include/linux/debug_locks.h
@@ -43,6 +43,8 @@ extern int debug_locks_off(void);
43# define locking_selftest() do { } while (0) 43# define locking_selftest() do { } while (0)
44#endif 44#endif
45 45
46struct task_struct;
47
46#ifdef CONFIG_LOCKDEP 48#ifdef CONFIG_LOCKDEP
47extern void debug_show_all_locks(void); 49extern void debug_show_all_locks(void);
48extern void debug_show_held_locks(struct task_struct *task); 50extern void debug_show_held_locks(struct task_struct *task);