aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 13:08:46 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 13:08:46 -0400
commit8ed575904373d7aaab7f15a8db2edc317a44df43 (patch)
tree3b2e92a396a1bbec8e1fb499f25e8aed93ab5692 /include
parent27d1097d39509494706eaa2620ef3b1e780a3224 (diff)
parent210cc679faf0e1cabda9fc5d1279644f5e52aecb (diff)
Merge branch 'forlinus' of git://parisc-linux.org/home/kyle/git/parisc-2.6
Diffstat (limited to 'include')
-rw-r--r--include/asm-parisc/assembly.h71
-rw-r--r--include/asm-parisc/bitops.h290
-rw-r--r--include/asm-parisc/errno.h1
-rw-r--r--include/asm-parisc/grfioctl.h2
-rw-r--r--include/asm-parisc/led.h3
-rw-r--r--include/asm-parisc/parisc-device.h7
-rw-r--r--include/asm-parisc/pci.h2
-rw-r--r--include/asm-parisc/pgtable.h2
-rw-r--r--include/asm-parisc/processor.h19
-rw-r--r--include/asm-parisc/psw.h51
-rw-r--r--include/asm-parisc/ptrace.h2
-rw-r--r--include/asm-parisc/spinlock.h5
-rw-r--r--include/asm-parisc/spinlock_types.h8
-rw-r--r--include/asm-parisc/system.h48
-rw-r--r--include/asm-parisc/tlbflush.h29
-rw-r--r--include/asm-parisc/types.h2
-rw-r--r--include/asm-parisc/unistd.h16
-rw-r--r--include/linux/hil.h483
-rw-r--r--include/linux/hil_mlc.h168
-rw-r--r--include/linux/hp_sdc.h300
-rw-r--r--include/linux/input.h1
21 files changed, 1270 insertions, 240 deletions
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
index 30b023411fef..3ce3440d1b0c 100644
--- a/include/asm-parisc/assembly.h
+++ b/include/asm-parisc/assembly.h
@@ -21,7 +21,9 @@
21#ifndef _PARISC_ASSEMBLY_H 21#ifndef _PARISC_ASSEMBLY_H
22#define _PARISC_ASSEMBLY_H 22#define _PARISC_ASSEMBLY_H
23 23
24#ifdef __LP64__ 24#define CALLEE_FLOAT_FRAME_SIZE 80
25
26#ifdef CONFIG_64BIT
25#define LDREG ldd 27#define LDREG ldd
26#define STREG std 28#define STREG std
27#define LDREGX ldd,s 29#define LDREGX ldd,s
@@ -30,8 +32,8 @@
30#define SHRREG shrd 32#define SHRREG shrd
31#define RP_OFFSET 16 33#define RP_OFFSET 16
32#define FRAME_SIZE 128 34#define FRAME_SIZE 128
33#define CALLEE_SAVE_FRAME_SIZE 144 35#define CALLEE_REG_FRAME_SIZE 144
34#else 36#else /* CONFIG_64BIT */
35#define LDREG ldw 37#define LDREG ldw
36#define STREG stw 38#define STREG stw
37#define LDREGX ldwx,s 39#define LDREGX ldwx,s
@@ -40,9 +42,11 @@
40#define SHRREG shr 42#define SHRREG shr
41#define RP_OFFSET 20 43#define RP_OFFSET 20
42#define FRAME_SIZE 64 44#define FRAME_SIZE 64
43#define CALLEE_SAVE_FRAME_SIZE 128 45#define CALLEE_REG_FRAME_SIZE 128
44#endif 46#endif
45 47
48#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
49
46#ifdef CONFIG_PA20 50#ifdef CONFIG_PA20
47#define BL b,l 51#define BL b,l
48# ifdef CONFIG_64BIT 52# ifdef CONFIG_64BIT
@@ -300,9 +304,35 @@
300 fldd,mb -8(\regs), %fr0 304 fldd,mb -8(\regs), %fr0
301 .endm 305 .endm
302 306
307 .macro callee_save_float
308 fstd,ma %fr12, 8(%r30)
309 fstd,ma %fr13, 8(%r30)
310 fstd,ma %fr14, 8(%r30)
311 fstd,ma %fr15, 8(%r30)
312 fstd,ma %fr16, 8(%r30)
313 fstd,ma %fr17, 8(%r30)
314 fstd,ma %fr18, 8(%r30)
315 fstd,ma %fr19, 8(%r30)
316 fstd,ma %fr20, 8(%r30)
317 fstd,ma %fr21, 8(%r30)
318 .endm
319
320 .macro callee_rest_float
321 fldd,mb -8(%r30), %fr21
322 fldd,mb -8(%r30), %fr20
323 fldd,mb -8(%r30), %fr19
324 fldd,mb -8(%r30), %fr18
325 fldd,mb -8(%r30), %fr17
326 fldd,mb -8(%r30), %fr16
327 fldd,mb -8(%r30), %fr15
328 fldd,mb -8(%r30), %fr14
329 fldd,mb -8(%r30), %fr13
330 fldd,mb -8(%r30), %fr12
331 .endm
332
303#ifdef __LP64__ 333#ifdef __LP64__
304 .macro callee_save 334 .macro callee_save
305 std,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30) 335 std,ma %r3, CALLEE_REG_FRAME_SIZE(%r30)
306 mfctl %cr27, %r3 336 mfctl %cr27, %r3
307 std %r4, -136(%r30) 337 std %r4, -136(%r30)
308 std %r5, -128(%r30) 338 std %r5, -128(%r30)
@@ -340,13 +370,13 @@
340 ldd -128(%r30), %r5 370 ldd -128(%r30), %r5
341 ldd -136(%r30), %r4 371 ldd -136(%r30), %r4
342 mtctl %r3, %cr27 372 mtctl %r3, %cr27
343 ldd,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3 373 ldd,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3
344 .endm 374 .endm
345 375
346#else /* ! __LP64__ */ 376#else /* ! __LP64__ */
347 377
348 .macro callee_save 378 .macro callee_save
349 stw,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30) 379 stw,ma %r3, CALLEE_REG_FRAME_SIZE(%r30)
350 mfctl %cr27, %r3 380 mfctl %cr27, %r3
351 stw %r4, -124(%r30) 381 stw %r4, -124(%r30)
352 stw %r5, -120(%r30) 382 stw %r5, -120(%r30)
@@ -384,7 +414,7 @@
384 ldw -120(%r30), %r5 414 ldw -120(%r30), %r5
385 ldw -124(%r30), %r4 415 ldw -124(%r30), %r4
386 mtctl %r3, %cr27 416 mtctl %r3, %cr27
387 ldw,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3 417 ldw,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3
388 .endm 418 .endm
389#endif /* ! __LP64__ */ 419#endif /* ! __LP64__ */
390 420
@@ -450,5 +480,30 @@
450 REST_CR (%cr22, PT_PSW (\regs)) 480 REST_CR (%cr22, PT_PSW (\regs))
451 .endm 481 .endm
452 482
483
484 /* First step to create a "relied upon translation"
485 * See PA 2.0 Arch. page F-4 and F-5.
486 *
487 * The ssm was originally necessary due to a "PCxT bug".
488 * But someone decided it needed to be added to the architecture
489 * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual.
490 * It's been carried forward into PA 2.0 Arch as well. :^(
491 *
492 * "ssm 0,%r0" is a NOP with side effects (prefetch barrier).
493 * rsm/ssm prevents the ifetch unit from speculatively fetching
494 * instructions past this line in the code stream.
495 * PA 2.0 processor will single step all insn in the same QUAD (4 insn).
496 */
497 .macro pcxt_ssm_bug
498 rsm PSW_SM_I,%r0
499 nop /* 1 */
500 nop /* 2 */
501 nop /* 3 */
502 nop /* 4 */
503 nop /* 5 */
504 nop /* 6 */
505 nop /* 7 */
506 .endm
507
453#endif /* __ASSEMBLY__ */ 508#endif /* __ASSEMBLY__ */
454#endif 509#endif
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index af7db694b22d..55b98c67fd82 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -2,7 +2,7 @@
2#define _PARISC_BITOPS_H 2#define _PARISC_BITOPS_H
3 3
4#include <linux/compiler.h> 4#include <linux/compiler.h>
5#include <asm/spinlock.h> 5#include <asm/types.h> /* for BITS_PER_LONG/SHIFT_PER_LONG */
6#include <asm/byteorder.h> 6#include <asm/byteorder.h>
7#include <asm/atomic.h> 7#include <asm/atomic.h>
8 8
@@ -12,193 +12,157 @@
12 * to include/asm-i386/bitops.h or kerneldoc 12 * to include/asm-i386/bitops.h or kerneldoc
13 */ 13 */
14 14
15#ifdef __LP64__ 15#define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1))
16# define SHIFT_PER_LONG 6
17#ifndef BITS_PER_LONG
18# define BITS_PER_LONG 64
19#endif
20#else
21# define SHIFT_PER_LONG 5
22#ifndef BITS_PER_LONG
23# define BITS_PER_LONG 32
24#endif
25#endif
26
27#define CHOP_SHIFTCOUNT(x) ((x) & (BITS_PER_LONG - 1))
28 16
29 17
30#define smp_mb__before_clear_bit() smp_mb() 18#define smp_mb__before_clear_bit() smp_mb()
31#define smp_mb__after_clear_bit() smp_mb() 19#define smp_mb__after_clear_bit() smp_mb()
32 20
33static __inline__ void set_bit(int nr, volatile unsigned long * address) 21/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion
22 * on use of volatile and __*_bit() (set/clear/change):
23 * *_bit() want use of volatile.
24 * __*_bit() are "relaxed" and don't use spinlock or volatile.
25 */
26
27static __inline__ void set_bit(int nr, volatile unsigned long * addr)
34{ 28{
35 unsigned long mask; 29 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
36 unsigned long *addr = (unsigned long *) address;
37 unsigned long flags; 30 unsigned long flags;
38 31
39 addr += (nr >> SHIFT_PER_LONG); 32 addr += (nr >> SHIFT_PER_LONG);
40 mask = 1L << CHOP_SHIFTCOUNT(nr);
41 _atomic_spin_lock_irqsave(addr, flags); 33 _atomic_spin_lock_irqsave(addr, flags);
42 *addr |= mask; 34 *addr |= mask;
43 _atomic_spin_unlock_irqrestore(addr, flags); 35 _atomic_spin_unlock_irqrestore(addr, flags);
44} 36}
45 37
46static __inline__ void __set_bit(int nr, volatile unsigned long * address) 38static __inline__ void __set_bit(unsigned long nr, volatile unsigned long * addr)
47{ 39{
48 unsigned long mask; 40 unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
49 unsigned long *addr = (unsigned long *) address;
50 41
51 addr += (nr >> SHIFT_PER_LONG); 42 *m |= 1UL << CHOP_SHIFTCOUNT(nr);
52 mask = 1L << CHOP_SHIFTCOUNT(nr);
53 *addr |= mask;
54} 43}
55 44
56static __inline__ void clear_bit(int nr, volatile unsigned long * address) 45static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
57{ 46{
58 unsigned long mask; 47 unsigned long mask = ~(1UL << CHOP_SHIFTCOUNT(nr));
59 unsigned long *addr = (unsigned long *) address;
60 unsigned long flags; 48 unsigned long flags;
61 49
62 addr += (nr >> SHIFT_PER_LONG); 50 addr += (nr >> SHIFT_PER_LONG);
63 mask = 1L << CHOP_SHIFTCOUNT(nr);
64 _atomic_spin_lock_irqsave(addr, flags); 51 _atomic_spin_lock_irqsave(addr, flags);
65 *addr &= ~mask; 52 *addr &= mask;
66 _atomic_spin_unlock_irqrestore(addr, flags); 53 _atomic_spin_unlock_irqrestore(addr, flags);
67} 54}
68 55
69static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * address) 56static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * addr)
70{ 57{
71 unsigned long mask; 58 unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
72 unsigned long *addr = (unsigned long *) address;
73 59
74 addr += (nr >> SHIFT_PER_LONG); 60 *m &= ~(1UL << CHOP_SHIFTCOUNT(nr));
75 mask = 1L << CHOP_SHIFTCOUNT(nr);
76 *addr &= ~mask;
77} 61}
78 62
79static __inline__ void change_bit(int nr, volatile unsigned long * address) 63static __inline__ void change_bit(int nr, volatile unsigned long * addr)
80{ 64{
81 unsigned long mask; 65 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
82 unsigned long *addr = (unsigned long *) address;
83 unsigned long flags; 66 unsigned long flags;
84 67
85 addr += (nr >> SHIFT_PER_LONG); 68 addr += (nr >> SHIFT_PER_LONG);
86 mask = 1L << CHOP_SHIFTCOUNT(nr);
87 _atomic_spin_lock_irqsave(addr, flags); 69 _atomic_spin_lock_irqsave(addr, flags);
88 *addr ^= mask; 70 *addr ^= mask;
89 _atomic_spin_unlock_irqrestore(addr, flags); 71 _atomic_spin_unlock_irqrestore(addr, flags);
90} 72}
91 73
92static __inline__ void __change_bit(int nr, volatile unsigned long * address) 74static __inline__ void __change_bit(unsigned long nr, volatile unsigned long * addr)
93{ 75{
94 unsigned long mask; 76 unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
95 unsigned long *addr = (unsigned long *) address;
96 77
97 addr += (nr >> SHIFT_PER_LONG); 78 *m ^= 1UL << CHOP_SHIFTCOUNT(nr);
98 mask = 1L << CHOP_SHIFTCOUNT(nr);
99 *addr ^= mask;
100} 79}
101 80
102static __inline__ int test_and_set_bit(int nr, volatile unsigned long * address) 81static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
103{ 82{
104 unsigned long mask; 83 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
105 unsigned long *addr = (unsigned long *) address; 84 unsigned long oldbit;
106 int oldbit;
107 unsigned long flags; 85 unsigned long flags;
108 86
109 addr += (nr >> SHIFT_PER_LONG); 87 addr += (nr >> SHIFT_PER_LONG);
110 mask = 1L << CHOP_SHIFTCOUNT(nr);
111 _atomic_spin_lock_irqsave(addr, flags); 88 _atomic_spin_lock_irqsave(addr, flags);
112 oldbit = (*addr & mask) ? 1 : 0; 89 oldbit = *addr;
113 *addr |= mask; 90 *addr = oldbit | mask;
114 _atomic_spin_unlock_irqrestore(addr, flags); 91 _atomic_spin_unlock_irqrestore(addr, flags);
115 92
116 return oldbit; 93 return (oldbit & mask) ? 1 : 0;
117} 94}
118 95
119static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address) 96static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address)
120{ 97{
121 unsigned long mask; 98 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
122 unsigned long *addr = (unsigned long *) address; 99 unsigned long oldbit;
123 int oldbit; 100 unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
124 101
125 addr += (nr >> SHIFT_PER_LONG); 102 oldbit = *addr;
126 mask = 1L << CHOP_SHIFTCOUNT(nr); 103 *addr = oldbit | mask;
127 oldbit = (*addr & mask) ? 1 : 0;
128 *addr |= mask;
129 104
130 return oldbit; 105 return (oldbit & mask) ? 1 : 0;
131} 106}
132 107
133static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * address) 108static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
134{ 109{
135 unsigned long mask; 110 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
136 unsigned long *addr = (unsigned long *) address; 111 unsigned long oldbit;
137 int oldbit;
138 unsigned long flags; 112 unsigned long flags;
139 113
140 addr += (nr >> SHIFT_PER_LONG); 114 addr += (nr >> SHIFT_PER_LONG);
141 mask = 1L << CHOP_SHIFTCOUNT(nr);
142 _atomic_spin_lock_irqsave(addr, flags); 115 _atomic_spin_lock_irqsave(addr, flags);
143 oldbit = (*addr & mask) ? 1 : 0; 116 oldbit = *addr;
144 *addr &= ~mask; 117 *addr = oldbit & ~mask;
145 _atomic_spin_unlock_irqrestore(addr, flags); 118 _atomic_spin_unlock_irqrestore(addr, flags);
146 119
147 return oldbit; 120 return (oldbit & mask) ? 1 : 0;
148} 121}
149 122
150static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address) 123static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address)
151{ 124{
152 unsigned long mask; 125 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
153 unsigned long *addr = (unsigned long *) address; 126 unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
154 int oldbit; 127 unsigned long oldbit;
155 128
156 addr += (nr >> SHIFT_PER_LONG); 129 oldbit = *addr;
157 mask = 1L << CHOP_SHIFTCOUNT(nr); 130 *addr = oldbit & ~mask;
158 oldbit = (*addr & mask) ? 1 : 0;
159 *addr &= ~mask;
160 131
161 return oldbit; 132 return (oldbit & mask) ? 1 : 0;
162} 133}
163 134
164static __inline__ int test_and_change_bit(int nr, volatile unsigned long * address) 135static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)
165{ 136{
166 unsigned long mask; 137 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
167 unsigned long *addr = (unsigned long *) address; 138 unsigned long oldbit;
168 int oldbit;
169 unsigned long flags; 139 unsigned long flags;
170 140
171 addr += (nr >> SHIFT_PER_LONG); 141 addr += (nr >> SHIFT_PER_LONG);
172 mask = 1L << CHOP_SHIFTCOUNT(nr);
173 _atomic_spin_lock_irqsave(addr, flags); 142 _atomic_spin_lock_irqsave(addr, flags);
174 oldbit = (*addr & mask) ? 1 : 0; 143 oldbit = *addr;
175 *addr ^= mask; 144 *addr = oldbit ^ mask;
176 _atomic_spin_unlock_irqrestore(addr, flags); 145 _atomic_spin_unlock_irqrestore(addr, flags);
177 146
178 return oldbit; 147 return (oldbit & mask) ? 1 : 0;
179} 148}
180 149
181static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address) 150static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address)
182{ 151{
183 unsigned long mask; 152 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
184 unsigned long *addr = (unsigned long *) address; 153 unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
185 int oldbit; 154 unsigned long oldbit;
186 155
187 addr += (nr >> SHIFT_PER_LONG); 156 oldbit = *addr;
188 mask = 1L << CHOP_SHIFTCOUNT(nr); 157 *addr = oldbit ^ mask;
189 oldbit = (*addr & mask) ? 1 : 0;
190 *addr ^= mask;
191 158
192 return oldbit; 159 return (oldbit & mask) ? 1 : 0;
193} 160}
194 161
195static __inline__ int test_bit(int nr, const volatile unsigned long *address) 162static __inline__ int test_bit(int nr, const volatile unsigned long *address)
196{ 163{
197 unsigned long mask; 164 unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
198 const unsigned long *addr = (const unsigned long *)address; 165 const unsigned long *addr = (const unsigned long *)address + (nr >> SHIFT_PER_LONG);
199
200 addr += (nr >> SHIFT_PER_LONG);
201 mask = 1L << CHOP_SHIFTCOUNT(nr);
202 166
203 return !!(*addr & mask); 167 return !!(*addr & mask);
204} 168}
@@ -229,7 +193,7 @@ static __inline__ unsigned long __ffs(unsigned long x)
229 unsigned long ret; 193 unsigned long ret;
230 194
231 __asm__( 195 __asm__(
232#if BITS_PER_LONG > 32 196#ifdef __LP64__
233 " ldi 63,%1\n" 197 " ldi 63,%1\n"
234 " extrd,u,*<> %0,63,32,%%r0\n" 198 " extrd,u,*<> %0,63,32,%%r0\n"
235 " extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */ 199 " extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */
@@ -304,14 +268,7 @@ static __inline__ int fls(int x)
304 * hweightN: returns the hamming weight (i.e. the number 268 * hweightN: returns the hamming weight (i.e. the number
305 * of bits set) of a N-bit word 269 * of bits set) of a N-bit word
306 */ 270 */
307#define hweight64(x) \ 271#define hweight64(x) generic_hweight64(x)
308({ \
309 unsigned long __x = (x); \
310 unsigned int __w; \
311 __w = generic_hweight32((unsigned int) __x); \
312 __w += generic_hweight32((unsigned int) (__x>>32)); \
313 __w; \
314})
315#define hweight32(x) generic_hweight32(x) 272#define hweight32(x) generic_hweight32(x)
316#define hweight16(x) generic_hweight16(x) 273#define hweight16(x) generic_hweight16(x)
317#define hweight8(x) generic_hweight8(x) 274#define hweight8(x) generic_hweight8(x)
@@ -324,7 +281,13 @@ static __inline__ int fls(int x)
324 */ 281 */
325static inline int sched_find_first_bit(const unsigned long *b) 282static inline int sched_find_first_bit(const unsigned long *b)
326{ 283{
327#ifndef __LP64__ 284#ifdef __LP64__
285 if (unlikely(b[0]))
286 return __ffs(b[0]);
287 if (unlikely(b[1]))
288 return __ffs(b[1]) + 64;
289 return __ffs(b[2]) + 128;
290#else
328 if (unlikely(b[0])) 291 if (unlikely(b[0]))
329 return __ffs(b[0]); 292 return __ffs(b[0]);
330 if (unlikely(b[1])) 293 if (unlikely(b[1]))
@@ -334,14 +297,6 @@ static inline int sched_find_first_bit(const unsigned long *b)
334 if (b[3]) 297 if (b[3])
335 return __ffs(b[3]) + 96; 298 return __ffs(b[3]) + 96;
336 return __ffs(b[4]) + 128; 299 return __ffs(b[4]) + 128;
337#else
338 if (unlikely(b[0]))
339 return __ffs(b[0]);
340 if (unlikely(((unsigned int)b[1])))
341 return __ffs(b[1]) + 64;
342 if (b[1] >> 32)
343 return __ffs(b[1] >> 32) + 96;
344 return __ffs(b[2]) + 128;
345#endif 300#endif
346} 301}
347 302
@@ -391,7 +346,7 @@ found_middle:
391 346
392static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) 347static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
393{ 348{
394 const unsigned long *p = addr + (offset >> 6); 349 const unsigned long *p = addr + (offset >> SHIFT_PER_LONG);
395 unsigned long result = offset & ~(BITS_PER_LONG-1); 350 unsigned long result = offset & ~(BITS_PER_LONG-1);
396 unsigned long tmp; 351 unsigned long tmp;
397 352
@@ -445,71 +400,90 @@ found_middle:
445 * test_and_{set,clear}_bit guarantee atomicity without 400 * test_and_{set,clear}_bit guarantee atomicity without
446 * disabling interrupts. 401 * disabling interrupts.
447 */ 402 */
448#ifdef __LP64__
449#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
450#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
451#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
452#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
453#else
454#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
455#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
456#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
457#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
458#endif
459 403
460#endif /* __KERNEL__ */ 404/* '3' is bits per byte */
405#define LE_BYTE_ADDR ((sizeof(unsigned long) - 1) << 3)
461 406
462static __inline__ int ext2_test_bit(int nr, __const__ void * addr) 407#define ext2_test_bit(nr, addr) \
463{ 408 test_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
464 __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; 409#define ext2_set_bit(nr, addr) \
410 __test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
411#define ext2_clear_bit(nr, addr) \
412 __test_and_clear_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
465 413
466 return (ADDR[nr >> 3] >> (nr & 7)) & 1; 414#define ext2_set_bit_atomic(l,nr,addr) \
467} 415 test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
416#define ext2_clear_bit_atomic(l,nr,addr) \
417 test_and_clear_bit( (nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
418
419#endif /* __KERNEL__ */
468 420
469/*
470 * This implementation of ext2_find_{first,next}_zero_bit was stolen from
471 * Linus' asm-alpha/bitops.h and modified for a big-endian machine.
472 */
473 421
474#define ext2_find_first_zero_bit(addr, size) \ 422#define ext2_find_first_zero_bit(addr, size) \
475 ext2_find_next_zero_bit((addr), (size), 0) 423 ext2_find_next_zero_bit((addr), (size), 0)
476 424
477extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, 425/* include/linux/byteorder does not support "unsigned long" type */
478 unsigned long size, unsigned long offset) 426static inline unsigned long ext2_swabp(unsigned long * x)
479{ 427{
480 unsigned int *p = ((unsigned int *) addr) + (offset >> 5); 428#ifdef __LP64__
481 unsigned int result = offset & ~31UL; 429 return (unsigned long) __swab64p((u64 *) x);
482 unsigned int tmp; 430#else
431 return (unsigned long) __swab32p((u32 *) x);
432#endif
433}
434
435/* include/linux/byteorder doesn't support "unsigned long" type */
436static inline unsigned long ext2_swab(unsigned long y)
437{
438#ifdef __LP64__
439 return (unsigned long) __swab64((u64) y);
440#else
441 return (unsigned long) __swab32((u32) y);
442#endif
443}
444
445static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
446{
447 unsigned long *p = (unsigned long *) addr + (offset >> SHIFT_PER_LONG);
448 unsigned long result = offset & ~(BITS_PER_LONG - 1);
449 unsigned long tmp;
483 450
484 if (offset >= size) 451 if (offset >= size)
485 return size; 452 return size;
486 size -= result; 453 size -= result;
487 offset &= 31UL; 454 offset &= (BITS_PER_LONG - 1UL);
488 if (offset) { 455 if (offset) {
489 tmp = cpu_to_le32p(p++); 456 tmp = ext2_swabp(p++);
490 tmp |= ~0UL >> (32-offset); 457 tmp |= (~0UL >> (BITS_PER_LONG - offset));
491 if (size < 32) 458 if (size < BITS_PER_LONG)
492 goto found_first; 459 goto found_first;
493 if (tmp != ~0U) 460 if (~tmp)
494 goto found_middle; 461 goto found_middle;
495 size -= 32; 462 size -= BITS_PER_LONG;
496 result += 32; 463 result += BITS_PER_LONG;
497 } 464 }
498 while (size >= 32) { 465
499 if ((tmp = cpu_to_le32p(p++)) != ~0U) 466 while (size & ~(BITS_PER_LONG - 1)) {
500 goto found_middle; 467 if (~(tmp = *(p++)))
501 result += 32; 468 goto found_middle_swap;
502 size -= 32; 469 result += BITS_PER_LONG;
470 size -= BITS_PER_LONG;
503 } 471 }
504 if (!size) 472 if (!size)
505 return result; 473 return result;
506 tmp = cpu_to_le32p(p); 474 tmp = ext2_swabp(p);
507found_first: 475found_first:
508 tmp |= ~0U << size; 476 tmp |= ~0UL << size;
477 if (tmp == ~0UL) /* Are any bits zero? */
478 return result + size; /* Nope. Skip ffz */
509found_middle: 479found_middle:
510 return result + ffz(tmp); 480 return result + ffz(tmp);
481
482found_middle_swap:
483 return result + ffz(ext2_swab(tmp));
511} 484}
512 485
486
513/* Bitmap functions for the minix filesystem. */ 487/* Bitmap functions for the minix filesystem. */
514#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr) 488#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
515#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr)) 489#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr))
diff --git a/include/asm-parisc/errno.h b/include/asm-parisc/errno.h
index 08464c405471..e2f3ddc796be 100644
--- a/include/asm-parisc/errno.h
+++ b/include/asm-parisc/errno.h
@@ -114,6 +114,7 @@
114 114
115#define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */ 115#define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */
116#define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ 116#define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */
117#define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */
117 118
118/* for robust mutexes */ 119/* for robust mutexes */
119#define EOWNERDEAD 254 /* Owner died */ 120#define EOWNERDEAD 254 /* Owner died */
diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h
index d3cfc0168fb1..6a910311b56b 100644
--- a/include/asm-parisc/grfioctl.h
+++ b/include/asm-parisc/grfioctl.h
@@ -69,6 +69,8 @@
69#define CRT_ID_TVRX S9000_ID_98765 /* TVRX (gto/falcon) */ 69#define CRT_ID_TVRX S9000_ID_98765 /* TVRX (gto/falcon) */
70#define CRT_ID_ARTIST S9000_ID_ARTIST /* Artist */ 70#define CRT_ID_ARTIST S9000_ID_ARTIST /* Artist */
71#define CRT_ID_SUMMIT 0x2FC1066B /* Summit FX2, FX4, FX6 ... */ 71#define CRT_ID_SUMMIT 0x2FC1066B /* Summit FX2, FX4, FX6 ... */
72#define CRT_ID_LEGO 0x35ACDA30 /* Lego FX5, FX10 ... */
73#define CRT_ID_PINNACLE 0x35ACDA16 /* Pinnacle FXe */
72 74
73/* structure for ioctl(GCDESCRIBE) */ 75/* structure for ioctl(GCDESCRIBE) */
74 76
diff --git a/include/asm-parisc/led.h b/include/asm-parisc/led.h
index 1ac8ab6c580d..efadfd543ec6 100644
--- a/include/asm-parisc/led.h
+++ b/include/asm-parisc/led.h
@@ -23,9 +23,6 @@
23 23
24#define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */ 24#define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */
25 25
26/* led tasklet struct */
27extern struct tasklet_struct led_tasklet;
28
29/* register_led_driver() */ 26/* register_led_driver() */
30int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg); 27int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg);
31 28
diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
index ef69ab4b17a9..1d247e32a608 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/include/asm-parisc/parisc-device.h
@@ -1,7 +1,7 @@
1#include <linux/device.h> 1#include <linux/device.h>
2 2
3struct parisc_device { 3struct parisc_device {
4 unsigned long hpa; /* Hard Physical Address */ 4 struct resource hpa; /* Hard Physical Address */
5 struct parisc_device_id id; 5 struct parisc_device_id id;
6 struct parisc_driver *driver; /* Driver for this device */ 6 struct parisc_driver *driver; /* Driver for this device */
7 char name[80]; /* The hardware description */ 7 char name[80]; /* The hardware description */
@@ -39,6 +39,11 @@ struct parisc_driver {
39#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv) 39#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv)
40#define parisc_parent(d) to_parisc_device(d->dev.parent) 40#define parisc_parent(d) to_parisc_device(d->dev.parent)
41 41
42static inline char *parisc_pathname(struct parisc_device *d)
43{
44 return d->dev.bus_id;
45}
46
42static inline void 47static inline void
43parisc_set_drvdata(struct parisc_device *d, void *p) 48parisc_set_drvdata(struct parisc_device *d, void *p)
44{ 49{
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index d0b761f690b5..fa39d07d49e9 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -69,7 +69,7 @@ struct pci_hba_data {
69#define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS) 69#define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS)
70#define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1)) 70#define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1))
71 71
72#if CONFIG_64BIT 72#ifdef CONFIG_64BIT
73#define PCI_F_EXTEND 0xffffffff00000000UL 73#define PCI_F_EXTEND 0xffffffff00000000UL
74#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a) 74#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a)
75 75
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index 820c6e712cd7..c28fb6f48c6c 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -501,6 +501,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
501#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 501#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
502 remap_pfn_range(vma, vaddr, pfn, size, prot) 502 remap_pfn_range(vma, vaddr, pfn, size, prot)
503 503
504#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE)
505
504#define MK_IOSPACE_PFN(space, pfn) (pfn) 506#define MK_IOSPACE_PFN(space, pfn) (pfn)
505#define GET_IOSPACE(pfn) 0 507#define GET_IOSPACE(pfn) 0
506#define GET_PFN(pfn) (pfn) 508#define GET_PFN(pfn) (pfn)
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index a9dfadd05658..aae40e8c3aa8 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -122,8 +122,27 @@ struct thread_struct {
122}; 122};
123 123
124/* Thread struct flags. */ 124/* Thread struct flags. */
125#define PARISC_UAC_NOPRINT (1UL << 0) /* see prctl and unaligned.c */
126#define PARISC_UAC_SIGBUS (1UL << 1)
125#define PARISC_KERNEL_DEATH (1UL << 31) /* see die_if_kernel()... */ 127#define PARISC_KERNEL_DEATH (1UL << 31) /* see die_if_kernel()... */
126 128
129#define PARISC_UAC_SHIFT 0
130#define PARISC_UAC_MASK (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
131
132#define SET_UNALIGN_CTL(task,value) \
133 ({ \
134 (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
135 | (((value) << PARISC_UAC_SHIFT) & \
136 PARISC_UAC_MASK)); \
137 0; \
138 })
139
140#define GET_UNALIGN_CTL(task,addr) \
141 ({ \
142 put_user(((task)->thread.flags & PARISC_UAC_MASK) \
143 >> PARISC_UAC_SHIFT, (int __user *) (addr)); \
144 })
145
127#define INIT_THREAD { \ 146#define INIT_THREAD { \
128 regs: { gr: { 0, }, \ 147 regs: { gr: { 0, }, \
129 fr: { 0, }, \ 148 fr: { 0, }, \
diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h
index 51323029f377..4334d6ca2add 100644
--- a/include/asm-parisc/psw.h
+++ b/include/asm-parisc/psw.h
@@ -1,4 +1,7 @@
1#ifndef _PARISC_PSW_H 1#ifndef _PARISC_PSW_H
2
3#include <linux/config.h>
4
2#define PSW_I 0x00000001 5#define PSW_I 0x00000001
3#define PSW_D 0x00000002 6#define PSW_D 0x00000002
4#define PSW_P 0x00000004 7#define PSW_P 0x00000004
@@ -9,6 +12,16 @@
9#define PSW_G 0x00000040 /* PA1.x only */ 12#define PSW_G 0x00000040 /* PA1.x only */
10#define PSW_O 0x00000080 /* PA2.0 only */ 13#define PSW_O 0x00000080 /* PA2.0 only */
11 14
15/* ssm/rsm instructions number PSW_W and PSW_E differently */
16#define PSW_SM_I PSW_I /* Enable External Interrupts */
17#define PSW_SM_D PSW_D
18#define PSW_SM_P PSW_P
19#define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */
20#define PSW_SM_R PSW_R /* Enable Recover Counter Trap */
21#define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */
22
23#define PSW_SM_QUIET PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I
24
12#define PSW_CB 0x0000ff00 25#define PSW_CB 0x0000ff00
13 26
14#define PSW_M 0x00010000 27#define PSW_M 0x00010000
@@ -30,33 +43,21 @@
30#define PSW_Z 0x40000000 /* PA1.x only */ 43#define PSW_Z 0x40000000 /* PA1.x only */
31#define PSW_Y 0x80000000 /* PA1.x only */ 44#define PSW_Y 0x80000000 /* PA1.x only */
32 45
33#ifdef __LP64__ 46#ifdef CONFIG_64BIT
34#define PSW_HI_CB 0x000000ff /* PA2.0 only */ 47# define PSW_HI_CB 0x000000ff /* PA2.0 only */
35#endif 48#endif
36 49
37/* PSW bits to be used with ssm/rsm */ 50#ifdef CONFIG_64BIT
38#define PSW_SM_I 0x1 51# define USER_PSW_HI_MASK PSW_HI_CB
39#define PSW_SM_D 0x2 52# define WIDE_PSW PSW_W
40#define PSW_SM_P 0x4 53#else
41#define PSW_SM_Q 0x8 54# define WIDE_PSW 0
42#define PSW_SM_R 0x10
43#define PSW_SM_F 0x20
44#define PSW_SM_G 0x40
45#define PSW_SM_O 0x80
46#define PSW_SM_E 0x100
47#define PSW_SM_W 0x200
48
49#ifdef __LP64__
50# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
51# define KERNEL_PSW (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D)
52# define REAL_MODE_PSW (PSW_W | PSW_Q)
53# define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
54# define USER_PSW_HI_MASK (PSW_HI_CB)
55#else
56# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
57# define KERNEL_PSW (PSW_C | PSW_Q | PSW_P | PSW_D)
58# define REAL_MODE_PSW (PSW_Q)
59# define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
60#endif 55#endif
61 56
57/* Used when setting up for rfi */
58#define KERNEL_PSW (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D)
59#define REAL_MODE_PSW (WIDE_PSW | PSW_Q)
60#define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
61#define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
62
62#endif 63#endif
diff --git a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h
index 3f428aa371a4..93f990e418f1 100644
--- a/include/asm-parisc/ptrace.h
+++ b/include/asm-parisc/ptrace.h
@@ -49,7 +49,7 @@ struct pt_regs {
49#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0) 49#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
50#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0) 50#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
51#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) 51#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3)
52#define profile_pc(regs) instruction_pointer(regs) 52unsigned long profile_pc(struct pt_regs *);
53extern void show_regs(struct pt_regs *); 53extern void show_regs(struct pt_regs *);
54#endif 54#endif
55 55
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index 43eaa6e742e0..7c3f406a746a 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -5,11 +5,6 @@
5#include <asm/processor.h> 5#include <asm/processor.h>
6#include <asm/spinlock_types.h> 6#include <asm/spinlock_types.h>
7 7
8/* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
9 * since it only has load-and-zero. Moreover, at least on some PA processors,
10 * the semaphore address has to be 16-byte aligned.
11 */
12
13static inline int __raw_spin_is_locked(raw_spinlock_t *x) 8static inline int __raw_spin_is_locked(raw_spinlock_t *x)
14{ 9{
15 volatile unsigned int *a = __ldcw_align(x); 10 volatile unsigned int *a = __ldcw_align(x);
diff --git a/include/asm-parisc/spinlock_types.h b/include/asm-parisc/spinlock_types.h
index 785bba822fbf..d6b479bdb886 100644
--- a/include/asm-parisc/spinlock_types.h
+++ b/include/asm-parisc/spinlock_types.h
@@ -6,11 +6,15 @@
6#endif 6#endif
7 7
8typedef struct { 8typedef struct {
9#ifdef CONFIG_PA20
10 volatile unsigned int slock;
11# define __RAW_SPIN_LOCK_UNLOCKED { 1 }
12#else
9 volatile unsigned int lock[4]; 13 volatile unsigned int lock[4];
14# define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
15#endif
10} raw_spinlock_t; 16} raw_spinlock_t;
11 17
12#define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
13
14typedef struct { 18typedef struct {
15 raw_spinlock_t lock; 19 raw_spinlock_t lock;
16 volatile int counter; 20 volatile int counter;
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index 26ff844a21c1..f3928d3a80cb 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -138,13 +138,7 @@ static inline void set_eiem(unsigned long val)
138#define set_wmb(var, value) do { var = value; wmb(); } while (0) 138#define set_wmb(var, value) do { var = value; wmb(); } while (0)
139 139
140 140
141/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ 141#ifndef CONFIG_PA20
142#define __ldcw(a) ({ \
143 unsigned __ret; \
144 __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
145 __ret; \
146})
147
148/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, 142/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
149 and GCC only guarantees 8-byte alignment for stack locals, we can't 143 and GCC only guarantees 8-byte alignment for stack locals, we can't
150 be assured of 16-byte alignment for atomic lock data even if we 144 be assured of 16-byte alignment for atomic lock data even if we
@@ -152,37 +146,41 @@ static inline void set_eiem(unsigned long val)
152 we use a struct containing an array of four ints for the atomic lock 146 we use a struct containing an array of four ints for the atomic lock
153 type and dynamically select the 16-byte aligned int from the array 147 type and dynamically select the 16-byte aligned int from the array
154 for the semaphore. */ 148 for the semaphore. */
149
155#define __PA_LDCW_ALIGNMENT 16 150#define __PA_LDCW_ALIGNMENT 16
156#define __ldcw_align(a) ({ \ 151#define __ldcw_align(a) ({ \
157 unsigned long __ret = (unsigned long) &(a)->lock[0]; \ 152 unsigned long __ret = (unsigned long) &(a)->lock[0]; \
158 __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ 153 __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
159 (volatile unsigned int *) __ret; \ 154 (volatile unsigned int *) __ret; \
160}) 155})
156#define LDCW "ldcw"
161 157
162#ifdef CONFIG_SMP 158#else /*CONFIG_PA20*/
163# define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) 159/* From: "Jim Hull" <jim.hull of hp.com>
164#endif 160 I've attached a summary of the change, but basically, for PA 2.0, as
161 long as the ",CO" (coherent operation) completer is specified, then the
162 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
163 they only require "natural" alignment (4-byte for ldcw, 8-byte for
164 ldcd). */
165 165
166#define KERNEL_START (0x10100000 - 0x1000) 166#define __PA_LDCW_ALIGNMENT 4
167#define __ldcw_align(a) ((volatile unsigned int *)a)
168#define LDCW "ldcw,co"
167 169
168/* This is for the serialisation of PxTLB broadcasts. At least on the 170#endif /*!CONFIG_PA20*/
169 * N class systems, only one PxTLB inter processor broadcast can be
170 * active at any one time on the Merced bus. This tlb purge
171 * synchronisation is fairly lightweight and harmless so we activate
172 * it on all SMP systems not just the N class. */
173#ifdef CONFIG_SMP
174extern spinlock_t pa_tlb_lock;
175 171
176#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) 172/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
177#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) 173#define __ldcw(a) ({ \
178 174 unsigned __ret; \
179#else 175 __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \
180 176 __ret; \
181#define purge_tlb_start(x) do { } while(0) 177})
182#define purge_tlb_end(x) do { } while (0)
183 178
179#ifdef CONFIG_SMP
180# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
184#endif 181#endif
185 182
183#define KERNEL_START (0x10100000 - 0x1000)
186#define arch_align_stack(x) (x) 184#define arch_align_stack(x) (x)
187 185
188#endif 186#endif
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index eb27b78930e8..84af4ab1fe51 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -7,6 +7,26 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <asm/mmu_context.h> 8#include <asm/mmu_context.h>
9 9
10
11/* This is for the serialisation of PxTLB broadcasts. At least on the
12 * N class systems, only one PxTLB inter processor broadcast can be
13 * active at any one time on the Merced bus. This tlb purge
14 * synchronisation is fairly lightweight and harmless so we activate
15 * it on all SMP systems not just the N class. */
16#ifdef CONFIG_SMP
17extern spinlock_t pa_tlb_lock;
18
19#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
20#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
21
22#else
23
24#define purge_tlb_start(x) do { } while(0)
25#define purge_tlb_end(x) do { } while (0)
26
27#endif
28
29
10extern void flush_tlb_all(void); 30extern void flush_tlb_all(void);
11 31
12/* 32/*
@@ -64,29 +84,26 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
64{ 84{
65 unsigned long npages; 85 unsigned long npages;
66 86
67
68 npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 87 npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
69 if (npages >= 512) /* XXX arbitrary, should be tuned */ 88 if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */
70 flush_tlb_all(); 89 flush_tlb_all();
71 else { 90 else {
72 91
73 mtsp(vma->vm_mm->context,1); 92 mtsp(vma->vm_mm->context,1);
93 purge_tlb_start();
74 if (split_tlb) { 94 if (split_tlb) {
75 purge_tlb_start();
76 while (npages--) { 95 while (npages--) {
77 pdtlb(start); 96 pdtlb(start);
78 pitlb(start); 97 pitlb(start);
79 start += PAGE_SIZE; 98 start += PAGE_SIZE;
80 } 99 }
81 purge_tlb_end();
82 } else { 100 } else {
83 purge_tlb_start();
84 while (npages--) { 101 while (npages--) {
85 pdtlb(start); 102 pdtlb(start);
86 start += PAGE_SIZE; 103 start += PAGE_SIZE;
87 } 104 }
88 purge_tlb_end();
89 } 105 }
106 purge_tlb_end();
90 } 107 }
91} 108}
92 109
diff --git a/include/asm-parisc/types.h b/include/asm-parisc/types.h
index d21b9d0d63ea..34fdce361a5a 100644
--- a/include/asm-parisc/types.h
+++ b/include/asm-parisc/types.h
@@ -33,8 +33,10 @@ typedef unsigned long long __u64;
33 33
34#ifdef __LP64__ 34#ifdef __LP64__
35#define BITS_PER_LONG 64 35#define BITS_PER_LONG 64
36#define SHIFT_PER_LONG 6
36#else 37#else
37#define BITS_PER_LONG 32 38#define BITS_PER_LONG 32
39#define SHIFT_PER_LONG 5
38#endif 40#endif
39 41
40#ifndef __ASSEMBLY__ 42#ifndef __ASSEMBLY__
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index 6a9f0cadff58..e7a620c5c5e6 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -687,8 +687,8 @@
687#define __NR_shmget (__NR_Linux + 194) 687#define __NR_shmget (__NR_Linux + 194)
688#define __NR_shmctl (__NR_Linux + 195) 688#define __NR_shmctl (__NR_Linux + 195)
689 689
690#define __NR_getpmsg (__NR_Linux + 196) /* some people actually want streams */ 690#define __NR_getpmsg (__NR_Linux + 196) /* Somebody *wants* streams? */
691#define __NR_putpmsg (__NR_Linux + 197) /* some people actually want streams */ 691#define __NR_putpmsg (__NR_Linux + 197)
692 692
693#define __NR_lstat64 (__NR_Linux + 198) 693#define __NR_lstat64 (__NR_Linux + 198)
694#define __NR_truncate64 (__NR_Linux + 199) 694#define __NR_truncate64 (__NR_Linux + 199)
@@ -755,8 +755,14 @@
755#define __NR_mbind (__NR_Linux + 260) 755#define __NR_mbind (__NR_Linux + 260)
756#define __NR_get_mempolicy (__NR_Linux + 261) 756#define __NR_get_mempolicy (__NR_Linux + 261)
757#define __NR_set_mempolicy (__NR_Linux + 262) 757#define __NR_set_mempolicy (__NR_Linux + 262)
758#define __NR_vserver (__NR_Linux + 263)
759#define __NR_add_key (__NR_Linux + 264)
760#define __NR_request_key (__NR_Linux + 265)
761#define __NR_keyctl (__NR_Linux + 266)
762#define __NR_ioprio_set (__NR_Linux + 267)
763#define __NR_ioprio_get (__NR_Linux + 268)
758 764
759#define __NR_Linux_syscalls 263 765#define __NR_Linux_syscalls 269
760 766
761#define HPUX_GATEWAY_ADDR 0xC0000004 767#define HPUX_GATEWAY_ADDR 0xC0000004
762#define LINUX_GATEWAY_ADDR 0x100 768#define LINUX_GATEWAY_ADDR 0x100
@@ -807,10 +813,10 @@
807#define K_INLINE_SYSCALL(name, nr, args...) ({ \ 813#define K_INLINE_SYSCALL(name, nr, args...) ({ \
808 long __sys_res; \ 814 long __sys_res; \
809 { \ 815 { \
810 register unsigned long __res asm("r28"); \ 816 register unsigned long __res __asm__("r28"); \
811 K_LOAD_ARGS_##nr(args) \ 817 K_LOAD_ARGS_##nr(args) \
812 /* FIXME: HACK stw/ldw r19 around syscall */ \ 818 /* FIXME: HACK stw/ldw r19 around syscall */ \
813 asm volatile( \ 819 __asm__ volatile( \
814 K_STW_ASM_PIC \ 820 K_STW_ASM_PIC \
815 " ble 0x100(%%sr2, %%r0)\n" \ 821 " ble 0x100(%%sr2, %%r0)\n" \
816 " ldi %1, %%r20\n" \ 822 " ldi %1, %%r20\n" \
diff --git a/include/linux/hil.h b/include/linux/hil.h
new file mode 100644
index 000000000000..13352d7d0caf
--- /dev/null
+++ b/include/linux/hil.h
@@ -0,0 +1,483 @@
1#ifndef _HIL_H_
2#define _HIL_H_
3
4/*
5 * Hewlett Packard Human Interface Loop (HP-HIL) Protocol -- header.
6 *
7 * Copyright (c) 2001 Brian S. Julin
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL").
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 *
32 * References:
33 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
34 *
35 * A note of thanks to HP for providing and shipping reference materials
36 * free of charge to help in the development of HIL support for Linux.
37 *
38 */
39
40#include <asm/types.h>
41
42/* Physical constants relevant to raw loop/device timing.
43 */
44
45#define HIL_CLOCK 8MHZ
46#define HIL_EK1_CLOCK 30HZ
47#define HIL_EK2_CLOCK 60HZ
48
49#define HIL_TIMEOUT_DEV 5 /* ms */
50#define HIL_TIMEOUT_DEVS 10 /* ms */
51#define HIL_TIMEOUT_NORESP 10 /* ms */
52#define HIL_TIMEOUT_DEVS_DATA 16 /* ms */
53#define HIL_TIMEOUT_SELFTEST 200 /* ms */
54
55
56/* Actual wire line coding. These will only be useful if someone is
57 * implementing a software MLC to run HIL devices on a non-parisc machine.
58 */
59
60#define HIL_WIRE_PACKET_LEN 15
61enum hil_wire_bitpos {
62 HIL_WIRE_START = 0,
63 HIL_WIRE_ADDR2,
64 HIL_WIRE_ADDR1,
65 HIL_WIRE_ADDR0,
66 HIL_WIRE_COMMAND,
67 HIL_WIRE_DATA7,
68 HIL_WIRE_DATA6,
69 HIL_WIRE_DATA5,
70 HIL_WIRE_DATA4,
71 HIL_WIRE_DATA3,
72 HIL_WIRE_DATA2,
73 HIL_WIRE_DATA1,
74 HIL_WIRE_DATA0,
75 HIL_WIRE_PARITY,
76 HIL_WIRE_STOP
77};
78
79/* HP documentation uses these bit positions to refer to commands;
80 * we will call these "packets".
81 */
82enum hil_pkt_bitpos {
83 HIL_PKT_CMD = 0x00000800,
84 HIL_PKT_ADDR2 = 0x00000400,
85 HIL_PKT_ADDR1 = 0x00000200,
86 HIL_PKT_ADDR0 = 0x00000100,
87 HIL_PKT_ADDR_MASK = 0x00000700,
88 HIL_PKT_ADDR_SHIFT = 8,
89 HIL_PKT_DATA7 = 0x00000080,
90 HIL_PKT_DATA6 = 0x00000040,
91 HIL_PKT_DATA5 = 0x00000020,
92 HIL_PKT_DATA4 = 0x00000010,
93 HIL_PKT_DATA3 = 0x00000008,
94 HIL_PKT_DATA2 = 0x00000004,
95 HIL_PKT_DATA1 = 0x00000002,
96 HIL_PKT_DATA0 = 0x00000001,
97 HIL_PKT_DATA_MASK = 0x000000FF,
98 HIL_PKT_DATA_SHIFT = 0
99};
100
101/* The HIL MLC also has several error/status/control bits. We extend the
102 * "packet" to include these when direct access to the MLC is available,
103 * or emulate them in cases where they are not available.
104 *
105 * This way the device driver knows that the underlying MLC driver
106 * has had to deal with loop errors.
107 */
108enum hil_error_bitpos {
109 HIL_ERR_OB = 0x00000800, /* MLC is busy sending an auto-poll,
110 or we have filled up the output
111 buffer and must wait. */
112 HIL_ERR_INT = 0x00010000, /* A normal interrupt has occurred. */
113 HIL_ERR_NMI = 0x00020000, /* An NMI has occurred. */
114 HIL_ERR_LERR = 0x00040000, /* A poll didn't come back. */
115 HIL_ERR_PERR = 0x01000000, /* There was a Parity Error. */
116 HIL_ERR_FERR = 0x02000000, /* There was a Framing Error. */
117 HIL_ERR_FOF = 0x04000000 /* Input FIFO Overflowed. */
118};
119
120enum hil_control_bitpos {
121 HIL_CTRL_TEST = 0x00010000,
122 HIL_CTRL_IPF = 0x00040000,
123 HIL_CTRL_APE = 0x02000000
124};
125
126/* Bits 30,31 are unused, we use them to control write behavior. */
127#define HIL_DO_ALTER_CTRL 0x40000000 /* Write MSW of packet to control
128 before writing LSW to loop */
129#define HIL_CTRL_ONLY 0xc0000000 /* *Only* alter the control registers */
130
131/* This gives us a 32-bit "packet"
132 */
133typedef u32 hil_packet;
134
135
136/* HIL Loop commands
137 */
138enum hil_command {
139 HIL_CMD_IFC = 0x00, /* Interface Clear */
140 HIL_CMD_EPT = 0x01, /* Enter Pass-Thru Mode */
141 HIL_CMD_ELB = 0x02, /* Enter Loop-Back Mode */
142 HIL_CMD_IDD = 0x03, /* Identify and Describe */
143 HIL_CMD_DSR = 0x04, /* Device Soft Reset */
144 HIL_CMD_PST = 0x05, /* Perform Self Test */
145 HIL_CMD_RRG = 0x06, /* Read Register */
146 HIL_CMD_WRG = 0x07, /* Write Register */
147 HIL_CMD_ACF = 0x08, /* Auto Configure */
148 HIL_CMDID_ACF = 0x07, /* Auto Configure bits with incremented ID */
149 HIL_CMD_POL = 0x10, /* Poll */
150 HIL_CMDCT_POL = 0x0f, /* Poll command bits with item count */
151 HIL_CMD_RPL = 0x20, /* RePoll */
152 HIL_CMDCT_RPL = 0x0f, /* RePoll command bits with item count */
153 HIL_CMD_RNM = 0x30, /* Report Name */
154 HIL_CMD_RST = 0x31, /* Report Status */
155 HIL_CMD_EXD = 0x32, /* Extended Describe */
156 HIL_CMD_RSC = 0x33, /* Report Security Code */
157
158 /* 0x34 to 0x3c reserved for future use */
159
160 HIL_CMD_DKA = 0x3d, /* Disable Keyswitch Autorepeat */
161 HIL_CMD_EK1 = 0x3e, /* Enable Keyswitch Autorepeat 1 */
162 HIL_CMD_EK2 = 0x3f, /* Enable Keyswitch Autorepeat 2 */
163 HIL_CMD_PR1 = 0x40, /* Prompt1 */
164 HIL_CMD_PR2 = 0x41, /* Prompt2 */
165 HIL_CMD_PR3 = 0x42, /* Prompt3 */
166 HIL_CMD_PR4 = 0x43, /* Prompt4 */
167 HIL_CMD_PR5 = 0x44, /* Prompt5 */
168 HIL_CMD_PR6 = 0x45, /* Prompt6 */
169 HIL_CMD_PR7 = 0x46, /* Prompt7 */
170 HIL_CMD_PRM = 0x47, /* Prompt (General Purpose) */
171 HIL_CMD_AK1 = 0x48, /* Acknowlege1 */
172 HIL_CMD_AK2 = 0x49, /* Acknowlege2 */
173 HIL_CMD_AK3 = 0x4a, /* Acknowlege3 */
174 HIL_CMD_AK4 = 0x4b, /* Acknowlege4 */
175 HIL_CMD_AK5 = 0x4c, /* Acknowlege5 */
176 HIL_CMD_AK6 = 0x4d, /* Acknowlege6 */
177 HIL_CMD_AK7 = 0x4e, /* Acknowlege7 */
178 HIL_CMD_ACK = 0x4f, /* Acknowlege (General Purpose) */
179
180 /* 0x50 to 0x78 reserved for future use */
181 /* 0x80 to 0xEF device-specific commands */
182 /* 0xf0 to 0xf9 reserved for future use */
183
184 HIL_CMD_RIO = 0xfa, /* Register I/O Error */
185 HIL_CMD_SHR = 0xfb, /* System Hard Reset */
186 HIL_CMD_TER = 0xfc, /* Transmission Error */
187 HIL_CMD_CAE = 0xfd, /* Configuration Address Error */
188 HIL_CMD_DHR = 0xfe, /* Device Hard Reset */
189
190 /* 0xff is prohibited from use. */
191};
192
193
194/*
195 * Response "records" to HIL commands
196 */
197
198/* Device ID byte
199 */
200#define HIL_IDD_DID_TYPE_MASK 0xe0 /* Primary type bits */
201#define HIL_IDD_DID_TYPE_KB_INTEGRAL 0xa0 /* Integral keyboard */
202#define HIL_IDD_DID_TYPE_KB_ITF 0xc0 /* ITD keyboard */
203#define HIL_IDD_DID_TYPE_KB_RSVD 0xe0 /* Reserved keyboard type */
204#define HIL_IDD_DID_TYPE_KB_LANG_MASK 0x1f /* Keyboard locale bits */
205#define HIL_IDD_DID_KBLANG_USE_ESD 0x00 /* Use ESD Locale instead */
206#define HIL_IDD_DID_TYPE_ABS 0x80 /* Absolute Positioners */
207#define HIL_IDD_DID_ABS_RSVD1_MASK 0xf8 /* Reserved */
208#define HIL_IDD_DID_ABS_RSVD1 0x98
209#define HIL_IDD_DID_ABS_TABLET_MASK 0xf8 /* Tablets and digitizers */
210#define HIL_IDD_DID_ABS_TABLET 0x90
211#define HIL_IDD_DID_ABS_TSCREEN_MASK 0xfc /* Touch screens */
212#define HIL_IDD_DID_ABS_TSCREEN 0x8c
213#define HIL_IDD_DID_ABS_RSVD2_MASK 0xfc /* Reserved */
214#define HIL_IDD_DID_ABS_RSVD2 0x88
215#define HIL_IDD_DID_ABS_RSVD3_MASK 0xfc /* Reserved */
216#define HIL_IDD_DID_ABS_RSVD3 0x80
217#define HIL_IDD_DID_TYPE_REL 0x60 /* Relative Positioners */
218#define HIL_IDD_DID_REL_RSVD1_MASK 0xf0 /* Reserved */
219#define HIL_IDD_DID_REL_RSVD1 0x70
220#define HIL_IDD_DID_REL_RSVD2_MASK 0xfc /* Reserved */
221#define HIL_IDD_DID_REL_RSVD2 0x6c
222#define HIL_IDD_DID_REL_MOUSE_MASK 0xfc /* Mouse */
223#define HIL_IDD_DID_REL_MOUSE 0x68
224#define HIL_IDD_DID_REL_QUAD_MASK 0xf8 /* Other Quadrature Devices */
225#define HIL_IDD_DID_REL_QUAD 0x60
226#define HIL_IDD_DID_TYPE_CHAR 0x40 /* Character Entry */
227#define HIL_IDD_DID_CHAR_BARCODE_MASK 0xfc /* Barcode Reader */
228#define HIL_IDD_DID_CHAR_BARCODE 0x5c
229#define HIL_IDD_DID_CHAR_RSVD1_MASK 0xfc /* Reserved */
230#define HIL_IDD_DID_CHAR_RSVD1 0x58
231#define HIL_IDD_DID_CHAR_RSVD2_MASK 0xf8 /* Reserved */
232#define HIL_IDD_DID_CHAR_RSVD2 0x50
233#define HIL_IDD_DID_CHAR_RSVD3_MASK 0xf0 /* Reserved */
234#define HIL_IDD_DID_CHAR_RSVD3 0x40
235#define HIL_IDD_DID_TYPE_OTHER 0x20 /* Miscellaneous */
236#define HIL_IDD_DID_OTHER_RSVD1_MASK 0xf0 /* Reserved */
237#define HIL_IDD_DID_OTHER_RSVD1 0x30
238#define HIL_IDD_DID_OTHER_BARCODE_MASK 0xfc /* Tone Generator */
239#define HIL_IDD_DID_OTHER_BARCODE 0x2c
240#define HIL_IDD_DID_OTHER_RSVD2_MASK 0xfc /* Reserved */
241#define HIL_IDD_DID_OTHER_RSVD2 0x28
242#define HIL_IDD_DID_OTHER_RSVD3_MASK 0xf8 /* Reserved */
243#define HIL_IDD_DID_OTHER_RSVD3 0x20
244#define HIL_IDD_DID_TYPE_KEYPAD 0x00 /* Vectra Keyboard */
245
246/* IDD record header
247 */
248#define HIL_IDD_HEADER_AXSET_MASK 0x03 /* Number of axis in a set */
249#define HIL_IDD_HEADER_RSC 0x04 /* Supports RSC command */
250#define HIL_IDD_HEADER_EXD 0x08 /* Supports EXD command */
251#define HIL_IDD_HEADER_IOD 0x10 /* IOD byte to follow */
252#define HIL_IDD_HEADER_16BIT 0x20 /* 16 (vs. 8) bit resolution */
253#define HIL_IDD_HEADER_ABS 0x40 /* Reports Absolute Position */
254#define HIL_IDD_HEADER_2X_AXIS 0x80 /* Two sets of 1-3 axis */
255
256/* I/O Descriptor
257 */
258#define HIL_IDD_IOD_NBUTTON_MASK 0x07 /* Number of buttons */
259#define HIL_IDD_IOD_PROXIMITY 0x08 /* Proximity in/out events */
260#define HIL_IDD_IOD_PROMPT_MASK 0x70 /* Number of prompts/acks */
261#define HIL_IDD_IOD_PROMPT_SHIFT 4
262#define HIL_IDD_IOD_PROMPT 0x80 /* Generic prompt/ack */
263
264#define HIL_IDD_NUM_AXES_PER_SET(header_packet) \
265((header_packet) & HIL_IDD_HEADER_AXSET_MASK)
266
267#define HIL_IDD_NUM_AXSETS(header_packet) \
268(2 - !((header_packet) & HIL_IDD_HEADER_2X_AXIS))
269
270#define HIL_IDD_LEN(header_packet) \
271((4 - !(header_packet & HIL_IDD_HEADER_IOD) - \
272 2 * !(HIL_IDD_NUM_AXES_PER_SET(header_packet))) + \
273 2 * HIL_IDD_NUM_AXES_PER_SET(header_packet) * \
274 !!((header_packet) & HIL_IDD_HEADER_ABS))
275
276/* The following HIL_IDD_* macros assume you have an array of
277 * packets and/or unpacked 8-bit data in the order that they
278 * were received.
279 */
280
281#define HIL_IDD_AXIS_COUNTS_PER_M(header_ptr) \
282(!(HIL_IDD_NUM_AXSETS(*(header_ptr))) ? -1 : \
283(((*(header_ptr + 1) & HIL_PKT_DATA_MASK) + \
284 ((*(header_ptr + 2) & HIL_PKT_DATA_MASK)) << 8) \
285* ((*(header_ptr) & HIL_IDD_HEADER_16BIT) ? 100 : 1)))
286
287#define HIL_IDD_AXIS_MAX(header_ptr, __axnum) \
288((!(*(header_ptr) & HIL_IDD_HEADER_ABS) || \
289 (HIL_IDD_NUM_AXES_PER_SET(*(header_ptr)) <= __axnum)) ? 0 : \
290 ((HIL_PKT_DATA_MASK & *((header_ptr) + 3 + 2 * __axnum)) + \
291 ((HIL_PKT_DATA_MASK & *((header_ptr) + 4 + 2 * __axnum)) << 8)))
292
293#define HIL_IDD_IOD(header_ptr) \
294(*(header_ptr + HIL_IDD_LEN((*header_ptr)) - 1))
295
296#define HIL_IDD_HAS_GEN_PROMPT(header_ptr) \
297((*header_ptr & HIL_IDD_HEADER_IOD) && \
298 (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROMPT))
299
300#define HIL_IDD_HAS_GEN_PROXIMITY(header_ptr) \
301((*header_ptr & HIL_IDD_HEADER_IOD) && \
302 (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROXIMITY))
303
304#define HIL_IDD_NUM_BUTTONS(header_ptr) \
305((*header_ptr & HIL_IDD_HEADER_IOD) ? \
306 (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NBUTTON_MASK) : 0)
307
308#define HIL_IDD_NUM_PROMPTS(header_ptr) \
309((*header_ptr & HIL_IDD_HEADER_IOD) ? \
310 ((HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NPROMPT_MASK) \
311 >> HIL_IDD_IOD_PROMPT_SHIFT) : 0)
312
313/* The response to HIL EXD commands -- the "extended describe record" */
314#define HIL_EXD_HEADER_WRG 0x03 /* Supports type2 WRG */
315#define HIL_EXD_HEADER_WRG_TYPE1 0x01 /* Supports type1 WRG */
316#define HIL_EXD_HEADER_WRG_TYPE2 0x02 /* Supports type2 WRG */
317#define HIL_EXD_HEADER_RRG 0x04 /* Supports RRG command */
318#define HIL_EXD_HEADER_RNM 0x10 /* Supports RNM command */
319#define HIL_EXD_HEADER_RST 0x20 /* Supports RST command */
320#define HIL_EXD_HEADER_LOCALE 0x40 /* Contains locale code */
321
322#define HIL_EXD_NUM_RRG(header_ptr) \
323((*header_ptr & HIL_EXD_HEADER_RRG) ? \
324 (*(header_ptr + 1) & HIL_PKT_DATA_MASK) : 0)
325
326#define HIL_EXD_NUM_WWG(header_ptr) \
327((*header_ptr & HIL_EXD_HEADER_WRG) ? \
328 (*(header_ptr + 2 - !(*header_ptr & HIL_EXD_HEADER_RRG)) & \
329 HIL_PKT_DATA_MASK) : 0)
330
331#define HIL_EXD_LEN(header_ptr) \
332(!!(*header_ptr & HIL_EXD_HEADER_RRG) + \
333 !!(*header_ptr & HIL_EXD_HEADER_WRG) + \
334 !!(*header_ptr & HIL_EXD_HEADER_LOCALE) + \
335 2 * !!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) + 1)
336
337#define HIL_EXD_LOCALE(header_ptr) \
338(!(*header_ptr & HIL_EXD_HEADER_LOCALE) ? -1 : \
339 (*(header_ptr + HIL_EXD_LEN(header_ptr) - 1) & HIL_PKT_DATA_MASK))
340
341#define HIL_EXD_WRG_TYPE2_LEN(header_ptr) \
342(!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) ? -1 : \
343 (*(header_ptr + HIL_EXD_LEN(header_ptr) - 2 - \
344 !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) + \
345 ((*(header_ptr + HIL_EXD_LEN(header_ptr) - 1 - \
346 !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) << 8))
347
348/* Device locale codes. */
349
350/* Last defined locale code. Everything above this is "Reserved",
351 and note that this same table applies to the Device ID Byte where
352 keyboards may have a nationality code which is only 5 bits. */
353#define HIL_LOCALE_MAX 0x1f
354
355/* Map to hopefully useful strings. I was trying to make these look
356 like locale.aliases strings do; maybe that isn't the right table to
357 emulate. In either case, I didn't have much to work on. */
358#define HIL_LOCALE_MAP \
359"", /* 0x00 Reserved */ \
360"", /* 0x01 Reserved */ \
361"", /* 0x02 Reserved */ \
362"swiss.french", /* 0x03 Swiss/French */ \
363"portuguese", /* 0x04 Portuguese */ \
364"arabic", /* 0x05 Arabic */ \
365"hebrew", /* 0x06 Hebrew */ \
366"english.canadian", /* 0x07 Canadian English */ \
367"turkish", /* 0x08 Turkish */ \
368"greek", /* 0x09 Greek */ \
369"thai", /* 0x0a Thai (Thailand) */ \
370"italian", /* 0x0b Italian */ \
371"korean", /* 0x0c Hangul (Korea) */ \
372"dutch", /* 0x0d Dutch */ \
373"swedish", /* 0x0e Swedish */ \
374"german", /* 0x0f German */ \
375"chinese", /* 0x10 Chinese-PRC */ \
376"chinese", /* 0x11 Chinese-ROC */ \
377"swiss.french", /* 0x12 Swiss/French II */ \
378"spanish", /* 0x13 Spanish */ \
379"swiss.german", /* 0x14 Swiss/German II */ \
380"flemish", /* 0x15 Belgian (Flemish) */ \
381"finnish", /* 0x16 Finnish */ \
382"english.uk", /* 0x17 United Kingdom */ \
383"french.canadian", /* 0x18 French/Canadian */ \
384"swiss.german", /* 0x19 Swiss/German */ \
385"norwegian", /* 0x1a Norwegian */ \
386"french", /* 0x1b French */ \
387"danish", /* 0x1c Danish */ \
388"japanese", /* 0x1d Katakana */ \
389"spanish", /* 0x1e Latin American/Spanish*/\
390"english.us" /* 0x1f United States */ \
391
392
393/* HIL keycodes */
394#define HIL_KEYCODES_SET1_TBLSIZE 128
395#define HIL_KEYCODES_SET1 \
396 KEY_5, KEY_RESERVED, KEY_RIGHTALT, KEY_LEFTALT, \
397 KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_LEFTCTRL, KEY_SYSRQ, \
398 KEY_KP4, KEY_KP8, KEY_KP5, KEY_KP9, \
399 KEY_KP6, KEY_KP7, KEY_KPCOMMA, KEY_KPENTER, \
400 KEY_KP1, KEY_KPSLASH, KEY_KP2, KEY_KPPLUS, \
401 KEY_KP3, KEY_KPASTERISK, KEY_KP0, KEY_KPMINUS, \
402 KEY_B, KEY_V, KEY_C, KEY_X, \
403 KEY_Z, KEY_RESERVED, KEY_RESERVED, KEY_ESC, \
404 KEY_6, KEY_F10, KEY_3, KEY_F11, \
405 KEY_KPDOT, KEY_F9, KEY_TAB /*KP*/, KEY_F12, \
406 KEY_H, KEY_G, KEY_F, KEY_D, \
407 KEY_S, KEY_A, KEY_RESERVED, KEY_CAPSLOCK, \
408 KEY_U, KEY_Y, KEY_T, KEY_R, \
409 KEY_E, KEY_W, KEY_Q, KEY_TAB, \
410 KEY_7, KEY_6, KEY_5, KEY_4, \
411 KEY_3, KEY_2, KEY_1, KEY_GRAVE, \
412 KEY_F13, KEY_F14, KEY_F15, KEY_F16, \
413 KEY_F17, KEY_F18, KEY_F19, KEY_F20, \
414 KEY_MENU, KEY_F4, KEY_F3, KEY_F2, \
415 KEY_F1, KEY_VOLUMEUP, KEY_STOP, KEY_SENDFILE, \
416 KEY_SYSRQ, KEY_F5, KEY_F6, KEY_F7, \
417 KEY_F8, KEY_VOLUMEDOWN, KEY_DEL_EOL, KEY_DEL_EOS, \
418 KEY_8, KEY_9, KEY_0, KEY_MINUS, \
419 KEY_EQUAL, KEY_BACKSPACE, KEY_INS_LINE, KEY_DEL_LINE, \
420 KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, \
421 KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_INSERT, KEY_DELETE, \
422 KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \
423 KEY_APOSTROPHE, KEY_ENTER, KEY_HOME, KEY_PAGEUP, \
424 KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, \
425 KEY_BACKSLASH, KEY_SELECT, KEY_102ND, KEY_PAGEDOWN, \
426 KEY_N, KEY_SPACE, KEY_NEXT, KEY_RESERVED, \
427 KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT
428
429
430#define HIL_KEYCODES_SET3_TBLSIZE 128
431#define HIL_KEYCODES_SET3 \
432 KEY_RESERVED, KEY_ESC, KEY_1, KEY_2, \
433 KEY_3, KEY_4, KEY_5, KEY_6, \
434 KEY_7, KEY_8, KEY_9, KEY_0, \
435 KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, \
436 KEY_Q, KEY_W, KEY_E, KEY_R, \
437 KEY_T, KEY_Y, KEY_U, KEY_I, \
438 KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, \
439 KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S, \
440 KEY_D, KEY_F, KEY_G, KEY_H, \
441 KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \
442 KEY_APOSTROPHE,KEY_GRAVE, KEY_LEFTSHIFT, KEY_BACKSLASH, \
443 KEY_Z, KEY_X, KEY_C, KEY_V, \
444 KEY_B, KEY_N, KEY_M, KEY_COMMA, \
445 KEY_DOT, KEY_SLASH, KEY_RIGHTSHIFT, KEY_KPASTERISK, \
446 KEY_LEFTALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1, \
447 KEY_F2, KEY_F3, KEY_F4, KEY_F5, \
448 KEY_F6, KEY_F7, KEY_F8, KEY_F9, \
449 KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KP7, \
450 KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4, \
451 KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1, \
452 KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT, \
453 KEY_SYSRQ, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
454 KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
455 KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
456 KEY_UP, KEY_LEFT, KEY_DOWN, KEY_RIGHT, \
457 KEY_HOME, KEY_PAGEUP, KEY_END, KEY_PAGEDOWN, \
458 KEY_INSERT, KEY_DELETE, KEY_102ND, KEY_RESERVED, \
459 KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
460 KEY_F1, KEY_F2, KEY_F3, KEY_F4, \
461 KEY_F5, KEY_F6, KEY_F7, KEY_F8, \
462 KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
463 KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
464
465
466/* Response to POL command, the "poll record header" */
467
468#define HIL_POL_NUM_AXES_MASK 0x03 /* Number of axis reported */
469#define HIL_POL_CTS 0x04 /* Device ready to receive data */
470#define HIL_POL_STATUS_PENDING 0x08 /* Device has status to report */
471#define HIL_POL_CHARTYPE_MASK 0x70 /* Type of character data to follow */
472#define HIL_POL_CHARTYPE_NONE 0x00 /* No character data to follow */
473#define HIL_POL_CHARTYPE_RSVD1 0x10 /* Reserved Set 1 */
474#define HIL_POL_CHARTYPE_ASCII 0x20 /* U.S. ASCII */
475#define HIL_POL_CHARTYPE_BINARY 0x30 /* Binary data */
476#define HIL_POL_CHARTYPE_SET1 0x40 /* Keycode Set 1 */
477#define HIL_POL_CHARTYPE_RSVD2 0x50 /* Reserved Set 2 */
478#define HIL_POL_CHARTYPE_SET2 0x60 /* Keycode Set 2 */
479#define HIL_POL_CHARTYPE_SET3 0x70 /* Keycode Set 3 */
480#define HIL_POL_AXIS_ALT 0x80 /* Data is from axis set 2 */
481
482
483#endif /* _HIL_H_ */
diff --git a/include/linux/hil_mlc.h b/include/linux/hil_mlc.h
new file mode 100644
index 000000000000..8df29ca48a13
--- /dev/null
+++ b/include/linux/hil_mlc.h
@@ -0,0 +1,168 @@
1/*
2 * HP Human Interface Loop Master Link Controller driver.
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
31 *
32 */
33
34#include <linux/hil.h>
35#include <linux/time.h>
36#include <linux/interrupt.h>
37#include <asm/semaphore.h>
38#include <linux/serio.h>
39#include <linux/list.h>
40
41typedef struct hil_mlc hil_mlc;
42
43/* The HIL has a complicated state engine.
44 * We define the structure of nodes in the state engine here.
45 */
46enum hilse_act {
47 /* HILSE_OUT prepares to receive input if the next node
48 * is an IN or EXPECT, and then sends the given packet.
49 */
50 HILSE_OUT = 0,
51
52 /* HILSE_CTS checks if the loop is busy. */
53 HILSE_CTS,
54
55 /* HILSE_OUT_LAST sends the given command packet to
56 * the last configured/running device on the loop.
57 */
58 HILSE_OUT_LAST,
59
60 /* HILSE_OUT_DISC sends the given command packet to
61 * the next device past the last configured/running one.
62 */
63 HILSE_OUT_DISC,
64
65 /* HILSE_FUNC runs a callback function with given arguments.
66 * a positive return value causes the "ugly" branch to be taken.
67 */
68 HILSE_FUNC,
69
70 /* HILSE_IN simply expects any non-errored packet to arrive
71 * within arg usecs.
72 */
73 HILSE_IN = 0x100,
74
75 /* HILSE_EXPECT expects a particular packet to arrive
76 * within arg usecs, any other packet is considered an error.
77 */
78 HILSE_EXPECT,
79
80 /* HILSE_EXPECT_LAST as above but dev field should be last
81 * discovered/operational device.
82 */
83 HILSE_EXPECT_LAST,
84
85 /* HILSE_EXPECT_LAST as above but dev field should be first
86 * undiscovered/inoperational device.
87 */
88 HILSE_EXPECT_DISC
89};
90
91typedef int (hilse_func) (hil_mlc *mlc, int arg);
92struct hilse_node {
93 enum hilse_act act; /* How to process this node */
94 union {
95 hilse_func *func; /* Function to call if HILSE_FUNC */
96 hil_packet packet; /* Packet to send or to compare */
97 } object;
98 int arg; /* Timeout in usec or parm for func */
99 int good; /* Node to jump to on success */
100 int bad; /* Node to jump to on error */
101 int ugly; /* Node to jump to on timeout */
102};
103
104/* Methods for back-end drivers, e.g. hp_sdc_mlc */
105typedef int (hil_mlc_cts) (hil_mlc *mlc);
106typedef void (hil_mlc_out) (hil_mlc *mlc);
107typedef int (hil_mlc_in) (hil_mlc *mlc, suseconds_t timeout);
108
109struct hil_mlc_devinfo {
110 uint8_t idd[16]; /* Device ID Byte and Describe Record */
111 uint8_t rsc[16]; /* Security Code Header and Record */
112 uint8_t exd[16]; /* Extended Describe Record */
113 uint8_t rnm[16]; /* Device name as returned by RNM command */
114};
115
116struct hil_mlc_serio_map {
117 hil_mlc *mlc;
118 int di_revmap;
119 int didx;
120};
121
122/* How many (possibly old/detached) devices the we try to keep track of */
123#define HIL_MLC_DEVMEM 16
124
125struct hil_mlc {
126 struct list_head list; /* hil_mlc is organized as linked list */
127
128 rwlock_t lock;
129
130 void *priv; /* Data specific to a particular type of MLC */
131
132 int seidx; /* Current node in state engine */
133 int istarted, ostarted;
134
135 hil_mlc_cts *cts;
136 struct semaphore csem; /* Raised when loop idle */
137
138 hil_mlc_out *out;
139 struct semaphore osem; /* Raised when outpacket dispatched */
140 hil_packet opacket;
141
142 hil_mlc_in *in;
143 struct semaphore isem; /* Raised when a packet arrives */
144 hil_packet ipacket[16];
145 hil_packet imatch;
146 int icount;
147 struct timeval instart;
148 suseconds_t intimeout;
149
150 int ddi; /* Last operational device id */
151 int lcv; /* LCV to throttle loops */
152 struct timeval lcv_tv; /* Time loop was started */
153
154 int di_map[7]; /* Maps below items to live devs */
155 struct hil_mlc_devinfo di[HIL_MLC_DEVMEM];
156 struct serio *serio[HIL_MLC_DEVMEM];
157 struct hil_mlc_serio_map serio_map[HIL_MLC_DEVMEM];
158 hil_packet serio_opacket[HIL_MLC_DEVMEM];
159 int serio_oidx[HIL_MLC_DEVMEM];
160 struct hil_mlc_devinfo di_scratch; /* Temporary area */
161
162 int opercnt;
163
164 struct tasklet_struct *tasklet;
165};
166
167int hil_mlc_register(hil_mlc *mlc);
168int hil_mlc_unregister(hil_mlc *mlc);
diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h
new file mode 100644
index 000000000000..debd71515312
--- /dev/null
+++ b/include/linux/hp_sdc.h
@@ -0,0 +1,300 @@
1/*
2 * HP i8042 System Device Controller -- header
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 *
31 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
32 *
33 * System Device Controller Microprocessor Firmware Theory of Operation
34 * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
35 *
36 */
37
38#ifndef _LINUX_HP_SDC_H
39#define _LINUX_HP_SDC_H
40
41#include <linux/interrupt.h>
42#include <linux/types.h>
43#include <linux/time.h>
44#include <linux/timer.h>
45#if defined(__hppa__)
46#include <asm/hardware.h>
47#endif
48
49
50/* No 4X status reads take longer than this (in usec).
51 */
52#define HP_SDC_MAX_REG_DELAY 20000
53
54typedef void (hp_sdc_irqhook) (int irq, void *dev_id,
55 uint8_t status, uint8_t data);
56
57int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback);
58int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback);
59int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback);
60int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback);
61int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback);
62int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback);
63
64typedef struct {
65 int actidx; /* Start of act. Acts are atomic WRT I/O to SDC */
66 int idx; /* Index within the act */
67 int endidx; /* transaction is over and done if idx == endidx */
68 uint8_t *seq; /* commands/data for the transaction */
69 union {
70 hp_sdc_irqhook *irqhook; /* Callback, isr or tasklet context */
71 struct semaphore *semaphore; /* Semaphore to sleep on. */
72 } act;
73} hp_sdc_transaction;
74int hp_sdc_enqueue_transaction(hp_sdc_transaction *this);
75int hp_sdc_dequeue_transaction(hp_sdc_transaction *this);
76
77/* The HP_SDC_ACT* values are peculiar to this driver.
78 * Nuance: never HP_SDC_ACT_DATAIN | HP_SDC_ACT_DEALLOC, use another
79 * act to perform the dealloc.
80 */
81#define HP_SDC_ACT_PRECMD 0x01 /* Send a command first */
82#define HP_SDC_ACT_DATAREG 0x02 /* Set data registers */
83#define HP_SDC_ACT_DATAOUT 0x04 /* Send data bytes */
84#define HP_SDC_ACT_POSTCMD 0x08 /* Send command after */
85#define HP_SDC_ACT_DATAIN 0x10 /* Collect data after */
86#define HP_SDC_ACT_DURING 0x1f
87#define HP_SDC_ACT_SEMAPHORE 0x20 /* Raise semaphore after */
88#define HP_SDC_ACT_CALLBACK 0x40 /* Pass data to IRQ handler */
89#define HP_SDC_ACT_DEALLOC 0x80 /* Destroy transaction after */
90#define HP_SDC_ACT_AFTER 0xe0
91#define HP_SDC_ACT_DEAD 0x60 /* Act timed out. */
92
93/* Rest of the flags are straightforward representation of the SDC interface */
94#define HP_SDC_STATUS_IBF 0x02 /* Input buffer full */
95
96#define HP_SDC_STATUS_IRQMASK 0xf0 /* Bits containing "level 1" irq */
97#define HP_SDC_STATUS_PERIODIC 0x10 /* Periodic 10ms timer */
98#define HP_SDC_STATUS_USERTIMER 0x20 /* "Special purpose" timer */
99#define HP_SDC_STATUS_TIMER 0x30 /* Both PERIODIC and USERTIMER */
100#define HP_SDC_STATUS_REG 0x40 /* Data from an i8042 register */
101#define HP_SDC_STATUS_HILCMD 0x50 /* Command from HIL MLC */
102#define HP_SDC_STATUS_HILDATA 0x60 /* Data from HIL MLC */
103#define HP_SDC_STATUS_PUP 0x70 /* Sucessful power-up self test */
104#define HP_SDC_STATUS_KCOOKED 0x80 /* Key from cooked kbd */
105#define HP_SDC_STATUS_KRPG 0xc0 /* Key from Repeat Gen */
106#define HP_SDC_STATUS_KMOD_SUP 0x10 /* Shift key is up */
107#define HP_SDC_STATUS_KMOD_CUP 0x20 /* Control key is up */
108
109#define HP_SDC_NMISTATUS_FHS 0x40 /* NMI is a fast handshake irq */
110
111/* Internal i8042 registers (there are more, but they are not too useful). */
112
113#define HP_SDC_USE 0x02 /* Resource usage (including OB bit) */
114#define HP_SDC_IM 0x04 /* Interrupt mask */
115#define HP_SDC_CFG 0x11 /* Configuration register */
116#define HP_SDC_KBLANGUAGE 0x12 /* Keyboard language */
117
118#define HP_SDC_D0 0x70 /* General purpose data buffer 0 */
119#define HP_SDC_D1 0x71 /* General purpose data buffer 1 */
120#define HP_SDC_D2 0x72 /* General purpose data buffer 2 */
121#define HP_SDC_D3 0x73 /* General purpose data buffer 3 */
122#define HP_SDC_VT1 0x74 /* Timer for voice 1 */
123#define HP_SDC_VT2 0x75 /* Timer for voice 2 */
124#define HP_SDC_VT3 0x76 /* Timer for voice 3 */
125#define HP_SDC_VT4 0x77 /* Timer for voice 4 */
126#define HP_SDC_KBN 0x78 /* Which HIL devs are Nimitz */
127#define HP_SDC_KBC 0x79 /* Which HIL devs are cooked kbds */
128#define HP_SDC_LPS 0x7a /* i8042's view of HIL status */
129#define HP_SDC_LPC 0x7b /* i8042's view of HIL "control" */
130#define HP_SDC_RSV 0x7c /* Reserved "for testing" */
131#define HP_SDC_LPR 0x7d /* i8042 count of HIL reconfigs */
132#define HP_SDC_XTD 0x7e /* "Extended Configuration" register */
133#define HP_SDC_STR 0x7f /* i8042 self-test result */
134
135/* Bitfields for above registers */
136#define HP_SDC_USE_LOOP 0x04 /* Command is currently on the loop. */
137
138#define HP_SDC_IM_MASK 0x1f /* these bits not part of cmd/status */
139#define HP_SDC_IM_FH 0x10 /* Mask the fast handshake irq */
140#define HP_SDC_IM_PT 0x08 /* Mask the periodic timer irq */
141#define HP_SDC_IM_TIMERS 0x04 /* Mask the MT/DT/CT irq */
142#define HP_SDC_IM_RESET 0x02 /* Mask the reset key irq */
143#define HP_SDC_IM_HIL 0x01 /* Mask the HIL MLC irq */
144
145#define HP_SDC_CFG_ROLLOVER 0x08 /* WTF is "N-key rollover"? */
146#define HP_SDC_CFG_KBD 0x10 /* There is a keyboard */
147#define HP_SDC_CFG_NEW 0x20 /* Supports/uses HIL MLC */
148#define HP_SDC_CFG_KBD_OLD 0x03 /* keyboard code for non-HIL */
149#define HP_SDC_CFG_KBD_NEW 0x07 /* keyboard code from HIL autoconfig */
150#define HP_SDC_CFG_REV 0x40 /* Code revision bit */
151#define HP_SDC_CFG_IDPROM 0x80 /* IDPROM present in kbd (not HIL) */
152
153#define HP_SDC_LPS_NDEV 0x07 /* # devices autoconfigured on HIL */
154#define HP_SDC_LPS_ACSUCC 0x08 /* loop autoconfigured successfully */
155#define HP_SDC_LPS_ACFAIL 0x80 /* last loop autoconfigure failed */
156
157#define HP_SDC_LPC_APE_IPF 0x01 /* HIL MLC APE/IPF (autopoll) set */
158#define HP_SDC_LPC_ARCONERR 0x02 /* i8042 autoreconfigs loop on err */
159#define HP_SDC_LPC_ARCQUIET 0x03 /* i8042 doesn't report autoreconfigs*/
160#define HP_SDC_LPC_COOK 0x10 /* i8042 cooks devices in _KBN */
161#define HP_SDC_LPC_RC 0x80 /* causes autoreconfig */
162
163#define HP_SDC_XTD_REV 0x07 /* contains revision code */
164#define HP_SDC_XTD_REV_STRINGS(val, str) \
165switch (val) { \
166 case 0x1: str = "1820-3712"; break; \
167 case 0x2: str = "1820-4379"; break; \
168 case 0x3: str = "1820-4784"; break; \
169 default: str = "unknown"; \
170};
171#define HP_SDC_XTD_BEEPER 0x08 /* TI SN76494 beeper available */
172#define HP_SDC_XTD_BBRTC 0x20 /* OKI MSM-58321 BBRTC present */
173
174#define HP_SDC_CMD_LOAD_RT 0x31 /* Load real time (from 8042) */
175#define HP_SDC_CMD_LOAD_FHS 0x36 /* Load the fast handshake timer */
176#define HP_SDC_CMD_LOAD_MT 0x38 /* Load the match timer */
177#define HP_SDC_CMD_LOAD_DT 0x3B /* Load the delay timer */
178#define HP_SDC_CMD_LOAD_CT 0x3E /* Load the cycle timer */
179
180#define HP_SDC_CMD_SET_IM 0x40 /* 010xxxxx == set irq mask */
181
182/* The documents provided do not explicitly state that all registers betweem
183 * 0x01 and 0x1f inclusive can be read by sending their register index as a
184 * command, but this is implied and appears to be the case.
185 */
186#define HP_SDC_CMD_READ_RAM 0x00 /* Load from i8042 RAM (autoinc) */
187#define HP_SDC_CMD_READ_USE 0x02 /* Undocumented! Load from usage reg */
188#define HP_SDC_CMD_READ_IM 0x04 /* Load current interrupt mask */
189#define HP_SDC_CMD_READ_KCC 0x11 /* Load primary kbd config code */
190#define HP_SDC_CMD_READ_KLC 0x12 /* Load primary kbd language code */
191#define HP_SDC_CMD_READ_T1 0x13 /* Load timer output buffer byte 1 */
192#define HP_SDC_CMD_READ_T2 0x14 /* Load timer output buffer byte 1 */
193#define HP_SDC_CMD_READ_T3 0x15 /* Load timer output buffer byte 1 */
194#define HP_SDC_CMD_READ_T4 0x16 /* Load timer output buffer byte 1 */
195#define HP_SDC_CMD_READ_T5 0x17 /* Load timer output buffer byte 1 */
196#define HP_SDC_CMD_READ_D0 0xf0 /* Load from i8042 RAM location 0x70 */
197#define HP_SDC_CMD_READ_D1 0xf1 /* Load from i8042 RAM location 0x71 */
198#define HP_SDC_CMD_READ_D2 0xf2 /* Load from i8042 RAM location 0x72 */
199#define HP_SDC_CMD_READ_D3 0xf3 /* Load from i8042 RAM location 0x73 */
200#define HP_SDC_CMD_READ_VT1 0xf4 /* Load from i8042 RAM location 0x74 */
201#define HP_SDC_CMD_READ_VT2 0xf5 /* Load from i8042 RAM location 0x75 */
202#define HP_SDC_CMD_READ_VT3 0xf6 /* Load from i8042 RAM location 0x76 */
203#define HP_SDC_CMD_READ_VT4 0xf7 /* Load from i8042 RAM location 0x77 */
204#define HP_SDC_CMD_READ_KBN 0xf8 /* Load from i8042 RAM location 0x78 */
205#define HP_SDC_CMD_READ_KBC 0xf9 /* Load from i8042 RAM location 0x79 */
206#define HP_SDC_CMD_READ_LPS 0xfa /* Load from i8042 RAM location 0x7a */
207#define HP_SDC_CMD_READ_LPC 0xfb /* Load from i8042 RAM location 0x7b */
208#define HP_SDC_CMD_READ_RSV 0xfc /* Load from i8042 RAM location 0x7c */
209#define HP_SDC_CMD_READ_LPR 0xfd /* Load from i8042 RAM location 0x7d */
210#define HP_SDC_CMD_READ_XTD 0xfe /* Load from i8042 RAM location 0x7e */
211#define HP_SDC_CMD_READ_STR 0xff /* Load from i8042 RAM location 0x7f */
212
213#define HP_SDC_CMD_SET_ARD 0xA0 /* Set emulated autorepeat delay */
214#define HP_SDC_CMD_SET_ARR 0xA2 /* Set emulated autorepeat rate */
215#define HP_SDC_CMD_SET_BELL 0xA3 /* Set voice 3 params for "beep" cmd */
216#define HP_SDC_CMD_SET_RPGR 0xA6 /* Set "RPG" irq rate (doesn't work) */
217#define HP_SDC_CMD_SET_RTMS 0xAD /* Set the RTC time (milliseconds) */
218#define HP_SDC_CMD_SET_RTD 0xAF /* Set the RTC time (days) */
219#define HP_SDC_CMD_SET_FHS 0xB2 /* Set fast handshake timer */
220#define HP_SDC_CMD_SET_MT 0xB4 /* Set match timer */
221#define HP_SDC_CMD_SET_DT 0xB7 /* Set delay timer */
222#define HP_SDC_CMD_SET_CT 0xBA /* Set cycle timer */
223#define HP_SDC_CMD_SET_RAMP 0xC1 /* Reset READ_RAM autoinc counter */
224#define HP_SDC_CMD_SET_D0 0xe0 /* Load to i8042 RAM location 0x70 */
225#define HP_SDC_CMD_SET_D1 0xe1 /* Load to i8042 RAM location 0x71 */
226#define HP_SDC_CMD_SET_D2 0xe2 /* Load to i8042 RAM location 0x72 */
227#define HP_SDC_CMD_SET_D3 0xe3 /* Load to i8042 RAM location 0x73 */
228#define HP_SDC_CMD_SET_VT1 0xe4 /* Load to i8042 RAM location 0x74 */
229#define HP_SDC_CMD_SET_VT2 0xe5 /* Load to i8042 RAM location 0x75 */
230#define HP_SDC_CMD_SET_VT3 0xe6 /* Load to i8042 RAM location 0x76 */
231#define HP_SDC_CMD_SET_VT4 0xe7 /* Load to i8042 RAM location 0x77 */
232#define HP_SDC_CMD_SET_KBN 0xe8 /* Load to i8042 RAM location 0x78 */
233#define HP_SDC_CMD_SET_KBC 0xe9 /* Load to i8042 RAM location 0x79 */
234#define HP_SDC_CMD_SET_LPS 0xea /* Load to i8042 RAM location 0x7a */
235#define HP_SDC_CMD_SET_LPC 0xeb /* Load to i8042 RAM location 0x7b */
236#define HP_SDC_CMD_SET_RSV 0xec /* Load to i8042 RAM location 0x7c */
237#define HP_SDC_CMD_SET_LPR 0xed /* Load to i8042 RAM location 0x7d */
238#define HP_SDC_CMD_SET_XTD 0xee /* Load to i8042 RAM location 0x7e */
239#define HP_SDC_CMD_SET_STR 0xef /* Load to i8042 RAM location 0x7f */
240
241#define HP_SDC_CMD_DO_RTCW 0xc2 /* i8042 RAM 0x70 --> RTC */
242#define HP_SDC_CMD_DO_RTCR 0xc3 /* RTC[0x70 0:3] --> irq/status/data */
243#define HP_SDC_CMD_DO_BEEP 0xc4 /* i8042 RAM 0x70-74 --> beeper,VT3 */
244#define HP_SDC_CMD_DO_HIL 0xc5 /* i8042 RAM 0x70-73 -->
245 HIL MLC R0,R1 i8042 HIL watchdog */
246
247/* Values used to (de)mangle input/output to/from the HIL MLC */
248#define HP_SDC_DATA 0x40 /* Data from an 8042 register */
249#define HP_SDC_HIL_CMD 0x50 /* Data from HIL MLC R1/8042 */
250#define HP_SDC_HIL_R1MASK 0x0f /* Contents of HIL MLC R1 0:3 */
251#define HP_SDC_HIL_AUTO 0x10 /* Set if POL results from i8042 */
252#define HP_SDC_HIL_ISERR 0x80 /* Has meaning as in next 4 values */
253#define HP_SDC_HIL_RC_DONE 0x80 /* i8042 auto-configured loop */
254#define HP_SDC_HIL_ERR 0x81 /* HIL MLC R2 had a bit set */
255#define HP_SDC_HIL_TO 0x82 /* i8042 HIL watchdog expired */
256#define HP_SDC_HIL_RC 0x84 /* i8042 is auto-configuring loop */
257#define HP_SDC_HIL_DAT 0x60 /* Data from HIL MLC R0 */
258
259
260typedef struct {
261 rwlock_t ibf_lock;
262 rwlock_t lock; /* user/tasklet lock */
263 rwlock_t rtq_lock; /* isr/tasklet lock */
264 rwlock_t hook_lock; /* isr/user lock for handler add/del */
265
266 unsigned int irq, nmi; /* Our IRQ lines */
267 unsigned long base_io, status_io, data_io; /* Our IO ports */
268
269 uint8_t im; /* Interrupt mask */
270 int set_im; /* Interrupt mask needs to be set. */
271
272 int ibf; /* Last known status of IBF flag */
273 uint8_t wi; /* current i8042 write index */
274 uint8_t r7[4]; /* current i8042[0x70 - 0x74] values */
275 uint8_t r11, r7e; /* Values from version/revision regs */
276
277 hp_sdc_irqhook *timer, *reg, *hil, *pup, *cooked;
278
279#define HP_SDC_QUEUE_LEN 16
280 hp_sdc_transaction *tq[HP_SDC_QUEUE_LEN]; /* All pending read/writes */
281
282 int rcurr, rqty; /* Current read transact in process */
283 struct timeval rtv; /* Time when current read started */
284 int wcurr; /* Current write transact in process */
285
286 int dev_err; /* carries status from registration */
287#if defined(__hppa__)
288 struct parisc_device *dev;
289#elif defined(__mc68000__)
290 void *dev;
291#else
292#error No support for device registration on this arch yet.
293#endif
294
295 struct timer_list kicker; /* Keeps below task alive */
296 struct tasklet_struct task;
297
298} hp_i8042_sdc;
299
300#endif /* _LINUX_HP_SDC_H */
diff --git a/include/linux/input.h b/include/linux/input.h
index e8c296ff6257..d7836311ada9 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -644,6 +644,7 @@ struct input_absinfo {
644#define BUS_ADB 0x17 644#define BUS_ADB 0x17
645#define BUS_I2C 0x18 645#define BUS_I2C 0x18
646#define BUS_HOST 0x19 646#define BUS_HOST 0x19
647#define BUS_GSC 0x1A
647 648
648/* 649/*
649 * Values describing the status of an effect 650 * Values describing the status of an effect