Commit 2f82af08fcc7dc01a7e98a49a5995a77e32a2925
Committed by
Linus Torvalds
1 parent
f199fd9906
Exists in
master
and in
4 other branches
Nicolas Pitre has a new email address
Due to problems at cam.org, my nico@cam.org email address is no longer valid. FRom now on, nico@fluxnic.net should be used instead. Signed-off-by: Nicolas Pitre <nico@fluxnic.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 39 changed files with 45 additions and 45 deletions Inline Diff
- CREDITS
- Documentation/arm/SA1100/ADSBitsy
- Documentation/arm/SA1100/Assabet
- Documentation/arm/SA1100/Brutus
- Documentation/arm/SA1100/GraphicsClient
- Documentation/arm/SA1100/GraphicsMaster
- Documentation/arm/SA1100/Victor
- MAINTAINERS
- arch/arm/boot/compressed/head-sa1100.S
- arch/arm/lib/lib1funcs.S
- arch/arm/lib/sha1.S
- arch/arm/mach-sa1100/include/mach/assabet.h
- arch/arm/mach-sa1100/include/mach/hardware.h
- arch/arm/mach-sa1100/include/mach/memory.h
- arch/arm/mach-sa1100/include/mach/neponset.h
- arch/arm/mach-sa1100/include/mach/system.h
- arch/arm/mach-sa1100/include/mach/uncompress.h
- arch/arm/mach-sa1100/pm.c
- arch/arm/mach-sa1100/time.c
- arch/arm/mm/proc-xscale.S
- arch/arm/plat-iop/setup.c
- arch/arm/plat-omap/include/mach/system.h
- drivers/input/keyboard/pxa27x_keypad.c
- drivers/mtd/chips/cfi_cmdset_0001.c
- drivers/mtd/chips/cfi_cmdset_0020.c
- drivers/mtd/maps/bfin-async-flash.c
- drivers/mtd/maps/ceiva.c
- drivers/mtd/maps/dc21285.c
- drivers/mtd/maps/ipaq-flash.c
- drivers/mtd/maps/pxa2xx-flash.c
- drivers/mtd/maps/sa1100-flash.c
- drivers/mtd/mtdblock.c
- drivers/mtd/mtdpart.c
- drivers/net/smc91x.c
- drivers/net/smc91x.h
- drivers/rtc/rtc-sa1100.c
- drivers/video/sa1100fb.c
- include/linux/mtd/partitions.h
- lib/inflate.c
CREDITS
1 | This is at least a partial credits-file of people that have | 1 | This is at least a partial credits-file of people that have |
2 | contributed to the Linux project. It is sorted by name and | 2 | contributed to the Linux project. It is sorted by name and |
3 | formatted to allow easy grepping and beautification by | 3 | formatted to allow easy grepping and beautification by |
4 | scripts. The fields are: name (N), email (E), web-address | 4 | scripts. The fields are: name (N), email (E), web-address |
5 | (W), PGP key ID and fingerprint (P), description (D), and | 5 | (W), PGP key ID and fingerprint (P), description (D), and |
6 | snail-mail address (S). | 6 | snail-mail address (S). |
7 | Thanks, | 7 | Thanks, |
8 | 8 | ||
9 | Linus | 9 | Linus |
10 | ---------- | 10 | ---------- |
11 | 11 | ||
12 | N: Matti Aarnio | 12 | N: Matti Aarnio |
13 | E: mea@nic.funet.fi | 13 | E: mea@nic.funet.fi |
14 | D: Alpha systems hacking, IPv6 and other network related stuff | 14 | D: Alpha systems hacking, IPv6 and other network related stuff |
15 | D: One of assisting postmasters for vger.kernel.org's lists | 15 | D: One of assisting postmasters for vger.kernel.org's lists |
16 | S: (ask for current address) | 16 | S: (ask for current address) |
17 | S: Finland | 17 | S: Finland |
18 | 18 | ||
19 | N: Dragos Acostachioaie | 19 | N: Dragos Acostachioaie |
20 | E: dragos@iname.com | 20 | E: dragos@iname.com |
21 | W: http://www.arbornet.org/~dragos | 21 | W: http://www.arbornet.org/~dragos |
22 | D: /proc/sysvipc | 22 | D: /proc/sysvipc |
23 | S: C. Negri 6, bl. D3 | 23 | S: C. Negri 6, bl. D3 |
24 | S: Iasi 6600 | 24 | S: Iasi 6600 |
25 | S: Romania | 25 | S: Romania |
26 | 26 | ||
27 | N: Mark Adler | 27 | N: Mark Adler |
28 | E: madler@alumni.caltech.edu | 28 | E: madler@alumni.caltech.edu |
29 | W: http://alumnus.caltech.edu/~madler/ | 29 | W: http://alumnus.caltech.edu/~madler/ |
30 | D: zlib decompression | 30 | D: zlib decompression |
31 | 31 | ||
32 | N: Monalisa Agrawal | 32 | N: Monalisa Agrawal |
33 | E: magrawal@nortelnetworks.com | 33 | E: magrawal@nortelnetworks.com |
34 | D: Basic Interphase 5575 driver with UBR and ABR support. | 34 | D: Basic Interphase 5575 driver with UBR and ABR support. |
35 | S: 75 Donald St, Apt 42 | 35 | S: 75 Donald St, Apt 42 |
36 | S: Weymouth, MA 02188 | 36 | S: Weymouth, MA 02188 |
37 | S: USA | 37 | S: USA |
38 | 38 | ||
39 | N: Dave Airlie | 39 | N: Dave Airlie |
40 | E: airlied@linux.ie | 40 | E: airlied@linux.ie |
41 | W: http://www.csn.ul.ie/~airlied | 41 | W: http://www.csn.ul.ie/~airlied |
42 | D: NFS over TCP patches | 42 | D: NFS over TCP patches |
43 | D: in-kernel DRM Maintainer | 43 | D: in-kernel DRM Maintainer |
44 | S: Longford, Ireland | 44 | S: Longford, Ireland |
45 | S: Sydney, Australia | 45 | S: Sydney, Australia |
46 | 46 | ||
47 | N: Tigran A. Aivazian | 47 | N: Tigran A. Aivazian |
48 | E: tigran@aivazian.fsnet.co.uk | 48 | E: tigran@aivazian.fsnet.co.uk |
49 | W: http://www.moses.uklinux.net/patches | 49 | W: http://www.moses.uklinux.net/patches |
50 | D: BFS filesystem | 50 | D: BFS filesystem |
51 | D: Intel IA32 CPU microcode update support | 51 | D: Intel IA32 CPU microcode update support |
52 | D: Various kernel patches | 52 | D: Various kernel patches |
53 | S: United Kingdom | 53 | S: United Kingdom |
54 | 54 | ||
55 | N: Werner Almesberger | 55 | N: Werner Almesberger |
56 | E: werner@almesberger.net | 56 | E: werner@almesberger.net |
57 | W: http://www.almesberger.net/ | 57 | W: http://www.almesberger.net/ |
58 | D: dosfs, LILO, some fd features, ATM, various other hacks here and there | 58 | D: dosfs, LILO, some fd features, ATM, various other hacks here and there |
59 | S: Buenos Aires | 59 | S: Buenos Aires |
60 | S: Argentina | 60 | S: Argentina |
61 | 61 | ||
62 | N: Tim Alpaerts | 62 | N: Tim Alpaerts |
63 | E: tim_alpaerts@toyota-motor-europe.com | 63 | E: tim_alpaerts@toyota-motor-europe.com |
64 | D: 802.2 class II logical link control layer, | 64 | D: 802.2 class II logical link control layer, |
65 | D: the humble start of an opening towards the IBM SNA protocols | 65 | D: the humble start of an opening towards the IBM SNA protocols |
66 | S: Klaproosstraat 72 c 10 | 66 | S: Klaproosstraat 72 c 10 |
67 | S: B-2610 Wilrijk-Antwerpen | 67 | S: B-2610 Wilrijk-Antwerpen |
68 | S: Belgium | 68 | S: Belgium |
69 | 69 | ||
70 | N: Anton Altaparmakov | 70 | N: Anton Altaparmakov |
71 | E: aia21@cantab.net | 71 | E: aia21@cantab.net |
72 | W: http://www-stu.christs.cam.ac.uk/~aia21/ | 72 | W: http://www-stu.christs.cam.ac.uk/~aia21/ |
73 | D: Author of new NTFS driver, various other kernel hacks. | 73 | D: Author of new NTFS driver, various other kernel hacks. |
74 | S: Christ's College | 74 | S: Christ's College |
75 | S: Cambridge CB2 3BU | 75 | S: Cambridge CB2 3BU |
76 | S: United Kingdom | 76 | S: United Kingdom |
77 | 77 | ||
78 | N: C. Scott Ananian | 78 | N: C. Scott Ananian |
79 | E: cananian@alumni.princeton.edu | 79 | E: cananian@alumni.princeton.edu |
80 | W: http://www.pdos.lcs.mit.edu/~cananian | 80 | W: http://www.pdos.lcs.mit.edu/~cananian |
81 | P: 1024/85AD9EED AD C0 49 08 91 67 DF D7 FA 04 1A EE 09 E8 44 B0 | 81 | P: 1024/85AD9EED AD C0 49 08 91 67 DF D7 FA 04 1A EE 09 E8 44 B0 |
82 | D: Unix98 pty support. | 82 | D: Unix98 pty support. |
83 | D: APM update to 1.2 spec. | 83 | D: APM update to 1.2 spec. |
84 | D: /devfs hacking. | 84 | D: /devfs hacking. |
85 | S: 7 Kiwi Loop | 85 | S: 7 Kiwi Loop |
86 | S: Howell, NJ 07731 | 86 | S: Howell, NJ 07731 |
87 | S: USA | 87 | S: USA |
88 | 88 | ||
89 | N: Erik Andersen | 89 | N: Erik Andersen |
90 | E: andersen@codepoet.org | 90 | E: andersen@codepoet.org |
91 | W: http://www.codepoet.org/ | 91 | W: http://www.codepoet.org/ |
92 | P: 1024D/30D39057 1BC4 2742 E885 E4DE 9301 0C82 5F9B 643E 30D3 9057 | 92 | P: 1024D/30D39057 1BC4 2742 E885 E4DE 9301 0C82 5F9B 643E 30D3 9057 |
93 | D: Maintainer of ide-cd and Uniform CD-ROM driver, | 93 | D: Maintainer of ide-cd and Uniform CD-ROM driver, |
94 | D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update. | 94 | D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update. |
95 | S: 352 North 525 East | 95 | S: 352 North 525 East |
96 | S: Springville, Utah 84663 | 96 | S: Springville, Utah 84663 |
97 | S: USA | 97 | S: USA |
98 | 98 | ||
99 | N: Michael Ang | 99 | N: Michael Ang |
100 | E: mang@subcarrier.org | 100 | E: mang@subcarrier.org |
101 | W: http://www.subcarrier.org/mang | 101 | W: http://www.subcarrier.org/mang |
102 | D: Linux/PA-RISC hacker | 102 | D: Linux/PA-RISC hacker |
103 | S: 85 Frank St. | 103 | S: 85 Frank St. |
104 | S: Ottawa, Ontario | 104 | S: Ottawa, Ontario |
105 | S: Canada K2P 0X3 | 105 | S: Canada K2P 0X3 |
106 | 106 | ||
107 | N: H. Peter Anvin | 107 | N: H. Peter Anvin |
108 | E: hpa@zytor.com | 108 | E: hpa@zytor.com |
109 | W: http://www.zytor.com/~hpa/ | 109 | W: http://www.zytor.com/~hpa/ |
110 | P: 2047/2A960705 BA 03 D3 2C 14 A8 A8 BD 1E DF FE 69 EE 35 BD 74 | 110 | P: 2047/2A960705 BA 03 D3 2C 14 A8 A8 BD 1E DF FE 69 EE 35 BD 74 |
111 | D: Author of the SYSLINUX boot loader, maintainer of the linux.* news | 111 | D: Author of the SYSLINUX boot loader, maintainer of the linux.* news |
112 | D: hierarchy and the Linux Device List; various kernel hacks | 112 | D: hierarchy and the Linux Device List; various kernel hacks |
113 | S: 4390 Albany Drive #46 | 113 | S: 4390 Albany Drive #46 |
114 | S: San Jose, California 95129 | 114 | S: San Jose, California 95129 |
115 | S: USA | 115 | S: USA |
116 | 116 | ||
117 | N: Andrea Arcangeli | 117 | N: Andrea Arcangeli |
118 | E: andrea@suse.de | 118 | E: andrea@suse.de |
119 | W: http://www.kernel.org/pub/linux/kernel/people/andrea/ | 119 | W: http://www.kernel.org/pub/linux/kernel/people/andrea/ |
120 | P: 1024D/68B9CB43 13D9 8355 295F 4823 7C49 C012 DFA1 686E 68B9 CB43 | 120 | P: 1024D/68B9CB43 13D9 8355 295F 4823 7C49 C012 DFA1 686E 68B9 CB43 |
121 | P: 1024R/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 | 121 | P: 1024R/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 |
122 | D: Parport hacker | 122 | D: Parport hacker |
123 | D: Implemented a workaround for some interrupt buggy printers | 123 | D: Implemented a workaround for some interrupt buggy printers |
124 | D: Author of pscan that helps to fix lp/parport bugs | 124 | D: Author of pscan that helps to fix lp/parport bugs |
125 | D: Author of lil (Linux Interrupt Latency benchmark) | 125 | D: Author of lil (Linux Interrupt Latency benchmark) |
126 | D: Fixed the shm swap deallocation at swapoff time (try_to_unuse message) | 126 | D: Fixed the shm swap deallocation at swapoff time (try_to_unuse message) |
127 | D: VM hacker | 127 | D: VM hacker |
128 | D: Various other kernel hacks | 128 | D: Various other kernel hacks |
129 | S: Imola 40026 | 129 | S: Imola 40026 |
130 | S: Italy | 130 | S: Italy |
131 | 131 | ||
132 | N: Derek Atkins | 132 | N: Derek Atkins |
133 | E: warlord@MIT.EDU | 133 | E: warlord@MIT.EDU |
134 | D: Linux-AFS Port, random kernel hacker, | 134 | D: Linux-AFS Port, random kernel hacker, |
135 | D: VFS fixes (new notify_change in particular) | 135 | D: VFS fixes (new notify_change in particular) |
136 | D: Moving all VFS access checks into the file systems | 136 | D: Moving all VFS access checks into the file systems |
137 | S: MIT Room E15-341 | 137 | S: MIT Room E15-341 |
138 | S: 20 Ames Street | 138 | S: 20 Ames Street |
139 | S: Cambridge, Massachusetts 02139 | 139 | S: Cambridge, Massachusetts 02139 |
140 | S: USA | 140 | S: USA |
141 | 141 | ||
142 | N: Michel Aubry | 142 | N: Michel Aubry |
143 | E: giovanni <giovanni@sudfr.com> | 143 | E: giovanni <giovanni@sudfr.com> |
144 | D: Aladdin 1533/1543(C) chipset IDE | 144 | D: Aladdin 1533/1543(C) chipset IDE |
145 | D: VIA MVP-3/TX Pro III chipset IDE | 145 | D: VIA MVP-3/TX Pro III chipset IDE |
146 | 146 | ||
147 | N: Jens Axboe | 147 | N: Jens Axboe |
148 | E: axboe@suse.de | 148 | E: axboe@suse.de |
149 | D: Linux CD-ROM maintainer, DVD support | 149 | D: Linux CD-ROM maintainer, DVD support |
150 | D: elevator + block layer rewrites | 150 | D: elevator + block layer rewrites |
151 | D: highmem I/O support | 151 | D: highmem I/O support |
152 | D: misc hacking on IDE, SCSI, block drivers, etc | 152 | D: misc hacking on IDE, SCSI, block drivers, etc |
153 | S: Peter Bangs Vej 258, 2TH | 153 | S: Peter Bangs Vej 258, 2TH |
154 | S: 2500 Valby | 154 | S: 2500 Valby |
155 | S: Denmark | 155 | S: Denmark |
156 | 156 | ||
157 | N: John Aycock | 157 | N: John Aycock |
158 | E: aycock@cpsc.ucalgary.ca | 158 | E: aycock@cpsc.ucalgary.ca |
159 | D: Adaptec 274x driver | 159 | D: Adaptec 274x driver |
160 | S: Department of Computer Science | 160 | S: Department of Computer Science |
161 | S: University of Calgary | 161 | S: University of Calgary |
162 | S: Calgary, Alberta | 162 | S: Calgary, Alberta |
163 | S: Canada | 163 | S: Canada |
164 | 164 | ||
165 | N: Miles Bader | 165 | N: Miles Bader |
166 | E: miles@gnu.org | 166 | E: miles@gnu.org |
167 | D: v850 port (uClinux) | 167 | D: v850 port (uClinux) |
168 | S: NEC Corporation | 168 | S: NEC Corporation |
169 | S: 1753 Shimonumabe, Nakahara-ku | 169 | S: 1753 Shimonumabe, Nakahara-ku |
170 | S: Kawasaki 211-8666 | 170 | S: Kawasaki 211-8666 |
171 | S: Japan | 171 | S: Japan |
172 | 172 | ||
173 | N: Ralf Baechle | 173 | N: Ralf Baechle |
174 | E: ralf@gnu.org | 174 | E: ralf@gnu.org |
175 | P: 1024/AF7B30C1 CF 97 C2 CC 6D AE A7 FE C8 BA 9C FC 88 DE 32 C3 | 175 | P: 1024/AF7B30C1 CF 97 C2 CC 6D AE A7 FE C8 BA 9C FC 88 DE 32 C3 |
176 | D: Linux/MIPS port | 176 | D: Linux/MIPS port |
177 | D: Linux/68k hacker | 177 | D: Linux/68k hacker |
178 | S: Hauptstrasse 19 | 178 | S: Hauptstrasse 19 |
179 | S: 79837 St. Blasien | 179 | S: 79837 St. Blasien |
180 | S: Germany | 180 | S: Germany |
181 | 181 | ||
182 | N: Krishna Balasubramanian | 182 | N: Krishna Balasubramanian |
183 | E: balasub@cis.ohio-state.edu | 183 | E: balasub@cis.ohio-state.edu |
184 | D: Wrote SYS V IPC (part of standard kernel since 0.99.10) | 184 | D: Wrote SYS V IPC (part of standard kernel since 0.99.10) |
185 | 185 | ||
186 | N: Dario Ballabio | 186 | N: Dario Ballabio |
187 | E: ballabio_dario@emc.com | 187 | E: ballabio_dario@emc.com |
188 | E: dario.ballabio@tiscalinet.it | 188 | E: dario.ballabio@tiscalinet.it |
189 | E: dario.ballabio@inwind.it | 189 | E: dario.ballabio@inwind.it |
190 | D: Author and maintainer of the Ultrastor 14F/34F SCSI driver | 190 | D: Author and maintainer of the Ultrastor 14F/34F SCSI driver |
191 | D: Author and maintainer of the EATA ISA/EISA/PCI SCSI driver | 191 | D: Author and maintainer of the EATA ISA/EISA/PCI SCSI driver |
192 | S: EMC Corporation | 192 | S: EMC Corporation |
193 | S: Milano | 193 | S: Milano |
194 | S: Italy | 194 | S: Italy |
195 | 195 | ||
196 | N: Paul Bame | 196 | N: Paul Bame |
197 | E: bame@debian.org | 197 | E: bame@debian.org |
198 | E: bame@puffin.external.hp.com | 198 | E: bame@puffin.external.hp.com |
199 | E: paul_bame@hp.com | 199 | E: paul_bame@hp.com |
200 | W: http://www.parisc-linux.org | 200 | W: http://www.parisc-linux.org |
201 | D: PA-RISC 32 and 64-bit early boot, firmware interface, interrupts, misc | 201 | D: PA-RISC 32 and 64-bit early boot, firmware interface, interrupts, misc |
202 | S: MS42 | 202 | S: MS42 |
203 | S: Hewlett-Packard | 203 | S: Hewlett-Packard |
204 | S: 3404 E Harmony Rd | 204 | S: 3404 E Harmony Rd |
205 | S: Fort Collins, CO 80525 | 205 | S: Fort Collins, CO 80525 |
206 | S: USA | 206 | S: USA |
207 | 207 | ||
208 | N: Arindam Banerji | 208 | N: Arindam Banerji |
209 | E: axb@cse.nd.edu | 209 | E: axb@cse.nd.edu |
210 | D: Contributed ESDI driver routines needed to port LINUX to the PS/2 MCA. | 210 | D: Contributed ESDI driver routines needed to port LINUX to the PS/2 MCA. |
211 | S: Department of Computer Science & Eng. | 211 | S: Department of Computer Science & Eng. |
212 | S: University of Notre Dame | 212 | S: University of Notre Dame |
213 | S: Notre Dame, Indiana | 213 | S: Notre Dame, Indiana |
214 | S: USA | 214 | S: USA |
215 | 215 | ||
216 | N: Greg Banks | 216 | N: Greg Banks |
217 | E: gnb@alphalink.com.au | 217 | E: gnb@alphalink.com.au |
218 | D: IDT77105 ATM network driver | 218 | D: IDT77105 ATM network driver |
219 | D: some SuperH port work | 219 | D: some SuperH port work |
220 | D: some trivial futzing with kconfig | 220 | D: some trivial futzing with kconfig |
221 | 221 | ||
222 | N: James Banks | 222 | N: James Banks |
223 | E: james@sovereign.org | 223 | E: james@sovereign.org |
224 | D: TLAN network driver | 224 | D: TLAN network driver |
225 | D: Logitech Busmouse driver | 225 | D: Logitech Busmouse driver |
226 | 226 | ||
227 | N: Krzysztof G. Baranowski | 227 | N: Krzysztof G. Baranowski |
228 | E: kgb@manjak.knm.org.pl | 228 | E: kgb@manjak.knm.org.pl |
229 | P: 1024/FA6F16D1 96 D1 1A CF 5F CA 69 EC F9 4F 36 1F 6D 60 7B DA | 229 | P: 1024/FA6F16D1 96 D1 1A CF 5F CA 69 EC F9 4F 36 1F 6D 60 7B DA |
230 | D: Maintainer of the System V file system. | 230 | D: Maintainer of the System V file system. |
231 | D: System V fs update for 2.1.x dcache. | 231 | D: System V fs update for 2.1.x dcache. |
232 | D: Forward ported a couple of SCSI drivers. | 232 | D: Forward ported a couple of SCSI drivers. |
233 | D: Various bugfixes. | 233 | D: Various bugfixes. |
234 | S: ul. Koscielna 12a | 234 | S: ul. Koscielna 12a |
235 | S: 62-300 Wrzesnia | 235 | S: 62-300 Wrzesnia |
236 | S: Poland | 236 | S: Poland |
237 | 237 | ||
238 | N: Fred Barnes | 238 | N: Fred Barnes |
239 | E: frmb2@ukc.ac.uk | 239 | E: frmb2@ukc.ac.uk |
240 | D: Various parport/ppdev hacks and fixes | 240 | D: Various parport/ppdev hacks and fixes |
241 | S: Computing Lab, The University | 241 | S: Computing Lab, The University |
242 | S: Canterbury, KENT | 242 | S: Canterbury, KENT |
243 | S: CT2 7NF | 243 | S: CT2 7NF |
244 | S: England | 244 | S: England |
245 | 245 | ||
246 | N: Paul Barton-Davis | 246 | N: Paul Barton-Davis |
247 | E: pbd@op.net | 247 | E: pbd@op.net |
248 | D: Driver for WaveFront soundcards (Turtle Beach Maui, Tropez, Tropez+) | 248 | D: Driver for WaveFront soundcards (Turtle Beach Maui, Tropez, Tropez+) |
249 | D: Various bugfixes and changes to sound drivers | 249 | D: Various bugfixes and changes to sound drivers |
250 | S: USA | 250 | S: USA |
251 | 251 | ||
252 | N: Carlos Henrique Bauer | 252 | N: Carlos Henrique Bauer |
253 | E: chbauer@acm.org | 253 | E: chbauer@acm.org |
254 | E: bauer@atlas.unisinos.br | 254 | E: bauer@atlas.unisinos.br |
255 | D: Some new sysctl entries for the parport driver. | 255 | D: Some new sysctl entries for the parport driver. |
256 | D: New sysctl function for handling unsigned longs | 256 | D: New sysctl function for handling unsigned longs |
257 | S: Universidade do Vale do Rio dos Sinos - UNISINOS | 257 | S: Universidade do Vale do Rio dos Sinos - UNISINOS |
258 | S: DSI/IDASI | 258 | S: DSI/IDASI |
259 | S: Av. Unisinos, 950 | 259 | S: Av. Unisinos, 950 |
260 | S: 93022000 Sao Leopoldo RS | 260 | S: 93022000 Sao Leopoldo RS |
261 | S: Brazil | 261 | S: Brazil |
262 | 262 | ||
263 | N: Peter Bauer | 263 | N: Peter Bauer |
264 | E: 100136.3530@compuserve.com | 264 | E: 100136.3530@compuserve.com |
265 | D: Driver for depca-ethernet-board | 265 | D: Driver for depca-ethernet-board |
266 | S: 69259 Wilhemsfeld | 266 | S: 69259 Wilhemsfeld |
267 | S: Rainweg 15 | 267 | S: Rainweg 15 |
268 | S: Germany | 268 | S: Germany |
269 | 269 | ||
270 | N: Fred Baumgarten | 270 | N: Fred Baumgarten |
271 | E: dc6iq@insl1.etec.uni-karlsruhe.de | 271 | E: dc6iq@insl1.etec.uni-karlsruhe.de |
272 | E: dc6iq@adacom.org | 272 | E: dc6iq@adacom.org |
273 | E: dc6iq@db0ais.#hes.deu.eu (packet radio) | 273 | E: dc6iq@db0ais.#hes.deu.eu (packet radio) |
274 | D: NET-2 & netstat(8) | 274 | D: NET-2 & netstat(8) |
275 | S: Soevener Strasse 11 | 275 | S: Soevener Strasse 11 |
276 | S: 53773 Hennef | 276 | S: 53773 Hennef |
277 | S: Germany | 277 | S: Germany |
278 | 278 | ||
279 | N: Donald Becker | 279 | N: Donald Becker |
280 | E: becker@cesdis.gsfc.nasa.gov | 280 | E: becker@cesdis.gsfc.nasa.gov |
281 | D: General low-level networking hacker | 281 | D: General low-level networking hacker |
282 | D: Most of the ethercard drivers | 282 | D: Most of the ethercard drivers |
283 | D: Original author of the NFS server | 283 | D: Original author of the NFS server |
284 | S: USRA Center of Excellence in Space Data and Information Sciences | 284 | S: USRA Center of Excellence in Space Data and Information Sciences |
285 | S: Code 930.5, Goddard Space Flight Center | 285 | S: Code 930.5, Goddard Space Flight Center |
286 | S: Greenbelt, Maryland 20771 | 286 | S: Greenbelt, Maryland 20771 |
287 | S: USA | 287 | S: USA |
288 | 288 | ||
289 | N: Adam Belay | 289 | N: Adam Belay |
290 | E: ambx1@neo.rr.com | 290 | E: ambx1@neo.rr.com |
291 | D: Linux Plug and Play Support | 291 | D: Linux Plug and Play Support |
292 | S: USA | 292 | S: USA |
293 | 293 | ||
294 | N: Daniele Bellucci | 294 | N: Daniele Bellucci |
295 | E: bellucda@tiscali.it | 295 | E: bellucda@tiscali.it |
296 | D: Various Janitor work. | 296 | D: Various Janitor work. |
297 | W: http://web.tiscali.it/bellucda | 297 | W: http://web.tiscali.it/bellucda |
298 | S: Via Delle Palme, 9 | 298 | S: Via Delle Palme, 9 |
299 | S: Terni 05100 | 299 | S: Terni 05100 |
300 | S: Italy | 300 | S: Italy |
301 | 301 | ||
302 | N: Krzysztof Benedyczak | 302 | N: Krzysztof Benedyczak |
303 | E: golbi@mat.uni.torun.pl | 303 | E: golbi@mat.uni.torun.pl |
304 | W: http://www.mat.uni.torun.pl/~golbi | 304 | W: http://www.mat.uni.torun.pl/~golbi |
305 | D: POSIX message queues fs (with M. Wronski) | 305 | D: POSIX message queues fs (with M. Wronski) |
306 | S: ul. Podmiejska 52 | 306 | S: ul. Podmiejska 52 |
307 | S: Radunica | 307 | S: Radunica |
308 | S: 83-000 Pruszcz Gdanski | 308 | S: 83-000 Pruszcz Gdanski |
309 | S: Poland | 309 | S: Poland |
310 | 310 | ||
311 | N: Randolph Bentson | 311 | N: Randolph Bentson |
312 | E: bentson@grieg.seaslug.org | 312 | E: bentson@grieg.seaslug.org |
313 | W: http://www.aa.net/~bentson/ | 313 | W: http://www.aa.net/~bentson/ |
314 | P: 1024/39ED5729 5C A8 7A F4 B2 7A D1 3E B5 3B 81 CF 47 30 11 71 | 314 | P: 1024/39ED5729 5C A8 7A F4 B2 7A D1 3E B5 3B 81 CF 47 30 11 71 |
315 | D: Author of driver for Cyclom-Y and Cyclades-Z async mux | 315 | D: Author of driver for Cyclom-Y and Cyclades-Z async mux |
316 | S: 2322 37th Ave SW | 316 | S: 2322 37th Ave SW |
317 | S: Seattle, Washington 98126-2010 | 317 | S: Seattle, Washington 98126-2010 |
318 | S: USA | 318 | S: USA |
319 | 319 | ||
320 | N: Muli Ben-Yehuda | 320 | N: Muli Ben-Yehuda |
321 | E: mulix@mulix.org | 321 | E: mulix@mulix.org |
322 | E: muli@il.ibm.com | 322 | E: muli@il.ibm.com |
323 | W: http://www.mulix.org | 323 | W: http://www.mulix.org |
324 | D: trident OSS sound driver, x86-64 dma-ops and Calgary IOMMU, | 324 | D: trident OSS sound driver, x86-64 dma-ops and Calgary IOMMU, |
325 | D: KVM and Xen bits and other misc. hackery. | 325 | D: KVM and Xen bits and other misc. hackery. |
326 | S: Haifa, Israel | 326 | S: Haifa, Israel |
327 | 327 | ||
328 | N: Johannes Berg | 328 | N: Johannes Berg |
329 | E: johannes@sipsolutions.net | 329 | E: johannes@sipsolutions.net |
330 | W: http://johannes.sipsolutions.net/ | 330 | W: http://johannes.sipsolutions.net/ |
331 | P: 1024D/9AB78CA5 AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5 | 331 | P: 1024D/9AB78CA5 AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5 |
332 | D: powerpc & 802.11 hacker | 332 | D: powerpc & 802.11 hacker |
333 | 333 | ||
334 | N: Stephen R. van den Berg (AKA BuGless) | 334 | N: Stephen R. van den Berg (AKA BuGless) |
335 | E: berg@pool.informatik.rwth-aachen.de | 335 | E: berg@pool.informatik.rwth-aachen.de |
336 | D: General kernel, gcc, and libc hacker | 336 | D: General kernel, gcc, and libc hacker |
337 | D: Specialisation: tweaking, ensuring portability, tweaking, cleaning, | 337 | D: Specialisation: tweaking, ensuring portability, tweaking, cleaning, |
338 | D: tweaking and occasionally debugging :-) | 338 | D: tweaking and occasionally debugging :-) |
339 | S: Bouwensstraat 22 | 339 | S: Bouwensstraat 22 |
340 | S: 6369 BG Simpelveld | 340 | S: 6369 BG Simpelveld |
341 | S: The Netherlands | 341 | S: The Netherlands |
342 | 342 | ||
343 | N: Peter Berger | 343 | N: Peter Berger |
344 | E: pberger@brimson.com | 344 | E: pberger@brimson.com |
345 | W: http://www.brimson.com | 345 | W: http://www.brimson.com |
346 | D: Author/maintainer of Digi AccelePort USB driver | 346 | D: Author/maintainer of Digi AccelePort USB driver |
347 | S: 1549 Hiironen Rd. | 347 | S: 1549 Hiironen Rd. |
348 | S: Brimson, MN 55602 | 348 | S: Brimson, MN 55602 |
349 | S: USA | 349 | S: USA |
350 | 350 | ||
351 | N: Hennus Bergman | 351 | N: Hennus Bergman |
352 | P: 1024/77D50909 76 99 FD 31 91 E1 96 1C 90 BB 22 80 62 F6 BD 63 | 352 | P: 1024/77D50909 76 99 FD 31 91 E1 96 1C 90 BB 22 80 62 F6 BD 63 |
353 | D: Author and maintainer of the QIC-02 tape driver | 353 | D: Author and maintainer of the QIC-02 tape driver |
354 | S: The Netherlands | 354 | S: The Netherlands |
355 | 355 | ||
356 | N: Tomas Berndtsson | 356 | N: Tomas Berndtsson |
357 | E: tomas@nocrew.org | 357 | E: tomas@nocrew.org |
358 | W: http://tomas.nocrew.org/ | 358 | W: http://tomas.nocrew.org/ |
359 | D: dsp56k device driver | 359 | D: dsp56k device driver |
360 | 360 | ||
361 | N: Ross Biro | 361 | N: Ross Biro |
362 | E: ross.biro@gmail.com | 362 | E: ross.biro@gmail.com |
363 | D: Original author of the Linux networking code | 363 | D: Original author of the Linux networking code |
364 | 364 | ||
365 | N: Anton Blanchard | 365 | N: Anton Blanchard |
366 | E: anton@samba.org | 366 | E: anton@samba.org |
367 | W: http://samba.org/~anton/ | 367 | W: http://samba.org/~anton/ |
368 | P: 1024/8462A731 4C 55 86 34 44 59 A7 99 2B 97 88 4A 88 9A 0D 97 | 368 | P: 1024/8462A731 4C 55 86 34 44 59 A7 99 2B 97 88 4A 88 9A 0D 97 |
369 | D: sun4 port, Sparc hacker | 369 | D: sun4 port, Sparc hacker |
370 | 370 | ||
371 | N: Hugh Blemings | 371 | N: Hugh Blemings |
372 | E: hugh@blemings.org | 372 | E: hugh@blemings.org |
373 | W: http://blemings.org/hugh | 373 | W: http://blemings.org/hugh |
374 | D: Original author of the Keyspan USB to serial drivers, random PowerPC hacker | 374 | D: Original author of the Keyspan USB to serial drivers, random PowerPC hacker |
375 | S: PO Box 234 | 375 | S: PO Box 234 |
376 | S: Belconnen ACT 2616 | 376 | S: Belconnen ACT 2616 |
377 | S: Australia | 377 | S: Australia |
378 | 378 | ||
379 | N: Philip Blundell | 379 | N: Philip Blundell |
380 | E: philb@gnu.org | 380 | E: philb@gnu.org |
381 | D: Linux/ARM hacker | 381 | D: Linux/ARM hacker |
382 | D: Device driver hacker (eexpress, 3c505, c-qcam, ...) | 382 | D: Device driver hacker (eexpress, 3c505, c-qcam, ...) |
383 | D: m68k port to HP9000/300 | 383 | D: m68k port to HP9000/300 |
384 | D: AUN network protocols | 384 | D: AUN network protocols |
385 | D: Co-architect of the parallel port sharing system | 385 | D: Co-architect of the parallel port sharing system |
386 | D: IPv6 netfilter | 386 | D: IPv6 netfilter |
387 | S: FutureTV Labs Ltd | 387 | S: FutureTV Labs Ltd |
388 | S: Brunswick House, 61-69 Newmarket Rd, Cambridge CB5 8EG | 388 | S: Brunswick House, 61-69 Newmarket Rd, Cambridge CB5 8EG |
389 | S: United Kingdom | 389 | S: United Kingdom |
390 | 390 | ||
391 | N: Thomas Bogendรถrfer | 391 | N: Thomas Bogendรถrfer |
392 | E: tsbogend@alpha.franken.de | 392 | E: tsbogend@alpha.franken.de |
393 | D: PCnet32 driver, SONIC driver, JAZZ_ESP driver | 393 | D: PCnet32 driver, SONIC driver, JAZZ_ESP driver |
394 | D: newport abscon driver, g364 framebuffer driver | 394 | D: newport abscon driver, g364 framebuffer driver |
395 | D: strace for Linux/Alpha | 395 | D: strace for Linux/Alpha |
396 | D: Linux/MIPS hacker | 396 | D: Linux/MIPS hacker |
397 | S: Schafhofstr. 40 | 397 | S: Schafhofstr. 40 |
398 | S: 90556 Cadolzburg | 398 | S: 90556 Cadolzburg |
399 | S: Germany | 399 | S: Germany |
400 | 400 | ||
401 | N: Bill Bogstad | 401 | N: Bill Bogstad |
402 | E: bogstad@pobox.com | 402 | E: bogstad@pobox.com |
403 | D: wrote /proc/self hack, minor samba & dosemu patches | 403 | D: wrote /proc/self hack, minor samba & dosemu patches |
404 | 404 | ||
405 | N: Axel Boldt | 405 | N: Axel Boldt |
406 | E: axel@uni-paderborn.de | 406 | E: axel@uni-paderborn.de |
407 | W: http://math-www.uni-paderborn.de/~axel/ | 407 | W: http://math-www.uni-paderborn.de/~axel/ |
408 | D: Configuration help text support | 408 | D: Configuration help text support |
409 | D: Linux CD and Support Giveaway List | 409 | D: Linux CD and Support Giveaway List |
410 | 410 | ||
411 | N: Erik Inge Bolsรธ | 411 | N: Erik Inge Bolsรธ |
412 | E: knan@mo.himolde.no | 412 | E: knan@mo.himolde.no |
413 | D: Misc kernel hacks | 413 | D: Misc kernel hacks |
414 | D: Updated PC speaker driver for 2.3 | 414 | D: Updated PC speaker driver for 2.3 |
415 | S: Norway | 415 | S: Norway |
416 | 416 | ||
417 | N: Andreas E. Bombe | 417 | N: Andreas E. Bombe |
418 | E: andreas.bombe@munich.netsurf.de | 418 | E: andreas.bombe@munich.netsurf.de |
419 | W: http://home.pages.de/~andreas.bombe/ | 419 | W: http://home.pages.de/~andreas.bombe/ |
420 | P: 1024/04880A44 72E5 7031 4414 2EB6 F6B4 4CBD 1181 7032 0488 0A44 | 420 | P: 1024/04880A44 72E5 7031 4414 2EB6 F6B4 4CBD 1181 7032 0488 0A44 |
421 | D: IEEE 1394 subsystem rewrite and maintainer | 421 | D: IEEE 1394 subsystem rewrite and maintainer |
422 | D: Texas Instruments PCILynx IEEE 1394 driver | 422 | D: Texas Instruments PCILynx IEEE 1394 driver |
423 | 423 | ||
424 | N: Al Borchers | 424 | N: Al Borchers |
425 | E: alborchers@steinerpoint.com | 425 | E: alborchers@steinerpoint.com |
426 | D: Author/maintainer of Digi AccelePort USB driver | 426 | D: Author/maintainer of Digi AccelePort USB driver |
427 | D: work on usbserial and keyspan_pda drivers | 427 | D: work on usbserial and keyspan_pda drivers |
428 | S: 4912 Zenith Ave. S. | 428 | S: 4912 Zenith Ave. S. |
429 | S: Minneapolis, MN 55410 | 429 | S: Minneapolis, MN 55410 |
430 | S: USA | 430 | S: USA |
431 | 431 | ||
432 | N: Marc Boucher | 432 | N: Marc Boucher |
433 | E: marc@mbsi.ca | 433 | E: marc@mbsi.ca |
434 | P: CA 67 A5 1A 38 CE B6 F2 D5 83 51 03 D2 9C 30 9E CE D2 DD 65 | 434 | P: CA 67 A5 1A 38 CE B6 F2 D5 83 51 03 D2 9C 30 9E CE D2 DD 65 |
435 | D: Netfilter core | 435 | D: Netfilter core |
436 | D: IP policy routing by mark | 436 | D: IP policy routing by mark |
437 | D: Various fixes (mostly networking) | 437 | D: Various fixes (mostly networking) |
438 | S: Montreal, Quebec | 438 | S: Montreal, Quebec |
439 | S: Canada | 439 | S: Canada |
440 | 440 | ||
441 | N: Zoltรกn Bรถszรถrmรฉnyi | 441 | N: Zoltรกn Bรถszรถrmรฉnyi |
442 | E: zboszor@mail.externet.hu | 442 | E: zboszor@mail.externet.hu |
443 | D: MTRR emulation with Cyrix style ARR registers, Athlon MTRR support | 443 | D: MTRR emulation with Cyrix style ARR registers, Athlon MTRR support |
444 | 444 | ||
445 | N: John Boyd | 445 | N: John Boyd |
446 | E: boyd@cis.ohio-state.edu | 446 | E: boyd@cis.ohio-state.edu |
447 | D: Co-author of wd7000 SCSI driver | 447 | D: Co-author of wd7000 SCSI driver |
448 | S: 101 Curl Drive #591 | 448 | S: 101 Curl Drive #591 |
449 | S: Columbus, Ohio 43210 | 449 | S: Columbus, Ohio 43210 |
450 | S: USA | 450 | S: USA |
451 | 451 | ||
452 | N: Peter Braam | 452 | N: Peter Braam |
453 | E: braam@clusterfs.com | 453 | E: braam@clusterfs.com |
454 | W: http://www.clusterfs.com/ | 454 | W: http://www.clusterfs.com/ |
455 | D: Coda & InterMezzo filesystems | 455 | D: Coda & InterMezzo filesystems |
456 | S: 181 McNeil | 456 | S: 181 McNeil |
457 | S: Canmore, AB | 457 | S: Canmore, AB |
458 | S: Canada, T1W 2R9 | 458 | S: Canada, T1W 2R9 |
459 | 459 | ||
460 | N: Ryan Bradetich | 460 | N: Ryan Bradetich |
461 | E: rbradetich@uswest.net | 461 | E: rbradetich@uswest.net |
462 | D: Linux/PA-RISC hacker | 462 | D: Linux/PA-RISC hacker |
463 | S: 1200 Goldenrod Dr. | 463 | S: 1200 Goldenrod Dr. |
464 | S: Nampa, Idaho 83686 | 464 | S: Nampa, Idaho 83686 |
465 | S: USA | 465 | S: USA |
466 | 466 | ||
467 | N: Dirk J. Brandewie | 467 | N: Dirk J. Brandewie |
468 | E: dirk.j.brandewie@intel.com | 468 | E: dirk.j.brandewie@intel.com |
469 | E: linux-wimax@intel.com | 469 | E: linux-wimax@intel.com |
470 | D: Intel Wireless WiMAX Connection 2400 SDIO driver | 470 | D: Intel Wireless WiMAX Connection 2400 SDIO driver |
471 | 471 | ||
472 | N: Derrick J. Brashear | 472 | N: Derrick J. Brashear |
473 | E: shadow@dementia.org | 473 | E: shadow@dementia.org |
474 | W: http://www.dementia.org/~shadow | 474 | W: http://www.dementia.org/~shadow |
475 | P: 512/71EC9367 C5 29 0F BC 83 51 B9 F0 BC 05 89 A0 4F 1F 30 05 | 475 | P: 512/71EC9367 C5 29 0F BC 83 51 B9 F0 BC 05 89 A0 4F 1F 30 05 |
476 | D: Author of Sparc CS4231 audio driver, random Sparc work | 476 | D: Author of Sparc CS4231 audio driver, random Sparc work |
477 | S: 403 Gilmore Avenue | 477 | S: 403 Gilmore Avenue |
478 | S: Trafford, Pennsylvania 15085 | 478 | S: Trafford, Pennsylvania 15085 |
479 | S: USA | 479 | S: USA |
480 | 480 | ||
481 | N: Dag Brattli | 481 | N: Dag Brattli |
482 | E: dagb@cs.uit.no | 482 | E: dagb@cs.uit.no |
483 | W: http://www.cs.uit.no/~dagb | 483 | W: http://www.cs.uit.no/~dagb |
484 | D: IrDA Subsystem | 484 | D: IrDA Subsystem |
485 | S: 19. Wellington Road | 485 | S: 19. Wellington Road |
486 | S: Lancaster, LA1 4DN | 486 | S: Lancaster, LA1 4DN |
487 | S: UK, England | 487 | S: UK, England |
488 | 488 | ||
489 | N: Lars Brinkhoff | 489 | N: Lars Brinkhoff |
490 | E: lars@nocrew.org | 490 | E: lars@nocrew.org |
491 | W: http://lars.nocrew.org/ | 491 | W: http://lars.nocrew.org/ |
492 | D: dsp56k device driver | 492 | D: dsp56k device driver |
493 | D: ptrace proxy in user mode kernel port | 493 | D: ptrace proxy in user mode kernel port |
494 | S: Kopmansg 2 | 494 | S: Kopmansg 2 |
495 | S: 411 13 Goteborg | 495 | S: 411 13 Goteborg |
496 | S: Sweden | 496 | S: Sweden |
497 | 497 | ||
498 | N: Paul Bristow | 498 | N: Paul Bristow |
499 | E: paul@paulbristow.net | 499 | E: paul@paulbristow.net |
500 | W: http://paulbristow.net/linux/idefloppy.html | 500 | W: http://paulbristow.net/linux/idefloppy.html |
501 | D: Maintainer of IDE/ATAPI floppy driver | 501 | D: Maintainer of IDE/ATAPI floppy driver |
502 | 502 | ||
503 | N: Dominik Brodowski | 503 | N: Dominik Brodowski |
504 | E: linux@brodo.de | 504 | E: linux@brodo.de |
505 | W: http://www.brodo.de/ | 505 | W: http://www.brodo.de/ |
506 | P: 1024D/725B37C6 190F 3E77 9C89 3B6D BECD 46EE 67C3 0308 725B 37C6 | 506 | P: 1024D/725B37C6 190F 3E77 9C89 3B6D BECD 46EE 67C3 0308 725B 37C6 |
507 | D: parts of CPUFreq code, ACPI bugfixes | 507 | D: parts of CPUFreq code, ACPI bugfixes |
508 | S: Tuebingen, Germany | 508 | S: Tuebingen, Germany |
509 | 509 | ||
510 | N: Andries Brouwer | 510 | N: Andries Brouwer |
511 | E: aeb@cwi.nl | 511 | E: aeb@cwi.nl |
512 | D: random Linux hacker | 512 | D: random Linux hacker |
513 | S: Bessemerstraat 21 | 513 | S: Bessemerstraat 21 |
514 | S: Amsterdam | 514 | S: Amsterdam |
515 | S: The Netherlands | 515 | S: The Netherlands |
516 | 516 | ||
517 | N: Zach Brown | 517 | N: Zach Brown |
518 | E: zab@zabbo.net | 518 | E: zab@zabbo.net |
519 | D: maestro pci sound | 519 | D: maestro pci sound |
520 | 520 | ||
521 | N: Gary Brubaker | 521 | N: Gary Brubaker |
522 | E: xavyer@ix.netcom.com | 522 | E: xavyer@ix.netcom.com |
523 | D: USB Serial Empeg Empeg-car Mark I/II Driver | 523 | D: USB Serial Empeg Empeg-car Mark I/II Driver |
524 | 524 | ||
525 | N: Matthias Bruestle | 525 | N: Matthias Bruestle |
526 | E: m@mbsks.franken.de | 526 | E: m@mbsks.franken.de |
527 | D: REINER SCT cyberJack pinpad/e-com USB chipcard reader driver | 527 | D: REINER SCT cyberJack pinpad/e-com USB chipcard reader driver |
528 | S: Germany | 528 | S: Germany |
529 | 529 | ||
530 | N: Adrian Bunk | 530 | N: Adrian Bunk |
531 | P: 1024D/4F12B400 B29C E71E FE19 6755 5C8A 84D4 99FC EA98 4F12 B400 | 531 | P: 1024D/4F12B400 B29C E71E FE19 6755 5C8A 84D4 99FC EA98 4F12 B400 |
532 | D: misc kernel hacking and testing | 532 | D: misc kernel hacking and testing |
533 | 533 | ||
534 | N: Ray Burr | 534 | N: Ray Burr |
535 | E: ryb@nightmare.com | 535 | E: ryb@nightmare.com |
536 | D: Original author of Amiga FFS filesystem | 536 | D: Original author of Amiga FFS filesystem |
537 | S: Orlando, Florida | 537 | S: Orlando, Florida |
538 | S: USA | 538 | S: USA |
539 | 539 | ||
540 | N: Lennert Buytenhek | 540 | N: Lennert Buytenhek |
541 | E: kernel@wantstofly.org | 541 | E: kernel@wantstofly.org |
542 | D: Original (2.4) rewrite of the ethernet bridging code | 542 | D: Original (2.4) rewrite of the ethernet bridging code |
543 | D: Various ARM bits and pieces | 543 | D: Various ARM bits and pieces |
544 | S: Ravenhorst 58 | 544 | S: Ravenhorst 58 |
545 | S: 2317 AK Leiden | 545 | S: 2317 AK Leiden |
546 | S: The Netherlands | 546 | S: The Netherlands |
547 | 547 | ||
548 | N: Michael Callahan | 548 | N: Michael Callahan |
549 | E: callahan@maths.ox.ac.uk | 549 | E: callahan@maths.ox.ac.uk |
550 | D: PPP for Linux | 550 | D: PPP for Linux |
551 | S: The Mathematical Institute | 551 | S: The Mathematical Institute |
552 | S: 25-29 St Giles | 552 | S: 25-29 St Giles |
553 | S: Oxford | 553 | S: Oxford |
554 | S: United Kingdom | 554 | S: United Kingdom |
555 | 555 | ||
556 | N: Luiz Fernando N. Capitulino | 556 | N: Luiz Fernando N. Capitulino |
557 | E: lcapitulino@mandriva.com.br | 557 | E: lcapitulino@mandriva.com.br |
558 | E: lcapitulino@gmail.com | 558 | E: lcapitulino@gmail.com |
559 | W: http://www.cpu.eti.br | 559 | W: http://www.cpu.eti.br |
560 | D: misc kernel hacking | 560 | D: misc kernel hacking |
561 | S: Mandriva | 561 | S: Mandriva |
562 | S: Brazil | 562 | S: Brazil |
563 | 563 | ||
564 | N: Remy Card | 564 | N: Remy Card |
565 | E: Remy.Card@masi.ibp.fr | 565 | E: Remy.Card@masi.ibp.fr |
566 | E: Remy.Card@linux.org | 566 | E: Remy.Card@linux.org |
567 | D: Extended file system [defunct] designer and developer | 567 | D: Extended file system [defunct] designer and developer |
568 | D: Second extended file system designer and developer | 568 | D: Second extended file system designer and developer |
569 | S: Institut Blaise Pascal | 569 | S: Institut Blaise Pascal |
570 | S: 4 Place Jussieu | 570 | S: 4 Place Jussieu |
571 | S: 75252 Paris Cedex 05 | 571 | S: 75252 Paris Cedex 05 |
572 | S: France | 572 | S: France |
573 | 573 | ||
574 | N: Ulf Carlsson | 574 | N: Ulf Carlsson |
575 | D: SGI Indy audio (HAL2) drivers | 575 | D: SGI Indy audio (HAL2) drivers |
576 | E: ulfc@bun.falkenberg.se | 576 | E: ulfc@bun.falkenberg.se |
577 | 577 | ||
578 | N: Ed Carp | 578 | N: Ed Carp |
579 | E: ecarp@netcom.com | 579 | E: ecarp@netcom.com |
580 | D: uucp, elm, pine, pico port | 580 | D: uucp, elm, pine, pico port |
581 | D: cron, at(1) developer | 581 | D: cron, at(1) developer |
582 | S: 48287 Sawleaf | 582 | S: 48287 Sawleaf |
583 | S: Fremont, California 94539 | 583 | S: Fremont, California 94539 |
584 | S: USA | 584 | S: USA |
585 | 585 | ||
586 | N: Florent Chabaud | 586 | N: Florent Chabaud |
587 | E: florent.chabaud@polytechnique.org | 587 | E: florent.chabaud@polytechnique.org |
588 | D: software suspend | 588 | D: software suspend |
589 | S: SGDN/DCSSI/SDS/LTI | 589 | S: SGDN/DCSSI/SDS/LTI |
590 | S: 58, Bd Latour-Maubourg | 590 | S: 58, Bd Latour-Maubourg |
591 | S: 75700 Paris 07 SP | 591 | S: 75700 Paris 07 SP |
592 | S: France | 592 | S: France |
593 | 593 | ||
594 | N: Gordon Chaffee | 594 | N: Gordon Chaffee |
595 | E: chaffee@cs.berkeley.edu | 595 | E: chaffee@cs.berkeley.edu |
596 | W: http://bmrc.berkeley.edu/people/chaffee/ | 596 | W: http://bmrc.berkeley.edu/people/chaffee/ |
597 | D: vfat, fat32, joliet, native language support | 597 | D: vfat, fat32, joliet, native language support |
598 | S: 3700 Warwick Road | 598 | S: 3700 Warwick Road |
599 | S: Fremont, California 94555 | 599 | S: Fremont, California 94555 |
600 | S: USA | 600 | S: USA |
601 | 601 | ||
602 | N: Chih-Jen Chang | 602 | N: Chih-Jen Chang |
603 | E: chihjenc@scf.usc.edu | 603 | E: chihjenc@scf.usc.edu |
604 | E: chihjen@iis.sinica.edu.tw | 604 | E: chihjen@iis.sinica.edu.tw |
605 | D: IGMP(Internet Group Management Protocol) version 2 | 605 | D: IGMP(Internet Group Management Protocol) version 2 |
606 | S: 3F, 65 Tajen street | 606 | S: 3F, 65 Tajen street |
607 | S: Tamsui town, Taipei county, | 607 | S: Tamsui town, Taipei county, |
608 | S: Taiwan 251 | 608 | S: Taiwan 251 |
609 | S: Republic of China | 609 | S: Republic of China |
610 | 610 | ||
611 | N: Reinette Chatre | 611 | N: Reinette Chatre |
612 | E: reinette.chatre@intel.com | 612 | E: reinette.chatre@intel.com |
613 | D: WiMedia Link Protocol implementation | 613 | D: WiMedia Link Protocol implementation |
614 | D: UWB stack bits and pieces | 614 | D: UWB stack bits and pieces |
615 | 615 | ||
616 | N: Michael Elizabeth Chastain | 616 | N: Michael Elizabeth Chastain |
617 | E: mec@shout.net | 617 | E: mec@shout.net |
618 | D: Configure, Menuconfig, xconfig | 618 | D: Configure, Menuconfig, xconfig |
619 | 619 | ||
620 | N: Raymond Chen | 620 | N: Raymond Chen |
621 | E: raymondc@microsoft.com | 621 | E: raymondc@microsoft.com |
622 | D: Author of Configure script | 622 | D: Author of Configure script |
623 | S: 14509 NE 39th Street #1096 | 623 | S: 14509 NE 39th Street #1096 |
624 | S: Bellevue, Washington 98007 | 624 | S: Bellevue, Washington 98007 |
625 | S: USA | 625 | S: USA |
626 | 626 | ||
627 | N: Christopher L. Cheney | 627 | N: Christopher L. Cheney |
628 | E: ccheney@debian.org | 628 | E: ccheney@debian.org |
629 | E: ccheney@cheney.cx | 629 | E: ccheney@cheney.cx |
630 | W: http://www.cheney.cx | 630 | W: http://www.cheney.cx |
631 | P: 1024D/8E384AF2 2D31 1927 87D7 1F24 9FF9 1BC5 D106 5AB3 8E38 4AF2 | 631 | P: 1024D/8E384AF2 2D31 1927 87D7 1F24 9FF9 1BC5 D106 5AB3 8E38 4AF2 |
632 | D: Vista Imaging usb webcam driver | 632 | D: Vista Imaging usb webcam driver |
633 | S: 314 Prince of Wales | 633 | S: 314 Prince of Wales |
634 | S: Conroe, TX 77304 | 634 | S: Conroe, TX 77304 |
635 | S: USA | 635 | S: USA |
636 | 636 | ||
637 | N: Stuart Cheshire | 637 | N: Stuart Cheshire |
638 | E: cheshire@cs.stanford.edu | 638 | E: cheshire@cs.stanford.edu |
639 | D: Author of Starmode Radio IP (STRIP) driver | 639 | D: Author of Starmode Radio IP (STRIP) driver |
640 | D: Originator of design for new combined interrupt handlers | 640 | D: Originator of design for new combined interrupt handlers |
641 | S: William Gates Department | 641 | S: William Gates Department |
642 | S: Stanford University | 642 | S: Stanford University |
643 | S: Stanford, California 94305 | 643 | S: Stanford, California 94305 |
644 | S: USA | 644 | S: USA |
645 | 645 | ||
646 | N: Randolph Chung | 646 | N: Randolph Chung |
647 | E: tausq@debian.org | 647 | E: tausq@debian.org |
648 | D: Linux/PA-RISC hacker | 648 | D: Linux/PA-RISC hacker |
649 | S: Hong Kong | 649 | S: Hong Kong |
650 | 650 | ||
651 | N: Juan Jose Ciarlante | 651 | N: Juan Jose Ciarlante |
652 | W: http://juanjox.kernelnotes.org/ | 652 | W: http://juanjox.kernelnotes.org/ |
653 | E: jjciarla@raiz.uncu.edu.ar | 653 | E: jjciarla@raiz.uncu.edu.ar |
654 | E: jjo@mendoza.gov.ar | 654 | E: jjo@mendoza.gov.ar |
655 | D: Network driver alias support | 655 | D: Network driver alias support |
656 | D: IP masq hashing and app modules | 656 | D: IP masq hashing and app modules |
657 | D: IP masq 2.1 features and bugs | 657 | D: IP masq 2.1 features and bugs |
658 | S: Las Cuevas 2385 - Bo Guemes | 658 | S: Las Cuevas 2385 - Bo Guemes |
659 | S: Las Heras, Mendoza CP 5539 | 659 | S: Las Heras, Mendoza CP 5539 |
660 | S: Argentina | 660 | S: Argentina |
661 | 661 | ||
662 | N: Steven P. Cole | 662 | N: Steven P. Cole |
663 | E: scole@lanl.gov | 663 | E: scole@lanl.gov |
664 | E: elenstev@mesatop.com | 664 | E: elenstev@mesatop.com |
665 | D: Various build fixes and kernel documentation. | 665 | D: Various build fixes and kernel documentation. |
666 | S: Los Alamos, New Mexico | 666 | S: Los Alamos, New Mexico |
667 | S: USA | 667 | S: USA |
668 | 668 | ||
669 | N: Hamish Coleman | 669 | N: Hamish Coleman |
670 | E: hamish@zot.apana.org.au | 670 | E: hamish@zot.apana.org.au |
671 | D: SEEQ8005 network driver | 671 | D: SEEQ8005 network driver |
672 | S: 98 Paxton Street | 672 | S: 98 Paxton Street |
673 | S: East Malvern, Victoria, 3145 | 673 | S: East Malvern, Victoria, 3145 |
674 | S: Australia | 674 | S: Australia |
675 | 675 | ||
676 | N: Neil Conway | 676 | N: Neil Conway |
677 | E: nconway.list@ukaea.org.uk | 677 | E: nconway.list@ukaea.org.uk |
678 | D: Assorted sched/mm titbits | 678 | D: Assorted sched/mm titbits |
679 | S: Oxfordshire, UK. | 679 | S: Oxfordshire, UK. |
680 | 680 | ||
681 | N: Kees Cook | 681 | N: Kees Cook |
682 | E: kees@outflux.net | 682 | E: kees@outflux.net |
683 | W: http://outflux.net/ | 683 | W: http://outflux.net/ |
684 | P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D | 684 | P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D |
685 | D: Minor updates to SCSI types, added /proc/pid/maps protection | 685 | D: Minor updates to SCSI types, added /proc/pid/maps protection |
686 | S: (ask for current address) | 686 | S: (ask for current address) |
687 | S: USA | 687 | S: USA |
688 | 688 | ||
689 | N: Robin Cornelius | 689 | N: Robin Cornelius |
690 | E: robincornelius@users.sourceforge.net | 690 | E: robincornelius@users.sourceforge.net |
691 | D: Ralink rt2x00 WLAN driver | 691 | D: Ralink rt2x00 WLAN driver |
692 | S: Cornwall, U.K. | 692 | S: Cornwall, U.K. |
693 | 693 | ||
694 | N: Mark Corner | 694 | N: Mark Corner |
695 | E: mcorner@umich.edu | 695 | E: mcorner@umich.edu |
696 | W: http://www.eecs.umich.edu/~mcorner/ | 696 | W: http://www.eecs.umich.edu/~mcorner/ |
697 | D: USB Bluetooth Driver | 697 | D: USB Bluetooth Driver |
698 | S: University of Michigan | 698 | S: University of Michigan |
699 | S: Ann Arbor, MI | 699 | S: Ann Arbor, MI |
700 | 700 | ||
701 | N: Michael Cornwell | 701 | N: Michael Cornwell |
702 | E: cornwell@acm.org | 702 | E: cornwell@acm.org |
703 | D: Original designer and co-author of ATA Taskfile | 703 | D: Original designer and co-author of ATA Taskfile |
704 | D: Kernel module SMART utilities | 704 | D: Kernel module SMART utilities |
705 | S: Santa Cruz, California | 705 | S: Santa Cruz, California |
706 | S: USA | 706 | S: USA |
707 | 707 | ||
708 | N: Luis Correia | 708 | N: Luis Correia |
709 | E: lfcorreia@users.sf.net | 709 | E: lfcorreia@users.sf.net |
710 | D: Ralink rt2x00 WLAN driver | 710 | D: Ralink rt2x00 WLAN driver |
711 | S: Belas, Portugal | 711 | S: Belas, Portugal |
712 | 712 | ||
713 | N: Alan Cox | 713 | N: Alan Cox |
714 | W: http://www.linux.org.uk/diary/ | 714 | W: http://www.linux.org.uk/diary/ |
715 | D: Linux Networking (0.99.10->2.0.29) | 715 | D: Linux Networking (0.99.10->2.0.29) |
716 | D: Original Appletalk, AX.25, and IPX code | 716 | D: Original Appletalk, AX.25, and IPX code |
717 | D: 3c501 hacker | 717 | D: 3c501 hacker |
718 | D: Watchdog timer drivers | 718 | D: Watchdog timer drivers |
719 | D: Linux/SMP x86 (up to 2.0 only) | 719 | D: Linux/SMP x86 (up to 2.0 only) |
720 | D: Initial Mac68K port | 720 | D: Initial Mac68K port |
721 | D: Video4Linux design, bw-qcam and PMS driver ports. | 721 | D: Video4Linux design, bw-qcam and PMS driver ports. |
722 | D: IDE modularisation work | 722 | D: IDE modularisation work |
723 | D: Z85230 driver | 723 | D: Z85230 driver |
724 | D: Former security contact point (please use vendor-sec@lst.de) | 724 | D: Former security contact point (please use vendor-sec@lst.de) |
725 | D: ex 2.2 maintainer | 725 | D: ex 2.2 maintainer |
726 | D: 2.1.x modular sound | 726 | D: 2.1.x modular sound |
727 | S: c/o Red Hat UK Ltd | 727 | S: c/o Red Hat UK Ltd |
728 | S: Alexandra House | 728 | S: Alexandra House |
729 | S: Alexandra Terrace | 729 | S: Alexandra Terrace |
730 | S: Guildford, GU1 3DA | 730 | S: Guildford, GU1 3DA |
731 | S: United Kingdom | 731 | S: United Kingdom |
732 | 732 | ||
733 | N: Cristian Mihail Craciunescu | 733 | N: Cristian Mihail Craciunescu |
734 | W: http://www.dnt.ro/~cristi/ | 734 | W: http://www.dnt.ro/~cristi/ |
735 | E: cristi@dnt.ro | 735 | E: cristi@dnt.ro |
736 | D: Support for Xircom PGSDB9 (firmware and host driver) | 736 | D: Support for Xircom PGSDB9 (firmware and host driver) |
737 | S: Bucharest | 737 | S: Bucharest |
738 | S: Romania | 738 | S: Romania |
739 | 739 | ||
740 | N: Laurence Culhane | 740 | N: Laurence Culhane |
741 | E: loz@holmes.demon.co.uk | 741 | E: loz@holmes.demon.co.uk |
742 | D: Wrote the initial alpha SLIP code | 742 | D: Wrote the initial alpha SLIP code |
743 | S: 81 Hood Street | 743 | S: 81 Hood Street |
744 | S: Northampton | 744 | S: Northampton |
745 | S: NN1 3QT | 745 | S: NN1 3QT |
746 | S: United Kingdom | 746 | S: United Kingdom |
747 | 747 | ||
748 | N: Uwe Dannowski | 748 | N: Uwe Dannowski |
749 | E: Uwe.Dannowski@ira.uka.de | 749 | E: Uwe.Dannowski@ira.uka.de |
750 | W: http://i30www.ira.uka.de/~dannowsk/ | 750 | W: http://i30www.ira.uka.de/~dannowsk/ |
751 | D: FORE PCA-200E driver | 751 | D: FORE PCA-200E driver |
752 | S: University of Karlsruhe | 752 | S: University of Karlsruhe |
753 | S: Germany | 753 | S: Germany |
754 | 754 | ||
755 | N: Ray Dassen | 755 | N: Ray Dassen |
756 | E: jdassen@wi.LeidenUniv.nl | 756 | E: jdassen@wi.LeidenUniv.nl |
757 | W: http://www.wi.leidenuniv.nl/~jdassen/ | 757 | W: http://www.wi.leidenuniv.nl/~jdassen/ |
758 | P: 1024/672D05C1 DD 60 32 60 F7 90 64 80 E7 6F D4 E4 F8 C9 4A 58 | 758 | P: 1024/672D05C1 DD 60 32 60 F7 90 64 80 E7 6F D4 E4 F8 C9 4A 58 |
759 | D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer, | 759 | D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer, |
760 | D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels. | 760 | D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels. |
761 | S: Zuidsingel 10A | 761 | S: Zuidsingel 10A |
762 | S: 2312 SB Leiden | 762 | S: 2312 SB Leiden |
763 | S: The Netherlands | 763 | S: The Netherlands |
764 | 764 | ||
765 | N: David Davies | 765 | N: David Davies |
766 | E: davies@wanton.lkg.dec.com | 766 | E: davies@wanton.lkg.dec.com |
767 | D: Network driver author - depca, ewrk3 and de4x5 | 767 | D: Network driver author - depca, ewrk3 and de4x5 |
768 | D: Wrote shared interrupt support | 768 | D: Wrote shared interrupt support |
769 | S: Digital Equipment Corporation | 769 | S: Digital Equipment Corporation |
770 | S: 550 King Street | 770 | S: 550 King Street |
771 | S: Littleton, Massachusetts 01460 | 771 | S: Littleton, Massachusetts 01460 |
772 | S: USA | 772 | S: USA |
773 | 773 | ||
774 | N: Frank Davis | 774 | N: Frank Davis |
775 | E: fdavis@si.rr.com | 775 | E: fdavis@si.rr.com |
776 | E: fdavis112@juno.com | 776 | E: fdavis112@juno.com |
777 | D: Various kernel patches | 777 | D: Various kernel patches |
778 | S: 8 Lakeview Terr. | 778 | S: 8 Lakeview Terr. |
779 | S: Kerhonkson, NY 12446 | 779 | S: Kerhonkson, NY 12446 |
780 | S: USA | 780 | S: USA |
781 | 781 | ||
782 | N: Wayne Davison | 782 | N: Wayne Davison |
783 | E: davison@borland.com | 783 | E: davison@borland.com |
784 | D: Second extended file system co-designer | 784 | D: Second extended file system co-designer |
785 | 785 | ||
786 | N: Terry Dawson | 786 | N: Terry Dawson |
787 | E: terry@perf.no.itg.telecom.com.au | 787 | E: terry@perf.no.itg.telecom.com.au |
788 | E: terry@albert.vk2ktj.ampr.org (Amateur Radio use only) | 788 | E: terry@albert.vk2ktj.ampr.org (Amateur Radio use only) |
789 | D: trivial hack to add variable address length routing to Rose. | 789 | D: trivial hack to add variable address length routing to Rose. |
790 | D: AX25-HOWTO, HAM-HOWTO, IPX-HOWTO, NET-2-HOWTO | 790 | D: AX25-HOWTO, HAM-HOWTO, IPX-HOWTO, NET-2-HOWTO |
791 | D: ax25-utils maintainer. | 791 | D: ax25-utils maintainer. |
792 | 792 | ||
793 | N: Helge Deller | 793 | N: Helge Deller |
794 | E: deller@gmx.de | 794 | E: deller@gmx.de |
795 | E: hdeller@redhat.de | 795 | E: hdeller@redhat.de |
796 | D: PA-RISC Linux hacker, LASI-, ASP-, WAX-, LCD/LED-driver | 796 | D: PA-RISC Linux hacker, LASI-, ASP-, WAX-, LCD/LED-driver |
797 | S: Schimmelsrain 1 | 797 | S: Schimmelsrain 1 |
798 | S: D-69231 Rauenberg | 798 | S: D-69231 Rauenberg |
799 | S: Germany | 799 | S: Germany |
800 | 800 | ||
801 | N: Jean Delvare | 801 | N: Jean Delvare |
802 | E: khali@linux-fr.org | 802 | E: khali@linux-fr.org |
803 | W: http://khali.linux-fr.org/ | 803 | W: http://khali.linux-fr.org/ |
804 | D: Several hardware monitoring drivers | 804 | D: Several hardware monitoring drivers |
805 | S: France | 805 | S: France |
806 | 806 | ||
807 | N: Peter Denison | 807 | N: Peter Denison |
808 | E: peterd@pnd-pc.demon.co.uk | 808 | E: peterd@pnd-pc.demon.co.uk |
809 | W: http://www.pnd-pc.demon.co.uk/promise/ | 809 | W: http://www.pnd-pc.demon.co.uk/promise/ |
810 | D: Promise DC4030VL caching HD controller drivers | 810 | D: Promise DC4030VL caching HD controller drivers |
811 | 811 | ||
812 | N: Todd J. Derr | 812 | N: Todd J. Derr |
813 | E: tjd@fore.com | 813 | E: tjd@fore.com |
814 | W: http://www.wordsmith.org/~tjd | 814 | W: http://www.wordsmith.org/~tjd |
815 | D: Random console hacks and other miscellaneous stuff | 815 | D: Random console hacks and other miscellaneous stuff |
816 | S: 3000 FORE Drive | 816 | S: 3000 FORE Drive |
817 | S: Warrendale, Pennsylvania 15086 | 817 | S: Warrendale, Pennsylvania 15086 |
818 | S: USA | 818 | S: USA |
819 | 819 | ||
820 | N: Martin Devera | 820 | N: Martin Devera |
821 | E: devik@cdi.cz | 821 | E: devik@cdi.cz |
822 | W: http://luxik.cdi.cz/~devik/qos/ | 822 | W: http://luxik.cdi.cz/~devik/qos/ |
823 | D: HTB qdisc and random networking hacks | 823 | D: HTB qdisc and random networking hacks |
824 | 824 | ||
825 | N: Alex deVries | 825 | N: Alex deVries |
826 | E: alex@onefishtwo.ca | 826 | E: alex@onefishtwo.ca |
827 | D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux. | 827 | D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux. |
828 | S: 41.5 William Street | 828 | S: 41.5 William Street |
829 | S: Ottawa, Ontario | 829 | S: Ottawa, Ontario |
830 | S: K1N 6Z9 | 830 | S: K1N 6Z9 |
831 | S: CANADA | 831 | S: CANADA |
832 | 832 | ||
833 | N: Jeff Dike | 833 | N: Jeff Dike |
834 | E: jdike@karaya.com | 834 | E: jdike@karaya.com |
835 | W: http://user-mode-linux.sourceforge.net | 835 | W: http://user-mode-linux.sourceforge.net |
836 | D: User mode kernel port | 836 | D: User mode kernel port |
837 | S: 375 Tubbs Hill Rd | 837 | S: 375 Tubbs Hill Rd |
838 | S: Deering NH 03244 | 838 | S: Deering NH 03244 |
839 | S: USA | 839 | S: USA |
840 | 840 | ||
841 | N: Matt Domsch | 841 | N: Matt Domsch |
842 | E: Matt_Domsch@dell.com | 842 | E: Matt_Domsch@dell.com |
843 | W: http://www.dell.com/linux | 843 | W: http://www.dell.com/linux |
844 | W: http://domsch.com/linux | 844 | W: http://domsch.com/linux |
845 | D: Linux/IA-64 | 845 | D: Linux/IA-64 |
846 | D: Dell PowerEdge server, SCSI layer, misc drivers, and other patches | 846 | D: Dell PowerEdge server, SCSI layer, misc drivers, and other patches |
847 | S: Dell Inc. | 847 | S: Dell Inc. |
848 | S: One Dell Way | 848 | S: One Dell Way |
849 | S: Round Rock, TX 78682 | 849 | S: Round Rock, TX 78682 |
850 | S: USA | 850 | S: USA |
851 | 851 | ||
852 | N: Ben Dooks | 852 | N: Ben Dooks |
853 | E: ben-linux@fluff.org | 853 | E: ben-linux@fluff.org |
854 | E: ben@simtec.co.uk | 854 | E: ben@simtec.co.uk |
855 | W: http://www.fluff.org/ben/ | 855 | W: http://www.fluff.org/ben/ |
856 | W: http://www.simtec.co.uk/ | 856 | W: http://www.simtec.co.uk/ |
857 | D: Samsung S3C2410/S3C2440 support, general ARM support | 857 | D: Samsung S3C2410/S3C2440 support, general ARM support |
858 | D: Maintaining Simtec Electronics development boards | 858 | D: Maintaining Simtec Electronics development boards |
859 | S: Simtec Electronics | 859 | S: Simtec Electronics |
860 | S: Avondale Drive | 860 | S: Avondale Drive |
861 | S: Tarleton | 861 | S: Tarleton |
862 | S: Preston | 862 | S: Preston |
863 | S: Lancs | 863 | S: Lancs |
864 | S: PR4 6AX | 864 | S: PR4 6AX |
865 | S: United Kingdom | 865 | S: United Kingdom |
866 | 866 | ||
867 | N: Ivo van Doorn | 867 | N: Ivo van Doorn |
868 | E: IvDoorn@gmail.com | 868 | E: IvDoorn@gmail.com |
869 | W: http://www.mendiosus.nl | 869 | W: http://www.mendiosus.nl |
870 | D: Ralink rt2x00 WLAN driver | 870 | D: Ralink rt2x00 WLAN driver |
871 | S: Haarlem, The Netherlands | 871 | S: Haarlem, The Netherlands |
872 | 872 | ||
873 | N: John G Dorsey | 873 | N: John G Dorsey |
874 | E: john+@cs.cmu.edu | 874 | E: john+@cs.cmu.edu |
875 | D: ARM Linux ports to Assabet/Neponset, Spot | 875 | D: ARM Linux ports to Assabet/Neponset, Spot |
876 | S: Department of Electrical and Computer Engineering | 876 | S: Department of Electrical and Computer Engineering |
877 | S: Carnegie Mellon University | 877 | S: Carnegie Mellon University |
878 | S: Pittsburgh, PA 15213 | 878 | S: Pittsburgh, PA 15213 |
879 | S: USA | 879 | S: USA |
880 | 880 | ||
881 | N: Eddie C. Dost | 881 | N: Eddie C. Dost |
882 | E: ecd@skynet.be | 882 | E: ecd@skynet.be |
883 | D: Linux/Sparc kernel hacker | 883 | D: Linux/Sparc kernel hacker |
884 | D: Linux/Sparc maintainer | 884 | D: Linux/Sparc maintainer |
885 | S: Rue de la Chapelle 51 | 885 | S: Rue de la Chapelle 51 |
886 | S: 4850 Moresnet | 886 | S: 4850 Moresnet |
887 | S: Belgium | 887 | S: Belgium |
888 | 888 | ||
889 | N: Cort Dougan | 889 | N: Cort Dougan |
890 | E: cort@fsmlabs.com | 890 | E: cort@fsmlabs.com |
891 | W: http://www.fsmlabs.com/linuxppcbk.html | 891 | W: http://www.fsmlabs.com/linuxppcbk.html |
892 | D: PowerPC | 892 | D: PowerPC |
893 | 893 | ||
894 | N: Daniel Drake | 894 | N: Daniel Drake |
895 | E: dsd@gentoo.org | 895 | E: dsd@gentoo.org |
896 | D: USBAT02 CompactFlash support in usb-storage | 896 | D: USBAT02 CompactFlash support in usb-storage |
897 | S: UK | 897 | S: UK |
898 | 898 | ||
899 | N: Oleg Drokin | 899 | N: Oleg Drokin |
900 | E: green@ccssu.crimea.ua | 900 | E: green@ccssu.crimea.ua |
901 | W: http://www.ccssu.crimea.ua/~green | 901 | W: http://www.ccssu.crimea.ua/~green |
902 | D: Cleaning up sound drivers, SA1100 Watchdog. | 902 | D: Cleaning up sound drivers, SA1100 Watchdog. |
903 | S: Skvoznoy per., 14a | 903 | S: Skvoznoy per., 14a |
904 | S: Evpatoria | 904 | S: Evpatoria |
905 | S: Crimea | 905 | S: Crimea |
906 | S: UKRAINE, 334320 | 906 | S: UKRAINE, 334320 |
907 | 907 | ||
908 | N: Walt Drummond | 908 | N: Walt Drummond |
909 | E: drummond@valinux.com | 909 | E: drummond@valinux.com |
910 | D: Linux/IA-64 | 910 | D: Linux/IA-64 |
911 | S: 1382 Bordeaux Drive | 911 | S: 1382 Bordeaux Drive |
912 | S: Sunnyvale, CA 94087 | 912 | S: Sunnyvale, CA 94087 |
913 | S: USA | 913 | S: USA |
914 | 914 | ||
915 | N: Bruno Ducrot | 915 | N: Bruno Ducrot |
916 | E: ducrot@poupinou.org | 916 | E: ducrot@poupinou.org |
917 | D: CPUFreq and ACPI bugfixes. | 917 | D: CPUFreq and ACPI bugfixes. |
918 | S: Mougin, France | 918 | S: Mougin, France |
919 | 919 | ||
920 | N: Don Dugger | 920 | N: Don Dugger |
921 | E: n0ano@valinux.com | 921 | E: n0ano@valinux.com |
922 | D: Linux/IA-64 | 922 | D: Linux/IA-64 |
923 | S: 1209 Pearl Street, #12 | 923 | S: 1209 Pearl Street, #12 |
924 | S: Boulder, CO 80302 | 924 | S: Boulder, CO 80302 |
925 | S: USA | 925 | S: USA |
926 | 926 | ||
927 | N: Thomas Dunbar | 927 | N: Thomas Dunbar |
928 | E: tdunbar@vt.edu | 928 | E: tdunbar@vt.edu |
929 | D: TeX & METAFONT hacking/maintenance | 929 | D: TeX & METAFONT hacking/maintenance |
930 | S: Virginia Tech Computing Center | 930 | S: Virginia Tech Computing Center |
931 | S: 1700 Pratt Drive | 931 | S: 1700 Pratt Drive |
932 | S: Blacksburg, Virginia 24061 | 932 | S: Blacksburg, Virginia 24061 |
933 | S: USA | 933 | S: USA |
934 | 934 | ||
935 | N: Randy Dunlap | 935 | N: Randy Dunlap |
936 | E: rdunlap@xenotime.net | 936 | E: rdunlap@xenotime.net |
937 | W: http://www.xenotime.net/linux/linux.html | 937 | W: http://www.xenotime.net/linux/linux.html |
938 | W: http://www.linux-usb.org | 938 | W: http://www.linux-usb.org |
939 | D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers | 939 | D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers |
940 | D: x86 SMP, ACPI, bootflag hacking | 940 | D: x86 SMP, ACPI, bootflag hacking |
941 | S: (ask for current address) | 941 | S: (ask for current address) |
942 | S: USA | 942 | S: USA |
943 | 943 | ||
944 | N: Bob Dunlop | 944 | N: Bob Dunlop |
945 | E: rjd@xyzzy.clara.co.uk | 945 | E: rjd@xyzzy.clara.co.uk |
946 | E: bob.dunlop@farsite.co.uk | 946 | E: bob.dunlop@farsite.co.uk |
947 | W: www.farsite.co.uk | 947 | W: www.farsite.co.uk |
948 | D: FarSync card device driver | 948 | D: FarSync card device driver |
949 | S: FarSite Communications Ltd | 949 | S: FarSite Communications Ltd |
950 | S: Tempus Business Centre | 950 | S: Tempus Business Centre |
951 | S: 60 Kingsclere Road | 951 | S: 60 Kingsclere Road |
952 | S: Basingstoke RG21 6XG | 952 | S: Basingstoke RG21 6XG |
953 | S: UK | 953 | S: UK |
954 | 954 | ||
955 | N: Cyrus Durgin | 955 | N: Cyrus Durgin |
956 | E: cider@speakeasy.org | 956 | E: cider@speakeasy.org |
957 | W: http://www.speakeasy.org/~cider/ | 957 | W: http://www.speakeasy.org/~cider/ |
958 | D: implemented kmod | 958 | D: implemented kmod |
959 | 959 | ||
960 | N: Torsten Duwe | 960 | N: Torsten Duwe |
961 | E: Torsten.Duwe@informatik.uni-erlangen.de | 961 | E: Torsten.Duwe@informatik.uni-erlangen.de |
962 | D: Part-time kernel hacker | 962 | D: Part-time kernel hacker |
963 | D: The Linux Support Team Erlangen | 963 | D: The Linux Support Team Erlangen |
964 | S: Grevenbroicher Str. 17 | 964 | S: Grevenbroicher Str. 17 |
965 | S: 47807 Krefeld | 965 | S: 47807 Krefeld |
966 | S: Germany | 966 | S: Germany |
967 | 967 | ||
968 | N: Tom Dyas | 968 | N: Tom Dyas |
969 | E: tdyas@eden.rutgers.edu | 969 | E: tdyas@eden.rutgers.edu |
970 | D: minor hacks and some sparc port stuff | 970 | D: minor hacks and some sparc port stuff |
971 | S: New Jersey | 971 | S: New Jersey |
972 | S: USA | 972 | S: USA |
973 | 973 | ||
974 | N: Drew Eckhardt | 974 | N: Drew Eckhardt |
975 | E: drew@PoohSticks.ORG | 975 | E: drew@PoohSticks.ORG |
976 | D: SCSI code | 976 | D: SCSI code |
977 | D: Assorted snippets elsewhere | 977 | D: Assorted snippets elsewhere |
978 | D: Boot sector "..." printing | 978 | D: Boot sector "..." printing |
979 | S: 2037 Walnut #6 | 979 | S: 2037 Walnut #6 |
980 | S: Boulder, Colorado 80302 | 980 | S: Boulder, Colorado 80302 |
981 | S: USA | 981 | S: USA |
982 | 982 | ||
983 | N: Heiko Eiรfeldt | 983 | N: Heiko Eiรfeldt |
984 | E: heiko@colossus.escape.de heiko@unifix.de | 984 | E: heiko@colossus.escape.de heiko@unifix.de |
985 | D: verify_area stuff, generic SCSI fixes | 985 | D: verify_area stuff, generic SCSI fixes |
986 | D: SCSI Programming HOWTO | 986 | D: SCSI Programming HOWTO |
987 | D: POSIX.1 compliance testing | 987 | D: POSIX.1 compliance testing |
988 | S: Unifix Software GmbH | 988 | S: Unifix Software GmbH |
989 | S: Bueltenweg 27a | 989 | S: Bueltenweg 27a |
990 | S: D-38106 Braunschweig | 990 | S: D-38106 Braunschweig |
991 | S: Germany | 991 | S: Germany |
992 | 992 | ||
993 | N: Bjorn Ekwall | 993 | N: Bjorn Ekwall |
994 | E: bj0rn@blox.se | 994 | E: bj0rn@blox.se |
995 | W: http://www.pi.se/blox/ | 995 | W: http://www.pi.se/blox/ |
996 | D: Extended support for loadable modules | 996 | D: Extended support for loadable modules |
997 | D: D-Link pocket adapter drivers | 997 | D: D-Link pocket adapter drivers |
998 | S: Brevia 1043 | 998 | S: Brevia 1043 |
999 | S: S-114 79 Stockholm | 999 | S: S-114 79 Stockholm |
1000 | S: Sweden | 1000 | S: Sweden |
1001 | 1001 | ||
1002 | N: Pekka Enberg | 1002 | N: Pekka Enberg |
1003 | E: penberg@cs.helsinki.fi | 1003 | E: penberg@cs.helsinki.fi |
1004 | W: http://www.cs.helsinki.fi/u/penberg/ | 1004 | W: http://www.cs.helsinki.fi/u/penberg/ |
1005 | D: Various kernel hacks, fixes, and cleanups. | 1005 | D: Various kernel hacks, fixes, and cleanups. |
1006 | D: Slab allocators | 1006 | D: Slab allocators |
1007 | S: Finland | 1007 | S: Finland |
1008 | 1008 | ||
1009 | N: David Engebretsen | 1009 | N: David Engebretsen |
1010 | E: engebret@us.ibm.com | 1010 | E: engebret@us.ibm.com |
1011 | D: Linux port to 64-bit PowerPC architecture | 1011 | D: Linux port to 64-bit PowerPC architecture |
1012 | 1012 | ||
1013 | N: Michael Engel | 1013 | N: Michael Engel |
1014 | E: engel@unix-ag.org | 1014 | E: engel@unix-ag.org |
1015 | D: DECstation framebuffer drivers | 1015 | D: DECstation framebuffer drivers |
1016 | S: Germany | 1016 | S: Germany |
1017 | 1017 | ||
1018 | N: Paal-Kristian Engstad | 1018 | N: Paal-Kristian Engstad |
1019 | E: engstad@intermetrics.com | 1019 | E: engstad@intermetrics.com |
1020 | D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.) | 1020 | D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.) |
1021 | S: 17101 Springdale Street #225 | 1021 | S: 17101 Springdale Street #225 |
1022 | S: Huntington Beach, California 92649 | 1022 | S: Huntington Beach, California 92649 |
1023 | S: USA | 1023 | S: USA |
1024 | 1024 | ||
1025 | N: Stephane Eranian | 1025 | N: Stephane Eranian |
1026 | E: eranian@hpl.hp.com | 1026 | E: eranian@hpl.hp.com |
1027 | D: Linux/ia64 | 1027 | D: Linux/ia64 |
1028 | S: 1501 Page Mill Rd, MS 1U17 | 1028 | S: 1501 Page Mill Rd, MS 1U17 |
1029 | S: Palo Alto, CA 94304 | 1029 | S: Palo Alto, CA 94304 |
1030 | S: USA | 1030 | S: USA |
1031 | 1031 | ||
1032 | N: Johannes Erdfelt | 1032 | N: Johannes Erdfelt |
1033 | E: johannes@erdfelt.com | 1033 | E: johannes@erdfelt.com |
1034 | D: Linux/IA-64 bootloader and kernel goop, USB | 1034 | D: Linux/IA-64 bootloader and kernel goop, USB |
1035 | S: 6350 Stoneridge Mall Road | 1035 | S: 6350 Stoneridge Mall Road |
1036 | S: Pleasanton, CA 94588 | 1036 | S: Pleasanton, CA 94588 |
1037 | S: USA | 1037 | S: USA |
1038 | 1038 | ||
1039 | N: Doug Evans | 1039 | N: Doug Evans |
1040 | E: dje@cygnus.com | 1040 | E: dje@cygnus.com |
1041 | D: Wrote Xenix FS (part of standard kernel since 0.99.15) | 1041 | D: Wrote Xenix FS (part of standard kernel since 0.99.15) |
1042 | 1042 | ||
1043 | N: Riccardo Facchetti | 1043 | N: Riccardo Facchetti |
1044 | E: fizban@tin.it | 1044 | E: fizban@tin.it |
1045 | P: 1024/6E657BB5 AF 22 90 33 78 76 04 8B AF F9 97 1E B5 E2 65 30 | 1045 | P: 1024/6E657BB5 AF 22 90 33 78 76 04 8B AF F9 97 1E B5 E2 65 30 |
1046 | D: Audio Excel DSP 16 init driver author | 1046 | D: Audio Excel DSP 16 init driver author |
1047 | D: libmodem author | 1047 | D: libmodem author |
1048 | D: Yet Another Micro Monitor port and current maintainer | 1048 | D: Yet Another Micro Monitor port and current maintainer |
1049 | D: First ELF-HOWTO author | 1049 | D: First ELF-HOWTO author |
1050 | D: random kernel hacker | 1050 | D: random kernel hacker |
1051 | S: Via Paolo VI n.29 | 1051 | S: Via Paolo VI n.29 |
1052 | S: 23900 - LECCO (Lc) | 1052 | S: 23900 - LECCO (Lc) |
1053 | S: Italy | 1053 | S: Italy |
1054 | 1054 | ||
1055 | N: Nils Faerber | 1055 | N: Nils Faerber |
1056 | E: nils@kernelconcepts.de | 1056 | E: nils@kernelconcepts.de |
1057 | D: i810 TCO watchdog driver author | 1057 | D: i810 TCO watchdog driver author |
1058 | D: Mitsumi LU005 tests and fixes | 1058 | D: Mitsumi LU005 tests and fixes |
1059 | D: port and fixes of cs46xx sounddriver | 1059 | D: port and fixes of cs46xx sounddriver |
1060 | S: Dreisbachstrasse 24 | 1060 | S: Dreisbachstrasse 24 |
1061 | S: D-57250 Netphen | 1061 | S: D-57250 Netphen |
1062 | S: Germany | 1062 | S: Germany |
1063 | 1063 | ||
1064 | N: Rik Faith | 1064 | N: Rik Faith |
1065 | E: faith@acm.org | 1065 | E: faith@acm.org |
1066 | D: Future Domain TMC-16x0 SCSI driver (author) | 1066 | D: Future Domain TMC-16x0 SCSI driver (author) |
1067 | D: APM driver (early port) | 1067 | D: APM driver (early port) |
1068 | D: DRM drivers (author of several) | 1068 | D: DRM drivers (author of several) |
1069 | 1069 | ||
1070 | N: Jรกnos Farkas | 1070 | N: Jรกnos Farkas |
1071 | E: chexum@shadow.banki.hu | 1071 | E: chexum@shadow.banki.hu |
1072 | D: romfs, various (mostly networking) fixes | 1072 | D: romfs, various (mostly networking) fixes |
1073 | P: 1024/F81FB2E1 41 B7 E4 E6 3E D4 A6 71 6D 9C F3 9F F2 BF DF 6E | 1073 | P: 1024/F81FB2E1 41 B7 E4 E6 3E D4 A6 71 6D 9C F3 9F F2 BF DF 6E |
1074 | S: Madarรกsz Viktor utca 25 | 1074 | S: Madarรกsz Viktor utca 25 |
1075 | S: 1131 Budapest | 1075 | S: 1131 Budapest |
1076 | S: Hungary | 1076 | S: Hungary |
1077 | 1077 | ||
1078 | N: Ben Fennema | 1078 | N: Ben Fennema |
1079 | E: bfennema@falcon.csc.calpoly.edu | 1079 | E: bfennema@falcon.csc.calpoly.edu |
1080 | W: http://www.csc.calpoly.edu/~bfennema | 1080 | W: http://www.csc.calpoly.edu/~bfennema |
1081 | D: UDF filesystem | 1081 | D: UDF filesystem |
1082 | S: (ask for current address) | 1082 | S: (ask for current address) |
1083 | S: USA | 1083 | S: USA |
1084 | 1084 | ||
1085 | N: Jรผrgen Fischer | 1085 | N: Jรผrgen Fischer |
1086 | E: fischer@norbit.de | 1086 | E: fischer@norbit.de |
1087 | D: Author of Adaptec AHA-152x SCSI driver | 1087 | D: Author of Adaptec AHA-152x SCSI driver |
1088 | S: Schulstraรe 18 | 1088 | S: Schulstraรe 18 |
1089 | S: 26506 Norden | 1089 | S: 26506 Norden |
1090 | S: Germany | 1090 | S: Germany |
1091 | 1091 | ||
1092 | N: Jeremy Fitzhardinge | 1092 | N: Jeremy Fitzhardinge |
1093 | E: jeremy@goop.org | 1093 | E: jeremy@goop.org |
1094 | W: http://www.goop.org/~jeremy | 1094 | W: http://www.goop.org/~jeremy |
1095 | D: author of userfs filesystem | 1095 | D: author of userfs filesystem |
1096 | D: Improved mmap and munmap handling | 1096 | D: Improved mmap and munmap handling |
1097 | D: General mm minor tidyups | 1097 | D: General mm minor tidyups |
1098 | D: autofs v4 maintainer | 1098 | D: autofs v4 maintainer |
1099 | S: 987 Alabama St | 1099 | S: 987 Alabama St |
1100 | S: San Francisco | 1100 | S: San Francisco |
1101 | S: CA, 94110 | 1101 | S: CA, 94110 |
1102 | S: USA | 1102 | S: USA |
1103 | 1103 | ||
1104 | N: Ralf Flaxa | 1104 | N: Ralf Flaxa |
1105 | E: rfflaxa@immd4.informatik.uni-erlangen.de | 1105 | E: rfflaxa@immd4.informatik.uni-erlangen.de |
1106 | D: The Linux Support Team Erlangen | 1106 | D: The Linux Support Team Erlangen |
1107 | D: Creator of LST distribution | 1107 | D: Creator of LST distribution |
1108 | D: Author of installation tool LISA | 1108 | D: Author of installation tool LISA |
1109 | S: Pfitznerweg 6 | 1109 | S: Pfitznerweg 6 |
1110 | S: 74523 Schwaebisch Hall | 1110 | S: 74523 Schwaebisch Hall |
1111 | S: Germany | 1111 | S: Germany |
1112 | 1112 | ||
1113 | N: Lawrence Foard | 1113 | N: Lawrence Foard |
1114 | E: entropy@world.std.com | 1114 | E: entropy@world.std.com |
1115 | D: Floppy track reading, fs code | 1115 | D: Floppy track reading, fs code |
1116 | S: 217 Park Avenue, Suite 108 | 1116 | S: 217 Park Avenue, Suite 108 |
1117 | S: Worcester, Massachusetts 01609 | 1117 | S: Worcester, Massachusetts 01609 |
1118 | S: USA | 1118 | S: USA |
1119 | 1119 | ||
1120 | N: Karl Fogel | 1120 | N: Karl Fogel |
1121 | E: kfogel@cs.oberlin.edu | 1121 | E: kfogel@cs.oberlin.edu |
1122 | D: Contributor, Linux User's Guide | 1122 | D: Contributor, Linux User's Guide |
1123 | S: 1123 North Oak Park Avenue | 1123 | S: 1123 North Oak Park Avenue |
1124 | S: Oak Park, Illinois 60302 | 1124 | S: Oak Park, Illinois 60302 |
1125 | S: USA | 1125 | S: USA |
1126 | 1126 | ||
1127 | N: Daniel J. Frasnelli | 1127 | N: Daniel J. Frasnelli |
1128 | E: dfrasnel@alphalinux.org | 1128 | E: dfrasnel@alphalinux.org |
1129 | W: http://www.alphalinux.org/ | 1129 | W: http://www.alphalinux.org/ |
1130 | P: 1024/3EF87611 B9 F1 44 50 D3 E8 C2 80 DA E5 55 AA 56 7C 42 DA | 1130 | P: 1024/3EF87611 B9 F1 44 50 D3 E8 C2 80 DA E5 55 AA 56 7C 42 DA |
1131 | D: DEC Alpha hacker | 1131 | D: DEC Alpha hacker |
1132 | D: Miscellaneous bug squisher | 1132 | D: Miscellaneous bug squisher |
1133 | 1133 | ||
1134 | N: Jim Freeman | 1134 | N: Jim Freeman |
1135 | E: jfree@sovereign.org | 1135 | E: jfree@sovereign.org |
1136 | W: http://www.sovereign.org/ | 1136 | W: http://www.sovereign.org/ |
1137 | D: Initial GPL'd Frame Relay driver | 1137 | D: Initial GPL'd Frame Relay driver |
1138 | D: Dynamic PPP devices | 1138 | D: Dynamic PPP devices |
1139 | D: Sundry modularizations (PPP, IPX, ...) and fixes | 1139 | D: Sundry modularizations (PPP, IPX, ...) and fixes |
1140 | 1140 | ||
1141 | N: Bob Frey | 1141 | N: Bob Frey |
1142 | E: bobf@advansys.com | 1142 | E: bobf@advansys.com |
1143 | D: AdvanSys SCSI driver | 1143 | D: AdvanSys SCSI driver |
1144 | S: 1150 Ringwood Court | 1144 | S: 1150 Ringwood Court |
1145 | S: San Jose, California 95131 | 1145 | S: San Jose, California 95131 |
1146 | S: USA | 1146 | S: USA |
1147 | 1147 | ||
1148 | N: Adam Fritzler | 1148 | N: Adam Fritzler |
1149 | E: mid@zigamorph.net | 1149 | E: mid@zigamorph.net |
1150 | 1150 | ||
1151 | N: Fernando Fuganti | 1151 | N: Fernando Fuganti |
1152 | E: fuganti@conectiva.com.br | 1152 | E: fuganti@conectiva.com.br |
1153 | E: fuganti@netbank.com.br | 1153 | E: fuganti@netbank.com.br |
1154 | D: random kernel hacker, ZF MachZ Watchdog driver | 1154 | D: random kernel hacker, ZF MachZ Watchdog driver |
1155 | S: Conectiva S.A. | 1155 | S: Conectiva S.A. |
1156 | S: R. Tocantins, 89 - Cristo Rei | 1156 | S: R. Tocantins, 89 - Cristo Rei |
1157 | S: 80050-430 - Curitiba - Paranรก | 1157 | S: 80050-430 - Curitiba - Paranรก |
1158 | S: Brazil | 1158 | S: Brazil |
1159 | 1159 | ||
1160 | N: Kumar Gala | 1160 | N: Kumar Gala |
1161 | E: galak@kernel.crashing.org | 1161 | E: galak@kernel.crashing.org |
1162 | D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support | 1162 | D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support |
1163 | S: Austin, Texas 78729 | 1163 | S: Austin, Texas 78729 |
1164 | S: USA | 1164 | S: USA |
1165 | 1165 | ||
1166 | N: Nigel Gamble | 1166 | N: Nigel Gamble |
1167 | E: nigel@nrg.org | 1167 | E: nigel@nrg.org |
1168 | D: Interrupt-driven printer driver | 1168 | D: Interrupt-driven printer driver |
1169 | D: Preemptible kernel | 1169 | D: Preemptible kernel |
1170 | S: 120 Alley Way | 1170 | S: 120 Alley Way |
1171 | S: Mountain View, California 94040 | 1171 | S: Mountain View, California 94040 |
1172 | S: USA | 1172 | S: USA |
1173 | 1173 | ||
1174 | N: Jeff Garzik | 1174 | N: Jeff Garzik |
1175 | E: jgarzik@pobox.com | 1175 | E: jgarzik@pobox.com |
1176 | 1176 | ||
1177 | N: Jacques Gelinas | 1177 | N: Jacques Gelinas |
1178 | E: jacques@solucorp.qc.ca | 1178 | E: jacques@solucorp.qc.ca |
1179 | D: Author of the Umsdos file system | 1179 | D: Author of the Umsdos file system |
1180 | S: 1326 De Val-Brillant | 1180 | S: 1326 De Val-Brillant |
1181 | S: Laval, Quebec | 1181 | S: Laval, Quebec |
1182 | S: Canada H7Y 1V9 | 1182 | S: Canada H7Y 1V9 |
1183 | 1183 | ||
1184 | N: David Gentzel | 1184 | N: David Gentzel |
1185 | E: gentzel@telerama.lm.com | 1185 | E: gentzel@telerama.lm.com |
1186 | D: Original BusLogic driver and original UltraStor driver | 1186 | D: Original BusLogic driver and original UltraStor driver |
1187 | S: Whitfield Software Services | 1187 | S: Whitfield Software Services |
1188 | S: 600 North Bell Avenue, Suite 160 | 1188 | S: 600 North Bell Avenue, Suite 160 |
1189 | S: Carnegie, Pennsylvania 15106-4304 | 1189 | S: Carnegie, Pennsylvania 15106-4304 |
1190 | S: USA | 1190 | S: USA |
1191 | 1191 | ||
1192 | N: Kai Germaschewski | 1192 | N: Kai Germaschewski |
1193 | E: kai@germaschewski.name | 1193 | E: kai@germaschewski.name |
1194 | D: Major kbuild rework during the 2.5 cycle | 1194 | D: Major kbuild rework during the 2.5 cycle |
1195 | D: ISDN Maintainer | 1195 | D: ISDN Maintainer |
1196 | S: USA | 1196 | S: USA |
1197 | 1197 | ||
1198 | N: Philip Gladstone | 1198 | N: Philip Gladstone |
1199 | E: philip@gladstonefamily.net | 1199 | E: philip@gladstonefamily.net |
1200 | D: Kernel / timekeeping stuff | 1200 | D: Kernel / timekeeping stuff |
1201 | S: Carlisle, MA 01741 | 1201 | S: Carlisle, MA 01741 |
1202 | S: USA | 1202 | S: USA |
1203 | 1203 | ||
1204 | N: Jan-Benedict Glaw | 1204 | N: Jan-Benedict Glaw |
1205 | E: jbglaw@lug-owl.de | 1205 | E: jbglaw@lug-owl.de |
1206 | D: SRM environment driver (for Alpha systems) | 1206 | D: SRM environment driver (for Alpha systems) |
1207 | P: 1024D/8399E1BB 250D 3BCF 7127 0D8C A444 A961 1DBD 5E75 8399 E1BB | 1207 | P: 1024D/8399E1BB 250D 3BCF 7127 0D8C A444 A961 1DBD 5E75 8399 E1BB |
1208 | 1208 | ||
1209 | N: Thomas Gleixner | 1209 | N: Thomas Gleixner |
1210 | E: tglx@linutronix.de | 1210 | E: tglx@linutronix.de |
1211 | D: NAND flash hardware support, JFFS2 on NAND flash | 1211 | D: NAND flash hardware support, JFFS2 on NAND flash |
1212 | 1212 | ||
1213 | N: Richard E. Gooch | 1213 | N: Richard E. Gooch |
1214 | E: rgooch@atnf.csiro.au | 1214 | E: rgooch@atnf.csiro.au |
1215 | D: parent process death signal to children | 1215 | D: parent process death signal to children |
1216 | D: prctl() syscall | 1216 | D: prctl() syscall |
1217 | D: /proc/mtrr support to manipulate MTRRs on Intel P6 family | 1217 | D: /proc/mtrr support to manipulate MTRRs on Intel P6 family |
1218 | D: Device FileSystem (devfs) | 1218 | D: Device FileSystem (devfs) |
1219 | S: CSIRO Australia Telescope National Facility | 1219 | S: CSIRO Australia Telescope National Facility |
1220 | S: P.O. Box 76, Epping | 1220 | S: P.O. Box 76, Epping |
1221 | S: New South Wales, 2121 | 1221 | S: New South Wales, 2121 |
1222 | S: Australia | 1222 | S: Australia |
1223 | 1223 | ||
1224 | N: Carlos E. Gorges | 1224 | N: Carlos E. Gorges |
1225 | E: carlos@techlinux.com.br | 1225 | E: carlos@techlinux.com.br |
1226 | D: fix smp support on cmpci driver | 1226 | D: fix smp support on cmpci driver |
1227 | P: 2048G/EA3C4B19 FF31 33A6 0362 4915 B7EB E541 17D0 0379 EA3C 4B19 | 1227 | P: 2048G/EA3C4B19 FF31 33A6 0362 4915 B7EB E541 17D0 0379 EA3C 4B19 |
1228 | S: Brazil | 1228 | S: Brazil |
1229 | 1229 | ||
1230 | N: Dmitry S. Gorodchanin | 1230 | N: Dmitry S. Gorodchanin |
1231 | E: pgmdsg@ibi.com | 1231 | E: pgmdsg@ibi.com |
1232 | D: RISCom/8 driver, misc kernel fixes. | 1232 | D: RISCom/8 driver, misc kernel fixes. |
1233 | S: 4 Main Street | 1233 | S: 4 Main Street |
1234 | S: Woodbridge, Connecticut 06525 | 1234 | S: Woodbridge, Connecticut 06525 |
1235 | S: USA | 1235 | S: USA |
1236 | 1236 | ||
1237 | N: Paul Gortmaker | 1237 | N: Paul Gortmaker |
1238 | E: p_gortmaker@yahoo.com | 1238 | E: p_gortmaker@yahoo.com |
1239 | D: Author of RTC driver & several net drivers, Ethernet & BootPrompt Howto. | 1239 | D: Author of RTC driver & several net drivers, Ethernet & BootPrompt Howto. |
1240 | D: Made support for modules, ramdisk, generic-serial, etc. optional. | 1240 | D: Made support for modules, ramdisk, generic-serial, etc. optional. |
1241 | D: Transformed old user space bdflush into 1st kernel thread - kflushd. | 1241 | D: Transformed old user space bdflush into 1st kernel thread - kflushd. |
1242 | D: Many other patches, documentation files, mini kernels, utilities, ... | 1242 | D: Many other patches, documentation files, mini kernels, utilities, ... |
1243 | 1243 | ||
1244 | N: Masanori GOTO | 1244 | N: Masanori GOTO |
1245 | E: gotom@debian.or.jp | 1245 | E: gotom@debian.or.jp |
1246 | D: Workbit NinjaSCSI-32Bi/UDE driver | 1246 | D: Workbit NinjaSCSI-32Bi/UDE driver |
1247 | S: Japan | 1247 | S: Japan |
1248 | 1248 | ||
1249 | N: John E. Gotts | 1249 | N: John E. Gotts |
1250 | E: jgotts@linuxsavvy.com | 1250 | E: jgotts@linuxsavvy.com |
1251 | D: kernel hacker | 1251 | D: kernel hacker |
1252 | S: 8124 Constitution Apt. 7 | 1252 | S: 8124 Constitution Apt. 7 |
1253 | S: Sterling Heights, Michigan 48313 | 1253 | S: Sterling Heights, Michigan 48313 |
1254 | S: USA | 1254 | S: USA |
1255 | 1255 | ||
1256 | N: Wolfgang Grandegger | 1256 | N: Wolfgang Grandegger |
1257 | E: wg@grandegger.com | 1257 | E: wg@grandegger.com |
1258 | D: Controller Area Network (device drivers) | 1258 | D: Controller Area Network (device drivers) |
1259 | 1259 | ||
1260 | N: William Greathouse | 1260 | N: William Greathouse |
1261 | E: wgreathouse@smva.com | 1261 | E: wgreathouse@smva.com |
1262 | E: wgreathouse@myfavoritei.com | 1262 | E: wgreathouse@myfavoritei.com |
1263 | D: Current Belkin USB Serial Adapter F5U103 hacker | 1263 | D: Current Belkin USB Serial Adapter F5U103 hacker |
1264 | D: Kernel hacker, embedded systems | 1264 | D: Kernel hacker, embedded systems |
1265 | S: 7802 Fitzwater Road | 1265 | S: 7802 Fitzwater Road |
1266 | S: Brecksville, OH 44141-1334 | 1266 | S: Brecksville, OH 44141-1334 |
1267 | S: USA | 1267 | S: USA |
1268 | 1268 | ||
1269 | N: Tristan Greaves | 1269 | N: Tristan Greaves |
1270 | E: tristan@extricate.org | 1270 | E: tristan@extricate.org |
1271 | W: http://www.extricate.org/ | 1271 | W: http://www.extricate.org/ |
1272 | D: Miscellaneous ipv4 sysctl patches | 1272 | D: Miscellaneous ipv4 sysctl patches |
1273 | 1273 | ||
1274 | N: Michael A. Griffith | 1274 | N: Michael A. Griffith |
1275 | E: grif@cs.ucr.edu | 1275 | E: grif@cs.ucr.edu |
1276 | W: http://www.cs.ucr.edu/~grif | 1276 | W: http://www.cs.ucr.edu/~grif |
1277 | D: Loopback speedup, qlogic SCSI hacking, VT_LOCKSWITCH | 1277 | D: Loopback speedup, qlogic SCSI hacking, VT_LOCKSWITCH |
1278 | S: Department of Computer Science | 1278 | S: Department of Computer Science |
1279 | S: University of California, Riverside | 1279 | S: University of California, Riverside |
1280 | S: Riverside, California 92521-0304 | 1280 | S: Riverside, California 92521-0304 |
1281 | S: USA | 1281 | S: USA |
1282 | 1282 | ||
1283 | N: Hans Grobler | 1283 | N: Hans Grobler |
1284 | E: grobh@sun.ac.za | 1284 | E: grobh@sun.ac.za |
1285 | D: Various AX.25/ROSE/NETROM + hamradio driver patches | 1285 | D: Various AX.25/ROSE/NETROM + hamradio driver patches |
1286 | D: Various X.25/LABP + driver patches | 1286 | D: Various X.25/LABP + driver patches |
1287 | D: Misc kernel fixes and updates | 1287 | D: Misc kernel fixes and updates |
1288 | S: Department of Electronic Engineering | 1288 | S: Department of Electronic Engineering |
1289 | S: University of Stellenbosch | 1289 | S: University of Stellenbosch |
1290 | S: Stellenbosch, Western Cape | 1290 | S: Stellenbosch, Western Cape |
1291 | S: South Africa | 1291 | S: South Africa |
1292 | 1292 | ||
1293 | N: Grant Grundler | 1293 | N: Grant Grundler |
1294 | E: grundler@parisc-linux.org | 1294 | E: grundler@parisc-linux.org |
1295 | W: http://obmouse.sourceforge.net/ | 1295 | W: http://obmouse.sourceforge.net/ |
1296 | W: http://www.parisc-linux.org/ | 1296 | W: http://www.parisc-linux.org/ |
1297 | D: obmouse - rewrote Olivier Florent's Omnibook 600 "pop-up" mouse driver | 1297 | D: obmouse - rewrote Olivier Florent's Omnibook 600 "pop-up" mouse driver |
1298 | D: PA-RISC - Interrupt/PCI HBA/IOMMU author and architect | 1298 | D: PA-RISC - Interrupt/PCI HBA/IOMMU author and architect |
1299 | S: Mountain View, California | 1299 | S: Mountain View, California |
1300 | S: USA | 1300 | S: USA |
1301 | 1301 | ||
1302 | N: Grant Guenther | 1302 | N: Grant Guenther |
1303 | E: grant@torque.net | 1303 | E: grant@torque.net |
1304 | W: http://www.torque.net/linux-pp.html | 1304 | W: http://www.torque.net/linux-pp.html |
1305 | D: original author of ppa driver for parallel port ZIP drive | 1305 | D: original author of ppa driver for parallel port ZIP drive |
1306 | D: original architect of the parallel-port sharing scheme | 1306 | D: original architect of the parallel-port sharing scheme |
1307 | D: PARIDE subsystem: drivers for parallel port IDE & ATAPI devices | 1307 | D: PARIDE subsystem: drivers for parallel port IDE & ATAPI devices |
1308 | S: 44 St. Joseph Street, Suite 506 | 1308 | S: 44 St. Joseph Street, Suite 506 |
1309 | S: Toronto, Ontario, M4Y 2W4 | 1309 | S: Toronto, Ontario, M4Y 2W4 |
1310 | S: Canada | 1310 | S: Canada |
1311 | 1311 | ||
1312 | N: Richard Gรผnther | 1312 | N: Richard Gรผnther |
1313 | E: rguenth@tat.physik.uni-tuebingen.de | 1313 | E: rguenth@tat.physik.uni-tuebingen.de |
1314 | W: http://www.tat.physik.uni-tuebingen.de/~rguenth | 1314 | W: http://www.tat.physik.uni-tuebingen.de/~rguenth |
1315 | P: 2048/2E829319 2F 83 FC 93 E9 E4 19 E2 93 7A 32 42 45 37 23 57 | 1315 | P: 2048/2E829319 2F 83 FC 93 E9 E4 19 E2 93 7A 32 42 45 37 23 57 |
1316 | D: binfmt_misc | 1316 | D: binfmt_misc |
1317 | S: 72074 Tรผbingen | 1317 | S: 72074 Tรผbingen |
1318 | S: Germany | 1318 | S: Germany |
1319 | 1319 | ||
1320 | N: Justin Guyett | 1320 | N: Justin Guyett |
1321 | E: jguyett@andrew.cmu.edu | 1321 | E: jguyett@andrew.cmu.edu |
1322 | D: via-rhine net driver hacking | 1322 | D: via-rhine net driver hacking |
1323 | 1323 | ||
1324 | N: Danny ter Haar | 1324 | N: Danny ter Haar |
1325 | E: dth@cistron.nl | 1325 | E: dth@cistron.nl |
1326 | D: /proc/cpuinfo, reboot on panic , kernel pre-patch tester ;) | 1326 | D: /proc/cpuinfo, reboot on panic , kernel pre-patch tester ;) |
1327 | S: Cistron | 1327 | S: Cistron |
1328 | S: PO-Box 297 | 1328 | S: PO-Box 297 |
1329 | S: 2400 AG, Alphen aan den Rijn | 1329 | S: 2400 AG, Alphen aan den Rijn |
1330 | S: The Netherlands | 1330 | S: The Netherlands |
1331 | 1331 | ||
1332 | N: Enver Haase | 1332 | N: Enver Haase |
1333 | E: ehaase@inf.fu-berlin.de | 1333 | E: ehaase@inf.fu-berlin.de |
1334 | W: http://www.inf.fu-berlin.de/~ehaase | 1334 | W: http://www.inf.fu-berlin.de/~ehaase |
1335 | D: Driver for the Commodore A2232 serial board | 1335 | D: Driver for the Commodore A2232 serial board |
1336 | 1336 | ||
1337 | N: Bruno Haible | 1337 | N: Bruno Haible |
1338 | E: haible@ma2s2.mathematik.uni-karlsruhe.de | 1338 | E: haible@ma2s2.mathematik.uni-karlsruhe.de |
1339 | D: SysV FS, shm swapping, memory management fixes | 1339 | D: SysV FS, shm swapping, memory management fixes |
1340 | S: 17 rue Danton | 1340 | S: 17 rue Danton |
1341 | S: F - 94270 Le Kremlin-Bicรชtre | 1341 | S: F - 94270 Le Kremlin-Bicรชtre |
1342 | S: France | 1342 | S: France |
1343 | 1343 | ||
1344 | N: Greg Hankins | 1344 | N: Greg Hankins |
1345 | E: gregh@cc.gatech.edu | 1345 | E: gregh@cc.gatech.edu |
1346 | D: fixed keyboard driver to separate LED and locking status | 1346 | D: fixed keyboard driver to separate LED and locking status |
1347 | S: 25360 Georgia Tech Station | 1347 | S: 25360 Georgia Tech Station |
1348 | S: Atlanta, Georgia 30332 | 1348 | S: Atlanta, Georgia 30332 |
1349 | S: USA | 1349 | S: USA |
1350 | 1350 | ||
1351 | N: Brad Hards | 1351 | N: Brad Hards |
1352 | E: bradh@frogmouth.net | 1352 | E: bradh@frogmouth.net |
1353 | D: Various USB bits, other minor patches | 1353 | D: Various USB bits, other minor patches |
1354 | 1354 | ||
1355 | N: Angelo Haritsis | 1355 | N: Angelo Haritsis |
1356 | E: ah@computer.org | 1356 | E: ah@computer.org |
1357 | D: kernel patches (serial, watchdog) | 1357 | D: kernel patches (serial, watchdog) |
1358 | D: xringd, vuzkern, greekXfonts | 1358 | D: xringd, vuzkern, greekXfonts |
1359 | S: 77 Clarence Mews | 1359 | S: 77 Clarence Mews |
1360 | S: London SE16 1GD | 1360 | S: London SE16 1GD |
1361 | S: United Kingdom | 1361 | S: United Kingdom |
1362 | 1362 | ||
1363 | N: Jan Harkes | 1363 | N: Jan Harkes |
1364 | E: jaharkes@cs.cmu.edu | 1364 | E: jaharkes@cs.cmu.edu |
1365 | W: http://www.coda.cs.cmu.edu/ | 1365 | W: http://www.coda.cs.cmu.edu/ |
1366 | D: Coda file system | 1366 | D: Coda file system |
1367 | S: Computer Science Department | 1367 | S: Computer Science Department |
1368 | S: Carnegie Mellon University | 1368 | S: Carnegie Mellon University |
1369 | S: 5000 Forbes Avenue | 1369 | S: 5000 Forbes Avenue |
1370 | S: Pittsburgh, Pennsylvania 15213 | 1370 | S: Pittsburgh, Pennsylvania 15213 |
1371 | S: USA | 1371 | S: USA |
1372 | 1372 | ||
1373 | N: Kai Harrekilde-Petersen | 1373 | N: Kai Harrekilde-Petersen |
1374 | E: kai.harrekilde@get2net.dk | 1374 | E: kai.harrekilde@get2net.dk |
1375 | D: Original author of the ftape-HOWTO, i82078 fdc detection code. | 1375 | D: Original author of the ftape-HOWTO, i82078 fdc detection code. |
1376 | 1376 | ||
1377 | N: Bart Hartgers | 1377 | N: Bart Hartgers |
1378 | E: bart@etpmod.phys.tue.nl | 1378 | E: bart@etpmod.phys.tue.nl |
1379 | D: MTRR emulation with Centaur MCRs | 1379 | D: MTRR emulation with Centaur MCRs |
1380 | S: Gen Stedmanstraat 212 | 1380 | S: Gen Stedmanstraat 212 |
1381 | S: 5623 HZ Eindhoven | 1381 | S: 5623 HZ Eindhoven |
1382 | S: The Netherlands | 1382 | S: The Netherlands |
1383 | 1383 | ||
1384 | N: Oliver Hartkopp | 1384 | N: Oliver Hartkopp |
1385 | E: oliver.hartkopp@volkswagen.de | 1385 | E: oliver.hartkopp@volkswagen.de |
1386 | W: http://www.volkswagen.de | 1386 | W: http://www.volkswagen.de |
1387 | D: Controller Area Network (network layer core) | 1387 | D: Controller Area Network (network layer core) |
1388 | S: Brieffach 1776 | 1388 | S: Brieffach 1776 |
1389 | S: 38436 Wolfsburg | 1389 | S: 38436 Wolfsburg |
1390 | S: Germany | 1390 | S: Germany |
1391 | 1391 | ||
1392 | N: Andrew Haylett | 1392 | N: Andrew Haylett |
1393 | E: ajh@primag.co.uk | 1393 | E: ajh@primag.co.uk |
1394 | D: Selection mechanism | 1394 | D: Selection mechanism |
1395 | 1395 | ||
1396 | N: Andre Hedrick | 1396 | N: Andre Hedrick |
1397 | E: andre@linux-ide.org | 1397 | E: andre@linux-ide.org |
1398 | E: andre@linuxdiskcert.org | 1398 | E: andre@linuxdiskcert.org |
1399 | W: http://www.linux-ide.org/ | 1399 | W: http://www.linux-ide.org/ |
1400 | W: http://www.linuxdiskcert.org/ | 1400 | W: http://www.linuxdiskcert.org/ |
1401 | D: Random SMP kernel hacker... | 1401 | D: Random SMP kernel hacker... |
1402 | D: Uniform Multi-Platform E-IDE driver | 1402 | D: Uniform Multi-Platform E-IDE driver |
1403 | D: Active-ATA-Chipset maddness.......... | 1403 | D: Active-ATA-Chipset maddness.......... |
1404 | D: Ultra DMA 133/100/66/33 w/48-bit Addressing | 1404 | D: Ultra DMA 133/100/66/33 w/48-bit Addressing |
1405 | D: ATA-Disconnect, ATA-TCQ | 1405 | D: ATA-Disconnect, ATA-TCQ |
1406 | D: ATA-Smart Kernel Daemon | 1406 | D: ATA-Smart Kernel Daemon |
1407 | D: Serial ATA | 1407 | D: Serial ATA |
1408 | D: ATA Command Block and Taskfile | 1408 | D: ATA Command Block and Taskfile |
1409 | S: Linux ATA Development (LAD) | 1409 | S: Linux ATA Development (LAD) |
1410 | S: Concord, CA | 1410 | S: Concord, CA |
1411 | 1411 | ||
1412 | N: Jochen Hein | 1412 | N: Jochen Hein |
1413 | E: jochen@jochen.org | 1413 | E: jochen@jochen.org |
1414 | P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B CB 0A DA DA 40 77 05 6C | 1414 | P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B CB 0A DA DA 40 77 05 6C |
1415 | P: 1024D/77D4FC9B F5C5 1C20 1DFC DEC3 3107 54A4 2332 ADFC 77D4 FC9B | 1415 | P: 1024D/77D4FC9B F5C5 1C20 1DFC DEC3 3107 54A4 2332 ADFC 77D4 FC9B |
1416 | D: National Language Support | 1416 | D: National Language Support |
1417 | D: Linux Internationalization Project | 1417 | D: Linux Internationalization Project |
1418 | D: German Localization for Linux and GNU software | 1418 | D: German Localization for Linux and GNU software |
1419 | S: Auf der Fittel 18 | 1419 | S: Auf der Fittel 18 |
1420 | S: 53347 Alfter | 1420 | S: 53347 Alfter |
1421 | S: Germany | 1421 | S: Germany |
1422 | 1422 | ||
1423 | N: Christoph Hellwig | 1423 | N: Christoph Hellwig |
1424 | E: hch@infradead.org | 1424 | E: hch@infradead.org |
1425 | D: all kinds of driver, filesystem & core kernel hacking | 1425 | D: all kinds of driver, filesystem & core kernel hacking |
1426 | D: freevxfs driver | 1426 | D: freevxfs driver |
1427 | D: sysvfs maintainer | 1427 | D: sysvfs maintainer |
1428 | D: chief codingstyle nitpicker | 1428 | D: chief codingstyle nitpicker |
1429 | S: Ampferstr. 50 / 4 | 1429 | S: Ampferstr. 50 / 4 |
1430 | S: 6020 Innsbruck | 1430 | S: 6020 Innsbruck |
1431 | S: Austria | 1431 | S: Austria |
1432 | 1432 | ||
1433 | N: Richard Henderson | 1433 | N: Richard Henderson |
1434 | E: rth@twiddle.net | 1434 | E: rth@twiddle.net |
1435 | E: rth@cygnus.com | 1435 | E: rth@cygnus.com |
1436 | D: Alpha hacker, kernel and userland | 1436 | D: Alpha hacker, kernel and userland |
1437 | S: 1668 California St. | 1437 | S: 1668 California St. |
1438 | S: Mountain View, California 94041 | 1438 | S: Mountain View, California 94041 |
1439 | S: USA | 1439 | S: USA |
1440 | 1440 | ||
1441 | N: Benjamin Herrenschmidt | 1441 | N: Benjamin Herrenschmidt |
1442 | E: benh@kernel.crashing.org | 1442 | E: benh@kernel.crashing.org |
1443 | D: Various parts of PPC/PPC64 & PowerMac | 1443 | D: Various parts of PPC/PPC64 & PowerMac |
1444 | S: 312/107 Canberra Avenue | 1444 | S: 312/107 Canberra Avenue |
1445 | S: Griffith, ACT 2603 | 1445 | S: Griffith, ACT 2603 |
1446 | S: Australia | 1446 | S: Australia |
1447 | 1447 | ||
1448 | N: Sebastian Hetze | 1448 | N: Sebastian Hetze |
1449 | E: she@lunetix.de | 1449 | E: she@lunetix.de |
1450 | D: German Linux Documentation, | 1450 | D: German Linux Documentation, |
1451 | D: Organization of German Linux Conferences | 1451 | D: Organization of German Linux Conferences |
1452 | S: Danckelmannstr. 48 | 1452 | S: Danckelmannstr. 48 |
1453 | S: 14059 Berlin | 1453 | S: 14059 Berlin |
1454 | S: Germany | 1454 | S: Germany |
1455 | 1455 | ||
1456 | N: David Hinds | 1456 | N: David Hinds |
1457 | E: dahinds@users.sourceforge.net | 1457 | E: dahinds@users.sourceforge.net |
1458 | W: http://tao.stanford.edu/~dhinds | 1458 | W: http://tao.stanford.edu/~dhinds |
1459 | D: PCMCIA and CardBus stuff, PCMCIA-HOWTO, PCMCIA client drivers | 1459 | D: PCMCIA and CardBus stuff, PCMCIA-HOWTO, PCMCIA client drivers |
1460 | S: 2019 W. Middlefield Rd #1 | 1460 | S: 2019 W. Middlefield Rd #1 |
1461 | S: Mountain View, CA 94043 | 1461 | S: Mountain View, CA 94043 |
1462 | S: USA | 1462 | S: USA |
1463 | 1463 | ||
1464 | N: Michael Hipp | 1464 | N: Michael Hipp |
1465 | E: hippm@informatik.uni-tuebingen.de | 1465 | E: hippm@informatik.uni-tuebingen.de |
1466 | D: drivers for the racal ni5210 & ni6510 Ethernet-boards | 1466 | D: drivers for the racal ni5210 & ni6510 Ethernet-boards |
1467 | S: Talstr. 1 | 1467 | S: Talstr. 1 |
1468 | S: D - 72072 Tuebingen | 1468 | S: D - 72072 Tuebingen |
1469 | S: Germany | 1469 | S: Germany |
1470 | 1470 | ||
1471 | N: Richard Hirst | 1471 | N: Richard Hirst |
1472 | E: richard@sleepie.demon.co.uk | 1472 | E: richard@sleepie.demon.co.uk |
1473 | E: rhirst@linuxcare.com | 1473 | E: rhirst@linuxcare.com |
1474 | W: http://www.sleepie.demon.co.uk/ | 1474 | W: http://www.sleepie.demon.co.uk/ |
1475 | D: linux-m68k VME support | 1475 | D: linux-m68k VME support |
1476 | D: PA-RISC port, scsi and network drivers | 1476 | D: PA-RISC port, scsi and network drivers |
1477 | D: 53c700/53c710 driver author, 82596 driver maintainer | 1477 | D: 53c700/53c710 driver author, 82596 driver maintainer |
1478 | S: United Kingdom | 1478 | S: United Kingdom |
1479 | 1479 | ||
1480 | N: Jauder Ho | 1480 | N: Jauder Ho |
1481 | E: jauderho@carumba.com | 1481 | E: jauderho@carumba.com |
1482 | W: http://www.carumba.com/ | 1482 | W: http://www.carumba.com/ |
1483 | D: bug toaster (A1 sauce makes all the difference) | 1483 | D: bug toaster (A1 sauce makes all the difference) |
1484 | D: Random linux hacker | 1484 | D: Random linux hacker |
1485 | 1485 | ||
1486 | N: Tim Hockin | 1486 | N: Tim Hockin |
1487 | E: thockin@hockin.org | 1487 | E: thockin@hockin.org |
1488 | W: http://www.hockin.org/~thockin | 1488 | W: http://www.hockin.org/~thockin |
1489 | D: Natsemi ethernet | 1489 | D: Natsemi ethernet |
1490 | D: Cobalt Networks (x86) support | 1490 | D: Cobalt Networks (x86) support |
1491 | D: This-and-That | 1491 | D: This-and-That |
1492 | 1492 | ||
1493 | N: Dirk Hohndel | 1493 | N: Dirk Hohndel |
1494 | E: hohndel@suse.de | 1494 | E: hohndel@suse.de |
1495 | D: The XFree86[tm] Project | 1495 | D: The XFree86[tm] Project |
1496 | D: USB mouse maintainer | 1496 | D: USB mouse maintainer |
1497 | S: SuSE Rhein/Main AG | 1497 | S: SuSE Rhein/Main AG |
1498 | S: Mergenthalerallee 45-47 | 1498 | S: Mergenthalerallee 45-47 |
1499 | S: 65760 Eschborn | 1499 | S: 65760 Eschborn |
1500 | S: Germany | 1500 | S: Germany |
1501 | 1501 | ||
1502 | N: Kenji Hollis | 1502 | N: Kenji Hollis |
1503 | E: kenji@bitgate.com | 1503 | E: kenji@bitgate.com |
1504 | W: http://www.bitgate.com/ | 1504 | W: http://www.bitgate.com/ |
1505 | D: Berkshire PC Watchdog Driver | 1505 | D: Berkshire PC Watchdog Driver |
1506 | D: Small/Industrial Driver Project | 1506 | D: Small/Industrial Driver Project |
1507 | 1507 | ||
1508 | N: Nick Holloway | 1508 | N: Nick Holloway |
1509 | E: Nick.Holloway@pyrites.org.uk | 1509 | E: Nick.Holloway@pyrites.org.uk |
1510 | W: http://www.pyrites.org.uk/ | 1510 | W: http://www.pyrites.org.uk/ |
1511 | P: 1024/36115A04 F4E1 3384 FCFD C055 15D6 BA4C AB03 FBF8 3611 5A04 | 1511 | P: 1024/36115A04 F4E1 3384 FCFD C055 15D6 BA4C AB03 FBF8 3611 5A04 |
1512 | D: Occasional Linux hacker... | 1512 | D: Occasional Linux hacker... |
1513 | S: (ask for current address) | 1513 | S: (ask for current address) |
1514 | S: United Kingdom | 1514 | S: United Kingdom |
1515 | 1515 | ||
1516 | N: Ron Holt | 1516 | N: Ron Holt |
1517 | E: ron@holt.org | 1517 | E: ron@holt.org |
1518 | E: rholt@netcom.com | 1518 | E: rholt@netcom.com |
1519 | W: http://www.holt.org/ | 1519 | W: http://www.holt.org/ |
1520 | W: http://www.ronholt.com/ | 1520 | W: http://www.ronholt.com/ |
1521 | D: Kernel development | 1521 | D: Kernel development |
1522 | D: Kernel LDT modifications to support Wabi and Wine | 1522 | D: Kernel LDT modifications to support Wabi and Wine |
1523 | S: Holtron Internetics, Inc. | 1523 | S: Holtron Internetics, Inc. |
1524 | S: 998 East 900 South, Suite 26 | 1524 | S: 998 East 900 South, Suite 26 |
1525 | S: Provo, Utah 84606-5607 | 1525 | S: Provo, Utah 84606-5607 |
1526 | S: USA | 1526 | S: USA |
1527 | 1527 | ||
1528 | N: Marcel Holtmann | 1528 | N: Marcel Holtmann |
1529 | E: marcel@holtmann.org | 1529 | E: marcel@holtmann.org |
1530 | W: http://www.holtmann.org | 1530 | W: http://www.holtmann.org |
1531 | D: Maintainer of the Linux Bluetooth Subsystem | 1531 | D: Maintainer of the Linux Bluetooth Subsystem |
1532 | D: Author and maintainer of the various Bluetooth HCI drivers | 1532 | D: Author and maintainer of the various Bluetooth HCI drivers |
1533 | D: Author and maintainer of the CAPI message transport protocol driver | 1533 | D: Author and maintainer of the CAPI message transport protocol driver |
1534 | D: Author and maintainer of the Bluetooth HID protocol driver | 1534 | D: Author and maintainer of the Bluetooth HID protocol driver |
1535 | D: Various other Bluetooth related patches, cleanups and fixes | 1535 | D: Various other Bluetooth related patches, cleanups and fixes |
1536 | S: Germany | 1536 | S: Germany |
1537 | 1537 | ||
1538 | N: Rob W. W. Hooft | 1538 | N: Rob W. W. Hooft |
1539 | E: hooft@EMBL-Heidelberg.DE | 1539 | E: hooft@EMBL-Heidelberg.DE |
1540 | D: Shared libs for graphics-tools and for the f2c compiler | 1540 | D: Shared libs for graphics-tools and for the f2c compiler |
1541 | D: Some kernel programming on the floppy and sound drivers in early days | 1541 | D: Some kernel programming on the floppy and sound drivers in early days |
1542 | D: Some other hacks to get different kinds of programs to work for linux | 1542 | D: Some other hacks to get different kinds of programs to work for linux |
1543 | S: Panoramastrasse 18 | 1543 | S: Panoramastrasse 18 |
1544 | S: D-69126 Heidelberg | 1544 | S: D-69126 Heidelberg |
1545 | S: Germany | 1545 | S: Germany |
1546 | 1546 | ||
1547 | N: Christopher Horn | 1547 | N: Christopher Horn |
1548 | E: chorn@warwick.net | 1548 | E: chorn@warwick.net |
1549 | D: Miscellaneous sysctl hacks | 1549 | D: Miscellaneous sysctl hacks |
1550 | S: 36 Mudtown Road | 1550 | S: 36 Mudtown Road |
1551 | S: Wantage, New Jersey 07461 | 1551 | S: Wantage, New Jersey 07461 |
1552 | S: USA | 1552 | S: USA |
1553 | 1553 | ||
1554 | N: Harald Hoyer | 1554 | N: Harald Hoyer |
1555 | E: harald.hoyer@parzelle.de | 1555 | E: harald.hoyer@parzelle.de |
1556 | W: http://parzelle.de/ | 1556 | W: http://parzelle.de/ |
1557 | D: ip_masq_quake | 1557 | D: ip_masq_quake |
1558 | D: md boot support | 1558 | D: md boot support |
1559 | S: Hohe Strasse 30 | 1559 | S: Hohe Strasse 30 |
1560 | S: D-70176 Stuttgart | 1560 | S: D-70176 Stuttgart |
1561 | S: Germany | 1561 | S: Germany |
1562 | 1562 | ||
1563 | N: Jan Hubicka | 1563 | N: Jan Hubicka |
1564 | E: hubicka@freesoft.cz | 1564 | E: hubicka@freesoft.cz |
1565 | E: hubicka@suse.cz | 1565 | E: hubicka@suse.cz |
1566 | W: http://www.paru.cas.cz/~hubicka/ | 1566 | W: http://www.paru.cas.cz/~hubicka/ |
1567 | D: Random kernel tweaks and fixes. | 1567 | D: Random kernel tweaks and fixes. |
1568 | S: Dukelskych bojovniku 1944 | 1568 | S: Dukelskych bojovniku 1944 |
1569 | S: Tabor 390 03 | 1569 | S: Tabor 390 03 |
1570 | S: Czech Republic | 1570 | S: Czech Republic |
1571 | 1571 | ||
1572 | N: David Huggins-Daines | 1572 | N: David Huggins-Daines |
1573 | E: dhd@debian.org | 1573 | E: dhd@debian.org |
1574 | E: dhd@eradicator.org | 1574 | E: dhd@eradicator.org |
1575 | E: dhd@cepstral.com | 1575 | E: dhd@cepstral.com |
1576 | D: PA-RISC port | 1576 | D: PA-RISC port |
1577 | D: Nubus subsystem | 1577 | D: Nubus subsystem |
1578 | D: Generic 68k Macintosh framebuffer driver | 1578 | D: Generic 68k Macintosh framebuffer driver |
1579 | D: STI framebuffer tweaks | 1579 | D: STI framebuffer tweaks |
1580 | D: LTPC driver tweaks | 1580 | D: LTPC driver tweaks |
1581 | S: 110 S. 12th St., Apt. A | 1581 | S: 110 S. 12th St., Apt. A |
1582 | S: Pittsburgh, PA 15203-1250 | 1582 | S: Pittsburgh, PA 15203-1250 |
1583 | S: USA | 1583 | S: USA |
1584 | 1584 | ||
1585 | N: Gareth Hughes | 1585 | N: Gareth Hughes |
1586 | E: gareth.hughes@acm.org | 1586 | E: gareth.hughes@acm.org |
1587 | D: Pentium III FXSR, SSE support | 1587 | D: Pentium III FXSR, SSE support |
1588 | D: Author/maintainer of most DRM drivers (especially ATI, MGA) | 1588 | D: Author/maintainer of most DRM drivers (especially ATI, MGA) |
1589 | D: Core DRM templates, general DRM and 3D-related hacking | 1589 | D: Core DRM templates, general DRM and 3D-related hacking |
1590 | S: No fixed address | 1590 | S: No fixed address |
1591 | 1591 | ||
1592 | N: Kenn Humborg | 1592 | N: Kenn Humborg |
1593 | E: kenn@wombat.ie | 1593 | E: kenn@wombat.ie |
1594 | D: Mods to loop device to support sparse backing files | 1594 | D: Mods to loop device to support sparse backing files |
1595 | S: Ballinagard | 1595 | S: Ballinagard |
1596 | S: Roscommon | 1596 | S: Roscommon |
1597 | S: Ireland | 1597 | S: Ireland |
1598 | 1598 | ||
1599 | N: Michael Hunold | 1599 | N: Michael Hunold |
1600 | E: michael@mihu.de | 1600 | E: michael@mihu.de |
1601 | W: http://www.mihu.de/linux/ | 1601 | W: http://www.mihu.de/linux/ |
1602 | D: Generic saa7146 video4linux-2 driver core, | 1602 | D: Generic saa7146 video4linux-2 driver core, |
1603 | D: Driver for the "Multimedia eXtension Board", "dpc7146", | 1603 | D: Driver for the "Multimedia eXtension Board", "dpc7146", |
1604 | D: "Hexium Orion", "Hexium Gemini" | 1604 | D: "Hexium Orion", "Hexium Gemini" |
1605 | 1605 | ||
1606 | N: Miguel de Icaza Amozurrutia | 1606 | N: Miguel de Icaza Amozurrutia |
1607 | E: miguel@nuclecu.unam.mx | 1607 | E: miguel@nuclecu.unam.mx |
1608 | D: Linux/SPARC team, Midnight Commander maintainer | 1608 | D: Linux/SPARC team, Midnight Commander maintainer |
1609 | S: Avenida Copilco 162, 22-1003 | 1609 | S: Avenida Copilco 162, 22-1003 |
1610 | S: Mexico, DF | 1610 | S: Mexico, DF |
1611 | S: Mexico | 1611 | S: Mexico |
1612 | 1612 | ||
1613 | N: Ian Jackson | 1613 | N: Ian Jackson |
1614 | E: iwj10@cus.cam.ac.uk | 1614 | E: iwj10@cus.cam.ac.uk |
1615 | E: ijackson@nyx.cs.du.edu | 1615 | E: ijackson@nyx.cs.du.edu |
1616 | D: FAQ maintainer and poster of the daily postings | 1616 | D: FAQ maintainer and poster of the daily postings |
1617 | D: FSSTND group member | 1617 | D: FSSTND group member |
1618 | D: Debian core team member and maintainer of several Debian packages | 1618 | D: Debian core team member and maintainer of several Debian packages |
1619 | S: 2 Lexington Close | 1619 | S: 2 Lexington Close |
1620 | S: Cambridge | 1620 | S: Cambridge |
1621 | S: CB3 0DS | 1621 | S: CB3 0DS |
1622 | S: United Kingdom | 1622 | S: United Kingdom |
1623 | 1623 | ||
1624 | N: Andreas Jaeger | 1624 | N: Andreas Jaeger |
1625 | E: aj@suse.de | 1625 | E: aj@suse.de |
1626 | D: Various smaller kernel fixes | 1626 | D: Various smaller kernel fixes |
1627 | D: glibc developer | 1627 | D: glibc developer |
1628 | S: Gottfried-Kinkel-Str. 18 | 1628 | S: Gottfried-Kinkel-Str. 18 |
1629 | S: D 67659 Kaiserslautern | 1629 | S: D 67659 Kaiserslautern |
1630 | S: Germany | 1630 | S: Germany |
1631 | 1631 | ||
1632 | N: Mike Jagdis | 1632 | N: Mike Jagdis |
1633 | E: jaggy@purplet.demon.co.uk | 1633 | E: jaggy@purplet.demon.co.uk |
1634 | E: Mike.Jagdis@purplet.demon.co.uk | 1634 | E: Mike.Jagdis@purplet.demon.co.uk |
1635 | D: iBCS personalities, socket and X interfaces, x.out loader, syscalls... | 1635 | D: iBCS personalities, socket and X interfaces, x.out loader, syscalls... |
1636 | D: Purple Distribution maintainer | 1636 | D: Purple Distribution maintainer |
1637 | D: UK FidoNet support | 1637 | D: UK FidoNet support |
1638 | D: ISODE && PP | 1638 | D: ISODE && PP |
1639 | D: Kernel and device driver hacking | 1639 | D: Kernel and device driver hacking |
1640 | S: 280 Silverdale Road | 1640 | S: 280 Silverdale Road |
1641 | S: Earley | 1641 | S: Earley |
1642 | S: Reading | 1642 | S: Reading |
1643 | S: RG6 2NU | 1643 | S: RG6 2NU |
1644 | S: United Kingdom | 1644 | S: United Kingdom |
1645 | 1645 | ||
1646 | N: Jakub Jelinek | 1646 | N: Jakub Jelinek |
1647 | E: jakub@redhat.com | 1647 | E: jakub@redhat.com |
1648 | W: http://sunsite.mff.cuni.cz/~jj | 1648 | W: http://sunsite.mff.cuni.cz/~jj |
1649 | P: 1024/0F7623C5 53 95 71 3C EB 73 99 97 02 49 40 47 F9 19 68 20 | 1649 | P: 1024/0F7623C5 53 95 71 3C EB 73 99 97 02 49 40 47 F9 19 68 20 |
1650 | D: Sparc hacker, SILO, mc | 1650 | D: Sparc hacker, SILO, mc |
1651 | D: Maintain sunsite.mff.cuni.cz | 1651 | D: Maintain sunsite.mff.cuni.cz |
1652 | S: K osmidomkum 723 | 1652 | S: K osmidomkum 723 |
1653 | S: 160 00 Praha 6 | 1653 | S: 160 00 Praha 6 |
1654 | S: Czech Republic | 1654 | S: Czech Republic |
1655 | 1655 | ||
1656 | N: Niels Kristian Bech Jensen | 1656 | N: Niels Kristian Bech Jensen |
1657 | E: nkbj1970@hotmail.com | 1657 | E: nkbj1970@hotmail.com |
1658 | D: Miscellaneous kernel updates and fixes. | 1658 | D: Miscellaneous kernel updates and fixes. |
1659 | 1659 | ||
1660 | N: Michael K. Johnson | 1660 | N: Michael K. Johnson |
1661 | E: johnsonm@redhat.com | 1661 | E: johnsonm@redhat.com |
1662 | W: http://www.redhat.com/~johnsonm | 1662 | W: http://www.redhat.com/~johnsonm |
1663 | P: 1024/4536A8DD 2A EC 88 08 40 64 CE D8 DD F8 12 2B 61 43 83 15 | 1663 | P: 1024/4536A8DD 2A EC 88 08 40 64 CE D8 DD F8 12 2B 61 43 83 15 |
1664 | D: The Linux Documentation Project | 1664 | D: The Linux Documentation Project |
1665 | D: Kernel Hackers' Guide | 1665 | D: Kernel Hackers' Guide |
1666 | D: Procps | 1666 | D: Procps |
1667 | D: Proc filesystem | 1667 | D: Proc filesystem |
1668 | D: Maintain tsx-11.mit.edu | 1668 | D: Maintain tsx-11.mit.edu |
1669 | D: LP driver | 1669 | D: LP driver |
1670 | S: 201 Howell Street, Apartment 1C | 1670 | S: 201 Howell Street, Apartment 1C |
1671 | S: Chapel Hill, North Carolina 27514-4818 | 1671 | S: Chapel Hill, North Carolina 27514-4818 |
1672 | S: USA | 1672 | S: USA |
1673 | 1673 | ||
1674 | N: Dave Jones | 1674 | N: Dave Jones |
1675 | E: davej@redhat.com | 1675 | E: davej@redhat.com |
1676 | W: http://www.codemonkey.org.uk | 1676 | W: http://www.codemonkey.org.uk |
1677 | D: Assorted VIA x86 support. | 1677 | D: Assorted VIA x86 support. |
1678 | D: 2.5 AGPGART overhaul. | 1678 | D: 2.5 AGPGART overhaul. |
1679 | D: CPUFREQ maintenance. | 1679 | D: CPUFREQ maintenance. |
1680 | D: Fedora kernel maintainence. | 1680 | D: Fedora kernel maintainence. |
1681 | D: Misc/Other. | 1681 | D: Misc/Other. |
1682 | S: 314 Littleton Rd, Westford, MA 01886, USA | 1682 | S: 314 Littleton Rd, Westford, MA 01886, USA |
1683 | 1683 | ||
1684 | N: Martin Josfsson | 1684 | N: Martin Josfsson |
1685 | E: gandalf@wlug.westbo.se | 1685 | E: gandalf@wlug.westbo.se |
1686 | P: 1024D/F6B6D3B1 7610 7CED 5C34 4AA6 DBA2 8BE1 5A6D AF95 F6B6 D3B1 | 1686 | P: 1024D/F6B6D3B1 7610 7CED 5C34 4AA6 DBA2 8BE1 5A6D AF95 F6B6 D3B1 |
1687 | D: netfilter: SAME target | 1687 | D: netfilter: SAME target |
1688 | D: netfilter: helper target | 1688 | D: netfilter: helper target |
1689 | D: netfilter: various other hacks | 1689 | D: netfilter: various other hacks |
1690 | S: Ronneby | 1690 | S: Ronneby |
1691 | S: Sweden | 1691 | S: Sweden |
1692 | 1692 | ||
1693 | N: Ani Joshi | 1693 | N: Ani Joshi |
1694 | E: ajoshi@shell.unixbox.com | 1694 | E: ajoshi@shell.unixbox.com |
1695 | D: fbdev hacking | 1695 | D: fbdev hacking |
1696 | 1696 | ||
1697 | N: Jesper Juhl | 1697 | N: Jesper Juhl |
1698 | E: jj@chaosbits.net | 1698 | E: jj@chaosbits.net |
1699 | D: Various fixes, cleanups and minor features all over the tree. | 1699 | D: Various fixes, cleanups and minor features all over the tree. |
1700 | D: Wrote initial version of the hdaps driver (since passed on to others). | 1700 | D: Wrote initial version of the hdaps driver (since passed on to others). |
1701 | S: Lemnosvej 1, 3.tv | 1701 | S: Lemnosvej 1, 3.tv |
1702 | S: 2300 Copenhagen S. | 1702 | S: 2300 Copenhagen S. |
1703 | S: Denmark | 1703 | S: Denmark |
1704 | 1704 | ||
1705 | N: Jozsef Kadlecsik | 1705 | N: Jozsef Kadlecsik |
1706 | E: kadlec@blackhole.kfki.hu | 1706 | E: kadlec@blackhole.kfki.hu |
1707 | P: 1024D/470DB964 4CB3 1A05 713E 9BF7 FAC5 5809 DD8C B7B1 470D B964 | 1707 | P: 1024D/470DB964 4CB3 1A05 713E 9BF7 FAC5 5809 DD8C B7B1 470D B964 |
1708 | D: netfilter: TCP window tracking code | 1708 | D: netfilter: TCP window tracking code |
1709 | D: netfilter: raw table | 1709 | D: netfilter: raw table |
1710 | D: netfilter: iprange match | 1710 | D: netfilter: iprange match |
1711 | D: netfilter: new logging interfaces | 1711 | D: netfilter: new logging interfaces |
1712 | D: netfilter: various other hacks | 1712 | D: netfilter: various other hacks |
1713 | S: Tata | 1713 | S: Tata |
1714 | S: Hungary | 1714 | S: Hungary |
1715 | 1715 | ||
1716 | N: Bernhard Kaindl | 1716 | N: Bernhard Kaindl |
1717 | E: bkaindl@netway.at | 1717 | E: bkaindl@netway.at |
1718 | E: edv@bartelt.via.at | 1718 | E: edv@bartelt.via.at |
1719 | D: Author of a menu based configuration tool, kmenu, which | 1719 | D: Author of a menu based configuration tool, kmenu, which |
1720 | D: is the predecessor of 'make menuconfig' and 'make xconfig'. | 1720 | D: is the predecessor of 'make menuconfig' and 'make xconfig'. |
1721 | D: digiboard driver update(modularisation work and 2.1.x upd) | 1721 | D: digiboard driver update(modularisation work and 2.1.x upd) |
1722 | S: Tallak 95 | 1722 | S: Tallak 95 |
1723 | S: 8103 Rein | 1723 | S: 8103 Rein |
1724 | S: Austria | 1724 | S: Austria |
1725 | 1725 | ||
1726 | N: Mitsuru Kanda | 1726 | N: Mitsuru Kanda |
1727 | E: mk@linux-ipv6.org | 1727 | E: mk@linux-ipv6.org |
1728 | E: mk@isl.rdc.toshiba.co.jp | 1728 | E: mk@isl.rdc.toshiba.co.jp |
1729 | E: mk@karaba.org | 1729 | E: mk@karaba.org |
1730 | W: http://www.karaba.org/~mk/ | 1730 | W: http://www.karaba.org/~mk/ |
1731 | P: 1024D/2EC7E30D 4DC3 949B 5A6C F0D6 375F 4472 8888 A8E1 2EC7 E30D | 1731 | P: 1024D/2EC7E30D 4DC3 949B 5A6C F0D6 375F 4472 8888 A8E1 2EC7 E30D |
1732 | D: IPsec, IPv6 | 1732 | D: IPsec, IPv6 |
1733 | D: USAGI/WIDE Project, TOSHIBA CORPORATION | 1733 | D: USAGI/WIDE Project, TOSHIBA CORPORATION |
1734 | S: 2-47-8, Takinogawa, | 1734 | S: 2-47-8, Takinogawa, |
1735 | S: Kita, Tokyo 114-0023 | 1735 | S: Kita, Tokyo 114-0023 |
1736 | S: Japan | 1736 | S: Japan |
1737 | 1737 | ||
1738 | N: Jan Kara | 1738 | N: Jan Kara |
1739 | E: jack@atrey.karlin.mff.cuni.cz | 1739 | E: jack@atrey.karlin.mff.cuni.cz |
1740 | E: jack@suse.cz | 1740 | E: jack@suse.cz |
1741 | D: Quota fixes for 2.2 kernel | 1741 | D: Quota fixes for 2.2 kernel |
1742 | D: Quota fixes for 2.3 kernel | 1742 | D: Quota fixes for 2.3 kernel |
1743 | D: Few other fixes in filesystem area (buffer cache, isofs, loopback) | 1743 | D: Few other fixes in filesystem area (buffer cache, isofs, loopback) |
1744 | W: http://atrey.karlin.mff.cuni.cz/~jack/ | 1744 | W: http://atrey.karlin.mff.cuni.cz/~jack/ |
1745 | S: Krosenska' 543 | 1745 | S: Krosenska' 543 |
1746 | S: 181 00 Praha 8 | 1746 | S: 181 00 Praha 8 |
1747 | S: Czech Republic | 1747 | S: Czech Republic |
1748 | 1748 | ||
1749 | N: Jan "Yenya" Kasprzak | 1749 | N: Jan "Yenya" Kasprzak |
1750 | E: kas@fi.muni.cz | 1750 | E: kas@fi.muni.cz |
1751 | D: Author of the COSA/SRP sync serial board driver. | 1751 | D: Author of the COSA/SRP sync serial board driver. |
1752 | D: Port of the syncppp.c from the 2.0 to the 2.1 kernel. | 1752 | D: Port of the syncppp.c from the 2.0 to the 2.1 kernel. |
1753 | P: 1024/D3498839 0D 99 A7 FB 20 66 05 D7 8B 35 FC DE 05 B1 8A 5E | 1753 | P: 1024/D3498839 0D 99 A7 FB 20 66 05 D7 8B 35 FC DE 05 B1 8A 5E |
1754 | W: http://www.fi.muni.cz/~kas/ | 1754 | W: http://www.fi.muni.cz/~kas/ |
1755 | S: c/o Faculty of Informatics, Masaryk University | 1755 | S: c/o Faculty of Informatics, Masaryk University |
1756 | S: Botanicka' 68a | 1756 | S: Botanicka' 68a |
1757 | S: 602 00 Brno | 1757 | S: 602 00 Brno |
1758 | S: Czech Republic | 1758 | S: Czech Republic |
1759 | 1759 | ||
1760 | N: Jakob Kemi | 1760 | N: Jakob Kemi |
1761 | E: jakob.kemi@telia.com | 1761 | E: jakob.kemi@telia.com |
1762 | D: V4L W9966 Webcam driver | 1762 | D: V4L W9966 Webcam driver |
1763 | S: Forsbyvรคgen 33 | 1763 | S: Forsbyvรคgen 33 |
1764 | S: 74143 Knivsta | 1764 | S: 74143 Knivsta |
1765 | S: Sweden | 1765 | S: Sweden |
1766 | 1766 | ||
1767 | N: Fred N. van Kempen | 1767 | N: Fred N. van Kempen |
1768 | E: waltje@linux.com | 1768 | E: waltje@linux.com |
1769 | D: NET-2 | 1769 | D: NET-2 |
1770 | D: Drivers | 1770 | D: Drivers |
1771 | D: Kernel cleanups | 1771 | D: Kernel cleanups |
1772 | S: Korte Heul 95 | 1772 | S: Korte Heul 95 |
1773 | S: 1403 ND BUSSUM | 1773 | S: 1403 ND BUSSUM |
1774 | S: The Netherlands | 1774 | S: The Netherlands |
1775 | 1775 | ||
1776 | N: Karl Keyte | 1776 | N: Karl Keyte |
1777 | E: karl@koft.com | 1777 | E: karl@koft.com |
1778 | D: Disk usage statistics and modifications to line printer driver | 1778 | D: Disk usage statistics and modifications to line printer driver |
1779 | S: 26a Sheen Road | 1779 | S: 26a Sheen Road |
1780 | S: Richmond | 1780 | S: Richmond |
1781 | S: Surrey | 1781 | S: Surrey |
1782 | S: TW9 1AE | 1782 | S: TW9 1AE |
1783 | S: United Kingdom | 1783 | S: United Kingdom |
1784 | 1784 | ||
1785 | N: Marko Kiiskila | 1785 | N: Marko Kiiskila |
1786 | E: marko@iprg.nokia.com | 1786 | E: marko@iprg.nokia.com |
1787 | D: Author of ATM Lan Emulation | 1787 | D: Author of ATM Lan Emulation |
1788 | S: 660 Harvard Ave. #7 | 1788 | S: 660 Harvard Ave. #7 |
1789 | S: Santa Clara, CA 95051 | 1789 | S: Santa Clara, CA 95051 |
1790 | S: USA | 1790 | S: USA |
1791 | 1791 | ||
1792 | N: Russell King | 1792 | N: Russell King |
1793 | E: rmk@arm.linux.org.uk | 1793 | E: rmk@arm.linux.org.uk |
1794 | D: Linux/arm integrator, maintainer & hacker | 1794 | D: Linux/arm integrator, maintainer & hacker |
1795 | D: Acornfb, Cyber2000fb author | 1795 | D: Acornfb, Cyber2000fb author |
1796 | S: Burgh Heath, Tadworth, Surrey. | 1796 | S: Burgh Heath, Tadworth, Surrey. |
1797 | S: England | 1797 | S: England |
1798 | 1798 | ||
1799 | N: Olaf Kirch | 1799 | N: Olaf Kirch |
1800 | E: okir@monad.swb.de | 1800 | E: okir@monad.swb.de |
1801 | D: Author of the Linux Network Administrators' Guide | 1801 | D: Author of the Linux Network Administrators' Guide |
1802 | S: Kattreinstr 38 | 1802 | S: Kattreinstr 38 |
1803 | S: D-64295 | 1803 | S: D-64295 |
1804 | S: Germany | 1804 | S: Germany |
1805 | 1805 | ||
1806 | N: Andi Kleen | 1806 | N: Andi Kleen |
1807 | E: andi@firstfloor.org | 1807 | E: andi@firstfloor.org |
1808 | U: http://www.halobates.de | 1808 | U: http://www.halobates.de |
1809 | D: network, x86, NUMA, various hacks | 1809 | D: network, x86, NUMA, various hacks |
1810 | S: Schwalbenstr. 96 | 1810 | S: Schwalbenstr. 96 |
1811 | S: 85551 Ottobrunn | 1811 | S: 85551 Ottobrunn |
1812 | S: Germany | 1812 | S: Germany |
1813 | 1813 | ||
1814 | N: Ian Kluft | 1814 | N: Ian Kluft |
1815 | E: ikluft@thunder.sbay.org | 1815 | E: ikluft@thunder.sbay.org |
1816 | W: http://www.kluft.com/~ikluft/ | 1816 | W: http://www.kluft.com/~ikluft/ |
1817 | D: NET-1 beta testing & minor patches, original Smail binary packages for | 1817 | D: NET-1 beta testing & minor patches, original Smail binary packages for |
1818 | D: Slackware and Debian, vote-taker for 2nd comp.os.linux reorganization | 1818 | D: Slackware and Debian, vote-taker for 2nd comp.os.linux reorganization |
1819 | S: Post Office Box 611311 | 1819 | S: Post Office Box 611311 |
1820 | S: San Jose, California 95161-1311 | 1820 | S: San Jose, California 95161-1311 |
1821 | S: USA | 1821 | S: USA |
1822 | 1822 | ||
1823 | N: Thorsten Knabe | 1823 | N: Thorsten Knabe |
1824 | E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> | 1824 | E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> |
1825 | E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de> | 1825 | E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de> |
1826 | W: http://www.student.informatik.tu-darmstadt.de/~tek | 1826 | W: http://www.student.informatik.tu-darmstadt.de/~tek |
1827 | W: http://www.tu-darmstadt.de/~tek01 | 1827 | W: http://www.tu-darmstadt.de/~tek01 |
1828 | P: 1024/3BC8D885 8C 29 C5 0A C0 D1 D6 F4 20 D4 2D AB 29 F6 D0 60 | 1828 | P: 1024/3BC8D885 8C 29 C5 0A C0 D1 D6 F4 20 D4 2D AB 29 F6 D0 60 |
1829 | D: AD1816 sound driver | 1829 | D: AD1816 sound driver |
1830 | S: Am Bergfried 10 | 1830 | S: Am Bergfried 10 |
1831 | S: 63225 Langen | 1831 | S: 63225 Langen |
1832 | S: Germany | 1832 | S: Germany |
1833 | 1833 | ||
1834 | N: Alain L. Knaff | 1834 | N: Alain L. Knaff |
1835 | E: Alain.Knaff@lll.lu | 1835 | E: Alain.Knaff@lll.lu |
1836 | D: floppy driver | 1836 | D: floppy driver |
1837 | S: 19, rue Jean l'Aveugle | 1837 | S: 19, rue Jean l'Aveugle |
1838 | S: L-1148 Luxembourg-City | 1838 | S: L-1148 Luxembourg-City |
1839 | S: Luxembourg | 1839 | S: Luxembourg |
1840 | 1840 | ||
1841 | N: Gerd Knorr | 1841 | N: Gerd Knorr |
1842 | W: http://bytesex.org | 1842 | W: http://bytesex.org |
1843 | E: kraxel@bytesex.org | 1843 | E: kraxel@bytesex.org |
1844 | E: kraxel@suse.de | 1844 | E: kraxel@suse.de |
1845 | D: video4linux, bttv, vesafb, some scsi, misc fixes | 1845 | D: video4linux, bttv, vesafb, some scsi, misc fixes |
1846 | 1846 | ||
1847 | N: Harald Koenig | 1847 | N: Harald Koenig |
1848 | E: koenig@tat.physik.uni-tuebingen.de | 1848 | E: koenig@tat.physik.uni-tuebingen.de |
1849 | D: XFree86 (S3), DCF77, some kernel hacks and fixes | 1849 | D: XFree86 (S3), DCF77, some kernel hacks and fixes |
1850 | S: Koenigsberger Str. 90 | 1850 | S: Koenigsberger Str. 90 |
1851 | S: D-72336 Balingen | 1851 | S: D-72336 Balingen |
1852 | S: Germany | 1852 | S: Germany |
1853 | 1853 | ||
1854 | N: Rudolf Koenig | 1854 | N: Rudolf Koenig |
1855 | E: rfkoenig@immd4.informatik.uni-erlangen.de | 1855 | E: rfkoenig@immd4.informatik.uni-erlangen.de |
1856 | D: The Linux Support Team Erlangen | 1856 | D: The Linux Support Team Erlangen |
1857 | 1857 | ||
1858 | N: Andreas Koensgen | 1858 | N: Andreas Koensgen |
1859 | E: ajk@comnets.uni-bremen.de | 1859 | E: ajk@comnets.uni-bremen.de |
1860 | D: 6pack driver for AX.25 | 1860 | D: 6pack driver for AX.25 |
1861 | 1861 | ||
1862 | N: Harald Koerfgen | 1862 | N: Harald Koerfgen |
1863 | E: hkoerfg@web.de | 1863 | E: hkoerfg@web.de |
1864 | D: Linux/MIPS kernel hacks and fixes, | 1864 | D: Linux/MIPS kernel hacks and fixes, |
1865 | D: DECstation port, Sharp Mobilon port | 1865 | D: DECstation port, Sharp Mobilon port |
1866 | S: D-50931 Koeln | 1866 | S: D-50931 Koeln |
1867 | S: Germany | 1867 | S: Germany |
1868 | 1868 | ||
1869 | N: Willy Konynenberg | 1869 | N: Willy Konynenberg |
1870 | E: willy@xos.nl | 1870 | E: willy@xos.nl |
1871 | W: http://www.xos.nl/ | 1871 | W: http://www.xos.nl/ |
1872 | D: IP transparent proxy support | 1872 | D: IP transparent proxy support |
1873 | S: X/OS Experts in Open Systems BV | 1873 | S: X/OS Experts in Open Systems BV |
1874 | S: Kruislaan 419 | 1874 | S: Kruislaan 419 |
1875 | S: 1098 VA Amsterdam | 1875 | S: 1098 VA Amsterdam |
1876 | S: The Netherlands | 1876 | S: The Netherlands |
1877 | 1877 | ||
1878 | N: Jiri Kosina | 1878 | N: Jiri Kosina |
1879 | E: jikos@jikos.cz | 1879 | E: jikos@jikos.cz |
1880 | E: jkosina@suse.cz | 1880 | E: jkosina@suse.cz |
1881 | D: Generic HID layer - original code split, fixes | 1881 | D: Generic HID layer - original code split, fixes |
1882 | D: Various ACPI fixes, keeping correct battery state through suspend | 1882 | D: Various ACPI fixes, keeping correct battery state through suspend |
1883 | D: various lockdep annotations, autofs and other random bugfixes | 1883 | D: various lockdep annotations, autofs and other random bugfixes |
1884 | S: Prague, Czech Republic | 1884 | S: Prague, Czech Republic |
1885 | 1885 | ||
1886 | N: Gene Kozin | 1886 | N: Gene Kozin |
1887 | E: 74604.152@compuserve.com | 1887 | E: 74604.152@compuserve.com |
1888 | W: http://www.sangoma.com | 1888 | W: http://www.sangoma.com |
1889 | D: WAN Router & Sangoma WAN drivers | 1889 | D: WAN Router & Sangoma WAN drivers |
1890 | S: Sangoma Technologies Inc. | 1890 | S: Sangoma Technologies Inc. |
1891 | S: 7170 Warden Avenue, Unit 2 | 1891 | S: 7170 Warden Avenue, Unit 2 |
1892 | S: Markham, Ontario | 1892 | S: Markham, Ontario |
1893 | S: L3R 8B2 | 1893 | S: L3R 8B2 |
1894 | S: Canada | 1894 | S: Canada |
1895 | 1895 | ||
1896 | N: Maxim Krasnyansky | 1896 | N: Maxim Krasnyansky |
1897 | E: maxk@qualcomm.com | 1897 | E: maxk@qualcomm.com |
1898 | W: http://vtun.sf.net | 1898 | W: http://vtun.sf.net |
1899 | W: http://bluez.sf.net | 1899 | W: http://bluez.sf.net |
1900 | D: Author of the Universal TUN/TAP driver | 1900 | D: Author of the Universal TUN/TAP driver |
1901 | D: Author of the Linux Bluetooth Subsystem (BlueZ) | 1901 | D: Author of the Linux Bluetooth Subsystem (BlueZ) |
1902 | D: Various other kernel patches, cleanups and fixes | 1902 | D: Various other kernel patches, cleanups and fixes |
1903 | S: 2213 La Terrace Circle | 1903 | S: 2213 La Terrace Circle |
1904 | S: San Jose, CA 95123 | 1904 | S: San Jose, CA 95123 |
1905 | S: USA | 1905 | S: USA |
1906 | 1906 | ||
1907 | N: Andreas S. Krebs | 1907 | N: Andreas S. Krebs |
1908 | E: akrebs@altavista.net | 1908 | E: akrebs@altavista.net |
1909 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards | 1909 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards |
1910 | 1910 | ||
1911 | N: Greg Kroah-Hartman | 1911 | N: Greg Kroah-Hartman |
1912 | E: greg@kroah.com | 1912 | E: greg@kroah.com |
1913 | E: gregkh@suse.de | 1913 | E: gregkh@suse.de |
1914 | W: http://www.kroah.com/linux/ | 1914 | W: http://www.kroah.com/linux/ |
1915 | D: USB Serial Converter driver framework, USB Handspring Visor driver | 1915 | D: USB Serial Converter driver framework, USB Handspring Visor driver |
1916 | D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver | 1916 | D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver |
1917 | D: USB I/O Edgeport driver, USB Serial IrDA driver | 1917 | D: USB I/O Edgeport driver, USB Serial IrDA driver |
1918 | D: USB Bluetooth driver, USB Skeleton driver | 1918 | D: USB Bluetooth driver, USB Skeleton driver |
1919 | D: bits and pieces of USB core code. | 1919 | D: bits and pieces of USB core code. |
1920 | D: PCI Hotplug core, PCI Hotplug Compaq driver modifications | 1920 | D: PCI Hotplug core, PCI Hotplug Compaq driver modifications |
1921 | D: portions of the Linux Security Module (LSM) framework | 1921 | D: portions of the Linux Security Module (LSM) framework |
1922 | D: parts of the driver core, debugfs. | 1922 | D: parts of the driver core, debugfs. |
1923 | 1923 | ||
1924 | N: Russell Kroll | 1924 | N: Russell Kroll |
1925 | E: rkroll@exploits.org | 1925 | E: rkroll@exploits.org |
1926 | W: http://www.exploits.org/ | 1926 | W: http://www.exploits.org/ |
1927 | D: V4L radio cards: radio-aztech (new), others (bugfixes/features) | 1927 | D: V4L radio cards: radio-aztech (new), others (bugfixes/features) |
1928 | D: Loopback block device: dynamic sizing ("max_loop" as module) | 1928 | D: Loopback block device: dynamic sizing ("max_loop" as module) |
1929 | S: Post Office Box 691886 | 1929 | S: Post Office Box 691886 |
1930 | S: San Antonio, Texas 78269-1886 | 1930 | S: San Antonio, Texas 78269-1886 |
1931 | S: USA | 1931 | S: USA |
1932 | 1932 | ||
1933 | N: Denis O. Kropp | 1933 | N: Denis O. Kropp |
1934 | E: dok@directfb.org | 1934 | E: dok@directfb.org |
1935 | D: NeoMagic framebuffer driver | 1935 | D: NeoMagic framebuffer driver |
1936 | S: Badensche Str. 46 | 1936 | S: Badensche Str. 46 |
1937 | S: 10715 Berlin | 1937 | S: 10715 Berlin |
1938 | S: Germany | 1938 | S: Germany |
1939 | 1939 | ||
1940 | N: Andrzej M. Krzysztofowicz | 1940 | N: Andrzej M. Krzysztofowicz |
1941 | E: ankry@mif.pg.gda.pl | 1941 | E: ankry@mif.pg.gda.pl |
1942 | D: Some 8-bit XT disk driver and devfs hacking | 1942 | D: Some 8-bit XT disk driver and devfs hacking |
1943 | D: Aladdin 1533/1543(C) chipset IDE | 1943 | D: Aladdin 1533/1543(C) chipset IDE |
1944 | D: PIIX chipset IDE | 1944 | D: PIIX chipset IDE |
1945 | S: ul. Matemblewska 1B/10 | 1945 | S: ul. Matemblewska 1B/10 |
1946 | S: 80-283 Gdansk | 1946 | S: 80-283 Gdansk |
1947 | S: Poland | 1947 | S: Poland |
1948 | 1948 | ||
1949 | N: Gero Kuhlmann | 1949 | N: Gero Kuhlmann |
1950 | E: gero@gkminix.han.de | 1950 | E: gero@gkminix.han.de |
1951 | D: mounting root via NFS | 1951 | D: mounting root via NFS |
1952 | S: Donarweg 4 | 1952 | S: Donarweg 4 |
1953 | S: D-30657 Hannover | 1953 | S: D-30657 Hannover |
1954 | S: Germany | 1954 | S: Germany |
1955 | 1955 | ||
1956 | N: Markus Kuhn | 1956 | N: Markus Kuhn |
1957 | E: mskuhn@cip.informatik.uni-erlangen.de | 1957 | E: mskuhn@cip.informatik.uni-erlangen.de |
1958 | W: http://wwwcip.informatik.uni-erlangen.de/user/mskuhn | 1958 | W: http://wwwcip.informatik.uni-erlangen.de/user/mskuhn |
1959 | D: Unicode, real-time, time, standards | 1959 | D: Unicode, real-time, time, standards |
1960 | S: Schlehenweg 9 | 1960 | S: Schlehenweg 9 |
1961 | S: D-91080 Uttenreuth | 1961 | S: D-91080 Uttenreuth |
1962 | S: Germany | 1962 | S: Germany |
1963 | 1963 | ||
1964 | N: Jaya Kumar | 1964 | N: Jaya Kumar |
1965 | E: jayalk@intworks.biz | 1965 | E: jayalk@intworks.biz |
1966 | W: http://www.intworks.biz | 1966 | W: http://www.intworks.biz |
1967 | D: Arc monochrome LCD framebuffer driver, x86 reboot fixups | 1967 | D: Arc monochrome LCD framebuffer driver, x86 reboot fixups |
1968 | D: pirq addr, CS5535 alsa audio driver | 1968 | D: pirq addr, CS5535 alsa audio driver |
1969 | S: Gurgaon, India | 1969 | S: Gurgaon, India |
1970 | S: Kuala Lumpur, Malaysia | 1970 | S: Kuala Lumpur, Malaysia |
1971 | 1971 | ||
1972 | N: Gabor Kuti | 1972 | N: Gabor Kuti |
1973 | M: seasons@falcon.sch.bme.hu | 1973 | M: seasons@falcon.sch.bme.hu |
1974 | M: seasons@makosteszta.sote.hu | 1974 | M: seasons@makosteszta.sote.hu |
1975 | D: Original author of software suspend | 1975 | D: Original author of software suspend |
1976 | 1976 | ||
1977 | N: Jaroslav Kysela | 1977 | N: Jaroslav Kysela |
1978 | E: perex@perex.cz | 1978 | E: perex@perex.cz |
1979 | W: http://www.perex.cz | 1979 | W: http://www.perex.cz |
1980 | D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters | 1980 | D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters |
1981 | D: ISA PnP | 1981 | D: ISA PnP |
1982 | S: Sindlovy Dvory 117 | 1982 | S: Sindlovy Dvory 117 |
1983 | S: 370 01 Ceske Budejovice | 1983 | S: 370 01 Ceske Budejovice |
1984 | S: Czech Republic | 1984 | S: Czech Republic |
1985 | 1985 | ||
1986 | N: Bas Laarhoven | 1986 | N: Bas Laarhoven |
1987 | E: sjml@xs4all.nl | 1987 | E: sjml@xs4all.nl |
1988 | D: Loadable modules and ftape driver | 1988 | D: Loadable modules and ftape driver |
1989 | S: J. Obrechtstr 23 | 1989 | S: J. Obrechtstr 23 |
1990 | S: NL-5216 GP 's-Hertogenbosch | 1990 | S: NL-5216 GP 's-Hertogenbosch |
1991 | S: The Netherlands | 1991 | S: The Netherlands |
1992 | 1992 | ||
1993 | N: Savio Lam | 1993 | N: Savio Lam |
1994 | E: lam836@cs.cuhk.hk | 1994 | E: lam836@cs.cuhk.hk |
1995 | D: Author of the dialog utility, foundation | 1995 | D: Author of the dialog utility, foundation |
1996 | D: for Menuconfig's lxdialog. | 1996 | D: for Menuconfig's lxdialog. |
1997 | 1997 | ||
1998 | N: Christoph Lameter | 1998 | N: Christoph Lameter |
1999 | E: christoph@lameter.com | 1999 | E: christoph@lameter.com |
2000 | D: Digiboard PC/Xe and PC/Xi, Digiboard EPCA | 2000 | D: Digiboard PC/Xe and PC/Xi, Digiboard EPCA |
2001 | D: NUMA support, Slab allocators, Page migration | 2001 | D: NUMA support, Slab allocators, Page migration |
2002 | D: Scalability, Time subsystem | 2002 | D: Scalability, Time subsystem |
2003 | 2003 | ||
2004 | N: Paul Laufer | 2004 | N: Paul Laufer |
2005 | E: paul@laufernet.com | 2005 | E: paul@laufernet.com |
2006 | D: Soundblaster driver fixes, ISAPnP quirk | 2006 | D: Soundblaster driver fixes, ISAPnP quirk |
2007 | S: California, USA | 2007 | S: California, USA |
2008 | 2008 | ||
2009 | N: Jonathan Layes | 2009 | N: Jonathan Layes |
2010 | D: ARPD support | 2010 | D: ARPD support |
2011 | 2011 | ||
2012 | N: Tom Lees | 2012 | N: Tom Lees |
2013 | E: tom@lpsg.demon.co.uk | 2013 | E: tom@lpsg.demon.co.uk |
2014 | W: http://www.lpsg.demon.co.uk/ | 2014 | W: http://www.lpsg.demon.co.uk/ |
2015 | P: 1024/87D4D065 2A 66 86 9D 02 4D A6 1E B8 A2 17 9D 4F 9B 89 D6 | 2015 | P: 1024/87D4D065 2A 66 86 9D 02 4D A6 1E B8 A2 17 9D 4F 9B 89 D6 |
2016 | D: Original author and current maintainer of | 2016 | D: Original author and current maintainer of |
2017 | D: PnP code. | 2017 | D: PnP code. |
2018 | 2018 | ||
2019 | N: David van Leeuwen | 2019 | N: David van Leeuwen |
2020 | E: david@tm.tno.nl | 2020 | E: david@tm.tno.nl |
2021 | D: Philips/LMS cm206 cdrom driver, generic cdrom driver | 2021 | D: Philips/LMS cm206 cdrom driver, generic cdrom driver |
2022 | S: Scheltemalaan 14 | 2022 | S: Scheltemalaan 14 |
2023 | S: 3817 KS Amersfoort | 2023 | S: 3817 KS Amersfoort |
2024 | S: The Netherlands | 2024 | S: The Netherlands |
2025 | 2025 | ||
2026 | N: Volker Lendecke | 2026 | N: Volker Lendecke |
2027 | E: vl@kki.org | 2027 | E: vl@kki.org |
2028 | D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.) | 2028 | D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.) |
2029 | D: NCP filesystem support (to mount NetWare volumes) | 2029 | D: NCP filesystem support (to mount NetWare volumes) |
2030 | S: Von-Ossietzky-Str. 12 | 2030 | S: Von-Ossietzky-Str. 12 |
2031 | S: 37085 Gรถttingen | 2031 | S: 37085 Gรถttingen |
2032 | S: Germany | 2032 | S: Germany |
2033 | 2033 | ||
2034 | N: Kevin Lentin | 2034 | N: Kevin Lentin |
2035 | E: kevinl@cs.monash.edu.au | 2035 | E: kevinl@cs.monash.edu.au |
2036 | D: NCR53C400/T130B SCSI extension to NCR5380 driver. | 2036 | D: NCR53C400/T130B SCSI extension to NCR5380 driver. |
2037 | S: 18 Board Street | 2037 | S: 18 Board Street |
2038 | S: Doncaster VIC 3108 | 2038 | S: Doncaster VIC 3108 |
2039 | S: Australia | 2039 | S: Australia |
2040 | 2040 | ||
2041 | N: Hans Lermen | 2041 | N: Hans Lermen |
2042 | E: lermen@elserv.ffm.fgan.de | 2042 | E: lermen@elserv.ffm.fgan.de |
2043 | D: Author of the LOADLIN Linux loader, hacking on boot stuff | 2043 | D: Author of the LOADLIN Linux loader, hacking on boot stuff |
2044 | D: Coordinator of DOSEMU releases | 2044 | D: Coordinator of DOSEMU releases |
2045 | S: Am Muehlenweg 38 | 2045 | S: Am Muehlenweg 38 |
2046 | S: D53424 Remagen | 2046 | S: D53424 Remagen |
2047 | S: Germany | 2047 | S: Germany |
2048 | 2048 | ||
2049 | N: Colin Leroy | 2049 | N: Colin Leroy |
2050 | E: colin@colino.net | 2050 | E: colin@colino.net |
2051 | W: http://www.geekounet.org/ | 2051 | W: http://www.geekounet.org/ |
2052 | D: PowerMac adt746x fan driver | 2052 | D: PowerMac adt746x fan driver |
2053 | D: Random fixing of various drivers (macintosh, usb, sound) | 2053 | D: Random fixing of various drivers (macintosh, usb, sound) |
2054 | S: Toulouse | 2054 | S: Toulouse |
2055 | S: France | 2055 | S: France |
2056 | 2056 | ||
2057 | N: Achim Leubner | 2057 | N: Achim Leubner |
2058 | E: achim_leubner@adaptec.com | 2058 | E: achim_leubner@adaptec.com |
2059 | D: GDT Disk Array Controller/Storage RAID controller driver | 2059 | D: GDT Disk Array Controller/Storage RAID controller driver |
2060 | S: ICP vortex GmbH | 2060 | S: ICP vortex GmbH |
2061 | S: Neckarsulm | 2061 | S: Neckarsulm |
2062 | S: Germany | 2062 | S: Germany |
2063 | 2063 | ||
2064 | N: Phil Lewis | 2064 | N: Phil Lewis |
2065 | E: beans@bucket.ualr.edu | 2065 | E: beans@bucket.ualr.edu |
2066 | D: Promised to send money if I would put his name in the source tree. | 2066 | D: Promised to send money if I would put his name in the source tree. |
2067 | S: Post Office Box 371 | 2067 | S: Post Office Box 371 |
2068 | S: North Little Rock, Arkansas 72115 | 2068 | S: North Little Rock, Arkansas 72115 |
2069 | S: USA | 2069 | S: USA |
2070 | 2070 | ||
2071 | N: Stephan Linz | 2071 | N: Stephan Linz |
2072 | E: linz@mazet.de | 2072 | E: linz@mazet.de |
2073 | E: Stephan.Linz@gmx.de | 2073 | E: Stephan.Linz@gmx.de |
2074 | W: http://www.crosswinds.net/~tuxer | 2074 | W: http://www.crosswinds.net/~tuxer |
2075 | D: PCILynx patch to work with 1394a PHY and without local RAM | 2075 | D: PCILynx patch to work with 1394a PHY and without local RAM |
2076 | S: (ask for current address) | 2076 | S: (ask for current address) |
2077 | S: Germany | 2077 | S: Germany |
2078 | 2078 | ||
2079 | N: Christophe Lizzi | 2079 | N: Christophe Lizzi |
2080 | E: lizzi@cnam.fr | 2080 | E: lizzi@cnam.fr |
2081 | W: http://cedric.cnam.fr/personne/lizzi | 2081 | W: http://cedric.cnam.fr/personne/lizzi |
2082 | D: FORE Systems 200E-series ATM network driver, sparc64 port of ATM | 2082 | D: FORE Systems 200E-series ATM network driver, sparc64 port of ATM |
2083 | S: CNAM, Laboratoire CEDRIC | 2083 | S: CNAM, Laboratoire CEDRIC |
2084 | S: 292, rue St-Martin | 2084 | S: 292, rue St-Martin |
2085 | S: 75141 Paris Cedex 03 | 2085 | S: 75141 Paris Cedex 03 |
2086 | S: France | 2086 | S: France |
2087 | 2087 | ||
2088 | N: Siegfried "Frieder" Loeffler (dg1sek) | 2088 | N: Siegfried "Frieder" Loeffler (dg1sek) |
2089 | E: floeff@tunix.mathematik.uni-stuttgart.de, fl@LF.net | 2089 | E: floeff@tunix.mathematik.uni-stuttgart.de, fl@LF.net |
2090 | W: http://www.mathematik.uni-stuttgart.de/~floeff | 2090 | W: http://www.mathematik.uni-stuttgart.de/~floeff |
2091 | D: Busmaster driver for HP 10/100 Mbit Network Adapters | 2091 | D: Busmaster driver for HP 10/100 Mbit Network Adapters |
2092 | S: University of Stuttgart, Germany and | 2092 | S: University of Stuttgart, Germany and |
2093 | S: Ecole Nationale Superieure des Telecommunications, Paris | 2093 | S: Ecole Nationale Superieure des Telecommunications, Paris |
2094 | S: France | 2094 | S: France |
2095 | 2095 | ||
2096 | N: Jamie Lokier | 2096 | N: Jamie Lokier |
2097 | E: jamie@shareable.org | 2097 | E: jamie@shareable.org |
2098 | W: http://www.shareable.org/ | 2098 | W: http://www.shareable.org/ |
2099 | D: Reboot-through-BIOS for broken 486 motherboards | 2099 | D: Reboot-through-BIOS for broken 486 motherboards |
2100 | D: Parport fixes, futex improvements | 2100 | D: Parport fixes, futex improvements |
2101 | D: First instruction of x86 sysenter path :) | 2101 | D: First instruction of x86 sysenter path :) |
2102 | S: 51 Sunningwell Road | 2102 | S: 51 Sunningwell Road |
2103 | S: Oxford | 2103 | S: Oxford |
2104 | S: OX1 4SZ | 2104 | S: OX1 4SZ |
2105 | S: United Kingdom | 2105 | S: United Kingdom |
2106 | 2106 | ||
2107 | N: Mark Lord | 2107 | N: Mark Lord |
2108 | E: mlord@pobox.com | 2108 | E: mlord@pobox.com |
2109 | D: EIDE driver, hd.c support | 2109 | D: EIDE driver, hd.c support |
2110 | D: EIDE PCI and bus-master DMA support | 2110 | D: EIDE PCI and bus-master DMA support |
2111 | D: Hard Disk Parameter (hdparm) utility | 2111 | D: Hard Disk Parameter (hdparm) utility |
2112 | S: 33 Ridgefield Cr | 2112 | S: 33 Ridgefield Cr |
2113 | S: Nepean, Ontario | 2113 | S: Nepean, Ontario |
2114 | S: Canada K2H 6S3 | 2114 | S: Canada K2H 6S3 |
2115 | 2115 | ||
2116 | N: Warner Losh | 2116 | N: Warner Losh |
2117 | E: imp@village.org | 2117 | E: imp@village.org |
2118 | D: Linux/MIPS Deskstation support, Provided OI/OB for Linux | 2118 | D: Linux/MIPS Deskstation support, Provided OI/OB for Linux |
2119 | S: 8786 Niwot Road | 2119 | S: 8786 Niwot Road |
2120 | S: Niwot, Colorado 80503 | 2120 | S: Niwot, Colorado 80503 |
2121 | S: USA | 2121 | S: USA |
2122 | 2122 | ||
2123 | N: Robert M. Love | 2123 | N: Robert M. Love |
2124 | E: rml@tech9.net | 2124 | E: rml@tech9.net |
2125 | E: rml@novell.com | 2125 | E: rml@novell.com |
2126 | D: misc. kernel hacking and debugging | 2126 | D: misc. kernel hacking and debugging |
2127 | S: Cambridge, MA 02139 | 2127 | S: Cambridge, MA 02139 |
2128 | S: USA | 2128 | S: USA |
2129 | 2129 | ||
2130 | N: Martin von Lรถwis | 2130 | N: Martin von Lรถwis |
2131 | E: loewis@informatik.hu-berlin.de | 2131 | E: loewis@informatik.hu-berlin.de |
2132 | D: script binary format | 2132 | D: script binary format |
2133 | D: NTFS driver | 2133 | D: NTFS driver |
2134 | 2134 | ||
2135 | N: H.J. Lu | 2135 | N: H.J. Lu |
2136 | E: hjl@gnu.ai.mit.edu | 2136 | E: hjl@gnu.ai.mit.edu |
2137 | D: GCC + libraries hacker | 2137 | D: GCC + libraries hacker |
2138 | 2138 | ||
2139 | N: Yanir Lubetkin | 2139 | N: Yanir Lubetkin |
2140 | E: yanirx.lubatkin@intel.com | 2140 | E: yanirx.lubatkin@intel.com |
2141 | E: linux-wimax@intel.com | 2141 | E: linux-wimax@intel.com |
2142 | D: Intel Wireless WiMAX Connection 2400 driver | 2142 | D: Intel Wireless WiMAX Connection 2400 driver |
2143 | 2143 | ||
2144 | N: Michal Ludvig | 2144 | N: Michal Ludvig |
2145 | E: michal@logix.cz | 2145 | E: michal@logix.cz |
2146 | E: michal.ludvig@asterisk.co.nz | 2146 | E: michal.ludvig@asterisk.co.nz |
2147 | W: http://www.logix.cz/michal | 2147 | W: http://www.logix.cz/michal |
2148 | P: 1024D/C45B2218 1162 6471 D391 76E0 9F99 29DA 0C3A 2509 C45B 2218 | 2148 | P: 1024D/C45B2218 1162 6471 D391 76E0 9F99 29DA 0C3A 2509 C45B 2218 |
2149 | D: VIA PadLock driver | 2149 | D: VIA PadLock driver |
2150 | D: Netfilter pkttype module | 2150 | D: Netfilter pkttype module |
2151 | S: Asterisk Ltd. | 2151 | S: Asterisk Ltd. |
2152 | S: Auckland | 2152 | S: Auckland |
2153 | S: New Zealand | 2153 | S: New Zealand |
2154 | 2154 | ||
2155 | N: Tuomas J. Lukka | 2155 | N: Tuomas J. Lukka |
2156 | E: Tuomas.Lukka@Helsinki.FI | 2156 | E: Tuomas.Lukka@Helsinki.FI |
2157 | D: Original dual-monitor patches | 2157 | D: Original dual-monitor patches |
2158 | D: Console-mouse-tracking patches | 2158 | D: Console-mouse-tracking patches |
2159 | S: Puistokaari 1 E 18 | 2159 | S: Puistokaari 1 E 18 |
2160 | S: 00200 Helsinki | 2160 | S: 00200 Helsinki |
2161 | S: Finland | 2161 | S: Finland |
2162 | 2162 | ||
2163 | N: Daniel J. Maas | 2163 | N: Daniel J. Maas |
2164 | E: dmaas@dcine.com | 2164 | E: dmaas@dcine.com |
2165 | W: http://www.maasdigital.com | 2165 | W: http://www.maasdigital.com |
2166 | D: dv1394 | 2166 | D: dv1394 |
2167 | 2167 | ||
2168 | N: Hamish Macdonald | 2168 | N: Hamish Macdonald |
2169 | E: hamishm@lucent.com | 2169 | E: hamishm@lucent.com |
2170 | D: Linux/68k port | 2170 | D: Linux/68k port |
2171 | S: 32 Clydesdale Avenue | 2171 | S: 32 Clydesdale Avenue |
2172 | S: Kanata, Ontario | 2172 | S: Kanata, Ontario |
2173 | S: Canada K2M-2G7 | 2173 | S: Canada K2M-2G7 |
2174 | 2174 | ||
2175 | N: Peter MacDonald | 2175 | N: Peter MacDonald |
2176 | D: SLS distribution | 2176 | D: SLS distribution |
2177 | D: Initial implementation of VC's, pty's and select() | 2177 | D: Initial implementation of VC's, pty's and select() |
2178 | 2178 | ||
2179 | N: Pavel Machek | 2179 | N: Pavel Machek |
2180 | E: pavel@ucw.cz | 2180 | E: pavel@ucw.cz |
2181 | D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd | 2181 | D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd |
2182 | D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB, | 2182 | D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB, |
2183 | D: work on suspend-to-ram/disk, killing duplicates from ioctl32 | 2183 | D: work on suspend-to-ram/disk, killing duplicates from ioctl32 |
2184 | S: Volkova 1131 | 2184 | S: Volkova 1131 |
2185 | S: 198 00 Praha 9 | 2185 | S: 198 00 Praha 9 |
2186 | S: Czech Republic | 2186 | S: Czech Republic |
2187 | 2187 | ||
2188 | N: Paul Mackerras | 2188 | N: Paul Mackerras |
2189 | E: paulus@samba.org | 2189 | E: paulus@samba.org |
2190 | D: PPP driver | 2190 | D: PPP driver |
2191 | D: Linux for PowerPC | 2191 | D: Linux for PowerPC |
2192 | D: Linux port for PCI Power Macintosh | 2192 | D: Linux port for PCI Power Macintosh |
2193 | 2193 | ||
2194 | N: Pat Mackinlay | 2194 | N: Pat Mackinlay |
2195 | E: pat@it.com.au | 2195 | E: pat@it.com.au |
2196 | D: 8 bit XT hard disk driver | 2196 | D: 8 bit XT hard disk driver |
2197 | D: Miscellaneous ST0x, TMC-8xx and other SCSI hacking | 2197 | D: Miscellaneous ST0x, TMC-8xx and other SCSI hacking |
2198 | S: 25 McMillan Street | 2198 | S: 25 McMillan Street |
2199 | S: Victoria Park 6100 | 2199 | S: Victoria Park 6100 |
2200 | S: Australia | 2200 | S: Australia |
2201 | 2201 | ||
2202 | N: James B. MacLean | 2202 | N: James B. MacLean |
2203 | E: macleajb@ednet.ns.ca | 2203 | E: macleajb@ednet.ns.ca |
2204 | W: http://www.ednet.ns.ca/~macleajb/dosemu.html | 2204 | W: http://www.ednet.ns.ca/~macleajb/dosemu.html |
2205 | D: Former Coordinator of DOSEMU releases | 2205 | D: Former Coordinator of DOSEMU releases |
2206 | D: Program in DOSEMU | 2206 | D: Program in DOSEMU |
2207 | S: PO BOX 220, HFX. CENTRAL | 2207 | S: PO BOX 220, HFX. CENTRAL |
2208 | S: Halifax, Nova Scotia | 2208 | S: Halifax, Nova Scotia |
2209 | S: Canada B3J 3C8 | 2209 | S: Canada B3J 3C8 |
2210 | 2210 | ||
2211 | N: Kai Mรคkisara | 2211 | N: Kai Mรคkisara |
2212 | E: Kai.Makisara@kolumbus.fi | 2212 | E: Kai.Makisara@kolumbus.fi |
2213 | D: SCSI Tape Driver | 2213 | D: SCSI Tape Driver |
2214 | 2214 | ||
2215 | N: Asit Mallick | 2215 | N: Asit Mallick |
2216 | E: asit.k.mallick@intel.com | 2216 | E: asit.k.mallick@intel.com |
2217 | D: Linux/IA-64 | 2217 | D: Linux/IA-64 |
2218 | S: 2200 Mission College Blvd | 2218 | S: 2200 Mission College Blvd |
2219 | S: Santa Clara, CA 95052 | 2219 | S: Santa Clara, CA 95052 |
2220 | S: USA | 2220 | S: USA |
2221 | 2221 | ||
2222 | N: Petko Manolov | 2222 | N: Petko Manolov |
2223 | E: petkan@users.sourceforge.net | 2223 | E: petkan@users.sourceforge.net |
2224 | D: USB ethernet pegasus/pegasus-II driver | 2224 | D: USB ethernet pegasus/pegasus-II driver |
2225 | D: USB ethernet rtl8150 driver | 2225 | D: USB ethernet rtl8150 driver |
2226 | D: optimizing i[45]86 string routines | 2226 | D: optimizing i[45]86 string routines |
2227 | D: i386 task switching hacks | 2227 | D: i386 task switching hacks |
2228 | S: 482 Shadowgraph Dr. | 2228 | S: 482 Shadowgraph Dr. |
2229 | S: San Jose, CA 95110 | 2229 | S: San Jose, CA 95110 |
2230 | S: USA | 2230 | S: USA |
2231 | 2231 | ||
2232 | N: Martin Mares | 2232 | N: Martin Mares |
2233 | E: mj@ucw.cz | 2233 | E: mj@ucw.cz |
2234 | W: http://www.ucw.cz/~mj/ | 2234 | W: http://www.ucw.cz/~mj/ |
2235 | D: BIOS video mode handling code | 2235 | D: BIOS video mode handling code |
2236 | D: MOXA C-218 serial board driver | 2236 | D: MOXA C-218 serial board driver |
2237 | D: Network autoconfiguration | 2237 | D: Network autoconfiguration |
2238 | D: PCI subsystem | 2238 | D: PCI subsystem |
2239 | D: Random kernel hacking | 2239 | D: Random kernel hacking |
2240 | S: Kankovskeho 1241 | 2240 | S: Kankovskeho 1241 |
2241 | S: 182 00 Praha 8 | 2241 | S: 182 00 Praha 8 |
2242 | S: Czech Republic | 2242 | S: Czech Republic |
2243 | 2243 | ||
2244 | N: John A. Martin | 2244 | N: John A. Martin |
2245 | E: jam@acm.org | 2245 | E: jam@acm.org |
2246 | W: http://www.tux.org/~jam/ | 2246 | W: http://www.tux.org/~jam/ |
2247 | P: 1024/04456D53 9D A3 6C 6B 88 80 8A 61 D7 06 22 4F 95 40 CE D2 | 2247 | P: 1024/04456D53 9D A3 6C 6B 88 80 8A 61 D7 06 22 4F 95 40 CE D2 |
2248 | P: 1024/3B986635 5A61 7EE6 9E20 51FB 59FB 2DA5 3E18 DD55 3B98 6635 | 2248 | P: 1024/3B986635 5A61 7EE6 9E20 51FB 59FB 2DA5 3E18 DD55 3B98 6635 |
2249 | D: FSSTND contributor | 2249 | D: FSSTND contributor |
2250 | D: Credit file compilator | 2250 | D: Credit file compilator |
2251 | 2251 | ||
2252 | N: Kevin E. Martin | 2252 | N: Kevin E. Martin |
2253 | E: martin@cs.unc.edu | 2253 | E: martin@cs.unc.edu |
2254 | D: Developed original accelerated X servers included in XFree86 | 2254 | D: Developed original accelerated X servers included in XFree86 |
2255 | D: XF86_Mach64 | 2255 | D: XF86_Mach64 |
2256 | D: XF86_Mach32 | 2256 | D: XF86_Mach32 |
2257 | D: XF86_Mach8 | 2257 | D: XF86_Mach8 |
2258 | D: XF86_8514 | 2258 | D: XF86_8514 |
2259 | D: cfdisk (curses based disk partitioning program) | 2259 | D: cfdisk (curses based disk partitioning program) |
2260 | 2260 | ||
2261 | N: John S. Marvin | 2261 | N: John S. Marvin |
2262 | E: jsm@fc.hp.com | 2262 | E: jsm@fc.hp.com |
2263 | D: PA-RISC port | 2263 | D: PA-RISC port |
2264 | S: Hewlett Packard | 2264 | S: Hewlett Packard |
2265 | S: MS 42 | 2265 | S: MS 42 |
2266 | S: 3404 E. Harmony Road | 2266 | S: 3404 E. Harmony Road |
2267 | S: Fort Collins, CO 80528 | 2267 | S: Fort Collins, CO 80528 |
2268 | S: USA | 2268 | S: USA |
2269 | 2269 | ||
2270 | N: Torben Mathiasen | 2270 | N: Torben Mathiasen |
2271 | E: torben.mathiasen@compaq.com | 2271 | E: torben.mathiasen@compaq.com |
2272 | E: torben@kernel.dk | 2272 | E: torben@kernel.dk |
2273 | W: http://tlan.kernel.dk | 2273 | W: http://tlan.kernel.dk |
2274 | D: ThunderLAN maintainer | 2274 | D: ThunderLAN maintainer |
2275 | D: ThunderLAN updates and other kernel fixes. | 2275 | D: ThunderLAN updates and other kernel fixes. |
2276 | S: Bremensgade 29, st.th | 2276 | S: Bremensgade 29, st.th |
2277 | S: 2300 Copenhagen S | 2277 | S: 2300 Copenhagen S |
2278 | S: Denmark | 2278 | S: Denmark |
2279 | 2279 | ||
2280 | N: Claudio S. Matsuoka | 2280 | N: Claudio S. Matsuoka |
2281 | E: cmatsuoka@gmail.com | 2281 | E: cmatsuoka@gmail.com |
2282 | E: claudio@mandriva.com | 2282 | E: claudio@mandriva.com |
2283 | W: http://helllabs.org/~claudio | 2283 | W: http://helllabs.org/~claudio |
2284 | D: V4L, OV511 and HDA-codec hacks | 2284 | D: V4L, OV511 and HDA-codec hacks |
2285 | S: Conectiva S.A. | 2285 | S: Conectiva S.A. |
2286 | S: Souza Naves 1250 | 2286 | S: Souza Naves 1250 |
2287 | S: 80050-040 Curitiba PR | 2287 | S: 80050-040 Curitiba PR |
2288 | S: Brazil | 2288 | S: Brazil |
2289 | 2289 | ||
2290 | N: Heinz Mauelshagen | 2290 | N: Heinz Mauelshagen |
2291 | E: mge@EZ-Darmstadt.Telekom.de | 2291 | E: mge@EZ-Darmstadt.Telekom.de |
2292 | D: Logical Volume Manager | 2292 | D: Logical Volume Manager |
2293 | S: Bartningstr. 12 | 2293 | S: Bartningstr. 12 |
2294 | S: 64289 Darmstadt | 2294 | S: 64289 Darmstadt |
2295 | S: Germany | 2295 | S: Germany |
2296 | 2296 | ||
2297 | N: Mark W. McClelland | 2297 | N: Mark W. McClelland |
2298 | E: mmcclell@bigfoot.com | 2298 | E: mmcclell@bigfoot.com |
2299 | E: mark@alpha.dyndns.org | 2299 | E: mark@alpha.dyndns.org |
2300 | W: http://alpha.dyndns.org/ov511/ | 2300 | W: http://alpha.dyndns.org/ov511/ |
2301 | P: 1024D/357375CC 317C 58AC 1B39 2AB0 AB96 EB38 0B6F 731F 3573 75CC | 2301 | P: 1024D/357375CC 317C 58AC 1B39 2AB0 AB96 EB38 0B6F 731F 3573 75CC |
2302 | D: OV511 driver | 2302 | D: OV511 driver |
2303 | S: (address available on request) | 2303 | S: (address available on request) |
2304 | S: USA | 2304 | S: USA |
2305 | 2305 | ||
2306 | N: Ian McDonald | 2306 | N: Ian McDonald |
2307 | E: ian.mcdonald@jandi.co.nz | 2307 | E: ian.mcdonald@jandi.co.nz |
2308 | E: imcdnzl@gmail.com | 2308 | E: imcdnzl@gmail.com |
2309 | W: http://wand.net.nz/~iam4 | 2309 | W: http://wand.net.nz/~iam4 |
2310 | W: http://imcdnzl.blogspot.com | 2310 | W: http://imcdnzl.blogspot.com |
2311 | D: DCCP, CCID3 | 2311 | D: DCCP, CCID3 |
2312 | S: Hamilton | 2312 | S: Hamilton |
2313 | S: New Zealand | 2313 | S: New Zealand |
2314 | 2314 | ||
2315 | N: Patrick McHardy | 2315 | N: Patrick McHardy |
2316 | E: kaber@trash.net | 2316 | E: kaber@trash.net |
2317 | P: 1024D/12155E80 B128 7DE6 FF0A C2B2 48BE AB4C C9D4 964E 1215 5E80 | 2317 | P: 1024D/12155E80 B128 7DE6 FF0A C2B2 48BE AB4C C9D4 964E 1215 5E80 |
2318 | D: netfilter: endless number of bugfixes | 2318 | D: netfilter: endless number of bugfixes |
2319 | D: netfilter: CLASSIFY target | 2319 | D: netfilter: CLASSIFY target |
2320 | D: netfilter: addrtype match | 2320 | D: netfilter: addrtype match |
2321 | D: tc: HFSC scheduler | 2321 | D: tc: HFSC scheduler |
2322 | S: Freiburg | 2322 | S: Freiburg |
2323 | S: Germany | 2323 | S: Germany |
2324 | 2324 | ||
2325 | N: Paul E. McKenney | 2325 | N: Paul E. McKenney |
2326 | E: paulmck@us.ibm.com | 2326 | E: paulmck@us.ibm.com |
2327 | W: http://www.rdrop.com/users/paulmck/ | 2327 | W: http://www.rdrop.com/users/paulmck/ |
2328 | D: RCU and variants | 2328 | D: RCU and variants |
2329 | D: rcutorture module | 2329 | D: rcutorture module |
2330 | 2330 | ||
2331 | N: Mike McLagan | 2331 | N: Mike McLagan |
2332 | E: mike.mclagan@linux.org | 2332 | E: mike.mclagan@linux.org |
2333 | W: http://www.invlogic.com/~mmclagan | 2333 | W: http://www.invlogic.com/~mmclagan |
2334 | D: DLCI/FRAD drivers for Sangoma SDLAs | 2334 | D: DLCI/FRAD drivers for Sangoma SDLAs |
2335 | S: Innovative Logic Corp | 2335 | S: Innovative Logic Corp |
2336 | S: Post Office Box 1068 | 2336 | S: Post Office Box 1068 |
2337 | S: Laurel, Maryland 20732 | 2337 | S: Laurel, Maryland 20732 |
2338 | S: USA | 2338 | S: USA |
2339 | 2339 | ||
2340 | N: Bradley McLean | 2340 | N: Bradley McLean |
2341 | E: brad@bradpc.gaylord.com | 2341 | E: brad@bradpc.gaylord.com |
2342 | D: Device driver hacker | 2342 | D: Device driver hacker |
2343 | D: General kernel debugger | 2343 | D: General kernel debugger |
2344 | S: 249 Nichols Avenue | 2344 | S: 249 Nichols Avenue |
2345 | S: Syracuse, New York 13206 | 2345 | S: Syracuse, New York 13206 |
2346 | S: USA | 2346 | S: USA |
2347 | 2347 | ||
2348 | N: Kyle McMartin | 2348 | N: Kyle McMartin |
2349 | E: kyle@parisc-linux.org | 2349 | E: kyle@parisc-linux.org |
2350 | D: Linux/PARISC hacker | 2350 | D: Linux/PARISC hacker |
2351 | D: AD1889 sound driver | 2351 | D: AD1889 sound driver |
2352 | S: Ottawa, Canada | 2352 | S: Ottawa, Canada |
2353 | 2353 | ||
2354 | N: Dirk Melchers | 2354 | N: Dirk Melchers |
2355 | E: dirk@merlin.nbg.sub.org | 2355 | E: dirk@merlin.nbg.sub.org |
2356 | D: 8 bit XT hard disk driver for OMTI5520 | 2356 | D: 8 bit XT hard disk driver for OMTI5520 |
2357 | S: Schloessleinsgasse 31 | 2357 | S: Schloessleinsgasse 31 |
2358 | S: D-90453 Nuernberg | 2358 | S: D-90453 Nuernberg |
2359 | S: Germany | 2359 | S: Germany |
2360 | 2360 | ||
2361 | N: Arnaldo Carvalho de Melo | 2361 | N: Arnaldo Carvalho de Melo |
2362 | E: acme@ghostprotocols.net | 2362 | E: acme@ghostprotocols.net |
2363 | E: arnaldo.melo@gmail.com | 2363 | E: arnaldo.melo@gmail.com |
2364 | E: acme@redhat.com | 2364 | E: acme@redhat.com |
2365 | W: http://oops.ghostprotocols.net:81/blog/ | 2365 | W: http://oops.ghostprotocols.net:81/blog/ |
2366 | P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01 | 2366 | P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01 |
2367 | D: IPX, LLC, DCCP, cyc2x, wl3501_cs, net/ hacks | 2367 | D: IPX, LLC, DCCP, cyc2x, wl3501_cs, net/ hacks |
2368 | S: R. Brasรญlio Itiberรช, 4270/1010 - รgua Verde | 2368 | S: R. Brasรญlio Itiberรช, 4270/1010 - รgua Verde |
2369 | S: 80240-060 - Curitiba - Paranรก | 2369 | S: 80240-060 - Curitiba - Paranรก |
2370 | S: Brazil | 2370 | S: Brazil |
2371 | 2371 | ||
2372 | N: Karsten Merker | 2372 | N: Karsten Merker |
2373 | E: merker@linuxtag.org | 2373 | E: merker@linuxtag.org |
2374 | D: DECstation framebuffer drivers | 2374 | D: DECstation framebuffer drivers |
2375 | S: Germany | 2375 | S: Germany |
2376 | 2376 | ||
2377 | N: Michael Meskes | 2377 | N: Michael Meskes |
2378 | E: meskes@debian.org | 2378 | E: meskes@debian.org |
2379 | P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03 AB AB 15 A3 AE AD 39 7D | 2379 | P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03 AB AB 15 A3 AE AD 39 7D |
2380 | D: Kernel hacker. PostgreSQL hacker. Software watchdog daemon. | 2380 | D: Kernel hacker. PostgreSQL hacker. Software watchdog daemon. |
2381 | D: Maintainer of several Debian packages | 2381 | D: Maintainer of several Debian packages |
2382 | S: Th.-Heuss-Str. 61 | 2382 | S: Th.-Heuss-Str. 61 |
2383 | S: D-41812 Erkelenz | 2383 | S: D-41812 Erkelenz |
2384 | S: Germany | 2384 | S: Germany |
2385 | 2385 | ||
2386 | N: Nigel Metheringham | 2386 | N: Nigel Metheringham |
2387 | E: Nigel.Metheringham@ThePLAnet.net | 2387 | E: Nigel.Metheringham@ThePLAnet.net |
2388 | P: 1024/31455639 B7 99 BD B8 00 17 BD 46 C1 15 B8 AB 87 BC 25 FA | 2388 | P: 1024/31455639 B7 99 BD B8 00 17 BD 46 C1 15 B8 AB 87 BC 25 FA |
2389 | D: IP Masquerading work and minor fixes | 2389 | D: IP Masquerading work and minor fixes |
2390 | S: Planet Online | 2390 | S: Planet Online |
2391 | S: The White House, Melbourne Street, LEEDS | 2391 | S: The White House, Melbourne Street, LEEDS |
2392 | S: LS2 7PS, United Kingdom | 2392 | S: LS2 7PS, United Kingdom |
2393 | 2393 | ||
2394 | N: Craig Metz | 2394 | N: Craig Metz |
2395 | E: cmetz@inner.net | 2395 | E: cmetz@inner.net |
2396 | D: Some of PAS 16 mixer & PCM support, inet6-apps | 2396 | D: Some of PAS 16 mixer & PCM support, inet6-apps |
2397 | 2397 | ||
2398 | N: William (Bill) Metzenthen | 2398 | N: William (Bill) Metzenthen |
2399 | E: billm@suburbia.net | 2399 | E: billm@suburbia.net |
2400 | D: Author of the FPU emulator. | 2400 | D: Author of the FPU emulator. |
2401 | D: Minor kernel hacker for other lost causes (Hercules mono, etc). | 2401 | D: Minor kernel hacker for other lost causes (Hercules mono, etc). |
2402 | S: 22 Parker Street | 2402 | S: 22 Parker Street |
2403 | S: Ormond | 2403 | S: Ormond |
2404 | S: Victoria 3163 | 2404 | S: Victoria 3163 |
2405 | S: Australia | 2405 | S: Australia |
2406 | 2406 | ||
2407 | N: Pauline Middelink | 2407 | N: Pauline Middelink |
2408 | E: middelin@polyware.nl | 2408 | E: middelin@polyware.nl |
2409 | D: General low-level bug fixes, /proc fixes, identd support | 2409 | D: General low-level bug fixes, /proc fixes, identd support |
2410 | D: Author of IP masquerading | 2410 | D: Author of IP masquerading |
2411 | D: Zoran ZR36120 Video For Linux driver | 2411 | D: Zoran ZR36120 Video For Linux driver |
2412 | S: Boterkorfhoek 34 | 2412 | S: Boterkorfhoek 34 |
2413 | S: 7546 JA Enschede | 2413 | S: 7546 JA Enschede |
2414 | S: Netherlands | 2414 | S: Netherlands |
2415 | 2415 | ||
2416 | N: David S. Miller | 2416 | N: David S. Miller |
2417 | E: davem@davemloft.net | 2417 | E: davem@davemloft.net |
2418 | D: Sparc and blue box hacker | 2418 | D: Sparc and blue box hacker |
2419 | D: Vger Linux mailing list co-maintainer | 2419 | D: Vger Linux mailing list co-maintainer |
2420 | D: Linux Emacs elf/qmagic support + other libc/gcc things | 2420 | D: Linux Emacs elf/qmagic support + other libc/gcc things |
2421 | D: Yee bore de yee bore! ;-) | 2421 | D: Yee bore de yee bore! ;-) |
2422 | S: 575 Harrison St. #103 | 2422 | S: 575 Harrison St. #103 |
2423 | S: San Francisco, CA 94105 | 2423 | S: San Francisco, CA 94105 |
2424 | S: USA | 2424 | S: USA |
2425 | 2425 | ||
2426 | N: Rick Miller | 2426 | N: Rick Miller |
2427 | E: rdmiller@execpc.com | 2427 | E: rdmiller@execpc.com |
2428 | W: http://www.execpc.com/~rdmiller/ | 2428 | W: http://www.execpc.com/~rdmiller/ |
2429 | D: Original Linux Device Registrar (Major/minor numbers) | 2429 | D: Original Linux Device Registrar (Major/minor numbers) |
2430 | D: au-play, bwBASIC | 2430 | D: au-play, bwBASIC |
2431 | S: S78 W16203 Woods Road | 2431 | S: S78 W16203 Woods Road |
2432 | S: Muskego, Wisconsin 53150 | 2432 | S: Muskego, Wisconsin 53150 |
2433 | S: USA | 2433 | S: USA |
2434 | 2434 | ||
2435 | N: Harald Milz | 2435 | N: Harald Milz |
2436 | E: hm@seneca.linux.de | 2436 | E: hm@seneca.linux.de |
2437 | D: Linux Projects Map, Linux Commercial-HOWTO | 2437 | D: Linux Projects Map, Linux Commercial-HOWTO |
2438 | D: general Linux publicity in Germany, vacation port | 2438 | D: general Linux publicity in Germany, vacation port |
2439 | D: UUCP and CNEWS binary packages for LST | 2439 | D: UUCP and CNEWS binary packages for LST |
2440 | S: Editorial Board iX Mag | 2440 | S: Editorial Board iX Mag |
2441 | S: Helstorfer Str. 7 | 2441 | S: Helstorfer Str. 7 |
2442 | S: D-30625 Hannover | 2442 | S: D-30625 Hannover |
2443 | S: Germany | 2443 | S: Germany |
2444 | 2444 | ||
2445 | N: Corey Minyard | 2445 | N: Corey Minyard |
2446 | E: minyard@wf-rch.cirr.com | 2446 | E: minyard@wf-rch.cirr.com |
2447 | E: minyard@mvista.com | 2447 | E: minyard@mvista.com |
2448 | W: http://home.attbi.com/~minyard | 2448 | W: http://home.attbi.com/~minyard |
2449 | D: Sony CDU31A CDROM Driver | 2449 | D: Sony CDU31A CDROM Driver |
2450 | D: IPMI driver | 2450 | D: IPMI driver |
2451 | D: Various networking fixes long ago | 2451 | D: Various networking fixes long ago |
2452 | D: Original ppc_md work | 2452 | D: Original ppc_md work |
2453 | D: Shared zlib | 2453 | D: Shared zlib |
2454 | S: 7406 Wheat Field Rd | 2454 | S: 7406 Wheat Field Rd |
2455 | S: Garland, Texas 75044 | 2455 | S: Garland, Texas 75044 |
2456 | S: USA | 2456 | S: USA |
2457 | 2457 | ||
2458 | N: Kazunori Miyazawa | 2458 | N: Kazunori Miyazawa |
2459 | E: miyazawa@linux-ipv6.org | 2459 | E: miyazawa@linux-ipv6.org |
2460 | E: Kazunori.Miyazawa@jp.yokogawa.com | 2460 | E: Kazunori.Miyazawa@jp.yokogawa.com |
2461 | E: kazunori@miyazawa.org | 2461 | E: kazunori@miyazawa.org |
2462 | W: http://www.miyazawa.org/~kazunori/ | 2462 | W: http://www.miyazawa.org/~kazunori/ |
2463 | D: IPsec, IPv6 | 2463 | D: IPsec, IPv6 |
2464 | D: USAGI/WIDE Project, Yokogawa Electric Corporation | 2464 | D: USAGI/WIDE Project, Yokogawa Electric Corporation |
2465 | S: 2-20-4-203, Nakacho, | 2465 | S: 2-20-4-203, Nakacho, |
2466 | S: Musashino, Tokyo 180-0006 | 2466 | S: Musashino, Tokyo 180-0006 |
2467 | S: Japan | 2467 | S: Japan |
2468 | 2468 | ||
2469 | N: Patrick Mochel | 2469 | N: Patrick Mochel |
2470 | E: mochel@osdl.org | 2470 | E: mochel@osdl.org |
2471 | E: mochelp@infinity.powertie.org | 2471 | E: mochelp@infinity.powertie.org |
2472 | D: PCI Power Management, ACPI work | 2472 | D: PCI Power Management, ACPI work |
2473 | S: 12725 SW Millikan Way, Suite 400 | 2473 | S: 12725 SW Millikan Way, Suite 400 |
2474 | S: Beaverton, Oregon 97005 | 2474 | S: Beaverton, Oregon 97005 |
2475 | S: USA | 2475 | S: USA |
2476 | 2476 | ||
2477 | N: Eberhard Mรถnkeberg | 2477 | N: Eberhard Mรถnkeberg |
2478 | E: emoenke@gwdg.de | 2478 | E: emoenke@gwdg.de |
2479 | D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster) | 2479 | D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster) |
2480 | S: Ruhstrathรถhe 2 b. | 2480 | S: Ruhstrathรถhe 2 b. |
2481 | S: D-37085 Gรถttingen | 2481 | S: D-37085 Gรถttingen |
2482 | S: Germany | 2482 | S: Germany |
2483 | 2483 | ||
2484 | N: Thomas Molina | 2484 | N: Thomas Molina |
2485 | E: tmolina@cablespeed.com | 2485 | E: tmolina@cablespeed.com |
2486 | D: bug fixes, documentation, minor hackery | 2486 | D: bug fixes, documentation, minor hackery |
2487 | 2487 | ||
2488 | N: Paul Moore | 2488 | N: Paul Moore |
2489 | E: paul.moore@hp.com | 2489 | E: paul.moore@hp.com |
2490 | D: NetLabel author | 2490 | D: NetLabel author |
2491 | S: Hewlett-Packard | 2491 | S: Hewlett-Packard |
2492 | S: 110 Spit Brook Road | 2492 | S: 110 Spit Brook Road |
2493 | S: Nashua, NH 03062 | 2493 | S: Nashua, NH 03062 |
2494 | 2494 | ||
2495 | N: James Morris | 2495 | N: James Morris |
2496 | E: jmorris@namei.org | 2496 | E: jmorris@namei.org |
2497 | W: http://namei.org/ | 2497 | W: http://namei.org/ |
2498 | D: Netfilter, Linux Security Modules (LSM), SELinux, IPSec, | 2498 | D: Netfilter, Linux Security Modules (LSM), SELinux, IPSec, |
2499 | D: Crypto API, general networking, miscellaneous. | 2499 | D: Crypto API, general networking, miscellaneous. |
2500 | S: PO Box 707 | 2500 | S: PO Box 707 |
2501 | S: Spit Junction NSW 2088 | 2501 | S: Spit Junction NSW 2088 |
2502 | S: Australia | 2502 | S: Australia |
2503 | 2503 | ||
2504 | N: David Mosberger-Tang | 2504 | N: David Mosberger-Tang |
2505 | E: davidm@hpl.hp.com if IA-64 related, else David.Mosberger@acm.org | 2505 | E: davidm@hpl.hp.com if IA-64 related, else David.Mosberger@acm.org |
2506 | D: Linux/Alpha and Linux/ia64 | 2506 | D: Linux/Alpha and Linux/ia64 |
2507 | S: 35706 Runckel Lane | 2507 | S: 35706 Runckel Lane |
2508 | S: Fremont, California 94536 | 2508 | S: Fremont, California 94536 |
2509 | S: USA | 2509 | S: USA |
2510 | 2510 | ||
2511 | N: Sam Mosel | 2511 | N: Sam Mosel |
2512 | E: sam.mosel@computer.org | 2512 | E: sam.mosel@computer.org |
2513 | D: Wacom Intuos USB Support | 2513 | D: Wacom Intuos USB Support |
2514 | S: 22 Seaview St | 2514 | S: 22 Seaview St |
2515 | S: Fullarton 5063 | 2515 | S: Fullarton 5063 |
2516 | S: South Australia | 2516 | S: South Australia |
2517 | 2517 | ||
2518 | N. Wolfgang Muees | 2518 | N. Wolfgang Muees |
2519 | E: wolfgang@iksw-muees.de | 2519 | E: wolfgang@iksw-muees.de |
2520 | D: Auerswald USB driver | 2520 | D: Auerswald USB driver |
2521 | 2521 | ||
2522 | N: Ian A. Murdock | 2522 | N: Ian A. Murdock |
2523 | E: imurdock@gnu.ai.mit.edu | 2523 | E: imurdock@gnu.ai.mit.edu |
2524 | D: Creator of Debian distribution | 2524 | D: Creator of Debian distribution |
2525 | S: 30 White Tail Lane | 2525 | S: 30 White Tail Lane |
2526 | S: Lafayette, Indiana 47905 | 2526 | S: Lafayette, Indiana 47905 |
2527 | S: USA | 2527 | S: USA |
2528 | 2528 | ||
2529 | N: Scott Murray | 2529 | N: Scott Murray |
2530 | E: scottm@somanetworks.com | 2530 | E: scottm@somanetworks.com |
2531 | E: scott@spiteful.org | 2531 | E: scott@spiteful.org |
2532 | D: OPL3-SA2, OPL3-SA3 sound driver | 2532 | D: OPL3-SA2, OPL3-SA3 sound driver |
2533 | D: CompactPCI hotplug core | 2533 | D: CompactPCI hotplug core |
2534 | D: Ziatech ZT5550 and generic CompactPCI hotplug drivers | 2534 | D: Ziatech ZT5550 and generic CompactPCI hotplug drivers |
2535 | S: Toronto, Ontario | 2535 | S: Toronto, Ontario |
2536 | S: Canada | 2536 | S: Canada |
2537 | 2537 | ||
2538 | N: Zwane Mwaikambo | 2538 | N: Zwane Mwaikambo |
2539 | E: zwane@arm.linux.org.uk | 2539 | E: zwane@arm.linux.org.uk |
2540 | D: Various driver hacking | 2540 | D: Various driver hacking |
2541 | D: Lowlevel x86 kernel hacking | 2541 | D: Lowlevel x86 kernel hacking |
2542 | D: General debugging | 2542 | D: General debugging |
2543 | S: (ask for current address) | 2543 | S: (ask for current address) |
2544 | S: Tanzania | 2544 | S: Tanzania |
2545 | 2545 | ||
2546 | N: Trond Myklebust | 2546 | N: Trond Myklebust |
2547 | E: trond.myklebust@fys.uio.no | 2547 | E: trond.myklebust@fys.uio.no |
2548 | D: current NFS client hacker. | 2548 | D: current NFS client hacker. |
2549 | S: Dagaliveien 31e | 2549 | S: Dagaliveien 31e |
2550 | S: N-0391 Oslo | 2550 | S: N-0391 Oslo |
2551 | S: Norway | 2551 | S: Norway |
2552 | 2552 | ||
2553 | N: Johan Myreen | 2553 | N: Johan Myreen |
2554 | E: jem@iki.fi | 2554 | E: jem@iki.fi |
2555 | D: PS/2 mouse driver writer etc. | 2555 | D: PS/2 mouse driver writer etc. |
2556 | S: Dragonvagen 1 A 13 | 2556 | S: Dragonvagen 1 A 13 |
2557 | S: FIN-00330 Helsingfors | 2557 | S: FIN-00330 Helsingfors |
2558 | S: Finland | 2558 | S: Finland |
2559 | 2559 | ||
2560 | N: Matija Nalis | 2560 | N: Matija Nalis |
2561 | E: mnalis@jagor.srce.hr | 2561 | E: mnalis@jagor.srce.hr |
2562 | E: mnalis@voyager.hr | 2562 | E: mnalis@voyager.hr |
2563 | D: Maintainer of the Umsdos file system | 2563 | D: Maintainer of the Umsdos file system |
2564 | S: Listopadska 7 | 2564 | S: Listopadska 7 |
2565 | S: 10000 Zagreb | 2565 | S: 10000 Zagreb |
2566 | S: Croatia | 2566 | S: Croatia |
2567 | 2567 | ||
2568 | N: Jonathan Naylor | 2568 | N: Jonathan Naylor |
2569 | E: g4klx@g4klx.demon.co.uk | 2569 | E: g4klx@g4klx.demon.co.uk |
2570 | E: g4klx@amsat.org | 2570 | E: g4klx@amsat.org |
2571 | W: http://zone.pspt.fi/~jsn/ | 2571 | W: http://zone.pspt.fi/~jsn/ |
2572 | D: AX.25, NET/ROM and ROSE amateur radio protocol suites | 2572 | D: AX.25, NET/ROM and ROSE amateur radio protocol suites |
2573 | D: CCITT X.25 PLP and LAPB. | 2573 | D: CCITT X.25 PLP and LAPB. |
2574 | S: 24 Castle View Drive | 2574 | S: 24 Castle View Drive |
2575 | S: Cromford | 2575 | S: Cromford |
2576 | S: Matlock | 2576 | S: Matlock |
2577 | S: Derbyshire DE4 3RL | 2577 | S: Derbyshire DE4 3RL |
2578 | S: United Kingdom | 2578 | S: United Kingdom |
2579 | 2579 | ||
2580 | N: Ian S. Nelson | 2580 | N: Ian S. Nelson |
2581 | E: nelsonis@earthlink.net | 2581 | E: nelsonis@earthlink.net |
2582 | P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6 9E97 576F 1B97 00D3 D983 | 2582 | P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6 9E97 576F 1B97 00D3 D983 |
2583 | D: Minor mmap and ide hacks | 2583 | D: Minor mmap and ide hacks |
2584 | S: 1370 Atlantis Ave. | 2584 | S: 1370 Atlantis Ave. |
2585 | S: Lafayette CO, 80026 | 2585 | S: Lafayette CO, 80026 |
2586 | S: USA | 2586 | S: USA |
2587 | 2587 | ||
2588 | N: Russell Nelson | 2588 | N: Russell Nelson |
2589 | E: nelson@crynwr.com | 2589 | E: nelson@crynwr.com |
2590 | W: http://www.crynwr.com/~nelson | 2590 | W: http://www.crynwr.com/~nelson |
2591 | P: 1024/83942741 FF 68 EE 27 A0 5A AA C3 F5 DC 05 62 BD 5B 20 2F | 2591 | P: 1024/83942741 FF 68 EE 27 A0 5A AA C3 F5 DC 05 62 BD 5B 20 2F |
2592 | D: Author of cs89x0, maintainer of kernel changelog through 1.3.3 | 2592 | D: Author of cs89x0, maintainer of kernel changelog through 1.3.3 |
2593 | D: Wrote many packet drivers, from which some Ethernet drivers are derived. | 2593 | D: Wrote many packet drivers, from which some Ethernet drivers are derived. |
2594 | S: 521 Pleasant Valley Road | 2594 | S: 521 Pleasant Valley Road |
2595 | S: Potsdam, New York 13676 | 2595 | S: Potsdam, New York 13676 |
2596 | S: USA | 2596 | S: USA |
2597 | 2597 | ||
2598 | N: Dave Neuer | 2598 | N: Dave Neuer |
2599 | E: dave.neuer@pobox.com | 2599 | E: dave.neuer@pobox.com |
2600 | D: Helped implement support for Compaq's H31xx series iPAQs | 2600 | D: Helped implement support for Compaq's H31xx series iPAQs |
2601 | D: Other mostly minor tweaks & bugfixes | 2601 | D: Other mostly minor tweaks & bugfixes |
2602 | 2602 | ||
2603 | N: Michael Neuffer | 2603 | N: Michael Neuffer |
2604 | E: mike@i-Connect.Net | 2604 | E: mike@i-Connect.Net |
2605 | E: neuffer@goofy.zdv.uni-mainz.de | 2605 | E: neuffer@goofy.zdv.uni-mainz.de |
2606 | W: http://www.i-Connect.Net/~mike/ | 2606 | W: http://www.i-Connect.Net/~mike/ |
2607 | D: Developer and maintainer of the EATA-DMA SCSI driver | 2607 | D: Developer and maintainer of the EATA-DMA SCSI driver |
2608 | D: Co-developer EATA-PIO SCSI driver | 2608 | D: Co-developer EATA-PIO SCSI driver |
2609 | D: /proc/scsi and assorted other snippets | 2609 | D: /proc/scsi and assorted other snippets |
2610 | S: Zum Schiersteiner Grund 2 | 2610 | S: Zum Schiersteiner Grund 2 |
2611 | S: 55127 Mainz | 2611 | S: 55127 Mainz |
2612 | S: Germany | 2612 | S: Germany |
2613 | 2613 | ||
2614 | N: Gustavo Niemeyer | 2614 | N: Gustavo Niemeyer |
2615 | E: niemeyer@conectiva.com | 2615 | E: niemeyer@conectiva.com |
2616 | W: https://moin.conectiva.com.br/GustavoNiemeyer | 2616 | W: https://moin.conectiva.com.br/GustavoNiemeyer |
2617 | D: wl3501 PCMCIA wireless card initial support for wireless extensions in 2.4 | 2617 | D: wl3501 PCMCIA wireless card initial support for wireless extensions in 2.4 |
2618 | S: Conectiva S.A. | 2618 | S: Conectiva S.A. |
2619 | S: R. Tocantins 89 | 2619 | S: R. Tocantins 89 |
2620 | S: 80050-430 Curitiba PR | 2620 | S: 80050-430 Curitiba PR |
2621 | S: Brazil | 2621 | S: Brazil |
2622 | 2622 | ||
2623 | N: David C. Niemi | 2623 | N: David C. Niemi |
2624 | E: niemi@tux.org | 2624 | E: niemi@tux.org |
2625 | W: http://www.tux.org/~niemi/ | 2625 | W: http://www.tux.org/~niemi/ |
2626 | D: Assistant maintainer of Mtools, fdutils, and floppy driver | 2626 | D: Assistant maintainer of Mtools, fdutils, and floppy driver |
2627 | D: Administrator of Tux.Org Linux Server, http://www.tux.org | 2627 | D: Administrator of Tux.Org Linux Server, http://www.tux.org |
2628 | S: 2364 Old Trail Drive | 2628 | S: 2364 Old Trail Drive |
2629 | S: Reston, Virginia 20191 | 2629 | S: Reston, Virginia 20191 |
2630 | S: USA | 2630 | S: USA |
2631 | 2631 | ||
2632 | N: Fredrik Noring | 2632 | N: Fredrik Noring |
2633 | E: noring@nocrew.org | 2633 | E: noring@nocrew.org |
2634 | W: http://www.lysator.liu.se/~noring/ | 2634 | W: http://www.lysator.liu.se/~noring/ |
2635 | D: dsp56k device driver | 2635 | D: dsp56k device driver |
2636 | 2636 | ||
2637 | N: Michael O'Reilly | 2637 | N: Michael O'Reilly |
2638 | E: michael@iinet.com.au | 2638 | E: michael@iinet.com.au |
2639 | E: oreillym@tartarus.uwa.edu.au | 2639 | E: oreillym@tartarus.uwa.edu.au |
2640 | D: Wrote the original dynamic sized disk cache stuff. I think the only | 2640 | D: Wrote the original dynamic sized disk cache stuff. I think the only |
2641 | D: part that remains is the GFP_KERNEL et al #defines. :) | 2641 | D: part that remains is the GFP_KERNEL et al #defines. :) |
2642 | S: 192 Nichsolson Road | 2642 | S: 192 Nichsolson Road |
2643 | S: Subiaco, 6008 | 2643 | S: Subiaco, 6008 |
2644 | S: Perth, Western Australia | 2644 | S: Perth, Western Australia |
2645 | S: Australia | 2645 | S: Australia |
2646 | 2646 | ||
2647 | N: Miguel Ojeda Sandonis | 2647 | N: Miguel Ojeda Sandonis |
2648 | E: miguel.ojeda.sandonis@gmail.com | 2648 | E: miguel.ojeda.sandonis@gmail.com |
2649 | W: http://miguelojeda.es | 2649 | W: http://miguelojeda.es |
2650 | W: http://jair.lab.fi.uva.es/~migojed/ | 2650 | W: http://jair.lab.fi.uva.es/~migojed/ |
2651 | D: Author of the ks0108, cfag12864b and cfag12864bfb auxiliary display drivers. | 2651 | D: Author of the ks0108, cfag12864b and cfag12864bfb auxiliary display drivers. |
2652 | D: Maintainer of the auxiliary display drivers tree (drivers/auxdisplay/*) | 2652 | D: Maintainer of the auxiliary display drivers tree (drivers/auxdisplay/*) |
2653 | S: C/ Mieses 20, 9-B | 2653 | S: C/ Mieses 20, 9-B |
2654 | S: Valladolid 47009 | 2654 | S: Valladolid 47009 |
2655 | S: Spain | 2655 | S: Spain |
2656 | 2656 | ||
2657 | N: Gadi Oxman | 2657 | N: Gadi Oxman |
2658 | E: gadio@netvision.net.il | 2658 | E: gadio@netvision.net.il |
2659 | D: Original author and maintainer of IDE/ATAPI floppy/tape drivers | 2659 | D: Original author and maintainer of IDE/ATAPI floppy/tape drivers |
2660 | 2660 | ||
2661 | N: Greg Page | 2661 | N: Greg Page |
2662 | E: gpage@sovereign.org | 2662 | E: gpage@sovereign.org |
2663 | D: IPX development and support | 2663 | D: IPX development and support |
2664 | 2664 | ||
2665 | N: David Parsons | 2665 | N: David Parsons |
2666 | E: orc@pell.chi.il.us | 2666 | E: orc@pell.chi.il.us |
2667 | D: improved memory detection code. | 2667 | D: improved memory detection code. |
2668 | 2668 | ||
2669 | N: Ivan Passos | 2669 | N: Ivan Passos |
2670 | E: ivan@cyclades.com | 2670 | E: ivan@cyclades.com |
2671 | D: Author of the Cyclades-PC300 synchronous card driver | 2671 | D: Author of the Cyclades-PC300 synchronous card driver |
2672 | D: Maintainer of the Cyclom-Y/Cyclades-Z asynchronous card driver | 2672 | D: Maintainer of the Cyclom-Y/Cyclades-Z asynchronous card driver |
2673 | S: Cyclades Corp | 2673 | S: Cyclades Corp |
2674 | S: 41934 Christy St | 2674 | S: 41934 Christy St |
2675 | S: Fremont, CA 94538 | 2675 | S: Fremont, CA 94538 |
2676 | S: USA | 2676 | S: USA |
2677 | 2677 | ||
2678 | N: Mikulas Patocka | 2678 | N: Mikulas Patocka |
2679 | E: mikulas@artax.karlin.mff.cuni.cz | 2679 | E: mikulas@artax.karlin.mff.cuni.cz |
2680 | W: http://artax.karlin.mff.cuni.cz/~mikulas/ | 2680 | W: http://artax.karlin.mff.cuni.cz/~mikulas/ |
2681 | P: 1024/BB11D2D5 A0 F1 28 4A C4 14 1E CF 92 58 7A 8F 69 BC A4 D3 | 2681 | P: 1024/BB11D2D5 A0 F1 28 4A C4 14 1E CF 92 58 7A 8F 69 BC A4 D3 |
2682 | D: Read/write HPFS filesystem | 2682 | D: Read/write HPFS filesystem |
2683 | S: Weissova 8 | 2683 | S: Weissova 8 |
2684 | S: 644 00 Brno | 2684 | S: 644 00 Brno |
2685 | S: Czech Republic | 2685 | S: Czech Republic |
2686 | 2686 | ||
2687 | N: Vojtech Pavlik | 2687 | N: Vojtech Pavlik |
2688 | E: vojtech@suse.cz | 2688 | E: vojtech@suse.cz |
2689 | D: Joystick driver | 2689 | D: Joystick driver |
2690 | D: arcnet-hardware readme | 2690 | D: arcnet-hardware readme |
2691 | D: Minor ARCnet hacking | 2691 | D: Minor ARCnet hacking |
2692 | D: USB (HID, ACM, Printer ...) | 2692 | D: USB (HID, ACM, Printer ...) |
2693 | S: Ucitelska 1576 | 2693 | S: Ucitelska 1576 |
2694 | S: Prague 8 | 2694 | S: Prague 8 |
2695 | S: 182 00 Czech Republic | 2695 | S: 182 00 Czech Republic |
2696 | 2696 | ||
2697 | N: Rick Payne | 2697 | N: Rick Payne |
2698 | D: RFC2385 Support for TCP | 2698 | D: RFC2385 Support for TCP |
2699 | 2699 | ||
2700 | N: Barak A. Pearlmutter | 2700 | N: Barak A. Pearlmutter |
2701 | E: bap@cs.unm.edu | 2701 | E: bap@cs.unm.edu |
2702 | W: http://www.cs.unm.edu/~bap/ | 2702 | W: http://www.cs.unm.edu/~bap/ |
2703 | P: 512/602D785D 9B A1 83 CD EE CB AD 93 20 C6 4C B7 F5 E9 60 D4 | 2703 | P: 512/602D785D 9B A1 83 CD EE CB AD 93 20 C6 4C B7 F5 E9 60 D4 |
2704 | D: Author of mark-and-sweep GC integrated by Alan Cox | 2704 | D: Author of mark-and-sweep GC integrated by Alan Cox |
2705 | S: Computer Science Department | 2705 | S: Computer Science Department |
2706 | S: FEC 313 | 2706 | S: FEC 313 |
2707 | S: University of New Mexico | 2707 | S: University of New Mexico |
2708 | S: Albuquerque, New Mexico 87131 | 2708 | S: Albuquerque, New Mexico 87131 |
2709 | S: USA | 2709 | S: USA |
2710 | 2710 | ||
2711 | N: Avery Pennarun | 2711 | N: Avery Pennarun |
2712 | E: apenwarr@worldvisions.ca | 2712 | E: apenwarr@worldvisions.ca |
2713 | W: http://www.worldvisions.ca/~apenwarr/ | 2713 | W: http://www.worldvisions.ca/~apenwarr/ |
2714 | D: ARCnet driver | 2714 | D: ARCnet driver |
2715 | D: "make xconfig" improvements | 2715 | D: "make xconfig" improvements |
2716 | D: Various minor hacking | 2716 | D: Various minor hacking |
2717 | S: RR #5, 497 Pole Line Road | 2717 | S: RR #5, 497 Pole Line Road |
2718 | S: Thunder Bay, Ontario | 2718 | S: Thunder Bay, Ontario |
2719 | S: CANADA P7C 5M9 | 2719 | S: CANADA P7C 5M9 |
2720 | 2720 | ||
2721 | N: Inaky Perez-Gonzalez | 2721 | N: Inaky Perez-Gonzalez |
2722 | E: inaky.perez-gonzalez@intel.com | 2722 | E: inaky.perez-gonzalez@intel.com |
2723 | E: linux-wimax@intel.com | 2723 | E: linux-wimax@intel.com |
2724 | E: inakypg@yahoo.com | 2724 | E: inakypg@yahoo.com |
2725 | D: WiMAX stack | 2725 | D: WiMAX stack |
2726 | D: Intel Wireless WiMAX Connection 2400 driver | 2726 | D: Intel Wireless WiMAX Connection 2400 driver |
2727 | 2727 | ||
2728 | N: Yuri Per | 2728 | N: Yuri Per |
2729 | E: yuri@pts.mipt.ru | 2729 | E: yuri@pts.mipt.ru |
2730 | D: Some smbfs fixes | 2730 | D: Some smbfs fixes |
2731 | S: Demonstratsii 8-382 | 2731 | S: Demonstratsii 8-382 |
2732 | S: Tula 300000 | 2732 | S: Tula 300000 |
2733 | S: Russia | 2733 | S: Russia |
2734 | 2734 | ||
2735 | N: Inaky Perez-Gonzalez | 2735 | N: Inaky Perez-Gonzalez |
2736 | E: inaky.perez-gonzalez@intel.com | 2736 | E: inaky.perez-gonzalez@intel.com |
2737 | D: UWB stack, HWA-RC driver and HWA-HC drivers | 2737 | D: UWB stack, HWA-RC driver and HWA-HC drivers |
2738 | D: Wireless USB additions to the USB stack | 2738 | D: Wireless USB additions to the USB stack |
2739 | D: WiMedia Link Protocol bits and pieces | 2739 | D: WiMedia Link Protocol bits and pieces |
2740 | 2740 | ||
2741 | N: Gordon Peters | 2741 | N: Gordon Peters |
2742 | E: GordPeters@smarttech.com | 2742 | E: GordPeters@smarttech.com |
2743 | D: Isochronous receive for IEEE 1394 driver (OHCI module). | 2743 | D: Isochronous receive for IEEE 1394 driver (OHCI module). |
2744 | D: Bugfixes for the aforementioned. | 2744 | D: Bugfixes for the aforementioned. |
2745 | S: Calgary, Alberta | 2745 | S: Calgary, Alberta |
2746 | S: Canada | 2746 | S: Canada |
2747 | 2747 | ||
2748 | N: Johnnie Peters | 2748 | N: Johnnie Peters |
2749 | E: jpeters@phx.mcd.mot.com | 2749 | E: jpeters@phx.mcd.mot.com |
2750 | D: Motorola PowerPC changes for PReP | 2750 | D: Motorola PowerPC changes for PReP |
2751 | S: 2900 S. Diable Way | 2751 | S: 2900 S. Diable Way |
2752 | S: Tempe, Arizona 85282 | 2752 | S: Tempe, Arizona 85282 |
2753 | S: USA | 2753 | S: USA |
2754 | 2754 | ||
2755 | N: Kirk Petersen | 2755 | N: Kirk Petersen |
2756 | E: kirk@speakeasy.org | 2756 | E: kirk@speakeasy.org |
2757 | W: http://www.speakeasy.org/~kirk/ | 2757 | W: http://www.speakeasy.org/~kirk/ |
2758 | D: implemented kmod | 2758 | D: implemented kmod |
2759 | D: modularized BSD Unix domain sockets | 2759 | D: modularized BSD Unix domain sockets |
2760 | 2760 | ||
2761 | N: Martin Kasper Petersen | 2761 | N: Martin Kasper Petersen |
2762 | E: mkp@mkp.net | 2762 | E: mkp@mkp.net |
2763 | D: PA-RISC port | 2763 | D: PA-RISC port |
2764 | D: XFS file system | 2764 | D: XFS file system |
2765 | D: kiobuf based block I/O work | 2765 | D: kiobuf based block I/O work |
2766 | S: 314 Frank St. | 2766 | S: 314 Frank St. |
2767 | S: Ottawa, Ontario | 2767 | S: Ottawa, Ontario |
2768 | S: Canada K2P 0X8 | 2768 | S: Canada K2P 0X8 |
2769 | 2769 | ||
2770 | N: Mikael Pettersson | 2770 | N: Mikael Pettersson |
2771 | E: mikpe@it.uu.se | 2771 | E: mikpe@it.uu.se |
2772 | W: http://user.it.uu.se/~mikpe/linux/ | 2772 | W: http://user.it.uu.se/~mikpe/linux/ |
2773 | D: Miscellaneous fixes | 2773 | D: Miscellaneous fixes |
2774 | 2774 | ||
2775 | N: Reed H. Petty | 2775 | N: Reed H. Petty |
2776 | E: rhp@draper.net | 2776 | E: rhp@draper.net |
2777 | W: http://www.draper.net | 2777 | W: http://www.draper.net |
2778 | D: Loop device driver extensions | 2778 | D: Loop device driver extensions |
2779 | D: Encryption transfer modules (no export) | 2779 | D: Encryption transfer modules (no export) |
2780 | S: Post Office Box 1815 | 2780 | S: Post Office Box 1815 |
2781 | S: Harrison, Arkansas 72602-1815 | 2781 | S: Harrison, Arkansas 72602-1815 |
2782 | S: USA | 2782 | S: USA |
2783 | 2783 | ||
2784 | N: Kai Petzke | 2784 | N: Kai Petzke |
2785 | E: petzke@teltarif.de | 2785 | E: petzke@teltarif.de |
2786 | W: http://www.teltarif.de/ | 2786 | W: http://www.teltarif.de/ |
2787 | P: 1024/B42868C1 D9 59 B9 98 BB 93 05 38 2E 3E 31 79 C3 65 5D E1 | 2787 | P: 1024/B42868C1 D9 59 B9 98 BB 93 05 38 2E 3E 31 79 C3 65 5D E1 |
2788 | D: Driver for Laser Magnetic Storage CD-ROM | 2788 | D: Driver for Laser Magnetic Storage CD-ROM |
2789 | D: Some kernel bug fixes | 2789 | D: Some kernel bug fixes |
2790 | D: Port of the database Postgres | 2790 | D: Port of the database Postgres |
2791 | D: Book: "Linux verstehen und anwenden" (Hanser-Verlag) | 2791 | D: Book: "Linux verstehen und anwenden" (Hanser-Verlag) |
2792 | S: Triftstra=DFe 55 | 2792 | S: Triftstra=DFe 55 |
2793 | S: 13353 Berlin | 2793 | S: 13353 Berlin |
2794 | S: Germany | 2794 | S: Germany |
2795 | 2795 | ||
2796 | N: Emanuel Pirker | 2796 | N: Emanuel Pirker |
2797 | E: epirker@edu.uni-klu.ac.at | 2797 | E: epirker@edu.uni-klu.ac.at |
2798 | D: AIC5800 IEEE 1394, RAW I/O on 1394 | 2798 | D: AIC5800 IEEE 1394, RAW I/O on 1394 |
2799 | D: Starter of Linux1394 effort | 2799 | D: Starter of Linux1394 effort |
2800 | S: ask per mail for current address | 2800 | S: ask per mail for current address |
2801 | 2801 | ||
2802 | N: Nicolas Pitre | 2802 | N: Nicolas Pitre |
2803 | E: nico@cam.org | 2803 | E: nico@fluxnic.net |
2804 | D: StrongARM SA1100 support integrator & hacker | 2804 | D: StrongARM SA1100 support integrator & hacker |
2805 | D: Xscale PXA architecture | 2805 | D: Xscale PXA architecture |
2806 | D: unified SMC 91C9x/91C11x ethernet driver (smc91x) | 2806 | D: unified SMC 91C9x/91C11x ethernet driver (smc91x) |
2807 | S: Montreal, Quebec, Canada | 2807 | S: Montreal, Quebec, Canada |
2808 | 2808 | ||
2809 | N: Ken Pizzini | 2809 | N: Ken Pizzini |
2810 | E: ken@halcyon.com | 2810 | E: ken@halcyon.com |
2811 | D: CDROM driver "sonycd535" (Sony CDU-535/531) | 2811 | D: CDROM driver "sonycd535" (Sony CDU-535/531) |
2812 | 2812 | ||
2813 | N: Stelian Pop | 2813 | N: Stelian Pop |
2814 | E: stelian@popies.net | 2814 | E: stelian@popies.net |
2815 | P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 | 2815 | P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 |
2816 | D: sonypi, meye drivers, mct_u232 usb serial hacks | 2816 | D: sonypi, meye drivers, mct_u232 usb serial hacks |
2817 | S: Paris, France | 2817 | S: Paris, France |
2818 | 2818 | ||
2819 | N: Pete Popov | 2819 | N: Pete Popov |
2820 | E: pete_popov@yahoo.com | 2820 | E: pete_popov@yahoo.com |
2821 | D: Linux/MIPS AMD/Alchemy Port and mips hacking and debugging | 2821 | D: Linux/MIPS AMD/Alchemy Port and mips hacking and debugging |
2822 | S: San Jose, CA 95134 | 2822 | S: San Jose, CA 95134 |
2823 | S: USA | 2823 | S: USA |
2824 | 2824 | ||
2825 | N: Matt Porter | 2825 | N: Matt Porter |
2826 | E: mporter@kernel.crashing.org | 2826 | E: mporter@kernel.crashing.org |
2827 | D: Motorola PowerPC PReP support | 2827 | D: Motorola PowerPC PReP support |
2828 | D: cPCI PowerPC support | 2828 | D: cPCI PowerPC support |
2829 | D: Embedded PowerPC 4xx/6xx/7xx/74xx support | 2829 | D: Embedded PowerPC 4xx/6xx/7xx/74xx support |
2830 | S: Chandler, Arizona 85249 | 2830 | S: Chandler, Arizona 85249 |
2831 | S: USA | 2831 | S: USA |
2832 | 2832 | ||
2833 | N: Frederic Potter | 2833 | N: Frederic Potter |
2834 | E: fpotter@cirpack.com | 2834 | E: fpotter@cirpack.com |
2835 | D: Some PCI kernel support | 2835 | D: Some PCI kernel support |
2836 | 2836 | ||
2837 | N: Rui Prior | 2837 | N: Rui Prior |
2838 | E: rprior@inescn.pt | 2838 | E: rprior@inescn.pt |
2839 | D: ATM device driver for NICStAR based cards | 2839 | D: ATM device driver for NICStAR based cards |
2840 | 2840 | ||
2841 | N: Stefan Probst | 2841 | N: Stefan Probst |
2842 | E: sp@caldera.de | 2842 | E: sp@caldera.de |
2843 | D: The Linux Support Team Erlangen, 1993-97 | 2843 | D: The Linux Support Team Erlangen, 1993-97 |
2844 | S: Caldera (Deutschland) GmbH | 2844 | S: Caldera (Deutschland) GmbH |
2845 | S: Lazarettstrasse 8 | 2845 | S: Lazarettstrasse 8 |
2846 | S: 91054 Erlangen | 2846 | S: 91054 Erlangen |
2847 | S: Germany | 2847 | S: Germany |
2848 | 2848 | ||
2849 | N: Giuliano Procida | 2849 | N: Giuliano Procida |
2850 | E: myxie@debian.org,gprocida@madge.com | 2850 | E: myxie@debian.org,gprocida@madge.com |
2851 | D: Madge Ambassador driver (Collage 155 Server ATM adapter) | 2851 | D: Madge Ambassador driver (Collage 155 Server ATM adapter) |
2852 | D: Madge Horizon driver (Collage 25 and 155 Client ATM adapters) | 2852 | D: Madge Horizon driver (Collage 25 and 155 Client ATM adapters) |
2853 | P: 1024/93898735 D3 9E F4 F7 6D 8D 2F 3A 38 BA 06 7C 2B 33 43 7D | 2853 | P: 1024/93898735 D3 9E F4 F7 6D 8D 2F 3A 38 BA 06 7C 2B 33 43 7D |
2854 | S: Madge Networks | 2854 | S: Madge Networks |
2855 | S: Framewood Road | 2855 | S: Framewood Road |
2856 | S: Wexham SL3 6PJ | 2856 | S: Wexham SL3 6PJ |
2857 | S: United Kingdom | 2857 | S: United Kingdom |
2858 | 2858 | ||
2859 | N: Daniel Quinlan | 2859 | N: Daniel Quinlan |
2860 | E: quinlan@pathname.com | 2860 | E: quinlan@pathname.com |
2861 | W: http://www.pathname.com/~quinlan/ | 2861 | W: http://www.pathname.com/~quinlan/ |
2862 | D: FSSTND coordinator; FHS editor | 2862 | D: FSSTND coordinator; FHS editor |
2863 | D: random Linux documentation, patches, and hacks | 2863 | D: random Linux documentation, patches, and hacks |
2864 | S: 4390 Albany Drive #41A | 2864 | S: 4390 Albany Drive #41A |
2865 | S: San Jose, California 95129 | 2865 | S: San Jose, California 95129 |
2866 | S: USA | 2866 | S: USA |
2867 | 2867 | ||
2868 | N: Juan Quintela | 2868 | N: Juan Quintela |
2869 | E: quintela@fi.udc.es | 2869 | E: quintela@fi.udc.es |
2870 | D: Memory Management hacking | 2870 | D: Memory Management hacking |
2871 | S: LFCIA | 2871 | S: LFCIA |
2872 | S: Departamento de Computaciรณn | 2872 | S: Departamento de Computaciรณn |
2873 | S: Universidade da Coruรฑa | 2873 | S: Universidade da Coruรฑa |
2874 | S: E-15071 | 2874 | S: E-15071 |
2875 | S: A Coruรฑa | 2875 | S: A Coruรฑa |
2876 | S: Spain | 2876 | S: Spain |
2877 | 2877 | ||
2878 | N: Augusto Cesar Radtke | 2878 | N: Augusto Cesar Radtke |
2879 | E: bishop@sekure.org | 2879 | E: bishop@sekure.org |
2880 | W: http://bishop.sekure.org | 2880 | W: http://bishop.sekure.org |
2881 | D: {copy,get,put}_user calls updates | 2881 | D: {copy,get,put}_user calls updates |
2882 | D: Miscellaneous hacks | 2882 | D: Miscellaneous hacks |
2883 | S: R. Otto Marquardt, 226 - Garcia | 2883 | S: R. Otto Marquardt, 226 - Garcia |
2884 | S: 89020-350 Blumenau - Santa Catarina | 2884 | S: 89020-350 Blumenau - Santa Catarina |
2885 | S: Brazil | 2885 | S: Brazil |
2886 | 2886 | ||
2887 | N: Goutham Rao | 2887 | N: Goutham Rao |
2888 | E: goutham.rao@intel.com | 2888 | E: goutham.rao@intel.com |
2889 | D: Linux/IA-64 | 2889 | D: Linux/IA-64 |
2890 | S: 2200 Mission College Blvd | 2890 | S: 2200 Mission College Blvd |
2891 | S: Santa Clara, CA 95052 | 2891 | S: Santa Clara, CA 95052 |
2892 | S: USA | 2892 | S: USA |
2893 | 2893 | ||
2894 | N: Eric S. Raymond | 2894 | N: Eric S. Raymond |
2895 | E: esr@thyrsus.com | 2895 | E: esr@thyrsus.com |
2896 | W: http://www.tuxedo.org/~esr/ | 2896 | W: http://www.tuxedo.org/~esr/ |
2897 | D: terminfo master file maintainer | 2897 | D: terminfo master file maintainer |
2898 | D: Editor: Installation HOWTO, Distributions HOWTO, XFree86 HOWTO | 2898 | D: Editor: Installation HOWTO, Distributions HOWTO, XFree86 HOWTO |
2899 | D: Author: fetchmail, Emacs VC mode, Emacs GUD mode | 2899 | D: Author: fetchmail, Emacs VC mode, Emacs GUD mode |
2900 | S: 6 Karen Drive | 2900 | S: 6 Karen Drive |
2901 | S: Malvern, Pennsylvania 19355 | 2901 | S: Malvern, Pennsylvania 19355 |
2902 | S: USA | 2902 | S: USA |
2903 | 2903 | ||
2904 | N: Stefan Reinauer | 2904 | N: Stefan Reinauer |
2905 | E: stepan@linux.de | 2905 | E: stepan@linux.de |
2906 | W: http://www.freiburg.linux.de/~stepan/ | 2906 | W: http://www.freiburg.linux.de/~stepan/ |
2907 | D: Modularization of some filesystems | 2907 | D: Modularization of some filesystems |
2908 | D: /proc/sound, minor fixes | 2908 | D: /proc/sound, minor fixes |
2909 | S: Schlossbergring 9 | 2909 | S: Schlossbergring 9 |
2910 | S: 79098 Freiburg | 2910 | S: 79098 Freiburg |
2911 | S: Germany | 2911 | S: Germany |
2912 | 2912 | ||
2913 | N: Joerg Reuter | 2913 | N: Joerg Reuter |
2914 | E: jreuter@yaina.de | 2914 | E: jreuter@yaina.de |
2915 | W: http://yaina.de/jreuter/ | 2915 | W: http://yaina.de/jreuter/ |
2916 | W: http://www.qsl.net/dl1bke/ | 2916 | W: http://www.qsl.net/dl1bke/ |
2917 | D: Generic Z8530 driver, AX.25 DAMA slave implementation | 2917 | D: Generic Z8530 driver, AX.25 DAMA slave implementation |
2918 | D: Several AX.25 hacks | 2918 | D: Several AX.25 hacks |
2919 | 2919 | ||
2920 | N: Francois-Rene Rideau | 2920 | N: Francois-Rene Rideau |
2921 | E: fare@tunes.org | 2921 | E: fare@tunes.org |
2922 | W: http://www.tunes.org/~fare | 2922 | W: http://www.tunes.org/~fare |
2923 | D: petty kernel janitor (byteorder, ufs) | 2923 | D: petty kernel janitor (byteorder, ufs) |
2924 | S: 6, rue Augustin Thierry | 2924 | S: 6, rue Augustin Thierry |
2925 | S: 75019 Paris | 2925 | S: 75019 Paris |
2926 | S: France | 2926 | S: France |
2927 | 2927 | ||
2928 | N: Rik van Riel | 2928 | N: Rik van Riel |
2929 | E: riel@redhat.com | 2929 | E: riel@redhat.com |
2930 | W: http://www.surriel.com/ | 2930 | W: http://www.surriel.com/ |
2931 | D: Linux-MM site, Documentation/sysctl/*, swap/mm readaround | 2931 | D: Linux-MM site, Documentation/sysctl/*, swap/mm readaround |
2932 | D: kswapd fixes, random kernel hacker, rmap VM, | 2932 | D: kswapd fixes, random kernel hacker, rmap VM, |
2933 | D: nl.linux.org administrator, minor scheduler additions | 2933 | D: nl.linux.org administrator, minor scheduler additions |
2934 | S: Red Hat Boston | 2934 | S: Red Hat Boston |
2935 | S: 3 Lan Drive | 2935 | S: 3 Lan Drive |
2936 | S: Westford, MA 01886 | 2936 | S: Westford, MA 01886 |
2937 | S: USA | 2937 | S: USA |
2938 | 2938 | ||
2939 | N: Pekka Riikonen | 2939 | N: Pekka Riikonen |
2940 | E: priikone@poseidon.pspt.fi | 2940 | E: priikone@poseidon.pspt.fi |
2941 | E: priikone@ssh.com | 2941 | E: priikone@ssh.com |
2942 | D: Random kernel hacking and bug fixes | 2942 | D: Random kernel hacking and bug fixes |
2943 | D: International kernel patch project | 2943 | D: International kernel patch project |
2944 | S: Kasarmikatu 11 A4 | 2944 | S: Kasarmikatu 11 A4 |
2945 | S: 70110 Kuopio | 2945 | S: 70110 Kuopio |
2946 | S: Finland | 2946 | S: Finland |
2947 | 2947 | ||
2948 | N: Luca Risolia | 2948 | N: Luca Risolia |
2949 | E: luca.risolia@studio.unibo.it | 2949 | E: luca.risolia@studio.unibo.it |
2950 | P: 1024D/FCE635A4 88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4 | 2950 | P: 1024D/FCE635A4 88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4 |
2951 | D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips | 2951 | D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips |
2952 | D: V4L2 driver for SN9C10x PC Camera Controllers | 2952 | D: V4L2 driver for SN9C10x PC Camera Controllers |
2953 | D: V4L2 driver for ET61X151 and ET61X251 PC Camera Controllers | 2953 | D: V4L2 driver for ET61X151 and ET61X251 PC Camera Controllers |
2954 | D: V4L2 driver for ZC0301 Image Processor and Control Chip | 2954 | D: V4L2 driver for ZC0301 Image Processor and Control Chip |
2955 | S: Via Liberta' 41/A | 2955 | S: Via Liberta' 41/A |
2956 | S: Osio Sotto, 24046, Bergamo | 2956 | S: Osio Sotto, 24046, Bergamo |
2957 | S: Italy | 2957 | S: Italy |
2958 | 2958 | ||
2959 | N: William E. Roadcap | 2959 | N: William E. Roadcap |
2960 | E: roadcapw@cfw.com | 2960 | E: roadcapw@cfw.com |
2961 | W: http://www.cfw.com/~roadcapw | 2961 | W: http://www.cfw.com/~roadcapw |
2962 | D: Author of menu based configuration tool, Menuconfig. | 2962 | D: Author of menu based configuration tool, Menuconfig. |
2963 | S: 1407 Broad Street | 2963 | S: 1407 Broad Street |
2964 | S: Waynesboro, Virginia 22980 | 2964 | S: Waynesboro, Virginia 22980 |
2965 | S: USA | 2965 | S: USA |
2966 | 2966 | ||
2967 | N: Andrew J. Robinson | 2967 | N: Andrew J. Robinson |
2968 | E: arobinso@nyx.net | 2968 | E: arobinso@nyx.net |
2969 | W: http://www.nyx.net/~arobinso | 2969 | W: http://www.nyx.net/~arobinso |
2970 | D: Hayes ESP serial port driver | 2970 | D: Hayes ESP serial port driver |
2971 | 2971 | ||
2972 | N: Florian La Roche | 2972 | N: Florian La Roche |
2973 | E: rzsfl@rz.uni-sb.de | 2973 | E: rzsfl@rz.uni-sb.de |
2974 | E: flla@stud.uni-sb.de | 2974 | E: flla@stud.uni-sb.de |
2975 | D: Net programs and kernel net hacker | 2975 | D: Net programs and kernel net hacker |
2976 | S: Gaildorfer Str. 27 | 2976 | S: Gaildorfer Str. 27 |
2977 | S: 7000 Stuttgart 50 | 2977 | S: 7000 Stuttgart 50 |
2978 | S: Germany | 2978 | S: Germany |
2979 | 2979 | ||
2980 | N: Christoph Rohland | 2980 | N: Christoph Rohland |
2981 | E: hans-christoph.rohland@sap.com | 2981 | E: hans-christoph.rohland@sap.com |
2982 | E: ch.rohland@gmx.net | 2982 | E: ch.rohland@gmx.net |
2983 | D: shm fs, SYSV semaphores, af_unix | 2983 | D: shm fs, SYSV semaphores, af_unix |
2984 | S: Neue Heimat Str. 8 | 2984 | S: Neue Heimat Str. 8 |
2985 | S: D-68789 St.Leon-Rot | 2985 | S: D-68789 St.Leon-Rot |
2986 | S: Germany | 2986 | S: Germany |
2987 | 2987 | ||
2988 | N: Thiago Berlitz Rondon | 2988 | N: Thiago Berlitz Rondon |
2989 | E: maluco@mileniumnet.com.br | 2989 | E: maluco@mileniumnet.com.br |
2990 | W: http://vivaldi.linuxms.com.br/~maluco | 2990 | W: http://vivaldi.linuxms.com.br/~maluco |
2991 | D: Miscellaneous kernel hacker | 2991 | D: Miscellaneous kernel hacker |
2992 | S: R. Anhanguera, 1487 - Ipiranga | 2992 | S: R. Anhanguera, 1487 - Ipiranga |
2993 | S: 79080-740 - Campo Grande - Mato Grosso do Sul | 2993 | S: 79080-740 - Campo Grande - Mato Grosso do Sul |
2994 | S: Brazil | 2994 | S: Brazil |
2995 | 2995 | ||
2996 | N: Stephen Rothwell | 2996 | N: Stephen Rothwell |
2997 | E: sfr@canb.auug.org.au | 2997 | E: sfr@canb.auug.org.au |
2998 | W: http://www.canb.auug.org.au/~sfr | 2998 | W: http://www.canb.auug.org.au/~sfr |
2999 | P: 1024/BD8C7805 CD A4 9D 01 10 6E 7E 3B 91 88 FA D9 C8 40 AA 02 | 2999 | P: 1024/BD8C7805 CD A4 9D 01 10 6E 7E 3B 91 88 FA D9 C8 40 AA 02 |
3000 | D: Boot/setup/build work for setup > 2K | 3000 | D: Boot/setup/build work for setup > 2K |
3001 | D: Author, APM driver | 3001 | D: Author, APM driver |
3002 | D: Directory notification | 3002 | D: Directory notification |
3003 | S: 66 Maltby Circuit | 3003 | S: 66 Maltby Circuit |
3004 | S: Wanniassa ACT 2903 | 3004 | S: Wanniassa ACT 2903 |
3005 | S: Australia | 3005 | S: Australia |
3006 | 3006 | ||
3007 | N: Gerard Roudier | 3007 | N: Gerard Roudier |
3008 | E: groudier@free.fr | 3008 | E: groudier@free.fr |
3009 | D: Contributed to asynchronous read-ahead improvement | 3009 | D: Contributed to asynchronous read-ahead improvement |
3010 | S: 21 Rue Carnot | 3010 | S: 21 Rue Carnot |
3011 | S: 95170 Deuil La Barre | 3011 | S: 95170 Deuil La Barre |
3012 | S: France | 3012 | S: France |
3013 | 3013 | ||
3014 | N: Sebastien Rougeaux | 3014 | N: Sebastien Rougeaux |
3015 | E: Sebastien.Rougeaux@syseng.anu.edu.au | 3015 | E: Sebastien.Rougeaux@syseng.anu.edu.au |
3016 | D: IEEE 1394 OHCI module | 3016 | D: IEEE 1394 OHCI module |
3017 | S: Research School of Information Science and Engineering | 3017 | S: Research School of Information Science and Engineering |
3018 | S: The Australian National University, ACT 0200 | 3018 | S: The Australian National University, ACT 0200 |
3019 | S: Australia | 3019 | S: Australia |
3020 | 3020 | ||
3021 | N: Aristeu Sergio Rozanski Filho | 3021 | N: Aristeu Sergio Rozanski Filho |
3022 | E: aris@cathedrallabs.org | 3022 | E: aris@cathedrallabs.org |
3023 | D: Support for EtherExpress 10 ISA (i82595) in eepro driver | 3023 | D: Support for EtherExpress 10 ISA (i82595) in eepro driver |
3024 | D: User level driver support for input | 3024 | D: User level driver support for input |
3025 | S: R. Jose Serrato, 130 - Santa Candida | 3025 | S: R. Jose Serrato, 130 - Santa Candida |
3026 | S: 82640-320 - Curitiba - Paranรก | 3026 | S: 82640-320 - Curitiba - Paranรก |
3027 | S: Brazil | 3027 | S: Brazil |
3028 | 3028 | ||
3029 | N: Alessandro Rubini | 3029 | N: Alessandro Rubini |
3030 | E: rubini@ipvvis.unipv.it | 3030 | E: rubini@ipvvis.unipv.it |
3031 | D: the gpm mouse server and kernel support for it | 3031 | D: the gpm mouse server and kernel support for it |
3032 | 3032 | ||
3033 | N: Philipp Rumpf | 3033 | N: Philipp Rumpf |
3034 | E: prumpf@tux.org | 3034 | E: prumpf@tux.org |
3035 | D: random bugfixes | 3035 | D: random bugfixes |
3036 | S: Drausnickstrasse 29 | 3036 | S: Drausnickstrasse 29 |
3037 | S: 91052 Erlangen | 3037 | S: 91052 Erlangen |
3038 | S: Germany | 3038 | S: Germany |
3039 | 3039 | ||
3040 | N: Paul `Rusty' Russell | 3040 | N: Paul `Rusty' Russell |
3041 | E: rusty@rustcorp.com.au | 3041 | E: rusty@rustcorp.com.au |
3042 | W: http://ozlabs.org/~rusty | 3042 | W: http://ozlabs.org/~rusty |
3043 | D: Ruggedly handsome. | 3043 | D: Ruggedly handsome. |
3044 | D: netfilter, ipchains with Michael Neuling. | 3044 | D: netfilter, ipchains with Michael Neuling. |
3045 | S: 52 Moore St | 3045 | S: 52 Moore St |
3046 | S: Turner ACT 2612 | 3046 | S: Turner ACT 2612 |
3047 | S: Australia | 3047 | S: Australia |
3048 | 3048 | ||
3049 | N: Richard Russon (FlatCap) | 3049 | N: Richard Russon (FlatCap) |
3050 | E: kernel@flatcap.org | 3050 | E: kernel@flatcap.org |
3051 | W: http://www.flatcap.org | 3051 | W: http://www.flatcap.org |
3052 | D: NTFS support | 3052 | D: NTFS support |
3053 | D: LDM support (Win2000/XP Logical Disk Manager/Dynamic Disks) | 3053 | D: LDM support (Win2000/XP Logical Disk Manager/Dynamic Disks) |
3054 | S: 50 Swansea Road | 3054 | S: 50 Swansea Road |
3055 | S: Reading | 3055 | S: Reading |
3056 | S: United Kingdom | 3056 | S: United Kingdom |
3057 | 3057 | ||
3058 | N: Bill Ryder | 3058 | N: Bill Ryder |
3059 | E: bryder@sgi.com | 3059 | E: bryder@sgi.com |
3060 | D: FTDI_SIO usb/serial converter driver | 3060 | D: FTDI_SIO usb/serial converter driver |
3061 | W: http://reality.sgi.com/bryder_wellington/ftdi_sio | 3061 | W: http://reality.sgi.com/bryder_wellington/ftdi_sio |
3062 | S: I/3 Walter St | 3062 | S: I/3 Walter St |
3063 | S: Wellington | 3063 | S: Wellington |
3064 | S: New Zealand | 3064 | S: New Zealand |
3065 | 3065 | ||
3066 | N: Sampo Saaristo | 3066 | N: Sampo Saaristo |
3067 | E: sambo@cs.tut.fi | 3067 | E: sambo@cs.tut.fi |
3068 | D: Co-author of Multi-Protocol Over ATM (MPOA) | 3068 | D: Co-author of Multi-Protocol Over ATM (MPOA) |
3069 | S: Tampere University of Technology / Telecom lab | 3069 | S: Tampere University of Technology / Telecom lab |
3070 | S: Hermiankatu 12C | 3070 | S: Hermiankatu 12C |
3071 | S: FIN-33720 Tampere | 3071 | S: FIN-33720 Tampere |
3072 | S: Finland | 3072 | S: Finland |
3073 | 3073 | ||
3074 | N: Thomas Sailer | 3074 | N: Thomas Sailer |
3075 | E: t.sailer@alumni.ethz.ch | 3075 | E: t.sailer@alumni.ethz.ch |
3076 | E: HB9JNX@HB9W.CHE.EU (packet radio) | 3076 | E: HB9JNX@HB9W.CHE.EU (packet radio) |
3077 | D: Baycom driver | 3077 | D: Baycom driver |
3078 | S: Markusstrasse 18 | 3078 | S: Markusstrasse 18 |
3079 | S: 8006 Zuerich | 3079 | S: 8006 Zuerich |
3080 | S: Switzerland | 3080 | S: Switzerland |
3081 | 3081 | ||
3082 | N: Manuel Estrada Sainz | 3082 | N: Manuel Estrada Sainz |
3083 | D: Firmware loader (request_firmware) | 3083 | D: Firmware loader (request_firmware) |
3084 | 3084 | ||
3085 | N: Wayne Salamon | 3085 | N: Wayne Salamon |
3086 | E: wsalamon@tislabs.com | 3086 | E: wsalamon@tislabs.com |
3087 | E: wsalamon@nai.com | 3087 | E: wsalamon@nai.com |
3088 | D: portions of the Linux Security Module (LSM) framework and security modules | 3088 | D: portions of the Linux Security Module (LSM) framework and security modules |
3089 | 3089 | ||
3090 | N: Robert Sanders | 3090 | N: Robert Sanders |
3091 | E: gt8134b@prism.gatech.edu | 3091 | E: gt8134b@prism.gatech.edu |
3092 | D: Dosemu | 3092 | D: Dosemu |
3093 | 3093 | ||
3094 | N: Duncan Sands | 3094 | N: Duncan Sands |
3095 | E: duncan.sands@free.fr | 3095 | E: duncan.sands@free.fr |
3096 | W: http://topo.math.u-psud.fr/~sands | 3096 | W: http://topo.math.u-psud.fr/~sands |
3097 | D: Alcatel SpeedTouch USB driver | 3097 | D: Alcatel SpeedTouch USB driver |
3098 | S: 69 rue Dunois | 3098 | S: 69 rue Dunois |
3099 | S: 75013 Paris | 3099 | S: 75013 Paris |
3100 | S: France | 3100 | S: France |
3101 | 3101 | ||
3102 | N: Dipankar Sarma | 3102 | N: Dipankar Sarma |
3103 | E: dipankar@in.ibm.com | 3103 | E: dipankar@in.ibm.com |
3104 | D: RCU | 3104 | D: RCU |
3105 | 3105 | ||
3106 | N: Hannu Savolainen | 3106 | N: Hannu Savolainen |
3107 | E: hannu@opensound.com | 3107 | E: hannu@opensound.com |
3108 | D: Maintainer of the sound drivers until 2.1.x days. | 3108 | D: Maintainer of the sound drivers until 2.1.x days. |
3109 | D: Original compressed boot image support. | 3109 | D: Original compressed boot image support. |
3110 | S: Valurink. 4A11 | 3110 | S: Valurink. 4A11 |
3111 | S: 03600 Karkkila | 3111 | S: 03600 Karkkila |
3112 | S: Finland | 3112 | S: Finland |
3113 | 3113 | ||
3114 | N: Deepak Saxena | 3114 | N: Deepak Saxena |
3115 | E: dsaxena@plexity.net | 3115 | E: dsaxena@plexity.net |
3116 | D: I2O kernel layer (config, block, core, pci, net). I2O disk support for LILO | 3116 | D: I2O kernel layer (config, block, core, pci, net). I2O disk support for LILO |
3117 | D: XScale(IOP, IXP) porting and other random ARM bits | 3117 | D: XScale(IOP, IXP) porting and other random ARM bits |
3118 | S: Portland, OR | 3118 | S: Portland, OR |
3119 | 3119 | ||
3120 | N: Eric Schenk | 3120 | N: Eric Schenk |
3121 | E: Eric.Schenk@dna.lth.se | 3121 | E: Eric.Schenk@dna.lth.se |
3122 | D: Random kernel debugging. | 3122 | D: Random kernel debugging. |
3123 | D: SYSV Semaphore code rewrite. | 3123 | D: SYSV Semaphore code rewrite. |
3124 | D: Network layer debugging. | 3124 | D: Network layer debugging. |
3125 | D: Dial on demand facility (diald). | 3125 | D: Dial on demand facility (diald). |
3126 | S: Dag Hammerskjolds v. 3E | 3126 | S: Dag Hammerskjolds v. 3E |
3127 | S: S-226 64 LUND | 3127 | S: S-226 64 LUND |
3128 | S: Sweden | 3128 | S: Sweden |
3129 | 3129 | ||
3130 | N: Henning P. Schmiedehausen | 3130 | N: Henning P. Schmiedehausen |
3131 | E: hps@tanstaafl.de | 3131 | E: hps@tanstaafl.de |
3132 | D: added PCI support to the serial driver | 3132 | D: added PCI support to the serial driver |
3133 | S: Buckenhof, Germany | 3133 | S: Buckenhof, Germany |
3134 | 3134 | ||
3135 | N: Michael Schmitz | 3135 | N: Michael Schmitz |
3136 | E: | 3136 | E: |
3137 | D: Macintosh IDE Driver | 3137 | D: Macintosh IDE Driver |
3138 | 3138 | ||
3139 | N: Peter De Schrijver | 3139 | N: Peter De Schrijver |
3140 | E: stud11@cc4.kuleuven.ac.be | 3140 | E: stud11@cc4.kuleuven.ac.be |
3141 | D: Mitsumi CD-ROM driver patches March version | 3141 | D: Mitsumi CD-ROM driver patches March version |
3142 | S: Molenbaan 29 | 3142 | S: Molenbaan 29 |
3143 | S: B2240 Zandhoven | 3143 | S: B2240 Zandhoven |
3144 | S: Belgium | 3144 | S: Belgium |
3145 | 3145 | ||
3146 | N: Martin Schulze | 3146 | N: Martin Schulze |
3147 | E: joey@linux.de | 3147 | E: joey@linux.de |
3148 | W: http://home.pages.de/~joey/ | 3148 | W: http://home.pages.de/~joey/ |
3149 | D: Random Linux Hacker, Linux Promoter | 3149 | D: Random Linux Hacker, Linux Promoter |
3150 | D: CD-List, Books-List, Ex-FAQ | 3150 | D: CD-List, Books-List, Ex-FAQ |
3151 | D: Linux-Support, -Mailbox, -Stammtisch | 3151 | D: Linux-Support, -Mailbox, -Stammtisch |
3152 | D: several improvements to system programs | 3152 | D: several improvements to system programs |
3153 | S: Oldenburg | 3153 | S: Oldenburg |
3154 | S: Germany | 3154 | S: Germany |
3155 | 3155 | ||
3156 | N: Robert Schwebel | 3156 | N: Robert Schwebel |
3157 | E: robert@schwebel.de | 3157 | E: robert@schwebel.de |
3158 | W: http://www.schwebel.de | 3158 | W: http://www.schwebel.de |
3159 | D: Embedded hacker and book author, | 3159 | D: Embedded hacker and book author, |
3160 | D: AMD Elan support for Linux | 3160 | D: AMD Elan support for Linux |
3161 | S: Pengutronix | 3161 | S: Pengutronix |
3162 | S: Braunschweiger Strasse 79 | 3162 | S: Braunschweiger Strasse 79 |
3163 | S: 31134 Hildesheim | 3163 | S: 31134 Hildesheim |
3164 | S: Germany | 3164 | S: Germany |
3165 | 3165 | ||
3166 | N: Darren Senn | 3166 | N: Darren Senn |
3167 | E: sinster@darkwater.com | 3167 | E: sinster@darkwater.com |
3168 | D: Whatever I notice needs doing (so far: itimers, /proc) | 3168 | D: Whatever I notice needs doing (so far: itimers, /proc) |
3169 | S: Post Office Box 64132 | 3169 | S: Post Office Box 64132 |
3170 | S: Sunnyvale, California 94088-4132 | 3170 | S: Sunnyvale, California 94088-4132 |
3171 | S: USA | 3171 | S: USA |
3172 | 3172 | ||
3173 | N: Stas Sergeev | 3173 | N: Stas Sergeev |
3174 | E: stsp@users.sourceforge.net | 3174 | E: stsp@users.sourceforge.net |
3175 | D: PCM PC-Speaker driver | 3175 | D: PCM PC-Speaker driver |
3176 | D: misc fixes | 3176 | D: misc fixes |
3177 | S: Russia | 3177 | S: Russia |
3178 | 3178 | ||
3179 | N: Simon Shapiro | 3179 | N: Simon Shapiro |
3180 | E: shimon@i-Connect.Net | 3180 | E: shimon@i-Connect.Net |
3181 | W: http://www.-i-Connect.Net/~shimon | 3181 | W: http://www.-i-Connect.Net/~shimon |
3182 | D: SCSI debugging | 3182 | D: SCSI debugging |
3183 | D: Maintainer of the Debian Kernel packages | 3183 | D: Maintainer of the Debian Kernel packages |
3184 | S: 14355 SW Allen Blvd., Suite #140 | 3184 | S: 14355 SW Allen Blvd., Suite #140 |
3185 | S: Beaverton, Oregon 97008 | 3185 | S: Beaverton, Oregon 97008 |
3186 | S: USA | 3186 | S: USA |
3187 | 3187 | ||
3188 | N: Mike Shaver | 3188 | N: Mike Shaver |
3189 | E: shaver@hungry.org | 3189 | E: shaver@hungry.org |
3190 | W: http://www.hungry.org/~shaver/ | 3190 | W: http://www.hungry.org/~shaver/ |
3191 | D: MIPS work, /proc/sys/net, misc net hacking | 3191 | D: MIPS work, /proc/sys/net, misc net hacking |
3192 | S: 149 Union St. | 3192 | S: 149 Union St. |
3193 | S: Kingston, Ontario | 3193 | S: Kingston, Ontario |
3194 | S: Canada K7L 2P4 | 3194 | S: Canada K7L 2P4 |
3195 | 3195 | ||
3196 | N: John Shifflett | 3196 | N: John Shifflett |
3197 | E: john@geolog.com | 3197 | E: john@geolog.com |
3198 | E: jshiffle@netcom.com | 3198 | E: jshiffle@netcom.com |
3199 | D: Always IN2000 SCSI driver | 3199 | D: Always IN2000 SCSI driver |
3200 | D: wd33c93 SCSI driver (linux-m68k) | 3200 | D: wd33c93 SCSI driver (linux-m68k) |
3201 | S: San Jose, California | 3201 | S: San Jose, California |
3202 | S: USA | 3202 | S: USA |
3203 | 3203 | ||
3204 | N: Robert Siemer | 3204 | N: Robert Siemer |
3205 | E: Robert.Siemer@gmx.de | 3205 | E: Robert.Siemer@gmx.de |
3206 | P: 2048/C99A4289 2F DC 17 2E 56 62 01 C8 3D F2 AC 09 F2 E5 DD EE | 3206 | P: 2048/C99A4289 2F DC 17 2E 56 62 01 C8 3D F2 AC 09 F2 E5 DD EE |
3207 | D: miroSOUND PCM20 radio RDS driver, ACI rewrite | 3207 | D: miroSOUND PCM20 radio RDS driver, ACI rewrite |
3208 | S: Klosterweg 28 / i309 | 3208 | S: Klosterweg 28 / i309 |
3209 | S: 76131 Karlsruhe | 3209 | S: 76131 Karlsruhe |
3210 | S: Germany | 3210 | S: Germany |
3211 | 3211 | ||
3212 | N: James Simmons | 3212 | N: James Simmons |
3213 | E: jsimmons@infradead.org | 3213 | E: jsimmons@infradead.org |
3214 | E: jsimmons@users.sf.net | 3214 | E: jsimmons@users.sf.net |
3215 | D: Frame buffer device maintainer | 3215 | D: Frame buffer device maintainer |
3216 | D: input layer developement | 3216 | D: input layer developement |
3217 | D: tty/console layer | 3217 | D: tty/console layer |
3218 | D: various mipsel devices | 3218 | D: various mipsel devices |
3219 | S: 115 Carmel Avenue | 3219 | S: 115 Carmel Avenue |
3220 | S: El Cerrito CA 94530 | 3220 | S: El Cerrito CA 94530 |
3221 | S: USA | 3221 | S: USA |
3222 | 3222 | ||
3223 | N: Jaspreet Singh | 3223 | N: Jaspreet Singh |
3224 | E: jaspreet@sangoma.com | 3224 | E: jaspreet@sangoma.com |
3225 | W: www.sangoma.com | 3225 | W: www.sangoma.com |
3226 | D: WANPIPE drivers & API Support for Sangoma S508/FT1 cards | 3226 | D: WANPIPE drivers & API Support for Sangoma S508/FT1 cards |
3227 | S: Sangoma Technologies Inc., | 3227 | S: Sangoma Technologies Inc., |
3228 | S: 1001 Denison Street | 3228 | S: 1001 Denison Street |
3229 | S: Suite 101 | 3229 | S: Suite 101 |
3230 | S: Markham, Ontario L3R 2Z6 | 3230 | S: Markham, Ontario L3R 2Z6 |
3231 | S: Canada | 3231 | S: Canada |
3232 | 3232 | ||
3233 | N: Rick Sladkey | 3233 | N: Rick Sladkey |
3234 | E: jrs@world.std.com | 3234 | E: jrs@world.std.com |
3235 | D: utility hacker: Emacs, NFS server, mount, kmem-ps, UPS debugger, strace, GDB | 3235 | D: utility hacker: Emacs, NFS server, mount, kmem-ps, UPS debugger, strace, GDB |
3236 | D: library hacker: RPC, profil(3), realpath(3), regexp.h | 3236 | D: library hacker: RPC, profil(3), realpath(3), regexp.h |
3237 | D: kernel hacker: unnamed block devs, NFS client, fast select, precision timer | 3237 | D: kernel hacker: unnamed block devs, NFS client, fast select, precision timer |
3238 | S: 24 Avon Place | 3238 | S: 24 Avon Place |
3239 | S: Arlington, Massachusetts 02174 | 3239 | S: Arlington, Massachusetts 02174 |
3240 | S: USA | 3240 | S: USA |
3241 | 3241 | ||
3242 | N: Craig Small | 3242 | N: Craig Small |
3243 | E: csmall@triode.apana.org.au | 3243 | E: csmall@triode.apana.org.au |
3244 | E: vk2xlz@gonzo.vk2xlz.ampr.org (packet radio) | 3244 | E: vk2xlz@gonzo.vk2xlz.ampr.org (packet radio) |
3245 | D: Gracilis PackeTwin device driver | 3245 | D: Gracilis PackeTwin device driver |
3246 | D: RSPF daemon | 3246 | D: RSPF daemon |
3247 | S: 10 Stockalls Place | 3247 | S: 10 Stockalls Place |
3248 | S: Minto, NSW, 2566 | 3248 | S: Minto, NSW, 2566 |
3249 | S: Australia | 3249 | S: Australia |
3250 | 3250 | ||
3251 | N: Stephen Smalley | 3251 | N: Stephen Smalley |
3252 | E: sds@tycho.nsa.gov | 3252 | E: sds@tycho.nsa.gov |
3253 | D: portions of the Linux Security Module (LSM) framework and security modules | 3253 | D: portions of the Linux Security Module (LSM) framework and security modules |
3254 | 3254 | ||
3255 | N: Chris Smith | 3255 | N: Chris Smith |
3256 | E: csmith@convex.com | 3256 | E: csmith@convex.com |
3257 | D: Read only HPFS filesystem | 3257 | D: Read only HPFS filesystem |
3258 | S: Richardson, Texas | 3258 | S: Richardson, Texas |
3259 | S: USA | 3259 | S: USA |
3260 | 3260 | ||
3261 | N: Christopher Smith | 3261 | N: Christopher Smith |
3262 | E: x@xman.org | 3262 | E: x@xman.org |
3263 | D: Tulip net driver hacker | 3263 | D: Tulip net driver hacker |
3264 | 3264 | ||
3265 | N: Mark Smith | 3265 | N: Mark Smith |
3266 | E: mark.smith@comdev.cc | 3266 | E: mark.smith@comdev.cc |
3267 | D: Multicast support in bonding driver | 3267 | D: Multicast support in bonding driver |
3268 | 3268 | ||
3269 | N: Miquel van Smoorenburg | 3269 | N: Miquel van Smoorenburg |
3270 | E: miquels@cistron.nl | 3270 | E: miquels@cistron.nl |
3271 | D: Kernel and net hacker. Sysvinit, minicom. doing Debian stuff. | 3271 | D: Kernel and net hacker. Sysvinit, minicom. doing Debian stuff. |
3272 | S: Cistron Internet Services | 3272 | S: Cistron Internet Services |
3273 | S: PO-Box 297 | 3273 | S: PO-Box 297 |
3274 | S: 2400 AG, Alphen aan den Rijn | 3274 | S: 2400 AG, Alphen aan den Rijn |
3275 | S: The Netherlands | 3275 | S: The Netherlands |
3276 | 3276 | ||
3277 | N: Scott Snyder | 3277 | N: Scott Snyder |
3278 | E: snyder@fnald0.fnal.gov | 3278 | E: snyder@fnald0.fnal.gov |
3279 | D: ATAPI cdrom driver | 3279 | D: ATAPI cdrom driver |
3280 | S: MS 352, Fermilab | 3280 | S: MS 352, Fermilab |
3281 | S: Post Office Box 500 | 3281 | S: Post Office Box 500 |
3282 | S: Batavia, Illinois 60510 | 3282 | S: Batavia, Illinois 60510 |
3283 | S: USA | 3283 | S: USA |
3284 | 3284 | ||
3285 | N: Leo Spiekman | 3285 | N: Leo Spiekman |
3286 | E: leo@netlabs.net | 3286 | E: leo@netlabs.net |
3287 | W: http://www.netlabs.net/hp/leo/ | 3287 | W: http://www.netlabs.net/hp/leo/ |
3288 | D: Optics Storage 8000AT cdrom driver | 3288 | D: Optics Storage 8000AT cdrom driver |
3289 | S: Cliffwood, New Jersey 07721 | 3289 | S: Cliffwood, New Jersey 07721 |
3290 | S: USA | 3290 | S: USA |
3291 | 3291 | ||
3292 | N: Manfred Spraul | 3292 | N: Manfred Spraul |
3293 | E: manfred@colorfullife.com | 3293 | E: manfred@colorfullife.com |
3294 | W: http://www.colorfullife.com/~manfred | 3294 | W: http://www.colorfullife.com/~manfred |
3295 | D: Lots of tiny hacks. Larger improvments to SysV IPC msg, | 3295 | D: Lots of tiny hacks. Larger improvments to SysV IPC msg, |
3296 | D: slab, pipe, select. | 3296 | D: slab, pipe, select. |
3297 | S: 71701 Schwieberdingen | 3297 | S: 71701 Schwieberdingen |
3298 | S: Germany | 3298 | S: Germany |
3299 | 3299 | ||
3300 | N: Andrew Stanley-Jones | 3300 | N: Andrew Stanley-Jones |
3301 | E: asj@lanmedia.com | 3301 | E: asj@lanmedia.com |
3302 | D: LanMedia Corp. Device WAN card device driver | 3302 | D: LanMedia Corp. Device WAN card device driver |
3303 | S: #102, 686 W. Maude Ave | 3303 | S: #102, 686 W. Maude Ave |
3304 | S: Sunyvale, CA 94086 | 3304 | S: Sunyvale, CA 94086 |
3305 | S: USA | 3305 | S: USA |
3306 | 3306 | ||
3307 | N: Michael Still | 3307 | N: Michael Still |
3308 | E: mikal@stillhq.com | 3308 | E: mikal@stillhq.com |
3309 | W: http://www.stillhq.com | 3309 | W: http://www.stillhq.com |
3310 | D: Various janitorial patches | 3310 | D: Various janitorial patches |
3311 | D: mandocs and mandocs_install build targets | 3311 | D: mandocs and mandocs_install build targets |
3312 | S: (Email me and ask) | 3312 | S: (Email me and ask) |
3313 | S: Australia | 3313 | S: Australia |
3314 | 3314 | ||
3315 | N: Henrik Storner | 3315 | N: Henrik Storner |
3316 | E: storner@image.dk | 3316 | E: storner@image.dk |
3317 | W: http://www.image.dk/~storner/ | 3317 | W: http://www.image.dk/~storner/ |
3318 | W: http://www.sslug.dk/ | 3318 | W: http://www.sslug.dk/ |
3319 | D: Configure script: Invented tristate for module-configuration | 3319 | D: Configure script: Invented tristate for module-configuration |
3320 | D: vfat/msdos integration, kerneld docs, Linux promotion | 3320 | D: vfat/msdos integration, kerneld docs, Linux promotion |
3321 | D: Miscellaneous bug-fixes | 3321 | D: Miscellaneous bug-fixes |
3322 | S: Chr. Winthersvej 1 B, st.th. | 3322 | S: Chr. Winthersvej 1 B, st.th. |
3323 | S: DK-1860 Frederiksberg C | 3323 | S: DK-1860 Frederiksberg C |
3324 | S: Denmark | 3324 | S: Denmark |
3325 | 3325 | ||
3326 | N: Drew Sullivan | 3326 | N: Drew Sullivan |
3327 | E: drew@ss.org | 3327 | E: drew@ss.org |
3328 | W: http://www.ss.org/ | 3328 | W: http://www.ss.org/ |
3329 | P: 1024/ACFFA969 5A 9C 42 AB E4 24 82 31 99 56 00 BF D3 2B 25 46 | 3329 | P: 1024/ACFFA969 5A 9C 42 AB E4 24 82 31 99 56 00 BF D3 2B 25 46 |
3330 | D: iBCS2 developer | 3330 | D: iBCS2 developer |
3331 | S: 22 Irvington Cres. | 3331 | S: 22 Irvington Cres. |
3332 | S: Willowdale, Ontario | 3332 | S: Willowdale, Ontario |
3333 | S: Canada M2N 2Z1 | 3333 | S: Canada M2N 2Z1 |
3334 | 3334 | ||
3335 | N: Adam Sulmicki | 3335 | N: Adam Sulmicki |
3336 | E: adam@cfar.umd.edu | 3336 | E: adam@cfar.umd.edu |
3337 | W: http://www.eax.com | 3337 | W: http://www.eax.com |
3338 | D: core networking fixes | 3338 | D: core networking fixes |
3339 | D: patch-kernel enhancements | 3339 | D: patch-kernel enhancements |
3340 | D: misc kernel fixes and updates | 3340 | D: misc kernel fixes and updates |
3341 | 3341 | ||
3342 | N: Adrian Sun | 3342 | N: Adrian Sun |
3343 | E: asun@cobaltnet.com | 3343 | E: asun@cobaltnet.com |
3344 | D: hfs support | 3344 | D: hfs support |
3345 | D: alpha rtc port, random appletalk fixes | 3345 | D: alpha rtc port, random appletalk fixes |
3346 | S: Department of Zoology, University of Washington | 3346 | S: Department of Zoology, University of Washington |
3347 | S: Seattle, WA 98195-1800 | 3347 | S: Seattle, WA 98195-1800 |
3348 | S: USA | 3348 | S: USA |
3349 | 3349 | ||
3350 | N: Eugene Surovegin | 3350 | N: Eugene Surovegin |
3351 | E: ebs@ebshome.net | 3351 | E: ebs@ebshome.net |
3352 | W: http://kernel.ebshome.net/ | 3352 | W: http://kernel.ebshome.net/ |
3353 | P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C 2365 7602 F33D AE54 67F1 | 3353 | P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C 2365 7602 F33D AE54 67F1 |
3354 | D: Embedded PowerPC 4xx: EMAC, I2C, PIC and random hacks/fixes | 3354 | D: Embedded PowerPC 4xx: EMAC, I2C, PIC and random hacks/fixes |
3355 | S: Sunnyvale, California 94085 | 3355 | S: Sunnyvale, California 94085 |
3356 | S: USA | 3356 | S: USA |
3357 | 3357 | ||
3358 | N: Corey Thomas | 3358 | N: Corey Thomas |
3359 | E: corey@world.std.com | 3359 | E: corey@world.std.com |
3360 | W: http://world.std.com/~corey/index.html | 3360 | W: http://world.std.com/~corey/index.html |
3361 | D: Raylink/WebGear wireless LAN device driver (ray_cs) author | 3361 | D: Raylink/WebGear wireless LAN device driver (ray_cs) author |
3362 | S: 145 Howard St. | 3362 | S: 145 Howard St. |
3363 | S: Northborough, MA 01532 | 3363 | S: Northborough, MA 01532 |
3364 | S: USA | 3364 | S: USA |
3365 | 3365 | ||
3366 | N: Tommy Thorn | 3366 | N: Tommy Thorn |
3367 | E: Tommy.Thorn@irisa.fr | 3367 | E: Tommy.Thorn@irisa.fr |
3368 | W: http://www.irisa.fr/prive/thorn/index.html | 3368 | W: http://www.irisa.fr/prive/thorn/index.html |
3369 | P: 512/B4AFC909 BC BF 6D B1 52 26 1E D6 E3 2F A3 24 2A 84 FE 21 | 3369 | P: 512/B4AFC909 BC BF 6D B1 52 26 1E D6 E3 2F A3 24 2A 84 FE 21 |
3370 | D: Device driver hacker (aha1542 & plip) | 3370 | D: Device driver hacker (aha1542 & plip) |
3371 | S: IRISA | 3371 | S: IRISA |
3372 | S: Universit=E9 de Rennes I | 3372 | S: Universit=E9 de Rennes I |
3373 | S: F-35042 Rennes Cedex | 3373 | S: F-35042 Rennes Cedex |
3374 | S: France | 3374 | S: France |
3375 | 3375 | ||
3376 | N: Urs Thuermann | 3376 | N: Urs Thuermann |
3377 | E: urs.thuermann@volkswagen.de | 3377 | E: urs.thuermann@volkswagen.de |
3378 | W: http://www.volkswagen.de | 3378 | W: http://www.volkswagen.de |
3379 | D: Controller Area Network (network layer core) | 3379 | D: Controller Area Network (network layer core) |
3380 | S: Brieffach 1776 | 3380 | S: Brieffach 1776 |
3381 | S: 38436 Wolfsburg | 3381 | S: 38436 Wolfsburg |
3382 | S: Germany | 3382 | S: Germany |
3383 | 3383 | ||
3384 | N: Jon Tombs | 3384 | N: Jon Tombs |
3385 | E: jon@gte.esi.us.es | 3385 | E: jon@gte.esi.us.es |
3386 | W: http://www.esi.us.es/~jon | 3386 | W: http://www.esi.us.es/~jon |
3387 | D: NFS mmap() | 3387 | D: NFS mmap() |
3388 | D: XF86_S3 | 3388 | D: XF86_S3 |
3389 | D: Kernel modules | 3389 | D: Kernel modules |
3390 | D: Parts of various other programs (xfig, open, ...) | 3390 | D: Parts of various other programs (xfig, open, ...) |
3391 | S: C/ Federico Garcia Lorca 1 10-A | 3391 | S: C/ Federico Garcia Lorca 1 10-A |
3392 | S: Sevilla 41005 | 3392 | S: Sevilla 41005 |
3393 | S: Spain | 3393 | S: Spain |
3394 | 3394 | ||
3395 | N: Linus Torvalds | 3395 | N: Linus Torvalds |
3396 | E: torvalds@linux-foundation.org | 3396 | E: torvalds@linux-foundation.org |
3397 | D: Original kernel hacker | 3397 | D: Original kernel hacker |
3398 | S: Portland, Oregon 97005 | 3398 | S: Portland, Oregon 97005 |
3399 | S: USA | 3399 | S: USA |
3400 | 3400 | ||
3401 | N: Marcelo Tosatti | 3401 | N: Marcelo Tosatti |
3402 | E: marcelo@kvack.org | 3402 | E: marcelo@kvack.org |
3403 | D: v2.4 kernel maintainer | 3403 | D: v2.4 kernel maintainer |
3404 | S: Brazil | 3404 | S: Brazil |
3405 | 3405 | ||
3406 | N: Stefan Traby | 3406 | N: Stefan Traby |
3407 | E: stefan@quant-x.com | 3407 | E: stefan@quant-x.com |
3408 | D: Minor Alpha kernel hacks | 3408 | D: Minor Alpha kernel hacks |
3409 | S: Mitterlasznitzstr. 13 | 3409 | S: Mitterlasznitzstr. 13 |
3410 | S: 8302 Nestelbach | 3410 | S: 8302 Nestelbach |
3411 | S: Austria | 3411 | S: Austria |
3412 | 3412 | ||
3413 | N: Jeff Tranter | 3413 | N: Jeff Tranter |
3414 | E: tranter@pobox.com | 3414 | E: tranter@pobox.com |
3415 | D: Enhancements to Joystick driver | 3415 | D: Enhancements to Joystick driver |
3416 | D: Author of Sound HOWTO and CD-ROM HOWTO | 3416 | D: Author of Sound HOWTO and CD-ROM HOWTO |
3417 | D: Author of several small utilities | 3417 | D: Author of several small utilities |
3418 | D: (bogomips, scope, eject, statserial) | 3418 | D: (bogomips, scope, eject, statserial) |
3419 | S: 1 Laurie Court | 3419 | S: 1 Laurie Court |
3420 | S: Kanata, Ontario | 3420 | S: Kanata, Ontario |
3421 | S: Canada K2L 1S2 | 3421 | S: Canada K2L 1S2 |
3422 | 3422 | ||
3423 | N: Andrew Tridgell | 3423 | N: Andrew Tridgell |
3424 | E: tridge@samba.org | 3424 | E: tridge@samba.org |
3425 | W: http://samba.org/tridge/ | 3425 | W: http://samba.org/tridge/ |
3426 | D: dosemu, networking, samba | 3426 | D: dosemu, networking, samba |
3427 | S: 3 Ballow Crescent | 3427 | S: 3 Ballow Crescent |
3428 | S: MacGregor A.C.T 2615 | 3428 | S: MacGregor A.C.T 2615 |
3429 | S: Australia | 3429 | S: Australia |
3430 | 3430 | ||
3431 | N: Josh Triplett | 3431 | N: Josh Triplett |
3432 | E: josh@freedesktop.org | 3432 | E: josh@freedesktop.org |
3433 | P: 1024D/D0FE7AFB B24A 65C9 1D71 2AC2 DE87 CA26 189B 9946 D0FE 7AFB | 3433 | P: 1024D/D0FE7AFB B24A 65C9 1D71 2AC2 DE87 CA26 189B 9946 D0FE 7AFB |
3434 | D: rcutorture maintainer | 3434 | D: rcutorture maintainer |
3435 | D: lock annotations, finding and fixing lock bugs | 3435 | D: lock annotations, finding and fixing lock bugs |
3436 | 3436 | ||
3437 | N: Winfried Trรผmper | 3437 | N: Winfried Trรผmper |
3438 | E: winni@xpilot.org | 3438 | E: winni@xpilot.org |
3439 | W: http://www.shop.de/~winni/ | 3439 | W: http://www.shop.de/~winni/ |
3440 | D: German HOWTO, Crash-Kurs Linux (German, 100 comprehensive pages) | 3440 | D: German HOWTO, Crash-Kurs Linux (German, 100 comprehensive pages) |
3441 | D: CD-Writing HOWTO, various mini-HOWTOs | 3441 | D: CD-Writing HOWTO, various mini-HOWTOs |
3442 | D: One-week tutorials on Linux twice a year (free of charge) | 3442 | D: One-week tutorials on Linux twice a year (free of charge) |
3443 | D: Linux-Workshop Kรถln (aka LUG Cologne, Germany), Installfests | 3443 | D: Linux-Workshop Kรถln (aka LUG Cologne, Germany), Installfests |
3444 | S: Tacitusstr. 6 | 3444 | S: Tacitusstr. 6 |
3445 | S: D-50968 Kรถln | 3445 | S: D-50968 Kรถln |
3446 | 3446 | ||
3447 | N: Tsu-Sheng Tsao | 3447 | N: Tsu-Sheng Tsao |
3448 | E: tsusheng@scf.usc.edu | 3448 | E: tsusheng@scf.usc.edu |
3449 | D: IGMP(Internet Group Management Protocol) version 2 | 3449 | D: IGMP(Internet Group Management Protocol) version 2 |
3450 | S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD | 3450 | S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD |
3451 | S: Taipei | 3451 | S: Taipei |
3452 | S: Taiwan 112 | 3452 | S: Taiwan 112 |
3453 | S: Republic of China | 3453 | S: Republic of China |
3454 | S: 24335 Delta Drive | 3454 | S: 24335 Delta Drive |
3455 | S: Diamond Bar, California 91765 | 3455 | S: Diamond Bar, California 91765 |
3456 | S: USA | 3456 | S: USA |
3457 | 3457 | ||
3458 | N: Theodore Ts'o | 3458 | N: Theodore Ts'o |
3459 | E: tytso@mit.edu | 3459 | E: tytso@mit.edu |
3460 | D: Random Linux hacker | 3460 | D: Random Linux hacker |
3461 | D: Maintainer of tsx-11.mit.edu ftp archive | 3461 | D: Maintainer of tsx-11.mit.edu ftp archive |
3462 | D: Maintainer of c.o.l.* Usenet<->mail gateway | 3462 | D: Maintainer of c.o.l.* Usenet<->mail gateway |
3463 | D: Author of serial driver | 3463 | D: Author of serial driver |
3464 | D: Author of the new e2fsck | 3464 | D: Author of the new e2fsck |
3465 | D: Author of job control and system call restart code | 3465 | D: Author of job control and system call restart code |
3466 | D: Author of ramdisk device driver | 3466 | D: Author of ramdisk device driver |
3467 | D: Author of loopback device driver | 3467 | D: Author of loopback device driver |
3468 | D: Author of /dev/random driver | 3468 | D: Author of /dev/random driver |
3469 | S: MIT Room E40-343 | 3469 | S: MIT Room E40-343 |
3470 | S: 1 Amherst Street | 3470 | S: 1 Amherst Street |
3471 | S: Cambridge, Massachusetts 02139 | 3471 | S: Cambridge, Massachusetts 02139 |
3472 | S: USA | 3472 | S: USA |
3473 | 3473 | ||
3474 | N: Simmule Turner | 3474 | N: Simmule Turner |
3475 | E: sturner@tele-tv.com | 3475 | E: sturner@tele-tv.com |
3476 | D: Added swapping to filesystem | 3476 | D: Added swapping to filesystem |
3477 | S: 4226 Landgreen Street | 3477 | S: 4226 Landgreen Street |
3478 | S: Rockville, Maryland 20853 | 3478 | S: Rockville, Maryland 20853 |
3479 | S: USA | 3479 | S: USA |
3480 | 3480 | ||
3481 | N: Stephen Tweedie | 3481 | N: Stephen Tweedie |
3482 | E: sct@redhat.com | 3482 | E: sct@redhat.com |
3483 | P: 1024/E7A417AD E2 FE A4 20 34 EC ED FC 7D 7E 67 8D E0 31 D1 69 | 3483 | P: 1024/E7A417AD E2 FE A4 20 34 EC ED FC 7D 7E 67 8D E0 31 D1 69 |
3484 | P: 1024D/43BE7544 D2A4 8556 08E6 90E7 076C BA3F 243F 20A4 43BE 7544 | 3484 | P: 1024D/43BE7544 D2A4 8556 08E6 90E7 076C BA3F 243F 20A4 43BE 7544 |
3485 | D: Second extended file system developer | 3485 | D: Second extended file system developer |
3486 | D: General filesystem hacker | 3486 | D: General filesystem hacker |
3487 | D: kswap vm management code | 3487 | D: kswap vm management code |
3488 | S: 44 Campbell Park Crescent | 3488 | S: 44 Campbell Park Crescent |
3489 | S: Edinburgh EH13 0HT | 3489 | S: Edinburgh EH13 0HT |
3490 | S: United Kingdom | 3490 | S: United Kingdom |
3491 | 3491 | ||
3492 | N: Thomas Uhl | 3492 | N: Thomas Uhl |
3493 | E: uhl@sun1.rz.fh-heilbronn.de | 3493 | E: uhl@sun1.rz.fh-heilbronn.de |
3494 | D: Application programmer | 3494 | D: Application programmer |
3495 | D: Linux promoter | 3495 | D: Linux promoter |
3496 | D: Author of a German book on Linux | 3496 | D: Author of a German book on Linux |
3497 | S: Obere Heerbergstrasse 17 | 3497 | S: Obere Heerbergstrasse 17 |
3498 | S: 97078 Wuerzburg | 3498 | S: 97078 Wuerzburg |
3499 | S: Germany | 3499 | S: Germany |
3500 | 3500 | ||
3501 | N: Greg Ungerer | 3501 | N: Greg Ungerer |
3502 | E: gerg@snapgear.com | 3502 | E: gerg@snapgear.com |
3503 | D: uClinux kernel hacker | 3503 | D: uClinux kernel hacker |
3504 | D: Port uClinux to the Motorola ColdFire CPU | 3504 | D: Port uClinux to the Motorola ColdFire CPU |
3505 | D: Author of Stallion multiport serial drivers | 3505 | D: Author of Stallion multiport serial drivers |
3506 | S: SnapGear Inc. | 3506 | S: SnapGear Inc. |
3507 | S: 825 Stanley St | 3507 | S: 825 Stanley St |
3508 | S: Woolloongabba. QLD. 4102 | 3508 | S: Woolloongabba. QLD. 4102 |
3509 | S: Australia | 3509 | S: Australia |
3510 | 3510 | ||
3511 | N: Jeffrey A. Uphoff | 3511 | N: Jeffrey A. Uphoff |
3512 | E: juphoff@transmeta.com | 3512 | E: juphoff@transmeta.com |
3513 | E: jeff.uphoff@linux.org | 3513 | E: jeff.uphoff@linux.org |
3514 | P: 1024/9ED505C5 D7 BB CA AA 10 45 40 1B 16 19 0A C0 38 A0 3E CB | 3514 | P: 1024/9ED505C5 D7 BB CA AA 10 45 40 1B 16 19 0A C0 38 A0 3E CB |
3515 | D: Linux Security/Alert mailing lists' moderator/maintainer. | 3515 | D: Linux Security/Alert mailing lists' moderator/maintainer. |
3516 | D: NSM (rpc.statd) developer. | 3516 | D: NSM (rpc.statd) developer. |
3517 | D: PAM S/Key module developer. | 3517 | D: PAM S/Key module developer. |
3518 | D: 'dip' contributor. | 3518 | D: 'dip' contributor. |
3519 | D: AIPS port, astronomical community support. | 3519 | D: AIPS port, astronomical community support. |
3520 | S: Transmeta Corporation | 3520 | S: Transmeta Corporation |
3521 | S: 2540 Mission College Blvd. | 3521 | S: 2540 Mission College Blvd. |
3522 | S: Santa Clara, CA 95054 | 3522 | S: Santa Clara, CA 95054 |
3523 | S: USA | 3523 | S: USA |
3524 | 3524 | ||
3525 | N: Matthias Urlichs | 3525 | N: Matthias Urlichs |
3526 | E: smurf@smurf.noris.de | 3526 | E: smurf@smurf.noris.de |
3527 | E: smurf@debian.org | 3527 | E: smurf@debian.org |
3528 | E: matthias@urlichs.de | 3528 | E: matthias@urlichs.de |
3529 | D: Consultant, developer, kernel hacker | 3529 | D: Consultant, developer, kernel hacker |
3530 | D: In a previous life, worked on Streams/ISDN/BSD networking code for Linux | 3530 | D: In a previous life, worked on Streams/ISDN/BSD networking code for Linux |
3531 | S: Schleiermacherstrasse 12 | 3531 | S: Schleiermacherstrasse 12 |
3532 | S: 90491 Nuernberg | 3532 | S: 90491 Nuernberg |
3533 | S: Germany | 3533 | S: Germany |
3534 | 3534 | ||
3535 | N: Geert Uytterhoeven | 3535 | N: Geert Uytterhoeven |
3536 | E: geert@linux-m68k.org | 3536 | E: geert@linux-m68k.org |
3537 | W: http://users.telenet.be/geertu/ | 3537 | W: http://users.telenet.be/geertu/ |
3538 | P: 1024/862678A6 C51D 361C 0BD1 4C90 B275 C553 6EEA 11BA 8626 78A6 | 3538 | P: 1024/862678A6 C51D 361C 0BD1 4C90 B275 C553 6EEA 11BA 8626 78A6 |
3539 | D: m68k/Amiga and PPC/CHRP Longtrail coordinator | 3539 | D: m68k/Amiga and PPC/CHRP Longtrail coordinator |
3540 | D: Frame buffer device and XF68_FBDev maintainer | 3540 | D: Frame buffer device and XF68_FBDev maintainer |
3541 | D: m68k IDE maintainer | 3541 | D: m68k IDE maintainer |
3542 | D: Amiga Zorro maintainer | 3542 | D: Amiga Zorro maintainer |
3543 | D: Amiga Buddha and Catweasel chipset IDE | 3543 | D: Amiga Buddha and Catweasel chipset IDE |
3544 | D: Atari Falcon chipset IDE | 3544 | D: Atari Falcon chipset IDE |
3545 | D: Amiga Gayle chipset IDE | 3545 | D: Amiga Gayle chipset IDE |
3546 | D: mipsel NEC DDB Vrc-5074 | 3546 | D: mipsel NEC DDB Vrc-5074 |
3547 | S: Haterbeekstraat 55B | 3547 | S: Haterbeekstraat 55B |
3548 | S: B-3200 Aarschot | 3548 | S: B-3200 Aarschot |
3549 | S: Belgium | 3549 | S: Belgium |
3550 | 3550 | ||
3551 | N: Chris Vance | 3551 | N: Chris Vance |
3552 | E: cvance@tislabs.com | 3552 | E: cvance@tislabs.com |
3553 | E: cvance@nai.com | 3553 | E: cvance@nai.com |
3554 | D: portions of the Linux Security Module (LSM) framework and security modules | 3554 | D: portions of the Linux Security Module (LSM) framework and security modules |
3555 | 3555 | ||
3556 | N: Petr Vandrovec | 3556 | N: Petr Vandrovec |
3557 | E: vandrove@vc.cvut.cz | 3557 | E: vandrove@vc.cvut.cz |
3558 | D: Small contributions to ncpfs | 3558 | D: Small contributions to ncpfs |
3559 | D: Matrox framebuffer driver | 3559 | D: Matrox framebuffer driver |
3560 | S: Chudenicka 8 | 3560 | S: Chudenicka 8 |
3561 | S: 10200 Prague 10, Hostivar | 3561 | S: 10200 Prague 10, Hostivar |
3562 | S: Czech Republic | 3562 | S: Czech Republic |
3563 | 3563 | ||
3564 | N: Thibaut Varene | 3564 | N: Thibaut Varene |
3565 | E: T-Bone@parisc-linux.org | 3565 | E: T-Bone@parisc-linux.org |
3566 | W: http://www.parisc-linux.org/~varenet/ | 3566 | W: http://www.parisc-linux.org/~varenet/ |
3567 | P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 | 3567 | P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 |
3568 | D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits | 3568 | D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits |
3569 | D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there | 3569 | D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there |
3570 | D: AD1889 sound driver | 3570 | D: AD1889 sound driver |
3571 | S: Paris, France | 3571 | S: Paris, France |
3572 | 3572 | ||
3573 | N: Heikki Vatiainen | 3573 | N: Heikki Vatiainen |
3574 | E: hessu@cs.tut.fi | 3574 | E: hessu@cs.tut.fi |
3575 | D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks | 3575 | D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks |
3576 | S: Tampere University of Technology / Telecom lab | 3576 | S: Tampere University of Technology / Telecom lab |
3577 | S: Hermiankatu 12C | 3577 | S: Hermiankatu 12C |
3578 | S: FIN-33720 Tampere | 3578 | S: FIN-33720 Tampere |
3579 | S: Finland | 3579 | S: Finland |
3580 | 3580 | ||
3581 | N: Andrew Veliath | 3581 | N: Andrew Veliath |
3582 | E: andrewtv@usa.net | 3582 | E: andrewtv@usa.net |
3583 | D: Turtle Beach MultiSound sound driver | 3583 | D: Turtle Beach MultiSound sound driver |
3584 | S: USA | 3584 | S: USA |
3585 | 3585 | ||
3586 | N: Dirk Verworner | 3586 | N: Dirk Verworner |
3587 | D: Co-author of German book ``Linux-Kernel-Programmierung'' | 3587 | D: Co-author of German book ``Linux-Kernel-Programmierung'' |
3588 | D: Co-founder of Berlin Linux User Group | 3588 | D: Co-founder of Berlin Linux User Group |
3589 | 3589 | ||
3590 | N: Riku Voipio | 3590 | N: Riku Voipio |
3591 | E: riku.voipio@iki.fi | 3591 | E: riku.voipio@iki.fi |
3592 | D: Author of PCA9532 LED and Fintek f75375s hwmon driver | 3592 | D: Author of PCA9532 LED and Fintek f75375s hwmon driver |
3593 | D: Some random ARM board patches | 3593 | D: Some random ARM board patches |
3594 | S: Finland | 3594 | S: Finland |
3595 | 3595 | ||
3596 | N: Patrick Volkerding | 3596 | N: Patrick Volkerding |
3597 | E: volkerdi@ftp.cdrom.com | 3597 | E: volkerdi@ftp.cdrom.com |
3598 | D: Produced the Slackware distribution, updated the SVGAlib | 3598 | D: Produced the Slackware distribution, updated the SVGAlib |
3599 | D: patches for ghostscript, worked on color 'ls', etc. | 3599 | D: patches for ghostscript, worked on color 'ls', etc. |
3600 | S: 301 15th Street S. | 3600 | S: 301 15th Street S. |
3601 | S: Moorhead, Minnesota 56560 | 3601 | S: Moorhead, Minnesota 56560 |
3602 | S: USA | 3602 | S: USA |
3603 | 3603 | ||
3604 | N: Jos Vos | 3604 | N: Jos Vos |
3605 | E: jos@xos.nl | 3605 | E: jos@xos.nl |
3606 | W: http://www.xos.nl/ | 3606 | W: http://www.xos.nl/ |
3607 | D: Various IP firewall updates, ipfwadm | 3607 | D: Various IP firewall updates, ipfwadm |
3608 | S: X/OS Experts in Open Systems BV | 3608 | S: X/OS Experts in Open Systems BV |
3609 | S: Kruislaan 419 | 3609 | S: Kruislaan 419 |
3610 | S: 1098 VA Amsterdam | 3610 | S: 1098 VA Amsterdam |
3611 | S: The Netherlands | 3611 | S: The Netherlands |
3612 | 3612 | ||
3613 | N: Jeroen Vreeken | 3613 | N: Jeroen Vreeken |
3614 | E: pe1rxq@amsat.org | 3614 | E: pe1rxq@amsat.org |
3615 | W: http://www.chello.nl/~j.vreeken/ | 3615 | W: http://www.chello.nl/~j.vreeken/ |
3616 | D: SE401 usb webcam driver | 3616 | D: SE401 usb webcam driver |
3617 | D: ZD1201 usb wireless lan driver | 3617 | D: ZD1201 usb wireless lan driver |
3618 | S: Maastrichterweg 63 | 3618 | S: Maastrichterweg 63 |
3619 | S: 5554 GG Valkenswaard | 3619 | S: 5554 GG Valkenswaard |
3620 | S: The Netherlands | 3620 | S: The Netherlands |
3621 | 3621 | ||
3622 | N: Mark Wallis | 3622 | N: Mark Wallis |
3623 | E: mwallis@serialmonkey.com | 3623 | E: mwallis@serialmonkey.com |
3624 | W: http://mark.serialmonkey.com | 3624 | W: http://mark.serialmonkey.com |
3625 | D: Ralink rt2x00 WLAN driver | 3625 | D: Ralink rt2x00 WLAN driver |
3626 | S: Newcastle, Australia | 3626 | S: Newcastle, Australia |
3627 | 3627 | ||
3628 | N: Peter Shaobo Wang | 3628 | N: Peter Shaobo Wang |
3629 | E: pwang@mmdcorp.com | 3629 | E: pwang@mmdcorp.com |
3630 | W: http://www.mmdcorp.com/pw/linux | 3630 | W: http://www.mmdcorp.com/pw/linux |
3631 | D: Driver for Interphase ATM (i)Chip SAR adapter card family (x575, x525, x531). | 3631 | D: Driver for Interphase ATM (i)Chip SAR adapter card family (x575, x525, x531). |
3632 | S: 1513 Brewster Dr. | 3632 | S: 1513 Brewster Dr. |
3633 | S: Carrollton, TX 75010 | 3633 | S: Carrollton, TX 75010 |
3634 | S: USA | 3634 | S: USA |
3635 | 3635 | ||
3636 | N: Tim Waugh | 3636 | N: Tim Waugh |
3637 | E: tim@cyberelk.net | 3637 | E: tim@cyberelk.net |
3638 | D: Co-architect of the parallel-port sharing system | 3638 | D: Co-architect of the parallel-port sharing system |
3639 | S: 17 Curling Vale | 3639 | S: 17 Curling Vale |
3640 | S: GUILDFORD | 3640 | S: GUILDFORD |
3641 | S: Surrey | 3641 | S: Surrey |
3642 | S: GU2 7PJ | 3642 | S: GU2 7PJ |
3643 | S: United Kingdom | 3643 | S: United Kingdom |
3644 | 3644 | ||
3645 | N: Juergen Weigert | 3645 | N: Juergen Weigert |
3646 | E: jnweiger@immd4.informatik.uni-erlangen.de | 3646 | E: jnweiger@immd4.informatik.uni-erlangen.de |
3647 | D: The Linux Support Team Erlangen | 3647 | D: The Linux Support Team Erlangen |
3648 | 3648 | ||
3649 | N: David Weinehall | 3649 | N: David Weinehall |
3650 | E: tao@acc.umu.se | 3650 | E: tao@acc.umu.se |
3651 | P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16 | 3651 | P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16 |
3652 | W: http://www.acc.umu.se/~tao/ | 3652 | W: http://www.acc.umu.se/~tao/ |
3653 | D: v2.0 kernel maintainer | 3653 | D: v2.0 kernel maintainer |
3654 | D: Fixes for the NE/2-driver | 3654 | D: Fixes for the NE/2-driver |
3655 | D: Miscellaneous MCA-support | 3655 | D: Miscellaneous MCA-support |
3656 | D: Cleanup of the Config-files | 3656 | D: Cleanup of the Config-files |
3657 | 3657 | ||
3658 | N: Matt Welsh | 3658 | N: Matt Welsh |
3659 | E: mdw@metalab.unc.edu | 3659 | E: mdw@metalab.unc.edu |
3660 | W: http://www.cs.berkeley.edu/~mdw | 3660 | W: http://www.cs.berkeley.edu/~mdw |
3661 | D: Original Linux Documentation Project coordinator | 3661 | D: Original Linux Documentation Project coordinator |
3662 | D: Author, "Running Linux" (O'Reilly) | 3662 | D: Author, "Running Linux" (O'Reilly) |
3663 | D: Author, "Linux Installation and Getting Started" (LDP) and several HOWTOs | 3663 | D: Author, "Linux Installation and Getting Started" (LDP) and several HOWTOs |
3664 | D: Linuxdoc-SGML formatting system (now SGML-Tools) | 3664 | D: Linuxdoc-SGML formatting system (now SGML-Tools) |
3665 | D: Device drivers for various high-speed network interfaces (Myrinet, ATM) | 3665 | D: Device drivers for various high-speed network interfaces (Myrinet, ATM) |
3666 | D: Keithley DAS1200 device driver | 3666 | D: Keithley DAS1200 device driver |
3667 | D: Original maintainer of sunsite WWW and FTP sites | 3667 | D: Original maintainer of sunsite WWW and FTP sites |
3668 | D: Original moderator of c.o.l.announce and c.o.l.answers | 3668 | D: Original moderator of c.o.l.announce and c.o.l.answers |
3669 | S: Computer Science Division | 3669 | S: Computer Science Division |
3670 | S: UC Berkeley | 3670 | S: UC Berkeley |
3671 | S: Berkeley, CA 94720-1776 | 3671 | S: Berkeley, CA 94720-1776 |
3672 | S: USA | 3672 | S: USA |
3673 | 3673 | ||
3674 | N: Harald Welte | 3674 | N: Harald Welte |
3675 | E: laforge@netfilter.org | 3675 | E: laforge@netfilter.org |
3676 | P: 1024D/30F48BFF DBDE 6912 8831 9A53 879B 9190 5DA5 C655 30F4 8BFF | 3676 | P: 1024D/30F48BFF DBDE 6912 8831 9A53 879B 9190 5DA5 C655 30F4 8BFF |
3677 | W: http://gnumonks.org/users/laforge | 3677 | W: http://gnumonks.org/users/laforge |
3678 | D: netfilter: new nat helper infrastructure | 3678 | D: netfilter: new nat helper infrastructure |
3679 | D: netfilter: ULOG, ECN, DSCP target | 3679 | D: netfilter: ULOG, ECN, DSCP target |
3680 | D: netfilter: TTL match | 3680 | D: netfilter: TTL match |
3681 | D: netfilter: IPv6 mangle table | 3681 | D: netfilter: IPv6 mangle table |
3682 | D: netfilter: various other hacks | 3682 | D: netfilter: various other hacks |
3683 | S: Berlin | 3683 | S: Berlin |
3684 | S: Germany | 3684 | S: Germany |
3685 | 3685 | ||
3686 | N: Bill Wendling | 3686 | N: Bill Wendling |
3687 | E: wendling@ganymede.isdn.uiuc.edu | 3687 | E: wendling@ganymede.isdn.uiuc.edu |
3688 | W: http://www.ncsa.uiuc.edu/~wendling/ | 3688 | W: http://www.ncsa.uiuc.edu/~wendling/ |
3689 | D: Various random hacks. Mostly on poll/select logic. | 3689 | D: Various random hacks. Mostly on poll/select logic. |
3690 | S: 605 E. Springfield Ave. | 3690 | S: 605 E. Springfield Ave. |
3691 | S: Champaign, IL 61820 | 3691 | S: Champaign, IL 61820 |
3692 | S: USA | 3692 | S: USA |
3693 | 3693 | ||
3694 | N: Mike Westall | 3694 | N: Mike Westall |
3695 | D: IBM Turboways 25 ATM Device Driver | 3695 | D: IBM Turboways 25 ATM Device Driver |
3696 | E: westall@cs.clemson.edu | 3696 | E: westall@cs.clemson.edu |
3697 | S: Department of Computer Science | 3697 | S: Department of Computer Science |
3698 | S: Clemson University | 3698 | S: Clemson University |
3699 | S: Clemson SC 29634 USA | 3699 | S: Clemson SC 29634 USA |
3700 | 3700 | ||
3701 | N: Greg Wettstein | 3701 | N: Greg Wettstein |
3702 | E: greg@wind.rmcc.com | 3702 | E: greg@wind.rmcc.com |
3703 | D: Filesystem valid flag for MINIX filesystem. | 3703 | D: Filesystem valid flag for MINIX filesystem. |
3704 | D: Minor kernel debugging. | 3704 | D: Minor kernel debugging. |
3705 | D: Development and maintenance of sysklogd. | 3705 | D: Development and maintenance of sysklogd. |
3706 | D: Monitoring of development kernels for long-term stability. | 3706 | D: Monitoring of development kernels for long-term stability. |
3707 | D: Early implementations of Linux in a commercial environment. | 3707 | D: Early implementations of Linux in a commercial environment. |
3708 | S: Dr. Greg Wettstein, Ph.D. | 3708 | S: Dr. Greg Wettstein, Ph.D. |
3709 | S: Oncology Research Division Computing Facility | 3709 | S: Oncology Research Division Computing Facility |
3710 | S: Roger Maris Cancer Center | 3710 | S: Roger Maris Cancer Center |
3711 | S: 820 4th St. N. | 3711 | S: 820 4th St. N. |
3712 | S: Fargo, North Dakota 58122 | 3712 | S: Fargo, North Dakota 58122 |
3713 | S: USA | 3713 | S: USA |
3714 | 3714 | ||
3715 | N: Steven Whitehouse | 3715 | N: Steven Whitehouse |
3716 | E: steve@chygwyn.com | 3716 | E: steve@chygwyn.com |
3717 | W: http://www.chygwyn.com/~steve | 3717 | W: http://www.chygwyn.com/~steve |
3718 | D: Linux DECnet project | 3718 | D: Linux DECnet project |
3719 | D: Minor debugging of other networking protocols. | 3719 | D: Minor debugging of other networking protocols. |
3720 | D: Misc bug fixes and GFS2 filesystem development | 3720 | D: Misc bug fixes and GFS2 filesystem development |
3721 | 3721 | ||
3722 | N: Hans-Joachim Widmaier | 3722 | N: Hans-Joachim Widmaier |
3723 | E: hjw@zvw.de | 3723 | E: hjw@zvw.de |
3724 | D: AFFS rewrite | 3724 | D: AFFS rewrite |
3725 | S: Eichenweg 16 | 3725 | S: Eichenweg 16 |
3726 | S: 73650 Winterbach | 3726 | S: 73650 Winterbach |
3727 | S: Germany | 3727 | S: Germany |
3728 | 3728 | ||
3729 | N: Urban Widmark | 3729 | N: Urban Widmark |
3730 | E: urban@svenskatest.se | 3730 | E: urban@svenskatest.se |
3731 | D: via-rhine, misc net driver hacking | 3731 | D: via-rhine, misc net driver hacking |
3732 | 3732 | ||
3733 | N: Marco van Wieringen | 3733 | N: Marco van Wieringen |
3734 | E: mvw@planets.elm.net | 3734 | E: mvw@planets.elm.net |
3735 | D: Author of process accounting and diskquota | 3735 | D: Author of process accounting and diskquota |
3736 | S: Breeburgsingel 12 | 3736 | S: Breeburgsingel 12 |
3737 | S: 2135 CN Hoofddorp | 3737 | S: 2135 CN Hoofddorp |
3738 | S: The Netherlands | 3738 | S: The Netherlands |
3739 | 3739 | ||
3740 | N: Matthew Wilcox | 3740 | N: Matthew Wilcox |
3741 | E: matthew@wil.cx | 3741 | E: matthew@wil.cx |
3742 | W: ftp://ftp.uk.linux.org/pub/linux/people/willy/ | 3742 | W: ftp://ftp.uk.linux.org/pub/linux/people/willy/ |
3743 | D: Linux/PARISC hacker. Filesystem hacker. Random other hacking. Custom | 3743 | D: Linux/PARISC hacker. Filesystem hacker. Random other hacking. Custom |
3744 | D: PPC port hacking. | 3744 | D: PPC port hacking. |
3745 | 3745 | ||
3746 | N: G\"unter Windau | 3746 | N: G\"unter Windau |
3747 | E: gunter@mbfys.kun.nl | 3747 | E: gunter@mbfys.kun.nl |
3748 | D: Some bug fixes in the polling printer driver (lp.c) | 3748 | D: Some bug fixes in the polling printer driver (lp.c) |
3749 | S: University of Nijmegen | 3749 | S: University of Nijmegen |
3750 | S: Geert-Grooteplein Noord 21 | 3750 | S: Geert-Grooteplein Noord 21 |
3751 | S: 6525 EZ Nijmegen | 3751 | S: 6525 EZ Nijmegen |
3752 | S: The Netherlands | 3752 | S: The Netherlands |
3753 | 3753 | ||
3754 | N: Ulrich Windl | 3754 | N: Ulrich Windl |
3755 | E: Ulrich.Windl@rz.uni-regensburg.de | 3755 | E: Ulrich.Windl@rz.uni-regensburg.de |
3756 | P: 1024/E843660D CF D7 43 A1 5A 49 14 25 7C 04 A0 6E 4C 3A AC 6D | 3756 | P: 1024/E843660D CF D7 43 A1 5A 49 14 25 7C 04 A0 6E 4C 3A AC 6D |
3757 | D: Supports NTP on Linux. Added PPS code. Fixed bugs in adjtimex(). | 3757 | D: Supports NTP on Linux. Added PPS code. Fixed bugs in adjtimex(). |
3758 | S: Alte Regensburger Str. 11a | 3758 | S: Alte Regensburger Str. 11a |
3759 | S: 93149 Nittenau | 3759 | S: 93149 Nittenau |
3760 | S: Germany | 3760 | S: Germany |
3761 | 3761 | ||
3762 | N: Gertjan van Wingerde | 3762 | N: Gertjan van Wingerde |
3763 | E: gwingerde@gmail.com | 3763 | E: gwingerde@gmail.com |
3764 | D: Ralink rt2x00 WLAN driver | 3764 | D: Ralink rt2x00 WLAN driver |
3765 | D: Minix V2 file-system | 3765 | D: Minix V2 file-system |
3766 | D: Misc fixes | 3766 | D: Misc fixes |
3767 | S: Geessinkweg 177 | 3767 | S: Geessinkweg 177 |
3768 | S: 7544 TX Enschede | 3768 | S: 7544 TX Enschede |
3769 | S: The Netherlands | 3769 | S: The Netherlands |
3770 | 3770 | ||
3771 | N: Lars Wirzenius | 3771 | N: Lars Wirzenius |
3772 | E: liw@iki.fi | 3772 | E: liw@iki.fi |
3773 | D: Linux System Administrator's Guide, author, former maintainer | 3773 | D: Linux System Administrator's Guide, author, former maintainer |
3774 | D: comp.os.linux.announce, former moderator | 3774 | D: comp.os.linux.announce, former moderator |
3775 | D: Linux Documentation Project, co-founder | 3775 | D: Linux Documentation Project, co-founder |
3776 | D: Original sprintf in kernel | 3776 | D: Original sprintf in kernel |
3777 | D: Original kernel README (for version 0.97) | 3777 | D: Original kernel README (for version 0.97) |
3778 | D: Linux News (electronic magazine, now dead), founder and former editor | 3778 | D: Linux News (electronic magazine, now dead), founder and former editor |
3779 | D: Meta-FAQ, originator, former maintainer | 3779 | D: Meta-FAQ, originator, former maintainer |
3780 | D: INFO-SHEET, former maintainer | 3780 | D: INFO-SHEET, former maintainer |
3781 | D: Author of the longest-living linux bug | 3781 | D: Author of the longest-living linux bug |
3782 | 3782 | ||
3783 | N: Jonathan Woithe | 3783 | N: Jonathan Woithe |
3784 | E: jwoithe@physics.adelaide.edu.au | 3784 | E: jwoithe@physics.adelaide.edu.au |
3785 | W: http://www.physics.adelaide.edu.au/~jwoithe | 3785 | W: http://www.physics.adelaide.edu.au/~jwoithe |
3786 | D: ALS-007 sound card extensions to Sound Blaster driver | 3786 | D: ALS-007 sound card extensions to Sound Blaster driver |
3787 | S: 20 Jordan St | 3787 | S: 20 Jordan St |
3788 | S: Valley View, SA 5093 | 3788 | S: Valley View, SA 5093 |
3789 | S: Australia | 3789 | S: Australia |
3790 | 3790 | ||
3791 | N: Clifford Wolf | 3791 | N: Clifford Wolf |
3792 | E: god@clifford.at | 3792 | E: god@clifford.at |
3793 | W: http://www.clifford.at/ | 3793 | W: http://www.clifford.at/ |
3794 | D: Menuconfig/lxdialog improvement | 3794 | D: Menuconfig/lxdialog improvement |
3795 | S: Foehrengasse 16 | 3795 | S: Foehrengasse 16 |
3796 | S: A-2333 Leopoldsdorf b. Wien | 3796 | S: A-2333 Leopoldsdorf b. Wien |
3797 | S: Austria | 3797 | S: Austria |
3798 | 3798 | ||
3799 | N: Roger E. Wolff | 3799 | N: Roger E. Wolff |
3800 | E: R.E.Wolff@BitWizard.nl | 3800 | E: R.E.Wolff@BitWizard.nl |
3801 | D: Written kmalloc/kfree | 3801 | D: Written kmalloc/kfree |
3802 | D: Written Specialix IO8+ driver | 3802 | D: Written Specialix IO8+ driver |
3803 | D: Written Specialix SX driver | 3803 | D: Written Specialix SX driver |
3804 | S: van Bronckhorststraat 12 | 3804 | S: van Bronckhorststraat 12 |
3805 | S: 2612 XV Delft | 3805 | S: 2612 XV Delft |
3806 | S: The Netherlands | 3806 | S: The Netherlands |
3807 | 3807 | ||
3808 | N: Thomas Woller | 3808 | N: Thomas Woller |
3809 | D: CS461x Cirrus Logic sound driver | 3809 | D: CS461x Cirrus Logic sound driver |
3810 | 3810 | ||
3811 | N: David Woodhouse | 3811 | N: David Woodhouse |
3812 | E: dwmw2@infradead.org | 3812 | E: dwmw2@infradead.org |
3813 | D: JFFS2 file system, Memory Technology Device subsystem, | 3813 | D: JFFS2 file system, Memory Technology Device subsystem, |
3814 | D: various other stuff that annoyed me by not working. | 3814 | D: various other stuff that annoyed me by not working. |
3815 | S: c/o Intel Corporation | 3815 | S: c/o Intel Corporation |
3816 | S: Pipers Way | 3816 | S: Pipers Way |
3817 | S: Swindon. SN3 1RJ | 3817 | S: Swindon. SN3 1RJ |
3818 | S: England | 3818 | S: England |
3819 | 3819 | ||
3820 | N: Chris Wright | 3820 | N: Chris Wright |
3821 | E: chrisw@sous-sol.org | 3821 | E: chrisw@sous-sol.org |
3822 | D: hacking on LSM framework and security modules. | 3822 | D: hacking on LSM framework and security modules. |
3823 | S: Portland, OR | 3823 | S: Portland, OR |
3824 | S: USA | 3824 | S: USA |
3825 | 3825 | ||
3826 | N: Michal Wronski | 3826 | N: Michal Wronski |
3827 | E: michal.wronski@gmail.com | 3827 | E: michal.wronski@gmail.com |
3828 | D: POSIX message queues fs (with K. Benedyczak) | 3828 | D: POSIX message queues fs (with K. Benedyczak) |
3829 | S: Krakow | 3829 | S: Krakow |
3830 | S: Poland | 3830 | S: Poland |
3831 | 3831 | ||
3832 | N: Frank Xia | 3832 | N: Frank Xia |
3833 | E: qx@math.columbia.edu | 3833 | E: qx@math.columbia.edu |
3834 | D: Xiafs filesystem [defunct] | 3834 | D: Xiafs filesystem [defunct] |
3835 | S: 542 West 112th Street, 5N | 3835 | S: 542 West 112th Street, 5N |
3836 | S: New York, New York 10025 | 3836 | S: New York, New York 10025 |
3837 | S: USA | 3837 | S: USA |
3838 | 3838 | ||
3839 | N: Li Yang | 3839 | N: Li Yang |
3840 | E: leoli@freescale.com | 3840 | E: leoli@freescale.com |
3841 | D: Freescale Highspeed USB device driver | 3841 | D: Freescale Highspeed USB device driver |
3842 | D: Freescale QE SoC support and Ethernet driver | 3842 | D: Freescale QE SoC support and Ethernet driver |
3843 | S: B-1206 Jingmao Guojigongyu | 3843 | S: B-1206 Jingmao Guojigongyu |
3844 | S: 16 Baliqiao Nanjie, Beijing 101100 | 3844 | S: 16 Baliqiao Nanjie, Beijing 101100 |
3845 | S: People's Repulic of China | 3845 | S: People's Repulic of China |
3846 | 3846 | ||
3847 | N: Victor Yodaiken | 3847 | N: Victor Yodaiken |
3848 | E: yodaiken@fsmlabs.com | 3848 | E: yodaiken@fsmlabs.com |
3849 | D: RTLinux (RealTime Linux) | 3849 | D: RTLinux (RealTime Linux) |
3850 | S: POB 1822 | 3850 | S: POB 1822 |
3851 | S: Socorro NM, 87801 | 3851 | S: Socorro NM, 87801 |
3852 | S: USA | 3852 | S: USA |
3853 | 3853 | ||
3854 | N: Hiroshi YOKOTA | 3854 | N: Hiroshi YOKOTA |
3855 | E: yokota@netlab.is.tsukuba.ac.jp | 3855 | E: yokota@netlab.is.tsukuba.ac.jp |
3856 | D: Workbit NinjaSCSI-3/32Bi PCMCIA driver | 3856 | D: Workbit NinjaSCSI-3/32Bi PCMCIA driver |
3857 | D: Workbit NinjaSCSI-32Bi/UDE driver | 3857 | D: Workbit NinjaSCSI-32Bi/UDE driver |
3858 | S: Japan | 3858 | S: Japan |
3859 | 3859 | ||
3860 | N: Hideaki YOSHIFUJI | 3860 | N: Hideaki YOSHIFUJI |
3861 | E: hideaki@yoshifuji.org | 3861 | E: hideaki@yoshifuji.org |
3862 | E: yoshfuji@linux-ipv6.org | 3862 | E: yoshfuji@linux-ipv6.org |
3863 | W: http://www.yoshifuji.org/~hideaki/ | 3863 | W: http://www.yoshifuji.org/~hideaki/ |
3864 | P: 1024D/E0620EEA 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA | 3864 | P: 1024D/E0620EEA 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA |
3865 | D: IPv6 and other networking related stuff | 3865 | D: IPv6 and other networking related stuff |
3866 | D: USAGI/WIDE Project, Keio University | 3866 | D: USAGI/WIDE Project, Keio University |
3867 | S: Jeunet Palace Kawasaki #1-201, 10-2, Furukawa-cho, Saiwai-ku | 3867 | S: Jeunet Palace Kawasaki #1-201, 10-2, Furukawa-cho, Saiwai-ku |
3868 | S: Kawasaki, Kanagawa 212-0025 | 3868 | S: Kawasaki, Kanagawa 212-0025 |
3869 | S: Japan | 3869 | S: Japan |
3870 | 3870 | ||
3871 | N: Eric Youngdale | 3871 | N: Eric Youngdale |
3872 | E: eric@andante.org | 3872 | E: eric@andante.org |
3873 | W: http://www.andante.org | 3873 | W: http://www.andante.org |
3874 | D: General kernel hacker | 3874 | D: General kernel hacker |
3875 | D: SCSI iso9660 and ELF | 3875 | D: SCSI iso9660 and ELF |
3876 | S: 6389 Hawk View Lane | 3876 | S: 6389 Hawk View Lane |
3877 | S: Alexandria, Virginia 22312 | 3877 | S: Alexandria, Virginia 22312 |
3878 | S: USA | 3878 | S: USA |
3879 | 3879 | ||
3880 | N: Niibe Yutaka | 3880 | N: Niibe Yutaka |
3881 | E: gniibe@mri.co.jp | 3881 | E: gniibe@mri.co.jp |
3882 | D: PLIP driver | 3882 | D: PLIP driver |
3883 | D: Asynchronous socket I/O in the NET code | 3883 | D: Asynchronous socket I/O in the NET code |
3884 | S: Mitsubishi Research Institute, Inc. | 3884 | S: Mitsubishi Research Institute, Inc. |
3885 | S: ARCO Tower 1-8-1 Shimomeguro Meguro-ku | 3885 | S: ARCO Tower 1-8-1 Shimomeguro Meguro-ku |
3886 | S: Tokyo 153 | 3886 | S: Tokyo 153 |
3887 | S: Japan | 3887 | S: Japan |
3888 | 3888 | ||
3889 | N: James R. Van Zandt | 3889 | N: James R. Van Zandt |
3890 | E: jrv@vanzandt.mv.com | 3890 | E: jrv@vanzandt.mv.com |
3891 | P: 1024/E298966D F0 37 4F FD E5 7E C5 E6 F1 A0 1E 22 6F 46 DA 0C | 3891 | P: 1024/E298966D F0 37 4F FD E5 7E C5 E6 F1 A0 1E 22 6F 46 DA 0C |
3892 | D: Author and maintainer of the Double Talk speech synthesizer driver | 3892 | D: Author and maintainer of the Double Talk speech synthesizer driver |
3893 | S: 27 Spencer Drive | 3893 | S: 27 Spencer Drive |
3894 | S: Nashua, New Hampshire 03062 | 3894 | S: Nashua, New Hampshire 03062 |
3895 | S: USA | 3895 | S: USA |
3896 | 3896 | ||
3897 | N: Orest Zborowski | 3897 | N: Orest Zborowski |
3898 | E: orestz@eskimo.com | 3898 | E: orestz@eskimo.com |
3899 | D: XFree86 and kernel development | 3899 | D: XFree86 and kernel development |
3900 | S: 1507 145th Place SE #B5 | 3900 | S: 1507 145th Place SE #B5 |
3901 | S: Bellevue, Washington 98007 | 3901 | S: Bellevue, Washington 98007 |
3902 | S: USA | 3902 | S: USA |
3903 | 3903 | ||
3904 | N: Richard Zidlicky | 3904 | N: Richard Zidlicky |
3905 | E: rz@linux-m68k.org, rdzidlic@geocities.com | 3905 | E: rz@linux-m68k.org, rdzidlic@geocities.com |
3906 | W: http://www.geocities.com/rdzidlic | 3906 | W: http://www.geocities.com/rdzidlic |
3907 | D: Q40 port - see arch/m68k/q40/README | 3907 | D: Q40 port - see arch/m68k/q40/README |
3908 | D: various m68k hacks | 3908 | D: various m68k hacks |
3909 | S: Germany | 3909 | S: Germany |
3910 | 3910 | ||
3911 | N: Werner Zimmermann | 3911 | N: Werner Zimmermann |
3912 | E: Werner.Zimmermann@fht-esslingen.de | 3912 | E: Werner.Zimmermann@fht-esslingen.de |
3913 | D: CDROM driver "aztcd" (Aztech/Okano/Orchid/Wearnes) | 3913 | D: CDROM driver "aztcd" (Aztech/Okano/Orchid/Wearnes) |
3914 | S: Flandernstrasse 101 | 3914 | S: Flandernstrasse 101 |
3915 | S: D-73732 Esslingen | 3915 | S: D-73732 Esslingen |
3916 | S: Germany | 3916 | S: Germany |
3917 | 3917 | ||
3918 | N: Leonard N. Zubkoff | 3918 | N: Leonard N. Zubkoff |
3919 | W: http://www.dandelion.com/Linux/ | 3919 | W: http://www.dandelion.com/Linux/ |
3920 | D: BusLogic SCSI driver | 3920 | D: BusLogic SCSI driver |
3921 | D: Mylex DAC960 PCI RAID driver | 3921 | D: Mylex DAC960 PCI RAID driver |
3922 | D: Miscellaneous kernel fixes | 3922 | D: Miscellaneous kernel fixes |
3923 | 3923 | ||
3924 | N: Alessandro Zummo | 3924 | N: Alessandro Zummo |
3925 | E: a.zummo@towertech.it | 3925 | E: a.zummo@towertech.it |
3926 | D: CMI8330 support is sb_card.c | 3926 | D: CMI8330 support is sb_card.c |
3927 | D: ISAPnP fixes in sb_card.c | 3927 | D: ISAPnP fixes in sb_card.c |
3928 | D: ZyXEL omni.net lcd plus driver | 3928 | D: ZyXEL omni.net lcd plus driver |
3929 | D: RTC subsystem | 3929 | D: RTC subsystem |
3930 | S: Italy | 3930 | S: Italy |
3931 | 3931 | ||
3932 | N: Marc Zyngier | 3932 | N: Marc Zyngier |
3933 | E: maz@wild-wind.fr.eu.org | 3933 | E: maz@wild-wind.fr.eu.org |
3934 | W: http://www.misterjones.org | 3934 | W: http://www.misterjones.org |
3935 | D: MD driver | 3935 | D: MD driver |
3936 | D: EISA/sysfs subsystem | 3936 | D: EISA/sysfs subsystem |
3937 | S: France | 3937 | S: France |
3938 | 3938 | ||
3939 | 3939 | ||
3940 | # Don't add your name here, unless you really _are_ after Marc | 3940 | # Don't add your name here, unless you really _are_ after Marc |
3941 | # alphabetically. Leonard used to be very proud of being the | 3941 | # alphabetically. Leonard used to be very proud of being the |
3942 | # last entry, and he'll get positively pissed if he can't even | 3942 | # last entry, and he'll get positively pissed if he can't even |
3943 | # be second-to-last. (and this file really _is_ supposed to be | 3943 | # be second-to-last. (and this file really _is_ supposed to be |
3944 | # in alphabetic order) | 3944 | # in alphabetic order) |
3945 | 3945 |
Documentation/arm/SA1100/ADSBitsy
1 | ADS Bitsy Single Board Computer | 1 | ADS Bitsy Single Board Computer |
2 | (It is different from Bitsy(iPAQ) of Compaq) | 2 | (It is different from Bitsy(iPAQ) of Compaq) |
3 | 3 | ||
4 | For more details, contact Applied Data Systems or see | 4 | For more details, contact Applied Data Systems or see |
5 | http://www.applieddata.net/products.html | 5 | http://www.applieddata.net/products.html |
6 | 6 | ||
7 | The Linux support for this product has been provided by | 7 | The Linux support for this product has been provided by |
8 | Woojung Huh <whuh@applieddata.net> | 8 | Woojung Huh <whuh@applieddata.net> |
9 | 9 | ||
10 | Use 'make adsbitsy_config' before any 'make config'. | 10 | Use 'make adsbitsy_config' before any 'make config'. |
11 | This will set up defaults for ADS Bitsy support. | 11 | This will set up defaults for ADS Bitsy support. |
12 | 12 | ||
13 | The kernel zImage is linked to be loaded and executed at 0xc0400000. | 13 | The kernel zImage is linked to be loaded and executed at 0xc0400000. |
14 | 14 | ||
15 | Linux can be used with the ADS BootLoader that ships with the | 15 | Linux can be used with the ADS BootLoader that ships with the |
16 | newer rev boards. See their documentation on how to load Linux. | 16 | newer rev boards. See their documentation on how to load Linux. |
17 | 17 | ||
18 | Supported peripherals: | 18 | Supported peripherals: |
19 | - SA1100 LCD frame buffer (8/16bpp...sort of) | 19 | - SA1100 LCD frame buffer (8/16bpp...sort of) |
20 | - SA1111 USB Master | 20 | - SA1111 USB Master |
21 | - SA1100 serial port | 21 | - SA1100 serial port |
22 | - pcmcia, compact flash | 22 | - pcmcia, compact flash |
23 | - touchscreen(ucb1200) | 23 | - touchscreen(ucb1200) |
24 | - console on LCD screen | 24 | - console on LCD screen |
25 | - serial ports (ttyS[0-2]) | 25 | - serial ports (ttyS[0-2]) |
26 | - ttyS0 is default for serial console | 26 | - ttyS0 is default for serial console |
27 | 27 | ||
28 | To do: | 28 | To do: |
29 | - everything else! :-) | 29 | - everything else! :-) |
30 | 30 | ||
31 | Notes: | 31 | Notes: |
32 | 32 | ||
33 | - The flash on board is divided into 3 partitions. | 33 | - The flash on board is divided into 3 partitions. |
34 | You should be careful to use flash on board. | 34 | You should be careful to use flash on board. |
35 | It's partition is different from GraphicsClient Plus and GraphicsMaster | 35 | It's partition is different from GraphicsClient Plus and GraphicsMaster |
36 | 36 | ||
37 | - 16bpp mode requires a different cable than what ships with the board. | 37 | - 16bpp mode requires a different cable than what ships with the board. |
38 | Contact ADS or look through the manual to wire your own. Currently, | 38 | Contact ADS or look through the manual to wire your own. Currently, |
39 | if you compile with 16bit mode support and switch into a lower bpp | 39 | if you compile with 16bit mode support and switch into a lower bpp |
40 | mode, the timing is off so the image is corrupted. This will be | 40 | mode, the timing is off so the image is corrupted. This will be |
41 | fixed soon. | 41 | fixed soon. |
42 | 42 | ||
43 | Any contribution can be sent to nico@cam.org and will be greatly welcome! | 43 | Any contribution can be sent to nico@fluxnic.net and will be greatly welcome! |
44 | 44 |
Documentation/arm/SA1100/Assabet
1 | The Intel Assabet (SA-1110 evaluation) board | 1 | The Intel Assabet (SA-1110 evaluation) board |
2 | ============================================ | 2 | ============================================ |
3 | 3 | ||
4 | Please see: | 4 | Please see: |
5 | http://developer.intel.com/design/strong/quicklist/eval-plat/sa-1110.htm | 5 | http://developer.intel.com/design/strong/quicklist/eval-plat/sa-1110.htm |
6 | http://developer.intel.com/design/strong/guides/278278.htm | 6 | http://developer.intel.com/design/strong/guides/278278.htm |
7 | 7 | ||
8 | Also some notes from John G Dorsey <jd5q@andrew.cmu.edu>: | 8 | Also some notes from John G Dorsey <jd5q@andrew.cmu.edu>: |
9 | http://www.cs.cmu.edu/~wearable/software/assabet.html | 9 | http://www.cs.cmu.edu/~wearable/software/assabet.html |
10 | 10 | ||
11 | 11 | ||
12 | Building the kernel | 12 | Building the kernel |
13 | ------------------- | 13 | ------------------- |
14 | 14 | ||
15 | To build the kernel with current defaults: | 15 | To build the kernel with current defaults: |
16 | 16 | ||
17 | make assabet_config | 17 | make assabet_config |
18 | make oldconfig | 18 | make oldconfig |
19 | make zImage | 19 | make zImage |
20 | 20 | ||
21 | The resulting kernel image should be available in linux/arch/arm/boot/zImage. | 21 | The resulting kernel image should be available in linux/arch/arm/boot/zImage. |
22 | 22 | ||
23 | 23 | ||
24 | Installing a bootloader | 24 | Installing a bootloader |
25 | ----------------------- | 25 | ----------------------- |
26 | 26 | ||
27 | A couple of bootloaders able to boot Linux on Assabet are available: | 27 | A couple of bootloaders able to boot Linux on Assabet are available: |
28 | 28 | ||
29 | BLOB (http://www.lartmaker.nl/lartware/blob/) | 29 | BLOB (http://www.lartmaker.nl/lartware/blob/) |
30 | 30 | ||
31 | BLOB is a bootloader used within the LART project. Some contributed | 31 | BLOB is a bootloader used within the LART project. Some contributed |
32 | patches were merged into BLOB to add support for Assabet. | 32 | patches were merged into BLOB to add support for Assabet. |
33 | 33 | ||
34 | Compaq's Bootldr + John Dorsey's patch for Assabet support | 34 | Compaq's Bootldr + John Dorsey's patch for Assabet support |
35 | (http://www.handhelds.org/Compaq/bootldr.html) | 35 | (http://www.handhelds.org/Compaq/bootldr.html) |
36 | (http://www.wearablegroup.org/software/bootldr/) | 36 | (http://www.wearablegroup.org/software/bootldr/) |
37 | 37 | ||
38 | Bootldr is the bootloader developed by Compaq for the iPAQ Pocket PC. | 38 | Bootldr is the bootloader developed by Compaq for the iPAQ Pocket PC. |
39 | John Dorsey has produced add-on patches to add support for Assabet and | 39 | John Dorsey has produced add-on patches to add support for Assabet and |
40 | the JFFS filesystem. | 40 | the JFFS filesystem. |
41 | 41 | ||
42 | RedBoot (http://sources.redhat.com/redboot/) | 42 | RedBoot (http://sources.redhat.com/redboot/) |
43 | 43 | ||
44 | RedBoot is a bootloader developed by Red Hat based on the eCos RTOS | 44 | RedBoot is a bootloader developed by Red Hat based on the eCos RTOS |
45 | hardware abstraction layer. It supports Assabet amongst many other | 45 | hardware abstraction layer. It supports Assabet amongst many other |
46 | hardware platforms. | 46 | hardware platforms. |
47 | 47 | ||
48 | RedBoot is currently the recommended choice since it's the only one to have | 48 | RedBoot is currently the recommended choice since it's the only one to have |
49 | networking support, and is the most actively maintained. | 49 | networking support, and is the most actively maintained. |
50 | 50 | ||
51 | Brief examples on how to boot Linux with RedBoot are shown below. But first | 51 | Brief examples on how to boot Linux with RedBoot are shown below. But first |
52 | you need to have RedBoot installed in your flash memory. A known to work | 52 | you need to have RedBoot installed in your flash memory. A known to work |
53 | precompiled RedBoot binary is available from the following location: | 53 | precompiled RedBoot binary is available from the following location: |
54 | 54 | ||
55 | ftp://ftp.netwinder.org/users/n/nico/ | 55 | ftp://ftp.netwinder.org/users/n/nico/ |
56 | ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/nico/ | 56 | ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/nico/ |
57 | ftp://ftp.handhelds.org/pub/linux/arm/sa-1100-patches/ | 57 | ftp://ftp.handhelds.org/pub/linux/arm/sa-1100-patches/ |
58 | 58 | ||
59 | Look for redboot-assabet*.tgz. Some installation infos are provided in | 59 | Look for redboot-assabet*.tgz. Some installation infos are provided in |
60 | redboot-assabet*.txt. | 60 | redboot-assabet*.txt. |
61 | 61 | ||
62 | 62 | ||
63 | Initial RedBoot configuration | 63 | Initial RedBoot configuration |
64 | ----------------------------- | 64 | ----------------------------- |
65 | 65 | ||
66 | The commands used here are explained in The RedBoot User's Guide available | 66 | The commands used here are explained in The RedBoot User's Guide available |
67 | on-line at http://sources.redhat.com/ecos/docs-latest/redboot/redboot.html. | 67 | on-line at http://sources.redhat.com/ecos/docs-latest/redboot/redboot.html. |
68 | Please refer to it for explanations. | 68 | Please refer to it for explanations. |
69 | 69 | ||
70 | If you have a CF network card (my Assabet kit contained a CF+ LP-E from | 70 | If you have a CF network card (my Assabet kit contained a CF+ LP-E from |
71 | Socket Communications Inc.), you should strongly consider using it for TFTP | 71 | Socket Communications Inc.), you should strongly consider using it for TFTP |
72 | file transfers. You must insert it before RedBoot runs since it can't detect | 72 | file transfers. You must insert it before RedBoot runs since it can't detect |
73 | it dynamically. | 73 | it dynamically. |
74 | 74 | ||
75 | To initialize the flash directory: | 75 | To initialize the flash directory: |
76 | 76 | ||
77 | fis init -f | 77 | fis init -f |
78 | 78 | ||
79 | To initialize the non-volatile settings, like whether you want to use BOOTP or | 79 | To initialize the non-volatile settings, like whether you want to use BOOTP or |
80 | a static IP address, etc, use this command: | 80 | a static IP address, etc, use this command: |
81 | 81 | ||
82 | fconfig -i | 82 | fconfig -i |
83 | 83 | ||
84 | 84 | ||
85 | Writing a kernel image into flash | 85 | Writing a kernel image into flash |
86 | --------------------------------- | 86 | --------------------------------- |
87 | 87 | ||
88 | First, the kernel image must be loaded into RAM. If you have the zImage file | 88 | First, the kernel image must be loaded into RAM. If you have the zImage file |
89 | available on a TFTP server: | 89 | available on a TFTP server: |
90 | 90 | ||
91 | load zImage -r -b 0x100000 | 91 | load zImage -r -b 0x100000 |
92 | 92 | ||
93 | If you rather want to use Y-Modem upload over the serial port: | 93 | If you rather want to use Y-Modem upload over the serial port: |
94 | 94 | ||
95 | load -m ymodem -r -b 0x100000 | 95 | load -m ymodem -r -b 0x100000 |
96 | 96 | ||
97 | To write it to flash: | 97 | To write it to flash: |
98 | 98 | ||
99 | fis create "Linux kernel" -b 0x100000 -l 0xc0000 | 99 | fis create "Linux kernel" -b 0x100000 -l 0xc0000 |
100 | 100 | ||
101 | 101 | ||
102 | Booting the kernel | 102 | Booting the kernel |
103 | ------------------ | 103 | ------------------ |
104 | 104 | ||
105 | The kernel still requires a filesystem to boot. A ramdisk image can be loaded | 105 | The kernel still requires a filesystem to boot. A ramdisk image can be loaded |
106 | as follows: | 106 | as follows: |
107 | 107 | ||
108 | load ramdisk_image.gz -r -b 0x800000 | 108 | load ramdisk_image.gz -r -b 0x800000 |
109 | 109 | ||
110 | Again, Y-Modem upload can be used instead of TFTP by replacing the file name | 110 | Again, Y-Modem upload can be used instead of TFTP by replacing the file name |
111 | by '-y ymodem'. | 111 | by '-y ymodem'. |
112 | 112 | ||
113 | Now the kernel can be retrieved from flash like this: | 113 | Now the kernel can be retrieved from flash like this: |
114 | 114 | ||
115 | fis load "Linux kernel" | 115 | fis load "Linux kernel" |
116 | 116 | ||
117 | or loaded as described previously. To boot the kernel: | 117 | or loaded as described previously. To boot the kernel: |
118 | 118 | ||
119 | exec -b 0x100000 -l 0xc0000 | 119 | exec -b 0x100000 -l 0xc0000 |
120 | 120 | ||
121 | The ramdisk image could be stored into flash as well, but there are better | 121 | The ramdisk image could be stored into flash as well, but there are better |
122 | solutions for on-flash filesystems as mentioned below. | 122 | solutions for on-flash filesystems as mentioned below. |
123 | 123 | ||
124 | 124 | ||
125 | Using JFFS2 | 125 | Using JFFS2 |
126 | ----------- | 126 | ----------- |
127 | 127 | ||
128 | Using JFFS2 (the Second Journalling Flash File System) is probably the most | 128 | Using JFFS2 (the Second Journalling Flash File System) is probably the most |
129 | convenient way to store a writable filesystem into flash. JFFS2 is used in | 129 | convenient way to store a writable filesystem into flash. JFFS2 is used in |
130 | conjunction with the MTD layer which is responsible for low-level flash | 130 | conjunction with the MTD layer which is responsible for low-level flash |
131 | management. More information on the Linux MTD can be found on-line at: | 131 | management. More information on the Linux MTD can be found on-line at: |
132 | http://www.linux-mtd.infradead.org/. A JFFS howto with some infos about | 132 | http://www.linux-mtd.infradead.org/. A JFFS howto with some infos about |
133 | creating JFFS/JFFS2 images is available from the same site. | 133 | creating JFFS/JFFS2 images is available from the same site. |
134 | 134 | ||
135 | For instance, a sample JFFS2 image can be retrieved from the same FTP sites | 135 | For instance, a sample JFFS2 image can be retrieved from the same FTP sites |
136 | mentioned below for the precompiled RedBoot image. | 136 | mentioned below for the precompiled RedBoot image. |
137 | 137 | ||
138 | To load this file: | 138 | To load this file: |
139 | 139 | ||
140 | load sample_img.jffs2 -r -b 0x100000 | 140 | load sample_img.jffs2 -r -b 0x100000 |
141 | 141 | ||
142 | The result should look like: | 142 | The result should look like: |
143 | 143 | ||
144 | RedBoot> load sample_img.jffs2 -r -b 0x100000 | 144 | RedBoot> load sample_img.jffs2 -r -b 0x100000 |
145 | Raw file loaded 0x00100000-0x00377424 | 145 | Raw file loaded 0x00100000-0x00377424 |
146 | 146 | ||
147 | Now we must know the size of the unallocated flash: | 147 | Now we must know the size of the unallocated flash: |
148 | 148 | ||
149 | fis free | 149 | fis free |
150 | 150 | ||
151 | Result: | 151 | Result: |
152 | 152 | ||
153 | RedBoot> fis free | 153 | RedBoot> fis free |
154 | 0x500E0000 .. 0x503C0000 | 154 | 0x500E0000 .. 0x503C0000 |
155 | 155 | ||
156 | The values above may be different depending on the size of the filesystem and | 156 | The values above may be different depending on the size of the filesystem and |
157 | the type of flash. See their usage below as an example and take care of | 157 | the type of flash. See their usage below as an example and take care of |
158 | substituting yours appropriately. | 158 | substituting yours appropriately. |
159 | 159 | ||
160 | We must determine some values: | 160 | We must determine some values: |
161 | 161 | ||
162 | size of unallocated flash: 0x503c0000 - 0x500e0000 = 0x2e0000 | 162 | size of unallocated flash: 0x503c0000 - 0x500e0000 = 0x2e0000 |
163 | size of the filesystem image: 0x00377424 - 0x00100000 = 0x277424 | 163 | size of the filesystem image: 0x00377424 - 0x00100000 = 0x277424 |
164 | 164 | ||
165 | We want to fit the filesystem image of course, but we also want to give it all | 165 | We want to fit the filesystem image of course, but we also want to give it all |
166 | the remaining flash space as well. To write it: | 166 | the remaining flash space as well. To write it: |
167 | 167 | ||
168 | fis unlock -f 0x500E0000 -l 0x2e0000 | 168 | fis unlock -f 0x500E0000 -l 0x2e0000 |
169 | fis erase -f 0x500E0000 -l 0x2e0000 | 169 | fis erase -f 0x500E0000 -l 0x2e0000 |
170 | fis write -b 0x100000 -l 0x277424 -f 0x500E0000 | 170 | fis write -b 0x100000 -l 0x277424 -f 0x500E0000 |
171 | fis create "JFFS2" -n -f 0x500E0000 -l 0x2e0000 | 171 | fis create "JFFS2" -n -f 0x500E0000 -l 0x2e0000 |
172 | 172 | ||
173 | Now the filesystem is associated to a MTD "partition" once Linux has discovered | 173 | Now the filesystem is associated to a MTD "partition" once Linux has discovered |
174 | what they are in the boot process. From Redboot, the 'fis list' command | 174 | what they are in the boot process. From Redboot, the 'fis list' command |
175 | displays them: | 175 | displays them: |
176 | 176 | ||
177 | RedBoot> fis list | 177 | RedBoot> fis list |
178 | Name FLASH addr Mem addr Length Entry point | 178 | Name FLASH addr Mem addr Length Entry point |
179 | RedBoot 0x50000000 0x50000000 0x00020000 0x00000000 | 179 | RedBoot 0x50000000 0x50000000 0x00020000 0x00000000 |
180 | RedBoot config 0x503C0000 0x503C0000 0x00020000 0x00000000 | 180 | RedBoot config 0x503C0000 0x503C0000 0x00020000 0x00000000 |
181 | FIS directory 0x503E0000 0x503E0000 0x00020000 0x00000000 | 181 | FIS directory 0x503E0000 0x503E0000 0x00020000 0x00000000 |
182 | Linux kernel 0x50020000 0x00100000 0x000C0000 0x00000000 | 182 | Linux kernel 0x50020000 0x00100000 0x000C0000 0x00000000 |
183 | JFFS2 0x500E0000 0x500E0000 0x002E0000 0x00000000 | 183 | JFFS2 0x500E0000 0x500E0000 0x002E0000 0x00000000 |
184 | 184 | ||
185 | However Linux should display something like: | 185 | However Linux should display something like: |
186 | 186 | ||
187 | SA1100 flash: probing 32-bit flash bus | 187 | SA1100 flash: probing 32-bit flash bus |
188 | SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode | 188 | SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode |
189 | Using RedBoot partition definition | 189 | Using RedBoot partition definition |
190 | Creating 5 MTD partitions on "SA1100 flash": | 190 | Creating 5 MTD partitions on "SA1100 flash": |
191 | 0x00000000-0x00020000 : "RedBoot" | 191 | 0x00000000-0x00020000 : "RedBoot" |
192 | 0x00020000-0x000e0000 : "Linux kernel" | 192 | 0x00020000-0x000e0000 : "Linux kernel" |
193 | 0x000e0000-0x003c0000 : "JFFS2" | 193 | 0x000e0000-0x003c0000 : "JFFS2" |
194 | 0x003c0000-0x003e0000 : "RedBoot config" | 194 | 0x003c0000-0x003e0000 : "RedBoot config" |
195 | 0x003e0000-0x00400000 : "FIS directory" | 195 | 0x003e0000-0x00400000 : "FIS directory" |
196 | 196 | ||
197 | What's important here is the position of the partition we are interested in, | 197 | What's important here is the position of the partition we are interested in, |
198 | which is the third one. Within Linux, this correspond to /dev/mtdblock2. | 198 | which is the third one. Within Linux, this correspond to /dev/mtdblock2. |
199 | Therefore to boot Linux with the kernel and its root filesystem in flash, we | 199 | Therefore to boot Linux with the kernel and its root filesystem in flash, we |
200 | need this RedBoot command: | 200 | need this RedBoot command: |
201 | 201 | ||
202 | fis load "Linux kernel" | 202 | fis load "Linux kernel" |
203 | exec -b 0x100000 -l 0xc0000 -c "root=/dev/mtdblock2" | 203 | exec -b 0x100000 -l 0xc0000 -c "root=/dev/mtdblock2" |
204 | 204 | ||
205 | Of course other filesystems than JFFS might be used, like cramfs for example. | 205 | Of course other filesystems than JFFS might be used, like cramfs for example. |
206 | You might want to boot with a root filesystem over NFS, etc. It is also | 206 | You might want to boot with a root filesystem over NFS, etc. It is also |
207 | possible, and sometimes more convenient, to flash a filesystem directly from | 207 | possible, and sometimes more convenient, to flash a filesystem directly from |
208 | within Linux while booted from a ramdisk or NFS. The Linux MTD repository has | 208 | within Linux while booted from a ramdisk or NFS. The Linux MTD repository has |
209 | many tools to deal with flash memory as well, to erase it for example. JFFS2 | 209 | many tools to deal with flash memory as well, to erase it for example. JFFS2 |
210 | can then be mounted directly on a freshly erased partition and files can be | 210 | can then be mounted directly on a freshly erased partition and files can be |
211 | copied over directly. Etc... | 211 | copied over directly. Etc... |
212 | 212 | ||
213 | 213 | ||
214 | RedBoot scripting | 214 | RedBoot scripting |
215 | ----------------- | 215 | ----------------- |
216 | 216 | ||
217 | All the commands above aren't so useful if they have to be typed in every | 217 | All the commands above aren't so useful if they have to be typed in every |
218 | time the Assabet is rebooted. Therefore it's possible to automatize the boot | 218 | time the Assabet is rebooted. Therefore it's possible to automatize the boot |
219 | process using RedBoot's scripting capability. | 219 | process using RedBoot's scripting capability. |
220 | 220 | ||
221 | For example, I use this to boot Linux with both the kernel and the ramdisk | 221 | For example, I use this to boot Linux with both the kernel and the ramdisk |
222 | images retrieved from a TFTP server on the network: | 222 | images retrieved from a TFTP server on the network: |
223 | 223 | ||
224 | RedBoot> fconfig | 224 | RedBoot> fconfig |
225 | Run script at boot: false true | 225 | Run script at boot: false true |
226 | Boot script: | 226 | Boot script: |
227 | Enter script, terminate with empty line | 227 | Enter script, terminate with empty line |
228 | >> load zImage -r -b 0x100000 | 228 | >> load zImage -r -b 0x100000 |
229 | >> load ramdisk_ks.gz -r -b 0x800000 | 229 | >> load ramdisk_ks.gz -r -b 0x800000 |
230 | >> exec -b 0x100000 -l 0xc0000 | 230 | >> exec -b 0x100000 -l 0xc0000 |
231 | >> | 231 | >> |
232 | Boot script timeout (1000ms resolution): 3 | 232 | Boot script timeout (1000ms resolution): 3 |
233 | Use BOOTP for network configuration: true | 233 | Use BOOTP for network configuration: true |
234 | GDB connection port: 9000 | 234 | GDB connection port: 9000 |
235 | Network debug at boot time: false | 235 | Network debug at boot time: false |
236 | Update RedBoot non-volatile configuration - are you sure (y/n)? y | 236 | Update RedBoot non-volatile configuration - are you sure (y/n)? y |
237 | 237 | ||
238 | Then, rebooting the Assabet is just a matter of waiting for the login prompt. | 238 | Then, rebooting the Assabet is just a matter of waiting for the login prompt. |
239 | 239 | ||
240 | 240 | ||
241 | 241 | ||
242 | Nicolas Pitre | 242 | Nicolas Pitre |
243 | nico@cam.org | 243 | nico@fluxnic.net |
244 | June 12, 2001 | 244 | June 12, 2001 |
245 | 245 | ||
246 | 246 | ||
247 | Status of peripherals in -rmk tree (updated 14/10/2001) | 247 | Status of peripherals in -rmk tree (updated 14/10/2001) |
248 | ------------------------------------------------------- | 248 | ------------------------------------------------------- |
249 | 249 | ||
250 | Assabet: | 250 | Assabet: |
251 | Serial ports: | 251 | Serial ports: |
252 | Radio: TX, RX, CTS, DSR, DCD, RI | 252 | Radio: TX, RX, CTS, DSR, DCD, RI |
253 | PM: Not tested. | 253 | PM: Not tested. |
254 | COM: TX, RX, CTS, DSR, DCD, RTS, DTR, PM | 254 | COM: TX, RX, CTS, DSR, DCD, RTS, DTR, PM |
255 | PM: Not tested. | 255 | PM: Not tested. |
256 | I2C: Implemented, not fully tested. | 256 | I2C: Implemented, not fully tested. |
257 | L3: Fully tested, pass. | 257 | L3: Fully tested, pass. |
258 | PM: Not tested. | 258 | PM: Not tested. |
259 | 259 | ||
260 | Video: | 260 | Video: |
261 | LCD: Fully tested. PM | 261 | LCD: Fully tested. PM |
262 | (LCD doesn't like being blanked with | 262 | (LCD doesn't like being blanked with |
263 | neponset connected) | 263 | neponset connected) |
264 | Video out: Not fully | 264 | Video out: Not fully |
265 | 265 | ||
266 | Audio: | 266 | Audio: |
267 | UDA1341: | 267 | UDA1341: |
268 | Playback: Fully tested, pass. | 268 | Playback: Fully tested, pass. |
269 | Record: Implemented, not tested. | 269 | Record: Implemented, not tested. |
270 | PM: Not tested. | 270 | PM: Not tested. |
271 | 271 | ||
272 | UCB1200: | 272 | UCB1200: |
273 | Audio play: Implemented, not heavily tested. | 273 | Audio play: Implemented, not heavily tested. |
274 | Audio rec: Implemented, not heavily tested. | 274 | Audio rec: Implemented, not heavily tested. |
275 | Telco audio play: Implemented, not heavily tested. | 275 | Telco audio play: Implemented, not heavily tested. |
276 | Telco audio rec: Implemented, not heavily tested. | 276 | Telco audio rec: Implemented, not heavily tested. |
277 | POTS control: No | 277 | POTS control: No |
278 | Touchscreen: Yes | 278 | Touchscreen: Yes |
279 | PM: Not tested. | 279 | PM: Not tested. |
280 | 280 | ||
281 | Other: | 281 | Other: |
282 | PCMCIA: | 282 | PCMCIA: |
283 | LPE: Fully tested, pass. | 283 | LPE: Fully tested, pass. |
284 | USB: No | 284 | USB: No |
285 | IRDA: | 285 | IRDA: |
286 | SIR: Fully tested, pass. | 286 | SIR: Fully tested, pass. |
287 | FIR: Fully tested, pass. | 287 | FIR: Fully tested, pass. |
288 | PM: Not tested. | 288 | PM: Not tested. |
289 | 289 | ||
290 | Neponset: | 290 | Neponset: |
291 | Serial ports: | 291 | Serial ports: |
292 | COM1,2: TX, RX, CTS, DSR, DCD, RTS, DTR | 292 | COM1,2: TX, RX, CTS, DSR, DCD, RTS, DTR |
293 | PM: Not tested. | 293 | PM: Not tested. |
294 | USB: Implemented, not heavily tested. | 294 | USB: Implemented, not heavily tested. |
295 | PCMCIA: Implemented, not heavily tested. | 295 | PCMCIA: Implemented, not heavily tested. |
296 | PM: Not tested. | 296 | PM: Not tested. |
297 | CF: Implemented, not heavily tested. | 297 | CF: Implemented, not heavily tested. |
298 | PM: Not tested. | 298 | PM: Not tested. |
299 | 299 | ||
300 | More stuff can be found in the -np (Nicolas Pitre's) tree. | 300 | More stuff can be found in the -np (Nicolas Pitre's) tree. |
301 | 301 | ||
302 | 302 |
Documentation/arm/SA1100/Brutus
1 | Brutus is an evaluation platform for the SA1100 manufactured by Intel. | 1 | Brutus is an evaluation platform for the SA1100 manufactured by Intel. |
2 | For more details, see: | 2 | For more details, see: |
3 | 3 | ||
4 | http://developer.intel.com/design/strong/applnots/sa1100lx/getstart.htm | 4 | http://developer.intel.com/design/strong/applnots/sa1100lx/getstart.htm |
5 | 5 | ||
6 | To compile for Brutus, you must issue the following commands: | 6 | To compile for Brutus, you must issue the following commands: |
7 | 7 | ||
8 | make brutus_config | 8 | make brutus_config |
9 | make config | 9 | make config |
10 | [accept all the defaults] | 10 | [accept all the defaults] |
11 | make zImage | 11 | make zImage |
12 | 12 | ||
13 | The resulting kernel will end up in linux/arch/arm/boot/zImage. This file | 13 | The resulting kernel will end up in linux/arch/arm/boot/zImage. This file |
14 | must be loaded at 0xc0008000 in Brutus's memory and execution started at | 14 | must be loaded at 0xc0008000 in Brutus's memory and execution started at |
15 | 0xc0008000 as well with the value of registers r0 = 0 and r1 = 16 upon | 15 | 0xc0008000 as well with the value of registers r0 = 0 and r1 = 16 upon |
16 | entry. | 16 | entry. |
17 | 17 | ||
18 | But prior to execute the kernel, a ramdisk image must also be loaded in | 18 | But prior to execute the kernel, a ramdisk image must also be loaded in |
19 | memory. Use memory address 0xd8000000 for this. Note that the file | 19 | memory. Use memory address 0xd8000000 for this. Note that the file |
20 | containing the (compressed) ramdisk image must not exceed 4 MB. | 20 | containing the (compressed) ramdisk image must not exceed 4 MB. |
21 | 21 | ||
22 | Typically, you'll need angelboot to load the kernel. | 22 | Typically, you'll need angelboot to load the kernel. |
23 | The following angelboot.opt file should be used: | 23 | The following angelboot.opt file should be used: |
24 | 24 | ||
25 | ----- begin angelboot.opt ----- | 25 | ----- begin angelboot.opt ----- |
26 | base 0xc0008000 | 26 | base 0xc0008000 |
27 | entry 0xc0008000 | 27 | entry 0xc0008000 |
28 | r0 0x00000000 | 28 | r0 0x00000000 |
29 | r1 0x00000010 | 29 | r1 0x00000010 |
30 | device /dev/ttyS0 | 30 | device /dev/ttyS0 |
31 | options "9600 8N1" | 31 | options "9600 8N1" |
32 | baud 115200 | 32 | baud 115200 |
33 | otherfile ramdisk_img.gz | 33 | otherfile ramdisk_img.gz |
34 | otherbase 0xd8000000 | 34 | otherbase 0xd8000000 |
35 | ----- end angelboot.opt ----- | 35 | ----- end angelboot.opt ----- |
36 | 36 | ||
37 | Then load the kernel and ramdisk with: | 37 | Then load the kernel and ramdisk with: |
38 | 38 | ||
39 | angelboot -f angelboot.opt zImage | 39 | angelboot -f angelboot.opt zImage |
40 | 40 | ||
41 | The first Brutus serial port (assumed to be linked to /dev/ttyS0 on your | 41 | The first Brutus serial port (assumed to be linked to /dev/ttyS0 on your |
42 | host PC) is used by angel to load the kernel and ramdisk image. The serial | 42 | host PC) is used by angel to load the kernel and ramdisk image. The serial |
43 | console is provided through the second Brutus serial port. To access it, | 43 | console is provided through the second Brutus serial port. To access it, |
44 | you may use minicom configured with /dev/ttyS1, 9600 baud, 8N1, no flow | 44 | you may use minicom configured with /dev/ttyS1, 9600 baud, 8N1, no flow |
45 | control. | 45 | control. |
46 | 46 | ||
47 | Currently supported: | 47 | Currently supported: |
48 | - RS232 serial ports | 48 | - RS232 serial ports |
49 | - audio output | 49 | - audio output |
50 | - LCD screen | 50 | - LCD screen |
51 | - keyboard | 51 | - keyboard |
52 | 52 | ||
53 | The actual Brutus support may not be complete without extra patches. | 53 | The actual Brutus support may not be complete without extra patches. |
54 | If such patches exist, they should be found from | 54 | If such patches exist, they should be found from |
55 | ftp.netwinder.org/users/n/nico. | 55 | ftp.netwinder.org/users/n/nico. |
56 | 56 | ||
57 | A full PCMCIA support is still missing, although it's possible to hack | 57 | A full PCMCIA support is still missing, although it's possible to hack |
58 | some drivers in order to drive already inserted cards at boot time with | 58 | some drivers in order to drive already inserted cards at boot time with |
59 | little modifications. | 59 | little modifications. |
60 | 60 | ||
61 | Any contribution is welcome. | 61 | Any contribution is welcome. |
62 | 62 | ||
63 | Please send patches to nico@cam.org | 63 | Please send patches to nico@fluxnic.net |
64 | 64 | ||
65 | Have Fun ! | 65 | Have Fun ! |
66 | 66 | ||
67 | 67 |
Documentation/arm/SA1100/GraphicsClient
1 | ADS GraphicsClient Plus Single Board Computer | 1 | ADS GraphicsClient Plus Single Board Computer |
2 | 2 | ||
3 | For more details, contact Applied Data Systems or see | 3 | For more details, contact Applied Data Systems or see |
4 | http://www.applieddata.net/products.html | 4 | http://www.applieddata.net/products.html |
5 | 5 | ||
6 | The original Linux support for this product has been provided by | 6 | The original Linux support for this product has been provided by |
7 | Nicolas Pitre <nico@cam.org>. Continued development work by | 7 | Nicolas Pitre <nico@fluxnic.net>. Continued development work by |
8 | Woojung Huh <whuh@applieddata.net> | 8 | Woojung Huh <whuh@applieddata.net> |
9 | 9 | ||
10 | It's currently possible to mount a root filesystem via NFS providing a | 10 | It's currently possible to mount a root filesystem via NFS providing a |
11 | complete Linux environment. Otherwise a ramdisk image may be used. The | 11 | complete Linux environment. Otherwise a ramdisk image may be used. The |
12 | board supports MTD/JFFS, so you could also mount something on there. | 12 | board supports MTD/JFFS, so you could also mount something on there. |
13 | 13 | ||
14 | Use 'make graphicsclient_config' before any 'make config'. This will set up | 14 | Use 'make graphicsclient_config' before any 'make config'. This will set up |
15 | defaults for GraphicsClient Plus support. | 15 | defaults for GraphicsClient Plus support. |
16 | 16 | ||
17 | The kernel zImage is linked to be loaded and executed at 0xc0200000. | 17 | The kernel zImage is linked to be loaded and executed at 0xc0200000. |
18 | Also the following registers should have the specified values upon entry: | 18 | Also the following registers should have the specified values upon entry: |
19 | 19 | ||
20 | r0 = 0 | 20 | r0 = 0 |
21 | r1 = 29 (this is the GraphicsClient architecture number) | 21 | r1 = 29 (this is the GraphicsClient architecture number) |
22 | 22 | ||
23 | Linux can be used with the ADS BootLoader that ships with the | 23 | Linux can be used with the ADS BootLoader that ships with the |
24 | newer rev boards. See their documentation on how to load Linux. | 24 | newer rev boards. See their documentation on how to load Linux. |
25 | Angel is not available for the GraphicsClient Plus AFAIK. | 25 | Angel is not available for the GraphicsClient Plus AFAIK. |
26 | 26 | ||
27 | There is a board known as just the GraphicsClient that ADS used to | 27 | There is a board known as just the GraphicsClient that ADS used to |
28 | produce but has end of lifed. This code will not work on the older | 28 | produce but has end of lifed. This code will not work on the older |
29 | board with the ADS bootloader, but should still work with Angel, | 29 | board with the ADS bootloader, but should still work with Angel, |
30 | as outlined below. In any case, if you're planning on deploying | 30 | as outlined below. In any case, if you're planning on deploying |
31 | something en masse, you should probably get the newer board. | 31 | something en masse, you should probably get the newer board. |
32 | 32 | ||
33 | If using Angel on the older boards, here is a typical angel.opt option file | 33 | If using Angel on the older boards, here is a typical angel.opt option file |
34 | if the kernel is loaded through the Angel Debug Monitor: | 34 | if the kernel is loaded through the Angel Debug Monitor: |
35 | 35 | ||
36 | ----- begin angelboot.opt ----- | 36 | ----- begin angelboot.opt ----- |
37 | base 0xc0200000 | 37 | base 0xc0200000 |
38 | entry 0xc0200000 | 38 | entry 0xc0200000 |
39 | r0 0x00000000 | 39 | r0 0x00000000 |
40 | r1 0x0000001d | 40 | r1 0x0000001d |
41 | device /dev/ttyS1 | 41 | device /dev/ttyS1 |
42 | options "38400 8N1" | 42 | options "38400 8N1" |
43 | baud 115200 | 43 | baud 115200 |
44 | #otherfile ramdisk.gz | 44 | #otherfile ramdisk.gz |
45 | #otherbase 0xc0800000 | 45 | #otherbase 0xc0800000 |
46 | exec minicom | 46 | exec minicom |
47 | ----- end angelboot.opt ----- | 47 | ----- end angelboot.opt ----- |
48 | 48 | ||
49 | Then the kernel (and ramdisk if otherfile/otherbase lines above are | 49 | Then the kernel (and ramdisk if otherfile/otherbase lines above are |
50 | uncommented) would be loaded with: | 50 | uncommented) would be loaded with: |
51 | 51 | ||
52 | angelboot -f angelboot.opt zImage | 52 | angelboot -f angelboot.opt zImage |
53 | 53 | ||
54 | Here it is assumed that the board is connected to ttyS1 on your PC | 54 | Here it is assumed that the board is connected to ttyS1 on your PC |
55 | and that minicom is preconfigured with /dev/ttyS1, 38400 baud, 8N1, no flow | 55 | and that minicom is preconfigured with /dev/ttyS1, 38400 baud, 8N1, no flow |
56 | control by default. | 56 | control by default. |
57 | 57 | ||
58 | If any other bootloader is used, ensure it accomplish the same, especially | 58 | If any other bootloader is used, ensure it accomplish the same, especially |
59 | for r0/r1 register values before jumping into the kernel. | 59 | for r0/r1 register values before jumping into the kernel. |
60 | 60 | ||
61 | 61 | ||
62 | Supported peripherals: | 62 | Supported peripherals: |
63 | - SA1100 LCD frame buffer (8/16bpp...sort of) | 63 | - SA1100 LCD frame buffer (8/16bpp...sort of) |
64 | - on-board SMC 92C96 ethernet NIC | 64 | - on-board SMC 92C96 ethernet NIC |
65 | - SA1100 serial port | 65 | - SA1100 serial port |
66 | - flash memory access (MTD/JFFS) | 66 | - flash memory access (MTD/JFFS) |
67 | - pcmcia | 67 | - pcmcia |
68 | - touchscreen(ucb1200) | 68 | - touchscreen(ucb1200) |
69 | - ps/2 keyboard | 69 | - ps/2 keyboard |
70 | - console on LCD screen | 70 | - console on LCD screen |
71 | - serial ports (ttyS[0-2]) | 71 | - serial ports (ttyS[0-2]) |
72 | - ttyS0 is default for serial console | 72 | - ttyS0 is default for serial console |
73 | - Smart I/O (ADC, keypad, digital inputs, etc) | 73 | - Smart I/O (ADC, keypad, digital inputs, etc) |
74 | See http://www.applieddata.com/developers/linux for IOCTL documentation | 74 | See http://www.applieddata.com/developers/linux for IOCTL documentation |
75 | and example user space code. ps/2 keybd is multiplexed through this driver | 75 | and example user space code. ps/2 keybd is multiplexed through this driver |
76 | 76 | ||
77 | To do: | 77 | To do: |
78 | - UCB1200 audio with new ucb_generic layer | 78 | - UCB1200 audio with new ucb_generic layer |
79 | - everything else! :-) | 79 | - everything else! :-) |
80 | 80 | ||
81 | Notes: | 81 | Notes: |
82 | 82 | ||
83 | - The flash on board is divided into 3 partitions. mtd0 is where | 83 | - The flash on board is divided into 3 partitions. mtd0 is where |
84 | the ADS boot ROM and zImage is stored. It's been marked as | 84 | the ADS boot ROM and zImage is stored. It's been marked as |
85 | read-only to keep you from blasting over the bootloader. :) mtd1 is | 85 | read-only to keep you from blasting over the bootloader. :) mtd1 is |
86 | for the ramdisk.gz image. mtd2 is user flash space and can be | 86 | for the ramdisk.gz image. mtd2 is user flash space and can be |
87 | utilized for either JFFS or if you're feeling crazy, running ext2 | 87 | utilized for either JFFS or if you're feeling crazy, running ext2 |
88 | on top of it. If you're not using the ADS bootloader, you're | 88 | on top of it. If you're not using the ADS bootloader, you're |
89 | welcome to blast over the mtd1 partition also. | 89 | welcome to blast over the mtd1 partition also. |
90 | 90 | ||
91 | - 16bpp mode requires a different cable than what ships with the board. | 91 | - 16bpp mode requires a different cable than what ships with the board. |
92 | Contact ADS or look through the manual to wire your own. Currently, | 92 | Contact ADS or look through the manual to wire your own. Currently, |
93 | if you compile with 16bit mode support and switch into a lower bpp | 93 | if you compile with 16bit mode support and switch into a lower bpp |
94 | mode, the timing is off so the image is corrupted. This will be | 94 | mode, the timing is off so the image is corrupted. This will be |
95 | fixed soon. | 95 | fixed soon. |
96 | 96 | ||
97 | Any contribution can be sent to nico@cam.org and will be greatly welcome! | 97 | Any contribution can be sent to nico@fluxnic.net and will be greatly welcome! |
98 | 98 | ||
99 | 99 |
Documentation/arm/SA1100/GraphicsMaster
1 | ADS GraphicsMaster Single Board Computer | 1 | ADS GraphicsMaster Single Board Computer |
2 | 2 | ||
3 | For more details, contact Applied Data Systems or see | 3 | For more details, contact Applied Data Systems or see |
4 | http://www.applieddata.net/products.html | 4 | http://www.applieddata.net/products.html |
5 | 5 | ||
6 | The original Linux support for this product has been provided by | 6 | The original Linux support for this product has been provided by |
7 | Nicolas Pitre <nico@cam.org>. Continued development work by | 7 | Nicolas Pitre <nico@fluxnic.net>. Continued development work by |
8 | Woojung Huh <whuh@applieddata.net> | 8 | Woojung Huh <whuh@applieddata.net> |
9 | 9 | ||
10 | Use 'make graphicsmaster_config' before any 'make config'. | 10 | Use 'make graphicsmaster_config' before any 'make config'. |
11 | This will set up defaults for GraphicsMaster support. | 11 | This will set up defaults for GraphicsMaster support. |
12 | 12 | ||
13 | The kernel zImage is linked to be loaded and executed at 0xc0400000. | 13 | The kernel zImage is linked to be loaded and executed at 0xc0400000. |
14 | 14 | ||
15 | Linux can be used with the ADS BootLoader that ships with the | 15 | Linux can be used with the ADS BootLoader that ships with the |
16 | newer rev boards. See their documentation on how to load Linux. | 16 | newer rev boards. See their documentation on how to load Linux. |
17 | 17 | ||
18 | Supported peripherals: | 18 | Supported peripherals: |
19 | - SA1100 LCD frame buffer (8/16bpp...sort of) | 19 | - SA1100 LCD frame buffer (8/16bpp...sort of) |
20 | - SA1111 USB Master | 20 | - SA1111 USB Master |
21 | - on-board SMC 92C96 ethernet NIC | 21 | - on-board SMC 92C96 ethernet NIC |
22 | - SA1100 serial port | 22 | - SA1100 serial port |
23 | - flash memory access (MTD/JFFS) | 23 | - flash memory access (MTD/JFFS) |
24 | - pcmcia, compact flash | 24 | - pcmcia, compact flash |
25 | - touchscreen(ucb1200) | 25 | - touchscreen(ucb1200) |
26 | - ps/2 keyboard | 26 | - ps/2 keyboard |
27 | - console on LCD screen | 27 | - console on LCD screen |
28 | - serial ports (ttyS[0-2]) | 28 | - serial ports (ttyS[0-2]) |
29 | - ttyS0 is default for serial console | 29 | - ttyS0 is default for serial console |
30 | - Smart I/O (ADC, keypad, digital inputs, etc) | 30 | - Smart I/O (ADC, keypad, digital inputs, etc) |
31 | See http://www.applieddata.com/developers/linux for IOCTL documentation | 31 | See http://www.applieddata.com/developers/linux for IOCTL documentation |
32 | and example user space code. ps/2 keybd is multiplexed through this driver | 32 | and example user space code. ps/2 keybd is multiplexed through this driver |
33 | 33 | ||
34 | To do: | 34 | To do: |
35 | - everything else! :-) | 35 | - everything else! :-) |
36 | 36 | ||
37 | Notes: | 37 | Notes: |
38 | 38 | ||
39 | - The flash on board is divided into 3 partitions. mtd0 is where | 39 | - The flash on board is divided into 3 partitions. mtd0 is where |
40 | the zImage is stored. It's been marked as read-only to keep you | 40 | the zImage is stored. It's been marked as read-only to keep you |
41 | from blasting over the bootloader. :) mtd1 is | 41 | from blasting over the bootloader. :) mtd1 is |
42 | for the ramdisk.gz image. mtd2 is user flash space and can be | 42 | for the ramdisk.gz image. mtd2 is user flash space and can be |
43 | utilized for either JFFS or if you're feeling crazy, running ext2 | 43 | utilized for either JFFS or if you're feeling crazy, running ext2 |
44 | on top of it. If you're not using the ADS bootloader, you're | 44 | on top of it. If you're not using the ADS bootloader, you're |
45 | welcome to blast over the mtd1 partition also. | 45 | welcome to blast over the mtd1 partition also. |
46 | 46 | ||
47 | - 16bpp mode requires a different cable than what ships with the board. | 47 | - 16bpp mode requires a different cable than what ships with the board. |
48 | Contact ADS or look through the manual to wire your own. Currently, | 48 | Contact ADS or look through the manual to wire your own. Currently, |
49 | if you compile with 16bit mode support and switch into a lower bpp | 49 | if you compile with 16bit mode support and switch into a lower bpp |
50 | mode, the timing is off so the image is corrupted. This will be | 50 | mode, the timing is off so the image is corrupted. This will be |
51 | fixed soon. | 51 | fixed soon. |
52 | 52 | ||
53 | Any contribution can be sent to nico@cam.org and will be greatly welcome! | 53 | Any contribution can be sent to nico@fluxnic.net and will be greatly welcome! |
54 | 54 |
Documentation/arm/SA1100/Victor
1 | Victor is known as a "digital talking book player" manufactured by | 1 | Victor is known as a "digital talking book player" manufactured by |
2 | VisuAide, Inc. to be used by blind people. | 2 | VisuAide, Inc. to be used by blind people. |
3 | 3 | ||
4 | For more information related to Victor, see: | 4 | For more information related to Victor, see: |
5 | 5 | ||
6 | http://www.visuaide.com/victor | 6 | http://www.visuaide.com/victor |
7 | 7 | ||
8 | Of course Victor is using Linux as its main operating system. | 8 | Of course Victor is using Linux as its main operating system. |
9 | The Victor implementation for Linux is maintained by Nicolas Pitre: | 9 | The Victor implementation for Linux is maintained by Nicolas Pitre: |
10 | 10 | ||
11 | nico@visuaide.com | 11 | nico@visuaide.com |
12 | nico@cam.org | 12 | nico@fluxnic.net |
13 | 13 | ||
14 | For any comments, please feel free to contact me through the above | 14 | For any comments, please feel free to contact me through the above |
15 | addresses. | 15 | addresses. |
16 | 16 | ||
17 | 17 |
MAINTAINERS
1 | 1 | ||
2 | List of maintainers and how to submit kernel changes | 2 | List of maintainers and how to submit kernel changes |
3 | 3 | ||
4 | Please try to follow the guidelines below. This will make things | 4 | Please try to follow the guidelines below. This will make things |
5 | easier on the maintainers. Not all of these guidelines matter for every | 5 | easier on the maintainers. Not all of these guidelines matter for every |
6 | trivial patch so apply some common sense. | 6 | trivial patch so apply some common sense. |
7 | 7 | ||
8 | 1. Always _test_ your changes, however small, on at least 4 or | 8 | 1. Always _test_ your changes, however small, on at least 4 or |
9 | 5 people, preferably many more. | 9 | 5 people, preferably many more. |
10 | 10 | ||
11 | 2. Try to release a few ALPHA test versions to the net. Announce | 11 | 2. Try to release a few ALPHA test versions to the net. Announce |
12 | them onto the kernel channel and await results. This is especially | 12 | them onto the kernel channel and await results. This is especially |
13 | important for device drivers, because often that's the only way | 13 | important for device drivers, because often that's the only way |
14 | you will find things like the fact version 3 firmware needs | 14 | you will find things like the fact version 3 firmware needs |
15 | a magic fix you didn't know about, or some clown changed the | 15 | a magic fix you didn't know about, or some clown changed the |
16 | chips on a board and not its name. (Don't laugh! Look at the | 16 | chips on a board and not its name. (Don't laugh! Look at the |
17 | SMC etherpower for that.) | 17 | SMC etherpower for that.) |
18 | 18 | ||
19 | 3. Make sure your changes compile correctly in multiple | 19 | 3. Make sure your changes compile correctly in multiple |
20 | configurations. In particular check that changes work both as a | 20 | configurations. In particular check that changes work both as a |
21 | module and built into the kernel. | 21 | module and built into the kernel. |
22 | 22 | ||
23 | 4. When you are happy with a change make it generally available for | 23 | 4. When you are happy with a change make it generally available for |
24 | testing and await feedback. | 24 | testing and await feedback. |
25 | 25 | ||
26 | 5. Make a patch available to the relevant maintainer in the list. Use | 26 | 5. Make a patch available to the relevant maintainer in the list. Use |
27 | 'diff -u' to make the patch easy to merge. Be prepared to get your | 27 | 'diff -u' to make the patch easy to merge. Be prepared to get your |
28 | changes sent back with seemingly silly requests about formatting | 28 | changes sent back with seemingly silly requests about formatting |
29 | and variable names. These aren't as silly as they seem. One | 29 | and variable names. These aren't as silly as they seem. One |
30 | job the maintainers (and especially Linus) do is to keep things | 30 | job the maintainers (and especially Linus) do is to keep things |
31 | looking the same. Sometimes this means that the clever hack in | 31 | looking the same. Sometimes this means that the clever hack in |
32 | your driver to get around a problem actually needs to become a | 32 | your driver to get around a problem actually needs to become a |
33 | generalized kernel feature ready for next time. | 33 | generalized kernel feature ready for next time. |
34 | 34 | ||
35 | PLEASE check your patch with the automated style checker | 35 | PLEASE check your patch with the automated style checker |
36 | (scripts/checkpatch.pl) to catch trival style violations. | 36 | (scripts/checkpatch.pl) to catch trival style violations. |
37 | See Documentation/CodingStyle for guidance here. | 37 | See Documentation/CodingStyle for guidance here. |
38 | 38 | ||
39 | PLEASE CC: the maintainers and mailing lists that are generated | 39 | PLEASE CC: the maintainers and mailing lists that are generated |
40 | by scripts/get_maintainer.pl. The results returned by the | 40 | by scripts/get_maintainer.pl. The results returned by the |
41 | script will be best if you have git installed and are making | 41 | script will be best if you have git installed and are making |
42 | your changes in a branch derived from Linus' latest git tree. | 42 | your changes in a branch derived from Linus' latest git tree. |
43 | See Documentation/SubmittingPatches for details. | 43 | See Documentation/SubmittingPatches for details. |
44 | 44 | ||
45 | PLEASE try to include any credit lines you want added with the | 45 | PLEASE try to include any credit lines you want added with the |
46 | patch. It avoids people being missed off by mistake and makes | 46 | patch. It avoids people being missed off by mistake and makes |
47 | it easier to know who wants adding and who doesn't. | 47 | it easier to know who wants adding and who doesn't. |
48 | 48 | ||
49 | PLEASE document known bugs. If it doesn't work for everything | 49 | PLEASE document known bugs. If it doesn't work for everything |
50 | or does something very odd once a month document it. | 50 | or does something very odd once a month document it. |
51 | 51 | ||
52 | PLEASE remember that submissions must be made under the terms | 52 | PLEASE remember that submissions must be made under the terms |
53 | of the OSDL certificate of contribution and should include a | 53 | of the OSDL certificate of contribution and should include a |
54 | Signed-off-by: line. The current version of this "Developer's | 54 | Signed-off-by: line. The current version of this "Developer's |
55 | Certificate of Origin" (DCO) is listed in the file | 55 | Certificate of Origin" (DCO) is listed in the file |
56 | Documentation/SubmittingPatches. | 56 | Documentation/SubmittingPatches. |
57 | 57 | ||
58 | 6. Make sure you have the right to send any changes you make. If you | 58 | 6. Make sure you have the right to send any changes you make. If you |
59 | do changes at work you may find your employer owns the patch | 59 | do changes at work you may find your employer owns the patch |
60 | not you. | 60 | not you. |
61 | 61 | ||
62 | 7. When sending security related changes or reports to a maintainer | 62 | 7. When sending security related changes or reports to a maintainer |
63 | please Cc: security@kernel.org, especially if the maintainer | 63 | please Cc: security@kernel.org, especially if the maintainer |
64 | does not respond. | 64 | does not respond. |
65 | 65 | ||
66 | 8. Happy hacking. | 66 | 8. Happy hacking. |
67 | 67 | ||
68 | ----------------------------------- | 68 | ----------------------------------- |
69 | 69 | ||
70 | Maintainers List (try to look for most precise areas first) | 70 | Maintainers List (try to look for most precise areas first) |
71 | 71 | ||
72 | Note: For the hard of thinking, this list is meant to remain in alphabetical | 72 | Note: For the hard of thinking, this list is meant to remain in alphabetical |
73 | order. If you could add yourselves to it in alphabetical order that would be | 73 | order. If you could add yourselves to it in alphabetical order that would be |
74 | so much easier [Ed] | 74 | so much easier [Ed] |
75 | 75 | ||
76 | P: Person (obsolete) | 76 | P: Person (obsolete) |
77 | M: Mail patches to: FullName <address@domain> | 77 | M: Mail patches to: FullName <address@domain> |
78 | L: Mailing list that is relevant to this area | 78 | L: Mailing list that is relevant to this area |
79 | W: Web-page with status/info | 79 | W: Web-page with status/info |
80 | T: SCM tree type and location. Type is one of: git, hg, quilt, stgit. | 80 | T: SCM tree type and location. Type is one of: git, hg, quilt, stgit. |
81 | S: Status, one of the following: | 81 | S: Status, one of the following: |
82 | 82 | ||
83 | Supported: Someone is actually paid to look after this. | 83 | Supported: Someone is actually paid to look after this. |
84 | Maintained: Someone actually looks after it. | 84 | Maintained: Someone actually looks after it. |
85 | Odd Fixes: It has a maintainer but they don't have time to do | 85 | Odd Fixes: It has a maintainer but they don't have time to do |
86 | much other than throw the odd patch in. See below.. | 86 | much other than throw the odd patch in. See below.. |
87 | Orphan: No current maintainer [but maybe you could take the | 87 | Orphan: No current maintainer [but maybe you could take the |
88 | role as you write your new code]. | 88 | role as you write your new code]. |
89 | Obsolete: Old code. Something tagged obsolete generally means | 89 | Obsolete: Old code. Something tagged obsolete generally means |
90 | it has been replaced by a better system and you | 90 | it has been replaced by a better system and you |
91 | should be using that. | 91 | should be using that. |
92 | 92 | ||
93 | F: Files and directories with wildcard patterns. | 93 | F: Files and directories with wildcard patterns. |
94 | A trailing slash includes all files and subdirectory files. | 94 | A trailing slash includes all files and subdirectory files. |
95 | F: drivers/net/ all files in and below drivers/net | 95 | F: drivers/net/ all files in and below drivers/net |
96 | F: drivers/net/* all files in drivers/net, but not below | 96 | F: drivers/net/* all files in drivers/net, but not below |
97 | F: */net/* all files in "any top level directory"/net | 97 | F: */net/* all files in "any top level directory"/net |
98 | One pattern per line. Multiple F: lines acceptable. | 98 | One pattern per line. Multiple F: lines acceptable. |
99 | X: Files and directories that are NOT maintained, same rules as F: | 99 | X: Files and directories that are NOT maintained, same rules as F: |
100 | Files exclusions are tested before file matches. | 100 | Files exclusions are tested before file matches. |
101 | Can be useful for excluding a specific subdirectory, for instance: | 101 | Can be useful for excluding a specific subdirectory, for instance: |
102 | F: net/ | 102 | F: net/ |
103 | X: net/ipv6/ | 103 | X: net/ipv6/ |
104 | matches all files in and below net excluding net/ipv6/ | 104 | matches all files in and below net excluding net/ipv6/ |
105 | 105 | ||
106 | 3C505 NETWORK DRIVER | 106 | 3C505 NETWORK DRIVER |
107 | M: Philip Blundell <philb@gnu.org> | 107 | M: Philip Blundell <philb@gnu.org> |
108 | L: netdev@vger.kernel.org | 108 | L: netdev@vger.kernel.org |
109 | S: Maintained | 109 | S: Maintained |
110 | F: drivers/net/3c505* | 110 | F: drivers/net/3c505* |
111 | 111 | ||
112 | 3C59X NETWORK DRIVER | 112 | 3C59X NETWORK DRIVER |
113 | M: Steffen Klassert <klassert@mathematik.tu-chemnitz.de> | 113 | M: Steffen Klassert <klassert@mathematik.tu-chemnitz.de> |
114 | L: netdev@vger.kernel.org | 114 | L: netdev@vger.kernel.org |
115 | S: Maintained | 115 | S: Maintained |
116 | F: Documentation/networking/vortex.txt | 116 | F: Documentation/networking/vortex.txt |
117 | F: drivers/net/3c59x.c | 117 | F: drivers/net/3c59x.c |
118 | 118 | ||
119 | 3CR990 NETWORK DRIVER | 119 | 3CR990 NETWORK DRIVER |
120 | M: David Dillow <dave@thedillows.org> | 120 | M: David Dillow <dave@thedillows.org> |
121 | L: netdev@vger.kernel.org | 121 | L: netdev@vger.kernel.org |
122 | S: Maintained | 122 | S: Maintained |
123 | F: drivers/net/typhoon* | 123 | F: drivers/net/typhoon* |
124 | 124 | ||
125 | 3W-9XXX SATA-RAID CONTROLLER DRIVER | 125 | 3W-9XXX SATA-RAID CONTROLLER DRIVER |
126 | M: Adam Radford <linuxraid@amcc.com> | 126 | M: Adam Radford <linuxraid@amcc.com> |
127 | L: linux-scsi@vger.kernel.org | 127 | L: linux-scsi@vger.kernel.org |
128 | W: http://www.amcc.com | 128 | W: http://www.amcc.com |
129 | S: Supported | 129 | S: Supported |
130 | F: drivers/scsi/3w-9xxx* | 130 | F: drivers/scsi/3w-9xxx* |
131 | 131 | ||
132 | 3W-XXXX ATA-RAID CONTROLLER DRIVER | 132 | 3W-XXXX ATA-RAID CONTROLLER DRIVER |
133 | M: Adam Radford <linuxraid@amcc.com> | 133 | M: Adam Radford <linuxraid@amcc.com> |
134 | L: linux-scsi@vger.kernel.org | 134 | L: linux-scsi@vger.kernel.org |
135 | W: http://www.amcc.com | 135 | W: http://www.amcc.com |
136 | S: Supported | 136 | S: Supported |
137 | F: drivers/scsi/3w-xxxx* | 137 | F: drivers/scsi/3w-xxxx* |
138 | 138 | ||
139 | 53C700 AND 53C700-66 SCSI DRIVER | 139 | 53C700 AND 53C700-66 SCSI DRIVER |
140 | M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> | 140 | M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> |
141 | L: linux-scsi@vger.kernel.org | 141 | L: linux-scsi@vger.kernel.org |
142 | S: Maintained | 142 | S: Maintained |
143 | F: drivers/scsi/53c700* | 143 | F: drivers/scsi/53c700* |
144 | 144 | ||
145 | 6PACK NETWORK DRIVER FOR AX.25 | 145 | 6PACK NETWORK DRIVER FOR AX.25 |
146 | M: Andreas Koensgen <ajk@comnets.uni-bremen.de> | 146 | M: Andreas Koensgen <ajk@comnets.uni-bremen.de> |
147 | L: linux-hams@vger.kernel.org | 147 | L: linux-hams@vger.kernel.org |
148 | S: Maintained | 148 | S: Maintained |
149 | F: drivers/net/hamradio/6pack.c | 149 | F: drivers/net/hamradio/6pack.c |
150 | 150 | ||
151 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER | 151 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER |
152 | M: Francois Romieu <romieu@fr.zoreil.com> | 152 | M: Francois Romieu <romieu@fr.zoreil.com> |
153 | L: netdev@vger.kernel.org | 153 | L: netdev@vger.kernel.org |
154 | S: Maintained | 154 | S: Maintained |
155 | F: drivers/net/r8169.c | 155 | F: drivers/net/r8169.c |
156 | 156 | ||
157 | 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER | 157 | 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER |
158 | L: linux-serial@vger.kernel.org | 158 | L: linux-serial@vger.kernel.org |
159 | W: http://serial.sourceforge.net | 159 | W: http://serial.sourceforge.net |
160 | S: Orphan | 160 | S: Orphan |
161 | F: drivers/serial/8250* | 161 | F: drivers/serial/8250* |
162 | F: include/linux/serial_8250.h | 162 | F: include/linux/serial_8250.h |
163 | 163 | ||
164 | 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.] | 164 | 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.] |
165 | M: Paul Gortmaker <p_gortmaker@yahoo.com> | 165 | M: Paul Gortmaker <p_gortmaker@yahoo.com> |
166 | L: netdev@vger.kernel.org | 166 | L: netdev@vger.kernel.org |
167 | S: Maintained | 167 | S: Maintained |
168 | F: drivers/net/*8390* | 168 | F: drivers/net/*8390* |
169 | F: drivers/net/ax88796.c | 169 | F: drivers/net/ax88796.c |
170 | 170 | ||
171 | 9P FILE SYSTEM | 171 | 9P FILE SYSTEM |
172 | M: Eric Van Hensbergen <ericvh@gmail.com> | 172 | M: Eric Van Hensbergen <ericvh@gmail.com> |
173 | M: Ron Minnich <rminnich@sandia.gov> | 173 | M: Ron Minnich <rminnich@sandia.gov> |
174 | M: Latchesar Ionkov <lucho@ionkov.net> | 174 | M: Latchesar Ionkov <lucho@ionkov.net> |
175 | L: v9fs-developer@lists.sourceforge.net | 175 | L: v9fs-developer@lists.sourceforge.net |
176 | W: http://swik.net/v9fs | 176 | W: http://swik.net/v9fs |
177 | T: git git://git.kernel.org/pub/scm/linux/kernel/ericvh/v9fs.git | 177 | T: git git://git.kernel.org/pub/scm/linux/kernel/ericvh/v9fs.git |
178 | S: Maintained | 178 | S: Maintained |
179 | F: Documentation/filesystems/9p.txt | 179 | F: Documentation/filesystems/9p.txt |
180 | F: fs/9p/ | 180 | F: fs/9p/ |
181 | 181 | ||
182 | A2232 SERIAL BOARD DRIVER | 182 | A2232 SERIAL BOARD DRIVER |
183 | M: Enver Haase <A2232@gmx.net> | 183 | M: Enver Haase <A2232@gmx.net> |
184 | L: linux-m68k@lists.linux-m68k.org | 184 | L: linux-m68k@lists.linux-m68k.org |
185 | S: Maintained | 185 | S: Maintained |
186 | F: drivers/char/ser_a2232* | 186 | F: drivers/char/ser_a2232* |
187 | 187 | ||
188 | AACRAID SCSI RAID DRIVER | 188 | AACRAID SCSI RAID DRIVER |
189 | M: Adaptec OEM Raid Solutions <aacraid@adaptec.com> | 189 | M: Adaptec OEM Raid Solutions <aacraid@adaptec.com> |
190 | L: linux-scsi@vger.kernel.org | 190 | L: linux-scsi@vger.kernel.org |
191 | W: http://www.adaptec.com/ | 191 | W: http://www.adaptec.com/ |
192 | S: Supported | 192 | S: Supported |
193 | F: Documentation/scsi/aacraid.txt | 193 | F: Documentation/scsi/aacraid.txt |
194 | F: drivers/scsi/aacraid/ | 194 | F: drivers/scsi/aacraid/ |
195 | 195 | ||
196 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER | 196 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER |
197 | M: Hans de Goede <j.w.r.degoede@hhs.nl> | 197 | M: Hans de Goede <j.w.r.degoede@hhs.nl> |
198 | L: lm-sensors@lm-sensors.org | 198 | L: lm-sensors@lm-sensors.org |
199 | S: Maintained | 199 | S: Maintained |
200 | F: drivers/hwmon/abituguru.c | 200 | F: drivers/hwmon/abituguru.c |
201 | 201 | ||
202 | ABIT UGURU 3 HARDWARE MONITOR DRIVER | 202 | ABIT UGURU 3 HARDWARE MONITOR DRIVER |
203 | M: Alistair John Strachan <alistair@devzero.co.uk> | 203 | M: Alistair John Strachan <alistair@devzero.co.uk> |
204 | L: lm-sensors@lm-sensors.org | 204 | L: lm-sensors@lm-sensors.org |
205 | S: Maintained | 205 | S: Maintained |
206 | F: drivers/hwmon/abituguru3.c | 206 | F: drivers/hwmon/abituguru3.c |
207 | 207 | ||
208 | ACENIC DRIVER | 208 | ACENIC DRIVER |
209 | M: Jes Sorensen <jes@trained-monkey.org> | 209 | M: Jes Sorensen <jes@trained-monkey.org> |
210 | L: linux-acenic@sunsite.dk | 210 | L: linux-acenic@sunsite.dk |
211 | S: Maintained | 211 | S: Maintained |
212 | F: drivers/net/acenic* | 212 | F: drivers/net/acenic* |
213 | 213 | ||
214 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER | 214 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER |
215 | M: Peter Feuerer <peter@piie.net> | 215 | M: Peter Feuerer <peter@piie.net> |
216 | W: http://piie.net/?section=acerhdf | 216 | W: http://piie.net/?section=acerhdf |
217 | S: Maintained | 217 | S: Maintained |
218 | F: drivers/platform/x86/acerhdf.c | 218 | F: drivers/platform/x86/acerhdf.c |
219 | 219 | ||
220 | ACER WMI LAPTOP EXTRAS | 220 | ACER WMI LAPTOP EXTRAS |
221 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 221 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> |
222 | L: aceracpi@googlegroups.com (subscribers-only) | 222 | L: aceracpi@googlegroups.com (subscribers-only) |
223 | W: http://code.google.com/p/aceracpi | 223 | W: http://code.google.com/p/aceracpi |
224 | S: Maintained | 224 | S: Maintained |
225 | F: drivers/platform/x86/acer-wmi.c | 225 | F: drivers/platform/x86/acer-wmi.c |
226 | 226 | ||
227 | ACPI | 227 | ACPI |
228 | M: Len Brown <lenb@kernel.org> | 228 | M: Len Brown <lenb@kernel.org> |
229 | L: linux-acpi@vger.kernel.org | 229 | L: linux-acpi@vger.kernel.org |
230 | W: http://www.lesswatts.org/projects/acpi/ | 230 | W: http://www.lesswatts.org/projects/acpi/ |
231 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git | 231 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git |
232 | S: Supported | 232 | S: Supported |
233 | F: drivers/acpi/ | 233 | F: drivers/acpi/ |
234 | F: drivers/pnp/pnpacpi/ | 234 | F: drivers/pnp/pnpacpi/ |
235 | F: include/linux/acpi.h | 235 | F: include/linux/acpi.h |
236 | 236 | ||
237 | ACPI BATTERY DRIVERS | 237 | ACPI BATTERY DRIVERS |
238 | M: Alexey Starikovskiy <astarikovskiy@suse.de> | 238 | M: Alexey Starikovskiy <astarikovskiy@suse.de> |
239 | L: linux-acpi@vger.kernel.org | 239 | L: linux-acpi@vger.kernel.org |
240 | W: http://www.lesswatts.org/projects/acpi/ | 240 | W: http://www.lesswatts.org/projects/acpi/ |
241 | S: Supported | 241 | S: Supported |
242 | F: drivers/acpi/battery.c | 242 | F: drivers/acpi/battery.c |
243 | F: drivers/acpi/*sbs* | 243 | F: drivers/acpi/*sbs* |
244 | 244 | ||
245 | ACPI EC DRIVER | 245 | ACPI EC DRIVER |
246 | M: Alexey Starikovskiy <astarikovskiy@suse.de> | 246 | M: Alexey Starikovskiy <astarikovskiy@suse.de> |
247 | L: linux-acpi@vger.kernel.org | 247 | L: linux-acpi@vger.kernel.org |
248 | W: http://www.lesswatts.org/projects/acpi/ | 248 | W: http://www.lesswatts.org/projects/acpi/ |
249 | S: Supported | 249 | S: Supported |
250 | F: drivers/acpi/ec.c | 250 | F: drivers/acpi/ec.c |
251 | 251 | ||
252 | ACPI FAN DRIVER | 252 | ACPI FAN DRIVER |
253 | M: Zhang Rui <rui.zhang@intel.com> | 253 | M: Zhang Rui <rui.zhang@intel.com> |
254 | L: linux-acpi@vger.kernel.org | 254 | L: linux-acpi@vger.kernel.org |
255 | W: http://www.lesswatts.org/projects/acpi/ | 255 | W: http://www.lesswatts.org/projects/acpi/ |
256 | S: Supported | 256 | S: Supported |
257 | F: drivers/acpi/fan.c | 257 | F: drivers/acpi/fan.c |
258 | 258 | ||
259 | ACPI PCI HOTPLUG DRIVER | 259 | ACPI PCI HOTPLUG DRIVER |
260 | M: Kristen Carlson Accardi <kristen.c.accardi@intel.com> | 260 | M: Kristen Carlson Accardi <kristen.c.accardi@intel.com> |
261 | L: linux-pci@vger.kernel.org | 261 | L: linux-pci@vger.kernel.org |
262 | S: Supported | 262 | S: Supported |
263 | F: drivers/pci/hotplug/acpi* | 263 | F: drivers/pci/hotplug/acpi* |
264 | 264 | ||
265 | ACPI THERMAL DRIVER | 265 | ACPI THERMAL DRIVER |
266 | M: Zhang Rui <rui.zhang@intel.com> | 266 | M: Zhang Rui <rui.zhang@intel.com> |
267 | L: linux-acpi@vger.kernel.org | 267 | L: linux-acpi@vger.kernel.org |
268 | W: http://www.lesswatts.org/projects/acpi/ | 268 | W: http://www.lesswatts.org/projects/acpi/ |
269 | S: Supported | 269 | S: Supported |
270 | F: drivers/acpi/*thermal* | 270 | F: drivers/acpi/*thermal* |
271 | 271 | ||
272 | ACPI VIDEO DRIVER | 272 | ACPI VIDEO DRIVER |
273 | M: Zhang Rui <rui.zhang@intel.com> | 273 | M: Zhang Rui <rui.zhang@intel.com> |
274 | L: linux-acpi@vger.kernel.org | 274 | L: linux-acpi@vger.kernel.org |
275 | W: http://www.lesswatts.org/projects/acpi/ | 275 | W: http://www.lesswatts.org/projects/acpi/ |
276 | S: Supported | 276 | S: Supported |
277 | F: drivers/acpi/video.c | 277 | F: drivers/acpi/video.c |
278 | 278 | ||
279 | ACPI WMI DRIVER | 279 | ACPI WMI DRIVER |
280 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 280 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> |
281 | L: linux-acpi@vger.kernel.org | 281 | L: linux-acpi@vger.kernel.org |
282 | W: http://www.lesswatts.org/projects/acpi/ | 282 | W: http://www.lesswatts.org/projects/acpi/ |
283 | S: Maintained | 283 | S: Maintained |
284 | F: drivers/platform/x86/wmi.c | 284 | F: drivers/platform/x86/wmi.c |
285 | 285 | ||
286 | AD1889 ALSA SOUND DRIVER | 286 | AD1889 ALSA SOUND DRIVER |
287 | M: Kyle McMartin <kyle@mcmartin.ca> | 287 | M: Kyle McMartin <kyle@mcmartin.ca> |
288 | M: Thibaut Varene <T-Bone@parisc-linux.org> | 288 | M: Thibaut Varene <T-Bone@parisc-linux.org> |
289 | W: http://wiki.parisc-linux.org/AD1889 | 289 | W: http://wiki.parisc-linux.org/AD1889 |
290 | L: linux-parisc@vger.kernel.org | 290 | L: linux-parisc@vger.kernel.org |
291 | S: Maintained | 291 | S: Maintained |
292 | F: sound/pci/ad1889.* | 292 | F: sound/pci/ad1889.* |
293 | 293 | ||
294 | ADM1025 HARDWARE MONITOR DRIVER | 294 | ADM1025 HARDWARE MONITOR DRIVER |
295 | M: Jean Delvare <khali@linux-fr.org> | 295 | M: Jean Delvare <khali@linux-fr.org> |
296 | L: lm-sensors@lm-sensors.org | 296 | L: lm-sensors@lm-sensors.org |
297 | S: Maintained | 297 | S: Maintained |
298 | F: Documentation/hwmon/adm1025 | 298 | F: Documentation/hwmon/adm1025 |
299 | F: drivers/hwmon/adm1025.c | 299 | F: drivers/hwmon/adm1025.c |
300 | 300 | ||
301 | ADM1029 HARDWARE MONITOR DRIVER | 301 | ADM1029 HARDWARE MONITOR DRIVER |
302 | M: Corentin Labbe <corentin.labbe@geomatys.fr> | 302 | M: Corentin Labbe <corentin.labbe@geomatys.fr> |
303 | L: lm-sensors@lm-sensors.org | 303 | L: lm-sensors@lm-sensors.org |
304 | S: Maintained | 304 | S: Maintained |
305 | F: drivers/hwmon/adm1029.c | 305 | F: drivers/hwmon/adm1029.c |
306 | 306 | ||
307 | ADM8211 WIRELESS DRIVER | 307 | ADM8211 WIRELESS DRIVER |
308 | M: Michael Wu <flamingice@sourmilk.net> | 308 | M: Michael Wu <flamingice@sourmilk.net> |
309 | L: linux-wireless@vger.kernel.org | 309 | L: linux-wireless@vger.kernel.org |
310 | W: http://linuxwireless.org/ | 310 | W: http://linuxwireless.org/ |
311 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git | 311 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git |
312 | S: Maintained | 312 | S: Maintained |
313 | F: drivers/net/wireless/adm8211.* | 313 | F: drivers/net/wireless/adm8211.* |
314 | 314 | ||
315 | ADT746X FAN DRIVER | 315 | ADT746X FAN DRIVER |
316 | M: Colin Leroy <colin@colino.net> | 316 | M: Colin Leroy <colin@colino.net> |
317 | S: Maintained | 317 | S: Maintained |
318 | F: drivers/macintosh/therm_adt746x.c | 318 | F: drivers/macintosh/therm_adt746x.c |
319 | 319 | ||
320 | ADVANSYS SCSI DRIVER | 320 | ADVANSYS SCSI DRIVER |
321 | M: Matthew Wilcox <matthew@wil.cx> | 321 | M: Matthew Wilcox <matthew@wil.cx> |
322 | L: linux-scsi@vger.kernel.org | 322 | L: linux-scsi@vger.kernel.org |
323 | S: Maintained | 323 | S: Maintained |
324 | F: Documentation/scsi/advansys.txt | 324 | F: Documentation/scsi/advansys.txt |
325 | F: drivers/scsi/advansys.c | 325 | F: drivers/scsi/advansys.c |
326 | 326 | ||
327 | AEDSP16 DRIVER | 327 | AEDSP16 DRIVER |
328 | M: Riccardo Facchetti <fizban@tin.it> | 328 | M: Riccardo Facchetti <fizban@tin.it> |
329 | S: Maintained | 329 | S: Maintained |
330 | F: sound/oss/aedsp16.c | 330 | F: sound/oss/aedsp16.c |
331 | 331 | ||
332 | AFFS FILE SYSTEM | 332 | AFFS FILE SYSTEM |
333 | M: Roman Zippel <zippel@linux-m68k.org> | 333 | M: Roman Zippel <zippel@linux-m68k.org> |
334 | S: Maintained | 334 | S: Maintained |
335 | F: Documentation/filesystems/affs.txt | 335 | F: Documentation/filesystems/affs.txt |
336 | F: fs/affs/ | 336 | F: fs/affs/ |
337 | 337 | ||
338 | AFS FILESYSTEM & AF_RXRPC SOCKET DOMAIN | 338 | AFS FILESYSTEM & AF_RXRPC SOCKET DOMAIN |
339 | M: David Howells <dhowells@redhat.com> | 339 | M: David Howells <dhowells@redhat.com> |
340 | L: linux-afs@lists.infradead.org | 340 | L: linux-afs@lists.infradead.org |
341 | S: Supported | 341 | S: Supported |
342 | F: fs/afs/ | 342 | F: fs/afs/ |
343 | F: include/net/af_rxrpc.h | 343 | F: include/net/af_rxrpc.h |
344 | F: net/rxrpc/af_rxrpc.c | 344 | F: net/rxrpc/af_rxrpc.c |
345 | 345 | ||
346 | AGPGART DRIVER | 346 | AGPGART DRIVER |
347 | M: David Airlie <airlied@linux.ie> | 347 | M: David Airlie <airlied@linux.ie> |
348 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git | 348 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git |
349 | S: Maintained | 349 | S: Maintained |
350 | F: drivers/char/agp/ | 350 | F: drivers/char/agp/ |
351 | F: include/linux/agp* | 351 | F: include/linux/agp* |
352 | 352 | ||
353 | AHA152X SCSI DRIVER | 353 | AHA152X SCSI DRIVER |
354 | M: "Juergen E. Fischer" <fischer@norbit.de> | 354 | M: "Juergen E. Fischer" <fischer@norbit.de> |
355 | L: linux-scsi@vger.kernel.org | 355 | L: linux-scsi@vger.kernel.org |
356 | S: Maintained | 356 | S: Maintained |
357 | F: drivers/scsi/aha152x* | 357 | F: drivers/scsi/aha152x* |
358 | F: drivers/scsi/pcmcia/aha152x* | 358 | F: drivers/scsi/pcmcia/aha152x* |
359 | 359 | ||
360 | AIC7XXX / AIC79XX SCSI DRIVER | 360 | AIC7XXX / AIC79XX SCSI DRIVER |
361 | M: Hannes Reinecke <hare@suse.de> | 361 | M: Hannes Reinecke <hare@suse.de> |
362 | L: linux-scsi@vger.kernel.org | 362 | L: linux-scsi@vger.kernel.org |
363 | S: Maintained | 363 | S: Maintained |
364 | F: drivers/scsi/aic7xxx/ | 364 | F: drivers/scsi/aic7xxx/ |
365 | F: drivers/scsi/aic7xxx_old/ | 365 | F: drivers/scsi/aic7xxx_old/ |
366 | 366 | ||
367 | AIO | 367 | AIO |
368 | M: Benjamin LaHaise <bcrl@kvack.org> | 368 | M: Benjamin LaHaise <bcrl@kvack.org> |
369 | L: linux-aio@kvack.org | 369 | L: linux-aio@kvack.org |
370 | S: Supported | 370 | S: Supported |
371 | F: fs/aio.c | 371 | F: fs/aio.c |
372 | F: include/linux/*aio*.h | 372 | F: include/linux/*aio*.h |
373 | 373 | ||
374 | ALCATEL SPEEDTOUCH USB DRIVER | 374 | ALCATEL SPEEDTOUCH USB DRIVER |
375 | M: Duncan Sands <duncan.sands@free.fr> | 375 | M: Duncan Sands <duncan.sands@free.fr> |
376 | L: linux-usb@vger.kernel.org | 376 | L: linux-usb@vger.kernel.org |
377 | W: http://www.linux-usb.org/SpeedTouch/ | 377 | W: http://www.linux-usb.org/SpeedTouch/ |
378 | S: Maintained | 378 | S: Maintained |
379 | F: drivers/usb/atm/speedtch.c | 379 | F: drivers/usb/atm/speedtch.c |
380 | F: drivers/usb/atm/usbatm.c | 380 | F: drivers/usb/atm/usbatm.c |
381 | 381 | ||
382 | ALCHEMY AU1XX0 MMC DRIVER | 382 | ALCHEMY AU1XX0 MMC DRIVER |
383 | M: Manuel Lauss <manuel.lauss@gmail.com> | 383 | M: Manuel Lauss <manuel.lauss@gmail.com> |
384 | S: Maintained | 384 | S: Maintained |
385 | F: drivers/mmc/host/au1xmmc.c | 385 | F: drivers/mmc/host/au1xmmc.c |
386 | 386 | ||
387 | ALI1563 I2C DRIVER | 387 | ALI1563 I2C DRIVER |
388 | M: Rudolf Marek <r.marek@assembler.cz> | 388 | M: Rudolf Marek <r.marek@assembler.cz> |
389 | L: linux-i2c@vger.kernel.org | 389 | L: linux-i2c@vger.kernel.org |
390 | S: Maintained | 390 | S: Maintained |
391 | F: Documentation/i2c/busses/i2c-ali1563 | 391 | F: Documentation/i2c/busses/i2c-ali1563 |
392 | F: drivers/i2c/busses/i2c-ali1563.c | 392 | F: drivers/i2c/busses/i2c-ali1563.c |
393 | 393 | ||
394 | ALPHA PORT | 394 | ALPHA PORT |
395 | M: Richard Henderson <rth@twiddle.net> | 395 | M: Richard Henderson <rth@twiddle.net> |
396 | S: Odd Fixes for 2.4; Maintained for 2.6. | 396 | S: Odd Fixes for 2.4; Maintained for 2.6. |
397 | M: Ivan Kokshaysky <ink@jurassic.park.msu.ru> | 397 | M: Ivan Kokshaysky <ink@jurassic.park.msu.ru> |
398 | S: Maintained for 2.4; PCI support for 2.6. | 398 | S: Maintained for 2.4; PCI support for 2.6. |
399 | L: linux-alpha@vger.kernel.org | 399 | L: linux-alpha@vger.kernel.org |
400 | F: arch/alpha/ | 400 | F: arch/alpha/ |
401 | 401 | ||
402 | AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER | 402 | AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER |
403 | M: Thomas Dahlmann <dahlmann.thomas@arcor.de> | 403 | M: Thomas Dahlmann <dahlmann.thomas@arcor.de> |
404 | L: linux-geode@lists.infradead.org (moderated for non-subscribers) | 404 | L: linux-geode@lists.infradead.org (moderated for non-subscribers) |
405 | S: Supported | 405 | S: Supported |
406 | F: drivers/usb/gadget/amd5536udc.* | 406 | F: drivers/usb/gadget/amd5536udc.* |
407 | 407 | ||
408 | AMD GEODE PROCESSOR/CHIPSET SUPPORT | 408 | AMD GEODE PROCESSOR/CHIPSET SUPPORT |
409 | P: Jordan Crouse | 409 | P: Jordan Crouse |
410 | L: linux-geode@lists.infradead.org (moderated for non-subscribers) | 410 | L: linux-geode@lists.infradead.org (moderated for non-subscribers) |
411 | W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html | 411 | W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html |
412 | S: Supported | 412 | S: Supported |
413 | F: arch/x86/kernel/geode_32.c | 413 | F: arch/x86/kernel/geode_32.c |
414 | F: drivers/char/hw_random/geode-rng.c | 414 | F: drivers/char/hw_random/geode-rng.c |
415 | F: drivers/crypto/geode* | 415 | F: drivers/crypto/geode* |
416 | F: drivers/video/geode/ | 416 | F: drivers/video/geode/ |
417 | F: arch/x86/include/asm/geode.h | 417 | F: arch/x86/include/asm/geode.h |
418 | 418 | ||
419 | AMD IOMMU (AMD-VI) | 419 | AMD IOMMU (AMD-VI) |
420 | M: Joerg Roedel <joerg.roedel@amd.com> | 420 | M: Joerg Roedel <joerg.roedel@amd.com> |
421 | L: iommu@lists.linux-foundation.org | 421 | L: iommu@lists.linux-foundation.org |
422 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git | 422 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git |
423 | S: Supported | 423 | S: Supported |
424 | F: arch/x86/kernel/amd_iommu*.c | 424 | F: arch/x86/kernel/amd_iommu*.c |
425 | F: arch/x86/include/asm/amd_iommu*.h | 425 | F: arch/x86/include/asm/amd_iommu*.h |
426 | 426 | ||
427 | AMD MICROCODE UPDATE SUPPORT | 427 | AMD MICROCODE UPDATE SUPPORT |
428 | M: Andreas Herrmann <andreas.herrmann3@amd.com> | 428 | M: Andreas Herrmann <andreas.herrmann3@amd.com> |
429 | L: amd64-microcode@amd64.org | 429 | L: amd64-microcode@amd64.org |
430 | S: Supported | 430 | S: Supported |
431 | F: arch/x86/kernel/microcode_amd.c | 431 | F: arch/x86/kernel/microcode_amd.c |
432 | 432 | ||
433 | AMS (Apple Motion Sensor) DRIVER | 433 | AMS (Apple Motion Sensor) DRIVER |
434 | M: Stelian Pop <stelian@popies.net> | 434 | M: Stelian Pop <stelian@popies.net> |
435 | M: Michael Hanselmann <linux-kernel@hansmi.ch> | 435 | M: Michael Hanselmann <linux-kernel@hansmi.ch> |
436 | S: Supported | 436 | S: Supported |
437 | F: drivers/hwmon/ams/ | 437 | F: drivers/hwmon/ams/ |
438 | 438 | ||
439 | AMSO1100 RNIC DRIVER | 439 | AMSO1100 RNIC DRIVER |
440 | M: Tom Tucker <tom@opengridcomputing.com> | 440 | M: Tom Tucker <tom@opengridcomputing.com> |
441 | M: Steve Wise <swise@opengridcomputing.com> | 441 | M: Steve Wise <swise@opengridcomputing.com> |
442 | L: linux-rdma@vger.kernel.org | 442 | L: linux-rdma@vger.kernel.org |
443 | S: Maintained | 443 | S: Maintained |
444 | F: drivers/infiniband/hw/amso1100/ | 444 | F: drivers/infiniband/hw/amso1100/ |
445 | 445 | ||
446 | AOA (Apple Onboard Audio) ALSA DRIVER | 446 | AOA (Apple Onboard Audio) ALSA DRIVER |
447 | M: Johannes Berg <johannes@sipsolutions.net> | 447 | M: Johannes Berg <johannes@sipsolutions.net> |
448 | L: linuxppc-dev@ozlabs.org | 448 | L: linuxppc-dev@ozlabs.org |
449 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 449 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
450 | S: Maintained | 450 | S: Maintained |
451 | F: sound/aoa/ | 451 | F: sound/aoa/ |
452 | 452 | ||
453 | APM DRIVER | 453 | APM DRIVER |
454 | M: Stephen Rothwell <sfr@canb.auug.org.au> | 454 | M: Stephen Rothwell <sfr@canb.auug.org.au> |
455 | L: linux-laptop@vger.kernel.org | 455 | L: linux-laptop@vger.kernel.org |
456 | W: http://www.canb.auug.org.au/~sfr/ | 456 | W: http://www.canb.auug.org.au/~sfr/ |
457 | S: Supported | 457 | S: Supported |
458 | F: arch/x86/kernel/apm_32.c | 458 | F: arch/x86/kernel/apm_32.c |
459 | F: include/linux/apm_bios.h | 459 | F: include/linux/apm_bios.h |
460 | 460 | ||
461 | APPLE BCM5974 MULTITOUCH DRIVER | 461 | APPLE BCM5974 MULTITOUCH DRIVER |
462 | M: Henrik Rydberg <rydberg@euromail.se> | 462 | M: Henrik Rydberg <rydberg@euromail.se> |
463 | L: linux-input@vger.kernel.org | 463 | L: linux-input@vger.kernel.org |
464 | S: Maintained | 464 | S: Maintained |
465 | F: drivers/input/mouse/bcm5974.c | 465 | F: drivers/input/mouse/bcm5974.c |
466 | 466 | ||
467 | APPLE SMC DRIVER | 467 | APPLE SMC DRIVER |
468 | M: Nicolas Boichat <nicolas@boichat.ch> | 468 | M: Nicolas Boichat <nicolas@boichat.ch> |
469 | L: mactel-linux-devel@lists.sourceforge.net | 469 | L: mactel-linux-devel@lists.sourceforge.net |
470 | S: Maintained | 470 | S: Maintained |
471 | F: drivers/hwmon/applesmc.c | 471 | F: drivers/hwmon/applesmc.c |
472 | 472 | ||
473 | APPLETALK NETWORK LAYER | 473 | APPLETALK NETWORK LAYER |
474 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 474 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
475 | S: Maintained | 475 | S: Maintained |
476 | F: drivers/net/appletalk/ | 476 | F: drivers/net/appletalk/ |
477 | F: net/appletalk/ | 477 | F: net/appletalk/ |
478 | 478 | ||
479 | APPLETOUCH TOUCHPAD DRIVER | 479 | APPLETOUCH TOUCHPAD DRIVER |
480 | M: Johannes Berg <johannes@sipsolutions.net> | 480 | M: Johannes Berg <johannes@sipsolutions.net> |
481 | L: linux-input@vger.kernel.org | 481 | L: linux-input@vger.kernel.org |
482 | S: Maintained | 482 | S: Maintained |
483 | F: Documentation/input/appletouch.txt | 483 | F: Documentation/input/appletouch.txt |
484 | F: drivers/input/mouse/appletouch.c | 484 | F: drivers/input/mouse/appletouch.c |
485 | 485 | ||
486 | ARC FRAMEBUFFER DRIVER | 486 | ARC FRAMEBUFFER DRIVER |
487 | M: Jaya Kumar <jayalk@intworks.biz> | 487 | M: Jaya Kumar <jayalk@intworks.biz> |
488 | S: Maintained | 488 | S: Maintained |
489 | F: drivers/video/arcfb.c | 489 | F: drivers/video/arcfb.c |
490 | F: drivers/video/fb_defio.c | 490 | F: drivers/video/fb_defio.c |
491 | 491 | ||
492 | ARM MFM AND FLOPPY DRIVERS | 492 | ARM MFM AND FLOPPY DRIVERS |
493 | M: Ian Molton <spyro@f2s.com> | 493 | M: Ian Molton <spyro@f2s.com> |
494 | S: Maintained | 494 | S: Maintained |
495 | F: arch/arm/lib/floppydma.S | 495 | F: arch/arm/lib/floppydma.S |
496 | F: arch/arm/include/asm/floppy.h | 496 | F: arch/arm/include/asm/floppy.h |
497 | 497 | ||
498 | ARM PORT | 498 | ARM PORT |
499 | M: Russell King <linux@arm.linux.org.uk> | 499 | M: Russell King <linux@arm.linux.org.uk> |
500 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 500 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
501 | W: http://www.arm.linux.org.uk/ | 501 | W: http://www.arm.linux.org.uk/ |
502 | S: Maintained | 502 | S: Maintained |
503 | F: arch/arm/ | 503 | F: arch/arm/ |
504 | 504 | ||
505 | ARM PRIMECELL MMCI PL180/1 DRIVER | 505 | ARM PRIMECELL MMCI PL180/1 DRIVER |
506 | S: Orphan | 506 | S: Orphan |
507 | F: drivers/mmc/host/mmci.* | 507 | F: drivers/mmc/host/mmci.* |
508 | 508 | ||
509 | ARM/ADI ROADRUNNER MACHINE SUPPORT | 509 | ARM/ADI ROADRUNNER MACHINE SUPPORT |
510 | M: Lennert Buytenhek <kernel@wantstofly.org> | 510 | M: Lennert Buytenhek <kernel@wantstofly.org> |
511 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 511 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
512 | S: Maintained | 512 | S: Maintained |
513 | F: arch/arm/mach-ixp23xx/ | 513 | F: arch/arm/mach-ixp23xx/ |
514 | F: arch/arm/mach-ixp23xx/include/mach/ | 514 | F: arch/arm/mach-ixp23xx/include/mach/ |
515 | 515 | ||
516 | ARM/ADS SPHERE MACHINE SUPPORT | 516 | ARM/ADS SPHERE MACHINE SUPPORT |
517 | M: Lennert Buytenhek <kernel@wantstofly.org> | 517 | M: Lennert Buytenhek <kernel@wantstofly.org> |
518 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 518 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
519 | S: Maintained | 519 | S: Maintained |
520 | 520 | ||
521 | ARM/AFEB9260 MACHINE SUPPORT | 521 | ARM/AFEB9260 MACHINE SUPPORT |
522 | M: Sergey Lapin <slapin@ossfans.org> | 522 | M: Sergey Lapin <slapin@ossfans.org> |
523 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 523 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
524 | S: Maintained | 524 | S: Maintained |
525 | 525 | ||
526 | ARM/AJECO 1ARM MACHINE SUPPORT | 526 | ARM/AJECO 1ARM MACHINE SUPPORT |
527 | M: Lennert Buytenhek <kernel@wantstofly.org> | 527 | M: Lennert Buytenhek <kernel@wantstofly.org> |
528 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 528 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
529 | S: Maintained | 529 | S: Maintained |
530 | 530 | ||
531 | ARM/ATMEL AT91RM9200 ARM ARCHITECTURE | 531 | ARM/ATMEL AT91RM9200 ARM ARCHITECTURE |
532 | M: Andrew Victor <linux@maxim.org.za> | 532 | M: Andrew Victor <linux@maxim.org.za> |
533 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 533 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
534 | W: http://maxim.org.za/at91_26.html | 534 | W: http://maxim.org.za/at91_26.html |
535 | S: Maintained | 535 | S: Maintained |
536 | 536 | ||
537 | ARM/BCMRING ARM ARCHITECTURE | 537 | ARM/BCMRING ARM ARCHITECTURE |
538 | M: Leo Chen <leochen@broadcom.com> | 538 | M: Leo Chen <leochen@broadcom.com> |
539 | M: Scott Branden <sbranden@broadcom.com> | 539 | M: Scott Branden <sbranden@broadcom.com> |
540 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 540 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
541 | S: Maintained | 541 | S: Maintained |
542 | F: arch/arm/mach-bcmring | 542 | F: arch/arm/mach-bcmring |
543 | 543 | ||
544 | ARM/BCMRING MTD NAND DRIVER | 544 | ARM/BCMRING MTD NAND DRIVER |
545 | M: Leo Chen <leochen@broadcom.com> | 545 | M: Leo Chen <leochen@broadcom.com> |
546 | M: Scott Branden <sbranden@broadcom.com> | 546 | M: Scott Branden <sbranden@broadcom.com> |
547 | L: linux-mtd@lists.infradead.org | 547 | L: linux-mtd@lists.infradead.org |
548 | S: Maintained | 548 | S: Maintained |
549 | F: drivers/mtd/nand/bcm_umi_nand.c | 549 | F: drivers/mtd/nand/bcm_umi_nand.c |
550 | F: drivers/mtd/nand/bcm_umi_bch.c | 550 | F: drivers/mtd/nand/bcm_umi_bch.c |
551 | F: drivers/mtd/nand/bcm_umi_hamming.c | 551 | F: drivers/mtd/nand/bcm_umi_hamming.c |
552 | F: drivers/mtd/nand/nand_bcm_umi.h | 552 | F: drivers/mtd/nand/nand_bcm_umi.h |
553 | 553 | ||
554 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE | 554 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE |
555 | M: Hartley Sweeten <hsweeten@visionengravers.com> | 555 | M: Hartley Sweeten <hsweeten@visionengravers.com> |
556 | M: Ryan Mallon <ryan@bluewatersys.com> | 556 | M: Ryan Mallon <ryan@bluewatersys.com> |
557 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 557 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
558 | S: Maintained | 558 | S: Maintained |
559 | F: arch/arm/mach-ep93xx/ | 559 | F: arch/arm/mach-ep93xx/ |
560 | F: arch/arm/mach-ep93xx/include/mach/ | 560 | F: arch/arm/mach-ep93xx/include/mach/ |
561 | 561 | ||
562 | ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT | 562 | ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT |
563 | M: Lennert Buytenhek <kernel@wantstofly.org> | 563 | M: Lennert Buytenhek <kernel@wantstofly.org> |
564 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 564 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
565 | S: Maintained | 565 | S: Maintained |
566 | 566 | ||
567 | ARM/CLKDEV SUPPORT | 567 | ARM/CLKDEV SUPPORT |
568 | M: Russell King <linux@arm.linux.org.uk> | 568 | M: Russell King <linux@arm.linux.org.uk> |
569 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 569 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
570 | F: arch/arm/common/clkdev.c | 570 | F: arch/arm/common/clkdev.c |
571 | F: arch/arm/include/asm/clkdev.h | 571 | F: arch/arm/include/asm/clkdev.h |
572 | 572 | ||
573 | ARM/COMPULAB CM-X270/EM-X270 and CM-X300 MACHINE SUPPORT | 573 | ARM/COMPULAB CM-X270/EM-X270 and CM-X300 MACHINE SUPPORT |
574 | M: Mike Rapoport <mike@compulab.co.il> | 574 | M: Mike Rapoport <mike@compulab.co.il> |
575 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 575 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
576 | S: Maintained | 576 | S: Maintained |
577 | 577 | ||
578 | ARM/CORGI MACHINE SUPPORT | 578 | ARM/CORGI MACHINE SUPPORT |
579 | M: Richard Purdie <rpurdie@rpsys.net> | 579 | M: Richard Purdie <rpurdie@rpsys.net> |
580 | S: Maintained | 580 | S: Maintained |
581 | 581 | ||
582 | ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE | 582 | ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE |
583 | M: Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | 583 | M: Paulius Zaleckas <paulius.zaleckas@teltonika.lt> |
584 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 584 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
585 | T: git git://gitorious.org/linux-gemini/mainline.git | 585 | T: git git://gitorious.org/linux-gemini/mainline.git |
586 | S: Maintained | 586 | S: Maintained |
587 | F: arch/arm/mach-gemini/ | 587 | F: arch/arm/mach-gemini/ |
588 | 588 | ||
589 | ARM/EBSA110 MACHINE SUPPORT | 589 | ARM/EBSA110 MACHINE SUPPORT |
590 | M: Russell King <linux@arm.linux.org.uk> | 590 | M: Russell King <linux@arm.linux.org.uk> |
591 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 591 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
592 | W: http://www.arm.linux.org.uk/ | 592 | W: http://www.arm.linux.org.uk/ |
593 | S: Maintained | 593 | S: Maintained |
594 | F: arch/arm/mach-ebsa110/ | 594 | F: arch/arm/mach-ebsa110/ |
595 | F: drivers/net/arm/am79c961a.* | 595 | F: drivers/net/arm/am79c961a.* |
596 | 596 | ||
597 | ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6) | 597 | ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6) |
598 | M: Daniel Ribeiro <drwyrm@gmail.com> | 598 | M: Daniel Ribeiro <drwyrm@gmail.com> |
599 | M: Stefan Schmidt <stefan@openezx.org> | 599 | M: Stefan Schmidt <stefan@openezx.org> |
600 | M: Harald Welte <laforge@openezx.org> | 600 | M: Harald Welte <laforge@openezx.org> |
601 | L: openezx-devel@lists.openezx.org (subscribers-only) | 601 | L: openezx-devel@lists.openezx.org (subscribers-only) |
602 | W: http://www.openezx.org/ | 602 | W: http://www.openezx.org/ |
603 | S: Maintained | 603 | S: Maintained |
604 | T: topgit git://git.openezx.org/openezx.git | 604 | T: topgit git://git.openezx.org/openezx.git |
605 | F: arch/arm/mach-pxa/ezx.c | 605 | F: arch/arm/mach-pxa/ezx.c |
606 | 606 | ||
607 | ARM/FARADAY FA526 PORT | 607 | ARM/FARADAY FA526 PORT |
608 | M: Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | 608 | M: Paulius Zaleckas <paulius.zaleckas@teltonika.lt> |
609 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 609 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
610 | S: Maintained | 610 | S: Maintained |
611 | F: arch/arm/mm/*-fa* | 611 | F: arch/arm/mm/*-fa* |
612 | 612 | ||
613 | ARM/FOOTBRIDGE ARCHITECTURE | 613 | ARM/FOOTBRIDGE ARCHITECTURE |
614 | M: Russell King <linux@arm.linux.org.uk> | 614 | M: Russell King <linux@arm.linux.org.uk> |
615 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 615 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
616 | W: http://www.arm.linux.org.uk/ | 616 | W: http://www.arm.linux.org.uk/ |
617 | S: Maintained | 617 | S: Maintained |
618 | F: arch/arm/include/asm/hardware/dec21285.h | 618 | F: arch/arm/include/asm/hardware/dec21285.h |
619 | F: arch/arm/mach-footbridge/ | 619 | F: arch/arm/mach-footbridge/ |
620 | 620 | ||
621 | ARM/FREESCALE IMX / MXC ARM ARCHITECTURE | 621 | ARM/FREESCALE IMX / MXC ARM ARCHITECTURE |
622 | M: Sascha Hauer <kernel@pengutronix.de> | 622 | M: Sascha Hauer <kernel@pengutronix.de> |
623 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 623 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
624 | S: Maintained | 624 | S: Maintained |
625 | 625 | ||
626 | ARM/GLOMATION GESBC9312SX MACHINE SUPPORT | 626 | ARM/GLOMATION GESBC9312SX MACHINE SUPPORT |
627 | M: Lennert Buytenhek <kernel@wantstofly.org> | 627 | M: Lennert Buytenhek <kernel@wantstofly.org> |
628 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 628 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
629 | S: Maintained | 629 | S: Maintained |
630 | 630 | ||
631 | ARM/GUMSTIX MACHINE SUPPORT | 631 | ARM/GUMSTIX MACHINE SUPPORT |
632 | M: Steve Sakoman <sakoman@gmail.com> | 632 | M: Steve Sakoman <sakoman@gmail.com> |
633 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 633 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
634 | S: Maintained | 634 | S: Maintained |
635 | 635 | ||
636 | ARM/H4700 (HP IPAQ HX4700) MACHINE SUPPORT | 636 | ARM/H4700 (HP IPAQ HX4700) MACHINE SUPPORT |
637 | M: Philipp Zabel <philipp.zabel@gmail.com> | 637 | M: Philipp Zabel <philipp.zabel@gmail.com> |
638 | S: Maintained | 638 | S: Maintained |
639 | F: arch/arm/mach-pxa/hx4700.c | 639 | F: arch/arm/mach-pxa/hx4700.c |
640 | F: arch/arm/mach-pxa/include/mach/hx4700.h | 640 | F: arch/arm/mach-pxa/include/mach/hx4700.h |
641 | 641 | ||
642 | ARM/HP JORNADA 7XX MACHINE SUPPORT | 642 | ARM/HP JORNADA 7XX MACHINE SUPPORT |
643 | M: Kristoffer Ericson <kristoffer.ericson@gmail.com> | 643 | M: Kristoffer Ericson <kristoffer.ericson@gmail.com> |
644 | W: www.jlime.com | 644 | W: www.jlime.com |
645 | S: Maintained | 645 | S: Maintained |
646 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git | 646 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git |
647 | F: arch/arm/mach-sa1100/jornada720.c | 647 | F: arch/arm/mach-sa1100/jornada720.c |
648 | F: arch/arm/mach-sa1100/include/mach/jornada720.h | 648 | F: arch/arm/mach-sa1100/include/mach/jornada720.h |
649 | 649 | ||
650 | ARM/INTEL IOP32X ARM ARCHITECTURE | 650 | ARM/INTEL IOP32X ARM ARCHITECTURE |
651 | M: Lennert Buytenhek <kernel@wantstofly.org> | 651 | M: Lennert Buytenhek <kernel@wantstofly.org> |
652 | M: Dan Williams <dan.j.williams@intel.com> | 652 | M: Dan Williams <dan.j.williams@intel.com> |
653 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 653 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
654 | S: Supported | 654 | S: Supported |
655 | 655 | ||
656 | ARM/INTEL IOP33X ARM ARCHITECTURE | 656 | ARM/INTEL IOP33X ARM ARCHITECTURE |
657 | M: Dan Williams <dan.j.williams@intel.com> | 657 | M: Dan Williams <dan.j.williams@intel.com> |
658 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 658 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
659 | S: Supported | 659 | S: Supported |
660 | 660 | ||
661 | ARM/INTEL IOP13XX ARM ARCHITECTURE | 661 | ARM/INTEL IOP13XX ARM ARCHITECTURE |
662 | M: Lennert Buytenhek <kernel@wantstofly.org> | 662 | M: Lennert Buytenhek <kernel@wantstofly.org> |
663 | M: Dan Williams <dan.j.williams@intel.com> | 663 | M: Dan Williams <dan.j.williams@intel.com> |
664 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 664 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
665 | S: Supported | 665 | S: Supported |
666 | 666 | ||
667 | ARM/INTEL IQ81342EX MACHINE SUPPORT | 667 | ARM/INTEL IQ81342EX MACHINE SUPPORT |
668 | M: Lennert Buytenhek <kernel@wantstofly.org> | 668 | M: Lennert Buytenhek <kernel@wantstofly.org> |
669 | M: Dan Williams <dan.j.williams@intel.com> | 669 | M: Dan Williams <dan.j.williams@intel.com> |
670 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 670 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
671 | S: Supported | 671 | S: Supported |
672 | 672 | ||
673 | ARM/INTEL IXP2000 ARM ARCHITECTURE | 673 | ARM/INTEL IXP2000 ARM ARCHITECTURE |
674 | M: Lennert Buytenhek <kernel@wantstofly.org> | 674 | M: Lennert Buytenhek <kernel@wantstofly.org> |
675 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 675 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
676 | S: Maintained | 676 | S: Maintained |
677 | 677 | ||
678 | ARM/INTEL IXDP2850 MACHINE SUPPORT | 678 | ARM/INTEL IXDP2850 MACHINE SUPPORT |
679 | M: Lennert Buytenhek <kernel@wantstofly.org> | 679 | M: Lennert Buytenhek <kernel@wantstofly.org> |
680 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 680 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
681 | S: Maintained | 681 | S: Maintained |
682 | 682 | ||
683 | ARM/INTEL IXP23XX ARM ARCHITECTURE | 683 | ARM/INTEL IXP23XX ARM ARCHITECTURE |
684 | M: Lennert Buytenhek <kernel@wantstofly.org> | 684 | M: Lennert Buytenhek <kernel@wantstofly.org> |
685 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 685 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
686 | S: Maintained | 686 | S: Maintained |
687 | 687 | ||
688 | ARM/INTEL XSC3 (MANZANO) ARM CORE | 688 | ARM/INTEL XSC3 (MANZANO) ARM CORE |
689 | M: Lennert Buytenhek <kernel@wantstofly.org> | 689 | M: Lennert Buytenhek <kernel@wantstofly.org> |
690 | M: Dan Williams <dan.j.williams@intel.com> | 690 | M: Dan Williams <dan.j.williams@intel.com> |
691 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 691 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
692 | S: Supported | 692 | S: Supported |
693 | 693 | ||
694 | ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT | 694 | ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT |
695 | M: Lennert Buytenhek <kernel@wantstofly.org> | 695 | M: Lennert Buytenhek <kernel@wantstofly.org> |
696 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 696 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
697 | S: Maintained | 697 | S: Maintained |
698 | 698 | ||
699 | ARM/LOGICPD PXA270 MACHINE SUPPORT | 699 | ARM/LOGICPD PXA270 MACHINE SUPPORT |
700 | M: Lennert Buytenhek <kernel@wantstofly.org> | 700 | M: Lennert Buytenhek <kernel@wantstofly.org> |
701 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 701 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
702 | S: Maintained | 702 | S: Maintained |
703 | 703 | ||
704 | ARM/MAGICIAN MACHINE SUPPORT | 704 | ARM/MAGICIAN MACHINE SUPPORT |
705 | M: Philipp Zabel <philipp.zabel@gmail.com> | 705 | M: Philipp Zabel <philipp.zabel@gmail.com> |
706 | S: Maintained | 706 | S: Maintained |
707 | 707 | ||
708 | ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support | 708 | ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support |
709 | M: Lennert Buytenhek <buytenh@marvell.com> | 709 | M: Lennert Buytenhek <buytenh@marvell.com> |
710 | M: Nicolas Pitre <nico@marvell.com> | 710 | M: Nicolas Pitre <nico@marvell.com> |
711 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 711 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
712 | T: git git://git.marvell.com/orion | 712 | T: git git://git.marvell.com/orion |
713 | S: Maintained | 713 | S: Maintained |
714 | F: arch/arm/mach-loki/ | 714 | F: arch/arm/mach-loki/ |
715 | F: arch/arm/mach-kirkwood/ | 715 | F: arch/arm/mach-kirkwood/ |
716 | F: arch/arm/mach-mv78xx0/ | 716 | F: arch/arm/mach-mv78xx0/ |
717 | F: arch/arm/mach-orion5x/ | 717 | F: arch/arm/mach-orion5x/ |
718 | F: arch/arm/plat-orion/ | 718 | F: arch/arm/plat-orion/ |
719 | 719 | ||
720 | ARM/MIOA701 MACHINE SUPPORT | 720 | ARM/MIOA701 MACHINE SUPPORT |
721 | M: Robert Jarzmik <robert.jarzmik@free.fr> | 721 | M: Robert Jarzmik <robert.jarzmik@free.fr> |
722 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 722 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
723 | F: arch/arm/mach-pxa/mioa701.c | 723 | F: arch/arm/mach-pxa/mioa701.c |
724 | S: Maintained | 724 | S: Maintained |
725 | 725 | ||
726 | ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT | 726 | ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT |
727 | M: Michael Petchkovsky <mkpetch@internode.on.net> | 727 | M: Michael Petchkovsky <mkpetch@internode.on.net> |
728 | S: Maintained | 728 | S: Maintained |
729 | 729 | ||
730 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT | 730 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT |
731 | M: Nelson Castillo <arhuaco@freaks-unidos.net> | 731 | M: Nelson Castillo <arhuaco@freaks-unidos.net> |
732 | L: openmoko-kernel@lists.openmoko.org (subscribers-only) | 732 | L: openmoko-kernel@lists.openmoko.org (subscribers-only) |
733 | W: http://wiki.openmoko.org/wiki/Neo_FreeRunner | 733 | W: http://wiki.openmoko.org/wiki/Neo_FreeRunner |
734 | S: Supported | 734 | S: Supported |
735 | 735 | ||
736 | ARM/TOSA MACHINE SUPPORT | 736 | ARM/TOSA MACHINE SUPPORT |
737 | M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 737 | M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
738 | M: Dirk Opfer <dirk@opfer-online.de> | 738 | M: Dirk Opfer <dirk@opfer-online.de> |
739 | S: Maintained | 739 | S: Maintained |
740 | 740 | ||
741 | ARM/PALMTX,PALMT5,PALMLD,PALMTE2 SUPPORT | 741 | ARM/PALMTX,PALMT5,PALMLD,PALMTE2 SUPPORT |
742 | M: Marek Vasut <marek.vasut@gmail.com> | 742 | M: Marek Vasut <marek.vasut@gmail.com> |
743 | W: http://hackndev.com | 743 | W: http://hackndev.com |
744 | S: Maintained | 744 | S: Maintained |
745 | 745 | ||
746 | ARM/PALM TREO 680 SUPPORT | 746 | ARM/PALM TREO 680 SUPPORT |
747 | M: Tomas Cech <sleep_walker@suse.cz> | 747 | M: Tomas Cech <sleep_walker@suse.cz> |
748 | W: http://hackndev.com | 748 | W: http://hackndev.com |
749 | S: Maintained | 749 | S: Maintained |
750 | 750 | ||
751 | ARM/PALMZ72 SUPPORT | 751 | ARM/PALMZ72 SUPPORT |
752 | M: Sergey Lapin <slapin@ossfans.org> | 752 | M: Sergey Lapin <slapin@ossfans.org> |
753 | W: http://hackndev.com | 753 | W: http://hackndev.com |
754 | S: Maintained | 754 | S: Maintained |
755 | 755 | ||
756 | ARM/PLEB SUPPORT | 756 | ARM/PLEB SUPPORT |
757 | M: Peter Chubb <pleb@gelato.unsw.edu.au> | 757 | M: Peter Chubb <pleb@gelato.unsw.edu.au> |
758 | W: http://www.disy.cse.unsw.edu.au/Hardware/PLEB | 758 | W: http://www.disy.cse.unsw.edu.au/Hardware/PLEB |
759 | S: Maintained | 759 | S: Maintained |
760 | 760 | ||
761 | ARM/PT DIGITAL BOARD PORT | 761 | ARM/PT DIGITAL BOARD PORT |
762 | M: Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de> | 762 | M: Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de> |
763 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 763 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
764 | W: http://www.arm.linux.org.uk/ | 764 | W: http://www.arm.linux.org.uk/ |
765 | S: Maintained | 765 | S: Maintained |
766 | 766 | ||
767 | ARM/RADISYS ENP2611 MACHINE SUPPORT | 767 | ARM/RADISYS ENP2611 MACHINE SUPPORT |
768 | M: Lennert Buytenhek <kernel@wantstofly.org> | 768 | M: Lennert Buytenhek <kernel@wantstofly.org> |
769 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 769 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
770 | S: Maintained | 770 | S: Maintained |
771 | 771 | ||
772 | ARM/RISCPC ARCHITECTURE | 772 | ARM/RISCPC ARCHITECTURE |
773 | M: Russell King <linux@arm.linux.org.uk> | 773 | M: Russell King <linux@arm.linux.org.uk> |
774 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 774 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
775 | W: http://www.arm.linux.org.uk/ | 775 | W: http://www.arm.linux.org.uk/ |
776 | S: Maintained | 776 | S: Maintained |
777 | F: arch/arm/common/time-acorn.c | 777 | F: arch/arm/common/time-acorn.c |
778 | F: arch/arm/include/asm/hardware/entry-macro-iomd.S | 778 | F: arch/arm/include/asm/hardware/entry-macro-iomd.S |
779 | F: arch/arm/include/asm/hardware/ioc.h | 779 | F: arch/arm/include/asm/hardware/ioc.h |
780 | F: arch/arm/include/asm/hardware/iomd.h | 780 | F: arch/arm/include/asm/hardware/iomd.h |
781 | F: arch/arm/include/asm/hardware/memc.h | 781 | F: arch/arm/include/asm/hardware/memc.h |
782 | F: arch/arm/mach-rpc/ | 782 | F: arch/arm/mach-rpc/ |
783 | F: drivers/net/arm/ether* | 783 | F: drivers/net/arm/ether* |
784 | F: drivers/scsi/arm/ | 784 | F: drivers/scsi/arm/ |
785 | 785 | ||
786 | ARM/SHARK MACHINE SUPPORT | 786 | ARM/SHARK MACHINE SUPPORT |
787 | M: Alexander Schulz <alex@shark-linux.de> | 787 | M: Alexander Schulz <alex@shark-linux.de> |
788 | W: http://www.shark-linux.de/shark.html | 788 | W: http://www.shark-linux.de/shark.html |
789 | S: Maintained | 789 | S: Maintained |
790 | 790 | ||
791 | ARM/SAMSUNG ARM ARCHITECTURES | 791 | ARM/SAMSUNG ARM ARCHITECTURES |
792 | M: Ben Dooks <ben-linux@fluff.org> | 792 | M: Ben Dooks <ben-linux@fluff.org> |
793 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 793 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
794 | W: http://www.fluff.org/ben/linux/ | 794 | W: http://www.fluff.org/ben/linux/ |
795 | S: Maintained | 795 | S: Maintained |
796 | F: arch/arm/plat-s3c/ | 796 | F: arch/arm/plat-s3c/ |
797 | F: arch/arm/plat-s3c24xx/ | 797 | F: arch/arm/plat-s3c24xx/ |
798 | 798 | ||
799 | ARM/S3C2410 ARM ARCHITECTURE | 799 | ARM/S3C2410 ARM ARCHITECTURE |
800 | M: Ben Dooks <ben-linux@fluff.org> | 800 | M: Ben Dooks <ben-linux@fluff.org> |
801 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 801 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
802 | W: http://www.fluff.org/ben/linux/ | 802 | W: http://www.fluff.org/ben/linux/ |
803 | S: Maintained | 803 | S: Maintained |
804 | F: arch/arm/mach-s3c2410/ | 804 | F: arch/arm/mach-s3c2410/ |
805 | 805 | ||
806 | ARM/S3C2440 ARM ARCHITECTURE | 806 | ARM/S3C2440 ARM ARCHITECTURE |
807 | M: Ben Dooks <ben-linux@fluff.org> | 807 | M: Ben Dooks <ben-linux@fluff.org> |
808 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 808 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
809 | W: http://www.fluff.org/ben/linux/ | 809 | W: http://www.fluff.org/ben/linux/ |
810 | S: Maintained | 810 | S: Maintained |
811 | F: arch/arm/mach-s3c2440/ | 811 | F: arch/arm/mach-s3c2440/ |
812 | 812 | ||
813 | ARM/S3C2442 ARM ARCHITECTURE | 813 | ARM/S3C2442 ARM ARCHITECTURE |
814 | M: Ben Dooks <ben-linux@fluff.org> | 814 | M: Ben Dooks <ben-linux@fluff.org> |
815 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 815 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
816 | W: http://www.fluff.org/ben/linux/ | 816 | W: http://www.fluff.org/ben/linux/ |
817 | S: Maintained | 817 | S: Maintained |
818 | F: arch/arm/mach-s3c2442/ | 818 | F: arch/arm/mach-s3c2442/ |
819 | 819 | ||
820 | ARM/S3C2443 ARM ARCHITECTURE | 820 | ARM/S3C2443 ARM ARCHITECTURE |
821 | M: Ben Dooks <ben-linux@fluff.org> | 821 | M: Ben Dooks <ben-linux@fluff.org> |
822 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 822 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
823 | W: http://www.fluff.org/ben/linux/ | 823 | W: http://www.fluff.org/ben/linux/ |
824 | S: Maintained | 824 | S: Maintained |
825 | F: arch/arm/mach-s3c2443/ | 825 | F: arch/arm/mach-s3c2443/ |
826 | 826 | ||
827 | ARM/S3C6400 ARM ARCHITECTURE | 827 | ARM/S3C6400 ARM ARCHITECTURE |
828 | M: Ben Dooks <ben-linux@fluff.org> | 828 | M: Ben Dooks <ben-linux@fluff.org> |
829 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 829 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
830 | W: http://www.fluff.org/ben/linux/ | 830 | W: http://www.fluff.org/ben/linux/ |
831 | S: Maintained | 831 | S: Maintained |
832 | F: arch/arm/mach-s3c6400/ | 832 | F: arch/arm/mach-s3c6400/ |
833 | 833 | ||
834 | ARM/S3C6410 ARM ARCHITECTURE | 834 | ARM/S3C6410 ARM ARCHITECTURE |
835 | M: Ben Dooks <ben-linux@fluff.org> | 835 | M: Ben Dooks <ben-linux@fluff.org> |
836 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 836 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
837 | W: http://www.fluff.org/ben/linux/ | 837 | W: http://www.fluff.org/ben/linux/ |
838 | S: Maintained | 838 | S: Maintained |
839 | F: arch/arm/mach-s3c6410/ | 839 | F: arch/arm/mach-s3c6410/ |
840 | 840 | ||
841 | ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT | 841 | ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT |
842 | M: Lennert Buytenhek <kernel@wantstofly.org> | 842 | M: Lennert Buytenhek <kernel@wantstofly.org> |
843 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 843 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
844 | S: Maintained | 844 | S: Maintained |
845 | 845 | ||
846 | ARM/THECUS N2100 MACHINE SUPPORT | 846 | ARM/THECUS N2100 MACHINE SUPPORT |
847 | M: Lennert Buytenhek <kernel@wantstofly.org> | 847 | M: Lennert Buytenhek <kernel@wantstofly.org> |
848 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 848 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
849 | S: Maintained | 849 | S: Maintained |
850 | 850 | ||
851 | ARM/NUVOTON W90X900 ARM ARCHITECTURE | 851 | ARM/NUVOTON W90X900 ARM ARCHITECTURE |
852 | M: Wan ZongShun <mcuos.com@gmail.com> | 852 | M: Wan ZongShun <mcuos.com@gmail.com> |
853 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 853 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
854 | W: http://www.mcuos.com | 854 | W: http://www.mcuos.com |
855 | S: Maintained | 855 | S: Maintained |
856 | 856 | ||
857 | ARM/VFP SUPPORT | 857 | ARM/VFP SUPPORT |
858 | M: Russell King <linux@arm.linux.org.uk> | 858 | M: Russell King <linux@arm.linux.org.uk> |
859 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 859 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
860 | W: http://www.arm.linux.org.uk/ | 860 | W: http://www.arm.linux.org.uk/ |
861 | S: Maintained | 861 | S: Maintained |
862 | F: arch/arm/vfp/ | 862 | F: arch/arm/vfp/ |
863 | 863 | ||
864 | ASUS ACPI EXTRAS DRIVER | 864 | ASUS ACPI EXTRAS DRIVER |
865 | M: Corentin Chary <corentincj@iksaif.net> | 865 | M: Corentin Chary <corentincj@iksaif.net> |
866 | M: Karol Kozimor <sziwan@users.sourceforge.net> | 866 | M: Karol Kozimor <sziwan@users.sourceforge.net> |
867 | L: acpi4asus-user@lists.sourceforge.net | 867 | L: acpi4asus-user@lists.sourceforge.net |
868 | W: http://acpi4asus.sf.net | 868 | W: http://acpi4asus.sf.net |
869 | S: Maintained | 869 | S: Maintained |
870 | F: arch/x86/kernel/acpi/boot.c | 870 | F: arch/x86/kernel/acpi/boot.c |
871 | F: drivers/platform/x86/asus_acpi.c | 871 | F: drivers/platform/x86/asus_acpi.c |
872 | 872 | ||
873 | ASUS ASB100 HARDWARE MONITOR DRIVER | 873 | ASUS ASB100 HARDWARE MONITOR DRIVER |
874 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> | 874 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
875 | L: lm-sensors@lm-sensors.org | 875 | L: lm-sensors@lm-sensors.org |
876 | S: Maintained | 876 | S: Maintained |
877 | F: drivers/hwmon/asb100.c | 877 | F: drivers/hwmon/asb100.c |
878 | 878 | ||
879 | ASUS LAPTOP EXTRAS DRIVER | 879 | ASUS LAPTOP EXTRAS DRIVER |
880 | M: Corentin Chary <corentincj@iksaif.net> | 880 | M: Corentin Chary <corentincj@iksaif.net> |
881 | L: acpi4asus-user@lists.sourceforge.net | 881 | L: acpi4asus-user@lists.sourceforge.net |
882 | W: http://acpi4asus.sf.net | 882 | W: http://acpi4asus.sf.net |
883 | S: Maintained | 883 | S: Maintained |
884 | F: drivers/platform/x86/asus-laptop.c | 884 | F: drivers/platform/x86/asus-laptop.c |
885 | 885 | ||
886 | ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API | 886 | ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API |
887 | M: Dan Williams <dan.j.williams@intel.com> | 887 | M: Dan Williams <dan.j.williams@intel.com> |
888 | M: Maciej Sosnowski <maciej.sosnowski@intel.com> | 888 | M: Maciej Sosnowski <maciej.sosnowski@intel.com> |
889 | W: http://sourceforge.net/projects/xscaleiop | 889 | W: http://sourceforge.net/projects/xscaleiop |
890 | S: Supported | 890 | S: Supported |
891 | F: Documentation/crypto/async-tx-api.txt | 891 | F: Documentation/crypto/async-tx-api.txt |
892 | F: crypto/async_tx/ | 892 | F: crypto/async_tx/ |
893 | F: drivers/dma/ | 893 | F: drivers/dma/ |
894 | F: include/linux/dmaengine.h | 894 | F: include/linux/dmaengine.h |
895 | F: include/linux/async_tx.h | 895 | F: include/linux/async_tx.h |
896 | 896 | ||
897 | ATA OVER ETHERNET (AOE) DRIVER | 897 | ATA OVER ETHERNET (AOE) DRIVER |
898 | M: "Ed L. Cashin" <ecashin@coraid.com> | 898 | M: "Ed L. Cashin" <ecashin@coraid.com> |
899 | W: http://www.coraid.com/support/linux | 899 | W: http://www.coraid.com/support/linux |
900 | S: Supported | 900 | S: Supported |
901 | F: Documentation/aoe/ | 901 | F: Documentation/aoe/ |
902 | F: drivers/block/aoe/ | 902 | F: drivers/block/aoe/ |
903 | 903 | ||
904 | ATHEROS ATH5K WIRELESS DRIVER | 904 | ATHEROS ATH5K WIRELESS DRIVER |
905 | M: Jiri Slaby <jirislaby@gmail.com> | 905 | M: Jiri Slaby <jirislaby@gmail.com> |
906 | M: Nick Kossifidis <mickflemm@gmail.com> | 906 | M: Nick Kossifidis <mickflemm@gmail.com> |
907 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> | 907 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> |
908 | M: Bob Copeland <me@bobcopeland.com> | 908 | M: Bob Copeland <me@bobcopeland.com> |
909 | L: linux-wireless@vger.kernel.org | 909 | L: linux-wireless@vger.kernel.org |
910 | L: ath5k-devel@lists.ath5k.org | 910 | L: ath5k-devel@lists.ath5k.org |
911 | W: http://wireless.kernel.org/en/users/Drivers/ath5k | 911 | W: http://wireless.kernel.org/en/users/Drivers/ath5k |
912 | S: Maintained | 912 | S: Maintained |
913 | F: drivers/net/wireless/ath/ath5k/ | 913 | F: drivers/net/wireless/ath/ath5k/ |
914 | 914 | ||
915 | ATHEROS ATH9K WIRELESS DRIVER | 915 | ATHEROS ATH9K WIRELESS DRIVER |
916 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> | 916 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> |
917 | M: Jouni Malinen <jmalinen@atheros.com> | 917 | M: Jouni Malinen <jmalinen@atheros.com> |
918 | M: Sujith Manoharan <Sujith.Manoharan@atheros.com> | 918 | M: Sujith Manoharan <Sujith.Manoharan@atheros.com> |
919 | M: Vasanthakumar Thiagarajan <vasanth@atheros.com> | 919 | M: Vasanthakumar Thiagarajan <vasanth@atheros.com> |
920 | M: Senthil Balasubramanian <senthilkumar@atheros.com> | 920 | M: Senthil Balasubramanian <senthilkumar@atheros.com> |
921 | L: linux-wireless@vger.kernel.org | 921 | L: linux-wireless@vger.kernel.org |
922 | L: ath9k-devel@lists.ath9k.org | 922 | L: ath9k-devel@lists.ath9k.org |
923 | W: http://wireless.kernel.org/en/users/Drivers/ath9k | 923 | W: http://wireless.kernel.org/en/users/Drivers/ath9k |
924 | S: Supported | 924 | S: Supported |
925 | F: drivers/net/wireless/ath/ath9k/ | 925 | F: drivers/net/wireless/ath/ath9k/ |
926 | 926 | ||
927 | ATHEROS AR9170 WIRELESS DRIVER | 927 | ATHEROS AR9170 WIRELESS DRIVER |
928 | M: Christian Lamparter <chunkeey@web.de> | 928 | M: Christian Lamparter <chunkeey@web.de> |
929 | L: linux-wireless@vger.kernel.org | 929 | L: linux-wireless@vger.kernel.org |
930 | W: http://wireless.kernel.org/en/users/Drivers/ar9170 | 930 | W: http://wireless.kernel.org/en/users/Drivers/ar9170 |
931 | S: Maintained | 931 | S: Maintained |
932 | F: drivers/net/wireless/ath/ar9170/ | 932 | F: drivers/net/wireless/ath/ar9170/ |
933 | 933 | ||
934 | ATI_REMOTE2 DRIVER | 934 | ATI_REMOTE2 DRIVER |
935 | M: Ville Syrjala <syrjala@sci.fi> | 935 | M: Ville Syrjala <syrjala@sci.fi> |
936 | S: Maintained | 936 | S: Maintained |
937 | F: drivers/input/misc/ati_remote2.c | 937 | F: drivers/input/misc/ati_remote2.c |
938 | 938 | ||
939 | ATLX ETHERNET DRIVERS | 939 | ATLX ETHERNET DRIVERS |
940 | M: Jay Cliburn <jcliburn@gmail.com> | 940 | M: Jay Cliburn <jcliburn@gmail.com> |
941 | M: Chris Snook <chris.snook@gmail.com> | 941 | M: Chris Snook <chris.snook@gmail.com> |
942 | M: Jie Yang <jie.yang@atheros.com> | 942 | M: Jie Yang <jie.yang@atheros.com> |
943 | L: atl1-devel@lists.sourceforge.net | 943 | L: atl1-devel@lists.sourceforge.net |
944 | W: http://sourceforge.net/projects/atl1 | 944 | W: http://sourceforge.net/projects/atl1 |
945 | W: http://atl1.sourceforge.net | 945 | W: http://atl1.sourceforge.net |
946 | S: Maintained | 946 | S: Maintained |
947 | F: drivers/net/atlx/ | 947 | F: drivers/net/atlx/ |
948 | 948 | ||
949 | ATM | 949 | ATM |
950 | M: Chas Williams <chas@cmf.nrl.navy.mil> | 950 | M: Chas Williams <chas@cmf.nrl.navy.mil> |
951 | L: linux-atm-general@lists.sourceforge.net (subscribers-only) | 951 | L: linux-atm-general@lists.sourceforge.net (subscribers-only) |
952 | L: netdev@vger.kernel.org | 952 | L: netdev@vger.kernel.org |
953 | W: http://linux-atm.sourceforge.net | 953 | W: http://linux-atm.sourceforge.net |
954 | S: Maintained | 954 | S: Maintained |
955 | F: drivers/atm/ | 955 | F: drivers/atm/ |
956 | F: include/linux/atm* | 956 | F: include/linux/atm* |
957 | 957 | ||
958 | ATMEL AT91 MCI DRIVER | 958 | ATMEL AT91 MCI DRIVER |
959 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 959 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
960 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 960 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
961 | W: http://www.atmel.com/products/AT91/ | 961 | W: http://www.atmel.com/products/AT91/ |
962 | W: http://www.at91.com/ | 962 | W: http://www.at91.com/ |
963 | S: Maintained | 963 | S: Maintained |
964 | F: drivers/mmc/host/at91_mci.c | 964 | F: drivers/mmc/host/at91_mci.c |
965 | 965 | ||
966 | ATMEL AT91 / AT32 MCI DRIVER | 966 | ATMEL AT91 / AT32 MCI DRIVER |
967 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 967 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
968 | S: Maintained | 968 | S: Maintained |
969 | F: drivers/mmc/host/atmel-mci.c | 969 | F: drivers/mmc/host/atmel-mci.c |
970 | F: drivers/mmc/host/atmel-mci-regs.h | 970 | F: drivers/mmc/host/atmel-mci-regs.h |
971 | 971 | ||
972 | ATMEL AT91 / AT32 SERIAL DRIVER | 972 | ATMEL AT91 / AT32 SERIAL DRIVER |
973 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 973 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
974 | S: Supported | 974 | S: Supported |
975 | F: drivers/serial/atmel_serial.c | 975 | F: drivers/serial/atmel_serial.c |
976 | 976 | ||
977 | ATMEL LCDFB DRIVER | 977 | ATMEL LCDFB DRIVER |
978 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 978 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
979 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 979 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
980 | S: Maintained | 980 | S: Maintained |
981 | F: drivers/video/atmel_lcdfb.c | 981 | F: drivers/video/atmel_lcdfb.c |
982 | F: include/video/atmel_lcdc.h | 982 | F: include/video/atmel_lcdc.h |
983 | 983 | ||
984 | ATMEL MACB ETHERNET DRIVER | 984 | ATMEL MACB ETHERNET DRIVER |
985 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 985 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
986 | S: Supported | 986 | S: Supported |
987 | F: drivers/net/macb.* | 987 | F: drivers/net/macb.* |
988 | 988 | ||
989 | ATMEL SPI DRIVER | 989 | ATMEL SPI DRIVER |
990 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 990 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
991 | S: Supported | 991 | S: Supported |
992 | F: drivers/spi/atmel_spi.* | 992 | F: drivers/spi/atmel_spi.* |
993 | 993 | ||
994 | ATMEL USBA UDC DRIVER | 994 | ATMEL USBA UDC DRIVER |
995 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 995 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
996 | L: kernel@avr32linux.org | 996 | L: kernel@avr32linux.org |
997 | W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver | 997 | W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver |
998 | S: Supported | 998 | S: Supported |
999 | F: drivers/usb/gadget/atmel_usba_udc.* | 999 | F: drivers/usb/gadget/atmel_usba_udc.* |
1000 | 1000 | ||
1001 | ATMEL WIRELESS DRIVER | 1001 | ATMEL WIRELESS DRIVER |
1002 | M: Simon Kelley <simon@thekelleys.org.uk> | 1002 | M: Simon Kelley <simon@thekelleys.org.uk> |
1003 | L: linux-wireless@vger.kernel.org | 1003 | L: linux-wireless@vger.kernel.org |
1004 | W: http://www.thekelleys.org.uk/atmel | 1004 | W: http://www.thekelleys.org.uk/atmel |
1005 | W: http://atmelwlandriver.sourceforge.net/ | 1005 | W: http://atmelwlandriver.sourceforge.net/ |
1006 | S: Maintained | 1006 | S: Maintained |
1007 | F: drivers/net/wireless/atmel* | 1007 | F: drivers/net/wireless/atmel* |
1008 | 1008 | ||
1009 | AUDIT SUBSYSTEM | 1009 | AUDIT SUBSYSTEM |
1010 | M: Al Viro <viro@zeniv.linux.org.uk> | 1010 | M: Al Viro <viro@zeniv.linux.org.uk> |
1011 | M: Eric Paris <eparis@redhat.com> | 1011 | M: Eric Paris <eparis@redhat.com> |
1012 | L: linux-audit@redhat.com (subscribers-only) | 1012 | L: linux-audit@redhat.com (subscribers-only) |
1013 | W: http://people.redhat.com/sgrubb/audit/ | 1013 | W: http://people.redhat.com/sgrubb/audit/ |
1014 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git | 1014 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git |
1015 | S: Maintained | 1015 | S: Maintained |
1016 | F: include/linux/audit.h | 1016 | F: include/linux/audit.h |
1017 | F: kernel/audit* | 1017 | F: kernel/audit* |
1018 | 1018 | ||
1019 | AUXILIARY DISPLAY DRIVERS | 1019 | AUXILIARY DISPLAY DRIVERS |
1020 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> | 1020 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> |
1021 | W: http://miguelojeda.es/auxdisplay.htm | 1021 | W: http://miguelojeda.es/auxdisplay.htm |
1022 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 1022 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
1023 | S: Maintained | 1023 | S: Maintained |
1024 | F: drivers/auxdisplay/ | 1024 | F: drivers/auxdisplay/ |
1025 | F: include/linux/cfag12864b.h | 1025 | F: include/linux/cfag12864b.h |
1026 | 1026 | ||
1027 | AVR32 ARCHITECTURE | 1027 | AVR32 ARCHITECTURE |
1028 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 1028 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
1029 | W: http://www.atmel.com/products/AVR32/ | 1029 | W: http://www.atmel.com/products/AVR32/ |
1030 | W: http://avr32linux.org/ | 1030 | W: http://avr32linux.org/ |
1031 | W: http://avrfreaks.net/ | 1031 | W: http://avrfreaks.net/ |
1032 | S: Supported | 1032 | S: Supported |
1033 | F: arch/avr32/ | 1033 | F: arch/avr32/ |
1034 | 1034 | ||
1035 | AVR32/AT32AP MACHINE SUPPORT | 1035 | AVR32/AT32AP MACHINE SUPPORT |
1036 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 1036 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
1037 | S: Supported | 1037 | S: Supported |
1038 | F: arch/avr32/mach-at32ap/ | 1038 | F: arch/avr32/mach-at32ap/ |
1039 | 1039 | ||
1040 | AX.25 NETWORK LAYER | 1040 | AX.25 NETWORK LAYER |
1041 | M: Ralf Baechle <ralf@linux-mips.org> | 1041 | M: Ralf Baechle <ralf@linux-mips.org> |
1042 | L: linux-hams@vger.kernel.org | 1042 | L: linux-hams@vger.kernel.org |
1043 | W: http://www.linux-ax25.org/ | 1043 | W: http://www.linux-ax25.org/ |
1044 | S: Maintained | 1044 | S: Maintained |
1045 | F: include/linux/ax25.h | 1045 | F: include/linux/ax25.h |
1046 | F: include/net/ax25.h | 1046 | F: include/net/ax25.h |
1047 | F: net/ax25/ | 1047 | F: net/ax25/ |
1048 | 1048 | ||
1049 | B43 WIRELESS DRIVER | 1049 | B43 WIRELESS DRIVER |
1050 | M: Michael Buesch <mb@bu3sch.de> | 1050 | M: Michael Buesch <mb@bu3sch.de> |
1051 | M: Stefano Brivio <stefano.brivio@polimi.it> | 1051 | M: Stefano Brivio <stefano.brivio@polimi.it> |
1052 | L: linux-wireless@vger.kernel.org | 1052 | L: linux-wireless@vger.kernel.org |
1053 | W: http://linuxwireless.org/en/users/Drivers/b43 | 1053 | W: http://linuxwireless.org/en/users/Drivers/b43 |
1054 | S: Maintained | 1054 | S: Maintained |
1055 | F: drivers/net/wireless/b43/ | 1055 | F: drivers/net/wireless/b43/ |
1056 | 1056 | ||
1057 | B43LEGACY WIRELESS DRIVER | 1057 | B43LEGACY WIRELESS DRIVER |
1058 | M: Larry Finger <Larry.Finger@lwfinger.net> | 1058 | M: Larry Finger <Larry.Finger@lwfinger.net> |
1059 | M: Stefano Brivio <stefano.brivio@polimi.it> | 1059 | M: Stefano Brivio <stefano.brivio@polimi.it> |
1060 | L: linux-wireless@vger.kernel.org | 1060 | L: linux-wireless@vger.kernel.org |
1061 | W: http://linuxwireless.org/en/users/Drivers/b43 | 1061 | W: http://linuxwireless.org/en/users/Drivers/b43 |
1062 | S: Maintained | 1062 | S: Maintained |
1063 | F: drivers/net/wireless/b43legacy/ | 1063 | F: drivers/net/wireless/b43legacy/ |
1064 | 1064 | ||
1065 | BACKLIGHT CLASS/SUBSYSTEM | 1065 | BACKLIGHT CLASS/SUBSYSTEM |
1066 | M: Richard Purdie <rpurdie@rpsys.net> | 1066 | M: Richard Purdie <rpurdie@rpsys.net> |
1067 | S: Maintained | 1067 | S: Maintained |
1068 | F: drivers/video/backlight/ | 1068 | F: drivers/video/backlight/ |
1069 | F: include/linux/backlight.h | 1069 | F: include/linux/backlight.h |
1070 | 1070 | ||
1071 | BAYCOM/HDLCDRV DRIVERS FOR AX.25 | 1071 | BAYCOM/HDLCDRV DRIVERS FOR AX.25 |
1072 | M: Thomas Sailer <t.sailer@alumni.ethz.ch> | 1072 | M: Thomas Sailer <t.sailer@alumni.ethz.ch> |
1073 | L: linux-hams@vger.kernel.org | 1073 | L: linux-hams@vger.kernel.org |
1074 | W: http://www.baycom.org/~tom/ham/ham.html | 1074 | W: http://www.baycom.org/~tom/ham/ham.html |
1075 | S: Maintained | 1075 | S: Maintained |
1076 | F: drivers/net/hamradio/baycom* | 1076 | F: drivers/net/hamradio/baycom* |
1077 | 1077 | ||
1078 | BEFS FILE SYSTEM | 1078 | BEFS FILE SYSTEM |
1079 | M: "Sergey S. Kostyliov" <rathamahata@php4.ru> | 1079 | M: "Sergey S. Kostyliov" <rathamahata@php4.ru> |
1080 | S: Maintained | 1080 | S: Maintained |
1081 | F: Documentation/filesystems/befs.txt | 1081 | F: Documentation/filesystems/befs.txt |
1082 | F: fs/befs/ | 1082 | F: fs/befs/ |
1083 | 1083 | ||
1084 | BFS FILE SYSTEM | 1084 | BFS FILE SYSTEM |
1085 | M: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk> | 1085 | M: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk> |
1086 | S: Maintained | 1086 | S: Maintained |
1087 | F: Documentation/filesystems/bfs.txt | 1087 | F: Documentation/filesystems/bfs.txt |
1088 | F: fs/bfs/ | 1088 | F: fs/bfs/ |
1089 | F: include/linux/bfs_fs.h | 1089 | F: include/linux/bfs_fs.h |
1090 | 1090 | ||
1091 | BLACKFIN ARCHITECTURE | 1091 | BLACKFIN ARCHITECTURE |
1092 | M: Mike Frysinger <vapier@gentoo.org> | 1092 | M: Mike Frysinger <vapier@gentoo.org> |
1093 | L: uclinux-dist-devel@blackfin.uclinux.org | 1093 | L: uclinux-dist-devel@blackfin.uclinux.org |
1094 | W: http://blackfin.uclinux.org | 1094 | W: http://blackfin.uclinux.org |
1095 | S: Supported | 1095 | S: Supported |
1096 | F: arch/blackfin/ | 1096 | F: arch/blackfin/ |
1097 | 1097 | ||
1098 | BLACKFIN EMAC DRIVER | 1098 | BLACKFIN EMAC DRIVER |
1099 | M: Michael Hennerich <michael.hennerich@analog.com> | 1099 | M: Michael Hennerich <michael.hennerich@analog.com> |
1100 | L: uclinux-dist-devel@blackfin.uclinux.org | 1100 | L: uclinux-dist-devel@blackfin.uclinux.org |
1101 | W: http://blackfin.uclinux.org | 1101 | W: http://blackfin.uclinux.org |
1102 | S: Supported | 1102 | S: Supported |
1103 | F: drivers/net/bfin_mac.* | 1103 | F: drivers/net/bfin_mac.* |
1104 | 1104 | ||
1105 | BLACKFIN RTC DRIVER | 1105 | BLACKFIN RTC DRIVER |
1106 | M: Mike Frysinger <vapier.adi@gmail.com> | 1106 | M: Mike Frysinger <vapier.adi@gmail.com> |
1107 | L: uclinux-dist-devel@blackfin.uclinux.org | 1107 | L: uclinux-dist-devel@blackfin.uclinux.org |
1108 | W: http://blackfin.uclinux.org | 1108 | W: http://blackfin.uclinux.org |
1109 | S: Supported | 1109 | S: Supported |
1110 | F: drivers/rtc/rtc-bfin.c | 1110 | F: drivers/rtc/rtc-bfin.c |
1111 | 1111 | ||
1112 | BLACKFIN SERIAL DRIVER | 1112 | BLACKFIN SERIAL DRIVER |
1113 | M: Sonic Zhang <sonic.zhang@analog.com> | 1113 | M: Sonic Zhang <sonic.zhang@analog.com> |
1114 | L: uclinux-dist-devel@blackfin.uclinux.org | 1114 | L: uclinux-dist-devel@blackfin.uclinux.org |
1115 | W: http://blackfin.uclinux.org | 1115 | W: http://blackfin.uclinux.org |
1116 | S: Supported | 1116 | S: Supported |
1117 | F: drivers/serial/bfin_5xx.c | 1117 | F: drivers/serial/bfin_5xx.c |
1118 | 1118 | ||
1119 | BLACKFIN WATCHDOG DRIVER | 1119 | BLACKFIN WATCHDOG DRIVER |
1120 | M: Mike Frysinger <vapier.adi@gmail.com> | 1120 | M: Mike Frysinger <vapier.adi@gmail.com> |
1121 | L: uclinux-dist-devel@blackfin.uclinux.org | 1121 | L: uclinux-dist-devel@blackfin.uclinux.org |
1122 | W: http://blackfin.uclinux.org | 1122 | W: http://blackfin.uclinux.org |
1123 | S: Supported | 1123 | S: Supported |
1124 | F: drivers/watchdog/bfin_wdt.c | 1124 | F: drivers/watchdog/bfin_wdt.c |
1125 | 1125 | ||
1126 | BLACKFIN I2C TWI DRIVER | 1126 | BLACKFIN I2C TWI DRIVER |
1127 | M: Sonic Zhang <sonic.zhang@analog.com> | 1127 | M: Sonic Zhang <sonic.zhang@analog.com> |
1128 | L: uclinux-dist-devel@blackfin.uclinux.org | 1128 | L: uclinux-dist-devel@blackfin.uclinux.org |
1129 | W: http://blackfin.uclinux.org/ | 1129 | W: http://blackfin.uclinux.org/ |
1130 | S: Supported | 1130 | S: Supported |
1131 | F: drivers/i2c/busses/i2c-bfin-twi.c | 1131 | F: drivers/i2c/busses/i2c-bfin-twi.c |
1132 | 1132 | ||
1133 | BLOCK LAYER | 1133 | BLOCK LAYER |
1134 | M: Jens Axboe <axboe@kernel.dk> | 1134 | M: Jens Axboe <axboe@kernel.dk> |
1135 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git | 1135 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git |
1136 | S: Maintained | 1136 | S: Maintained |
1137 | F: block/ | 1137 | F: block/ |
1138 | 1138 | ||
1139 | BLOCK2MTD DRIVER | 1139 | BLOCK2MTD DRIVER |
1140 | M: Joern Engel <joern@lazybastard.org> | 1140 | M: Joern Engel <joern@lazybastard.org> |
1141 | L: linux-mtd@lists.infradead.org | 1141 | L: linux-mtd@lists.infradead.org |
1142 | S: Maintained | 1142 | S: Maintained |
1143 | F: drivers/mtd/devices/block2mtd.c | 1143 | F: drivers/mtd/devices/block2mtd.c |
1144 | 1144 | ||
1145 | BLUETOOTH DRIVERS | 1145 | BLUETOOTH DRIVERS |
1146 | M: Marcel Holtmann <marcel@holtmann.org> | 1146 | M: Marcel Holtmann <marcel@holtmann.org> |
1147 | L: linux-bluetooth@vger.kernel.org | 1147 | L: linux-bluetooth@vger.kernel.org |
1148 | W: http://www.bluez.org/ | 1148 | W: http://www.bluez.org/ |
1149 | S: Maintained | 1149 | S: Maintained |
1150 | F: drivers/bluetooth/ | 1150 | F: drivers/bluetooth/ |
1151 | 1151 | ||
1152 | BLUETOOTH SUBSYSTEM | 1152 | BLUETOOTH SUBSYSTEM |
1153 | M: Marcel Holtmann <marcel@holtmann.org> | 1153 | M: Marcel Holtmann <marcel@holtmann.org> |
1154 | L: linux-bluetooth@vger.kernel.org | 1154 | L: linux-bluetooth@vger.kernel.org |
1155 | W: http://www.bluez.org/ | 1155 | W: http://www.bluez.org/ |
1156 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git | 1156 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git |
1157 | S: Maintained | 1157 | S: Maintained |
1158 | F: net/bluetooth/ | 1158 | F: net/bluetooth/ |
1159 | F: include/net/bluetooth/ | 1159 | F: include/net/bluetooth/ |
1160 | 1160 | ||
1161 | BONDING DRIVER | 1161 | BONDING DRIVER |
1162 | M: Jay Vosburgh <fubar@us.ibm.com> | 1162 | M: Jay Vosburgh <fubar@us.ibm.com> |
1163 | L: bonding-devel@lists.sourceforge.net | 1163 | L: bonding-devel@lists.sourceforge.net |
1164 | W: http://sourceforge.net/projects/bonding/ | 1164 | W: http://sourceforge.net/projects/bonding/ |
1165 | S: Supported | 1165 | S: Supported |
1166 | F: drivers/net/bonding/ | 1166 | F: drivers/net/bonding/ |
1167 | F: include/linux/if_bonding.h | 1167 | F: include/linux/if_bonding.h |
1168 | 1168 | ||
1169 | BROADCOM B44 10/100 ETHERNET DRIVER | 1169 | BROADCOM B44 10/100 ETHERNET DRIVER |
1170 | M: Gary Zambrano <zambrano@broadcom.com> | 1170 | M: Gary Zambrano <zambrano@broadcom.com> |
1171 | L: netdev@vger.kernel.org | 1171 | L: netdev@vger.kernel.org |
1172 | S: Supported | 1172 | S: Supported |
1173 | F: drivers/net/b44.* | 1173 | F: drivers/net/b44.* |
1174 | 1174 | ||
1175 | BROADCOM BNX2 GIGABIT ETHERNET DRIVER | 1175 | BROADCOM BNX2 GIGABIT ETHERNET DRIVER |
1176 | M: Michael Chan <mchan@broadcom.com> | 1176 | M: Michael Chan <mchan@broadcom.com> |
1177 | L: netdev@vger.kernel.org | 1177 | L: netdev@vger.kernel.org |
1178 | S: Supported | 1178 | S: Supported |
1179 | F: drivers/net/bnx2.* | 1179 | F: drivers/net/bnx2.* |
1180 | F: drivers/net/bnx2_* | 1180 | F: drivers/net/bnx2_* |
1181 | 1181 | ||
1182 | BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER | 1182 | BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER |
1183 | M: Eilon Greenstein <eilong@broadcom.com> | 1183 | M: Eilon Greenstein <eilong@broadcom.com> |
1184 | L: netdev@vger.kernel.org | 1184 | L: netdev@vger.kernel.org |
1185 | S: Supported | 1185 | S: Supported |
1186 | F: drivers/net/bnx2x* | 1186 | F: drivers/net/bnx2x* |
1187 | 1187 | ||
1188 | BROADCOM TG3 GIGABIT ETHERNET DRIVER | 1188 | BROADCOM TG3 GIGABIT ETHERNET DRIVER |
1189 | M: Matt Carlson <mcarlson@broadcom.com> | 1189 | M: Matt Carlson <mcarlson@broadcom.com> |
1190 | M: Michael Chan <mchan@broadcom.com> | 1190 | M: Michael Chan <mchan@broadcom.com> |
1191 | L: netdev@vger.kernel.org | 1191 | L: netdev@vger.kernel.org |
1192 | S: Supported | 1192 | S: Supported |
1193 | F: drivers/net/tg3.* | 1193 | F: drivers/net/tg3.* |
1194 | 1194 | ||
1195 | BSG (block layer generic sg v4 driver) | 1195 | BSG (block layer generic sg v4 driver) |
1196 | M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 1196 | M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> |
1197 | L: linux-scsi@vger.kernel.org | 1197 | L: linux-scsi@vger.kernel.org |
1198 | S: Supported | 1198 | S: Supported |
1199 | F: block/bsg.c | 1199 | F: block/bsg.c |
1200 | F: include/linux/bsg.h | 1200 | F: include/linux/bsg.h |
1201 | 1201 | ||
1202 | BT8XXGPIO DRIVER | 1202 | BT8XXGPIO DRIVER |
1203 | M: Michael Buesch <mb@bu3sch.de> | 1203 | M: Michael Buesch <mb@bu3sch.de> |
1204 | W: http://bu3sch.de/btgpio.php | 1204 | W: http://bu3sch.de/btgpio.php |
1205 | S: Maintained | 1205 | S: Maintained |
1206 | F: drivers/gpio/bt8xxgpio.c | 1206 | F: drivers/gpio/bt8xxgpio.c |
1207 | 1207 | ||
1208 | BTRFS FILE SYSTEM | 1208 | BTRFS FILE SYSTEM |
1209 | M: Chris Mason <chris.mason@oracle.com> | 1209 | M: Chris Mason <chris.mason@oracle.com> |
1210 | L: linux-btrfs@vger.kernel.org | 1210 | L: linux-btrfs@vger.kernel.org |
1211 | W: http://btrfs.wiki.kernel.org/ | 1211 | W: http://btrfs.wiki.kernel.org/ |
1212 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git | 1212 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git |
1213 | S: Maintained | 1213 | S: Maintained |
1214 | F: Documentation/filesystems/btrfs.txt | 1214 | F: Documentation/filesystems/btrfs.txt |
1215 | F: fs/btrfs/ | 1215 | F: fs/btrfs/ |
1216 | 1216 | ||
1217 | BTTV VIDEO4LINUX DRIVER | 1217 | BTTV VIDEO4LINUX DRIVER |
1218 | M: Mauro Carvalho Chehab <mchehab@infradead.org> | 1218 | M: Mauro Carvalho Chehab <mchehab@infradead.org> |
1219 | L: linux-media@vger.kernel.org | 1219 | L: linux-media@vger.kernel.org |
1220 | W: http://linuxtv.org | 1220 | W: http://linuxtv.org |
1221 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 1221 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
1222 | S: Maintained | 1222 | S: Maintained |
1223 | F: Documentation/video4linux/bttv/ | 1223 | F: Documentation/video4linux/bttv/ |
1224 | F: drivers/media/video/bt8xx/bttv* | 1224 | F: drivers/media/video/bt8xx/bttv* |
1225 | 1225 | ||
1226 | CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS | 1226 | CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS |
1227 | M: David Howells <dhowells@redhat.com> | 1227 | M: David Howells <dhowells@redhat.com> |
1228 | L: linux-cachefs@redhat.com | 1228 | L: linux-cachefs@redhat.com |
1229 | S: Supported | 1229 | S: Supported |
1230 | F: Documentation/filesystems/caching/cachefiles.txt | 1230 | F: Documentation/filesystems/caching/cachefiles.txt |
1231 | F: fs/cachefiles/ | 1231 | F: fs/cachefiles/ |
1232 | 1232 | ||
1233 | CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER | 1233 | CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER |
1234 | M: Jonathan Corbet <corbet@lwn.net> | 1234 | M: Jonathan Corbet <corbet@lwn.net> |
1235 | L: linux-media@vger.kernel.org | 1235 | L: linux-media@vger.kernel.org |
1236 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 1236 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
1237 | S: Maintained | 1237 | S: Maintained |
1238 | F: Documentation/video4linux/cafe_ccic | 1238 | F: Documentation/video4linux/cafe_ccic |
1239 | F: drivers/media/video/cafe_ccic* | 1239 | F: drivers/media/video/cafe_ccic* |
1240 | 1240 | ||
1241 | CALGARY x86-64 IOMMU | 1241 | CALGARY x86-64 IOMMU |
1242 | M: Muli Ben-Yehuda <muli@il.ibm.com> | 1242 | M: Muli Ben-Yehuda <muli@il.ibm.com> |
1243 | M: "Jon D. Mason" <jdmason@kudzu.us> | 1243 | M: "Jon D. Mason" <jdmason@kudzu.us> |
1244 | L: discuss@x86-64.org | 1244 | L: discuss@x86-64.org |
1245 | S: Maintained | 1245 | S: Maintained |
1246 | F: arch/x86/kernel/pci-calgary_64.c | 1246 | F: arch/x86/kernel/pci-calgary_64.c |
1247 | F: arch/x86/kernel/tce_64.c | 1247 | F: arch/x86/kernel/tce_64.c |
1248 | F: arch/x86/include/asm/calgary.h | 1248 | F: arch/x86/include/asm/calgary.h |
1249 | F: arch/x86/include/asm/tce.h | 1249 | F: arch/x86/include/asm/tce.h |
1250 | 1250 | ||
1251 | CAN NETWORK LAYER | 1251 | CAN NETWORK LAYER |
1252 | M: Urs Thuermann <urs.thuermann@volkswagen.de> | 1252 | M: Urs Thuermann <urs.thuermann@volkswagen.de> |
1253 | M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de> | 1253 | M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de> |
1254 | L: socketcan-core@lists.berlios.de (subscribers-only) | 1254 | L: socketcan-core@lists.berlios.de (subscribers-only) |
1255 | W: http://developer.berlios.de/projects/socketcan/ | 1255 | W: http://developer.berlios.de/projects/socketcan/ |
1256 | S: Maintained | 1256 | S: Maintained |
1257 | F: drivers/net/can/ | 1257 | F: drivers/net/can/ |
1258 | F: include/linux/can/ | 1258 | F: include/linux/can/ |
1259 | F: include/linux/can.h | 1259 | F: include/linux/can.h |
1260 | 1260 | ||
1261 | CAN NETWORK DRIVERS | 1261 | CAN NETWORK DRIVERS |
1262 | M: Wolfgang Grandegger <wg@grandegger.com> | 1262 | M: Wolfgang Grandegger <wg@grandegger.com> |
1263 | L: socketcan-core@lists.berlios.de (subscribers-only) | 1263 | L: socketcan-core@lists.berlios.de (subscribers-only) |
1264 | W: http://developer.berlios.de/projects/socketcan/ | 1264 | W: http://developer.berlios.de/projects/socketcan/ |
1265 | S: Maintained | 1265 | S: Maintained |
1266 | 1266 | ||
1267 | CELL BROADBAND ENGINE ARCHITECTURE | 1267 | CELL BROADBAND ENGINE ARCHITECTURE |
1268 | M: Arnd Bergmann <arnd@arndb.de> | 1268 | M: Arnd Bergmann <arnd@arndb.de> |
1269 | L: linuxppc-dev@ozlabs.org | 1269 | L: linuxppc-dev@ozlabs.org |
1270 | L: cbe-oss-dev@ozlabs.org | 1270 | L: cbe-oss-dev@ozlabs.org |
1271 | W: http://www.ibm.com/developerworks/power/cell/ | 1271 | W: http://www.ibm.com/developerworks/power/cell/ |
1272 | S: Supported | 1272 | S: Supported |
1273 | F: arch/powerpc/include/asm/cell*.h | 1273 | F: arch/powerpc/include/asm/cell*.h |
1274 | F: arch/powerpc/include/asm/spu*.h | 1274 | F: arch/powerpc/include/asm/spu*.h |
1275 | F: arch/powerpc/oprofile/*cell* | 1275 | F: arch/powerpc/oprofile/*cell* |
1276 | F: arch/powerpc/platforms/cell/ | 1276 | F: arch/powerpc/platforms/cell/ |
1277 | 1277 | ||
1278 | CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM: | 1278 | CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM: |
1279 | M: David Vrabel <david.vrabel@csr.com> | 1279 | M: David Vrabel <david.vrabel@csr.com> |
1280 | L: linux-usb@vger.kernel.org | 1280 | L: linux-usb@vger.kernel.org |
1281 | S: Supported | 1281 | S: Supported |
1282 | F: Documentation/usb/WUSB-Design-overview.txt | 1282 | F: Documentation/usb/WUSB-Design-overview.txt |
1283 | F: Documentation/usb/wusb-cbaf | 1283 | F: Documentation/usb/wusb-cbaf |
1284 | F: drivers/usb/wusbcore/ | 1284 | F: drivers/usb/wusbcore/ |
1285 | F: include/linux/usb/wusb* | 1285 | F: include/linux/usb/wusb* |
1286 | 1286 | ||
1287 | CFAG12864B LCD DRIVER | 1287 | CFAG12864B LCD DRIVER |
1288 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> | 1288 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> |
1289 | W: http://miguelojeda.es/auxdisplay.htm | 1289 | W: http://miguelojeda.es/auxdisplay.htm |
1290 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 1290 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
1291 | S: Maintained | 1291 | S: Maintained |
1292 | F: drivers/auxdisplay/cfag12864b.c | 1292 | F: drivers/auxdisplay/cfag12864b.c |
1293 | F: include/linux/cfag12864b.h | 1293 | F: include/linux/cfag12864b.h |
1294 | 1294 | ||
1295 | CFAG12864BFB LCD FRAMEBUFFER DRIVER | 1295 | CFAG12864BFB LCD FRAMEBUFFER DRIVER |
1296 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> | 1296 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> |
1297 | W: http://miguelojeda.es/auxdisplay.htm | 1297 | W: http://miguelojeda.es/auxdisplay.htm |
1298 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 1298 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
1299 | S: Maintained | 1299 | S: Maintained |
1300 | F: drivers/auxdisplay/cfag12864bfb.c | 1300 | F: drivers/auxdisplay/cfag12864bfb.c |
1301 | F: include/linux/cfag12864b.h | 1301 | F: include/linux/cfag12864b.h |
1302 | 1302 | ||
1303 | CFG80211 and NL80211 | 1303 | CFG80211 and NL80211 |
1304 | M: Johannes Berg <johannes@sipsolutions.net> | 1304 | M: Johannes Berg <johannes@sipsolutions.net> |
1305 | L: linux-wireless@vger.kernel.org | 1305 | L: linux-wireless@vger.kernel.org |
1306 | S: Maintained | 1306 | S: Maintained |
1307 | F: include/linux/nl80211.h | 1307 | F: include/linux/nl80211.h |
1308 | F: include/net/cfg80211.h | 1308 | F: include/net/cfg80211.h |
1309 | F: net/wireless/* | 1309 | F: net/wireless/* |
1310 | X: net/wireless/wext* | 1310 | X: net/wireless/wext* |
1311 | 1311 | ||
1312 | CHECKPATCH | 1312 | CHECKPATCH |
1313 | M: Andy Whitcroft <apw@canonical.com> | 1313 | M: Andy Whitcroft <apw@canonical.com> |
1314 | S: Supported | 1314 | S: Supported |
1315 | F: scripts/checkpatch.pl | 1315 | F: scripts/checkpatch.pl |
1316 | 1316 | ||
1317 | CISCO 10G ETHERNET DRIVER | 1317 | CISCO 10G ETHERNET DRIVER |
1318 | M: Scott Feldman <scofeldm@cisco.com> | 1318 | M: Scott Feldman <scofeldm@cisco.com> |
1319 | M: Joe Eykholt <jeykholt@cisco.com> | 1319 | M: Joe Eykholt <jeykholt@cisco.com> |
1320 | S: Supported | 1320 | S: Supported |
1321 | F: drivers/net/enic/ | 1321 | F: drivers/net/enic/ |
1322 | 1322 | ||
1323 | CIRRUS LOGIC EP93XX ETHERNET DRIVER | 1323 | CIRRUS LOGIC EP93XX ETHERNET DRIVER |
1324 | M: Lennert Buytenhek <kernel@wantstofly.org> | 1324 | M: Lennert Buytenhek <kernel@wantstofly.org> |
1325 | L: netdev@vger.kernel.org | 1325 | L: netdev@vger.kernel.org |
1326 | S: Maintained | 1326 | S: Maintained |
1327 | F: drivers/net/arm/ep93xx_eth.c | 1327 | F: drivers/net/arm/ep93xx_eth.c |
1328 | 1328 | ||
1329 | CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER | 1329 | CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER |
1330 | M: Lennert Buytenhek <kernel@wantstofly.org> | 1330 | M: Lennert Buytenhek <kernel@wantstofly.org> |
1331 | L: linux-usb@vger.kernel.org | 1331 | L: linux-usb@vger.kernel.org |
1332 | S: Maintained | 1332 | S: Maintained |
1333 | F: drivers/usb/host/ohci-ep93xx.c | 1333 | F: drivers/usb/host/ohci-ep93xx.c |
1334 | 1334 | ||
1335 | CIRRUS LOGIC CS4270 SOUND DRIVER | 1335 | CIRRUS LOGIC CS4270 SOUND DRIVER |
1336 | M: Timur Tabi <timur@freescale.com> | 1336 | M: Timur Tabi <timur@freescale.com> |
1337 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 1337 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
1338 | S: Supported | 1338 | S: Supported |
1339 | F: sound/soc/codecs/cs4270* | 1339 | F: sound/soc/codecs/cs4270* |
1340 | 1340 | ||
1341 | CLK API | 1341 | CLK API |
1342 | M: Russell King <linux@arm.linux.org.uk> | 1342 | M: Russell King <linux@arm.linux.org.uk> |
1343 | F: include/linux/clk.h | 1343 | F: include/linux/clk.h |
1344 | 1344 | ||
1345 | CISCO FCOE HBA DRIVER | 1345 | CISCO FCOE HBA DRIVER |
1346 | M: Abhijeet Joglekar <abjoglek@cisco.com> | 1346 | M: Abhijeet Joglekar <abjoglek@cisco.com> |
1347 | M: Joe Eykholt <jeykholt@cisco.com> | 1347 | M: Joe Eykholt <jeykholt@cisco.com> |
1348 | L: linux-scsi@vger.kernel.org | 1348 | L: linux-scsi@vger.kernel.org |
1349 | S: Supported | 1349 | S: Supported |
1350 | F: drivers/scsi/fnic/ | 1350 | F: drivers/scsi/fnic/ |
1351 | 1351 | ||
1352 | CODA FILE SYSTEM | 1352 | CODA FILE SYSTEM |
1353 | M: Jan Harkes <jaharkes@cs.cmu.edu> | 1353 | M: Jan Harkes <jaharkes@cs.cmu.edu> |
1354 | M: coda@cs.cmu.edu | 1354 | M: coda@cs.cmu.edu |
1355 | L: codalist@coda.cs.cmu.edu | 1355 | L: codalist@coda.cs.cmu.edu |
1356 | W: http://www.coda.cs.cmu.edu/ | 1356 | W: http://www.coda.cs.cmu.edu/ |
1357 | S: Maintained | 1357 | S: Maintained |
1358 | F: Documentation/filesystems/coda.txt | 1358 | F: Documentation/filesystems/coda.txt |
1359 | F: fs/coda/ | 1359 | F: fs/coda/ |
1360 | F: include/linux/coda*.h | 1360 | F: include/linux/coda*.h |
1361 | 1361 | ||
1362 | COMMON INTERNET FILE SYSTEM (CIFS) | 1362 | COMMON INTERNET FILE SYSTEM (CIFS) |
1363 | M: Steve French <sfrench@samba.org> | 1363 | M: Steve French <sfrench@samba.org> |
1364 | L: linux-cifs-client@lists.samba.org | 1364 | L: linux-cifs-client@lists.samba.org |
1365 | L: samba-technical@lists.samba.org | 1365 | L: samba-technical@lists.samba.org |
1366 | W: http://linux-cifs.samba.org/ | 1366 | W: http://linux-cifs.samba.org/ |
1367 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git | 1367 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git |
1368 | S: Supported | 1368 | S: Supported |
1369 | F: Documentation/filesystems/cifs.txt | 1369 | F: Documentation/filesystems/cifs.txt |
1370 | F: fs/cifs/ | 1370 | F: fs/cifs/ |
1371 | 1371 | ||
1372 | COMPACTPCI HOTPLUG CORE | 1372 | COMPACTPCI HOTPLUG CORE |
1373 | M: Scott Murray <scott@spiteful.org> | 1373 | M: Scott Murray <scott@spiteful.org> |
1374 | L: linux-pci@vger.kernel.org | 1374 | L: linux-pci@vger.kernel.org |
1375 | S: Maintained | 1375 | S: Maintained |
1376 | F: drivers/pci/hotplug/cpci_hotplug* | 1376 | F: drivers/pci/hotplug/cpci_hotplug* |
1377 | 1377 | ||
1378 | COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER | 1378 | COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER |
1379 | M: Scott Murray <scott@spiteful.org> | 1379 | M: Scott Murray <scott@spiteful.org> |
1380 | L: linux-pci@vger.kernel.org | 1380 | L: linux-pci@vger.kernel.org |
1381 | S: Maintained | 1381 | S: Maintained |
1382 | F: drivers/pci/hotplug/cpcihp_zt5550.* | 1382 | F: drivers/pci/hotplug/cpcihp_zt5550.* |
1383 | 1383 | ||
1384 | COMPACTPCI HOTPLUG GENERIC DRIVER | 1384 | COMPACTPCI HOTPLUG GENERIC DRIVER |
1385 | M: Scott Murray <scott@spiteful.org> | 1385 | M: Scott Murray <scott@spiteful.org> |
1386 | L: linux-pci@vger.kernel.org | 1386 | L: linux-pci@vger.kernel.org |
1387 | S: Maintained | 1387 | S: Maintained |
1388 | F: drivers/pci/hotplug/cpcihp_generic.c | 1388 | F: drivers/pci/hotplug/cpcihp_generic.c |
1389 | 1389 | ||
1390 | COMPAL LAPTOP SUPPORT | 1390 | COMPAL LAPTOP SUPPORT |
1391 | M: Cezary Jackiewicz <cezary.jackiewicz@gmail.com> | 1391 | M: Cezary Jackiewicz <cezary.jackiewicz@gmail.com> |
1392 | S: Maintained | 1392 | S: Maintained |
1393 | F: drivers/platform/x86/compal-laptop.c | 1393 | F: drivers/platform/x86/compal-laptop.c |
1394 | 1394 | ||
1395 | COMPUTONE INTELLIPORT MULTIPORT CARD | 1395 | COMPUTONE INTELLIPORT MULTIPORT CARD |
1396 | M: "Michael H. Warfield" <mhw@wittsend.com> | 1396 | M: "Michael H. Warfield" <mhw@wittsend.com> |
1397 | W: http://www.wittsend.com/computone.html | 1397 | W: http://www.wittsend.com/computone.html |
1398 | S: Maintained | 1398 | S: Maintained |
1399 | F: Documentation/serial/computone.txt | 1399 | F: Documentation/serial/computone.txt |
1400 | F: drivers/char/ip2/ | 1400 | F: drivers/char/ip2/ |
1401 | 1401 | ||
1402 | CONEXANT ACCESSRUNNER USB DRIVER | 1402 | CONEXANT ACCESSRUNNER USB DRIVER |
1403 | M: Simon Arlott <cxacru@fire.lp0.eu> | 1403 | M: Simon Arlott <cxacru@fire.lp0.eu> |
1404 | L: accessrunner-general@lists.sourceforge.net | 1404 | L: accessrunner-general@lists.sourceforge.net |
1405 | W: http://accessrunner.sourceforge.net/ | 1405 | W: http://accessrunner.sourceforge.net/ |
1406 | S: Maintained | 1406 | S: Maintained |
1407 | F: drivers/usb/atm/cxacru.c | 1407 | F: drivers/usb/atm/cxacru.c |
1408 | 1408 | ||
1409 | CONFIGFS | 1409 | CONFIGFS |
1410 | M: Joel Becker <joel.becker@oracle.com> | 1410 | M: Joel Becker <joel.becker@oracle.com> |
1411 | S: Supported | 1411 | S: Supported |
1412 | F: fs/configfs/ | 1412 | F: fs/configfs/ |
1413 | F: include/linux/configfs.h | 1413 | F: include/linux/configfs.h |
1414 | 1414 | ||
1415 | CONNECTOR | 1415 | CONNECTOR |
1416 | M: Evgeniy Polyakov <zbr@ioremap.net> | 1416 | M: Evgeniy Polyakov <zbr@ioremap.net> |
1417 | L: netdev@vger.kernel.org | 1417 | L: netdev@vger.kernel.org |
1418 | S: Maintained | 1418 | S: Maintained |
1419 | F: drivers/connector/ | 1419 | F: drivers/connector/ |
1420 | 1420 | ||
1421 | CONTROL GROUPS (CGROUPS) | 1421 | CONTROL GROUPS (CGROUPS) |
1422 | M: Paul Menage <menage@google.com> | 1422 | M: Paul Menage <menage@google.com> |
1423 | M: Li Zefan <lizf@cn.fujitsu.com> | 1423 | M: Li Zefan <lizf@cn.fujitsu.com> |
1424 | L: containers@lists.linux-foundation.org | 1424 | L: containers@lists.linux-foundation.org |
1425 | S: Maintained | 1425 | S: Maintained |
1426 | F: include/linux/cgroup* | 1426 | F: include/linux/cgroup* |
1427 | F: kernel/cgroup* | 1427 | F: kernel/cgroup* |
1428 | F: mm/*cgroup* | 1428 | F: mm/*cgroup* |
1429 | 1429 | ||
1430 | CORETEMP HARDWARE MONITORING DRIVER | 1430 | CORETEMP HARDWARE MONITORING DRIVER |
1431 | M: Rudolf Marek <r.marek@assembler.cz> | 1431 | M: Rudolf Marek <r.marek@assembler.cz> |
1432 | L: lm-sensors@lm-sensors.org | 1432 | L: lm-sensors@lm-sensors.org |
1433 | S: Maintained | 1433 | S: Maintained |
1434 | F: Documentation/hwmon/coretemp | 1434 | F: Documentation/hwmon/coretemp |
1435 | F: drivers/hwmon/coretemp.c | 1435 | F: drivers/hwmon/coretemp.c |
1436 | 1436 | ||
1437 | COSA/SRP SYNC SERIAL DRIVER | 1437 | COSA/SRP SYNC SERIAL DRIVER |
1438 | M: Jan "Yenya" Kasprzak <kas@fi.muni.cz> | 1438 | M: Jan "Yenya" Kasprzak <kas@fi.muni.cz> |
1439 | W: http://www.fi.muni.cz/~kas/cosa/ | 1439 | W: http://www.fi.muni.cz/~kas/cosa/ |
1440 | S: Maintained | 1440 | S: Maintained |
1441 | F: drivers/net/wan/cosa* | 1441 | F: drivers/net/wan/cosa* |
1442 | 1442 | ||
1443 | CPMAC ETHERNET DRIVER | 1443 | CPMAC ETHERNET DRIVER |
1444 | M: Florian Fainelli <florian@openwrt.org> | 1444 | M: Florian Fainelli <florian@openwrt.org> |
1445 | L: netdev@vger.kernel.org | 1445 | L: netdev@vger.kernel.org |
1446 | S: Maintained | 1446 | S: Maintained |
1447 | F: drivers/net/cpmac.c | 1447 | F: drivers/net/cpmac.c |
1448 | 1448 | ||
1449 | CPU FREQUENCY DRIVERS | 1449 | CPU FREQUENCY DRIVERS |
1450 | M: Dave Jones <davej@redhat.com> | 1450 | M: Dave Jones <davej@redhat.com> |
1451 | L: cpufreq@vger.kernel.org | 1451 | L: cpufreq@vger.kernel.org |
1452 | W: http://www.codemonkey.org.uk/projects/cpufreq/ | 1452 | W: http://www.codemonkey.org.uk/projects/cpufreq/ |
1453 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git | 1453 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git |
1454 | S: Maintained | 1454 | S: Maintained |
1455 | F: arch/x86/kernel/cpu/cpufreq/ | 1455 | F: arch/x86/kernel/cpu/cpufreq/ |
1456 | F: drivers/cpufreq/ | 1456 | F: drivers/cpufreq/ |
1457 | F: include/linux/cpufreq.h | 1457 | F: include/linux/cpufreq.h |
1458 | 1458 | ||
1459 | CPUID/MSR DRIVER | 1459 | CPUID/MSR DRIVER |
1460 | M: "H. Peter Anvin" <hpa@zytor.com> | 1460 | M: "H. Peter Anvin" <hpa@zytor.com> |
1461 | S: Maintained | 1461 | S: Maintained |
1462 | F: arch/x86/kernel/cpuid.c | 1462 | F: arch/x86/kernel/cpuid.c |
1463 | F: arch/x86/kernel/msr.c | 1463 | F: arch/x86/kernel/msr.c |
1464 | 1464 | ||
1465 | CPUSETS | 1465 | CPUSETS |
1466 | M: Paul Menage <menage@google.com> | 1466 | M: Paul Menage <menage@google.com> |
1467 | W: http://www.bullopensource.org/cpuset/ | 1467 | W: http://www.bullopensource.org/cpuset/ |
1468 | W: http://oss.sgi.com/projects/cpusets/ | 1468 | W: http://oss.sgi.com/projects/cpusets/ |
1469 | S: Supported | 1469 | S: Supported |
1470 | F: Documentation/cgroups/cpusets.txt | 1470 | F: Documentation/cgroups/cpusets.txt |
1471 | F: include/linux/cpuset.h | 1471 | F: include/linux/cpuset.h |
1472 | F: kernel/cpuset.c | 1472 | F: kernel/cpuset.c |
1473 | 1473 | ||
1474 | CRAMFS FILESYSTEM | 1474 | CRAMFS FILESYSTEM |
1475 | W: http://sourceforge.net/projects/cramfs/ | 1475 | W: http://sourceforge.net/projects/cramfs/ |
1476 | S: Orphan | 1476 | S: Orphan |
1477 | F: Documentation/filesystems/cramfs.txt | 1477 | F: Documentation/filesystems/cramfs.txt |
1478 | F: fs/cramfs/ | 1478 | F: fs/cramfs/ |
1479 | 1479 | ||
1480 | CRIS PORT | 1480 | CRIS PORT |
1481 | M: Mikael Starvik <starvik@axis.com> | 1481 | M: Mikael Starvik <starvik@axis.com> |
1482 | M: Jesper Nilsson <jesper.nilsson@axis.com> | 1482 | M: Jesper Nilsson <jesper.nilsson@axis.com> |
1483 | L: linux-cris-kernel@axis.com | 1483 | L: linux-cris-kernel@axis.com |
1484 | W: http://developer.axis.com | 1484 | W: http://developer.axis.com |
1485 | S: Maintained | 1485 | S: Maintained |
1486 | F: arch/cris/ | 1486 | F: arch/cris/ |
1487 | 1487 | ||
1488 | CRYPTO API | 1488 | CRYPTO API |
1489 | M: Herbert Xu <herbert@gondor.apana.org.au> | 1489 | M: Herbert Xu <herbert@gondor.apana.org.au> |
1490 | M: "David S. Miller" <davem@davemloft.net> | 1490 | M: "David S. Miller" <davem@davemloft.net> |
1491 | L: linux-crypto@vger.kernel.org | 1491 | L: linux-crypto@vger.kernel.org |
1492 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git | 1492 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git |
1493 | S: Maintained | 1493 | S: Maintained |
1494 | F: Documentation/crypto/ | 1494 | F: Documentation/crypto/ |
1495 | F: arch/*/crypto/ | 1495 | F: arch/*/crypto/ |
1496 | F: crypto/ | 1496 | F: crypto/ |
1497 | F: drivers/crypto/ | 1497 | F: drivers/crypto/ |
1498 | F: include/crypto/ | 1498 | F: include/crypto/ |
1499 | 1499 | ||
1500 | CRYPTOGRAPHIC RANDOM NUMBER GENERATOR | 1500 | CRYPTOGRAPHIC RANDOM NUMBER GENERATOR |
1501 | M: Neil Horman <nhorman@tuxdriver.com> | 1501 | M: Neil Horman <nhorman@tuxdriver.com> |
1502 | L: linux-crypto@vger.kernel.org | 1502 | L: linux-crypto@vger.kernel.org |
1503 | S: Maintained | 1503 | S: Maintained |
1504 | 1504 | ||
1505 | CS5535 Audio ALSA driver | 1505 | CS5535 Audio ALSA driver |
1506 | M: Jaya Kumar <jayakumar.alsa@gmail.com> | 1506 | M: Jaya Kumar <jayakumar.alsa@gmail.com> |
1507 | S: Maintained | 1507 | S: Maintained |
1508 | F: sound/pci/cs5535audio/ | 1508 | F: sound/pci/cs5535audio/ |
1509 | 1509 | ||
1510 | CX18 VIDEO4LINUX DRIVER | 1510 | CX18 VIDEO4LINUX DRIVER |
1511 | M: Hans Verkuil <hverkuil@xs4all.nl> | 1511 | M: Hans Verkuil <hverkuil@xs4all.nl> |
1512 | M: Andy Walls <awalls@radix.net> | 1512 | M: Andy Walls <awalls@radix.net> |
1513 | L: ivtv-devel@ivtvdriver.org | 1513 | L: ivtv-devel@ivtvdriver.org |
1514 | L: linux-media@vger.kernel.org | 1514 | L: linux-media@vger.kernel.org |
1515 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 1515 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
1516 | W: http://linuxtv.org | 1516 | W: http://linuxtv.org |
1517 | W: http://www.ivtvdriver.org/index.php/Cx18 | 1517 | W: http://www.ivtvdriver.org/index.php/Cx18 |
1518 | S: Maintained | 1518 | S: Maintained |
1519 | F: Documentation/video4linux/cx18.txt | 1519 | F: Documentation/video4linux/cx18.txt |
1520 | F: drivers/media/video/cx18/ | 1520 | F: drivers/media/video/cx18/ |
1521 | 1521 | ||
1522 | CXGB3 ETHERNET DRIVER (CXGB3) | 1522 | CXGB3 ETHERNET DRIVER (CXGB3) |
1523 | M: Divy Le Ray <divy@chelsio.com> | 1523 | M: Divy Le Ray <divy@chelsio.com> |
1524 | L: netdev@vger.kernel.org | 1524 | L: netdev@vger.kernel.org |
1525 | W: http://www.chelsio.com | 1525 | W: http://www.chelsio.com |
1526 | S: Supported | 1526 | S: Supported |
1527 | F: drivers/net/cxgb3/ | 1527 | F: drivers/net/cxgb3/ |
1528 | 1528 | ||
1529 | CXGB3 IWARP RNIC DRIVER (IW_CXGB3) | 1529 | CXGB3 IWARP RNIC DRIVER (IW_CXGB3) |
1530 | M: Steve Wise <swise@chelsio.com> | 1530 | M: Steve Wise <swise@chelsio.com> |
1531 | L: linux-rdma@vger.kernel.org | 1531 | L: linux-rdma@vger.kernel.org |
1532 | W: http://www.openfabrics.org | 1532 | W: http://www.openfabrics.org |
1533 | S: Supported | 1533 | S: Supported |
1534 | F: drivers/infiniband/hw/cxgb3/ | 1534 | F: drivers/infiniband/hw/cxgb3/ |
1535 | 1535 | ||
1536 | CYBERPRO FB DRIVER | 1536 | CYBERPRO FB DRIVER |
1537 | M: Russell King <linux@arm.linux.org.uk> | 1537 | M: Russell King <linux@arm.linux.org.uk> |
1538 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 1538 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
1539 | W: http://www.arm.linux.org.uk/ | 1539 | W: http://www.arm.linux.org.uk/ |
1540 | S: Maintained | 1540 | S: Maintained |
1541 | F: drivers/video/cyber2000fb.* | 1541 | F: drivers/video/cyber2000fb.* |
1542 | 1542 | ||
1543 | CYCLADES 2X SYNC CARD DRIVER | 1543 | CYCLADES 2X SYNC CARD DRIVER |
1544 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 1544 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
1545 | W: http://oops.ghostprotocols.net:81/blog | 1545 | W: http://oops.ghostprotocols.net:81/blog |
1546 | S: Maintained | 1546 | S: Maintained |
1547 | F: drivers/net/wan/cycx* | 1547 | F: drivers/net/wan/cycx* |
1548 | 1548 | ||
1549 | CYCLADES ASYNC MUX DRIVER | 1549 | CYCLADES ASYNC MUX DRIVER |
1550 | W: http://www.cyclades.com/ | 1550 | W: http://www.cyclades.com/ |
1551 | S: Orphan | 1551 | S: Orphan |
1552 | F: drivers/char/cyclades.c | 1552 | F: drivers/char/cyclades.c |
1553 | F: include/linux/cyclades.h | 1553 | F: include/linux/cyclades.h |
1554 | 1554 | ||
1555 | CYCLADES PC300 DRIVER | 1555 | CYCLADES PC300 DRIVER |
1556 | W: http://www.cyclades.com/ | 1556 | W: http://www.cyclades.com/ |
1557 | S: Orphan | 1557 | S: Orphan |
1558 | F: drivers/net/wan/pc300* | 1558 | F: drivers/net/wan/pc300* |
1559 | 1559 | ||
1560 | DAMA SLAVE for AX.25 | 1560 | DAMA SLAVE for AX.25 |
1561 | M: Joerg Reuter <jreuter@yaina.de> | 1561 | M: Joerg Reuter <jreuter@yaina.de> |
1562 | W: http://yaina.de/jreuter/ | 1562 | W: http://yaina.de/jreuter/ |
1563 | W: http://www.qsl.net/dl1bke/ | 1563 | W: http://www.qsl.net/dl1bke/ |
1564 | L: linux-hams@vger.kernel.org | 1564 | L: linux-hams@vger.kernel.org |
1565 | S: Maintained | 1565 | S: Maintained |
1566 | F: net/ax25/af_ax25.c | 1566 | F: net/ax25/af_ax25.c |
1567 | F: net/ax25/ax25_dev.c | 1567 | F: net/ax25/ax25_dev.c |
1568 | F: net/ax25/ax25_ds_* | 1568 | F: net/ax25/ax25_ds_* |
1569 | F: net/ax25/ax25_in.c | 1569 | F: net/ax25/ax25_in.c |
1570 | F: net/ax25/ax25_out.c | 1570 | F: net/ax25/ax25_out.c |
1571 | F: net/ax25/ax25_timer.c | 1571 | F: net/ax25/ax25_timer.c |
1572 | F: net/ax25/sysctl_net_ax25.c | 1572 | F: net/ax25/sysctl_net_ax25.c |
1573 | 1573 | ||
1574 | DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER | 1574 | DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER |
1575 | M: Tobias Ringstrom <tori@unhappy.mine.nu> | 1575 | M: Tobias Ringstrom <tori@unhappy.mine.nu> |
1576 | L: netdev@vger.kernel.org | 1576 | L: netdev@vger.kernel.org |
1577 | S: Maintained | 1577 | S: Maintained |
1578 | F: Documentation/networking/dmfe.txt | 1578 | F: Documentation/networking/dmfe.txt |
1579 | F: drivers/net/tulip/dmfe.c | 1579 | F: drivers/net/tulip/dmfe.c |
1580 | 1580 | ||
1581 | DC390/AM53C974 SCSI driver | 1581 | DC390/AM53C974 SCSI driver |
1582 | M: Kurt Garloff <garloff@suse.de> | 1582 | M: Kurt Garloff <garloff@suse.de> |
1583 | W: http://www.garloff.de/kurt/linux/dc390/ | 1583 | W: http://www.garloff.de/kurt/linux/dc390/ |
1584 | M: Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 1584 | M: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
1585 | S: Maintained | 1585 | S: Maintained |
1586 | F: drivers/scsi/tmscsim.* | 1586 | F: drivers/scsi/tmscsim.* |
1587 | 1587 | ||
1588 | DC395x SCSI driver | 1588 | DC395x SCSI driver |
1589 | M: Oliver Neukum <oliver@neukum.name> | 1589 | M: Oliver Neukum <oliver@neukum.name> |
1590 | M: Ali Akcaagac <aliakc@web.de> | 1590 | M: Ali Akcaagac <aliakc@web.de> |
1591 | M: Jamie Lenehan <lenehan@twibble.org> | 1591 | M: Jamie Lenehan <lenehan@twibble.org> |
1592 | W: http://twibble.org/dist/dc395x/ | 1592 | W: http://twibble.org/dist/dc395x/ |
1593 | L: dc395x@twibble.org | 1593 | L: dc395x@twibble.org |
1594 | L: http://lists.twibble.org/mailman/listinfo/dc395x/ | 1594 | L: http://lists.twibble.org/mailman/listinfo/dc395x/ |
1595 | S: Maintained | 1595 | S: Maintained |
1596 | F: Documentation/scsi/dc395x.txt | 1596 | F: Documentation/scsi/dc395x.txt |
1597 | F: drivers/scsi/dc395x.* | 1597 | F: drivers/scsi/dc395x.* |
1598 | 1598 | ||
1599 | DCCP PROTOCOL | 1599 | DCCP PROTOCOL |
1600 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 1600 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
1601 | L: dccp@vger.kernel.org | 1601 | L: dccp@vger.kernel.org |
1602 | W: http://linux-net.osdl.org/index.php/DCCP | 1602 | W: http://linux-net.osdl.org/index.php/DCCP |
1603 | S: Maintained | 1603 | S: Maintained |
1604 | F: include/linux/dccp.h | 1604 | F: include/linux/dccp.h |
1605 | F: include/linux/tfrc.h | 1605 | F: include/linux/tfrc.h |
1606 | F: net/dccp/ | 1606 | F: net/dccp/ |
1607 | 1607 | ||
1608 | DECnet NETWORK LAYER | 1608 | DECnet NETWORK LAYER |
1609 | M: Christine Caulfield <christine.caulfield@googlemail.com> | 1609 | M: Christine Caulfield <christine.caulfield@googlemail.com> |
1610 | W: http://linux-decnet.sourceforge.net | 1610 | W: http://linux-decnet.sourceforge.net |
1611 | L: linux-decnet-user@lists.sourceforge.net | 1611 | L: linux-decnet-user@lists.sourceforge.net |
1612 | S: Maintained | 1612 | S: Maintained |
1613 | F: Documentation/networking/decnet.txt | 1613 | F: Documentation/networking/decnet.txt |
1614 | F: net/decnet/ | 1614 | F: net/decnet/ |
1615 | 1615 | ||
1616 | DEFXX FDDI NETWORK DRIVER | 1616 | DEFXX FDDI NETWORK DRIVER |
1617 | M: "Maciej W. Rozycki" <macro@linux-mips.org> | 1617 | M: "Maciej W. Rozycki" <macro@linux-mips.org> |
1618 | S: Maintained | 1618 | S: Maintained |
1619 | F: drivers/net/defxx.* | 1619 | F: drivers/net/defxx.* |
1620 | 1620 | ||
1621 | DELL LAPTOP DRIVER | 1621 | DELL LAPTOP DRIVER |
1622 | M: Matthew Garrett <mjg59@srcf.ucam.org> | 1622 | M: Matthew Garrett <mjg59@srcf.ucam.org> |
1623 | S: Maintained | 1623 | S: Maintained |
1624 | F: drivers/platform/x86/dell-laptop.c | 1624 | F: drivers/platform/x86/dell-laptop.c |
1625 | 1625 | ||
1626 | DELL LAPTOP SMM DRIVER | 1626 | DELL LAPTOP SMM DRIVER |
1627 | M: Massimo Dal Zotto <dz@debian.org> | 1627 | M: Massimo Dal Zotto <dz@debian.org> |
1628 | W: http://www.debian.org/~dz/i8k/ | 1628 | W: http://www.debian.org/~dz/i8k/ |
1629 | S: Maintained | 1629 | S: Maintained |
1630 | F: drivers/char/i8k.c | 1630 | F: drivers/char/i8k.c |
1631 | F: include/linux/i8k.h | 1631 | F: include/linux/i8k.h |
1632 | 1632 | ||
1633 | DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas) | 1633 | DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas) |
1634 | M: Doug Warzecha <Douglas_Warzecha@dell.com> | 1634 | M: Doug Warzecha <Douglas_Warzecha@dell.com> |
1635 | S: Maintained | 1635 | S: Maintained |
1636 | F: Documentation/dcdbas.txt | 1636 | F: Documentation/dcdbas.txt |
1637 | F: drivers/firmware/dcdbas.* | 1637 | F: drivers/firmware/dcdbas.* |
1638 | 1638 | ||
1639 | DELL WMI EXTRAS DRIVER | 1639 | DELL WMI EXTRAS DRIVER |
1640 | M: Matthew Garrett <mjg59@srcf.ucam.org> | 1640 | M: Matthew Garrett <mjg59@srcf.ucam.org> |
1641 | S: Maintained | 1641 | S: Maintained |
1642 | 1642 | ||
1643 | DEVICE NUMBER REGISTRY | 1643 | DEVICE NUMBER REGISTRY |
1644 | M: Torben Mathiasen <device@lanana.org> | 1644 | M: Torben Mathiasen <device@lanana.org> |
1645 | W: http://lanana.org/docs/device-list/index.html | 1645 | W: http://lanana.org/docs/device-list/index.html |
1646 | S: Maintained | 1646 | S: Maintained |
1647 | 1647 | ||
1648 | DEVICE-MAPPER (LVM) | 1648 | DEVICE-MAPPER (LVM) |
1649 | P: Alasdair Kergon | 1649 | P: Alasdair Kergon |
1650 | L: dm-devel@redhat.com | 1650 | L: dm-devel@redhat.com |
1651 | W: http://sources.redhat.com/dm | 1651 | W: http://sources.redhat.com/dm |
1652 | S: Maintained | 1652 | S: Maintained |
1653 | F: Documentation/device-mapper/ | 1653 | F: Documentation/device-mapper/ |
1654 | F: drivers/md/dm* | 1654 | F: drivers/md/dm* |
1655 | F: include/linux/device-mapper.h | 1655 | F: include/linux/device-mapper.h |
1656 | F: include/linux/dm-*.h | 1656 | F: include/linux/dm-*.h |
1657 | 1657 | ||
1658 | DIGI INTL. EPCA DRIVER | 1658 | DIGI INTL. EPCA DRIVER |
1659 | M: "Digi International, Inc" <Eng.Linux@digi.com> | 1659 | M: "Digi International, Inc" <Eng.Linux@digi.com> |
1660 | L: Eng.Linux@digi.com | 1660 | L: Eng.Linux@digi.com |
1661 | W: http://www.digi.com | 1661 | W: http://www.digi.com |
1662 | S: Orphan | 1662 | S: Orphan |
1663 | F: Documentation/serial/digiepca.txt | 1663 | F: Documentation/serial/digiepca.txt |
1664 | F: drivers/char/epca* | 1664 | F: drivers/char/epca* |
1665 | F: drivers/char/digi* | 1665 | F: drivers/char/digi* |
1666 | 1666 | ||
1667 | DIRECTORY NOTIFICATION (DNOTIFY) | 1667 | DIRECTORY NOTIFICATION (DNOTIFY) |
1668 | M: Eric Paris <eparis@parisplace.org> | 1668 | M: Eric Paris <eparis@parisplace.org> |
1669 | S: Maintained | 1669 | S: Maintained |
1670 | F: Documentation/filesystems/dnotify.txt | 1670 | F: Documentation/filesystems/dnotify.txt |
1671 | F: fs/notify/dnotify/ | 1671 | F: fs/notify/dnotify/ |
1672 | F: include/linux/dnotify.h | 1672 | F: include/linux/dnotify.h |
1673 | 1673 | ||
1674 | DISK GEOMETRY AND PARTITION HANDLING | 1674 | DISK GEOMETRY AND PARTITION HANDLING |
1675 | M: Andries Brouwer <aeb@cwi.nl> | 1675 | M: Andries Brouwer <aeb@cwi.nl> |
1676 | W: http://www.win.tue.nl/~aeb/linux/Large-Disk.html | 1676 | W: http://www.win.tue.nl/~aeb/linux/Large-Disk.html |
1677 | W: http://www.win.tue.nl/~aeb/linux/zip/zip-1.html | 1677 | W: http://www.win.tue.nl/~aeb/linux/zip/zip-1.html |
1678 | W: http://www.win.tue.nl/~aeb/partitions/partition_types-1.html | 1678 | W: http://www.win.tue.nl/~aeb/partitions/partition_types-1.html |
1679 | S: Maintained | 1679 | S: Maintained |
1680 | 1680 | ||
1681 | DISKQUOTA | 1681 | DISKQUOTA |
1682 | M: Jan Kara <jack@suse.cz> | 1682 | M: Jan Kara <jack@suse.cz> |
1683 | S: Maintained | 1683 | S: Maintained |
1684 | F: Documentation/filesystems/quota.txt | 1684 | F: Documentation/filesystems/quota.txt |
1685 | F: fs/quota/ | 1685 | F: fs/quota/ |
1686 | F: include/linux/quota*.h | 1686 | F: include/linux/quota*.h |
1687 | 1687 | ||
1688 | DISTRIBUTED LOCK MANAGER (DLM) | 1688 | DISTRIBUTED LOCK MANAGER (DLM) |
1689 | M: Christine Caulfield <ccaulfie@redhat.com> | 1689 | M: Christine Caulfield <ccaulfie@redhat.com> |
1690 | M: David Teigland <teigland@redhat.com> | 1690 | M: David Teigland <teigland@redhat.com> |
1691 | L: cluster-devel@redhat.com | 1691 | L: cluster-devel@redhat.com |
1692 | W: http://sources.redhat.com/cluster/ | 1692 | W: http://sources.redhat.com/cluster/ |
1693 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm.git | 1693 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm.git |
1694 | S: Supported | 1694 | S: Supported |
1695 | F: fs/dlm/ | 1695 | F: fs/dlm/ |
1696 | 1696 | ||
1697 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM | 1697 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM |
1698 | M: Maciej Sosnowski <maciej.sosnowski@intel.com> | 1698 | M: Maciej Sosnowski <maciej.sosnowski@intel.com> |
1699 | M: Dan Williams <dan.j.williams@intel.com> | 1699 | M: Dan Williams <dan.j.williams@intel.com> |
1700 | S: Supported | 1700 | S: Supported |
1701 | F: drivers/dma/ | 1701 | F: drivers/dma/ |
1702 | F: include/linux/dma* | 1702 | F: include/linux/dma* |
1703 | 1703 | ||
1704 | DME1737 HARDWARE MONITOR DRIVER | 1704 | DME1737 HARDWARE MONITOR DRIVER |
1705 | M: Juerg Haefliger <juergh@gmail.com> | 1705 | M: Juerg Haefliger <juergh@gmail.com> |
1706 | L: lm-sensors@lm-sensors.org | 1706 | L: lm-sensors@lm-sensors.org |
1707 | S: Maintained | 1707 | S: Maintained |
1708 | F: Documentation/hwmon/dme1737 | 1708 | F: Documentation/hwmon/dme1737 |
1709 | F: drivers/hwmon/dme1737.c | 1709 | F: drivers/hwmon/dme1737.c |
1710 | 1710 | ||
1711 | DOCBOOK FOR DOCUMENTATION | 1711 | DOCBOOK FOR DOCUMENTATION |
1712 | M: Randy Dunlap <rdunlap@xenotime.net> | 1712 | M: Randy Dunlap <rdunlap@xenotime.net> |
1713 | S: Maintained | 1713 | S: Maintained |
1714 | 1714 | ||
1715 | DOCKING STATION DRIVER | 1715 | DOCKING STATION DRIVER |
1716 | M: Shaohua Li <shaohua.li@intel.com> | 1716 | M: Shaohua Li <shaohua.li@intel.com> |
1717 | L: linux-acpi@vger.kernel.org | 1717 | L: linux-acpi@vger.kernel.org |
1718 | S: Supported | 1718 | S: Supported |
1719 | F: drivers/acpi/dock.c | 1719 | F: drivers/acpi/dock.c |
1720 | 1720 | ||
1721 | DOCUMENTATION | 1721 | DOCUMENTATION |
1722 | M: Randy Dunlap <rdunlap@xenotime.net> | 1722 | M: Randy Dunlap <rdunlap@xenotime.net> |
1723 | L: linux-doc@vger.kernel.org | 1723 | L: linux-doc@vger.kernel.org |
1724 | S: Maintained | 1724 | S: Maintained |
1725 | F: Documentation/ | 1725 | F: Documentation/ |
1726 | 1726 | ||
1727 | DOUBLETALK DRIVER | 1727 | DOUBLETALK DRIVER |
1728 | M: "James R. Van Zandt" <jrv@vanzandt.mv.com> | 1728 | M: "James R. Van Zandt" <jrv@vanzandt.mv.com> |
1729 | L: blinux-list@redhat.com | 1729 | L: blinux-list@redhat.com |
1730 | S: Maintained | 1730 | S: Maintained |
1731 | F: drivers/char/dtlk.c | 1731 | F: drivers/char/dtlk.c |
1732 | F: include/linux/dtlk.h | 1732 | F: include/linux/dtlk.h |
1733 | 1733 | ||
1734 | DPT_I2O SCSI RAID DRIVER | 1734 | DPT_I2O SCSI RAID DRIVER |
1735 | M: Adaptec OEM Raid Solutions <aacraid@adaptec.com> | 1735 | M: Adaptec OEM Raid Solutions <aacraid@adaptec.com> |
1736 | L: linux-scsi@vger.kernel.org | 1736 | L: linux-scsi@vger.kernel.org |
1737 | W: http://www.adaptec.com/ | 1737 | W: http://www.adaptec.com/ |
1738 | S: Maintained | 1738 | S: Maintained |
1739 | F: drivers/scsi/dpt* | 1739 | F: drivers/scsi/dpt* |
1740 | F: drivers/scsi/dpt/ | 1740 | F: drivers/scsi/dpt/ |
1741 | 1741 | ||
1742 | DRIVER CORE, KOBJECTS, AND SYSFS | 1742 | DRIVER CORE, KOBJECTS, AND SYSFS |
1743 | M: Greg Kroah-Hartman <gregkh@suse.de> | 1743 | M: Greg Kroah-Hartman <gregkh@suse.de> |
1744 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 1744 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
1745 | S: Supported | 1745 | S: Supported |
1746 | F: Documentation/kobject.txt | 1746 | F: Documentation/kobject.txt |
1747 | F: drivers/base/ | 1747 | F: drivers/base/ |
1748 | F: fs/sysfs/ | 1748 | F: fs/sysfs/ |
1749 | F: include/linux/kobj* | 1749 | F: include/linux/kobj* |
1750 | F: lib/kobj* | 1750 | F: lib/kobj* |
1751 | 1751 | ||
1752 | DRM DRIVERS | 1752 | DRM DRIVERS |
1753 | M: David Airlie <airlied@linux.ie> | 1753 | M: David Airlie <airlied@linux.ie> |
1754 | L: dri-devel@lists.sourceforge.net | 1754 | L: dri-devel@lists.sourceforge.net |
1755 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git | 1755 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git |
1756 | S: Maintained | 1756 | S: Maintained |
1757 | F: drivers/gpu/drm/ | 1757 | F: drivers/gpu/drm/ |
1758 | 1758 | ||
1759 | DSCC4 DRIVER | 1759 | DSCC4 DRIVER |
1760 | M: Francois Romieu <romieu@fr.zoreil.com> | 1760 | M: Francois Romieu <romieu@fr.zoreil.com> |
1761 | L: netdev@vger.kernel.org | 1761 | L: netdev@vger.kernel.org |
1762 | S: Maintained | 1762 | S: Maintained |
1763 | F: drivers/net/wan/dscc4.c | 1763 | F: drivers/net/wan/dscc4.c |
1764 | 1764 | ||
1765 | DZ DECSTATION DZ11 SERIAL DRIVER | 1765 | DZ DECSTATION DZ11 SERIAL DRIVER |
1766 | M: "Maciej W. Rozycki" <macro@linux-mips.org> | 1766 | M: "Maciej W. Rozycki" <macro@linux-mips.org> |
1767 | S: Maintained | 1767 | S: Maintained |
1768 | F: drivers/serial/dz.* | 1768 | F: drivers/serial/dz.* |
1769 | 1769 | ||
1770 | EATA-DMA SCSI DRIVER | 1770 | EATA-DMA SCSI DRIVER |
1771 | M: Michael Neuffer <mike@i-Connect.Net> | 1771 | M: Michael Neuffer <mike@i-Connect.Net> |
1772 | L: linux-eata@i-connect.net | 1772 | L: linux-eata@i-connect.net |
1773 | L: linux-scsi@vger.kernel.org | 1773 | L: linux-scsi@vger.kernel.org |
1774 | S: Maintained | 1774 | S: Maintained |
1775 | F: drivers/scsi/eata* | 1775 | F: drivers/scsi/eata* |
1776 | 1776 | ||
1777 | EATA ISA/EISA/PCI SCSI DRIVER | 1777 | EATA ISA/EISA/PCI SCSI DRIVER |
1778 | M: Dario Ballabio <ballabio_dario@emc.com> | 1778 | M: Dario Ballabio <ballabio_dario@emc.com> |
1779 | L: linux-scsi@vger.kernel.org | 1779 | L: linux-scsi@vger.kernel.org |
1780 | S: Maintained | 1780 | S: Maintained |
1781 | F: drivers/scsi/eata.c | 1781 | F: drivers/scsi/eata.c |
1782 | 1782 | ||
1783 | EATA-PIO SCSI DRIVER | 1783 | EATA-PIO SCSI DRIVER |
1784 | M: Michael Neuffer <mike@i-Connect.Net> | 1784 | M: Michael Neuffer <mike@i-Connect.Net> |
1785 | L: linux-eata@i-connect.net | 1785 | L: linux-eata@i-connect.net |
1786 | L: linux-scsi@vger.kernel.org | 1786 | L: linux-scsi@vger.kernel.org |
1787 | S: Maintained | 1787 | S: Maintained |
1788 | F: drivers/scsi/eata_pio.* | 1788 | F: drivers/scsi/eata_pio.* |
1789 | 1789 | ||
1790 | EBTABLES | 1790 | EBTABLES |
1791 | M: Bart De Schuymer <bart.de.schuymer@pandora.be> | 1791 | M: Bart De Schuymer <bart.de.schuymer@pandora.be> |
1792 | L: ebtables-user@lists.sourceforge.net | 1792 | L: ebtables-user@lists.sourceforge.net |
1793 | L: ebtables-devel@lists.sourceforge.net | 1793 | L: ebtables-devel@lists.sourceforge.net |
1794 | W: http://ebtables.sourceforge.net/ | 1794 | W: http://ebtables.sourceforge.net/ |
1795 | S: Maintained | 1795 | S: Maintained |
1796 | F: include/linux/netfilter_bridge/ebt_*.h | 1796 | F: include/linux/netfilter_bridge/ebt_*.h |
1797 | F: net/bridge/netfilter/ebt*.c | 1797 | F: net/bridge/netfilter/ebt*.c |
1798 | 1798 | ||
1799 | ECRYPT FILE SYSTEM | 1799 | ECRYPT FILE SYSTEM |
1800 | M: Tyler Hicks <tyhicks@linux.vnet.ibm.com> | 1800 | M: Tyler Hicks <tyhicks@linux.vnet.ibm.com> |
1801 | M: Dustin Kirkland <kirkland@canonical.com> | 1801 | M: Dustin Kirkland <kirkland@canonical.com> |
1802 | L: ecryptfs-devel@lists.launchpad.net | 1802 | L: ecryptfs-devel@lists.launchpad.net |
1803 | W: https://launchpad.net/ecryptfs | 1803 | W: https://launchpad.net/ecryptfs |
1804 | S: Supported | 1804 | S: Supported |
1805 | F: Documentation/filesystems/ecryptfs.txt | 1805 | F: Documentation/filesystems/ecryptfs.txt |
1806 | F: fs/ecryptfs/ | 1806 | F: fs/ecryptfs/ |
1807 | 1807 | ||
1808 | EDAC-CORE | 1808 | EDAC-CORE |
1809 | M: Doug Thompson <dougthompson@xmission.com> | 1809 | M: Doug Thompson <dougthompson@xmission.com> |
1810 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1810 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1811 | W: bluesmoke.sourceforge.net | 1811 | W: bluesmoke.sourceforge.net |
1812 | S: Supported | 1812 | S: Supported |
1813 | F: Documentation/edac.txt | 1813 | F: Documentation/edac.txt |
1814 | F: drivers/edac/edac_* | 1814 | F: drivers/edac/edac_* |
1815 | F: include/linux/edac.h | 1815 | F: include/linux/edac.h |
1816 | 1816 | ||
1817 | EDAC-AMD64 | 1817 | EDAC-AMD64 |
1818 | M: Doug Thompson <dougthompson@xmission.com> | 1818 | M: Doug Thompson <dougthompson@xmission.com> |
1819 | M: Borislav Petkov <borislav.petkov@amd.com> | 1819 | M: Borislav Petkov <borislav.petkov@amd.com> |
1820 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1820 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1821 | W: bluesmoke.sourceforge.net | 1821 | W: bluesmoke.sourceforge.net |
1822 | S: Supported | 1822 | S: Supported |
1823 | F: drivers/edac/amd64_edac* | 1823 | F: drivers/edac/amd64_edac* |
1824 | 1824 | ||
1825 | EDAC-E752X | 1825 | EDAC-E752X |
1826 | M: Mark Gross <mark.gross@intel.com> | 1826 | M: Mark Gross <mark.gross@intel.com> |
1827 | M: Doug Thompson <dougthompson@xmission.com> | 1827 | M: Doug Thompson <dougthompson@xmission.com> |
1828 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1828 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1829 | W: bluesmoke.sourceforge.net | 1829 | W: bluesmoke.sourceforge.net |
1830 | S: Maintained | 1830 | S: Maintained |
1831 | F: drivers/edac/e752x_edac.c | 1831 | F: drivers/edac/e752x_edac.c |
1832 | 1832 | ||
1833 | EDAC-E7XXX | 1833 | EDAC-E7XXX |
1834 | M: Doug Thompson <dougthompson@xmission.com> | 1834 | M: Doug Thompson <dougthompson@xmission.com> |
1835 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1835 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1836 | W: bluesmoke.sourceforge.net | 1836 | W: bluesmoke.sourceforge.net |
1837 | S: Maintained | 1837 | S: Maintained |
1838 | F: drivers/edac/e7xxx_edac.c | 1838 | F: drivers/edac/e7xxx_edac.c |
1839 | 1839 | ||
1840 | EDAC-I82443BXGX | 1840 | EDAC-I82443BXGX |
1841 | M: Tim Small <tim@buttersideup.com> | 1841 | M: Tim Small <tim@buttersideup.com> |
1842 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1842 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1843 | W: bluesmoke.sourceforge.net | 1843 | W: bluesmoke.sourceforge.net |
1844 | S: Maintained | 1844 | S: Maintained |
1845 | F: drivers/edac/i82443bxgx_edac.c | 1845 | F: drivers/edac/i82443bxgx_edac.c |
1846 | 1846 | ||
1847 | EDAC-I3000 | 1847 | EDAC-I3000 |
1848 | M: Jason Uhlenkott <juhlenko@akamai.com> | 1848 | M: Jason Uhlenkott <juhlenko@akamai.com> |
1849 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1849 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1850 | W: bluesmoke.sourceforge.net | 1850 | W: bluesmoke.sourceforge.net |
1851 | S: Maintained | 1851 | S: Maintained |
1852 | F: drivers/edac/i3000_edac.c | 1852 | F: drivers/edac/i3000_edac.c |
1853 | 1853 | ||
1854 | EDAC-I5000 | 1854 | EDAC-I5000 |
1855 | M: Doug Thompson <dougthompson@xmission.com> | 1855 | M: Doug Thompson <dougthompson@xmission.com> |
1856 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1856 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1857 | W: bluesmoke.sourceforge.net | 1857 | W: bluesmoke.sourceforge.net |
1858 | S: Maintained | 1858 | S: Maintained |
1859 | F: drivers/edac/i5000_edac.c | 1859 | F: drivers/edac/i5000_edac.c |
1860 | 1860 | ||
1861 | EDAC-I5400 | 1861 | EDAC-I5400 |
1862 | M: Mauro Carvalho Chehab <mchehab@redhat.com> | 1862 | M: Mauro Carvalho Chehab <mchehab@redhat.com> |
1863 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1863 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1864 | W: bluesmoke.sourceforge.net | 1864 | W: bluesmoke.sourceforge.net |
1865 | S: Maintained | 1865 | S: Maintained |
1866 | F: drivers/edac/i5400_edac.c | 1866 | F: drivers/edac/i5400_edac.c |
1867 | 1867 | ||
1868 | EDAC-I82975X | 1868 | EDAC-I82975X |
1869 | M: Ranganathan Desikan <ravi@jetztechnologies.com> | 1869 | M: Ranganathan Desikan <ravi@jetztechnologies.com> |
1870 | M: "Arvind R." <arvind@jetztechnologies.com> | 1870 | M: "Arvind R." <arvind@jetztechnologies.com> |
1871 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1871 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1872 | W: bluesmoke.sourceforge.net | 1872 | W: bluesmoke.sourceforge.net |
1873 | S: Maintained | 1873 | S: Maintained |
1874 | F: drivers/edac/i82975x_edac.c | 1874 | F: drivers/edac/i82975x_edac.c |
1875 | 1875 | ||
1876 | EDAC-PASEMI | 1876 | EDAC-PASEMI |
1877 | M: Egor Martovetsky <egor@pasemi.com> | 1877 | M: Egor Martovetsky <egor@pasemi.com> |
1878 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1878 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1879 | W: bluesmoke.sourceforge.net | 1879 | W: bluesmoke.sourceforge.net |
1880 | S: Maintained | 1880 | S: Maintained |
1881 | F: drivers/edac/pasemi_edac.c | 1881 | F: drivers/edac/pasemi_edac.c |
1882 | 1882 | ||
1883 | EDAC-R82600 | 1883 | EDAC-R82600 |
1884 | M: Tim Small <tim@buttersideup.com> | 1884 | M: Tim Small <tim@buttersideup.com> |
1885 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) | 1885 | L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) |
1886 | W: bluesmoke.sourceforge.net | 1886 | W: bluesmoke.sourceforge.net |
1887 | S: Maintained | 1887 | S: Maintained |
1888 | F: drivers/edac/r82600_edac.c | 1888 | F: drivers/edac/r82600_edac.c |
1889 | 1889 | ||
1890 | EEEPC LAPTOP EXTRAS DRIVER | 1890 | EEEPC LAPTOP EXTRAS DRIVER |
1891 | M: Corentin Chary <corentincj@iksaif.net> | 1891 | M: Corentin Chary <corentincj@iksaif.net> |
1892 | L: acpi4asus-user@lists.sourceforge.net | 1892 | L: acpi4asus-user@lists.sourceforge.net |
1893 | W: http://acpi4asus.sf.net | 1893 | W: http://acpi4asus.sf.net |
1894 | S: Maintained | 1894 | S: Maintained |
1895 | F: drivers/platform/x86/eeepc-laptop.c | 1895 | F: drivers/platform/x86/eeepc-laptop.c |
1896 | 1896 | ||
1897 | EFS FILESYSTEM | 1897 | EFS FILESYSTEM |
1898 | W: http://aeschi.ch.eu.org/efs/ | 1898 | W: http://aeschi.ch.eu.org/efs/ |
1899 | S: Orphan | 1899 | S: Orphan |
1900 | F: fs/efs/ | 1900 | F: fs/efs/ |
1901 | 1901 | ||
1902 | EHCA (IBM GX bus InfiniBand adapter) DRIVER | 1902 | EHCA (IBM GX bus InfiniBand adapter) DRIVER |
1903 | M: Hoang-Nam Nguyen <hnguyen@de.ibm.com> | 1903 | M: Hoang-Nam Nguyen <hnguyen@de.ibm.com> |
1904 | M: Christoph Raisch <raisch@de.ibm.com> | 1904 | M: Christoph Raisch <raisch@de.ibm.com> |
1905 | L: linux-rdma@vger.kernel.org | 1905 | L: linux-rdma@vger.kernel.org |
1906 | S: Supported | 1906 | S: Supported |
1907 | F: drivers/infiniband/hw/ehca/ | 1907 | F: drivers/infiniband/hw/ehca/ |
1908 | 1908 | ||
1909 | EMBEDDED LINUX | 1909 | EMBEDDED LINUX |
1910 | M: Paul Gortmaker <paul.gortmaker@windriver.com> | 1910 | M: Paul Gortmaker <paul.gortmaker@windriver.com> |
1911 | M: Matt Mackall <mpm@selenic.com> | 1911 | M: Matt Mackall <mpm@selenic.com> |
1912 | M: David Woodhouse <dwmw2@infradead.org> | 1912 | M: David Woodhouse <dwmw2@infradead.org> |
1913 | L: linux-embedded@vger.kernel.org | 1913 | L: linux-embedded@vger.kernel.org |
1914 | S: Maintained | 1914 | S: Maintained |
1915 | 1915 | ||
1916 | EMULEX LPFC FC SCSI DRIVER | 1916 | EMULEX LPFC FC SCSI DRIVER |
1917 | M: James Smart <james.smart@emulex.com> | 1917 | M: James Smart <james.smart@emulex.com> |
1918 | L: linux-scsi@vger.kernel.org | 1918 | L: linux-scsi@vger.kernel.org |
1919 | W: http://sourceforge.net/projects/lpfcxxxx | 1919 | W: http://sourceforge.net/projects/lpfcxxxx |
1920 | S: Supported | 1920 | S: Supported |
1921 | F: drivers/scsi/lpfc/ | 1921 | F: drivers/scsi/lpfc/ |
1922 | 1922 | ||
1923 | ENE CB710 FLASH CARD READER DRIVER | 1923 | ENE CB710 FLASH CARD READER DRIVER |
1924 | M: Michaล Mirosลaw <mirq-linux@rere.qmqm.pl> | 1924 | M: Michaล Mirosลaw <mirq-linux@rere.qmqm.pl> |
1925 | S: Maintained | 1925 | S: Maintained |
1926 | F: drivers/misc/cb710/ | 1926 | F: drivers/misc/cb710/ |
1927 | F: drivers/mmc/host/cb710-mmc.* | 1927 | F: drivers/mmc/host/cb710-mmc.* |
1928 | F: include/linux/cb710.h | 1928 | F: include/linux/cb710.h |
1929 | 1929 | ||
1930 | EPSON 1355 FRAMEBUFFER DRIVER | 1930 | EPSON 1355 FRAMEBUFFER DRIVER |
1931 | M: Christopher Hoover <ch@murgatroid.com> | 1931 | M: Christopher Hoover <ch@murgatroid.com> |
1932 | M: Christopher Hoover <ch@hpl.hp.com> | 1932 | M: Christopher Hoover <ch@hpl.hp.com> |
1933 | S: Maintained | 1933 | S: Maintained |
1934 | F: drivers/video/epson1355fb.c | 1934 | F: drivers/video/epson1355fb.c |
1935 | 1935 | ||
1936 | EPSON S1D13XXX FRAMEBUFFER DRIVER | 1936 | EPSON S1D13XXX FRAMEBUFFER DRIVER |
1937 | M: Kristoffer Ericson <kristoffer.ericson@gmail.com> | 1937 | M: Kristoffer Ericson <kristoffer.ericson@gmail.com> |
1938 | S: Maintained | 1938 | S: Maintained |
1939 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git | 1939 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git |
1940 | F: drivers/video/s1d13xxxfb.c | 1940 | F: drivers/video/s1d13xxxfb.c |
1941 | F: include/video/s1d13xxxfb.h | 1941 | F: include/video/s1d13xxxfb.h |
1942 | 1942 | ||
1943 | ETHEREXPRESS-16 NETWORK DRIVER | 1943 | ETHEREXPRESS-16 NETWORK DRIVER |
1944 | M: Philip Blundell <philb@gnu.org> | 1944 | M: Philip Blundell <philb@gnu.org> |
1945 | L: netdev@vger.kernel.org | 1945 | L: netdev@vger.kernel.org |
1946 | S: Maintained | 1946 | S: Maintained |
1947 | F: drivers/net/eexpress.* | 1947 | F: drivers/net/eexpress.* |
1948 | 1948 | ||
1949 | ETHERNET BRIDGE | 1949 | ETHERNET BRIDGE |
1950 | M: Stephen Hemminger <shemminger@linux-foundation.org> | 1950 | M: Stephen Hemminger <shemminger@linux-foundation.org> |
1951 | L: bridge@lists.linux-foundation.org | 1951 | L: bridge@lists.linux-foundation.org |
1952 | W: http://www.linux-foundation.org/en/Net:Bridge | 1952 | W: http://www.linux-foundation.org/en/Net:Bridge |
1953 | S: Maintained | 1953 | S: Maintained |
1954 | F: include/linux/netfilter_bridge/ | 1954 | F: include/linux/netfilter_bridge/ |
1955 | F: net/bridge/ | 1955 | F: net/bridge/ |
1956 | 1956 | ||
1957 | ETHERTEAM 16I DRIVER | 1957 | ETHERTEAM 16I DRIVER |
1958 | M: Mika Kuoppala <miku@iki.fi> | 1958 | M: Mika Kuoppala <miku@iki.fi> |
1959 | S: Maintained | 1959 | S: Maintained |
1960 | F: drivers/net/eth16i.c | 1960 | F: drivers/net/eth16i.c |
1961 | 1961 | ||
1962 | EXT2 FILE SYSTEM | 1962 | EXT2 FILE SYSTEM |
1963 | L: linux-ext4@vger.kernel.org | 1963 | L: linux-ext4@vger.kernel.org |
1964 | S: Maintained | 1964 | S: Maintained |
1965 | F: Documentation/filesystems/ext2.txt | 1965 | F: Documentation/filesystems/ext2.txt |
1966 | F: fs/ext2/ | 1966 | F: fs/ext2/ |
1967 | F: include/linux/ext2* | 1967 | F: include/linux/ext2* |
1968 | 1968 | ||
1969 | EXT3 FILE SYSTEM | 1969 | EXT3 FILE SYSTEM |
1970 | M: Stephen Tweedie <sct@redhat.com> | 1970 | M: Stephen Tweedie <sct@redhat.com> |
1971 | M: Andrew Morton <akpm@linux-foundation.org> | 1971 | M: Andrew Morton <akpm@linux-foundation.org> |
1972 | M: Andreas Dilger <adilger@sun.com> | 1972 | M: Andreas Dilger <adilger@sun.com> |
1973 | L: linux-ext4@vger.kernel.org | 1973 | L: linux-ext4@vger.kernel.org |
1974 | S: Maintained | 1974 | S: Maintained |
1975 | F: Documentation/filesystems/ext3.txt | 1975 | F: Documentation/filesystems/ext3.txt |
1976 | F: fs/ext3/ | 1976 | F: fs/ext3/ |
1977 | F: include/linux/ext3* | 1977 | F: include/linux/ext3* |
1978 | 1978 | ||
1979 | EXT4 FILE SYSTEM | 1979 | EXT4 FILE SYSTEM |
1980 | M: "Theodore Ts'o" <tytso@mit.edu> | 1980 | M: "Theodore Ts'o" <tytso@mit.edu> |
1981 | M: Andreas Dilger <adilger@sun.com> | 1981 | M: Andreas Dilger <adilger@sun.com> |
1982 | L: linux-ext4@vger.kernel.org | 1982 | L: linux-ext4@vger.kernel.org |
1983 | W: http://ext4.wiki.kernel.org | 1983 | W: http://ext4.wiki.kernel.org |
1984 | S: Maintained | 1984 | S: Maintained |
1985 | F: Documentation/filesystems/ext4.txt | 1985 | F: Documentation/filesystems/ext4.txt |
1986 | F: fs/ext4/ | 1986 | F: fs/ext4/ |
1987 | 1987 | ||
1988 | F71805F HARDWARE MONITORING DRIVER | 1988 | F71805F HARDWARE MONITORING DRIVER |
1989 | M: Jean Delvare <khali@linux-fr.org> | 1989 | M: Jean Delvare <khali@linux-fr.org> |
1990 | L: lm-sensors@lm-sensors.org | 1990 | L: lm-sensors@lm-sensors.org |
1991 | S: Maintained | 1991 | S: Maintained |
1992 | F: Documentation/hwmon/f71805f | 1992 | F: Documentation/hwmon/f71805f |
1993 | F: drivers/hwmon/f71805f.c | 1993 | F: drivers/hwmon/f71805f.c |
1994 | 1994 | ||
1995 | FARSYNC SYNCHRONOUS DRIVER | 1995 | FARSYNC SYNCHRONOUS DRIVER |
1996 | M: Kevin Curtis <kevin.curtis@farsite.co.uk> | 1996 | M: Kevin Curtis <kevin.curtis@farsite.co.uk> |
1997 | W: http://www.farsite.co.uk/ | 1997 | W: http://www.farsite.co.uk/ |
1998 | S: Supported | 1998 | S: Supported |
1999 | F: drivers/net/wan/farsync.* | 1999 | F: drivers/net/wan/farsync.* |
2000 | 2000 | ||
2001 | FAULT INJECTION SUPPORT | 2001 | FAULT INJECTION SUPPORT |
2002 | M: Akinobu Mita <akinobu.mita@gmail.com> | 2002 | M: Akinobu Mita <akinobu.mita@gmail.com> |
2003 | S: Supported | 2003 | S: Supported |
2004 | F: Documentation/fault-injection/ | 2004 | F: Documentation/fault-injection/ |
2005 | F: lib/fault-inject.c | 2005 | F: lib/fault-inject.c |
2006 | 2006 | ||
2007 | FILE LOCKING (flock() and fcntl()/lockf()) | 2007 | FILE LOCKING (flock() and fcntl()/lockf()) |
2008 | M: Matthew Wilcox <matthew@wil.cx> | 2008 | M: Matthew Wilcox <matthew@wil.cx> |
2009 | L: linux-fsdevel@vger.kernel.org | 2009 | L: linux-fsdevel@vger.kernel.org |
2010 | S: Maintained | 2010 | S: Maintained |
2011 | F: include/linux/fcntl.h | 2011 | F: include/linux/fcntl.h |
2012 | F: include/linux/fs.h | 2012 | F: include/linux/fs.h |
2013 | F: fs/fcntl.c | 2013 | F: fs/fcntl.c |
2014 | F: fs/locks.c | 2014 | F: fs/locks.c |
2015 | 2015 | ||
2016 | FILESYSTEMS (VFS and infrastructure) | 2016 | FILESYSTEMS (VFS and infrastructure) |
2017 | M: Alexander Viro <viro@zeniv.linux.org.uk> | 2017 | M: Alexander Viro <viro@zeniv.linux.org.uk> |
2018 | L: linux-fsdevel@vger.kernel.org | 2018 | L: linux-fsdevel@vger.kernel.org |
2019 | S: Maintained | 2019 | S: Maintained |
2020 | F: fs/* | 2020 | F: fs/* |
2021 | 2021 | ||
2022 | FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER | 2022 | FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER |
2023 | M: Riku Voipio <riku.vipio@iki.fi> | 2023 | M: Riku Voipio <riku.vipio@iki.fi> |
2024 | L: lm-sensors@lm-sensors.org | 2024 | L: lm-sensors@lm-sensors.org |
2025 | S: Maintained | 2025 | S: Maintained |
2026 | F: drivers/hwmon/f75375s.c | 2026 | F: drivers/hwmon/f75375s.c |
2027 | F: include/linux/f75375s.h | 2027 | F: include/linux/f75375s.h |
2028 | 2028 | ||
2029 | FIREWIRE SUBSYSTEM | 2029 | FIREWIRE SUBSYSTEM |
2030 | M: Kristian Hoegsberg <krh@redhat.com> | 2030 | M: Kristian Hoegsberg <krh@redhat.com> |
2031 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> | 2031 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> |
2032 | L: linux1394-devel@lists.sourceforge.net | 2032 | L: linux1394-devel@lists.sourceforge.net |
2033 | W: http://www.linux1394.org/ | 2033 | W: http://www.linux1394.org/ |
2034 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git | 2034 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git |
2035 | S: Maintained | 2035 | S: Maintained |
2036 | F: drivers/firewire/ | 2036 | F: drivers/firewire/ |
2037 | F: include/linux/firewire*.h | 2037 | F: include/linux/firewire*.h |
2038 | 2038 | ||
2039 | FIRMWARE LOADER (request_firmware) | 2039 | FIRMWARE LOADER (request_firmware) |
2040 | S: Orphan | 2040 | S: Orphan |
2041 | F: Documentation/firmware_class/ | 2041 | F: Documentation/firmware_class/ |
2042 | F: drivers/base/firmware*.c | 2042 | F: drivers/base/firmware*.c |
2043 | F: include/linux/firmware.h | 2043 | F: include/linux/firmware.h |
2044 | 2044 | ||
2045 | FPU EMULATOR | 2045 | FPU EMULATOR |
2046 | M: Bill Metzenthen <billm@melbpc.org.au> | 2046 | M: Bill Metzenthen <billm@melbpc.org.au> |
2047 | W: http://floatingpoint.sourceforge.net/emulator/index.html | 2047 | W: http://floatingpoint.sourceforge.net/emulator/index.html |
2048 | S: Maintained | 2048 | S: Maintained |
2049 | F: arch/x86/math-emu/ | 2049 | F: arch/x86/math-emu/ |
2050 | 2050 | ||
2051 | FRAME RELAY DLCI/FRAD (Sangoma drivers too) | 2051 | FRAME RELAY DLCI/FRAD (Sangoma drivers too) |
2052 | M: Mike McLagan <mike.mclagan@linux.org> | 2052 | M: Mike McLagan <mike.mclagan@linux.org> |
2053 | L: netdev@vger.kernel.org | 2053 | L: netdev@vger.kernel.org |
2054 | S: Maintained | 2054 | S: Maintained |
2055 | F: drivers/net/wan/dlci.c | 2055 | F: drivers/net/wan/dlci.c |
2056 | F: drivers/net/wan/sdla.c | 2056 | F: drivers/net/wan/sdla.c |
2057 | 2057 | ||
2058 | FRAMEBUFFER LAYER | 2058 | FRAMEBUFFER LAYER |
2059 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2059 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
2060 | W: http://linux-fbdev.sourceforge.net/ | 2060 | W: http://linux-fbdev.sourceforge.net/ |
2061 | S: Orphan | 2061 | S: Orphan |
2062 | F: Documentation/fb/ | 2062 | F: Documentation/fb/ |
2063 | F: drivers/video/fb* | 2063 | F: drivers/video/fb* |
2064 | F: include/linux/fb.h | 2064 | F: include/linux/fb.h |
2065 | 2065 | ||
2066 | FREESCALE DMA DRIVER | 2066 | FREESCALE DMA DRIVER |
2067 | M: Li Yang <leoli@freescale.com> | 2067 | M: Li Yang <leoli@freescale.com> |
2068 | M: Zhang Wei <zw@zh-kernel.org> | 2068 | M: Zhang Wei <zw@zh-kernel.org> |
2069 | L: linuxppc-dev@ozlabs.org | 2069 | L: linuxppc-dev@ozlabs.org |
2070 | S: Maintained | 2070 | S: Maintained |
2071 | F: drivers/dma/fsldma.* | 2071 | F: drivers/dma/fsldma.* |
2072 | 2072 | ||
2073 | FREESCALE I2C CPM DRIVER | 2073 | FREESCALE I2C CPM DRIVER |
2074 | M: Jochen Friedrich <jochen@scram.de> | 2074 | M: Jochen Friedrich <jochen@scram.de> |
2075 | L: linuxppc-dev@ozlabs.org | 2075 | L: linuxppc-dev@ozlabs.org |
2076 | L: linux-i2c@vger.kernel.org | 2076 | L: linux-i2c@vger.kernel.org |
2077 | S: Maintained | 2077 | S: Maintained |
2078 | F: drivers/i2c/busses/i2c-cpm.c | 2078 | F: drivers/i2c/busses/i2c-cpm.c |
2079 | 2079 | ||
2080 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER | 2080 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER |
2081 | M: Sascha Hauer <kernel@pengutronix.de> | 2081 | M: Sascha Hauer <kernel@pengutronix.de> |
2082 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2082 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
2083 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 2083 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
2084 | S: Maintained | 2084 | S: Maintained |
2085 | F: arch/arm/plat-mxc/include/mach/imxfb.h | 2085 | F: arch/arm/plat-mxc/include/mach/imxfb.h |
2086 | F: drivers/video/imxfb.c | 2086 | F: drivers/video/imxfb.c |
2087 | 2087 | ||
2088 | FREESCALE SOC FS_ENET DRIVER | 2088 | FREESCALE SOC FS_ENET DRIVER |
2089 | M: Pantelis Antoniou <pantelis.antoniou@gmail.com> | 2089 | M: Pantelis Antoniou <pantelis.antoniou@gmail.com> |
2090 | M: Vitaly Bordug <vbordug@ru.mvista.com> | 2090 | M: Vitaly Bordug <vbordug@ru.mvista.com> |
2091 | L: linuxppc-dev@ozlabs.org | 2091 | L: linuxppc-dev@ozlabs.org |
2092 | L: netdev@vger.kernel.org | 2092 | L: netdev@vger.kernel.org |
2093 | S: Maintained | 2093 | S: Maintained |
2094 | F: drivers/net/fs_enet/ | 2094 | F: drivers/net/fs_enet/ |
2095 | F: include/linux/fs_enet_pd.h | 2095 | F: include/linux/fs_enet_pd.h |
2096 | 2096 | ||
2097 | FREESCALE QUICC ENGINE LIBRARY | 2097 | FREESCALE QUICC ENGINE LIBRARY |
2098 | M: Timur Tabi <timur@freescale.com> | 2098 | M: Timur Tabi <timur@freescale.com> |
2099 | L: linuxppc-dev@ozlabs.org | 2099 | L: linuxppc-dev@ozlabs.org |
2100 | S: Supported | 2100 | S: Supported |
2101 | F: arch/powerpc/sysdev/qe_lib/ | 2101 | F: arch/powerpc/sysdev/qe_lib/ |
2102 | F: arch/powerpc/include/asm/*qe.h | 2102 | F: arch/powerpc/include/asm/*qe.h |
2103 | 2103 | ||
2104 | FREESCALE HIGHSPEED USB DEVICE DRIVER | 2104 | FREESCALE HIGHSPEED USB DEVICE DRIVER |
2105 | M: Li Yang <leoli@freescale.com> | 2105 | M: Li Yang <leoli@freescale.com> |
2106 | L: linux-usb@vger.kernel.org | 2106 | L: linux-usb@vger.kernel.org |
2107 | L: linuxppc-dev@ozlabs.org | 2107 | L: linuxppc-dev@ozlabs.org |
2108 | S: Maintained | 2108 | S: Maintained |
2109 | F: drivers/usb/gadget/fsl_usb2_udc.c | 2109 | F: drivers/usb/gadget/fsl_usb2_udc.c |
2110 | 2110 | ||
2111 | FREESCALE QUICC ENGINE UCC ETHERNET DRIVER | 2111 | FREESCALE QUICC ENGINE UCC ETHERNET DRIVER |
2112 | M: Li Yang <leoli@freescale.com> | 2112 | M: Li Yang <leoli@freescale.com> |
2113 | L: netdev@vger.kernel.org | 2113 | L: netdev@vger.kernel.org |
2114 | L: linuxppc-dev@ozlabs.org | 2114 | L: linuxppc-dev@ozlabs.org |
2115 | S: Maintained | 2115 | S: Maintained |
2116 | F: drivers/net/ucc_geth* | 2116 | F: drivers/net/ucc_geth* |
2117 | 2117 | ||
2118 | FREESCALE QUICC ENGINE UCC UART DRIVER | 2118 | FREESCALE QUICC ENGINE UCC UART DRIVER |
2119 | M: Timur Tabi <timur@freescale.com> | 2119 | M: Timur Tabi <timur@freescale.com> |
2120 | L: linuxppc-dev@ozlabs.org | 2120 | L: linuxppc-dev@ozlabs.org |
2121 | S: Supported | 2121 | S: Supported |
2122 | F: drivers/serial/ucc_uart.c | 2122 | F: drivers/serial/ucc_uart.c |
2123 | 2123 | ||
2124 | FREESCALE SOC SOUND DRIVERS | 2124 | FREESCALE SOC SOUND DRIVERS |
2125 | M: Timur Tabi <timur@freescale.com> | 2125 | M: Timur Tabi <timur@freescale.com> |
2126 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 2126 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
2127 | L: linuxppc-dev@ozlabs.org | 2127 | L: linuxppc-dev@ozlabs.org |
2128 | S: Supported | 2128 | S: Supported |
2129 | F: sound/soc/fsl/fsl* | 2129 | F: sound/soc/fsl/fsl* |
2130 | F: sound/soc/fsl/mpc8610_hpcd.c | 2130 | F: sound/soc/fsl/mpc8610_hpcd.c |
2131 | 2131 | ||
2132 | FREEVXFS FILESYSTEM | 2132 | FREEVXFS FILESYSTEM |
2133 | M: Christoph Hellwig <hch@infradead.org> | 2133 | M: Christoph Hellwig <hch@infradead.org> |
2134 | W: ftp://ftp.openlinux.org/pub/people/hch/vxfs | 2134 | W: ftp://ftp.openlinux.org/pub/people/hch/vxfs |
2135 | S: Maintained | 2135 | S: Maintained |
2136 | F: fs/freevxfs/ | 2136 | F: fs/freevxfs/ |
2137 | 2137 | ||
2138 | FREEZER | 2138 | FREEZER |
2139 | M: Pavel Machek <pavel@ucw.cz> | 2139 | M: Pavel Machek <pavel@ucw.cz> |
2140 | M: "Rafael J. Wysocki" <rjw@sisk.pl> | 2140 | M: "Rafael J. Wysocki" <rjw@sisk.pl> |
2141 | L: linux-pm@lists.linux-foundation.org | 2141 | L: linux-pm@lists.linux-foundation.org |
2142 | S: Supported | 2142 | S: Supported |
2143 | F: Documentation/power/freezing-of-tasks.txt | 2143 | F: Documentation/power/freezing-of-tasks.txt |
2144 | F: include/linux/freezer.h | 2144 | F: include/linux/freezer.h |
2145 | F: kernel/freezer.c | 2145 | F: kernel/freezer.c |
2146 | 2146 | ||
2147 | FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS | 2147 | FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS |
2148 | M: David Howells <dhowells@redhat.com> | 2148 | M: David Howells <dhowells@redhat.com> |
2149 | L: linux-cachefs@redhat.com | 2149 | L: linux-cachefs@redhat.com |
2150 | S: Supported | 2150 | S: Supported |
2151 | F: Documentation/filesystems/caching/ | 2151 | F: Documentation/filesystems/caching/ |
2152 | F: fs/fscache/ | 2152 | F: fs/fscache/ |
2153 | F: include/linux/fscache*.h | 2153 | F: include/linux/fscache*.h |
2154 | 2154 | ||
2155 | FTRACE | 2155 | FTRACE |
2156 | M: Steven Rostedt <rostedt@goodmis.org> | 2156 | M: Steven Rostedt <rostedt@goodmis.org> |
2157 | S: Maintained | 2157 | S: Maintained |
2158 | F: Documentation/trace/ftrace.txt | 2158 | F: Documentation/trace/ftrace.txt |
2159 | F: arch/*/*/*/ftrace.h | 2159 | F: arch/*/*/*/ftrace.h |
2160 | F: arch/*/kernel/ftrace.c | 2160 | F: arch/*/kernel/ftrace.c |
2161 | F: include/*/ftrace.h | 2161 | F: include/*/ftrace.h |
2162 | F: kernel/trace/ | 2162 | F: kernel/trace/ |
2163 | 2163 | ||
2164 | FUJITSU FR-V (FRV) PORT | 2164 | FUJITSU FR-V (FRV) PORT |
2165 | M: David Howells <dhowells@redhat.com> | 2165 | M: David Howells <dhowells@redhat.com> |
2166 | S: Maintained | 2166 | S: Maintained |
2167 | F: arch/frv/ | 2167 | F: arch/frv/ |
2168 | 2168 | ||
2169 | FUJITSU LAPTOP EXTRAS | 2169 | FUJITSU LAPTOP EXTRAS |
2170 | M: Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | 2170 | M: Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
2171 | L: linux-acpi@vger.kernel.org | 2171 | L: linux-acpi@vger.kernel.org |
2172 | S: Maintained | 2172 | S: Maintained |
2173 | F: drivers/platform/x86/fujitsu-laptop.c | 2173 | F: drivers/platform/x86/fujitsu-laptop.c |
2174 | 2174 | ||
2175 | FUSE: FILESYSTEM IN USERSPACE | 2175 | FUSE: FILESYSTEM IN USERSPACE |
2176 | M: Miklos Szeredi <miklos@szeredi.hu> | 2176 | M: Miklos Szeredi <miklos@szeredi.hu> |
2177 | L: fuse-devel@lists.sourceforge.net | 2177 | L: fuse-devel@lists.sourceforge.net |
2178 | W: http://fuse.sourceforge.net/ | 2178 | W: http://fuse.sourceforge.net/ |
2179 | S: Maintained | 2179 | S: Maintained |
2180 | F: fs/fuse/ | 2180 | F: fs/fuse/ |
2181 | F: include/linux/fuse.h | 2181 | F: include/linux/fuse.h |
2182 | 2182 | ||
2183 | FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) | 2183 | FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) |
2184 | M: Rik Faith <faith@cs.unc.edu> | 2184 | M: Rik Faith <faith@cs.unc.edu> |
2185 | L: linux-scsi@vger.kernel.org | 2185 | L: linux-scsi@vger.kernel.org |
2186 | S: Odd Fixes (e.g., new signatures) | 2186 | S: Odd Fixes (e.g., new signatures) |
2187 | F: drivers/scsi/fdomain.* | 2187 | F: drivers/scsi/fdomain.* |
2188 | 2188 | ||
2189 | GDT SCSI DISK ARRAY CONTROLLER DRIVER | 2189 | GDT SCSI DISK ARRAY CONTROLLER DRIVER |
2190 | M: Achim Leubner <achim_leubner@adaptec.com> | 2190 | M: Achim Leubner <achim_leubner@adaptec.com> |
2191 | L: linux-scsi@vger.kernel.org | 2191 | L: linux-scsi@vger.kernel.org |
2192 | W: http://www.icp-vortex.com/ | 2192 | W: http://www.icp-vortex.com/ |
2193 | S: Supported | 2193 | S: Supported |
2194 | F: drivers/scsi/gdt* | 2194 | F: drivers/scsi/gdt* |
2195 | 2195 | ||
2196 | GENERIC GPIO I2C DRIVER | 2196 | GENERIC GPIO I2C DRIVER |
2197 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 2197 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> |
2198 | S: Supported | 2198 | S: Supported |
2199 | F: drivers/i2c/busses/i2c-gpio.c | 2199 | F: drivers/i2c/busses/i2c-gpio.c |
2200 | F: include/linux/i2c-gpio.h | 2200 | F: include/linux/i2c-gpio.h |
2201 | 2201 | ||
2202 | GENERIC HDLC (WAN) DRIVERS | 2202 | GENERIC HDLC (WAN) DRIVERS |
2203 | M: Krzysztof Halasa <khc@pm.waw.pl> | 2203 | M: Krzysztof Halasa <khc@pm.waw.pl> |
2204 | W: http://www.kernel.org/pub/linux/utils/net/hdlc/ | 2204 | W: http://www.kernel.org/pub/linux/utils/net/hdlc/ |
2205 | S: Maintained | 2205 | S: Maintained |
2206 | F: drivers/net/wan/c101.c | 2206 | F: drivers/net/wan/c101.c |
2207 | F: drivers/net/wan/hd6457* | 2207 | F: drivers/net/wan/hd6457* |
2208 | F: drivers/net/wan/hdlc* | 2208 | F: drivers/net/wan/hdlc* |
2209 | F: drivers/net/wan/n2.c | 2209 | F: drivers/net/wan/n2.c |
2210 | F: drivers/net/wan/pc300too.c | 2210 | F: drivers/net/wan/pc300too.c |
2211 | F: drivers/net/wan/pci200syn.c | 2211 | F: drivers/net/wan/pci200syn.c |
2212 | F: drivers/net/wan/wanxl* | 2212 | F: drivers/net/wan/wanxl* |
2213 | 2213 | ||
2214 | GENERIC INCLUDE/ASM HEADER FILES | 2214 | GENERIC INCLUDE/ASM HEADER FILES |
2215 | M: Arnd Bergmann <arnd@arndb.de> | 2215 | M: Arnd Bergmann <arnd@arndb.de> |
2216 | L: linux-arch@vger.kernel.org | 2216 | L: linux-arch@vger.kernel.org |
2217 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git | 2217 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git |
2218 | S: Maintained | 2218 | S: Maintained |
2219 | F: include/asm-generic | 2219 | F: include/asm-generic |
2220 | 2220 | ||
2221 | GFS2 FILE SYSTEM | 2221 | GFS2 FILE SYSTEM |
2222 | M: Steven Whitehouse <swhiteho@redhat.com> | 2222 | M: Steven Whitehouse <swhiteho@redhat.com> |
2223 | L: cluster-devel@redhat.com | 2223 | L: cluster-devel@redhat.com |
2224 | W: http://sources.redhat.com/cluster/ | 2224 | W: http://sources.redhat.com/cluster/ |
2225 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git | 2225 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git |
2226 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git | 2226 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git |
2227 | S: Supported | 2227 | S: Supported |
2228 | F: Documentation/filesystems/gfs2*.txt | 2228 | F: Documentation/filesystems/gfs2*.txt |
2229 | F: fs/gfs2/ | 2229 | F: fs/gfs2/ |
2230 | F: include/linux/gfs2_ondisk.h | 2230 | F: include/linux/gfs2_ondisk.h |
2231 | 2231 | ||
2232 | GIGASET ISDN DRIVERS | 2232 | GIGASET ISDN DRIVERS |
2233 | M: Hansjoerg Lipp <hjlipp@web.de> | 2233 | M: Hansjoerg Lipp <hjlipp@web.de> |
2234 | M: Tilman Schmidt <tilman@imap.cc> | 2234 | M: Tilman Schmidt <tilman@imap.cc> |
2235 | L: gigaset307x-common@lists.sourceforge.net | 2235 | L: gigaset307x-common@lists.sourceforge.net |
2236 | W: http://gigaset307x.sourceforge.net/ | 2236 | W: http://gigaset307x.sourceforge.net/ |
2237 | S: Maintained | 2237 | S: Maintained |
2238 | F: Documentation/isdn/README.gigaset | 2238 | F: Documentation/isdn/README.gigaset |
2239 | F: drivers/isdn/gigaset/ | 2239 | F: drivers/isdn/gigaset/ |
2240 | F: include/linux/gigaset_dev.h | 2240 | F: include/linux/gigaset_dev.h |
2241 | 2241 | ||
2242 | HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER | 2242 | HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER |
2243 | M: Frank Seidel <frank@f-seidel.de> | 2243 | M: Frank Seidel <frank@f-seidel.de> |
2244 | L: lm-sensors@lm-sensors.org | 2244 | L: lm-sensors@lm-sensors.org |
2245 | W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ | 2245 | W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ |
2246 | S: Maintained | 2246 | S: Maintained |
2247 | F: drivers/hwmon/hdaps.c | 2247 | F: drivers/hwmon/hdaps.c |
2248 | 2248 | ||
2249 | HYPERVISOR VIRTUAL CONSOLE DRIVER | 2249 | HYPERVISOR VIRTUAL CONSOLE DRIVER |
2250 | L: linuxppc-dev@ozlabs.org | 2250 | L: linuxppc-dev@ozlabs.org |
2251 | S: Odd Fixes | 2251 | S: Odd Fixes |
2252 | F: drivers/char/hvc_* | 2252 | F: drivers/char/hvc_* |
2253 | 2253 | ||
2254 | GSPCA FINEPIX SUBDRIVER | 2254 | GSPCA FINEPIX SUBDRIVER |
2255 | M: Frank Zago <frank@zago.net> | 2255 | M: Frank Zago <frank@zago.net> |
2256 | L: linux-media@vger.kernel.org | 2256 | L: linux-media@vger.kernel.org |
2257 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2257 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2258 | S: Maintained | 2258 | S: Maintained |
2259 | F: drivers/media/video/gspca/finepix.c | 2259 | F: drivers/media/video/gspca/finepix.c |
2260 | 2260 | ||
2261 | GSPCA M5602 SUBDRIVER | 2261 | GSPCA M5602 SUBDRIVER |
2262 | M: Erik Andren <erik.andren@gmail.com> | 2262 | M: Erik Andren <erik.andren@gmail.com> |
2263 | L: linux-media@vger.kernel.org | 2263 | L: linux-media@vger.kernel.org |
2264 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2264 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2265 | S: Maintained | 2265 | S: Maintained |
2266 | F: drivers/media/video/gspca/m5602/ | 2266 | F: drivers/media/video/gspca/m5602/ |
2267 | 2267 | ||
2268 | GSPCA PAC207 SONIXB SUBDRIVER | 2268 | GSPCA PAC207 SONIXB SUBDRIVER |
2269 | M: Hans de Goede <hdegoede@redhat.com> | 2269 | M: Hans de Goede <hdegoede@redhat.com> |
2270 | L: linux-media@vger.kernel.org | 2270 | L: linux-media@vger.kernel.org |
2271 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2271 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2272 | S: Maintained | 2272 | S: Maintained |
2273 | F: drivers/media/video/gspca/pac207.c | 2273 | F: drivers/media/video/gspca/pac207.c |
2274 | 2274 | ||
2275 | GSPCA SN9C20X SUBDRIVER | 2275 | GSPCA SN9C20X SUBDRIVER |
2276 | M: Brian Johnson <brijohn@gmail.com> | 2276 | M: Brian Johnson <brijohn@gmail.com> |
2277 | L: linux-media@vger.kernel.org | 2277 | L: linux-media@vger.kernel.org |
2278 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2278 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2279 | S: Maintained | 2279 | S: Maintained |
2280 | F: drivers/media/video/gspca/sn9c20x.c | 2280 | F: drivers/media/video/gspca/sn9c20x.c |
2281 | 2281 | ||
2282 | GSPCA T613 SUBDRIVER | 2282 | GSPCA T613 SUBDRIVER |
2283 | M: Leandro Costantino <lcostantino@gmail.com> | 2283 | M: Leandro Costantino <lcostantino@gmail.com> |
2284 | L: linux-media@vger.kernel.org | 2284 | L: linux-media@vger.kernel.org |
2285 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2285 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2286 | S: Maintained | 2286 | S: Maintained |
2287 | F: drivers/media/video/gspca/t613.c | 2287 | F: drivers/media/video/gspca/t613.c |
2288 | 2288 | ||
2289 | GSPCA USB WEBCAM DRIVER | 2289 | GSPCA USB WEBCAM DRIVER |
2290 | M: Jean-Francois Moine <moinejf@free.fr> | 2290 | M: Jean-Francois Moine <moinejf@free.fr> |
2291 | W: http://moinejf.free.fr | 2291 | W: http://moinejf.free.fr |
2292 | L: linux-media@vger.kernel.org | 2292 | L: linux-media@vger.kernel.org |
2293 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2293 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2294 | S: Maintained | 2294 | S: Maintained |
2295 | F: drivers/media/video/gspca/ | 2295 | F: drivers/media/video/gspca/ |
2296 | 2296 | ||
2297 | HARDWARE MONITORING | 2297 | HARDWARE MONITORING |
2298 | L: lm-sensors@lm-sensors.org | 2298 | L: lm-sensors@lm-sensors.org |
2299 | W: http://www.lm-sensors.org/ | 2299 | W: http://www.lm-sensors.org/ |
2300 | S: Orphan | 2300 | S: Orphan |
2301 | F: drivers/hwmon/ | 2301 | F: drivers/hwmon/ |
2302 | 2302 | ||
2303 | HARDWARE RANDOM NUMBER GENERATOR CORE | 2303 | HARDWARE RANDOM NUMBER GENERATOR CORE |
2304 | S: Orphan | 2304 | S: Orphan |
2305 | F: Documentation/hw_random.txt | 2305 | F: Documentation/hw_random.txt |
2306 | F: drivers/char/hw_random/ | 2306 | F: drivers/char/hw_random/ |
2307 | F: include/linux/hw_random.h | 2307 | F: include/linux/hw_random.h |
2308 | 2308 | ||
2309 | HARMONY SOUND DRIVER | 2309 | HARMONY SOUND DRIVER |
2310 | M: Kyle McMartin <kyle@mcmartin.ca> | 2310 | M: Kyle McMartin <kyle@mcmartin.ca> |
2311 | L: linux-parisc@vger.kernel.org | 2311 | L: linux-parisc@vger.kernel.org |
2312 | S: Maintained | 2312 | S: Maintained |
2313 | F: sound/parisc/harmony.* | 2313 | F: sound/parisc/harmony.* |
2314 | 2314 | ||
2315 | HAYES ESP SERIAL DRIVER | 2315 | HAYES ESP SERIAL DRIVER |
2316 | M: "Andrew J. Robinson" <arobinso@nyx.net> | 2316 | M: "Andrew J. Robinson" <arobinso@nyx.net> |
2317 | W: http://www.nyx.net/~arobinso | 2317 | W: http://www.nyx.net/~arobinso |
2318 | S: Maintained | 2318 | S: Maintained |
2319 | F: Documentation/serial/hayes-esp.txt | 2319 | F: Documentation/serial/hayes-esp.txt |
2320 | F: drivers/char/esp.c | 2320 | F: drivers/char/esp.c |
2321 | 2321 | ||
2322 | HEWLETT-PACKARD SMART2 RAID DRIVER | 2322 | HEWLETT-PACKARD SMART2 RAID DRIVER |
2323 | M: Chirag Kantharia <chirag.kantharia@hp.com> | 2323 | M: Chirag Kantharia <chirag.kantharia@hp.com> |
2324 | L: iss_storagedev@hp.com | 2324 | L: iss_storagedev@hp.com |
2325 | S: Maintained | 2325 | S: Maintained |
2326 | F: Documentation/blockdev/cpqarray.txt | 2326 | F: Documentation/blockdev/cpqarray.txt |
2327 | F: drivers/block/cpqarray.* | 2327 | F: drivers/block/cpqarray.* |
2328 | 2328 | ||
2329 | HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) | 2329 | HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) |
2330 | M: Mike Miller <mike.miller@hp.com> | 2330 | M: Mike Miller <mike.miller@hp.com> |
2331 | L: iss_storagedev@hp.com | 2331 | L: iss_storagedev@hp.com |
2332 | S: Supported | 2332 | S: Supported |
2333 | F: Documentation/blockdev/cciss.txt | 2333 | F: Documentation/blockdev/cciss.txt |
2334 | F: drivers/block/cciss* | 2334 | F: drivers/block/cciss* |
2335 | F: include/linux/cciss_ioctl.h | 2335 | F: include/linux/cciss_ioctl.h |
2336 | 2336 | ||
2337 | HFS FILESYSTEM | 2337 | HFS FILESYSTEM |
2338 | M: Roman Zippel <zippel@linux-m68k.org> | 2338 | M: Roman Zippel <zippel@linux-m68k.org> |
2339 | S: Maintained | 2339 | S: Maintained |
2340 | F: Documentation/filesystems/hfs.txt | 2340 | F: Documentation/filesystems/hfs.txt |
2341 | F: fs/hfs/ | 2341 | F: fs/hfs/ |
2342 | 2342 | ||
2343 | HGA FRAMEBUFFER DRIVER | 2343 | HGA FRAMEBUFFER DRIVER |
2344 | M: Ferenc Bakonyi <fero@drama.obuda.kando.hu> | 2344 | M: Ferenc Bakonyi <fero@drama.obuda.kando.hu> |
2345 | L: linux-nvidia@lists.surfsouth.com | 2345 | L: linux-nvidia@lists.surfsouth.com |
2346 | W: http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml | 2346 | W: http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml |
2347 | S: Maintained | 2347 | S: Maintained |
2348 | F: drivers/video/hgafb.c | 2348 | F: drivers/video/hgafb.c |
2349 | 2349 | ||
2350 | HIBERNATION (aka Software Suspend, aka swsusp) | 2350 | HIBERNATION (aka Software Suspend, aka swsusp) |
2351 | M: Pavel Machek <pavel@ucw.cz> | 2351 | M: Pavel Machek <pavel@ucw.cz> |
2352 | M: "Rafael J. Wysocki" <rjw@sisk.pl> | 2352 | M: "Rafael J. Wysocki" <rjw@sisk.pl> |
2353 | L: linux-pm@lists.linux-foundation.org | 2353 | L: linux-pm@lists.linux-foundation.org |
2354 | S: Supported | 2354 | S: Supported |
2355 | F: arch/x86/power/ | 2355 | F: arch/x86/power/ |
2356 | F: drivers/base/power/ | 2356 | F: drivers/base/power/ |
2357 | F: kernel/power/ | 2357 | F: kernel/power/ |
2358 | F: include/linux/suspend.h | 2358 | F: include/linux/suspend.h |
2359 | F: include/linux/freezer.h | 2359 | F: include/linux/freezer.h |
2360 | F: include/linux/pm.h | 2360 | F: include/linux/pm.h |
2361 | F: arch/*/include/asm/suspend*.h | 2361 | F: arch/*/include/asm/suspend*.h |
2362 | 2362 | ||
2363 | HID CORE LAYER | 2363 | HID CORE LAYER |
2364 | M: Jiri Kosina <jkosina@suse.cz> | 2364 | M: Jiri Kosina <jkosina@suse.cz> |
2365 | L: linux-input@vger.kernel.org | 2365 | L: linux-input@vger.kernel.org |
2366 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git | 2366 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git |
2367 | S: Maintained | 2367 | S: Maintained |
2368 | F: drivers/hid/ | 2368 | F: drivers/hid/ |
2369 | F: include/linux/hid* | 2369 | F: include/linux/hid* |
2370 | 2370 | ||
2371 | HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS | 2371 | HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS |
2372 | M: Thomas Gleixner <tglx@linutronix.de> | 2372 | M: Thomas Gleixner <tglx@linutronix.de> |
2373 | S: Maintained | 2373 | S: Maintained |
2374 | F: Documentation/timers/ | 2374 | F: Documentation/timers/ |
2375 | F: kernel/hrtimer.c | 2375 | F: kernel/hrtimer.c |
2376 | F: include/linux/hrtimer.h | 2376 | F: include/linux/hrtimer.h |
2377 | 2377 | ||
2378 | HIGH-SPEED SCC DRIVER FOR AX.25 | 2378 | HIGH-SPEED SCC DRIVER FOR AX.25 |
2379 | M: Klaus Kudielka <klaus.kudielka@ieee.org> | 2379 | M: Klaus Kudielka <klaus.kudielka@ieee.org> |
2380 | L: linux-hams@vger.kernel.org | 2380 | L: linux-hams@vger.kernel.org |
2381 | W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/ | 2381 | W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/ |
2382 | S: Maintained | 2382 | S: Maintained |
2383 | F: drivers/net/hamradio/dmascc.c | 2383 | F: drivers/net/hamradio/dmascc.c |
2384 | F: drivers/net/hamradio/scc.c | 2384 | F: drivers/net/hamradio/scc.c |
2385 | 2385 | ||
2386 | HIGHPOINT ROCKETRAID 3xxx RAID DRIVER | 2386 | HIGHPOINT ROCKETRAID 3xxx RAID DRIVER |
2387 | M: HighPoint Linux Team <linux@highpoint-tech.com> | 2387 | M: HighPoint Linux Team <linux@highpoint-tech.com> |
2388 | W: http://www.highpoint-tech.com | 2388 | W: http://www.highpoint-tech.com |
2389 | S: Supported | 2389 | S: Supported |
2390 | F: Documentation/scsi/hptiop.txt | 2390 | F: Documentation/scsi/hptiop.txt |
2391 | F: drivers/scsi/hptiop.c | 2391 | F: drivers/scsi/hptiop.c |
2392 | 2392 | ||
2393 | HIPPI | 2393 | HIPPI |
2394 | M: Jes Sorensen <jes@trained-monkey.org> | 2394 | M: Jes Sorensen <jes@trained-monkey.org> |
2395 | L: linux-hippi@sunsite.dk | 2395 | L: linux-hippi@sunsite.dk |
2396 | S: Maintained | 2396 | S: Maintained |
2397 | F: include/linux/hippidevice.h | 2397 | F: include/linux/hippidevice.h |
2398 | F: include/linux/if_hippi.h | 2398 | F: include/linux/if_hippi.h |
2399 | F: net/802/hippi.c | 2399 | F: net/802/hippi.c |
2400 | 2400 | ||
2401 | HOST AP DRIVER | 2401 | HOST AP DRIVER |
2402 | M: Jouni Malinen <j@w1.fi> | 2402 | M: Jouni Malinen <j@w1.fi> |
2403 | L: hostap@shmoo.com (subscribers-only) | 2403 | L: hostap@shmoo.com (subscribers-only) |
2404 | L: linux-wireless@vger.kernel.org | 2404 | L: linux-wireless@vger.kernel.org |
2405 | W: http://hostap.epitest.fi/ | 2405 | W: http://hostap.epitest.fi/ |
2406 | S: Maintained | 2406 | S: Maintained |
2407 | F: drivers/net/wireless/hostap/ | 2407 | F: drivers/net/wireless/hostap/ |
2408 | 2408 | ||
2409 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER | 2409 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER |
2410 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 2410 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> |
2411 | S: Odd Fixes | 2411 | S: Odd Fixes |
2412 | F: drivers/platform/x86/tc1100-wmi.c | 2412 | F: drivers/platform/x86/tc1100-wmi.c |
2413 | 2413 | ||
2414 | HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series | 2414 | HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series |
2415 | M: Jaroslav Kysela <perex@perex.cz> | 2415 | M: Jaroslav Kysela <perex@perex.cz> |
2416 | S: Maintained | 2416 | S: Maintained |
2417 | F: drivers/net/hp100.* | 2417 | F: drivers/net/hp100.* |
2418 | 2418 | ||
2419 | HPET: High Precision Event Timers driver | 2419 | HPET: High Precision Event Timers driver |
2420 | M: Clemens Ladisch <clemens@ladisch.de> | 2420 | M: Clemens Ladisch <clemens@ladisch.de> |
2421 | S: Maintained | 2421 | S: Maintained |
2422 | F: Documentation/timers/hpet.txt | 2422 | F: Documentation/timers/hpet.txt |
2423 | F: drivers/char/hpet.c | 2423 | F: drivers/char/hpet.c |
2424 | F: include/linux/hpet.h | 2424 | F: include/linux/hpet.h |
2425 | 2425 | ||
2426 | HPET: i386 | 2426 | HPET: i386 |
2427 | M: "Venkatesh Pallipadi (Venki)" <venkatesh.pallipadi@intel.com> | 2427 | M: "Venkatesh Pallipadi (Venki)" <venkatesh.pallipadi@intel.com> |
2428 | S: Maintained | 2428 | S: Maintained |
2429 | F: arch/x86/kernel/hpet.c | 2429 | F: arch/x86/kernel/hpet.c |
2430 | F: arch/x86/include/asm/hpet.h | 2430 | F: arch/x86/include/asm/hpet.h |
2431 | 2431 | ||
2432 | HPET: x86_64 | 2432 | HPET: x86_64 |
2433 | M: Vojtech Pavlik <vojtech@suse.cz> | 2433 | M: Vojtech Pavlik <vojtech@suse.cz> |
2434 | S: Maintained | 2434 | S: Maintained |
2435 | 2435 | ||
2436 | HPET: ACPI | 2436 | HPET: ACPI |
2437 | M: Bob Picco <bob.picco@hp.com> | 2437 | M: Bob Picco <bob.picco@hp.com> |
2438 | S: Maintained | 2438 | S: Maintained |
2439 | F: drivers/char/hpet.c | 2439 | F: drivers/char/hpet.c |
2440 | 2440 | ||
2441 | HPFS FILESYSTEM | 2441 | HPFS FILESYSTEM |
2442 | M: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> | 2442 | M: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> |
2443 | W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi | 2443 | W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi |
2444 | S: Maintained | 2444 | S: Maintained |
2445 | F: fs/hpfs/ | 2445 | F: fs/hpfs/ |
2446 | 2446 | ||
2447 | HSO 3G MODEM DRIVER | 2447 | HSO 3G MODEM DRIVER |
2448 | M: Jan Dumon <j.dumon@option.com> | 2448 | M: Jan Dumon <j.dumon@option.com> |
2449 | W: http://www.pharscape.org | 2449 | W: http://www.pharscape.org |
2450 | S: Maintained | 2450 | S: Maintained |
2451 | F: drivers/net/usb/hso.c | 2451 | F: drivers/net/usb/hso.c |
2452 | 2452 | ||
2453 | HTCPEN TOUCHSCREEN DRIVER | 2453 | HTCPEN TOUCHSCREEN DRIVER |
2454 | M: Pau Oliva Fora <pof@eslack.org> | 2454 | M: Pau Oliva Fora <pof@eslack.org> |
2455 | L: linux-input@vger.kernel.org | 2455 | L: linux-input@vger.kernel.org |
2456 | S: Maintained | 2456 | S: Maintained |
2457 | F: drivers/input/touchscreen/htcpen.c | 2457 | F: drivers/input/touchscreen/htcpen.c |
2458 | 2458 | ||
2459 | HUGETLB FILESYSTEM | 2459 | HUGETLB FILESYSTEM |
2460 | M: William Irwin <wli@holomorphy.com> | 2460 | M: William Irwin <wli@holomorphy.com> |
2461 | S: Maintained | 2461 | S: Maintained |
2462 | F: fs/hugetlbfs/ | 2462 | F: fs/hugetlbfs/ |
2463 | 2463 | ||
2464 | I2C/SMBUS STUB DRIVER | 2464 | I2C/SMBUS STUB DRIVER |
2465 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> | 2465 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
2466 | L: linux-i2c@vger.kernel.org | 2466 | L: linux-i2c@vger.kernel.org |
2467 | S: Maintained | 2467 | S: Maintained |
2468 | F: drivers/i2c/busses/i2c-stub.c | 2468 | F: drivers/i2c/busses/i2c-stub.c |
2469 | 2469 | ||
2470 | I2C SUBSYSTEM | 2470 | I2C SUBSYSTEM |
2471 | M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org> | 2471 | M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org> |
2472 | M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org> | 2472 | M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org> |
2473 | L: linux-i2c@vger.kernel.org | 2473 | L: linux-i2c@vger.kernel.org |
2474 | W: http://i2c.wiki.kernel.org/ | 2474 | W: http://i2c.wiki.kernel.org/ |
2475 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ | 2475 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ |
2476 | S: Maintained | 2476 | S: Maintained |
2477 | F: Documentation/i2c/ | 2477 | F: Documentation/i2c/ |
2478 | F: drivers/i2c/ | 2478 | F: drivers/i2c/ |
2479 | F: include/linux/i2c.h | 2479 | F: include/linux/i2c.h |
2480 | F: include/linux/i2c-dev.h | 2480 | F: include/linux/i2c-dev.h |
2481 | F: include/linux/i2c-id.h | 2481 | F: include/linux/i2c-id.h |
2482 | 2482 | ||
2483 | I2C-TINY-USB DRIVER | 2483 | I2C-TINY-USB DRIVER |
2484 | M: Till Harbaum <till@harbaum.org> | 2484 | M: Till Harbaum <till@harbaum.org> |
2485 | L: linux-i2c@vger.kernel.org | 2485 | L: linux-i2c@vger.kernel.org |
2486 | W: http://www.harbaum.org/till/i2c_tiny_usb | 2486 | W: http://www.harbaum.org/till/i2c_tiny_usb |
2487 | S: Maintained | 2487 | S: Maintained |
2488 | F: drivers/i2c/busses/i2c-tiny-usb.c | 2488 | F: drivers/i2c/busses/i2c-tiny-usb.c |
2489 | 2489 | ||
2490 | i386 BOOT CODE | 2490 | i386 BOOT CODE |
2491 | M: "H. Peter Anvin" <hpa@zytor.com> | 2491 | M: "H. Peter Anvin" <hpa@zytor.com> |
2492 | S: Maintained | 2492 | S: Maintained |
2493 | F: arch/x86/boot/ | 2493 | F: arch/x86/boot/ |
2494 | 2494 | ||
2495 | i386 SETUP CODE / CPU ERRATA WORKAROUNDS | 2495 | i386 SETUP CODE / CPU ERRATA WORKAROUNDS |
2496 | M: "H. Peter Anvin" <hpa@zytor.com> | 2496 | M: "H. Peter Anvin" <hpa@zytor.com> |
2497 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup.git | 2497 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup.git |
2498 | S: Maintained | 2498 | S: Maintained |
2499 | 2499 | ||
2500 | IA64 (Itanium) PLATFORM | 2500 | IA64 (Itanium) PLATFORM |
2501 | M: Tony Luck <tony.luck@intel.com> | 2501 | M: Tony Luck <tony.luck@intel.com> |
2502 | M: Fenghua Yu <fenghua.yu@intel.com> | 2502 | M: Fenghua Yu <fenghua.yu@intel.com> |
2503 | L: linux-ia64@vger.kernel.org | 2503 | L: linux-ia64@vger.kernel.org |
2504 | W: http://www.ia64-linux.org/ | 2504 | W: http://www.ia64-linux.org/ |
2505 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6.git | 2505 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6.git |
2506 | S: Maintained | 2506 | S: Maintained |
2507 | F: arch/ia64/ | 2507 | F: arch/ia64/ |
2508 | 2508 | ||
2509 | IBM MCA SCSI SUBSYSTEM DRIVER | 2509 | IBM MCA SCSI SUBSYSTEM DRIVER |
2510 | M: Michael Lang <langa2@kph.uni-mainz.de> | 2510 | M: Michael Lang <langa2@kph.uni-mainz.de> |
2511 | W: http://www.uni-mainz.de/~langm000/linux.html | 2511 | W: http://www.uni-mainz.de/~langm000/linux.html |
2512 | S: Maintained | 2512 | S: Maintained |
2513 | F: drivers/scsi/ibmmca.c | 2513 | F: drivers/scsi/ibmmca.c |
2514 | 2514 | ||
2515 | IBM Power Linux RAID adapter | 2515 | IBM Power Linux RAID adapter |
2516 | M: Brian King <brking@us.ibm.com> | 2516 | M: Brian King <brking@us.ibm.com> |
2517 | S: Supported | 2517 | S: Supported |
2518 | F: drivers/scsi/ipr.* | 2518 | F: drivers/scsi/ipr.* |
2519 | 2519 | ||
2520 | IBM ServeRAID RAID DRIVER | 2520 | IBM ServeRAID RAID DRIVER |
2521 | P: Jack Hammer | 2521 | P: Jack Hammer |
2522 | M: Dave Jeffery <ipslinux@adaptec.com> | 2522 | M: Dave Jeffery <ipslinux@adaptec.com> |
2523 | W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html | 2523 | W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html |
2524 | S: Supported | 2524 | S: Supported |
2525 | F: drivers/scsi/ips.* | 2525 | F: drivers/scsi/ips.* |
2526 | 2526 | ||
2527 | IDE SUBSYSTEM | 2527 | IDE SUBSYSTEM |
2528 | M: "David S. Miller" <davem@davemloft.net> | 2528 | M: "David S. Miller" <davem@davemloft.net> |
2529 | L: linux-ide@vger.kernel.org | 2529 | L: linux-ide@vger.kernel.org |
2530 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git | 2530 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git |
2531 | S: Maintained | 2531 | S: Maintained |
2532 | F: Documentation/ide/ | 2532 | F: Documentation/ide/ |
2533 | F: drivers/ide/ | 2533 | F: drivers/ide/ |
2534 | F: include/linux/ide.h | 2534 | F: include/linux/ide.h |
2535 | 2535 | ||
2536 | IDE/ATAPI DRIVERS | 2536 | IDE/ATAPI DRIVERS |
2537 | M: Borislav Petkov <petkovbb@gmail.com> | 2537 | M: Borislav Petkov <petkovbb@gmail.com> |
2538 | L: linux-ide@vger.kernel.org | 2538 | L: linux-ide@vger.kernel.org |
2539 | S: Maintained | 2539 | S: Maintained |
2540 | F: Documentation/cdrom/ide-cd | 2540 | F: Documentation/cdrom/ide-cd |
2541 | F: drivers/ide/ide-cd* | 2541 | F: drivers/ide/ide-cd* |
2542 | 2542 | ||
2543 | IDLE-I7300 | 2543 | IDLE-I7300 |
2544 | M: Andy Henroid <andrew.d.henroid@intel.com> | 2544 | M: Andy Henroid <andrew.d.henroid@intel.com> |
2545 | L: linux-pm@lists.linux-foundation.org | 2545 | L: linux-pm@lists.linux-foundation.org |
2546 | S: Supported | 2546 | S: Supported |
2547 | F: drivers/idle/i7300_idle.c | 2547 | F: drivers/idle/i7300_idle.c |
2548 | 2548 | ||
2549 | IEEE 1394 SUBSYSTEM | 2549 | IEEE 1394 SUBSYSTEM |
2550 | M: Ben Collins <ben.collins@ubuntu.com> | 2550 | M: Ben Collins <ben.collins@ubuntu.com> |
2551 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> | 2551 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> |
2552 | L: linux1394-devel@lists.sourceforge.net | 2552 | L: linux1394-devel@lists.sourceforge.net |
2553 | W: http://www.linux1394.org/ | 2553 | W: http://www.linux1394.org/ |
2554 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git | 2554 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git |
2555 | S: Maintained | 2555 | S: Maintained |
2556 | F: drivers/ieee1394/ | 2556 | F: drivers/ieee1394/ |
2557 | 2557 | ||
2558 | IEEE 1394 RAW I/O DRIVER | 2558 | IEEE 1394 RAW I/O DRIVER |
2559 | M: Dan Dennedy <dan@dennedy.org> | 2559 | M: Dan Dennedy <dan@dennedy.org> |
2560 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> | 2560 | M: Stefan Richter <stefanr@s5r6.in-berlin.de> |
2561 | L: linux1394-devel@lists.sourceforge.net | 2561 | L: linux1394-devel@lists.sourceforge.net |
2562 | S: Maintained | 2562 | S: Maintained |
2563 | F: drivers/ieee1394/raw1394* | 2563 | F: drivers/ieee1394/raw1394* |
2564 | 2564 | ||
2565 | IEEE 802.15.4 SUBSYSTEM | 2565 | IEEE 802.15.4 SUBSYSTEM |
2566 | M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2566 | M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
2567 | M: Sergey Lapin <slapin@ossfans.org> | 2567 | M: Sergey Lapin <slapin@ossfans.org> |
2568 | L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) | 2568 | L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) |
2569 | W: http://apps.sourceforge.net/trac/linux-zigbee | 2569 | W: http://apps.sourceforge.net/trac/linux-zigbee |
2570 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git | 2570 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git |
2571 | S: Maintained | 2571 | S: Maintained |
2572 | F: net/ieee802154/ | 2572 | F: net/ieee802154/ |
2573 | F: drivers/ieee802154/ | 2573 | F: drivers/ieee802154/ |
2574 | 2574 | ||
2575 | INTEGRITY MEASUREMENT ARCHITECTURE (IMA) | 2575 | INTEGRITY MEASUREMENT ARCHITECTURE (IMA) |
2576 | M: Mimi Zohar <zohar@us.ibm.com> | 2576 | M: Mimi Zohar <zohar@us.ibm.com> |
2577 | S: Supported | 2577 | S: Supported |
2578 | F: security/integrity/ima/ | 2578 | F: security/integrity/ima/ |
2579 | 2579 | ||
2580 | IMS TWINTURBO FRAMEBUFFER DRIVER | 2580 | IMS TWINTURBO FRAMEBUFFER DRIVER |
2581 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2581 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
2582 | S: Orphan | 2582 | S: Orphan |
2583 | F: drivers/video/imsttfb.c | 2583 | F: drivers/video/imsttfb.c |
2584 | 2584 | ||
2585 | INFINIBAND SUBSYSTEM | 2585 | INFINIBAND SUBSYSTEM |
2586 | M: Roland Dreier <rolandd@cisco.com> | 2586 | M: Roland Dreier <rolandd@cisco.com> |
2587 | M: Sean Hefty <sean.hefty@intel.com> | 2587 | M: Sean Hefty <sean.hefty@intel.com> |
2588 | M: Hal Rosenstock <hal.rosenstock@gmail.com> | 2588 | M: Hal Rosenstock <hal.rosenstock@gmail.com> |
2589 | L: linux-rdma@vger.kernel.org | 2589 | L: linux-rdma@vger.kernel.org |
2590 | W: http://www.openib.org/ | 2590 | W: http://www.openib.org/ |
2591 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git | 2591 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git |
2592 | S: Supported | 2592 | S: Supported |
2593 | F: Documentation/infiniband/ | 2593 | F: Documentation/infiniband/ |
2594 | F: drivers/infiniband/ | 2594 | F: drivers/infiniband/ |
2595 | F: include/linux/if_infiniband.h | 2595 | F: include/linux/if_infiniband.h |
2596 | 2596 | ||
2597 | INOTIFY | 2597 | INOTIFY |
2598 | M: John McCutchan <john@johnmccutchan.com> | 2598 | M: John McCutchan <john@johnmccutchan.com> |
2599 | M: Robert Love <rlove@rlove.org> | 2599 | M: Robert Love <rlove@rlove.org> |
2600 | M: Eric Paris <eparis@parisplace.org> | 2600 | M: Eric Paris <eparis@parisplace.org> |
2601 | S: Maintained | 2601 | S: Maintained |
2602 | F: Documentation/filesystems/inotify.txt | 2602 | F: Documentation/filesystems/inotify.txt |
2603 | F: fs/notify/inotify/ | 2603 | F: fs/notify/inotify/ |
2604 | F: include/linux/inotify.h | 2604 | F: include/linux/inotify.h |
2605 | 2605 | ||
2606 | INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS | 2606 | INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS |
2607 | M: Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2607 | M: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
2608 | M: Dmitry Torokhov <dtor@mail.ru> | 2608 | M: Dmitry Torokhov <dtor@mail.ru> |
2609 | L: linux-input@vger.kernel.org | 2609 | L: linux-input@vger.kernel.org |
2610 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git | 2610 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git |
2611 | S: Maintained | 2611 | S: Maintained |
2612 | F: drivers/input/ | 2612 | F: drivers/input/ |
2613 | 2613 | ||
2614 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) | 2614 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) |
2615 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> | 2615 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> |
2616 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2616 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
2617 | S: Maintained | 2617 | S: Maintained |
2618 | F: Documentation/fb/intelfb.txt | 2618 | F: Documentation/fb/intelfb.txt |
2619 | F: drivers/video/intelfb/ | 2619 | F: drivers/video/intelfb/ |
2620 | 2620 | ||
2621 | INTEL 810/815 FRAMEBUFFER DRIVER | 2621 | INTEL 810/815 FRAMEBUFFER DRIVER |
2622 | M: Antonino Daplas <adaplas@gmail.com> | 2622 | M: Antonino Daplas <adaplas@gmail.com> |
2623 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2623 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
2624 | S: Maintained | 2624 | S: Maintained |
2625 | F: drivers/video/i810/ | 2625 | F: drivers/video/i810/ |
2626 | 2626 | ||
2627 | INTEL MENLOW THERMAL DRIVER | 2627 | INTEL MENLOW THERMAL DRIVER |
2628 | M: Sujith Thomas <sujith.thomas@intel.com> | 2628 | M: Sujith Thomas <sujith.thomas@intel.com> |
2629 | L: linux-acpi@vger.kernel.org | 2629 | L: linux-acpi@vger.kernel.org |
2630 | W: http://www.lesswatts.org/projects/acpi/ | 2630 | W: http://www.lesswatts.org/projects/acpi/ |
2631 | S: Supported | 2631 | S: Supported |
2632 | F: drivers/platform/x86/intel_menlow.c | 2632 | F: drivers/platform/x86/intel_menlow.c |
2633 | 2633 | ||
2634 | INTEL IA32 MICROCODE UPDATE SUPPORT | 2634 | INTEL IA32 MICROCODE UPDATE SUPPORT |
2635 | M: Tigran Aivazian <tigran@aivazian.fsnet.co.uk> | 2635 | M: Tigran Aivazian <tigran@aivazian.fsnet.co.uk> |
2636 | S: Maintained | 2636 | S: Maintained |
2637 | F: arch/x86/kernel/microcode_core.c | 2637 | F: arch/x86/kernel/microcode_core.c |
2638 | F: arch/x86/kernel/microcode_intel.c | 2638 | F: arch/x86/kernel/microcode_intel.c |
2639 | 2639 | ||
2640 | INTEL I/OAT DMA DRIVER | 2640 | INTEL I/OAT DMA DRIVER |
2641 | M: Maciej Sosnowski <maciej.sosnowski@intel.com> | 2641 | M: Maciej Sosnowski <maciej.sosnowski@intel.com> |
2642 | S: Supported | 2642 | S: Supported |
2643 | F: drivers/dma/ioat* | 2643 | F: drivers/dma/ioat* |
2644 | 2644 | ||
2645 | INTEL IOMMU (VT-d) | 2645 | INTEL IOMMU (VT-d) |
2646 | M: David Woodhouse <dwmw2@infradead.org> | 2646 | M: David Woodhouse <dwmw2@infradead.org> |
2647 | L: iommu@lists.linux-foundation.org | 2647 | L: iommu@lists.linux-foundation.org |
2648 | T: git git://git.infradead.org/iommu-2.6.git | 2648 | T: git git://git.infradead.org/iommu-2.6.git |
2649 | S: Supported | 2649 | S: Supported |
2650 | F: drivers/pci/intel-iommu.c | 2650 | F: drivers/pci/intel-iommu.c |
2651 | F: include/linux/intel-iommu.h | 2651 | F: include/linux/intel-iommu.h |
2652 | 2652 | ||
2653 | INTEL IOP-ADMA DMA DRIVER | 2653 | INTEL IOP-ADMA DMA DRIVER |
2654 | M: Dan Williams <dan.j.williams@intel.com> | 2654 | M: Dan Williams <dan.j.williams@intel.com> |
2655 | S: Supported | 2655 | S: Supported |
2656 | F: drivers/dma/iop-adma.c | 2656 | F: drivers/dma/iop-adma.c |
2657 | 2657 | ||
2658 | INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT | 2658 | INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT |
2659 | M: Krzysztof Halasa <khc@pm.waw.pl> | 2659 | M: Krzysztof Halasa <khc@pm.waw.pl> |
2660 | S: Maintained | 2660 | S: Maintained |
2661 | F: arch/arm/mach-ixp4xx/include/mach/qmgr.h | 2661 | F: arch/arm/mach-ixp4xx/include/mach/qmgr.h |
2662 | F: arch/arm/mach-ixp4xx/include/mach/npe.h | 2662 | F: arch/arm/mach-ixp4xx/include/mach/npe.h |
2663 | F: arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | 2663 | F: arch/arm/mach-ixp4xx/ixp4xx_qmgr.c |
2664 | F: arch/arm/mach-ixp4xx/ixp4xx_npe.c | 2664 | F: arch/arm/mach-ixp4xx/ixp4xx_npe.c |
2665 | F: drivers/net/arm/ixp4xx_eth.c | 2665 | F: drivers/net/arm/ixp4xx_eth.c |
2666 | F: drivers/net/wan/ixp4xx_hss.c | 2666 | F: drivers/net/wan/ixp4xx_hss.c |
2667 | 2667 | ||
2668 | INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT | 2668 | INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT |
2669 | M: Deepak Saxena <dsaxena@plexity.net> | 2669 | M: Deepak Saxena <dsaxena@plexity.net> |
2670 | S: Maintained | 2670 | S: Maintained |
2671 | F: drivers/char/hw_random/ixp4xx-rng.c | 2671 | F: drivers/char/hw_random/ixp4xx-rng.c |
2672 | 2672 | ||
2673 | INTEL IXP2000 ETHERNET DRIVER | 2673 | INTEL IXP2000 ETHERNET DRIVER |
2674 | M: Lennert Buytenhek <kernel@wantstofly.org> | 2674 | M: Lennert Buytenhek <kernel@wantstofly.org> |
2675 | L: netdev@vger.kernel.org | 2675 | L: netdev@vger.kernel.org |
2676 | S: Maintained | 2676 | S: Maintained |
2677 | F: drivers/net/ixp2000/ | 2677 | F: drivers/net/ixp2000/ |
2678 | 2678 | ||
2679 | INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe) | 2679 | INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe) |
2680 | M: Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2680 | M: Jeff Kirsher <jeffrey.t.kirsher@intel.com> |
2681 | M: Jesse Brandeburg <jesse.brandeburg@intel.com> | 2681 | M: Jesse Brandeburg <jesse.brandeburg@intel.com> |
2682 | M: Bruce Allan <bruce.w.allan@intel.com> | 2682 | M: Bruce Allan <bruce.w.allan@intel.com> |
2683 | M: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> | 2683 | M: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> |
2684 | M: John Ronciak <john.ronciak@intel.com> | 2684 | M: John Ronciak <john.ronciak@intel.com> |
2685 | L: e1000-devel@lists.sourceforge.net | 2685 | L: e1000-devel@lists.sourceforge.net |
2686 | W: http://e1000.sourceforge.net/ | 2686 | W: http://e1000.sourceforge.net/ |
2687 | S: Supported | 2687 | S: Supported |
2688 | F: drivers/net/e100.c | 2688 | F: drivers/net/e100.c |
2689 | F: drivers/net/e1000/ | 2689 | F: drivers/net/e1000/ |
2690 | F: drivers/net/e1000e/ | 2690 | F: drivers/net/e1000e/ |
2691 | F: drivers/net/igb/ | 2691 | F: drivers/net/igb/ |
2692 | F: drivers/net/ixgb/ | 2692 | F: drivers/net/ixgb/ |
2693 | F: drivers/net/ixgbe/ | 2693 | F: drivers/net/ixgbe/ |
2694 | 2694 | ||
2695 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT | 2695 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT |
2696 | M: Zhu Yi <yi.zhu@intel.com> | 2696 | M: Zhu Yi <yi.zhu@intel.com> |
2697 | M: Reinette Chatre <reinette.chatre@intel.com> | 2697 | M: Reinette Chatre <reinette.chatre@intel.com> |
2698 | M: Intel Linux Wireless <ilw@linux.intel.com> | 2698 | M: Intel Linux Wireless <ilw@linux.intel.com> |
2699 | L: linux-wireless@vger.kernel.org | 2699 | L: linux-wireless@vger.kernel.org |
2700 | W: http://ipw2100.sourceforge.net | 2700 | W: http://ipw2100.sourceforge.net |
2701 | S: Odd Fixes | 2701 | S: Odd Fixes |
2702 | F: Documentation/networking/README.ipw2100 | 2702 | F: Documentation/networking/README.ipw2100 |
2703 | F: drivers/net/wireless/ipw2x00/ipw2100.* | 2703 | F: drivers/net/wireless/ipw2x00/ipw2100.* |
2704 | 2704 | ||
2705 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT | 2705 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT |
2706 | M: Zhu Yi <yi.zhu@intel.com> | 2706 | M: Zhu Yi <yi.zhu@intel.com> |
2707 | M: Reinette Chatre <reinette.chatre@intel.com> | 2707 | M: Reinette Chatre <reinette.chatre@intel.com> |
2708 | M: Intel Linux Wireless <ilw@linux.intel.com> | 2708 | M: Intel Linux Wireless <ilw@linux.intel.com> |
2709 | L: linux-wireless@vger.kernel.org | 2709 | L: linux-wireless@vger.kernel.org |
2710 | W: http://ipw2200.sourceforge.net | 2710 | W: http://ipw2200.sourceforge.net |
2711 | S: Odd Fixes | 2711 | S: Odd Fixes |
2712 | F: Documentation/networking/README.ipw2200 | 2712 | F: Documentation/networking/README.ipw2200 |
2713 | F: drivers/net/wireless/ipw2x00/ipw2200.* | 2713 | F: drivers/net/wireless/ipw2x00/ipw2200.* |
2714 | 2714 | ||
2715 | INTEL WIRELESS WIMAX CONNECTION 2400 | 2715 | INTEL WIRELESS WIMAX CONNECTION 2400 |
2716 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 2716 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
2717 | M: linux-wimax@intel.com | 2717 | M: linux-wimax@intel.com |
2718 | L: wimax@linuxwimax.org | 2718 | L: wimax@linuxwimax.org |
2719 | S: Supported | 2719 | S: Supported |
2720 | W: http://linuxwimax.org | 2720 | W: http://linuxwimax.org |
2721 | F: Documentation/wimax/README.i2400m | 2721 | F: Documentation/wimax/README.i2400m |
2722 | F: drivers/net/wimax/i2400m/ | 2722 | F: drivers/net/wimax/i2400m/ |
2723 | F: include/linux/wimax/i2400m.h | 2723 | F: include/linux/wimax/i2400m.h |
2724 | 2724 | ||
2725 | INTEL WIRELESS WIFI LINK (iwlwifi) | 2725 | INTEL WIRELESS WIFI LINK (iwlwifi) |
2726 | M: Zhu Yi <yi.zhu@intel.com> | 2726 | M: Zhu Yi <yi.zhu@intel.com> |
2727 | M: Reinette Chatre <reinette.chatre@intel.com> | 2727 | M: Reinette Chatre <reinette.chatre@intel.com> |
2728 | M: Intel Linux Wireless <ilw@linux.intel.com> | 2728 | M: Intel Linux Wireless <ilw@linux.intel.com> |
2729 | L: linux-wireless@vger.kernel.org | 2729 | L: linux-wireless@vger.kernel.org |
2730 | W: http://intellinuxwireless.org | 2730 | W: http://intellinuxwireless.org |
2731 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git | 2731 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git |
2732 | S: Supported | 2732 | S: Supported |
2733 | F: drivers/net/wireless/iwlwifi/ | 2733 | F: drivers/net/wireless/iwlwifi/ |
2734 | 2734 | ||
2735 | IOC3 ETHERNET DRIVER | 2735 | IOC3 ETHERNET DRIVER |
2736 | M: Ralf Baechle <ralf@linux-mips.org> | 2736 | M: Ralf Baechle <ralf@linux-mips.org> |
2737 | L: linux-mips@linux-mips.org | 2737 | L: linux-mips@linux-mips.org |
2738 | S: Maintained | 2738 | S: Maintained |
2739 | F: drivers/net/ioc3-eth.c | 2739 | F: drivers/net/ioc3-eth.c |
2740 | 2740 | ||
2741 | IOC3 SERIAL DRIVER | 2741 | IOC3 SERIAL DRIVER |
2742 | M: Pat Gefre <pfg@sgi.com> | 2742 | M: Pat Gefre <pfg@sgi.com> |
2743 | L: linux-mips@linux-mips.org | 2743 | L: linux-mips@linux-mips.org |
2744 | S: Maintained | 2744 | S: Maintained |
2745 | F: drivers/serial/ioc3_serial.c | 2745 | F: drivers/serial/ioc3_serial.c |
2746 | 2746 | ||
2747 | IP MASQUERADING | 2747 | IP MASQUERADING |
2748 | M: Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar> | 2748 | M: Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar> |
2749 | S: Maintained | 2749 | S: Maintained |
2750 | F: net/ipv4/netfilter/ipt_MASQUERADE.c | 2750 | F: net/ipv4/netfilter/ipt_MASQUERADE.c |
2751 | 2751 | ||
2752 | IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER | 2752 | IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER |
2753 | M: Francois Romieu <romieu@fr.zoreil.com> | 2753 | M: Francois Romieu <romieu@fr.zoreil.com> |
2754 | M: Sorbica Shieh <sorbica@icplus.com.tw> | 2754 | M: Sorbica Shieh <sorbica@icplus.com.tw> |
2755 | M: Jesse Huang <jesse@icplus.com.tw> | 2755 | M: Jesse Huang <jesse@icplus.com.tw> |
2756 | L: netdev@vger.kernel.org | 2756 | L: netdev@vger.kernel.org |
2757 | S: Maintained | 2757 | S: Maintained |
2758 | F: drivers/net/ipg.c | 2758 | F: drivers/net/ipg.c |
2759 | 2759 | ||
2760 | IPATH DRIVER | 2760 | IPATH DRIVER |
2761 | M: Ralph Campbell <infinipath@qlogic.com> | 2761 | M: Ralph Campbell <infinipath@qlogic.com> |
2762 | L: linux-rdma@vger.kernel.org | 2762 | L: linux-rdma@vger.kernel.org |
2763 | T: git git://git.qlogic.com/ipath-linux-2.6 | 2763 | T: git git://git.qlogic.com/ipath-linux-2.6 |
2764 | S: Supported | 2764 | S: Supported |
2765 | F: drivers/infiniband/hw/ipath/ | 2765 | F: drivers/infiniband/hw/ipath/ |
2766 | 2766 | ||
2767 | IPMI SUBSYSTEM | 2767 | IPMI SUBSYSTEM |
2768 | M: Corey Minyard <minyard@acm.org> | 2768 | M: Corey Minyard <minyard@acm.org> |
2769 | L: openipmi-developer@lists.sourceforge.net | 2769 | L: openipmi-developer@lists.sourceforge.net |
2770 | W: http://openipmi.sourceforge.net/ | 2770 | W: http://openipmi.sourceforge.net/ |
2771 | S: Supported | 2771 | S: Supported |
2772 | F: Documentation/IPMI.txt | 2772 | F: Documentation/IPMI.txt |
2773 | F: drivers/char/ipmi/ | 2773 | F: drivers/char/ipmi/ |
2774 | F: include/linux/ipmi* | 2774 | F: include/linux/ipmi* |
2775 | 2775 | ||
2776 | IPS SCSI RAID DRIVER | 2776 | IPS SCSI RAID DRIVER |
2777 | M: Adaptec OEM Raid Solutions <aacraid@adaptec.com> | 2777 | M: Adaptec OEM Raid Solutions <aacraid@adaptec.com> |
2778 | L: linux-scsi@vger.kernel.org | 2778 | L: linux-scsi@vger.kernel.org |
2779 | W: http://www.adaptec.com/ | 2779 | W: http://www.adaptec.com/ |
2780 | S: Maintained | 2780 | S: Maintained |
2781 | F: drivers/scsi/ips* | 2781 | F: drivers/scsi/ips* |
2782 | 2782 | ||
2783 | IPVS | 2783 | IPVS |
2784 | M: Wensong Zhang <wensong@linux-vs.org> | 2784 | M: Wensong Zhang <wensong@linux-vs.org> |
2785 | M: Simon Horman <horms@verge.net.au> | 2785 | M: Simon Horman <horms@verge.net.au> |
2786 | M: Julian Anastasov <ja@ssi.bg> | 2786 | M: Julian Anastasov <ja@ssi.bg> |
2787 | L: netdev@vger.kernel.org | 2787 | L: netdev@vger.kernel.org |
2788 | L: lvs-devel@vger.kernel.org | 2788 | L: lvs-devel@vger.kernel.org |
2789 | S: Maintained | 2789 | S: Maintained |
2790 | F: Documentation/networking/ipvs-sysctl.txt | 2790 | F: Documentation/networking/ipvs-sysctl.txt |
2791 | F: net/netfilter/ipvs/ | 2791 | F: net/netfilter/ipvs/ |
2792 | 2792 | ||
2793 | IPWIRELESS DRIVER | 2793 | IPWIRELESS DRIVER |
2794 | M: Jiri Kosina <jkosina@suse.cz> | 2794 | M: Jiri Kosina <jkosina@suse.cz> |
2795 | M: David Sterba <dsterba@suse.cz> | 2795 | M: David Sterba <dsterba@suse.cz> |
2796 | S: Maintained | 2796 | S: Maintained |
2797 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/ipwireless_cs.git | 2797 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/ipwireless_cs.git |
2798 | F: drivers/char/pcmcia/ipwireless/ | 2798 | F: drivers/char/pcmcia/ipwireless/ |
2799 | 2799 | ||
2800 | IPX NETWORK LAYER | 2800 | IPX NETWORK LAYER |
2801 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2801 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
2802 | L: netdev@vger.kernel.org | 2802 | L: netdev@vger.kernel.org |
2803 | S: Maintained | 2803 | S: Maintained |
2804 | F: include/linux/ipx.h | 2804 | F: include/linux/ipx.h |
2805 | F: include/net/ipx.h | 2805 | F: include/net/ipx.h |
2806 | F: net/ipx/ | 2806 | F: net/ipx/ |
2807 | 2807 | ||
2808 | IRDA SUBSYSTEM | 2808 | IRDA SUBSYSTEM |
2809 | M: Samuel Ortiz <samuel@sortiz.org> | 2809 | M: Samuel Ortiz <samuel@sortiz.org> |
2810 | L: irda-users@lists.sourceforge.net (subscribers-only) | 2810 | L: irda-users@lists.sourceforge.net (subscribers-only) |
2811 | W: http://irda.sourceforge.net/ | 2811 | W: http://irda.sourceforge.net/ |
2812 | S: Maintained | 2812 | S: Maintained |
2813 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git | 2813 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git |
2814 | F: Documentation/networking/irda.txt | 2814 | F: Documentation/networking/irda.txt |
2815 | F: drivers/net/irda/ | 2815 | F: drivers/net/irda/ |
2816 | F: include/net/irda/ | 2816 | F: include/net/irda/ |
2817 | F: net/irda/ | 2817 | F: net/irda/ |
2818 | 2818 | ||
2819 | ISAPNP | 2819 | ISAPNP |
2820 | M: Jaroslav Kysela <perex@perex.cz> | 2820 | M: Jaroslav Kysela <perex@perex.cz> |
2821 | S: Maintained | 2821 | S: Maintained |
2822 | F: Documentation/isapnp.txt | 2822 | F: Documentation/isapnp.txt |
2823 | F: drivers/pnp/isapnp/ | 2823 | F: drivers/pnp/isapnp/ |
2824 | F: include/linux/isapnp.h | 2824 | F: include/linux/isapnp.h |
2825 | 2825 | ||
2826 | ISCSI | 2826 | ISCSI |
2827 | M: Mike Christie <michaelc@cs.wisc.edu> | 2827 | M: Mike Christie <michaelc@cs.wisc.edu> |
2828 | L: open-iscsi@googlegroups.com | 2828 | L: open-iscsi@googlegroups.com |
2829 | W: www.open-iscsi.org | 2829 | W: www.open-iscsi.org |
2830 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mnc/linux-2.6-iscsi.git | 2830 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mnc/linux-2.6-iscsi.git |
2831 | S: Maintained | 2831 | S: Maintained |
2832 | F: drivers/scsi/*iscsi* | 2832 | F: drivers/scsi/*iscsi* |
2833 | F: include/scsi/*iscsi* | 2833 | F: include/scsi/*iscsi* |
2834 | 2834 | ||
2835 | ISDN SUBSYSTEM | 2835 | ISDN SUBSYSTEM |
2836 | M: Karsten Keil <isdn@linux-pingi.de> | 2836 | M: Karsten Keil <isdn@linux-pingi.de> |
2837 | L: isdn4linux@listserv.isdn4linux.de (subscribers-only) | 2837 | L: isdn4linux@listserv.isdn4linux.de (subscribers-only) |
2838 | W: http://www.isdn4linux.de | 2838 | W: http://www.isdn4linux.de |
2839 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git | 2839 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git |
2840 | S: Maintained | 2840 | S: Maintained |
2841 | F: Documentation/isdn/ | 2841 | F: Documentation/isdn/ |
2842 | F: drivers/isdn/ | 2842 | F: drivers/isdn/ |
2843 | F: include/linux/isdn.h | 2843 | F: include/linux/isdn.h |
2844 | F: include/linux/isdn/ | 2844 | F: include/linux/isdn/ |
2845 | 2845 | ||
2846 | ISDN SUBSYSTEM (Eicon active card driver) | 2846 | ISDN SUBSYSTEM (Eicon active card driver) |
2847 | M: Armin Schindler <mac@melware.de> | 2847 | M: Armin Schindler <mac@melware.de> |
2848 | L: isdn4linux@listserv.isdn4linux.de (subscribers-only) | 2848 | L: isdn4linux@listserv.isdn4linux.de (subscribers-only) |
2849 | W: http://www.melware.de | 2849 | W: http://www.melware.de |
2850 | S: Maintained | 2850 | S: Maintained |
2851 | F: drivers/isdn/hardware/eicon/ | 2851 | F: drivers/isdn/hardware/eicon/ |
2852 | 2852 | ||
2853 | IVTV VIDEO4LINUX DRIVER | 2853 | IVTV VIDEO4LINUX DRIVER |
2854 | M: Hans Verkuil <hverkuil@xs4all.nl> | 2854 | M: Hans Verkuil <hverkuil@xs4all.nl> |
2855 | L: ivtv-devel@ivtvdriver.org | 2855 | L: ivtv-devel@ivtvdriver.org |
2856 | L: linux-media@vger.kernel.org | 2856 | L: linux-media@vger.kernel.org |
2857 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 2857 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
2858 | W: http://www.ivtvdriver.org | 2858 | W: http://www.ivtvdriver.org |
2859 | S: Maintained | 2859 | S: Maintained |
2860 | F: Documentation/video4linux/*.ivtv | 2860 | F: Documentation/video4linux/*.ivtv |
2861 | F: drivers/media/video/ivtv/ | 2861 | F: drivers/media/video/ivtv/ |
2862 | F: include/linux/ivtv* | 2862 | F: include/linux/ivtv* |
2863 | 2863 | ||
2864 | JFS FILESYSTEM | 2864 | JFS FILESYSTEM |
2865 | M: Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2865 | M: Dave Kleikamp <shaggy@linux.vnet.ibm.com> |
2866 | L: jfs-discussion@lists.sourceforge.net | 2866 | L: jfs-discussion@lists.sourceforge.net |
2867 | W: http://jfs.sourceforge.net/ | 2867 | W: http://jfs.sourceforge.net/ |
2868 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git | 2868 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git |
2869 | S: Maintained | 2869 | S: Maintained |
2870 | F: Documentation/filesystems/jfs.txt | 2870 | F: Documentation/filesystems/jfs.txt |
2871 | F: fs/jfs/ | 2871 | F: fs/jfs/ |
2872 | 2872 | ||
2873 | JME NETWORK DRIVER | 2873 | JME NETWORK DRIVER |
2874 | M: Guo-Fu Tseng <cooldavid@cooldavid.org> | 2874 | M: Guo-Fu Tseng <cooldavid@cooldavid.org> |
2875 | L: netdev@vger.kernel.org | 2875 | L: netdev@vger.kernel.org |
2876 | S: Maintained | 2876 | S: Maintained |
2877 | F: drivers/net/jme.* | 2877 | F: drivers/net/jme.* |
2878 | 2878 | ||
2879 | JOURNALLING FLASH FILE SYSTEM V2 (JFFS2) | 2879 | JOURNALLING FLASH FILE SYSTEM V2 (JFFS2) |
2880 | M: David Woodhouse <dwmw2@infradead.org> | 2880 | M: David Woodhouse <dwmw2@infradead.org> |
2881 | L: linux-mtd@lists.infradead.org | 2881 | L: linux-mtd@lists.infradead.org |
2882 | W: http://www.linux-mtd.infradead.org/doc/jffs2.html | 2882 | W: http://www.linux-mtd.infradead.org/doc/jffs2.html |
2883 | S: Maintained | 2883 | S: Maintained |
2884 | F: fs/jffs2/ | 2884 | F: fs/jffs2/ |
2885 | F: include/linux/jffs2.h | 2885 | F: include/linux/jffs2.h |
2886 | 2886 | ||
2887 | JOURNALLING LAYER FOR BLOCK DEVICES (JBD) | 2887 | JOURNALLING LAYER FOR BLOCK DEVICES (JBD) |
2888 | M: Stephen Tweedie <sct@redhat.com> | 2888 | M: Stephen Tweedie <sct@redhat.com> |
2889 | M: Andrew Morton <akpm@linux-foundation.org> | 2889 | M: Andrew Morton <akpm@linux-foundation.org> |
2890 | L: linux-ext4@vger.kernel.org | 2890 | L: linux-ext4@vger.kernel.org |
2891 | S: Maintained | 2891 | S: Maintained |
2892 | F: fs/jbd*/ | 2892 | F: fs/jbd*/ |
2893 | F: include/linux/ext*jbd*.h | 2893 | F: include/linux/ext*jbd*.h |
2894 | F: include/linux/jbd*.h | 2894 | F: include/linux/jbd*.h |
2895 | 2895 | ||
2896 | K8TEMP HARDWARE MONITORING DRIVER | 2896 | K8TEMP HARDWARE MONITORING DRIVER |
2897 | M: Rudolf Marek <r.marek@assembler.cz> | 2897 | M: Rudolf Marek <r.marek@assembler.cz> |
2898 | L: lm-sensors@lm-sensors.org | 2898 | L: lm-sensors@lm-sensors.org |
2899 | S: Maintained | 2899 | S: Maintained |
2900 | F: Documentation/hwmon/k8temp | 2900 | F: Documentation/hwmon/k8temp |
2901 | F: drivers/hwmon/k8temp.c | 2901 | F: drivers/hwmon/k8temp.c |
2902 | 2902 | ||
2903 | KCONFIG | 2903 | KCONFIG |
2904 | M: Roman Zippel <zippel@linux-m68k.org> | 2904 | M: Roman Zippel <zippel@linux-m68k.org> |
2905 | L: linux-kbuild@vger.kernel.org | 2905 | L: linux-kbuild@vger.kernel.org |
2906 | S: Maintained | 2906 | S: Maintained |
2907 | F: Documentation/kbuild/kconfig-language.txt | 2907 | F: Documentation/kbuild/kconfig-language.txt |
2908 | F: scripts/kconfig/ | 2908 | F: scripts/kconfig/ |
2909 | 2909 | ||
2910 | KDUMP | 2910 | KDUMP |
2911 | M: Vivek Goyal <vgoyal@redhat.com> | 2911 | M: Vivek Goyal <vgoyal@redhat.com> |
2912 | M: Haren Myneni <hbabu@us.ibm.com> | 2912 | M: Haren Myneni <hbabu@us.ibm.com> |
2913 | L: kexec@lists.infradead.org | 2913 | L: kexec@lists.infradead.org |
2914 | W: http://lse.sourceforge.net/kdump/ | 2914 | W: http://lse.sourceforge.net/kdump/ |
2915 | S: Maintained | 2915 | S: Maintained |
2916 | F: Documentation/kdump/ | 2916 | F: Documentation/kdump/ |
2917 | 2917 | ||
2918 | KERNEL AUTOMOUNTER (AUTOFS) | 2918 | KERNEL AUTOMOUNTER (AUTOFS) |
2919 | M: "H. Peter Anvin" <hpa@zytor.com> | 2919 | M: "H. Peter Anvin" <hpa@zytor.com> |
2920 | L: autofs@linux.kernel.org | 2920 | L: autofs@linux.kernel.org |
2921 | S: Odd Fixes | 2921 | S: Odd Fixes |
2922 | F: fs/autofs/ | 2922 | F: fs/autofs/ |
2923 | 2923 | ||
2924 | KERNEL AUTOMOUNTER v4 (AUTOFS4) | 2924 | KERNEL AUTOMOUNTER v4 (AUTOFS4) |
2925 | M: Ian Kent <raven@themaw.net> | 2925 | M: Ian Kent <raven@themaw.net> |
2926 | L: autofs@linux.kernel.org | 2926 | L: autofs@linux.kernel.org |
2927 | S: Maintained | 2927 | S: Maintained |
2928 | F: fs/autofs4/ | 2928 | F: fs/autofs4/ |
2929 | 2929 | ||
2930 | KERNEL BUILD | 2930 | KERNEL BUILD |
2931 | M: Sam Ravnborg <sam@ravnborg.org> | 2931 | M: Sam Ravnborg <sam@ravnborg.org> |
2932 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git | 2932 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git |
2933 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git | 2933 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git |
2934 | L: linux-kbuild@vger.kernel.org | 2934 | L: linux-kbuild@vger.kernel.org |
2935 | S: Maintained | 2935 | S: Maintained |
2936 | F: Documentation/kbuild/ | 2936 | F: Documentation/kbuild/ |
2937 | F: Makefile | 2937 | F: Makefile |
2938 | F: scripts/Makefile.* | 2938 | F: scripts/Makefile.* |
2939 | 2939 | ||
2940 | KERNEL JANITORS | 2940 | KERNEL JANITORS |
2941 | L: kernel-janitors@vger.kernel.org | 2941 | L: kernel-janitors@vger.kernel.org |
2942 | W: http://www.kerneljanitors.org/ | 2942 | W: http://www.kerneljanitors.org/ |
2943 | S: Odd fixes | 2943 | S: Odd fixes |
2944 | 2944 | ||
2945 | KERNEL NFSD, SUNRPC, AND LOCKD SERVERS | 2945 | KERNEL NFSD, SUNRPC, AND LOCKD SERVERS |
2946 | M: "J. Bruce Fields" <bfields@fieldses.org> | 2946 | M: "J. Bruce Fields" <bfields@fieldses.org> |
2947 | M: Neil Brown <neilb@suse.de> | 2947 | M: Neil Brown <neilb@suse.de> |
2948 | L: linux-nfs@vger.kernel.org | 2948 | L: linux-nfs@vger.kernel.org |
2949 | W: http://nfs.sourceforge.net/ | 2949 | W: http://nfs.sourceforge.net/ |
2950 | S: Supported | 2950 | S: Supported |
2951 | F: fs/nfsd/ | 2951 | F: fs/nfsd/ |
2952 | F: include/linux/nfsd/ | 2952 | F: include/linux/nfsd/ |
2953 | F: fs/lockd/ | 2953 | F: fs/lockd/ |
2954 | F: fs/nfs_common/ | 2954 | F: fs/nfs_common/ |
2955 | F: net/sunrpc/ | 2955 | F: net/sunrpc/ |
2956 | F: include/linux/lockd/ | 2956 | F: include/linux/lockd/ |
2957 | F: include/linux/sunrpc/ | 2957 | F: include/linux/sunrpc/ |
2958 | 2958 | ||
2959 | KERNEL VIRTUAL MACHINE (KVM) | 2959 | KERNEL VIRTUAL MACHINE (KVM) |
2960 | M: Avi Kivity <avi@redhat.com> | 2960 | M: Avi Kivity <avi@redhat.com> |
2961 | M: Marcelo Tosatti <mtosatti@redhat.com> | 2961 | M: Marcelo Tosatti <mtosatti@redhat.com> |
2962 | L: kvm@vger.kernel.org | 2962 | L: kvm@vger.kernel.org |
2963 | W: http://kvm.qumranet.com | 2963 | W: http://kvm.qumranet.com |
2964 | S: Supported | 2964 | S: Supported |
2965 | F: Documentation/*/kvm.txt | 2965 | F: Documentation/*/kvm.txt |
2966 | F: arch/*/kvm/ | 2966 | F: arch/*/kvm/ |
2967 | F: arch/*/include/asm/kvm* | 2967 | F: arch/*/include/asm/kvm* |
2968 | F: include/linux/kvm* | 2968 | F: include/linux/kvm* |
2969 | F: virt/kvm/ | 2969 | F: virt/kvm/ |
2970 | 2970 | ||
2971 | KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V | 2971 | KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V |
2972 | M: Joerg Roedel <joerg.roedel@amd.com> | 2972 | M: Joerg Roedel <joerg.roedel@amd.com> |
2973 | L: kvm@vger.kernel.org | 2973 | L: kvm@vger.kernel.org |
2974 | W: http://kvm.qumranet.com | 2974 | W: http://kvm.qumranet.com |
2975 | S: Supported | 2975 | S: Supported |
2976 | F: arch/x86/include/asm/svm.h | 2976 | F: arch/x86/include/asm/svm.h |
2977 | F: arch/x86/kvm/kvm_svm.h | 2977 | F: arch/x86/kvm/kvm_svm.h |
2978 | F: arch/x86/kvm/svm.c | 2978 | F: arch/x86/kvm/svm.c |
2979 | 2979 | ||
2980 | KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC | 2980 | KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC |
2981 | M: Hollis Blanchard <hollisb@us.ibm.com> | 2981 | M: Hollis Blanchard <hollisb@us.ibm.com> |
2982 | L: kvm-ppc@vger.kernel.org | 2982 | L: kvm-ppc@vger.kernel.org |
2983 | W: http://kvm.qumranet.com | 2983 | W: http://kvm.qumranet.com |
2984 | S: Supported | 2984 | S: Supported |
2985 | F: arch/powerpc/include/asm/kvm* | 2985 | F: arch/powerpc/include/asm/kvm* |
2986 | F: arch/powerpc/kvm/ | 2986 | F: arch/powerpc/kvm/ |
2987 | 2987 | ||
2988 | KERNEL VIRTUAL MACHINE For Itanium (KVM/IA64) | 2988 | KERNEL VIRTUAL MACHINE For Itanium (KVM/IA64) |
2989 | M: Xiantao Zhang <xiantao.zhang@intel.com> | 2989 | M: Xiantao Zhang <xiantao.zhang@intel.com> |
2990 | L: kvm-ia64@vger.kernel.org | 2990 | L: kvm-ia64@vger.kernel.org |
2991 | W: http://kvm.qumranet.com | 2991 | W: http://kvm.qumranet.com |
2992 | S: Supported | 2992 | S: Supported |
2993 | F: Documentation/ia64/kvm.txt | 2993 | F: Documentation/ia64/kvm.txt |
2994 | F: arch/ia64/include/asm/kvm* | 2994 | F: arch/ia64/include/asm/kvm* |
2995 | F: arch/ia64/kvm/ | 2995 | F: arch/ia64/kvm/ |
2996 | 2996 | ||
2997 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) | 2997 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) |
2998 | M: Carsten Otte <cotte@de.ibm.com> | 2998 | M: Carsten Otte <cotte@de.ibm.com> |
2999 | M: Christian Borntraeger <borntraeger@de.ibm.com> | 2999 | M: Christian Borntraeger <borntraeger@de.ibm.com> |
3000 | M: linux390@de.ibm.com | 3000 | M: linux390@de.ibm.com |
3001 | L: linux-s390@vger.kernel.org | 3001 | L: linux-s390@vger.kernel.org |
3002 | W: http://www.ibm.com/developerworks/linux/linux390/ | 3002 | W: http://www.ibm.com/developerworks/linux/linux390/ |
3003 | S: Supported | 3003 | S: Supported |
3004 | F: Documentation/s390/kvm.txt | 3004 | F: Documentation/s390/kvm.txt |
3005 | F: arch/s390/include/asm/kvm* | 3005 | F: arch/s390/include/asm/kvm* |
3006 | F: arch/s390/kvm/ | 3006 | F: arch/s390/kvm/ |
3007 | 3007 | ||
3008 | KEXEC | 3008 | KEXEC |
3009 | M: Eric Biederman <ebiederm@xmission.com> | 3009 | M: Eric Biederman <ebiederm@xmission.com> |
3010 | W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ | 3010 | W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ |
3011 | L: kexec@lists.infradead.org | 3011 | L: kexec@lists.infradead.org |
3012 | S: Maintained | 3012 | S: Maintained |
3013 | F: include/linux/kexec.h | 3013 | F: include/linux/kexec.h |
3014 | F: kernel/kexec.c | 3014 | F: kernel/kexec.c |
3015 | 3015 | ||
3016 | KGDB | 3016 | KGDB |
3017 | M: Jason Wessel <jason.wessel@windriver.com> | 3017 | M: Jason Wessel <jason.wessel@windriver.com> |
3018 | L: kgdb-bugreport@lists.sourceforge.net | 3018 | L: kgdb-bugreport@lists.sourceforge.net |
3019 | S: Maintained | 3019 | S: Maintained |
3020 | F: Documentation/DocBook/kgdb.tmpl | 3020 | F: Documentation/DocBook/kgdb.tmpl |
3021 | F: drivers/misc/kgdbts.c | 3021 | F: drivers/misc/kgdbts.c |
3022 | F: drivers/serial/kgdboc.c | 3022 | F: drivers/serial/kgdboc.c |
3023 | F: include/linux/kgdb.h | 3023 | F: include/linux/kgdb.h |
3024 | F: kernel/kgdb.c | 3024 | F: kernel/kgdb.c |
3025 | 3025 | ||
3026 | KMEMCHECK | 3026 | KMEMCHECK |
3027 | M: Vegard Nossum <vegardno@ifi.uio.no> | 3027 | M: Vegard Nossum <vegardno@ifi.uio.no> |
3028 | P Pekka Enberg | 3028 | P Pekka Enberg |
3029 | M: penberg@cs.helsinki.fi | 3029 | M: penberg@cs.helsinki.fi |
3030 | S: Maintained | 3030 | S: Maintained |
3031 | 3031 | ||
3032 | KMEMLEAK | 3032 | KMEMLEAK |
3033 | M: Catalin Marinas <catalin.marinas@arm.com> | 3033 | M: Catalin Marinas <catalin.marinas@arm.com> |
3034 | S: Maintained | 3034 | S: Maintained |
3035 | F: Documentation/kmemleak.txt | 3035 | F: Documentation/kmemleak.txt |
3036 | F: include/linux/kmemleak.h | 3036 | F: include/linux/kmemleak.h |
3037 | F: mm/kmemleak.c | 3037 | F: mm/kmemleak.c |
3038 | F: mm/kmemleak-test.c | 3038 | F: mm/kmemleak-test.c |
3039 | 3039 | ||
3040 | KMEMTRACE | 3040 | KMEMTRACE |
3041 | M: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro> | 3041 | M: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro> |
3042 | S: Maintained | 3042 | S: Maintained |
3043 | F: Documentation/trace/kmemtrace.txt | 3043 | F: Documentation/trace/kmemtrace.txt |
3044 | F: include/linux/kmemtrace.h | 3044 | F: include/linux/kmemtrace.h |
3045 | F: kernel/trace/kmemtrace.c | 3045 | F: kernel/trace/kmemtrace.c |
3046 | 3046 | ||
3047 | KPROBES | 3047 | KPROBES |
3048 | M: Ananth N Mavinakayanahalli <ananth@in.ibm.com> | 3048 | M: Ananth N Mavinakayanahalli <ananth@in.ibm.com> |
3049 | M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> | 3049 | M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> |
3050 | M: "David S. Miller" <davem@davemloft.net> | 3050 | M: "David S. Miller" <davem@davemloft.net> |
3051 | M: Masami Hiramatsu <mhiramat@redhat.com> | 3051 | M: Masami Hiramatsu <mhiramat@redhat.com> |
3052 | S: Maintained | 3052 | S: Maintained |
3053 | F: Documentation/kprobes.txt | 3053 | F: Documentation/kprobes.txt |
3054 | F: include/linux/kprobes.h | 3054 | F: include/linux/kprobes.h |
3055 | F: kernel/kprobes.c | 3055 | F: kernel/kprobes.c |
3056 | 3056 | ||
3057 | KS0108 LCD CONTROLLER DRIVER | 3057 | KS0108 LCD CONTROLLER DRIVER |
3058 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> | 3058 | M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> |
3059 | W: http://miguelojeda.es/auxdisplay.htm | 3059 | W: http://miguelojeda.es/auxdisplay.htm |
3060 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 3060 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
3061 | S: Maintained | 3061 | S: Maintained |
3062 | F: Documentation/auxdisplay/ks0108 | 3062 | F: Documentation/auxdisplay/ks0108 |
3063 | F: drivers/auxdisplay/ks0108.c | 3063 | F: drivers/auxdisplay/ks0108.c |
3064 | F: include/linux/ks0108.h | 3064 | F: include/linux/ks0108.h |
3065 | 3065 | ||
3066 | LAPB module | 3066 | LAPB module |
3067 | L: linux-x25@vger.kernel.org | 3067 | L: linux-x25@vger.kernel.org |
3068 | S: Orphan | 3068 | S: Orphan |
3069 | F: Documentation/networking/lapb-module.txt | 3069 | F: Documentation/networking/lapb-module.txt |
3070 | F: include/*/lapb.h | 3070 | F: include/*/lapb.h |
3071 | F: net/lapb/ | 3071 | F: net/lapb/ |
3072 | 3072 | ||
3073 | LASI 53c700 driver for PARISC | 3073 | LASI 53c700 driver for PARISC |
3074 | M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> | 3074 | M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> |
3075 | L: linux-scsi@vger.kernel.org | 3075 | L: linux-scsi@vger.kernel.org |
3076 | S: Maintained | 3076 | S: Maintained |
3077 | F: Documentation/scsi/53c700.txt | 3077 | F: Documentation/scsi/53c700.txt |
3078 | F: drivers/scsi/53c700* | 3078 | F: drivers/scsi/53c700* |
3079 | 3079 | ||
3080 | LED SUBSYSTEM | 3080 | LED SUBSYSTEM |
3081 | M: Richard Purdie <rpurdie@rpsys.net> | 3081 | M: Richard Purdie <rpurdie@rpsys.net> |
3082 | S: Maintained | 3082 | S: Maintained |
3083 | F: drivers/leds/ | 3083 | F: drivers/leds/ |
3084 | F: include/linux/leds.h | 3084 | F: include/linux/leds.h |
3085 | 3085 | ||
3086 | LEGO USB Tower driver | 3086 | LEGO USB Tower driver |
3087 | M: Juergen Stuber <starblue@users.sourceforge.net> | 3087 | M: Juergen Stuber <starblue@users.sourceforge.net> |
3088 | L: legousb-devel@lists.sourceforge.net | 3088 | L: legousb-devel@lists.sourceforge.net |
3089 | W: http://legousb.sourceforge.net/ | 3089 | W: http://legousb.sourceforge.net/ |
3090 | S: Maintained | 3090 | S: Maintained |
3091 | F: drivers/usb/misc/legousbtower.c | 3091 | F: drivers/usb/misc/legousbtower.c |
3092 | 3092 | ||
3093 | LGUEST | 3093 | LGUEST |
3094 | M: Rusty Russell <rusty@rustcorp.com.au> | 3094 | M: Rusty Russell <rusty@rustcorp.com.au> |
3095 | L: lguest@ozlabs.org | 3095 | L: lguest@ozlabs.org |
3096 | W: http://lguest.ozlabs.org/ | 3096 | W: http://lguest.ozlabs.org/ |
3097 | S: Maintained | 3097 | S: Maintained |
3098 | F: Documentation/lguest/ | 3098 | F: Documentation/lguest/ |
3099 | F: arch/x86/lguest/ | 3099 | F: arch/x86/lguest/ |
3100 | F: drivers/lguest/ | 3100 | F: drivers/lguest/ |
3101 | F: include/linux/lguest*.h | 3101 | F: include/linux/lguest*.h |
3102 | F: arch/x86/include/asm/lguest*.h | 3102 | F: arch/x86/include/asm/lguest*.h |
3103 | 3103 | ||
3104 | LINUX FOR IBM pSERIES (RS/6000) | 3104 | LINUX FOR IBM pSERIES (RS/6000) |
3105 | M: Paul Mackerras <paulus@au.ibm.com> | 3105 | M: Paul Mackerras <paulus@au.ibm.com> |
3106 | W: http://www.ibm.com/linux/ltc/projects/ppc | 3106 | W: http://www.ibm.com/linux/ltc/projects/ppc |
3107 | S: Supported | 3107 | S: Supported |
3108 | 3108 | ||
3109 | LINUX FOR POWERPC (32-BIT AND 64-BIT) | 3109 | LINUX FOR POWERPC (32-BIT AND 64-BIT) |
3110 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 3110 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
3111 | M: Paul Mackerras <paulus@samba.org> | 3111 | M: Paul Mackerras <paulus@samba.org> |
3112 | W: http://www.penguinppc.org/ | 3112 | W: http://www.penguinppc.org/ |
3113 | L: linuxppc-dev@ozlabs.org | 3113 | L: linuxppc-dev@ozlabs.org |
3114 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git | 3114 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git |
3115 | S: Supported | 3115 | S: Supported |
3116 | 3116 | ||
3117 | LINUX FOR POWER MACINTOSH | 3117 | LINUX FOR POWER MACINTOSH |
3118 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 3118 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
3119 | W: http://www.penguinppc.org/ | 3119 | W: http://www.penguinppc.org/ |
3120 | L: linuxppc-dev@ozlabs.org | 3120 | L: linuxppc-dev@ozlabs.org |
3121 | S: Maintained | 3121 | S: Maintained |
3122 | 3122 | ||
3123 | LINUX FOR POWERPC EMBEDDED MPC5XXX | 3123 | LINUX FOR POWERPC EMBEDDED MPC5XXX |
3124 | M: Grant Likely <grant.likely@secretlab.ca> | 3124 | M: Grant Likely <grant.likely@secretlab.ca> |
3125 | L: linuxppc-dev@ozlabs.org | 3125 | L: linuxppc-dev@ozlabs.org |
3126 | T: git git://git.secretlab.ca/git/linux-2.6.git | 3126 | T: git git://git.secretlab.ca/git/linux-2.6.git |
3127 | S: Maintained | 3127 | S: Maintained |
3128 | 3128 | ||
3129 | LINUX FOR POWERPC EMBEDDED PPC4XX | 3129 | LINUX FOR POWERPC EMBEDDED PPC4XX |
3130 | M: Josh Boyer <jwboyer@linux.vnet.ibm.com> | 3130 | M: Josh Boyer <jwboyer@linux.vnet.ibm.com> |
3131 | M: Matt Porter <mporter@kernel.crashing.org> | 3131 | M: Matt Porter <mporter@kernel.crashing.org> |
3132 | W: http://www.penguinppc.org/ | 3132 | W: http://www.penguinppc.org/ |
3133 | L: linuxppc-dev@ozlabs.org | 3133 | L: linuxppc-dev@ozlabs.org |
3134 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git | 3134 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git |
3135 | S: Maintained | 3135 | S: Maintained |
3136 | 3136 | ||
3137 | LINUX FOR POWERPC EMBEDDED XILINX VIRTEX | 3137 | LINUX FOR POWERPC EMBEDDED XILINX VIRTEX |
3138 | M: Grant Likely <grant.likely@secretlab.ca> | 3138 | M: Grant Likely <grant.likely@secretlab.ca> |
3139 | W: http://wiki.secretlab.ca/index.php/Linux_on_Xilinx_Virtex | 3139 | W: http://wiki.secretlab.ca/index.php/Linux_on_Xilinx_Virtex |
3140 | L: linuxppc-dev@ozlabs.org | 3140 | L: linuxppc-dev@ozlabs.org |
3141 | T: git git://git.secretlab.ca/git/linux-2.6.git | 3141 | T: git git://git.secretlab.ca/git/linux-2.6.git |
3142 | S: Maintained | 3142 | S: Maintained |
3143 | 3143 | ||
3144 | LINUX FOR POWERPC EMBEDDED PPC8XX | 3144 | LINUX FOR POWERPC EMBEDDED PPC8XX |
3145 | M: Vitaly Bordug <vitb@kernel.crashing.org> | 3145 | M: Vitaly Bordug <vitb@kernel.crashing.org> |
3146 | M: Marcelo Tosatti <marcelo@kvack.org> | 3146 | M: Marcelo Tosatti <marcelo@kvack.org> |
3147 | W: http://www.penguinppc.org/ | 3147 | W: http://www.penguinppc.org/ |
3148 | L: linuxppc-dev@ozlabs.org | 3148 | L: linuxppc-dev@ozlabs.org |
3149 | S: Maintained | 3149 | S: Maintained |
3150 | 3150 | ||
3151 | LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX | 3151 | LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX |
3152 | M: Kumar Gala <galak@kernel.crashing.org> | 3152 | M: Kumar Gala <galak@kernel.crashing.org> |
3153 | W: http://www.penguinppc.org/ | 3153 | W: http://www.penguinppc.org/ |
3154 | L: linuxppc-dev@ozlabs.org | 3154 | L: linuxppc-dev@ozlabs.org |
3155 | S: Maintained | 3155 | S: Maintained |
3156 | 3156 | ||
3157 | LINUX FOR POWERPC PA SEMI PWRFICIENT | 3157 | LINUX FOR POWERPC PA SEMI PWRFICIENT |
3158 | M: Olof Johansson <olof@lixom.net> | 3158 | M: Olof Johansson <olof@lixom.net> |
3159 | W: http://www.pasemi.com/ | 3159 | W: http://www.pasemi.com/ |
3160 | L: linuxppc-dev@ozlabs.org | 3160 | L: linuxppc-dev@ozlabs.org |
3161 | S: Supported | 3161 | S: Supported |
3162 | 3162 | ||
3163 | LINUX SECURITY MODULE (LSM) FRAMEWORK | 3163 | LINUX SECURITY MODULE (LSM) FRAMEWORK |
3164 | M: Chris Wright <chrisw@sous-sol.org> | 3164 | M: Chris Wright <chrisw@sous-sol.org> |
3165 | L: linux-security-module@vger.kernel.org | 3165 | L: linux-security-module@vger.kernel.org |
3166 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/chrisw/lsm-2.6.git | 3166 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/chrisw/lsm-2.6.git |
3167 | S: Supported | 3167 | S: Supported |
3168 | 3168 | ||
3169 | LLC (802.2) | 3169 | LLC (802.2) |
3170 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 3170 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
3171 | S: Maintained | 3171 | S: Maintained |
3172 | F: include/linux/llc.h | 3172 | F: include/linux/llc.h |
3173 | F: include/net/llc* | 3173 | F: include/net/llc* |
3174 | F: net/llc/ | 3174 | F: net/llc/ |
3175 | 3175 | ||
3176 | LIS3LV02D ACCELEROMETER DRIVER | 3176 | LIS3LV02D ACCELEROMETER DRIVER |
3177 | M: Eric Piel <eric.piel@tremplin-utc.net> | 3177 | M: Eric Piel <eric.piel@tremplin-utc.net> |
3178 | S: Maintained | 3178 | S: Maintained |
3179 | F: Documentation/hwmon/lis3lv02d | 3179 | F: Documentation/hwmon/lis3lv02d |
3180 | F: drivers/hwmon/lis3lv02d.* | 3180 | F: drivers/hwmon/lis3lv02d.* |
3181 | 3181 | ||
3182 | LM83 HARDWARE MONITOR DRIVER | 3182 | LM83 HARDWARE MONITOR DRIVER |
3183 | M: Jean Delvare <khali@linux-fr.org> | 3183 | M: Jean Delvare <khali@linux-fr.org> |
3184 | L: lm-sensors@lm-sensors.org | 3184 | L: lm-sensors@lm-sensors.org |
3185 | S: Maintained | 3185 | S: Maintained |
3186 | F: Documentation/hwmon/lm83 | 3186 | F: Documentation/hwmon/lm83 |
3187 | F: drivers/hwmon/lm83.c | 3187 | F: drivers/hwmon/lm83.c |
3188 | 3188 | ||
3189 | LM90 HARDWARE MONITOR DRIVER | 3189 | LM90 HARDWARE MONITOR DRIVER |
3190 | M: Jean Delvare <khali@linux-fr.org> | 3190 | M: Jean Delvare <khali@linux-fr.org> |
3191 | L: lm-sensors@lm-sensors.org | 3191 | L: lm-sensors@lm-sensors.org |
3192 | S: Maintained | 3192 | S: Maintained |
3193 | F: Documentation/hwmon/lm90 | 3193 | F: Documentation/hwmon/lm90 |
3194 | F: drivers/hwmon/lm90.c | 3194 | F: drivers/hwmon/lm90.c |
3195 | 3195 | ||
3196 | LOCKDEP AND LOCKSTAT | 3196 | LOCKDEP AND LOCKSTAT |
3197 | M: Peter Zijlstra <peterz@infradead.org> | 3197 | M: Peter Zijlstra <peterz@infradead.org> |
3198 | M: Ingo Molnar <mingo@redhat.com> | 3198 | M: Ingo Molnar <mingo@redhat.com> |
3199 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git | 3199 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git |
3200 | S: Maintained | 3200 | S: Maintained |
3201 | F: Documentation/lockdep*.txt | 3201 | F: Documentation/lockdep*.txt |
3202 | F: Documentation/lockstat.txt | 3202 | F: Documentation/lockstat.txt |
3203 | F: include/linux/lockdep.h | 3203 | F: include/linux/lockdep.h |
3204 | F: kernel/lockdep* | 3204 | F: kernel/lockdep* |
3205 | 3205 | ||
3206 | LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks) | 3206 | LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks) |
3207 | M: "Richard Russon (FlatCap)" <ldm@flatcap.org> | 3207 | M: "Richard Russon (FlatCap)" <ldm@flatcap.org> |
3208 | L: linux-ntfs-dev@lists.sourceforge.net | 3208 | L: linux-ntfs-dev@lists.sourceforge.net |
3209 | W: http://www.linux-ntfs.org/content/view/19/37/ | 3209 | W: http://www.linux-ntfs.org/content/view/19/37/ |
3210 | S: Maintained | 3210 | S: Maintained |
3211 | F: Documentation/ldm.txt | 3211 | F: Documentation/ldm.txt |
3212 | F: fs/partitions/ldm.* | 3212 | F: fs/partitions/ldm.* |
3213 | 3213 | ||
3214 | LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) | 3214 | LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) |
3215 | M: Eric Moore <Eric.Moore@lsi.com> | 3215 | M: Eric Moore <Eric.Moore@lsi.com> |
3216 | M: support@lsi.com | 3216 | M: support@lsi.com |
3217 | L: DL-MPTFusionLinux@lsi.com | 3217 | L: DL-MPTFusionLinux@lsi.com |
3218 | L: linux-scsi@vger.kernel.org | 3218 | L: linux-scsi@vger.kernel.org |
3219 | W: http://www.lsilogic.com/support | 3219 | W: http://www.lsilogic.com/support |
3220 | S: Supported | 3220 | S: Supported |
3221 | F: drivers/message/fusion/ | 3221 | F: drivers/message/fusion/ |
3222 | 3222 | ||
3223 | LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers | 3223 | LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers |
3224 | M: Matthew Wilcox <matthew@wil.cx> | 3224 | M: Matthew Wilcox <matthew@wil.cx> |
3225 | L: linux-scsi@vger.kernel.org | 3225 | L: linux-scsi@vger.kernel.org |
3226 | S: Maintained | 3226 | S: Maintained |
3227 | F: drivers/scsi/sym53c8xx_2/ | 3227 | F: drivers/scsi/sym53c8xx_2/ |
3228 | 3228 | ||
3229 | LTP (Linux Test Project) | 3229 | LTP (Linux Test Project) |
3230 | M: Subrata Modak <subrata@linux.vnet.ibm.com> | 3230 | M: Subrata Modak <subrata@linux.vnet.ibm.com> |
3231 | M: Mike Frysinger <vapier@gentoo.org> | 3231 | M: Mike Frysinger <vapier@gentoo.org> |
3232 | L: ltp-list@lists.sourceforge.net (subscribers-only) | 3232 | L: ltp-list@lists.sourceforge.net (subscribers-only) |
3233 | W: http://ltp.sourceforge.net/ | 3233 | W: http://ltp.sourceforge.net/ |
3234 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git | 3234 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git |
3235 | S: Maintained | 3235 | S: Maintained |
3236 | 3236 | ||
3237 | M32R ARCHITECTURE | 3237 | M32R ARCHITECTURE |
3238 | M: Hirokazu Takata <takata@linux-m32r.org> | 3238 | M: Hirokazu Takata <takata@linux-m32r.org> |
3239 | L: linux-m32r@ml.linux-m32r.org | 3239 | L: linux-m32r@ml.linux-m32r.org |
3240 | L: linux-m32r-ja@ml.linux-m32r.org (in Japanese) | 3240 | L: linux-m32r-ja@ml.linux-m32r.org (in Japanese) |
3241 | W: http://www.linux-m32r.org/ | 3241 | W: http://www.linux-m32r.org/ |
3242 | S: Maintained | 3242 | S: Maintained |
3243 | F: arch/m32r/ | 3243 | F: arch/m32r/ |
3244 | 3244 | ||
3245 | M68K ARCHITECTURE | 3245 | M68K ARCHITECTURE |
3246 | M: Geert Uytterhoeven <geert@linux-m68k.org> | 3246 | M: Geert Uytterhoeven <geert@linux-m68k.org> |
3247 | M: Roman Zippel <zippel@linux-m68k.org> | 3247 | M: Roman Zippel <zippel@linux-m68k.org> |
3248 | L: linux-m68k@lists.linux-m68k.org | 3248 | L: linux-m68k@lists.linux-m68k.org |
3249 | W: http://www.linux-m68k.org/ | 3249 | W: http://www.linux-m68k.org/ |
3250 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git | 3250 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git |
3251 | S: Maintained | 3251 | S: Maintained |
3252 | F: arch/m68k/ | 3252 | F: arch/m68k/ |
3253 | F: drivers/zorro/ | 3253 | F: drivers/zorro/ |
3254 | 3254 | ||
3255 | M68K ON APPLE MACINTOSH | 3255 | M68K ON APPLE MACINTOSH |
3256 | M: Joshua Thompson <funaho@jurai.org> | 3256 | M: Joshua Thompson <funaho@jurai.org> |
3257 | W: http://www.mac.linux-m68k.org/ | 3257 | W: http://www.mac.linux-m68k.org/ |
3258 | L: linux-m68k@lists.linux-m68k.org | 3258 | L: linux-m68k@lists.linux-m68k.org |
3259 | S: Maintained | 3259 | S: Maintained |
3260 | F: arch/m68k/mac/ | 3260 | F: arch/m68k/mac/ |
3261 | 3261 | ||
3262 | M68K ON HP9000/300 | 3262 | M68K ON HP9000/300 |
3263 | M: Philip Blundell <philb@gnu.org> | 3263 | M: Philip Blundell <philb@gnu.org> |
3264 | W: http://www.tazenda.demon.co.uk/phil/linux-hp | 3264 | W: http://www.tazenda.demon.co.uk/phil/linux-hp |
3265 | S: Maintained | 3265 | S: Maintained |
3266 | F: arch/m68k/hp300/ | 3266 | F: arch/m68k/hp300/ |
3267 | 3267 | ||
3268 | MAC80211 | 3268 | MAC80211 |
3269 | M: Johannes Berg <johannes@sipsolutions.net> | 3269 | M: Johannes Berg <johannes@sipsolutions.net> |
3270 | L: linux-wireless@vger.kernel.org | 3270 | L: linux-wireless@vger.kernel.org |
3271 | W: http://linuxwireless.org/ | 3271 | W: http://linuxwireless.org/ |
3272 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git | 3272 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git |
3273 | S: Maintained | 3273 | S: Maintained |
3274 | F: Documentation/networking/mac80211-injection.txt | 3274 | F: Documentation/networking/mac80211-injection.txt |
3275 | F: include/net/mac80211.h | 3275 | F: include/net/mac80211.h |
3276 | F: net/mac80211/ | 3276 | F: net/mac80211/ |
3277 | 3277 | ||
3278 | MAC80211 PID RATE CONTROL | 3278 | MAC80211 PID RATE CONTROL |
3279 | M: Stefano Brivio <stefano.brivio@polimi.it> | 3279 | M: Stefano Brivio <stefano.brivio@polimi.it> |
3280 | M: Mattias Nissler <mattias.nissler@gmx.de> | 3280 | M: Mattias Nissler <mattias.nissler@gmx.de> |
3281 | L: linux-wireless@vger.kernel.org | 3281 | L: linux-wireless@vger.kernel.org |
3282 | W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID | 3282 | W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID |
3283 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git | 3283 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git |
3284 | S: Maintained | 3284 | S: Maintained |
3285 | F: net/mac80211/rc80211_pid* | 3285 | F: net/mac80211/rc80211_pid* |
3286 | 3286 | ||
3287 | MACVLAN DRIVER | 3287 | MACVLAN DRIVER |
3288 | M: Patrick McHardy <kaber@trash.net> | 3288 | M: Patrick McHardy <kaber@trash.net> |
3289 | L: netdev@vger.kernel.org | 3289 | L: netdev@vger.kernel.org |
3290 | S: Maintained | 3290 | S: Maintained |
3291 | F: drivers/net/macvlan.c | 3291 | F: drivers/net/macvlan.c |
3292 | F: include/linux/if_macvlan.h | 3292 | F: include/linux/if_macvlan.h |
3293 | 3293 | ||
3294 | MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7 | 3294 | MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7 |
3295 | M: Michael Kerrisk <mtk.manpages@gmail.com> | 3295 | M: Michael Kerrisk <mtk.manpages@gmail.com> |
3296 | W: http://www.kernel.org/doc/man-pages | 3296 | W: http://www.kernel.org/doc/man-pages |
3297 | L: linux-man@vger.kernel.org | 3297 | L: linux-man@vger.kernel.org |
3298 | S: Maintained | 3298 | S: Maintained |
3299 | 3299 | ||
3300 | MARVELL LIBERTAS WIRELESS DRIVER | 3300 | MARVELL LIBERTAS WIRELESS DRIVER |
3301 | M: Dan Williams <dcbw@redhat.com> | 3301 | M: Dan Williams <dcbw@redhat.com> |
3302 | L: libertas-dev@lists.infradead.org | 3302 | L: libertas-dev@lists.infradead.org |
3303 | S: Maintained | 3303 | S: Maintained |
3304 | F: drivers/net/wireless/libertas/ | 3304 | F: drivers/net/wireless/libertas/ |
3305 | 3305 | ||
3306 | MARVELL MV643XX ETHERNET DRIVER | 3306 | MARVELL MV643XX ETHERNET DRIVER |
3307 | M: Lennert Buytenhek <buytenh@marvell.com> | 3307 | M: Lennert Buytenhek <buytenh@marvell.com> |
3308 | L: netdev@vger.kernel.org | 3308 | L: netdev@vger.kernel.org |
3309 | S: Supported | 3309 | S: Supported |
3310 | F: drivers/net/mv643xx_eth.* | 3310 | F: drivers/net/mv643xx_eth.* |
3311 | F: include/linux/mv643xx.h | 3311 | F: include/linux/mv643xx.h |
3312 | 3312 | ||
3313 | MARVELL MWL8K WIRELESS DRIVER | 3313 | MARVELL MWL8K WIRELESS DRIVER |
3314 | M: Lennert Buytenhek <buytenh@marvell.com> | 3314 | M: Lennert Buytenhek <buytenh@marvell.com> |
3315 | L: linux-wireless@vger.kernel.org | 3315 | L: linux-wireless@vger.kernel.org |
3316 | S: Supported | 3316 | S: Supported |
3317 | F: drivers/net/wireless/mwl8k.c | 3317 | F: drivers/net/wireless/mwl8k.c |
3318 | 3318 | ||
3319 | MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER | 3319 | MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER |
3320 | M: Nicolas Pitre <nico@cam.org> | 3320 | M: Nicolas Pitre <nico@fluxnic.net> |
3321 | S: Maintained | 3321 | S: Maintained |
3322 | 3322 | ||
3323 | MARVELL YUKON / SYSKONNECT DRIVER | 3323 | MARVELL YUKON / SYSKONNECT DRIVER |
3324 | M: Mirko Lindner <mlindner@syskonnect.de> | 3324 | M: Mirko Lindner <mlindner@syskonnect.de> |
3325 | M: Ralph Roesler <rroesler@syskonnect.de> | 3325 | M: Ralph Roesler <rroesler@syskonnect.de> |
3326 | W: http://www.syskonnect.com | 3326 | W: http://www.syskonnect.com |
3327 | S: Supported | 3327 | S: Supported |
3328 | 3328 | ||
3329 | MATROX FRAMEBUFFER DRIVER | 3329 | MATROX FRAMEBUFFER DRIVER |
3330 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 3330 | M: Petr Vandrovec <vandrove@vc.cvut.cz> |
3331 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3331 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
3332 | S: Maintained | 3332 | S: Maintained |
3333 | F: drivers/video/matrox/matroxfb_* | 3333 | F: drivers/video/matrox/matroxfb_* |
3334 | F: include/linux/matroxfb.h | 3334 | F: include/linux/matroxfb.h |
3335 | 3335 | ||
3336 | MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER | 3336 | MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER |
3337 | M: "Hans J. Koch" <hjk@linutronix.de> | 3337 | M: "Hans J. Koch" <hjk@linutronix.de> |
3338 | L: lm-sensors@lm-sensors.org | 3338 | L: lm-sensors@lm-sensors.org |
3339 | S: Maintained | 3339 | S: Maintained |
3340 | F: Documentation/hwmon/max6650 | 3340 | F: Documentation/hwmon/max6650 |
3341 | F: drivers/hwmon/max6650.c | 3341 | F: drivers/hwmon/max6650.c |
3342 | 3342 | ||
3343 | MEDIA INPUT INFRASTRUCTURE (V4L/DVB) | 3343 | MEDIA INPUT INFRASTRUCTURE (V4L/DVB) |
3344 | M: Mauro Carvalho Chehab <mchehab@infradead.org> | 3344 | M: Mauro Carvalho Chehab <mchehab@infradead.org> |
3345 | P: LinuxTV.org Project | 3345 | P: LinuxTV.org Project |
3346 | L: linux-media@vger.kernel.org | 3346 | L: linux-media@vger.kernel.org |
3347 | W: http://linuxtv.org | 3347 | W: http://linuxtv.org |
3348 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 3348 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
3349 | S: Maintained | 3349 | S: Maintained |
3350 | F: Documentation/dvb/ | 3350 | F: Documentation/dvb/ |
3351 | F: Documentation/video4linux/ | 3351 | F: Documentation/video4linux/ |
3352 | F: drivers/media/ | 3352 | F: drivers/media/ |
3353 | F: include/media/ | 3353 | F: include/media/ |
3354 | F: include/linux/dvb/ | 3354 | F: include/linux/dvb/ |
3355 | F: include/linux/videodev*.h | 3355 | F: include/linux/videodev*.h |
3356 | 3356 | ||
3357 | MEGARAID SCSI DRIVERS | 3357 | MEGARAID SCSI DRIVERS |
3358 | M: Neela Syam Kolli <megaraidlinux@lsi.com> | 3358 | M: Neela Syam Kolli <megaraidlinux@lsi.com> |
3359 | L: linux-scsi@vger.kernel.org | 3359 | L: linux-scsi@vger.kernel.org |
3360 | W: http://megaraid.lsilogic.com | 3360 | W: http://megaraid.lsilogic.com |
3361 | S: Maintained | 3361 | S: Maintained |
3362 | F: Documentation/scsi/megaraid.txt | 3362 | F: Documentation/scsi/megaraid.txt |
3363 | F: drivers/scsi/megaraid.* | 3363 | F: drivers/scsi/megaraid.* |
3364 | F: drivers/scsi/megaraid/ | 3364 | F: drivers/scsi/megaraid/ |
3365 | 3365 | ||
3366 | MEMORY MANAGEMENT | 3366 | MEMORY MANAGEMENT |
3367 | L: linux-mm@kvack.org | 3367 | L: linux-mm@kvack.org |
3368 | W: http://www.linux-mm.org | 3368 | W: http://www.linux-mm.org |
3369 | S: Maintained | 3369 | S: Maintained |
3370 | F: include/linux/mm.h | 3370 | F: include/linux/mm.h |
3371 | F: mm/ | 3371 | F: mm/ |
3372 | 3372 | ||
3373 | MEMORY RESOURCE CONTROLLER | 3373 | MEMORY RESOURCE CONTROLLER |
3374 | M: Balbir Singh <balbir@linux.vnet.ibm.com> | 3374 | M: Balbir Singh <balbir@linux.vnet.ibm.com> |
3375 | M: Pavel Emelyanov <xemul@openvz.org> | 3375 | M: Pavel Emelyanov <xemul@openvz.org> |
3376 | M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 3376 | M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> |
3377 | L: linux-mm@kvack.org | 3377 | L: linux-mm@kvack.org |
3378 | S: Maintained | 3378 | S: Maintained |
3379 | F: mm/memcontrol.c | 3379 | F: mm/memcontrol.c |
3380 | 3380 | ||
3381 | MEMORY TECHNOLOGY DEVICES (MTD) | 3381 | MEMORY TECHNOLOGY DEVICES (MTD) |
3382 | M: David Woodhouse <dwmw2@infradead.org> | 3382 | M: David Woodhouse <dwmw2@infradead.org> |
3383 | W: http://www.linux-mtd.infradead.org/ | 3383 | W: http://www.linux-mtd.infradead.org/ |
3384 | L: linux-mtd@lists.infradead.org | 3384 | L: linux-mtd@lists.infradead.org |
3385 | T: git git://git.infradead.org/mtd-2.6.git | 3385 | T: git git://git.infradead.org/mtd-2.6.git |
3386 | S: Maintained | 3386 | S: Maintained |
3387 | F: drivers/mtd/ | 3387 | F: drivers/mtd/ |
3388 | F: include/linux/mtd/ | 3388 | F: include/linux/mtd/ |
3389 | F: include/mtd/ | 3389 | F: include/mtd/ |
3390 | 3390 | ||
3391 | MICROBLAZE ARCHITECTURE | 3391 | MICROBLAZE ARCHITECTURE |
3392 | M: Michal Simek <monstr@monstr.eu> | 3392 | M: Michal Simek <monstr@monstr.eu> |
3393 | L: microblaze-uclinux@itee.uq.edu.au | 3393 | L: microblaze-uclinux@itee.uq.edu.au |
3394 | W: http://www.monstr.eu/fdt/ | 3394 | W: http://www.monstr.eu/fdt/ |
3395 | T: git git://git.monstr.eu/linux-2.6-microblaze.git | 3395 | T: git git://git.monstr.eu/linux-2.6-microblaze.git |
3396 | S: Supported | 3396 | S: Supported |
3397 | F: arch/microblaze/ | 3397 | F: arch/microblaze/ |
3398 | 3398 | ||
3399 | MICROTEK X6 SCANNER | 3399 | MICROTEK X6 SCANNER |
3400 | M: Oliver Neukum <oliver@neukum.name> | 3400 | M: Oliver Neukum <oliver@neukum.name> |
3401 | S: Maintained | 3401 | S: Maintained |
3402 | F: drivers/usb/image/microtek.* | 3402 | F: drivers/usb/image/microtek.* |
3403 | 3403 | ||
3404 | MIPS | 3404 | MIPS |
3405 | M: Ralf Baechle <ralf@linux-mips.org> | 3405 | M: Ralf Baechle <ralf@linux-mips.org> |
3406 | W: http://www.linux-mips.org/ | 3406 | W: http://www.linux-mips.org/ |
3407 | L: linux-mips@linux-mips.org | 3407 | L: linux-mips@linux-mips.org |
3408 | T: git git://git.linux-mips.org/pub/scm/linux.git | 3408 | T: git git://git.linux-mips.org/pub/scm/linux.git |
3409 | S: Supported | 3409 | S: Supported |
3410 | F: Documentation/mips/ | 3410 | F: Documentation/mips/ |
3411 | F: arch/mips/ | 3411 | F: arch/mips/ |
3412 | 3412 | ||
3413 | MISCELLANEOUS MCA-SUPPORT | 3413 | MISCELLANEOUS MCA-SUPPORT |
3414 | M: James Bottomley <James.Bottomley@HansenPartnership.com> | 3414 | M: James Bottomley <James.Bottomley@HansenPartnership.com> |
3415 | S: Maintained | 3415 | S: Maintained |
3416 | F: Documentation/ia64/mca.txt | 3416 | F: Documentation/ia64/mca.txt |
3417 | F: Documentation/mca.txt | 3417 | F: Documentation/mca.txt |
3418 | F: drivers/mca/ | 3418 | F: drivers/mca/ |
3419 | F: include/linux/mca* | 3419 | F: include/linux/mca* |
3420 | 3420 | ||
3421 | MODULE SUPPORT | 3421 | MODULE SUPPORT |
3422 | M: Rusty Russell <rusty@rustcorp.com.au> | 3422 | M: Rusty Russell <rusty@rustcorp.com.au> |
3423 | S: Maintained | 3423 | S: Maintained |
3424 | F: include/linux/module.h | 3424 | F: include/linux/module.h |
3425 | F: kernel/module.c | 3425 | F: kernel/module.c |
3426 | 3426 | ||
3427 | MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER | 3427 | MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER |
3428 | M: Stelian Pop <stelian@popies.net> | 3428 | M: Stelian Pop <stelian@popies.net> |
3429 | W: http://popies.net/meye/ | 3429 | W: http://popies.net/meye/ |
3430 | S: Maintained | 3430 | S: Maintained |
3431 | F: Documentation/video4linux/meye.txt | 3431 | F: Documentation/video4linux/meye.txt |
3432 | F: drivers/media/video/meye.* | 3432 | F: drivers/media/video/meye.* |
3433 | F: include/linux/meye.h | 3433 | F: include/linux/meye.h |
3434 | 3434 | ||
3435 | MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER | 3435 | MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER |
3436 | M: Pavel Pisa <ppisa@pikron.com> | 3436 | M: Pavel Pisa <ppisa@pikron.com> |
3437 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 3437 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
3438 | S: Maintained | 3438 | S: Maintained |
3439 | F: drivers/mmc/host/imxmmc.* | 3439 | F: drivers/mmc/host/imxmmc.* |
3440 | 3440 | ||
3441 | MOUSE AND MISC DEVICES [GENERAL] | 3441 | MOUSE AND MISC DEVICES [GENERAL] |
3442 | M: Alessandro Rubini <rubini@ipvvis.unipv.it> | 3442 | M: Alessandro Rubini <rubini@ipvvis.unipv.it> |
3443 | S: Maintained | 3443 | S: Maintained |
3444 | F: drivers/input/mouse/ | 3444 | F: drivers/input/mouse/ |
3445 | F: include/linux/gpio_mouse.h | 3445 | F: include/linux/gpio_mouse.h |
3446 | 3446 | ||
3447 | MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD | 3447 | MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD |
3448 | M: Jiri Slaby <jirislaby@gmail.com> | 3448 | M: Jiri Slaby <jirislaby@gmail.com> |
3449 | S: Maintained | 3449 | S: Maintained |
3450 | F: Documentation/serial/moxa-smartio | 3450 | F: Documentation/serial/moxa-smartio |
3451 | F: drivers/char/mxser.* | 3451 | F: drivers/char/mxser.* |
3452 | 3452 | ||
3453 | MSI LAPTOP SUPPORT | 3453 | MSI LAPTOP SUPPORT |
3454 | M: Lennart Poettering <mzxreary@0pointer.de> | 3454 | M: Lennart Poettering <mzxreary@0pointer.de> |
3455 | W: https://tango.0pointer.de/mailman/listinfo/s270-linux | 3455 | W: https://tango.0pointer.de/mailman/listinfo/s270-linux |
3456 | W: http://0pointer.de/lennart/tchibo.html | 3456 | W: http://0pointer.de/lennart/tchibo.html |
3457 | S: Maintained | 3457 | S: Maintained |
3458 | F: drivers/platform/x86/msi-laptop.c | 3458 | F: drivers/platform/x86/msi-laptop.c |
3459 | 3459 | ||
3460 | MULTIFUNCTION DEVICES (MFD) | 3460 | MULTIFUNCTION DEVICES (MFD) |
3461 | M: Samuel Ortiz <sameo@linux.intel.com> | 3461 | M: Samuel Ortiz <sameo@linux.intel.com> |
3462 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git | 3462 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git |
3463 | S: Supported | 3463 | S: Supported |
3464 | F: drivers/mfd/ | 3464 | F: drivers/mfd/ |
3465 | 3465 | ||
3466 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM | 3466 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM |
3467 | S: Orphan | 3467 | S: Orphan |
3468 | L: linux-mmc@vger.kernel.org | 3468 | L: linux-mmc@vger.kernel.org |
3469 | F: drivers/mmc/ | 3469 | F: drivers/mmc/ |
3470 | F: include/linux/mmc/ | 3470 | F: include/linux/mmc/ |
3471 | 3471 | ||
3472 | MULTIMEDIA CARD (MMC) ETC. OVER SPI | 3472 | MULTIMEDIA CARD (MMC) ETC. OVER SPI |
3473 | M: David Brownell <dbrownell@users.sourceforge.net> | 3473 | M: David Brownell <dbrownell@users.sourceforge.net> |
3474 | S: Odd Fixes | 3474 | S: Odd Fixes |
3475 | F: drivers/mmc/host/mmc_spi.c | 3475 | F: drivers/mmc/host/mmc_spi.c |
3476 | F: include/linux/spi/mmc_spi.h | 3476 | F: include/linux/spi/mmc_spi.h |
3477 | 3477 | ||
3478 | MULTISOUND SOUND DRIVER | 3478 | MULTISOUND SOUND DRIVER |
3479 | M: Andrew Veliath <andrewtv@usa.net> | 3479 | M: Andrew Veliath <andrewtv@usa.net> |
3480 | S: Maintained | 3480 | S: Maintained |
3481 | F: Documentation/sound/oss/MultiSound | 3481 | F: Documentation/sound/oss/MultiSound |
3482 | F: sound/oss/msnd* | 3482 | F: sound/oss/msnd* |
3483 | 3483 | ||
3484 | MULTITECH MULTIPORT CARD (ISICOM) | 3484 | MULTITECH MULTIPORT CARD (ISICOM) |
3485 | M: Jiri Slaby <jirislaby@gmail.com> | 3485 | M: Jiri Slaby <jirislaby@gmail.com> |
3486 | S: Maintained | 3486 | S: Maintained |
3487 | F: drivers/char/isicom.c | 3487 | F: drivers/char/isicom.c |
3488 | F: include/linux/isicom.h | 3488 | F: include/linux/isicom.h |
3489 | 3489 | ||
3490 | MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER | 3490 | MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER |
3491 | M: Felipe Balbi <felipe.balbi@nokia.com> | 3491 | M: Felipe Balbi <felipe.balbi@nokia.com> |
3492 | L: linux-usb@vger.kernel.org | 3492 | L: linux-usb@vger.kernel.org |
3493 | T: git git://gitorious.org/musb/mainline.git | 3493 | T: git git://gitorious.org/musb/mainline.git |
3494 | S: Maintained | 3494 | S: Maintained |
3495 | F: drivers/usb/musb/ | 3495 | F: drivers/usb/musb/ |
3496 | 3496 | ||
3497 | MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE) | 3497 | MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE) |
3498 | M: Andrew Gallatin <gallatin@myri.com> | 3498 | M: Andrew Gallatin <gallatin@myri.com> |
3499 | M: Brice Goglin <brice@myri.com> | 3499 | M: Brice Goglin <brice@myri.com> |
3500 | L: netdev@vger.kernel.org | 3500 | L: netdev@vger.kernel.org |
3501 | W: http://www.myri.com/scs/download-Myri10GE.html | 3501 | W: http://www.myri.com/scs/download-Myri10GE.html |
3502 | S: Supported | 3502 | S: Supported |
3503 | F: drivers/net/myri10ge/ | 3503 | F: drivers/net/myri10ge/ |
3504 | 3504 | ||
3505 | NATSEMI ETHERNET DRIVER (DP8381x) | 3505 | NATSEMI ETHERNET DRIVER (DP8381x) |
3506 | M: Tim Hockin <thockin@hockin.org> | 3506 | M: Tim Hockin <thockin@hockin.org> |
3507 | S: Maintained | 3507 | S: Maintained |
3508 | F: drivers/net/natsemi.c | 3508 | F: drivers/net/natsemi.c |
3509 | 3509 | ||
3510 | NCP FILESYSTEM | 3510 | NCP FILESYSTEM |
3511 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 3511 | M: Petr Vandrovec <vandrove@vc.cvut.cz> |
3512 | L: linware@sh.cvut.cz | 3512 | L: linware@sh.cvut.cz |
3513 | S: Maintained | 3513 | S: Maintained |
3514 | F: fs/ncpfs/ | 3514 | F: fs/ncpfs/ |
3515 | 3515 | ||
3516 | NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) | 3516 | NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) |
3517 | M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> | 3517 | M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> |
3518 | L: linux-scsi@vger.kernel.org | 3518 | L: linux-scsi@vger.kernel.org |
3519 | S: Maintained | 3519 | S: Maintained |
3520 | F: drivers/scsi/NCR_D700.* | 3520 | F: drivers/scsi/NCR_D700.* |
3521 | 3521 | ||
3522 | NETEFFECT IWARP RNIC DRIVER (IW_NES) | 3522 | NETEFFECT IWARP RNIC DRIVER (IW_NES) |
3523 | M: Faisal Latif <faisal.latif@intel.com> | 3523 | M: Faisal Latif <faisal.latif@intel.com> |
3524 | M: Chien Tung <chien.tin.tung@intel.com> | 3524 | M: Chien Tung <chien.tin.tung@intel.com> |
3525 | L: linux-rdma@vger.kernel.org | 3525 | L: linux-rdma@vger.kernel.org |
3526 | W: http://www.neteffect.com | 3526 | W: http://www.neteffect.com |
3527 | S: Supported | 3527 | S: Supported |
3528 | F: drivers/infiniband/hw/nes/ | 3528 | F: drivers/infiniband/hw/nes/ |
3529 | 3529 | ||
3530 | NETEM NETWORK EMULATOR | 3530 | NETEM NETWORK EMULATOR |
3531 | M: Stephen Hemminger <shemminger@linux-foundation.org> | 3531 | M: Stephen Hemminger <shemminger@linux-foundation.org> |
3532 | L: netem@lists.linux-foundation.org | 3532 | L: netem@lists.linux-foundation.org |
3533 | S: Maintained | 3533 | S: Maintained |
3534 | F: net/sched/sch_netem.c | 3534 | F: net/sched/sch_netem.c |
3535 | 3535 | ||
3536 | NETERION (S2IO) 10GbE DRIVER (xframe/vxge) | 3536 | NETERION (S2IO) 10GbE DRIVER (xframe/vxge) |
3537 | M: Ramkrishna Vepa <ram.vepa@neterion.com> | 3537 | M: Ramkrishna Vepa <ram.vepa@neterion.com> |
3538 | M: Rastapur Santosh <santosh.rastapur@neterion.com> | 3538 | M: Rastapur Santosh <santosh.rastapur@neterion.com> |
3539 | M: Sivakumar Subramani <sivakumar.subramani@neterion.com> | 3539 | M: Sivakumar Subramani <sivakumar.subramani@neterion.com> |
3540 | M: Sreenivasa Honnur <sreenivasa.honnur@neterion.com> | 3540 | M: Sreenivasa Honnur <sreenivasa.honnur@neterion.com> |
3541 | M: Anil Murthy <anil.murthy@neterion.com> | 3541 | M: Anil Murthy <anil.murthy@neterion.com> |
3542 | L: netdev@vger.kernel.org | 3542 | L: netdev@vger.kernel.org |
3543 | W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous | 3543 | W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous |
3544 | W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous | 3544 | W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous |
3545 | S: Supported | 3545 | S: Supported |
3546 | F: Documentation/networking/s2io.txt | 3546 | F: Documentation/networking/s2io.txt |
3547 | F: drivers/net/s2io* | 3547 | F: drivers/net/s2io* |
3548 | 3548 | ||
3549 | NETFILTER/IPTABLES/IPCHAINS | 3549 | NETFILTER/IPTABLES/IPCHAINS |
3550 | P: Rusty Russell | 3550 | P: Rusty Russell |
3551 | P: Marc Boucher | 3551 | P: Marc Boucher |
3552 | P: James Morris | 3552 | P: James Morris |
3553 | P: Harald Welte | 3553 | P: Harald Welte |
3554 | P: Jozsef Kadlecsik | 3554 | P: Jozsef Kadlecsik |
3555 | M: Patrick McHardy <kaber@trash.net> | 3555 | M: Patrick McHardy <kaber@trash.net> |
3556 | L: netfilter-devel@vger.kernel.org | 3556 | L: netfilter-devel@vger.kernel.org |
3557 | L: netfilter@vger.kernel.org | 3557 | L: netfilter@vger.kernel.org |
3558 | L: coreteam@netfilter.org | 3558 | L: coreteam@netfilter.org |
3559 | W: http://www.netfilter.org/ | 3559 | W: http://www.netfilter.org/ |
3560 | W: http://www.iptables.org/ | 3560 | W: http://www.iptables.org/ |
3561 | T: git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git | 3561 | T: git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git |
3562 | S: Supported | 3562 | S: Supported |
3563 | F: include/linux/netfilter* | 3563 | F: include/linux/netfilter* |
3564 | F: include/linux/netfilter/ | 3564 | F: include/linux/netfilter/ |
3565 | F: include/net/netfilter/ | 3565 | F: include/net/netfilter/ |
3566 | F: net/*/netfilter.c | 3566 | F: net/*/netfilter.c |
3567 | F: net/*/netfilter/ | 3567 | F: net/*/netfilter/ |
3568 | F: net/netfilter/ | 3568 | F: net/netfilter/ |
3569 | 3569 | ||
3570 | NETLABEL | 3570 | NETLABEL |
3571 | M: Paul Moore <paul.moore@hp.com> | 3571 | M: Paul Moore <paul.moore@hp.com> |
3572 | W: http://netlabel.sf.net | 3572 | W: http://netlabel.sf.net |
3573 | L: netdev@vger.kernel.org | 3573 | L: netdev@vger.kernel.org |
3574 | S: Supported | 3574 | S: Supported |
3575 | F: Documentation/netlabel/ | 3575 | F: Documentation/netlabel/ |
3576 | F: include/net/netlabel.h | 3576 | F: include/net/netlabel.h |
3577 | F: net/netlabel/ | 3577 | F: net/netlabel/ |
3578 | 3578 | ||
3579 | NETROM NETWORK LAYER | 3579 | NETROM NETWORK LAYER |
3580 | M: Ralf Baechle <ralf@linux-mips.org> | 3580 | M: Ralf Baechle <ralf@linux-mips.org> |
3581 | L: linux-hams@vger.kernel.org | 3581 | L: linux-hams@vger.kernel.org |
3582 | W: http://www.linux-ax25.org/ | 3582 | W: http://www.linux-ax25.org/ |
3583 | S: Maintained | 3583 | S: Maintained |
3584 | F: include/linux/netrom.h | 3584 | F: include/linux/netrom.h |
3585 | F: include/net/netrom.h | 3585 | F: include/net/netrom.h |
3586 | F: net/netrom/ | 3586 | F: net/netrom/ |
3587 | 3587 | ||
3588 | NETWORK BLOCK DEVICE (NBD) | 3588 | NETWORK BLOCK DEVICE (NBD) |
3589 | M: Paul Clements <Paul.Clements@steeleye.com> | 3589 | M: Paul Clements <Paul.Clements@steeleye.com> |
3590 | S: Maintained | 3590 | S: Maintained |
3591 | F: Documentation/blockdev/nbd.txt | 3591 | F: Documentation/blockdev/nbd.txt |
3592 | F: drivers/block/nbd.c | 3592 | F: drivers/block/nbd.c |
3593 | F: include/linux/nbd.h | 3593 | F: include/linux/nbd.h |
3594 | 3594 | ||
3595 | NETWORKING [GENERAL] | 3595 | NETWORKING [GENERAL] |
3596 | M: "David S. Miller" <davem@davemloft.net> | 3596 | M: "David S. Miller" <davem@davemloft.net> |
3597 | L: netdev@vger.kernel.org | 3597 | L: netdev@vger.kernel.org |
3598 | W: http://www.linuxfoundation.org/en/Net | 3598 | W: http://www.linuxfoundation.org/en/Net |
3599 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git | 3599 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git |
3600 | S: Maintained | 3600 | S: Maintained |
3601 | F: net/ | 3601 | F: net/ |
3602 | F: include/net/ | 3602 | F: include/net/ |
3603 | F: include/linux/in.h | 3603 | F: include/linux/in.h |
3604 | F: include/linux/net.h | 3604 | F: include/linux/net.h |
3605 | F: include/linux/netdevice.h | 3605 | F: include/linux/netdevice.h |
3606 | 3606 | ||
3607 | NETWORKING [IPv4/IPv6] | 3607 | NETWORKING [IPv4/IPv6] |
3608 | M: "David S. Miller" <davem@davemloft.net> | 3608 | M: "David S. Miller" <davem@davemloft.net> |
3609 | M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | 3609 | M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> |
3610 | M: "Pekka Savola (ipv6)" <pekkas@netcore.fi> | 3610 | M: "Pekka Savola (ipv6)" <pekkas@netcore.fi> |
3611 | M: James Morris <jmorris@namei.org> | 3611 | M: James Morris <jmorris@namei.org> |
3612 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> | 3612 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> |
3613 | M: Patrick McHardy <kaber@trash.net> | 3613 | M: Patrick McHardy <kaber@trash.net> |
3614 | L: netdev@vger.kernel.org | 3614 | L: netdev@vger.kernel.org |
3615 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git | 3615 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git |
3616 | S: Maintained | 3616 | S: Maintained |
3617 | F: net/ipv4/ | 3617 | F: net/ipv4/ |
3618 | F: net/ipv6/ | 3618 | F: net/ipv6/ |
3619 | F: include/net/ip* | 3619 | F: include/net/ip* |
3620 | 3620 | ||
3621 | NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) | 3621 | NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) |
3622 | M: Paul Moore <paul.moore@hp.com> | 3622 | M: Paul Moore <paul.moore@hp.com> |
3623 | L: netdev@vger.kernel.org | 3623 | L: netdev@vger.kernel.org |
3624 | S: Maintained | 3624 | S: Maintained |
3625 | 3625 | ||
3626 | NETWORKING [WIRELESS] | 3626 | NETWORKING [WIRELESS] |
3627 | M: "John W. Linville" <linville@tuxdriver.com> | 3627 | M: "John W. Linville" <linville@tuxdriver.com> |
3628 | L: linux-wireless@vger.kernel.org | 3628 | L: linux-wireless@vger.kernel.org |
3629 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git | 3629 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git |
3630 | S: Maintained | 3630 | S: Maintained |
3631 | F: net/mac80211/ | 3631 | F: net/mac80211/ |
3632 | F: net/rfkill/ | 3632 | F: net/rfkill/ |
3633 | F: net/wireless/ | 3633 | F: net/wireless/ |
3634 | F: include/net/ieee80211* | 3634 | F: include/net/ieee80211* |
3635 | F: include/linux/wireless.h | 3635 | F: include/linux/wireless.h |
3636 | F: drivers/net/wireless/ | 3636 | F: drivers/net/wireless/ |
3637 | 3637 | ||
3638 | NETWORKING DRIVERS | 3638 | NETWORKING DRIVERS |
3639 | L: netdev@vger.kernel.org | 3639 | L: netdev@vger.kernel.org |
3640 | W: http://www.linuxfoundation.org/en/Net | 3640 | W: http://www.linuxfoundation.org/en/Net |
3641 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git | 3641 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git |
3642 | S: Odd Fixes | 3642 | S: Odd Fixes |
3643 | F: drivers/net/ | 3643 | F: drivers/net/ |
3644 | F: include/linux/if_* | 3644 | F: include/linux/if_* |
3645 | F: include/linux/*device.h | 3645 | F: include/linux/*device.h |
3646 | 3646 | ||
3647 | NETXEN (1/10) GbE SUPPORT | 3647 | NETXEN (1/10) GbE SUPPORT |
3648 | M: Dhananjay Phadke <dhananjay@netxen.com> | 3648 | M: Dhananjay Phadke <dhananjay@netxen.com> |
3649 | L: netdev@vger.kernel.org | 3649 | L: netdev@vger.kernel.org |
3650 | W: http://www.netxen.com | 3650 | W: http://www.netxen.com |
3651 | S: Supported | 3651 | S: Supported |
3652 | F: drivers/net/netxen/ | 3652 | F: drivers/net/netxen/ |
3653 | 3653 | ||
3654 | NFS, SUNRPC, AND LOCKD CLIENTS | 3654 | NFS, SUNRPC, AND LOCKD CLIENTS |
3655 | M: Trond Myklebust <Trond.Myklebust@netapp.com> | 3655 | M: Trond Myklebust <Trond.Myklebust@netapp.com> |
3656 | L: linux-nfs@vger.kernel.org | 3656 | L: linux-nfs@vger.kernel.org |
3657 | W: http://client.linux-nfs.org | 3657 | W: http://client.linux-nfs.org |
3658 | T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git | 3658 | T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git |
3659 | S: Maintained | 3659 | S: Maintained |
3660 | F: fs/lockd/ | 3660 | F: fs/lockd/ |
3661 | F: fs/nfs/ | 3661 | F: fs/nfs/ |
3662 | F: fs/nfs_common/ | 3662 | F: fs/nfs_common/ |
3663 | F: net/sunrpc/ | 3663 | F: net/sunrpc/ |
3664 | F: include/linux/lockd/ | 3664 | F: include/linux/lockd/ |
3665 | F: include/linux/nfs* | 3665 | F: include/linux/nfs* |
3666 | F: include/linux/sunrpc/ | 3666 | F: include/linux/sunrpc/ |
3667 | 3667 | ||
3668 | NI5010 NETWORK DRIVER | 3668 | NI5010 NETWORK DRIVER |
3669 | M: Jan-Pascal van Best <janpascal@vanbest.org> | 3669 | M: Jan-Pascal van Best <janpascal@vanbest.org> |
3670 | M: Andreas Mohr <andi@lisas.de> | 3670 | M: Andreas Mohr <andi@lisas.de> |
3671 | L: netdev@vger.kernel.org | 3671 | L: netdev@vger.kernel.org |
3672 | S: Maintained | 3672 | S: Maintained |
3673 | F: drivers/net/ni5010.* | 3673 | F: drivers/net/ni5010.* |
3674 | 3674 | ||
3675 | NILFS2 FILESYSTEM | 3675 | NILFS2 FILESYSTEM |
3676 | M: KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp> | 3676 | M: KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp> |
3677 | L: users@nilfs.org | 3677 | L: users@nilfs.org |
3678 | W: http://www.nilfs.org/en/ | 3678 | W: http://www.nilfs.org/en/ |
3679 | S: Supported | 3679 | S: Supported |
3680 | F: Documentation/filesystems/nilfs2.txt | 3680 | F: Documentation/filesystems/nilfs2.txt |
3681 | F: fs/nilfs2/ | 3681 | F: fs/nilfs2/ |
3682 | F: include/linux/nilfs2_fs.h | 3682 | F: include/linux/nilfs2_fs.h |
3683 | 3683 | ||
3684 | NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER | 3684 | NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER |
3685 | M: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp> | 3685 | M: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp> |
3686 | W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/ | 3686 | W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/ |
3687 | S: Maintained | 3687 | S: Maintained |
3688 | F: Documentation/scsi/NinjaSCSI.txt | 3688 | F: Documentation/scsi/NinjaSCSI.txt |
3689 | F: drivers/scsi/pcmcia/nsp_* | 3689 | F: drivers/scsi/pcmcia/nsp_* |
3690 | 3690 | ||
3691 | NINJA SCSI-32Bi/UDE PCI/CARDBUS SCSI HOST ADAPTER DRIVER | 3691 | NINJA SCSI-32Bi/UDE PCI/CARDBUS SCSI HOST ADAPTER DRIVER |
3692 | M: GOTO Masanori <gotom@debian.or.jp> | 3692 | M: GOTO Masanori <gotom@debian.or.jp> |
3693 | M: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp> | 3693 | M: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp> |
3694 | W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/ | 3694 | W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/ |
3695 | S: Maintained | 3695 | S: Maintained |
3696 | F: Documentation/scsi/NinjaSCSI.txt | 3696 | F: Documentation/scsi/NinjaSCSI.txt |
3697 | F: drivers/scsi/nsp32* | 3697 | F: drivers/scsi/nsp32* |
3698 | 3698 | ||
3699 | NTFS FILESYSTEM | 3699 | NTFS FILESYSTEM |
3700 | M: Anton Altaparmakov <aia21@cantab.net> | 3700 | M: Anton Altaparmakov <aia21@cantab.net> |
3701 | L: linux-ntfs-dev@lists.sourceforge.net | 3701 | L: linux-ntfs-dev@lists.sourceforge.net |
3702 | W: http://www.linux-ntfs.org/ | 3702 | W: http://www.linux-ntfs.org/ |
3703 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git | 3703 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git |
3704 | S: Maintained | 3704 | S: Maintained |
3705 | F: Documentation/filesystems/ntfs.txt | 3705 | F: Documentation/filesystems/ntfs.txt |
3706 | F: fs/ntfs/ | 3706 | F: fs/ntfs/ |
3707 | 3707 | ||
3708 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER | 3708 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER |
3709 | M: Antonino Daplas <adaplas@gmail.com> | 3709 | M: Antonino Daplas <adaplas@gmail.com> |
3710 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3710 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
3711 | S: Maintained | 3711 | S: Maintained |
3712 | F: drivers/video/riva/ | 3712 | F: drivers/video/riva/ |
3713 | F: drivers/video/nvidia/ | 3713 | F: drivers/video/nvidia/ |
3714 | 3714 | ||
3715 | OMAP SUPPORT | 3715 | OMAP SUPPORT |
3716 | M: "Tony Lindgren <tony@atomide.com>" <tony@atomide.com> | 3716 | M: "Tony Lindgren <tony@atomide.com>" <tony@atomide.com> |
3717 | L: linux-omap@vger.kernel.org | 3717 | L: linux-omap@vger.kernel.org |
3718 | W: http://www.muru.com/linux/omap/ | 3718 | W: http://www.muru.com/linux/omap/ |
3719 | W: http://linux.omap.com/ | 3719 | W: http://linux.omap.com/ |
3720 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git | 3720 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git |
3721 | S: Maintained | 3721 | S: Maintained |
3722 | F: arch/arm/*omap* | 3722 | F: arch/arm/*omap* |
3723 | 3723 | ||
3724 | OMAP CLOCK FRAMEWORK SUPPORT | 3724 | OMAP CLOCK FRAMEWORK SUPPORT |
3725 | M: Paul Walmsley <paul@pwsan.com> | 3725 | M: Paul Walmsley <paul@pwsan.com> |
3726 | L: linux-omap@vger.kernel.org | 3726 | L: linux-omap@vger.kernel.org |
3727 | S: Maintained | 3727 | S: Maintained |
3728 | F: arch/arm/*omap*/*clock* | 3728 | F: arch/arm/*omap*/*clock* |
3729 | 3729 | ||
3730 | OMAP POWER MANAGEMENT SUPPORT | 3730 | OMAP POWER MANAGEMENT SUPPORT |
3731 | M: Kevin Hilman <khilman@deeprootsystems.com> | 3731 | M: Kevin Hilman <khilman@deeprootsystems.com> |
3732 | L: linux-omap@vger.kernel.org | 3732 | L: linux-omap@vger.kernel.org |
3733 | S: Maintained | 3733 | S: Maintained |
3734 | F: arch/arm/*omap*/*pm* | 3734 | F: arch/arm/*omap*/*pm* |
3735 | 3735 | ||
3736 | OMAP AUDIO SUPPORT | 3736 | OMAP AUDIO SUPPORT |
3737 | M: Jarkko Nikula <jhnikula@gmail.com> | 3737 | M: Jarkko Nikula <jhnikula@gmail.com> |
3738 | L: alsa-devel@alsa-project.org (subscribers-only) | 3738 | L: alsa-devel@alsa-project.org (subscribers-only) |
3739 | L: linux-omap@vger.kernel.org | 3739 | L: linux-omap@vger.kernel.org |
3740 | S: Maintained | 3740 | S: Maintained |
3741 | F: sound/soc/omap/ | 3741 | F: sound/soc/omap/ |
3742 | 3742 | ||
3743 | OMAP FRAMEBUFFER SUPPORT | 3743 | OMAP FRAMEBUFFER SUPPORT |
3744 | M: Imre Deak <imre.deak@nokia.com> | 3744 | M: Imre Deak <imre.deak@nokia.com> |
3745 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3745 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
3746 | L: linux-omap@vger.kernel.org | 3746 | L: linux-omap@vger.kernel.org |
3747 | S: Maintained | 3747 | S: Maintained |
3748 | F: drivers/video/omap/ | 3748 | F: drivers/video/omap/ |
3749 | 3749 | ||
3750 | OMAP MMC SUPPORT | 3750 | OMAP MMC SUPPORT |
3751 | M: Jarkko Lavinen <jarkko.lavinen@nokia.com> | 3751 | M: Jarkko Lavinen <jarkko.lavinen@nokia.com> |
3752 | L: linux-omap@vger.kernel.org | 3752 | L: linux-omap@vger.kernel.org |
3753 | S: Maintained | 3753 | S: Maintained |
3754 | F: drivers/mmc/host/*omap* | 3754 | F: drivers/mmc/host/*omap* |
3755 | 3755 | ||
3756 | OMAP RANDOM NUMBER GENERATOR SUPPORT | 3756 | OMAP RANDOM NUMBER GENERATOR SUPPORT |
3757 | M: Deepak Saxena <dsaxena@plexity.net> | 3757 | M: Deepak Saxena <dsaxena@plexity.net> |
3758 | S: Maintained | 3758 | S: Maintained |
3759 | F: drivers/char/hw_random/omap-rng.c | 3759 | F: drivers/char/hw_random/omap-rng.c |
3760 | 3760 | ||
3761 | OMAP USB SUPPORT | 3761 | OMAP USB SUPPORT |
3762 | M: Felipe Balbi <felipe.balbi@nokia.com> | 3762 | M: Felipe Balbi <felipe.balbi@nokia.com> |
3763 | M: David Brownell <dbrownell@users.sourceforge.net> | 3763 | M: David Brownell <dbrownell@users.sourceforge.net> |
3764 | L: linux-usb@vger.kernel.org | 3764 | L: linux-usb@vger.kernel.org |
3765 | L: linux-omap@vger.kernel.org | 3765 | L: linux-omap@vger.kernel.org |
3766 | S: Maintained | 3766 | S: Maintained |
3767 | 3767 | ||
3768 | OMFS FILESYSTEM | 3768 | OMFS FILESYSTEM |
3769 | M: Bob Copeland <me@bobcopeland.com> | 3769 | M: Bob Copeland <me@bobcopeland.com> |
3770 | L: linux-karma-devel@lists.sourceforge.net | 3770 | L: linux-karma-devel@lists.sourceforge.net |
3771 | S: Maintained | 3771 | S: Maintained |
3772 | F: Documentation/filesystems/omfs.txt | 3772 | F: Documentation/filesystems/omfs.txt |
3773 | F: fs/omfs/ | 3773 | F: fs/omfs/ |
3774 | 3774 | ||
3775 | OMNIKEY CARDMAN 4000 DRIVER | 3775 | OMNIKEY CARDMAN 4000 DRIVER |
3776 | M: Harald Welte <laforge@gnumonks.org> | 3776 | M: Harald Welte <laforge@gnumonks.org> |
3777 | S: Maintained | 3777 | S: Maintained |
3778 | F: drivers/char/pcmcia/cm4000_cs.c | 3778 | F: drivers/char/pcmcia/cm4000_cs.c |
3779 | F: include/linux/cm4000_cs.h | 3779 | F: include/linux/cm4000_cs.h |
3780 | 3780 | ||
3781 | OMNIKEY CARDMAN 4040 DRIVER | 3781 | OMNIKEY CARDMAN 4040 DRIVER |
3782 | M: Harald Welte <laforge@gnumonks.org> | 3782 | M: Harald Welte <laforge@gnumonks.org> |
3783 | S: Maintained | 3783 | S: Maintained |
3784 | F: drivers/char/pcmcia/cm4040_cs.* | 3784 | F: drivers/char/pcmcia/cm4040_cs.* |
3785 | 3785 | ||
3786 | OMNIVISION OV7670 SENSOR DRIVER | 3786 | OMNIVISION OV7670 SENSOR DRIVER |
3787 | M: Jonathan Corbet <corbet@lwn.net> | 3787 | M: Jonathan Corbet <corbet@lwn.net> |
3788 | L: linux-media@vger.kernel.org | 3788 | L: linux-media@vger.kernel.org |
3789 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 3789 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
3790 | S: Maintained | 3790 | S: Maintained |
3791 | F: drivers/media/video/ov7670.c | 3791 | F: drivers/media/video/ov7670.c |
3792 | 3792 | ||
3793 | ONENAND FLASH DRIVER | 3793 | ONENAND FLASH DRIVER |
3794 | M: Kyungmin Park <kyungmin.park@samsung.com> | 3794 | M: Kyungmin Park <kyungmin.park@samsung.com> |
3795 | L: linux-mtd@lists.infradead.org | 3795 | L: linux-mtd@lists.infradead.org |
3796 | S: Maintained | 3796 | S: Maintained |
3797 | F: drivers/mtd/onenand/ | 3797 | F: drivers/mtd/onenand/ |
3798 | F: include/linux/mtd/onenand*.h | 3798 | F: include/linux/mtd/onenand*.h |
3799 | 3799 | ||
3800 | ONSTREAM SCSI TAPE DRIVER | 3800 | ONSTREAM SCSI TAPE DRIVER |
3801 | M: Willem Riede <osst@riede.org> | 3801 | M: Willem Riede <osst@riede.org> |
3802 | L: osst-users@lists.sourceforge.net | 3802 | L: osst-users@lists.sourceforge.net |
3803 | L: linux-scsi@vger.kernel.org | 3803 | L: linux-scsi@vger.kernel.org |
3804 | S: Maintained | 3804 | S: Maintained |
3805 | F: drivers/scsi/osst* | 3805 | F: drivers/scsi/osst* |
3806 | F: drivers/scsi/st* | 3806 | F: drivers/scsi/st* |
3807 | 3807 | ||
3808 | OPENCORES I2C BUS DRIVER | 3808 | OPENCORES I2C BUS DRIVER |
3809 | M: Peter Korsgaard <jacmet@sunsite.dk> | 3809 | M: Peter Korsgaard <jacmet@sunsite.dk> |
3810 | L: linux-i2c@vger.kernel.org | 3810 | L: linux-i2c@vger.kernel.org |
3811 | S: Maintained | 3811 | S: Maintained |
3812 | F: Documentation/i2c/busses/i2c-ocores | 3812 | F: Documentation/i2c/busses/i2c-ocores |
3813 | F: drivers/i2c/busses/i2c-ocores.c | 3813 | F: drivers/i2c/busses/i2c-ocores.c |
3814 | 3814 | ||
3815 | OPROFILE | 3815 | OPROFILE |
3816 | M: Robert Richter <robert.richter@amd.com> | 3816 | M: Robert Richter <robert.richter@amd.com> |
3817 | L: oprofile-list@lists.sf.net | 3817 | L: oprofile-list@lists.sf.net |
3818 | S: Maintained | 3818 | S: Maintained |
3819 | F: arch/*/oprofile/ | 3819 | F: arch/*/oprofile/ |
3820 | F: drivers/oprofile/ | 3820 | F: drivers/oprofile/ |
3821 | F: include/linux/oprofile.h | 3821 | F: include/linux/oprofile.h |
3822 | 3822 | ||
3823 | ORACLE CLUSTER FILESYSTEM 2 (OCFS2) | 3823 | ORACLE CLUSTER FILESYSTEM 2 (OCFS2) |
3824 | M: Mark Fasheh <mfasheh@suse.com> | 3824 | M: Mark Fasheh <mfasheh@suse.com> |
3825 | M: Joel Becker <joel.becker@oracle.com> | 3825 | M: Joel Becker <joel.becker@oracle.com> |
3826 | L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers) | 3826 | L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers) |
3827 | W: http://oss.oracle.com/projects/ocfs2/ | 3827 | W: http://oss.oracle.com/projects/ocfs2/ |
3828 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2.git | 3828 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2.git |
3829 | S: Supported | 3829 | S: Supported |
3830 | F: Documentation/filesystems/ocfs2.txt | 3830 | F: Documentation/filesystems/ocfs2.txt |
3831 | F: Documentation/filesystems/dlmfs.txt | 3831 | F: Documentation/filesystems/dlmfs.txt |
3832 | F: fs/ocfs2/ | 3832 | F: fs/ocfs2/ |
3833 | 3833 | ||
3834 | ORINOCO DRIVER | 3834 | ORINOCO DRIVER |
3835 | M: Pavel Roskin <proski@gnu.org> | 3835 | M: Pavel Roskin <proski@gnu.org> |
3836 | M: David Gibson <hermes@gibson.dropbear.id.au> | 3836 | M: David Gibson <hermes@gibson.dropbear.id.au> |
3837 | L: linux-wireless@vger.kernel.org | 3837 | L: linux-wireless@vger.kernel.org |
3838 | L: orinoco-users@lists.sourceforge.net | 3838 | L: orinoco-users@lists.sourceforge.net |
3839 | L: orinoco-devel@lists.sourceforge.net | 3839 | L: orinoco-devel@lists.sourceforge.net |
3840 | W: http://www.nongnu.org/orinoco/ | 3840 | W: http://www.nongnu.org/orinoco/ |
3841 | S: Maintained | 3841 | S: Maintained |
3842 | F: drivers/net/wireless/orinoco/ | 3842 | F: drivers/net/wireless/orinoco/ |
3843 | 3843 | ||
3844 | OSD LIBRARY and FILESYSTEM | 3844 | OSD LIBRARY and FILESYSTEM |
3845 | M: Boaz Harrosh <bharrosh@panasas.com> | 3845 | M: Boaz Harrosh <bharrosh@panasas.com> |
3846 | M: Benny Halevy <bhalevy@panasas.com> | 3846 | M: Benny Halevy <bhalevy@panasas.com> |
3847 | L: osd-dev@open-osd.org | 3847 | L: osd-dev@open-osd.org |
3848 | W: http://open-osd.org | 3848 | W: http://open-osd.org |
3849 | T: git git://git.open-osd.org/open-osd.git | 3849 | T: git git://git.open-osd.org/open-osd.git |
3850 | S: Maintained | 3850 | S: Maintained |
3851 | F: drivers/scsi/osd/ | 3851 | F: drivers/scsi/osd/ |
3852 | F: include/scsi/osd_* | 3852 | F: include/scsi/osd_* |
3853 | F: fs/exofs/ | 3853 | F: fs/exofs/ |
3854 | 3854 | ||
3855 | P54 WIRELESS DRIVER | 3855 | P54 WIRELESS DRIVER |
3856 | M: Michael Wu <flamingice@sourmilk.net> | 3856 | M: Michael Wu <flamingice@sourmilk.net> |
3857 | L: linux-wireless@vger.kernel.org | 3857 | L: linux-wireless@vger.kernel.org |
3858 | W: http://prism54.org | 3858 | W: http://prism54.org |
3859 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git | 3859 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git |
3860 | S: Maintained | 3860 | S: Maintained |
3861 | F: drivers/net/wireless/p54/ | 3861 | F: drivers/net/wireless/p54/ |
3862 | 3862 | ||
3863 | PA SEMI ETHERNET DRIVER | 3863 | PA SEMI ETHERNET DRIVER |
3864 | M: Olof Johansson <olof@lixom.net> | 3864 | M: Olof Johansson <olof@lixom.net> |
3865 | L: netdev@vger.kernel.org | 3865 | L: netdev@vger.kernel.org |
3866 | S: Maintained | 3866 | S: Maintained |
3867 | F: drivers/net/pasemi_mac.* | 3867 | F: drivers/net/pasemi_mac.* |
3868 | 3868 | ||
3869 | PA SEMI SMBUS DRIVER | 3869 | PA SEMI SMBUS DRIVER |
3870 | M: Olof Johansson <olof@lixom.net> | 3870 | M: Olof Johansson <olof@lixom.net> |
3871 | L: linux-i2c@vger.kernel.org | 3871 | L: linux-i2c@vger.kernel.org |
3872 | S: Maintained | 3872 | S: Maintained |
3873 | F: drivers/i2c/busses/i2c-pasemi.c | 3873 | F: drivers/i2c/busses/i2c-pasemi.c |
3874 | 3874 | ||
3875 | PANASONIC LAPTOP ACPI EXTRAS DRIVER | 3875 | PANASONIC LAPTOP ACPI EXTRAS DRIVER |
3876 | M: Harald Welte <laforge@gnumonks.org> | 3876 | M: Harald Welte <laforge@gnumonks.org> |
3877 | S: Maintained | 3877 | S: Maintained |
3878 | F: drivers/platform/x86/panasonic-laptop.c | 3878 | F: drivers/platform/x86/panasonic-laptop.c |
3879 | 3879 | ||
3880 | PANASONIC MN10300/AM33 PORT | 3880 | PANASONIC MN10300/AM33 PORT |
3881 | M: David Howells <dhowells@redhat.com> | 3881 | M: David Howells <dhowells@redhat.com> |
3882 | M: Koichi Yasutake <yasutake.koichi@jp.panasonic.com> | 3882 | M: Koichi Yasutake <yasutake.koichi@jp.panasonic.com> |
3883 | L: linux-am33-list@redhat.com (moderated for non-subscribers) | 3883 | L: linux-am33-list@redhat.com (moderated for non-subscribers) |
3884 | W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/ | 3884 | W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/ |
3885 | S: Maintained | 3885 | S: Maintained |
3886 | F: Documentation/mn10300/ | 3886 | F: Documentation/mn10300/ |
3887 | F: arch/mn10300/ | 3887 | F: arch/mn10300/ |
3888 | 3888 | ||
3889 | PARALLEL PORT SUPPORT | 3889 | PARALLEL PORT SUPPORT |
3890 | L: linux-parport@lists.infradead.org (subscribers-only) | 3890 | L: linux-parport@lists.infradead.org (subscribers-only) |
3891 | S: Orphan | 3891 | S: Orphan |
3892 | F: drivers/parport/ | 3892 | F: drivers/parport/ |
3893 | F: include/linux/parport*.h | 3893 | F: include/linux/parport*.h |
3894 | F: drivers/char/ppdev.c | 3894 | F: drivers/char/ppdev.c |
3895 | F: include/linux/ppdev.h | 3895 | F: include/linux/ppdev.h |
3896 | 3896 | ||
3897 | PARAVIRT_OPS INTERFACE | 3897 | PARAVIRT_OPS INTERFACE |
3898 | M: Jeremy Fitzhardinge <jeremy@xensource.com> | 3898 | M: Jeremy Fitzhardinge <jeremy@xensource.com> |
3899 | M: Chris Wright <chrisw@sous-sol.org> | 3899 | M: Chris Wright <chrisw@sous-sol.org> |
3900 | M: Alok Kataria <akataria@vmware.com> | 3900 | M: Alok Kataria <akataria@vmware.com> |
3901 | M: Rusty Russell <rusty@rustcorp.com.au> | 3901 | M: Rusty Russell <rusty@rustcorp.com.au> |
3902 | L: virtualization@lists.osdl.org | 3902 | L: virtualization@lists.osdl.org |
3903 | S: Supported | 3903 | S: Supported |
3904 | F: Documentation/ia64/paravirt_ops.txt | 3904 | F: Documentation/ia64/paravirt_ops.txt |
3905 | F: arch/*/kernel/paravirt* | 3905 | F: arch/*/kernel/paravirt* |
3906 | F: arch/*/include/asm/paravirt.h | 3906 | F: arch/*/include/asm/paravirt.h |
3907 | 3907 | ||
3908 | PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES | 3908 | PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES |
3909 | M: Tim Waugh <tim@cyberelk.net> | 3909 | M: Tim Waugh <tim@cyberelk.net> |
3910 | L: linux-parport@lists.infradead.org (subscribers-only) | 3910 | L: linux-parport@lists.infradead.org (subscribers-only) |
3911 | W: http://www.torque.net/linux-pp.html | 3911 | W: http://www.torque.net/linux-pp.html |
3912 | S: Maintained | 3912 | S: Maintained |
3913 | F: Documentation/blockdev/paride.txt | 3913 | F: Documentation/blockdev/paride.txt |
3914 | F: drivers/block/paride/ | 3914 | F: drivers/block/paride/ |
3915 | 3915 | ||
3916 | PARISC ARCHITECTURE | 3916 | PARISC ARCHITECTURE |
3917 | M: Kyle McMartin <kyle@mcmartin.ca> | 3917 | M: Kyle McMartin <kyle@mcmartin.ca> |
3918 | M: Helge Deller <deller@gmx.de> | 3918 | M: Helge Deller <deller@gmx.de> |
3919 | L: linux-parisc@vger.kernel.org | 3919 | L: linux-parisc@vger.kernel.org |
3920 | W: http://www.parisc-linux.org/ | 3920 | W: http://www.parisc-linux.org/ |
3921 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git | 3921 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git |
3922 | S: Maintained | 3922 | S: Maintained |
3923 | F: arch/parisc/ | 3923 | F: arch/parisc/ |
3924 | F: drivers/parisc/ | 3924 | F: drivers/parisc/ |
3925 | 3925 | ||
3926 | PC87360 HARDWARE MONITORING DRIVER | 3926 | PC87360 HARDWARE MONITORING DRIVER |
3927 | M: Jim Cromie <jim.cromie@gmail.com> | 3927 | M: Jim Cromie <jim.cromie@gmail.com> |
3928 | L: lm-sensors@lm-sensors.org | 3928 | L: lm-sensors@lm-sensors.org |
3929 | S: Maintained | 3929 | S: Maintained |
3930 | F: Documentation/hwmon/pc87360 | 3930 | F: Documentation/hwmon/pc87360 |
3931 | F: drivers/hwmon/pc87360.c | 3931 | F: drivers/hwmon/pc87360.c |
3932 | 3932 | ||
3933 | PC8736x GPIO DRIVER | 3933 | PC8736x GPIO DRIVER |
3934 | M: Jim Cromie <jim.cromie@gmail.com> | 3934 | M: Jim Cromie <jim.cromie@gmail.com> |
3935 | S: Maintained | 3935 | S: Maintained |
3936 | F: drivers/char/pc8736x_gpio.c | 3936 | F: drivers/char/pc8736x_gpio.c |
3937 | 3937 | ||
3938 | PCA9532 LED DRIVER | 3938 | PCA9532 LED DRIVER |
3939 | M: Riku Voipio <riku.voipio@iki.fi> | 3939 | M: Riku Voipio <riku.voipio@iki.fi> |
3940 | S: Maintained | 3940 | S: Maintained |
3941 | F: drivers/leds/leds-pca9532.c | 3941 | F: drivers/leds/leds-pca9532.c |
3942 | F: include/linux/leds-pca9532.h | 3942 | F: include/linux/leds-pca9532.h |
3943 | 3943 | ||
3944 | PCI ERROR RECOVERY | 3944 | PCI ERROR RECOVERY |
3945 | M: Linas Vepstas <linas@austin.ibm.com> | 3945 | M: Linas Vepstas <linas@austin.ibm.com> |
3946 | L: linux-pci@vger.kernel.org | 3946 | L: linux-pci@vger.kernel.org |
3947 | S: Supported | 3947 | S: Supported |
3948 | F: Documentation/PCI/pci-error-recovery.txt | 3948 | F: Documentation/PCI/pci-error-recovery.txt |
3949 | F: Documentation/powerpc/eeh-pci-error-recovery.txt | 3949 | F: Documentation/powerpc/eeh-pci-error-recovery.txt |
3950 | 3950 | ||
3951 | PCI SUBSYSTEM | 3951 | PCI SUBSYSTEM |
3952 | M: Jesse Barnes <jbarnes@virtuousgeek.org> | 3952 | M: Jesse Barnes <jbarnes@virtuousgeek.org> |
3953 | L: linux-pci@vger.kernel.org | 3953 | L: linux-pci@vger.kernel.org |
3954 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git | 3954 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git |
3955 | S: Supported | 3955 | S: Supported |
3956 | F: Documentation/PCI/ | 3956 | F: Documentation/PCI/ |
3957 | F: drivers/pci/ | 3957 | F: drivers/pci/ |
3958 | F: include/linux/pci* | 3958 | F: include/linux/pci* |
3959 | 3959 | ||
3960 | PCIE HOTPLUG DRIVER | 3960 | PCIE HOTPLUG DRIVER |
3961 | M: Kristen Carlson Accardi <kristen.c.accardi@intel.com> | 3961 | M: Kristen Carlson Accardi <kristen.c.accardi@intel.com> |
3962 | L: linux-pci@vger.kernel.org | 3962 | L: linux-pci@vger.kernel.org |
3963 | S: Supported | 3963 | S: Supported |
3964 | F: drivers/pci/pcie/ | 3964 | F: drivers/pci/pcie/ |
3965 | 3965 | ||
3966 | PCMCIA SUBSYSTEM | 3966 | PCMCIA SUBSYSTEM |
3967 | P: Linux PCMCIA Team | 3967 | P: Linux PCMCIA Team |
3968 | L: linux-pcmcia@lists.infradead.org | 3968 | L: linux-pcmcia@lists.infradead.org |
3969 | W: http://lists.infradead.org/mailman/listinfo/linux-pcmcia | 3969 | W: http://lists.infradead.org/mailman/listinfo/linux-pcmcia |
3970 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git | 3970 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git |
3971 | S: Maintained | 3971 | S: Maintained |
3972 | F: Documentation/pcmcia/ | 3972 | F: Documentation/pcmcia/ |
3973 | F: drivers/pcmcia/ | 3973 | F: drivers/pcmcia/ |
3974 | F: include/pcmcia/ | 3974 | F: include/pcmcia/ |
3975 | 3975 | ||
3976 | PCNET32 NETWORK DRIVER | 3976 | PCNET32 NETWORK DRIVER |
3977 | M: Don Fry <pcnet32@verizon.net> | 3977 | M: Don Fry <pcnet32@verizon.net> |
3978 | L: netdev@vger.kernel.org | 3978 | L: netdev@vger.kernel.org |
3979 | S: Maintained | 3979 | S: Maintained |
3980 | F: drivers/net/pcnet32.c | 3980 | F: drivers/net/pcnet32.c |
3981 | 3981 | ||
3982 | PER-TASK DELAY ACCOUNTING | 3982 | PER-TASK DELAY ACCOUNTING |
3983 | M: Balbir Singh <balbir@linux.vnet.ibm.com> | 3983 | M: Balbir Singh <balbir@linux.vnet.ibm.com> |
3984 | S: Maintained | 3984 | S: Maintained |
3985 | F: include/linux/delayacct.h | 3985 | F: include/linux/delayacct.h |
3986 | F: kernel/delayacct.c | 3986 | F: kernel/delayacct.c |
3987 | 3987 | ||
3988 | PERFORMANCE COUNTER SUBSYSTEM | 3988 | PERFORMANCE COUNTER SUBSYSTEM |
3989 | M: Peter Zijlstra <a.p.zijlstra@chello.nl> | 3989 | M: Peter Zijlstra <a.p.zijlstra@chello.nl> |
3990 | M: Paul Mackerras <paulus@samba.org> | 3990 | M: Paul Mackerras <paulus@samba.org> |
3991 | M: Ingo Molnar <mingo@elte.hu> | 3991 | M: Ingo Molnar <mingo@elte.hu> |
3992 | S: Supported | 3992 | S: Supported |
3993 | 3993 | ||
3994 | PERSONALITY HANDLING | 3994 | PERSONALITY HANDLING |
3995 | M: Christoph Hellwig <hch@infradead.org> | 3995 | M: Christoph Hellwig <hch@infradead.org> |
3996 | L: linux-abi-devel@lists.sourceforge.net | 3996 | L: linux-abi-devel@lists.sourceforge.net |
3997 | S: Maintained | 3997 | S: Maintained |
3998 | F: include/linux/personality.h | 3998 | F: include/linux/personality.h |
3999 | 3999 | ||
4000 | PHRAM MTD DRIVER | 4000 | PHRAM MTD DRIVER |
4001 | M: Joern Engel <joern@lazybastard.org> | 4001 | M: Joern Engel <joern@lazybastard.org> |
4002 | L: linux-mtd@lists.infradead.org | 4002 | L: linux-mtd@lists.infradead.org |
4003 | S: Maintained | 4003 | S: Maintained |
4004 | F: drivers/mtd/devices/phram.c | 4004 | F: drivers/mtd/devices/phram.c |
4005 | 4005 | ||
4006 | PKTCDVD DRIVER | 4006 | PKTCDVD DRIVER |
4007 | M: Peter Osterlund <petero2@telia.com> | 4007 | M: Peter Osterlund <petero2@telia.com> |
4008 | S: Maintained | 4008 | S: Maintained |
4009 | F: drivers/block/pktcdvd.c | 4009 | F: drivers/block/pktcdvd.c |
4010 | F: include/linux/pktcdvd.h | 4010 | F: include/linux/pktcdvd.h |
4011 | 4011 | ||
4012 | PMC SIERRA MaxRAID DRIVER | 4012 | PMC SIERRA MaxRAID DRIVER |
4013 | P: Anil Ravindranath | 4013 | P: Anil Ravindranath |
4014 | M: anil_ravindranath@pmc-sierra.com | 4014 | M: anil_ravindranath@pmc-sierra.com |
4015 | L: linux-scsi@vger.kernel.org | 4015 | L: linux-scsi@vger.kernel.org |
4016 | W: http://www.pmc-sierra.com/ | 4016 | W: http://www.pmc-sierra.com/ |
4017 | S: Supported | 4017 | S: Supported |
4018 | F: drivers/scsi/pmcraid.* | 4018 | F: drivers/scsi/pmcraid.* |
4019 | 4019 | ||
4020 | POSIX CLOCKS and TIMERS | 4020 | POSIX CLOCKS and TIMERS |
4021 | M: Thomas Gleixner <tglx@linutronix.de> | 4021 | M: Thomas Gleixner <tglx@linutronix.de> |
4022 | S: Supported | 4022 | S: Supported |
4023 | F: fs/timerfd.c | 4023 | F: fs/timerfd.c |
4024 | F: include/linux/timer* | 4024 | F: include/linux/timer* |
4025 | F: kernel/*timer* | 4025 | F: kernel/*timer* |
4026 | 4026 | ||
4027 | POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS | 4027 | POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS |
4028 | M: Anton Vorontsov <cbou@mail.ru> | 4028 | M: Anton Vorontsov <cbou@mail.ru> |
4029 | M: David Woodhouse <dwmw2@infradead.org> | 4029 | M: David Woodhouse <dwmw2@infradead.org> |
4030 | T: git git://git.infradead.org/battery-2.6.git | 4030 | T: git git://git.infradead.org/battery-2.6.git |
4031 | S: Maintained | 4031 | S: Maintained |
4032 | F: include/linux/power_supply.h | 4032 | F: include/linux/power_supply.h |
4033 | F: drivers/power/power_supply* | 4033 | F: drivers/power/power_supply* |
4034 | 4034 | ||
4035 | PNP SUPPORT | 4035 | PNP SUPPORT |
4036 | M: Adam Belay <abelay@mit.edu> | 4036 | M: Adam Belay <abelay@mit.edu> |
4037 | M: Bjorn Helgaas <bjorn.helgaas@hp.com> | 4037 | M: Bjorn Helgaas <bjorn.helgaas@hp.com> |
4038 | S: Maintained | 4038 | S: Maintained |
4039 | F: drivers/pnp/ | 4039 | F: drivers/pnp/ |
4040 | 4040 | ||
4041 | PNXxxxx I2C DRIVER | 4041 | PNXxxxx I2C DRIVER |
4042 | M: Vitaly Wool <vitalywool@gmail.com> | 4042 | M: Vitaly Wool <vitalywool@gmail.com> |
4043 | L: linux-i2c@vger.kernel.org | 4043 | L: linux-i2c@vger.kernel.org |
4044 | S: Maintained | 4044 | S: Maintained |
4045 | F: drivers/i2c/busses/i2c-pnx.c | 4045 | F: drivers/i2c/busses/i2c-pnx.c |
4046 | 4046 | ||
4047 | PPP PROTOCOL DRIVERS AND COMPRESSORS | 4047 | PPP PROTOCOL DRIVERS AND COMPRESSORS |
4048 | M: Paul Mackerras <paulus@samba.org> | 4048 | M: Paul Mackerras <paulus@samba.org> |
4049 | L: linux-ppp@vger.kernel.org | 4049 | L: linux-ppp@vger.kernel.org |
4050 | S: Maintained | 4050 | S: Maintained |
4051 | F: drivers/net/ppp_* | 4051 | F: drivers/net/ppp_* |
4052 | 4052 | ||
4053 | PPP OVER ATM (RFC 2364) | 4053 | PPP OVER ATM (RFC 2364) |
4054 | M: Mitchell Blank Jr <mitch@sfgoth.com> | 4054 | M: Mitchell Blank Jr <mitch@sfgoth.com> |
4055 | S: Maintained | 4055 | S: Maintained |
4056 | F: net/atm/pppoatm.c | 4056 | F: net/atm/pppoatm.c |
4057 | F: include/linux/atmppp.h | 4057 | F: include/linux/atmppp.h |
4058 | 4058 | ||
4059 | PPP OVER ETHERNET | 4059 | PPP OVER ETHERNET |
4060 | M: Michal Ostrowski <mostrows@earthlink.net> | 4060 | M: Michal Ostrowski <mostrows@earthlink.net> |
4061 | S: Maintained | 4061 | S: Maintained |
4062 | F: drivers/net/pppoe.c | 4062 | F: drivers/net/pppoe.c |
4063 | F: drivers/net/pppox.c | 4063 | F: drivers/net/pppox.c |
4064 | 4064 | ||
4065 | PPP OVER L2TP | 4065 | PPP OVER L2TP |
4066 | M: James Chapman <jchapman@katalix.com> | 4066 | M: James Chapman <jchapman@katalix.com> |
4067 | S: Maintained | 4067 | S: Maintained |
4068 | F: drivers/net/pppol2tp.c | 4068 | F: drivers/net/pppol2tp.c |
4069 | F: include/linux/if_pppol2tp.h | 4069 | F: include/linux/if_pppol2tp.h |
4070 | 4070 | ||
4071 | PPS SUPPORT | 4071 | PPS SUPPORT |
4072 | M: Rodolfo Giometti <giometti@enneenne.com> | 4072 | M: Rodolfo Giometti <giometti@enneenne.com> |
4073 | W: http://wiki.enneenne.com/index.php/LinuxPPS_support | 4073 | W: http://wiki.enneenne.com/index.php/LinuxPPS_support |
4074 | L: linuxpps@ml.enneenne.com (subscribers-only) | 4074 | L: linuxpps@ml.enneenne.com (subscribers-only) |
4075 | S: Maintained | 4075 | S: Maintained |
4076 | F: Documentation/pps/ | 4076 | F: Documentation/pps/ |
4077 | F: drivers/pps/ | 4077 | F: drivers/pps/ |
4078 | F: include/linux/pps*.h | 4078 | F: include/linux/pps*.h |
4079 | 4079 | ||
4080 | PREEMPTIBLE KERNEL | 4080 | PREEMPTIBLE KERNEL |
4081 | M: Robert Love <rml@tech9.net> | 4081 | M: Robert Love <rml@tech9.net> |
4082 | L: kpreempt-tech@lists.sourceforge.net | 4082 | L: kpreempt-tech@lists.sourceforge.net |
4083 | W: ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel | 4083 | W: ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel |
4084 | S: Supported | 4084 | S: Supported |
4085 | F: Documentation/preempt-locking.txt | 4085 | F: Documentation/preempt-locking.txt |
4086 | F: include/linux/preempt.h | 4086 | F: include/linux/preempt.h |
4087 | 4087 | ||
4088 | PRISM54 WIRELESS DRIVER | 4088 | PRISM54 WIRELESS DRIVER |
4089 | M: "Luis R. Rodriguez" <mcgrof@gmail.com> | 4089 | M: "Luis R. Rodriguez" <mcgrof@gmail.com> |
4090 | L: linux-wireless@vger.kernel.org | 4090 | L: linux-wireless@vger.kernel.org |
4091 | W: http://prism54.org | 4091 | W: http://prism54.org |
4092 | S: Maintained | 4092 | S: Maintained |
4093 | F: drivers/net/wireless/prism54/ | 4093 | F: drivers/net/wireless/prism54/ |
4094 | 4094 | ||
4095 | PROMISE DC4030 CACHING DISK CONTROLLER DRIVER | 4095 | PROMISE DC4030 CACHING DISK CONTROLLER DRIVER |
4096 | M: Peter Denison <promise@pnd-pc.demon.co.uk> | 4096 | M: Peter Denison <promise@pnd-pc.demon.co.uk> |
4097 | W: http://www.pnd-pc.demon.co.uk/promise/ | 4097 | W: http://www.pnd-pc.demon.co.uk/promise/ |
4098 | S: Maintained | 4098 | S: Maintained |
4099 | 4099 | ||
4100 | PROMISE SATA TX2/TX4 CONTROLLER LIBATA DRIVER | 4100 | PROMISE SATA TX2/TX4 CONTROLLER LIBATA DRIVER |
4101 | M: Mikael Pettersson <mikpe@it.uu.se> | 4101 | M: Mikael Pettersson <mikpe@it.uu.se> |
4102 | L: linux-ide@vger.kernel.org | 4102 | L: linux-ide@vger.kernel.org |
4103 | S: Maintained | 4103 | S: Maintained |
4104 | F: drivers/ata/sata_promise.* | 4104 | F: drivers/ata/sata_promise.* |
4105 | 4105 | ||
4106 | PS3 NETWORK SUPPORT | 4106 | PS3 NETWORK SUPPORT |
4107 | M: Geoff Levand <geoffrey.levand@am.sony.com> | 4107 | M: Geoff Levand <geoffrey.levand@am.sony.com> |
4108 | L: netdev@vger.kernel.org | 4108 | L: netdev@vger.kernel.org |
4109 | L: cbe-oss-dev@ozlabs.org | 4109 | L: cbe-oss-dev@ozlabs.org |
4110 | S: Supported | 4110 | S: Supported |
4111 | F: drivers/net/ps3_gelic_net.* | 4111 | F: drivers/net/ps3_gelic_net.* |
4112 | 4112 | ||
4113 | PS3 PLATFORM SUPPORT | 4113 | PS3 PLATFORM SUPPORT |
4114 | M: Geoff Levand <geoffrey.levand@am.sony.com> | 4114 | M: Geoff Levand <geoffrey.levand@am.sony.com> |
4115 | L: linuxppc-dev@ozlabs.org | 4115 | L: linuxppc-dev@ozlabs.org |
4116 | L: cbe-oss-dev@ozlabs.org | 4116 | L: cbe-oss-dev@ozlabs.org |
4117 | S: Supported | 4117 | S: Supported |
4118 | F: arch/powerpc/boot/ps3* | 4118 | F: arch/powerpc/boot/ps3* |
4119 | F: arch/powerpc/include/asm/lv1call.h | 4119 | F: arch/powerpc/include/asm/lv1call.h |
4120 | F: arch/powerpc/include/asm/ps3*.h | 4120 | F: arch/powerpc/include/asm/ps3*.h |
4121 | F: arch/powerpc/platforms/ps3/ | 4121 | F: arch/powerpc/platforms/ps3/ |
4122 | F: drivers/*/ps3* | 4122 | F: drivers/*/ps3* |
4123 | F: drivers/ps3/ | 4123 | F: drivers/ps3/ |
4124 | F: drivers/rtc/rtc-ps3.c | 4124 | F: drivers/rtc/rtc-ps3.c |
4125 | F: drivers/usb/host/*ps3.c | 4125 | F: drivers/usb/host/*ps3.c |
4126 | F: sound/ppc/snd_ps3* | 4126 | F: sound/ppc/snd_ps3* |
4127 | 4127 | ||
4128 | PS3VRAM DRIVER | 4128 | PS3VRAM DRIVER |
4129 | M: Jim Paris <jim@jtan.com> | 4129 | M: Jim Paris <jim@jtan.com> |
4130 | L: cbe-oss-dev@ozlabs.org | 4130 | L: cbe-oss-dev@ozlabs.org |
4131 | S: Maintained | 4131 | S: Maintained |
4132 | 4132 | ||
4133 | PTRACE SUPPORT | 4133 | PTRACE SUPPORT |
4134 | M: Roland McGrath <roland@redhat.com> | 4134 | M: Roland McGrath <roland@redhat.com> |
4135 | M: Oleg Nesterov <oleg@redhat.com> | 4135 | M: Oleg Nesterov <oleg@redhat.com> |
4136 | S: Maintained | 4136 | S: Maintained |
4137 | F: include/asm-generic/syscall.h | 4137 | F: include/asm-generic/syscall.h |
4138 | F: include/linux/ptrace.h | 4138 | F: include/linux/ptrace.h |
4139 | F: include/linux/regset.h | 4139 | F: include/linux/regset.h |
4140 | F: include/linux/tracehook.h | 4140 | F: include/linux/tracehook.h |
4141 | F: kernel/ptrace.c | 4141 | F: kernel/ptrace.c |
4142 | 4142 | ||
4143 | PVRUSB2 VIDEO4LINUX DRIVER | 4143 | PVRUSB2 VIDEO4LINUX DRIVER |
4144 | M: Mike Isely <isely@pobox.com> | 4144 | M: Mike Isely <isely@pobox.com> |
4145 | L: pvrusb2@isely.net (subscribers-only) | 4145 | L: pvrusb2@isely.net (subscribers-only) |
4146 | L: linux-media@vger.kernel.org | 4146 | L: linux-media@vger.kernel.org |
4147 | W: http://www.isely.net/pvrusb2/ | 4147 | W: http://www.isely.net/pvrusb2/ |
4148 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 4148 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
4149 | S: Maintained | 4149 | S: Maintained |
4150 | F: Documentation/video4linux/README.pvrusb2 | 4150 | F: Documentation/video4linux/README.pvrusb2 |
4151 | F: drivers/media/video/pvrusb2/ | 4151 | F: drivers/media/video/pvrusb2/ |
4152 | 4152 | ||
4153 | PXA2xx/PXA3xx SUPPORT | 4153 | PXA2xx/PXA3xx SUPPORT |
4154 | M: Eric Miao <eric.y.miao@gmail.com> | 4154 | M: Eric Miao <eric.y.miao@gmail.com> |
4155 | M: Russell King <linux@arm.linux.org.uk> | 4155 | M: Russell King <linux@arm.linux.org.uk> |
4156 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 4156 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
4157 | S: Maintained | 4157 | S: Maintained |
4158 | F: arch/arm/mach-pxa/ | 4158 | F: arch/arm/mach-pxa/ |
4159 | F: drivers/pcmcia/pxa2xx* | 4159 | F: drivers/pcmcia/pxa2xx* |
4160 | F: drivers/spi/pxa2xx* | 4160 | F: drivers/spi/pxa2xx* |
4161 | F: drivers/usb/gadget/pxa2* | 4161 | F: drivers/usb/gadget/pxa2* |
4162 | F: include/sound/pxa2xx-lib.h | 4162 | F: include/sound/pxa2xx-lib.h |
4163 | F: sound/arm/pxa* | 4163 | F: sound/arm/pxa* |
4164 | F: sound/soc/pxa | 4164 | F: sound/soc/pxa |
4165 | 4165 | ||
4166 | PXA168 SUPPORT | 4166 | PXA168 SUPPORT |
4167 | M: Eric Miao <eric.y.miao@gmail.com> | 4167 | M: Eric Miao <eric.y.miao@gmail.com> |
4168 | M: Jason Chagas <jason.chagas@marvell.com> | 4168 | M: Jason Chagas <jason.chagas@marvell.com> |
4169 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 4169 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
4170 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git | 4170 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git |
4171 | S: Maintained | 4171 | S: Maintained |
4172 | 4172 | ||
4173 | PXA910 SUPPORT | 4173 | PXA910 SUPPORT |
4174 | M: Eric Miao <eric.y.miao@gmail.com> | 4174 | M: Eric Miao <eric.y.miao@gmail.com> |
4175 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 4175 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
4176 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git | 4176 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git |
4177 | S: Maintained | 4177 | S: Maintained |
4178 | 4178 | ||
4179 | PXA MMCI DRIVER | 4179 | PXA MMCI DRIVER |
4180 | S: Orphan | 4180 | S: Orphan |
4181 | 4181 | ||
4182 | PXA RTC DRIVER | 4182 | PXA RTC DRIVER |
4183 | M: Robert Jarzmik <robert.jarzmik@free.fr> | 4183 | M: Robert Jarzmik <robert.jarzmik@free.fr> |
4184 | L: rtc-linux@googlegroups.com | 4184 | L: rtc-linux@googlegroups.com |
4185 | S: Maintained | 4185 | S: Maintained |
4186 | 4186 | ||
4187 | QLOGIC QLA2XXX FC-SCSI DRIVER | 4187 | QLOGIC QLA2XXX FC-SCSI DRIVER |
4188 | M: Andrew Vasquez <andrew.vasquez@qlogic.com> | 4188 | M: Andrew Vasquez <andrew.vasquez@qlogic.com> |
4189 | M: linux-driver@qlogic.com | 4189 | M: linux-driver@qlogic.com |
4190 | L: linux-scsi@vger.kernel.org | 4190 | L: linux-scsi@vger.kernel.org |
4191 | S: Supported | 4191 | S: Supported |
4192 | F: Documentation/scsi/LICENSE.qla2xxx | 4192 | F: Documentation/scsi/LICENSE.qla2xxx |
4193 | F: drivers/scsi/qla2xxx/ | 4193 | F: drivers/scsi/qla2xxx/ |
4194 | 4194 | ||
4195 | QLOGIC QLA3XXX NETWORK DRIVER | 4195 | QLOGIC QLA3XXX NETWORK DRIVER |
4196 | M: Ron Mercer <ron.mercer@qlogic.com> | 4196 | M: Ron Mercer <ron.mercer@qlogic.com> |
4197 | M: linux-driver@qlogic.com | 4197 | M: linux-driver@qlogic.com |
4198 | L: netdev@vger.kernel.org | 4198 | L: netdev@vger.kernel.org |
4199 | S: Supported | 4199 | S: Supported |
4200 | F: Documentation/networking/LICENSE.qla3xxx | 4200 | F: Documentation/networking/LICENSE.qla3xxx |
4201 | F: drivers/net/qla3xxx.* | 4201 | F: drivers/net/qla3xxx.* |
4202 | 4202 | ||
4203 | QLOGIC QLGE 10Gb ETHERNET DRIVER | 4203 | QLOGIC QLGE 10Gb ETHERNET DRIVER |
4204 | M: Ron Mercer <ron.mercer@qlogic.com> | 4204 | M: Ron Mercer <ron.mercer@qlogic.com> |
4205 | M: linux-driver@qlogic.com | 4205 | M: linux-driver@qlogic.com |
4206 | L: netdev@vger.kernel.org | 4206 | L: netdev@vger.kernel.org |
4207 | S: Supported | 4207 | S: Supported |
4208 | F: drivers/net/qlge/ | 4208 | F: drivers/net/qlge/ |
4209 | 4209 | ||
4210 | QNX4 FILESYSTEM | 4210 | QNX4 FILESYSTEM |
4211 | M: Anders Larsen <al@alarsen.net> | 4211 | M: Anders Larsen <al@alarsen.net> |
4212 | W: http://www.alarsen.net/linux/qnx4fs/ | 4212 | W: http://www.alarsen.net/linux/qnx4fs/ |
4213 | S: Maintained | 4213 | S: Maintained |
4214 | F: fs/qnx4/ | 4214 | F: fs/qnx4/ |
4215 | F: include/linux/qnx4_fs.h | 4215 | F: include/linux/qnx4_fs.h |
4216 | F: include/linux/qnxtypes.h | 4216 | F: include/linux/qnxtypes.h |
4217 | 4217 | ||
4218 | RADEON FRAMEBUFFER DISPLAY DRIVER | 4218 | RADEON FRAMEBUFFER DISPLAY DRIVER |
4219 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 4219 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
4220 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4220 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
4221 | S: Maintained | 4221 | S: Maintained |
4222 | F: drivers/video/aty/radeon* | 4222 | F: drivers/video/aty/radeon* |
4223 | F: include/linux/radeonfb.h | 4223 | F: include/linux/radeonfb.h |
4224 | 4224 | ||
4225 | RAGE128 FRAMEBUFFER DISPLAY DRIVER | 4225 | RAGE128 FRAMEBUFFER DISPLAY DRIVER |
4226 | M: Paul Mackerras <paulus@samba.org> | 4226 | M: Paul Mackerras <paulus@samba.org> |
4227 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4227 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
4228 | S: Maintained | 4228 | S: Maintained |
4229 | F: drivers/video/aty/aty128fb.c | 4229 | F: drivers/video/aty/aty128fb.c |
4230 | 4230 | ||
4231 | RALINK RT2X00 WIRELESS LAN DRIVER | 4231 | RALINK RT2X00 WIRELESS LAN DRIVER |
4232 | P: rt2x00 project | 4232 | P: rt2x00 project |
4233 | L: linux-wireless@vger.kernel.org | 4233 | L: linux-wireless@vger.kernel.org |
4234 | L: users@rt2x00.serialmonkey.com | 4234 | L: users@rt2x00.serialmonkey.com |
4235 | W: http://rt2x00.serialmonkey.com/ | 4235 | W: http://rt2x00.serialmonkey.com/ |
4236 | S: Maintained | 4236 | S: Maintained |
4237 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git | 4237 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git |
4238 | F: drivers/net/wireless/rt2x00/ | 4238 | F: drivers/net/wireless/rt2x00/ |
4239 | 4239 | ||
4240 | RAMDISK RAM BLOCK DEVICE DRIVER | 4240 | RAMDISK RAM BLOCK DEVICE DRIVER |
4241 | M: Nick Piggin <npiggin@suse.de> | 4241 | M: Nick Piggin <npiggin@suse.de> |
4242 | S: Maintained | 4242 | S: Maintained |
4243 | F: Documentation/blockdev/ramdisk.txt | 4243 | F: Documentation/blockdev/ramdisk.txt |
4244 | F: drivers/block/brd.c | 4244 | F: drivers/block/brd.c |
4245 | 4245 | ||
4246 | RANDOM NUMBER DRIVER | 4246 | RANDOM NUMBER DRIVER |
4247 | M: Matt Mackall <mpm@selenic.com> | 4247 | M: Matt Mackall <mpm@selenic.com> |
4248 | S: Maintained | 4248 | S: Maintained |
4249 | F: drivers/char/random.c | 4249 | F: drivers/char/random.c |
4250 | 4250 | ||
4251 | RAPIDIO SUBSYSTEM | 4251 | RAPIDIO SUBSYSTEM |
4252 | M: Matt Porter <mporter@kernel.crashing.org> | 4252 | M: Matt Porter <mporter@kernel.crashing.org> |
4253 | S: Maintained | 4253 | S: Maintained |
4254 | F: drivers/rapidio/ | 4254 | F: drivers/rapidio/ |
4255 | 4255 | ||
4256 | RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER | 4256 | RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER |
4257 | M: Corey Thomas <coreythomas@charter.net> | 4257 | M: Corey Thomas <coreythomas@charter.net> |
4258 | L: linux-wireless@vger.kernel.org | 4258 | L: linux-wireless@vger.kernel.org |
4259 | S: Maintained | 4259 | S: Maintained |
4260 | F: drivers/net/wireless/ray* | 4260 | F: drivers/net/wireless/ray* |
4261 | 4261 | ||
4262 | RCUTORTURE MODULE | 4262 | RCUTORTURE MODULE |
4263 | M: Josh Triplett <josh@freedesktop.org> | 4263 | M: Josh Triplett <josh@freedesktop.org> |
4264 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | 4264 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
4265 | S: Maintained | 4265 | S: Maintained |
4266 | F: Documentation/RCU/torture.txt | 4266 | F: Documentation/RCU/torture.txt |
4267 | F: kernel/rcutorture.c | 4267 | F: kernel/rcutorture.c |
4268 | 4268 | ||
4269 | RDC R-321X SoC | 4269 | RDC R-321X SoC |
4270 | M: Florian Fainelli <florian@openwrt.org> | 4270 | M: Florian Fainelli <florian@openwrt.org> |
4271 | S: Maintained | 4271 | S: Maintained |
4272 | 4272 | ||
4273 | RDC R6040 FAST ETHERNET DRIVER | 4273 | RDC R6040 FAST ETHERNET DRIVER |
4274 | M: Florian Fainelli <florian@openwrt.org> | 4274 | M: Florian Fainelli <florian@openwrt.org> |
4275 | L: netdev@vger.kernel.org | 4275 | L: netdev@vger.kernel.org |
4276 | S: Maintained | 4276 | S: Maintained |
4277 | F: drivers/net/r6040.c | 4277 | F: drivers/net/r6040.c |
4278 | 4278 | ||
4279 | RDS - RELIABLE DATAGRAM SOCKETS | 4279 | RDS - RELIABLE DATAGRAM SOCKETS |
4280 | M: Andy Grover <andy.grover@oracle.com> | 4280 | M: Andy Grover <andy.grover@oracle.com> |
4281 | L: rds-devel@oss.oracle.com (moderated for non-subscribers) | 4281 | L: rds-devel@oss.oracle.com (moderated for non-subscribers) |
4282 | S: Supported | 4282 | S: Supported |
4283 | F: net/rds/ | 4283 | F: net/rds/ |
4284 | 4284 | ||
4285 | READ-COPY UPDATE (RCU) | 4285 | READ-COPY UPDATE (RCU) |
4286 | M: Dipankar Sarma <dipankar@in.ibm.com> | 4286 | M: Dipankar Sarma <dipankar@in.ibm.com> |
4287 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | 4287 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
4288 | W: http://www.rdrop.com/users/paulmck/rclock/ | 4288 | W: http://www.rdrop.com/users/paulmck/rclock/ |
4289 | S: Supported | 4289 | S: Supported |
4290 | F: Documentation/RCU/rcu.txt | 4290 | F: Documentation/RCU/rcu.txt |
4291 | F: Documentation/RCU/rcuref.txt | 4291 | F: Documentation/RCU/rcuref.txt |
4292 | F: include/linux/rcupdate.h | 4292 | F: include/linux/rcupdate.h |
4293 | F: include/linux/srcu.h | 4293 | F: include/linux/srcu.h |
4294 | F: kernel/rcupdate.c | 4294 | F: kernel/rcupdate.c |
4295 | 4295 | ||
4296 | REAL TIME CLOCK DRIVER | 4296 | REAL TIME CLOCK DRIVER |
4297 | M: Paul Gortmaker <p_gortmaker@yahoo.com> | 4297 | M: Paul Gortmaker <p_gortmaker@yahoo.com> |
4298 | S: Maintained | 4298 | S: Maintained |
4299 | F: Documentation/rtc.txt | 4299 | F: Documentation/rtc.txt |
4300 | F: drivers/rtc/ | 4300 | F: drivers/rtc/ |
4301 | F: include/linux/rtc.h | 4301 | F: include/linux/rtc.h |
4302 | 4302 | ||
4303 | REAL TIME CLOCK (RTC) SUBSYSTEM | 4303 | REAL TIME CLOCK (RTC) SUBSYSTEM |
4304 | M: Alessandro Zummo <a.zummo@towertech.it> | 4304 | M: Alessandro Zummo <a.zummo@towertech.it> |
4305 | L: rtc-linux@googlegroups.com | 4305 | L: rtc-linux@googlegroups.com |
4306 | S: Maintained | 4306 | S: Maintained |
4307 | F: Documentation/rtc.txt | 4307 | F: Documentation/rtc.txt |
4308 | F: drivers/rtc/ | 4308 | F: drivers/rtc/ |
4309 | F: include/linux/rtc.h | 4309 | F: include/linux/rtc.h |
4310 | 4310 | ||
4311 | REISERFS FILE SYSTEM | 4311 | REISERFS FILE SYSTEM |
4312 | L: reiserfs-devel@vger.kernel.org | 4312 | L: reiserfs-devel@vger.kernel.org |
4313 | S: Supported | 4313 | S: Supported |
4314 | F: fs/reiserfs/ | 4314 | F: fs/reiserfs/ |
4315 | 4315 | ||
4316 | RFKILL | 4316 | RFKILL |
4317 | M: Johannes Berg <johannes@sipsolutions.net> | 4317 | M: Johannes Berg <johannes@sipsolutions.net> |
4318 | L: linux-wireless@vger.kernel.org | 4318 | L: linux-wireless@vger.kernel.org |
4319 | S: Maintained | 4319 | S: Maintained |
4320 | F Documentation/rfkill.txt | 4320 | F Documentation/rfkill.txt |
4321 | F: net/rfkill/ | 4321 | F: net/rfkill/ |
4322 | 4322 | ||
4323 | RISCOM8 DRIVER | 4323 | RISCOM8 DRIVER |
4324 | S: Orphan | 4324 | S: Orphan |
4325 | F: Documentation/serial/riscom8.txt | 4325 | F: Documentation/serial/riscom8.txt |
4326 | F: drivers/char/riscom8* | 4326 | F: drivers/char/riscom8* |
4327 | 4327 | ||
4328 | ROCKETPORT DRIVER | 4328 | ROCKETPORT DRIVER |
4329 | P: Comtrol Corp. | 4329 | P: Comtrol Corp. |
4330 | W: http://www.comtrol.com | 4330 | W: http://www.comtrol.com |
4331 | S: Maintained | 4331 | S: Maintained |
4332 | F: Documentation/serial/rocket.txt | 4332 | F: Documentation/serial/rocket.txt |
4333 | F: drivers/char/rocket* | 4333 | F: drivers/char/rocket* |
4334 | 4334 | ||
4335 | ROSE NETWORK LAYER | 4335 | ROSE NETWORK LAYER |
4336 | M: Ralf Baechle <ralf@linux-mips.org> | 4336 | M: Ralf Baechle <ralf@linux-mips.org> |
4337 | L: linux-hams@vger.kernel.org | 4337 | L: linux-hams@vger.kernel.org |
4338 | W: http://www.linux-ax25.org/ | 4338 | W: http://www.linux-ax25.org/ |
4339 | S: Maintained | 4339 | S: Maintained |
4340 | F: include/linux/rose.h | 4340 | F: include/linux/rose.h |
4341 | F: include/net/rose.h | 4341 | F: include/net/rose.h |
4342 | F: net/rose/ | 4342 | F: net/rose/ |
4343 | 4343 | ||
4344 | RTL8180 WIRELESS DRIVER | 4344 | RTL8180 WIRELESS DRIVER |
4345 | M: "John W. Linville" <linville@tuxdriver.com> | 4345 | M: "John W. Linville" <linville@tuxdriver.com> |
4346 | L: linux-wireless@vger.kernel.org | 4346 | L: linux-wireless@vger.kernel.org |
4347 | W: http://linuxwireless.org/ | 4347 | W: http://linuxwireless.org/ |
4348 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | 4348 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git |
4349 | S: Maintained | 4349 | S: Maintained |
4350 | F: drivers/net/wireless/rtl818x/rtl8180* | 4350 | F: drivers/net/wireless/rtl818x/rtl8180* |
4351 | 4351 | ||
4352 | RTL8187 WIRELESS DRIVER | 4352 | RTL8187 WIRELESS DRIVER |
4353 | M: Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 4353 | M: Herton Ronaldo Krzesinski <herton@mandriva.com.br> |
4354 | M: Hin-Tak Leung <htl10@users.sourceforge.net> | 4354 | M: Hin-Tak Leung <htl10@users.sourceforge.net> |
4355 | M: Larry Finger <Larry.Finger@lwfinger.net> | 4355 | M: Larry Finger <Larry.Finger@lwfinger.net> |
4356 | L: linux-wireless@vger.kernel.org | 4356 | L: linux-wireless@vger.kernel.org |
4357 | W: http://linuxwireless.org/ | 4357 | W: http://linuxwireless.org/ |
4358 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | 4358 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git |
4359 | S: Maintained | 4359 | S: Maintained |
4360 | F: drivers/net/wireless/rtl818x/rtl8187* | 4360 | F: drivers/net/wireless/rtl818x/rtl8187* |
4361 | 4361 | ||
4362 | S3 SAVAGE FRAMEBUFFER DRIVER | 4362 | S3 SAVAGE FRAMEBUFFER DRIVER |
4363 | M: Antonino Daplas <adaplas@gmail.com> | 4363 | M: Antonino Daplas <adaplas@gmail.com> |
4364 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4364 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
4365 | S: Maintained | 4365 | S: Maintained |
4366 | F: drivers/video/savage/ | 4366 | F: drivers/video/savage/ |
4367 | 4367 | ||
4368 | S390 | 4368 | S390 |
4369 | M: Martin Schwidefsky <schwidefsky@de.ibm.com> | 4369 | M: Martin Schwidefsky <schwidefsky@de.ibm.com> |
4370 | M: Heiko Carstens <heiko.carstens@de.ibm.com> | 4370 | M: Heiko Carstens <heiko.carstens@de.ibm.com> |
4371 | M: linux390@de.ibm.com | 4371 | M: linux390@de.ibm.com |
4372 | L: linux-s390@vger.kernel.org | 4372 | L: linux-s390@vger.kernel.org |
4373 | W: http://www.ibm.com/developerworks/linux/linux390/ | 4373 | W: http://www.ibm.com/developerworks/linux/linux390/ |
4374 | S: Supported | 4374 | S: Supported |
4375 | F: arch/s390/ | 4375 | F: arch/s390/ |
4376 | 4376 | ||
4377 | S390 NETWORK DRIVERS | 4377 | S390 NETWORK DRIVERS |
4378 | M: Ursula Braun <ursula.braun@de.ibm.com> | 4378 | M: Ursula Braun <ursula.braun@de.ibm.com> |
4379 | M: Frank Blaschka <blaschka@linux.vnet.ibm.com> | 4379 | M: Frank Blaschka <blaschka@linux.vnet.ibm.com> |
4380 | M: linux390@de.ibm.com | 4380 | M: linux390@de.ibm.com |
4381 | L: linux-s390@vger.kernel.org | 4381 | L: linux-s390@vger.kernel.org |
4382 | W: http://www.ibm.com/developerworks/linux/linux390/ | 4382 | W: http://www.ibm.com/developerworks/linux/linux390/ |
4383 | S: Supported | 4383 | S: Supported |
4384 | F: drivers/s390/net/ | 4384 | F: drivers/s390/net/ |
4385 | 4385 | ||
4386 | S390 ZCRYPT DRIVER | 4386 | S390 ZCRYPT DRIVER |
4387 | M: Felix Beck <felix.beck@de.ibm.com> | 4387 | M: Felix Beck <felix.beck@de.ibm.com> |
4388 | M: Ralph Wuerthner <ralph.wuerthner@de.ibm.com> | 4388 | M: Ralph Wuerthner <ralph.wuerthner@de.ibm.com> |
4389 | M: linux390@de.ibm.com | 4389 | M: linux390@de.ibm.com |
4390 | L: linux-s390@vger.kernel.org | 4390 | L: linux-s390@vger.kernel.org |
4391 | S: Supported | 4391 | S: Supported |
4392 | F: drivers/s390/crypto/ | 4392 | F: drivers/s390/crypto/ |
4393 | 4393 | ||
4394 | S390 ZFCP DRIVER | 4394 | S390 ZFCP DRIVER |
4395 | M: Christof Schmitt <christof.schmitt@de.ibm.com> | 4395 | M: Christof Schmitt <christof.schmitt@de.ibm.com> |
4396 | M: Martin Peschke <mp3@de.ibm.com> | 4396 | M: Martin Peschke <mp3@de.ibm.com> |
4397 | M: linux390@de.ibm.com | 4397 | M: linux390@de.ibm.com |
4398 | L: linux-s390@vger.kernel.org | 4398 | L: linux-s390@vger.kernel.org |
4399 | W: http://www.ibm.com/developerworks/linux/linux390/ | 4399 | W: http://www.ibm.com/developerworks/linux/linux390/ |
4400 | S: Supported | 4400 | S: Supported |
4401 | F: Documentation/s390/zfcpdump.txt | 4401 | F: Documentation/s390/zfcpdump.txt |
4402 | F: drivers/s390/scsi/zfcp_* | 4402 | F: drivers/s390/scsi/zfcp_* |
4403 | 4403 | ||
4404 | S390 IUCV NETWORK LAYER | 4404 | S390 IUCV NETWORK LAYER |
4405 | M: Ursula Braun <ursula.braun@de.ibm.com> | 4405 | M: Ursula Braun <ursula.braun@de.ibm.com> |
4406 | M: linux390@de.ibm.com | 4406 | M: linux390@de.ibm.com |
4407 | L: linux-s390@vger.kernel.org | 4407 | L: linux-s390@vger.kernel.org |
4408 | W: http://www.ibm.com/developerworks/linux/linux390/ | 4408 | W: http://www.ibm.com/developerworks/linux/linux390/ |
4409 | S: Supported | 4409 | S: Supported |
4410 | F: drivers/s390/net/*iucv* | 4410 | F: drivers/s390/net/*iucv* |
4411 | F: include/net/iucv/ | 4411 | F: include/net/iucv/ |
4412 | F: net/iucv/ | 4412 | F: net/iucv/ |
4413 | 4413 | ||
4414 | S3C24XX SD/MMC Driver | 4414 | S3C24XX SD/MMC Driver |
4415 | M: Ben Dooks <ben-linux@fluff.org> | 4415 | M: Ben Dooks <ben-linux@fluff.org> |
4416 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 4416 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
4417 | S: Supported | 4417 | S: Supported |
4418 | F: drivers/mmc/host/s3cmci.* | 4418 | F: drivers/mmc/host/s3cmci.* |
4419 | 4419 | ||
4420 | SAA7146 VIDEO4LINUX-2 DRIVER | 4420 | SAA7146 VIDEO4LINUX-2 DRIVER |
4421 | M: Michael Hunold <michael@mihu.de> | 4421 | M: Michael Hunold <michael@mihu.de> |
4422 | L: linux-media@vger.kernel.org | 4422 | L: linux-media@vger.kernel.org |
4423 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 4423 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
4424 | W: http://www.mihu.de/linux/saa7146 | 4424 | W: http://www.mihu.de/linux/saa7146 |
4425 | S: Maintained | 4425 | S: Maintained |
4426 | F: drivers/media/common/saa7146* | 4426 | F: drivers/media/common/saa7146* |
4427 | F: drivers/media/video/*7146* | 4427 | F: drivers/media/video/*7146* |
4428 | F: include/media/*7146* | 4428 | F: include/media/*7146* |
4429 | 4429 | ||
4430 | SC1200 WDT DRIVER | 4430 | SC1200 WDT DRIVER |
4431 | M: Zwane Mwaikambo <zwane@arm.linux.org.uk> | 4431 | M: Zwane Mwaikambo <zwane@arm.linux.org.uk> |
4432 | S: Maintained | 4432 | S: Maintained |
4433 | F: drivers/watchdog/sc1200wdt.c | 4433 | F: drivers/watchdog/sc1200wdt.c |
4434 | 4434 | ||
4435 | SCHEDULER | 4435 | SCHEDULER |
4436 | M: Ingo Molnar <mingo@elte.hu> | 4436 | M: Ingo Molnar <mingo@elte.hu> |
4437 | M: Peter Zijlstra <peterz@infradead.org> | 4437 | M: Peter Zijlstra <peterz@infradead.org> |
4438 | S: Maintained | 4438 | S: Maintained |
4439 | F: kernel/sched* | 4439 | F: kernel/sched* |
4440 | F: include/linux/sched.h | 4440 | F: include/linux/sched.h |
4441 | 4441 | ||
4442 | SCSI CDROM DRIVER | 4442 | SCSI CDROM DRIVER |
4443 | M: Jens Axboe <axboe@kernel.dk> | 4443 | M: Jens Axboe <axboe@kernel.dk> |
4444 | L: linux-scsi@vger.kernel.org | 4444 | L: linux-scsi@vger.kernel.org |
4445 | W: http://www.kernel.dk | 4445 | W: http://www.kernel.dk |
4446 | S: Maintained | 4446 | S: Maintained |
4447 | F: drivers/scsi/sr* | 4447 | F: drivers/scsi/sr* |
4448 | 4448 | ||
4449 | SCSI SG DRIVER | 4449 | SCSI SG DRIVER |
4450 | M: Doug Gilbert <dgilbert@interlog.com> | 4450 | M: Doug Gilbert <dgilbert@interlog.com> |
4451 | L: linux-scsi@vger.kernel.org | 4451 | L: linux-scsi@vger.kernel.org |
4452 | W: http://www.torque.net/sg | 4452 | W: http://www.torque.net/sg |
4453 | S: Maintained | 4453 | S: Maintained |
4454 | F: drivers/scsi/sg.c | 4454 | F: drivers/scsi/sg.c |
4455 | F: include/scsi/sg.h | 4455 | F: include/scsi/sg.h |
4456 | 4456 | ||
4457 | SCSI SUBSYSTEM | 4457 | SCSI SUBSYSTEM |
4458 | M: "James E.J. Bottomley" <James.Bottomley@suse.de> | 4458 | M: "James E.J. Bottomley" <James.Bottomley@suse.de> |
4459 | L: linux-scsi@vger.kernel.org | 4459 | L: linux-scsi@vger.kernel.org |
4460 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git | 4460 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git |
4461 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git | 4461 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git |
4462 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-pending-2.6.git | 4462 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-pending-2.6.git |
4463 | S: Maintained | 4463 | S: Maintained |
4464 | F: drivers/scsi/ | 4464 | F: drivers/scsi/ |
4465 | F: include/scsi/ | 4465 | F: include/scsi/ |
4466 | 4466 | ||
4467 | SCSI TAPE DRIVER | 4467 | SCSI TAPE DRIVER |
4468 | M: Kai Mรคkisara <Kai.Makisara@kolumbus.fi> | 4468 | M: Kai Mรคkisara <Kai.Makisara@kolumbus.fi> |
4469 | L: linux-scsi@vger.kernel.org | 4469 | L: linux-scsi@vger.kernel.org |
4470 | S: Maintained | 4470 | S: Maintained |
4471 | F: Documentation/scsi/st.txt | 4471 | F: Documentation/scsi/st.txt |
4472 | F: drivers/scsi/st* | 4472 | F: drivers/scsi/st* |
4473 | 4473 | ||
4474 | SCTP PROTOCOL | 4474 | SCTP PROTOCOL |
4475 | M: Vlad Yasevich <vladislav.yasevich@hp.com> | 4475 | M: Vlad Yasevich <vladislav.yasevich@hp.com> |
4476 | M: Sridhar Samudrala <sri@us.ibm.com> | 4476 | M: Sridhar Samudrala <sri@us.ibm.com> |
4477 | L: linux-sctp@vger.kernel.org | 4477 | L: linux-sctp@vger.kernel.org |
4478 | W: http://lksctp.sourceforge.net | 4478 | W: http://lksctp.sourceforge.net |
4479 | S: Supported | 4479 | S: Supported |
4480 | F: Documentation/networking/sctp.txt | 4480 | F: Documentation/networking/sctp.txt |
4481 | F: include/linux/sctp.h | 4481 | F: include/linux/sctp.h |
4482 | F: include/net/sctp/ | 4482 | F: include/net/sctp/ |
4483 | F: net/sctp/ | 4483 | F: net/sctp/ |
4484 | 4484 | ||
4485 | SCx200 CPU SUPPORT | 4485 | SCx200 CPU SUPPORT |
4486 | M: Jim Cromie <jim.cromie@gmail.com> | 4486 | M: Jim Cromie <jim.cromie@gmail.com> |
4487 | S: Odd Fixes | 4487 | S: Odd Fixes |
4488 | F: Documentation/i2c/busses/scx200_acb | 4488 | F: Documentation/i2c/busses/scx200_acb |
4489 | F: arch/x86/kernel/scx200_32.c | 4489 | F: arch/x86/kernel/scx200_32.c |
4490 | F: drivers/watchdog/scx200_wdt.c | 4490 | F: drivers/watchdog/scx200_wdt.c |
4491 | F: drivers/i2c/busses/scx200* | 4491 | F: drivers/i2c/busses/scx200* |
4492 | F: drivers/mtd/maps/scx200_docflash.c | 4492 | F: drivers/mtd/maps/scx200_docflash.c |
4493 | F: include/linux/scx200.h | 4493 | F: include/linux/scx200.h |
4494 | 4494 | ||
4495 | SCx200 GPIO DRIVER | 4495 | SCx200 GPIO DRIVER |
4496 | M: Jim Cromie <jim.cromie@gmail.com> | 4496 | M: Jim Cromie <jim.cromie@gmail.com> |
4497 | S: Maintained | 4497 | S: Maintained |
4498 | F: drivers/char/scx200_gpio.c | 4498 | F: drivers/char/scx200_gpio.c |
4499 | F: include/linux/scx200_gpio.h | 4499 | F: include/linux/scx200_gpio.h |
4500 | 4500 | ||
4501 | SCx200 HRT CLOCKSOURCE DRIVER | 4501 | SCx200 HRT CLOCKSOURCE DRIVER |
4502 | M: Jim Cromie <jim.cromie@gmail.com> | 4502 | M: Jim Cromie <jim.cromie@gmail.com> |
4503 | S: Maintained | 4503 | S: Maintained |
4504 | F: drivers/clocksource/scx200_hrt.c | 4504 | F: drivers/clocksource/scx200_hrt.c |
4505 | 4505 | ||
4506 | SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER | 4506 | SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER |
4507 | M: Sascha Sommer <saschasommer@freenet.de> | 4507 | M: Sascha Sommer <saschasommer@freenet.de> |
4508 | L: sdricohcs-devel@lists.sourceforge.net (subscribers-only) | 4508 | L: sdricohcs-devel@lists.sourceforge.net (subscribers-only) |
4509 | S: Maintained | 4509 | S: Maintained |
4510 | F: drivers/mmc/host/sdricoh_cs.c | 4510 | F: drivers/mmc/host/sdricoh_cs.c |
4511 | 4511 | ||
4512 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER | 4512 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER |
4513 | M: Pierre Ossman <pierre@ossman.eu> | 4513 | M: Pierre Ossman <pierre@ossman.eu> |
4514 | L: sdhci-devel@lists.ossman.eu | 4514 | L: sdhci-devel@lists.ossman.eu |
4515 | S: Maintained | 4515 | S: Maintained |
4516 | 4516 | ||
4517 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) | 4517 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) |
4518 | M: Anton Vorontsov <avorontsov@ru.mvista.com> | 4518 | M: Anton Vorontsov <avorontsov@ru.mvista.com> |
4519 | L: linuxppc-dev@ozlabs.org | 4519 | L: linuxppc-dev@ozlabs.org |
4520 | L: sdhci-devel@lists.ossman.eu | 4520 | L: sdhci-devel@lists.ossman.eu |
4521 | S: Maintained | 4521 | S: Maintained |
4522 | F: drivers/mmc/host/sdhci.* | 4522 | F: drivers/mmc/host/sdhci.* |
4523 | 4523 | ||
4524 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER | 4524 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER |
4525 | M: Ben Dooks <ben-linux@fluff.org> | 4525 | M: Ben Dooks <ben-linux@fluff.org> |
4526 | L: sdhci-devel@lists.ossman.eu | 4526 | L: sdhci-devel@lists.ossman.eu |
4527 | S: Maintained | 4527 | S: Maintained |
4528 | F: drivers/mmc/host/sdhci-s3c.c | 4528 | F: drivers/mmc/host/sdhci-s3c.c |
4529 | 4529 | ||
4530 | SECURITY SUBSYSTEM | 4530 | SECURITY SUBSYSTEM |
4531 | M: James Morris <jmorris@namei.org> | 4531 | M: James Morris <jmorris@namei.org> |
4532 | L: linux-security-module@vger.kernel.org (suggested Cc:) | 4532 | L: linux-security-module@vger.kernel.org (suggested Cc:) |
4533 | T: git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git | 4533 | T: git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git |
4534 | W: http://security.wiki.kernel.org/ | 4534 | W: http://security.wiki.kernel.org/ |
4535 | S: Supported | 4535 | S: Supported |
4536 | F: security/ | 4536 | F: security/ |
4537 | 4537 | ||
4538 | SECURITY CONTACT | 4538 | SECURITY CONTACT |
4539 | M: Security Officers <security@kernel.org> | 4539 | M: Security Officers <security@kernel.org> |
4540 | S: Supported | 4540 | S: Supported |
4541 | 4541 | ||
4542 | SELINUX SECURITY MODULE | 4542 | SELINUX SECURITY MODULE |
4543 | M: Stephen Smalley <sds@tycho.nsa.gov> | 4543 | M: Stephen Smalley <sds@tycho.nsa.gov> |
4544 | M: James Morris <jmorris@namei.org> | 4544 | M: James Morris <jmorris@namei.org> |
4545 | M: Eric Paris <eparis@parisplace.org> | 4545 | M: Eric Paris <eparis@parisplace.org> |
4546 | L: selinux@tycho.nsa.gov (subscribers-only, general discussion) | 4546 | L: selinux@tycho.nsa.gov (subscribers-only, general discussion) |
4547 | W: http://selinuxproject.org | 4547 | W: http://selinuxproject.org |
4548 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git | 4548 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git |
4549 | S: Supported | 4549 | S: Supported |
4550 | F: include/linux/selinux* | 4550 | F: include/linux/selinux* |
4551 | F: security/selinux/ | 4551 | F: security/selinux/ |
4552 | 4552 | ||
4553 | SENSABLE PHANTOM | 4553 | SENSABLE PHANTOM |
4554 | M: Jiri Slaby <jirislaby@gmail.com> | 4554 | M: Jiri Slaby <jirislaby@gmail.com> |
4555 | S: Maintained | 4555 | S: Maintained |
4556 | F: drivers/misc/phantom.c | 4556 | F: drivers/misc/phantom.c |
4557 | F: include/linux/phantom.h | 4557 | F: include/linux/phantom.h |
4558 | 4558 | ||
4559 | SERIAL ATA (SATA) SUBSYSTEM | 4559 | SERIAL ATA (SATA) SUBSYSTEM |
4560 | M: Jeff Garzik <jgarzik@pobox.com> | 4560 | M: Jeff Garzik <jgarzik@pobox.com> |
4561 | L: linux-ide@vger.kernel.org | 4561 | L: linux-ide@vger.kernel.org |
4562 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git | 4562 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git |
4563 | S: Supported | 4563 | S: Supported |
4564 | F: drivers/ata/ | 4564 | F: drivers/ata/ |
4565 | F: include/linux/ata.h | 4565 | F: include/linux/ata.h |
4566 | F: include/linux/libata.h | 4566 | F: include/linux/libata.h |
4567 | 4567 | ||
4568 | SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER | 4568 | SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER |
4569 | M: Sathya Perla <sathyap@serverengines.com> | 4569 | M: Sathya Perla <sathyap@serverengines.com> |
4570 | M: Subbu Seetharaman <subbus@serverengines.com> | 4570 | M: Subbu Seetharaman <subbus@serverengines.com> |
4571 | L: netdev@vger.kernel.org | 4571 | L: netdev@vger.kernel.org |
4572 | W: http://www.serverengines.com | 4572 | W: http://www.serverengines.com |
4573 | S: Supported | 4573 | S: Supported |
4574 | F: drivers/net/benet/ | 4574 | F: drivers/net/benet/ |
4575 | 4575 | ||
4576 | SFC NETWORK DRIVER | 4576 | SFC NETWORK DRIVER |
4577 | M: Solarflare linux maintainers <linux-net-drivers@solarflare.com> | 4577 | M: Solarflare linux maintainers <linux-net-drivers@solarflare.com> |
4578 | M: Steve Hodgson <shodgson@solarflare.com> | 4578 | M: Steve Hodgson <shodgson@solarflare.com> |
4579 | M: Ben Hutchings <bhutchings@solarflare.com> | 4579 | M: Ben Hutchings <bhutchings@solarflare.com> |
4580 | L: netdev@vger.kernel.org | 4580 | L: netdev@vger.kernel.org |
4581 | S: Supported | 4581 | S: Supported |
4582 | F: drivers/net/sfc/ | 4582 | F: drivers/net/sfc/ |
4583 | 4583 | ||
4584 | SGI GRU DRIVER | 4584 | SGI GRU DRIVER |
4585 | M: Jack Steiner <steiner@sgi.com> | 4585 | M: Jack Steiner <steiner@sgi.com> |
4586 | S: Maintained | 4586 | S: Maintained |
4587 | F: drivers/misc/sgi-gru/ | 4587 | F: drivers/misc/sgi-gru/ |
4588 | 4588 | ||
4589 | SGI SN-IA64 (Altix) SERIAL CONSOLE DRIVER | 4589 | SGI SN-IA64 (Altix) SERIAL CONSOLE DRIVER |
4590 | M: Pat Gefre <pfg@sgi.com> | 4590 | M: Pat Gefre <pfg@sgi.com> |
4591 | L: linux-ia64@vger.kernel.org | 4591 | L: linux-ia64@vger.kernel.org |
4592 | S: Supported | 4592 | S: Supported |
4593 | F: Documentation/ia64/serial.txt | 4593 | F: Documentation/ia64/serial.txt |
4594 | F: drivers/serial/ioc?_serial.c | 4594 | F: drivers/serial/ioc?_serial.c |
4595 | F: include/linux/ioc?.h | 4595 | F: include/linux/ioc?.h |
4596 | 4596 | ||
4597 | SGI VISUAL WORKSTATION 320 AND 540 | 4597 | SGI VISUAL WORKSTATION 320 AND 540 |
4598 | M: Andrey Panin <pazke@donpac.ru> | 4598 | M: Andrey Panin <pazke@donpac.ru> |
4599 | L: linux-visws-devel@lists.sf.net | 4599 | L: linux-visws-devel@lists.sf.net |
4600 | W: http://linux-visws.sf.net | 4600 | W: http://linux-visws.sf.net |
4601 | S: Maintained for 2.6. | 4601 | S: Maintained for 2.6. |
4602 | F: Documentation/sgi-visws.txt | 4602 | F: Documentation/sgi-visws.txt |
4603 | 4603 | ||
4604 | SGI XP/XPC/XPNET DRIVER | 4604 | SGI XP/XPC/XPNET DRIVER |
4605 | M: Robin Holt <holt@sgi.com> | 4605 | M: Robin Holt <holt@sgi.com> |
4606 | S: Maintained | 4606 | S: Maintained |
4607 | F: drivers/misc/sgi-xp/ | 4607 | F: drivers/misc/sgi-xp/ |
4608 | 4608 | ||
4609 | SHARP LH SUPPORT (LH7952X & LH7A40X) | 4609 | SHARP LH SUPPORT (LH7952X & LH7A40X) |
4610 | M: Marc Singer <elf@buici.com> | 4610 | M: Marc Singer <elf@buici.com> |
4611 | W: http://projects.buici.com/arm | 4611 | W: http://projects.buici.com/arm |
4612 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 4612 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
4613 | S: Maintained | 4613 | S: Maintained |
4614 | F: Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen | 4614 | F: Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen |
4615 | F: arch/arm/mach-lh7a40x/ | 4615 | F: arch/arm/mach-lh7a40x/ |
4616 | F: drivers/serial/serial_lh7a40x.c | 4616 | F: drivers/serial/serial_lh7a40x.c |
4617 | F: drivers/usb/gadget/lh7a40* | 4617 | F: drivers/usb/gadget/lh7a40* |
4618 | F: drivers/usb/host/ohci-lh7a40* | 4618 | F: drivers/usb/host/ohci-lh7a40* |
4619 | 4619 | ||
4620 | SHPC HOTPLUG DRIVER | 4620 | SHPC HOTPLUG DRIVER |
4621 | M: Kristen Carlson Accardi <kristen.c.accardi@intel.com> | 4621 | M: Kristen Carlson Accardi <kristen.c.accardi@intel.com> |
4622 | L: linux-pci@vger.kernel.org | 4622 | L: linux-pci@vger.kernel.org |
4623 | S: Supported | 4623 | S: Supported |
4624 | F: drivers/pci/hotplug/shpchp* | 4624 | F: drivers/pci/hotplug/shpchp* |
4625 | 4625 | ||
4626 | SIMTEC EB110ATX (Chalice CATS) | 4626 | SIMTEC EB110ATX (Chalice CATS) |
4627 | P: Ben Dooks | 4627 | P: Ben Dooks |
4628 | M: Vincent Sanders <support@simtec.co.uk> | 4628 | M: Vincent Sanders <support@simtec.co.uk> |
4629 | W: http://www.simtec.co.uk/products/EB110ATX/ | 4629 | W: http://www.simtec.co.uk/products/EB110ATX/ |
4630 | S: Supported | 4630 | S: Supported |
4631 | 4631 | ||
4632 | SIMTEC EB2410ITX (BAST) | 4632 | SIMTEC EB2410ITX (BAST) |
4633 | P: Ben Dooks | 4633 | P: Ben Dooks |
4634 | M: Vincent Sanders <support@simtec.co.uk> | 4634 | M: Vincent Sanders <support@simtec.co.uk> |
4635 | W: http://www.simtec.co.uk/products/EB2410ITX/ | 4635 | W: http://www.simtec.co.uk/products/EB2410ITX/ |
4636 | S: Supported | 4636 | S: Supported |
4637 | F: arch/arm/mach-s3c2410/ | 4637 | F: arch/arm/mach-s3c2410/ |
4638 | F: drivers/*/*s3c2410* | 4638 | F: drivers/*/*s3c2410* |
4639 | F: drivers/*/*/*s3c2410* | 4639 | F: drivers/*/*/*s3c2410* |
4640 | 4640 | ||
4641 | SIS 190 ETHERNET DRIVER | 4641 | SIS 190 ETHERNET DRIVER |
4642 | M: Francois Romieu <romieu@fr.zoreil.com> | 4642 | M: Francois Romieu <romieu@fr.zoreil.com> |
4643 | L: netdev@vger.kernel.org | 4643 | L: netdev@vger.kernel.org |
4644 | S: Maintained | 4644 | S: Maintained |
4645 | F: drivers/net/sis190.c | 4645 | F: drivers/net/sis190.c |
4646 | 4646 | ||
4647 | SIS 900/7016 FAST ETHERNET DRIVER | 4647 | SIS 900/7016 FAST ETHERNET DRIVER |
4648 | M: Daniele Venzano <venza@brownhat.org> | 4648 | M: Daniele Venzano <venza@brownhat.org> |
4649 | W: http://www.brownhat.org/sis900.html | 4649 | W: http://www.brownhat.org/sis900.html |
4650 | L: netdev@vger.kernel.org | 4650 | L: netdev@vger.kernel.org |
4651 | S: Maintained | 4651 | S: Maintained |
4652 | F: drivers/net/sis900.* | 4652 | F: drivers/net/sis900.* |
4653 | 4653 | ||
4654 | SIS 96X I2C/SMBUS DRIVER | 4654 | SIS 96X I2C/SMBUS DRIVER |
4655 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> | 4655 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
4656 | L: linux-i2c@vger.kernel.org | 4656 | L: linux-i2c@vger.kernel.org |
4657 | S: Maintained | 4657 | S: Maintained |
4658 | F: Documentation/i2c/busses/i2c-sis96x | 4658 | F: Documentation/i2c/busses/i2c-sis96x |
4659 | F: drivers/i2c/busses/i2c-sis96x.c | 4659 | F: drivers/i2c/busses/i2c-sis96x.c |
4660 | 4660 | ||
4661 | SIS FRAMEBUFFER DRIVER | 4661 | SIS FRAMEBUFFER DRIVER |
4662 | M: Thomas Winischhofer <thomas@winischhofer.net> | 4662 | M: Thomas Winischhofer <thomas@winischhofer.net> |
4663 | W: http://www.winischhofer.net/linuxsisvga.shtml | 4663 | W: http://www.winischhofer.net/linuxsisvga.shtml |
4664 | S: Maintained | 4664 | S: Maintained |
4665 | F: Documentation/fb/sisfb.txt | 4665 | F: Documentation/fb/sisfb.txt |
4666 | F: drivers/video/sis/ | 4666 | F: drivers/video/sis/ |
4667 | F: include/video/sisfb.h | 4667 | F: include/video/sisfb.h |
4668 | 4668 | ||
4669 | SIS USB2VGA DRIVER | 4669 | SIS USB2VGA DRIVER |
4670 | M: Thomas Winischhofer <thomas@winischhofer.net> | 4670 | M: Thomas Winischhofer <thomas@winischhofer.net> |
4671 | W: http://www.winischhofer.at/linuxsisusbvga.shtml | 4671 | W: http://www.winischhofer.at/linuxsisusbvga.shtml |
4672 | S: Maintained | 4672 | S: Maintained |
4673 | F: drivers/usb/misc/sisusbvga/ | 4673 | F: drivers/usb/misc/sisusbvga/ |
4674 | 4674 | ||
4675 | SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS | 4675 | SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS |
4676 | M: Stephen Hemminger <shemminger@linux-foundation.org> | 4676 | M: Stephen Hemminger <shemminger@linux-foundation.org> |
4677 | L: netdev@vger.kernel.org | 4677 | L: netdev@vger.kernel.org |
4678 | S: Maintained | 4678 | S: Maintained |
4679 | F: drivers/net/skge.* | 4679 | F: drivers/net/skge.* |
4680 | F: drivers/net/sky2.* | 4680 | F: drivers/net/sky2.* |
4681 | 4681 | ||
4682 | SLAB ALLOCATOR | 4682 | SLAB ALLOCATOR |
4683 | M: Christoph Lameter <cl@linux-foundation.org> | 4683 | M: Christoph Lameter <cl@linux-foundation.org> |
4684 | M: Pekka Enberg <penberg@cs.helsinki.fi> | 4684 | M: Pekka Enberg <penberg@cs.helsinki.fi> |
4685 | M: Matt Mackall <mpm@selenic.com> | 4685 | M: Matt Mackall <mpm@selenic.com> |
4686 | L: linux-mm@kvack.org | 4686 | L: linux-mm@kvack.org |
4687 | S: Maintained | 4687 | S: Maintained |
4688 | F: include/linux/sl?b*.h | 4688 | F: include/linux/sl?b*.h |
4689 | F: mm/sl?b.c | 4689 | F: mm/sl?b.c |
4690 | 4690 | ||
4691 | SMC91x ETHERNET DRIVER | 4691 | SMC91x ETHERNET DRIVER |
4692 | M: Nicolas Pitre <nico@cam.org> | 4692 | M: Nicolas Pitre <nico@fluxnic.net> |
4693 | S: Maintained | 4693 | S: Maintained |
4694 | F: drivers/net/smc91x.* | 4694 | F: drivers/net/smc91x.* |
4695 | 4695 | ||
4696 | SMSC47B397 HARDWARE MONITOR DRIVER | 4696 | SMSC47B397 HARDWARE MONITOR DRIVER |
4697 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> | 4697 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
4698 | L: lm-sensors@lm-sensors.org | 4698 | L: lm-sensors@lm-sensors.org |
4699 | S: Maintained | 4699 | S: Maintained |
4700 | F: Documentation/hwmon/smsc47b397 | 4700 | F: Documentation/hwmon/smsc47b397 |
4701 | F: drivers/hwmon/smsc47b397.c | 4701 | F: drivers/hwmon/smsc47b397.c |
4702 | 4702 | ||
4703 | SMSC911x ETHERNET DRIVER | 4703 | SMSC911x ETHERNET DRIVER |
4704 | M: Steve Glendinning <steve.glendinning@smsc.com> | 4704 | M: Steve Glendinning <steve.glendinning@smsc.com> |
4705 | L: netdev@vger.kernel.org | 4705 | L: netdev@vger.kernel.org |
4706 | S: Supported | 4706 | S: Supported |
4707 | F: include/linux/smsc911x.h | 4707 | F: include/linux/smsc911x.h |
4708 | F: drivers/net/smsc911x.* | 4708 | F: drivers/net/smsc911x.* |
4709 | 4709 | ||
4710 | SMSC9420 PCI ETHERNET DRIVER | 4710 | SMSC9420 PCI ETHERNET DRIVER |
4711 | M: Steve Glendinning <steve.glendinning@smsc.com> | 4711 | M: Steve Glendinning <steve.glendinning@smsc.com> |
4712 | L: netdev@vger.kernel.org | 4712 | L: netdev@vger.kernel.org |
4713 | S: Supported | 4713 | S: Supported |
4714 | F: drivers/net/smsc9420.* | 4714 | F: drivers/net/smsc9420.* |
4715 | 4715 | ||
4716 | SMX UIO Interface | 4716 | SMX UIO Interface |
4717 | M: Ben Nizette <bn@niasdigital.com> | 4717 | M: Ben Nizette <bn@niasdigital.com> |
4718 | S: Maintained | 4718 | S: Maintained |
4719 | F: drivers/uio/uio_smx.c | 4719 | F: drivers/uio/uio_smx.c |
4720 | 4720 | ||
4721 | SN-IA64 (Itanium) SUB-PLATFORM | 4721 | SN-IA64 (Itanium) SUB-PLATFORM |
4722 | M: Jes Sorensen <jes@sgi.com> | 4722 | M: Jes Sorensen <jes@sgi.com> |
4723 | L: linux-altix@sgi.com | 4723 | L: linux-altix@sgi.com |
4724 | L: linux-ia64@vger.kernel.org | 4724 | L: linux-ia64@vger.kernel.org |
4725 | W: http://www.sgi.com/altix | 4725 | W: http://www.sgi.com/altix |
4726 | S: Maintained | 4726 | S: Maintained |
4727 | F: arch/ia64/sn/ | 4727 | F: arch/ia64/sn/ |
4728 | 4728 | ||
4729 | SOC-CAMERA V4L2 SUBSYSTEM | 4729 | SOC-CAMERA V4L2 SUBSYSTEM |
4730 | M: Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 4730 | M: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
4731 | L: linux-media@vger.kernel.org | 4731 | L: linux-media@vger.kernel.org |
4732 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 4732 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
4733 | S: Maintained | 4733 | S: Maintained |
4734 | F: include/media/v4l2* | 4734 | F: include/media/v4l2* |
4735 | F: drivers/media/video/v4l2* | 4735 | F: drivers/media/video/v4l2* |
4736 | 4736 | ||
4737 | SOEKRIS NET48XX LED SUPPORT | 4737 | SOEKRIS NET48XX LED SUPPORT |
4738 | M: Chris Boot <bootc@bootc.net> | 4738 | M: Chris Boot <bootc@bootc.net> |
4739 | S: Maintained | 4739 | S: Maintained |
4740 | F: drivers/leds/leds-net48xx.c | 4740 | F: drivers/leds/leds-net48xx.c |
4741 | 4741 | ||
4742 | SOFTWARE RAID (Multiple Disks) SUPPORT | 4742 | SOFTWARE RAID (Multiple Disks) SUPPORT |
4743 | M: Neil Brown <neilb@suse.de> | 4743 | M: Neil Brown <neilb@suse.de> |
4744 | L: linux-raid@vger.kernel.org | 4744 | L: linux-raid@vger.kernel.org |
4745 | S: Supported | 4745 | S: Supported |
4746 | F: drivers/md/ | 4746 | F: drivers/md/ |
4747 | F: include/linux/raid/ | 4747 | F: include/linux/raid/ |
4748 | 4748 | ||
4749 | SONIC NETWORK DRIVER | 4749 | SONIC NETWORK DRIVER |
4750 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 4750 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> |
4751 | L: netdev@vger.kernel.org | 4751 | L: netdev@vger.kernel.org |
4752 | S: Maintained | 4752 | S: Maintained |
4753 | F: drivers/net/sonic.* | 4753 | F: drivers/net/sonic.* |
4754 | 4754 | ||
4755 | SONICS SILICON BACKPLANE DRIVER (SSB) | 4755 | SONICS SILICON BACKPLANE DRIVER (SSB) |
4756 | M: Michael Buesch <mb@bu3sch.de> | 4756 | M: Michael Buesch <mb@bu3sch.de> |
4757 | L: netdev@vger.kernel.org | 4757 | L: netdev@vger.kernel.org |
4758 | S: Maintained | 4758 | S: Maintained |
4759 | F: drivers/ssb/ | 4759 | F: drivers/ssb/ |
4760 | F: include/linux/ssb/ | 4760 | F: include/linux/ssb/ |
4761 | 4761 | ||
4762 | SONY VAIO CONTROL DEVICE DRIVER | 4762 | SONY VAIO CONTROL DEVICE DRIVER |
4763 | M: Mattia Dongili <malattia@linux.it> | 4763 | M: Mattia Dongili <malattia@linux.it> |
4764 | L: linux-acpi@vger.kernel.org | 4764 | L: linux-acpi@vger.kernel.org |
4765 | W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers | 4765 | W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers |
4766 | S: Maintained | 4766 | S: Maintained |
4767 | F: Documentation/laptops/sony-laptop.txt | 4767 | F: Documentation/laptops/sony-laptop.txt |
4768 | F: drivers/char/sonypi.c | 4768 | F: drivers/char/sonypi.c |
4769 | F: drivers/platform/x86/sony-laptop.c | 4769 | F: drivers/platform/x86/sony-laptop.c |
4770 | F: include/linux/sony-laptop.h | 4770 | F: include/linux/sony-laptop.h |
4771 | 4771 | ||
4772 | SONY MEMORYSTICK CARD SUPPORT | 4772 | SONY MEMORYSTICK CARD SUPPORT |
4773 | M: Alex Dubov <oakad@yahoo.com> | 4773 | M: Alex Dubov <oakad@yahoo.com> |
4774 | W: http://tifmxx.berlios.de/ | 4774 | W: http://tifmxx.berlios.de/ |
4775 | S: Maintained | 4775 | S: Maintained |
4776 | F: drivers/memstick/host/tifm_ms.c | 4776 | F: drivers/memstick/host/tifm_ms.c |
4777 | 4777 | ||
4778 | SOUND | 4778 | SOUND |
4779 | M: Jaroslav Kysela <perex@perex.cz> | 4779 | M: Jaroslav Kysela <perex@perex.cz> |
4780 | M: Takashi Iwai <tiwai@suse.de> | 4780 | M: Takashi Iwai <tiwai@suse.de> |
4781 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 4781 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
4782 | W: http://www.alsa-project.org/ | 4782 | W: http://www.alsa-project.org/ |
4783 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git | 4783 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git |
4784 | T: git git://git.alsa-project.org/alsa-kernel.git | 4784 | T: git git://git.alsa-project.org/alsa-kernel.git |
4785 | S: Maintained | 4785 | S: Maintained |
4786 | F: Documentation/sound/ | 4786 | F: Documentation/sound/ |
4787 | F: include/sound/ | 4787 | F: include/sound/ |
4788 | F: sound/ | 4788 | F: sound/ |
4789 | 4789 | ||
4790 | SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) | 4790 | SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) |
4791 | M: Liam Girdwood <lrg@slimlogic.co.uk> | 4791 | M: Liam Girdwood <lrg@slimlogic.co.uk> |
4792 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> | 4792 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> |
4793 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git | 4793 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git |
4794 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 4794 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
4795 | W: http://alsa-project.org/main/index.php/ASoC | 4795 | W: http://alsa-project.org/main/index.php/ASoC |
4796 | S: Supported | 4796 | S: Supported |
4797 | F: sound/soc/ | 4797 | F: sound/soc/ |
4798 | F: include/sound/soc* | 4798 | F: include/sound/soc* |
4799 | 4799 | ||
4800 | SPARC + UltraSPARC (sparc/sparc64) | 4800 | SPARC + UltraSPARC (sparc/sparc64) |
4801 | M: "David S. Miller" <davem@davemloft.net> | 4801 | M: "David S. Miller" <davem@davemloft.net> |
4802 | L: sparclinux@vger.kernel.org | 4802 | L: sparclinux@vger.kernel.org |
4803 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git | 4803 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git |
4804 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git | 4804 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git |
4805 | S: Maintained | 4805 | S: Maintained |
4806 | F: arch/sparc/ | 4806 | F: arch/sparc/ |
4807 | 4807 | ||
4808 | SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER | 4808 | SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER |
4809 | M: Roger Wolff <R.E.Wolff@BitWizard.nl> | 4809 | M: Roger Wolff <R.E.Wolff@BitWizard.nl> |
4810 | S: Supported | 4810 | S: Supported |
4811 | F: Documentation/serial/specialix.txt | 4811 | F: Documentation/serial/specialix.txt |
4812 | F: drivers/char/specialix* | 4812 | F: drivers/char/specialix* |
4813 | 4813 | ||
4814 | SPI SUBSYSTEM | 4814 | SPI SUBSYSTEM |
4815 | M: David Brownell <dbrownell@users.sourceforge.net> | 4815 | M: David Brownell <dbrownell@users.sourceforge.net> |
4816 | L: spi-devel-general@lists.sourceforge.net | 4816 | L: spi-devel-general@lists.sourceforge.net |
4817 | S: Maintained | 4817 | S: Maintained |
4818 | F: Documentation/spi/ | 4818 | F: Documentation/spi/ |
4819 | F: drivers/spi/ | 4819 | F: drivers/spi/ |
4820 | F: include/linux/spi/ | 4820 | F: include/linux/spi/ |
4821 | 4821 | ||
4822 | SPIDERNET NETWORK DRIVER for CELL | 4822 | SPIDERNET NETWORK DRIVER for CELL |
4823 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> | 4823 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> |
4824 | M: Jens Osterkamp <jens@de.ibm.com> | 4824 | M: Jens Osterkamp <jens@de.ibm.com> |
4825 | L: netdev@vger.kernel.org | 4825 | L: netdev@vger.kernel.org |
4826 | S: Supported | 4826 | S: Supported |
4827 | F: Documentation/networking/spider_net.txt | 4827 | F: Documentation/networking/spider_net.txt |
4828 | F: drivers/net/spider_net* | 4828 | F: drivers/net/spider_net* |
4829 | 4829 | ||
4830 | SPU FILE SYSTEM | 4830 | SPU FILE SYSTEM |
4831 | M: Jeremy Kerr <jk@ozlabs.org> | 4831 | M: Jeremy Kerr <jk@ozlabs.org> |
4832 | L: linuxppc-dev@ozlabs.org | 4832 | L: linuxppc-dev@ozlabs.org |
4833 | L: cbe-oss-dev@ozlabs.org | 4833 | L: cbe-oss-dev@ozlabs.org |
4834 | W: http://www.ibm.com/developerworks/power/cell/ | 4834 | W: http://www.ibm.com/developerworks/power/cell/ |
4835 | S: Supported | 4835 | S: Supported |
4836 | F: Documentation/filesystems/spufs.txt | 4836 | F: Documentation/filesystems/spufs.txt |
4837 | F: arch/powerpc/platforms/cell/spufs/ | 4837 | F: arch/powerpc/platforms/cell/spufs/ |
4838 | 4838 | ||
4839 | SQUASHFS FILE SYSTEM | 4839 | SQUASHFS FILE SYSTEM |
4840 | M: Phillip Lougher <phillip@lougher.demon.co.uk> | 4840 | M: Phillip Lougher <phillip@lougher.demon.co.uk> |
4841 | L: squashfs-devel@lists.sourceforge.net (subscribers-only) | 4841 | L: squashfs-devel@lists.sourceforge.net (subscribers-only) |
4842 | W: http://squashfs.org.uk | 4842 | W: http://squashfs.org.uk |
4843 | S: Maintained | 4843 | S: Maintained |
4844 | F: Documentation/filesystems/squashfs.txt | 4844 | F: Documentation/filesystems/squashfs.txt |
4845 | F: fs/squashfs/ | 4845 | F: fs/squashfs/ |
4846 | 4846 | ||
4847 | SRM (Alpha) environment access | 4847 | SRM (Alpha) environment access |
4848 | M: Jan-Benedict Glaw <jbglaw@lug-owl.de> | 4848 | M: Jan-Benedict Glaw <jbglaw@lug-owl.de> |
4849 | S: Maintained | 4849 | S: Maintained |
4850 | F: arch/alpha/kernel/srm_env.c | 4850 | F: arch/alpha/kernel/srm_env.c |
4851 | 4851 | ||
4852 | STABLE BRANCH | 4852 | STABLE BRANCH |
4853 | M: Greg Kroah-Hartman <greg@kroah.com> | 4853 | M: Greg Kroah-Hartman <greg@kroah.com> |
4854 | M: Chris Wright <chrisw@sous-sol.org> | 4854 | M: Chris Wright <chrisw@sous-sol.org> |
4855 | L: stable@kernel.org | 4855 | L: stable@kernel.org |
4856 | S: Maintained | 4856 | S: Maintained |
4857 | 4857 | ||
4858 | STAGING SUBSYSTEM | 4858 | STAGING SUBSYSTEM |
4859 | M: Greg Kroah-Hartman <gregkh@suse.de> | 4859 | M: Greg Kroah-Hartman <gregkh@suse.de> |
4860 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 4860 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
4861 | L: devel@driverdev.osuosl.org | 4861 | L: devel@driverdev.osuosl.org |
4862 | S: Maintained | 4862 | S: Maintained |
4863 | F: drivers/staging/ | 4863 | F: drivers/staging/ |
4864 | 4864 | ||
4865 | STARFIRE/DURALAN NETWORK DRIVER | 4865 | STARFIRE/DURALAN NETWORK DRIVER |
4866 | M: Ion Badulescu <ionut@badula.org> | 4866 | M: Ion Badulescu <ionut@badula.org> |
4867 | S: Odd Fixes | 4867 | S: Odd Fixes |
4868 | F: drivers/net/starfire* | 4868 | F: drivers/net/starfire* |
4869 | 4869 | ||
4870 | STARMODE RADIO IP (STRIP) PROTOCOL DRIVER | 4870 | STARMODE RADIO IP (STRIP) PROTOCOL DRIVER |
4871 | S: Orphan | 4871 | S: Orphan |
4872 | F: drivers/net/wireless/strip.c | 4872 | F: drivers/net/wireless/strip.c |
4873 | F: include/linux/if_strip.h | 4873 | F: include/linux/if_strip.h |
4874 | 4874 | ||
4875 | STRADIS MPEG-2 DECODER DRIVER | 4875 | STRADIS MPEG-2 DECODER DRIVER |
4876 | M: Nathan Laredo <laredo@gnu.org> | 4876 | M: Nathan Laredo <laredo@gnu.org> |
4877 | W: http://www.stradis.com/ | 4877 | W: http://www.stradis.com/ |
4878 | S: Maintained | 4878 | S: Maintained |
4879 | F: drivers/media/video/stradis.c | 4879 | F: drivers/media/video/stradis.c |
4880 | 4880 | ||
4881 | SUN3/3X | 4881 | SUN3/3X |
4882 | M: Sam Creasey <sammy@sammy.net> | 4882 | M: Sam Creasey <sammy@sammy.net> |
4883 | W: http://sammy.net/sun3/ | 4883 | W: http://sammy.net/sun3/ |
4884 | S: Maintained | 4884 | S: Maintained |
4885 | F: arch/m68k/kernel/*sun3* | 4885 | F: arch/m68k/kernel/*sun3* |
4886 | F: arch/m68k/sun3*/ | 4886 | F: arch/m68k/sun3*/ |
4887 | F: arch/m68k/include/asm/sun3* | 4887 | F: arch/m68k/include/asm/sun3* |
4888 | 4888 | ||
4889 | SUPERH | 4889 | SUPERH |
4890 | M: Paul Mundt <lethal@linux-sh.org> | 4890 | M: Paul Mundt <lethal@linux-sh.org> |
4891 | L: linux-sh@vger.kernel.org | 4891 | L: linux-sh@vger.kernel.org |
4892 | W: http://www.linux-sh.org | 4892 | W: http://www.linux-sh.org |
4893 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git | 4893 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git |
4894 | S: Supported | 4894 | S: Supported |
4895 | F: Documentation/sh/ | 4895 | F: Documentation/sh/ |
4896 | F: arch/sh/ | 4896 | F: arch/sh/ |
4897 | F: drivers/sh/ | 4897 | F: drivers/sh/ |
4898 | 4898 | ||
4899 | SUSPEND TO RAM | 4899 | SUSPEND TO RAM |
4900 | M: Len Brown <len.brown@intel.com> | 4900 | M: Len Brown <len.brown@intel.com> |
4901 | M: Pavel Machek <pavel@ucw.cz> | 4901 | M: Pavel Machek <pavel@ucw.cz> |
4902 | M: "Rafael J. Wysocki" <rjw@sisk.pl> | 4902 | M: "Rafael J. Wysocki" <rjw@sisk.pl> |
4903 | L: linux-pm@lists.linux-foundation.org | 4903 | L: linux-pm@lists.linux-foundation.org |
4904 | S: Supported | 4904 | S: Supported |
4905 | F: Documentation/power/ | 4905 | F: Documentation/power/ |
4906 | F: arch/x86/kernel/acpi/ | 4906 | F: arch/x86/kernel/acpi/ |
4907 | F: drivers/base/power/ | 4907 | F: drivers/base/power/ |
4908 | F: kernel/power/ | 4908 | F: kernel/power/ |
4909 | F: include/linux/suspend.h | 4909 | F: include/linux/suspend.h |
4910 | F: include/linux/freezer.h | 4910 | F: include/linux/freezer.h |
4911 | F: include/linux/pm.h | 4911 | F: include/linux/pm.h |
4912 | 4912 | ||
4913 | SVGA HANDLING | 4913 | SVGA HANDLING |
4914 | M: Martin Mares <mj@ucw.cz> | 4914 | M: Martin Mares <mj@ucw.cz> |
4915 | L: linux-video@atrey.karlin.mff.cuni.cz | 4915 | L: linux-video@atrey.karlin.mff.cuni.cz |
4916 | S: Maintained | 4916 | S: Maintained |
4917 | F: Documentation/svga.txt | 4917 | F: Documentation/svga.txt |
4918 | F: arch/x86/boot/video* | 4918 | F: arch/x86/boot/video* |
4919 | 4919 | ||
4920 | SYSV FILESYSTEM | 4920 | SYSV FILESYSTEM |
4921 | M: Christoph Hellwig <hch@infradead.org> | 4921 | M: Christoph Hellwig <hch@infradead.org> |
4922 | S: Maintained | 4922 | S: Maintained |
4923 | F: Documentation/filesystems/sysv-fs.txt | 4923 | F: Documentation/filesystems/sysv-fs.txt |
4924 | F: fs/sysv/ | 4924 | F: fs/sysv/ |
4925 | F: include/linux/sysv_fs.h | 4925 | F: include/linux/sysv_fs.h |
4926 | 4926 | ||
4927 | TASKSTATS STATISTICS INTERFACE | 4927 | TASKSTATS STATISTICS INTERFACE |
4928 | M: Balbir Singh <balbir@linux.vnet.ibm.com> | 4928 | M: Balbir Singh <balbir@linux.vnet.ibm.com> |
4929 | S: Maintained | 4929 | S: Maintained |
4930 | F: Documentation/accounting/taskstats* | 4930 | F: Documentation/accounting/taskstats* |
4931 | F: include/linux/taskstats* | 4931 | F: include/linux/taskstats* |
4932 | F: kernel/taskstats.c | 4932 | F: kernel/taskstats.c |
4933 | 4933 | ||
4934 | TC CLASSIFIER | 4934 | TC CLASSIFIER |
4935 | M: Jamal Hadi Salim <hadi@cyberus.ca> | 4935 | M: Jamal Hadi Salim <hadi@cyberus.ca> |
4936 | L: netdev@vger.kernel.org | 4936 | L: netdev@vger.kernel.org |
4937 | S: Maintained | 4937 | S: Maintained |
4938 | F: include/linux/pkt_cls.h | 4938 | F: include/linux/pkt_cls.h |
4939 | F: include/net/pkt_cls.h | 4939 | F: include/net/pkt_cls.h |
4940 | F: net/sched/ | 4940 | F: net/sched/ |
4941 | 4941 | ||
4942 | TCP LOW PRIORITY MODULE | 4942 | TCP LOW PRIORITY MODULE |
4943 | M: "Wong Hoi Sing, Edison" <hswong3i@gmail.com> | 4943 | M: "Wong Hoi Sing, Edison" <hswong3i@gmail.com> |
4944 | M: "Hung Hing Lun, Mike" <hlhung3i@gmail.com> | 4944 | M: "Hung Hing Lun, Mike" <hlhung3i@gmail.com> |
4945 | W: http://tcp-lp-mod.sourceforge.net/ | 4945 | W: http://tcp-lp-mod.sourceforge.net/ |
4946 | S: Maintained | 4946 | S: Maintained |
4947 | F: net/ipv4/tcp_lp.c | 4947 | F: net/ipv4/tcp_lp.c |
4948 | 4948 | ||
4949 | TEHUTI ETHERNET DRIVER | 4949 | TEHUTI ETHERNET DRIVER |
4950 | M: Alexander Indenbaum <baum@tehutinetworks.net> | 4950 | M: Alexander Indenbaum <baum@tehutinetworks.net> |
4951 | M: Andy Gospodarek <andy@greyhouse.net> | 4951 | M: Andy Gospodarek <andy@greyhouse.net> |
4952 | L: netdev@vger.kernel.org | 4952 | L: netdev@vger.kernel.org |
4953 | S: Supported | 4953 | S: Supported |
4954 | F: drivers/net/tehuti* | 4954 | F: drivers/net/tehuti* |
4955 | 4955 | ||
4956 | Telecom Clock Driver for MCPL0010 | 4956 | Telecom Clock Driver for MCPL0010 |
4957 | M: Mark Gross <mark.gross@intel.com> | 4957 | M: Mark Gross <mark.gross@intel.com> |
4958 | S: Supported | 4958 | S: Supported |
4959 | F: drivers/char/tlclk.c | 4959 | F: drivers/char/tlclk.c |
4960 | 4960 | ||
4961 | TENSILICA XTENSA PORT (xtensa) | 4961 | TENSILICA XTENSA PORT (xtensa) |
4962 | M: Chris Zankel <chris@zankel.net> | 4962 | M: Chris Zankel <chris@zankel.net> |
4963 | S: Maintained | 4963 | S: Maintained |
4964 | F: arch/xtensa/ | 4964 | F: arch/xtensa/ |
4965 | 4965 | ||
4966 | THINKPAD ACPI EXTRAS DRIVER | 4966 | THINKPAD ACPI EXTRAS DRIVER |
4967 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> | 4967 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> |
4968 | L: ibm-acpi-devel@lists.sourceforge.net | 4968 | L: ibm-acpi-devel@lists.sourceforge.net |
4969 | W: http://ibm-acpi.sourceforge.net | 4969 | W: http://ibm-acpi.sourceforge.net |
4970 | W: http://thinkwiki.org/wiki/Ibm-acpi | 4970 | W: http://thinkwiki.org/wiki/Ibm-acpi |
4971 | T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git | 4971 | T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git |
4972 | S: Maintained | 4972 | S: Maintained |
4973 | F: drivers/platform/x86/thinkpad_acpi.c | 4973 | F: drivers/platform/x86/thinkpad_acpi.c |
4974 | 4974 | ||
4975 | TI FLASH MEDIA INTERFACE DRIVER | 4975 | TI FLASH MEDIA INTERFACE DRIVER |
4976 | M: Alex Dubov <oakad@yahoo.com> | 4976 | M: Alex Dubov <oakad@yahoo.com> |
4977 | S: Maintained | 4977 | S: Maintained |
4978 | F: drivers/misc/tifm* | 4978 | F: drivers/misc/tifm* |
4979 | F: drivers/mmc/host/tifm_sd.c | 4979 | F: drivers/mmc/host/tifm_sd.c |
4980 | F: include/linux/tifm.h | 4980 | F: include/linux/tifm.h |
4981 | 4981 | ||
4982 | TI TWL4030 SERIES SOC CODEC DRIVER | 4982 | TI TWL4030 SERIES SOC CODEC DRIVER |
4983 | M: Peter Ujfalusi <peter.ujfalusi@nokia.com> | 4983 | M: Peter Ujfalusi <peter.ujfalusi@nokia.com> |
4984 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 4984 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
4985 | S: Maintained | 4985 | S: Maintained |
4986 | F: sound/soc/codecs/twl4030* | 4986 | F: sound/soc/codecs/twl4030* |
4987 | 4987 | ||
4988 | TIPC NETWORK LAYER | 4988 | TIPC NETWORK LAYER |
4989 | M: Per Liden <per.liden@ericsson.com> | 4989 | M: Per Liden <per.liden@ericsson.com> |
4990 | M: Jon Maloy <jon.maloy@ericsson.com> | 4990 | M: Jon Maloy <jon.maloy@ericsson.com> |
4991 | M: Allan Stephens <allan.stephens@windriver.com> | 4991 | M: Allan Stephens <allan.stephens@windriver.com> |
4992 | L: tipc-discussion@lists.sourceforge.net | 4992 | L: tipc-discussion@lists.sourceforge.net |
4993 | W: http://tipc.sourceforge.net/ | 4993 | W: http://tipc.sourceforge.net/ |
4994 | W: http://tipc.cslab.ericsson.net/ | 4994 | W: http://tipc.cslab.ericsson.net/ |
4995 | T: git git://tipc.cslab.ericsson.net/pub/git/tipc.git | 4995 | T: git git://tipc.cslab.ericsson.net/pub/git/tipc.git |
4996 | S: Maintained | 4996 | S: Maintained |
4997 | F: include/linux/tipc*.h | 4997 | F: include/linux/tipc*.h |
4998 | F: include/net/tipc/ | 4998 | F: include/net/tipc/ |
4999 | F: net/tipc/ | 4999 | F: net/tipc/ |
5000 | 5000 | ||
5001 | TLAN NETWORK DRIVER | 5001 | TLAN NETWORK DRIVER |
5002 | M: Samuel Chessman <chessman@tux.org> | 5002 | M: Samuel Chessman <chessman@tux.org> |
5003 | L: tlan-devel@lists.sourceforge.net (subscribers-only) | 5003 | L: tlan-devel@lists.sourceforge.net (subscribers-only) |
5004 | W: http://sourceforge.net/projects/tlan/ | 5004 | W: http://sourceforge.net/projects/tlan/ |
5005 | S: Maintained | 5005 | S: Maintained |
5006 | F: Documentation/networking/tlan.txt | 5006 | F: Documentation/networking/tlan.txt |
5007 | F: drivers/net/tlan.* | 5007 | F: drivers/net/tlan.* |
5008 | 5008 | ||
5009 | TOMOYO SECURITY MODULE | 5009 | TOMOYO SECURITY MODULE |
5010 | M: Kentaro Takeda <takedakn@nttdata.co.jp> | 5010 | M: Kentaro Takeda <takedakn@nttdata.co.jp> |
5011 | M: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 5011 | M: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> |
5012 | L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English) | 5012 | L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English) |
5013 | L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) | 5013 | L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) |
5014 | L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) | 5014 | L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) |
5015 | W: http://tomoyo.sourceforge.jp/ | 5015 | W: http://tomoyo.sourceforge.jp/ |
5016 | T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/ | 5016 | T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/ |
5017 | S: Maintained | 5017 | S: Maintained |
5018 | F: security/tomoyo/ | 5018 | F: security/tomoyo/ |
5019 | 5019 | ||
5020 | TOSHIBA ACPI EXTRAS DRIVER | 5020 | TOSHIBA ACPI EXTRAS DRIVER |
5021 | S: Orphan | 5021 | S: Orphan |
5022 | F: drivers/platform/x86/toshiba_acpi.c | 5022 | F: drivers/platform/x86/toshiba_acpi.c |
5023 | 5023 | ||
5024 | TOSHIBA SMM DRIVER | 5024 | TOSHIBA SMM DRIVER |
5025 | M: Jonathan Buzzard <jonathan@buzzard.org.uk> | 5025 | M: Jonathan Buzzard <jonathan@buzzard.org.uk> |
5026 | L: tlinux-users@tce.toshiba-dme.co.jp | 5026 | L: tlinux-users@tce.toshiba-dme.co.jp |
5027 | W: http://www.buzzard.org.uk/toshiba/ | 5027 | W: http://www.buzzard.org.uk/toshiba/ |
5028 | S: Maintained | 5028 | S: Maintained |
5029 | F: drivers/char/toshiba.c | 5029 | F: drivers/char/toshiba.c |
5030 | F: include/linux/toshiba.h | 5030 | F: include/linux/toshiba.h |
5031 | 5031 | ||
5032 | TMIO MMC DRIVER | 5032 | TMIO MMC DRIVER |
5033 | M: Ian Molton <ian@mnementh.co.uk> | 5033 | M: Ian Molton <ian@mnementh.co.uk> |
5034 | S: Maintained | 5034 | S: Maintained |
5035 | F: drivers/mmc/host/tmio_mmc.* | 5035 | F: drivers/mmc/host/tmio_mmc.* |
5036 | 5036 | ||
5037 | TMPFS (SHMEM FILESYSTEM) | 5037 | TMPFS (SHMEM FILESYSTEM) |
5038 | M: Hugh Dickins <hugh.dickins@tiscali.co.uk> | 5038 | M: Hugh Dickins <hugh.dickins@tiscali.co.uk> |
5039 | L: linux-mm@kvack.org | 5039 | L: linux-mm@kvack.org |
5040 | S: Maintained | 5040 | S: Maintained |
5041 | F: include/linux/shmem_fs.h | 5041 | F: include/linux/shmem_fs.h |
5042 | F: mm/shmem.c | 5042 | F: mm/shmem.c |
5043 | 5043 | ||
5044 | TPM DEVICE DRIVER | 5044 | TPM DEVICE DRIVER |
5045 | M: Debora Velarde <debora@linux.vnet.ibm.com> | 5045 | M: Debora Velarde <debora@linux.vnet.ibm.com> |
5046 | M: Rajiv Andrade <srajiv@linux.vnet.ibm.com> | 5046 | M: Rajiv Andrade <srajiv@linux.vnet.ibm.com> |
5047 | W: http://tpmdd.sourceforge.net | 5047 | W: http://tpmdd.sourceforge.net |
5048 | M: Marcel Selhorst <m.selhorst@sirrix.com> | 5048 | M: Marcel Selhorst <m.selhorst@sirrix.com> |
5049 | W: http://www.sirrix.com | 5049 | W: http://www.sirrix.com |
5050 | L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) | 5050 | L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) |
5051 | S: Maintained | 5051 | S: Maintained |
5052 | F: drivers/char/tpm/ | 5052 | F: drivers/char/tpm/ |
5053 | 5053 | ||
5054 | TRIVIAL PATCHES | 5054 | TRIVIAL PATCHES |
5055 | M: Jiri Kosina <trivial@kernel.org> | 5055 | M: Jiri Kosina <trivial@kernel.org> |
5056 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git | 5056 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git |
5057 | S: Maintained | 5057 | S: Maintained |
5058 | 5058 | ||
5059 | TTY LAYER | 5059 | TTY LAYER |
5060 | M: Greg Kroah-Hartman <gregkh@suse.de> | 5060 | M: Greg Kroah-Hartman <gregkh@suse.de> |
5061 | S: Maintained | 5061 | S: Maintained |
5062 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 5062 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
5063 | F: drivers/char/tty_* | 5063 | F: drivers/char/tty_* |
5064 | F: drivers/serial/serial_core.c | 5064 | F: drivers/serial/serial_core.c |
5065 | F: include/linux/serial_core.h | 5065 | F: include/linux/serial_core.h |
5066 | F: include/linux/serial.h | 5066 | F: include/linux/serial.h |
5067 | F: include/linux/tty.h | 5067 | F: include/linux/tty.h |
5068 | 5068 | ||
5069 | TULIP NETWORK DRIVERS | 5069 | TULIP NETWORK DRIVERS |
5070 | M: Grant Grundler <grundler@parisc-linux.org> | 5070 | M: Grant Grundler <grundler@parisc-linux.org> |
5071 | M: Kyle McMartin <kyle@mcmartin.ca> | 5071 | M: Kyle McMartin <kyle@mcmartin.ca> |
5072 | L: netdev@vger.kernel.org | 5072 | L: netdev@vger.kernel.org |
5073 | S: Maintained | 5073 | S: Maintained |
5074 | F: drivers/net/tulip/ | 5074 | F: drivers/net/tulip/ |
5075 | 5075 | ||
5076 | TUN/TAP driver | 5076 | TUN/TAP driver |
5077 | M: Maxim Krasnyansky <maxk@qualcomm.com> | 5077 | M: Maxim Krasnyansky <maxk@qualcomm.com> |
5078 | L: vtun@office.satix.net | 5078 | L: vtun@office.satix.net |
5079 | W: http://vtun.sourceforge.net/tun | 5079 | W: http://vtun.sourceforge.net/tun |
5080 | S: Maintained | 5080 | S: Maintained |
5081 | F: Documentation/networking/tuntap.txt | 5081 | F: Documentation/networking/tuntap.txt |
5082 | F: arch/um/os-Linux/drivers/ | 5082 | F: arch/um/os-Linux/drivers/ |
5083 | 5083 | ||
5084 | TURBOCHANNEL SUBSYSTEM | 5084 | TURBOCHANNEL SUBSYSTEM |
5085 | M: "Maciej W. Rozycki" <macro@linux-mips.org> | 5085 | M: "Maciej W. Rozycki" <macro@linux-mips.org> |
5086 | S: Maintained | 5086 | S: Maintained |
5087 | F: drivers/tc/ | 5087 | F: drivers/tc/ |
5088 | F: include/linux/tc.h | 5088 | F: include/linux/tc.h |
5089 | 5089 | ||
5090 | U14-34F SCSI DRIVER | 5090 | U14-34F SCSI DRIVER |
5091 | M: Dario Ballabio <ballabio_dario@emc.com> | 5091 | M: Dario Ballabio <ballabio_dario@emc.com> |
5092 | L: linux-scsi@vger.kernel.org | 5092 | L: linux-scsi@vger.kernel.org |
5093 | S: Maintained | 5093 | S: Maintained |
5094 | F: drivers/scsi/u14-34f.c | 5094 | F: drivers/scsi/u14-34f.c |
5095 | 5095 | ||
5096 | UBI FILE SYSTEM (UBIFS) | 5096 | UBI FILE SYSTEM (UBIFS) |
5097 | M: Artem Bityutskiy <dedekind@infradead.org> | 5097 | M: Artem Bityutskiy <dedekind@infradead.org> |
5098 | M: Adrian Hunter <adrian.hunter@nokia.com> | 5098 | M: Adrian Hunter <adrian.hunter@nokia.com> |
5099 | L: linux-mtd@lists.infradead.org | 5099 | L: linux-mtd@lists.infradead.org |
5100 | T: git git://git.infradead.org/ubifs-2.6.git | 5100 | T: git git://git.infradead.org/ubifs-2.6.git |
5101 | W: http://www.linux-mtd.infradead.org/doc/ubifs.html | 5101 | W: http://www.linux-mtd.infradead.org/doc/ubifs.html |
5102 | S: Maintained | 5102 | S: Maintained |
5103 | F: Documentation/filesystems/ubifs.txt | 5103 | F: Documentation/filesystems/ubifs.txt |
5104 | F: fs/ubifs/ | 5104 | F: fs/ubifs/ |
5105 | 5105 | ||
5106 | UCLINUX (AND M68KNOMMU) | 5106 | UCLINUX (AND M68KNOMMU) |
5107 | M: Greg Ungerer <gerg@uclinux.org> | 5107 | M: Greg Ungerer <gerg@uclinux.org> |
5108 | W: http://www.uclinux.org/ | 5108 | W: http://www.uclinux.org/ |
5109 | L: uclinux-dev@uclinux.org (subscribers-only) | 5109 | L: uclinux-dev@uclinux.org (subscribers-only) |
5110 | S: Maintained | 5110 | S: Maintained |
5111 | F: arch/m68knommu/ | 5111 | F: arch/m68knommu/ |
5112 | 5112 | ||
5113 | UCLINUX FOR RENESAS H8/300 (H8300) | 5113 | UCLINUX FOR RENESAS H8/300 (H8300) |
5114 | M: Yoshinori Sato <ysato@users.sourceforge.jp> | 5114 | M: Yoshinori Sato <ysato@users.sourceforge.jp> |
5115 | W: http://uclinux-h8.sourceforge.jp/ | 5115 | W: http://uclinux-h8.sourceforge.jp/ |
5116 | S: Supported | 5116 | S: Supported |
5117 | 5117 | ||
5118 | UDF FILESYSTEM | 5118 | UDF FILESYSTEM |
5119 | M: Jan Kara <jack@suse.cz> | 5119 | M: Jan Kara <jack@suse.cz> |
5120 | W: http://linux-udf.sourceforge.net | 5120 | W: http://linux-udf.sourceforge.net |
5121 | S: Maintained | 5121 | S: Maintained |
5122 | F: Documentation/filesystems/udf.txt | 5122 | F: Documentation/filesystems/udf.txt |
5123 | F: fs/udf/ | 5123 | F: fs/udf/ |
5124 | 5124 | ||
5125 | UFS FILESYSTEM | 5125 | UFS FILESYSTEM |
5126 | M: Evgeniy Dushistov <dushistov@mail.ru> | 5126 | M: Evgeniy Dushistov <dushistov@mail.ru> |
5127 | S: Maintained | 5127 | S: Maintained |
5128 | F: Documentation/filesystems/ufs.txt | 5128 | F: Documentation/filesystems/ufs.txt |
5129 | F: fs/ufs/ | 5129 | F: fs/ufs/ |
5130 | 5130 | ||
5131 | ULTRA-WIDEBAND (UWB) SUBSYSTEM: | 5131 | ULTRA-WIDEBAND (UWB) SUBSYSTEM: |
5132 | M: David Vrabel <david.vrabel@csr.com> | 5132 | M: David Vrabel <david.vrabel@csr.com> |
5133 | L: linux-usb@vger.kernel.org | 5133 | L: linux-usb@vger.kernel.org |
5134 | S: Supported | 5134 | S: Supported |
5135 | F: drivers/uwb/* | 5135 | F: drivers/uwb/* |
5136 | F: include/linux/uwb.h | 5136 | F: include/linux/uwb.h |
5137 | F: include/linux/uwb/ | 5137 | F: include/linux/uwb/ |
5138 | 5138 | ||
5139 | UNIFORM CDROM DRIVER | 5139 | UNIFORM CDROM DRIVER |
5140 | M: Jens Axboe <axboe@kernel.dk> | 5140 | M: Jens Axboe <axboe@kernel.dk> |
5141 | W: http://www.kernel.dk | 5141 | W: http://www.kernel.dk |
5142 | S: Maintained | 5142 | S: Maintained |
5143 | F: Documentation/cdrom/ | 5143 | F: Documentation/cdrom/ |
5144 | F: drivers/cdrom/cdrom.c | 5144 | F: drivers/cdrom/cdrom.c |
5145 | F: include/linux/cdrom.h | 5145 | F: include/linux/cdrom.h |
5146 | 5146 | ||
5147 | UNSORTED BLOCK IMAGES (UBI) | 5147 | UNSORTED BLOCK IMAGES (UBI) |
5148 | M: Artem Bityutskiy <dedekind@infradead.org> | 5148 | M: Artem Bityutskiy <dedekind@infradead.org> |
5149 | W: http://www.linux-mtd.infradead.org/ | 5149 | W: http://www.linux-mtd.infradead.org/ |
5150 | L: linux-mtd@lists.infradead.org | 5150 | L: linux-mtd@lists.infradead.org |
5151 | T: git git://git.infradead.org/ubi-2.6.git | 5151 | T: git git://git.infradead.org/ubi-2.6.git |
5152 | S: Maintained | 5152 | S: Maintained |
5153 | F: drivers/mtd/ubi/ | 5153 | F: drivers/mtd/ubi/ |
5154 | F: include/linux/mtd/ubi.h | 5154 | F: include/linux/mtd/ubi.h |
5155 | F: include/mtd/ubi-user.h | 5155 | F: include/mtd/ubi-user.h |
5156 | 5156 | ||
5157 | USB ACM DRIVER | 5157 | USB ACM DRIVER |
5158 | M: Oliver Neukum <oliver@neukum.name> | 5158 | M: Oliver Neukum <oliver@neukum.name> |
5159 | L: linux-usb@vger.kernel.org | 5159 | L: linux-usb@vger.kernel.org |
5160 | S: Maintained | 5160 | S: Maintained |
5161 | F: Documentation/usb/acm.txt | 5161 | F: Documentation/usb/acm.txt |
5162 | F: drivers/usb/class/cdc-acm.* | 5162 | F: drivers/usb/class/cdc-acm.* |
5163 | 5163 | ||
5164 | USB BLOCK DRIVER (UB ub) | 5164 | USB BLOCK DRIVER (UB ub) |
5165 | M: Pete Zaitcev <zaitcev@redhat.com> | 5165 | M: Pete Zaitcev <zaitcev@redhat.com> |
5166 | L: linux-usb@vger.kernel.org | 5166 | L: linux-usb@vger.kernel.org |
5167 | S: Supported | 5167 | S: Supported |
5168 | F: drivers/block/ub.c | 5168 | F: drivers/block/ub.c |
5169 | 5169 | ||
5170 | USB CDC ETHERNET DRIVER | 5170 | USB CDC ETHERNET DRIVER |
5171 | M: Greg Kroah-Hartman <greg@kroah.com> | 5171 | M: Greg Kroah-Hartman <greg@kroah.com> |
5172 | L: linux-usb@vger.kernel.org | 5172 | L: linux-usb@vger.kernel.org |
5173 | S: Maintained | 5173 | S: Maintained |
5174 | W: http://www.kroah.com/linux-usb/ | 5174 | W: http://www.kroah.com/linux-usb/ |
5175 | F: drivers/net/usb/cdc_*.c | 5175 | F: drivers/net/usb/cdc_*.c |
5176 | F: include/linux/usb/cdc.h | 5176 | F: include/linux/usb/cdc.h |
5177 | 5177 | ||
5178 | USB CYPRESS C67X00 DRIVER | 5178 | USB CYPRESS C67X00 DRIVER |
5179 | M: Peter Korsgaard <jacmet@sunsite.dk> | 5179 | M: Peter Korsgaard <jacmet@sunsite.dk> |
5180 | L: linux-usb@vger.kernel.org | 5180 | L: linux-usb@vger.kernel.org |
5181 | S: Maintained | 5181 | S: Maintained |
5182 | F: drivers/usb/c67x00/ | 5182 | F: drivers/usb/c67x00/ |
5183 | 5183 | ||
5184 | USB DAVICOM DM9601 DRIVER | 5184 | USB DAVICOM DM9601 DRIVER |
5185 | M: Peter Korsgaard <jacmet@sunsite.dk> | 5185 | M: Peter Korsgaard <jacmet@sunsite.dk> |
5186 | L: netdev@vger.kernel.org | 5186 | L: netdev@vger.kernel.org |
5187 | W: http://www.linux-usb.org/usbnet | 5187 | W: http://www.linux-usb.org/usbnet |
5188 | S: Maintained | 5188 | S: Maintained |
5189 | F: drivers/net/usb/dm9601.c | 5189 | F: drivers/net/usb/dm9601.c |
5190 | 5190 | ||
5191 | USB DIAMOND RIO500 DRIVER | 5191 | USB DIAMOND RIO500 DRIVER |
5192 | M: Cesar Miquel <miquel@df.uba.ar> | 5192 | M: Cesar Miquel <miquel@df.uba.ar> |
5193 | L: rio500-users@lists.sourceforge.net | 5193 | L: rio500-users@lists.sourceforge.net |
5194 | W: http://rio500.sourceforge.net | 5194 | W: http://rio500.sourceforge.net |
5195 | S: Maintained | 5195 | S: Maintained |
5196 | F: drivers/usb/misc/rio500* | 5196 | F: drivers/usb/misc/rio500* |
5197 | 5197 | ||
5198 | USB EHCI DRIVER | 5198 | USB EHCI DRIVER |
5199 | M: David Brownell <dbrownell@users.sourceforge.net> | 5199 | M: David Brownell <dbrownell@users.sourceforge.net> |
5200 | L: linux-usb@vger.kernel.org | 5200 | L: linux-usb@vger.kernel.org |
5201 | S: Odd Fixes | 5201 | S: Odd Fixes |
5202 | F: Documentation/usb/ehci.txt | 5202 | F: Documentation/usb/ehci.txt |
5203 | F: drivers/usb/host/ehci* | 5203 | F: drivers/usb/host/ehci* |
5204 | 5204 | ||
5205 | USB ET61X[12]51 DRIVER | 5205 | USB ET61X[12]51 DRIVER |
5206 | M: Luca Risolia <luca.risolia@studio.unibo.it> | 5206 | M: Luca Risolia <luca.risolia@studio.unibo.it> |
5207 | L: linux-usb@vger.kernel.org | 5207 | L: linux-usb@vger.kernel.org |
5208 | L: linux-media@vger.kernel.org | 5208 | L: linux-media@vger.kernel.org |
5209 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 5209 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
5210 | W: http://www.linux-projects.org | 5210 | W: http://www.linux-projects.org |
5211 | S: Maintained | 5211 | S: Maintained |
5212 | F: drivers/media/video/et61x251/ | 5212 | F: drivers/media/video/et61x251/ |
5213 | 5213 | ||
5214 | USB GADGET/PERIPHERAL SUBSYSTEM | 5214 | USB GADGET/PERIPHERAL SUBSYSTEM |
5215 | M: David Brownell <dbrownell@users.sourceforge.net> | 5215 | M: David Brownell <dbrownell@users.sourceforge.net> |
5216 | L: linux-usb@vger.kernel.org | 5216 | L: linux-usb@vger.kernel.org |
5217 | W: http://www.linux-usb.org/gadget | 5217 | W: http://www.linux-usb.org/gadget |
5218 | S: Maintained | 5218 | S: Maintained |
5219 | F: drivers/usb/gadget/ | 5219 | F: drivers/usb/gadget/ |
5220 | F: include/linux/usb/gadget* | 5220 | F: include/linux/usb/gadget* |
5221 | 5221 | ||
5222 | USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...) | 5222 | USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...) |
5223 | M: Jiri Kosina <jkosina@suse.cz> | 5223 | M: Jiri Kosina <jkosina@suse.cz> |
5224 | L: linux-usb@vger.kernel.org | 5224 | L: linux-usb@vger.kernel.org |
5225 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git | 5225 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git |
5226 | S: Maintained | 5226 | S: Maintained |
5227 | F: Documentation/usb/hiddev.txt | 5227 | F: Documentation/usb/hiddev.txt |
5228 | F: drivers/hid/usbhid/ | 5228 | F: drivers/hid/usbhid/ |
5229 | 5229 | ||
5230 | USB ISP116X DRIVER | 5230 | USB ISP116X DRIVER |
5231 | M: Olav Kongas <ok@artecdesign.ee> | 5231 | M: Olav Kongas <ok@artecdesign.ee> |
5232 | L: linux-usb@vger.kernel.org | 5232 | L: linux-usb@vger.kernel.org |
5233 | S: Maintained | 5233 | S: Maintained |
5234 | F: drivers/usb/host/isp116x* | 5234 | F: drivers/usb/host/isp116x* |
5235 | F: include/linux/usb/isp116x.h | 5235 | F: include/linux/usb/isp116x.h |
5236 | 5236 | ||
5237 | USB KAWASAKI LSI DRIVER | 5237 | USB KAWASAKI LSI DRIVER |
5238 | M: Oliver Neukum <oliver@neukum.name> | 5238 | M: Oliver Neukum <oliver@neukum.name> |
5239 | L: linux-usb@vger.kernel.org | 5239 | L: linux-usb@vger.kernel.org |
5240 | S: Maintained | 5240 | S: Maintained |
5241 | F: drivers/usb/serial/kl5kusb105.* | 5241 | F: drivers/usb/serial/kl5kusb105.* |
5242 | 5242 | ||
5243 | USB MASS STORAGE DRIVER | 5243 | USB MASS STORAGE DRIVER |
5244 | M: Matthew Dharm <mdharm-usb@one-eyed-alien.net> | 5244 | M: Matthew Dharm <mdharm-usb@one-eyed-alien.net> |
5245 | L: linux-usb@vger.kernel.org | 5245 | L: linux-usb@vger.kernel.org |
5246 | L: usb-storage@lists.one-eyed-alien.net | 5246 | L: usb-storage@lists.one-eyed-alien.net |
5247 | S: Maintained | 5247 | S: Maintained |
5248 | W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ | 5248 | W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ |
5249 | F: drivers/usb/storage/ | 5249 | F: drivers/usb/storage/ |
5250 | 5250 | ||
5251 | USB OHCI DRIVER | 5251 | USB OHCI DRIVER |
5252 | M: David Brownell <dbrownell@users.sourceforge.net> | 5252 | M: David Brownell <dbrownell@users.sourceforge.net> |
5253 | L: linux-usb@vger.kernel.org | 5253 | L: linux-usb@vger.kernel.org |
5254 | S: Odd Fixes | 5254 | S: Odd Fixes |
5255 | F: Documentation/usb/ohci.txt | 5255 | F: Documentation/usb/ohci.txt |
5256 | F: drivers/usb/host/ohci* | 5256 | F: drivers/usb/host/ohci* |
5257 | 5257 | ||
5258 | USB OPTION-CARD DRIVER | 5258 | USB OPTION-CARD DRIVER |
5259 | M: Matthias Urlichs <smurf@smurf.noris.de> | 5259 | M: Matthias Urlichs <smurf@smurf.noris.de> |
5260 | L: linux-usb@vger.kernel.org | 5260 | L: linux-usb@vger.kernel.org |
5261 | S: Maintained | 5261 | S: Maintained |
5262 | F: drivers/usb/serial/option.c | 5262 | F: drivers/usb/serial/option.c |
5263 | 5263 | ||
5264 | USB OV511 DRIVER | 5264 | USB OV511 DRIVER |
5265 | M: Mark McClelland <mmcclell@bigfoot.com> | 5265 | M: Mark McClelland <mmcclell@bigfoot.com> |
5266 | L: linux-usb@vger.kernel.org | 5266 | L: linux-usb@vger.kernel.org |
5267 | W: http://alpha.dyndns.org/ov511/ | 5267 | W: http://alpha.dyndns.org/ov511/ |
5268 | S: Maintained | 5268 | S: Maintained |
5269 | F: drivers/media/video/ov511.* | 5269 | F: drivers/media/video/ov511.* |
5270 | 5270 | ||
5271 | USB PEGASUS DRIVER | 5271 | USB PEGASUS DRIVER |
5272 | M: Petko Manolov <petkan@users.sourceforge.net> | 5272 | M: Petko Manolov <petkan@users.sourceforge.net> |
5273 | L: linux-usb@vger.kernel.org | 5273 | L: linux-usb@vger.kernel.org |
5274 | L: netdev@vger.kernel.org | 5274 | L: netdev@vger.kernel.org |
5275 | W: http://pegasus2.sourceforge.net/ | 5275 | W: http://pegasus2.sourceforge.net/ |
5276 | S: Maintained | 5276 | S: Maintained |
5277 | F: drivers/net/usb/pegasus.* | 5277 | F: drivers/net/usb/pegasus.* |
5278 | 5278 | ||
5279 | USB PRINTER DRIVER (usblp) | 5279 | USB PRINTER DRIVER (usblp) |
5280 | M: Pete Zaitcev <zaitcev@redhat.com> | 5280 | M: Pete Zaitcev <zaitcev@redhat.com> |
5281 | L: linux-usb@vger.kernel.org | 5281 | L: linux-usb@vger.kernel.org |
5282 | S: Supported | 5282 | S: Supported |
5283 | F: drivers/usb/class/usblp.c | 5283 | F: drivers/usb/class/usblp.c |
5284 | 5284 | ||
5285 | USB RTL8150 DRIVER | 5285 | USB RTL8150 DRIVER |
5286 | M: Petko Manolov <petkan@users.sourceforge.net> | 5286 | M: Petko Manolov <petkan@users.sourceforge.net> |
5287 | L: linux-usb@vger.kernel.org | 5287 | L: linux-usb@vger.kernel.org |
5288 | L: netdev@vger.kernel.org | 5288 | L: netdev@vger.kernel.org |
5289 | W: http://pegasus2.sourceforge.net/ | 5289 | W: http://pegasus2.sourceforge.net/ |
5290 | S: Maintained | 5290 | S: Maintained |
5291 | F: drivers/net/usb/rtl8150.c | 5291 | F: drivers/net/usb/rtl8150.c |
5292 | 5292 | ||
5293 | USB SE401 DRIVER | 5293 | USB SE401 DRIVER |
5294 | M: Jeroen Vreeken <pe1rxq@amsat.org> | 5294 | M: Jeroen Vreeken <pe1rxq@amsat.org> |
5295 | L: linux-usb@vger.kernel.org | 5295 | L: linux-usb@vger.kernel.org |
5296 | W: http://www.chello.nl/~j.vreeken/se401/ | 5296 | W: http://www.chello.nl/~j.vreeken/se401/ |
5297 | S: Maintained | 5297 | S: Maintained |
5298 | F: Documentation/video4linux/se401.txt | 5298 | F: Documentation/video4linux/se401.txt |
5299 | F: drivers/media/video/se401.* | 5299 | F: drivers/media/video/se401.* |
5300 | 5300 | ||
5301 | USB SERIAL BELKIN F5U103 DRIVER | 5301 | USB SERIAL BELKIN F5U103 DRIVER |
5302 | M: William Greathouse <wgreathouse@smva.com> | 5302 | M: William Greathouse <wgreathouse@smva.com> |
5303 | L: linux-usb@vger.kernel.org | 5303 | L: linux-usb@vger.kernel.org |
5304 | S: Maintained | 5304 | S: Maintained |
5305 | F: drivers/usb/serial/belkin_sa.* | 5305 | F: drivers/usb/serial/belkin_sa.* |
5306 | 5306 | ||
5307 | USB SERIAL CYPRESS M8 DRIVER | 5307 | USB SERIAL CYPRESS M8 DRIVER |
5308 | M: Lonnie Mendez <dignome@gmail.com> | 5308 | M: Lonnie Mendez <dignome@gmail.com> |
5309 | L: linux-usb@vger.kernel.org | 5309 | L: linux-usb@vger.kernel.org |
5310 | S: Maintained | 5310 | S: Maintained |
5311 | W: http://geocities.com/i0xox0i | 5311 | W: http://geocities.com/i0xox0i |
5312 | W: http://firstlight.net/cvs | 5312 | W: http://firstlight.net/cvs |
5313 | F: drivers/usb/serial/cypress_m8.* | 5313 | F: drivers/usb/serial/cypress_m8.* |
5314 | 5314 | ||
5315 | USB SERIAL CYBERJACK DRIVER | 5315 | USB SERIAL CYBERJACK DRIVER |
5316 | M: Matthias Bruestle and Harald Welte <support@reiner-sct.com> | 5316 | M: Matthias Bruestle and Harald Welte <support@reiner-sct.com> |
5317 | W: http://www.reiner-sct.de/support/treiber_cyberjack.php | 5317 | W: http://www.reiner-sct.de/support/treiber_cyberjack.php |
5318 | S: Maintained | 5318 | S: Maintained |
5319 | F: drivers/usb/serial/cyberjack.c | 5319 | F: drivers/usb/serial/cyberjack.c |
5320 | 5320 | ||
5321 | USB SERIAL DIGI ACCELEPORT DRIVER | 5321 | USB SERIAL DIGI ACCELEPORT DRIVER |
5322 | M: Peter Berger <pberger@brimson.com> | 5322 | M: Peter Berger <pberger@brimson.com> |
5323 | M: Al Borchers <alborchers@steinerpoint.com> | 5323 | M: Al Borchers <alborchers@steinerpoint.com> |
5324 | L: linux-usb@vger.kernel.org | 5324 | L: linux-usb@vger.kernel.org |
5325 | S: Maintained | 5325 | S: Maintained |
5326 | F: drivers/usb/serial/digi_acceleport.c | 5326 | F: drivers/usb/serial/digi_acceleport.c |
5327 | 5327 | ||
5328 | USB SERIAL DRIVER | 5328 | USB SERIAL DRIVER |
5329 | M: Greg Kroah-Hartman <gregkh@suse.de> | 5329 | M: Greg Kroah-Hartman <gregkh@suse.de> |
5330 | L: linux-usb@vger.kernel.org | 5330 | L: linux-usb@vger.kernel.org |
5331 | S: Supported | 5331 | S: Supported |
5332 | F: Documentation/usb/usb-serial.txt | 5332 | F: Documentation/usb/usb-serial.txt |
5333 | F: drivers/usb/serial/generic.c | 5333 | F: drivers/usb/serial/generic.c |
5334 | F: drivers/usb/serial/usb-serial.c | 5334 | F: drivers/usb/serial/usb-serial.c |
5335 | F: include/linux/usb/serial.h | 5335 | F: include/linux/usb/serial.h |
5336 | 5336 | ||
5337 | USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER | 5337 | USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER |
5338 | M: Gary Brubaker <xavyer@ix.netcom.com> | 5338 | M: Gary Brubaker <xavyer@ix.netcom.com> |
5339 | L: linux-usb@vger.kernel.org | 5339 | L: linux-usb@vger.kernel.org |
5340 | S: Maintained | 5340 | S: Maintained |
5341 | F: drivers/usb/serial/empeg.c | 5341 | F: drivers/usb/serial/empeg.c |
5342 | 5342 | ||
5343 | USB SERIAL KEYSPAN DRIVER | 5343 | USB SERIAL KEYSPAN DRIVER |
5344 | M: Greg Kroah-Hartman <greg@kroah.com> | 5344 | M: Greg Kroah-Hartman <greg@kroah.com> |
5345 | L: linux-usb@vger.kernel.org | 5345 | L: linux-usb@vger.kernel.org |
5346 | W: http://www.kroah.com/linux/ | 5346 | W: http://www.kroah.com/linux/ |
5347 | S: Maintained | 5347 | S: Maintained |
5348 | F: drivers/usb/serial/*keyspan* | 5348 | F: drivers/usb/serial/*keyspan* |
5349 | 5349 | ||
5350 | USB SERIAL WHITEHEAT DRIVER | 5350 | USB SERIAL WHITEHEAT DRIVER |
5351 | M: Support Department <support@connecttech.com> | 5351 | M: Support Department <support@connecttech.com> |
5352 | L: linux-usb@vger.kernel.org | 5352 | L: linux-usb@vger.kernel.org |
5353 | W: http://www.connecttech.com | 5353 | W: http://www.connecttech.com |
5354 | S: Supported | 5354 | S: Supported |
5355 | F: drivers/usb/serial/whiteheat* | 5355 | F: drivers/usb/serial/whiteheat* |
5356 | 5356 | ||
5357 | USB SMSC95XX ETHERNET DRIVER | 5357 | USB SMSC95XX ETHERNET DRIVER |
5358 | M: Steve Glendinning <steve.glendinning@smsc.com> | 5358 | M: Steve Glendinning <steve.glendinning@smsc.com> |
5359 | L: netdev@vger.kernel.org | 5359 | L: netdev@vger.kernel.org |
5360 | S: Supported | 5360 | S: Supported |
5361 | F: drivers/net/usb/smsc95xx.* | 5361 | F: drivers/net/usb/smsc95xx.* |
5362 | 5362 | ||
5363 | USB SN9C1xx DRIVER | 5363 | USB SN9C1xx DRIVER |
5364 | M: Luca Risolia <luca.risolia@studio.unibo.it> | 5364 | M: Luca Risolia <luca.risolia@studio.unibo.it> |
5365 | L: linux-usb@vger.kernel.org | 5365 | L: linux-usb@vger.kernel.org |
5366 | L: linux-media@vger.kernel.org | 5366 | L: linux-media@vger.kernel.org |
5367 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 5367 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
5368 | W: http://www.linux-projects.org | 5368 | W: http://www.linux-projects.org |
5369 | S: Maintained | 5369 | S: Maintained |
5370 | F: Documentation/video4linux/sn9c102.txt | 5370 | F: Documentation/video4linux/sn9c102.txt |
5371 | F: drivers/media/video/sn9c102/ | 5371 | F: drivers/media/video/sn9c102/ |
5372 | 5372 | ||
5373 | USB SUBSYSTEM | 5373 | USB SUBSYSTEM |
5374 | M: Greg Kroah-Hartman <gregkh@suse.de> | 5374 | M: Greg Kroah-Hartman <gregkh@suse.de> |
5375 | L: linux-usb@vger.kernel.org | 5375 | L: linux-usb@vger.kernel.org |
5376 | W: http://www.linux-usb.org | 5376 | W: http://www.linux-usb.org |
5377 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 5377 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
5378 | S: Supported | 5378 | S: Supported |
5379 | F: Documentation/usb/ | 5379 | F: Documentation/usb/ |
5380 | F: drivers/net/usb/ | 5380 | F: drivers/net/usb/ |
5381 | F: drivers/usb/ | 5381 | F: drivers/usb/ |
5382 | F: include/linux/usb.h | 5382 | F: include/linux/usb.h |
5383 | F: include/linux/usb/ | 5383 | F: include/linux/usb/ |
5384 | 5384 | ||
5385 | USB UHCI DRIVER | 5385 | USB UHCI DRIVER |
5386 | M: Alan Stern <stern@rowland.harvard.edu> | 5386 | M: Alan Stern <stern@rowland.harvard.edu> |
5387 | L: linux-usb@vger.kernel.org | 5387 | L: linux-usb@vger.kernel.org |
5388 | S: Maintained | 5388 | S: Maintained |
5389 | F: drivers/usb/host/uhci* | 5389 | F: drivers/usb/host/uhci* |
5390 | 5390 | ||
5391 | USB "USBNET" DRIVER FRAMEWORK | 5391 | USB "USBNET" DRIVER FRAMEWORK |
5392 | M: David Brownell <dbrownell@users.sourceforge.net> | 5392 | M: David Brownell <dbrownell@users.sourceforge.net> |
5393 | L: netdev@vger.kernel.org | 5393 | L: netdev@vger.kernel.org |
5394 | W: http://www.linux-usb.org/usbnet | 5394 | W: http://www.linux-usb.org/usbnet |
5395 | S: Maintained | 5395 | S: Maintained |
5396 | F: drivers/net/usb/usbnet.c | 5396 | F: drivers/net/usb/usbnet.c |
5397 | F: include/linux/usb/usbnet.h | 5397 | F: include/linux/usb/usbnet.h |
5398 | 5398 | ||
5399 | USB VIDEO CLASS | 5399 | USB VIDEO CLASS |
5400 | M: Laurent Pinchart <laurent.pinchart@skynet.be> | 5400 | M: Laurent Pinchart <laurent.pinchart@skynet.be> |
5401 | L: linux-uvc-devel@lists.berlios.de (subscribers-only) | 5401 | L: linux-uvc-devel@lists.berlios.de (subscribers-only) |
5402 | L: linux-media@vger.kernel.org | 5402 | L: linux-media@vger.kernel.org |
5403 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 5403 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
5404 | W: http://linux-uvc.berlios.de | 5404 | W: http://linux-uvc.berlios.de |
5405 | S: Maintained | 5405 | S: Maintained |
5406 | F: drivers/media/video/uvc/ | 5406 | F: drivers/media/video/uvc/ |
5407 | 5407 | ||
5408 | USB W996[87]CF DRIVER | 5408 | USB W996[87]CF DRIVER |
5409 | M: Luca Risolia <luca.risolia@studio.unibo.it> | 5409 | M: Luca Risolia <luca.risolia@studio.unibo.it> |
5410 | L: linux-usb@vger.kernel.org | 5410 | L: linux-usb@vger.kernel.org |
5411 | L: linux-media@vger.kernel.org | 5411 | L: linux-media@vger.kernel.org |
5412 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 5412 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
5413 | W: http://www.linux-projects.org | 5413 | W: http://www.linux-projects.org |
5414 | S: Maintained | 5414 | S: Maintained |
5415 | F: Documentation/video4linux/w9968cf.txt | 5415 | F: Documentation/video4linux/w9968cf.txt |
5416 | F: drivers/media/video/w996* | 5416 | F: drivers/media/video/w996* |
5417 | 5417 | ||
5418 | USB WIRELESS RNDIS DRIVER (rndis_wlan) | 5418 | USB WIRELESS RNDIS DRIVER (rndis_wlan) |
5419 | M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 5419 | M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> |
5420 | L: linux-wireless@vger.kernel.org | 5420 | L: linux-wireless@vger.kernel.org |
5421 | S: Maintained | 5421 | S: Maintained |
5422 | F: drivers/net/wireless/rndis_wlan.c | 5422 | F: drivers/net/wireless/rndis_wlan.c |
5423 | 5423 | ||
5424 | USB XHCI DRIVER | 5424 | USB XHCI DRIVER |
5425 | M: Sarah Sharp <sarah.a.sharp@intel.com> | 5425 | M: Sarah Sharp <sarah.a.sharp@intel.com> |
5426 | L: linux-usb@vger.kernel.org | 5426 | L: linux-usb@vger.kernel.org |
5427 | S: Supported | 5427 | S: Supported |
5428 | 5428 | ||
5429 | USB ZC0301 DRIVER | 5429 | USB ZC0301 DRIVER |
5430 | M: Luca Risolia <luca.risolia@studio.unibo.it> | 5430 | M: Luca Risolia <luca.risolia@studio.unibo.it> |
5431 | L: linux-usb@vger.kernel.org | 5431 | L: linux-usb@vger.kernel.org |
5432 | L: linux-media@vger.kernel.org | 5432 | L: linux-media@vger.kernel.org |
5433 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 5433 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
5434 | W: http://www.linux-projects.org | 5434 | W: http://www.linux-projects.org |
5435 | S: Maintained | 5435 | S: Maintained |
5436 | F: Documentation/video4linux/zc0301.txt | 5436 | F: Documentation/video4linux/zc0301.txt |
5437 | F: drivers/media/video/zc0301/ | 5437 | F: drivers/media/video/zc0301/ |
5438 | 5438 | ||
5439 | USB ZD1201 DRIVER | 5439 | USB ZD1201 DRIVER |
5440 | M: Jeroen Vreeken <pe1rxq@amsat.org> | 5440 | M: Jeroen Vreeken <pe1rxq@amsat.org> |
5441 | L: linux-usb@vger.kernel.org | 5441 | L: linux-usb@vger.kernel.org |
5442 | W: http://linux-lc100020.sourceforge.net | 5442 | W: http://linux-lc100020.sourceforge.net |
5443 | S: Maintained | 5443 | S: Maintained |
5444 | F: drivers/net/wireless/zd1201.* | 5444 | F: drivers/net/wireless/zd1201.* |
5445 | 5445 | ||
5446 | USB ZR364XX DRIVER | 5446 | USB ZR364XX DRIVER |
5447 | M: Antoine Jacquet <royale@zerezo.com> | 5447 | M: Antoine Jacquet <royale@zerezo.com> |
5448 | L: linux-usb@vger.kernel.org | 5448 | L: linux-usb@vger.kernel.org |
5449 | L: linux-media@vger.kernel.org | 5449 | L: linux-media@vger.kernel.org |
5450 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | 5450 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
5451 | W: http://royale.zerezo.com/zr364xx/ | 5451 | W: http://royale.zerezo.com/zr364xx/ |
5452 | S: Maintained | 5452 | S: Maintained |
5453 | F: Documentation/video4linux/zr364xx.txt | 5453 | F: Documentation/video4linux/zr364xx.txt |
5454 | F: drivers/media/video/zr364xx.c | 5454 | F: drivers/media/video/zr364xx.c |
5455 | 5455 | ||
5456 | USER-MODE LINUX (UML) | 5456 | USER-MODE LINUX (UML) |
5457 | M: Jeff Dike <jdike@addtoit.com> | 5457 | M: Jeff Dike <jdike@addtoit.com> |
5458 | L: user-mode-linux-devel@lists.sourceforge.net | 5458 | L: user-mode-linux-devel@lists.sourceforge.net |
5459 | L: user-mode-linux-user@lists.sourceforge.net | 5459 | L: user-mode-linux-user@lists.sourceforge.net |
5460 | W: http://user-mode-linux.sourceforge.net | 5460 | W: http://user-mode-linux.sourceforge.net |
5461 | S: Maintained | 5461 | S: Maintained |
5462 | F: Documentation/uml/ | 5462 | F: Documentation/uml/ |
5463 | F: arch/um/ | 5463 | F: arch/um/ |
5464 | F: fs/hostfs/ | 5464 | F: fs/hostfs/ |
5465 | F: fs/hppfs/ | 5465 | F: fs/hppfs/ |
5466 | 5466 | ||
5467 | USERSPACE I/O (UIO) | 5467 | USERSPACE I/O (UIO) |
5468 | M: "Hans J. Koch" <hjk@linutronix.de> | 5468 | M: "Hans J. Koch" <hjk@linutronix.de> |
5469 | M: Greg Kroah-Hartman <gregkh@suse.de> | 5469 | M: Greg Kroah-Hartman <gregkh@suse.de> |
5470 | S: Maintained | 5470 | S: Maintained |
5471 | F: Documentation/DocBook/uio-howto.tmpl | 5471 | F: Documentation/DocBook/uio-howto.tmpl |
5472 | F: drivers/uio/ | 5472 | F: drivers/uio/ |
5473 | F: include/linux/uio*.h | 5473 | F: include/linux/uio*.h |
5474 | 5474 | ||
5475 | UTIL-LINUX-NG PACKAGE | 5475 | UTIL-LINUX-NG PACKAGE |
5476 | M: Karel Zak <kzak@redhat.com> | 5476 | M: Karel Zak <kzak@redhat.com> |
5477 | L: util-linux-ng@vger.kernel.org | 5477 | L: util-linux-ng@vger.kernel.org |
5478 | W: http://kernel.org/~kzak/util-linux-ng/ | 5478 | W: http://kernel.org/~kzak/util-linux-ng/ |
5479 | T: git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git | 5479 | T: git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git |
5480 | S: Maintained | 5480 | S: Maintained |
5481 | 5481 | ||
5482 | UVESAFB DRIVER | 5482 | UVESAFB DRIVER |
5483 | M: Michal Januszewski <spock@gentoo.org> | 5483 | M: Michal Januszewski <spock@gentoo.org> |
5484 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5484 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
5485 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ | 5485 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ |
5486 | S: Maintained | 5486 | S: Maintained |
5487 | F: Documentation/fb/uvesafb.txt | 5487 | F: Documentation/fb/uvesafb.txt |
5488 | F: drivers/video/uvesafb.* | 5488 | F: drivers/video/uvesafb.* |
5489 | 5489 | ||
5490 | VFAT/FAT/MSDOS FILESYSTEM | 5490 | VFAT/FAT/MSDOS FILESYSTEM |
5491 | M: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 5491 | M: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> |
5492 | S: Maintained | 5492 | S: Maintained |
5493 | F: Documentation/filesystems/vfat.txt | 5493 | F: Documentation/filesystems/vfat.txt |
5494 | F: fs/fat/ | 5494 | F: fs/fat/ |
5495 | 5495 | ||
5496 | VIA RHINE NETWORK DRIVER | 5496 | VIA RHINE NETWORK DRIVER |
5497 | M: Roger Luethi <rl@hellgate.ch> | 5497 | M: Roger Luethi <rl@hellgate.ch> |
5498 | S: Maintained | 5498 | S: Maintained |
5499 | F: drivers/net/via-rhine.c | 5499 | F: drivers/net/via-rhine.c |
5500 | 5500 | ||
5501 | VIAPRO SMBUS DRIVER | 5501 | VIAPRO SMBUS DRIVER |
5502 | M: Jean Delvare <khali@linux-fr.org> | 5502 | M: Jean Delvare <khali@linux-fr.org> |
5503 | L: linux-i2c@vger.kernel.org | 5503 | L: linux-i2c@vger.kernel.org |
5504 | S: Maintained | 5504 | S: Maintained |
5505 | F: Documentation/i2c/busses/i2c-viapro | 5505 | F: Documentation/i2c/busses/i2c-viapro |
5506 | F: drivers/i2c/busses/i2c-viapro.c | 5506 | F: drivers/i2c/busses/i2c-viapro.c |
5507 | 5507 | ||
5508 | VIA SD/MMC CARD CONTROLLER DRIVER | 5508 | VIA SD/MMC CARD CONTROLLER DRIVER |
5509 | M: Joseph Chan <JosephChan@via.com.tw> | 5509 | M: Joseph Chan <JosephChan@via.com.tw> |
5510 | M: Harald Welte <HaraldWelte@viatech.com> | 5510 | M: Harald Welte <HaraldWelte@viatech.com> |
5511 | S: Maintained | 5511 | S: Maintained |
5512 | F: drivers/mmc/host/via-sdmmc.c | 5512 | F: drivers/mmc/host/via-sdmmc.c |
5513 | 5513 | ||
5514 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER | 5514 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER |
5515 | M: Joseph Chan <JosephChan@via.com.tw> | 5515 | M: Joseph Chan <JosephChan@via.com.tw> |
5516 | M: Scott Fang <ScottFang@viatech.com.cn> | 5516 | M: Scott Fang <ScottFang@viatech.com.cn> |
5517 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5517 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) |
5518 | S: Maintained | 5518 | S: Maintained |
5519 | F: drivers/video/via/ | 5519 | F: drivers/video/via/ |
5520 | 5520 | ||
5521 | VIA VELOCITY NETWORK DRIVER | 5521 | VIA VELOCITY NETWORK DRIVER |
5522 | M: Francois Romieu <romieu@fr.zoreil.com> | 5522 | M: Francois Romieu <romieu@fr.zoreil.com> |
5523 | L: netdev@vger.kernel.org | 5523 | L: netdev@vger.kernel.org |
5524 | S: Maintained | 5524 | S: Maintained |
5525 | F: drivers/net/via-velocity.* | 5525 | F: drivers/net/via-velocity.* |
5526 | 5526 | ||
5527 | VLAN (802.1Q) | 5527 | VLAN (802.1Q) |
5528 | M: Patrick McHardy <kaber@trash.net> | 5528 | M: Patrick McHardy <kaber@trash.net> |
5529 | L: netdev@vger.kernel.org | 5529 | L: netdev@vger.kernel.org |
5530 | S: Maintained | 5530 | S: Maintained |
5531 | F: drivers/net/macvlan.c | 5531 | F: drivers/net/macvlan.c |
5532 | F: include/linux/if_*vlan.h | 5532 | F: include/linux/if_*vlan.h |
5533 | F: net/8021q/ | 5533 | F: net/8021q/ |
5534 | 5534 | ||
5535 | VLYNQ BUS | 5535 | VLYNQ BUS |
5536 | M: Florian Fainelli <florian@openwrt.org> | 5536 | M: Florian Fainelli <florian@openwrt.org> |
5537 | L: openwrt-devel@lists.openwrt.org | 5537 | L: openwrt-devel@lists.openwrt.org |
5538 | S: Maintained | 5538 | S: Maintained |
5539 | F: drivers/vlynq/vlynq.c | 5539 | F: drivers/vlynq/vlynq.c |
5540 | F: include/linux/vlynq.h | 5540 | F: include/linux/vlynq.h |
5541 | 5541 | ||
5542 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK | 5542 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK |
5543 | M: Liam Girdwood <lrg@slimlogic.co.uk> | 5543 | M: Liam Girdwood <lrg@slimlogic.co.uk> |
5544 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> | 5544 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> |
5545 | W: http://opensource.wolfsonmicro.com/node/15 | 5545 | W: http://opensource.wolfsonmicro.com/node/15 |
5546 | W: http://www.slimlogic.co.uk/?p=48 | 5546 | W: http://www.slimlogic.co.uk/?p=48 |
5547 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git | 5547 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git |
5548 | S: Supported | 5548 | S: Supported |
5549 | F: drivers/regulator/ | 5549 | F: drivers/regulator/ |
5550 | F: include/linux/regulator/ | 5550 | F: include/linux/regulator/ |
5551 | 5551 | ||
5552 | VT1211 HARDWARE MONITOR DRIVER | 5552 | VT1211 HARDWARE MONITOR DRIVER |
5553 | M: Juerg Haefliger <juergh@gmail.com> | 5553 | M: Juerg Haefliger <juergh@gmail.com> |
5554 | L: lm-sensors@lm-sensors.org | 5554 | L: lm-sensors@lm-sensors.org |
5555 | S: Maintained | 5555 | S: Maintained |
5556 | F: Documentation/hwmon/vt1211 | 5556 | F: Documentation/hwmon/vt1211 |
5557 | F: drivers/hwmon/vt1211.c | 5557 | F: drivers/hwmon/vt1211.c |
5558 | 5558 | ||
5559 | VT8231 HARDWARE MONITOR DRIVER | 5559 | VT8231 HARDWARE MONITOR DRIVER |
5560 | M: Roger Lucas <vt8231@hiddenengine.co.uk> | 5560 | M: Roger Lucas <vt8231@hiddenengine.co.uk> |
5561 | L: lm-sensors@lm-sensors.org | 5561 | L: lm-sensors@lm-sensors.org |
5562 | S: Maintained | 5562 | S: Maintained |
5563 | F: drivers/hwmon/vt8231.c | 5563 | F: drivers/hwmon/vt8231.c |
5564 | 5564 | ||
5565 | W1 DALLAS'S 1-WIRE BUS | 5565 | W1 DALLAS'S 1-WIRE BUS |
5566 | M: Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 5566 | M: Evgeniy Polyakov <johnpol@2ka.mipt.ru> |
5567 | S: Maintained | 5567 | S: Maintained |
5568 | F: Documentation/w1/ | 5568 | F: Documentation/w1/ |
5569 | F: drivers/w1/ | 5569 | F: drivers/w1/ |
5570 | 5570 | ||
5571 | W83791D HARDWARE MONITORING DRIVER | 5571 | W83791D HARDWARE MONITORING DRIVER |
5572 | M: Marc Hulsman <m.hulsman@tudelft.nl> | 5572 | M: Marc Hulsman <m.hulsman@tudelft.nl> |
5573 | L: lm-sensors@lm-sensors.org | 5573 | L: lm-sensors@lm-sensors.org |
5574 | S: Maintained | 5574 | S: Maintained |
5575 | F: Documentation/hwmon/w83791d | 5575 | F: Documentation/hwmon/w83791d |
5576 | F: drivers/hwmon/w83791d.c | 5576 | F: drivers/hwmon/w83791d.c |
5577 | 5577 | ||
5578 | W83793 HARDWARE MONITORING DRIVER | 5578 | W83793 HARDWARE MONITORING DRIVER |
5579 | M: Rudolf Marek <r.marek@assembler.cz> | 5579 | M: Rudolf Marek <r.marek@assembler.cz> |
5580 | L: lm-sensors@lm-sensors.org | 5580 | L: lm-sensors@lm-sensors.org |
5581 | S: Maintained | 5581 | S: Maintained |
5582 | F: Documentation/hwmon/w83793 | 5582 | F: Documentation/hwmon/w83793 |
5583 | F: drivers/hwmon/w83793.c | 5583 | F: drivers/hwmon/w83793.c |
5584 | 5584 | ||
5585 | W83L51xD SD/MMC CARD INTERFACE DRIVER | 5585 | W83L51xD SD/MMC CARD INTERFACE DRIVER |
5586 | M: Pierre Ossman <pierre@ossman.eu> | 5586 | M: Pierre Ossman <pierre@ossman.eu> |
5587 | S: Maintained | 5587 | S: Maintained |
5588 | F: drivers/mmc/host/wbsd.* | 5588 | F: drivers/mmc/host/wbsd.* |
5589 | 5589 | ||
5590 | WATCHDOG DEVICE DRIVERS | 5590 | WATCHDOG DEVICE DRIVERS |
5591 | M: Wim Van Sebroeck <wim@iguana.be> | 5591 | M: Wim Van Sebroeck <wim@iguana.be> |
5592 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git | 5592 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git |
5593 | S: Maintained | 5593 | S: Maintained |
5594 | F: Documentation/watchdog/ | 5594 | F: Documentation/watchdog/ |
5595 | F: drivers/watchdog/ | 5595 | F: drivers/watchdog/ |
5596 | F: include/linux/watchdog.h | 5596 | F: include/linux/watchdog.h |
5597 | 5597 | ||
5598 | WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS | 5598 | WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS |
5599 | M: Jean Tourrilhes <jt@hpl.hp.com> | 5599 | M: Jean Tourrilhes <jt@hpl.hp.com> |
5600 | L: linux-wireless@vger.kernel.org | 5600 | L: linux-wireless@vger.kernel.org |
5601 | W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ | 5601 | W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ |
5602 | S: Maintained | 5602 | S: Maintained |
5603 | F: Documentation/networking/wavelan.txt | 5603 | F: Documentation/networking/wavelan.txt |
5604 | F: drivers/net/wireless/wavelan* | 5604 | F: drivers/net/wireless/wavelan* |
5605 | 5605 | ||
5606 | WD7000 SCSI DRIVER | 5606 | WD7000 SCSI DRIVER |
5607 | M: Miroslav Zagorac <zaga@fly.cc.fer.hr> | 5607 | M: Miroslav Zagorac <zaga@fly.cc.fer.hr> |
5608 | L: linux-scsi@vger.kernel.org | 5608 | L: linux-scsi@vger.kernel.org |
5609 | S: Maintained | 5609 | S: Maintained |
5610 | F: drivers/scsi/wd7000.c | 5610 | F: drivers/scsi/wd7000.c |
5611 | 5611 | ||
5612 | WIMAX STACK | 5612 | WIMAX STACK |
5613 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 5613 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
5614 | M: linux-wimax@intel.com | 5614 | M: linux-wimax@intel.com |
5615 | L: wimax@linuxwimax.org | 5615 | L: wimax@linuxwimax.org |
5616 | S: Supported | 5616 | S: Supported |
5617 | W: http://linuxwimax.org | 5617 | W: http://linuxwimax.org |
5618 | 5618 | ||
5619 | WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM | 5619 | WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM |
5620 | M: David Vrabel <david.vrabel@csr.com> | 5620 | M: David Vrabel <david.vrabel@csr.com> |
5621 | S: Maintained | 5621 | S: Maintained |
5622 | F: include/linux/wlp.h | 5622 | F: include/linux/wlp.h |
5623 | F: drivers/uwb/wlp/ | 5623 | F: drivers/uwb/wlp/ |
5624 | 5624 | ||
5625 | WISTRON LAPTOP BUTTON DRIVER | 5625 | WISTRON LAPTOP BUTTON DRIVER |
5626 | M: Miloslav Trmac <mitr@volny.cz> | 5626 | M: Miloslav Trmac <mitr@volny.cz> |
5627 | S: Maintained | 5627 | S: Maintained |
5628 | F: drivers/input/misc/wistron_btns.c | 5628 | F: drivers/input/misc/wistron_btns.c |
5629 | 5629 | ||
5630 | WL1251 WIRELESS DRIVER | 5630 | WL1251 WIRELESS DRIVER |
5631 | P: Kalle Valo | 5631 | P: Kalle Valo |
5632 | M: kalle.valo@nokia.com | 5632 | M: kalle.valo@nokia.com |
5633 | L: linux-wireless@vger.kernel.org | 5633 | L: linux-wireless@vger.kernel.org |
5634 | W: http://wireless.kernel.org | 5634 | W: http://wireless.kernel.org |
5635 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | 5635 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git |
5636 | S: Maintained | 5636 | S: Maintained |
5637 | F: drivers/net/wireless/wl12xx/* | 5637 | F: drivers/net/wireless/wl12xx/* |
5638 | X: drivers/net/wireless/wl12xx/wl1271* | 5638 | X: drivers/net/wireless/wl12xx/wl1271* |
5639 | 5639 | ||
5640 | WL1271 WIRELESS DRIVER | 5640 | WL1271 WIRELESS DRIVER |
5641 | M: Luciano Coelho <luciano.coelho@nokia.com> | 5641 | M: Luciano Coelho <luciano.coelho@nokia.com> |
5642 | L: linux-wireless@vger.kernel.org | 5642 | L: linux-wireless@vger.kernel.org |
5643 | W: http://wireless.kernel.org | 5643 | W: http://wireless.kernel.org |
5644 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | 5644 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git |
5645 | S: Maintained | 5645 | S: Maintained |
5646 | F: drivers/net/wireless/wl12xx/wl1271* | 5646 | F: drivers/net/wireless/wl12xx/wl1271* |
5647 | 5647 | ||
5648 | WL3501 WIRELESS PCMCIA CARD DRIVER | 5648 | WL3501 WIRELESS PCMCIA CARD DRIVER |
5649 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 5649 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
5650 | L: linux-wireless@vger.kernel.org | 5650 | L: linux-wireless@vger.kernel.org |
5651 | W: http://oops.ghostprotocols.net:81/blog | 5651 | W: http://oops.ghostprotocols.net:81/blog |
5652 | S: Maintained | 5652 | S: Maintained |
5653 | F: drivers/net/wireless/wl3501* | 5653 | F: drivers/net/wireless/wl3501* |
5654 | 5654 | ||
5655 | WM97XX TOUCHSCREEN DRIVERS | 5655 | WM97XX TOUCHSCREEN DRIVERS |
5656 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> | 5656 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> |
5657 | M: Liam Girdwood <lrg@slimlogic.co.uk> | 5657 | M: Liam Girdwood <lrg@slimlogic.co.uk> |
5658 | L: linux-input@vger.kernel.org | 5658 | L: linux-input@vger.kernel.org |
5659 | T: git git://opensource.wolfsonmicro.com/linux-2.6-touch | 5659 | T: git git://opensource.wolfsonmicro.com/linux-2.6-touch |
5660 | W: http://opensource.wolfsonmicro.com/node/7 | 5660 | W: http://opensource.wolfsonmicro.com/node/7 |
5661 | S: Supported | 5661 | S: Supported |
5662 | F: drivers/input/touchscreen/*wm97* | 5662 | F: drivers/input/touchscreen/*wm97* |
5663 | F: include/linux/wm97xx.h | 5663 | F: include/linux/wm97xx.h |
5664 | 5664 | ||
5665 | X.25 NETWORK LAYER | 5665 | X.25 NETWORK LAYER |
5666 | M: Henner Eisen <eis@baty.hanse.de> | 5666 | M: Henner Eisen <eis@baty.hanse.de> |
5667 | L: linux-x25@vger.kernel.org | 5667 | L: linux-x25@vger.kernel.org |
5668 | S: Maintained | 5668 | S: Maintained |
5669 | F: Documentation/networking/x25* | 5669 | F: Documentation/networking/x25* |
5670 | F: include/net/x25* | 5670 | F: include/net/x25* |
5671 | F: net/x25/ | 5671 | F: net/x25/ |
5672 | 5672 | ||
5673 | X86 ARCHITECTURE (32-BIT AND 64-BIT) | 5673 | X86 ARCHITECTURE (32-BIT AND 64-BIT) |
5674 | M: Thomas Gleixner <tglx@linutronix.de> | 5674 | M: Thomas Gleixner <tglx@linutronix.de> |
5675 | M: Ingo Molnar <mingo@redhat.com> | 5675 | M: Ingo Molnar <mingo@redhat.com> |
5676 | M: "H. Peter Anvin" <hpa@zytor.com> | 5676 | M: "H. Peter Anvin" <hpa@zytor.com> |
5677 | M: x86@kernel.org | 5677 | M: x86@kernel.org |
5678 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git | 5678 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git |
5679 | S: Maintained | 5679 | S: Maintained |
5680 | F: Documentation/x86/ | 5680 | F: Documentation/x86/ |
5681 | F: arch/x86/ | 5681 | F: arch/x86/ |
5682 | 5682 | ||
5683 | XEN HYPERVISOR INTERFACE | 5683 | XEN HYPERVISOR INTERFACE |
5684 | M: Jeremy Fitzhardinge <jeremy@xensource.com> | 5684 | M: Jeremy Fitzhardinge <jeremy@xensource.com> |
5685 | M: Chris Wright <chrisw@sous-sol.org> | 5685 | M: Chris Wright <chrisw@sous-sol.org> |
5686 | L: virtualization@lists.osdl.org | 5686 | L: virtualization@lists.osdl.org |
5687 | L: xen-devel@lists.xensource.com | 5687 | L: xen-devel@lists.xensource.com |
5688 | S: Supported | 5688 | S: Supported |
5689 | F: arch/x86/xen/ | 5689 | F: arch/x86/xen/ |
5690 | F: drivers/*/xen-*front.c | 5690 | F: drivers/*/xen-*front.c |
5691 | F: drivers/xen/ | 5691 | F: drivers/xen/ |
5692 | F: arch/x86/include/asm/xen/ | 5692 | F: arch/x86/include/asm/xen/ |
5693 | F: include/xen/ | 5693 | F: include/xen/ |
5694 | 5694 | ||
5695 | XFS FILESYSTEM | 5695 | XFS FILESYSTEM |
5696 | P: Silicon Graphics Inc | 5696 | P: Silicon Graphics Inc |
5697 | M: Felix Blyakher <felixb@sgi.com> | 5697 | M: Felix Blyakher <felixb@sgi.com> |
5698 | M: xfs-masters@oss.sgi.com | 5698 | M: xfs-masters@oss.sgi.com |
5699 | L: xfs@oss.sgi.com | 5699 | L: xfs@oss.sgi.com |
5700 | W: http://oss.sgi.com/projects/xfs | 5700 | W: http://oss.sgi.com/projects/xfs |
5701 | T: git git://oss.sgi.com/xfs/xfs.git | 5701 | T: git git://oss.sgi.com/xfs/xfs.git |
5702 | S: Supported | 5702 | S: Supported |
5703 | F: Documentation/filesystems/xfs.txt | 5703 | F: Documentation/filesystems/xfs.txt |
5704 | F: fs/xfs/ | 5704 | F: fs/xfs/ |
5705 | 5705 | ||
5706 | XILINX SYSTEMACE DRIVER | 5706 | XILINX SYSTEMACE DRIVER |
5707 | M: Grant Likely <grant.likely@secretlab.ca> | 5707 | M: Grant Likely <grant.likely@secretlab.ca> |
5708 | W: http://www.secretlab.ca/ | 5708 | W: http://www.secretlab.ca/ |
5709 | S: Maintained | 5709 | S: Maintained |
5710 | F: drivers/block/xsysace.c | 5710 | F: drivers/block/xsysace.c |
5711 | 5711 | ||
5712 | XILINX UARTLITE SERIAL DRIVER | 5712 | XILINX UARTLITE SERIAL DRIVER |
5713 | M: Peter Korsgaard <jacmet@sunsite.dk> | 5713 | M: Peter Korsgaard <jacmet@sunsite.dk> |
5714 | L: linux-serial@vger.kernel.org | 5714 | L: linux-serial@vger.kernel.org |
5715 | S: Maintained | 5715 | S: Maintained |
5716 | F: drivers/serial/uartlite.c | 5716 | F: drivers/serial/uartlite.c |
5717 | 5717 | ||
5718 | YAM DRIVER FOR AX.25 | 5718 | YAM DRIVER FOR AX.25 |
5719 | M: Jean-Paul Roubelat <jpr@f6fbb.org> | 5719 | M: Jean-Paul Roubelat <jpr@f6fbb.org> |
5720 | L: linux-hams@vger.kernel.org | 5720 | L: linux-hams@vger.kernel.org |
5721 | S: Maintained | 5721 | S: Maintained |
5722 | F: drivers/net/hamradio/yam* | 5722 | F: drivers/net/hamradio/yam* |
5723 | F: include/linux/yam.h | 5723 | F: include/linux/yam.h |
5724 | 5724 | ||
5725 | YEALINK PHONE DRIVER | 5725 | YEALINK PHONE DRIVER |
5726 | M: Henk Vergonet <Henk.Vergonet@gmail.com> | 5726 | M: Henk Vergonet <Henk.Vergonet@gmail.com> |
5727 | L: usbb2k-api-dev@nongnu.org | 5727 | L: usbb2k-api-dev@nongnu.org |
5728 | S: Maintained | 5728 | S: Maintained |
5729 | F: Documentation/input/yealink.txt | 5729 | F: Documentation/input/yealink.txt |
5730 | F: drivers/input/misc/yealink.* | 5730 | F: drivers/input/misc/yealink.* |
5731 | 5731 | ||
5732 | Z8530 DRIVER FOR AX.25 | 5732 | Z8530 DRIVER FOR AX.25 |
5733 | M: Joerg Reuter <jreuter@yaina.de> | 5733 | M: Joerg Reuter <jreuter@yaina.de> |
5734 | W: http://yaina.de/jreuter/ | 5734 | W: http://yaina.de/jreuter/ |
5735 | W: http://www.qsl.net/dl1bke/ | 5735 | W: http://www.qsl.net/dl1bke/ |
5736 | L: linux-hams@vger.kernel.org | 5736 | L: linux-hams@vger.kernel.org |
5737 | S: Maintained | 5737 | S: Maintained |
5738 | F: Documentation/networking/z8530drv.txt | 5738 | F: Documentation/networking/z8530drv.txt |
5739 | F: drivers/net/hamradio/*scc.c | 5739 | F: drivers/net/hamradio/*scc.c |
5740 | F: drivers/net/hamradio/z8530.h | 5740 | F: drivers/net/hamradio/z8530.h |
5741 | 5741 | ||
5742 | ZD1211RW WIRELESS DRIVER | 5742 | ZD1211RW WIRELESS DRIVER |
5743 | M: Daniel Drake <dsd@gentoo.org> | 5743 | M: Daniel Drake <dsd@gentoo.org> |
5744 | M: Ulrich Kunitz <kune@deine-taler.de> | 5744 | M: Ulrich Kunitz <kune@deine-taler.de> |
5745 | W: http://zd1211.ath.cx/wiki/DriverRewrite | 5745 | W: http://zd1211.ath.cx/wiki/DriverRewrite |
5746 | L: linux-wireless@vger.kernel.org | 5746 | L: linux-wireless@vger.kernel.org |
5747 | L: zd1211-devs@lists.sourceforge.net (subscribers-only) | 5747 | L: zd1211-devs@lists.sourceforge.net (subscribers-only) |
5748 | S: Maintained | 5748 | S: Maintained |
5749 | F: drivers/net/wireless/zd1211rw/ | 5749 | F: drivers/net/wireless/zd1211rw/ |
5750 | 5750 | ||
5751 | ZR36067 VIDEO FOR LINUX DRIVER | 5751 | ZR36067 VIDEO FOR LINUX DRIVER |
5752 | L: mjpeg-users@lists.sourceforge.net | 5752 | L: mjpeg-users@lists.sourceforge.net |
5753 | L: linux-media@vger.kernel.org | 5753 | L: linux-media@vger.kernel.org |
5754 | W: http://mjpeg.sourceforge.net/driver-zoran/ | 5754 | W: http://mjpeg.sourceforge.net/driver-zoran/ |
5755 | T: Mercurial http://linuxtv.org/hg/v4l-dvb | 5755 | T: Mercurial http://linuxtv.org/hg/v4l-dvb |
5756 | S: Odd Fixes | 5756 | S: Odd Fixes |
5757 | F: drivers/media/video/zoran/ | 5757 | F: drivers/media/video/zoran/ |
5758 | 5758 | ||
5759 | ZS DECSTATION Z85C30 SERIAL DRIVER | 5759 | ZS DECSTATION Z85C30 SERIAL DRIVER |
5760 | M: "Maciej W. Rozycki" <macro@linux-mips.org> | 5760 | M: "Maciej W. Rozycki" <macro@linux-mips.org> |
5761 | S: Maintained | 5761 | S: Maintained |
5762 | F: drivers/serial/zs.* | 5762 | F: drivers/serial/zs.* |
5763 | 5763 | ||
5764 | THE REST | 5764 | THE REST |
5765 | M: Linus Torvalds <torvalds@linux-foundation.org> | 5765 | M: Linus Torvalds <torvalds@linux-foundation.org> |
5766 | L: linux-kernel@vger.kernel.org | 5766 | L: linux-kernel@vger.kernel.org |
5767 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git | 5767 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git |
5768 | S: Buried alive in reporters | 5768 | S: Buried alive in reporters |
5769 | F: * | 5769 | F: * |
5770 | F: */ | 5770 | F: */ |
5771 | 5771 |
arch/arm/boot/compressed/head-sa1100.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/boot/compressed/head-sa1100.S | 2 | * linux/arch/arm/boot/compressed/head-sa1100.S |
3 | * | 3 | * |
4 | * Copyright (C) 1999 Nicolas Pitre <nico@cam.org> | 4 | * Copyright (C) 1999 Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * SA1100 specific tweaks. This is merged into head.S by the linker. | 6 | * SA1100 specific tweaks. This is merged into head.S by the linker. |
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
11 | #include <asm/mach-types.h> | 11 | #include <asm/mach-types.h> |
12 | 12 | ||
13 | .section ".start", "ax" | 13 | .section ".start", "ax" |
14 | 14 | ||
15 | __SA1100_start: | 15 | __SA1100_start: |
16 | 16 | ||
17 | @ Preserve r8/r7 i.e. kernel entry values | 17 | @ Preserve r8/r7 i.e. kernel entry values |
18 | #ifdef CONFIG_SA1100_COLLIE | 18 | #ifdef CONFIG_SA1100_COLLIE |
19 | mov r7, #MACH_TYPE_COLLIE | 19 | mov r7, #MACH_TYPE_COLLIE |
20 | #endif | 20 | #endif |
21 | #ifdef CONFIG_SA1100_SIMPAD | 21 | #ifdef CONFIG_SA1100_SIMPAD |
22 | @ UNTIL we've something like an open bootldr | 22 | @ UNTIL we've something like an open bootldr |
23 | mov r7, #MACH_TYPE_SIMPAD @should be 87 | 23 | mov r7, #MACH_TYPE_SIMPAD @should be 87 |
24 | #endif | 24 | #endif |
25 | mrc p15, 0, r0, c1, c0, 0 @ read control reg | 25 | mrc p15, 0, r0, c1, c0, 0 @ read control reg |
26 | ands r0, r0, #0x0d | 26 | ands r0, r0, #0x0d |
27 | beq 99f | 27 | beq 99f |
28 | 28 | ||
29 | @ Data cache might be active. | 29 | @ Data cache might be active. |
30 | @ Be sure to flush kernel binary out of the cache, | 30 | @ Be sure to flush kernel binary out of the cache, |
31 | @ whatever state it is, before it is turned off. | 31 | @ whatever state it is, before it is turned off. |
32 | @ This is done by fetching through currently executed | 32 | @ This is done by fetching through currently executed |
33 | @ memory to be sure we hit the same cache. | 33 | @ memory to be sure we hit the same cache. |
34 | bic r2, pc, #0x1f | 34 | bic r2, pc, #0x1f |
35 | add r3, r2, #0x4000 @ 16 kb is quite enough... | 35 | add r3, r2, #0x4000 @ 16 kb is quite enough... |
36 | 1: ldr r0, [r2], #32 | 36 | 1: ldr r0, [r2], #32 |
37 | teq r2, r3 | 37 | teq r2, r3 |
38 | bne 1b | 38 | bne 1b |
39 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | 39 | mcr p15, 0, r0, c7, c10, 4 @ drain WB |
40 | mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches | 40 | mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches |
41 | 41 | ||
42 | @ disabling MMU and caches | 42 | @ disabling MMU and caches |
43 | mrc p15, 0, r0, c1, c0, 0 @ read control reg | 43 | mrc p15, 0, r0, c1, c0, 0 @ read control reg |
44 | bic r0, r0, #0x0d @ clear WB, DC, MMU | 44 | bic r0, r0, #0x0d @ clear WB, DC, MMU |
45 | bic r0, r0, #0x1000 @ clear Icache | 45 | bic r0, r0, #0x1000 @ clear Icache |
46 | mcr p15, 0, r0, c1, c0, 0 | 46 | mcr p15, 0, r0, c1, c0, 0 |
47 | 99: | 47 | 99: |
48 | 48 |
arch/arm/lib/lib1funcs.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines | 2 | * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines |
3 | * | 3 | * |
4 | * Author: Nicolas Pitre <nico@cam.org> | 4 | * Author: Nicolas Pitre <nico@fluxnic.net> |
5 | * - contributed to gcc-3.4 on Sep 30, 2003 | 5 | * - contributed to gcc-3.4 on Sep 30, 2003 |
6 | * - adapted for the Linux kernel on Oct 2, 2003 | 6 | * - adapted for the Linux kernel on Oct 2, 2003 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. | 9 | /* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. |
10 | 10 | ||
11 | This file is free software; you can redistribute it and/or modify it | 11 | This file is free software; you can redistribute it and/or modify it |
12 | under the terms of the GNU General Public License as published by the | 12 | under the terms of the GNU General Public License as published by the |
13 | Free Software Foundation; either version 2, or (at your option) any | 13 | Free Software Foundation; either version 2, or (at your option) any |
14 | later version. | 14 | later version. |
15 | 15 | ||
16 | In addition to the permissions in the GNU General Public License, the | 16 | In addition to the permissions in the GNU General Public License, the |
17 | Free Software Foundation gives you unlimited permission to link the | 17 | Free Software Foundation gives you unlimited permission to link the |
18 | compiled version of this file into combinations with other programs, | 18 | compiled version of this file into combinations with other programs, |
19 | and to distribute those combinations without any restriction coming | 19 | and to distribute those combinations without any restriction coming |
20 | from the use of this file. (The General Public License restrictions | 20 | from the use of this file. (The General Public License restrictions |
21 | do apply in other respects; for example, they cover modification of | 21 | do apply in other respects; for example, they cover modification of |
22 | the file, and distribution when not linked into a combine | 22 | the file, and distribution when not linked into a combine |
23 | executable.) | 23 | executable.) |
24 | 24 | ||
25 | This file is distributed in the hope that it will be useful, but | 25 | This file is distributed in the hope that it will be useful, but |
26 | WITHOUT ANY WARRANTY; without even the implied warranty of | 26 | WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
28 | General Public License for more details. | 28 | General Public License for more details. |
29 | 29 | ||
30 | You should have received a copy of the GNU General Public License | 30 | You should have received a copy of the GNU General Public License |
31 | along with this program; see the file COPYING. If not, write to | 31 | along with this program; see the file COPYING. If not, write to |
32 | the Free Software Foundation, 59 Temple Place - Suite 330, | 32 | the Free Software Foundation, 59 Temple Place - Suite 330, |
33 | Boston, MA 02111-1307, USA. */ | 33 | Boston, MA 02111-1307, USA. */ |
34 | 34 | ||
35 | 35 | ||
36 | #include <linux/linkage.h> | 36 | #include <linux/linkage.h> |
37 | #include <asm/assembler.h> | 37 | #include <asm/assembler.h> |
38 | 38 | ||
39 | 39 | ||
40 | .macro ARM_DIV_BODY dividend, divisor, result, curbit | 40 | .macro ARM_DIV_BODY dividend, divisor, result, curbit |
41 | 41 | ||
42 | #if __LINUX_ARM_ARCH__ >= 5 | 42 | #if __LINUX_ARM_ARCH__ >= 5 |
43 | 43 | ||
44 | clz \curbit, \divisor | 44 | clz \curbit, \divisor |
45 | clz \result, \dividend | 45 | clz \result, \dividend |
46 | sub \result, \curbit, \result | 46 | sub \result, \curbit, \result |
47 | mov \curbit, #1 | 47 | mov \curbit, #1 |
48 | mov \divisor, \divisor, lsl \result | 48 | mov \divisor, \divisor, lsl \result |
49 | mov \curbit, \curbit, lsl \result | 49 | mov \curbit, \curbit, lsl \result |
50 | mov \result, #0 | 50 | mov \result, #0 |
51 | 51 | ||
52 | #else | 52 | #else |
53 | 53 | ||
54 | @ Initially shift the divisor left 3 bits if possible, | 54 | @ Initially shift the divisor left 3 bits if possible, |
55 | @ set curbit accordingly. This allows for curbit to be located | 55 | @ set curbit accordingly. This allows for curbit to be located |
56 | @ at the left end of each 4 bit nibbles in the division loop | 56 | @ at the left end of each 4 bit nibbles in the division loop |
57 | @ to save one loop in most cases. | 57 | @ to save one loop in most cases. |
58 | tst \divisor, #0xe0000000 | 58 | tst \divisor, #0xe0000000 |
59 | moveq \divisor, \divisor, lsl #3 | 59 | moveq \divisor, \divisor, lsl #3 |
60 | moveq \curbit, #8 | 60 | moveq \curbit, #8 |
61 | movne \curbit, #1 | 61 | movne \curbit, #1 |
62 | 62 | ||
63 | @ Unless the divisor is very big, shift it up in multiples of | 63 | @ Unless the divisor is very big, shift it up in multiples of |
64 | @ four bits, since this is the amount of unwinding in the main | 64 | @ four bits, since this is the amount of unwinding in the main |
65 | @ division loop. Continue shifting until the divisor is | 65 | @ division loop. Continue shifting until the divisor is |
66 | @ larger than the dividend. | 66 | @ larger than the dividend. |
67 | 1: cmp \divisor, #0x10000000 | 67 | 1: cmp \divisor, #0x10000000 |
68 | cmplo \divisor, \dividend | 68 | cmplo \divisor, \dividend |
69 | movlo \divisor, \divisor, lsl #4 | 69 | movlo \divisor, \divisor, lsl #4 |
70 | movlo \curbit, \curbit, lsl #4 | 70 | movlo \curbit, \curbit, lsl #4 |
71 | blo 1b | 71 | blo 1b |
72 | 72 | ||
73 | @ For very big divisors, we must shift it a bit at a time, or | 73 | @ For very big divisors, we must shift it a bit at a time, or |
74 | @ we will be in danger of overflowing. | 74 | @ we will be in danger of overflowing. |
75 | 1: cmp \divisor, #0x80000000 | 75 | 1: cmp \divisor, #0x80000000 |
76 | cmplo \divisor, \dividend | 76 | cmplo \divisor, \dividend |
77 | movlo \divisor, \divisor, lsl #1 | 77 | movlo \divisor, \divisor, lsl #1 |
78 | movlo \curbit, \curbit, lsl #1 | 78 | movlo \curbit, \curbit, lsl #1 |
79 | blo 1b | 79 | blo 1b |
80 | 80 | ||
81 | mov \result, #0 | 81 | mov \result, #0 |
82 | 82 | ||
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | @ Division loop | 85 | @ Division loop |
86 | 1: cmp \dividend, \divisor | 86 | 1: cmp \dividend, \divisor |
87 | subhs \dividend, \dividend, \divisor | 87 | subhs \dividend, \dividend, \divisor |
88 | orrhs \result, \result, \curbit | 88 | orrhs \result, \result, \curbit |
89 | cmp \dividend, \divisor, lsr #1 | 89 | cmp \dividend, \divisor, lsr #1 |
90 | subhs \dividend, \dividend, \divisor, lsr #1 | 90 | subhs \dividend, \dividend, \divisor, lsr #1 |
91 | orrhs \result, \result, \curbit, lsr #1 | 91 | orrhs \result, \result, \curbit, lsr #1 |
92 | cmp \dividend, \divisor, lsr #2 | 92 | cmp \dividend, \divisor, lsr #2 |
93 | subhs \dividend, \dividend, \divisor, lsr #2 | 93 | subhs \dividend, \dividend, \divisor, lsr #2 |
94 | orrhs \result, \result, \curbit, lsr #2 | 94 | orrhs \result, \result, \curbit, lsr #2 |
95 | cmp \dividend, \divisor, lsr #3 | 95 | cmp \dividend, \divisor, lsr #3 |
96 | subhs \dividend, \dividend, \divisor, lsr #3 | 96 | subhs \dividend, \dividend, \divisor, lsr #3 |
97 | orrhs \result, \result, \curbit, lsr #3 | 97 | orrhs \result, \result, \curbit, lsr #3 |
98 | cmp \dividend, #0 @ Early termination? | 98 | cmp \dividend, #0 @ Early termination? |
99 | movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? | 99 | movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? |
100 | movne \divisor, \divisor, lsr #4 | 100 | movne \divisor, \divisor, lsr #4 |
101 | bne 1b | 101 | bne 1b |
102 | 102 | ||
103 | .endm | 103 | .endm |
104 | 104 | ||
105 | 105 | ||
106 | .macro ARM_DIV2_ORDER divisor, order | 106 | .macro ARM_DIV2_ORDER divisor, order |
107 | 107 | ||
108 | #if __LINUX_ARM_ARCH__ >= 5 | 108 | #if __LINUX_ARM_ARCH__ >= 5 |
109 | 109 | ||
110 | clz \order, \divisor | 110 | clz \order, \divisor |
111 | rsb \order, \order, #31 | 111 | rsb \order, \order, #31 |
112 | 112 | ||
113 | #else | 113 | #else |
114 | 114 | ||
115 | cmp \divisor, #(1 << 16) | 115 | cmp \divisor, #(1 << 16) |
116 | movhs \divisor, \divisor, lsr #16 | 116 | movhs \divisor, \divisor, lsr #16 |
117 | movhs \order, #16 | 117 | movhs \order, #16 |
118 | movlo \order, #0 | 118 | movlo \order, #0 |
119 | 119 | ||
120 | cmp \divisor, #(1 << 8) | 120 | cmp \divisor, #(1 << 8) |
121 | movhs \divisor, \divisor, lsr #8 | 121 | movhs \divisor, \divisor, lsr #8 |
122 | addhs \order, \order, #8 | 122 | addhs \order, \order, #8 |
123 | 123 | ||
124 | cmp \divisor, #(1 << 4) | 124 | cmp \divisor, #(1 << 4) |
125 | movhs \divisor, \divisor, lsr #4 | 125 | movhs \divisor, \divisor, lsr #4 |
126 | addhs \order, \order, #4 | 126 | addhs \order, \order, #4 |
127 | 127 | ||
128 | cmp \divisor, #(1 << 2) | 128 | cmp \divisor, #(1 << 2) |
129 | addhi \order, \order, #3 | 129 | addhi \order, \order, #3 |
130 | addls \order, \order, \divisor, lsr #1 | 130 | addls \order, \order, \divisor, lsr #1 |
131 | 131 | ||
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | .endm | 134 | .endm |
135 | 135 | ||
136 | 136 | ||
137 | .macro ARM_MOD_BODY dividend, divisor, order, spare | 137 | .macro ARM_MOD_BODY dividend, divisor, order, spare |
138 | 138 | ||
139 | #if __LINUX_ARM_ARCH__ >= 5 | 139 | #if __LINUX_ARM_ARCH__ >= 5 |
140 | 140 | ||
141 | clz \order, \divisor | 141 | clz \order, \divisor |
142 | clz \spare, \dividend | 142 | clz \spare, \dividend |
143 | sub \order, \order, \spare | 143 | sub \order, \order, \spare |
144 | mov \divisor, \divisor, lsl \order | 144 | mov \divisor, \divisor, lsl \order |
145 | 145 | ||
146 | #else | 146 | #else |
147 | 147 | ||
148 | mov \order, #0 | 148 | mov \order, #0 |
149 | 149 | ||
150 | @ Unless the divisor is very big, shift it up in multiples of | 150 | @ Unless the divisor is very big, shift it up in multiples of |
151 | @ four bits, since this is the amount of unwinding in the main | 151 | @ four bits, since this is the amount of unwinding in the main |
152 | @ division loop. Continue shifting until the divisor is | 152 | @ division loop. Continue shifting until the divisor is |
153 | @ larger than the dividend. | 153 | @ larger than the dividend. |
154 | 1: cmp \divisor, #0x10000000 | 154 | 1: cmp \divisor, #0x10000000 |
155 | cmplo \divisor, \dividend | 155 | cmplo \divisor, \dividend |
156 | movlo \divisor, \divisor, lsl #4 | 156 | movlo \divisor, \divisor, lsl #4 |
157 | addlo \order, \order, #4 | 157 | addlo \order, \order, #4 |
158 | blo 1b | 158 | blo 1b |
159 | 159 | ||
160 | @ For very big divisors, we must shift it a bit at a time, or | 160 | @ For very big divisors, we must shift it a bit at a time, or |
161 | @ we will be in danger of overflowing. | 161 | @ we will be in danger of overflowing. |
162 | 1: cmp \divisor, #0x80000000 | 162 | 1: cmp \divisor, #0x80000000 |
163 | cmplo \divisor, \dividend | 163 | cmplo \divisor, \dividend |
164 | movlo \divisor, \divisor, lsl #1 | 164 | movlo \divisor, \divisor, lsl #1 |
165 | addlo \order, \order, #1 | 165 | addlo \order, \order, #1 |
166 | blo 1b | 166 | blo 1b |
167 | 167 | ||
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | @ Perform all needed substractions to keep only the reminder. | 170 | @ Perform all needed substractions to keep only the reminder. |
171 | @ Do comparisons in batch of 4 first. | 171 | @ Do comparisons in batch of 4 first. |
172 | subs \order, \order, #3 @ yes, 3 is intended here | 172 | subs \order, \order, #3 @ yes, 3 is intended here |
173 | blt 2f | 173 | blt 2f |
174 | 174 | ||
175 | 1: cmp \dividend, \divisor | 175 | 1: cmp \dividend, \divisor |
176 | subhs \dividend, \dividend, \divisor | 176 | subhs \dividend, \dividend, \divisor |
177 | cmp \dividend, \divisor, lsr #1 | 177 | cmp \dividend, \divisor, lsr #1 |
178 | subhs \dividend, \dividend, \divisor, lsr #1 | 178 | subhs \dividend, \dividend, \divisor, lsr #1 |
179 | cmp \dividend, \divisor, lsr #2 | 179 | cmp \dividend, \divisor, lsr #2 |
180 | subhs \dividend, \dividend, \divisor, lsr #2 | 180 | subhs \dividend, \dividend, \divisor, lsr #2 |
181 | cmp \dividend, \divisor, lsr #3 | 181 | cmp \dividend, \divisor, lsr #3 |
182 | subhs \dividend, \dividend, \divisor, lsr #3 | 182 | subhs \dividend, \dividend, \divisor, lsr #3 |
183 | cmp \dividend, #1 | 183 | cmp \dividend, #1 |
184 | mov \divisor, \divisor, lsr #4 | 184 | mov \divisor, \divisor, lsr #4 |
185 | subges \order, \order, #4 | 185 | subges \order, \order, #4 |
186 | bge 1b | 186 | bge 1b |
187 | 187 | ||
188 | tst \order, #3 | 188 | tst \order, #3 |
189 | teqne \dividend, #0 | 189 | teqne \dividend, #0 |
190 | beq 5f | 190 | beq 5f |
191 | 191 | ||
192 | @ Either 1, 2 or 3 comparison/substractions are left. | 192 | @ Either 1, 2 or 3 comparison/substractions are left. |
193 | 2: cmn \order, #2 | 193 | 2: cmn \order, #2 |
194 | blt 4f | 194 | blt 4f |
195 | beq 3f | 195 | beq 3f |
196 | cmp \dividend, \divisor | 196 | cmp \dividend, \divisor |
197 | subhs \dividend, \dividend, \divisor | 197 | subhs \dividend, \dividend, \divisor |
198 | mov \divisor, \divisor, lsr #1 | 198 | mov \divisor, \divisor, lsr #1 |
199 | 3: cmp \dividend, \divisor | 199 | 3: cmp \dividend, \divisor |
200 | subhs \dividend, \dividend, \divisor | 200 | subhs \dividend, \dividend, \divisor |
201 | mov \divisor, \divisor, lsr #1 | 201 | mov \divisor, \divisor, lsr #1 |
202 | 4: cmp \dividend, \divisor | 202 | 4: cmp \dividend, \divisor |
203 | subhs \dividend, \dividend, \divisor | 203 | subhs \dividend, \dividend, \divisor |
204 | 5: | 204 | 5: |
205 | .endm | 205 | .endm |
206 | 206 | ||
207 | 207 | ||
208 | ENTRY(__udivsi3) | 208 | ENTRY(__udivsi3) |
209 | ENTRY(__aeabi_uidiv) | 209 | ENTRY(__aeabi_uidiv) |
210 | 210 | ||
211 | subs r2, r1, #1 | 211 | subs r2, r1, #1 |
212 | moveq pc, lr | 212 | moveq pc, lr |
213 | bcc Ldiv0 | 213 | bcc Ldiv0 |
214 | cmp r0, r1 | 214 | cmp r0, r1 |
215 | bls 11f | 215 | bls 11f |
216 | tst r1, r2 | 216 | tst r1, r2 |
217 | beq 12f | 217 | beq 12f |
218 | 218 | ||
219 | ARM_DIV_BODY r0, r1, r2, r3 | 219 | ARM_DIV_BODY r0, r1, r2, r3 |
220 | 220 | ||
221 | mov r0, r2 | 221 | mov r0, r2 |
222 | mov pc, lr | 222 | mov pc, lr |
223 | 223 | ||
224 | 11: moveq r0, #1 | 224 | 11: moveq r0, #1 |
225 | movne r0, #0 | 225 | movne r0, #0 |
226 | mov pc, lr | 226 | mov pc, lr |
227 | 227 | ||
228 | 12: ARM_DIV2_ORDER r1, r2 | 228 | 12: ARM_DIV2_ORDER r1, r2 |
229 | 229 | ||
230 | mov r0, r0, lsr r2 | 230 | mov r0, r0, lsr r2 |
231 | mov pc, lr | 231 | mov pc, lr |
232 | 232 | ||
233 | ENDPROC(__udivsi3) | 233 | ENDPROC(__udivsi3) |
234 | ENDPROC(__aeabi_uidiv) | 234 | ENDPROC(__aeabi_uidiv) |
235 | 235 | ||
236 | ENTRY(__umodsi3) | 236 | ENTRY(__umodsi3) |
237 | 237 | ||
238 | subs r2, r1, #1 @ compare divisor with 1 | 238 | subs r2, r1, #1 @ compare divisor with 1 |
239 | bcc Ldiv0 | 239 | bcc Ldiv0 |
240 | cmpne r0, r1 @ compare dividend with divisor | 240 | cmpne r0, r1 @ compare dividend with divisor |
241 | moveq r0, #0 | 241 | moveq r0, #0 |
242 | tsthi r1, r2 @ see if divisor is power of 2 | 242 | tsthi r1, r2 @ see if divisor is power of 2 |
243 | andeq r0, r0, r2 | 243 | andeq r0, r0, r2 |
244 | movls pc, lr | 244 | movls pc, lr |
245 | 245 | ||
246 | ARM_MOD_BODY r0, r1, r2, r3 | 246 | ARM_MOD_BODY r0, r1, r2, r3 |
247 | 247 | ||
248 | mov pc, lr | 248 | mov pc, lr |
249 | 249 | ||
250 | ENDPROC(__umodsi3) | 250 | ENDPROC(__umodsi3) |
251 | 251 | ||
252 | ENTRY(__divsi3) | 252 | ENTRY(__divsi3) |
253 | ENTRY(__aeabi_idiv) | 253 | ENTRY(__aeabi_idiv) |
254 | 254 | ||
255 | cmp r1, #0 | 255 | cmp r1, #0 |
256 | eor ip, r0, r1 @ save the sign of the result. | 256 | eor ip, r0, r1 @ save the sign of the result. |
257 | beq Ldiv0 | 257 | beq Ldiv0 |
258 | rsbmi r1, r1, #0 @ loops below use unsigned. | 258 | rsbmi r1, r1, #0 @ loops below use unsigned. |
259 | subs r2, r1, #1 @ division by 1 or -1 ? | 259 | subs r2, r1, #1 @ division by 1 or -1 ? |
260 | beq 10f | 260 | beq 10f |
261 | movs r3, r0 | 261 | movs r3, r0 |
262 | rsbmi r3, r0, #0 @ positive dividend value | 262 | rsbmi r3, r0, #0 @ positive dividend value |
263 | cmp r3, r1 | 263 | cmp r3, r1 |
264 | bls 11f | 264 | bls 11f |
265 | tst r1, r2 @ divisor is power of 2 ? | 265 | tst r1, r2 @ divisor is power of 2 ? |
266 | beq 12f | 266 | beq 12f |
267 | 267 | ||
268 | ARM_DIV_BODY r3, r1, r0, r2 | 268 | ARM_DIV_BODY r3, r1, r0, r2 |
269 | 269 | ||
270 | cmp ip, #0 | 270 | cmp ip, #0 |
271 | rsbmi r0, r0, #0 | 271 | rsbmi r0, r0, #0 |
272 | mov pc, lr | 272 | mov pc, lr |
273 | 273 | ||
274 | 10: teq ip, r0 @ same sign ? | 274 | 10: teq ip, r0 @ same sign ? |
275 | rsbmi r0, r0, #0 | 275 | rsbmi r0, r0, #0 |
276 | mov pc, lr | 276 | mov pc, lr |
277 | 277 | ||
278 | 11: movlo r0, #0 | 278 | 11: movlo r0, #0 |
279 | moveq r0, ip, asr #31 | 279 | moveq r0, ip, asr #31 |
280 | orreq r0, r0, #1 | 280 | orreq r0, r0, #1 |
281 | mov pc, lr | 281 | mov pc, lr |
282 | 282 | ||
283 | 12: ARM_DIV2_ORDER r1, r2 | 283 | 12: ARM_DIV2_ORDER r1, r2 |
284 | 284 | ||
285 | cmp ip, #0 | 285 | cmp ip, #0 |
286 | mov r0, r3, lsr r2 | 286 | mov r0, r3, lsr r2 |
287 | rsbmi r0, r0, #0 | 287 | rsbmi r0, r0, #0 |
288 | mov pc, lr | 288 | mov pc, lr |
289 | 289 | ||
290 | ENDPROC(__divsi3) | 290 | ENDPROC(__divsi3) |
291 | ENDPROC(__aeabi_idiv) | 291 | ENDPROC(__aeabi_idiv) |
292 | 292 | ||
293 | ENTRY(__modsi3) | 293 | ENTRY(__modsi3) |
294 | 294 | ||
295 | cmp r1, #0 | 295 | cmp r1, #0 |
296 | beq Ldiv0 | 296 | beq Ldiv0 |
297 | rsbmi r1, r1, #0 @ loops below use unsigned. | 297 | rsbmi r1, r1, #0 @ loops below use unsigned. |
298 | movs ip, r0 @ preserve sign of dividend | 298 | movs ip, r0 @ preserve sign of dividend |
299 | rsbmi r0, r0, #0 @ if negative make positive | 299 | rsbmi r0, r0, #0 @ if negative make positive |
300 | subs r2, r1, #1 @ compare divisor with 1 | 300 | subs r2, r1, #1 @ compare divisor with 1 |
301 | cmpne r0, r1 @ compare dividend with divisor | 301 | cmpne r0, r1 @ compare dividend with divisor |
302 | moveq r0, #0 | 302 | moveq r0, #0 |
303 | tsthi r1, r2 @ see if divisor is power of 2 | 303 | tsthi r1, r2 @ see if divisor is power of 2 |
304 | andeq r0, r0, r2 | 304 | andeq r0, r0, r2 |
305 | bls 10f | 305 | bls 10f |
306 | 306 | ||
307 | ARM_MOD_BODY r0, r1, r2, r3 | 307 | ARM_MOD_BODY r0, r1, r2, r3 |
308 | 308 | ||
309 | 10: cmp ip, #0 | 309 | 10: cmp ip, #0 |
310 | rsbmi r0, r0, #0 | 310 | rsbmi r0, r0, #0 |
311 | mov pc, lr | 311 | mov pc, lr |
312 | 312 | ||
313 | ENDPROC(__modsi3) | 313 | ENDPROC(__modsi3) |
314 | 314 | ||
315 | #ifdef CONFIG_AEABI | 315 | #ifdef CONFIG_AEABI |
316 | 316 | ||
317 | ENTRY(__aeabi_uidivmod) | 317 | ENTRY(__aeabi_uidivmod) |
318 | 318 | ||
319 | stmfd sp!, {r0, r1, ip, lr} | 319 | stmfd sp!, {r0, r1, ip, lr} |
320 | bl __aeabi_uidiv | 320 | bl __aeabi_uidiv |
321 | ldmfd sp!, {r1, r2, ip, lr} | 321 | ldmfd sp!, {r1, r2, ip, lr} |
322 | mul r3, r0, r2 | 322 | mul r3, r0, r2 |
323 | sub r1, r1, r3 | 323 | sub r1, r1, r3 |
324 | mov pc, lr | 324 | mov pc, lr |
325 | 325 | ||
326 | ENDPROC(__aeabi_uidivmod) | 326 | ENDPROC(__aeabi_uidivmod) |
327 | 327 | ||
328 | ENTRY(__aeabi_idivmod) | 328 | ENTRY(__aeabi_idivmod) |
329 | 329 | ||
330 | stmfd sp!, {r0, r1, ip, lr} | 330 | stmfd sp!, {r0, r1, ip, lr} |
331 | bl __aeabi_idiv | 331 | bl __aeabi_idiv |
332 | ldmfd sp!, {r1, r2, ip, lr} | 332 | ldmfd sp!, {r1, r2, ip, lr} |
333 | mul r3, r0, r2 | 333 | mul r3, r0, r2 |
334 | sub r1, r1, r3 | 334 | sub r1, r1, r3 |
335 | mov pc, lr | 335 | mov pc, lr |
336 | 336 | ||
337 | ENDPROC(__aeabi_idivmod) | 337 | ENDPROC(__aeabi_idivmod) |
338 | 338 | ||
339 | #endif | 339 | #endif |
340 | 340 | ||
341 | Ldiv0: | 341 | Ldiv0: |
342 | 342 | ||
343 | str lr, [sp, #-8]! | 343 | str lr, [sp, #-8]! |
344 | bl __div0 | 344 | bl __div0 |
345 | mov r0, #0 @ About as wrong as it could be. | 345 | mov r0, #0 @ About as wrong as it could be. |
346 | ldr pc, [sp], #8 | 346 | ldr pc, [sp], #8 |
347 | 347 | ||
348 | 348 | ||
349 | 349 |
arch/arm/lib/sha1.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/lib/sha1.S | 2 | * linux/arch/arm/lib/sha1.S |
3 | * | 3 | * |
4 | * SHA transform optimized for ARM | 4 | * SHA transform optimized for ARM |
5 | * | 5 | * |
6 | * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org> | 6 | * Copyright: (C) 2005 by Nicolas Pitre <nico@fluxnic.net> |
7 | * Created: September 17, 2005 | 7 | * Created: September 17, 2005 |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | * | 12 | * |
13 | * The reference implementation for this code is linux/lib/sha1.c | 13 | * The reference implementation for this code is linux/lib/sha1.c |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | 17 | ||
18 | .text | 18 | .text |
19 | 19 | ||
20 | 20 | ||
21 | /* | 21 | /* |
22 | * void sha_transform(__u32 *digest, const char *in, __u32 *W) | 22 | * void sha_transform(__u32 *digest, const char *in, __u32 *W) |
23 | * | 23 | * |
24 | * Note: the "in" ptr may be unaligned. | 24 | * Note: the "in" ptr may be unaligned. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | ENTRY(sha_transform) | 27 | ENTRY(sha_transform) |
28 | 28 | ||
29 | stmfd sp!, {r4 - r8, lr} | 29 | stmfd sp!, {r4 - r8, lr} |
30 | 30 | ||
31 | @ for (i = 0; i < 16; i++) | 31 | @ for (i = 0; i < 16; i++) |
32 | @ W[i] = be32_to_cpu(in[i]); | 32 | @ W[i] = be32_to_cpu(in[i]); |
33 | 33 | ||
34 | #ifdef __ARMEB__ | 34 | #ifdef __ARMEB__ |
35 | mov r4, r0 | 35 | mov r4, r0 |
36 | mov r0, r2 | 36 | mov r0, r2 |
37 | mov r2, #64 | 37 | mov r2, #64 |
38 | bl memcpy | 38 | bl memcpy |
39 | mov r2, r0 | 39 | mov r2, r0 |
40 | mov r0, r4 | 40 | mov r0, r4 |
41 | #else | 41 | #else |
42 | mov r3, r2 | 42 | mov r3, r2 |
43 | mov lr, #16 | 43 | mov lr, #16 |
44 | 1: ldrb r4, [r1], #1 | 44 | 1: ldrb r4, [r1], #1 |
45 | ldrb r5, [r1], #1 | 45 | ldrb r5, [r1], #1 |
46 | ldrb r6, [r1], #1 | 46 | ldrb r6, [r1], #1 |
47 | ldrb r7, [r1], #1 | 47 | ldrb r7, [r1], #1 |
48 | subs lr, lr, #1 | 48 | subs lr, lr, #1 |
49 | orr r5, r5, r4, lsl #8 | 49 | orr r5, r5, r4, lsl #8 |
50 | orr r6, r6, r5, lsl #8 | 50 | orr r6, r6, r5, lsl #8 |
51 | orr r7, r7, r6, lsl #8 | 51 | orr r7, r7, r6, lsl #8 |
52 | str r7, [r3], #4 | 52 | str r7, [r3], #4 |
53 | bne 1b | 53 | bne 1b |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | @ for (i = 0; i < 64; i++) | 56 | @ for (i = 0; i < 64; i++) |
57 | @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31); | 57 | @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31); |
58 | 58 | ||
59 | sub r3, r2, #4 | 59 | sub r3, r2, #4 |
60 | mov lr, #64 | 60 | mov lr, #64 |
61 | 2: ldr r4, [r3, #4]! | 61 | 2: ldr r4, [r3, #4]! |
62 | subs lr, lr, #1 | 62 | subs lr, lr, #1 |
63 | ldr r5, [r3, #8] | 63 | ldr r5, [r3, #8] |
64 | ldr r6, [r3, #32] | 64 | ldr r6, [r3, #32] |
65 | ldr r7, [r3, #52] | 65 | ldr r7, [r3, #52] |
66 | eor r4, r4, r5 | 66 | eor r4, r4, r5 |
67 | eor r4, r4, r6 | 67 | eor r4, r4, r6 |
68 | eor r4, r4, r7 | 68 | eor r4, r4, r7 |
69 | mov r4, r4, ror #31 | 69 | mov r4, r4, ror #31 |
70 | str r4, [r3, #64] | 70 | str r4, [r3, #64] |
71 | bne 2b | 71 | bne 2b |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * The SHA functions are: | 74 | * The SHA functions are: |
75 | * | 75 | * |
76 | * f1(B,C,D) = (D ^ (B & (C ^ D))) | 76 | * f1(B,C,D) = (D ^ (B & (C ^ D))) |
77 | * f2(B,C,D) = (B ^ C ^ D) | 77 | * f2(B,C,D) = (B ^ C ^ D) |
78 | * f3(B,C,D) = ((B & C) | (D & (B | C))) | 78 | * f3(B,C,D) = ((B & C) | (D & (B | C))) |
79 | * | 79 | * |
80 | * Then the sub-blocks are processed as follows: | 80 | * Then the sub-blocks are processed as follows: |
81 | * | 81 | * |
82 | * A' = ror(A, 27) + f(B,C,D) + E + K + *W++ | 82 | * A' = ror(A, 27) + f(B,C,D) + E + K + *W++ |
83 | * B' = A | 83 | * B' = A |
84 | * C' = ror(B, 2) | 84 | * C' = ror(B, 2) |
85 | * D' = C | 85 | * D' = C |
86 | * E' = D | 86 | * E' = D |
87 | * | 87 | * |
88 | * We therefore unroll each loop 5 times to avoid register shuffling. | 88 | * We therefore unroll each loop 5 times to avoid register shuffling. |
89 | * Also the ror for C (and also D and E which are successivelyderived | 89 | * Also the ror for C (and also D and E which are successivelyderived |
90 | * from it) is applied in place to cut on an additional mov insn for | 90 | * from it) is applied in place to cut on an additional mov insn for |
91 | * each round. | 91 | * each round. |
92 | */ | 92 | */ |
93 | 93 | ||
94 | .macro sha_f1, A, B, C, D, E | 94 | .macro sha_f1, A, B, C, D, E |
95 | ldr r3, [r2], #4 | 95 | ldr r3, [r2], #4 |
96 | eor ip, \C, \D | 96 | eor ip, \C, \D |
97 | add \E, r1, \E, ror #2 | 97 | add \E, r1, \E, ror #2 |
98 | and ip, \B, ip, ror #2 | 98 | and ip, \B, ip, ror #2 |
99 | add \E, \E, \A, ror #27 | 99 | add \E, \E, \A, ror #27 |
100 | eor ip, ip, \D, ror #2 | 100 | eor ip, ip, \D, ror #2 |
101 | add \E, \E, r3 | 101 | add \E, \E, r3 |
102 | add \E, \E, ip | 102 | add \E, \E, ip |
103 | .endm | 103 | .endm |
104 | 104 | ||
105 | .macro sha_f2, A, B, C, D, E | 105 | .macro sha_f2, A, B, C, D, E |
106 | ldr r3, [r2], #4 | 106 | ldr r3, [r2], #4 |
107 | add \E, r1, \E, ror #2 | 107 | add \E, r1, \E, ror #2 |
108 | eor ip, \B, \C, ror #2 | 108 | eor ip, \B, \C, ror #2 |
109 | add \E, \E, \A, ror #27 | 109 | add \E, \E, \A, ror #27 |
110 | eor ip, ip, \D, ror #2 | 110 | eor ip, ip, \D, ror #2 |
111 | add \E, \E, r3 | 111 | add \E, \E, r3 |
112 | add \E, \E, ip | 112 | add \E, \E, ip |
113 | .endm | 113 | .endm |
114 | 114 | ||
115 | .macro sha_f3, A, B, C, D, E | 115 | .macro sha_f3, A, B, C, D, E |
116 | ldr r3, [r2], #4 | 116 | ldr r3, [r2], #4 |
117 | add \E, r1, \E, ror #2 | 117 | add \E, r1, \E, ror #2 |
118 | orr ip, \B, \C, ror #2 | 118 | orr ip, \B, \C, ror #2 |
119 | add \E, \E, \A, ror #27 | 119 | add \E, \E, \A, ror #27 |
120 | and ip, ip, \D, ror #2 | 120 | and ip, ip, \D, ror #2 |
121 | add \E, \E, r3 | 121 | add \E, \E, r3 |
122 | and r3, \B, \C, ror #2 | 122 | and r3, \B, \C, ror #2 |
123 | orr ip, ip, r3 | 123 | orr ip, ip, r3 |
124 | add \E, \E, ip | 124 | add \E, \E, ip |
125 | .endm | 125 | .endm |
126 | 126 | ||
127 | ldmia r0, {r4 - r8} | 127 | ldmia r0, {r4 - r8} |
128 | 128 | ||
129 | mov lr, #4 | 129 | mov lr, #4 |
130 | ldr r1, .L_sha_K + 0 | 130 | ldr r1, .L_sha_K + 0 |
131 | 131 | ||
132 | /* adjust initial values */ | 132 | /* adjust initial values */ |
133 | mov r6, r6, ror #30 | 133 | mov r6, r6, ror #30 |
134 | mov r7, r7, ror #30 | 134 | mov r7, r7, ror #30 |
135 | mov r8, r8, ror #30 | 135 | mov r8, r8, ror #30 |
136 | 136 | ||
137 | 3: subs lr, lr, #1 | 137 | 3: subs lr, lr, #1 |
138 | sha_f1 r4, r5, r6, r7, r8 | 138 | sha_f1 r4, r5, r6, r7, r8 |
139 | sha_f1 r8, r4, r5, r6, r7 | 139 | sha_f1 r8, r4, r5, r6, r7 |
140 | sha_f1 r7, r8, r4, r5, r6 | 140 | sha_f1 r7, r8, r4, r5, r6 |
141 | sha_f1 r6, r7, r8, r4, r5 | 141 | sha_f1 r6, r7, r8, r4, r5 |
142 | sha_f1 r5, r6, r7, r8, r4 | 142 | sha_f1 r5, r6, r7, r8, r4 |
143 | bne 3b | 143 | bne 3b |
144 | 144 | ||
145 | ldr r1, .L_sha_K + 4 | 145 | ldr r1, .L_sha_K + 4 |
146 | mov lr, #4 | 146 | mov lr, #4 |
147 | 147 | ||
148 | 4: subs lr, lr, #1 | 148 | 4: subs lr, lr, #1 |
149 | sha_f2 r4, r5, r6, r7, r8 | 149 | sha_f2 r4, r5, r6, r7, r8 |
150 | sha_f2 r8, r4, r5, r6, r7 | 150 | sha_f2 r8, r4, r5, r6, r7 |
151 | sha_f2 r7, r8, r4, r5, r6 | 151 | sha_f2 r7, r8, r4, r5, r6 |
152 | sha_f2 r6, r7, r8, r4, r5 | 152 | sha_f2 r6, r7, r8, r4, r5 |
153 | sha_f2 r5, r6, r7, r8, r4 | 153 | sha_f2 r5, r6, r7, r8, r4 |
154 | bne 4b | 154 | bne 4b |
155 | 155 | ||
156 | ldr r1, .L_sha_K + 8 | 156 | ldr r1, .L_sha_K + 8 |
157 | mov lr, #4 | 157 | mov lr, #4 |
158 | 158 | ||
159 | 5: subs lr, lr, #1 | 159 | 5: subs lr, lr, #1 |
160 | sha_f3 r4, r5, r6, r7, r8 | 160 | sha_f3 r4, r5, r6, r7, r8 |
161 | sha_f3 r8, r4, r5, r6, r7 | 161 | sha_f3 r8, r4, r5, r6, r7 |
162 | sha_f3 r7, r8, r4, r5, r6 | 162 | sha_f3 r7, r8, r4, r5, r6 |
163 | sha_f3 r6, r7, r8, r4, r5 | 163 | sha_f3 r6, r7, r8, r4, r5 |
164 | sha_f3 r5, r6, r7, r8, r4 | 164 | sha_f3 r5, r6, r7, r8, r4 |
165 | bne 5b | 165 | bne 5b |
166 | 166 | ||
167 | ldr r1, .L_sha_K + 12 | 167 | ldr r1, .L_sha_K + 12 |
168 | mov lr, #4 | 168 | mov lr, #4 |
169 | 169 | ||
170 | 6: subs lr, lr, #1 | 170 | 6: subs lr, lr, #1 |
171 | sha_f2 r4, r5, r6, r7, r8 | 171 | sha_f2 r4, r5, r6, r7, r8 |
172 | sha_f2 r8, r4, r5, r6, r7 | 172 | sha_f2 r8, r4, r5, r6, r7 |
173 | sha_f2 r7, r8, r4, r5, r6 | 173 | sha_f2 r7, r8, r4, r5, r6 |
174 | sha_f2 r6, r7, r8, r4, r5 | 174 | sha_f2 r6, r7, r8, r4, r5 |
175 | sha_f2 r5, r6, r7, r8, r4 | 175 | sha_f2 r5, r6, r7, r8, r4 |
176 | bne 6b | 176 | bne 6b |
177 | 177 | ||
178 | ldmia r0, {r1, r2, r3, ip, lr} | 178 | ldmia r0, {r1, r2, r3, ip, lr} |
179 | add r4, r1, r4 | 179 | add r4, r1, r4 |
180 | add r5, r2, r5 | 180 | add r5, r2, r5 |
181 | add r6, r3, r6, ror #2 | 181 | add r6, r3, r6, ror #2 |
182 | add r7, ip, r7, ror #2 | 182 | add r7, ip, r7, ror #2 |
183 | add r8, lr, r8, ror #2 | 183 | add r8, lr, r8, ror #2 |
184 | stmia r0, {r4 - r8} | 184 | stmia r0, {r4 - r8} |
185 | 185 | ||
186 | ldmfd sp!, {r4 - r8, pc} | 186 | ldmfd sp!, {r4 - r8, pc} |
187 | 187 | ||
188 | ENDPROC(sha_transform) | 188 | ENDPROC(sha_transform) |
189 | 189 | ||
190 | .align 2 | 190 | .align 2 |
191 | .L_sha_K: | 191 | .L_sha_K: |
192 | .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 | 192 | .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 |
193 | 193 | ||
194 | 194 | ||
195 | /* | 195 | /* |
196 | * void sha_init(__u32 *buf) | 196 | * void sha_init(__u32 *buf) |
197 | */ | 197 | */ |
198 | 198 | ||
199 | .align 2 | 199 | .align 2 |
200 | .L_sha_initial_digest: | 200 | .L_sha_initial_digest: |
201 | .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 | 201 | .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 |
202 | 202 | ||
203 | ENTRY(sha_init) | 203 | ENTRY(sha_init) |
204 | 204 | ||
205 | str lr, [sp, #-4]! | 205 | str lr, [sp, #-4]! |
206 | adr r1, .L_sha_initial_digest | 206 | adr r1, .L_sha_initial_digest |
207 | ldmia r1, {r1, r2, r3, ip, lr} | 207 | ldmia r1, {r1, r2, r3, ip, lr} |
208 | stmia r0, {r1, r2, r3, ip, lr} | 208 | stmia r0, {r1, r2, r3, ip, lr} |
209 | ldr pc, [sp], #4 | 209 | ldr pc, [sp], #4 |
210 | 210 | ||
211 | ENDPROC(sha_init) | 211 | ENDPROC(sha_init) |
212 | 212 |
arch/arm/mach-sa1100/include/mach/assabet.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-sa1100/include/mach/assabet.h | 2 | * arch/arm/mach-sa1100/include/mach/assabet.h |
3 | * | 3 | * |
4 | * Created 2000/06/05 by Nicolas Pitre <nico@cam.org> | 4 | * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * This file contains the hardware specific definitions for Assabet | 6 | * This file contains the hardware specific definitions for Assabet |
7 | * Only include this file from SA1100-specific files. | 7 | * Only include this file from SA1100-specific files. |
8 | * | 8 | * |
9 | * 2000/05/23 John Dorsey <john+@cs.cmu.edu> | 9 | * 2000/05/23 John Dorsey <john+@cs.cmu.edu> |
10 | * Definitions for Neponset added. | 10 | * Definitions for Neponset added. |
11 | */ | 11 | */ |
12 | #ifndef __ASM_ARCH_ASSABET_H | 12 | #ifndef __ASM_ARCH_ASSABET_H |
13 | #define __ASM_ARCH_ASSABET_H | 13 | #define __ASM_ARCH_ASSABET_H |
14 | 14 | ||
15 | 15 | ||
16 | /* System Configuration Register flags */ | 16 | /* System Configuration Register flags */ |
17 | 17 | ||
18 | #define ASSABET_SCR_SDRAM_LOW (1<<2) /* SDRAM size (low bit) */ | 18 | #define ASSABET_SCR_SDRAM_LOW (1<<2) /* SDRAM size (low bit) */ |
19 | #define ASSABET_SCR_SDRAM_HIGH (1<<3) /* SDRAM size (high bit) */ | 19 | #define ASSABET_SCR_SDRAM_HIGH (1<<3) /* SDRAM size (high bit) */ |
20 | #define ASSABET_SCR_FLASH_LOW (1<<4) /* Flash size (low bit) */ | 20 | #define ASSABET_SCR_FLASH_LOW (1<<4) /* Flash size (low bit) */ |
21 | #define ASSABET_SCR_FLASH_HIGH (1<<5) /* Flash size (high bit) */ | 21 | #define ASSABET_SCR_FLASH_HIGH (1<<5) /* Flash size (high bit) */ |
22 | #define ASSABET_SCR_GFX (1<<8) /* Graphics Accelerator (0 = present) */ | 22 | #define ASSABET_SCR_GFX (1<<8) /* Graphics Accelerator (0 = present) */ |
23 | #define ASSABET_SCR_SA1111 (1<<9) /* Neponset (0 = present) */ | 23 | #define ASSABET_SCR_SA1111 (1<<9) /* Neponset (0 = present) */ |
24 | 24 | ||
25 | #define ASSABET_SCR_INIT -1 | 25 | #define ASSABET_SCR_INIT -1 |
26 | 26 | ||
27 | extern unsigned long SCR_value; | 27 | extern unsigned long SCR_value; |
28 | 28 | ||
29 | #ifdef CONFIG_ASSABET_NEPONSET | 29 | #ifdef CONFIG_ASSABET_NEPONSET |
30 | #define machine_has_neponset() ((SCR_value & ASSABET_SCR_SA1111) == 0) | 30 | #define machine_has_neponset() ((SCR_value & ASSABET_SCR_SA1111) == 0) |
31 | #else | 31 | #else |
32 | #define machine_has_neponset() (0) | 32 | #define machine_has_neponset() (0) |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /* Board Control Register */ | 35 | /* Board Control Register */ |
36 | 36 | ||
37 | #define ASSABET_BCR_BASE 0xf1000000 | 37 | #define ASSABET_BCR_BASE 0xf1000000 |
38 | #define ASSABET_BCR (*(volatile unsigned int *)(ASSABET_BCR_BASE)) | 38 | #define ASSABET_BCR (*(volatile unsigned int *)(ASSABET_BCR_BASE)) |
39 | 39 | ||
40 | #define ASSABET_BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */ | 40 | #define ASSABET_BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */ |
41 | #define ASSABET_BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */ | 41 | #define ASSABET_BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */ |
42 | #define ASSABET_BCR_GFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */ | 42 | #define ASSABET_BCR_GFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */ |
43 | #define ASSABET_BCR_CODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */ | 43 | #define ASSABET_BCR_CODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */ |
44 | #define ASSABET_BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */ | 44 | #define ASSABET_BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */ |
45 | #define ASSABET_BCR_IRDA_MD0 (1<<4) /* Range/Power select */ | 45 | #define ASSABET_BCR_IRDA_MD0 (1<<4) /* Range/Power select */ |
46 | #define ASSABET_BCR_IRDA_MD1 (1<<5) /* Range/Power select */ | 46 | #define ASSABET_BCR_IRDA_MD1 (1<<5) /* Range/Power select */ |
47 | #define ASSABET_BCR_STEREO_LB (1<<6) /* Stereo Loopback */ | 47 | #define ASSABET_BCR_STEREO_LB (1<<6) /* Stereo Loopback */ |
48 | #define ASSABET_BCR_CF_BUS_OFF (1<<7) /* Compact Flash bus (0 = on, 1 = off (float)) */ | 48 | #define ASSABET_BCR_CF_BUS_OFF (1<<7) /* Compact Flash bus (0 = on, 1 = off (float)) */ |
49 | #define ASSABET_BCR_AUDIO_ON (1<<8) /* Audio power on */ | 49 | #define ASSABET_BCR_AUDIO_ON (1<<8) /* Audio power on */ |
50 | #define ASSABET_BCR_LIGHT_ON (1<<9) /* Backlight */ | 50 | #define ASSABET_BCR_LIGHT_ON (1<<9) /* Backlight */ |
51 | #define ASSABET_BCR_LCD_12RGB (1<<10) /* 0 = 16RGB, 1 = 12RGB */ | 51 | #define ASSABET_BCR_LCD_12RGB (1<<10) /* 0 = 16RGB, 1 = 12RGB */ |
52 | #define ASSABET_BCR_LCD_ON (1<<11) /* LCD power on */ | 52 | #define ASSABET_BCR_LCD_ON (1<<11) /* LCD power on */ |
53 | #define ASSABET_BCR_RS232EN (1<<12) /* RS232 transceiver enable */ | 53 | #define ASSABET_BCR_RS232EN (1<<12) /* RS232 transceiver enable */ |
54 | #define ASSABET_BCR_LED_RED (1<<13) /* D9 (0 = on, 1 = off) */ | 54 | #define ASSABET_BCR_LED_RED (1<<13) /* D9 (0 = on, 1 = off) */ |
55 | #define ASSABET_BCR_LED_GREEN (1<<14) /* D8 (0 = on, 1 = off) */ | 55 | #define ASSABET_BCR_LED_GREEN (1<<14) /* D8 (0 = on, 1 = off) */ |
56 | #define ASSABET_BCR_VIB_ON (1<<15) /* Vibration motor (quiet alert) */ | 56 | #define ASSABET_BCR_VIB_ON (1<<15) /* Vibration motor (quiet alert) */ |
57 | #define ASSABET_BCR_COM_DTR (1<<16) /* COMport Data Terminal Ready */ | 57 | #define ASSABET_BCR_COM_DTR (1<<16) /* COMport Data Terminal Ready */ |
58 | #define ASSABET_BCR_COM_RTS (1<<17) /* COMport Request To Send */ | 58 | #define ASSABET_BCR_COM_RTS (1<<17) /* COMport Request To Send */ |
59 | #define ASSABET_BCR_RAD_WU (1<<18) /* Radio wake up interrupt */ | 59 | #define ASSABET_BCR_RAD_WU (1<<18) /* Radio wake up interrupt */ |
60 | #define ASSABET_BCR_SMB_EN (1<<19) /* System management bus enable */ | 60 | #define ASSABET_BCR_SMB_EN (1<<19) /* System management bus enable */ |
61 | #define ASSABET_BCR_TV_IR_DEC (1<<20) /* TV IR Decode Enable (not implemented) */ | 61 | #define ASSABET_BCR_TV_IR_DEC (1<<20) /* TV IR Decode Enable (not implemented) */ |
62 | #define ASSABET_BCR_QMUTE (1<<21) /* Quick Mute */ | 62 | #define ASSABET_BCR_QMUTE (1<<21) /* Quick Mute */ |
63 | #define ASSABET_BCR_RAD_ON (1<<22) /* Radio Power On */ | 63 | #define ASSABET_BCR_RAD_ON (1<<22) /* Radio Power On */ |
64 | #define ASSABET_BCR_SPK_OFF (1<<23) /* 1 = Speaker amplifier power off */ | 64 | #define ASSABET_BCR_SPK_OFF (1<<23) /* 1 = Speaker amplifier power off */ |
65 | 65 | ||
66 | #ifdef CONFIG_SA1100_ASSABET | 66 | #ifdef CONFIG_SA1100_ASSABET |
67 | extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set); | 67 | extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set); |
68 | #else | 68 | #else |
69 | #define ASSABET_BCR_frob(x,y) do { } while (0) | 69 | #define ASSABET_BCR_frob(x,y) do { } while (0) |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #define ASSABET_BCR_set(x) ASSABET_BCR_frob((x), (x)) | 72 | #define ASSABET_BCR_set(x) ASSABET_BCR_frob((x), (x)) |
73 | #define ASSABET_BCR_clear(x) ASSABET_BCR_frob((x), 0) | 73 | #define ASSABET_BCR_clear(x) ASSABET_BCR_frob((x), 0) |
74 | 74 | ||
75 | #define ASSABET_BSR_BASE 0xf1000000 | 75 | #define ASSABET_BSR_BASE 0xf1000000 |
76 | #define ASSABET_BSR (*(volatile unsigned int*)(ASSABET_BSR_BASE)) | 76 | #define ASSABET_BSR (*(volatile unsigned int*)(ASSABET_BSR_BASE)) |
77 | 77 | ||
78 | #define ASSABET_BSR_RS232_VALID (1 << 24) | 78 | #define ASSABET_BSR_RS232_VALID (1 << 24) |
79 | #define ASSABET_BSR_COM_DCD (1 << 25) | 79 | #define ASSABET_BSR_COM_DCD (1 << 25) |
80 | #define ASSABET_BSR_COM_CTS (1 << 26) | 80 | #define ASSABET_BSR_COM_CTS (1 << 26) |
81 | #define ASSABET_BSR_COM_DSR (1 << 27) | 81 | #define ASSABET_BSR_COM_DSR (1 << 27) |
82 | #define ASSABET_BSR_RAD_CTS (1 << 28) | 82 | #define ASSABET_BSR_RAD_CTS (1 << 28) |
83 | #define ASSABET_BSR_RAD_DSR (1 << 29) | 83 | #define ASSABET_BSR_RAD_DSR (1 << 29) |
84 | #define ASSABET_BSR_RAD_DCD (1 << 30) | 84 | #define ASSABET_BSR_RAD_DCD (1 << 30) |
85 | #define ASSABET_BSR_RAD_RI (1 << 31) | 85 | #define ASSABET_BSR_RAD_RI (1 << 31) |
86 | 86 | ||
87 | 87 | ||
88 | /* GPIOs for which the generic definition doesn't say much */ | 88 | /* GPIOs for which the generic definition doesn't say much */ |
89 | #define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */ | 89 | #define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */ |
90 | #define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */ | 90 | #define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */ |
91 | #define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */ | 91 | #define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */ |
92 | #define ASSABET_GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */ | 92 | #define ASSABET_GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */ |
93 | #define ASSABET_GPIO_CF_CD GPIO_GPIO (22) /* CF CD */ | 93 | #define ASSABET_GPIO_CF_CD GPIO_GPIO (22) /* CF CD */ |
94 | #define ASSABET_GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */ | 94 | #define ASSABET_GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */ |
95 | #define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */ | 95 | #define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */ |
96 | #define ASSABET_GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */ | 96 | #define ASSABET_GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */ |
97 | #define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */ | 97 | #define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */ |
98 | #define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */ | 98 | #define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */ |
99 | 99 | ||
100 | #define ASSABET_IRQ_GPIO_CF_IRQ IRQ_GPIO21 | 100 | #define ASSABET_IRQ_GPIO_CF_IRQ IRQ_GPIO21 |
101 | #define ASSABET_IRQ_GPIO_CF_CD IRQ_GPIO22 | 101 | #define ASSABET_IRQ_GPIO_CF_CD IRQ_GPIO22 |
102 | #define ASSABET_IRQ_GPIO_CF_BVD2 IRQ_GPIO24 | 102 | #define ASSABET_IRQ_GPIO_CF_BVD2 IRQ_GPIO24 |
103 | #define ASSABET_IRQ_GPIO_CF_BVD1 IRQ_GPIO25 | 103 | #define ASSABET_IRQ_GPIO_CF_BVD1 IRQ_GPIO25 |
104 | 104 | ||
105 | #endif | 105 | #endif |
106 | 106 |
arch/arm/mach-sa1100/include/mach/hardware.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-sa1100/include/mach/hardware.h | 2 | * arch/arm/mach-sa1100/include/mach/hardware.h |
3 | * | 3 | * |
4 | * Copyright (C) 1998 Nicolas Pitre <nico@cam.org> | 4 | * Copyright (C) 1998 Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * This file contains the hardware definitions for SA1100 architecture | 6 | * This file contains the hardware definitions for SA1100 architecture |
7 | * | 7 | * |
8 | * 2000/05/23 John Dorsey <john+@cs.cmu.edu> | 8 | * 2000/05/23 John Dorsey <john+@cs.cmu.edu> |
9 | * Definitions for SA1111 added. | 9 | * Definitions for SA1111 added. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef __ASM_ARCH_HARDWARE_H | 12 | #ifndef __ASM_ARCH_HARDWARE_H |
13 | #define __ASM_ARCH_HARDWARE_H | 13 | #define __ASM_ARCH_HARDWARE_H |
14 | 14 | ||
15 | 15 | ||
16 | #define UNCACHEABLE_ADDR 0xfa050000 | 16 | #define UNCACHEABLE_ADDR 0xfa050000 |
17 | 17 | ||
18 | 18 | ||
19 | /* | 19 | /* |
20 | * SA1100 internal I/O mappings | 20 | * SA1100 internal I/O mappings |
21 | * | 21 | * |
22 | * We have the following mapping: | 22 | * We have the following mapping: |
23 | * phys virt | 23 | * phys virt |
24 | * 80000000 f8000000 | 24 | * 80000000 f8000000 |
25 | * 90000000 fa000000 | 25 | * 90000000 fa000000 |
26 | * a0000000 fc000000 | 26 | * a0000000 fc000000 |
27 | * b0000000 fe000000 | 27 | * b0000000 fe000000 |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #define VIO_BASE 0xf8000000 /* virtual start of IO space */ | 30 | #define VIO_BASE 0xf8000000 /* virtual start of IO space */ |
31 | #define VIO_SHIFT 3 /* x = IO space shrink power */ | 31 | #define VIO_SHIFT 3 /* x = IO space shrink power */ |
32 | #define PIO_START 0x80000000 /* physical start of IO space */ | 32 | #define PIO_START 0x80000000 /* physical start of IO space */ |
33 | 33 | ||
34 | #define io_p2v( x ) \ | 34 | #define io_p2v( x ) \ |
35 | ( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE ) | 35 | ( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE ) |
36 | #define io_v2p( x ) \ | 36 | #define io_v2p( x ) \ |
37 | ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START ) | 37 | ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START ) |
38 | 38 | ||
39 | #define CPU_SA1110_A0 (0) | 39 | #define CPU_SA1110_A0 (0) |
40 | #define CPU_SA1110_B0 (4) | 40 | #define CPU_SA1110_B0 (4) |
41 | #define CPU_SA1110_B1 (5) | 41 | #define CPU_SA1110_B1 (5) |
42 | #define CPU_SA1110_B2 (6) | 42 | #define CPU_SA1110_B2 (6) |
43 | #define CPU_SA1110_B4 (8) | 43 | #define CPU_SA1110_B4 (8) |
44 | 44 | ||
45 | #define CPU_SA1100_ID (0x4401a110) | 45 | #define CPU_SA1100_ID (0x4401a110) |
46 | #define CPU_SA1100_MASK (0xfffffff0) | 46 | #define CPU_SA1100_MASK (0xfffffff0) |
47 | #define CPU_SA1110_ID (0x6901b110) | 47 | #define CPU_SA1110_ID (0x6901b110) |
48 | #define CPU_SA1110_MASK (0xfffffff0) | 48 | #define CPU_SA1110_MASK (0xfffffff0) |
49 | 49 | ||
50 | #ifndef __ASSEMBLY__ | 50 | #ifndef __ASSEMBLY__ |
51 | 51 | ||
52 | #include <asm/cputype.h> | 52 | #include <asm/cputype.h> |
53 | 53 | ||
54 | #define CPU_REVISION (read_cpuid_id() & 15) | 54 | #define CPU_REVISION (read_cpuid_id() & 15) |
55 | 55 | ||
56 | #define cpu_is_sa1100() ((read_cpuid_id() & CPU_SA1100_MASK) == CPU_SA1100_ID) | 56 | #define cpu_is_sa1100() ((read_cpuid_id() & CPU_SA1100_MASK) == CPU_SA1100_ID) |
57 | #define cpu_is_sa1110() ((read_cpuid_id() & CPU_SA1110_MASK) == CPU_SA1110_ID) | 57 | #define cpu_is_sa1110() ((read_cpuid_id() & CPU_SA1110_MASK) == CPU_SA1110_ID) |
58 | 58 | ||
59 | # define __REG(x) (*((volatile unsigned long *)io_p2v(x))) | 59 | # define __REG(x) (*((volatile unsigned long *)io_p2v(x))) |
60 | # define __PREG(x) (io_v2p((unsigned long)&(x))) | 60 | # define __PREG(x) (io_v2p((unsigned long)&(x))) |
61 | 61 | ||
62 | static inline unsigned long get_clock_tick_rate(void) | 62 | static inline unsigned long get_clock_tick_rate(void) |
63 | { | 63 | { |
64 | return 3686400; | 64 | return 3686400; |
65 | } | 65 | } |
66 | #else | 66 | #else |
67 | 67 | ||
68 | # define __REG(x) io_p2v(x) | 68 | # define __REG(x) io_p2v(x) |
69 | # define __PREG(x) io_v2p(x) | 69 | # define __PREG(x) io_v2p(x) |
70 | 70 | ||
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #include "SA-1100.h" | 73 | #include "SA-1100.h" |
74 | 74 | ||
75 | #ifdef CONFIG_SA1101 | 75 | #ifdef CONFIG_SA1101 |
76 | #include "SA-1101.h" | 76 | #include "SA-1101.h" |
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | #endif /* _ASM_ARCH_HARDWARE_H */ | 79 | #endif /* _ASM_ARCH_HARDWARE_H */ |
80 | 80 |
arch/arm/mach-sa1100/include/mach/memory.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-sa1100/include/mach/memory.h | 2 | * arch/arm/mach-sa1100/include/mach/memory.h |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2000 Nicolas Pitre <nico@cam.org> | 4 | * Copyright (C) 1999-2000 Nicolas Pitre <nico@fluxnic.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __ASM_ARCH_MEMORY_H | 7 | #ifndef __ASM_ARCH_MEMORY_H |
8 | #define __ASM_ARCH_MEMORY_H | 8 | #define __ASM_ARCH_MEMORY_H |
9 | 9 | ||
10 | #include <asm/sizes.h> | 10 | #include <asm/sizes.h> |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * Physical DRAM offset is 0xc0000000 on the SA1100 | 13 | * Physical DRAM offset is 0xc0000000 on the SA1100 |
14 | */ | 14 | */ |
15 | #define PHYS_OFFSET UL(0xc0000000) | 15 | #define PHYS_OFFSET UL(0xc0000000) |
16 | 16 | ||
17 | #ifndef __ASSEMBLY__ | 17 | #ifndef __ASSEMBLY__ |
18 | 18 | ||
19 | #ifdef CONFIG_SA1111 | 19 | #ifdef CONFIG_SA1111 |
20 | void sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes); | 20 | void sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes); |
21 | 21 | ||
22 | #define arch_adjust_zones(node, size, holes) \ | 22 | #define arch_adjust_zones(node, size, holes) \ |
23 | sa1111_adjust_zones(node, size, holes) | 23 | sa1111_adjust_zones(node, size, holes) |
24 | 24 | ||
25 | #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_1M - 1) | 25 | #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_1M - 1) |
26 | #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_1M) | 26 | #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_1M) |
27 | 27 | ||
28 | #endif | 28 | #endif |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Because of the wide memory address space between physical RAM banks on the | 32 | * Because of the wide memory address space between physical RAM banks on the |
33 | * SA1100, it's much convenient to use Linux's SparseMEM support to implement | 33 | * SA1100, it's much convenient to use Linux's SparseMEM support to implement |
34 | * our memory map representation. Assuming all memory nodes have equal access | 34 | * our memory map representation. Assuming all memory nodes have equal access |
35 | * characteristics, we then have generic discontiguous memory support. | 35 | * characteristics, we then have generic discontiguous memory support. |
36 | * | 36 | * |
37 | * The sparsemem banks are matched with the physical memory bank addresses | 37 | * The sparsemem banks are matched with the physical memory bank addresses |
38 | * which are incidentally the same as virtual addresses. | 38 | * which are incidentally the same as virtual addresses. |
39 | * | 39 | * |
40 | * node 0: 0xc0000000 - 0xc7ffffff | 40 | * node 0: 0xc0000000 - 0xc7ffffff |
41 | * node 1: 0xc8000000 - 0xcfffffff | 41 | * node 1: 0xc8000000 - 0xcfffffff |
42 | * node 2: 0xd0000000 - 0xd7ffffff | 42 | * node 2: 0xd0000000 - 0xd7ffffff |
43 | * node 3: 0xd8000000 - 0xdfffffff | 43 | * node 3: 0xd8000000 - 0xdfffffff |
44 | */ | 44 | */ |
45 | #define MAX_PHYSMEM_BITS 32 | 45 | #define MAX_PHYSMEM_BITS 32 |
46 | #define SECTION_SIZE_BITS 27 | 46 | #define SECTION_SIZE_BITS 27 |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * Cache flushing area - SA1100 zero bank | 49 | * Cache flushing area - SA1100 zero bank |
50 | */ | 50 | */ |
51 | #define FLUSH_BASE_PHYS 0xe0000000 | 51 | #define FLUSH_BASE_PHYS 0xe0000000 |
52 | #define FLUSH_BASE 0xf5000000 | 52 | #define FLUSH_BASE 0xf5000000 |
53 | #define FLUSH_BASE_MINICACHE 0xf5100000 | 53 | #define FLUSH_BASE_MINICACHE 0xf5100000 |
54 | 54 | ||
55 | #endif | 55 | #endif |
56 | 56 |
arch/arm/mach-sa1100/include/mach/neponset.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-sa1100/include/mach/neponset.h | 2 | * arch/arm/mach-sa1100/include/mach/neponset.h |
3 | * | 3 | * |
4 | * Created 2000/06/05 by Nicolas Pitre <nico@cam.org> | 4 | * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * This file contains the hardware specific definitions for Assabet | 6 | * This file contains the hardware specific definitions for Assabet |
7 | * Only include this file from SA1100-specific files. | 7 | * Only include this file from SA1100-specific files. |
8 | * | 8 | * |
9 | * 2000/05/23 John Dorsey <john+@cs.cmu.edu> | 9 | * 2000/05/23 John Dorsey <john+@cs.cmu.edu> |
10 | * Definitions for Neponset added. | 10 | * Definitions for Neponset added. |
11 | */ | 11 | */ |
12 | #ifndef __ASM_ARCH_NEPONSET_H | 12 | #ifndef __ASM_ARCH_NEPONSET_H |
13 | #define __ASM_ARCH_NEPONSET_H | 13 | #define __ASM_ARCH_NEPONSET_H |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * Neponset definitions: | 16 | * Neponset definitions: |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define NEPONSET_CPLD_BASE (0x10000000) | 19 | #define NEPONSET_CPLD_BASE (0x10000000) |
20 | #define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000) | 20 | #define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000) |
21 | #define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE) | 21 | #define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE) |
22 | 22 | ||
23 | #define _IRR 0x10000024 /* Interrupt Reason Register */ | 23 | #define _IRR 0x10000024 /* Interrupt Reason Register */ |
24 | #define _AUD_CTL 0x100000c0 /* Audio controls (RW) */ | 24 | #define _AUD_CTL 0x100000c0 /* Audio controls (RW) */ |
25 | #define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */ | 25 | #define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */ |
26 | #define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */ | 26 | #define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */ |
27 | #define _NCR_0 0x100000a0 /* Control Register (RW) */ | 27 | #define _NCR_0 0x100000a0 /* Control Register (RW) */ |
28 | #define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */ | 28 | #define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */ |
29 | #define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */ | 29 | #define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */ |
30 | #define _SWPK 0x10000020 /* Switch pack (RO) */ | 30 | #define _SWPK 0x10000020 /* Switch pack (RO) */ |
31 | #define _WHOAMI 0x10000000 /* System ID Register (RO) */ | 31 | #define _WHOAMI 0x10000000 /* System ID Register (RO) */ |
32 | 32 | ||
33 | #define _LEDS 0x10000010 /* LEDs [31:0] (WO) */ | 33 | #define _LEDS 0x10000010 /* LEDs [31:0] (WO) */ |
34 | 34 | ||
35 | #define IRR (*((volatile u_char *) Nep_p2v(_IRR))) | 35 | #define IRR (*((volatile u_char *) Nep_p2v(_IRR))) |
36 | #define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL))) | 36 | #define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL))) |
37 | #define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0))) | 37 | #define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0))) |
38 | #define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1))) | 38 | #define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1))) |
39 | #define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0))) | 39 | #define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0))) |
40 | #define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT))) | 40 | #define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT))) |
41 | #define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN))) | 41 | #define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN))) |
42 | #define SWPK (*((volatile u_char *) Nep_p2v(_SWPK))) | 42 | #define SWPK (*((volatile u_char *) Nep_p2v(_SWPK))) |
43 | #define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI))) | 43 | #define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI))) |
44 | 44 | ||
45 | #define LEDS (*((volatile Word *) Nep_p2v(_LEDS))) | 45 | #define LEDS (*((volatile Word *) Nep_p2v(_LEDS))) |
46 | 46 | ||
47 | #define IRR_ETHERNET (1<<0) | 47 | #define IRR_ETHERNET (1<<0) |
48 | #define IRR_USAR (1<<1) | 48 | #define IRR_USAR (1<<1) |
49 | #define IRR_SA1111 (1<<2) | 49 | #define IRR_SA1111 (1<<2) |
50 | 50 | ||
51 | #define AUD_SEL_1341 (1<<0) | 51 | #define AUD_SEL_1341 (1<<0) |
52 | #define AUD_MUTE_1341 (1<<1) | 52 | #define AUD_MUTE_1341 (1<<1) |
53 | 53 | ||
54 | #define MDM_CTL0_RTS1 (1 << 0) | 54 | #define MDM_CTL0_RTS1 (1 << 0) |
55 | #define MDM_CTL0_DTR1 (1 << 1) | 55 | #define MDM_CTL0_DTR1 (1 << 1) |
56 | #define MDM_CTL0_RTS2 (1 << 2) | 56 | #define MDM_CTL0_RTS2 (1 << 2) |
57 | #define MDM_CTL0_DTR2 (1 << 3) | 57 | #define MDM_CTL0_DTR2 (1 << 3) |
58 | 58 | ||
59 | #define MDM_CTL1_CTS1 (1 << 0) | 59 | #define MDM_CTL1_CTS1 (1 << 0) |
60 | #define MDM_CTL1_DSR1 (1 << 1) | 60 | #define MDM_CTL1_DSR1 (1 << 1) |
61 | #define MDM_CTL1_DCD1 (1 << 2) | 61 | #define MDM_CTL1_DCD1 (1 << 2) |
62 | #define MDM_CTL1_CTS2 (1 << 3) | 62 | #define MDM_CTL1_CTS2 (1 << 3) |
63 | #define MDM_CTL1_DSR2 (1 << 4) | 63 | #define MDM_CTL1_DSR2 (1 << 4) |
64 | #define MDM_CTL1_DCD2 (1 << 5) | 64 | #define MDM_CTL1_DCD2 (1 << 5) |
65 | 65 | ||
66 | #define NCR_GP01_OFF (1<<0) | 66 | #define NCR_GP01_OFF (1<<0) |
67 | #define NCR_TP_PWR_EN (1<<1) | 67 | #define NCR_TP_PWR_EN (1<<1) |
68 | #define NCR_MS_PWR_EN (1<<2) | 68 | #define NCR_MS_PWR_EN (1<<2) |
69 | #define NCR_ENET_OSC_EN (1<<3) | 69 | #define NCR_ENET_OSC_EN (1<<3) |
70 | #define NCR_SPI_KB_WK_UP (1<<4) | 70 | #define NCR_SPI_KB_WK_UP (1<<4) |
71 | #define NCR_A0VPP (1<<5) | 71 | #define NCR_A0VPP (1<<5) |
72 | #define NCR_A1VPP (1<<6) | 72 | #define NCR_A1VPP (1<<6) |
73 | 73 | ||
74 | #endif | 74 | #endif |
75 | 75 |
arch/arm/mach-sa1100/include/mach/system.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-sa1100/include/mach/system.h | 2 | * arch/arm/mach-sa1100/include/mach/system.h |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Nicolas Pitre <nico@cam.org> | 4 | * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net> |
5 | */ | 5 | */ |
6 | #include <mach/hardware.h> | 6 | #include <mach/hardware.h> |
7 | 7 | ||
8 | static inline void arch_idle(void) | 8 | static inline void arch_idle(void) |
9 | { | 9 | { |
10 | cpu_do_idle(); | 10 | cpu_do_idle(); |
11 | } | 11 | } |
12 | 12 | ||
13 | static inline void arch_reset(char mode, const char *cmd) | 13 | static inline void arch_reset(char mode, const char *cmd) |
14 | { | 14 | { |
15 | if (mode == 's') { | 15 | if (mode == 's') { |
16 | /* Jump into ROM at address 0 */ | 16 | /* Jump into ROM at address 0 */ |
17 | cpu_reset(0); | 17 | cpu_reset(0); |
18 | } else { | 18 | } else { |
19 | /* Use on-chip reset capability */ | 19 | /* Use on-chip reset capability */ |
20 | RSRR = RSRR_SWR; | 20 | RSRR = RSRR_SWR; |
21 | } | 21 | } |
22 | } | 22 | } |
23 | 23 |
arch/arm/mach-sa1100/include/mach/uncompress.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-sa1100/include/mach/uncompress.h | 2 | * arch/arm/mach-sa1100/include/mach/uncompress.h |
3 | * | 3 | * |
4 | * (C) 1999 Nicolas Pitre <nico@cam.org> | 4 | * (C) 1999 Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * Reorganised to be machine independent. | 6 | * Reorganised to be machine independent. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "hardware.h" | 9 | #include "hardware.h" |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * The following code assumes the serial port has already been | 12 | * The following code assumes the serial port has already been |
13 | * initialized by the bootloader. We search for the first enabled | 13 | * initialized by the bootloader. We search for the first enabled |
14 | * port in the most probable order. If you didn't setup a port in | 14 | * port in the most probable order. If you didn't setup a port in |
15 | * your bootloader then nothing will appear (which might be desired). | 15 | * your bootloader then nothing will appear (which might be desired). |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) | 18 | #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) |
19 | 19 | ||
20 | static void putc(int c) | 20 | static void putc(int c) |
21 | { | 21 | { |
22 | unsigned long serial_port; | 22 | unsigned long serial_port; |
23 | 23 | ||
24 | do { | 24 | do { |
25 | serial_port = _Ser3UTCR0; | 25 | serial_port = _Ser3UTCR0; |
26 | if (UART(UTCR3) & UTCR3_TXE) break; | 26 | if (UART(UTCR3) & UTCR3_TXE) break; |
27 | serial_port = _Ser1UTCR0; | 27 | serial_port = _Ser1UTCR0; |
28 | if (UART(UTCR3) & UTCR3_TXE) break; | 28 | if (UART(UTCR3) & UTCR3_TXE) break; |
29 | serial_port = _Ser2UTCR0; | 29 | serial_port = _Ser2UTCR0; |
30 | if (UART(UTCR3) & UTCR3_TXE) break; | 30 | if (UART(UTCR3) & UTCR3_TXE) break; |
31 | return; | 31 | return; |
32 | } while (0); | 32 | } while (0); |
33 | 33 | ||
34 | /* wait for space in the UART's transmitter */ | 34 | /* wait for space in the UART's transmitter */ |
35 | while (!(UART(UTSR1) & UTSR1_TNF)) | 35 | while (!(UART(UTSR1) & UTSR1_TNF)) |
36 | barrier(); | 36 | barrier(); |
37 | 37 | ||
38 | /* send the character out. */ | 38 | /* send the character out. */ |
39 | UART(UTDR) = c; | 39 | UART(UTDR) = c; |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline void flush(void) | 42 | static inline void flush(void) |
43 | { | 43 | { |
44 | } | 44 | } |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Nothing to do for these | 47 | * Nothing to do for these |
48 | */ | 48 | */ |
49 | #define arch_decomp_setup() | 49 | #define arch_decomp_setup() |
50 | #define arch_decomp_wdog() | 50 | #define arch_decomp_wdog() |
51 | 51 |
arch/arm/mach-sa1100/pm.c
1 | /* | 1 | /* |
2 | * SA1100 Power Management Routines | 2 | * SA1100 Power Management Routines |
3 | * | 3 | * |
4 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> | 4 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License. | 7 | * modify it under the terms of the GNU General Public License. |
8 | * | 8 | * |
9 | * History: | 9 | * History: |
10 | * | 10 | * |
11 | * 2001-02-06: Cliff Brake Initial code | 11 | * 2001-02-06: Cliff Brake Initial code |
12 | * | 12 | * |
13 | * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> & | 13 | * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> & |
14 | * Chester Kuo <chester@linux.org.tw> | 14 | * Chester Kuo <chester@linux.org.tw> |
15 | * Save more value for the resume function! Support | 15 | * Save more value for the resume function! Support |
16 | * Bitsy/Assabet/Freebird board | 16 | * Bitsy/Assabet/Freebird board |
17 | * | 17 | * |
18 | * 2001-08-29: Nicolas Pitre <nico@cam.org> | 18 | * 2001-08-29: Nicolas Pitre <nico@fluxnic.net> |
19 | * Cleaned up, pushed platform dependent stuff | 19 | * Cleaned up, pushed platform dependent stuff |
20 | * in the platform specific files. | 20 | * in the platform specific files. |
21 | * | 21 | * |
22 | * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array. | 22 | * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array. |
23 | * Storage is local on the stack now. | 23 | * Storage is local on the stack now. |
24 | */ | 24 | */ |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/suspend.h> | 26 | #include <linux/suspend.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/time.h> | 28 | #include <linux/time.h> |
29 | 29 | ||
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | #include <asm/memory.h> | 31 | #include <asm/memory.h> |
32 | #include <asm/system.h> | 32 | #include <asm/system.h> |
33 | #include <asm/mach/time.h> | 33 | #include <asm/mach/time.h> |
34 | 34 | ||
35 | extern void sa1100_cpu_suspend(void); | 35 | extern void sa1100_cpu_suspend(void); |
36 | extern void sa1100_cpu_resume(void); | 36 | extern void sa1100_cpu_resume(void); |
37 | 37 | ||
38 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 38 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
39 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 39 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * List of global SA11x0 peripheral registers to preserve. | 42 | * List of global SA11x0 peripheral registers to preserve. |
43 | * More ones like CP and general purpose register values are preserved | 43 | * More ones like CP and general purpose register values are preserved |
44 | * on the stack and then the stack pointer is stored last in sleep.S. | 44 | * on the stack and then the stack pointer is stored last in sleep.S. |
45 | */ | 45 | */ |
46 | enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, | 46 | enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, |
47 | SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, | 47 | SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, |
48 | 48 | ||
49 | SLEEP_SAVE_Ser1SDCR0, | 49 | SLEEP_SAVE_Ser1SDCR0, |
50 | 50 | ||
51 | SLEEP_SAVE_COUNT | 51 | SLEEP_SAVE_COUNT |
52 | }; | 52 | }; |
53 | 53 | ||
54 | 54 | ||
55 | static int sa11x0_pm_enter(suspend_state_t state) | 55 | static int sa11x0_pm_enter(suspend_state_t state) |
56 | { | 56 | { |
57 | unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT]; | 57 | unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT]; |
58 | 58 | ||
59 | gpio = GPLR; | 59 | gpio = GPLR; |
60 | 60 | ||
61 | /* save vital registers */ | 61 | /* save vital registers */ |
62 | SAVE(GPDR); | 62 | SAVE(GPDR); |
63 | SAVE(GAFR); | 63 | SAVE(GAFR); |
64 | 64 | ||
65 | SAVE(PPDR); | 65 | SAVE(PPDR); |
66 | SAVE(PPSR); | 66 | SAVE(PPSR); |
67 | SAVE(PPAR); | 67 | SAVE(PPAR); |
68 | SAVE(PSDR); | 68 | SAVE(PSDR); |
69 | 69 | ||
70 | SAVE(Ser1SDCR0); | 70 | SAVE(Ser1SDCR0); |
71 | 71 | ||
72 | /* Clear previous reset status */ | 72 | /* Clear previous reset status */ |
73 | RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; | 73 | RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; |
74 | 74 | ||
75 | /* set resume return address */ | 75 | /* set resume return address */ |
76 | PSPR = virt_to_phys(sa1100_cpu_resume); | 76 | PSPR = virt_to_phys(sa1100_cpu_resume); |
77 | 77 | ||
78 | /* go zzz */ | 78 | /* go zzz */ |
79 | sa1100_cpu_suspend(); | 79 | sa1100_cpu_suspend(); |
80 | 80 | ||
81 | cpu_init(); | 81 | cpu_init(); |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * Ensure not to come back here if it wasn't intended | 84 | * Ensure not to come back here if it wasn't intended |
85 | */ | 85 | */ |
86 | PSPR = 0; | 86 | PSPR = 0; |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * Ensure interrupt sources are disabled; we will re-init | 89 | * Ensure interrupt sources are disabled; we will re-init |
90 | * the interrupt subsystem via the device manager. | 90 | * the interrupt subsystem via the device manager. |
91 | */ | 91 | */ |
92 | ICLR = 0; | 92 | ICLR = 0; |
93 | ICCR = 1; | 93 | ICCR = 1; |
94 | ICMR = 0; | 94 | ICMR = 0; |
95 | 95 | ||
96 | /* restore registers */ | 96 | /* restore registers */ |
97 | RESTORE(GPDR); | 97 | RESTORE(GPDR); |
98 | RESTORE(GAFR); | 98 | RESTORE(GAFR); |
99 | 99 | ||
100 | RESTORE(PPDR); | 100 | RESTORE(PPDR); |
101 | RESTORE(PPSR); | 101 | RESTORE(PPSR); |
102 | RESTORE(PPAR); | 102 | RESTORE(PPAR); |
103 | RESTORE(PSDR); | 103 | RESTORE(PSDR); |
104 | 104 | ||
105 | RESTORE(Ser1SDCR0); | 105 | RESTORE(Ser1SDCR0); |
106 | 106 | ||
107 | GPSR = gpio; | 107 | GPSR = gpio; |
108 | GPCR = ~gpio; | 108 | GPCR = ~gpio; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * Clear the peripheral sleep-hold bit. | 111 | * Clear the peripheral sleep-hold bit. |
112 | */ | 112 | */ |
113 | PSSR = PSSR_PH; | 113 | PSSR = PSSR_PH; |
114 | 114 | ||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | unsigned long sleep_phys_sp(void *sp) | 118 | unsigned long sleep_phys_sp(void *sp) |
119 | { | 119 | { |
120 | return virt_to_phys(sp); | 120 | return virt_to_phys(sp); |
121 | } | 121 | } |
122 | 122 | ||
123 | static struct platform_suspend_ops sa11x0_pm_ops = { | 123 | static struct platform_suspend_ops sa11x0_pm_ops = { |
124 | .enter = sa11x0_pm_enter, | 124 | .enter = sa11x0_pm_enter, |
125 | .valid = suspend_valid_only_mem, | 125 | .valid = suspend_valid_only_mem, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static int __init sa11x0_pm_init(void) | 128 | static int __init sa11x0_pm_init(void) |
129 | { | 129 | { |
130 | suspend_set_ops(&sa11x0_pm_ops); | 130 | suspend_set_ops(&sa11x0_pm_ops); |
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
133 | 133 | ||
134 | late_initcall(sa11x0_pm_init); | 134 | late_initcall(sa11x0_pm_init); |
135 | 135 |
arch/arm/mach-sa1100/time.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-sa1100/time.c | 2 | * linux/arch/arm/mach-sa1100/time.c |
3 | * | 3 | * |
4 | * Copyright (C) 1998 Deborah Wallach. | 4 | * Copyright (C) 1998 Deborah Wallach. |
5 | * Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com> | 5 | * Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com> |
6 | * | 6 | * |
7 | * 2000/03/29 (C) Nicolas Pitre <nico@cam.org> | 7 | * 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net> |
8 | * Rewritten: big cleanup, much simpler, better HZ accuracy. | 8 | * Rewritten: big cleanup, much simpler, better HZ accuracy. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/timex.h> | 15 | #include <linux/timex.h> |
16 | #include <linux/clockchips.h> | 16 | #include <linux/clockchips.h> |
17 | 17 | ||
18 | #include <asm/mach/time.h> | 18 | #include <asm/mach/time.h> |
19 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
20 | 20 | ||
21 | #define MIN_OSCR_DELTA 2 | 21 | #define MIN_OSCR_DELTA 2 |
22 | 22 | ||
23 | static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) | 23 | static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) |
24 | { | 24 | { |
25 | struct clock_event_device *c = dev_id; | 25 | struct clock_event_device *c = dev_id; |
26 | 26 | ||
27 | /* Disarm the compare/match, signal the event. */ | 27 | /* Disarm the compare/match, signal the event. */ |
28 | OIER &= ~OIER_E0; | 28 | OIER &= ~OIER_E0; |
29 | OSSR = OSSR_M0; | 29 | OSSR = OSSR_M0; |
30 | c->event_handler(c); | 30 | c->event_handler(c); |
31 | 31 | ||
32 | return IRQ_HANDLED; | 32 | return IRQ_HANDLED; |
33 | } | 33 | } |
34 | 34 | ||
35 | static int | 35 | static int |
36 | sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c) | 36 | sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c) |
37 | { | 37 | { |
38 | unsigned long flags, next, oscr; | 38 | unsigned long flags, next, oscr; |
39 | 39 | ||
40 | raw_local_irq_save(flags); | 40 | raw_local_irq_save(flags); |
41 | OIER |= OIER_E0; | 41 | OIER |= OIER_E0; |
42 | next = OSCR + delta; | 42 | next = OSCR + delta; |
43 | OSMR0 = next; | 43 | OSMR0 = next; |
44 | oscr = OSCR; | 44 | oscr = OSCR; |
45 | raw_local_irq_restore(flags); | 45 | raw_local_irq_restore(flags); |
46 | 46 | ||
47 | return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; | 47 | return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static void | 50 | static void |
51 | sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c) | 51 | sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c) |
52 | { | 52 | { |
53 | unsigned long flags; | 53 | unsigned long flags; |
54 | 54 | ||
55 | switch (mode) { | 55 | switch (mode) { |
56 | case CLOCK_EVT_MODE_ONESHOT: | 56 | case CLOCK_EVT_MODE_ONESHOT: |
57 | case CLOCK_EVT_MODE_UNUSED: | 57 | case CLOCK_EVT_MODE_UNUSED: |
58 | case CLOCK_EVT_MODE_SHUTDOWN: | 58 | case CLOCK_EVT_MODE_SHUTDOWN: |
59 | raw_local_irq_save(flags); | 59 | raw_local_irq_save(flags); |
60 | OIER &= ~OIER_E0; | 60 | OIER &= ~OIER_E0; |
61 | OSSR = OSSR_M0; | 61 | OSSR = OSSR_M0; |
62 | raw_local_irq_restore(flags); | 62 | raw_local_irq_restore(flags); |
63 | break; | 63 | break; |
64 | 64 | ||
65 | case CLOCK_EVT_MODE_RESUME: | 65 | case CLOCK_EVT_MODE_RESUME: |
66 | case CLOCK_EVT_MODE_PERIODIC: | 66 | case CLOCK_EVT_MODE_PERIODIC: |
67 | break; | 67 | break; |
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | static struct clock_event_device ckevt_sa1100_osmr0 = { | 71 | static struct clock_event_device ckevt_sa1100_osmr0 = { |
72 | .name = "osmr0", | 72 | .name = "osmr0", |
73 | .features = CLOCK_EVT_FEAT_ONESHOT, | 73 | .features = CLOCK_EVT_FEAT_ONESHOT, |
74 | .shift = 32, | 74 | .shift = 32, |
75 | .rating = 200, | 75 | .rating = 200, |
76 | .set_next_event = sa1100_osmr0_set_next_event, | 76 | .set_next_event = sa1100_osmr0_set_next_event, |
77 | .set_mode = sa1100_osmr0_set_mode, | 77 | .set_mode = sa1100_osmr0_set_mode, |
78 | }; | 78 | }; |
79 | 79 | ||
80 | static cycle_t sa1100_read_oscr(void) | 80 | static cycle_t sa1100_read_oscr(void) |
81 | { | 81 | { |
82 | return OSCR; | 82 | return OSCR; |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct clocksource cksrc_sa1100_oscr = { | 85 | static struct clocksource cksrc_sa1100_oscr = { |
86 | .name = "oscr", | 86 | .name = "oscr", |
87 | .rating = 200, | 87 | .rating = 200, |
88 | .read = sa1100_read_oscr, | 88 | .read = sa1100_read_oscr, |
89 | .mask = CLOCKSOURCE_MASK(32), | 89 | .mask = CLOCKSOURCE_MASK(32), |
90 | .shift = 20, | 90 | .shift = 20, |
91 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 91 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static struct irqaction sa1100_timer_irq = { | 94 | static struct irqaction sa1100_timer_irq = { |
95 | .name = "ost0", | 95 | .name = "ost0", |
96 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 96 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
97 | .handler = sa1100_ost0_interrupt, | 97 | .handler = sa1100_ost0_interrupt, |
98 | .dev_id = &ckevt_sa1100_osmr0, | 98 | .dev_id = &ckevt_sa1100_osmr0, |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static void __init sa1100_timer_init(void) | 101 | static void __init sa1100_timer_init(void) |
102 | { | 102 | { |
103 | OIER = 0; /* disable any timer interrupts */ | 103 | OIER = 0; /* disable any timer interrupts */ |
104 | OSSR = 0xf; /* clear status on all timers */ | 104 | OSSR = 0xf; /* clear status on all timers */ |
105 | 105 | ||
106 | ckevt_sa1100_osmr0.mult = | 106 | ckevt_sa1100_osmr0.mult = |
107 | div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift); | 107 | div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift); |
108 | ckevt_sa1100_osmr0.max_delta_ns = | 108 | ckevt_sa1100_osmr0.max_delta_ns = |
109 | clockevent_delta2ns(0x7fffffff, &ckevt_sa1100_osmr0); | 109 | clockevent_delta2ns(0x7fffffff, &ckevt_sa1100_osmr0); |
110 | ckevt_sa1100_osmr0.min_delta_ns = | 110 | ckevt_sa1100_osmr0.min_delta_ns = |
111 | clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1; | 111 | clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1; |
112 | ckevt_sa1100_osmr0.cpumask = cpumask_of(0); | 112 | ckevt_sa1100_osmr0.cpumask = cpumask_of(0); |
113 | 113 | ||
114 | cksrc_sa1100_oscr.mult = | 114 | cksrc_sa1100_oscr.mult = |
115 | clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift); | 115 | clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift); |
116 | 116 | ||
117 | setup_irq(IRQ_OST0, &sa1100_timer_irq); | 117 | setup_irq(IRQ_OST0, &sa1100_timer_irq); |
118 | 118 | ||
119 | clocksource_register(&cksrc_sa1100_oscr); | 119 | clocksource_register(&cksrc_sa1100_oscr); |
120 | clockevents_register_device(&ckevt_sa1100_osmr0); | 120 | clockevents_register_device(&ckevt_sa1100_osmr0); |
121 | } | 121 | } |
122 | 122 | ||
123 | #ifdef CONFIG_PM | 123 | #ifdef CONFIG_PM |
124 | unsigned long osmr[4], oier; | 124 | unsigned long osmr[4], oier; |
125 | 125 | ||
126 | static void sa1100_timer_suspend(void) | 126 | static void sa1100_timer_suspend(void) |
127 | { | 127 | { |
128 | osmr[0] = OSMR0; | 128 | osmr[0] = OSMR0; |
129 | osmr[1] = OSMR1; | 129 | osmr[1] = OSMR1; |
130 | osmr[2] = OSMR2; | 130 | osmr[2] = OSMR2; |
131 | osmr[3] = OSMR3; | 131 | osmr[3] = OSMR3; |
132 | oier = OIER; | 132 | oier = OIER; |
133 | } | 133 | } |
134 | 134 | ||
135 | static void sa1100_timer_resume(void) | 135 | static void sa1100_timer_resume(void) |
136 | { | 136 | { |
137 | OSSR = 0x0f; | 137 | OSSR = 0x0f; |
138 | OSMR0 = osmr[0]; | 138 | OSMR0 = osmr[0]; |
139 | OSMR1 = osmr[1]; | 139 | OSMR1 = osmr[1]; |
140 | OSMR2 = osmr[2]; | 140 | OSMR2 = osmr[2]; |
141 | OSMR3 = osmr[3]; | 141 | OSMR3 = osmr[3]; |
142 | OIER = oier; | 142 | OIER = oier; |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * OSMR0 is the system timer: make sure OSCR is sufficiently behind | 145 | * OSMR0 is the system timer: make sure OSCR is sufficiently behind |
146 | */ | 146 | */ |
147 | OSCR = OSMR0 - LATCH; | 147 | OSCR = OSMR0 - LATCH; |
148 | } | 148 | } |
149 | #else | 149 | #else |
150 | #define sa1100_timer_suspend NULL | 150 | #define sa1100_timer_suspend NULL |
151 | #define sa1100_timer_resume NULL | 151 | #define sa1100_timer_resume NULL |
152 | #endif | 152 | #endif |
153 | 153 | ||
154 | struct sys_timer sa1100_timer = { | 154 | struct sys_timer sa1100_timer = { |
155 | .init = sa1100_timer_init, | 155 | .init = sa1100_timer_init, |
156 | .suspend = sa1100_timer_suspend, | 156 | .suspend = sa1100_timer_suspend, |
157 | .resume = sa1100_timer_resume, | 157 | .resume = sa1100_timer_resume, |
158 | }; | 158 | }; |
159 | 159 |
arch/arm/mm/proc-xscale.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/mm/proc-xscale.S | 2 | * linux/arch/arm/mm/proc-xscale.S |
3 | * | 3 | * |
4 | * Author: Nicolas Pitre | 4 | * Author: Nicolas Pitre |
5 | * Created: November 2000 | 5 | * Created: November 2000 |
6 | * Copyright: (C) 2000, 2001 MontaVista Software Inc. | 6 | * Copyright: (C) 2000, 2001 MontaVista Software Inc. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * MMU functions for the Intel XScale CPUs | 12 | * MMU functions for the Intel XScale CPUs |
13 | * | 13 | * |
14 | * 2001 Aug 21: | 14 | * 2001 Aug 21: |
15 | * some contributions by Brett Gaines <brett.w.gaines@intel.com> | 15 | * some contributions by Brett Gaines <brett.w.gaines@intel.com> |
16 | * Copyright 2001 by Intel Corp. | 16 | * Copyright 2001 by Intel Corp. |
17 | * | 17 | * |
18 | * 2001 Sep 08: | 18 | * 2001 Sep 08: |
19 | * Completely revisited, many important fixes | 19 | * Completely revisited, many important fixes |
20 | * Nicolas Pitre <nico@cam.org> | 20 | * Nicolas Pitre <nico@fluxnic.net> |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/linkage.h> | 23 | #include <linux/linkage.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <asm/assembler.h> | 25 | #include <asm/assembler.h> |
26 | #include <asm/hwcap.h> | 26 | #include <asm/hwcap.h> |
27 | #include <asm/pgtable.h> | 27 | #include <asm/pgtable.h> |
28 | #include <asm/pgtable-hwdef.h> | 28 | #include <asm/pgtable-hwdef.h> |
29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/ptrace.h> | 30 | #include <asm/ptrace.h> |
31 | #include "proc-macros.S" | 31 | #include "proc-macros.S" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * This is the maximum size of an area which will be flushed. If the area | 34 | * This is the maximum size of an area which will be flushed. If the area |
35 | * is larger than this, then we flush the whole cache | 35 | * is larger than this, then we flush the whole cache |
36 | */ | 36 | */ |
37 | #define MAX_AREA_SIZE 32768 | 37 | #define MAX_AREA_SIZE 32768 |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * the cache line size of the I and D cache | 40 | * the cache line size of the I and D cache |
41 | */ | 41 | */ |
42 | #define CACHELINESIZE 32 | 42 | #define CACHELINESIZE 32 |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * the size of the data cache | 45 | * the size of the data cache |
46 | */ | 46 | */ |
47 | #define CACHESIZE 32768 | 47 | #define CACHESIZE 32768 |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Virtual address used to allocate the cache when flushed | 50 | * Virtual address used to allocate the cache when flushed |
51 | * | 51 | * |
52 | * This must be an address range which is _never_ used. It should | 52 | * This must be an address range which is _never_ used. It should |
53 | * apparently have a mapping in the corresponding page table for | 53 | * apparently have a mapping in the corresponding page table for |
54 | * compatibility with future CPUs that _could_ require it. For instance we | 54 | * compatibility with future CPUs that _could_ require it. For instance we |
55 | * don't care. | 55 | * don't care. |
56 | * | 56 | * |
57 | * This must be aligned on a 2*CACHESIZE boundary. The code selects one of | 57 | * This must be aligned on a 2*CACHESIZE boundary. The code selects one of |
58 | * the 2 areas in alternance each time the clean_d_cache macro is used. | 58 | * the 2 areas in alternance each time the clean_d_cache macro is used. |
59 | * Without this the XScale core exhibits cache eviction problems and no one | 59 | * Without this the XScale core exhibits cache eviction problems and no one |
60 | * knows why. | 60 | * knows why. |
61 | * | 61 | * |
62 | * Reminder: the vector table is located at 0xffff0000-0xffff0fff. | 62 | * Reminder: the vector table is located at 0xffff0000-0xffff0fff. |
63 | */ | 63 | */ |
64 | #define CLEAN_ADDR 0xfffe0000 | 64 | #define CLEAN_ADDR 0xfffe0000 |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * This macro is used to wait for a CP15 write and is needed | 67 | * This macro is used to wait for a CP15 write and is needed |
68 | * when we have to ensure that the last operation to the co-pro | 68 | * when we have to ensure that the last operation to the co-pro |
69 | * was completed before continuing with operation. | 69 | * was completed before continuing with operation. |
70 | */ | 70 | */ |
71 | .macro cpwait, rd | 71 | .macro cpwait, rd |
72 | mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 | 72 | mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 |
73 | mov \rd, \rd @ wait for completion | 73 | mov \rd, \rd @ wait for completion |
74 | sub pc, pc, #4 @ flush instruction pipeline | 74 | sub pc, pc, #4 @ flush instruction pipeline |
75 | .endm | 75 | .endm |
76 | 76 | ||
77 | .macro cpwait_ret, lr, rd | 77 | .macro cpwait_ret, lr, rd |
78 | mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 | 78 | mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 |
79 | sub pc, \lr, \rd, LSR #32 @ wait for completion and | 79 | sub pc, \lr, \rd, LSR #32 @ wait for completion and |
80 | @ flush instruction pipeline | 80 | @ flush instruction pipeline |
81 | .endm | 81 | .endm |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * This macro cleans the entire dcache using line allocate. | 84 | * This macro cleans the entire dcache using line allocate. |
85 | * The main loop has been unrolled to reduce loop overhead. | 85 | * The main loop has been unrolled to reduce loop overhead. |
86 | * rd and rs are two scratch registers. | 86 | * rd and rs are two scratch registers. |
87 | */ | 87 | */ |
88 | .macro clean_d_cache, rd, rs | 88 | .macro clean_d_cache, rd, rs |
89 | ldr \rs, =clean_addr | 89 | ldr \rs, =clean_addr |
90 | ldr \rd, [\rs] | 90 | ldr \rd, [\rs] |
91 | eor \rd, \rd, #CACHESIZE | 91 | eor \rd, \rd, #CACHESIZE |
92 | str \rd, [\rs] | 92 | str \rd, [\rs] |
93 | add \rs, \rd, #CACHESIZE | 93 | add \rs, \rd, #CACHESIZE |
94 | 1: mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line | 94 | 1: mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line |
95 | add \rd, \rd, #CACHELINESIZE | 95 | add \rd, \rd, #CACHELINESIZE |
96 | mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line | 96 | mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line |
97 | add \rd, \rd, #CACHELINESIZE | 97 | add \rd, \rd, #CACHELINESIZE |
98 | mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line | 98 | mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line |
99 | add \rd, \rd, #CACHELINESIZE | 99 | add \rd, \rd, #CACHELINESIZE |
100 | mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line | 100 | mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line |
101 | add \rd, \rd, #CACHELINESIZE | 101 | add \rd, \rd, #CACHELINESIZE |
102 | teq \rd, \rs | 102 | teq \rd, \rs |
103 | bne 1b | 103 | bne 1b |
104 | .endm | 104 | .endm |
105 | 105 | ||
106 | .data | 106 | .data |
107 | clean_addr: .word CLEAN_ADDR | 107 | clean_addr: .word CLEAN_ADDR |
108 | 108 | ||
109 | .text | 109 | .text |
110 | 110 | ||
111 | /* | 111 | /* |
112 | * cpu_xscale_proc_init() | 112 | * cpu_xscale_proc_init() |
113 | * | 113 | * |
114 | * Nothing too exciting at the moment | 114 | * Nothing too exciting at the moment |
115 | */ | 115 | */ |
116 | ENTRY(cpu_xscale_proc_init) | 116 | ENTRY(cpu_xscale_proc_init) |
117 | @ enable write buffer coalescing. Some bootloader disable it | 117 | @ enable write buffer coalescing. Some bootloader disable it |
118 | mrc p15, 0, r1, c1, c0, 1 | 118 | mrc p15, 0, r1, c1, c0, 1 |
119 | bic r1, r1, #1 | 119 | bic r1, r1, #1 |
120 | mcr p15, 0, r1, c1, c0, 1 | 120 | mcr p15, 0, r1, c1, c0, 1 |
121 | mov pc, lr | 121 | mov pc, lr |
122 | 122 | ||
123 | /* | 123 | /* |
124 | * cpu_xscale_proc_fin() | 124 | * cpu_xscale_proc_fin() |
125 | */ | 125 | */ |
126 | ENTRY(cpu_xscale_proc_fin) | 126 | ENTRY(cpu_xscale_proc_fin) |
127 | str lr, [sp, #-4]! | 127 | str lr, [sp, #-4]! |
128 | mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE | 128 | mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE |
129 | msr cpsr_c, r0 | 129 | msr cpsr_c, r0 |
130 | bl xscale_flush_kern_cache_all @ clean caches | 130 | bl xscale_flush_kern_cache_all @ clean caches |
131 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register | 131 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register |
132 | bic r0, r0, #0x1800 @ ...IZ........... | 132 | bic r0, r0, #0x1800 @ ...IZ........... |
133 | bic r0, r0, #0x0006 @ .............CA. | 133 | bic r0, r0, #0x0006 @ .............CA. |
134 | mcr p15, 0, r0, c1, c0, 0 @ disable caches | 134 | mcr p15, 0, r0, c1, c0, 0 @ disable caches |
135 | ldr pc, [sp], #4 | 135 | ldr pc, [sp], #4 |
136 | 136 | ||
137 | /* | 137 | /* |
138 | * cpu_xscale_reset(loc) | 138 | * cpu_xscale_reset(loc) |
139 | * | 139 | * |
140 | * Perform a soft reset of the system. Put the CPU into the | 140 | * Perform a soft reset of the system. Put the CPU into the |
141 | * same state as it would be if it had been reset, and branch | 141 | * same state as it would be if it had been reset, and branch |
142 | * to what would be the reset vector. | 142 | * to what would be the reset vector. |
143 | * | 143 | * |
144 | * loc: location to jump to for soft reset | 144 | * loc: location to jump to for soft reset |
145 | * | 145 | * |
146 | * Beware PXA270 erratum E7. | 146 | * Beware PXA270 erratum E7. |
147 | */ | 147 | */ |
148 | .align 5 | 148 | .align 5 |
149 | ENTRY(cpu_xscale_reset) | 149 | ENTRY(cpu_xscale_reset) |
150 | mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE | 150 | mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE |
151 | msr cpsr_c, r1 @ reset CPSR | 151 | msr cpsr_c, r1 @ reset CPSR |
152 | mcr p15, 0, r1, c10, c4, 1 @ unlock I-TLB | 152 | mcr p15, 0, r1, c10, c4, 1 @ unlock I-TLB |
153 | mcr p15, 0, r1, c8, c5, 0 @ invalidate I-TLB | 153 | mcr p15, 0, r1, c8, c5, 0 @ invalidate I-TLB |
154 | mrc p15, 0, r1, c1, c0, 0 @ ctrl register | 154 | mrc p15, 0, r1, c1, c0, 0 @ ctrl register |
155 | bic r1, r1, #0x0086 @ ........B....CA. | 155 | bic r1, r1, #0x0086 @ ........B....CA. |
156 | bic r1, r1, #0x3900 @ ..VIZ..S........ | 156 | bic r1, r1, #0x3900 @ ..VIZ..S........ |
157 | sub pc, pc, #4 @ flush pipeline | 157 | sub pc, pc, #4 @ flush pipeline |
158 | @ *** cache line aligned *** | 158 | @ *** cache line aligned *** |
159 | mcr p15, 0, r1, c1, c0, 0 @ ctrl register | 159 | mcr p15, 0, r1, c1, c0, 0 @ ctrl register |
160 | bic r1, r1, #0x0001 @ ...............M | 160 | bic r1, r1, #0x0001 @ ...............M |
161 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB | 161 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB |
162 | mcr p15, 0, r1, c1, c0, 0 @ ctrl register | 162 | mcr p15, 0, r1, c1, c0, 0 @ ctrl register |
163 | @ CAUTION: MMU turned off from this point. We count on the pipeline | 163 | @ CAUTION: MMU turned off from this point. We count on the pipeline |
164 | @ already containing those two last instructions to survive. | 164 | @ already containing those two last instructions to survive. |
165 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | 165 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
166 | mov pc, r0 | 166 | mov pc, r0 |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * cpu_xscale_do_idle() | 169 | * cpu_xscale_do_idle() |
170 | * | 170 | * |
171 | * Cause the processor to idle | 171 | * Cause the processor to idle |
172 | * | 172 | * |
173 | * For now we do nothing but go to idle mode for every case | 173 | * For now we do nothing but go to idle mode for every case |
174 | * | 174 | * |
175 | * XScale supports clock switching, but using idle mode support | 175 | * XScale supports clock switching, but using idle mode support |
176 | * allows external hardware to react to system state changes. | 176 | * allows external hardware to react to system state changes. |
177 | */ | 177 | */ |
178 | .align 5 | 178 | .align 5 |
179 | 179 | ||
180 | ENTRY(cpu_xscale_do_idle) | 180 | ENTRY(cpu_xscale_do_idle) |
181 | mov r0, #1 | 181 | mov r0, #1 |
182 | mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE | 182 | mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE |
183 | mov pc, lr | 183 | mov pc, lr |
184 | 184 | ||
185 | /* ================================= CACHE ================================ */ | 185 | /* ================================= CACHE ================================ */ |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * flush_user_cache_all() | 188 | * flush_user_cache_all() |
189 | * | 189 | * |
190 | * Invalidate all cache entries in a particular address | 190 | * Invalidate all cache entries in a particular address |
191 | * space. | 191 | * space. |
192 | */ | 192 | */ |
193 | ENTRY(xscale_flush_user_cache_all) | 193 | ENTRY(xscale_flush_user_cache_all) |
194 | /* FALLTHROUGH */ | 194 | /* FALLTHROUGH */ |
195 | 195 | ||
196 | /* | 196 | /* |
197 | * flush_kern_cache_all() | 197 | * flush_kern_cache_all() |
198 | * | 198 | * |
199 | * Clean and invalidate the entire cache. | 199 | * Clean and invalidate the entire cache. |
200 | */ | 200 | */ |
201 | ENTRY(xscale_flush_kern_cache_all) | 201 | ENTRY(xscale_flush_kern_cache_all) |
202 | mov r2, #VM_EXEC | 202 | mov r2, #VM_EXEC |
203 | mov ip, #0 | 203 | mov ip, #0 |
204 | __flush_whole_cache: | 204 | __flush_whole_cache: |
205 | clean_d_cache r0, r1 | 205 | clean_d_cache r0, r1 |
206 | tst r2, #VM_EXEC | 206 | tst r2, #VM_EXEC |
207 | mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB | 207 | mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB |
208 | mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | 208 | mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer |
209 | mov pc, lr | 209 | mov pc, lr |
210 | 210 | ||
211 | /* | 211 | /* |
212 | * flush_user_cache_range(start, end, vm_flags) | 212 | * flush_user_cache_range(start, end, vm_flags) |
213 | * | 213 | * |
214 | * Invalidate a range of cache entries in the specified | 214 | * Invalidate a range of cache entries in the specified |
215 | * address space. | 215 | * address space. |
216 | * | 216 | * |
217 | * - start - start address (may not be aligned) | 217 | * - start - start address (may not be aligned) |
218 | * - end - end address (exclusive, may not be aligned) | 218 | * - end - end address (exclusive, may not be aligned) |
219 | * - vma - vma_area_struct describing address space | 219 | * - vma - vma_area_struct describing address space |
220 | */ | 220 | */ |
221 | .align 5 | 221 | .align 5 |
222 | ENTRY(xscale_flush_user_cache_range) | 222 | ENTRY(xscale_flush_user_cache_range) |
223 | mov ip, #0 | 223 | mov ip, #0 |
224 | sub r3, r1, r0 @ calculate total size | 224 | sub r3, r1, r0 @ calculate total size |
225 | cmp r3, #MAX_AREA_SIZE | 225 | cmp r3, #MAX_AREA_SIZE |
226 | bhs __flush_whole_cache | 226 | bhs __flush_whole_cache |
227 | 227 | ||
228 | 1: tst r2, #VM_EXEC | 228 | 1: tst r2, #VM_EXEC |
229 | mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line | 229 | mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line |
230 | mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line | 230 | mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line |
231 | mcr p15, 0, r0, c7, c6, 1 @ Invalidate D cache line | 231 | mcr p15, 0, r0, c7, c6, 1 @ Invalidate D cache line |
232 | add r0, r0, #CACHELINESIZE | 232 | add r0, r0, #CACHELINESIZE |
233 | cmp r0, r1 | 233 | cmp r0, r1 |
234 | blo 1b | 234 | blo 1b |
235 | tst r2, #VM_EXEC | 235 | tst r2, #VM_EXEC |
236 | mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB | 236 | mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB |
237 | mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | 237 | mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer |
238 | mov pc, lr | 238 | mov pc, lr |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * coherent_kern_range(start, end) | 241 | * coherent_kern_range(start, end) |
242 | * | 242 | * |
243 | * Ensure coherency between the Icache and the Dcache in the | 243 | * Ensure coherency between the Icache and the Dcache in the |
244 | * region described by start. If you have non-snooping | 244 | * region described by start. If you have non-snooping |
245 | * Harvard caches, you need to implement this function. | 245 | * Harvard caches, you need to implement this function. |
246 | * | 246 | * |
247 | * - start - virtual start address | 247 | * - start - virtual start address |
248 | * - end - virtual end address | 248 | * - end - virtual end address |
249 | * | 249 | * |
250 | * Note: single I-cache line invalidation isn't used here since | 250 | * Note: single I-cache line invalidation isn't used here since |
251 | * it also trashes the mini I-cache used by JTAG debuggers. | 251 | * it also trashes the mini I-cache used by JTAG debuggers. |
252 | */ | 252 | */ |
253 | ENTRY(xscale_coherent_kern_range) | 253 | ENTRY(xscale_coherent_kern_range) |
254 | bic r0, r0, #CACHELINESIZE - 1 | 254 | bic r0, r0, #CACHELINESIZE - 1 |
255 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 255 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
256 | add r0, r0, #CACHELINESIZE | 256 | add r0, r0, #CACHELINESIZE |
257 | cmp r0, r1 | 257 | cmp r0, r1 |
258 | blo 1b | 258 | blo 1b |
259 | mov r0, #0 | 259 | mov r0, #0 |
260 | mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB | 260 | mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB |
261 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 261 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
262 | mov pc, lr | 262 | mov pc, lr |
263 | 263 | ||
264 | /* | 264 | /* |
265 | * coherent_user_range(start, end) | 265 | * coherent_user_range(start, end) |
266 | * | 266 | * |
267 | * Ensure coherency between the Icache and the Dcache in the | 267 | * Ensure coherency between the Icache and the Dcache in the |
268 | * region described by start. If you have non-snooping | 268 | * region described by start. If you have non-snooping |
269 | * Harvard caches, you need to implement this function. | 269 | * Harvard caches, you need to implement this function. |
270 | * | 270 | * |
271 | * - start - virtual start address | 271 | * - start - virtual start address |
272 | * - end - virtual end address | 272 | * - end - virtual end address |
273 | */ | 273 | */ |
274 | ENTRY(xscale_coherent_user_range) | 274 | ENTRY(xscale_coherent_user_range) |
275 | bic r0, r0, #CACHELINESIZE - 1 | 275 | bic r0, r0, #CACHELINESIZE - 1 |
276 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 276 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
277 | mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache entry | 277 | mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache entry |
278 | add r0, r0, #CACHELINESIZE | 278 | add r0, r0, #CACHELINESIZE |
279 | cmp r0, r1 | 279 | cmp r0, r1 |
280 | blo 1b | 280 | blo 1b |
281 | mov r0, #0 | 281 | mov r0, #0 |
282 | mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB | 282 | mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB |
283 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 283 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
284 | mov pc, lr | 284 | mov pc, lr |
285 | 285 | ||
286 | /* | 286 | /* |
287 | * flush_kern_dcache_page(void *page) | 287 | * flush_kern_dcache_page(void *page) |
288 | * | 288 | * |
289 | * Ensure no D cache aliasing occurs, either with itself or | 289 | * Ensure no D cache aliasing occurs, either with itself or |
290 | * the I cache | 290 | * the I cache |
291 | * | 291 | * |
292 | * - addr - page aligned address | 292 | * - addr - page aligned address |
293 | */ | 293 | */ |
294 | ENTRY(xscale_flush_kern_dcache_page) | 294 | ENTRY(xscale_flush_kern_dcache_page) |
295 | add r1, r0, #PAGE_SZ | 295 | add r1, r0, #PAGE_SZ |
296 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 296 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
297 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry | 297 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry |
298 | add r0, r0, #CACHELINESIZE | 298 | add r0, r0, #CACHELINESIZE |
299 | cmp r0, r1 | 299 | cmp r0, r1 |
300 | blo 1b | 300 | blo 1b |
301 | mov r0, #0 | 301 | mov r0, #0 |
302 | mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB | 302 | mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB |
303 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 303 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
304 | mov pc, lr | 304 | mov pc, lr |
305 | 305 | ||
306 | /* | 306 | /* |
307 | * dma_inv_range(start, end) | 307 | * dma_inv_range(start, end) |
308 | * | 308 | * |
309 | * Invalidate (discard) the specified virtual address range. | 309 | * Invalidate (discard) the specified virtual address range. |
310 | * May not write back any entries. If 'start' or 'end' | 310 | * May not write back any entries. If 'start' or 'end' |
311 | * are not cache line aligned, those lines must be written | 311 | * are not cache line aligned, those lines must be written |
312 | * back. | 312 | * back. |
313 | * | 313 | * |
314 | * - start - virtual start address | 314 | * - start - virtual start address |
315 | * - end - virtual end address | 315 | * - end - virtual end address |
316 | */ | 316 | */ |
317 | ENTRY(xscale_dma_inv_range) | 317 | ENTRY(xscale_dma_inv_range) |
318 | tst r0, #CACHELINESIZE - 1 | 318 | tst r0, #CACHELINESIZE - 1 |
319 | bic r0, r0, #CACHELINESIZE - 1 | 319 | bic r0, r0, #CACHELINESIZE - 1 |
320 | mcrne p15, 0, r0, c7, c10, 1 @ clean D entry | 320 | mcrne p15, 0, r0, c7, c10, 1 @ clean D entry |
321 | tst r1, #CACHELINESIZE - 1 | 321 | tst r1, #CACHELINESIZE - 1 |
322 | mcrne p15, 0, r1, c7, c10, 1 @ clean D entry | 322 | mcrne p15, 0, r1, c7, c10, 1 @ clean D entry |
323 | 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry | 323 | 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry |
324 | add r0, r0, #CACHELINESIZE | 324 | add r0, r0, #CACHELINESIZE |
325 | cmp r0, r1 | 325 | cmp r0, r1 |
326 | blo 1b | 326 | blo 1b |
327 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 327 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
328 | mov pc, lr | 328 | mov pc, lr |
329 | 329 | ||
330 | /* | 330 | /* |
331 | * dma_clean_range(start, end) | 331 | * dma_clean_range(start, end) |
332 | * | 332 | * |
333 | * Clean the specified virtual address range. | 333 | * Clean the specified virtual address range. |
334 | * | 334 | * |
335 | * - start - virtual start address | 335 | * - start - virtual start address |
336 | * - end - virtual end address | 336 | * - end - virtual end address |
337 | */ | 337 | */ |
338 | ENTRY(xscale_dma_clean_range) | 338 | ENTRY(xscale_dma_clean_range) |
339 | bic r0, r0, #CACHELINESIZE - 1 | 339 | bic r0, r0, #CACHELINESIZE - 1 |
340 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 340 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
341 | add r0, r0, #CACHELINESIZE | 341 | add r0, r0, #CACHELINESIZE |
342 | cmp r0, r1 | 342 | cmp r0, r1 |
343 | blo 1b | 343 | blo 1b |
344 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 344 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
345 | mov pc, lr | 345 | mov pc, lr |
346 | 346 | ||
347 | /* | 347 | /* |
348 | * dma_flush_range(start, end) | 348 | * dma_flush_range(start, end) |
349 | * | 349 | * |
350 | * Clean and invalidate the specified virtual address range. | 350 | * Clean and invalidate the specified virtual address range. |
351 | * | 351 | * |
352 | * - start - virtual start address | 352 | * - start - virtual start address |
353 | * - end - virtual end address | 353 | * - end - virtual end address |
354 | */ | 354 | */ |
355 | ENTRY(xscale_dma_flush_range) | 355 | ENTRY(xscale_dma_flush_range) |
356 | bic r0, r0, #CACHELINESIZE - 1 | 356 | bic r0, r0, #CACHELINESIZE - 1 |
357 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 357 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
358 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry | 358 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry |
359 | add r0, r0, #CACHELINESIZE | 359 | add r0, r0, #CACHELINESIZE |
360 | cmp r0, r1 | 360 | cmp r0, r1 |
361 | blo 1b | 361 | blo 1b |
362 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 362 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
363 | mov pc, lr | 363 | mov pc, lr |
364 | 364 | ||
365 | ENTRY(xscale_cache_fns) | 365 | ENTRY(xscale_cache_fns) |
366 | .long xscale_flush_kern_cache_all | 366 | .long xscale_flush_kern_cache_all |
367 | .long xscale_flush_user_cache_all | 367 | .long xscale_flush_user_cache_all |
368 | .long xscale_flush_user_cache_range | 368 | .long xscale_flush_user_cache_range |
369 | .long xscale_coherent_kern_range | 369 | .long xscale_coherent_kern_range |
370 | .long xscale_coherent_user_range | 370 | .long xscale_coherent_user_range |
371 | .long xscale_flush_kern_dcache_page | 371 | .long xscale_flush_kern_dcache_page |
372 | .long xscale_dma_inv_range | 372 | .long xscale_dma_inv_range |
373 | .long xscale_dma_clean_range | 373 | .long xscale_dma_clean_range |
374 | .long xscale_dma_flush_range | 374 | .long xscale_dma_flush_range |
375 | 375 | ||
376 | /* | 376 | /* |
377 | * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't | 377 | * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't |
378 | * clear the dirty bits, which means that if we invalidate a dirty line, | 378 | * clear the dirty bits, which means that if we invalidate a dirty line, |
379 | * the dirty data can still be written back to external memory later on. | 379 | * the dirty data can still be written back to external memory later on. |
380 | * | 380 | * |
381 | * The recommended workaround is to always do a clean D-cache line before | 381 | * The recommended workaround is to always do a clean D-cache line before |
382 | * doing an invalidate D-cache line, so on the affected processors, | 382 | * doing an invalidate D-cache line, so on the affected processors, |
383 | * dma_inv_range() is implemented as dma_flush_range(). | 383 | * dma_inv_range() is implemented as dma_flush_range(). |
384 | * | 384 | * |
385 | * See erratum #25 of "Intel 80200 Processor Specification Update", | 385 | * See erratum #25 of "Intel 80200 Processor Specification Update", |
386 | * revision January 22, 2003, available at: | 386 | * revision January 22, 2003, available at: |
387 | * http://www.intel.com/design/iio/specupdt/273415.htm | 387 | * http://www.intel.com/design/iio/specupdt/273415.htm |
388 | */ | 388 | */ |
389 | ENTRY(xscale_80200_A0_A1_cache_fns) | 389 | ENTRY(xscale_80200_A0_A1_cache_fns) |
390 | .long xscale_flush_kern_cache_all | 390 | .long xscale_flush_kern_cache_all |
391 | .long xscale_flush_user_cache_all | 391 | .long xscale_flush_user_cache_all |
392 | .long xscale_flush_user_cache_range | 392 | .long xscale_flush_user_cache_range |
393 | .long xscale_coherent_kern_range | 393 | .long xscale_coherent_kern_range |
394 | .long xscale_coherent_user_range | 394 | .long xscale_coherent_user_range |
395 | .long xscale_flush_kern_dcache_page | 395 | .long xscale_flush_kern_dcache_page |
396 | .long xscale_dma_flush_range | 396 | .long xscale_dma_flush_range |
397 | .long xscale_dma_clean_range | 397 | .long xscale_dma_clean_range |
398 | .long xscale_dma_flush_range | 398 | .long xscale_dma_flush_range |
399 | 399 | ||
400 | ENTRY(cpu_xscale_dcache_clean_area) | 400 | ENTRY(cpu_xscale_dcache_clean_area) |
401 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 401 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
402 | add r0, r0, #CACHELINESIZE | 402 | add r0, r0, #CACHELINESIZE |
403 | subs r1, r1, #CACHELINESIZE | 403 | subs r1, r1, #CACHELINESIZE |
404 | bhi 1b | 404 | bhi 1b |
405 | mov pc, lr | 405 | mov pc, lr |
406 | 406 | ||
407 | /* =============================== PageTable ============================== */ | 407 | /* =============================== PageTable ============================== */ |
408 | 408 | ||
409 | /* | 409 | /* |
410 | * cpu_xscale_switch_mm(pgd) | 410 | * cpu_xscale_switch_mm(pgd) |
411 | * | 411 | * |
412 | * Set the translation base pointer to be as described by pgd. | 412 | * Set the translation base pointer to be as described by pgd. |
413 | * | 413 | * |
414 | * pgd: new page tables | 414 | * pgd: new page tables |
415 | */ | 415 | */ |
416 | .align 5 | 416 | .align 5 |
417 | ENTRY(cpu_xscale_switch_mm) | 417 | ENTRY(cpu_xscale_switch_mm) |
418 | clean_d_cache r1, r2 | 418 | clean_d_cache r1, r2 |
419 | mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB | 419 | mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB |
420 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | 420 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer |
421 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | 421 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer |
422 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | 422 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
423 | cpwait_ret lr, ip | 423 | cpwait_ret lr, ip |
424 | 424 | ||
425 | /* | 425 | /* |
426 | * cpu_xscale_set_pte_ext(ptep, pte, ext) | 426 | * cpu_xscale_set_pte_ext(ptep, pte, ext) |
427 | * | 427 | * |
428 | * Set a PTE and flush it out | 428 | * Set a PTE and flush it out |
429 | * | 429 | * |
430 | * Errata 40: must set memory to write-through for user read-only pages. | 430 | * Errata 40: must set memory to write-through for user read-only pages. |
431 | */ | 431 | */ |
432 | cpu_xscale_mt_table: | 432 | cpu_xscale_mt_table: |
433 | .long 0x00 @ L_PTE_MT_UNCACHED | 433 | .long 0x00 @ L_PTE_MT_UNCACHED |
434 | .long PTE_BUFFERABLE @ L_PTE_MT_BUFFERABLE | 434 | .long PTE_BUFFERABLE @ L_PTE_MT_BUFFERABLE |
435 | .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH | 435 | .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH |
436 | .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK | 436 | .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK |
437 | .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED | 437 | .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED |
438 | .long 0x00 @ unused | 438 | .long 0x00 @ unused |
439 | .long PTE_EXT_TEX(1) | PTE_CACHEABLE @ L_PTE_MT_MINICACHE | 439 | .long PTE_EXT_TEX(1) | PTE_CACHEABLE @ L_PTE_MT_MINICACHE |
440 | .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC | 440 | .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC |
441 | .long 0x00 @ unused | 441 | .long 0x00 @ unused |
442 | .long PTE_BUFFERABLE @ L_PTE_MT_DEV_WC | 442 | .long PTE_BUFFERABLE @ L_PTE_MT_DEV_WC |
443 | .long 0x00 @ unused | 443 | .long 0x00 @ unused |
444 | .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED | 444 | .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED |
445 | .long 0x00 @ L_PTE_MT_DEV_NONSHARED | 445 | .long 0x00 @ L_PTE_MT_DEV_NONSHARED |
446 | .long 0x00 @ unused | 446 | .long 0x00 @ unused |
447 | .long 0x00 @ unused | 447 | .long 0x00 @ unused |
448 | .long 0x00 @ unused | 448 | .long 0x00 @ unused |
449 | 449 | ||
450 | .align 5 | 450 | .align 5 |
451 | ENTRY(cpu_xscale_set_pte_ext) | 451 | ENTRY(cpu_xscale_set_pte_ext) |
452 | xscale_set_pte_ext_prologue | 452 | xscale_set_pte_ext_prologue |
453 | 453 | ||
454 | @ | 454 | @ |
455 | @ Erratum 40: must set memory to write-through for user read-only pages | 455 | @ Erratum 40: must set memory to write-through for user read-only pages |
456 | @ | 456 | @ |
457 | and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2) | 457 | and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2) |
458 | teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER | 458 | teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER |
459 | 459 | ||
460 | moveq r1, #L_PTE_MT_WRITETHROUGH | 460 | moveq r1, #L_PTE_MT_WRITETHROUGH |
461 | and r1, r1, #L_PTE_MT_MASK | 461 | and r1, r1, #L_PTE_MT_MASK |
462 | adr ip, cpu_xscale_mt_table | 462 | adr ip, cpu_xscale_mt_table |
463 | ldr ip, [ip, r1] | 463 | ldr ip, [ip, r1] |
464 | bic r2, r2, #0x0c | 464 | bic r2, r2, #0x0c |
465 | orr r2, r2, ip | 465 | orr r2, r2, ip |
466 | 466 | ||
467 | xscale_set_pte_ext_epilogue | 467 | xscale_set_pte_ext_epilogue |
468 | mov pc, lr | 468 | mov pc, lr |
469 | 469 | ||
470 | 470 | ||
471 | .ltorg | 471 | .ltorg |
472 | 472 | ||
473 | .align | 473 | .align |
474 | 474 | ||
475 | __INIT | 475 | __INIT |
476 | 476 | ||
477 | .type __xscale_setup, #function | 477 | .type __xscale_setup, #function |
478 | __xscale_setup: | 478 | __xscale_setup: |
479 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB | 479 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB |
480 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | 480 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer |
481 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs | 481 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs |
482 | mov r0, #1 << 6 @ cp6 for IOP3xx and Bulverde | 482 | mov r0, #1 << 6 @ cp6 for IOP3xx and Bulverde |
483 | orr r0, r0, #1 << 13 @ Its undefined whether this | 483 | orr r0, r0, #1 << 13 @ Its undefined whether this |
484 | mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes | 484 | mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes |
485 | 485 | ||
486 | adr r5, xscale_crval | 486 | adr r5, xscale_crval |
487 | ldmia r5, {r5, r6} | 487 | ldmia r5, {r5, r6} |
488 | mrc p15, 0, r0, c1, c0, 0 @ get control register | 488 | mrc p15, 0, r0, c1, c0, 0 @ get control register |
489 | bic r0, r0, r5 | 489 | bic r0, r0, r5 |
490 | orr r0, r0, r6 | 490 | orr r0, r0, r6 |
491 | mov pc, lr | 491 | mov pc, lr |
492 | .size __xscale_setup, . - __xscale_setup | 492 | .size __xscale_setup, . - __xscale_setup |
493 | 493 | ||
494 | /* | 494 | /* |
495 | * R | 495 | * R |
496 | * .RVI ZFRS BLDP WCAM | 496 | * .RVI ZFRS BLDP WCAM |
497 | * ..11 1.01 .... .101 | 497 | * ..11 1.01 .... .101 |
498 | * | 498 | * |
499 | */ | 499 | */ |
500 | .type xscale_crval, #object | 500 | .type xscale_crval, #object |
501 | xscale_crval: | 501 | xscale_crval: |
502 | crval clear=0x00003b07, mmuset=0x00003905, ucset=0x00001900 | 502 | crval clear=0x00003b07, mmuset=0x00003905, ucset=0x00001900 |
503 | 503 | ||
504 | __INITDATA | 504 | __INITDATA |
505 | 505 | ||
506 | /* | 506 | /* |
507 | * Purpose : Function pointers used to access above functions - all calls | 507 | * Purpose : Function pointers used to access above functions - all calls |
508 | * come through these | 508 | * come through these |
509 | */ | 509 | */ |
510 | 510 | ||
511 | .type xscale_processor_functions, #object | 511 | .type xscale_processor_functions, #object |
512 | ENTRY(xscale_processor_functions) | 512 | ENTRY(xscale_processor_functions) |
513 | .word v5t_early_abort | 513 | .word v5t_early_abort |
514 | .word pabort_noifar | 514 | .word pabort_noifar |
515 | .word cpu_xscale_proc_init | 515 | .word cpu_xscale_proc_init |
516 | .word cpu_xscale_proc_fin | 516 | .word cpu_xscale_proc_fin |
517 | .word cpu_xscale_reset | 517 | .word cpu_xscale_reset |
518 | .word cpu_xscale_do_idle | 518 | .word cpu_xscale_do_idle |
519 | .word cpu_xscale_dcache_clean_area | 519 | .word cpu_xscale_dcache_clean_area |
520 | .word cpu_xscale_switch_mm | 520 | .word cpu_xscale_switch_mm |
521 | .word cpu_xscale_set_pte_ext | 521 | .word cpu_xscale_set_pte_ext |
522 | .size xscale_processor_functions, . - xscale_processor_functions | 522 | .size xscale_processor_functions, . - xscale_processor_functions |
523 | 523 | ||
524 | .section ".rodata" | 524 | .section ".rodata" |
525 | 525 | ||
526 | .type cpu_arch_name, #object | 526 | .type cpu_arch_name, #object |
527 | cpu_arch_name: | 527 | cpu_arch_name: |
528 | .asciz "armv5te" | 528 | .asciz "armv5te" |
529 | .size cpu_arch_name, . - cpu_arch_name | 529 | .size cpu_arch_name, . - cpu_arch_name |
530 | 530 | ||
531 | .type cpu_elf_name, #object | 531 | .type cpu_elf_name, #object |
532 | cpu_elf_name: | 532 | cpu_elf_name: |
533 | .asciz "v5" | 533 | .asciz "v5" |
534 | .size cpu_elf_name, . - cpu_elf_name | 534 | .size cpu_elf_name, . - cpu_elf_name |
535 | 535 | ||
536 | .type cpu_80200_A0_A1_name, #object | 536 | .type cpu_80200_A0_A1_name, #object |
537 | cpu_80200_A0_A1_name: | 537 | cpu_80200_A0_A1_name: |
538 | .asciz "XScale-80200 A0/A1" | 538 | .asciz "XScale-80200 A0/A1" |
539 | .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name | 539 | .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name |
540 | 540 | ||
541 | .type cpu_80200_name, #object | 541 | .type cpu_80200_name, #object |
542 | cpu_80200_name: | 542 | cpu_80200_name: |
543 | .asciz "XScale-80200" | 543 | .asciz "XScale-80200" |
544 | .size cpu_80200_name, . - cpu_80200_name | 544 | .size cpu_80200_name, . - cpu_80200_name |
545 | 545 | ||
546 | .type cpu_80219_name, #object | 546 | .type cpu_80219_name, #object |
547 | cpu_80219_name: | 547 | cpu_80219_name: |
548 | .asciz "XScale-80219" | 548 | .asciz "XScale-80219" |
549 | .size cpu_80219_name, . - cpu_80219_name | 549 | .size cpu_80219_name, . - cpu_80219_name |
550 | 550 | ||
551 | .type cpu_8032x_name, #object | 551 | .type cpu_8032x_name, #object |
552 | cpu_8032x_name: | 552 | cpu_8032x_name: |
553 | .asciz "XScale-IOP8032x Family" | 553 | .asciz "XScale-IOP8032x Family" |
554 | .size cpu_8032x_name, . - cpu_8032x_name | 554 | .size cpu_8032x_name, . - cpu_8032x_name |
555 | 555 | ||
556 | .type cpu_8033x_name, #object | 556 | .type cpu_8033x_name, #object |
557 | cpu_8033x_name: | 557 | cpu_8033x_name: |
558 | .asciz "XScale-IOP8033x Family" | 558 | .asciz "XScale-IOP8033x Family" |
559 | .size cpu_8033x_name, . - cpu_8033x_name | 559 | .size cpu_8033x_name, . - cpu_8033x_name |
560 | 560 | ||
561 | .type cpu_pxa250_name, #object | 561 | .type cpu_pxa250_name, #object |
562 | cpu_pxa250_name: | 562 | cpu_pxa250_name: |
563 | .asciz "XScale-PXA250" | 563 | .asciz "XScale-PXA250" |
564 | .size cpu_pxa250_name, . - cpu_pxa250_name | 564 | .size cpu_pxa250_name, . - cpu_pxa250_name |
565 | 565 | ||
566 | .type cpu_pxa210_name, #object | 566 | .type cpu_pxa210_name, #object |
567 | cpu_pxa210_name: | 567 | cpu_pxa210_name: |
568 | .asciz "XScale-PXA210" | 568 | .asciz "XScale-PXA210" |
569 | .size cpu_pxa210_name, . - cpu_pxa210_name | 569 | .size cpu_pxa210_name, . - cpu_pxa210_name |
570 | 570 | ||
571 | .type cpu_ixp42x_name, #object | 571 | .type cpu_ixp42x_name, #object |
572 | cpu_ixp42x_name: | 572 | cpu_ixp42x_name: |
573 | .asciz "XScale-IXP42x Family" | 573 | .asciz "XScale-IXP42x Family" |
574 | .size cpu_ixp42x_name, . - cpu_ixp42x_name | 574 | .size cpu_ixp42x_name, . - cpu_ixp42x_name |
575 | 575 | ||
576 | .type cpu_ixp43x_name, #object | 576 | .type cpu_ixp43x_name, #object |
577 | cpu_ixp43x_name: | 577 | cpu_ixp43x_name: |
578 | .asciz "XScale-IXP43x Family" | 578 | .asciz "XScale-IXP43x Family" |
579 | .size cpu_ixp43x_name, . - cpu_ixp43x_name | 579 | .size cpu_ixp43x_name, . - cpu_ixp43x_name |
580 | 580 | ||
581 | .type cpu_ixp46x_name, #object | 581 | .type cpu_ixp46x_name, #object |
582 | cpu_ixp46x_name: | 582 | cpu_ixp46x_name: |
583 | .asciz "XScale-IXP46x Family" | 583 | .asciz "XScale-IXP46x Family" |
584 | .size cpu_ixp46x_name, . - cpu_ixp46x_name | 584 | .size cpu_ixp46x_name, . - cpu_ixp46x_name |
585 | 585 | ||
586 | .type cpu_ixp2400_name, #object | 586 | .type cpu_ixp2400_name, #object |
587 | cpu_ixp2400_name: | 587 | cpu_ixp2400_name: |
588 | .asciz "XScale-IXP2400" | 588 | .asciz "XScale-IXP2400" |
589 | .size cpu_ixp2400_name, . - cpu_ixp2400_name | 589 | .size cpu_ixp2400_name, . - cpu_ixp2400_name |
590 | 590 | ||
591 | .type cpu_ixp2800_name, #object | 591 | .type cpu_ixp2800_name, #object |
592 | cpu_ixp2800_name: | 592 | cpu_ixp2800_name: |
593 | .asciz "XScale-IXP2800" | 593 | .asciz "XScale-IXP2800" |
594 | .size cpu_ixp2800_name, . - cpu_ixp2800_name | 594 | .size cpu_ixp2800_name, . - cpu_ixp2800_name |
595 | 595 | ||
596 | .type cpu_pxa255_name, #object | 596 | .type cpu_pxa255_name, #object |
597 | cpu_pxa255_name: | 597 | cpu_pxa255_name: |
598 | .asciz "XScale-PXA255" | 598 | .asciz "XScale-PXA255" |
599 | .size cpu_pxa255_name, . - cpu_pxa255_name | 599 | .size cpu_pxa255_name, . - cpu_pxa255_name |
600 | 600 | ||
601 | .type cpu_pxa270_name, #object | 601 | .type cpu_pxa270_name, #object |
602 | cpu_pxa270_name: | 602 | cpu_pxa270_name: |
603 | .asciz "XScale-PXA270" | 603 | .asciz "XScale-PXA270" |
604 | .size cpu_pxa270_name, . - cpu_pxa270_name | 604 | .size cpu_pxa270_name, . - cpu_pxa270_name |
605 | 605 | ||
606 | .align | 606 | .align |
607 | 607 | ||
608 | .section ".proc.info.init", #alloc, #execinstr | 608 | .section ".proc.info.init", #alloc, #execinstr |
609 | 609 | ||
610 | .type __80200_A0_A1_proc_info,#object | 610 | .type __80200_A0_A1_proc_info,#object |
611 | __80200_A0_A1_proc_info: | 611 | __80200_A0_A1_proc_info: |
612 | .long 0x69052000 | 612 | .long 0x69052000 |
613 | .long 0xfffffffe | 613 | .long 0xfffffffe |
614 | .long PMD_TYPE_SECT | \ | 614 | .long PMD_TYPE_SECT | \ |
615 | PMD_SECT_BUFFERABLE | \ | 615 | PMD_SECT_BUFFERABLE | \ |
616 | PMD_SECT_CACHEABLE | \ | 616 | PMD_SECT_CACHEABLE | \ |
617 | PMD_SECT_AP_WRITE | \ | 617 | PMD_SECT_AP_WRITE | \ |
618 | PMD_SECT_AP_READ | 618 | PMD_SECT_AP_READ |
619 | .long PMD_TYPE_SECT | \ | 619 | .long PMD_TYPE_SECT | \ |
620 | PMD_SECT_AP_WRITE | \ | 620 | PMD_SECT_AP_WRITE | \ |
621 | PMD_SECT_AP_READ | 621 | PMD_SECT_AP_READ |
622 | b __xscale_setup | 622 | b __xscale_setup |
623 | .long cpu_arch_name | 623 | .long cpu_arch_name |
624 | .long cpu_elf_name | 624 | .long cpu_elf_name |
625 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 625 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
626 | .long cpu_80200_name | 626 | .long cpu_80200_name |
627 | .long xscale_processor_functions | 627 | .long xscale_processor_functions |
628 | .long v4wbi_tlb_fns | 628 | .long v4wbi_tlb_fns |
629 | .long xscale_mc_user_fns | 629 | .long xscale_mc_user_fns |
630 | .long xscale_80200_A0_A1_cache_fns | 630 | .long xscale_80200_A0_A1_cache_fns |
631 | .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info | 631 | .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info |
632 | 632 | ||
633 | .type __80200_proc_info,#object | 633 | .type __80200_proc_info,#object |
634 | __80200_proc_info: | 634 | __80200_proc_info: |
635 | .long 0x69052000 | 635 | .long 0x69052000 |
636 | .long 0xfffffff0 | 636 | .long 0xfffffff0 |
637 | .long PMD_TYPE_SECT | \ | 637 | .long PMD_TYPE_SECT | \ |
638 | PMD_SECT_BUFFERABLE | \ | 638 | PMD_SECT_BUFFERABLE | \ |
639 | PMD_SECT_CACHEABLE | \ | 639 | PMD_SECT_CACHEABLE | \ |
640 | PMD_SECT_AP_WRITE | \ | 640 | PMD_SECT_AP_WRITE | \ |
641 | PMD_SECT_AP_READ | 641 | PMD_SECT_AP_READ |
642 | .long PMD_TYPE_SECT | \ | 642 | .long PMD_TYPE_SECT | \ |
643 | PMD_SECT_AP_WRITE | \ | 643 | PMD_SECT_AP_WRITE | \ |
644 | PMD_SECT_AP_READ | 644 | PMD_SECT_AP_READ |
645 | b __xscale_setup | 645 | b __xscale_setup |
646 | .long cpu_arch_name | 646 | .long cpu_arch_name |
647 | .long cpu_elf_name | 647 | .long cpu_elf_name |
648 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 648 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
649 | .long cpu_80200_name | 649 | .long cpu_80200_name |
650 | .long xscale_processor_functions | 650 | .long xscale_processor_functions |
651 | .long v4wbi_tlb_fns | 651 | .long v4wbi_tlb_fns |
652 | .long xscale_mc_user_fns | 652 | .long xscale_mc_user_fns |
653 | .long xscale_cache_fns | 653 | .long xscale_cache_fns |
654 | .size __80200_proc_info, . - __80200_proc_info | 654 | .size __80200_proc_info, . - __80200_proc_info |
655 | 655 | ||
656 | .type __80219_proc_info,#object | 656 | .type __80219_proc_info,#object |
657 | __80219_proc_info: | 657 | __80219_proc_info: |
658 | .long 0x69052e20 | 658 | .long 0x69052e20 |
659 | .long 0xffffffe0 | 659 | .long 0xffffffe0 |
660 | .long PMD_TYPE_SECT | \ | 660 | .long PMD_TYPE_SECT | \ |
661 | PMD_SECT_BUFFERABLE | \ | 661 | PMD_SECT_BUFFERABLE | \ |
662 | PMD_SECT_CACHEABLE | \ | 662 | PMD_SECT_CACHEABLE | \ |
663 | PMD_SECT_AP_WRITE | \ | 663 | PMD_SECT_AP_WRITE | \ |
664 | PMD_SECT_AP_READ | 664 | PMD_SECT_AP_READ |
665 | .long PMD_TYPE_SECT | \ | 665 | .long PMD_TYPE_SECT | \ |
666 | PMD_SECT_AP_WRITE | \ | 666 | PMD_SECT_AP_WRITE | \ |
667 | PMD_SECT_AP_READ | 667 | PMD_SECT_AP_READ |
668 | b __xscale_setup | 668 | b __xscale_setup |
669 | .long cpu_arch_name | 669 | .long cpu_arch_name |
670 | .long cpu_elf_name | 670 | .long cpu_elf_name |
671 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 671 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
672 | .long cpu_80219_name | 672 | .long cpu_80219_name |
673 | .long xscale_processor_functions | 673 | .long xscale_processor_functions |
674 | .long v4wbi_tlb_fns | 674 | .long v4wbi_tlb_fns |
675 | .long xscale_mc_user_fns | 675 | .long xscale_mc_user_fns |
676 | .long xscale_cache_fns | 676 | .long xscale_cache_fns |
677 | .size __80219_proc_info, . - __80219_proc_info | 677 | .size __80219_proc_info, . - __80219_proc_info |
678 | 678 | ||
679 | .type __8032x_proc_info,#object | 679 | .type __8032x_proc_info,#object |
680 | __8032x_proc_info: | 680 | __8032x_proc_info: |
681 | .long 0x69052420 | 681 | .long 0x69052420 |
682 | .long 0xfffff7e0 | 682 | .long 0xfffff7e0 |
683 | .long PMD_TYPE_SECT | \ | 683 | .long PMD_TYPE_SECT | \ |
684 | PMD_SECT_BUFFERABLE | \ | 684 | PMD_SECT_BUFFERABLE | \ |
685 | PMD_SECT_CACHEABLE | \ | 685 | PMD_SECT_CACHEABLE | \ |
686 | PMD_SECT_AP_WRITE | \ | 686 | PMD_SECT_AP_WRITE | \ |
687 | PMD_SECT_AP_READ | 687 | PMD_SECT_AP_READ |
688 | .long PMD_TYPE_SECT | \ | 688 | .long PMD_TYPE_SECT | \ |
689 | PMD_SECT_AP_WRITE | \ | 689 | PMD_SECT_AP_WRITE | \ |
690 | PMD_SECT_AP_READ | 690 | PMD_SECT_AP_READ |
691 | b __xscale_setup | 691 | b __xscale_setup |
692 | .long cpu_arch_name | 692 | .long cpu_arch_name |
693 | .long cpu_elf_name | 693 | .long cpu_elf_name |
694 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 694 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
695 | .long cpu_8032x_name | 695 | .long cpu_8032x_name |
696 | .long xscale_processor_functions | 696 | .long xscale_processor_functions |
697 | .long v4wbi_tlb_fns | 697 | .long v4wbi_tlb_fns |
698 | .long xscale_mc_user_fns | 698 | .long xscale_mc_user_fns |
699 | .long xscale_cache_fns | 699 | .long xscale_cache_fns |
700 | .size __8032x_proc_info, . - __8032x_proc_info | 700 | .size __8032x_proc_info, . - __8032x_proc_info |
701 | 701 | ||
702 | .type __8033x_proc_info,#object | 702 | .type __8033x_proc_info,#object |
703 | __8033x_proc_info: | 703 | __8033x_proc_info: |
704 | .long 0x69054010 | 704 | .long 0x69054010 |
705 | .long 0xfffffd30 | 705 | .long 0xfffffd30 |
706 | .long PMD_TYPE_SECT | \ | 706 | .long PMD_TYPE_SECT | \ |
707 | PMD_SECT_BUFFERABLE | \ | 707 | PMD_SECT_BUFFERABLE | \ |
708 | PMD_SECT_CACHEABLE | \ | 708 | PMD_SECT_CACHEABLE | \ |
709 | PMD_SECT_AP_WRITE | \ | 709 | PMD_SECT_AP_WRITE | \ |
710 | PMD_SECT_AP_READ | 710 | PMD_SECT_AP_READ |
711 | .long PMD_TYPE_SECT | \ | 711 | .long PMD_TYPE_SECT | \ |
712 | PMD_SECT_AP_WRITE | \ | 712 | PMD_SECT_AP_WRITE | \ |
713 | PMD_SECT_AP_READ | 713 | PMD_SECT_AP_READ |
714 | b __xscale_setup | 714 | b __xscale_setup |
715 | .long cpu_arch_name | 715 | .long cpu_arch_name |
716 | .long cpu_elf_name | 716 | .long cpu_elf_name |
717 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 717 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
718 | .long cpu_8033x_name | 718 | .long cpu_8033x_name |
719 | .long xscale_processor_functions | 719 | .long xscale_processor_functions |
720 | .long v4wbi_tlb_fns | 720 | .long v4wbi_tlb_fns |
721 | .long xscale_mc_user_fns | 721 | .long xscale_mc_user_fns |
722 | .long xscale_cache_fns | 722 | .long xscale_cache_fns |
723 | .size __8033x_proc_info, . - __8033x_proc_info | 723 | .size __8033x_proc_info, . - __8033x_proc_info |
724 | 724 | ||
725 | .type __pxa250_proc_info,#object | 725 | .type __pxa250_proc_info,#object |
726 | __pxa250_proc_info: | 726 | __pxa250_proc_info: |
727 | .long 0x69052100 | 727 | .long 0x69052100 |
728 | .long 0xfffff7f0 | 728 | .long 0xfffff7f0 |
729 | .long PMD_TYPE_SECT | \ | 729 | .long PMD_TYPE_SECT | \ |
730 | PMD_SECT_BUFFERABLE | \ | 730 | PMD_SECT_BUFFERABLE | \ |
731 | PMD_SECT_CACHEABLE | \ | 731 | PMD_SECT_CACHEABLE | \ |
732 | PMD_SECT_AP_WRITE | \ | 732 | PMD_SECT_AP_WRITE | \ |
733 | PMD_SECT_AP_READ | 733 | PMD_SECT_AP_READ |
734 | .long PMD_TYPE_SECT | \ | 734 | .long PMD_TYPE_SECT | \ |
735 | PMD_SECT_AP_WRITE | \ | 735 | PMD_SECT_AP_WRITE | \ |
736 | PMD_SECT_AP_READ | 736 | PMD_SECT_AP_READ |
737 | b __xscale_setup | 737 | b __xscale_setup |
738 | .long cpu_arch_name | 738 | .long cpu_arch_name |
739 | .long cpu_elf_name | 739 | .long cpu_elf_name |
740 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 740 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
741 | .long cpu_pxa250_name | 741 | .long cpu_pxa250_name |
742 | .long xscale_processor_functions | 742 | .long xscale_processor_functions |
743 | .long v4wbi_tlb_fns | 743 | .long v4wbi_tlb_fns |
744 | .long xscale_mc_user_fns | 744 | .long xscale_mc_user_fns |
745 | .long xscale_cache_fns | 745 | .long xscale_cache_fns |
746 | .size __pxa250_proc_info, . - __pxa250_proc_info | 746 | .size __pxa250_proc_info, . - __pxa250_proc_info |
747 | 747 | ||
748 | .type __pxa210_proc_info,#object | 748 | .type __pxa210_proc_info,#object |
749 | __pxa210_proc_info: | 749 | __pxa210_proc_info: |
750 | .long 0x69052120 | 750 | .long 0x69052120 |
751 | .long 0xfffff3f0 | 751 | .long 0xfffff3f0 |
752 | .long PMD_TYPE_SECT | \ | 752 | .long PMD_TYPE_SECT | \ |
753 | PMD_SECT_BUFFERABLE | \ | 753 | PMD_SECT_BUFFERABLE | \ |
754 | PMD_SECT_CACHEABLE | \ | 754 | PMD_SECT_CACHEABLE | \ |
755 | PMD_SECT_AP_WRITE | \ | 755 | PMD_SECT_AP_WRITE | \ |
756 | PMD_SECT_AP_READ | 756 | PMD_SECT_AP_READ |
757 | .long PMD_TYPE_SECT | \ | 757 | .long PMD_TYPE_SECT | \ |
758 | PMD_SECT_AP_WRITE | \ | 758 | PMD_SECT_AP_WRITE | \ |
759 | PMD_SECT_AP_READ | 759 | PMD_SECT_AP_READ |
760 | b __xscale_setup | 760 | b __xscale_setup |
761 | .long cpu_arch_name | 761 | .long cpu_arch_name |
762 | .long cpu_elf_name | 762 | .long cpu_elf_name |
763 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 763 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
764 | .long cpu_pxa210_name | 764 | .long cpu_pxa210_name |
765 | .long xscale_processor_functions | 765 | .long xscale_processor_functions |
766 | .long v4wbi_tlb_fns | 766 | .long v4wbi_tlb_fns |
767 | .long xscale_mc_user_fns | 767 | .long xscale_mc_user_fns |
768 | .long xscale_cache_fns | 768 | .long xscale_cache_fns |
769 | .size __pxa210_proc_info, . - __pxa210_proc_info | 769 | .size __pxa210_proc_info, . - __pxa210_proc_info |
770 | 770 | ||
771 | .type __ixp2400_proc_info, #object | 771 | .type __ixp2400_proc_info, #object |
772 | __ixp2400_proc_info: | 772 | __ixp2400_proc_info: |
773 | .long 0x69054190 | 773 | .long 0x69054190 |
774 | .long 0xfffffff0 | 774 | .long 0xfffffff0 |
775 | .long PMD_TYPE_SECT | \ | 775 | .long PMD_TYPE_SECT | \ |
776 | PMD_SECT_BUFFERABLE | \ | 776 | PMD_SECT_BUFFERABLE | \ |
777 | PMD_SECT_CACHEABLE | \ | 777 | PMD_SECT_CACHEABLE | \ |
778 | PMD_SECT_AP_WRITE | \ | 778 | PMD_SECT_AP_WRITE | \ |
779 | PMD_SECT_AP_READ | 779 | PMD_SECT_AP_READ |
780 | .long PMD_TYPE_SECT | \ | 780 | .long PMD_TYPE_SECT | \ |
781 | PMD_SECT_AP_WRITE | \ | 781 | PMD_SECT_AP_WRITE | \ |
782 | PMD_SECT_AP_READ | 782 | PMD_SECT_AP_READ |
783 | b __xscale_setup | 783 | b __xscale_setup |
784 | .long cpu_arch_name | 784 | .long cpu_arch_name |
785 | .long cpu_elf_name | 785 | .long cpu_elf_name |
786 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 786 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
787 | .long cpu_ixp2400_name | 787 | .long cpu_ixp2400_name |
788 | .long xscale_processor_functions | 788 | .long xscale_processor_functions |
789 | .long v4wbi_tlb_fns | 789 | .long v4wbi_tlb_fns |
790 | .long xscale_mc_user_fns | 790 | .long xscale_mc_user_fns |
791 | .long xscale_cache_fns | 791 | .long xscale_cache_fns |
792 | .size __ixp2400_proc_info, . - __ixp2400_proc_info | 792 | .size __ixp2400_proc_info, . - __ixp2400_proc_info |
793 | 793 | ||
794 | .type __ixp2800_proc_info, #object | 794 | .type __ixp2800_proc_info, #object |
795 | __ixp2800_proc_info: | 795 | __ixp2800_proc_info: |
796 | .long 0x690541a0 | 796 | .long 0x690541a0 |
797 | .long 0xfffffff0 | 797 | .long 0xfffffff0 |
798 | .long PMD_TYPE_SECT | \ | 798 | .long PMD_TYPE_SECT | \ |
799 | PMD_SECT_BUFFERABLE | \ | 799 | PMD_SECT_BUFFERABLE | \ |
800 | PMD_SECT_CACHEABLE | \ | 800 | PMD_SECT_CACHEABLE | \ |
801 | PMD_SECT_AP_WRITE | \ | 801 | PMD_SECT_AP_WRITE | \ |
802 | PMD_SECT_AP_READ | 802 | PMD_SECT_AP_READ |
803 | .long PMD_TYPE_SECT | \ | 803 | .long PMD_TYPE_SECT | \ |
804 | PMD_SECT_AP_WRITE | \ | 804 | PMD_SECT_AP_WRITE | \ |
805 | PMD_SECT_AP_READ | 805 | PMD_SECT_AP_READ |
806 | b __xscale_setup | 806 | b __xscale_setup |
807 | .long cpu_arch_name | 807 | .long cpu_arch_name |
808 | .long cpu_elf_name | 808 | .long cpu_elf_name |
809 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 809 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
810 | .long cpu_ixp2800_name | 810 | .long cpu_ixp2800_name |
811 | .long xscale_processor_functions | 811 | .long xscale_processor_functions |
812 | .long v4wbi_tlb_fns | 812 | .long v4wbi_tlb_fns |
813 | .long xscale_mc_user_fns | 813 | .long xscale_mc_user_fns |
814 | .long xscale_cache_fns | 814 | .long xscale_cache_fns |
815 | .size __ixp2800_proc_info, . - __ixp2800_proc_info | 815 | .size __ixp2800_proc_info, . - __ixp2800_proc_info |
816 | 816 | ||
817 | .type __ixp42x_proc_info, #object | 817 | .type __ixp42x_proc_info, #object |
818 | __ixp42x_proc_info: | 818 | __ixp42x_proc_info: |
819 | .long 0x690541c0 | 819 | .long 0x690541c0 |
820 | .long 0xffffffc0 | 820 | .long 0xffffffc0 |
821 | .long PMD_TYPE_SECT | \ | 821 | .long PMD_TYPE_SECT | \ |
822 | PMD_SECT_BUFFERABLE | \ | 822 | PMD_SECT_BUFFERABLE | \ |
823 | PMD_SECT_CACHEABLE | \ | 823 | PMD_SECT_CACHEABLE | \ |
824 | PMD_SECT_AP_WRITE | \ | 824 | PMD_SECT_AP_WRITE | \ |
825 | PMD_SECT_AP_READ | 825 | PMD_SECT_AP_READ |
826 | .long PMD_TYPE_SECT | \ | 826 | .long PMD_TYPE_SECT | \ |
827 | PMD_SECT_AP_WRITE | \ | 827 | PMD_SECT_AP_WRITE | \ |
828 | PMD_SECT_AP_READ | 828 | PMD_SECT_AP_READ |
829 | b __xscale_setup | 829 | b __xscale_setup |
830 | .long cpu_arch_name | 830 | .long cpu_arch_name |
831 | .long cpu_elf_name | 831 | .long cpu_elf_name |
832 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 832 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
833 | .long cpu_ixp42x_name | 833 | .long cpu_ixp42x_name |
834 | .long xscale_processor_functions | 834 | .long xscale_processor_functions |
835 | .long v4wbi_tlb_fns | 835 | .long v4wbi_tlb_fns |
836 | .long xscale_mc_user_fns | 836 | .long xscale_mc_user_fns |
837 | .long xscale_cache_fns | 837 | .long xscale_cache_fns |
838 | .size __ixp42x_proc_info, . - __ixp42x_proc_info | 838 | .size __ixp42x_proc_info, . - __ixp42x_proc_info |
839 | 839 | ||
840 | .type __ixp43x_proc_info, #object | 840 | .type __ixp43x_proc_info, #object |
841 | __ixp43x_proc_info: | 841 | __ixp43x_proc_info: |
842 | .long 0x69054040 | 842 | .long 0x69054040 |
843 | .long 0xfffffff0 | 843 | .long 0xfffffff0 |
844 | .long PMD_TYPE_SECT | \ | 844 | .long PMD_TYPE_SECT | \ |
845 | PMD_SECT_BUFFERABLE | \ | 845 | PMD_SECT_BUFFERABLE | \ |
846 | PMD_SECT_CACHEABLE | \ | 846 | PMD_SECT_CACHEABLE | \ |
847 | PMD_SECT_AP_WRITE | \ | 847 | PMD_SECT_AP_WRITE | \ |
848 | PMD_SECT_AP_READ | 848 | PMD_SECT_AP_READ |
849 | .long PMD_TYPE_SECT | \ | 849 | .long PMD_TYPE_SECT | \ |
850 | PMD_SECT_AP_WRITE | \ | 850 | PMD_SECT_AP_WRITE | \ |
851 | PMD_SECT_AP_READ | 851 | PMD_SECT_AP_READ |
852 | b __xscale_setup | 852 | b __xscale_setup |
853 | .long cpu_arch_name | 853 | .long cpu_arch_name |
854 | .long cpu_elf_name | 854 | .long cpu_elf_name |
855 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 855 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
856 | .long cpu_ixp43x_name | 856 | .long cpu_ixp43x_name |
857 | .long xscale_processor_functions | 857 | .long xscale_processor_functions |
858 | .long v4wbi_tlb_fns | 858 | .long v4wbi_tlb_fns |
859 | .long xscale_mc_user_fns | 859 | .long xscale_mc_user_fns |
860 | .long xscale_cache_fns | 860 | .long xscale_cache_fns |
861 | .size __ixp43x_proc_info, . - __ixp43x_proc_info | 861 | .size __ixp43x_proc_info, . - __ixp43x_proc_info |
862 | 862 | ||
863 | .type __ixp46x_proc_info, #object | 863 | .type __ixp46x_proc_info, #object |
864 | __ixp46x_proc_info: | 864 | __ixp46x_proc_info: |
865 | .long 0x69054200 | 865 | .long 0x69054200 |
866 | .long 0xffffff00 | 866 | .long 0xffffff00 |
867 | .long PMD_TYPE_SECT | \ | 867 | .long PMD_TYPE_SECT | \ |
868 | PMD_SECT_BUFFERABLE | \ | 868 | PMD_SECT_BUFFERABLE | \ |
869 | PMD_SECT_CACHEABLE | \ | 869 | PMD_SECT_CACHEABLE | \ |
870 | PMD_SECT_AP_WRITE | \ | 870 | PMD_SECT_AP_WRITE | \ |
871 | PMD_SECT_AP_READ | 871 | PMD_SECT_AP_READ |
872 | .long PMD_TYPE_SECT | \ | 872 | .long PMD_TYPE_SECT | \ |
873 | PMD_SECT_AP_WRITE | \ | 873 | PMD_SECT_AP_WRITE | \ |
874 | PMD_SECT_AP_READ | 874 | PMD_SECT_AP_READ |
875 | b __xscale_setup | 875 | b __xscale_setup |
876 | .long cpu_arch_name | 876 | .long cpu_arch_name |
877 | .long cpu_elf_name | 877 | .long cpu_elf_name |
878 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 878 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
879 | .long cpu_ixp46x_name | 879 | .long cpu_ixp46x_name |
880 | .long xscale_processor_functions | 880 | .long xscale_processor_functions |
881 | .long v4wbi_tlb_fns | 881 | .long v4wbi_tlb_fns |
882 | .long xscale_mc_user_fns | 882 | .long xscale_mc_user_fns |
883 | .long xscale_cache_fns | 883 | .long xscale_cache_fns |
884 | .size __ixp46x_proc_info, . - __ixp46x_proc_info | 884 | .size __ixp46x_proc_info, . - __ixp46x_proc_info |
885 | 885 | ||
886 | .type __pxa255_proc_info,#object | 886 | .type __pxa255_proc_info,#object |
887 | __pxa255_proc_info: | 887 | __pxa255_proc_info: |
888 | .long 0x69052d00 | 888 | .long 0x69052d00 |
889 | .long 0xfffffff0 | 889 | .long 0xfffffff0 |
890 | .long PMD_TYPE_SECT | \ | 890 | .long PMD_TYPE_SECT | \ |
891 | PMD_SECT_BUFFERABLE | \ | 891 | PMD_SECT_BUFFERABLE | \ |
892 | PMD_SECT_CACHEABLE | \ | 892 | PMD_SECT_CACHEABLE | \ |
893 | PMD_SECT_AP_WRITE | \ | 893 | PMD_SECT_AP_WRITE | \ |
894 | PMD_SECT_AP_READ | 894 | PMD_SECT_AP_READ |
895 | .long PMD_TYPE_SECT | \ | 895 | .long PMD_TYPE_SECT | \ |
896 | PMD_SECT_AP_WRITE | \ | 896 | PMD_SECT_AP_WRITE | \ |
897 | PMD_SECT_AP_READ | 897 | PMD_SECT_AP_READ |
898 | b __xscale_setup | 898 | b __xscale_setup |
899 | .long cpu_arch_name | 899 | .long cpu_arch_name |
900 | .long cpu_elf_name | 900 | .long cpu_elf_name |
901 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 901 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
902 | .long cpu_pxa255_name | 902 | .long cpu_pxa255_name |
903 | .long xscale_processor_functions | 903 | .long xscale_processor_functions |
904 | .long v4wbi_tlb_fns | 904 | .long v4wbi_tlb_fns |
905 | .long xscale_mc_user_fns | 905 | .long xscale_mc_user_fns |
906 | .long xscale_cache_fns | 906 | .long xscale_cache_fns |
907 | .size __pxa255_proc_info, . - __pxa255_proc_info | 907 | .size __pxa255_proc_info, . - __pxa255_proc_info |
908 | 908 | ||
909 | .type __pxa270_proc_info,#object | 909 | .type __pxa270_proc_info,#object |
910 | __pxa270_proc_info: | 910 | __pxa270_proc_info: |
911 | .long 0x69054110 | 911 | .long 0x69054110 |
912 | .long 0xfffffff0 | 912 | .long 0xfffffff0 |
913 | .long PMD_TYPE_SECT | \ | 913 | .long PMD_TYPE_SECT | \ |
914 | PMD_SECT_BUFFERABLE | \ | 914 | PMD_SECT_BUFFERABLE | \ |
915 | PMD_SECT_CACHEABLE | \ | 915 | PMD_SECT_CACHEABLE | \ |
916 | PMD_SECT_AP_WRITE | \ | 916 | PMD_SECT_AP_WRITE | \ |
917 | PMD_SECT_AP_READ | 917 | PMD_SECT_AP_READ |
918 | .long PMD_TYPE_SECT | \ | 918 | .long PMD_TYPE_SECT | \ |
919 | PMD_SECT_AP_WRITE | \ | 919 | PMD_SECT_AP_WRITE | \ |
920 | PMD_SECT_AP_READ | 920 | PMD_SECT_AP_READ |
921 | b __xscale_setup | 921 | b __xscale_setup |
922 | .long cpu_arch_name | 922 | .long cpu_arch_name |
923 | .long cpu_elf_name | 923 | .long cpu_elf_name |
924 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 924 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
925 | .long cpu_pxa270_name | 925 | .long cpu_pxa270_name |
926 | .long xscale_processor_functions | 926 | .long xscale_processor_functions |
927 | .long v4wbi_tlb_fns | 927 | .long v4wbi_tlb_fns |
928 | .long xscale_mc_user_fns | 928 | .long xscale_mc_user_fns |
929 | .long xscale_cache_fns | 929 | .long xscale_cache_fns |
930 | .size __pxa270_proc_info, . - __pxa270_proc_info | 930 | .size __pxa270_proc_info, . - __pxa270_proc_info |
931 | 931 | ||
932 | 932 |
arch/arm/plat-iop/setup.c
1 | /* | 1 | /* |
2 | * arch/arm/plat-iop/setup.c | 2 | * arch/arm/plat-iop/setup.c |
3 | * | 3 | * |
4 | * Author: Nicolas Pitre <nico@cam.org> | 4 | * Author: Nicolas Pitre <nico@fluxnic.net> |
5 | * Copyright (C) 2001 MontaVista Software, Inc. | 5 | * Copyright (C) 2001 MontaVista Software, Inc. |
6 | * Copyright (C) 2004 Intel Corporation. | 6 | * Copyright (C) 2004 Intel Corporation. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <asm/mach/map.h> | 15 | #include <asm/mach/map.h> |
16 | #include <asm/hardware/iop3xx.h> | 16 | #include <asm/hardware/iop3xx.h> |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Standard IO mapping for all IOP3xx based systems. Note that | 19 | * Standard IO mapping for all IOP3xx based systems. Note that |
20 | * the IOP3xx OCCDR must be mapped uncached and unbuffered. | 20 | * the IOP3xx OCCDR must be mapped uncached and unbuffered. |
21 | */ | 21 | */ |
22 | static struct map_desc iop3xx_std_desc[] __initdata = { | 22 | static struct map_desc iop3xx_std_desc[] __initdata = { |
23 | { /* mem mapped registers */ | 23 | { /* mem mapped registers */ |
24 | .virtual = IOP3XX_PERIPHERAL_VIRT_BASE, | 24 | .virtual = IOP3XX_PERIPHERAL_VIRT_BASE, |
25 | .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE), | 25 | .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE), |
26 | .length = IOP3XX_PERIPHERAL_SIZE, | 26 | .length = IOP3XX_PERIPHERAL_SIZE, |
27 | .type = MT_UNCACHED, | 27 | .type = MT_UNCACHED, |
28 | }, { /* PCI IO space */ | 28 | }, { /* PCI IO space */ |
29 | .virtual = IOP3XX_PCI_LOWER_IO_VA, | 29 | .virtual = IOP3XX_PCI_LOWER_IO_VA, |
30 | .pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA), | 30 | .pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA), |
31 | .length = IOP3XX_PCI_IO_WINDOW_SIZE, | 31 | .length = IOP3XX_PCI_IO_WINDOW_SIZE, |
32 | .type = MT_DEVICE, | 32 | .type = MT_DEVICE, |
33 | }, | 33 | }, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | void __init iop3xx_map_io(void) | 36 | void __init iop3xx_map_io(void) |
37 | { | 37 | { |
38 | iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc)); | 38 | iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc)); |
39 | } | 39 | } |
40 | 40 |
arch/arm/plat-omap/include/mach/system.h
1 | /* | 1 | /* |
2 | * Copied from arch/arm/mach-sa1100/include/mach/system.h | 2 | * Copied from arch/arm/mach-sa1100/include/mach/system.h |
3 | * Copyright (c) 1999 Nicolas Pitre <nico@cam.org> | 3 | * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net> |
4 | */ | 4 | */ |
5 | #ifndef __ASM_ARCH_SYSTEM_H | 5 | #ifndef __ASM_ARCH_SYSTEM_H |
6 | #define __ASM_ARCH_SYSTEM_H | 6 | #define __ASM_ARCH_SYSTEM_H |
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | 8 | ||
9 | #include <asm/mach-types.h> | 9 | #include <asm/mach-types.h> |
10 | #include <mach/hardware.h> | 10 | #include <mach/hardware.h> |
11 | 11 | ||
12 | #include <mach/prcm.h> | 12 | #include <mach/prcm.h> |
13 | 13 | ||
14 | #ifndef CONFIG_MACH_VOICEBLUE | 14 | #ifndef CONFIG_MACH_VOICEBLUE |
15 | #define voiceblue_reset() do {} while (0) | 15 | #define voiceblue_reset() do {} while (0) |
16 | #else | 16 | #else |
17 | extern void voiceblue_reset(void); | 17 | extern void voiceblue_reset(void); |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | static inline void arch_idle(void) | 20 | static inline void arch_idle(void) |
21 | { | 21 | { |
22 | cpu_do_idle(); | 22 | cpu_do_idle(); |
23 | } | 23 | } |
24 | 24 | ||
25 | static inline void omap1_arch_reset(char mode) | 25 | static inline void omap1_arch_reset(char mode) |
26 | { | 26 | { |
27 | /* | 27 | /* |
28 | * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 | 28 | * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 |
29 | * "Global Software Reset Affects Traffic Controller Frequency". | 29 | * "Global Software Reset Affects Traffic Controller Frequency". |
30 | */ | 30 | */ |
31 | if (cpu_is_omap5912()) { | 31 | if (cpu_is_omap5912()) { |
32 | omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), | 32 | omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), |
33 | DPLL_CTL); | 33 | DPLL_CTL); |
34 | omap_writew(0x8, ARM_RSTCT1); | 34 | omap_writew(0x8, ARM_RSTCT1); |
35 | } | 35 | } |
36 | 36 | ||
37 | if (machine_is_voiceblue()) | 37 | if (machine_is_voiceblue()) |
38 | voiceblue_reset(); | 38 | voiceblue_reset(); |
39 | else | 39 | else |
40 | omap_writew(1, ARM_RSTCT1); | 40 | omap_writew(1, ARM_RSTCT1); |
41 | } | 41 | } |
42 | 42 | ||
43 | static inline void arch_reset(char mode, const char *cmd) | 43 | static inline void arch_reset(char mode, const char *cmd) |
44 | { | 44 | { |
45 | if (!cpu_class_is_omap2()) | 45 | if (!cpu_class_is_omap2()) |
46 | omap1_arch_reset(mode); | 46 | omap1_arch_reset(mode); |
47 | else | 47 | else |
48 | omap_prcm_arch_reset(mode); | 48 | omap_prcm_arch_reset(mode); |
49 | } | 49 | } |
50 | 50 | ||
51 | #endif | 51 | #endif |
52 | 52 |
drivers/input/keyboard/pxa27x_keypad.c
1 | /* | 1 | /* |
2 | * linux/drivers/input/keyboard/pxa27x_keypad.c | 2 | * linux/drivers/input/keyboard/pxa27x_keypad.c |
3 | * | 3 | * |
4 | * Driver for the pxa27x matrix keyboard controller. | 4 | * Driver for the pxa27x matrix keyboard controller. |
5 | * | 5 | * |
6 | * Created: Feb 22, 2007 | 6 | * Created: Feb 22, 2007 |
7 | * Author: Rodolfo Giometti <giometti@linux.it> | 7 | * Author: Rodolfo Giometti <giometti@linux.it> |
8 | * | 8 | * |
9 | * Based on a previous implementations by Kevin O'Connor | 9 | * Based on a previous implementations by Kevin O'Connor |
10 | * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and | 10 | * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and |
11 | * on some suggestions by Nicolas Pitre <nico@cam.org>. | 11 | * on some suggestions by Nicolas Pitre <nico@fluxnic.net>. |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
15 | * published by the Free Software Foundation. | 15 | * published by the Free Software Foundation. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | 29 | ||
30 | #include <asm/mach/arch.h> | 30 | #include <asm/mach/arch.h> |
31 | #include <asm/mach/map.h> | 31 | #include <asm/mach/map.h> |
32 | 32 | ||
33 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
34 | #include <mach/pxa27x_keypad.h> | 34 | #include <mach/pxa27x_keypad.h> |
35 | /* | 35 | /* |
36 | * Keypad Controller registers | 36 | * Keypad Controller registers |
37 | */ | 37 | */ |
38 | #define KPC 0x0000 /* Keypad Control register */ | 38 | #define KPC 0x0000 /* Keypad Control register */ |
39 | #define KPDK 0x0008 /* Keypad Direct Key register */ | 39 | #define KPDK 0x0008 /* Keypad Direct Key register */ |
40 | #define KPREC 0x0010 /* Keypad Rotary Encoder register */ | 40 | #define KPREC 0x0010 /* Keypad Rotary Encoder register */ |
41 | #define KPMK 0x0018 /* Keypad Matrix Key register */ | 41 | #define KPMK 0x0018 /* Keypad Matrix Key register */ |
42 | #define KPAS 0x0020 /* Keypad Automatic Scan register */ | 42 | #define KPAS 0x0020 /* Keypad Automatic Scan register */ |
43 | 43 | ||
44 | /* Keypad Automatic Scan Multiple Key Presser register 0-3 */ | 44 | /* Keypad Automatic Scan Multiple Key Presser register 0-3 */ |
45 | #define KPASMKP0 0x0028 | 45 | #define KPASMKP0 0x0028 |
46 | #define KPASMKP1 0x0030 | 46 | #define KPASMKP1 0x0030 |
47 | #define KPASMKP2 0x0038 | 47 | #define KPASMKP2 0x0038 |
48 | #define KPASMKP3 0x0040 | 48 | #define KPASMKP3 0x0040 |
49 | #define KPKDI 0x0048 | 49 | #define KPKDI 0x0048 |
50 | 50 | ||
51 | /* bit definitions */ | 51 | /* bit definitions */ |
52 | #define KPC_MKRN(n) ((((n) - 1) & 0x7) << 26) /* matrix key row number */ | 52 | #define KPC_MKRN(n) ((((n) - 1) & 0x7) << 26) /* matrix key row number */ |
53 | #define KPC_MKCN(n) ((((n) - 1) & 0x7) << 23) /* matrix key column number */ | 53 | #define KPC_MKCN(n) ((((n) - 1) & 0x7) << 23) /* matrix key column number */ |
54 | #define KPC_DKN(n) ((((n) - 1) & 0x7) << 6) /* direct key number */ | 54 | #define KPC_DKN(n) ((((n) - 1) & 0x7) << 6) /* direct key number */ |
55 | 55 | ||
56 | #define KPC_AS (0x1 << 30) /* Automatic Scan bit */ | 56 | #define KPC_AS (0x1 << 30) /* Automatic Scan bit */ |
57 | #define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ | 57 | #define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ |
58 | #define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ | 58 | #define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ |
59 | #define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ | 59 | #define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ |
60 | 60 | ||
61 | #define KPC_MS(n) (0x1 << (13 + (n))) /* Matrix scan line 'n' */ | 61 | #define KPC_MS(n) (0x1 << (13 + (n))) /* Matrix scan line 'n' */ |
62 | #define KPC_MS_ALL (0xff << 13) | 62 | #define KPC_MS_ALL (0xff << 13) |
63 | 63 | ||
64 | #define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ | 64 | #define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ |
65 | #define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ | 65 | #define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ |
66 | #define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ | 66 | #define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ |
67 | #define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ | 67 | #define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ |
68 | #define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ | 68 | #define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ |
69 | #define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ | 69 | #define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ |
70 | #define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ | 70 | #define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ |
71 | #define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ | 71 | #define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ |
72 | #define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ | 72 | #define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ |
73 | 73 | ||
74 | #define KPDK_DKP (0x1 << 31) | 74 | #define KPDK_DKP (0x1 << 31) |
75 | #define KPDK_DK(n) ((n) & 0xff) | 75 | #define KPDK_DK(n) ((n) & 0xff) |
76 | 76 | ||
77 | #define KPREC_OF1 (0x1 << 31) | 77 | #define KPREC_OF1 (0x1 << 31) |
78 | #define kPREC_UF1 (0x1 << 30) | 78 | #define kPREC_UF1 (0x1 << 30) |
79 | #define KPREC_OF0 (0x1 << 15) | 79 | #define KPREC_OF0 (0x1 << 15) |
80 | #define KPREC_UF0 (0x1 << 14) | 80 | #define KPREC_UF0 (0x1 << 14) |
81 | 81 | ||
82 | #define KPREC_RECOUNT0(n) ((n) & 0xff) | 82 | #define KPREC_RECOUNT0(n) ((n) & 0xff) |
83 | #define KPREC_RECOUNT1(n) (((n) >> 16) & 0xff) | 83 | #define KPREC_RECOUNT1(n) (((n) >> 16) & 0xff) |
84 | 84 | ||
85 | #define KPMK_MKP (0x1 << 31) | 85 | #define KPMK_MKP (0x1 << 31) |
86 | #define KPAS_SO (0x1 << 31) | 86 | #define KPAS_SO (0x1 << 31) |
87 | #define KPASMKPx_SO (0x1 << 31) | 87 | #define KPASMKPx_SO (0x1 << 31) |
88 | 88 | ||
89 | #define KPAS_MUKP(n) (((n) >> 26) & 0x1f) | 89 | #define KPAS_MUKP(n) (((n) >> 26) & 0x1f) |
90 | #define KPAS_RP(n) (((n) >> 4) & 0xf) | 90 | #define KPAS_RP(n) (((n) >> 4) & 0xf) |
91 | #define KPAS_CP(n) ((n) & 0xf) | 91 | #define KPAS_CP(n) ((n) & 0xf) |
92 | 92 | ||
93 | #define KPASMKP_MKC_MASK (0xff) | 93 | #define KPASMKP_MKC_MASK (0xff) |
94 | 94 | ||
95 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) | 95 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) |
96 | #define keypad_writel(off, v) __raw_writel((v), keypad->mmio_base + (off)) | 96 | #define keypad_writel(off, v) __raw_writel((v), keypad->mmio_base + (off)) |
97 | 97 | ||
98 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | 98 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) |
99 | #define MAX_KEYPAD_KEYS (MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM) | 99 | #define MAX_KEYPAD_KEYS (MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM) |
100 | 100 | ||
101 | struct pxa27x_keypad { | 101 | struct pxa27x_keypad { |
102 | struct pxa27x_keypad_platform_data *pdata; | 102 | struct pxa27x_keypad_platform_data *pdata; |
103 | 103 | ||
104 | struct clk *clk; | 104 | struct clk *clk; |
105 | struct input_dev *input_dev; | 105 | struct input_dev *input_dev; |
106 | void __iomem *mmio_base; | 106 | void __iomem *mmio_base; |
107 | 107 | ||
108 | int irq; | 108 | int irq; |
109 | 109 | ||
110 | unsigned short keycodes[MAX_KEYPAD_KEYS]; | 110 | unsigned short keycodes[MAX_KEYPAD_KEYS]; |
111 | int rotary_rel_code[2]; | 111 | int rotary_rel_code[2]; |
112 | 112 | ||
113 | /* state row bits of each column scan */ | 113 | /* state row bits of each column scan */ |
114 | uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; | 114 | uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; |
115 | uint32_t direct_key_state; | 115 | uint32_t direct_key_state; |
116 | 116 | ||
117 | unsigned int direct_key_mask; | 117 | unsigned int direct_key_mask; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) | 120 | static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) |
121 | { | 121 | { |
122 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 122 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
123 | struct input_dev *input_dev = keypad->input_dev; | 123 | struct input_dev *input_dev = keypad->input_dev; |
124 | unsigned short keycode; | 124 | unsigned short keycode; |
125 | int i; | 125 | int i; |
126 | 126 | ||
127 | for (i = 0; i < pdata->matrix_key_map_size; i++) { | 127 | for (i = 0; i < pdata->matrix_key_map_size; i++) { |
128 | unsigned int key = pdata->matrix_key_map[i]; | 128 | unsigned int key = pdata->matrix_key_map[i]; |
129 | unsigned int row = KEY_ROW(key); | 129 | unsigned int row = KEY_ROW(key); |
130 | unsigned int col = KEY_COL(key); | 130 | unsigned int col = KEY_COL(key); |
131 | unsigned int scancode = MATRIX_SCAN_CODE(row, col, | 131 | unsigned int scancode = MATRIX_SCAN_CODE(row, col, |
132 | MATRIX_ROW_SHIFT); | 132 | MATRIX_ROW_SHIFT); |
133 | 133 | ||
134 | keycode = KEY_VAL(key); | 134 | keycode = KEY_VAL(key); |
135 | keypad->keycodes[scancode] = keycode; | 135 | keypad->keycodes[scancode] = keycode; |
136 | __set_bit(keycode, input_dev->keybit); | 136 | __set_bit(keycode, input_dev->keybit); |
137 | } | 137 | } |
138 | 138 | ||
139 | for (i = 0; i < pdata->direct_key_num; i++) { | 139 | for (i = 0; i < pdata->direct_key_num; i++) { |
140 | keycode = pdata->direct_key_map[i]; | 140 | keycode = pdata->direct_key_map[i]; |
141 | keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode; | 141 | keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode; |
142 | __set_bit(keycode, input_dev->keybit); | 142 | __set_bit(keycode, input_dev->keybit); |
143 | } | 143 | } |
144 | 144 | ||
145 | if (pdata->enable_rotary0) { | 145 | if (pdata->enable_rotary0) { |
146 | if (pdata->rotary0_up_key && pdata->rotary0_down_key) { | 146 | if (pdata->rotary0_up_key && pdata->rotary0_down_key) { |
147 | keycode = pdata->rotary0_up_key; | 147 | keycode = pdata->rotary0_up_key; |
148 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 0] = keycode; | 148 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 0] = keycode; |
149 | __set_bit(keycode, input_dev->keybit); | 149 | __set_bit(keycode, input_dev->keybit); |
150 | 150 | ||
151 | keycode = pdata->rotary0_down_key; | 151 | keycode = pdata->rotary0_down_key; |
152 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 1] = keycode; | 152 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 1] = keycode; |
153 | __set_bit(keycode, input_dev->keybit); | 153 | __set_bit(keycode, input_dev->keybit); |
154 | 154 | ||
155 | keypad->rotary_rel_code[0] = -1; | 155 | keypad->rotary_rel_code[0] = -1; |
156 | } else { | 156 | } else { |
157 | keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; | 157 | keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; |
158 | __set_bit(pdata->rotary0_rel_code, input_dev->relbit); | 158 | __set_bit(pdata->rotary0_rel_code, input_dev->relbit); |
159 | } | 159 | } |
160 | } | 160 | } |
161 | 161 | ||
162 | if (pdata->enable_rotary1) { | 162 | if (pdata->enable_rotary1) { |
163 | if (pdata->rotary1_up_key && pdata->rotary1_down_key) { | 163 | if (pdata->rotary1_up_key && pdata->rotary1_down_key) { |
164 | keycode = pdata->rotary1_up_key; | 164 | keycode = pdata->rotary1_up_key; |
165 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 2] = keycode; | 165 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 2] = keycode; |
166 | __set_bit(keycode, input_dev->keybit); | 166 | __set_bit(keycode, input_dev->keybit); |
167 | 167 | ||
168 | keycode = pdata->rotary1_down_key; | 168 | keycode = pdata->rotary1_down_key; |
169 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 3] = keycode; | 169 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 3] = keycode; |
170 | __set_bit(keycode, input_dev->keybit); | 170 | __set_bit(keycode, input_dev->keybit); |
171 | 171 | ||
172 | keypad->rotary_rel_code[1] = -1; | 172 | keypad->rotary_rel_code[1] = -1; |
173 | } else { | 173 | } else { |
174 | keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; | 174 | keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; |
175 | __set_bit(pdata->rotary1_rel_code, input_dev->relbit); | 175 | __set_bit(pdata->rotary1_rel_code, input_dev->relbit); |
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
179 | __clear_bit(KEY_RESERVED, input_dev->keybit); | 179 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
180 | } | 180 | } |
181 | 181 | ||
182 | static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad) | 182 | static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad) |
183 | { | 183 | { |
184 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 184 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
185 | struct input_dev *input_dev = keypad->input_dev; | 185 | struct input_dev *input_dev = keypad->input_dev; |
186 | int row, col, num_keys_pressed = 0; | 186 | int row, col, num_keys_pressed = 0; |
187 | uint32_t new_state[MAX_MATRIX_KEY_COLS]; | 187 | uint32_t new_state[MAX_MATRIX_KEY_COLS]; |
188 | uint32_t kpas = keypad_readl(KPAS); | 188 | uint32_t kpas = keypad_readl(KPAS); |
189 | 189 | ||
190 | num_keys_pressed = KPAS_MUKP(kpas); | 190 | num_keys_pressed = KPAS_MUKP(kpas); |
191 | 191 | ||
192 | memset(new_state, 0, sizeof(new_state)); | 192 | memset(new_state, 0, sizeof(new_state)); |
193 | 193 | ||
194 | if (num_keys_pressed == 0) | 194 | if (num_keys_pressed == 0) |
195 | goto scan; | 195 | goto scan; |
196 | 196 | ||
197 | if (num_keys_pressed == 1) { | 197 | if (num_keys_pressed == 1) { |
198 | col = KPAS_CP(kpas); | 198 | col = KPAS_CP(kpas); |
199 | row = KPAS_RP(kpas); | 199 | row = KPAS_RP(kpas); |
200 | 200 | ||
201 | /* if invalid row/col, treat as no key pressed */ | 201 | /* if invalid row/col, treat as no key pressed */ |
202 | if (col >= pdata->matrix_key_cols || | 202 | if (col >= pdata->matrix_key_cols || |
203 | row >= pdata->matrix_key_rows) | 203 | row >= pdata->matrix_key_rows) |
204 | goto scan; | 204 | goto scan; |
205 | 205 | ||
206 | new_state[col] = (1 << row); | 206 | new_state[col] = (1 << row); |
207 | goto scan; | 207 | goto scan; |
208 | } | 208 | } |
209 | 209 | ||
210 | if (num_keys_pressed > 1) { | 210 | if (num_keys_pressed > 1) { |
211 | uint32_t kpasmkp0 = keypad_readl(KPASMKP0); | 211 | uint32_t kpasmkp0 = keypad_readl(KPASMKP0); |
212 | uint32_t kpasmkp1 = keypad_readl(KPASMKP1); | 212 | uint32_t kpasmkp1 = keypad_readl(KPASMKP1); |
213 | uint32_t kpasmkp2 = keypad_readl(KPASMKP2); | 213 | uint32_t kpasmkp2 = keypad_readl(KPASMKP2); |
214 | uint32_t kpasmkp3 = keypad_readl(KPASMKP3); | 214 | uint32_t kpasmkp3 = keypad_readl(KPASMKP3); |
215 | 215 | ||
216 | new_state[0] = kpasmkp0 & KPASMKP_MKC_MASK; | 216 | new_state[0] = kpasmkp0 & KPASMKP_MKC_MASK; |
217 | new_state[1] = (kpasmkp0 >> 16) & KPASMKP_MKC_MASK; | 217 | new_state[1] = (kpasmkp0 >> 16) & KPASMKP_MKC_MASK; |
218 | new_state[2] = kpasmkp1 & KPASMKP_MKC_MASK; | 218 | new_state[2] = kpasmkp1 & KPASMKP_MKC_MASK; |
219 | new_state[3] = (kpasmkp1 >> 16) & KPASMKP_MKC_MASK; | 219 | new_state[3] = (kpasmkp1 >> 16) & KPASMKP_MKC_MASK; |
220 | new_state[4] = kpasmkp2 & KPASMKP_MKC_MASK; | 220 | new_state[4] = kpasmkp2 & KPASMKP_MKC_MASK; |
221 | new_state[5] = (kpasmkp2 >> 16) & KPASMKP_MKC_MASK; | 221 | new_state[5] = (kpasmkp2 >> 16) & KPASMKP_MKC_MASK; |
222 | new_state[6] = kpasmkp3 & KPASMKP_MKC_MASK; | 222 | new_state[6] = kpasmkp3 & KPASMKP_MKC_MASK; |
223 | new_state[7] = (kpasmkp3 >> 16) & KPASMKP_MKC_MASK; | 223 | new_state[7] = (kpasmkp3 >> 16) & KPASMKP_MKC_MASK; |
224 | } | 224 | } |
225 | scan: | 225 | scan: |
226 | for (col = 0; col < pdata->matrix_key_cols; col++) { | 226 | for (col = 0; col < pdata->matrix_key_cols; col++) { |
227 | uint32_t bits_changed; | 227 | uint32_t bits_changed; |
228 | int code; | 228 | int code; |
229 | 229 | ||
230 | bits_changed = keypad->matrix_key_state[col] ^ new_state[col]; | 230 | bits_changed = keypad->matrix_key_state[col] ^ new_state[col]; |
231 | if (bits_changed == 0) | 231 | if (bits_changed == 0) |
232 | continue; | 232 | continue; |
233 | 233 | ||
234 | for (row = 0; row < pdata->matrix_key_rows; row++) { | 234 | for (row = 0; row < pdata->matrix_key_rows; row++) { |
235 | if ((bits_changed & (1 << row)) == 0) | 235 | if ((bits_changed & (1 << row)) == 0) |
236 | continue; | 236 | continue; |
237 | 237 | ||
238 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); | 238 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); |
239 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | 239 | input_event(input_dev, EV_MSC, MSC_SCAN, code); |
240 | input_report_key(input_dev, keypad->keycodes[code], | 240 | input_report_key(input_dev, keypad->keycodes[code], |
241 | new_state[col] & (1 << row)); | 241 | new_state[col] & (1 << row)); |
242 | } | 242 | } |
243 | } | 243 | } |
244 | input_sync(input_dev); | 244 | input_sync(input_dev); |
245 | memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); | 245 | memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); |
246 | } | 246 | } |
247 | 247 | ||
248 | #define DEFAULT_KPREC (0x007f007f) | 248 | #define DEFAULT_KPREC (0x007f007f) |
249 | 249 | ||
250 | static inline int rotary_delta(uint32_t kprec) | 250 | static inline int rotary_delta(uint32_t kprec) |
251 | { | 251 | { |
252 | if (kprec & KPREC_OF0) | 252 | if (kprec & KPREC_OF0) |
253 | return (kprec & 0xff) + 0x7f; | 253 | return (kprec & 0xff) + 0x7f; |
254 | else if (kprec & KPREC_UF0) | 254 | else if (kprec & KPREC_UF0) |
255 | return (kprec & 0xff) - 0x7f - 0xff; | 255 | return (kprec & 0xff) - 0x7f - 0xff; |
256 | else | 256 | else |
257 | return (kprec & 0xff) - 0x7f; | 257 | return (kprec & 0xff) - 0x7f; |
258 | } | 258 | } |
259 | 259 | ||
260 | static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta) | 260 | static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta) |
261 | { | 261 | { |
262 | struct input_dev *dev = keypad->input_dev; | 262 | struct input_dev *dev = keypad->input_dev; |
263 | 263 | ||
264 | if (delta == 0) | 264 | if (delta == 0) |
265 | return; | 265 | return; |
266 | 266 | ||
267 | if (keypad->rotary_rel_code[r] == -1) { | 267 | if (keypad->rotary_rel_code[r] == -1) { |
268 | int code = MAX_MATRIX_KEY_NUM + 2 * r + (delta > 0 ? 0 : 1); | 268 | int code = MAX_MATRIX_KEY_NUM + 2 * r + (delta > 0 ? 0 : 1); |
269 | unsigned char keycode = keypad->keycodes[code]; | 269 | unsigned char keycode = keypad->keycodes[code]; |
270 | 270 | ||
271 | /* simulate a press-n-release */ | 271 | /* simulate a press-n-release */ |
272 | input_event(dev, EV_MSC, MSC_SCAN, code); | 272 | input_event(dev, EV_MSC, MSC_SCAN, code); |
273 | input_report_key(dev, keycode, 1); | 273 | input_report_key(dev, keycode, 1); |
274 | input_sync(dev); | 274 | input_sync(dev); |
275 | input_event(dev, EV_MSC, MSC_SCAN, code); | 275 | input_event(dev, EV_MSC, MSC_SCAN, code); |
276 | input_report_key(dev, keycode, 0); | 276 | input_report_key(dev, keycode, 0); |
277 | input_sync(dev); | 277 | input_sync(dev); |
278 | } else { | 278 | } else { |
279 | input_report_rel(dev, keypad->rotary_rel_code[r], delta); | 279 | input_report_rel(dev, keypad->rotary_rel_code[r], delta); |
280 | input_sync(dev); | 280 | input_sync(dev); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad) | 284 | static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad) |
285 | { | 285 | { |
286 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 286 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
287 | uint32_t kprec; | 287 | uint32_t kprec; |
288 | 288 | ||
289 | /* read and reset to default count value */ | 289 | /* read and reset to default count value */ |
290 | kprec = keypad_readl(KPREC); | 290 | kprec = keypad_readl(KPREC); |
291 | keypad_writel(KPREC, DEFAULT_KPREC); | 291 | keypad_writel(KPREC, DEFAULT_KPREC); |
292 | 292 | ||
293 | if (pdata->enable_rotary0) | 293 | if (pdata->enable_rotary0) |
294 | report_rotary_event(keypad, 0, rotary_delta(kprec)); | 294 | report_rotary_event(keypad, 0, rotary_delta(kprec)); |
295 | 295 | ||
296 | if (pdata->enable_rotary1) | 296 | if (pdata->enable_rotary1) |
297 | report_rotary_event(keypad, 1, rotary_delta(kprec >> 16)); | 297 | report_rotary_event(keypad, 1, rotary_delta(kprec >> 16)); |
298 | } | 298 | } |
299 | 299 | ||
300 | static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | 300 | static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) |
301 | { | 301 | { |
302 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 302 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
303 | struct input_dev *input_dev = keypad->input_dev; | 303 | struct input_dev *input_dev = keypad->input_dev; |
304 | unsigned int new_state; | 304 | unsigned int new_state; |
305 | uint32_t kpdk, bits_changed; | 305 | uint32_t kpdk, bits_changed; |
306 | int i; | 306 | int i; |
307 | 307 | ||
308 | kpdk = keypad_readl(KPDK); | 308 | kpdk = keypad_readl(KPDK); |
309 | 309 | ||
310 | if (pdata->enable_rotary0 || pdata->enable_rotary1) | 310 | if (pdata->enable_rotary0 || pdata->enable_rotary1) |
311 | pxa27x_keypad_scan_rotary(keypad); | 311 | pxa27x_keypad_scan_rotary(keypad); |
312 | 312 | ||
313 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; | 313 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; |
314 | bits_changed = keypad->direct_key_state ^ new_state; | 314 | bits_changed = keypad->direct_key_state ^ new_state; |
315 | 315 | ||
316 | if (bits_changed == 0) | 316 | if (bits_changed == 0) |
317 | return; | 317 | return; |
318 | 318 | ||
319 | for (i = 0; i < pdata->direct_key_num; i++) { | 319 | for (i = 0; i < pdata->direct_key_num; i++) { |
320 | if (bits_changed & (1 << i)) { | 320 | if (bits_changed & (1 << i)) { |
321 | int code = MAX_MATRIX_KEY_NUM + i; | 321 | int code = MAX_MATRIX_KEY_NUM + i; |
322 | 322 | ||
323 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | 323 | input_event(input_dev, EV_MSC, MSC_SCAN, code); |
324 | input_report_key(input_dev, keypad->keycodes[code], | 324 | input_report_key(input_dev, keypad->keycodes[code], |
325 | new_state & (1 << i)); | 325 | new_state & (1 << i)); |
326 | } | 326 | } |
327 | } | 327 | } |
328 | input_sync(input_dev); | 328 | input_sync(input_dev); |
329 | keypad->direct_key_state = new_state; | 329 | keypad->direct_key_state = new_state; |
330 | } | 330 | } |
331 | 331 | ||
332 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) | 332 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) |
333 | { | 333 | { |
334 | struct pxa27x_keypad *keypad = dev_id; | 334 | struct pxa27x_keypad *keypad = dev_id; |
335 | unsigned long kpc = keypad_readl(KPC); | 335 | unsigned long kpc = keypad_readl(KPC); |
336 | 336 | ||
337 | if (kpc & KPC_DI) | 337 | if (kpc & KPC_DI) |
338 | pxa27x_keypad_scan_direct(keypad); | 338 | pxa27x_keypad_scan_direct(keypad); |
339 | 339 | ||
340 | if (kpc & KPC_MI) | 340 | if (kpc & KPC_MI) |
341 | pxa27x_keypad_scan_matrix(keypad); | 341 | pxa27x_keypad_scan_matrix(keypad); |
342 | 342 | ||
343 | return IRQ_HANDLED; | 343 | return IRQ_HANDLED; |
344 | } | 344 | } |
345 | 345 | ||
346 | static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) | 346 | static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) |
347 | { | 347 | { |
348 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 348 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
349 | unsigned int mask = 0, direct_key_num = 0; | 349 | unsigned int mask = 0, direct_key_num = 0; |
350 | unsigned long kpc = 0; | 350 | unsigned long kpc = 0; |
351 | 351 | ||
352 | /* enable matrix keys with automatic scan */ | 352 | /* enable matrix keys with automatic scan */ |
353 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { | 353 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { |
354 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; | 354 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; |
355 | kpc |= KPC_MKRN(pdata->matrix_key_rows) | | 355 | kpc |= KPC_MKRN(pdata->matrix_key_rows) | |
356 | KPC_MKCN(pdata->matrix_key_cols); | 356 | KPC_MKCN(pdata->matrix_key_cols); |
357 | } | 357 | } |
358 | 358 | ||
359 | /* enable rotary key, debounce interval same as direct keys */ | 359 | /* enable rotary key, debounce interval same as direct keys */ |
360 | if (pdata->enable_rotary0) { | 360 | if (pdata->enable_rotary0) { |
361 | mask |= 0x03; | 361 | mask |= 0x03; |
362 | direct_key_num = 2; | 362 | direct_key_num = 2; |
363 | kpc |= KPC_REE0; | 363 | kpc |= KPC_REE0; |
364 | } | 364 | } |
365 | 365 | ||
366 | if (pdata->enable_rotary1) { | 366 | if (pdata->enable_rotary1) { |
367 | mask |= 0x0c; | 367 | mask |= 0x0c; |
368 | direct_key_num = 4; | 368 | direct_key_num = 4; |
369 | kpc |= KPC_REE1; | 369 | kpc |= KPC_REE1; |
370 | } | 370 | } |
371 | 371 | ||
372 | if (pdata->direct_key_num > direct_key_num) | 372 | if (pdata->direct_key_num > direct_key_num) |
373 | direct_key_num = pdata->direct_key_num; | 373 | direct_key_num = pdata->direct_key_num; |
374 | 374 | ||
375 | keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; | 375 | keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; |
376 | 376 | ||
377 | /* enable direct key */ | 377 | /* enable direct key */ |
378 | if (direct_key_num) | 378 | if (direct_key_num) |
379 | kpc |= KPC_DE | KPC_DIE | KPC_DKN(direct_key_num); | 379 | kpc |= KPC_DE | KPC_DIE | KPC_DKN(direct_key_num); |
380 | 380 | ||
381 | keypad_writel(KPC, kpc | KPC_RE_ZERO_DEB); | 381 | keypad_writel(KPC, kpc | KPC_RE_ZERO_DEB); |
382 | keypad_writel(KPREC, DEFAULT_KPREC); | 382 | keypad_writel(KPREC, DEFAULT_KPREC); |
383 | keypad_writel(KPKDI, pdata->debounce_interval); | 383 | keypad_writel(KPKDI, pdata->debounce_interval); |
384 | } | 384 | } |
385 | 385 | ||
386 | static int pxa27x_keypad_open(struct input_dev *dev) | 386 | static int pxa27x_keypad_open(struct input_dev *dev) |
387 | { | 387 | { |
388 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); | 388 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); |
389 | 389 | ||
390 | /* Enable unit clock */ | 390 | /* Enable unit clock */ |
391 | clk_enable(keypad->clk); | 391 | clk_enable(keypad->clk); |
392 | pxa27x_keypad_config(keypad); | 392 | pxa27x_keypad_config(keypad); |
393 | 393 | ||
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
396 | 396 | ||
397 | static void pxa27x_keypad_close(struct input_dev *dev) | 397 | static void pxa27x_keypad_close(struct input_dev *dev) |
398 | { | 398 | { |
399 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); | 399 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); |
400 | 400 | ||
401 | /* Disable clock unit */ | 401 | /* Disable clock unit */ |
402 | clk_disable(keypad->clk); | 402 | clk_disable(keypad->clk); |
403 | } | 403 | } |
404 | 404 | ||
405 | #ifdef CONFIG_PM | 405 | #ifdef CONFIG_PM |
406 | static int pxa27x_keypad_suspend(struct device *dev) | 406 | static int pxa27x_keypad_suspend(struct device *dev) |
407 | { | 407 | { |
408 | struct platform_device *pdev = to_platform_device(dev); | 408 | struct platform_device *pdev = to_platform_device(dev); |
409 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 409 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
410 | 410 | ||
411 | clk_disable(keypad->clk); | 411 | clk_disable(keypad->clk); |
412 | 412 | ||
413 | if (device_may_wakeup(&pdev->dev)) | 413 | if (device_may_wakeup(&pdev->dev)) |
414 | enable_irq_wake(keypad->irq); | 414 | enable_irq_wake(keypad->irq); |
415 | 415 | ||
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | 418 | ||
419 | static int pxa27x_keypad_resume(struct device *dev) | 419 | static int pxa27x_keypad_resume(struct device *dev) |
420 | { | 420 | { |
421 | struct platform_device *pdev = to_platform_device(dev); | 421 | struct platform_device *pdev = to_platform_device(dev); |
422 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 422 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
423 | struct input_dev *input_dev = keypad->input_dev; | 423 | struct input_dev *input_dev = keypad->input_dev; |
424 | 424 | ||
425 | if (device_may_wakeup(&pdev->dev)) | 425 | if (device_may_wakeup(&pdev->dev)) |
426 | disable_irq_wake(keypad->irq); | 426 | disable_irq_wake(keypad->irq); |
427 | 427 | ||
428 | mutex_lock(&input_dev->mutex); | 428 | mutex_lock(&input_dev->mutex); |
429 | 429 | ||
430 | if (input_dev->users) { | 430 | if (input_dev->users) { |
431 | /* Enable unit clock */ | 431 | /* Enable unit clock */ |
432 | clk_enable(keypad->clk); | 432 | clk_enable(keypad->clk); |
433 | pxa27x_keypad_config(keypad); | 433 | pxa27x_keypad_config(keypad); |
434 | } | 434 | } |
435 | 435 | ||
436 | mutex_unlock(&input_dev->mutex); | 436 | mutex_unlock(&input_dev->mutex); |
437 | 437 | ||
438 | return 0; | 438 | return 0; |
439 | } | 439 | } |
440 | 440 | ||
441 | static const struct dev_pm_ops pxa27x_keypad_pm_ops = { | 441 | static const struct dev_pm_ops pxa27x_keypad_pm_ops = { |
442 | .suspend = pxa27x_keypad_suspend, | 442 | .suspend = pxa27x_keypad_suspend, |
443 | .resume = pxa27x_keypad_resume, | 443 | .resume = pxa27x_keypad_resume, |
444 | }; | 444 | }; |
445 | #endif | 445 | #endif |
446 | 446 | ||
447 | static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | 447 | static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) |
448 | { | 448 | { |
449 | struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; | 449 | struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; |
450 | struct pxa27x_keypad *keypad; | 450 | struct pxa27x_keypad *keypad; |
451 | struct input_dev *input_dev; | 451 | struct input_dev *input_dev; |
452 | struct resource *res; | 452 | struct resource *res; |
453 | int irq, error; | 453 | int irq, error; |
454 | 454 | ||
455 | if (pdata == NULL) { | 455 | if (pdata == NULL) { |
456 | dev_err(&pdev->dev, "no platform data defined\n"); | 456 | dev_err(&pdev->dev, "no platform data defined\n"); |
457 | return -EINVAL; | 457 | return -EINVAL; |
458 | } | 458 | } |
459 | 459 | ||
460 | irq = platform_get_irq(pdev, 0); | 460 | irq = platform_get_irq(pdev, 0); |
461 | if (irq < 0) { | 461 | if (irq < 0) { |
462 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | 462 | dev_err(&pdev->dev, "failed to get keypad irq\n"); |
463 | return -ENXIO; | 463 | return -ENXIO; |
464 | } | 464 | } |
465 | 465 | ||
466 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 466 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
467 | if (res == NULL) { | 467 | if (res == NULL) { |
468 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | 468 | dev_err(&pdev->dev, "failed to get I/O memory\n"); |
469 | return -ENXIO; | 469 | return -ENXIO; |
470 | } | 470 | } |
471 | 471 | ||
472 | keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); | 472 | keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); |
473 | input_dev = input_allocate_device(); | 473 | input_dev = input_allocate_device(); |
474 | if (!keypad || !input_dev) { | 474 | if (!keypad || !input_dev) { |
475 | dev_err(&pdev->dev, "failed to allocate memory\n"); | 475 | dev_err(&pdev->dev, "failed to allocate memory\n"); |
476 | error = -ENOMEM; | 476 | error = -ENOMEM; |
477 | goto failed_free; | 477 | goto failed_free; |
478 | } | 478 | } |
479 | 479 | ||
480 | keypad->pdata = pdata; | 480 | keypad->pdata = pdata; |
481 | keypad->input_dev = input_dev; | 481 | keypad->input_dev = input_dev; |
482 | keypad->irq = irq; | 482 | keypad->irq = irq; |
483 | 483 | ||
484 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 484 | res = request_mem_region(res->start, resource_size(res), pdev->name); |
485 | if (res == NULL) { | 485 | if (res == NULL) { |
486 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 486 | dev_err(&pdev->dev, "failed to request I/O memory\n"); |
487 | error = -EBUSY; | 487 | error = -EBUSY; |
488 | goto failed_free; | 488 | goto failed_free; |
489 | } | 489 | } |
490 | 490 | ||
491 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | 491 | keypad->mmio_base = ioremap(res->start, resource_size(res)); |
492 | if (keypad->mmio_base == NULL) { | 492 | if (keypad->mmio_base == NULL) { |
493 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 493 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); |
494 | error = -ENXIO; | 494 | error = -ENXIO; |
495 | goto failed_free_mem; | 495 | goto failed_free_mem; |
496 | } | 496 | } |
497 | 497 | ||
498 | keypad->clk = clk_get(&pdev->dev, NULL); | 498 | keypad->clk = clk_get(&pdev->dev, NULL); |
499 | if (IS_ERR(keypad->clk)) { | 499 | if (IS_ERR(keypad->clk)) { |
500 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | 500 | dev_err(&pdev->dev, "failed to get keypad clock\n"); |
501 | error = PTR_ERR(keypad->clk); | 501 | error = PTR_ERR(keypad->clk); |
502 | goto failed_free_io; | 502 | goto failed_free_io; |
503 | } | 503 | } |
504 | 504 | ||
505 | input_dev->name = pdev->name; | 505 | input_dev->name = pdev->name; |
506 | input_dev->id.bustype = BUS_HOST; | 506 | input_dev->id.bustype = BUS_HOST; |
507 | input_dev->open = pxa27x_keypad_open; | 507 | input_dev->open = pxa27x_keypad_open; |
508 | input_dev->close = pxa27x_keypad_close; | 508 | input_dev->close = pxa27x_keypad_close; |
509 | input_dev->dev.parent = &pdev->dev; | 509 | input_dev->dev.parent = &pdev->dev; |
510 | 510 | ||
511 | input_dev->keycode = keypad->keycodes; | 511 | input_dev->keycode = keypad->keycodes; |
512 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | 512 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); |
513 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | 513 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); |
514 | 514 | ||
515 | input_set_drvdata(input_dev, keypad); | 515 | input_set_drvdata(input_dev, keypad); |
516 | 516 | ||
517 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 517 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
518 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 518 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
519 | 519 | ||
520 | pxa27x_keypad_build_keycode(keypad); | 520 | pxa27x_keypad_build_keycode(keypad); |
521 | 521 | ||
522 | if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) || | 522 | if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) || |
523 | (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) { | 523 | (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) { |
524 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | 524 | input_dev->evbit[0] |= BIT_MASK(EV_REL); |
525 | } | 525 | } |
526 | 526 | ||
527 | error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED, | 527 | error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED, |
528 | pdev->name, keypad); | 528 | pdev->name, keypad); |
529 | if (error) { | 529 | if (error) { |
530 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 530 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
531 | goto failed_put_clk; | 531 | goto failed_put_clk; |
532 | } | 532 | } |
533 | 533 | ||
534 | /* Register the input device */ | 534 | /* Register the input device */ |
535 | error = input_register_device(input_dev); | 535 | error = input_register_device(input_dev); |
536 | if (error) { | 536 | if (error) { |
537 | dev_err(&pdev->dev, "failed to register input device\n"); | 537 | dev_err(&pdev->dev, "failed to register input device\n"); |
538 | goto failed_free_irq; | 538 | goto failed_free_irq; |
539 | } | 539 | } |
540 | 540 | ||
541 | platform_set_drvdata(pdev, keypad); | 541 | platform_set_drvdata(pdev, keypad); |
542 | device_init_wakeup(&pdev->dev, 1); | 542 | device_init_wakeup(&pdev->dev, 1); |
543 | 543 | ||
544 | return 0; | 544 | return 0; |
545 | 545 | ||
546 | failed_free_irq: | 546 | failed_free_irq: |
547 | free_irq(irq, pdev); | 547 | free_irq(irq, pdev); |
548 | failed_put_clk: | 548 | failed_put_clk: |
549 | clk_put(keypad->clk); | 549 | clk_put(keypad->clk); |
550 | failed_free_io: | 550 | failed_free_io: |
551 | iounmap(keypad->mmio_base); | 551 | iounmap(keypad->mmio_base); |
552 | failed_free_mem: | 552 | failed_free_mem: |
553 | release_mem_region(res->start, resource_size(res)); | 553 | release_mem_region(res->start, resource_size(res)); |
554 | failed_free: | 554 | failed_free: |
555 | input_free_device(input_dev); | 555 | input_free_device(input_dev); |
556 | kfree(keypad); | 556 | kfree(keypad); |
557 | return error; | 557 | return error; |
558 | } | 558 | } |
559 | 559 | ||
560 | static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | 560 | static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) |
561 | { | 561 | { |
562 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 562 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
563 | struct resource *res; | 563 | struct resource *res; |
564 | 564 | ||
565 | free_irq(keypad->irq, pdev); | 565 | free_irq(keypad->irq, pdev); |
566 | clk_put(keypad->clk); | 566 | clk_put(keypad->clk); |
567 | 567 | ||
568 | input_unregister_device(keypad->input_dev); | 568 | input_unregister_device(keypad->input_dev); |
569 | input_free_device(keypad->input_dev); | 569 | input_free_device(keypad->input_dev); |
570 | 570 | ||
571 | iounmap(keypad->mmio_base); | 571 | iounmap(keypad->mmio_base); |
572 | 572 | ||
573 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 573 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
574 | release_mem_region(res->start, resource_size(res)); | 574 | release_mem_region(res->start, resource_size(res)); |
575 | 575 | ||
576 | platform_set_drvdata(pdev, NULL); | 576 | platform_set_drvdata(pdev, NULL); |
577 | kfree(keypad); | 577 | kfree(keypad); |
578 | 578 | ||
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | /* work with hotplug and coldplug */ | 582 | /* work with hotplug and coldplug */ |
583 | MODULE_ALIAS("platform:pxa27x-keypad"); | 583 | MODULE_ALIAS("platform:pxa27x-keypad"); |
584 | 584 | ||
585 | static struct platform_driver pxa27x_keypad_driver = { | 585 | static struct platform_driver pxa27x_keypad_driver = { |
586 | .probe = pxa27x_keypad_probe, | 586 | .probe = pxa27x_keypad_probe, |
587 | .remove = __devexit_p(pxa27x_keypad_remove), | 587 | .remove = __devexit_p(pxa27x_keypad_remove), |
588 | .driver = { | 588 | .driver = { |
589 | .name = "pxa27x-keypad", | 589 | .name = "pxa27x-keypad", |
590 | .owner = THIS_MODULE, | 590 | .owner = THIS_MODULE, |
591 | #ifdef CONFIG_PM | 591 | #ifdef CONFIG_PM |
592 | .pm = &pxa27x_keypad_pm_ops, | 592 | .pm = &pxa27x_keypad_pm_ops, |
593 | #endif | 593 | #endif |
594 | }, | 594 | }, |
595 | }; | 595 | }; |
596 | 596 | ||
597 | static int __init pxa27x_keypad_init(void) | 597 | static int __init pxa27x_keypad_init(void) |
598 | { | 598 | { |
599 | return platform_driver_register(&pxa27x_keypad_driver); | 599 | return platform_driver_register(&pxa27x_keypad_driver); |
600 | } | 600 | } |
601 | 601 | ||
602 | static void __exit pxa27x_keypad_exit(void) | 602 | static void __exit pxa27x_keypad_exit(void) |
603 | { | 603 | { |
604 | platform_driver_unregister(&pxa27x_keypad_driver); | 604 | platform_driver_unregister(&pxa27x_keypad_driver); |
605 | } | 605 | } |
606 | 606 | ||
607 | module_init(pxa27x_keypad_init); | 607 | module_init(pxa27x_keypad_init); |
608 | module_exit(pxa27x_keypad_exit); | 608 | module_exit(pxa27x_keypad_exit); |
609 | 609 | ||
610 | MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); | 610 | MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); |
611 | MODULE_LICENSE("GPL"); | 611 | MODULE_LICENSE("GPL"); |
612 | 612 |
drivers/mtd/chips/cfi_cmdset_0001.c
1 | /* | 1 | /* |
2 | * Common Flash Interface support: | 2 | * Common Flash Interface support: |
3 | * Intel Extended Vendor Command Set (ID 0x0001) | 3 | * Intel Extended Vendor Command Set (ID 0x0001) |
4 | * | 4 | * |
5 | * (C) 2000 Red Hat. GPL'd | 5 | * (C) 2000 Red Hat. GPL'd |
6 | * | 6 | * |
7 | * | 7 | * |
8 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 8 | * 10/10/2000 Nicolas Pitre <nico@fluxnic.net> |
9 | * - completely revamped method functions so they are aware and | 9 | * - completely revamped method functions so they are aware and |
10 | * independent of the flash geometry (buswidth, interleave, etc.) | 10 | * independent of the flash geometry (buswidth, interleave, etc.) |
11 | * - scalability vs code size is completely set at compile-time | 11 | * - scalability vs code size is completely set at compile-time |
12 | * (see include/linux/mtd/cfi.h for selection) | 12 | * (see include/linux/mtd/cfi.h for selection) |
13 | * - optimized write buffer method | 13 | * - optimized write buffer method |
14 | * 02/05/2002 Christopher Hoover <ch@hpl.hp.com>/<ch@murgatroid.com> | 14 | * 02/05/2002 Christopher Hoover <ch@hpl.hp.com>/<ch@murgatroid.com> |
15 | * - reworked lock/unlock/erase support for var size flash | 15 | * - reworked lock/unlock/erase support for var size flash |
16 | * 21/03/2007 Rodolfo Giometti <giometti@linux.it> | 16 | * 21/03/2007 Rodolfo Giometti <giometti@linux.it> |
17 | * - auto unlock sectors on resume for auto locking flash on power up | 17 | * - auto unlock sectors on resume for auto locking flash on power up |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | #include <asm/byteorder.h> | 26 | #include <asm/byteorder.h> |
27 | 27 | ||
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/reboot.h> | 32 | #include <linux/reboot.h> |
33 | #include <linux/bitmap.h> | 33 | #include <linux/bitmap.h> |
34 | #include <linux/mtd/xip.h> | 34 | #include <linux/mtd/xip.h> |
35 | #include <linux/mtd/map.h> | 35 | #include <linux/mtd/map.h> |
36 | #include <linux/mtd/mtd.h> | 36 | #include <linux/mtd/mtd.h> |
37 | #include <linux/mtd/compatmac.h> | 37 | #include <linux/mtd/compatmac.h> |
38 | #include <linux/mtd/cfi.h> | 38 | #include <linux/mtd/cfi.h> |
39 | 39 | ||
40 | /* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */ | 40 | /* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */ |
41 | /* #define CMDSET0001_DISABLE_WRITE_SUSPEND */ | 41 | /* #define CMDSET0001_DISABLE_WRITE_SUSPEND */ |
42 | 42 | ||
43 | // debugging, turns off buffer write mode if set to 1 | 43 | // debugging, turns off buffer write mode if set to 1 |
44 | #define FORCE_WORD_WRITE 0 | 44 | #define FORCE_WORD_WRITE 0 |
45 | 45 | ||
46 | #define MANUFACTURER_INTEL 0x0089 | 46 | #define MANUFACTURER_INTEL 0x0089 |
47 | #define I82802AB 0x00ad | 47 | #define I82802AB 0x00ad |
48 | #define I82802AC 0x00ac | 48 | #define I82802AC 0x00ac |
49 | #define PF38F4476 0x881c | 49 | #define PF38F4476 0x881c |
50 | #define MANUFACTURER_ST 0x0020 | 50 | #define MANUFACTURER_ST 0x0020 |
51 | #define M50LPW080 0x002F | 51 | #define M50LPW080 0x002F |
52 | #define M50FLW080A 0x0080 | 52 | #define M50FLW080A 0x0080 |
53 | #define M50FLW080B 0x0081 | 53 | #define M50FLW080B 0x0081 |
54 | #define AT49BV640D 0x02de | 54 | #define AT49BV640D 0x02de |
55 | 55 | ||
56 | static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 56 | static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
57 | static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 57 | static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
58 | static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 58 | static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
59 | static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *); | 59 | static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *); |
60 | static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); | 60 | static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); |
61 | static void cfi_intelext_sync (struct mtd_info *); | 61 | static void cfi_intelext_sync (struct mtd_info *); |
62 | static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); | 62 | static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); |
63 | static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); | 63 | static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); |
64 | #ifdef CONFIG_MTD_OTP | 64 | #ifdef CONFIG_MTD_OTP |
65 | static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 65 | static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
66 | static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 66 | static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
67 | static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 67 | static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
68 | static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t); | 68 | static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t); |
69 | static int cfi_intelext_get_fact_prot_info (struct mtd_info *, | 69 | static int cfi_intelext_get_fact_prot_info (struct mtd_info *, |
70 | struct otp_info *, size_t); | 70 | struct otp_info *, size_t); |
71 | static int cfi_intelext_get_user_prot_info (struct mtd_info *, | 71 | static int cfi_intelext_get_user_prot_info (struct mtd_info *, |
72 | struct otp_info *, size_t); | 72 | struct otp_info *, size_t); |
73 | #endif | 73 | #endif |
74 | static int cfi_intelext_suspend (struct mtd_info *); | 74 | static int cfi_intelext_suspend (struct mtd_info *); |
75 | static void cfi_intelext_resume (struct mtd_info *); | 75 | static void cfi_intelext_resume (struct mtd_info *); |
76 | static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *); | 76 | static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *); |
77 | 77 | ||
78 | static void cfi_intelext_destroy(struct mtd_info *); | 78 | static void cfi_intelext_destroy(struct mtd_info *); |
79 | 79 | ||
80 | struct mtd_info *cfi_cmdset_0001(struct map_info *, int); | 80 | struct mtd_info *cfi_cmdset_0001(struct map_info *, int); |
81 | 81 | ||
82 | static struct mtd_info *cfi_intelext_setup (struct mtd_info *); | 82 | static struct mtd_info *cfi_intelext_setup (struct mtd_info *); |
83 | static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **); | 83 | static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **); |
84 | 84 | ||
85 | static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, | 85 | static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, |
86 | size_t *retlen, void **virt, resource_size_t *phys); | 86 | size_t *retlen, void **virt, resource_size_t *phys); |
87 | static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); | 87 | static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); |
88 | 88 | ||
89 | static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); | 89 | static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); |
90 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); | 90 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); |
91 | static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); | 91 | static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); |
92 | #include "fwh_lock.h" | 92 | #include "fwh_lock.h" |
93 | 93 | ||
94 | 94 | ||
95 | 95 | ||
96 | /* | 96 | /* |
97 | * *********** SETUP AND PROBE BITS *********** | 97 | * *********** SETUP AND PROBE BITS *********** |
98 | */ | 98 | */ |
99 | 99 | ||
100 | static struct mtd_chip_driver cfi_intelext_chipdrv = { | 100 | static struct mtd_chip_driver cfi_intelext_chipdrv = { |
101 | .probe = NULL, /* Not usable directly */ | 101 | .probe = NULL, /* Not usable directly */ |
102 | .destroy = cfi_intelext_destroy, | 102 | .destroy = cfi_intelext_destroy, |
103 | .name = "cfi_cmdset_0001", | 103 | .name = "cfi_cmdset_0001", |
104 | .module = THIS_MODULE | 104 | .module = THIS_MODULE |
105 | }; | 105 | }; |
106 | 106 | ||
107 | /* #define DEBUG_LOCK_BITS */ | 107 | /* #define DEBUG_LOCK_BITS */ |
108 | /* #define DEBUG_CFI_FEATURES */ | 108 | /* #define DEBUG_CFI_FEATURES */ |
109 | 109 | ||
110 | #ifdef DEBUG_CFI_FEATURES | 110 | #ifdef DEBUG_CFI_FEATURES |
111 | static void cfi_tell_features(struct cfi_pri_intelext *extp) | 111 | static void cfi_tell_features(struct cfi_pri_intelext *extp) |
112 | { | 112 | { |
113 | int i; | 113 | int i; |
114 | printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion); | 114 | printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion); |
115 | printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); | 115 | printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); |
116 | printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); | 116 | printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); |
117 | printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); | 117 | printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); |
118 | printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); | 118 | printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); |
119 | printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); | 119 | printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); |
120 | printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); | 120 | printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); |
121 | printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); | 121 | printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); |
122 | printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); | 122 | printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); |
123 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); | 123 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); |
124 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); | 124 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); |
125 | printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); | 125 | printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); |
126 | printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"); | 126 | printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"); |
127 | for (i=11; i<32; i++) { | 127 | for (i=11; i<32; i++) { |
128 | if (extp->FeatureSupport & (1<<i)) | 128 | if (extp->FeatureSupport & (1<<i)) |
129 | printk(" - Unknown Bit %X: supported\n", i); | 129 | printk(" - Unknown Bit %X: supported\n", i); |
130 | } | 130 | } |
131 | 131 | ||
132 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); | 132 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); |
133 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); | 133 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); |
134 | for (i=1; i<8; i++) { | 134 | for (i=1; i<8; i++) { |
135 | if (extp->SuspendCmdSupport & (1<<i)) | 135 | if (extp->SuspendCmdSupport & (1<<i)) |
136 | printk(" - Unknown Bit %X: supported\n", i); | 136 | printk(" - Unknown Bit %X: supported\n", i); |
137 | } | 137 | } |
138 | 138 | ||
139 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); | 139 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); |
140 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); | 140 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); |
141 | printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); | 141 | printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); |
142 | for (i=2; i<3; i++) { | 142 | for (i=2; i<3; i++) { |
143 | if (extp->BlkStatusRegMask & (1<<i)) | 143 | if (extp->BlkStatusRegMask & (1<<i)) |
144 | printk(" - Unknown Bit %X Active: yes\n",i); | 144 | printk(" - Unknown Bit %X Active: yes\n",i); |
145 | } | 145 | } |
146 | printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no"); | 146 | printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no"); |
147 | printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no"); | 147 | printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no"); |
148 | for (i=6; i<16; i++) { | 148 | for (i=6; i<16; i++) { |
149 | if (extp->BlkStatusRegMask & (1<<i)) | 149 | if (extp->BlkStatusRegMask & (1<<i)) |
150 | printk(" - Unknown Bit %X Active: yes\n",i); | 150 | printk(" - Unknown Bit %X Active: yes\n",i); |
151 | } | 151 | } |
152 | 152 | ||
153 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", | 153 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", |
154 | extp->VccOptimal >> 4, extp->VccOptimal & 0xf); | 154 | extp->VccOptimal >> 4, extp->VccOptimal & 0xf); |
155 | if (extp->VppOptimal) | 155 | if (extp->VppOptimal) |
156 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", | 156 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", |
157 | extp->VppOptimal >> 4, extp->VppOptimal & 0xf); | 157 | extp->VppOptimal >> 4, extp->VppOptimal & 0xf); |
158 | } | 158 | } |
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | /* Atmel chips don't use the same PRI format as Intel chips */ | 161 | /* Atmel chips don't use the same PRI format as Intel chips */ |
162 | static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) | 162 | static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) |
163 | { | 163 | { |
164 | struct map_info *map = mtd->priv; | 164 | struct map_info *map = mtd->priv; |
165 | struct cfi_private *cfi = map->fldrv_priv; | 165 | struct cfi_private *cfi = map->fldrv_priv; |
166 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 166 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
167 | struct cfi_pri_atmel atmel_pri; | 167 | struct cfi_pri_atmel atmel_pri; |
168 | uint32_t features = 0; | 168 | uint32_t features = 0; |
169 | 169 | ||
170 | /* Reverse byteswapping */ | 170 | /* Reverse byteswapping */ |
171 | extp->FeatureSupport = cpu_to_le32(extp->FeatureSupport); | 171 | extp->FeatureSupport = cpu_to_le32(extp->FeatureSupport); |
172 | extp->BlkStatusRegMask = cpu_to_le16(extp->BlkStatusRegMask); | 172 | extp->BlkStatusRegMask = cpu_to_le16(extp->BlkStatusRegMask); |
173 | extp->ProtRegAddr = cpu_to_le16(extp->ProtRegAddr); | 173 | extp->ProtRegAddr = cpu_to_le16(extp->ProtRegAddr); |
174 | 174 | ||
175 | memcpy(&atmel_pri, extp, sizeof(atmel_pri)); | 175 | memcpy(&atmel_pri, extp, sizeof(atmel_pri)); |
176 | memset((char *)extp + 5, 0, sizeof(*extp) - 5); | 176 | memset((char *)extp + 5, 0, sizeof(*extp) - 5); |
177 | 177 | ||
178 | printk(KERN_ERR "atmel Features: %02x\n", atmel_pri.Features); | 178 | printk(KERN_ERR "atmel Features: %02x\n", atmel_pri.Features); |
179 | 179 | ||
180 | if (atmel_pri.Features & 0x01) /* chip erase supported */ | 180 | if (atmel_pri.Features & 0x01) /* chip erase supported */ |
181 | features |= (1<<0); | 181 | features |= (1<<0); |
182 | if (atmel_pri.Features & 0x02) /* erase suspend supported */ | 182 | if (atmel_pri.Features & 0x02) /* erase suspend supported */ |
183 | features |= (1<<1); | 183 | features |= (1<<1); |
184 | if (atmel_pri.Features & 0x04) /* program suspend supported */ | 184 | if (atmel_pri.Features & 0x04) /* program suspend supported */ |
185 | features |= (1<<2); | 185 | features |= (1<<2); |
186 | if (atmel_pri.Features & 0x08) /* simultaneous operations supported */ | 186 | if (atmel_pri.Features & 0x08) /* simultaneous operations supported */ |
187 | features |= (1<<9); | 187 | features |= (1<<9); |
188 | if (atmel_pri.Features & 0x20) /* page mode read supported */ | 188 | if (atmel_pri.Features & 0x20) /* page mode read supported */ |
189 | features |= (1<<7); | 189 | features |= (1<<7); |
190 | if (atmel_pri.Features & 0x40) /* queued erase supported */ | 190 | if (atmel_pri.Features & 0x40) /* queued erase supported */ |
191 | features |= (1<<4); | 191 | features |= (1<<4); |
192 | if (atmel_pri.Features & 0x80) /* Protection bits supported */ | 192 | if (atmel_pri.Features & 0x80) /* Protection bits supported */ |
193 | features |= (1<<6); | 193 | features |= (1<<6); |
194 | 194 | ||
195 | extp->FeatureSupport = features; | 195 | extp->FeatureSupport = features; |
196 | 196 | ||
197 | /* burst write mode not supported */ | 197 | /* burst write mode not supported */ |
198 | cfi->cfiq->BufWriteTimeoutTyp = 0; | 198 | cfi->cfiq->BufWriteTimeoutTyp = 0; |
199 | cfi->cfiq->BufWriteTimeoutMax = 0; | 199 | cfi->cfiq->BufWriteTimeoutMax = 0; |
200 | } | 200 | } |
201 | 201 | ||
202 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE | 202 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE |
203 | /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ | 203 | /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ |
204 | static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) | 204 | static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) |
205 | { | 205 | { |
206 | struct map_info *map = mtd->priv; | 206 | struct map_info *map = mtd->priv; |
207 | struct cfi_private *cfi = map->fldrv_priv; | 207 | struct cfi_private *cfi = map->fldrv_priv; |
208 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 208 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
209 | 209 | ||
210 | printk(KERN_WARNING "cfi_cmdset_0001: Suspend " | 210 | printk(KERN_WARNING "cfi_cmdset_0001: Suspend " |
211 | "erase on write disabled.\n"); | 211 | "erase on write disabled.\n"); |
212 | extp->SuspendCmdSupport &= ~1; | 212 | extp->SuspendCmdSupport &= ~1; |
213 | } | 213 | } |
214 | #endif | 214 | #endif |
215 | 215 | ||
216 | #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND | 216 | #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND |
217 | static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) | 217 | static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) |
218 | { | 218 | { |
219 | struct map_info *map = mtd->priv; | 219 | struct map_info *map = mtd->priv; |
220 | struct cfi_private *cfi = map->fldrv_priv; | 220 | struct cfi_private *cfi = map->fldrv_priv; |
221 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 221 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
222 | 222 | ||
223 | if (cfip && (cfip->FeatureSupport&4)) { | 223 | if (cfip && (cfip->FeatureSupport&4)) { |
224 | cfip->FeatureSupport &= ~4; | 224 | cfip->FeatureSupport &= ~4; |
225 | printk(KERN_WARNING "cfi_cmdset_0001: write suspend disabled\n"); | 225 | printk(KERN_WARNING "cfi_cmdset_0001: write suspend disabled\n"); |
226 | } | 226 | } |
227 | } | 227 | } |
228 | #endif | 228 | #endif |
229 | 229 | ||
230 | static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) | 230 | static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) |
231 | { | 231 | { |
232 | struct map_info *map = mtd->priv; | 232 | struct map_info *map = mtd->priv; |
233 | struct cfi_private *cfi = map->fldrv_priv; | 233 | struct cfi_private *cfi = map->fldrv_priv; |
234 | 234 | ||
235 | cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ | 235 | cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ |
236 | cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ | 236 | cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ |
237 | } | 237 | } |
238 | 238 | ||
239 | static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) | 239 | static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) |
240 | { | 240 | { |
241 | struct map_info *map = mtd->priv; | 241 | struct map_info *map = mtd->priv; |
242 | struct cfi_private *cfi = map->fldrv_priv; | 242 | struct cfi_private *cfi = map->fldrv_priv; |
243 | 243 | ||
244 | /* Note this is done after the region info is endian swapped */ | 244 | /* Note this is done after the region info is endian swapped */ |
245 | cfi->cfiq->EraseRegionInfo[1] = | 245 | cfi->cfiq->EraseRegionInfo[1] = |
246 | (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; | 246 | (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; |
247 | }; | 247 | }; |
248 | 248 | ||
249 | static void fixup_use_point(struct mtd_info *mtd, void *param) | 249 | static void fixup_use_point(struct mtd_info *mtd, void *param) |
250 | { | 250 | { |
251 | struct map_info *map = mtd->priv; | 251 | struct map_info *map = mtd->priv; |
252 | if (!mtd->point && map_is_linear(map)) { | 252 | if (!mtd->point && map_is_linear(map)) { |
253 | mtd->point = cfi_intelext_point; | 253 | mtd->point = cfi_intelext_point; |
254 | mtd->unpoint = cfi_intelext_unpoint; | 254 | mtd->unpoint = cfi_intelext_unpoint; |
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
258 | static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) | 258 | static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) |
259 | { | 259 | { |
260 | struct map_info *map = mtd->priv; | 260 | struct map_info *map = mtd->priv; |
261 | struct cfi_private *cfi = map->fldrv_priv; | 261 | struct cfi_private *cfi = map->fldrv_priv; |
262 | if (cfi->cfiq->BufWriteTimeoutTyp) { | 262 | if (cfi->cfiq->BufWriteTimeoutTyp) { |
263 | printk(KERN_INFO "Using buffer write method\n" ); | 263 | printk(KERN_INFO "Using buffer write method\n" ); |
264 | mtd->write = cfi_intelext_write_buffers; | 264 | mtd->write = cfi_intelext_write_buffers; |
265 | mtd->writev = cfi_intelext_writev; | 265 | mtd->writev = cfi_intelext_writev; |
266 | } | 266 | } |
267 | } | 267 | } |
268 | 268 | ||
269 | /* | 269 | /* |
270 | * Some chips power-up with all sectors locked by default. | 270 | * Some chips power-up with all sectors locked by default. |
271 | */ | 271 | */ |
272 | static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) | 272 | static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) |
273 | { | 273 | { |
274 | struct map_info *map = mtd->priv; | 274 | struct map_info *map = mtd->priv; |
275 | struct cfi_private *cfi = map->fldrv_priv; | 275 | struct cfi_private *cfi = map->fldrv_priv; |
276 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 276 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
277 | 277 | ||
278 | if (cfip->FeatureSupport&32) { | 278 | if (cfip->FeatureSupport&32) { |
279 | printk(KERN_INFO "Using auto-unlock on power-up/resume\n" ); | 279 | printk(KERN_INFO "Using auto-unlock on power-up/resume\n" ); |
280 | mtd->flags |= MTD_POWERUP_LOCK; | 280 | mtd->flags |= MTD_POWERUP_LOCK; |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | static struct cfi_fixup cfi_fixup_table[] = { | 284 | static struct cfi_fixup cfi_fixup_table[] = { |
285 | { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, | 285 | { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, |
286 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE | 286 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE |
287 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, | 287 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, |
288 | #endif | 288 | #endif |
289 | #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND | 289 | #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND |
290 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, | 290 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, |
291 | #endif | 291 | #endif |
292 | #if !FORCE_WORD_WRITE | 292 | #if !FORCE_WORD_WRITE |
293 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL }, | 293 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL }, |
294 | #endif | 294 | #endif |
295 | { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, | 295 | { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, |
296 | { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, | 296 | { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, |
297 | { MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, | 297 | { MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, |
298 | { 0, 0, NULL, NULL } | 298 | { 0, 0, NULL, NULL } |
299 | }; | 299 | }; |
300 | 300 | ||
301 | static struct cfi_fixup jedec_fixup_table[] = { | 301 | static struct cfi_fixup jedec_fixup_table[] = { |
302 | { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, | 302 | { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, |
303 | { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, | 303 | { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, |
304 | { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, | 304 | { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, |
305 | { MANUFACTURER_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, | 305 | { MANUFACTURER_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, |
306 | { MANUFACTURER_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, | 306 | { MANUFACTURER_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, |
307 | { 0, 0, NULL, NULL } | 307 | { 0, 0, NULL, NULL } |
308 | }; | 308 | }; |
309 | static struct cfi_fixup fixup_table[] = { | 309 | static struct cfi_fixup fixup_table[] = { |
310 | /* The CFI vendor ids and the JEDEC vendor IDs appear | 310 | /* The CFI vendor ids and the JEDEC vendor IDs appear |
311 | * to be common. It is like the devices id's are as | 311 | * to be common. It is like the devices id's are as |
312 | * well. This table is to pick all cases where | 312 | * well. This table is to pick all cases where |
313 | * we know that is the case. | 313 | * we know that is the case. |
314 | */ | 314 | */ |
315 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL }, | 315 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL }, |
316 | { 0, 0, NULL, NULL } | 316 | { 0, 0, NULL, NULL } |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static void cfi_fixup_major_minor(struct cfi_private *cfi, | 319 | static void cfi_fixup_major_minor(struct cfi_private *cfi, |
320 | struct cfi_pri_intelext *extp) | 320 | struct cfi_pri_intelext *extp) |
321 | { | 321 | { |
322 | if (cfi->mfr == MANUFACTURER_INTEL && | 322 | if (cfi->mfr == MANUFACTURER_INTEL && |
323 | cfi->id == PF38F4476 && extp->MinorVersion == '3') | 323 | cfi->id == PF38F4476 && extp->MinorVersion == '3') |
324 | extp->MinorVersion = '1'; | 324 | extp->MinorVersion = '1'; |
325 | } | 325 | } |
326 | 326 | ||
327 | static inline struct cfi_pri_intelext * | 327 | static inline struct cfi_pri_intelext * |
328 | read_pri_intelext(struct map_info *map, __u16 adr) | 328 | read_pri_intelext(struct map_info *map, __u16 adr) |
329 | { | 329 | { |
330 | struct cfi_private *cfi = map->fldrv_priv; | 330 | struct cfi_private *cfi = map->fldrv_priv; |
331 | struct cfi_pri_intelext *extp; | 331 | struct cfi_pri_intelext *extp; |
332 | unsigned int extra_size = 0; | 332 | unsigned int extra_size = 0; |
333 | unsigned int extp_size = sizeof(*extp); | 333 | unsigned int extp_size = sizeof(*extp); |
334 | 334 | ||
335 | again: | 335 | again: |
336 | extp = (struct cfi_pri_intelext *)cfi_read_pri(map, adr, extp_size, "Intel/Sharp"); | 336 | extp = (struct cfi_pri_intelext *)cfi_read_pri(map, adr, extp_size, "Intel/Sharp"); |
337 | if (!extp) | 337 | if (!extp) |
338 | return NULL; | 338 | return NULL; |
339 | 339 | ||
340 | cfi_fixup_major_minor(cfi, extp); | 340 | cfi_fixup_major_minor(cfi, extp); |
341 | 341 | ||
342 | if (extp->MajorVersion != '1' || | 342 | if (extp->MajorVersion != '1' || |
343 | (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { | 343 | (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { |
344 | printk(KERN_ERR " Unknown Intel/Sharp Extended Query " | 344 | printk(KERN_ERR " Unknown Intel/Sharp Extended Query " |
345 | "version %c.%c.\n", extp->MajorVersion, | 345 | "version %c.%c.\n", extp->MajorVersion, |
346 | extp->MinorVersion); | 346 | extp->MinorVersion); |
347 | kfree(extp); | 347 | kfree(extp); |
348 | return NULL; | 348 | return NULL; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Do some byteswapping if necessary */ | 351 | /* Do some byteswapping if necessary */ |
352 | extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); | 352 | extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); |
353 | extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); | 353 | extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); |
354 | extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); | 354 | extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); |
355 | 355 | ||
356 | if (extp->MinorVersion >= '0') { | 356 | if (extp->MinorVersion >= '0') { |
357 | extra_size = 0; | 357 | extra_size = 0; |
358 | 358 | ||
359 | /* Protection Register info */ | 359 | /* Protection Register info */ |
360 | extra_size += (extp->NumProtectionFields - 1) * | 360 | extra_size += (extp->NumProtectionFields - 1) * |
361 | sizeof(struct cfi_intelext_otpinfo); | 361 | sizeof(struct cfi_intelext_otpinfo); |
362 | } | 362 | } |
363 | 363 | ||
364 | if (extp->MinorVersion >= '1') { | 364 | if (extp->MinorVersion >= '1') { |
365 | /* Burst Read info */ | 365 | /* Burst Read info */ |
366 | extra_size += 2; | 366 | extra_size += 2; |
367 | if (extp_size < sizeof(*extp) + extra_size) | 367 | if (extp_size < sizeof(*extp) + extra_size) |
368 | goto need_more; | 368 | goto need_more; |
369 | extra_size += extp->extra[extra_size - 1]; | 369 | extra_size += extp->extra[extra_size - 1]; |
370 | } | 370 | } |
371 | 371 | ||
372 | if (extp->MinorVersion >= '3') { | 372 | if (extp->MinorVersion >= '3') { |
373 | int nb_parts, i; | 373 | int nb_parts, i; |
374 | 374 | ||
375 | /* Number of hardware-partitions */ | 375 | /* Number of hardware-partitions */ |
376 | extra_size += 1; | 376 | extra_size += 1; |
377 | if (extp_size < sizeof(*extp) + extra_size) | 377 | if (extp_size < sizeof(*extp) + extra_size) |
378 | goto need_more; | 378 | goto need_more; |
379 | nb_parts = extp->extra[extra_size - 1]; | 379 | nb_parts = extp->extra[extra_size - 1]; |
380 | 380 | ||
381 | /* skip the sizeof(partregion) field in CFI 1.4 */ | 381 | /* skip the sizeof(partregion) field in CFI 1.4 */ |
382 | if (extp->MinorVersion >= '4') | 382 | if (extp->MinorVersion >= '4') |
383 | extra_size += 2; | 383 | extra_size += 2; |
384 | 384 | ||
385 | for (i = 0; i < nb_parts; i++) { | 385 | for (i = 0; i < nb_parts; i++) { |
386 | struct cfi_intelext_regioninfo *rinfo; | 386 | struct cfi_intelext_regioninfo *rinfo; |
387 | rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; | 387 | rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; |
388 | extra_size += sizeof(*rinfo); | 388 | extra_size += sizeof(*rinfo); |
389 | if (extp_size < sizeof(*extp) + extra_size) | 389 | if (extp_size < sizeof(*extp) + extra_size) |
390 | goto need_more; | 390 | goto need_more; |
391 | rinfo->NumIdentPartitions=le16_to_cpu(rinfo->NumIdentPartitions); | 391 | rinfo->NumIdentPartitions=le16_to_cpu(rinfo->NumIdentPartitions); |
392 | extra_size += (rinfo->NumBlockTypes - 1) | 392 | extra_size += (rinfo->NumBlockTypes - 1) |
393 | * sizeof(struct cfi_intelext_blockinfo); | 393 | * sizeof(struct cfi_intelext_blockinfo); |
394 | } | 394 | } |
395 | 395 | ||
396 | if (extp->MinorVersion >= '4') | 396 | if (extp->MinorVersion >= '4') |
397 | extra_size += sizeof(struct cfi_intelext_programming_regioninfo); | 397 | extra_size += sizeof(struct cfi_intelext_programming_regioninfo); |
398 | 398 | ||
399 | if (extp_size < sizeof(*extp) + extra_size) { | 399 | if (extp_size < sizeof(*extp) + extra_size) { |
400 | need_more: | 400 | need_more: |
401 | extp_size = sizeof(*extp) + extra_size; | 401 | extp_size = sizeof(*extp) + extra_size; |
402 | kfree(extp); | 402 | kfree(extp); |
403 | if (extp_size > 4096) { | 403 | if (extp_size > 4096) { |
404 | printk(KERN_ERR | 404 | printk(KERN_ERR |
405 | "%s: cfi_pri_intelext is too fat\n", | 405 | "%s: cfi_pri_intelext is too fat\n", |
406 | __func__); | 406 | __func__); |
407 | return NULL; | 407 | return NULL; |
408 | } | 408 | } |
409 | goto again; | 409 | goto again; |
410 | } | 410 | } |
411 | } | 411 | } |
412 | 412 | ||
413 | return extp; | 413 | return extp; |
414 | } | 414 | } |
415 | 415 | ||
416 | struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | 416 | struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) |
417 | { | 417 | { |
418 | struct cfi_private *cfi = map->fldrv_priv; | 418 | struct cfi_private *cfi = map->fldrv_priv; |
419 | struct mtd_info *mtd; | 419 | struct mtd_info *mtd; |
420 | int i; | 420 | int i; |
421 | 421 | ||
422 | mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); | 422 | mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); |
423 | if (!mtd) { | 423 | if (!mtd) { |
424 | printk(KERN_ERR "Failed to allocate memory for MTD device\n"); | 424 | printk(KERN_ERR "Failed to allocate memory for MTD device\n"); |
425 | return NULL; | 425 | return NULL; |
426 | } | 426 | } |
427 | mtd->priv = map; | 427 | mtd->priv = map; |
428 | mtd->type = MTD_NORFLASH; | 428 | mtd->type = MTD_NORFLASH; |
429 | 429 | ||
430 | /* Fill in the default mtd operations */ | 430 | /* Fill in the default mtd operations */ |
431 | mtd->erase = cfi_intelext_erase_varsize; | 431 | mtd->erase = cfi_intelext_erase_varsize; |
432 | mtd->read = cfi_intelext_read; | 432 | mtd->read = cfi_intelext_read; |
433 | mtd->write = cfi_intelext_write_words; | 433 | mtd->write = cfi_intelext_write_words; |
434 | mtd->sync = cfi_intelext_sync; | 434 | mtd->sync = cfi_intelext_sync; |
435 | mtd->lock = cfi_intelext_lock; | 435 | mtd->lock = cfi_intelext_lock; |
436 | mtd->unlock = cfi_intelext_unlock; | 436 | mtd->unlock = cfi_intelext_unlock; |
437 | mtd->suspend = cfi_intelext_suspend; | 437 | mtd->suspend = cfi_intelext_suspend; |
438 | mtd->resume = cfi_intelext_resume; | 438 | mtd->resume = cfi_intelext_resume; |
439 | mtd->flags = MTD_CAP_NORFLASH; | 439 | mtd->flags = MTD_CAP_NORFLASH; |
440 | mtd->name = map->name; | 440 | mtd->name = map->name; |
441 | mtd->writesize = 1; | 441 | mtd->writesize = 1; |
442 | 442 | ||
443 | mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; | 443 | mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; |
444 | 444 | ||
445 | if (cfi->cfi_mode == CFI_MODE_CFI) { | 445 | if (cfi->cfi_mode == CFI_MODE_CFI) { |
446 | /* | 446 | /* |
447 | * It's a real CFI chip, not one for which the probe | 447 | * It's a real CFI chip, not one for which the probe |
448 | * routine faked a CFI structure. So we read the feature | 448 | * routine faked a CFI structure. So we read the feature |
449 | * table from it. | 449 | * table from it. |
450 | */ | 450 | */ |
451 | __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; | 451 | __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; |
452 | struct cfi_pri_intelext *extp; | 452 | struct cfi_pri_intelext *extp; |
453 | 453 | ||
454 | extp = read_pri_intelext(map, adr); | 454 | extp = read_pri_intelext(map, adr); |
455 | if (!extp) { | 455 | if (!extp) { |
456 | kfree(mtd); | 456 | kfree(mtd); |
457 | return NULL; | 457 | return NULL; |
458 | } | 458 | } |
459 | 459 | ||
460 | /* Install our own private info structure */ | 460 | /* Install our own private info structure */ |
461 | cfi->cmdset_priv = extp; | 461 | cfi->cmdset_priv = extp; |
462 | 462 | ||
463 | cfi_fixup(mtd, cfi_fixup_table); | 463 | cfi_fixup(mtd, cfi_fixup_table); |
464 | 464 | ||
465 | #ifdef DEBUG_CFI_FEATURES | 465 | #ifdef DEBUG_CFI_FEATURES |
466 | /* Tell the user about it in lots of lovely detail */ | 466 | /* Tell the user about it in lots of lovely detail */ |
467 | cfi_tell_features(extp); | 467 | cfi_tell_features(extp); |
468 | #endif | 468 | #endif |
469 | 469 | ||
470 | if(extp->SuspendCmdSupport & 1) { | 470 | if(extp->SuspendCmdSupport & 1) { |
471 | printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); | 471 | printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); |
472 | } | 472 | } |
473 | } | 473 | } |
474 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { | 474 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { |
475 | /* Apply jedec specific fixups */ | 475 | /* Apply jedec specific fixups */ |
476 | cfi_fixup(mtd, jedec_fixup_table); | 476 | cfi_fixup(mtd, jedec_fixup_table); |
477 | } | 477 | } |
478 | /* Apply generic fixups */ | 478 | /* Apply generic fixups */ |
479 | cfi_fixup(mtd, fixup_table); | 479 | cfi_fixup(mtd, fixup_table); |
480 | 480 | ||
481 | for (i=0; i< cfi->numchips; i++) { | 481 | for (i=0; i< cfi->numchips; i++) { |
482 | if (cfi->cfiq->WordWriteTimeoutTyp) | 482 | if (cfi->cfiq->WordWriteTimeoutTyp) |
483 | cfi->chips[i].word_write_time = | 483 | cfi->chips[i].word_write_time = |
484 | 1<<cfi->cfiq->WordWriteTimeoutTyp; | 484 | 1<<cfi->cfiq->WordWriteTimeoutTyp; |
485 | else | 485 | else |
486 | cfi->chips[i].word_write_time = 50000; | 486 | cfi->chips[i].word_write_time = 50000; |
487 | 487 | ||
488 | if (cfi->cfiq->BufWriteTimeoutTyp) | 488 | if (cfi->cfiq->BufWriteTimeoutTyp) |
489 | cfi->chips[i].buffer_write_time = | 489 | cfi->chips[i].buffer_write_time = |
490 | 1<<cfi->cfiq->BufWriteTimeoutTyp; | 490 | 1<<cfi->cfiq->BufWriteTimeoutTyp; |
491 | /* No default; if it isn't specified, we won't use it */ | 491 | /* No default; if it isn't specified, we won't use it */ |
492 | 492 | ||
493 | if (cfi->cfiq->BlockEraseTimeoutTyp) | 493 | if (cfi->cfiq->BlockEraseTimeoutTyp) |
494 | cfi->chips[i].erase_time = | 494 | cfi->chips[i].erase_time = |
495 | 1000<<cfi->cfiq->BlockEraseTimeoutTyp; | 495 | 1000<<cfi->cfiq->BlockEraseTimeoutTyp; |
496 | else | 496 | else |
497 | cfi->chips[i].erase_time = 2000000; | 497 | cfi->chips[i].erase_time = 2000000; |
498 | 498 | ||
499 | if (cfi->cfiq->WordWriteTimeoutTyp && | 499 | if (cfi->cfiq->WordWriteTimeoutTyp && |
500 | cfi->cfiq->WordWriteTimeoutMax) | 500 | cfi->cfiq->WordWriteTimeoutMax) |
501 | cfi->chips[i].word_write_time_max = | 501 | cfi->chips[i].word_write_time_max = |
502 | 1<<(cfi->cfiq->WordWriteTimeoutTyp + | 502 | 1<<(cfi->cfiq->WordWriteTimeoutTyp + |
503 | cfi->cfiq->WordWriteTimeoutMax); | 503 | cfi->cfiq->WordWriteTimeoutMax); |
504 | else | 504 | else |
505 | cfi->chips[i].word_write_time_max = 50000 * 8; | 505 | cfi->chips[i].word_write_time_max = 50000 * 8; |
506 | 506 | ||
507 | if (cfi->cfiq->BufWriteTimeoutTyp && | 507 | if (cfi->cfiq->BufWriteTimeoutTyp && |
508 | cfi->cfiq->BufWriteTimeoutMax) | 508 | cfi->cfiq->BufWriteTimeoutMax) |
509 | cfi->chips[i].buffer_write_time_max = | 509 | cfi->chips[i].buffer_write_time_max = |
510 | 1<<(cfi->cfiq->BufWriteTimeoutTyp + | 510 | 1<<(cfi->cfiq->BufWriteTimeoutTyp + |
511 | cfi->cfiq->BufWriteTimeoutMax); | 511 | cfi->cfiq->BufWriteTimeoutMax); |
512 | 512 | ||
513 | if (cfi->cfiq->BlockEraseTimeoutTyp && | 513 | if (cfi->cfiq->BlockEraseTimeoutTyp && |
514 | cfi->cfiq->BlockEraseTimeoutMax) | 514 | cfi->cfiq->BlockEraseTimeoutMax) |
515 | cfi->chips[i].erase_time_max = | 515 | cfi->chips[i].erase_time_max = |
516 | 1000<<(cfi->cfiq->BlockEraseTimeoutTyp + | 516 | 1000<<(cfi->cfiq->BlockEraseTimeoutTyp + |
517 | cfi->cfiq->BlockEraseTimeoutMax); | 517 | cfi->cfiq->BlockEraseTimeoutMax); |
518 | else | 518 | else |
519 | cfi->chips[i].erase_time_max = 2000000 * 8; | 519 | cfi->chips[i].erase_time_max = 2000000 * 8; |
520 | 520 | ||
521 | cfi->chips[i].ref_point_counter = 0; | 521 | cfi->chips[i].ref_point_counter = 0; |
522 | init_waitqueue_head(&(cfi->chips[i].wq)); | 522 | init_waitqueue_head(&(cfi->chips[i].wq)); |
523 | } | 523 | } |
524 | 524 | ||
525 | map->fldrv = &cfi_intelext_chipdrv; | 525 | map->fldrv = &cfi_intelext_chipdrv; |
526 | 526 | ||
527 | return cfi_intelext_setup(mtd); | 527 | return cfi_intelext_setup(mtd); |
528 | } | 528 | } |
529 | struct mtd_info *cfi_cmdset_0003(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001"))); | 529 | struct mtd_info *cfi_cmdset_0003(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001"))); |
530 | struct mtd_info *cfi_cmdset_0200(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001"))); | 530 | struct mtd_info *cfi_cmdset_0200(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001"))); |
531 | EXPORT_SYMBOL_GPL(cfi_cmdset_0001); | 531 | EXPORT_SYMBOL_GPL(cfi_cmdset_0001); |
532 | EXPORT_SYMBOL_GPL(cfi_cmdset_0003); | 532 | EXPORT_SYMBOL_GPL(cfi_cmdset_0003); |
533 | EXPORT_SYMBOL_GPL(cfi_cmdset_0200); | 533 | EXPORT_SYMBOL_GPL(cfi_cmdset_0200); |
534 | 534 | ||
535 | static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) | 535 | static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) |
536 | { | 536 | { |
537 | struct map_info *map = mtd->priv; | 537 | struct map_info *map = mtd->priv; |
538 | struct cfi_private *cfi = map->fldrv_priv; | 538 | struct cfi_private *cfi = map->fldrv_priv; |
539 | unsigned long offset = 0; | 539 | unsigned long offset = 0; |
540 | int i,j; | 540 | int i,j; |
541 | unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave; | 541 | unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave; |
542 | 542 | ||
543 | //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); | 543 | //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); |
544 | 544 | ||
545 | mtd->size = devsize * cfi->numchips; | 545 | mtd->size = devsize * cfi->numchips; |
546 | 546 | ||
547 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 547 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
548 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 548 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) |
549 | * mtd->numeraseregions, GFP_KERNEL); | 549 | * mtd->numeraseregions, GFP_KERNEL); |
550 | if (!mtd->eraseregions) { | 550 | if (!mtd->eraseregions) { |
551 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); | 551 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); |
552 | goto setup_err; | 552 | goto setup_err; |
553 | } | 553 | } |
554 | 554 | ||
555 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 555 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
556 | unsigned long ernum, ersize; | 556 | unsigned long ernum, ersize; |
557 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; | 557 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; |
558 | ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; | 558 | ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; |
559 | 559 | ||
560 | if (mtd->erasesize < ersize) { | 560 | if (mtd->erasesize < ersize) { |
561 | mtd->erasesize = ersize; | 561 | mtd->erasesize = ersize; |
562 | } | 562 | } |
563 | for (j=0; j<cfi->numchips; j++) { | 563 | for (j=0; j<cfi->numchips; j++) { |
564 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; | 564 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; |
565 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; | 565 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; |
566 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; | 566 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; |
567 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); | 567 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); |
568 | } | 568 | } |
569 | offset += (ersize * ernum); | 569 | offset += (ersize * ernum); |
570 | } | 570 | } |
571 | 571 | ||
572 | if (offset != devsize) { | 572 | if (offset != devsize) { |
573 | /* Argh */ | 573 | /* Argh */ |
574 | printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); | 574 | printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); |
575 | goto setup_err; | 575 | goto setup_err; |
576 | } | 576 | } |
577 | 577 | ||
578 | for (i=0; i<mtd->numeraseregions;i++){ | 578 | for (i=0; i<mtd->numeraseregions;i++){ |
579 | printk(KERN_DEBUG "erase region %d: offset=0x%llx,size=0x%x,blocks=%d\n", | 579 | printk(KERN_DEBUG "erase region %d: offset=0x%llx,size=0x%x,blocks=%d\n", |
580 | i,(unsigned long long)mtd->eraseregions[i].offset, | 580 | i,(unsigned long long)mtd->eraseregions[i].offset, |
581 | mtd->eraseregions[i].erasesize, | 581 | mtd->eraseregions[i].erasesize, |
582 | mtd->eraseregions[i].numblocks); | 582 | mtd->eraseregions[i].numblocks); |
583 | } | 583 | } |
584 | 584 | ||
585 | #ifdef CONFIG_MTD_OTP | 585 | #ifdef CONFIG_MTD_OTP |
586 | mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; | 586 | mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; |
587 | mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg; | 587 | mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg; |
588 | mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg; | 588 | mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg; |
589 | mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; | 589 | mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; |
590 | mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info; | 590 | mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info; |
591 | mtd->get_user_prot_info = cfi_intelext_get_user_prot_info; | 591 | mtd->get_user_prot_info = cfi_intelext_get_user_prot_info; |
592 | #endif | 592 | #endif |
593 | 593 | ||
594 | /* This function has the potential to distort the reality | 594 | /* This function has the potential to distort the reality |
595 | a bit and therefore should be called last. */ | 595 | a bit and therefore should be called last. */ |
596 | if (cfi_intelext_partition_fixup(mtd, &cfi) != 0) | 596 | if (cfi_intelext_partition_fixup(mtd, &cfi) != 0) |
597 | goto setup_err; | 597 | goto setup_err; |
598 | 598 | ||
599 | __module_get(THIS_MODULE); | 599 | __module_get(THIS_MODULE); |
600 | register_reboot_notifier(&mtd->reboot_notifier); | 600 | register_reboot_notifier(&mtd->reboot_notifier); |
601 | return mtd; | 601 | return mtd; |
602 | 602 | ||
603 | setup_err: | 603 | setup_err: |
604 | if(mtd) { | 604 | if(mtd) { |
605 | kfree(mtd->eraseregions); | 605 | kfree(mtd->eraseregions); |
606 | kfree(mtd); | 606 | kfree(mtd); |
607 | } | 607 | } |
608 | kfree(cfi->cmdset_priv); | 608 | kfree(cfi->cmdset_priv); |
609 | return NULL; | 609 | return NULL; |
610 | } | 610 | } |
611 | 611 | ||
612 | static int cfi_intelext_partition_fixup(struct mtd_info *mtd, | 612 | static int cfi_intelext_partition_fixup(struct mtd_info *mtd, |
613 | struct cfi_private **pcfi) | 613 | struct cfi_private **pcfi) |
614 | { | 614 | { |
615 | struct map_info *map = mtd->priv; | 615 | struct map_info *map = mtd->priv; |
616 | struct cfi_private *cfi = *pcfi; | 616 | struct cfi_private *cfi = *pcfi; |
617 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 617 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
618 | 618 | ||
619 | /* | 619 | /* |
620 | * Probing of multi-partition flash chips. | 620 | * Probing of multi-partition flash chips. |
621 | * | 621 | * |
622 | * To support multiple partitions when available, we simply arrange | 622 | * To support multiple partitions when available, we simply arrange |
623 | * for each of them to have their own flchip structure even if they | 623 | * for each of them to have their own flchip structure even if they |
624 | * are on the same physical chip. This means completely recreating | 624 | * are on the same physical chip. This means completely recreating |
625 | * a new cfi_private structure right here which is a blatent code | 625 | * a new cfi_private structure right here which is a blatent code |
626 | * layering violation, but this is still the least intrusive | 626 | * layering violation, but this is still the least intrusive |
627 | * arrangement at this point. This can be rearranged in the future | 627 | * arrangement at this point. This can be rearranged in the future |
628 | * if someone feels motivated enough. --nico | 628 | * if someone feels motivated enough. --nico |
629 | */ | 629 | */ |
630 | if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3' | 630 | if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3' |
631 | && extp->FeatureSupport & (1 << 9)) { | 631 | && extp->FeatureSupport & (1 << 9)) { |
632 | struct cfi_private *newcfi; | 632 | struct cfi_private *newcfi; |
633 | struct flchip *chip; | 633 | struct flchip *chip; |
634 | struct flchip_shared *shared; | 634 | struct flchip_shared *shared; |
635 | int offs, numregions, numparts, partshift, numvirtchips, i, j; | 635 | int offs, numregions, numparts, partshift, numvirtchips, i, j; |
636 | 636 | ||
637 | /* Protection Register info */ | 637 | /* Protection Register info */ |
638 | offs = (extp->NumProtectionFields - 1) * | 638 | offs = (extp->NumProtectionFields - 1) * |
639 | sizeof(struct cfi_intelext_otpinfo); | 639 | sizeof(struct cfi_intelext_otpinfo); |
640 | 640 | ||
641 | /* Burst Read info */ | 641 | /* Burst Read info */ |
642 | offs += extp->extra[offs+1]+2; | 642 | offs += extp->extra[offs+1]+2; |
643 | 643 | ||
644 | /* Number of partition regions */ | 644 | /* Number of partition regions */ |
645 | numregions = extp->extra[offs]; | 645 | numregions = extp->extra[offs]; |
646 | offs += 1; | 646 | offs += 1; |
647 | 647 | ||
648 | /* skip the sizeof(partregion) field in CFI 1.4 */ | 648 | /* skip the sizeof(partregion) field in CFI 1.4 */ |
649 | if (extp->MinorVersion >= '4') | 649 | if (extp->MinorVersion >= '4') |
650 | offs += 2; | 650 | offs += 2; |
651 | 651 | ||
652 | /* Number of hardware partitions */ | 652 | /* Number of hardware partitions */ |
653 | numparts = 0; | 653 | numparts = 0; |
654 | for (i = 0; i < numregions; i++) { | 654 | for (i = 0; i < numregions; i++) { |
655 | struct cfi_intelext_regioninfo *rinfo; | 655 | struct cfi_intelext_regioninfo *rinfo; |
656 | rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[offs]; | 656 | rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[offs]; |
657 | numparts += rinfo->NumIdentPartitions; | 657 | numparts += rinfo->NumIdentPartitions; |
658 | offs += sizeof(*rinfo) | 658 | offs += sizeof(*rinfo) |
659 | + (rinfo->NumBlockTypes - 1) * | 659 | + (rinfo->NumBlockTypes - 1) * |
660 | sizeof(struct cfi_intelext_blockinfo); | 660 | sizeof(struct cfi_intelext_blockinfo); |
661 | } | 661 | } |
662 | 662 | ||
663 | if (!numparts) | 663 | if (!numparts) |
664 | numparts = 1; | 664 | numparts = 1; |
665 | 665 | ||
666 | /* Programming Region info */ | 666 | /* Programming Region info */ |
667 | if (extp->MinorVersion >= '4') { | 667 | if (extp->MinorVersion >= '4') { |
668 | struct cfi_intelext_programming_regioninfo *prinfo; | 668 | struct cfi_intelext_programming_regioninfo *prinfo; |
669 | prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs]; | 669 | prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs]; |
670 | mtd->writesize = cfi->interleave << prinfo->ProgRegShift; | 670 | mtd->writesize = cfi->interleave << prinfo->ProgRegShift; |
671 | mtd->flags &= ~MTD_BIT_WRITEABLE; | 671 | mtd->flags &= ~MTD_BIT_WRITEABLE; |
672 | printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n", | 672 | printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n", |
673 | map->name, mtd->writesize, | 673 | map->name, mtd->writesize, |
674 | cfi->interleave * prinfo->ControlValid, | 674 | cfi->interleave * prinfo->ControlValid, |
675 | cfi->interleave * prinfo->ControlInvalid); | 675 | cfi->interleave * prinfo->ControlInvalid); |
676 | } | 676 | } |
677 | 677 | ||
678 | /* | 678 | /* |
679 | * All functions below currently rely on all chips having | 679 | * All functions below currently rely on all chips having |
680 | * the same geometry so we'll just assume that all hardware | 680 | * the same geometry so we'll just assume that all hardware |
681 | * partitions are of the same size too. | 681 | * partitions are of the same size too. |
682 | */ | 682 | */ |
683 | partshift = cfi->chipshift - __ffs(numparts); | 683 | partshift = cfi->chipshift - __ffs(numparts); |
684 | 684 | ||
685 | if ((1 << partshift) < mtd->erasesize) { | 685 | if ((1 << partshift) < mtd->erasesize) { |
686 | printk( KERN_ERR | 686 | printk( KERN_ERR |
687 | "%s: bad number of hw partitions (%d)\n", | 687 | "%s: bad number of hw partitions (%d)\n", |
688 | __func__, numparts); | 688 | __func__, numparts); |
689 | return -EINVAL; | 689 | return -EINVAL; |
690 | } | 690 | } |
691 | 691 | ||
692 | numvirtchips = cfi->numchips * numparts; | 692 | numvirtchips = cfi->numchips * numparts; |
693 | newcfi = kmalloc(sizeof(struct cfi_private) + numvirtchips * sizeof(struct flchip), GFP_KERNEL); | 693 | newcfi = kmalloc(sizeof(struct cfi_private) + numvirtchips * sizeof(struct flchip), GFP_KERNEL); |
694 | if (!newcfi) | 694 | if (!newcfi) |
695 | return -ENOMEM; | 695 | return -ENOMEM; |
696 | shared = kmalloc(sizeof(struct flchip_shared) * cfi->numchips, GFP_KERNEL); | 696 | shared = kmalloc(sizeof(struct flchip_shared) * cfi->numchips, GFP_KERNEL); |
697 | if (!shared) { | 697 | if (!shared) { |
698 | kfree(newcfi); | 698 | kfree(newcfi); |
699 | return -ENOMEM; | 699 | return -ENOMEM; |
700 | } | 700 | } |
701 | memcpy(newcfi, cfi, sizeof(struct cfi_private)); | 701 | memcpy(newcfi, cfi, sizeof(struct cfi_private)); |
702 | newcfi->numchips = numvirtchips; | 702 | newcfi->numchips = numvirtchips; |
703 | newcfi->chipshift = partshift; | 703 | newcfi->chipshift = partshift; |
704 | 704 | ||
705 | chip = &newcfi->chips[0]; | 705 | chip = &newcfi->chips[0]; |
706 | for (i = 0; i < cfi->numchips; i++) { | 706 | for (i = 0; i < cfi->numchips; i++) { |
707 | shared[i].writing = shared[i].erasing = NULL; | 707 | shared[i].writing = shared[i].erasing = NULL; |
708 | spin_lock_init(&shared[i].lock); | 708 | spin_lock_init(&shared[i].lock); |
709 | for (j = 0; j < numparts; j++) { | 709 | for (j = 0; j < numparts; j++) { |
710 | *chip = cfi->chips[i]; | 710 | *chip = cfi->chips[i]; |
711 | chip->start += j << partshift; | 711 | chip->start += j << partshift; |
712 | chip->priv = &shared[i]; | 712 | chip->priv = &shared[i]; |
713 | /* those should be reset too since | 713 | /* those should be reset too since |
714 | they create memory references. */ | 714 | they create memory references. */ |
715 | init_waitqueue_head(&chip->wq); | 715 | init_waitqueue_head(&chip->wq); |
716 | spin_lock_init(&chip->_spinlock); | 716 | spin_lock_init(&chip->_spinlock); |
717 | chip->mutex = &chip->_spinlock; | 717 | chip->mutex = &chip->_spinlock; |
718 | chip++; | 718 | chip++; |
719 | } | 719 | } |
720 | } | 720 | } |
721 | 721 | ||
722 | printk(KERN_DEBUG "%s: %d set(s) of %d interleaved chips " | 722 | printk(KERN_DEBUG "%s: %d set(s) of %d interleaved chips " |
723 | "--> %d partitions of %d KiB\n", | 723 | "--> %d partitions of %d KiB\n", |
724 | map->name, cfi->numchips, cfi->interleave, | 724 | map->name, cfi->numchips, cfi->interleave, |
725 | newcfi->numchips, 1<<(newcfi->chipshift-10)); | 725 | newcfi->numchips, 1<<(newcfi->chipshift-10)); |
726 | 726 | ||
727 | map->fldrv_priv = newcfi; | 727 | map->fldrv_priv = newcfi; |
728 | *pcfi = newcfi; | 728 | *pcfi = newcfi; |
729 | kfree(cfi); | 729 | kfree(cfi); |
730 | } | 730 | } |
731 | 731 | ||
732 | return 0; | 732 | return 0; |
733 | } | 733 | } |
734 | 734 | ||
735 | /* | 735 | /* |
736 | * *********** CHIP ACCESS FUNCTIONS *********** | 736 | * *********** CHIP ACCESS FUNCTIONS *********** |
737 | */ | 737 | */ |
738 | static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode) | 738 | static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode) |
739 | { | 739 | { |
740 | DECLARE_WAITQUEUE(wait, current); | 740 | DECLARE_WAITQUEUE(wait, current); |
741 | struct cfi_private *cfi = map->fldrv_priv; | 741 | struct cfi_private *cfi = map->fldrv_priv; |
742 | map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01); | 742 | map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01); |
743 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 743 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
744 | unsigned long timeo = jiffies + HZ; | 744 | unsigned long timeo = jiffies + HZ; |
745 | 745 | ||
746 | /* Prevent setting state FL_SYNCING for chip in suspended state. */ | 746 | /* Prevent setting state FL_SYNCING for chip in suspended state. */ |
747 | if (mode == FL_SYNCING && chip->oldstate != FL_READY) | 747 | if (mode == FL_SYNCING && chip->oldstate != FL_READY) |
748 | goto sleep; | 748 | goto sleep; |
749 | 749 | ||
750 | switch (chip->state) { | 750 | switch (chip->state) { |
751 | 751 | ||
752 | case FL_STATUS: | 752 | case FL_STATUS: |
753 | for (;;) { | 753 | for (;;) { |
754 | status = map_read(map, adr); | 754 | status = map_read(map, adr); |
755 | if (map_word_andequal(map, status, status_OK, status_OK)) | 755 | if (map_word_andequal(map, status, status_OK, status_OK)) |
756 | break; | 756 | break; |
757 | 757 | ||
758 | /* At this point we're fine with write operations | 758 | /* At this point we're fine with write operations |
759 | in other partitions as they don't conflict. */ | 759 | in other partitions as they don't conflict. */ |
760 | if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS)) | 760 | if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS)) |
761 | break; | 761 | break; |
762 | 762 | ||
763 | spin_unlock(chip->mutex); | 763 | spin_unlock(chip->mutex); |
764 | cfi_udelay(1); | 764 | cfi_udelay(1); |
765 | spin_lock(chip->mutex); | 765 | spin_lock(chip->mutex); |
766 | /* Someone else might have been playing with it. */ | 766 | /* Someone else might have been playing with it. */ |
767 | return -EAGAIN; | 767 | return -EAGAIN; |
768 | } | 768 | } |
769 | /* Fall through */ | 769 | /* Fall through */ |
770 | case FL_READY: | 770 | case FL_READY: |
771 | case FL_CFI_QUERY: | 771 | case FL_CFI_QUERY: |
772 | case FL_JEDEC_QUERY: | 772 | case FL_JEDEC_QUERY: |
773 | return 0; | 773 | return 0; |
774 | 774 | ||
775 | case FL_ERASING: | 775 | case FL_ERASING: |
776 | if (!cfip || | 776 | if (!cfip || |
777 | !(cfip->FeatureSupport & 2) || | 777 | !(cfip->FeatureSupport & 2) || |
778 | !(mode == FL_READY || mode == FL_POINT || | 778 | !(mode == FL_READY || mode == FL_POINT || |
779 | (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) | 779 | (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) |
780 | goto sleep; | 780 | goto sleep; |
781 | 781 | ||
782 | 782 | ||
783 | /* Erase suspend */ | 783 | /* Erase suspend */ |
784 | map_write(map, CMD(0xB0), adr); | 784 | map_write(map, CMD(0xB0), adr); |
785 | 785 | ||
786 | /* If the flash has finished erasing, then 'erase suspend' | 786 | /* If the flash has finished erasing, then 'erase suspend' |
787 | * appears to make some (28F320) flash devices switch to | 787 | * appears to make some (28F320) flash devices switch to |
788 | * 'read' mode. Make sure that we switch to 'read status' | 788 | * 'read' mode. Make sure that we switch to 'read status' |
789 | * mode so we get the right data. --rmk | 789 | * mode so we get the right data. --rmk |
790 | */ | 790 | */ |
791 | map_write(map, CMD(0x70), adr); | 791 | map_write(map, CMD(0x70), adr); |
792 | chip->oldstate = FL_ERASING; | 792 | chip->oldstate = FL_ERASING; |
793 | chip->state = FL_ERASE_SUSPENDING; | 793 | chip->state = FL_ERASE_SUSPENDING; |
794 | chip->erase_suspended = 1; | 794 | chip->erase_suspended = 1; |
795 | for (;;) { | 795 | for (;;) { |
796 | status = map_read(map, adr); | 796 | status = map_read(map, adr); |
797 | if (map_word_andequal(map, status, status_OK, status_OK)) | 797 | if (map_word_andequal(map, status, status_OK, status_OK)) |
798 | break; | 798 | break; |
799 | 799 | ||
800 | if (time_after(jiffies, timeo)) { | 800 | if (time_after(jiffies, timeo)) { |
801 | /* Urgh. Resume and pretend we weren't here. */ | 801 | /* Urgh. Resume and pretend we weren't here. */ |
802 | map_write(map, CMD(0xd0), adr); | 802 | map_write(map, CMD(0xd0), adr); |
803 | /* Make sure we're in 'read status' mode if it had finished */ | 803 | /* Make sure we're in 'read status' mode if it had finished */ |
804 | map_write(map, CMD(0x70), adr); | 804 | map_write(map, CMD(0x70), adr); |
805 | chip->state = FL_ERASING; | 805 | chip->state = FL_ERASING; |
806 | chip->oldstate = FL_READY; | 806 | chip->oldstate = FL_READY; |
807 | printk(KERN_ERR "%s: Chip not ready after erase " | 807 | printk(KERN_ERR "%s: Chip not ready after erase " |
808 | "suspended: status = 0x%lx\n", map->name, status.x[0]); | 808 | "suspended: status = 0x%lx\n", map->name, status.x[0]); |
809 | return -EIO; | 809 | return -EIO; |
810 | } | 810 | } |
811 | 811 | ||
812 | spin_unlock(chip->mutex); | 812 | spin_unlock(chip->mutex); |
813 | cfi_udelay(1); | 813 | cfi_udelay(1); |
814 | spin_lock(chip->mutex); | 814 | spin_lock(chip->mutex); |
815 | /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. | 815 | /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. |
816 | So we can just loop here. */ | 816 | So we can just loop here. */ |
817 | } | 817 | } |
818 | chip->state = FL_STATUS; | 818 | chip->state = FL_STATUS; |
819 | return 0; | 819 | return 0; |
820 | 820 | ||
821 | case FL_XIP_WHILE_ERASING: | 821 | case FL_XIP_WHILE_ERASING: |
822 | if (mode != FL_READY && mode != FL_POINT && | 822 | if (mode != FL_READY && mode != FL_POINT && |
823 | (mode != FL_WRITING || !cfip || !(cfip->SuspendCmdSupport&1))) | 823 | (mode != FL_WRITING || !cfip || !(cfip->SuspendCmdSupport&1))) |
824 | goto sleep; | 824 | goto sleep; |
825 | chip->oldstate = chip->state; | 825 | chip->oldstate = chip->state; |
826 | chip->state = FL_READY; | 826 | chip->state = FL_READY; |
827 | return 0; | 827 | return 0; |
828 | 828 | ||
829 | case FL_SHUTDOWN: | 829 | case FL_SHUTDOWN: |
830 | /* The machine is rebooting now,so no one can get chip anymore */ | 830 | /* The machine is rebooting now,so no one can get chip anymore */ |
831 | return -EIO; | 831 | return -EIO; |
832 | case FL_POINT: | 832 | case FL_POINT: |
833 | /* Only if there's no operation suspended... */ | 833 | /* Only if there's no operation suspended... */ |
834 | if (mode == FL_READY && chip->oldstate == FL_READY) | 834 | if (mode == FL_READY && chip->oldstate == FL_READY) |
835 | return 0; | 835 | return 0; |
836 | /* Fall through */ | 836 | /* Fall through */ |
837 | default: | 837 | default: |
838 | sleep: | 838 | sleep: |
839 | set_current_state(TASK_UNINTERRUPTIBLE); | 839 | set_current_state(TASK_UNINTERRUPTIBLE); |
840 | add_wait_queue(&chip->wq, &wait); | 840 | add_wait_queue(&chip->wq, &wait); |
841 | spin_unlock(chip->mutex); | 841 | spin_unlock(chip->mutex); |
842 | schedule(); | 842 | schedule(); |
843 | remove_wait_queue(&chip->wq, &wait); | 843 | remove_wait_queue(&chip->wq, &wait); |
844 | spin_lock(chip->mutex); | 844 | spin_lock(chip->mutex); |
845 | return -EAGAIN; | 845 | return -EAGAIN; |
846 | } | 846 | } |
847 | } | 847 | } |
848 | 848 | ||
849 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) | 849 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) |
850 | { | 850 | { |
851 | int ret; | 851 | int ret; |
852 | DECLARE_WAITQUEUE(wait, current); | 852 | DECLARE_WAITQUEUE(wait, current); |
853 | 853 | ||
854 | retry: | 854 | retry: |
855 | if (chip->priv && | 855 | if (chip->priv && |
856 | (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE | 856 | (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE |
857 | || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) { | 857 | || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) { |
858 | /* | 858 | /* |
859 | * OK. We have possibility for contention on the write/erase | 859 | * OK. We have possibility for contention on the write/erase |
860 | * operations which are global to the real chip and not per | 860 | * operations which are global to the real chip and not per |
861 | * partition. So let's fight it over in the partition which | 861 | * partition. So let's fight it over in the partition which |
862 | * currently has authority on the operation. | 862 | * currently has authority on the operation. |
863 | * | 863 | * |
864 | * The rules are as follows: | 864 | * The rules are as follows: |
865 | * | 865 | * |
866 | * - any write operation must own shared->writing. | 866 | * - any write operation must own shared->writing. |
867 | * | 867 | * |
868 | * - any erase operation must own _both_ shared->writing and | 868 | * - any erase operation must own _both_ shared->writing and |
869 | * shared->erasing. | 869 | * shared->erasing. |
870 | * | 870 | * |
871 | * - contention arbitration is handled in the owner's context. | 871 | * - contention arbitration is handled in the owner's context. |
872 | * | 872 | * |
873 | * The 'shared' struct can be read and/or written only when | 873 | * The 'shared' struct can be read and/or written only when |
874 | * its lock is taken. | 874 | * its lock is taken. |
875 | */ | 875 | */ |
876 | struct flchip_shared *shared = chip->priv; | 876 | struct flchip_shared *shared = chip->priv; |
877 | struct flchip *contender; | 877 | struct flchip *contender; |
878 | spin_lock(&shared->lock); | 878 | spin_lock(&shared->lock); |
879 | contender = shared->writing; | 879 | contender = shared->writing; |
880 | if (contender && contender != chip) { | 880 | if (contender && contender != chip) { |
881 | /* | 881 | /* |
882 | * The engine to perform desired operation on this | 882 | * The engine to perform desired operation on this |
883 | * partition is already in use by someone else. | 883 | * partition is already in use by someone else. |
884 | * Let's fight over it in the context of the chip | 884 | * Let's fight over it in the context of the chip |
885 | * currently using it. If it is possible to suspend, | 885 | * currently using it. If it is possible to suspend, |
886 | * that other partition will do just that, otherwise | 886 | * that other partition will do just that, otherwise |
887 | * it'll happily send us to sleep. In any case, when | 887 | * it'll happily send us to sleep. In any case, when |
888 | * get_chip returns success we're clear to go ahead. | 888 | * get_chip returns success we're clear to go ahead. |
889 | */ | 889 | */ |
890 | ret = spin_trylock(contender->mutex); | 890 | ret = spin_trylock(contender->mutex); |
891 | spin_unlock(&shared->lock); | 891 | spin_unlock(&shared->lock); |
892 | if (!ret) | 892 | if (!ret) |
893 | goto retry; | 893 | goto retry; |
894 | spin_unlock(chip->mutex); | 894 | spin_unlock(chip->mutex); |
895 | ret = chip_ready(map, contender, contender->start, mode); | 895 | ret = chip_ready(map, contender, contender->start, mode); |
896 | spin_lock(chip->mutex); | 896 | spin_lock(chip->mutex); |
897 | 897 | ||
898 | if (ret == -EAGAIN) { | 898 | if (ret == -EAGAIN) { |
899 | spin_unlock(contender->mutex); | 899 | spin_unlock(contender->mutex); |
900 | goto retry; | 900 | goto retry; |
901 | } | 901 | } |
902 | if (ret) { | 902 | if (ret) { |
903 | spin_unlock(contender->mutex); | 903 | spin_unlock(contender->mutex); |
904 | return ret; | 904 | return ret; |
905 | } | 905 | } |
906 | spin_lock(&shared->lock); | 906 | spin_lock(&shared->lock); |
907 | 907 | ||
908 | /* We should not own chip if it is already | 908 | /* We should not own chip if it is already |
909 | * in FL_SYNCING state. Put contender and retry. */ | 909 | * in FL_SYNCING state. Put contender and retry. */ |
910 | if (chip->state == FL_SYNCING) { | 910 | if (chip->state == FL_SYNCING) { |
911 | put_chip(map, contender, contender->start); | 911 | put_chip(map, contender, contender->start); |
912 | spin_unlock(contender->mutex); | 912 | spin_unlock(contender->mutex); |
913 | goto retry; | 913 | goto retry; |
914 | } | 914 | } |
915 | spin_unlock(contender->mutex); | 915 | spin_unlock(contender->mutex); |
916 | } | 916 | } |
917 | 917 | ||
918 | /* Check if we already have suspended erase | 918 | /* Check if we already have suspended erase |
919 | * on this chip. Sleep. */ | 919 | * on this chip. Sleep. */ |
920 | if (mode == FL_ERASING && shared->erasing | 920 | if (mode == FL_ERASING && shared->erasing |
921 | && shared->erasing->oldstate == FL_ERASING) { | 921 | && shared->erasing->oldstate == FL_ERASING) { |
922 | spin_unlock(&shared->lock); | 922 | spin_unlock(&shared->lock); |
923 | set_current_state(TASK_UNINTERRUPTIBLE); | 923 | set_current_state(TASK_UNINTERRUPTIBLE); |
924 | add_wait_queue(&chip->wq, &wait); | 924 | add_wait_queue(&chip->wq, &wait); |
925 | spin_unlock(chip->mutex); | 925 | spin_unlock(chip->mutex); |
926 | schedule(); | 926 | schedule(); |
927 | remove_wait_queue(&chip->wq, &wait); | 927 | remove_wait_queue(&chip->wq, &wait); |
928 | spin_lock(chip->mutex); | 928 | spin_lock(chip->mutex); |
929 | goto retry; | 929 | goto retry; |
930 | } | 930 | } |
931 | 931 | ||
932 | /* We now own it */ | 932 | /* We now own it */ |
933 | shared->writing = chip; | 933 | shared->writing = chip; |
934 | if (mode == FL_ERASING) | 934 | if (mode == FL_ERASING) |
935 | shared->erasing = chip; | 935 | shared->erasing = chip; |
936 | spin_unlock(&shared->lock); | 936 | spin_unlock(&shared->lock); |
937 | } | 937 | } |
938 | ret = chip_ready(map, chip, adr, mode); | 938 | ret = chip_ready(map, chip, adr, mode); |
939 | if (ret == -EAGAIN) | 939 | if (ret == -EAGAIN) |
940 | goto retry; | 940 | goto retry; |
941 | 941 | ||
942 | return ret; | 942 | return ret; |
943 | } | 943 | } |
944 | 944 | ||
945 | static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) | 945 | static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) |
946 | { | 946 | { |
947 | struct cfi_private *cfi = map->fldrv_priv; | 947 | struct cfi_private *cfi = map->fldrv_priv; |
948 | 948 | ||
949 | if (chip->priv) { | 949 | if (chip->priv) { |
950 | struct flchip_shared *shared = chip->priv; | 950 | struct flchip_shared *shared = chip->priv; |
951 | spin_lock(&shared->lock); | 951 | spin_lock(&shared->lock); |
952 | if (shared->writing == chip && chip->oldstate == FL_READY) { | 952 | if (shared->writing == chip && chip->oldstate == FL_READY) { |
953 | /* We own the ability to write, but we're done */ | 953 | /* We own the ability to write, but we're done */ |
954 | shared->writing = shared->erasing; | 954 | shared->writing = shared->erasing; |
955 | if (shared->writing && shared->writing != chip) { | 955 | if (shared->writing && shared->writing != chip) { |
956 | /* give back ownership to who we loaned it from */ | 956 | /* give back ownership to who we loaned it from */ |
957 | struct flchip *loaner = shared->writing; | 957 | struct flchip *loaner = shared->writing; |
958 | spin_lock(loaner->mutex); | 958 | spin_lock(loaner->mutex); |
959 | spin_unlock(&shared->lock); | 959 | spin_unlock(&shared->lock); |
960 | spin_unlock(chip->mutex); | 960 | spin_unlock(chip->mutex); |
961 | put_chip(map, loaner, loaner->start); | 961 | put_chip(map, loaner, loaner->start); |
962 | spin_lock(chip->mutex); | 962 | spin_lock(chip->mutex); |
963 | spin_unlock(loaner->mutex); | 963 | spin_unlock(loaner->mutex); |
964 | wake_up(&chip->wq); | 964 | wake_up(&chip->wq); |
965 | return; | 965 | return; |
966 | } | 966 | } |
967 | shared->erasing = NULL; | 967 | shared->erasing = NULL; |
968 | shared->writing = NULL; | 968 | shared->writing = NULL; |
969 | } else if (shared->erasing == chip && shared->writing != chip) { | 969 | } else if (shared->erasing == chip && shared->writing != chip) { |
970 | /* | 970 | /* |
971 | * We own the ability to erase without the ability | 971 | * We own the ability to erase without the ability |
972 | * to write, which means the erase was suspended | 972 | * to write, which means the erase was suspended |
973 | * and some other partition is currently writing. | 973 | * and some other partition is currently writing. |
974 | * Don't let the switch below mess things up since | 974 | * Don't let the switch below mess things up since |
975 | * we don't have ownership to resume anything. | 975 | * we don't have ownership to resume anything. |
976 | */ | 976 | */ |
977 | spin_unlock(&shared->lock); | 977 | spin_unlock(&shared->lock); |
978 | wake_up(&chip->wq); | 978 | wake_up(&chip->wq); |
979 | return; | 979 | return; |
980 | } | 980 | } |
981 | spin_unlock(&shared->lock); | 981 | spin_unlock(&shared->lock); |
982 | } | 982 | } |
983 | 983 | ||
984 | switch(chip->oldstate) { | 984 | switch(chip->oldstate) { |
985 | case FL_ERASING: | 985 | case FL_ERASING: |
986 | chip->state = chip->oldstate; | 986 | chip->state = chip->oldstate; |
987 | /* What if one interleaved chip has finished and the | 987 | /* What if one interleaved chip has finished and the |
988 | other hasn't? The old code would leave the finished | 988 | other hasn't? The old code would leave the finished |
989 | one in READY mode. That's bad, and caused -EROFS | 989 | one in READY mode. That's bad, and caused -EROFS |
990 | errors to be returned from do_erase_oneblock because | 990 | errors to be returned from do_erase_oneblock because |
991 | that's the only bit it checked for at the time. | 991 | that's the only bit it checked for at the time. |
992 | As the state machine appears to explicitly allow | 992 | As the state machine appears to explicitly allow |
993 | sending the 0x70 (Read Status) command to an erasing | 993 | sending the 0x70 (Read Status) command to an erasing |
994 | chip and expecting it to be ignored, that's what we | 994 | chip and expecting it to be ignored, that's what we |
995 | do. */ | 995 | do. */ |
996 | map_write(map, CMD(0xd0), adr); | 996 | map_write(map, CMD(0xd0), adr); |
997 | map_write(map, CMD(0x70), adr); | 997 | map_write(map, CMD(0x70), adr); |
998 | chip->oldstate = FL_READY; | 998 | chip->oldstate = FL_READY; |
999 | chip->state = FL_ERASING; | 999 | chip->state = FL_ERASING; |
1000 | break; | 1000 | break; |
1001 | 1001 | ||
1002 | case FL_XIP_WHILE_ERASING: | 1002 | case FL_XIP_WHILE_ERASING: |
1003 | chip->state = chip->oldstate; | 1003 | chip->state = chip->oldstate; |
1004 | chip->oldstate = FL_READY; | 1004 | chip->oldstate = FL_READY; |
1005 | break; | 1005 | break; |
1006 | 1006 | ||
1007 | case FL_READY: | 1007 | case FL_READY: |
1008 | case FL_STATUS: | 1008 | case FL_STATUS: |
1009 | case FL_JEDEC_QUERY: | 1009 | case FL_JEDEC_QUERY: |
1010 | /* We should really make set_vpp() count, rather than doing this */ | 1010 | /* We should really make set_vpp() count, rather than doing this */ |
1011 | DISABLE_VPP(map); | 1011 | DISABLE_VPP(map); |
1012 | break; | 1012 | break; |
1013 | default: | 1013 | default: |
1014 | printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate); | 1014 | printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate); |
1015 | } | 1015 | } |
1016 | wake_up(&chip->wq); | 1016 | wake_up(&chip->wq); |
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | #ifdef CONFIG_MTD_XIP | 1019 | #ifdef CONFIG_MTD_XIP |
1020 | 1020 | ||
1021 | /* | 1021 | /* |
1022 | * No interrupt what so ever can be serviced while the flash isn't in array | 1022 | * No interrupt what so ever can be serviced while the flash isn't in array |
1023 | * mode. This is ensured by the xip_disable() and xip_enable() functions | 1023 | * mode. This is ensured by the xip_disable() and xip_enable() functions |
1024 | * enclosing any code path where the flash is known not to be in array mode. | 1024 | * enclosing any code path where the flash is known not to be in array mode. |
1025 | * And within a XIP disabled code path, only functions marked with __xipram | 1025 | * And within a XIP disabled code path, only functions marked with __xipram |
1026 | * may be called and nothing else (it's a good thing to inspect generated | 1026 | * may be called and nothing else (it's a good thing to inspect generated |
1027 | * assembly to make sure inline functions were actually inlined and that gcc | 1027 | * assembly to make sure inline functions were actually inlined and that gcc |
1028 | * didn't emit calls to its own support functions). Also configuring MTD CFI | 1028 | * didn't emit calls to its own support functions). Also configuring MTD CFI |
1029 | * support to a single buswidth and a single interleave is also recommended. | 1029 | * support to a single buswidth and a single interleave is also recommended. |
1030 | */ | 1030 | */ |
1031 | 1031 | ||
1032 | static void xip_disable(struct map_info *map, struct flchip *chip, | 1032 | static void xip_disable(struct map_info *map, struct flchip *chip, |
1033 | unsigned long adr) | 1033 | unsigned long adr) |
1034 | { | 1034 | { |
1035 | /* TODO: chips with no XIP use should ignore and return */ | 1035 | /* TODO: chips with no XIP use should ignore and return */ |
1036 | (void) map_read(map, adr); /* ensure mmu mapping is up to date */ | 1036 | (void) map_read(map, adr); /* ensure mmu mapping is up to date */ |
1037 | local_irq_disable(); | 1037 | local_irq_disable(); |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static void __xipram xip_enable(struct map_info *map, struct flchip *chip, | 1040 | static void __xipram xip_enable(struct map_info *map, struct flchip *chip, |
1041 | unsigned long adr) | 1041 | unsigned long adr) |
1042 | { | 1042 | { |
1043 | struct cfi_private *cfi = map->fldrv_priv; | 1043 | struct cfi_private *cfi = map->fldrv_priv; |
1044 | if (chip->state != FL_POINT && chip->state != FL_READY) { | 1044 | if (chip->state != FL_POINT && chip->state != FL_READY) { |
1045 | map_write(map, CMD(0xff), adr); | 1045 | map_write(map, CMD(0xff), adr); |
1046 | chip->state = FL_READY; | 1046 | chip->state = FL_READY; |
1047 | } | 1047 | } |
1048 | (void) map_read(map, adr); | 1048 | (void) map_read(map, adr); |
1049 | xip_iprefetch(); | 1049 | xip_iprefetch(); |
1050 | local_irq_enable(); | 1050 | local_irq_enable(); |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | /* | 1053 | /* |
1054 | * When a delay is required for the flash operation to complete, the | 1054 | * When a delay is required for the flash operation to complete, the |
1055 | * xip_wait_for_operation() function is polling for both the given timeout | 1055 | * xip_wait_for_operation() function is polling for both the given timeout |
1056 | * and pending (but still masked) hardware interrupts. Whenever there is an | 1056 | * and pending (but still masked) hardware interrupts. Whenever there is an |
1057 | * interrupt pending then the flash erase or write operation is suspended, | 1057 | * interrupt pending then the flash erase or write operation is suspended, |
1058 | * array mode restored and interrupts unmasked. Task scheduling might also | 1058 | * array mode restored and interrupts unmasked. Task scheduling might also |
1059 | * happen at that point. The CPU eventually returns from the interrupt or | 1059 | * happen at that point. The CPU eventually returns from the interrupt or |
1060 | * the call to schedule() and the suspended flash operation is resumed for | 1060 | * the call to schedule() and the suspended flash operation is resumed for |
1061 | * the remaining of the delay period. | 1061 | * the remaining of the delay period. |
1062 | * | 1062 | * |
1063 | * Warning: this function _will_ fool interrupt latency tracing tools. | 1063 | * Warning: this function _will_ fool interrupt latency tracing tools. |
1064 | */ | 1064 | */ |
1065 | 1065 | ||
1066 | static int __xipram xip_wait_for_operation( | 1066 | static int __xipram xip_wait_for_operation( |
1067 | struct map_info *map, struct flchip *chip, | 1067 | struct map_info *map, struct flchip *chip, |
1068 | unsigned long adr, unsigned int chip_op_time_max) | 1068 | unsigned long adr, unsigned int chip_op_time_max) |
1069 | { | 1069 | { |
1070 | struct cfi_private *cfi = map->fldrv_priv; | 1070 | struct cfi_private *cfi = map->fldrv_priv; |
1071 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 1071 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
1072 | map_word status, OK = CMD(0x80); | 1072 | map_word status, OK = CMD(0x80); |
1073 | unsigned long usec, suspended, start, done; | 1073 | unsigned long usec, suspended, start, done; |
1074 | flstate_t oldstate, newstate; | 1074 | flstate_t oldstate, newstate; |
1075 | 1075 | ||
1076 | start = xip_currtime(); | 1076 | start = xip_currtime(); |
1077 | usec = chip_op_time_max; | 1077 | usec = chip_op_time_max; |
1078 | if (usec == 0) | 1078 | if (usec == 0) |
1079 | usec = 500000; | 1079 | usec = 500000; |
1080 | done = 0; | 1080 | done = 0; |
1081 | 1081 | ||
1082 | do { | 1082 | do { |
1083 | cpu_relax(); | 1083 | cpu_relax(); |
1084 | if (xip_irqpending() && cfip && | 1084 | if (xip_irqpending() && cfip && |
1085 | ((chip->state == FL_ERASING && (cfip->FeatureSupport&2)) || | 1085 | ((chip->state == FL_ERASING && (cfip->FeatureSupport&2)) || |
1086 | (chip->state == FL_WRITING && (cfip->FeatureSupport&4))) && | 1086 | (chip->state == FL_WRITING && (cfip->FeatureSupport&4))) && |
1087 | (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { | 1087 | (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { |
1088 | /* | 1088 | /* |
1089 | * Let's suspend the erase or write operation when | 1089 | * Let's suspend the erase or write operation when |
1090 | * supported. Note that we currently don't try to | 1090 | * supported. Note that we currently don't try to |
1091 | * suspend interleaved chips if there is already | 1091 | * suspend interleaved chips if there is already |
1092 | * another operation suspended (imagine what happens | 1092 | * another operation suspended (imagine what happens |
1093 | * when one chip was already done with the current | 1093 | * when one chip was already done with the current |
1094 | * operation while another chip suspended it, then | 1094 | * operation while another chip suspended it, then |
1095 | * we resume the whole thing at once). Yes, it | 1095 | * we resume the whole thing at once). Yes, it |
1096 | * can happen! | 1096 | * can happen! |
1097 | */ | 1097 | */ |
1098 | usec -= done; | 1098 | usec -= done; |
1099 | map_write(map, CMD(0xb0), adr); | 1099 | map_write(map, CMD(0xb0), adr); |
1100 | map_write(map, CMD(0x70), adr); | 1100 | map_write(map, CMD(0x70), adr); |
1101 | suspended = xip_currtime(); | 1101 | suspended = xip_currtime(); |
1102 | do { | 1102 | do { |
1103 | if (xip_elapsed_since(suspended) > 100000) { | 1103 | if (xip_elapsed_since(suspended) > 100000) { |
1104 | /* | 1104 | /* |
1105 | * The chip doesn't want to suspend | 1105 | * The chip doesn't want to suspend |
1106 | * after waiting for 100 msecs. | 1106 | * after waiting for 100 msecs. |
1107 | * This is a critical error but there | 1107 | * This is a critical error but there |
1108 | * is not much we can do here. | 1108 | * is not much we can do here. |
1109 | */ | 1109 | */ |
1110 | return -EIO; | 1110 | return -EIO; |
1111 | } | 1111 | } |
1112 | status = map_read(map, adr); | 1112 | status = map_read(map, adr); |
1113 | } while (!map_word_andequal(map, status, OK, OK)); | 1113 | } while (!map_word_andequal(map, status, OK, OK)); |
1114 | 1114 | ||
1115 | /* Suspend succeeded */ | 1115 | /* Suspend succeeded */ |
1116 | oldstate = chip->state; | 1116 | oldstate = chip->state; |
1117 | if (oldstate == FL_ERASING) { | 1117 | if (oldstate == FL_ERASING) { |
1118 | if (!map_word_bitsset(map, status, CMD(0x40))) | 1118 | if (!map_word_bitsset(map, status, CMD(0x40))) |
1119 | break; | 1119 | break; |
1120 | newstate = FL_XIP_WHILE_ERASING; | 1120 | newstate = FL_XIP_WHILE_ERASING; |
1121 | chip->erase_suspended = 1; | 1121 | chip->erase_suspended = 1; |
1122 | } else { | 1122 | } else { |
1123 | if (!map_word_bitsset(map, status, CMD(0x04))) | 1123 | if (!map_word_bitsset(map, status, CMD(0x04))) |
1124 | break; | 1124 | break; |
1125 | newstate = FL_XIP_WHILE_WRITING; | 1125 | newstate = FL_XIP_WHILE_WRITING; |
1126 | chip->write_suspended = 1; | 1126 | chip->write_suspended = 1; |
1127 | } | 1127 | } |
1128 | chip->state = newstate; | 1128 | chip->state = newstate; |
1129 | map_write(map, CMD(0xff), adr); | 1129 | map_write(map, CMD(0xff), adr); |
1130 | (void) map_read(map, adr); | 1130 | (void) map_read(map, adr); |
1131 | xip_iprefetch(); | 1131 | xip_iprefetch(); |
1132 | local_irq_enable(); | 1132 | local_irq_enable(); |
1133 | spin_unlock(chip->mutex); | 1133 | spin_unlock(chip->mutex); |
1134 | xip_iprefetch(); | 1134 | xip_iprefetch(); |
1135 | cond_resched(); | 1135 | cond_resched(); |
1136 | 1136 | ||
1137 | /* | 1137 | /* |
1138 | * We're back. However someone else might have | 1138 | * We're back. However someone else might have |
1139 | * decided to go write to the chip if we are in | 1139 | * decided to go write to the chip if we are in |
1140 | * a suspended erase state. If so let's wait | 1140 | * a suspended erase state. If so let's wait |
1141 | * until it's done. | 1141 | * until it's done. |
1142 | */ | 1142 | */ |
1143 | spin_lock(chip->mutex); | 1143 | spin_lock(chip->mutex); |
1144 | while (chip->state != newstate) { | 1144 | while (chip->state != newstate) { |
1145 | DECLARE_WAITQUEUE(wait, current); | 1145 | DECLARE_WAITQUEUE(wait, current); |
1146 | set_current_state(TASK_UNINTERRUPTIBLE); | 1146 | set_current_state(TASK_UNINTERRUPTIBLE); |
1147 | add_wait_queue(&chip->wq, &wait); | 1147 | add_wait_queue(&chip->wq, &wait); |
1148 | spin_unlock(chip->mutex); | 1148 | spin_unlock(chip->mutex); |
1149 | schedule(); | 1149 | schedule(); |
1150 | remove_wait_queue(&chip->wq, &wait); | 1150 | remove_wait_queue(&chip->wq, &wait); |
1151 | spin_lock(chip->mutex); | 1151 | spin_lock(chip->mutex); |
1152 | } | 1152 | } |
1153 | /* Disallow XIP again */ | 1153 | /* Disallow XIP again */ |
1154 | local_irq_disable(); | 1154 | local_irq_disable(); |
1155 | 1155 | ||
1156 | /* Resume the write or erase operation */ | 1156 | /* Resume the write or erase operation */ |
1157 | map_write(map, CMD(0xd0), adr); | 1157 | map_write(map, CMD(0xd0), adr); |
1158 | map_write(map, CMD(0x70), adr); | 1158 | map_write(map, CMD(0x70), adr); |
1159 | chip->state = oldstate; | 1159 | chip->state = oldstate; |
1160 | start = xip_currtime(); | 1160 | start = xip_currtime(); |
1161 | } else if (usec >= 1000000/HZ) { | 1161 | } else if (usec >= 1000000/HZ) { |
1162 | /* | 1162 | /* |
1163 | * Try to save on CPU power when waiting delay | 1163 | * Try to save on CPU power when waiting delay |
1164 | * is at least a system timer tick period. | 1164 | * is at least a system timer tick period. |
1165 | * No need to be extremely accurate here. | 1165 | * No need to be extremely accurate here. |
1166 | */ | 1166 | */ |
1167 | xip_cpu_idle(); | 1167 | xip_cpu_idle(); |
1168 | } | 1168 | } |
1169 | status = map_read(map, adr); | 1169 | status = map_read(map, adr); |
1170 | done = xip_elapsed_since(start); | 1170 | done = xip_elapsed_since(start); |
1171 | } while (!map_word_andequal(map, status, OK, OK) | 1171 | } while (!map_word_andequal(map, status, OK, OK) |
1172 | && done < usec); | 1172 | && done < usec); |
1173 | 1173 | ||
1174 | return (done >= usec) ? -ETIME : 0; | 1174 | return (done >= usec) ? -ETIME : 0; |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | /* | 1177 | /* |
1178 | * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while | 1178 | * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while |
1179 | * the flash is actively programming or erasing since we have to poll for | 1179 | * the flash is actively programming or erasing since we have to poll for |
1180 | * the operation to complete anyway. We can't do that in a generic way with | 1180 | * the operation to complete anyway. We can't do that in a generic way with |
1181 | * a XIP setup so do it before the actual flash operation in this case | 1181 | * a XIP setup so do it before the actual flash operation in this case |
1182 | * and stub it out from INVAL_CACHE_AND_WAIT. | 1182 | * and stub it out from INVAL_CACHE_AND_WAIT. |
1183 | */ | 1183 | */ |
1184 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ | 1184 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ |
1185 | INVALIDATE_CACHED_RANGE(map, from, size) | 1185 | INVALIDATE_CACHED_RANGE(map, from, size) |
1186 | 1186 | ||
1187 | #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \ | 1187 | #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \ |
1188 | xip_wait_for_operation(map, chip, cmd_adr, usec_max) | 1188 | xip_wait_for_operation(map, chip, cmd_adr, usec_max) |
1189 | 1189 | ||
1190 | #else | 1190 | #else |
1191 | 1191 | ||
1192 | #define xip_disable(map, chip, adr) | 1192 | #define xip_disable(map, chip, adr) |
1193 | #define xip_enable(map, chip, adr) | 1193 | #define xip_enable(map, chip, adr) |
1194 | #define XIP_INVAL_CACHED_RANGE(x...) | 1194 | #define XIP_INVAL_CACHED_RANGE(x...) |
1195 | #define INVAL_CACHE_AND_WAIT inval_cache_and_wait_for_operation | 1195 | #define INVAL_CACHE_AND_WAIT inval_cache_and_wait_for_operation |
1196 | 1196 | ||
1197 | static int inval_cache_and_wait_for_operation( | 1197 | static int inval_cache_and_wait_for_operation( |
1198 | struct map_info *map, struct flchip *chip, | 1198 | struct map_info *map, struct flchip *chip, |
1199 | unsigned long cmd_adr, unsigned long inval_adr, int inval_len, | 1199 | unsigned long cmd_adr, unsigned long inval_adr, int inval_len, |
1200 | unsigned int chip_op_time, unsigned int chip_op_time_max) | 1200 | unsigned int chip_op_time, unsigned int chip_op_time_max) |
1201 | { | 1201 | { |
1202 | struct cfi_private *cfi = map->fldrv_priv; | 1202 | struct cfi_private *cfi = map->fldrv_priv; |
1203 | map_word status, status_OK = CMD(0x80); | 1203 | map_word status, status_OK = CMD(0x80); |
1204 | int chip_state = chip->state; | 1204 | int chip_state = chip->state; |
1205 | unsigned int timeo, sleep_time, reset_timeo; | 1205 | unsigned int timeo, sleep_time, reset_timeo; |
1206 | 1206 | ||
1207 | spin_unlock(chip->mutex); | 1207 | spin_unlock(chip->mutex); |
1208 | if (inval_len) | 1208 | if (inval_len) |
1209 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); | 1209 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); |
1210 | spin_lock(chip->mutex); | 1210 | spin_lock(chip->mutex); |
1211 | 1211 | ||
1212 | timeo = chip_op_time_max; | 1212 | timeo = chip_op_time_max; |
1213 | if (!timeo) | 1213 | if (!timeo) |
1214 | timeo = 500000; | 1214 | timeo = 500000; |
1215 | reset_timeo = timeo; | 1215 | reset_timeo = timeo; |
1216 | sleep_time = chip_op_time / 2; | 1216 | sleep_time = chip_op_time / 2; |
1217 | 1217 | ||
1218 | for (;;) { | 1218 | for (;;) { |
1219 | status = map_read(map, cmd_adr); | 1219 | status = map_read(map, cmd_adr); |
1220 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1220 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1221 | break; | 1221 | break; |
1222 | 1222 | ||
1223 | if (!timeo) { | 1223 | if (!timeo) { |
1224 | map_write(map, CMD(0x70), cmd_adr); | 1224 | map_write(map, CMD(0x70), cmd_adr); |
1225 | chip->state = FL_STATUS; | 1225 | chip->state = FL_STATUS; |
1226 | return -ETIME; | 1226 | return -ETIME; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | /* OK Still waiting. Drop the lock, wait a while and retry. */ | 1229 | /* OK Still waiting. Drop the lock, wait a while and retry. */ |
1230 | spin_unlock(chip->mutex); | 1230 | spin_unlock(chip->mutex); |
1231 | if (sleep_time >= 1000000/HZ) { | 1231 | if (sleep_time >= 1000000/HZ) { |
1232 | /* | 1232 | /* |
1233 | * Half of the normal delay still remaining | 1233 | * Half of the normal delay still remaining |
1234 | * can be performed with a sleeping delay instead | 1234 | * can be performed with a sleeping delay instead |
1235 | * of busy waiting. | 1235 | * of busy waiting. |
1236 | */ | 1236 | */ |
1237 | msleep(sleep_time/1000); | 1237 | msleep(sleep_time/1000); |
1238 | timeo -= sleep_time; | 1238 | timeo -= sleep_time; |
1239 | sleep_time = 1000000/HZ; | 1239 | sleep_time = 1000000/HZ; |
1240 | } else { | 1240 | } else { |
1241 | udelay(1); | 1241 | udelay(1); |
1242 | cond_resched(); | 1242 | cond_resched(); |
1243 | timeo--; | 1243 | timeo--; |
1244 | } | 1244 | } |
1245 | spin_lock(chip->mutex); | 1245 | spin_lock(chip->mutex); |
1246 | 1246 | ||
1247 | while (chip->state != chip_state) { | 1247 | while (chip->state != chip_state) { |
1248 | /* Someone's suspended the operation: sleep */ | 1248 | /* Someone's suspended the operation: sleep */ |
1249 | DECLARE_WAITQUEUE(wait, current); | 1249 | DECLARE_WAITQUEUE(wait, current); |
1250 | set_current_state(TASK_UNINTERRUPTIBLE); | 1250 | set_current_state(TASK_UNINTERRUPTIBLE); |
1251 | add_wait_queue(&chip->wq, &wait); | 1251 | add_wait_queue(&chip->wq, &wait); |
1252 | spin_unlock(chip->mutex); | 1252 | spin_unlock(chip->mutex); |
1253 | schedule(); | 1253 | schedule(); |
1254 | remove_wait_queue(&chip->wq, &wait); | 1254 | remove_wait_queue(&chip->wq, &wait); |
1255 | spin_lock(chip->mutex); | 1255 | spin_lock(chip->mutex); |
1256 | } | 1256 | } |
1257 | if (chip->erase_suspended && chip_state == FL_ERASING) { | 1257 | if (chip->erase_suspended && chip_state == FL_ERASING) { |
1258 | /* Erase suspend occured while sleep: reset timeout */ | 1258 | /* Erase suspend occured while sleep: reset timeout */ |
1259 | timeo = reset_timeo; | 1259 | timeo = reset_timeo; |
1260 | chip->erase_suspended = 0; | 1260 | chip->erase_suspended = 0; |
1261 | } | 1261 | } |
1262 | if (chip->write_suspended && chip_state == FL_WRITING) { | 1262 | if (chip->write_suspended && chip_state == FL_WRITING) { |
1263 | /* Write suspend occured while sleep: reset timeout */ | 1263 | /* Write suspend occured while sleep: reset timeout */ |
1264 | timeo = reset_timeo; | 1264 | timeo = reset_timeo; |
1265 | chip->write_suspended = 0; | 1265 | chip->write_suspended = 0; |
1266 | } | 1266 | } |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | /* Done and happy. */ | 1269 | /* Done and happy. */ |
1270 | chip->state = FL_STATUS; | 1270 | chip->state = FL_STATUS; |
1271 | return 0; | 1271 | return 0; |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | #endif | 1274 | #endif |
1275 | 1275 | ||
1276 | #define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \ | 1276 | #define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \ |
1277 | INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max); | 1277 | INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max); |
1278 | 1278 | ||
1279 | 1279 | ||
1280 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) | 1280 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) |
1281 | { | 1281 | { |
1282 | unsigned long cmd_addr; | 1282 | unsigned long cmd_addr; |
1283 | struct cfi_private *cfi = map->fldrv_priv; | 1283 | struct cfi_private *cfi = map->fldrv_priv; |
1284 | int ret = 0; | 1284 | int ret = 0; |
1285 | 1285 | ||
1286 | adr += chip->start; | 1286 | adr += chip->start; |
1287 | 1287 | ||
1288 | /* Ensure cmd read/writes are aligned. */ | 1288 | /* Ensure cmd read/writes are aligned. */ |
1289 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 1289 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
1290 | 1290 | ||
1291 | spin_lock(chip->mutex); | 1291 | spin_lock(chip->mutex); |
1292 | 1292 | ||
1293 | ret = get_chip(map, chip, cmd_addr, FL_POINT); | 1293 | ret = get_chip(map, chip, cmd_addr, FL_POINT); |
1294 | 1294 | ||
1295 | if (!ret) { | 1295 | if (!ret) { |
1296 | if (chip->state != FL_POINT && chip->state != FL_READY) | 1296 | if (chip->state != FL_POINT && chip->state != FL_READY) |
1297 | map_write(map, CMD(0xff), cmd_addr); | 1297 | map_write(map, CMD(0xff), cmd_addr); |
1298 | 1298 | ||
1299 | chip->state = FL_POINT; | 1299 | chip->state = FL_POINT; |
1300 | chip->ref_point_counter++; | 1300 | chip->ref_point_counter++; |
1301 | } | 1301 | } |
1302 | spin_unlock(chip->mutex); | 1302 | spin_unlock(chip->mutex); |
1303 | 1303 | ||
1304 | return ret; | 1304 | return ret; |
1305 | } | 1305 | } |
1306 | 1306 | ||
1307 | static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, | 1307 | static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, |
1308 | size_t *retlen, void **virt, resource_size_t *phys) | 1308 | size_t *retlen, void **virt, resource_size_t *phys) |
1309 | { | 1309 | { |
1310 | struct map_info *map = mtd->priv; | 1310 | struct map_info *map = mtd->priv; |
1311 | struct cfi_private *cfi = map->fldrv_priv; | 1311 | struct cfi_private *cfi = map->fldrv_priv; |
1312 | unsigned long ofs, last_end = 0; | 1312 | unsigned long ofs, last_end = 0; |
1313 | int chipnum; | 1313 | int chipnum; |
1314 | int ret = 0; | 1314 | int ret = 0; |
1315 | 1315 | ||
1316 | if (!map->virt || (from + len > mtd->size)) | 1316 | if (!map->virt || (from + len > mtd->size)) |
1317 | return -EINVAL; | 1317 | return -EINVAL; |
1318 | 1318 | ||
1319 | /* Now lock the chip(s) to POINT state */ | 1319 | /* Now lock the chip(s) to POINT state */ |
1320 | 1320 | ||
1321 | /* ofs: offset within the first chip that the first read should start */ | 1321 | /* ofs: offset within the first chip that the first read should start */ |
1322 | chipnum = (from >> cfi->chipshift); | 1322 | chipnum = (from >> cfi->chipshift); |
1323 | ofs = from - (chipnum << cfi->chipshift); | 1323 | ofs = from - (chipnum << cfi->chipshift); |
1324 | 1324 | ||
1325 | *virt = map->virt + cfi->chips[chipnum].start + ofs; | 1325 | *virt = map->virt + cfi->chips[chipnum].start + ofs; |
1326 | *retlen = 0; | 1326 | *retlen = 0; |
1327 | if (phys) | 1327 | if (phys) |
1328 | *phys = map->phys + cfi->chips[chipnum].start + ofs; | 1328 | *phys = map->phys + cfi->chips[chipnum].start + ofs; |
1329 | 1329 | ||
1330 | while (len) { | 1330 | while (len) { |
1331 | unsigned long thislen; | 1331 | unsigned long thislen; |
1332 | 1332 | ||
1333 | if (chipnum >= cfi->numchips) | 1333 | if (chipnum >= cfi->numchips) |
1334 | break; | 1334 | break; |
1335 | 1335 | ||
1336 | /* We cannot point across chips that are virtually disjoint */ | 1336 | /* We cannot point across chips that are virtually disjoint */ |
1337 | if (!last_end) | 1337 | if (!last_end) |
1338 | last_end = cfi->chips[chipnum].start; | 1338 | last_end = cfi->chips[chipnum].start; |
1339 | else if (cfi->chips[chipnum].start != last_end) | 1339 | else if (cfi->chips[chipnum].start != last_end) |
1340 | break; | 1340 | break; |
1341 | 1341 | ||
1342 | if ((len + ofs -1) >> cfi->chipshift) | 1342 | if ((len + ofs -1) >> cfi->chipshift) |
1343 | thislen = (1<<cfi->chipshift) - ofs; | 1343 | thislen = (1<<cfi->chipshift) - ofs; |
1344 | else | 1344 | else |
1345 | thislen = len; | 1345 | thislen = len; |
1346 | 1346 | ||
1347 | ret = do_point_onechip(map, &cfi->chips[chipnum], ofs, thislen); | 1347 | ret = do_point_onechip(map, &cfi->chips[chipnum], ofs, thislen); |
1348 | if (ret) | 1348 | if (ret) |
1349 | break; | 1349 | break; |
1350 | 1350 | ||
1351 | *retlen += thislen; | 1351 | *retlen += thislen; |
1352 | len -= thislen; | 1352 | len -= thislen; |
1353 | 1353 | ||
1354 | ofs = 0; | 1354 | ofs = 0; |
1355 | last_end += 1 << cfi->chipshift; | 1355 | last_end += 1 << cfi->chipshift; |
1356 | chipnum++; | 1356 | chipnum++; |
1357 | } | 1357 | } |
1358 | return 0; | 1358 | return 0; |
1359 | } | 1359 | } |
1360 | 1360 | ||
1361 | static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) | 1361 | static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
1362 | { | 1362 | { |
1363 | struct map_info *map = mtd->priv; | 1363 | struct map_info *map = mtd->priv; |
1364 | struct cfi_private *cfi = map->fldrv_priv; | 1364 | struct cfi_private *cfi = map->fldrv_priv; |
1365 | unsigned long ofs; | 1365 | unsigned long ofs; |
1366 | int chipnum; | 1366 | int chipnum; |
1367 | 1367 | ||
1368 | /* Now unlock the chip(s) POINT state */ | 1368 | /* Now unlock the chip(s) POINT state */ |
1369 | 1369 | ||
1370 | /* ofs: offset within the first chip that the first read should start */ | 1370 | /* ofs: offset within the first chip that the first read should start */ |
1371 | chipnum = (from >> cfi->chipshift); | 1371 | chipnum = (from >> cfi->chipshift); |
1372 | ofs = from - (chipnum << cfi->chipshift); | 1372 | ofs = from - (chipnum << cfi->chipshift); |
1373 | 1373 | ||
1374 | while (len) { | 1374 | while (len) { |
1375 | unsigned long thislen; | 1375 | unsigned long thislen; |
1376 | struct flchip *chip; | 1376 | struct flchip *chip; |
1377 | 1377 | ||
1378 | chip = &cfi->chips[chipnum]; | 1378 | chip = &cfi->chips[chipnum]; |
1379 | if (chipnum >= cfi->numchips) | 1379 | if (chipnum >= cfi->numchips) |
1380 | break; | 1380 | break; |
1381 | 1381 | ||
1382 | if ((len + ofs -1) >> cfi->chipshift) | 1382 | if ((len + ofs -1) >> cfi->chipshift) |
1383 | thislen = (1<<cfi->chipshift) - ofs; | 1383 | thislen = (1<<cfi->chipshift) - ofs; |
1384 | else | 1384 | else |
1385 | thislen = len; | 1385 | thislen = len; |
1386 | 1386 | ||
1387 | spin_lock(chip->mutex); | 1387 | spin_lock(chip->mutex); |
1388 | if (chip->state == FL_POINT) { | 1388 | if (chip->state == FL_POINT) { |
1389 | chip->ref_point_counter--; | 1389 | chip->ref_point_counter--; |
1390 | if(chip->ref_point_counter == 0) | 1390 | if(chip->ref_point_counter == 0) |
1391 | chip->state = FL_READY; | 1391 | chip->state = FL_READY; |
1392 | } else | 1392 | } else |
1393 | printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */ | 1393 | printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */ |
1394 | 1394 | ||
1395 | put_chip(map, chip, chip->start); | 1395 | put_chip(map, chip, chip->start); |
1396 | spin_unlock(chip->mutex); | 1396 | spin_unlock(chip->mutex); |
1397 | 1397 | ||
1398 | len -= thislen; | 1398 | len -= thislen; |
1399 | ofs = 0; | 1399 | ofs = 0; |
1400 | chipnum++; | 1400 | chipnum++; |
1401 | } | 1401 | } |
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) | 1404 | static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) |
1405 | { | 1405 | { |
1406 | unsigned long cmd_addr; | 1406 | unsigned long cmd_addr; |
1407 | struct cfi_private *cfi = map->fldrv_priv; | 1407 | struct cfi_private *cfi = map->fldrv_priv; |
1408 | int ret; | 1408 | int ret; |
1409 | 1409 | ||
1410 | adr += chip->start; | 1410 | adr += chip->start; |
1411 | 1411 | ||
1412 | /* Ensure cmd read/writes are aligned. */ | 1412 | /* Ensure cmd read/writes are aligned. */ |
1413 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 1413 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
1414 | 1414 | ||
1415 | spin_lock(chip->mutex); | 1415 | spin_lock(chip->mutex); |
1416 | ret = get_chip(map, chip, cmd_addr, FL_READY); | 1416 | ret = get_chip(map, chip, cmd_addr, FL_READY); |
1417 | if (ret) { | 1417 | if (ret) { |
1418 | spin_unlock(chip->mutex); | 1418 | spin_unlock(chip->mutex); |
1419 | return ret; | 1419 | return ret; |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | if (chip->state != FL_POINT && chip->state != FL_READY) { | 1422 | if (chip->state != FL_POINT && chip->state != FL_READY) { |
1423 | map_write(map, CMD(0xff), cmd_addr); | 1423 | map_write(map, CMD(0xff), cmd_addr); |
1424 | 1424 | ||
1425 | chip->state = FL_READY; | 1425 | chip->state = FL_READY; |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | map_copy_from(map, buf, adr, len); | 1428 | map_copy_from(map, buf, adr, len); |
1429 | 1429 | ||
1430 | put_chip(map, chip, cmd_addr); | 1430 | put_chip(map, chip, cmd_addr); |
1431 | 1431 | ||
1432 | spin_unlock(chip->mutex); | 1432 | spin_unlock(chip->mutex); |
1433 | return 0; | 1433 | return 0; |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) | 1436 | static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) |
1437 | { | 1437 | { |
1438 | struct map_info *map = mtd->priv; | 1438 | struct map_info *map = mtd->priv; |
1439 | struct cfi_private *cfi = map->fldrv_priv; | 1439 | struct cfi_private *cfi = map->fldrv_priv; |
1440 | unsigned long ofs; | 1440 | unsigned long ofs; |
1441 | int chipnum; | 1441 | int chipnum; |
1442 | int ret = 0; | 1442 | int ret = 0; |
1443 | 1443 | ||
1444 | /* ofs: offset within the first chip that the first read should start */ | 1444 | /* ofs: offset within the first chip that the first read should start */ |
1445 | chipnum = (from >> cfi->chipshift); | 1445 | chipnum = (from >> cfi->chipshift); |
1446 | ofs = from - (chipnum << cfi->chipshift); | 1446 | ofs = from - (chipnum << cfi->chipshift); |
1447 | 1447 | ||
1448 | *retlen = 0; | 1448 | *retlen = 0; |
1449 | 1449 | ||
1450 | while (len) { | 1450 | while (len) { |
1451 | unsigned long thislen; | 1451 | unsigned long thislen; |
1452 | 1452 | ||
1453 | if (chipnum >= cfi->numchips) | 1453 | if (chipnum >= cfi->numchips) |
1454 | break; | 1454 | break; |
1455 | 1455 | ||
1456 | if ((len + ofs -1) >> cfi->chipshift) | 1456 | if ((len + ofs -1) >> cfi->chipshift) |
1457 | thislen = (1<<cfi->chipshift) - ofs; | 1457 | thislen = (1<<cfi->chipshift) - ofs; |
1458 | else | 1458 | else |
1459 | thislen = len; | 1459 | thislen = len; |
1460 | 1460 | ||
1461 | ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); | 1461 | ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); |
1462 | if (ret) | 1462 | if (ret) |
1463 | break; | 1463 | break; |
1464 | 1464 | ||
1465 | *retlen += thislen; | 1465 | *retlen += thislen; |
1466 | len -= thislen; | 1466 | len -= thislen; |
1467 | buf += thislen; | 1467 | buf += thislen; |
1468 | 1468 | ||
1469 | ofs = 0; | 1469 | ofs = 0; |
1470 | chipnum++; | 1470 | chipnum++; |
1471 | } | 1471 | } |
1472 | return ret; | 1472 | return ret; |
1473 | } | 1473 | } |
1474 | 1474 | ||
1475 | static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | 1475 | static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, |
1476 | unsigned long adr, map_word datum, int mode) | 1476 | unsigned long adr, map_word datum, int mode) |
1477 | { | 1477 | { |
1478 | struct cfi_private *cfi = map->fldrv_priv; | 1478 | struct cfi_private *cfi = map->fldrv_priv; |
1479 | map_word status, write_cmd; | 1479 | map_word status, write_cmd; |
1480 | int ret=0; | 1480 | int ret=0; |
1481 | 1481 | ||
1482 | adr += chip->start; | 1482 | adr += chip->start; |
1483 | 1483 | ||
1484 | switch (mode) { | 1484 | switch (mode) { |
1485 | case FL_WRITING: | 1485 | case FL_WRITING: |
1486 | write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41); | 1486 | write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41); |
1487 | break; | 1487 | break; |
1488 | case FL_OTP_WRITE: | 1488 | case FL_OTP_WRITE: |
1489 | write_cmd = CMD(0xc0); | 1489 | write_cmd = CMD(0xc0); |
1490 | break; | 1490 | break; |
1491 | default: | 1491 | default: |
1492 | return -EINVAL; | 1492 | return -EINVAL; |
1493 | } | 1493 | } |
1494 | 1494 | ||
1495 | spin_lock(chip->mutex); | 1495 | spin_lock(chip->mutex); |
1496 | ret = get_chip(map, chip, adr, mode); | 1496 | ret = get_chip(map, chip, adr, mode); |
1497 | if (ret) { | 1497 | if (ret) { |
1498 | spin_unlock(chip->mutex); | 1498 | spin_unlock(chip->mutex); |
1499 | return ret; | 1499 | return ret; |
1500 | } | 1500 | } |
1501 | 1501 | ||
1502 | XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map)); | 1502 | XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map)); |
1503 | ENABLE_VPP(map); | 1503 | ENABLE_VPP(map); |
1504 | xip_disable(map, chip, adr); | 1504 | xip_disable(map, chip, adr); |
1505 | map_write(map, write_cmd, adr); | 1505 | map_write(map, write_cmd, adr); |
1506 | map_write(map, datum, adr); | 1506 | map_write(map, datum, adr); |
1507 | chip->state = mode; | 1507 | chip->state = mode; |
1508 | 1508 | ||
1509 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, | 1509 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1510 | adr, map_bankwidth(map), | 1510 | adr, map_bankwidth(map), |
1511 | chip->word_write_time, | 1511 | chip->word_write_time, |
1512 | chip->word_write_time_max); | 1512 | chip->word_write_time_max); |
1513 | if (ret) { | 1513 | if (ret) { |
1514 | xip_enable(map, chip, adr); | 1514 | xip_enable(map, chip, adr); |
1515 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); | 1515 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); |
1516 | goto out; | 1516 | goto out; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | /* check for errors */ | 1519 | /* check for errors */ |
1520 | status = map_read(map, adr); | 1520 | status = map_read(map, adr); |
1521 | if (map_word_bitsset(map, status, CMD(0x1a))) { | 1521 | if (map_word_bitsset(map, status, CMD(0x1a))) { |
1522 | unsigned long chipstatus = MERGESTATUS(status); | 1522 | unsigned long chipstatus = MERGESTATUS(status); |
1523 | 1523 | ||
1524 | /* reset status */ | 1524 | /* reset status */ |
1525 | map_write(map, CMD(0x50), adr); | 1525 | map_write(map, CMD(0x50), adr); |
1526 | map_write(map, CMD(0x70), adr); | 1526 | map_write(map, CMD(0x70), adr); |
1527 | xip_enable(map, chip, adr); | 1527 | xip_enable(map, chip, adr); |
1528 | 1528 | ||
1529 | if (chipstatus & 0x02) { | 1529 | if (chipstatus & 0x02) { |
1530 | ret = -EROFS; | 1530 | ret = -EROFS; |
1531 | } else if (chipstatus & 0x08) { | 1531 | } else if (chipstatus & 0x08) { |
1532 | printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name); | 1532 | printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name); |
1533 | ret = -EIO; | 1533 | ret = -EIO; |
1534 | } else { | 1534 | } else { |
1535 | printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus); | 1535 | printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus); |
1536 | ret = -EINVAL; | 1536 | ret = -EINVAL; |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | goto out; | 1539 | goto out; |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | xip_enable(map, chip, adr); | 1542 | xip_enable(map, chip, adr); |
1543 | out: put_chip(map, chip, adr); | 1543 | out: put_chip(map, chip, adr); |
1544 | spin_unlock(chip->mutex); | 1544 | spin_unlock(chip->mutex); |
1545 | return ret; | 1545 | return ret; |
1546 | } | 1546 | } |
1547 | 1547 | ||
1548 | 1548 | ||
1549 | static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf) | 1549 | static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf) |
1550 | { | 1550 | { |
1551 | struct map_info *map = mtd->priv; | 1551 | struct map_info *map = mtd->priv; |
1552 | struct cfi_private *cfi = map->fldrv_priv; | 1552 | struct cfi_private *cfi = map->fldrv_priv; |
1553 | int ret = 0; | 1553 | int ret = 0; |
1554 | int chipnum; | 1554 | int chipnum; |
1555 | unsigned long ofs; | 1555 | unsigned long ofs; |
1556 | 1556 | ||
1557 | *retlen = 0; | 1557 | *retlen = 0; |
1558 | if (!len) | 1558 | if (!len) |
1559 | return 0; | 1559 | return 0; |
1560 | 1560 | ||
1561 | chipnum = to >> cfi->chipshift; | 1561 | chipnum = to >> cfi->chipshift; |
1562 | ofs = to - (chipnum << cfi->chipshift); | 1562 | ofs = to - (chipnum << cfi->chipshift); |
1563 | 1563 | ||
1564 | /* If it's not bus-aligned, do the first byte write */ | 1564 | /* If it's not bus-aligned, do the first byte write */ |
1565 | if (ofs & (map_bankwidth(map)-1)) { | 1565 | if (ofs & (map_bankwidth(map)-1)) { |
1566 | unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1); | 1566 | unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1); |
1567 | int gap = ofs - bus_ofs; | 1567 | int gap = ofs - bus_ofs; |
1568 | int n; | 1568 | int n; |
1569 | map_word datum; | 1569 | map_word datum; |
1570 | 1570 | ||
1571 | n = min_t(int, len, map_bankwidth(map)-gap); | 1571 | n = min_t(int, len, map_bankwidth(map)-gap); |
1572 | datum = map_word_ff(map); | 1572 | datum = map_word_ff(map); |
1573 | datum = map_word_load_partial(map, datum, buf, gap, n); | 1573 | datum = map_word_load_partial(map, datum, buf, gap, n); |
1574 | 1574 | ||
1575 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1575 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1576 | bus_ofs, datum, FL_WRITING); | 1576 | bus_ofs, datum, FL_WRITING); |
1577 | if (ret) | 1577 | if (ret) |
1578 | return ret; | 1578 | return ret; |
1579 | 1579 | ||
1580 | len -= n; | 1580 | len -= n; |
1581 | ofs += n; | 1581 | ofs += n; |
1582 | buf += n; | 1582 | buf += n; |
1583 | (*retlen) += n; | 1583 | (*retlen) += n; |
1584 | 1584 | ||
1585 | if (ofs >> cfi->chipshift) { | 1585 | if (ofs >> cfi->chipshift) { |
1586 | chipnum ++; | 1586 | chipnum ++; |
1587 | ofs = 0; | 1587 | ofs = 0; |
1588 | if (chipnum == cfi->numchips) | 1588 | if (chipnum == cfi->numchips) |
1589 | return 0; | 1589 | return 0; |
1590 | } | 1590 | } |
1591 | } | 1591 | } |
1592 | 1592 | ||
1593 | while(len >= map_bankwidth(map)) { | 1593 | while(len >= map_bankwidth(map)) { |
1594 | map_word datum = map_word_load(map, buf); | 1594 | map_word datum = map_word_load(map, buf); |
1595 | 1595 | ||
1596 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1596 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1597 | ofs, datum, FL_WRITING); | 1597 | ofs, datum, FL_WRITING); |
1598 | if (ret) | 1598 | if (ret) |
1599 | return ret; | 1599 | return ret; |
1600 | 1600 | ||
1601 | ofs += map_bankwidth(map); | 1601 | ofs += map_bankwidth(map); |
1602 | buf += map_bankwidth(map); | 1602 | buf += map_bankwidth(map); |
1603 | (*retlen) += map_bankwidth(map); | 1603 | (*retlen) += map_bankwidth(map); |
1604 | len -= map_bankwidth(map); | 1604 | len -= map_bankwidth(map); |
1605 | 1605 | ||
1606 | if (ofs >> cfi->chipshift) { | 1606 | if (ofs >> cfi->chipshift) { |
1607 | chipnum ++; | 1607 | chipnum ++; |
1608 | ofs = 0; | 1608 | ofs = 0; |
1609 | if (chipnum == cfi->numchips) | 1609 | if (chipnum == cfi->numchips) |
1610 | return 0; | 1610 | return 0; |
1611 | } | 1611 | } |
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | if (len & (map_bankwidth(map)-1)) { | 1614 | if (len & (map_bankwidth(map)-1)) { |
1615 | map_word datum; | 1615 | map_word datum; |
1616 | 1616 | ||
1617 | datum = map_word_ff(map); | 1617 | datum = map_word_ff(map); |
1618 | datum = map_word_load_partial(map, datum, buf, 0, len); | 1618 | datum = map_word_load_partial(map, datum, buf, 0, len); |
1619 | 1619 | ||
1620 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1620 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1621 | ofs, datum, FL_WRITING); | 1621 | ofs, datum, FL_WRITING); |
1622 | if (ret) | 1622 | if (ret) |
1623 | return ret; | 1623 | return ret; |
1624 | 1624 | ||
1625 | (*retlen) += len; | 1625 | (*retlen) += len; |
1626 | } | 1626 | } |
1627 | 1627 | ||
1628 | return 0; | 1628 | return 0; |
1629 | } | 1629 | } |
1630 | 1630 | ||
1631 | 1631 | ||
1632 | static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | 1632 | static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, |
1633 | unsigned long adr, const struct kvec **pvec, | 1633 | unsigned long adr, const struct kvec **pvec, |
1634 | unsigned long *pvec_seek, int len) | 1634 | unsigned long *pvec_seek, int len) |
1635 | { | 1635 | { |
1636 | struct cfi_private *cfi = map->fldrv_priv; | 1636 | struct cfi_private *cfi = map->fldrv_priv; |
1637 | map_word status, write_cmd, datum; | 1637 | map_word status, write_cmd, datum; |
1638 | unsigned long cmd_adr; | 1638 | unsigned long cmd_adr; |
1639 | int ret, wbufsize, word_gap, words; | 1639 | int ret, wbufsize, word_gap, words; |
1640 | const struct kvec *vec; | 1640 | const struct kvec *vec; |
1641 | unsigned long vec_seek; | 1641 | unsigned long vec_seek; |
1642 | unsigned long initial_adr; | 1642 | unsigned long initial_adr; |
1643 | int initial_len = len; | 1643 | int initial_len = len; |
1644 | 1644 | ||
1645 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; | 1645 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; |
1646 | adr += chip->start; | 1646 | adr += chip->start; |
1647 | initial_adr = adr; | 1647 | initial_adr = adr; |
1648 | cmd_adr = adr & ~(wbufsize-1); | 1648 | cmd_adr = adr & ~(wbufsize-1); |
1649 | 1649 | ||
1650 | /* Let's determine this according to the interleave only once */ | 1650 | /* Let's determine this according to the interleave only once */ |
1651 | write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9); | 1651 | write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9); |
1652 | 1652 | ||
1653 | spin_lock(chip->mutex); | 1653 | spin_lock(chip->mutex); |
1654 | ret = get_chip(map, chip, cmd_adr, FL_WRITING); | 1654 | ret = get_chip(map, chip, cmd_adr, FL_WRITING); |
1655 | if (ret) { | 1655 | if (ret) { |
1656 | spin_unlock(chip->mutex); | 1656 | spin_unlock(chip->mutex); |
1657 | return ret; | 1657 | return ret; |
1658 | } | 1658 | } |
1659 | 1659 | ||
1660 | XIP_INVAL_CACHED_RANGE(map, initial_adr, initial_len); | 1660 | XIP_INVAL_CACHED_RANGE(map, initial_adr, initial_len); |
1661 | ENABLE_VPP(map); | 1661 | ENABLE_VPP(map); |
1662 | xip_disable(map, chip, cmd_adr); | 1662 | xip_disable(map, chip, cmd_adr); |
1663 | 1663 | ||
1664 | /* ยง4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set | 1664 | /* ยง4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set |
1665 | [...], the device will not accept any more Write to Buffer commands". | 1665 | [...], the device will not accept any more Write to Buffer commands". |
1666 | So we must check here and reset those bits if they're set. Otherwise | 1666 | So we must check here and reset those bits if they're set. Otherwise |
1667 | we're just pissing in the wind */ | 1667 | we're just pissing in the wind */ |
1668 | if (chip->state != FL_STATUS) { | 1668 | if (chip->state != FL_STATUS) { |
1669 | map_write(map, CMD(0x70), cmd_adr); | 1669 | map_write(map, CMD(0x70), cmd_adr); |
1670 | chip->state = FL_STATUS; | 1670 | chip->state = FL_STATUS; |
1671 | } | 1671 | } |
1672 | status = map_read(map, cmd_adr); | 1672 | status = map_read(map, cmd_adr); |
1673 | if (map_word_bitsset(map, status, CMD(0x30))) { | 1673 | if (map_word_bitsset(map, status, CMD(0x30))) { |
1674 | xip_enable(map, chip, cmd_adr); | 1674 | xip_enable(map, chip, cmd_adr); |
1675 | printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %lx). Clearing.\n", status.x[0]); | 1675 | printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %lx). Clearing.\n", status.x[0]); |
1676 | xip_disable(map, chip, cmd_adr); | 1676 | xip_disable(map, chip, cmd_adr); |
1677 | map_write(map, CMD(0x50), cmd_adr); | 1677 | map_write(map, CMD(0x50), cmd_adr); |
1678 | map_write(map, CMD(0x70), cmd_adr); | 1678 | map_write(map, CMD(0x70), cmd_adr); |
1679 | } | 1679 | } |
1680 | 1680 | ||
1681 | chip->state = FL_WRITING_TO_BUFFER; | 1681 | chip->state = FL_WRITING_TO_BUFFER; |
1682 | map_write(map, write_cmd, cmd_adr); | 1682 | map_write(map, write_cmd, cmd_adr); |
1683 | ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0); | 1683 | ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0); |
1684 | if (ret) { | 1684 | if (ret) { |
1685 | /* Argh. Not ready for write to buffer */ | 1685 | /* Argh. Not ready for write to buffer */ |
1686 | map_word Xstatus = map_read(map, cmd_adr); | 1686 | map_word Xstatus = map_read(map, cmd_adr); |
1687 | map_write(map, CMD(0x70), cmd_adr); | 1687 | map_write(map, CMD(0x70), cmd_adr); |
1688 | chip->state = FL_STATUS; | 1688 | chip->state = FL_STATUS; |
1689 | status = map_read(map, cmd_adr); | 1689 | status = map_read(map, cmd_adr); |
1690 | map_write(map, CMD(0x50), cmd_adr); | 1690 | map_write(map, CMD(0x50), cmd_adr); |
1691 | map_write(map, CMD(0x70), cmd_adr); | 1691 | map_write(map, CMD(0x70), cmd_adr); |
1692 | xip_enable(map, chip, cmd_adr); | 1692 | xip_enable(map, chip, cmd_adr); |
1693 | printk(KERN_ERR "%s: Chip not ready for buffer write. Xstatus = %lx, status = %lx\n", | 1693 | printk(KERN_ERR "%s: Chip not ready for buffer write. Xstatus = %lx, status = %lx\n", |
1694 | map->name, Xstatus.x[0], status.x[0]); | 1694 | map->name, Xstatus.x[0], status.x[0]); |
1695 | goto out; | 1695 | goto out; |
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | /* Figure out the number of words to write */ | 1698 | /* Figure out the number of words to write */ |
1699 | word_gap = (-adr & (map_bankwidth(map)-1)); | 1699 | word_gap = (-adr & (map_bankwidth(map)-1)); |
1700 | words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map)); | 1700 | words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map)); |
1701 | if (!word_gap) { | 1701 | if (!word_gap) { |
1702 | words--; | 1702 | words--; |
1703 | } else { | 1703 | } else { |
1704 | word_gap = map_bankwidth(map) - word_gap; | 1704 | word_gap = map_bankwidth(map) - word_gap; |
1705 | adr -= word_gap; | 1705 | adr -= word_gap; |
1706 | datum = map_word_ff(map); | 1706 | datum = map_word_ff(map); |
1707 | } | 1707 | } |
1708 | 1708 | ||
1709 | /* Write length of data to come */ | 1709 | /* Write length of data to come */ |
1710 | map_write(map, CMD(words), cmd_adr ); | 1710 | map_write(map, CMD(words), cmd_adr ); |
1711 | 1711 | ||
1712 | /* Write data */ | 1712 | /* Write data */ |
1713 | vec = *pvec; | 1713 | vec = *pvec; |
1714 | vec_seek = *pvec_seek; | 1714 | vec_seek = *pvec_seek; |
1715 | do { | 1715 | do { |
1716 | int n = map_bankwidth(map) - word_gap; | 1716 | int n = map_bankwidth(map) - word_gap; |
1717 | if (n > vec->iov_len - vec_seek) | 1717 | if (n > vec->iov_len - vec_seek) |
1718 | n = vec->iov_len - vec_seek; | 1718 | n = vec->iov_len - vec_seek; |
1719 | if (n > len) | 1719 | if (n > len) |
1720 | n = len; | 1720 | n = len; |
1721 | 1721 | ||
1722 | if (!word_gap && len < map_bankwidth(map)) | 1722 | if (!word_gap && len < map_bankwidth(map)) |
1723 | datum = map_word_ff(map); | 1723 | datum = map_word_ff(map); |
1724 | 1724 | ||
1725 | datum = map_word_load_partial(map, datum, | 1725 | datum = map_word_load_partial(map, datum, |
1726 | vec->iov_base + vec_seek, | 1726 | vec->iov_base + vec_seek, |
1727 | word_gap, n); | 1727 | word_gap, n); |
1728 | 1728 | ||
1729 | len -= n; | 1729 | len -= n; |
1730 | word_gap += n; | 1730 | word_gap += n; |
1731 | if (!len || word_gap == map_bankwidth(map)) { | 1731 | if (!len || word_gap == map_bankwidth(map)) { |
1732 | map_write(map, datum, adr); | 1732 | map_write(map, datum, adr); |
1733 | adr += map_bankwidth(map); | 1733 | adr += map_bankwidth(map); |
1734 | word_gap = 0; | 1734 | word_gap = 0; |
1735 | } | 1735 | } |
1736 | 1736 | ||
1737 | vec_seek += n; | 1737 | vec_seek += n; |
1738 | if (vec_seek == vec->iov_len) { | 1738 | if (vec_seek == vec->iov_len) { |
1739 | vec++; | 1739 | vec++; |
1740 | vec_seek = 0; | 1740 | vec_seek = 0; |
1741 | } | 1741 | } |
1742 | } while (len); | 1742 | } while (len); |
1743 | *pvec = vec; | 1743 | *pvec = vec; |
1744 | *pvec_seek = vec_seek; | 1744 | *pvec_seek = vec_seek; |
1745 | 1745 | ||
1746 | /* GO GO GO */ | 1746 | /* GO GO GO */ |
1747 | map_write(map, CMD(0xd0), cmd_adr); | 1747 | map_write(map, CMD(0xd0), cmd_adr); |
1748 | chip->state = FL_WRITING; | 1748 | chip->state = FL_WRITING; |
1749 | 1749 | ||
1750 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, | 1750 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, |
1751 | initial_adr, initial_len, | 1751 | initial_adr, initial_len, |
1752 | chip->buffer_write_time, | 1752 | chip->buffer_write_time, |
1753 | chip->buffer_write_time_max); | 1753 | chip->buffer_write_time_max); |
1754 | if (ret) { | 1754 | if (ret) { |
1755 | map_write(map, CMD(0x70), cmd_adr); | 1755 | map_write(map, CMD(0x70), cmd_adr); |
1756 | chip->state = FL_STATUS; | 1756 | chip->state = FL_STATUS; |
1757 | xip_enable(map, chip, cmd_adr); | 1757 | xip_enable(map, chip, cmd_adr); |
1758 | printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name); | 1758 | printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name); |
1759 | goto out; | 1759 | goto out; |
1760 | } | 1760 | } |
1761 | 1761 | ||
1762 | /* check for errors */ | 1762 | /* check for errors */ |
1763 | status = map_read(map, cmd_adr); | 1763 | status = map_read(map, cmd_adr); |
1764 | if (map_word_bitsset(map, status, CMD(0x1a))) { | 1764 | if (map_word_bitsset(map, status, CMD(0x1a))) { |
1765 | unsigned long chipstatus = MERGESTATUS(status); | 1765 | unsigned long chipstatus = MERGESTATUS(status); |
1766 | 1766 | ||
1767 | /* reset status */ | 1767 | /* reset status */ |
1768 | map_write(map, CMD(0x50), cmd_adr); | 1768 | map_write(map, CMD(0x50), cmd_adr); |
1769 | map_write(map, CMD(0x70), cmd_adr); | 1769 | map_write(map, CMD(0x70), cmd_adr); |
1770 | xip_enable(map, chip, cmd_adr); | 1770 | xip_enable(map, chip, cmd_adr); |
1771 | 1771 | ||
1772 | if (chipstatus & 0x02) { | 1772 | if (chipstatus & 0x02) { |
1773 | ret = -EROFS; | 1773 | ret = -EROFS; |
1774 | } else if (chipstatus & 0x08) { | 1774 | } else if (chipstatus & 0x08) { |
1775 | printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name); | 1775 | printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name); |
1776 | ret = -EIO; | 1776 | ret = -EIO; |
1777 | } else { | 1777 | } else { |
1778 | printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus); | 1778 | printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus); |
1779 | ret = -EINVAL; | 1779 | ret = -EINVAL; |
1780 | } | 1780 | } |
1781 | 1781 | ||
1782 | goto out; | 1782 | goto out; |
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | xip_enable(map, chip, cmd_adr); | 1785 | xip_enable(map, chip, cmd_adr); |
1786 | out: put_chip(map, chip, cmd_adr); | 1786 | out: put_chip(map, chip, cmd_adr); |
1787 | spin_unlock(chip->mutex); | 1787 | spin_unlock(chip->mutex); |
1788 | return ret; | 1788 | return ret; |
1789 | } | 1789 | } |
1790 | 1790 | ||
1791 | static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs, | 1791 | static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs, |
1792 | unsigned long count, loff_t to, size_t *retlen) | 1792 | unsigned long count, loff_t to, size_t *retlen) |
1793 | { | 1793 | { |
1794 | struct map_info *map = mtd->priv; | 1794 | struct map_info *map = mtd->priv; |
1795 | struct cfi_private *cfi = map->fldrv_priv; | 1795 | struct cfi_private *cfi = map->fldrv_priv; |
1796 | int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; | 1796 | int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; |
1797 | int ret = 0; | 1797 | int ret = 0; |
1798 | int chipnum; | 1798 | int chipnum; |
1799 | unsigned long ofs, vec_seek, i; | 1799 | unsigned long ofs, vec_seek, i; |
1800 | size_t len = 0; | 1800 | size_t len = 0; |
1801 | 1801 | ||
1802 | for (i = 0; i < count; i++) | 1802 | for (i = 0; i < count; i++) |
1803 | len += vecs[i].iov_len; | 1803 | len += vecs[i].iov_len; |
1804 | 1804 | ||
1805 | *retlen = 0; | 1805 | *retlen = 0; |
1806 | if (!len) | 1806 | if (!len) |
1807 | return 0; | 1807 | return 0; |
1808 | 1808 | ||
1809 | chipnum = to >> cfi->chipshift; | 1809 | chipnum = to >> cfi->chipshift; |
1810 | ofs = to - (chipnum << cfi->chipshift); | 1810 | ofs = to - (chipnum << cfi->chipshift); |
1811 | vec_seek = 0; | 1811 | vec_seek = 0; |
1812 | 1812 | ||
1813 | do { | 1813 | do { |
1814 | /* We must not cross write block boundaries */ | 1814 | /* We must not cross write block boundaries */ |
1815 | int size = wbufsize - (ofs & (wbufsize-1)); | 1815 | int size = wbufsize - (ofs & (wbufsize-1)); |
1816 | 1816 | ||
1817 | if (size > len) | 1817 | if (size > len) |
1818 | size = len; | 1818 | size = len; |
1819 | ret = do_write_buffer(map, &cfi->chips[chipnum], | 1819 | ret = do_write_buffer(map, &cfi->chips[chipnum], |
1820 | ofs, &vecs, &vec_seek, size); | 1820 | ofs, &vecs, &vec_seek, size); |
1821 | if (ret) | 1821 | if (ret) |
1822 | return ret; | 1822 | return ret; |
1823 | 1823 | ||
1824 | ofs += size; | 1824 | ofs += size; |
1825 | (*retlen) += size; | 1825 | (*retlen) += size; |
1826 | len -= size; | 1826 | len -= size; |
1827 | 1827 | ||
1828 | if (ofs >> cfi->chipshift) { | 1828 | if (ofs >> cfi->chipshift) { |
1829 | chipnum ++; | 1829 | chipnum ++; |
1830 | ofs = 0; | 1830 | ofs = 0; |
1831 | if (chipnum == cfi->numchips) | 1831 | if (chipnum == cfi->numchips) |
1832 | return 0; | 1832 | return 0; |
1833 | } | 1833 | } |
1834 | 1834 | ||
1835 | /* Be nice and reschedule with the chip in a usable state for other | 1835 | /* Be nice and reschedule with the chip in a usable state for other |
1836 | processes. */ | 1836 | processes. */ |
1837 | cond_resched(); | 1837 | cond_resched(); |
1838 | 1838 | ||
1839 | } while (len); | 1839 | } while (len); |
1840 | 1840 | ||
1841 | return 0; | 1841 | return 0; |
1842 | } | 1842 | } |
1843 | 1843 | ||
1844 | static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, | 1844 | static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, |
1845 | size_t len, size_t *retlen, const u_char *buf) | 1845 | size_t len, size_t *retlen, const u_char *buf) |
1846 | { | 1846 | { |
1847 | struct kvec vec; | 1847 | struct kvec vec; |
1848 | 1848 | ||
1849 | vec.iov_base = (void *) buf; | 1849 | vec.iov_base = (void *) buf; |
1850 | vec.iov_len = len; | 1850 | vec.iov_len = len; |
1851 | 1851 | ||
1852 | return cfi_intelext_writev(mtd, &vec, 1, to, retlen); | 1852 | return cfi_intelext_writev(mtd, &vec, 1, to, retlen); |
1853 | } | 1853 | } |
1854 | 1854 | ||
1855 | static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | 1855 | static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, |
1856 | unsigned long adr, int len, void *thunk) | 1856 | unsigned long adr, int len, void *thunk) |
1857 | { | 1857 | { |
1858 | struct cfi_private *cfi = map->fldrv_priv; | 1858 | struct cfi_private *cfi = map->fldrv_priv; |
1859 | map_word status; | 1859 | map_word status; |
1860 | int retries = 3; | 1860 | int retries = 3; |
1861 | int ret; | 1861 | int ret; |
1862 | 1862 | ||
1863 | adr += chip->start; | 1863 | adr += chip->start; |
1864 | 1864 | ||
1865 | retry: | 1865 | retry: |
1866 | spin_lock(chip->mutex); | 1866 | spin_lock(chip->mutex); |
1867 | ret = get_chip(map, chip, adr, FL_ERASING); | 1867 | ret = get_chip(map, chip, adr, FL_ERASING); |
1868 | if (ret) { | 1868 | if (ret) { |
1869 | spin_unlock(chip->mutex); | 1869 | spin_unlock(chip->mutex); |
1870 | return ret; | 1870 | return ret; |
1871 | } | 1871 | } |
1872 | 1872 | ||
1873 | XIP_INVAL_CACHED_RANGE(map, adr, len); | 1873 | XIP_INVAL_CACHED_RANGE(map, adr, len); |
1874 | ENABLE_VPP(map); | 1874 | ENABLE_VPP(map); |
1875 | xip_disable(map, chip, adr); | 1875 | xip_disable(map, chip, adr); |
1876 | 1876 | ||
1877 | /* Clear the status register first */ | 1877 | /* Clear the status register first */ |
1878 | map_write(map, CMD(0x50), adr); | 1878 | map_write(map, CMD(0x50), adr); |
1879 | 1879 | ||
1880 | /* Now erase */ | 1880 | /* Now erase */ |
1881 | map_write(map, CMD(0x20), adr); | 1881 | map_write(map, CMD(0x20), adr); |
1882 | map_write(map, CMD(0xD0), adr); | 1882 | map_write(map, CMD(0xD0), adr); |
1883 | chip->state = FL_ERASING; | 1883 | chip->state = FL_ERASING; |
1884 | chip->erase_suspended = 0; | 1884 | chip->erase_suspended = 0; |
1885 | 1885 | ||
1886 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, | 1886 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1887 | adr, len, | 1887 | adr, len, |
1888 | chip->erase_time, | 1888 | chip->erase_time, |
1889 | chip->erase_time_max); | 1889 | chip->erase_time_max); |
1890 | if (ret) { | 1890 | if (ret) { |
1891 | map_write(map, CMD(0x70), adr); | 1891 | map_write(map, CMD(0x70), adr); |
1892 | chip->state = FL_STATUS; | 1892 | chip->state = FL_STATUS; |
1893 | xip_enable(map, chip, adr); | 1893 | xip_enable(map, chip, adr); |
1894 | printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name); | 1894 | printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name); |
1895 | goto out; | 1895 | goto out; |
1896 | } | 1896 | } |
1897 | 1897 | ||
1898 | /* We've broken this before. It doesn't hurt to be safe */ | 1898 | /* We've broken this before. It doesn't hurt to be safe */ |
1899 | map_write(map, CMD(0x70), adr); | 1899 | map_write(map, CMD(0x70), adr); |
1900 | chip->state = FL_STATUS; | 1900 | chip->state = FL_STATUS; |
1901 | status = map_read(map, adr); | 1901 | status = map_read(map, adr); |
1902 | 1902 | ||
1903 | /* check for errors */ | 1903 | /* check for errors */ |
1904 | if (map_word_bitsset(map, status, CMD(0x3a))) { | 1904 | if (map_word_bitsset(map, status, CMD(0x3a))) { |
1905 | unsigned long chipstatus = MERGESTATUS(status); | 1905 | unsigned long chipstatus = MERGESTATUS(status); |
1906 | 1906 | ||
1907 | /* Reset the error bits */ | 1907 | /* Reset the error bits */ |
1908 | map_write(map, CMD(0x50), adr); | 1908 | map_write(map, CMD(0x50), adr); |
1909 | map_write(map, CMD(0x70), adr); | 1909 | map_write(map, CMD(0x70), adr); |
1910 | xip_enable(map, chip, adr); | 1910 | xip_enable(map, chip, adr); |
1911 | 1911 | ||
1912 | if ((chipstatus & 0x30) == 0x30) { | 1912 | if ((chipstatus & 0x30) == 0x30) { |
1913 | printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipstatus); | 1913 | printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipstatus); |
1914 | ret = -EINVAL; | 1914 | ret = -EINVAL; |
1915 | } else if (chipstatus & 0x02) { | 1915 | } else if (chipstatus & 0x02) { |
1916 | /* Protection bit set */ | 1916 | /* Protection bit set */ |
1917 | ret = -EROFS; | 1917 | ret = -EROFS; |
1918 | } else if (chipstatus & 0x8) { | 1918 | } else if (chipstatus & 0x8) { |
1919 | /* Voltage */ | 1919 | /* Voltage */ |
1920 | printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name); | 1920 | printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name); |
1921 | ret = -EIO; | 1921 | ret = -EIO; |
1922 | } else if (chipstatus & 0x20 && retries--) { | 1922 | } else if (chipstatus & 0x20 && retries--) { |
1923 | printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); | 1923 | printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); |
1924 | put_chip(map, chip, adr); | 1924 | put_chip(map, chip, adr); |
1925 | spin_unlock(chip->mutex); | 1925 | spin_unlock(chip->mutex); |
1926 | goto retry; | 1926 | goto retry; |
1927 | } else { | 1927 | } else { |
1928 | printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus); | 1928 | printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus); |
1929 | ret = -EIO; | 1929 | ret = -EIO; |
1930 | } | 1930 | } |
1931 | 1931 | ||
1932 | goto out; | 1932 | goto out; |
1933 | } | 1933 | } |
1934 | 1934 | ||
1935 | xip_enable(map, chip, adr); | 1935 | xip_enable(map, chip, adr); |
1936 | out: put_chip(map, chip, adr); | 1936 | out: put_chip(map, chip, adr); |
1937 | spin_unlock(chip->mutex); | 1937 | spin_unlock(chip->mutex); |
1938 | return ret; | 1938 | return ret; |
1939 | } | 1939 | } |
1940 | 1940 | ||
1941 | static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | 1941 | static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) |
1942 | { | 1942 | { |
1943 | unsigned long ofs, len; | 1943 | unsigned long ofs, len; |
1944 | int ret; | 1944 | int ret; |
1945 | 1945 | ||
1946 | ofs = instr->addr; | 1946 | ofs = instr->addr; |
1947 | len = instr->len; | 1947 | len = instr->len; |
1948 | 1948 | ||
1949 | ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL); | 1949 | ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL); |
1950 | if (ret) | 1950 | if (ret) |
1951 | return ret; | 1951 | return ret; |
1952 | 1952 | ||
1953 | instr->state = MTD_ERASE_DONE; | 1953 | instr->state = MTD_ERASE_DONE; |
1954 | mtd_erase_callback(instr); | 1954 | mtd_erase_callback(instr); |
1955 | 1955 | ||
1956 | return 0; | 1956 | return 0; |
1957 | } | 1957 | } |
1958 | 1958 | ||
1959 | static void cfi_intelext_sync (struct mtd_info *mtd) | 1959 | static void cfi_intelext_sync (struct mtd_info *mtd) |
1960 | { | 1960 | { |
1961 | struct map_info *map = mtd->priv; | 1961 | struct map_info *map = mtd->priv; |
1962 | struct cfi_private *cfi = map->fldrv_priv; | 1962 | struct cfi_private *cfi = map->fldrv_priv; |
1963 | int i; | 1963 | int i; |
1964 | struct flchip *chip; | 1964 | struct flchip *chip; |
1965 | int ret = 0; | 1965 | int ret = 0; |
1966 | 1966 | ||
1967 | for (i=0; !ret && i<cfi->numchips; i++) { | 1967 | for (i=0; !ret && i<cfi->numchips; i++) { |
1968 | chip = &cfi->chips[i]; | 1968 | chip = &cfi->chips[i]; |
1969 | 1969 | ||
1970 | spin_lock(chip->mutex); | 1970 | spin_lock(chip->mutex); |
1971 | ret = get_chip(map, chip, chip->start, FL_SYNCING); | 1971 | ret = get_chip(map, chip, chip->start, FL_SYNCING); |
1972 | 1972 | ||
1973 | if (!ret) { | 1973 | if (!ret) { |
1974 | chip->oldstate = chip->state; | 1974 | chip->oldstate = chip->state; |
1975 | chip->state = FL_SYNCING; | 1975 | chip->state = FL_SYNCING; |
1976 | /* No need to wake_up() on this state change - | 1976 | /* No need to wake_up() on this state change - |
1977 | * as the whole point is that nobody can do anything | 1977 | * as the whole point is that nobody can do anything |
1978 | * with the chip now anyway. | 1978 | * with the chip now anyway. |
1979 | */ | 1979 | */ |
1980 | } | 1980 | } |
1981 | spin_unlock(chip->mutex); | 1981 | spin_unlock(chip->mutex); |
1982 | } | 1982 | } |
1983 | 1983 | ||
1984 | /* Unlock the chips again */ | 1984 | /* Unlock the chips again */ |
1985 | 1985 | ||
1986 | for (i--; i >=0; i--) { | 1986 | for (i--; i >=0; i--) { |
1987 | chip = &cfi->chips[i]; | 1987 | chip = &cfi->chips[i]; |
1988 | 1988 | ||
1989 | spin_lock(chip->mutex); | 1989 | spin_lock(chip->mutex); |
1990 | 1990 | ||
1991 | if (chip->state == FL_SYNCING) { | 1991 | if (chip->state == FL_SYNCING) { |
1992 | chip->state = chip->oldstate; | 1992 | chip->state = chip->oldstate; |
1993 | chip->oldstate = FL_READY; | 1993 | chip->oldstate = FL_READY; |
1994 | wake_up(&chip->wq); | 1994 | wake_up(&chip->wq); |
1995 | } | 1995 | } |
1996 | spin_unlock(chip->mutex); | 1996 | spin_unlock(chip->mutex); |
1997 | } | 1997 | } |
1998 | } | 1998 | } |
1999 | 1999 | ||
2000 | static int __xipram do_getlockstatus_oneblock(struct map_info *map, | 2000 | static int __xipram do_getlockstatus_oneblock(struct map_info *map, |
2001 | struct flchip *chip, | 2001 | struct flchip *chip, |
2002 | unsigned long adr, | 2002 | unsigned long adr, |
2003 | int len, void *thunk) | 2003 | int len, void *thunk) |
2004 | { | 2004 | { |
2005 | struct cfi_private *cfi = map->fldrv_priv; | 2005 | struct cfi_private *cfi = map->fldrv_priv; |
2006 | int status, ofs_factor = cfi->interleave * cfi->device_type; | 2006 | int status, ofs_factor = cfi->interleave * cfi->device_type; |
2007 | 2007 | ||
2008 | adr += chip->start; | 2008 | adr += chip->start; |
2009 | xip_disable(map, chip, adr+(2*ofs_factor)); | 2009 | xip_disable(map, chip, adr+(2*ofs_factor)); |
2010 | map_write(map, CMD(0x90), adr+(2*ofs_factor)); | 2010 | map_write(map, CMD(0x90), adr+(2*ofs_factor)); |
2011 | chip->state = FL_JEDEC_QUERY; | 2011 | chip->state = FL_JEDEC_QUERY; |
2012 | status = cfi_read_query(map, adr+(2*ofs_factor)); | 2012 | status = cfi_read_query(map, adr+(2*ofs_factor)); |
2013 | xip_enable(map, chip, 0); | 2013 | xip_enable(map, chip, 0); |
2014 | return status; | 2014 | return status; |
2015 | } | 2015 | } |
2016 | 2016 | ||
2017 | #ifdef DEBUG_LOCK_BITS | 2017 | #ifdef DEBUG_LOCK_BITS |
2018 | static int __xipram do_printlockstatus_oneblock(struct map_info *map, | 2018 | static int __xipram do_printlockstatus_oneblock(struct map_info *map, |
2019 | struct flchip *chip, | 2019 | struct flchip *chip, |
2020 | unsigned long adr, | 2020 | unsigned long adr, |
2021 | int len, void *thunk) | 2021 | int len, void *thunk) |
2022 | { | 2022 | { |
2023 | printk(KERN_DEBUG "block status register for 0x%08lx is %x\n", | 2023 | printk(KERN_DEBUG "block status register for 0x%08lx is %x\n", |
2024 | adr, do_getlockstatus_oneblock(map, chip, adr, len, thunk)); | 2024 | adr, do_getlockstatus_oneblock(map, chip, adr, len, thunk)); |
2025 | return 0; | 2025 | return 0; |
2026 | } | 2026 | } |
2027 | #endif | 2027 | #endif |
2028 | 2028 | ||
2029 | #define DO_XXLOCK_ONEBLOCK_LOCK ((void *) 1) | 2029 | #define DO_XXLOCK_ONEBLOCK_LOCK ((void *) 1) |
2030 | #define DO_XXLOCK_ONEBLOCK_UNLOCK ((void *) 2) | 2030 | #define DO_XXLOCK_ONEBLOCK_UNLOCK ((void *) 2) |
2031 | 2031 | ||
2032 | static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip, | 2032 | static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip, |
2033 | unsigned long adr, int len, void *thunk) | 2033 | unsigned long adr, int len, void *thunk) |
2034 | { | 2034 | { |
2035 | struct cfi_private *cfi = map->fldrv_priv; | 2035 | struct cfi_private *cfi = map->fldrv_priv; |
2036 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 2036 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
2037 | int udelay; | 2037 | int udelay; |
2038 | int ret; | 2038 | int ret; |
2039 | 2039 | ||
2040 | adr += chip->start; | 2040 | adr += chip->start; |
2041 | 2041 | ||
2042 | spin_lock(chip->mutex); | 2042 | spin_lock(chip->mutex); |
2043 | ret = get_chip(map, chip, adr, FL_LOCKING); | 2043 | ret = get_chip(map, chip, adr, FL_LOCKING); |
2044 | if (ret) { | 2044 | if (ret) { |
2045 | spin_unlock(chip->mutex); | 2045 | spin_unlock(chip->mutex); |
2046 | return ret; | 2046 | return ret; |
2047 | } | 2047 | } |
2048 | 2048 | ||
2049 | ENABLE_VPP(map); | 2049 | ENABLE_VPP(map); |
2050 | xip_disable(map, chip, adr); | 2050 | xip_disable(map, chip, adr); |
2051 | 2051 | ||
2052 | map_write(map, CMD(0x60), adr); | 2052 | map_write(map, CMD(0x60), adr); |
2053 | if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { | 2053 | if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { |
2054 | map_write(map, CMD(0x01), adr); | 2054 | map_write(map, CMD(0x01), adr); |
2055 | chip->state = FL_LOCKING; | 2055 | chip->state = FL_LOCKING; |
2056 | } else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) { | 2056 | } else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) { |
2057 | map_write(map, CMD(0xD0), adr); | 2057 | map_write(map, CMD(0xD0), adr); |
2058 | chip->state = FL_UNLOCKING; | 2058 | chip->state = FL_UNLOCKING; |
2059 | } else | 2059 | } else |
2060 | BUG(); | 2060 | BUG(); |
2061 | 2061 | ||
2062 | /* | 2062 | /* |
2063 | * If Instant Individual Block Locking supported then no need | 2063 | * If Instant Individual Block Locking supported then no need |
2064 | * to delay. | 2064 | * to delay. |
2065 | */ | 2065 | */ |
2066 | udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0; | 2066 | udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0; |
2067 | 2067 | ||
2068 | ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100); | 2068 | ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100); |
2069 | if (ret) { | 2069 | if (ret) { |
2070 | map_write(map, CMD(0x70), adr); | 2070 | map_write(map, CMD(0x70), adr); |
2071 | chip->state = FL_STATUS; | 2071 | chip->state = FL_STATUS; |
2072 | xip_enable(map, chip, adr); | 2072 | xip_enable(map, chip, adr); |
2073 | printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name); | 2073 | printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name); |
2074 | goto out; | 2074 | goto out; |
2075 | } | 2075 | } |
2076 | 2076 | ||
2077 | xip_enable(map, chip, adr); | 2077 | xip_enable(map, chip, adr); |
2078 | out: put_chip(map, chip, adr); | 2078 | out: put_chip(map, chip, adr); |
2079 | spin_unlock(chip->mutex); | 2079 | spin_unlock(chip->mutex); |
2080 | return ret; | 2080 | return ret; |
2081 | } | 2081 | } |
2082 | 2082 | ||
2083 | static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 2083 | static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
2084 | { | 2084 | { |
2085 | int ret; | 2085 | int ret; |
2086 | 2086 | ||
2087 | #ifdef DEBUG_LOCK_BITS | 2087 | #ifdef DEBUG_LOCK_BITS |
2088 | printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", | 2088 | printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", |
2089 | __func__, ofs, len); | 2089 | __func__, ofs, len); |
2090 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, | 2090 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, |
2091 | ofs, len, NULL); | 2091 | ofs, len, NULL); |
2092 | #endif | 2092 | #endif |
2093 | 2093 | ||
2094 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, | 2094 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, |
2095 | ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); | 2095 | ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); |
2096 | 2096 | ||
2097 | #ifdef DEBUG_LOCK_BITS | 2097 | #ifdef DEBUG_LOCK_BITS |
2098 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", | 2098 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", |
2099 | __func__, ret); | 2099 | __func__, ret); |
2100 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, | 2100 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, |
2101 | ofs, len, NULL); | 2101 | ofs, len, NULL); |
2102 | #endif | 2102 | #endif |
2103 | 2103 | ||
2104 | return ret; | 2104 | return ret; |
2105 | } | 2105 | } |
2106 | 2106 | ||
2107 | static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 2107 | static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
2108 | { | 2108 | { |
2109 | int ret; | 2109 | int ret; |
2110 | 2110 | ||
2111 | #ifdef DEBUG_LOCK_BITS | 2111 | #ifdef DEBUG_LOCK_BITS |
2112 | printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", | 2112 | printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", |
2113 | __func__, ofs, len); | 2113 | __func__, ofs, len); |
2114 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, | 2114 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, |
2115 | ofs, len, NULL); | 2115 | ofs, len, NULL); |
2116 | #endif | 2116 | #endif |
2117 | 2117 | ||
2118 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, | 2118 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, |
2119 | ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); | 2119 | ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); |
2120 | 2120 | ||
2121 | #ifdef DEBUG_LOCK_BITS | 2121 | #ifdef DEBUG_LOCK_BITS |
2122 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", | 2122 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", |
2123 | __func__, ret); | 2123 | __func__, ret); |
2124 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, | 2124 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, |
2125 | ofs, len, NULL); | 2125 | ofs, len, NULL); |
2126 | #endif | 2126 | #endif |
2127 | 2127 | ||
2128 | return ret; | 2128 | return ret; |
2129 | } | 2129 | } |
2130 | 2130 | ||
2131 | #ifdef CONFIG_MTD_OTP | 2131 | #ifdef CONFIG_MTD_OTP |
2132 | 2132 | ||
2133 | typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, | 2133 | typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, |
2134 | u_long data_offset, u_char *buf, u_int size, | 2134 | u_long data_offset, u_char *buf, u_int size, |
2135 | u_long prot_offset, u_int groupno, u_int groupsize); | 2135 | u_long prot_offset, u_int groupno, u_int groupsize); |
2136 | 2136 | ||
2137 | static int __xipram | 2137 | static int __xipram |
2138 | do_otp_read(struct map_info *map, struct flchip *chip, u_long offset, | 2138 | do_otp_read(struct map_info *map, struct flchip *chip, u_long offset, |
2139 | u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz) | 2139 | u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz) |
2140 | { | 2140 | { |
2141 | struct cfi_private *cfi = map->fldrv_priv; | 2141 | struct cfi_private *cfi = map->fldrv_priv; |
2142 | int ret; | 2142 | int ret; |
2143 | 2143 | ||
2144 | spin_lock(chip->mutex); | 2144 | spin_lock(chip->mutex); |
2145 | ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY); | 2145 | ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY); |
2146 | if (ret) { | 2146 | if (ret) { |
2147 | spin_unlock(chip->mutex); | 2147 | spin_unlock(chip->mutex); |
2148 | return ret; | 2148 | return ret; |
2149 | } | 2149 | } |
2150 | 2150 | ||
2151 | /* let's ensure we're not reading back cached data from array mode */ | 2151 | /* let's ensure we're not reading back cached data from array mode */ |
2152 | INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); | 2152 | INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); |
2153 | 2153 | ||
2154 | xip_disable(map, chip, chip->start); | 2154 | xip_disable(map, chip, chip->start); |
2155 | if (chip->state != FL_JEDEC_QUERY) { | 2155 | if (chip->state != FL_JEDEC_QUERY) { |
2156 | map_write(map, CMD(0x90), chip->start); | 2156 | map_write(map, CMD(0x90), chip->start); |
2157 | chip->state = FL_JEDEC_QUERY; | 2157 | chip->state = FL_JEDEC_QUERY; |
2158 | } | 2158 | } |
2159 | map_copy_from(map, buf, chip->start + offset, size); | 2159 | map_copy_from(map, buf, chip->start + offset, size); |
2160 | xip_enable(map, chip, chip->start); | 2160 | xip_enable(map, chip, chip->start); |
2161 | 2161 | ||
2162 | /* then ensure we don't keep OTP data in the cache */ | 2162 | /* then ensure we don't keep OTP data in the cache */ |
2163 | INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); | 2163 | INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); |
2164 | 2164 | ||
2165 | put_chip(map, chip, chip->start); | 2165 | put_chip(map, chip, chip->start); |
2166 | spin_unlock(chip->mutex); | 2166 | spin_unlock(chip->mutex); |
2167 | return 0; | 2167 | return 0; |
2168 | } | 2168 | } |
2169 | 2169 | ||
2170 | static int | 2170 | static int |
2171 | do_otp_write(struct map_info *map, struct flchip *chip, u_long offset, | 2171 | do_otp_write(struct map_info *map, struct flchip *chip, u_long offset, |
2172 | u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz) | 2172 | u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz) |
2173 | { | 2173 | { |
2174 | int ret; | 2174 | int ret; |
2175 | 2175 | ||
2176 | while (size) { | 2176 | while (size) { |
2177 | unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1); | 2177 | unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1); |
2178 | int gap = offset - bus_ofs; | 2178 | int gap = offset - bus_ofs; |
2179 | int n = min_t(int, size, map_bankwidth(map)-gap); | 2179 | int n = min_t(int, size, map_bankwidth(map)-gap); |
2180 | map_word datum = map_word_ff(map); | 2180 | map_word datum = map_word_ff(map); |
2181 | 2181 | ||
2182 | datum = map_word_load_partial(map, datum, buf, gap, n); | 2182 | datum = map_word_load_partial(map, datum, buf, gap, n); |
2183 | ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); | 2183 | ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); |
2184 | if (ret) | 2184 | if (ret) |
2185 | return ret; | 2185 | return ret; |
2186 | 2186 | ||
2187 | offset += n; | 2187 | offset += n; |
2188 | buf += n; | 2188 | buf += n; |
2189 | size -= n; | 2189 | size -= n; |
2190 | } | 2190 | } |
2191 | 2191 | ||
2192 | return 0; | 2192 | return 0; |
2193 | } | 2193 | } |
2194 | 2194 | ||
2195 | static int | 2195 | static int |
2196 | do_otp_lock(struct map_info *map, struct flchip *chip, u_long offset, | 2196 | do_otp_lock(struct map_info *map, struct flchip *chip, u_long offset, |
2197 | u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz) | 2197 | u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz) |
2198 | { | 2198 | { |
2199 | struct cfi_private *cfi = map->fldrv_priv; | 2199 | struct cfi_private *cfi = map->fldrv_priv; |
2200 | map_word datum; | 2200 | map_word datum; |
2201 | 2201 | ||
2202 | /* make sure area matches group boundaries */ | 2202 | /* make sure area matches group boundaries */ |
2203 | if (size != grpsz) | 2203 | if (size != grpsz) |
2204 | return -EXDEV; | 2204 | return -EXDEV; |
2205 | 2205 | ||
2206 | datum = map_word_ff(map); | 2206 | datum = map_word_ff(map); |
2207 | datum = map_word_clr(map, datum, CMD(1 << grpno)); | 2207 | datum = map_word_clr(map, datum, CMD(1 << grpno)); |
2208 | return do_write_oneword(map, chip, prot, datum, FL_OTP_WRITE); | 2208 | return do_write_oneword(map, chip, prot, datum, FL_OTP_WRITE); |
2209 | } | 2209 | } |
2210 | 2210 | ||
2211 | static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, | 2211 | static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, |
2212 | size_t *retlen, u_char *buf, | 2212 | size_t *retlen, u_char *buf, |
2213 | otp_op_t action, int user_regs) | 2213 | otp_op_t action, int user_regs) |
2214 | { | 2214 | { |
2215 | struct map_info *map = mtd->priv; | 2215 | struct map_info *map = mtd->priv; |
2216 | struct cfi_private *cfi = map->fldrv_priv; | 2216 | struct cfi_private *cfi = map->fldrv_priv; |
2217 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 2217 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
2218 | struct flchip *chip; | 2218 | struct flchip *chip; |
2219 | struct cfi_intelext_otpinfo *otp; | 2219 | struct cfi_intelext_otpinfo *otp; |
2220 | u_long devsize, reg_prot_offset, data_offset; | 2220 | u_long devsize, reg_prot_offset, data_offset; |
2221 | u_int chip_num, chip_step, field, reg_fact_size, reg_user_size; | 2221 | u_int chip_num, chip_step, field, reg_fact_size, reg_user_size; |
2222 | u_int groups, groupno, groupsize, reg_fact_groups, reg_user_groups; | 2222 | u_int groups, groupno, groupsize, reg_fact_groups, reg_user_groups; |
2223 | int ret; | 2223 | int ret; |
2224 | 2224 | ||
2225 | *retlen = 0; | 2225 | *retlen = 0; |
2226 | 2226 | ||
2227 | /* Check that we actually have some OTP registers */ | 2227 | /* Check that we actually have some OTP registers */ |
2228 | if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields) | 2228 | if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields) |
2229 | return -ENODATA; | 2229 | return -ENODATA; |
2230 | 2230 | ||
2231 | /* we need real chips here not virtual ones */ | 2231 | /* we need real chips here not virtual ones */ |
2232 | devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave; | 2232 | devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave; |
2233 | chip_step = devsize >> cfi->chipshift; | 2233 | chip_step = devsize >> cfi->chipshift; |
2234 | chip_num = 0; | 2234 | chip_num = 0; |
2235 | 2235 | ||
2236 | /* Some chips have OTP located in the _top_ partition only. | 2236 | /* Some chips have OTP located in the _top_ partition only. |
2237 | For example: Intel 28F256L18T (T means top-parameter device) */ | 2237 | For example: Intel 28F256L18T (T means top-parameter device) */ |
2238 | if (cfi->mfr == MANUFACTURER_INTEL) { | 2238 | if (cfi->mfr == MANUFACTURER_INTEL) { |
2239 | switch (cfi->id) { | 2239 | switch (cfi->id) { |
2240 | case 0x880b: | 2240 | case 0x880b: |
2241 | case 0x880c: | 2241 | case 0x880c: |
2242 | case 0x880d: | 2242 | case 0x880d: |
2243 | chip_num = chip_step - 1; | 2243 | chip_num = chip_step - 1; |
2244 | } | 2244 | } |
2245 | } | 2245 | } |
2246 | 2246 | ||
2247 | for ( ; chip_num < cfi->numchips; chip_num += chip_step) { | 2247 | for ( ; chip_num < cfi->numchips; chip_num += chip_step) { |
2248 | chip = &cfi->chips[chip_num]; | 2248 | chip = &cfi->chips[chip_num]; |
2249 | otp = (struct cfi_intelext_otpinfo *)&extp->extra[0]; | 2249 | otp = (struct cfi_intelext_otpinfo *)&extp->extra[0]; |
2250 | 2250 | ||
2251 | /* first OTP region */ | 2251 | /* first OTP region */ |
2252 | field = 0; | 2252 | field = 0; |
2253 | reg_prot_offset = extp->ProtRegAddr; | 2253 | reg_prot_offset = extp->ProtRegAddr; |
2254 | reg_fact_groups = 1; | 2254 | reg_fact_groups = 1; |
2255 | reg_fact_size = 1 << extp->FactProtRegSize; | 2255 | reg_fact_size = 1 << extp->FactProtRegSize; |
2256 | reg_user_groups = 1; | 2256 | reg_user_groups = 1; |
2257 | reg_user_size = 1 << extp->UserProtRegSize; | 2257 | reg_user_size = 1 << extp->UserProtRegSize; |
2258 | 2258 | ||
2259 | while (len > 0) { | 2259 | while (len > 0) { |
2260 | /* flash geometry fixup */ | 2260 | /* flash geometry fixup */ |
2261 | data_offset = reg_prot_offset + 1; | 2261 | data_offset = reg_prot_offset + 1; |
2262 | data_offset *= cfi->interleave * cfi->device_type; | 2262 | data_offset *= cfi->interleave * cfi->device_type; |
2263 | reg_prot_offset *= cfi->interleave * cfi->device_type; | 2263 | reg_prot_offset *= cfi->interleave * cfi->device_type; |
2264 | reg_fact_size *= cfi->interleave; | 2264 | reg_fact_size *= cfi->interleave; |
2265 | reg_user_size *= cfi->interleave; | 2265 | reg_user_size *= cfi->interleave; |
2266 | 2266 | ||
2267 | if (user_regs) { | 2267 | if (user_regs) { |
2268 | groups = reg_user_groups; | 2268 | groups = reg_user_groups; |
2269 | groupsize = reg_user_size; | 2269 | groupsize = reg_user_size; |
2270 | /* skip over factory reg area */ | 2270 | /* skip over factory reg area */ |
2271 | groupno = reg_fact_groups; | 2271 | groupno = reg_fact_groups; |
2272 | data_offset += reg_fact_groups * reg_fact_size; | 2272 | data_offset += reg_fact_groups * reg_fact_size; |
2273 | } else { | 2273 | } else { |
2274 | groups = reg_fact_groups; | 2274 | groups = reg_fact_groups; |
2275 | groupsize = reg_fact_size; | 2275 | groupsize = reg_fact_size; |
2276 | groupno = 0; | 2276 | groupno = 0; |
2277 | } | 2277 | } |
2278 | 2278 | ||
2279 | while (len > 0 && groups > 0) { | 2279 | while (len > 0 && groups > 0) { |
2280 | if (!action) { | 2280 | if (!action) { |
2281 | /* | 2281 | /* |
2282 | * Special case: if action is NULL | 2282 | * Special case: if action is NULL |
2283 | * we fill buf with otp_info records. | 2283 | * we fill buf with otp_info records. |
2284 | */ | 2284 | */ |
2285 | struct otp_info *otpinfo; | 2285 | struct otp_info *otpinfo; |
2286 | map_word lockword; | 2286 | map_word lockword; |
2287 | len -= sizeof(struct otp_info); | 2287 | len -= sizeof(struct otp_info); |
2288 | if (len <= 0) | 2288 | if (len <= 0) |
2289 | return -ENOSPC; | 2289 | return -ENOSPC; |
2290 | ret = do_otp_read(map, chip, | 2290 | ret = do_otp_read(map, chip, |
2291 | reg_prot_offset, | 2291 | reg_prot_offset, |
2292 | (u_char *)&lockword, | 2292 | (u_char *)&lockword, |
2293 | map_bankwidth(map), | 2293 | map_bankwidth(map), |
2294 | 0, 0, 0); | 2294 | 0, 0, 0); |
2295 | if (ret) | 2295 | if (ret) |
2296 | return ret; | 2296 | return ret; |
2297 | otpinfo = (struct otp_info *)buf; | 2297 | otpinfo = (struct otp_info *)buf; |
2298 | otpinfo->start = from; | 2298 | otpinfo->start = from; |
2299 | otpinfo->length = groupsize; | 2299 | otpinfo->length = groupsize; |
2300 | otpinfo->locked = | 2300 | otpinfo->locked = |
2301 | !map_word_bitsset(map, lockword, | 2301 | !map_word_bitsset(map, lockword, |
2302 | CMD(1 << groupno)); | 2302 | CMD(1 << groupno)); |
2303 | from += groupsize; | 2303 | from += groupsize; |
2304 | buf += sizeof(*otpinfo); | 2304 | buf += sizeof(*otpinfo); |
2305 | *retlen += sizeof(*otpinfo); | 2305 | *retlen += sizeof(*otpinfo); |
2306 | } else if (from >= groupsize) { | 2306 | } else if (from >= groupsize) { |
2307 | from -= groupsize; | 2307 | from -= groupsize; |
2308 | data_offset += groupsize; | 2308 | data_offset += groupsize; |
2309 | } else { | 2309 | } else { |
2310 | int size = groupsize; | 2310 | int size = groupsize; |
2311 | data_offset += from; | 2311 | data_offset += from; |
2312 | size -= from; | 2312 | size -= from; |
2313 | from = 0; | 2313 | from = 0; |
2314 | if (size > len) | 2314 | if (size > len) |
2315 | size = len; | 2315 | size = len; |
2316 | ret = action(map, chip, data_offset, | 2316 | ret = action(map, chip, data_offset, |
2317 | buf, size, reg_prot_offset, | 2317 | buf, size, reg_prot_offset, |
2318 | groupno, groupsize); | 2318 | groupno, groupsize); |
2319 | if (ret < 0) | 2319 | if (ret < 0) |
2320 | return ret; | 2320 | return ret; |
2321 | buf += size; | 2321 | buf += size; |
2322 | len -= size; | 2322 | len -= size; |
2323 | *retlen += size; | 2323 | *retlen += size; |
2324 | data_offset += size; | 2324 | data_offset += size; |
2325 | } | 2325 | } |
2326 | groupno++; | 2326 | groupno++; |
2327 | groups--; | 2327 | groups--; |
2328 | } | 2328 | } |
2329 | 2329 | ||
2330 | /* next OTP region */ | 2330 | /* next OTP region */ |
2331 | if (++field == extp->NumProtectionFields) | 2331 | if (++field == extp->NumProtectionFields) |
2332 | break; | 2332 | break; |
2333 | reg_prot_offset = otp->ProtRegAddr; | 2333 | reg_prot_offset = otp->ProtRegAddr; |
2334 | reg_fact_groups = otp->FactGroups; | 2334 | reg_fact_groups = otp->FactGroups; |
2335 | reg_fact_size = 1 << otp->FactProtRegSize; | 2335 | reg_fact_size = 1 << otp->FactProtRegSize; |
2336 | reg_user_groups = otp->UserGroups; | 2336 | reg_user_groups = otp->UserGroups; |
2337 | reg_user_size = 1 << otp->UserProtRegSize; | 2337 | reg_user_size = 1 << otp->UserProtRegSize; |
2338 | otp++; | 2338 | otp++; |
2339 | } | 2339 | } |
2340 | } | 2340 | } |
2341 | 2341 | ||
2342 | return 0; | 2342 | return 0; |
2343 | } | 2343 | } |
2344 | 2344 | ||
2345 | static int cfi_intelext_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, | 2345 | static int cfi_intelext_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, |
2346 | size_t len, size_t *retlen, | 2346 | size_t len, size_t *retlen, |
2347 | u_char *buf) | 2347 | u_char *buf) |
2348 | { | 2348 | { |
2349 | return cfi_intelext_otp_walk(mtd, from, len, retlen, | 2349 | return cfi_intelext_otp_walk(mtd, from, len, retlen, |
2350 | buf, do_otp_read, 0); | 2350 | buf, do_otp_read, 0); |
2351 | } | 2351 | } |
2352 | 2352 | ||
2353 | static int cfi_intelext_read_user_prot_reg(struct mtd_info *mtd, loff_t from, | 2353 | static int cfi_intelext_read_user_prot_reg(struct mtd_info *mtd, loff_t from, |
2354 | size_t len, size_t *retlen, | 2354 | size_t len, size_t *retlen, |
2355 | u_char *buf) | 2355 | u_char *buf) |
2356 | { | 2356 | { |
2357 | return cfi_intelext_otp_walk(mtd, from, len, retlen, | 2357 | return cfi_intelext_otp_walk(mtd, from, len, retlen, |
2358 | buf, do_otp_read, 1); | 2358 | buf, do_otp_read, 1); |
2359 | } | 2359 | } |
2360 | 2360 | ||
2361 | static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from, | 2361 | static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from, |
2362 | size_t len, size_t *retlen, | 2362 | size_t len, size_t *retlen, |
2363 | u_char *buf) | 2363 | u_char *buf) |
2364 | { | 2364 | { |
2365 | return cfi_intelext_otp_walk(mtd, from, len, retlen, | 2365 | return cfi_intelext_otp_walk(mtd, from, len, retlen, |
2366 | buf, do_otp_write, 1); | 2366 | buf, do_otp_write, 1); |
2367 | } | 2367 | } |
2368 | 2368 | ||
2369 | static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd, | 2369 | static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd, |
2370 | loff_t from, size_t len) | 2370 | loff_t from, size_t len) |
2371 | { | 2371 | { |
2372 | size_t retlen; | 2372 | size_t retlen; |
2373 | return cfi_intelext_otp_walk(mtd, from, len, &retlen, | 2373 | return cfi_intelext_otp_walk(mtd, from, len, &retlen, |
2374 | NULL, do_otp_lock, 1); | 2374 | NULL, do_otp_lock, 1); |
2375 | } | 2375 | } |
2376 | 2376 | ||
2377 | static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, | 2377 | static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, |
2378 | struct otp_info *buf, size_t len) | 2378 | struct otp_info *buf, size_t len) |
2379 | { | 2379 | { |
2380 | size_t retlen; | 2380 | size_t retlen; |
2381 | int ret; | 2381 | int ret; |
2382 | 2382 | ||
2383 | ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0); | 2383 | ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0); |
2384 | return ret ? : retlen; | 2384 | return ret ? : retlen; |
2385 | } | 2385 | } |
2386 | 2386 | ||
2387 | static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, | 2387 | static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, |
2388 | struct otp_info *buf, size_t len) | 2388 | struct otp_info *buf, size_t len) |
2389 | { | 2389 | { |
2390 | size_t retlen; | 2390 | size_t retlen; |
2391 | int ret; | 2391 | int ret; |
2392 | 2392 | ||
2393 | ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1); | 2393 | ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1); |
2394 | return ret ? : retlen; | 2394 | return ret ? : retlen; |
2395 | } | 2395 | } |
2396 | 2396 | ||
2397 | #endif | 2397 | #endif |
2398 | 2398 | ||
2399 | static void cfi_intelext_save_locks(struct mtd_info *mtd) | 2399 | static void cfi_intelext_save_locks(struct mtd_info *mtd) |
2400 | { | 2400 | { |
2401 | struct mtd_erase_region_info *region; | 2401 | struct mtd_erase_region_info *region; |
2402 | int block, status, i; | 2402 | int block, status, i; |
2403 | unsigned long adr; | 2403 | unsigned long adr; |
2404 | size_t len; | 2404 | size_t len; |
2405 | 2405 | ||
2406 | for (i = 0; i < mtd->numeraseregions; i++) { | 2406 | for (i = 0; i < mtd->numeraseregions; i++) { |
2407 | region = &mtd->eraseregions[i]; | 2407 | region = &mtd->eraseregions[i]; |
2408 | if (!region->lockmap) | 2408 | if (!region->lockmap) |
2409 | continue; | 2409 | continue; |
2410 | 2410 | ||
2411 | for (block = 0; block < region->numblocks; block++){ | 2411 | for (block = 0; block < region->numblocks; block++){ |
2412 | len = region->erasesize; | 2412 | len = region->erasesize; |
2413 | adr = region->offset + block * len; | 2413 | adr = region->offset + block * len; |
2414 | 2414 | ||
2415 | status = cfi_varsize_frob(mtd, | 2415 | status = cfi_varsize_frob(mtd, |
2416 | do_getlockstatus_oneblock, adr, len, NULL); | 2416 | do_getlockstatus_oneblock, adr, len, NULL); |
2417 | if (status) | 2417 | if (status) |
2418 | set_bit(block, region->lockmap); | 2418 | set_bit(block, region->lockmap); |
2419 | else | 2419 | else |
2420 | clear_bit(block, region->lockmap); | 2420 | clear_bit(block, region->lockmap); |
2421 | } | 2421 | } |
2422 | } | 2422 | } |
2423 | } | 2423 | } |
2424 | 2424 | ||
2425 | static int cfi_intelext_suspend(struct mtd_info *mtd) | 2425 | static int cfi_intelext_suspend(struct mtd_info *mtd) |
2426 | { | 2426 | { |
2427 | struct map_info *map = mtd->priv; | 2427 | struct map_info *map = mtd->priv; |
2428 | struct cfi_private *cfi = map->fldrv_priv; | 2428 | struct cfi_private *cfi = map->fldrv_priv; |
2429 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 2429 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
2430 | int i; | 2430 | int i; |
2431 | struct flchip *chip; | 2431 | struct flchip *chip; |
2432 | int ret = 0; | 2432 | int ret = 0; |
2433 | 2433 | ||
2434 | if ((mtd->flags & MTD_POWERUP_LOCK) | 2434 | if ((mtd->flags & MTD_POWERUP_LOCK) |
2435 | && extp && (extp->FeatureSupport & (1 << 5))) | 2435 | && extp && (extp->FeatureSupport & (1 << 5))) |
2436 | cfi_intelext_save_locks(mtd); | 2436 | cfi_intelext_save_locks(mtd); |
2437 | 2437 | ||
2438 | for (i=0; !ret && i<cfi->numchips; i++) { | 2438 | for (i=0; !ret && i<cfi->numchips; i++) { |
2439 | chip = &cfi->chips[i]; | 2439 | chip = &cfi->chips[i]; |
2440 | 2440 | ||
2441 | spin_lock(chip->mutex); | 2441 | spin_lock(chip->mutex); |
2442 | 2442 | ||
2443 | switch (chip->state) { | 2443 | switch (chip->state) { |
2444 | case FL_READY: | 2444 | case FL_READY: |
2445 | case FL_STATUS: | 2445 | case FL_STATUS: |
2446 | case FL_CFI_QUERY: | 2446 | case FL_CFI_QUERY: |
2447 | case FL_JEDEC_QUERY: | 2447 | case FL_JEDEC_QUERY: |
2448 | if (chip->oldstate == FL_READY) { | 2448 | if (chip->oldstate == FL_READY) { |
2449 | /* place the chip in a known state before suspend */ | 2449 | /* place the chip in a known state before suspend */ |
2450 | map_write(map, CMD(0xFF), cfi->chips[i].start); | 2450 | map_write(map, CMD(0xFF), cfi->chips[i].start); |
2451 | chip->oldstate = chip->state; | 2451 | chip->oldstate = chip->state; |
2452 | chip->state = FL_PM_SUSPENDED; | 2452 | chip->state = FL_PM_SUSPENDED; |
2453 | /* No need to wake_up() on this state change - | 2453 | /* No need to wake_up() on this state change - |
2454 | * as the whole point is that nobody can do anything | 2454 | * as the whole point is that nobody can do anything |
2455 | * with the chip now anyway. | 2455 | * with the chip now anyway. |
2456 | */ | 2456 | */ |
2457 | } else { | 2457 | } else { |
2458 | /* There seems to be an operation pending. We must wait for it. */ | 2458 | /* There seems to be an operation pending. We must wait for it. */ |
2459 | printk(KERN_NOTICE "Flash device refused suspend due to pending operation (oldstate %d)\n", chip->oldstate); | 2459 | printk(KERN_NOTICE "Flash device refused suspend due to pending operation (oldstate %d)\n", chip->oldstate); |
2460 | ret = -EAGAIN; | 2460 | ret = -EAGAIN; |
2461 | } | 2461 | } |
2462 | break; | 2462 | break; |
2463 | default: | 2463 | default: |
2464 | /* Should we actually wait? Once upon a time these routines weren't | 2464 | /* Should we actually wait? Once upon a time these routines weren't |
2465 | allowed to. Or should we return -EAGAIN, because the upper layers | 2465 | allowed to. Or should we return -EAGAIN, because the upper layers |
2466 | ought to have already shut down anything which was using the device | 2466 | ought to have already shut down anything which was using the device |
2467 | anyway? The latter for now. */ | 2467 | anyway? The latter for now. */ |
2468 | printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->oldstate); | 2468 | printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->oldstate); |
2469 | ret = -EAGAIN; | 2469 | ret = -EAGAIN; |
2470 | case FL_PM_SUSPENDED: | 2470 | case FL_PM_SUSPENDED: |
2471 | break; | 2471 | break; |
2472 | } | 2472 | } |
2473 | spin_unlock(chip->mutex); | 2473 | spin_unlock(chip->mutex); |
2474 | } | 2474 | } |
2475 | 2475 | ||
2476 | /* Unlock the chips again */ | 2476 | /* Unlock the chips again */ |
2477 | 2477 | ||
2478 | if (ret) { | 2478 | if (ret) { |
2479 | for (i--; i >=0; i--) { | 2479 | for (i--; i >=0; i--) { |
2480 | chip = &cfi->chips[i]; | 2480 | chip = &cfi->chips[i]; |
2481 | 2481 | ||
2482 | spin_lock(chip->mutex); | 2482 | spin_lock(chip->mutex); |
2483 | 2483 | ||
2484 | if (chip->state == FL_PM_SUSPENDED) { | 2484 | if (chip->state == FL_PM_SUSPENDED) { |
2485 | /* No need to force it into a known state here, | 2485 | /* No need to force it into a known state here, |
2486 | because we're returning failure, and it didn't | 2486 | because we're returning failure, and it didn't |
2487 | get power cycled */ | 2487 | get power cycled */ |
2488 | chip->state = chip->oldstate; | 2488 | chip->state = chip->oldstate; |
2489 | chip->oldstate = FL_READY; | 2489 | chip->oldstate = FL_READY; |
2490 | wake_up(&chip->wq); | 2490 | wake_up(&chip->wq); |
2491 | } | 2491 | } |
2492 | spin_unlock(chip->mutex); | 2492 | spin_unlock(chip->mutex); |
2493 | } | 2493 | } |
2494 | } | 2494 | } |
2495 | 2495 | ||
2496 | return ret; | 2496 | return ret; |
2497 | } | 2497 | } |
2498 | 2498 | ||
2499 | static void cfi_intelext_restore_locks(struct mtd_info *mtd) | 2499 | static void cfi_intelext_restore_locks(struct mtd_info *mtd) |
2500 | { | 2500 | { |
2501 | struct mtd_erase_region_info *region; | 2501 | struct mtd_erase_region_info *region; |
2502 | int block, i; | 2502 | int block, i; |
2503 | unsigned long adr; | 2503 | unsigned long adr; |
2504 | size_t len; | 2504 | size_t len; |
2505 | 2505 | ||
2506 | for (i = 0; i < mtd->numeraseregions; i++) { | 2506 | for (i = 0; i < mtd->numeraseregions; i++) { |
2507 | region = &mtd->eraseregions[i]; | 2507 | region = &mtd->eraseregions[i]; |
2508 | if (!region->lockmap) | 2508 | if (!region->lockmap) |
2509 | continue; | 2509 | continue; |
2510 | 2510 | ||
2511 | for (block = 0; block < region->numblocks; block++) { | 2511 | for (block = 0; block < region->numblocks; block++) { |
2512 | len = region->erasesize; | 2512 | len = region->erasesize; |
2513 | adr = region->offset + block * len; | 2513 | adr = region->offset + block * len; |
2514 | 2514 | ||
2515 | if (!test_bit(block, region->lockmap)) | 2515 | if (!test_bit(block, region->lockmap)) |
2516 | cfi_intelext_unlock(mtd, adr, len); | 2516 | cfi_intelext_unlock(mtd, adr, len); |
2517 | } | 2517 | } |
2518 | } | 2518 | } |
2519 | } | 2519 | } |
2520 | 2520 | ||
2521 | static void cfi_intelext_resume(struct mtd_info *mtd) | 2521 | static void cfi_intelext_resume(struct mtd_info *mtd) |
2522 | { | 2522 | { |
2523 | struct map_info *map = mtd->priv; | 2523 | struct map_info *map = mtd->priv; |
2524 | struct cfi_private *cfi = map->fldrv_priv; | 2524 | struct cfi_private *cfi = map->fldrv_priv; |
2525 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; | 2525 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
2526 | int i; | 2526 | int i; |
2527 | struct flchip *chip; | 2527 | struct flchip *chip; |
2528 | 2528 | ||
2529 | for (i=0; i<cfi->numchips; i++) { | 2529 | for (i=0; i<cfi->numchips; i++) { |
2530 | 2530 | ||
2531 | chip = &cfi->chips[i]; | 2531 | chip = &cfi->chips[i]; |
2532 | 2532 | ||
2533 | spin_lock(chip->mutex); | 2533 | spin_lock(chip->mutex); |
2534 | 2534 | ||
2535 | /* Go to known state. Chip may have been power cycled */ | 2535 | /* Go to known state. Chip may have been power cycled */ |
2536 | if (chip->state == FL_PM_SUSPENDED) { | 2536 | if (chip->state == FL_PM_SUSPENDED) { |
2537 | map_write(map, CMD(0xFF), cfi->chips[i].start); | 2537 | map_write(map, CMD(0xFF), cfi->chips[i].start); |
2538 | chip->oldstate = chip->state = FL_READY; | 2538 | chip->oldstate = chip->state = FL_READY; |
2539 | wake_up(&chip->wq); | 2539 | wake_up(&chip->wq); |
2540 | } | 2540 | } |
2541 | 2541 | ||
2542 | spin_unlock(chip->mutex); | 2542 | spin_unlock(chip->mutex); |
2543 | } | 2543 | } |
2544 | 2544 | ||
2545 | if ((mtd->flags & MTD_POWERUP_LOCK) | 2545 | if ((mtd->flags & MTD_POWERUP_LOCK) |
2546 | && extp && (extp->FeatureSupport & (1 << 5))) | 2546 | && extp && (extp->FeatureSupport & (1 << 5))) |
2547 | cfi_intelext_restore_locks(mtd); | 2547 | cfi_intelext_restore_locks(mtd); |
2548 | } | 2548 | } |
2549 | 2549 | ||
2550 | static int cfi_intelext_reset(struct mtd_info *mtd) | 2550 | static int cfi_intelext_reset(struct mtd_info *mtd) |
2551 | { | 2551 | { |
2552 | struct map_info *map = mtd->priv; | 2552 | struct map_info *map = mtd->priv; |
2553 | struct cfi_private *cfi = map->fldrv_priv; | 2553 | struct cfi_private *cfi = map->fldrv_priv; |
2554 | int i, ret; | 2554 | int i, ret; |
2555 | 2555 | ||
2556 | for (i=0; i < cfi->numchips; i++) { | 2556 | for (i=0; i < cfi->numchips; i++) { |
2557 | struct flchip *chip = &cfi->chips[i]; | 2557 | struct flchip *chip = &cfi->chips[i]; |
2558 | 2558 | ||
2559 | /* force the completion of any ongoing operation | 2559 | /* force the completion of any ongoing operation |
2560 | and switch to array mode so any bootloader in | 2560 | and switch to array mode so any bootloader in |
2561 | flash is accessible for soft reboot. */ | 2561 | flash is accessible for soft reboot. */ |
2562 | spin_lock(chip->mutex); | 2562 | spin_lock(chip->mutex); |
2563 | ret = get_chip(map, chip, chip->start, FL_SHUTDOWN); | 2563 | ret = get_chip(map, chip, chip->start, FL_SHUTDOWN); |
2564 | if (!ret) { | 2564 | if (!ret) { |
2565 | map_write(map, CMD(0xff), chip->start); | 2565 | map_write(map, CMD(0xff), chip->start); |
2566 | chip->state = FL_SHUTDOWN; | 2566 | chip->state = FL_SHUTDOWN; |
2567 | } | 2567 | } |
2568 | spin_unlock(chip->mutex); | 2568 | spin_unlock(chip->mutex); |
2569 | } | 2569 | } |
2570 | 2570 | ||
2571 | return 0; | 2571 | return 0; |
2572 | } | 2572 | } |
2573 | 2573 | ||
2574 | static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val, | 2574 | static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val, |
2575 | void *v) | 2575 | void *v) |
2576 | { | 2576 | { |
2577 | struct mtd_info *mtd; | 2577 | struct mtd_info *mtd; |
2578 | 2578 | ||
2579 | mtd = container_of(nb, struct mtd_info, reboot_notifier); | 2579 | mtd = container_of(nb, struct mtd_info, reboot_notifier); |
2580 | cfi_intelext_reset(mtd); | 2580 | cfi_intelext_reset(mtd); |
2581 | return NOTIFY_DONE; | 2581 | return NOTIFY_DONE; |
2582 | } | 2582 | } |
2583 | 2583 | ||
2584 | static void cfi_intelext_destroy(struct mtd_info *mtd) | 2584 | static void cfi_intelext_destroy(struct mtd_info *mtd) |
2585 | { | 2585 | { |
2586 | struct map_info *map = mtd->priv; | 2586 | struct map_info *map = mtd->priv; |
2587 | struct cfi_private *cfi = map->fldrv_priv; | 2587 | struct cfi_private *cfi = map->fldrv_priv; |
2588 | struct mtd_erase_region_info *region; | 2588 | struct mtd_erase_region_info *region; |
2589 | int i; | 2589 | int i; |
2590 | cfi_intelext_reset(mtd); | 2590 | cfi_intelext_reset(mtd); |
2591 | unregister_reboot_notifier(&mtd->reboot_notifier); | 2591 | unregister_reboot_notifier(&mtd->reboot_notifier); |
2592 | kfree(cfi->cmdset_priv); | 2592 | kfree(cfi->cmdset_priv); |
2593 | kfree(cfi->cfiq); | 2593 | kfree(cfi->cfiq); |
2594 | kfree(cfi->chips[0].priv); | 2594 | kfree(cfi->chips[0].priv); |
2595 | kfree(cfi); | 2595 | kfree(cfi); |
2596 | for (i = 0; i < mtd->numeraseregions; i++) { | 2596 | for (i = 0; i < mtd->numeraseregions; i++) { |
2597 | region = &mtd->eraseregions[i]; | 2597 | region = &mtd->eraseregions[i]; |
2598 | if (region->lockmap) | 2598 | if (region->lockmap) |
2599 | kfree(region->lockmap); | 2599 | kfree(region->lockmap); |
2600 | } | 2600 | } |
2601 | kfree(mtd->eraseregions); | 2601 | kfree(mtd->eraseregions); |
2602 | } | 2602 | } |
2603 | 2603 | ||
2604 | MODULE_LICENSE("GPL"); | 2604 | MODULE_LICENSE("GPL"); |
2605 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al."); | 2605 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al."); |
2606 | MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips"); | 2606 | MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips"); |
2607 | MODULE_ALIAS("cfi_cmdset_0003"); | 2607 | MODULE_ALIAS("cfi_cmdset_0003"); |
2608 | MODULE_ALIAS("cfi_cmdset_0200"); | 2608 | MODULE_ALIAS("cfi_cmdset_0200"); |
2609 | 2609 |
drivers/mtd/chips/cfi_cmdset_0020.c
1 | /* | 1 | /* |
2 | * Common Flash Interface support: | 2 | * Common Flash Interface support: |
3 | * ST Advanced Architecture Command Set (ID 0x0020) | 3 | * ST Advanced Architecture Command Set (ID 0x0020) |
4 | * | 4 | * |
5 | * (C) 2000 Red Hat. GPL'd | 5 | * (C) 2000 Red Hat. GPL'd |
6 | * | 6 | * |
7 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 7 | * 10/10/2000 Nicolas Pitre <nico@fluxnic.net> |
8 | * - completely revamped method functions so they are aware and | 8 | * - completely revamped method functions so they are aware and |
9 | * independent of the flash geometry (buswidth, interleave, etc.) | 9 | * independent of the flash geometry (buswidth, interleave, etc.) |
10 | * - scalability vs code size is completely set at compile-time | 10 | * - scalability vs code size is completely set at compile-time |
11 | * (see include/linux/mtd/cfi.h for selection) | 11 | * (see include/linux/mtd/cfi.h for selection) |
12 | * - optimized write buffer method | 12 | * - optimized write buffer method |
13 | * 06/21/2002 Joern Engel <joern@wh.fh-wedel.de> and others | 13 | * 06/21/2002 Joern Engel <joern@wh.fh-wedel.de> and others |
14 | * - modified Intel Command Set 0x0001 to support ST Advanced Architecture | 14 | * - modified Intel Command Set 0x0001 to support ST Advanced Architecture |
15 | * (command set 0x0020) | 15 | * (command set 0x0020) |
16 | * - added a writev function | 16 | * - added a writev function |
17 | * 07/13/2005 Joern Engel <joern@wh.fh-wedel.de> | 17 | * 07/13/2005 Joern Engel <joern@wh.fh-wedel.de> |
18 | * - Plugged memory leak in cfi_staa_writev(). | 18 | * - Plugged memory leak in cfi_staa_writev(). |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
28 | 28 | ||
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/mtd/map.h> | 33 | #include <linux/mtd/map.h> |
34 | #include <linux/mtd/cfi.h> | 34 | #include <linux/mtd/cfi.h> |
35 | #include <linux/mtd/mtd.h> | 35 | #include <linux/mtd/mtd.h> |
36 | #include <linux/mtd/compatmac.h> | 36 | #include <linux/mtd/compatmac.h> |
37 | 37 | ||
38 | 38 | ||
39 | static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 39 | static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
40 | static int cfi_staa_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 40 | static int cfi_staa_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
41 | static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, | 41 | static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, |
42 | unsigned long count, loff_t to, size_t *retlen); | 42 | unsigned long count, loff_t to, size_t *retlen); |
43 | static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *); | 43 | static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *); |
44 | static void cfi_staa_sync (struct mtd_info *); | 44 | static void cfi_staa_sync (struct mtd_info *); |
45 | static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); | 45 | static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); |
46 | static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); | 46 | static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); |
47 | static int cfi_staa_suspend (struct mtd_info *); | 47 | static int cfi_staa_suspend (struct mtd_info *); |
48 | static void cfi_staa_resume (struct mtd_info *); | 48 | static void cfi_staa_resume (struct mtd_info *); |
49 | 49 | ||
50 | static void cfi_staa_destroy(struct mtd_info *); | 50 | static void cfi_staa_destroy(struct mtd_info *); |
51 | 51 | ||
52 | struct mtd_info *cfi_cmdset_0020(struct map_info *, int); | 52 | struct mtd_info *cfi_cmdset_0020(struct map_info *, int); |
53 | 53 | ||
54 | static struct mtd_info *cfi_staa_setup (struct map_info *); | 54 | static struct mtd_info *cfi_staa_setup (struct map_info *); |
55 | 55 | ||
56 | static struct mtd_chip_driver cfi_staa_chipdrv = { | 56 | static struct mtd_chip_driver cfi_staa_chipdrv = { |
57 | .probe = NULL, /* Not usable directly */ | 57 | .probe = NULL, /* Not usable directly */ |
58 | .destroy = cfi_staa_destroy, | 58 | .destroy = cfi_staa_destroy, |
59 | .name = "cfi_cmdset_0020", | 59 | .name = "cfi_cmdset_0020", |
60 | .module = THIS_MODULE | 60 | .module = THIS_MODULE |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* #define DEBUG_LOCK_BITS */ | 63 | /* #define DEBUG_LOCK_BITS */ |
64 | //#define DEBUG_CFI_FEATURES | 64 | //#define DEBUG_CFI_FEATURES |
65 | 65 | ||
66 | #ifdef DEBUG_CFI_FEATURES | 66 | #ifdef DEBUG_CFI_FEATURES |
67 | static void cfi_tell_features(struct cfi_pri_intelext *extp) | 67 | static void cfi_tell_features(struct cfi_pri_intelext *extp) |
68 | { | 68 | { |
69 | int i; | 69 | int i; |
70 | printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); | 70 | printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); |
71 | printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); | 71 | printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); |
72 | printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); | 72 | printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); |
73 | printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); | 73 | printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); |
74 | printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); | 74 | printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); |
75 | printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); | 75 | printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); |
76 | printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); | 76 | printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); |
77 | printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); | 77 | printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); |
78 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); | 78 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); |
79 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); | 79 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); |
80 | for (i=9; i<32; i++) { | 80 | for (i=9; i<32; i++) { |
81 | if (extp->FeatureSupport & (1<<i)) | 81 | if (extp->FeatureSupport & (1<<i)) |
82 | printk(" - Unknown Bit %X: supported\n", i); | 82 | printk(" - Unknown Bit %X: supported\n", i); |
83 | } | 83 | } |
84 | 84 | ||
85 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); | 85 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); |
86 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); | 86 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); |
87 | for (i=1; i<8; i++) { | 87 | for (i=1; i<8; i++) { |
88 | if (extp->SuspendCmdSupport & (1<<i)) | 88 | if (extp->SuspendCmdSupport & (1<<i)) |
89 | printk(" - Unknown Bit %X: supported\n", i); | 89 | printk(" - Unknown Bit %X: supported\n", i); |
90 | } | 90 | } |
91 | 91 | ||
92 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); | 92 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); |
93 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); | 93 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); |
94 | printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); | 94 | printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); |
95 | for (i=2; i<16; i++) { | 95 | for (i=2; i<16; i++) { |
96 | if (extp->BlkStatusRegMask & (1<<i)) | 96 | if (extp->BlkStatusRegMask & (1<<i)) |
97 | printk(" - Unknown Bit %X Active: yes\n",i); | 97 | printk(" - Unknown Bit %X Active: yes\n",i); |
98 | } | 98 | } |
99 | 99 | ||
100 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", | 100 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", |
101 | extp->VccOptimal >> 8, extp->VccOptimal & 0xf); | 101 | extp->VccOptimal >> 8, extp->VccOptimal & 0xf); |
102 | if (extp->VppOptimal) | 102 | if (extp->VppOptimal) |
103 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", | 103 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", |
104 | extp->VppOptimal >> 8, extp->VppOptimal & 0xf); | 104 | extp->VppOptimal >> 8, extp->VppOptimal & 0xf); |
105 | } | 105 | } |
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | /* This routine is made available to other mtd code via | 108 | /* This routine is made available to other mtd code via |
109 | * inter_module_register. It must only be accessed through | 109 | * inter_module_register. It must only be accessed through |
110 | * inter_module_get which will bump the use count of this module. The | 110 | * inter_module_get which will bump the use count of this module. The |
111 | * addresses passed back in cfi are valid as long as the use count of | 111 | * addresses passed back in cfi are valid as long as the use count of |
112 | * this module is non-zero, i.e. between inter_module_get and | 112 | * this module is non-zero, i.e. between inter_module_get and |
113 | * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000. | 113 | * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000. |
114 | */ | 114 | */ |
115 | struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) | 115 | struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) |
116 | { | 116 | { |
117 | struct cfi_private *cfi = map->fldrv_priv; | 117 | struct cfi_private *cfi = map->fldrv_priv; |
118 | int i; | 118 | int i; |
119 | 119 | ||
120 | if (cfi->cfi_mode) { | 120 | if (cfi->cfi_mode) { |
121 | /* | 121 | /* |
122 | * It's a real CFI chip, not one for which the probe | 122 | * It's a real CFI chip, not one for which the probe |
123 | * routine faked a CFI structure. So we read the feature | 123 | * routine faked a CFI structure. So we read the feature |
124 | * table from it. | 124 | * table from it. |
125 | */ | 125 | */ |
126 | __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; | 126 | __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; |
127 | struct cfi_pri_intelext *extp; | 127 | struct cfi_pri_intelext *extp; |
128 | 128 | ||
129 | extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics"); | 129 | extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics"); |
130 | if (!extp) | 130 | if (!extp) |
131 | return NULL; | 131 | return NULL; |
132 | 132 | ||
133 | if (extp->MajorVersion != '1' || | 133 | if (extp->MajorVersion != '1' || |
134 | (extp->MinorVersion < '0' || extp->MinorVersion > '3')) { | 134 | (extp->MinorVersion < '0' || extp->MinorVersion > '3')) { |
135 | printk(KERN_ERR " Unknown ST Microelectronics" | 135 | printk(KERN_ERR " Unknown ST Microelectronics" |
136 | " Extended Query version %c.%c.\n", | 136 | " Extended Query version %c.%c.\n", |
137 | extp->MajorVersion, extp->MinorVersion); | 137 | extp->MajorVersion, extp->MinorVersion); |
138 | kfree(extp); | 138 | kfree(extp); |
139 | return NULL; | 139 | return NULL; |
140 | } | 140 | } |
141 | 141 | ||
142 | /* Do some byteswapping if necessary */ | 142 | /* Do some byteswapping if necessary */ |
143 | extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); | 143 | extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); |
144 | extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); | 144 | extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); |
145 | 145 | ||
146 | #ifdef DEBUG_CFI_FEATURES | 146 | #ifdef DEBUG_CFI_FEATURES |
147 | /* Tell the user about it in lots of lovely detail */ | 147 | /* Tell the user about it in lots of lovely detail */ |
148 | cfi_tell_features(extp); | 148 | cfi_tell_features(extp); |
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | /* Install our own private info structure */ | 151 | /* Install our own private info structure */ |
152 | cfi->cmdset_priv = extp; | 152 | cfi->cmdset_priv = extp; |
153 | } | 153 | } |
154 | 154 | ||
155 | for (i=0; i< cfi->numchips; i++) { | 155 | for (i=0; i< cfi->numchips; i++) { |
156 | cfi->chips[i].word_write_time = 128; | 156 | cfi->chips[i].word_write_time = 128; |
157 | cfi->chips[i].buffer_write_time = 128; | 157 | cfi->chips[i].buffer_write_time = 128; |
158 | cfi->chips[i].erase_time = 1024; | 158 | cfi->chips[i].erase_time = 1024; |
159 | cfi->chips[i].ref_point_counter = 0; | 159 | cfi->chips[i].ref_point_counter = 0; |
160 | init_waitqueue_head(&(cfi->chips[i].wq)); | 160 | init_waitqueue_head(&(cfi->chips[i].wq)); |
161 | } | 161 | } |
162 | 162 | ||
163 | return cfi_staa_setup(map); | 163 | return cfi_staa_setup(map); |
164 | } | 164 | } |
165 | EXPORT_SYMBOL_GPL(cfi_cmdset_0020); | 165 | EXPORT_SYMBOL_GPL(cfi_cmdset_0020); |
166 | 166 | ||
167 | static struct mtd_info *cfi_staa_setup(struct map_info *map) | 167 | static struct mtd_info *cfi_staa_setup(struct map_info *map) |
168 | { | 168 | { |
169 | struct cfi_private *cfi = map->fldrv_priv; | 169 | struct cfi_private *cfi = map->fldrv_priv; |
170 | struct mtd_info *mtd; | 170 | struct mtd_info *mtd; |
171 | unsigned long offset = 0; | 171 | unsigned long offset = 0; |
172 | int i,j; | 172 | int i,j; |
173 | unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave; | 173 | unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave; |
174 | 174 | ||
175 | mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); | 175 | mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); |
176 | //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); | 176 | //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); |
177 | 177 | ||
178 | if (!mtd) { | 178 | if (!mtd) { |
179 | printk(KERN_ERR "Failed to allocate memory for MTD device\n"); | 179 | printk(KERN_ERR "Failed to allocate memory for MTD device\n"); |
180 | kfree(cfi->cmdset_priv); | 180 | kfree(cfi->cmdset_priv); |
181 | return NULL; | 181 | return NULL; |
182 | } | 182 | } |
183 | 183 | ||
184 | mtd->priv = map; | 184 | mtd->priv = map; |
185 | mtd->type = MTD_NORFLASH; | 185 | mtd->type = MTD_NORFLASH; |
186 | mtd->size = devsize * cfi->numchips; | 186 | mtd->size = devsize * cfi->numchips; |
187 | 187 | ||
188 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 188 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
189 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 189 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) |
190 | * mtd->numeraseregions, GFP_KERNEL); | 190 | * mtd->numeraseregions, GFP_KERNEL); |
191 | if (!mtd->eraseregions) { | 191 | if (!mtd->eraseregions) { |
192 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); | 192 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); |
193 | kfree(cfi->cmdset_priv); | 193 | kfree(cfi->cmdset_priv); |
194 | kfree(mtd); | 194 | kfree(mtd); |
195 | return NULL; | 195 | return NULL; |
196 | } | 196 | } |
197 | 197 | ||
198 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 198 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
199 | unsigned long ernum, ersize; | 199 | unsigned long ernum, ersize; |
200 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; | 200 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; |
201 | ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; | 201 | ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; |
202 | 202 | ||
203 | if (mtd->erasesize < ersize) { | 203 | if (mtd->erasesize < ersize) { |
204 | mtd->erasesize = ersize; | 204 | mtd->erasesize = ersize; |
205 | } | 205 | } |
206 | for (j=0; j<cfi->numchips; j++) { | 206 | for (j=0; j<cfi->numchips; j++) { |
207 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; | 207 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; |
208 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; | 208 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; |
209 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; | 209 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; |
210 | } | 210 | } |
211 | offset += (ersize * ernum); | 211 | offset += (ersize * ernum); |
212 | } | 212 | } |
213 | 213 | ||
214 | if (offset != devsize) { | 214 | if (offset != devsize) { |
215 | /* Argh */ | 215 | /* Argh */ |
216 | printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); | 216 | printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); |
217 | kfree(mtd->eraseregions); | 217 | kfree(mtd->eraseregions); |
218 | kfree(cfi->cmdset_priv); | 218 | kfree(cfi->cmdset_priv); |
219 | kfree(mtd); | 219 | kfree(mtd); |
220 | return NULL; | 220 | return NULL; |
221 | } | 221 | } |
222 | 222 | ||
223 | for (i=0; i<mtd->numeraseregions;i++){ | 223 | for (i=0; i<mtd->numeraseregions;i++){ |
224 | printk(KERN_DEBUG "%d: offset=0x%llx,size=0x%x,blocks=%d\n", | 224 | printk(KERN_DEBUG "%d: offset=0x%llx,size=0x%x,blocks=%d\n", |
225 | i, (unsigned long long)mtd->eraseregions[i].offset, | 225 | i, (unsigned long long)mtd->eraseregions[i].offset, |
226 | mtd->eraseregions[i].erasesize, | 226 | mtd->eraseregions[i].erasesize, |
227 | mtd->eraseregions[i].numblocks); | 227 | mtd->eraseregions[i].numblocks); |
228 | } | 228 | } |
229 | 229 | ||
230 | /* Also select the correct geometry setup too */ | 230 | /* Also select the correct geometry setup too */ |
231 | mtd->erase = cfi_staa_erase_varsize; | 231 | mtd->erase = cfi_staa_erase_varsize; |
232 | mtd->read = cfi_staa_read; | 232 | mtd->read = cfi_staa_read; |
233 | mtd->write = cfi_staa_write_buffers; | 233 | mtd->write = cfi_staa_write_buffers; |
234 | mtd->writev = cfi_staa_writev; | 234 | mtd->writev = cfi_staa_writev; |
235 | mtd->sync = cfi_staa_sync; | 235 | mtd->sync = cfi_staa_sync; |
236 | mtd->lock = cfi_staa_lock; | 236 | mtd->lock = cfi_staa_lock; |
237 | mtd->unlock = cfi_staa_unlock; | 237 | mtd->unlock = cfi_staa_unlock; |
238 | mtd->suspend = cfi_staa_suspend; | 238 | mtd->suspend = cfi_staa_suspend; |
239 | mtd->resume = cfi_staa_resume; | 239 | mtd->resume = cfi_staa_resume; |
240 | mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE; | 240 | mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE; |
241 | mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ | 241 | mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ |
242 | map->fldrv = &cfi_staa_chipdrv; | 242 | map->fldrv = &cfi_staa_chipdrv; |
243 | __module_get(THIS_MODULE); | 243 | __module_get(THIS_MODULE); |
244 | mtd->name = map->name; | 244 | mtd->name = map->name; |
245 | return mtd; | 245 | return mtd; |
246 | } | 246 | } |
247 | 247 | ||
248 | 248 | ||
249 | static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) | 249 | static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) |
250 | { | 250 | { |
251 | map_word status, status_OK; | 251 | map_word status, status_OK; |
252 | unsigned long timeo; | 252 | unsigned long timeo; |
253 | DECLARE_WAITQUEUE(wait, current); | 253 | DECLARE_WAITQUEUE(wait, current); |
254 | int suspended = 0; | 254 | int suspended = 0; |
255 | unsigned long cmd_addr; | 255 | unsigned long cmd_addr; |
256 | struct cfi_private *cfi = map->fldrv_priv; | 256 | struct cfi_private *cfi = map->fldrv_priv; |
257 | 257 | ||
258 | adr += chip->start; | 258 | adr += chip->start; |
259 | 259 | ||
260 | /* Ensure cmd read/writes are aligned. */ | 260 | /* Ensure cmd read/writes are aligned. */ |
261 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 261 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
262 | 262 | ||
263 | /* Let's determine this according to the interleave only once */ | 263 | /* Let's determine this according to the interleave only once */ |
264 | status_OK = CMD(0x80); | 264 | status_OK = CMD(0x80); |
265 | 265 | ||
266 | timeo = jiffies + HZ; | 266 | timeo = jiffies + HZ; |
267 | retry: | 267 | retry: |
268 | spin_lock_bh(chip->mutex); | 268 | spin_lock_bh(chip->mutex); |
269 | 269 | ||
270 | /* Check that the chip's ready to talk to us. | 270 | /* Check that the chip's ready to talk to us. |
271 | * If it's in FL_ERASING state, suspend it and make it talk now. | 271 | * If it's in FL_ERASING state, suspend it and make it talk now. |
272 | */ | 272 | */ |
273 | switch (chip->state) { | 273 | switch (chip->state) { |
274 | case FL_ERASING: | 274 | case FL_ERASING: |
275 | if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) | 275 | if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) |
276 | goto sleep; /* We don't support erase suspend */ | 276 | goto sleep; /* We don't support erase suspend */ |
277 | 277 | ||
278 | map_write (map, CMD(0xb0), cmd_addr); | 278 | map_write (map, CMD(0xb0), cmd_addr); |
279 | /* If the flash has finished erasing, then 'erase suspend' | 279 | /* If the flash has finished erasing, then 'erase suspend' |
280 | * appears to make some (28F320) flash devices switch to | 280 | * appears to make some (28F320) flash devices switch to |
281 | * 'read' mode. Make sure that we switch to 'read status' | 281 | * 'read' mode. Make sure that we switch to 'read status' |
282 | * mode so we get the right data. --rmk | 282 | * mode so we get the right data. --rmk |
283 | */ | 283 | */ |
284 | map_write(map, CMD(0x70), cmd_addr); | 284 | map_write(map, CMD(0x70), cmd_addr); |
285 | chip->oldstate = FL_ERASING; | 285 | chip->oldstate = FL_ERASING; |
286 | chip->state = FL_ERASE_SUSPENDING; | 286 | chip->state = FL_ERASE_SUSPENDING; |
287 | // printk("Erase suspending at 0x%lx\n", cmd_addr); | 287 | // printk("Erase suspending at 0x%lx\n", cmd_addr); |
288 | for (;;) { | 288 | for (;;) { |
289 | status = map_read(map, cmd_addr); | 289 | status = map_read(map, cmd_addr); |
290 | if (map_word_andequal(map, status, status_OK, status_OK)) | 290 | if (map_word_andequal(map, status, status_OK, status_OK)) |
291 | break; | 291 | break; |
292 | 292 | ||
293 | if (time_after(jiffies, timeo)) { | 293 | if (time_after(jiffies, timeo)) { |
294 | /* Urgh */ | 294 | /* Urgh */ |
295 | map_write(map, CMD(0xd0), cmd_addr); | 295 | map_write(map, CMD(0xd0), cmd_addr); |
296 | /* make sure we're in 'read status' mode */ | 296 | /* make sure we're in 'read status' mode */ |
297 | map_write(map, CMD(0x70), cmd_addr); | 297 | map_write(map, CMD(0x70), cmd_addr); |
298 | chip->state = FL_ERASING; | 298 | chip->state = FL_ERASING; |
299 | spin_unlock_bh(chip->mutex); | 299 | spin_unlock_bh(chip->mutex); |
300 | printk(KERN_ERR "Chip not ready after erase " | 300 | printk(KERN_ERR "Chip not ready after erase " |
301 | "suspended: status = 0x%lx\n", status.x[0]); | 301 | "suspended: status = 0x%lx\n", status.x[0]); |
302 | return -EIO; | 302 | return -EIO; |
303 | } | 303 | } |
304 | 304 | ||
305 | spin_unlock_bh(chip->mutex); | 305 | spin_unlock_bh(chip->mutex); |
306 | cfi_udelay(1); | 306 | cfi_udelay(1); |
307 | spin_lock_bh(chip->mutex); | 307 | spin_lock_bh(chip->mutex); |
308 | } | 308 | } |
309 | 309 | ||
310 | suspended = 1; | 310 | suspended = 1; |
311 | map_write(map, CMD(0xff), cmd_addr); | 311 | map_write(map, CMD(0xff), cmd_addr); |
312 | chip->state = FL_READY; | 312 | chip->state = FL_READY; |
313 | break; | 313 | break; |
314 | 314 | ||
315 | #if 0 | 315 | #if 0 |
316 | case FL_WRITING: | 316 | case FL_WRITING: |
317 | /* Not quite yet */ | 317 | /* Not quite yet */ |
318 | #endif | 318 | #endif |
319 | 319 | ||
320 | case FL_READY: | 320 | case FL_READY: |
321 | break; | 321 | break; |
322 | 322 | ||
323 | case FL_CFI_QUERY: | 323 | case FL_CFI_QUERY: |
324 | case FL_JEDEC_QUERY: | 324 | case FL_JEDEC_QUERY: |
325 | map_write(map, CMD(0x70), cmd_addr); | 325 | map_write(map, CMD(0x70), cmd_addr); |
326 | chip->state = FL_STATUS; | 326 | chip->state = FL_STATUS; |
327 | 327 | ||
328 | case FL_STATUS: | 328 | case FL_STATUS: |
329 | status = map_read(map, cmd_addr); | 329 | status = map_read(map, cmd_addr); |
330 | if (map_word_andequal(map, status, status_OK, status_OK)) { | 330 | if (map_word_andequal(map, status, status_OK, status_OK)) { |
331 | map_write(map, CMD(0xff), cmd_addr); | 331 | map_write(map, CMD(0xff), cmd_addr); |
332 | chip->state = FL_READY; | 332 | chip->state = FL_READY; |
333 | break; | 333 | break; |
334 | } | 334 | } |
335 | 335 | ||
336 | /* Urgh. Chip not yet ready to talk to us. */ | 336 | /* Urgh. Chip not yet ready to talk to us. */ |
337 | if (time_after(jiffies, timeo)) { | 337 | if (time_after(jiffies, timeo)) { |
338 | spin_unlock_bh(chip->mutex); | 338 | spin_unlock_bh(chip->mutex); |
339 | printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %lx\n", status.x[0]); | 339 | printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %lx\n", status.x[0]); |
340 | return -EIO; | 340 | return -EIO; |
341 | } | 341 | } |
342 | 342 | ||
343 | /* Latency issues. Drop the lock, wait a while and retry */ | 343 | /* Latency issues. Drop the lock, wait a while and retry */ |
344 | spin_unlock_bh(chip->mutex); | 344 | spin_unlock_bh(chip->mutex); |
345 | cfi_udelay(1); | 345 | cfi_udelay(1); |
346 | goto retry; | 346 | goto retry; |
347 | 347 | ||
348 | default: | 348 | default: |
349 | sleep: | 349 | sleep: |
350 | /* Stick ourselves on a wait queue to be woken when | 350 | /* Stick ourselves on a wait queue to be woken when |
351 | someone changes the status */ | 351 | someone changes the status */ |
352 | set_current_state(TASK_UNINTERRUPTIBLE); | 352 | set_current_state(TASK_UNINTERRUPTIBLE); |
353 | add_wait_queue(&chip->wq, &wait); | 353 | add_wait_queue(&chip->wq, &wait); |
354 | spin_unlock_bh(chip->mutex); | 354 | spin_unlock_bh(chip->mutex); |
355 | schedule(); | 355 | schedule(); |
356 | remove_wait_queue(&chip->wq, &wait); | 356 | remove_wait_queue(&chip->wq, &wait); |
357 | timeo = jiffies + HZ; | 357 | timeo = jiffies + HZ; |
358 | goto retry; | 358 | goto retry; |
359 | } | 359 | } |
360 | 360 | ||
361 | map_copy_from(map, buf, adr, len); | 361 | map_copy_from(map, buf, adr, len); |
362 | 362 | ||
363 | if (suspended) { | 363 | if (suspended) { |
364 | chip->state = chip->oldstate; | 364 | chip->state = chip->oldstate; |
365 | /* What if one interleaved chip has finished and the | 365 | /* What if one interleaved chip has finished and the |
366 | other hasn't? The old code would leave the finished | 366 | other hasn't? The old code would leave the finished |
367 | one in READY mode. That's bad, and caused -EROFS | 367 | one in READY mode. That's bad, and caused -EROFS |
368 | errors to be returned from do_erase_oneblock because | 368 | errors to be returned from do_erase_oneblock because |
369 | that's the only bit it checked for at the time. | 369 | that's the only bit it checked for at the time. |
370 | As the state machine appears to explicitly allow | 370 | As the state machine appears to explicitly allow |
371 | sending the 0x70 (Read Status) command to an erasing | 371 | sending the 0x70 (Read Status) command to an erasing |
372 | chip and expecting it to be ignored, that's what we | 372 | chip and expecting it to be ignored, that's what we |
373 | do. */ | 373 | do. */ |
374 | map_write(map, CMD(0xd0), cmd_addr); | 374 | map_write(map, CMD(0xd0), cmd_addr); |
375 | map_write(map, CMD(0x70), cmd_addr); | 375 | map_write(map, CMD(0x70), cmd_addr); |
376 | } | 376 | } |
377 | 377 | ||
378 | wake_up(&chip->wq); | 378 | wake_up(&chip->wq); |
379 | spin_unlock_bh(chip->mutex); | 379 | spin_unlock_bh(chip->mutex); |
380 | return 0; | 380 | return 0; |
381 | } | 381 | } |
382 | 382 | ||
383 | static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) | 383 | static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) |
384 | { | 384 | { |
385 | struct map_info *map = mtd->priv; | 385 | struct map_info *map = mtd->priv; |
386 | struct cfi_private *cfi = map->fldrv_priv; | 386 | struct cfi_private *cfi = map->fldrv_priv; |
387 | unsigned long ofs; | 387 | unsigned long ofs; |
388 | int chipnum; | 388 | int chipnum; |
389 | int ret = 0; | 389 | int ret = 0; |
390 | 390 | ||
391 | /* ofs: offset within the first chip that the first read should start */ | 391 | /* ofs: offset within the first chip that the first read should start */ |
392 | chipnum = (from >> cfi->chipshift); | 392 | chipnum = (from >> cfi->chipshift); |
393 | ofs = from - (chipnum << cfi->chipshift); | 393 | ofs = from - (chipnum << cfi->chipshift); |
394 | 394 | ||
395 | *retlen = 0; | 395 | *retlen = 0; |
396 | 396 | ||
397 | while (len) { | 397 | while (len) { |
398 | unsigned long thislen; | 398 | unsigned long thislen; |
399 | 399 | ||
400 | if (chipnum >= cfi->numchips) | 400 | if (chipnum >= cfi->numchips) |
401 | break; | 401 | break; |
402 | 402 | ||
403 | if ((len + ofs -1) >> cfi->chipshift) | 403 | if ((len + ofs -1) >> cfi->chipshift) |
404 | thislen = (1<<cfi->chipshift) - ofs; | 404 | thislen = (1<<cfi->chipshift) - ofs; |
405 | else | 405 | else |
406 | thislen = len; | 406 | thislen = len; |
407 | 407 | ||
408 | ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); | 408 | ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); |
409 | if (ret) | 409 | if (ret) |
410 | break; | 410 | break; |
411 | 411 | ||
412 | *retlen += thislen; | 412 | *retlen += thislen; |
413 | len -= thislen; | 413 | len -= thislen; |
414 | buf += thislen; | 414 | buf += thislen; |
415 | 415 | ||
416 | ofs = 0; | 416 | ofs = 0; |
417 | chipnum++; | 417 | chipnum++; |
418 | } | 418 | } |
419 | return ret; | 419 | return ret; |
420 | } | 420 | } |
421 | 421 | ||
422 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | 422 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, |
423 | unsigned long adr, const u_char *buf, int len) | 423 | unsigned long adr, const u_char *buf, int len) |
424 | { | 424 | { |
425 | struct cfi_private *cfi = map->fldrv_priv; | 425 | struct cfi_private *cfi = map->fldrv_priv; |
426 | map_word status, status_OK; | 426 | map_word status, status_OK; |
427 | unsigned long cmd_adr, timeo; | 427 | unsigned long cmd_adr, timeo; |
428 | DECLARE_WAITQUEUE(wait, current); | 428 | DECLARE_WAITQUEUE(wait, current); |
429 | int wbufsize, z; | 429 | int wbufsize, z; |
430 | 430 | ||
431 | /* M58LW064A requires bus alignment for buffer wriets -- saw */ | 431 | /* M58LW064A requires bus alignment for buffer wriets -- saw */ |
432 | if (adr & (map_bankwidth(map)-1)) | 432 | if (adr & (map_bankwidth(map)-1)) |
433 | return -EINVAL; | 433 | return -EINVAL; |
434 | 434 | ||
435 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; | 435 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; |
436 | adr += chip->start; | 436 | adr += chip->start; |
437 | cmd_adr = adr & ~(wbufsize-1); | 437 | cmd_adr = adr & ~(wbufsize-1); |
438 | 438 | ||
439 | /* Let's determine this according to the interleave only once */ | 439 | /* Let's determine this according to the interleave only once */ |
440 | status_OK = CMD(0x80); | 440 | status_OK = CMD(0x80); |
441 | 441 | ||
442 | timeo = jiffies + HZ; | 442 | timeo = jiffies + HZ; |
443 | retry: | 443 | retry: |
444 | 444 | ||
445 | #ifdef DEBUG_CFI_FEATURES | 445 | #ifdef DEBUG_CFI_FEATURES |
446 | printk("%s: chip->state[%d]\n", __func__, chip->state); | 446 | printk("%s: chip->state[%d]\n", __func__, chip->state); |
447 | #endif | 447 | #endif |
448 | spin_lock_bh(chip->mutex); | 448 | spin_lock_bh(chip->mutex); |
449 | 449 | ||
450 | /* Check that the chip's ready to talk to us. | 450 | /* Check that the chip's ready to talk to us. |
451 | * Later, we can actually think about interrupting it | 451 | * Later, we can actually think about interrupting it |
452 | * if it's in FL_ERASING state. | 452 | * if it's in FL_ERASING state. |
453 | * Not just yet, though. | 453 | * Not just yet, though. |
454 | */ | 454 | */ |
455 | switch (chip->state) { | 455 | switch (chip->state) { |
456 | case FL_READY: | 456 | case FL_READY: |
457 | break; | 457 | break; |
458 | 458 | ||
459 | case FL_CFI_QUERY: | 459 | case FL_CFI_QUERY: |
460 | case FL_JEDEC_QUERY: | 460 | case FL_JEDEC_QUERY: |
461 | map_write(map, CMD(0x70), cmd_adr); | 461 | map_write(map, CMD(0x70), cmd_adr); |
462 | chip->state = FL_STATUS; | 462 | chip->state = FL_STATUS; |
463 | #ifdef DEBUG_CFI_FEATURES | 463 | #ifdef DEBUG_CFI_FEATURES |
464 | printk("%s: 1 status[%x]\n", __func__, map_read(map, cmd_adr)); | 464 | printk("%s: 1 status[%x]\n", __func__, map_read(map, cmd_adr)); |
465 | #endif | 465 | #endif |
466 | 466 | ||
467 | case FL_STATUS: | 467 | case FL_STATUS: |
468 | status = map_read(map, cmd_adr); | 468 | status = map_read(map, cmd_adr); |
469 | if (map_word_andequal(map, status, status_OK, status_OK)) | 469 | if (map_word_andequal(map, status, status_OK, status_OK)) |
470 | break; | 470 | break; |
471 | /* Urgh. Chip not yet ready to talk to us. */ | 471 | /* Urgh. Chip not yet ready to talk to us. */ |
472 | if (time_after(jiffies, timeo)) { | 472 | if (time_after(jiffies, timeo)) { |
473 | spin_unlock_bh(chip->mutex); | 473 | spin_unlock_bh(chip->mutex); |
474 | printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %lx, status = %lx\n", | 474 | printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %lx, status = %lx\n", |
475 | status.x[0], map_read(map, cmd_adr).x[0]); | 475 | status.x[0], map_read(map, cmd_adr).x[0]); |
476 | return -EIO; | 476 | return -EIO; |
477 | } | 477 | } |
478 | 478 | ||
479 | /* Latency issues. Drop the lock, wait a while and retry */ | 479 | /* Latency issues. Drop the lock, wait a while and retry */ |
480 | spin_unlock_bh(chip->mutex); | 480 | spin_unlock_bh(chip->mutex); |
481 | cfi_udelay(1); | 481 | cfi_udelay(1); |
482 | goto retry; | 482 | goto retry; |
483 | 483 | ||
484 | default: | 484 | default: |
485 | /* Stick ourselves on a wait queue to be woken when | 485 | /* Stick ourselves on a wait queue to be woken when |
486 | someone changes the status */ | 486 | someone changes the status */ |
487 | set_current_state(TASK_UNINTERRUPTIBLE); | 487 | set_current_state(TASK_UNINTERRUPTIBLE); |
488 | add_wait_queue(&chip->wq, &wait); | 488 | add_wait_queue(&chip->wq, &wait); |
489 | spin_unlock_bh(chip->mutex); | 489 | spin_unlock_bh(chip->mutex); |
490 | schedule(); | 490 | schedule(); |
491 | remove_wait_queue(&chip->wq, &wait); | 491 | remove_wait_queue(&chip->wq, &wait); |
492 | timeo = jiffies + HZ; | 492 | timeo = jiffies + HZ; |
493 | goto retry; | 493 | goto retry; |
494 | } | 494 | } |
495 | 495 | ||
496 | ENABLE_VPP(map); | 496 | ENABLE_VPP(map); |
497 | map_write(map, CMD(0xe8), cmd_adr); | 497 | map_write(map, CMD(0xe8), cmd_adr); |
498 | chip->state = FL_WRITING_TO_BUFFER; | 498 | chip->state = FL_WRITING_TO_BUFFER; |
499 | 499 | ||
500 | z = 0; | 500 | z = 0; |
501 | for (;;) { | 501 | for (;;) { |
502 | status = map_read(map, cmd_adr); | 502 | status = map_read(map, cmd_adr); |
503 | if (map_word_andequal(map, status, status_OK, status_OK)) | 503 | if (map_word_andequal(map, status, status_OK, status_OK)) |
504 | break; | 504 | break; |
505 | 505 | ||
506 | spin_unlock_bh(chip->mutex); | 506 | spin_unlock_bh(chip->mutex); |
507 | cfi_udelay(1); | 507 | cfi_udelay(1); |
508 | spin_lock_bh(chip->mutex); | 508 | spin_lock_bh(chip->mutex); |
509 | 509 | ||
510 | if (++z > 100) { | 510 | if (++z > 100) { |
511 | /* Argh. Not ready for write to buffer */ | 511 | /* Argh. Not ready for write to buffer */ |
512 | DISABLE_VPP(map); | 512 | DISABLE_VPP(map); |
513 | map_write(map, CMD(0x70), cmd_adr); | 513 | map_write(map, CMD(0x70), cmd_adr); |
514 | chip->state = FL_STATUS; | 514 | chip->state = FL_STATUS; |
515 | spin_unlock_bh(chip->mutex); | 515 | spin_unlock_bh(chip->mutex); |
516 | printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %lx\n", status.x[0]); | 516 | printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %lx\n", status.x[0]); |
517 | return -EIO; | 517 | return -EIO; |
518 | } | 518 | } |
519 | } | 519 | } |
520 | 520 | ||
521 | /* Write length of data to come */ | 521 | /* Write length of data to come */ |
522 | map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); | 522 | map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); |
523 | 523 | ||
524 | /* Write data */ | 524 | /* Write data */ |
525 | for (z = 0; z < len; | 525 | for (z = 0; z < len; |
526 | z += map_bankwidth(map), buf += map_bankwidth(map)) { | 526 | z += map_bankwidth(map), buf += map_bankwidth(map)) { |
527 | map_word d; | 527 | map_word d; |
528 | d = map_word_load(map, buf); | 528 | d = map_word_load(map, buf); |
529 | map_write(map, d, adr+z); | 529 | map_write(map, d, adr+z); |
530 | } | 530 | } |
531 | /* GO GO GO */ | 531 | /* GO GO GO */ |
532 | map_write(map, CMD(0xd0), cmd_adr); | 532 | map_write(map, CMD(0xd0), cmd_adr); |
533 | chip->state = FL_WRITING; | 533 | chip->state = FL_WRITING; |
534 | 534 | ||
535 | spin_unlock_bh(chip->mutex); | 535 | spin_unlock_bh(chip->mutex); |
536 | cfi_udelay(chip->buffer_write_time); | 536 | cfi_udelay(chip->buffer_write_time); |
537 | spin_lock_bh(chip->mutex); | 537 | spin_lock_bh(chip->mutex); |
538 | 538 | ||
539 | timeo = jiffies + (HZ/2); | 539 | timeo = jiffies + (HZ/2); |
540 | z = 0; | 540 | z = 0; |
541 | for (;;) { | 541 | for (;;) { |
542 | if (chip->state != FL_WRITING) { | 542 | if (chip->state != FL_WRITING) { |
543 | /* Someone's suspended the write. Sleep */ | 543 | /* Someone's suspended the write. Sleep */ |
544 | set_current_state(TASK_UNINTERRUPTIBLE); | 544 | set_current_state(TASK_UNINTERRUPTIBLE); |
545 | add_wait_queue(&chip->wq, &wait); | 545 | add_wait_queue(&chip->wq, &wait); |
546 | spin_unlock_bh(chip->mutex); | 546 | spin_unlock_bh(chip->mutex); |
547 | schedule(); | 547 | schedule(); |
548 | remove_wait_queue(&chip->wq, &wait); | 548 | remove_wait_queue(&chip->wq, &wait); |
549 | timeo = jiffies + (HZ / 2); /* FIXME */ | 549 | timeo = jiffies + (HZ / 2); /* FIXME */ |
550 | spin_lock_bh(chip->mutex); | 550 | spin_lock_bh(chip->mutex); |
551 | continue; | 551 | continue; |
552 | } | 552 | } |
553 | 553 | ||
554 | status = map_read(map, cmd_adr); | 554 | status = map_read(map, cmd_adr); |
555 | if (map_word_andequal(map, status, status_OK, status_OK)) | 555 | if (map_word_andequal(map, status, status_OK, status_OK)) |
556 | break; | 556 | break; |
557 | 557 | ||
558 | /* OK Still waiting */ | 558 | /* OK Still waiting */ |
559 | if (time_after(jiffies, timeo)) { | 559 | if (time_after(jiffies, timeo)) { |
560 | /* clear status */ | 560 | /* clear status */ |
561 | map_write(map, CMD(0x50), cmd_adr); | 561 | map_write(map, CMD(0x50), cmd_adr); |
562 | /* put back into read status register mode */ | 562 | /* put back into read status register mode */ |
563 | map_write(map, CMD(0x70), adr); | 563 | map_write(map, CMD(0x70), adr); |
564 | chip->state = FL_STATUS; | 564 | chip->state = FL_STATUS; |
565 | DISABLE_VPP(map); | 565 | DISABLE_VPP(map); |
566 | spin_unlock_bh(chip->mutex); | 566 | spin_unlock_bh(chip->mutex); |
567 | printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); | 567 | printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); |
568 | return -EIO; | 568 | return -EIO; |
569 | } | 569 | } |
570 | 570 | ||
571 | /* Latency issues. Drop the lock, wait a while and retry */ | 571 | /* Latency issues. Drop the lock, wait a while and retry */ |
572 | spin_unlock_bh(chip->mutex); | 572 | spin_unlock_bh(chip->mutex); |
573 | cfi_udelay(1); | 573 | cfi_udelay(1); |
574 | z++; | 574 | z++; |
575 | spin_lock_bh(chip->mutex); | 575 | spin_lock_bh(chip->mutex); |
576 | } | 576 | } |
577 | if (!z) { | 577 | if (!z) { |
578 | chip->buffer_write_time--; | 578 | chip->buffer_write_time--; |
579 | if (!chip->buffer_write_time) | 579 | if (!chip->buffer_write_time) |
580 | chip->buffer_write_time++; | 580 | chip->buffer_write_time++; |
581 | } | 581 | } |
582 | if (z > 1) | 582 | if (z > 1) |
583 | chip->buffer_write_time++; | 583 | chip->buffer_write_time++; |
584 | 584 | ||
585 | /* Done and happy. */ | 585 | /* Done and happy. */ |
586 | DISABLE_VPP(map); | 586 | DISABLE_VPP(map); |
587 | chip->state = FL_STATUS; | 587 | chip->state = FL_STATUS; |
588 | 588 | ||
589 | /* check for errors: 'lock bit', 'VPP', 'dead cell'/'unerased cell' or 'incorrect cmd' -- saw */ | 589 | /* check for errors: 'lock bit', 'VPP', 'dead cell'/'unerased cell' or 'incorrect cmd' -- saw */ |
590 | if (map_word_bitsset(map, status, CMD(0x3a))) { | 590 | if (map_word_bitsset(map, status, CMD(0x3a))) { |
591 | #ifdef DEBUG_CFI_FEATURES | 591 | #ifdef DEBUG_CFI_FEATURES |
592 | printk("%s: 2 status[%lx]\n", __func__, status.x[0]); | 592 | printk("%s: 2 status[%lx]\n", __func__, status.x[0]); |
593 | #endif | 593 | #endif |
594 | /* clear status */ | 594 | /* clear status */ |
595 | map_write(map, CMD(0x50), cmd_adr); | 595 | map_write(map, CMD(0x50), cmd_adr); |
596 | /* put back into read status register mode */ | 596 | /* put back into read status register mode */ |
597 | map_write(map, CMD(0x70), adr); | 597 | map_write(map, CMD(0x70), adr); |
598 | wake_up(&chip->wq); | 598 | wake_up(&chip->wq); |
599 | spin_unlock_bh(chip->mutex); | 599 | spin_unlock_bh(chip->mutex); |
600 | return map_word_bitsset(map, status, CMD(0x02)) ? -EROFS : -EIO; | 600 | return map_word_bitsset(map, status, CMD(0x02)) ? -EROFS : -EIO; |
601 | } | 601 | } |
602 | wake_up(&chip->wq); | 602 | wake_up(&chip->wq); |
603 | spin_unlock_bh(chip->mutex); | 603 | spin_unlock_bh(chip->mutex); |
604 | 604 | ||
605 | return 0; | 605 | return 0; |
606 | } | 606 | } |
607 | 607 | ||
608 | static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | 608 | static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, |
609 | size_t len, size_t *retlen, const u_char *buf) | 609 | size_t len, size_t *retlen, const u_char *buf) |
610 | { | 610 | { |
611 | struct map_info *map = mtd->priv; | 611 | struct map_info *map = mtd->priv; |
612 | struct cfi_private *cfi = map->fldrv_priv; | 612 | struct cfi_private *cfi = map->fldrv_priv; |
613 | int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; | 613 | int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; |
614 | int ret = 0; | 614 | int ret = 0; |
615 | int chipnum; | 615 | int chipnum; |
616 | unsigned long ofs; | 616 | unsigned long ofs; |
617 | 617 | ||
618 | *retlen = 0; | 618 | *retlen = 0; |
619 | if (!len) | 619 | if (!len) |
620 | return 0; | 620 | return 0; |
621 | 621 | ||
622 | chipnum = to >> cfi->chipshift; | 622 | chipnum = to >> cfi->chipshift; |
623 | ofs = to - (chipnum << cfi->chipshift); | 623 | ofs = to - (chipnum << cfi->chipshift); |
624 | 624 | ||
625 | #ifdef DEBUG_CFI_FEATURES | 625 | #ifdef DEBUG_CFI_FEATURES |
626 | printk("%s: map_bankwidth(map)[%x]\n", __func__, map_bankwidth(map)); | 626 | printk("%s: map_bankwidth(map)[%x]\n", __func__, map_bankwidth(map)); |
627 | printk("%s: chipnum[%x] wbufsize[%x]\n", __func__, chipnum, wbufsize); | 627 | printk("%s: chipnum[%x] wbufsize[%x]\n", __func__, chipnum, wbufsize); |
628 | printk("%s: ofs[%x] len[%x]\n", __func__, ofs, len); | 628 | printk("%s: ofs[%x] len[%x]\n", __func__, ofs, len); |
629 | #endif | 629 | #endif |
630 | 630 | ||
631 | /* Write buffer is worth it only if more than one word to write... */ | 631 | /* Write buffer is worth it only if more than one word to write... */ |
632 | while (len > 0) { | 632 | while (len > 0) { |
633 | /* We must not cross write block boundaries */ | 633 | /* We must not cross write block boundaries */ |
634 | int size = wbufsize - (ofs & (wbufsize-1)); | 634 | int size = wbufsize - (ofs & (wbufsize-1)); |
635 | 635 | ||
636 | if (size > len) | 636 | if (size > len) |
637 | size = len; | 637 | size = len; |
638 | 638 | ||
639 | ret = do_write_buffer(map, &cfi->chips[chipnum], | 639 | ret = do_write_buffer(map, &cfi->chips[chipnum], |
640 | ofs, buf, size); | 640 | ofs, buf, size); |
641 | if (ret) | 641 | if (ret) |
642 | return ret; | 642 | return ret; |
643 | 643 | ||
644 | ofs += size; | 644 | ofs += size; |
645 | buf += size; | 645 | buf += size; |
646 | (*retlen) += size; | 646 | (*retlen) += size; |
647 | len -= size; | 647 | len -= size; |
648 | 648 | ||
649 | if (ofs >> cfi->chipshift) { | 649 | if (ofs >> cfi->chipshift) { |
650 | chipnum ++; | 650 | chipnum ++; |
651 | ofs = 0; | 651 | ofs = 0; |
652 | if (chipnum == cfi->numchips) | 652 | if (chipnum == cfi->numchips) |
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | } | 655 | } |
656 | 656 | ||
657 | return 0; | 657 | return 0; |
658 | } | 658 | } |
659 | 659 | ||
660 | /* | 660 | /* |
661 | * Writev for ECC-Flashes is a little more complicated. We need to maintain | 661 | * Writev for ECC-Flashes is a little more complicated. We need to maintain |
662 | * a small buffer for this. | 662 | * a small buffer for this. |
663 | * XXX: If the buffer size is not a multiple of 2, this will break | 663 | * XXX: If the buffer size is not a multiple of 2, this will break |
664 | */ | 664 | */ |
665 | #define ECCBUF_SIZE (mtd->writesize) | 665 | #define ECCBUF_SIZE (mtd->writesize) |
666 | #define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1)) | 666 | #define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1)) |
667 | #define ECCBUF_MOD(x) ((x) & (ECCBUF_SIZE - 1)) | 667 | #define ECCBUF_MOD(x) ((x) & (ECCBUF_SIZE - 1)) |
668 | static int | 668 | static int |
669 | cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, | 669 | cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, |
670 | unsigned long count, loff_t to, size_t *retlen) | 670 | unsigned long count, loff_t to, size_t *retlen) |
671 | { | 671 | { |
672 | unsigned long i; | 672 | unsigned long i; |
673 | size_t totlen = 0, thislen; | 673 | size_t totlen = 0, thislen; |
674 | int ret = 0; | 674 | int ret = 0; |
675 | size_t buflen = 0; | 675 | size_t buflen = 0; |
676 | static char *buffer; | 676 | static char *buffer; |
677 | 677 | ||
678 | if (!ECCBUF_SIZE) { | 678 | if (!ECCBUF_SIZE) { |
679 | /* We should fall back to a general writev implementation. | 679 | /* We should fall back to a general writev implementation. |
680 | * Until that is written, just break. | 680 | * Until that is written, just break. |
681 | */ | 681 | */ |
682 | return -EIO; | 682 | return -EIO; |
683 | } | 683 | } |
684 | buffer = kmalloc(ECCBUF_SIZE, GFP_KERNEL); | 684 | buffer = kmalloc(ECCBUF_SIZE, GFP_KERNEL); |
685 | if (!buffer) | 685 | if (!buffer) |
686 | return -ENOMEM; | 686 | return -ENOMEM; |
687 | 687 | ||
688 | for (i=0; i<count; i++) { | 688 | for (i=0; i<count; i++) { |
689 | size_t elem_len = vecs[i].iov_len; | 689 | size_t elem_len = vecs[i].iov_len; |
690 | void *elem_base = vecs[i].iov_base; | 690 | void *elem_base = vecs[i].iov_base; |
691 | if (!elem_len) /* FIXME: Might be unnecessary. Check that */ | 691 | if (!elem_len) /* FIXME: Might be unnecessary. Check that */ |
692 | continue; | 692 | continue; |
693 | if (buflen) { /* cut off head */ | 693 | if (buflen) { /* cut off head */ |
694 | if (buflen + elem_len < ECCBUF_SIZE) { /* just accumulate */ | 694 | if (buflen + elem_len < ECCBUF_SIZE) { /* just accumulate */ |
695 | memcpy(buffer+buflen, elem_base, elem_len); | 695 | memcpy(buffer+buflen, elem_base, elem_len); |
696 | buflen += elem_len; | 696 | buflen += elem_len; |
697 | continue; | 697 | continue; |
698 | } | 698 | } |
699 | memcpy(buffer+buflen, elem_base, ECCBUF_SIZE-buflen); | 699 | memcpy(buffer+buflen, elem_base, ECCBUF_SIZE-buflen); |
700 | ret = mtd->write(mtd, to, ECCBUF_SIZE, &thislen, buffer); | 700 | ret = mtd->write(mtd, to, ECCBUF_SIZE, &thislen, buffer); |
701 | totlen += thislen; | 701 | totlen += thislen; |
702 | if (ret || thislen != ECCBUF_SIZE) | 702 | if (ret || thislen != ECCBUF_SIZE) |
703 | goto write_error; | 703 | goto write_error; |
704 | elem_len -= thislen-buflen; | 704 | elem_len -= thislen-buflen; |
705 | elem_base += thislen-buflen; | 705 | elem_base += thislen-buflen; |
706 | to += ECCBUF_SIZE; | 706 | to += ECCBUF_SIZE; |
707 | } | 707 | } |
708 | if (ECCBUF_DIV(elem_len)) { /* write clean aligned data */ | 708 | if (ECCBUF_DIV(elem_len)) { /* write clean aligned data */ |
709 | ret = mtd->write(mtd, to, ECCBUF_DIV(elem_len), &thislen, elem_base); | 709 | ret = mtd->write(mtd, to, ECCBUF_DIV(elem_len), &thislen, elem_base); |
710 | totlen += thislen; | 710 | totlen += thislen; |
711 | if (ret || thislen != ECCBUF_DIV(elem_len)) | 711 | if (ret || thislen != ECCBUF_DIV(elem_len)) |
712 | goto write_error; | 712 | goto write_error; |
713 | to += thislen; | 713 | to += thislen; |
714 | } | 714 | } |
715 | buflen = ECCBUF_MOD(elem_len); /* cut off tail */ | 715 | buflen = ECCBUF_MOD(elem_len); /* cut off tail */ |
716 | if (buflen) { | 716 | if (buflen) { |
717 | memset(buffer, 0xff, ECCBUF_SIZE); | 717 | memset(buffer, 0xff, ECCBUF_SIZE); |
718 | memcpy(buffer, elem_base + thislen, buflen); | 718 | memcpy(buffer, elem_base + thislen, buflen); |
719 | } | 719 | } |
720 | } | 720 | } |
721 | if (buflen) { /* flush last page, even if not full */ | 721 | if (buflen) { /* flush last page, even if not full */ |
722 | /* This is sometimes intended behaviour, really */ | 722 | /* This is sometimes intended behaviour, really */ |
723 | ret = mtd->write(mtd, to, buflen, &thislen, buffer); | 723 | ret = mtd->write(mtd, to, buflen, &thislen, buffer); |
724 | totlen += thislen; | 724 | totlen += thislen; |
725 | if (ret || thislen != ECCBUF_SIZE) | 725 | if (ret || thislen != ECCBUF_SIZE) |
726 | goto write_error; | 726 | goto write_error; |
727 | } | 727 | } |
728 | write_error: | 728 | write_error: |
729 | if (retlen) | 729 | if (retlen) |
730 | *retlen = totlen; | 730 | *retlen = totlen; |
731 | kfree(buffer); | 731 | kfree(buffer); |
732 | return ret; | 732 | return ret; |
733 | } | 733 | } |
734 | 734 | ||
735 | 735 | ||
736 | static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) | 736 | static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) |
737 | { | 737 | { |
738 | struct cfi_private *cfi = map->fldrv_priv; | 738 | struct cfi_private *cfi = map->fldrv_priv; |
739 | map_word status, status_OK; | 739 | map_word status, status_OK; |
740 | unsigned long timeo; | 740 | unsigned long timeo; |
741 | int retries = 3; | 741 | int retries = 3; |
742 | DECLARE_WAITQUEUE(wait, current); | 742 | DECLARE_WAITQUEUE(wait, current); |
743 | int ret = 0; | 743 | int ret = 0; |
744 | 744 | ||
745 | adr += chip->start; | 745 | adr += chip->start; |
746 | 746 | ||
747 | /* Let's determine this according to the interleave only once */ | 747 | /* Let's determine this according to the interleave only once */ |
748 | status_OK = CMD(0x80); | 748 | status_OK = CMD(0x80); |
749 | 749 | ||
750 | timeo = jiffies + HZ; | 750 | timeo = jiffies + HZ; |
751 | retry: | 751 | retry: |
752 | spin_lock_bh(chip->mutex); | 752 | spin_lock_bh(chip->mutex); |
753 | 753 | ||
754 | /* Check that the chip's ready to talk to us. */ | 754 | /* Check that the chip's ready to talk to us. */ |
755 | switch (chip->state) { | 755 | switch (chip->state) { |
756 | case FL_CFI_QUERY: | 756 | case FL_CFI_QUERY: |
757 | case FL_JEDEC_QUERY: | 757 | case FL_JEDEC_QUERY: |
758 | case FL_READY: | 758 | case FL_READY: |
759 | map_write(map, CMD(0x70), adr); | 759 | map_write(map, CMD(0x70), adr); |
760 | chip->state = FL_STATUS; | 760 | chip->state = FL_STATUS; |
761 | 761 | ||
762 | case FL_STATUS: | 762 | case FL_STATUS: |
763 | status = map_read(map, adr); | 763 | status = map_read(map, adr); |
764 | if (map_word_andequal(map, status, status_OK, status_OK)) | 764 | if (map_word_andequal(map, status, status_OK, status_OK)) |
765 | break; | 765 | break; |
766 | 766 | ||
767 | /* Urgh. Chip not yet ready to talk to us. */ | 767 | /* Urgh. Chip not yet ready to talk to us. */ |
768 | if (time_after(jiffies, timeo)) { | 768 | if (time_after(jiffies, timeo)) { |
769 | spin_unlock_bh(chip->mutex); | 769 | spin_unlock_bh(chip->mutex); |
770 | printk(KERN_ERR "waiting for chip to be ready timed out in erase\n"); | 770 | printk(KERN_ERR "waiting for chip to be ready timed out in erase\n"); |
771 | return -EIO; | 771 | return -EIO; |
772 | } | 772 | } |
773 | 773 | ||
774 | /* Latency issues. Drop the lock, wait a while and retry */ | 774 | /* Latency issues. Drop the lock, wait a while and retry */ |
775 | spin_unlock_bh(chip->mutex); | 775 | spin_unlock_bh(chip->mutex); |
776 | cfi_udelay(1); | 776 | cfi_udelay(1); |
777 | goto retry; | 777 | goto retry; |
778 | 778 | ||
779 | default: | 779 | default: |
780 | /* Stick ourselves on a wait queue to be woken when | 780 | /* Stick ourselves on a wait queue to be woken when |
781 | someone changes the status */ | 781 | someone changes the status */ |
782 | set_current_state(TASK_UNINTERRUPTIBLE); | 782 | set_current_state(TASK_UNINTERRUPTIBLE); |
783 | add_wait_queue(&chip->wq, &wait); | 783 | add_wait_queue(&chip->wq, &wait); |
784 | spin_unlock_bh(chip->mutex); | 784 | spin_unlock_bh(chip->mutex); |
785 | schedule(); | 785 | schedule(); |
786 | remove_wait_queue(&chip->wq, &wait); | 786 | remove_wait_queue(&chip->wq, &wait); |
787 | timeo = jiffies + HZ; | 787 | timeo = jiffies + HZ; |
788 | goto retry; | 788 | goto retry; |
789 | } | 789 | } |
790 | 790 | ||
791 | ENABLE_VPP(map); | 791 | ENABLE_VPP(map); |
792 | /* Clear the status register first */ | 792 | /* Clear the status register first */ |
793 | map_write(map, CMD(0x50), adr); | 793 | map_write(map, CMD(0x50), adr); |
794 | 794 | ||
795 | /* Now erase */ | 795 | /* Now erase */ |
796 | map_write(map, CMD(0x20), adr); | 796 | map_write(map, CMD(0x20), adr); |
797 | map_write(map, CMD(0xD0), adr); | 797 | map_write(map, CMD(0xD0), adr); |
798 | chip->state = FL_ERASING; | 798 | chip->state = FL_ERASING; |
799 | 799 | ||
800 | spin_unlock_bh(chip->mutex); | 800 | spin_unlock_bh(chip->mutex); |
801 | msleep(1000); | 801 | msleep(1000); |
802 | spin_lock_bh(chip->mutex); | 802 | spin_lock_bh(chip->mutex); |
803 | 803 | ||
804 | /* FIXME. Use a timer to check this, and return immediately. */ | 804 | /* FIXME. Use a timer to check this, and return immediately. */ |
805 | /* Once the state machine's known to be working I'll do that */ | 805 | /* Once the state machine's known to be working I'll do that */ |
806 | 806 | ||
807 | timeo = jiffies + (HZ*20); | 807 | timeo = jiffies + (HZ*20); |
808 | for (;;) { | 808 | for (;;) { |
809 | if (chip->state != FL_ERASING) { | 809 | if (chip->state != FL_ERASING) { |
810 | /* Someone's suspended the erase. Sleep */ | 810 | /* Someone's suspended the erase. Sleep */ |
811 | set_current_state(TASK_UNINTERRUPTIBLE); | 811 | set_current_state(TASK_UNINTERRUPTIBLE); |
812 | add_wait_queue(&chip->wq, &wait); | 812 | add_wait_queue(&chip->wq, &wait); |
813 | spin_unlock_bh(chip->mutex); | 813 | spin_unlock_bh(chip->mutex); |
814 | schedule(); | 814 | schedule(); |
815 | remove_wait_queue(&chip->wq, &wait); | 815 | remove_wait_queue(&chip->wq, &wait); |
816 | timeo = jiffies + (HZ*20); /* FIXME */ | 816 | timeo = jiffies + (HZ*20); /* FIXME */ |
817 | spin_lock_bh(chip->mutex); | 817 | spin_lock_bh(chip->mutex); |
818 | continue; | 818 | continue; |
819 | } | 819 | } |
820 | 820 | ||
821 | status = map_read(map, adr); | 821 | status = map_read(map, adr); |
822 | if (map_word_andequal(map, status, status_OK, status_OK)) | 822 | if (map_word_andequal(map, status, status_OK, status_OK)) |
823 | break; | 823 | break; |
824 | 824 | ||
825 | /* OK Still waiting */ | 825 | /* OK Still waiting */ |
826 | if (time_after(jiffies, timeo)) { | 826 | if (time_after(jiffies, timeo)) { |
827 | map_write(map, CMD(0x70), adr); | 827 | map_write(map, CMD(0x70), adr); |
828 | chip->state = FL_STATUS; | 828 | chip->state = FL_STATUS; |
829 | printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); | 829 | printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); |
830 | DISABLE_VPP(map); | 830 | DISABLE_VPP(map); |
831 | spin_unlock_bh(chip->mutex); | 831 | spin_unlock_bh(chip->mutex); |
832 | return -EIO; | 832 | return -EIO; |
833 | } | 833 | } |
834 | 834 | ||
835 | /* Latency issues. Drop the lock, wait a while and retry */ | 835 | /* Latency issues. Drop the lock, wait a while and retry */ |
836 | spin_unlock_bh(chip->mutex); | 836 | spin_unlock_bh(chip->mutex); |
837 | cfi_udelay(1); | 837 | cfi_udelay(1); |
838 | spin_lock_bh(chip->mutex); | 838 | spin_lock_bh(chip->mutex); |
839 | } | 839 | } |
840 | 840 | ||
841 | DISABLE_VPP(map); | 841 | DISABLE_VPP(map); |
842 | ret = 0; | 842 | ret = 0; |
843 | 843 | ||
844 | /* We've broken this before. It doesn't hurt to be safe */ | 844 | /* We've broken this before. It doesn't hurt to be safe */ |
845 | map_write(map, CMD(0x70), adr); | 845 | map_write(map, CMD(0x70), adr); |
846 | chip->state = FL_STATUS; | 846 | chip->state = FL_STATUS; |
847 | status = map_read(map, adr); | 847 | status = map_read(map, adr); |
848 | 848 | ||
849 | /* check for lock bit */ | 849 | /* check for lock bit */ |
850 | if (map_word_bitsset(map, status, CMD(0x3a))) { | 850 | if (map_word_bitsset(map, status, CMD(0x3a))) { |
851 | unsigned char chipstatus = status.x[0]; | 851 | unsigned char chipstatus = status.x[0]; |
852 | if (!map_word_equal(map, status, CMD(chipstatus))) { | 852 | if (!map_word_equal(map, status, CMD(chipstatus))) { |
853 | int i, w; | 853 | int i, w; |
854 | for (w=0; w<map_words(map); w++) { | 854 | for (w=0; w<map_words(map); w++) { |
855 | for (i = 0; i<cfi_interleave(cfi); i++) { | 855 | for (i = 0; i<cfi_interleave(cfi); i++) { |
856 | chipstatus |= status.x[w] >> (cfi->device_type * 8); | 856 | chipstatus |= status.x[w] >> (cfi->device_type * 8); |
857 | } | 857 | } |
858 | } | 858 | } |
859 | printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n", | 859 | printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n", |
860 | status.x[0], chipstatus); | 860 | status.x[0], chipstatus); |
861 | } | 861 | } |
862 | /* Reset the error bits */ | 862 | /* Reset the error bits */ |
863 | map_write(map, CMD(0x50), adr); | 863 | map_write(map, CMD(0x50), adr); |
864 | map_write(map, CMD(0x70), adr); | 864 | map_write(map, CMD(0x70), adr); |
865 | 865 | ||
866 | if ((chipstatus & 0x30) == 0x30) { | 866 | if ((chipstatus & 0x30) == 0x30) { |
867 | printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); | 867 | printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); |
868 | ret = -EIO; | 868 | ret = -EIO; |
869 | } else if (chipstatus & 0x02) { | 869 | } else if (chipstatus & 0x02) { |
870 | /* Protection bit set */ | 870 | /* Protection bit set */ |
871 | ret = -EROFS; | 871 | ret = -EROFS; |
872 | } else if (chipstatus & 0x8) { | 872 | } else if (chipstatus & 0x8) { |
873 | /* Voltage */ | 873 | /* Voltage */ |
874 | printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus); | 874 | printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus); |
875 | ret = -EIO; | 875 | ret = -EIO; |
876 | } else if (chipstatus & 0x20) { | 876 | } else if (chipstatus & 0x20) { |
877 | if (retries--) { | 877 | if (retries--) { |
878 | printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus); | 878 | printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus); |
879 | timeo = jiffies + HZ; | 879 | timeo = jiffies + HZ; |
880 | chip->state = FL_STATUS; | 880 | chip->state = FL_STATUS; |
881 | spin_unlock_bh(chip->mutex); | 881 | spin_unlock_bh(chip->mutex); |
882 | goto retry; | 882 | goto retry; |
883 | } | 883 | } |
884 | printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus); | 884 | printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus); |
885 | ret = -EIO; | 885 | ret = -EIO; |
886 | } | 886 | } |
887 | } | 887 | } |
888 | 888 | ||
889 | wake_up(&chip->wq); | 889 | wake_up(&chip->wq); |
890 | spin_unlock_bh(chip->mutex); | 890 | spin_unlock_bh(chip->mutex); |
891 | return ret; | 891 | return ret; |
892 | } | 892 | } |
893 | 893 | ||
894 | static int cfi_staa_erase_varsize(struct mtd_info *mtd, | 894 | static int cfi_staa_erase_varsize(struct mtd_info *mtd, |
895 | struct erase_info *instr) | 895 | struct erase_info *instr) |
896 | { struct map_info *map = mtd->priv; | 896 | { struct map_info *map = mtd->priv; |
897 | struct cfi_private *cfi = map->fldrv_priv; | 897 | struct cfi_private *cfi = map->fldrv_priv; |
898 | unsigned long adr, len; | 898 | unsigned long adr, len; |
899 | int chipnum, ret = 0; | 899 | int chipnum, ret = 0; |
900 | int i, first; | 900 | int i, first; |
901 | struct mtd_erase_region_info *regions = mtd->eraseregions; | 901 | struct mtd_erase_region_info *regions = mtd->eraseregions; |
902 | 902 | ||
903 | if (instr->addr > mtd->size) | 903 | if (instr->addr > mtd->size) |
904 | return -EINVAL; | 904 | return -EINVAL; |
905 | 905 | ||
906 | if ((instr->len + instr->addr) > mtd->size) | 906 | if ((instr->len + instr->addr) > mtd->size) |
907 | return -EINVAL; | 907 | return -EINVAL; |
908 | 908 | ||
909 | /* Check that both start and end of the requested erase are | 909 | /* Check that both start and end of the requested erase are |
910 | * aligned with the erasesize at the appropriate addresses. | 910 | * aligned with the erasesize at the appropriate addresses. |
911 | */ | 911 | */ |
912 | 912 | ||
913 | i = 0; | 913 | i = 0; |
914 | 914 | ||
915 | /* Skip all erase regions which are ended before the start of | 915 | /* Skip all erase regions which are ended before the start of |
916 | the requested erase. Actually, to save on the calculations, | 916 | the requested erase. Actually, to save on the calculations, |
917 | we skip to the first erase region which starts after the | 917 | we skip to the first erase region which starts after the |
918 | start of the requested erase, and then go back one. | 918 | start of the requested erase, and then go back one. |
919 | */ | 919 | */ |
920 | 920 | ||
921 | while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) | 921 | while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) |
922 | i++; | 922 | i++; |
923 | i--; | 923 | i--; |
924 | 924 | ||
925 | /* OK, now i is pointing at the erase region in which this | 925 | /* OK, now i is pointing at the erase region in which this |
926 | erase request starts. Check the start of the requested | 926 | erase request starts. Check the start of the requested |
927 | erase range is aligned with the erase size which is in | 927 | erase range is aligned with the erase size which is in |
928 | effect here. | 928 | effect here. |
929 | */ | 929 | */ |
930 | 930 | ||
931 | if (instr->addr & (regions[i].erasesize-1)) | 931 | if (instr->addr & (regions[i].erasesize-1)) |
932 | return -EINVAL; | 932 | return -EINVAL; |
933 | 933 | ||
934 | /* Remember the erase region we start on */ | 934 | /* Remember the erase region we start on */ |
935 | first = i; | 935 | first = i; |
936 | 936 | ||
937 | /* Next, check that the end of the requested erase is aligned | 937 | /* Next, check that the end of the requested erase is aligned |
938 | * with the erase region at that address. | 938 | * with the erase region at that address. |
939 | */ | 939 | */ |
940 | 940 | ||
941 | while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset) | 941 | while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset) |
942 | i++; | 942 | i++; |
943 | 943 | ||
944 | /* As before, drop back one to point at the region in which | 944 | /* As before, drop back one to point at the region in which |
945 | the address actually falls | 945 | the address actually falls |
946 | */ | 946 | */ |
947 | i--; | 947 | i--; |
948 | 948 | ||
949 | if ((instr->addr + instr->len) & (regions[i].erasesize-1)) | 949 | if ((instr->addr + instr->len) & (regions[i].erasesize-1)) |
950 | return -EINVAL; | 950 | return -EINVAL; |
951 | 951 | ||
952 | chipnum = instr->addr >> cfi->chipshift; | 952 | chipnum = instr->addr >> cfi->chipshift; |
953 | adr = instr->addr - (chipnum << cfi->chipshift); | 953 | adr = instr->addr - (chipnum << cfi->chipshift); |
954 | len = instr->len; | 954 | len = instr->len; |
955 | 955 | ||
956 | i=first; | 956 | i=first; |
957 | 957 | ||
958 | while(len) { | 958 | while(len) { |
959 | ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); | 959 | ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); |
960 | 960 | ||
961 | if (ret) | 961 | if (ret) |
962 | return ret; | 962 | return ret; |
963 | 963 | ||
964 | adr += regions[i].erasesize; | 964 | adr += regions[i].erasesize; |
965 | len -= regions[i].erasesize; | 965 | len -= regions[i].erasesize; |
966 | 966 | ||
967 | if (adr % (1<< cfi->chipshift) == (((unsigned long)regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift))) | 967 | if (adr % (1<< cfi->chipshift) == (((unsigned long)regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift))) |
968 | i++; | 968 | i++; |
969 | 969 | ||
970 | if (adr >> cfi->chipshift) { | 970 | if (adr >> cfi->chipshift) { |
971 | adr = 0; | 971 | adr = 0; |
972 | chipnum++; | 972 | chipnum++; |
973 | 973 | ||
974 | if (chipnum >= cfi->numchips) | 974 | if (chipnum >= cfi->numchips) |
975 | break; | 975 | break; |
976 | } | 976 | } |
977 | } | 977 | } |
978 | 978 | ||
979 | instr->state = MTD_ERASE_DONE; | 979 | instr->state = MTD_ERASE_DONE; |
980 | mtd_erase_callback(instr); | 980 | mtd_erase_callback(instr); |
981 | 981 | ||
982 | return 0; | 982 | return 0; |
983 | } | 983 | } |
984 | 984 | ||
985 | static void cfi_staa_sync (struct mtd_info *mtd) | 985 | static void cfi_staa_sync (struct mtd_info *mtd) |
986 | { | 986 | { |
987 | struct map_info *map = mtd->priv; | 987 | struct map_info *map = mtd->priv; |
988 | struct cfi_private *cfi = map->fldrv_priv; | 988 | struct cfi_private *cfi = map->fldrv_priv; |
989 | int i; | 989 | int i; |
990 | struct flchip *chip; | 990 | struct flchip *chip; |
991 | int ret = 0; | 991 | int ret = 0; |
992 | DECLARE_WAITQUEUE(wait, current); | 992 | DECLARE_WAITQUEUE(wait, current); |
993 | 993 | ||
994 | for (i=0; !ret && i<cfi->numchips; i++) { | 994 | for (i=0; !ret && i<cfi->numchips; i++) { |
995 | chip = &cfi->chips[i]; | 995 | chip = &cfi->chips[i]; |
996 | 996 | ||
997 | retry: | 997 | retry: |
998 | spin_lock_bh(chip->mutex); | 998 | spin_lock_bh(chip->mutex); |
999 | 999 | ||
1000 | switch(chip->state) { | 1000 | switch(chip->state) { |
1001 | case FL_READY: | 1001 | case FL_READY: |
1002 | case FL_STATUS: | 1002 | case FL_STATUS: |
1003 | case FL_CFI_QUERY: | 1003 | case FL_CFI_QUERY: |
1004 | case FL_JEDEC_QUERY: | 1004 | case FL_JEDEC_QUERY: |
1005 | chip->oldstate = chip->state; | 1005 | chip->oldstate = chip->state; |
1006 | chip->state = FL_SYNCING; | 1006 | chip->state = FL_SYNCING; |
1007 | /* No need to wake_up() on this state change - | 1007 | /* No need to wake_up() on this state change - |
1008 | * as the whole point is that nobody can do anything | 1008 | * as the whole point is that nobody can do anything |
1009 | * with the chip now anyway. | 1009 | * with the chip now anyway. |
1010 | */ | 1010 | */ |
1011 | case FL_SYNCING: | 1011 | case FL_SYNCING: |
1012 | spin_unlock_bh(chip->mutex); | 1012 | spin_unlock_bh(chip->mutex); |
1013 | break; | 1013 | break; |
1014 | 1014 | ||
1015 | default: | 1015 | default: |
1016 | /* Not an idle state */ | 1016 | /* Not an idle state */ |
1017 | set_current_state(TASK_UNINTERRUPTIBLE); | 1017 | set_current_state(TASK_UNINTERRUPTIBLE); |
1018 | add_wait_queue(&chip->wq, &wait); | 1018 | add_wait_queue(&chip->wq, &wait); |
1019 | 1019 | ||
1020 | spin_unlock_bh(chip->mutex); | 1020 | spin_unlock_bh(chip->mutex); |
1021 | schedule(); | 1021 | schedule(); |
1022 | remove_wait_queue(&chip->wq, &wait); | 1022 | remove_wait_queue(&chip->wq, &wait); |
1023 | 1023 | ||
1024 | goto retry; | 1024 | goto retry; |
1025 | } | 1025 | } |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | /* Unlock the chips again */ | 1028 | /* Unlock the chips again */ |
1029 | 1029 | ||
1030 | for (i--; i >=0; i--) { | 1030 | for (i--; i >=0; i--) { |
1031 | chip = &cfi->chips[i]; | 1031 | chip = &cfi->chips[i]; |
1032 | 1032 | ||
1033 | spin_lock_bh(chip->mutex); | 1033 | spin_lock_bh(chip->mutex); |
1034 | 1034 | ||
1035 | if (chip->state == FL_SYNCING) { | 1035 | if (chip->state == FL_SYNCING) { |
1036 | chip->state = chip->oldstate; | 1036 | chip->state = chip->oldstate; |
1037 | wake_up(&chip->wq); | 1037 | wake_up(&chip->wq); |
1038 | } | 1038 | } |
1039 | spin_unlock_bh(chip->mutex); | 1039 | spin_unlock_bh(chip->mutex); |
1040 | } | 1040 | } |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) | 1043 | static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) |
1044 | { | 1044 | { |
1045 | struct cfi_private *cfi = map->fldrv_priv; | 1045 | struct cfi_private *cfi = map->fldrv_priv; |
1046 | map_word status, status_OK; | 1046 | map_word status, status_OK; |
1047 | unsigned long timeo = jiffies + HZ; | 1047 | unsigned long timeo = jiffies + HZ; |
1048 | DECLARE_WAITQUEUE(wait, current); | 1048 | DECLARE_WAITQUEUE(wait, current); |
1049 | 1049 | ||
1050 | adr += chip->start; | 1050 | adr += chip->start; |
1051 | 1051 | ||
1052 | /* Let's determine this according to the interleave only once */ | 1052 | /* Let's determine this according to the interleave only once */ |
1053 | status_OK = CMD(0x80); | 1053 | status_OK = CMD(0x80); |
1054 | 1054 | ||
1055 | timeo = jiffies + HZ; | 1055 | timeo = jiffies + HZ; |
1056 | retry: | 1056 | retry: |
1057 | spin_lock_bh(chip->mutex); | 1057 | spin_lock_bh(chip->mutex); |
1058 | 1058 | ||
1059 | /* Check that the chip's ready to talk to us. */ | 1059 | /* Check that the chip's ready to talk to us. */ |
1060 | switch (chip->state) { | 1060 | switch (chip->state) { |
1061 | case FL_CFI_QUERY: | 1061 | case FL_CFI_QUERY: |
1062 | case FL_JEDEC_QUERY: | 1062 | case FL_JEDEC_QUERY: |
1063 | case FL_READY: | 1063 | case FL_READY: |
1064 | map_write(map, CMD(0x70), adr); | 1064 | map_write(map, CMD(0x70), adr); |
1065 | chip->state = FL_STATUS; | 1065 | chip->state = FL_STATUS; |
1066 | 1066 | ||
1067 | case FL_STATUS: | 1067 | case FL_STATUS: |
1068 | status = map_read(map, adr); | 1068 | status = map_read(map, adr); |
1069 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1069 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1070 | break; | 1070 | break; |
1071 | 1071 | ||
1072 | /* Urgh. Chip not yet ready to talk to us. */ | 1072 | /* Urgh. Chip not yet ready to talk to us. */ |
1073 | if (time_after(jiffies, timeo)) { | 1073 | if (time_after(jiffies, timeo)) { |
1074 | spin_unlock_bh(chip->mutex); | 1074 | spin_unlock_bh(chip->mutex); |
1075 | printk(KERN_ERR "waiting for chip to be ready timed out in lock\n"); | 1075 | printk(KERN_ERR "waiting for chip to be ready timed out in lock\n"); |
1076 | return -EIO; | 1076 | return -EIO; |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | /* Latency issues. Drop the lock, wait a while and retry */ | 1079 | /* Latency issues. Drop the lock, wait a while and retry */ |
1080 | spin_unlock_bh(chip->mutex); | 1080 | spin_unlock_bh(chip->mutex); |
1081 | cfi_udelay(1); | 1081 | cfi_udelay(1); |
1082 | goto retry; | 1082 | goto retry; |
1083 | 1083 | ||
1084 | default: | 1084 | default: |
1085 | /* Stick ourselves on a wait queue to be woken when | 1085 | /* Stick ourselves on a wait queue to be woken when |
1086 | someone changes the status */ | 1086 | someone changes the status */ |
1087 | set_current_state(TASK_UNINTERRUPTIBLE); | 1087 | set_current_state(TASK_UNINTERRUPTIBLE); |
1088 | add_wait_queue(&chip->wq, &wait); | 1088 | add_wait_queue(&chip->wq, &wait); |
1089 | spin_unlock_bh(chip->mutex); | 1089 | spin_unlock_bh(chip->mutex); |
1090 | schedule(); | 1090 | schedule(); |
1091 | remove_wait_queue(&chip->wq, &wait); | 1091 | remove_wait_queue(&chip->wq, &wait); |
1092 | timeo = jiffies + HZ; | 1092 | timeo = jiffies + HZ; |
1093 | goto retry; | 1093 | goto retry; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | ENABLE_VPP(map); | 1096 | ENABLE_VPP(map); |
1097 | map_write(map, CMD(0x60), adr); | 1097 | map_write(map, CMD(0x60), adr); |
1098 | map_write(map, CMD(0x01), adr); | 1098 | map_write(map, CMD(0x01), adr); |
1099 | chip->state = FL_LOCKING; | 1099 | chip->state = FL_LOCKING; |
1100 | 1100 | ||
1101 | spin_unlock_bh(chip->mutex); | 1101 | spin_unlock_bh(chip->mutex); |
1102 | msleep(1000); | 1102 | msleep(1000); |
1103 | spin_lock_bh(chip->mutex); | 1103 | spin_lock_bh(chip->mutex); |
1104 | 1104 | ||
1105 | /* FIXME. Use a timer to check this, and return immediately. */ | 1105 | /* FIXME. Use a timer to check this, and return immediately. */ |
1106 | /* Once the state machine's known to be working I'll do that */ | 1106 | /* Once the state machine's known to be working I'll do that */ |
1107 | 1107 | ||
1108 | timeo = jiffies + (HZ*2); | 1108 | timeo = jiffies + (HZ*2); |
1109 | for (;;) { | 1109 | for (;;) { |
1110 | 1110 | ||
1111 | status = map_read(map, adr); | 1111 | status = map_read(map, adr); |
1112 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1112 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1113 | break; | 1113 | break; |
1114 | 1114 | ||
1115 | /* OK Still waiting */ | 1115 | /* OK Still waiting */ |
1116 | if (time_after(jiffies, timeo)) { | 1116 | if (time_after(jiffies, timeo)) { |
1117 | map_write(map, CMD(0x70), adr); | 1117 | map_write(map, CMD(0x70), adr); |
1118 | chip->state = FL_STATUS; | 1118 | chip->state = FL_STATUS; |
1119 | printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); | 1119 | printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); |
1120 | DISABLE_VPP(map); | 1120 | DISABLE_VPP(map); |
1121 | spin_unlock_bh(chip->mutex); | 1121 | spin_unlock_bh(chip->mutex); |
1122 | return -EIO; | 1122 | return -EIO; |
1123 | } | 1123 | } |
1124 | 1124 | ||
1125 | /* Latency issues. Drop the lock, wait a while and retry */ | 1125 | /* Latency issues. Drop the lock, wait a while and retry */ |
1126 | spin_unlock_bh(chip->mutex); | 1126 | spin_unlock_bh(chip->mutex); |
1127 | cfi_udelay(1); | 1127 | cfi_udelay(1); |
1128 | spin_lock_bh(chip->mutex); | 1128 | spin_lock_bh(chip->mutex); |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | /* Done and happy. */ | 1131 | /* Done and happy. */ |
1132 | chip->state = FL_STATUS; | 1132 | chip->state = FL_STATUS; |
1133 | DISABLE_VPP(map); | 1133 | DISABLE_VPP(map); |
1134 | wake_up(&chip->wq); | 1134 | wake_up(&chip->wq); |
1135 | spin_unlock_bh(chip->mutex); | 1135 | spin_unlock_bh(chip->mutex); |
1136 | return 0; | 1136 | return 0; |
1137 | } | 1137 | } |
1138 | static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 1138 | static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
1139 | { | 1139 | { |
1140 | struct map_info *map = mtd->priv; | 1140 | struct map_info *map = mtd->priv; |
1141 | struct cfi_private *cfi = map->fldrv_priv; | 1141 | struct cfi_private *cfi = map->fldrv_priv; |
1142 | unsigned long adr; | 1142 | unsigned long adr; |
1143 | int chipnum, ret = 0; | 1143 | int chipnum, ret = 0; |
1144 | #ifdef DEBUG_LOCK_BITS | 1144 | #ifdef DEBUG_LOCK_BITS |
1145 | int ofs_factor = cfi->interleave * cfi->device_type; | 1145 | int ofs_factor = cfi->interleave * cfi->device_type; |
1146 | #endif | 1146 | #endif |
1147 | 1147 | ||
1148 | if (ofs & (mtd->erasesize - 1)) | 1148 | if (ofs & (mtd->erasesize - 1)) |
1149 | return -EINVAL; | 1149 | return -EINVAL; |
1150 | 1150 | ||
1151 | if (len & (mtd->erasesize -1)) | 1151 | if (len & (mtd->erasesize -1)) |
1152 | return -EINVAL; | 1152 | return -EINVAL; |
1153 | 1153 | ||
1154 | if ((len + ofs) > mtd->size) | 1154 | if ((len + ofs) > mtd->size) |
1155 | return -EINVAL; | 1155 | return -EINVAL; |
1156 | 1156 | ||
1157 | chipnum = ofs >> cfi->chipshift; | 1157 | chipnum = ofs >> cfi->chipshift; |
1158 | adr = ofs - (chipnum << cfi->chipshift); | 1158 | adr = ofs - (chipnum << cfi->chipshift); |
1159 | 1159 | ||
1160 | while(len) { | 1160 | while(len) { |
1161 | 1161 | ||
1162 | #ifdef DEBUG_LOCK_BITS | 1162 | #ifdef DEBUG_LOCK_BITS |
1163 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1163 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1164 | printk("before lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1164 | printk("before lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1165 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1165 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1166 | #endif | 1166 | #endif |
1167 | 1167 | ||
1168 | ret = do_lock_oneblock(map, &cfi->chips[chipnum], adr); | 1168 | ret = do_lock_oneblock(map, &cfi->chips[chipnum], adr); |
1169 | 1169 | ||
1170 | #ifdef DEBUG_LOCK_BITS | 1170 | #ifdef DEBUG_LOCK_BITS |
1171 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1171 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1172 | printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1172 | printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1173 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1173 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1174 | #endif | 1174 | #endif |
1175 | 1175 | ||
1176 | if (ret) | 1176 | if (ret) |
1177 | return ret; | 1177 | return ret; |
1178 | 1178 | ||
1179 | adr += mtd->erasesize; | 1179 | adr += mtd->erasesize; |
1180 | len -= mtd->erasesize; | 1180 | len -= mtd->erasesize; |
1181 | 1181 | ||
1182 | if (adr >> cfi->chipshift) { | 1182 | if (adr >> cfi->chipshift) { |
1183 | adr = 0; | 1183 | adr = 0; |
1184 | chipnum++; | 1184 | chipnum++; |
1185 | 1185 | ||
1186 | if (chipnum >= cfi->numchips) | 1186 | if (chipnum >= cfi->numchips) |
1187 | break; | 1187 | break; |
1188 | } | 1188 | } |
1189 | } | 1189 | } |
1190 | return 0; | 1190 | return 0; |
1191 | } | 1191 | } |
1192 | static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) | 1192 | static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) |
1193 | { | 1193 | { |
1194 | struct cfi_private *cfi = map->fldrv_priv; | 1194 | struct cfi_private *cfi = map->fldrv_priv; |
1195 | map_word status, status_OK; | 1195 | map_word status, status_OK; |
1196 | unsigned long timeo = jiffies + HZ; | 1196 | unsigned long timeo = jiffies + HZ; |
1197 | DECLARE_WAITQUEUE(wait, current); | 1197 | DECLARE_WAITQUEUE(wait, current); |
1198 | 1198 | ||
1199 | adr += chip->start; | 1199 | adr += chip->start; |
1200 | 1200 | ||
1201 | /* Let's determine this according to the interleave only once */ | 1201 | /* Let's determine this according to the interleave only once */ |
1202 | status_OK = CMD(0x80); | 1202 | status_OK = CMD(0x80); |
1203 | 1203 | ||
1204 | timeo = jiffies + HZ; | 1204 | timeo = jiffies + HZ; |
1205 | retry: | 1205 | retry: |
1206 | spin_lock_bh(chip->mutex); | 1206 | spin_lock_bh(chip->mutex); |
1207 | 1207 | ||
1208 | /* Check that the chip's ready to talk to us. */ | 1208 | /* Check that the chip's ready to talk to us. */ |
1209 | switch (chip->state) { | 1209 | switch (chip->state) { |
1210 | case FL_CFI_QUERY: | 1210 | case FL_CFI_QUERY: |
1211 | case FL_JEDEC_QUERY: | 1211 | case FL_JEDEC_QUERY: |
1212 | case FL_READY: | 1212 | case FL_READY: |
1213 | map_write(map, CMD(0x70), adr); | 1213 | map_write(map, CMD(0x70), adr); |
1214 | chip->state = FL_STATUS; | 1214 | chip->state = FL_STATUS; |
1215 | 1215 | ||
1216 | case FL_STATUS: | 1216 | case FL_STATUS: |
1217 | status = map_read(map, adr); | 1217 | status = map_read(map, adr); |
1218 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1218 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1219 | break; | 1219 | break; |
1220 | 1220 | ||
1221 | /* Urgh. Chip not yet ready to talk to us. */ | 1221 | /* Urgh. Chip not yet ready to talk to us. */ |
1222 | if (time_after(jiffies, timeo)) { | 1222 | if (time_after(jiffies, timeo)) { |
1223 | spin_unlock_bh(chip->mutex); | 1223 | spin_unlock_bh(chip->mutex); |
1224 | printk(KERN_ERR "waiting for chip to be ready timed out in unlock\n"); | 1224 | printk(KERN_ERR "waiting for chip to be ready timed out in unlock\n"); |
1225 | return -EIO; | 1225 | return -EIO; |
1226 | } | 1226 | } |
1227 | 1227 | ||
1228 | /* Latency issues. Drop the lock, wait a while and retry */ | 1228 | /* Latency issues. Drop the lock, wait a while and retry */ |
1229 | spin_unlock_bh(chip->mutex); | 1229 | spin_unlock_bh(chip->mutex); |
1230 | cfi_udelay(1); | 1230 | cfi_udelay(1); |
1231 | goto retry; | 1231 | goto retry; |
1232 | 1232 | ||
1233 | default: | 1233 | default: |
1234 | /* Stick ourselves on a wait queue to be woken when | 1234 | /* Stick ourselves on a wait queue to be woken when |
1235 | someone changes the status */ | 1235 | someone changes the status */ |
1236 | set_current_state(TASK_UNINTERRUPTIBLE); | 1236 | set_current_state(TASK_UNINTERRUPTIBLE); |
1237 | add_wait_queue(&chip->wq, &wait); | 1237 | add_wait_queue(&chip->wq, &wait); |
1238 | spin_unlock_bh(chip->mutex); | 1238 | spin_unlock_bh(chip->mutex); |
1239 | schedule(); | 1239 | schedule(); |
1240 | remove_wait_queue(&chip->wq, &wait); | 1240 | remove_wait_queue(&chip->wq, &wait); |
1241 | timeo = jiffies + HZ; | 1241 | timeo = jiffies + HZ; |
1242 | goto retry; | 1242 | goto retry; |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | ENABLE_VPP(map); | 1245 | ENABLE_VPP(map); |
1246 | map_write(map, CMD(0x60), adr); | 1246 | map_write(map, CMD(0x60), adr); |
1247 | map_write(map, CMD(0xD0), adr); | 1247 | map_write(map, CMD(0xD0), adr); |
1248 | chip->state = FL_UNLOCKING; | 1248 | chip->state = FL_UNLOCKING; |
1249 | 1249 | ||
1250 | spin_unlock_bh(chip->mutex); | 1250 | spin_unlock_bh(chip->mutex); |
1251 | msleep(1000); | 1251 | msleep(1000); |
1252 | spin_lock_bh(chip->mutex); | 1252 | spin_lock_bh(chip->mutex); |
1253 | 1253 | ||
1254 | /* FIXME. Use a timer to check this, and return immediately. */ | 1254 | /* FIXME. Use a timer to check this, and return immediately. */ |
1255 | /* Once the state machine's known to be working I'll do that */ | 1255 | /* Once the state machine's known to be working I'll do that */ |
1256 | 1256 | ||
1257 | timeo = jiffies + (HZ*2); | 1257 | timeo = jiffies + (HZ*2); |
1258 | for (;;) { | 1258 | for (;;) { |
1259 | 1259 | ||
1260 | status = map_read(map, adr); | 1260 | status = map_read(map, adr); |
1261 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1261 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1262 | break; | 1262 | break; |
1263 | 1263 | ||
1264 | /* OK Still waiting */ | 1264 | /* OK Still waiting */ |
1265 | if (time_after(jiffies, timeo)) { | 1265 | if (time_after(jiffies, timeo)) { |
1266 | map_write(map, CMD(0x70), adr); | 1266 | map_write(map, CMD(0x70), adr); |
1267 | chip->state = FL_STATUS; | 1267 | chip->state = FL_STATUS; |
1268 | printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); | 1268 | printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]); |
1269 | DISABLE_VPP(map); | 1269 | DISABLE_VPP(map); |
1270 | spin_unlock_bh(chip->mutex); | 1270 | spin_unlock_bh(chip->mutex); |
1271 | return -EIO; | 1271 | return -EIO; |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | /* Latency issues. Drop the unlock, wait a while and retry */ | 1274 | /* Latency issues. Drop the unlock, wait a while and retry */ |
1275 | spin_unlock_bh(chip->mutex); | 1275 | spin_unlock_bh(chip->mutex); |
1276 | cfi_udelay(1); | 1276 | cfi_udelay(1); |
1277 | spin_lock_bh(chip->mutex); | 1277 | spin_lock_bh(chip->mutex); |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | /* Done and happy. */ | 1280 | /* Done and happy. */ |
1281 | chip->state = FL_STATUS; | 1281 | chip->state = FL_STATUS; |
1282 | DISABLE_VPP(map); | 1282 | DISABLE_VPP(map); |
1283 | wake_up(&chip->wq); | 1283 | wake_up(&chip->wq); |
1284 | spin_unlock_bh(chip->mutex); | 1284 | spin_unlock_bh(chip->mutex); |
1285 | return 0; | 1285 | return 0; |
1286 | } | 1286 | } |
1287 | static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 1287 | static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
1288 | { | 1288 | { |
1289 | struct map_info *map = mtd->priv; | 1289 | struct map_info *map = mtd->priv; |
1290 | struct cfi_private *cfi = map->fldrv_priv; | 1290 | struct cfi_private *cfi = map->fldrv_priv; |
1291 | unsigned long adr; | 1291 | unsigned long adr; |
1292 | int chipnum, ret = 0; | 1292 | int chipnum, ret = 0; |
1293 | #ifdef DEBUG_LOCK_BITS | 1293 | #ifdef DEBUG_LOCK_BITS |
1294 | int ofs_factor = cfi->interleave * cfi->device_type; | 1294 | int ofs_factor = cfi->interleave * cfi->device_type; |
1295 | #endif | 1295 | #endif |
1296 | 1296 | ||
1297 | chipnum = ofs >> cfi->chipshift; | 1297 | chipnum = ofs >> cfi->chipshift; |
1298 | adr = ofs - (chipnum << cfi->chipshift); | 1298 | adr = ofs - (chipnum << cfi->chipshift); |
1299 | 1299 | ||
1300 | #ifdef DEBUG_LOCK_BITS | 1300 | #ifdef DEBUG_LOCK_BITS |
1301 | { | 1301 | { |
1302 | unsigned long temp_adr = adr; | 1302 | unsigned long temp_adr = adr; |
1303 | unsigned long temp_len = len; | 1303 | unsigned long temp_len = len; |
1304 | 1304 | ||
1305 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1305 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1306 | while (temp_len) { | 1306 | while (temp_len) { |
1307 | printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); | 1307 | printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); |
1308 | temp_adr += mtd->erasesize; | 1308 | temp_adr += mtd->erasesize; |
1309 | temp_len -= mtd->erasesize; | 1309 | temp_len -= mtd->erasesize; |
1310 | } | 1310 | } |
1311 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1311 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1312 | } | 1312 | } |
1313 | #endif | 1313 | #endif |
1314 | 1314 | ||
1315 | ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr); | 1315 | ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr); |
1316 | 1316 | ||
1317 | #ifdef DEBUG_LOCK_BITS | 1317 | #ifdef DEBUG_LOCK_BITS |
1318 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1318 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1319 | printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1319 | printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1320 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1320 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1321 | #endif | 1321 | #endif |
1322 | 1322 | ||
1323 | return ret; | 1323 | return ret; |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | static int cfi_staa_suspend(struct mtd_info *mtd) | 1326 | static int cfi_staa_suspend(struct mtd_info *mtd) |
1327 | { | 1327 | { |
1328 | struct map_info *map = mtd->priv; | 1328 | struct map_info *map = mtd->priv; |
1329 | struct cfi_private *cfi = map->fldrv_priv; | 1329 | struct cfi_private *cfi = map->fldrv_priv; |
1330 | int i; | 1330 | int i; |
1331 | struct flchip *chip; | 1331 | struct flchip *chip; |
1332 | int ret = 0; | 1332 | int ret = 0; |
1333 | 1333 | ||
1334 | for (i=0; !ret && i<cfi->numchips; i++) { | 1334 | for (i=0; !ret && i<cfi->numchips; i++) { |
1335 | chip = &cfi->chips[i]; | 1335 | chip = &cfi->chips[i]; |
1336 | 1336 | ||
1337 | spin_lock_bh(chip->mutex); | 1337 | spin_lock_bh(chip->mutex); |
1338 | 1338 | ||
1339 | switch(chip->state) { | 1339 | switch(chip->state) { |
1340 | case FL_READY: | 1340 | case FL_READY: |
1341 | case FL_STATUS: | 1341 | case FL_STATUS: |
1342 | case FL_CFI_QUERY: | 1342 | case FL_CFI_QUERY: |
1343 | case FL_JEDEC_QUERY: | 1343 | case FL_JEDEC_QUERY: |
1344 | chip->oldstate = chip->state; | 1344 | chip->oldstate = chip->state; |
1345 | chip->state = FL_PM_SUSPENDED; | 1345 | chip->state = FL_PM_SUSPENDED; |
1346 | /* No need to wake_up() on this state change - | 1346 | /* No need to wake_up() on this state change - |
1347 | * as the whole point is that nobody can do anything | 1347 | * as the whole point is that nobody can do anything |
1348 | * with the chip now anyway. | 1348 | * with the chip now anyway. |
1349 | */ | 1349 | */ |
1350 | case FL_PM_SUSPENDED: | 1350 | case FL_PM_SUSPENDED: |
1351 | break; | 1351 | break; |
1352 | 1352 | ||
1353 | default: | 1353 | default: |
1354 | ret = -EAGAIN; | 1354 | ret = -EAGAIN; |
1355 | break; | 1355 | break; |
1356 | } | 1356 | } |
1357 | spin_unlock_bh(chip->mutex); | 1357 | spin_unlock_bh(chip->mutex); |
1358 | } | 1358 | } |
1359 | 1359 | ||
1360 | /* Unlock the chips again */ | 1360 | /* Unlock the chips again */ |
1361 | 1361 | ||
1362 | if (ret) { | 1362 | if (ret) { |
1363 | for (i--; i >=0; i--) { | 1363 | for (i--; i >=0; i--) { |
1364 | chip = &cfi->chips[i]; | 1364 | chip = &cfi->chips[i]; |
1365 | 1365 | ||
1366 | spin_lock_bh(chip->mutex); | 1366 | spin_lock_bh(chip->mutex); |
1367 | 1367 | ||
1368 | if (chip->state == FL_PM_SUSPENDED) { | 1368 | if (chip->state == FL_PM_SUSPENDED) { |
1369 | /* No need to force it into a known state here, | 1369 | /* No need to force it into a known state here, |
1370 | because we're returning failure, and it didn't | 1370 | because we're returning failure, and it didn't |
1371 | get power cycled */ | 1371 | get power cycled */ |
1372 | chip->state = chip->oldstate; | 1372 | chip->state = chip->oldstate; |
1373 | wake_up(&chip->wq); | 1373 | wake_up(&chip->wq); |
1374 | } | 1374 | } |
1375 | spin_unlock_bh(chip->mutex); | 1375 | spin_unlock_bh(chip->mutex); |
1376 | } | 1376 | } |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | return ret; | 1379 | return ret; |
1380 | } | 1380 | } |
1381 | 1381 | ||
1382 | static void cfi_staa_resume(struct mtd_info *mtd) | 1382 | static void cfi_staa_resume(struct mtd_info *mtd) |
1383 | { | 1383 | { |
1384 | struct map_info *map = mtd->priv; | 1384 | struct map_info *map = mtd->priv; |
1385 | struct cfi_private *cfi = map->fldrv_priv; | 1385 | struct cfi_private *cfi = map->fldrv_priv; |
1386 | int i; | 1386 | int i; |
1387 | struct flchip *chip; | 1387 | struct flchip *chip; |
1388 | 1388 | ||
1389 | for (i=0; i<cfi->numchips; i++) { | 1389 | for (i=0; i<cfi->numchips; i++) { |
1390 | 1390 | ||
1391 | chip = &cfi->chips[i]; | 1391 | chip = &cfi->chips[i]; |
1392 | 1392 | ||
1393 | spin_lock_bh(chip->mutex); | 1393 | spin_lock_bh(chip->mutex); |
1394 | 1394 | ||
1395 | /* Go to known state. Chip may have been power cycled */ | 1395 | /* Go to known state. Chip may have been power cycled */ |
1396 | if (chip->state == FL_PM_SUSPENDED) { | 1396 | if (chip->state == FL_PM_SUSPENDED) { |
1397 | map_write(map, CMD(0xFF), 0); | 1397 | map_write(map, CMD(0xFF), 0); |
1398 | chip->state = FL_READY; | 1398 | chip->state = FL_READY; |
1399 | wake_up(&chip->wq); | 1399 | wake_up(&chip->wq); |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | spin_unlock_bh(chip->mutex); | 1402 | spin_unlock_bh(chip->mutex); |
1403 | } | 1403 | } |
1404 | } | 1404 | } |
1405 | 1405 | ||
1406 | static void cfi_staa_destroy(struct mtd_info *mtd) | 1406 | static void cfi_staa_destroy(struct mtd_info *mtd) |
1407 | { | 1407 | { |
1408 | struct map_info *map = mtd->priv; | 1408 | struct map_info *map = mtd->priv; |
1409 | struct cfi_private *cfi = map->fldrv_priv; | 1409 | struct cfi_private *cfi = map->fldrv_priv; |
1410 | kfree(cfi->cmdset_priv); | 1410 | kfree(cfi->cmdset_priv); |
1411 | kfree(cfi); | 1411 | kfree(cfi); |
1412 | } | 1412 | } |
1413 | 1413 | ||
1414 | MODULE_LICENSE("GPL"); | 1414 | MODULE_LICENSE("GPL"); |
1415 | 1415 |
drivers/mtd/maps/bfin-async-flash.c
1 | /* | 1 | /* |
2 | * drivers/mtd/maps/bfin-async-flash.c | 2 | * drivers/mtd/maps/bfin-async-flash.c |
3 | * | 3 | * |
4 | * Handle the case where flash memory and ethernet mac/phy are | 4 | * Handle the case where flash memory and ethernet mac/phy are |
5 | * mapped onto the same async bank. The BF533-STAMP does this | 5 | * mapped onto the same async bank. The BF533-STAMP does this |
6 | * for example. All board-specific configuration goes in your | 6 | * for example. All board-specific configuration goes in your |
7 | * board resources file. | 7 | * board resources file. |
8 | * | 8 | * |
9 | * Copyright 2000 Nicolas Pitre <nico@cam.org> | 9 | * Copyright 2000 Nicolas Pitre <nico@fluxnic.net> |
10 | * Copyright 2005-2008 Analog Devices Inc. | 10 | * Copyright 2005-2008 Analog Devices Inc. |
11 | * | 11 | * |
12 | * Enter bugs at http://blackfin.uclinux.org/ | 12 | * Enter bugs at http://blackfin.uclinux.org/ |
13 | * | 13 | * |
14 | * Licensed under the GPL-2 or later. | 14 | * Licensed under the GPL-2 or later. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
21 | #include <linux/mtd/map.h> | 21 | #include <linux/mtd/map.h> |
22 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
23 | #include <linux/mtd/physmap.h> | 23 | #include <linux/mtd/physmap.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | 26 | ||
27 | #include <asm/blackfin.h> | 27 | #include <asm/blackfin.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <asm/unaligned.h> | 30 | #include <asm/unaligned.h> |
31 | 31 | ||
32 | #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) | 32 | #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) |
33 | 33 | ||
34 | #define DRIVER_NAME "bfin-async-flash" | 34 | #define DRIVER_NAME "bfin-async-flash" |
35 | 35 | ||
36 | struct async_state { | 36 | struct async_state { |
37 | struct mtd_info *mtd; | 37 | struct mtd_info *mtd; |
38 | struct map_info map; | 38 | struct map_info map; |
39 | int enet_flash_pin; | 39 | int enet_flash_pin; |
40 | uint32_t flash_ambctl0, flash_ambctl1; | 40 | uint32_t flash_ambctl0, flash_ambctl1; |
41 | uint32_t save_ambctl0, save_ambctl1; | 41 | uint32_t save_ambctl0, save_ambctl1; |
42 | unsigned long irq_flags; | 42 | unsigned long irq_flags; |
43 | #ifdef CONFIG_MTD_PARTITIONS | 43 | #ifdef CONFIG_MTD_PARTITIONS |
44 | struct mtd_partition *parts; | 44 | struct mtd_partition *parts; |
45 | #endif | 45 | #endif |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static void switch_to_flash(struct async_state *state) | 48 | static void switch_to_flash(struct async_state *state) |
49 | { | 49 | { |
50 | local_irq_save(state->irq_flags); | 50 | local_irq_save(state->irq_flags); |
51 | 51 | ||
52 | gpio_set_value(state->enet_flash_pin, 0); | 52 | gpio_set_value(state->enet_flash_pin, 0); |
53 | 53 | ||
54 | state->save_ambctl0 = bfin_read_EBIU_AMBCTL0(); | 54 | state->save_ambctl0 = bfin_read_EBIU_AMBCTL0(); |
55 | state->save_ambctl1 = bfin_read_EBIU_AMBCTL1(); | 55 | state->save_ambctl1 = bfin_read_EBIU_AMBCTL1(); |
56 | bfin_write_EBIU_AMBCTL0(state->flash_ambctl0); | 56 | bfin_write_EBIU_AMBCTL0(state->flash_ambctl0); |
57 | bfin_write_EBIU_AMBCTL1(state->flash_ambctl1); | 57 | bfin_write_EBIU_AMBCTL1(state->flash_ambctl1); |
58 | SSYNC(); | 58 | SSYNC(); |
59 | } | 59 | } |
60 | 60 | ||
61 | static void switch_back(struct async_state *state) | 61 | static void switch_back(struct async_state *state) |
62 | { | 62 | { |
63 | bfin_write_EBIU_AMBCTL0(state->save_ambctl0); | 63 | bfin_write_EBIU_AMBCTL0(state->save_ambctl0); |
64 | bfin_write_EBIU_AMBCTL1(state->save_ambctl1); | 64 | bfin_write_EBIU_AMBCTL1(state->save_ambctl1); |
65 | SSYNC(); | 65 | SSYNC(); |
66 | 66 | ||
67 | gpio_set_value(state->enet_flash_pin, 1); | 67 | gpio_set_value(state->enet_flash_pin, 1); |
68 | 68 | ||
69 | local_irq_restore(state->irq_flags); | 69 | local_irq_restore(state->irq_flags); |
70 | } | 70 | } |
71 | 71 | ||
72 | static map_word bfin_read(struct map_info *map, unsigned long ofs) | 72 | static map_word bfin_read(struct map_info *map, unsigned long ofs) |
73 | { | 73 | { |
74 | struct async_state *state = (struct async_state *)map->map_priv_1; | 74 | struct async_state *state = (struct async_state *)map->map_priv_1; |
75 | uint16_t word; | 75 | uint16_t word; |
76 | map_word test; | 76 | map_word test; |
77 | 77 | ||
78 | switch_to_flash(state); | 78 | switch_to_flash(state); |
79 | 79 | ||
80 | word = readw(map->virt + ofs); | 80 | word = readw(map->virt + ofs); |
81 | 81 | ||
82 | switch_back(state); | 82 | switch_back(state); |
83 | 83 | ||
84 | test.x[0] = word; | 84 | test.x[0] = word; |
85 | return test; | 85 | return test; |
86 | } | 86 | } |
87 | 87 | ||
88 | static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) | 88 | static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) |
89 | { | 89 | { |
90 | struct async_state *state = (struct async_state *)map->map_priv_1; | 90 | struct async_state *state = (struct async_state *)map->map_priv_1; |
91 | 91 | ||
92 | switch_to_flash(state); | 92 | switch_to_flash(state); |
93 | 93 | ||
94 | memcpy(to, map->virt + from, len); | 94 | memcpy(to, map->virt + from, len); |
95 | 95 | ||
96 | switch_back(state); | 96 | switch_back(state); |
97 | } | 97 | } |
98 | 98 | ||
99 | static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs) | 99 | static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs) |
100 | { | 100 | { |
101 | struct async_state *state = (struct async_state *)map->map_priv_1; | 101 | struct async_state *state = (struct async_state *)map->map_priv_1; |
102 | uint16_t d; | 102 | uint16_t d; |
103 | 103 | ||
104 | d = d1.x[0]; | 104 | d = d1.x[0]; |
105 | 105 | ||
106 | switch_to_flash(state); | 106 | switch_to_flash(state); |
107 | 107 | ||
108 | writew(d, map->virt + ofs); | 108 | writew(d, map->virt + ofs); |
109 | SSYNC(); | 109 | SSYNC(); |
110 | 110 | ||
111 | switch_back(state); | 111 | switch_back(state); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void bfin_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) | 114 | static void bfin_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) |
115 | { | 115 | { |
116 | struct async_state *state = (struct async_state *)map->map_priv_1; | 116 | struct async_state *state = (struct async_state *)map->map_priv_1; |
117 | 117 | ||
118 | switch_to_flash(state); | 118 | switch_to_flash(state); |
119 | 119 | ||
120 | memcpy(map->virt + to, from, len); | 120 | memcpy(map->virt + to, from, len); |
121 | SSYNC(); | 121 | SSYNC(); |
122 | 122 | ||
123 | switch_back(state); | 123 | switch_back(state); |
124 | } | 124 | } |
125 | 125 | ||
126 | #ifdef CONFIG_MTD_PARTITIONS | 126 | #ifdef CONFIG_MTD_PARTITIONS |
127 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | 127 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; |
128 | #endif | 128 | #endif |
129 | 129 | ||
130 | static int __devinit bfin_flash_probe(struct platform_device *pdev) | 130 | static int __devinit bfin_flash_probe(struct platform_device *pdev) |
131 | { | 131 | { |
132 | int ret; | 132 | int ret; |
133 | struct physmap_flash_data *pdata = pdev->dev.platform_data; | 133 | struct physmap_flash_data *pdata = pdev->dev.platform_data; |
134 | struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 134 | struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
135 | struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 135 | struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
136 | struct async_state *state; | 136 | struct async_state *state; |
137 | 137 | ||
138 | state = kzalloc(sizeof(*state), GFP_KERNEL); | 138 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
139 | if (!state) | 139 | if (!state) |
140 | return -ENOMEM; | 140 | return -ENOMEM; |
141 | 141 | ||
142 | state->map.name = DRIVER_NAME; | 142 | state->map.name = DRIVER_NAME; |
143 | state->map.read = bfin_read; | 143 | state->map.read = bfin_read; |
144 | state->map.copy_from = bfin_copy_from; | 144 | state->map.copy_from = bfin_copy_from; |
145 | state->map.write = bfin_write; | 145 | state->map.write = bfin_write; |
146 | state->map.copy_to = bfin_copy_to; | 146 | state->map.copy_to = bfin_copy_to; |
147 | state->map.bankwidth = pdata->width; | 147 | state->map.bankwidth = pdata->width; |
148 | state->map.size = memory->end - memory->start + 1; | 148 | state->map.size = memory->end - memory->start + 1; |
149 | state->map.virt = (void __iomem *)memory->start; | 149 | state->map.virt = (void __iomem *)memory->start; |
150 | state->map.phys = memory->start; | 150 | state->map.phys = memory->start; |
151 | state->map.map_priv_1 = (unsigned long)state; | 151 | state->map.map_priv_1 = (unsigned long)state; |
152 | state->enet_flash_pin = platform_get_irq(pdev, 0); | 152 | state->enet_flash_pin = platform_get_irq(pdev, 0); |
153 | state->flash_ambctl0 = flash_ambctl->start; | 153 | state->flash_ambctl0 = flash_ambctl->start; |
154 | state->flash_ambctl1 = flash_ambctl->end; | 154 | state->flash_ambctl1 = flash_ambctl->end; |
155 | 155 | ||
156 | if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { | 156 | if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { |
157 | pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); | 157 | pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); |
158 | kfree(state); | 158 | kfree(state); |
159 | return -EBUSY; | 159 | return -EBUSY; |
160 | } | 160 | } |
161 | gpio_direction_output(state->enet_flash_pin, 1); | 161 | gpio_direction_output(state->enet_flash_pin, 1); |
162 | 162 | ||
163 | pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); | 163 | pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); |
164 | state->mtd = do_map_probe(memory->name, &state->map); | 164 | state->mtd = do_map_probe(memory->name, &state->map); |
165 | if (!state->mtd) { | 165 | if (!state->mtd) { |
166 | gpio_free(state->enet_flash_pin); | 166 | gpio_free(state->enet_flash_pin); |
167 | kfree(state); | 167 | kfree(state); |
168 | return -ENXIO; | 168 | return -ENXIO; |
169 | } | 169 | } |
170 | 170 | ||
171 | #ifdef CONFIG_MTD_PARTITIONS | 171 | #ifdef CONFIG_MTD_PARTITIONS |
172 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); | 172 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); |
173 | if (ret > 0) { | 173 | if (ret > 0) { |
174 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); | 174 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); |
175 | add_mtd_partitions(state->mtd, pdata->parts, ret); | 175 | add_mtd_partitions(state->mtd, pdata->parts, ret); |
176 | state->parts = pdata->parts; | 176 | state->parts = pdata->parts; |
177 | 177 | ||
178 | } else if (pdata->nr_parts) { | 178 | } else if (pdata->nr_parts) { |
179 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); | 179 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); |
180 | add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts); | 180 | add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts); |
181 | 181 | ||
182 | } else | 182 | } else |
183 | #endif | 183 | #endif |
184 | { | 184 | { |
185 | pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); | 185 | pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); |
186 | add_mtd_device(state->mtd); | 186 | add_mtd_device(state->mtd); |
187 | } | 187 | } |
188 | 188 | ||
189 | platform_set_drvdata(pdev, state); | 189 | platform_set_drvdata(pdev, state); |
190 | 190 | ||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | static int __devexit bfin_flash_remove(struct platform_device *pdev) | 194 | static int __devexit bfin_flash_remove(struct platform_device *pdev) |
195 | { | 195 | { |
196 | struct async_state *state = platform_get_drvdata(pdev); | 196 | struct async_state *state = platform_get_drvdata(pdev); |
197 | gpio_free(state->enet_flash_pin); | 197 | gpio_free(state->enet_flash_pin); |
198 | #ifdef CONFIG_MTD_PARTITIONS | 198 | #ifdef CONFIG_MTD_PARTITIONS |
199 | del_mtd_partitions(state->mtd); | 199 | del_mtd_partitions(state->mtd); |
200 | kfree(state->parts); | 200 | kfree(state->parts); |
201 | #endif | 201 | #endif |
202 | map_destroy(state->mtd); | 202 | map_destroy(state->mtd); |
203 | kfree(state); | 203 | kfree(state); |
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
206 | 206 | ||
207 | static struct platform_driver bfin_flash_driver = { | 207 | static struct platform_driver bfin_flash_driver = { |
208 | .probe = bfin_flash_probe, | 208 | .probe = bfin_flash_probe, |
209 | .remove = __devexit_p(bfin_flash_remove), | 209 | .remove = __devexit_p(bfin_flash_remove), |
210 | .driver = { | 210 | .driver = { |
211 | .name = DRIVER_NAME, | 211 | .name = DRIVER_NAME, |
212 | }, | 212 | }, |
213 | }; | 213 | }; |
214 | 214 | ||
215 | static int __init bfin_flash_init(void) | 215 | static int __init bfin_flash_init(void) |
216 | { | 216 | { |
217 | return platform_driver_register(&bfin_flash_driver); | 217 | return platform_driver_register(&bfin_flash_driver); |
218 | } | 218 | } |
219 | module_init(bfin_flash_init); | 219 | module_init(bfin_flash_init); |
220 | 220 | ||
221 | static void __exit bfin_flash_exit(void) | 221 | static void __exit bfin_flash_exit(void) |
222 | { | 222 | { |
223 | platform_driver_unregister(&bfin_flash_driver); | 223 | platform_driver_unregister(&bfin_flash_driver); |
224 | } | 224 | } |
225 | module_exit(bfin_flash_exit); | 225 | module_exit(bfin_flash_exit); |
226 | 226 | ||
227 | MODULE_LICENSE("GPL"); | 227 | MODULE_LICENSE("GPL"); |
228 | MODULE_DESCRIPTION("MTD map driver for Blackfins with flash/ethernet on same async bank"); | 228 | MODULE_DESCRIPTION("MTD map driver for Blackfins with flash/ethernet on same async bank"); |
229 | 229 |
drivers/mtd/maps/ceiva.c
1 | /* | 1 | /* |
2 | * Ceiva flash memory driver. | 2 | * Ceiva flash memory driver. |
3 | * Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net> | 3 | * Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net> |
4 | * | 4 | * |
5 | * Note: this driver supports jedec compatible devices. Modification | 5 | * Note: this driver supports jedec compatible devices. Modification |
6 | * for CFI compatible devices should be straight forward: change | 6 | * for CFI compatible devices should be straight forward: change |
7 | * jedec_probe to cfi_probe. | 7 | * jedec_probe to cfi_probe. |
8 | * | 8 | * |
9 | * Based on: sa1100-flash.c, which has the following copyright: | 9 | * Based on: sa1100-flash.c, which has the following copyright: |
10 | * Flash memory access on SA11x0 based devices | 10 | * Flash memory access on SA11x0 based devices |
11 | * | 11 | * |
12 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 12 | * (C) 2000 Nicolas Pitre <nico@fluxnic.net> |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #include <linux/mtd/mtd.h> | 23 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/map.h> | 24 | #include <linux/mtd/map.h> |
25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
26 | #include <linux/mtd/concat.h> | 26 | #include <linux/mtd/concat.h> |
27 | 27 | ||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <asm/mach-types.h> | 29 | #include <asm/mach-types.h> |
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/sizes.h> | 31 | #include <asm/sizes.h> |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * This isn't complete yet, so... | 34 | * This isn't complete yet, so... |
35 | */ | 35 | */ |
36 | #define CONFIG_MTD_CEIVA_STATICMAP | 36 | #define CONFIG_MTD_CEIVA_STATICMAP |
37 | 37 | ||
38 | #ifdef CONFIG_MTD_CEIVA_STATICMAP | 38 | #ifdef CONFIG_MTD_CEIVA_STATICMAP |
39 | /* | 39 | /* |
40 | * See include/linux/mtd/partitions.h for definition of the mtd_partition | 40 | * See include/linux/mtd/partitions.h for definition of the mtd_partition |
41 | * structure. | 41 | * structure. |
42 | * | 42 | * |
43 | * Please note: | 43 | * Please note: |
44 | * 1. The flash size given should be the largest flash size that can | 44 | * 1. The flash size given should be the largest flash size that can |
45 | * be accomodated. | 45 | * be accomodated. |
46 | * | 46 | * |
47 | * 2. The bus width must defined in clps_setup_flash. | 47 | * 2. The bus width must defined in clps_setup_flash. |
48 | * | 48 | * |
49 | * The MTD layer will detect flash chip aliasing and reduce the size of | 49 | * The MTD layer will detect flash chip aliasing and reduce the size of |
50 | * the map accordingly. | 50 | * the map accordingly. |
51 | * | 51 | * |
52 | */ | 52 | */ |
53 | 53 | ||
54 | #ifdef CONFIG_ARCH_CEIVA | 54 | #ifdef CONFIG_ARCH_CEIVA |
55 | /* Flash / Partition sizing */ | 55 | /* Flash / Partition sizing */ |
56 | /* For the 28F8003, we use the block mapping to calcuate the sizes */ | 56 | /* For the 28F8003, we use the block mapping to calcuate the sizes */ |
57 | #define MAX_SIZE_KiB (16 + 8 + 8 + 96 + (7*128)) | 57 | #define MAX_SIZE_KiB (16 + 8 + 8 + 96 + (7*128)) |
58 | #define BOOT_PARTITION_SIZE_KiB (16) | 58 | #define BOOT_PARTITION_SIZE_KiB (16) |
59 | #define PARAMS_PARTITION_SIZE_KiB (8) | 59 | #define PARAMS_PARTITION_SIZE_KiB (8) |
60 | #define KERNEL_PARTITION_SIZE_KiB (4*128) | 60 | #define KERNEL_PARTITION_SIZE_KiB (4*128) |
61 | /* Use both remaing portion of first flash, and all of second flash */ | 61 | /* Use both remaing portion of first flash, and all of second flash */ |
62 | #define ROOT_PARTITION_SIZE_KiB (3*128) + (8*128) | 62 | #define ROOT_PARTITION_SIZE_KiB (3*128) + (8*128) |
63 | 63 | ||
64 | static struct mtd_partition ceiva_partitions[] = { | 64 | static struct mtd_partition ceiva_partitions[] = { |
65 | { | 65 | { |
66 | .name = "Ceiva BOOT partition", | 66 | .name = "Ceiva BOOT partition", |
67 | .size = BOOT_PARTITION_SIZE_KiB*1024, | 67 | .size = BOOT_PARTITION_SIZE_KiB*1024, |
68 | .offset = 0, | 68 | .offset = 0, |
69 | 69 | ||
70 | },{ | 70 | },{ |
71 | .name = "Ceiva parameters partition", | 71 | .name = "Ceiva parameters partition", |
72 | .size = PARAMS_PARTITION_SIZE_KiB*1024, | 72 | .size = PARAMS_PARTITION_SIZE_KiB*1024, |
73 | .offset = (16 + 8) * 1024, | 73 | .offset = (16 + 8) * 1024, |
74 | },{ | 74 | },{ |
75 | .name = "Ceiva kernel partition", | 75 | .name = "Ceiva kernel partition", |
76 | .size = (KERNEL_PARTITION_SIZE_KiB)*1024, | 76 | .size = (KERNEL_PARTITION_SIZE_KiB)*1024, |
77 | .offset = 0x20000, | 77 | .offset = 0x20000, |
78 | 78 | ||
79 | },{ | 79 | },{ |
80 | .name = "Ceiva root filesystem partition", | 80 | .name = "Ceiva root filesystem partition", |
81 | .offset = MTDPART_OFS_APPEND, | 81 | .offset = MTDPART_OFS_APPEND, |
82 | .size = (ROOT_PARTITION_SIZE_KiB)*1024, | 82 | .size = (ROOT_PARTITION_SIZE_KiB)*1024, |
83 | } | 83 | } |
84 | }; | 84 | }; |
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | static int __init clps_static_partitions(struct mtd_partition **parts) | 87 | static int __init clps_static_partitions(struct mtd_partition **parts) |
88 | { | 88 | { |
89 | int nb_parts = 0; | 89 | int nb_parts = 0; |
90 | 90 | ||
91 | #ifdef CONFIG_ARCH_CEIVA | 91 | #ifdef CONFIG_ARCH_CEIVA |
92 | if (machine_is_ceiva()) { | 92 | if (machine_is_ceiva()) { |
93 | *parts = ceiva_partitions; | 93 | *parts = ceiva_partitions; |
94 | nb_parts = ARRAY_SIZE(ceiva_partitions); | 94 | nb_parts = ARRAY_SIZE(ceiva_partitions); |
95 | } | 95 | } |
96 | #endif | 96 | #endif |
97 | return nb_parts; | 97 | return nb_parts; |
98 | } | 98 | } |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | struct clps_info { | 101 | struct clps_info { |
102 | unsigned long base; | 102 | unsigned long base; |
103 | unsigned long size; | 103 | unsigned long size; |
104 | int width; | 104 | int width; |
105 | void *vbase; | 105 | void *vbase; |
106 | struct map_info *map; | 106 | struct map_info *map; |
107 | struct mtd_info *mtd; | 107 | struct mtd_info *mtd; |
108 | struct resource *res; | 108 | struct resource *res; |
109 | }; | 109 | }; |
110 | 110 | ||
111 | #define NR_SUBMTD 4 | 111 | #define NR_SUBMTD 4 |
112 | 112 | ||
113 | static struct clps_info info[NR_SUBMTD]; | 113 | static struct clps_info info[NR_SUBMTD]; |
114 | 114 | ||
115 | static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd) | 115 | static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd) |
116 | { | 116 | { |
117 | struct mtd_info *subdev[nr]; | 117 | struct mtd_info *subdev[nr]; |
118 | struct map_info *maps; | 118 | struct map_info *maps; |
119 | int i, found = 0, ret = 0; | 119 | int i, found = 0, ret = 0; |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Allocate the map_info structs in one go. | 122 | * Allocate the map_info structs in one go. |
123 | */ | 123 | */ |
124 | maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL); | 124 | maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL); |
125 | if (!maps) | 125 | if (!maps) |
126 | return -ENOMEM; | 126 | return -ENOMEM; |
127 | /* | 127 | /* |
128 | * Claim and then map the memory regions. | 128 | * Claim and then map the memory regions. |
129 | */ | 129 | */ |
130 | for (i = 0; i < nr; i++) { | 130 | for (i = 0; i < nr; i++) { |
131 | if (clps[i].base == (unsigned long)-1) | 131 | if (clps[i].base == (unsigned long)-1) |
132 | break; | 132 | break; |
133 | 133 | ||
134 | clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash"); | 134 | clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash"); |
135 | if (!clps[i].res) { | 135 | if (!clps[i].res) { |
136 | ret = -EBUSY; | 136 | ret = -EBUSY; |
137 | break; | 137 | break; |
138 | } | 138 | } |
139 | 139 | ||
140 | clps[i].map = maps + i; | 140 | clps[i].map = maps + i; |
141 | 141 | ||
142 | clps[i].map->name = "clps flash"; | 142 | clps[i].map->name = "clps flash"; |
143 | clps[i].map->phys = clps[i].base; | 143 | clps[i].map->phys = clps[i].base; |
144 | 144 | ||
145 | clps[i].vbase = ioremap(clps[i].base, clps[i].size); | 145 | clps[i].vbase = ioremap(clps[i].base, clps[i].size); |
146 | if (!clps[i].vbase) { | 146 | if (!clps[i].vbase) { |
147 | ret = -ENOMEM; | 147 | ret = -ENOMEM; |
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | 150 | ||
151 | clps[i].map->virt = (void __iomem *)clps[i].vbase; | 151 | clps[i].map->virt = (void __iomem *)clps[i].vbase; |
152 | clps[i].map->bankwidth = clps[i].width; | 152 | clps[i].map->bankwidth = clps[i].width; |
153 | clps[i].map->size = clps[i].size; | 153 | clps[i].map->size = clps[i].size; |
154 | 154 | ||
155 | simple_map_init(&clps[i].map); | 155 | simple_map_init(&clps[i].map); |
156 | 156 | ||
157 | clps[i].mtd = do_map_probe("jedec_probe", clps[i].map); | 157 | clps[i].mtd = do_map_probe("jedec_probe", clps[i].map); |
158 | if (clps[i].mtd == NULL) { | 158 | if (clps[i].mtd == NULL) { |
159 | ret = -ENXIO; | 159 | ret = -ENXIO; |
160 | break; | 160 | break; |
161 | } | 161 | } |
162 | clps[i].mtd->owner = THIS_MODULE; | 162 | clps[i].mtd->owner = THIS_MODULE; |
163 | subdev[i] = clps[i].mtd; | 163 | subdev[i] = clps[i].mtd; |
164 | 164 | ||
165 | printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, " | 165 | printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, " |
166 | "%d-bit\n", clps[i].base, clps[i].mtd->size >> 20, | 166 | "%d-bit\n", clps[i].base, clps[i].mtd->size >> 20, |
167 | clps[i].width * 8); | 167 | clps[i].width * 8); |
168 | found += 1; | 168 | found += 1; |
169 | } | 169 | } |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * ENXIO is special. It means we didn't find a chip when | 172 | * ENXIO is special. It means we didn't find a chip when |
173 | * we probed. We need to tear down the mapping, free the | 173 | * we probed. We need to tear down the mapping, free the |
174 | * resource and mark it as such. | 174 | * resource and mark it as such. |
175 | */ | 175 | */ |
176 | if (ret == -ENXIO) { | 176 | if (ret == -ENXIO) { |
177 | iounmap(clps[i].vbase); | 177 | iounmap(clps[i].vbase); |
178 | clps[i].vbase = NULL; | 178 | clps[i].vbase = NULL; |
179 | release_resource(clps[i].res); | 179 | release_resource(clps[i].res); |
180 | clps[i].res = NULL; | 180 | clps[i].res = NULL; |
181 | } | 181 | } |
182 | 182 | ||
183 | /* | 183 | /* |
184 | * If we found one device, don't bother with concat support. | 184 | * If we found one device, don't bother with concat support. |
185 | * If we found multiple devices, use concat if we have it | 185 | * If we found multiple devices, use concat if we have it |
186 | * available, otherwise fail. | 186 | * available, otherwise fail. |
187 | */ | 187 | */ |
188 | if (ret == 0 || ret == -ENXIO) { | 188 | if (ret == 0 || ret == -ENXIO) { |
189 | if (found == 1) { | 189 | if (found == 1) { |
190 | *rmtd = subdev[0]; | 190 | *rmtd = subdev[0]; |
191 | ret = 0; | 191 | ret = 0; |
192 | } else if (found > 1) { | 192 | } else if (found > 1) { |
193 | /* | 193 | /* |
194 | * We detected multiple devices. Concatenate | 194 | * We detected multiple devices. Concatenate |
195 | * them together. | 195 | * them together. |
196 | */ | 196 | */ |
197 | #ifdef CONFIG_MTD_CONCAT | 197 | #ifdef CONFIG_MTD_CONCAT |
198 | *rmtd = mtd_concat_create(subdev, found, | 198 | *rmtd = mtd_concat_create(subdev, found, |
199 | "clps flash"); | 199 | "clps flash"); |
200 | if (*rmtd == NULL) | 200 | if (*rmtd == NULL) |
201 | ret = -ENXIO; | 201 | ret = -ENXIO; |
202 | #else | 202 | #else |
203 | printk(KERN_ERR "clps flash: multiple devices " | 203 | printk(KERN_ERR "clps flash: multiple devices " |
204 | "found but MTD concat support disabled.\n"); | 204 | "found but MTD concat support disabled.\n"); |
205 | ret = -ENXIO; | 205 | ret = -ENXIO; |
206 | #endif | 206 | #endif |
207 | } | 207 | } |
208 | } | 208 | } |
209 | 209 | ||
210 | /* | 210 | /* |
211 | * If we failed, clean up. | 211 | * If we failed, clean up. |
212 | */ | 212 | */ |
213 | if (ret) { | 213 | if (ret) { |
214 | do { | 214 | do { |
215 | if (clps[i].mtd) | 215 | if (clps[i].mtd) |
216 | map_destroy(clps[i].mtd); | 216 | map_destroy(clps[i].mtd); |
217 | if (clps[i].vbase) | 217 | if (clps[i].vbase) |
218 | iounmap(clps[i].vbase); | 218 | iounmap(clps[i].vbase); |
219 | if (clps[i].res) | 219 | if (clps[i].res) |
220 | release_resource(clps[i].res); | 220 | release_resource(clps[i].res); |
221 | } while (i--); | 221 | } while (i--); |
222 | 222 | ||
223 | kfree(maps); | 223 | kfree(maps); |
224 | } | 224 | } |
225 | 225 | ||
226 | return ret; | 226 | return ret; |
227 | } | 227 | } |
228 | 228 | ||
229 | static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd) | 229 | static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd) |
230 | { | 230 | { |
231 | int i; | 231 | int i; |
232 | 232 | ||
233 | del_mtd_partitions(mtd); | 233 | del_mtd_partitions(mtd); |
234 | 234 | ||
235 | if (mtd != clps[0].mtd) | 235 | if (mtd != clps[0].mtd) |
236 | mtd_concat_destroy(mtd); | 236 | mtd_concat_destroy(mtd); |
237 | 237 | ||
238 | for (i = NR_SUBMTD; i >= 0; i--) { | 238 | for (i = NR_SUBMTD; i >= 0; i--) { |
239 | if (clps[i].mtd) | 239 | if (clps[i].mtd) |
240 | map_destroy(clps[i].mtd); | 240 | map_destroy(clps[i].mtd); |
241 | if (clps[i].vbase) | 241 | if (clps[i].vbase) |
242 | iounmap(clps[i].vbase); | 242 | iounmap(clps[i].vbase); |
243 | if (clps[i].res) | 243 | if (clps[i].res) |
244 | release_resource(clps[i].res); | 244 | release_resource(clps[i].res); |
245 | } | 245 | } |
246 | kfree(clps[0].map); | 246 | kfree(clps[0].map); |
247 | } | 247 | } |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * We define the memory space, size, and width for the flash memory | 250 | * We define the memory space, size, and width for the flash memory |
251 | * space here. | 251 | * space here. |
252 | */ | 252 | */ |
253 | 253 | ||
254 | static int __init clps_setup_flash(void) | 254 | static int __init clps_setup_flash(void) |
255 | { | 255 | { |
256 | int nr; | 256 | int nr; |
257 | 257 | ||
258 | #ifdef CONFIG_ARCH_CEIVA | 258 | #ifdef CONFIG_ARCH_CEIVA |
259 | if (machine_is_ceiva()) { | 259 | if (machine_is_ceiva()) { |
260 | info[0].base = CS0_PHYS_BASE; | 260 | info[0].base = CS0_PHYS_BASE; |
261 | info[0].size = SZ_32M; | 261 | info[0].size = SZ_32M; |
262 | info[0].width = CEIVA_FLASH_WIDTH; | 262 | info[0].width = CEIVA_FLASH_WIDTH; |
263 | info[1].base = CS1_PHYS_BASE; | 263 | info[1].base = CS1_PHYS_BASE; |
264 | info[1].size = SZ_32M; | 264 | info[1].size = SZ_32M; |
265 | info[1].width = CEIVA_FLASH_WIDTH; | 265 | info[1].width = CEIVA_FLASH_WIDTH; |
266 | nr = 2; | 266 | nr = 2; |
267 | } | 267 | } |
268 | #endif | 268 | #endif |
269 | return nr; | 269 | return nr; |
270 | } | 270 | } |
271 | 271 | ||
272 | static struct mtd_partition *parsed_parts; | 272 | static struct mtd_partition *parsed_parts; |
273 | static const char *probes[] = { "cmdlinepart", "RedBoot", NULL }; | 273 | static const char *probes[] = { "cmdlinepart", "RedBoot", NULL }; |
274 | 274 | ||
275 | static void __init clps_locate_partitions(struct mtd_info *mtd) | 275 | static void __init clps_locate_partitions(struct mtd_info *mtd) |
276 | { | 276 | { |
277 | const char *part_type = NULL; | 277 | const char *part_type = NULL; |
278 | int nr_parts = 0; | 278 | int nr_parts = 0; |
279 | do { | 279 | do { |
280 | /* | 280 | /* |
281 | * Partition selection stuff. | 281 | * Partition selection stuff. |
282 | */ | 282 | */ |
283 | nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0); | 283 | nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0); |
284 | if (nr_parts > 0) { | 284 | if (nr_parts > 0) { |
285 | part_type = "command line"; | 285 | part_type = "command line"; |
286 | break; | 286 | break; |
287 | } | 287 | } |
288 | #ifdef CONFIG_MTD_CEIVA_STATICMAP | 288 | #ifdef CONFIG_MTD_CEIVA_STATICMAP |
289 | nr_parts = clps_static_partitions(&parsed_parts); | 289 | nr_parts = clps_static_partitions(&parsed_parts); |
290 | if (nr_parts > 0) { | 290 | if (nr_parts > 0) { |
291 | part_type = "static"; | 291 | part_type = "static"; |
292 | break; | 292 | break; |
293 | } | 293 | } |
294 | printk("found: %d partitions\n", nr_parts); | 294 | printk("found: %d partitions\n", nr_parts); |
295 | #endif | 295 | #endif |
296 | } while (0); | 296 | } while (0); |
297 | 297 | ||
298 | if (nr_parts == 0) { | 298 | if (nr_parts == 0) { |
299 | printk(KERN_NOTICE "clps flash: no partition info " | 299 | printk(KERN_NOTICE "clps flash: no partition info " |
300 | "available, registering whole flash\n"); | 300 | "available, registering whole flash\n"); |
301 | add_mtd_device(mtd); | 301 | add_mtd_device(mtd); |
302 | } else { | 302 | } else { |
303 | printk(KERN_NOTICE "clps flash: using %s partition " | 303 | printk(KERN_NOTICE "clps flash: using %s partition " |
304 | "definition\n", part_type); | 304 | "definition\n", part_type); |
305 | add_mtd_partitions(mtd, parsed_parts, nr_parts); | 305 | add_mtd_partitions(mtd, parsed_parts, nr_parts); |
306 | } | 306 | } |
307 | 307 | ||
308 | /* Always succeeds. */ | 308 | /* Always succeeds. */ |
309 | } | 309 | } |
310 | 310 | ||
311 | static void __exit clps_destroy_partitions(void) | 311 | static void __exit clps_destroy_partitions(void) |
312 | { | 312 | { |
313 | kfree(parsed_parts); | 313 | kfree(parsed_parts); |
314 | } | 314 | } |
315 | 315 | ||
316 | static struct mtd_info *mymtd; | 316 | static struct mtd_info *mymtd; |
317 | 317 | ||
318 | static int __init clps_mtd_init(void) | 318 | static int __init clps_mtd_init(void) |
319 | { | 319 | { |
320 | int ret; | 320 | int ret; |
321 | int nr; | 321 | int nr; |
322 | 322 | ||
323 | nr = clps_setup_flash(); | 323 | nr = clps_setup_flash(); |
324 | if (nr < 0) | 324 | if (nr < 0) |
325 | return nr; | 325 | return nr; |
326 | 326 | ||
327 | ret = clps_setup_mtd(info, nr, &mymtd); | 327 | ret = clps_setup_mtd(info, nr, &mymtd); |
328 | if (ret) | 328 | if (ret) |
329 | return ret; | 329 | return ret; |
330 | 330 | ||
331 | clps_locate_partitions(mymtd); | 331 | clps_locate_partitions(mymtd); |
332 | 332 | ||
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | 335 | ||
336 | static void __exit clps_mtd_cleanup(void) | 336 | static void __exit clps_mtd_cleanup(void) |
337 | { | 337 | { |
338 | clps_destroy_mtd(info, mymtd); | 338 | clps_destroy_mtd(info, mymtd); |
339 | clps_destroy_partitions(); | 339 | clps_destroy_partitions(); |
340 | } | 340 | } |
341 | 341 | ||
342 | module_init(clps_mtd_init); | 342 | module_init(clps_mtd_init); |
343 | module_exit(clps_mtd_cleanup); | 343 | module_exit(clps_mtd_cleanup); |
344 | 344 | ||
345 | MODULE_AUTHOR("Rob Scott"); | 345 | MODULE_AUTHOR("Rob Scott"); |
346 | MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver"); | 346 | MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver"); |
347 | MODULE_LICENSE("GPL"); | 347 | MODULE_LICENSE("GPL"); |
348 | 348 |
drivers/mtd/maps/dc21285.c
1 | /* | 1 | /* |
2 | * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip) | 2 | * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip) |
3 | * | 3 | * |
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * This code is GPL | 6 | * This code is GPL |
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | 14 | ||
15 | #include <linux/mtd/mtd.h> | 15 | #include <linux/mtd/mtd.h> |
16 | #include <linux/mtd/map.h> | 16 | #include <linux/mtd/map.h> |
17 | #include <linux/mtd/partitions.h> | 17 | #include <linux/mtd/partitions.h> |
18 | 18 | ||
19 | #include <asm/io.h> | 19 | #include <asm/io.h> |
20 | #include <asm/hardware/dec21285.h> | 20 | #include <asm/hardware/dec21285.h> |
21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
22 | 22 | ||
23 | 23 | ||
24 | static struct mtd_info *dc21285_mtd; | 24 | static struct mtd_info *dc21285_mtd; |
25 | 25 | ||
26 | #ifdef CONFIG_ARCH_NETWINDER | 26 | #ifdef CONFIG_ARCH_NETWINDER |
27 | /* | 27 | /* |
28 | * This is really ugly, but it seams to be the only | 28 | * This is really ugly, but it seams to be the only |
29 | * realiable way to do it, as the cpld state machine | 29 | * realiable way to do it, as the cpld state machine |
30 | * is unpredictible. So we have a 25us penalty per | 30 | * is unpredictible. So we have a 25us penalty per |
31 | * write access. | 31 | * write access. |
32 | */ | 32 | */ |
33 | static void nw_en_write(void) | 33 | static void nw_en_write(void) |
34 | { | 34 | { |
35 | unsigned long flags; | 35 | unsigned long flags; |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * we want to write a bit pattern XXX1 to Xilinx to enable | 38 | * we want to write a bit pattern XXX1 to Xilinx to enable |
39 | * the write gate, which will be open for about the next 2ms. | 39 | * the write gate, which will be open for about the next 2ms. |
40 | */ | 40 | */ |
41 | spin_lock_irqsave(&nw_gpio_lock, flags); | 41 | spin_lock_irqsave(&nw_gpio_lock, flags); |
42 | nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE); | 42 | nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE); |
43 | spin_unlock_irqrestore(&nw_gpio_lock, flags); | 43 | spin_unlock_irqrestore(&nw_gpio_lock, flags); |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * let the ISA bus to catch on... | 46 | * let the ISA bus to catch on... |
47 | */ | 47 | */ |
48 | udelay(25); | 48 | udelay(25); |
49 | } | 49 | } |
50 | #else | 50 | #else |
51 | #define nw_en_write() do { } while (0) | 51 | #define nw_en_write() do { } while (0) |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | static map_word dc21285_read8(struct map_info *map, unsigned long ofs) | 54 | static map_word dc21285_read8(struct map_info *map, unsigned long ofs) |
55 | { | 55 | { |
56 | map_word val; | 56 | map_word val; |
57 | val.x[0] = *(uint8_t*)(map->virt + ofs); | 57 | val.x[0] = *(uint8_t*)(map->virt + ofs); |
58 | return val; | 58 | return val; |
59 | } | 59 | } |
60 | 60 | ||
61 | static map_word dc21285_read16(struct map_info *map, unsigned long ofs) | 61 | static map_word dc21285_read16(struct map_info *map, unsigned long ofs) |
62 | { | 62 | { |
63 | map_word val; | 63 | map_word val; |
64 | val.x[0] = *(uint16_t*)(map->virt + ofs); | 64 | val.x[0] = *(uint16_t*)(map->virt + ofs); |
65 | return val; | 65 | return val; |
66 | } | 66 | } |
67 | 67 | ||
68 | static map_word dc21285_read32(struct map_info *map, unsigned long ofs) | 68 | static map_word dc21285_read32(struct map_info *map, unsigned long ofs) |
69 | { | 69 | { |
70 | map_word val; | 70 | map_word val; |
71 | val.x[0] = *(uint32_t*)(map->virt + ofs); | 71 | val.x[0] = *(uint32_t*)(map->virt + ofs); |
72 | return val; | 72 | return val; |
73 | } | 73 | } |
74 | 74 | ||
75 | static void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) | 75 | static void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) |
76 | { | 76 | { |
77 | memcpy(to, (void*)(map->virt + from), len); | 77 | memcpy(to, (void*)(map->virt + from), len); |
78 | } | 78 | } |
79 | 79 | ||
80 | static void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr) | 80 | static void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr) |
81 | { | 81 | { |
82 | if (machine_is_netwinder()) | 82 | if (machine_is_netwinder()) |
83 | nw_en_write(); | 83 | nw_en_write(); |
84 | *CSR_ROMWRITEREG = adr & 3; | 84 | *CSR_ROMWRITEREG = adr & 3; |
85 | adr &= ~3; | 85 | adr &= ~3; |
86 | *(uint8_t*)(map->virt + adr) = d.x[0]; | 86 | *(uint8_t*)(map->virt + adr) = d.x[0]; |
87 | } | 87 | } |
88 | 88 | ||
89 | static void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr) | 89 | static void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr) |
90 | { | 90 | { |
91 | if (machine_is_netwinder()) | 91 | if (machine_is_netwinder()) |
92 | nw_en_write(); | 92 | nw_en_write(); |
93 | *CSR_ROMWRITEREG = adr & 3; | 93 | *CSR_ROMWRITEREG = adr & 3; |
94 | adr &= ~3; | 94 | adr &= ~3; |
95 | *(uint16_t*)(map->virt + adr) = d.x[0]; | 95 | *(uint16_t*)(map->virt + adr) = d.x[0]; |
96 | } | 96 | } |
97 | 97 | ||
98 | static void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr) | 98 | static void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr) |
99 | { | 99 | { |
100 | if (machine_is_netwinder()) | 100 | if (machine_is_netwinder()) |
101 | nw_en_write(); | 101 | nw_en_write(); |
102 | *(uint32_t*)(map->virt + adr) = d.x[0]; | 102 | *(uint32_t*)(map->virt + adr) = d.x[0]; |
103 | } | 103 | } |
104 | 104 | ||
105 | static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len) | 105 | static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len) |
106 | { | 106 | { |
107 | while (len > 0) { | 107 | while (len > 0) { |
108 | map_word d; | 108 | map_word d; |
109 | d.x[0] = *((uint32_t*)from); | 109 | d.x[0] = *((uint32_t*)from); |
110 | dc21285_write32(map, d, to); | 110 | dc21285_write32(map, d, to); |
111 | from += 4; | 111 | from += 4; |
112 | to += 4; | 112 | to += 4; |
113 | len -= 4; | 113 | len -= 4; |
114 | } | 114 | } |
115 | } | 115 | } |
116 | 116 | ||
117 | static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len) | 117 | static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len) |
118 | { | 118 | { |
119 | while (len > 0) { | 119 | while (len > 0) { |
120 | map_word d; | 120 | map_word d; |
121 | d.x[0] = *((uint16_t*)from); | 121 | d.x[0] = *((uint16_t*)from); |
122 | dc21285_write16(map, d, to); | 122 | dc21285_write16(map, d, to); |
123 | from += 2; | 123 | from += 2; |
124 | to += 2; | 124 | to += 2; |
125 | len -= 2; | 125 | len -= 2; |
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
129 | static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len) | 129 | static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len) |
130 | { | 130 | { |
131 | map_word d; | 131 | map_word d; |
132 | d.x[0] = *((uint8_t*)from); | 132 | d.x[0] = *((uint8_t*)from); |
133 | dc21285_write8(map, d, to); | 133 | dc21285_write8(map, d, to); |
134 | from++; | 134 | from++; |
135 | to++; | 135 | to++; |
136 | len--; | 136 | len--; |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct map_info dc21285_map = { | 139 | static struct map_info dc21285_map = { |
140 | .name = "DC21285 flash", | 140 | .name = "DC21285 flash", |
141 | .phys = NO_XIP, | 141 | .phys = NO_XIP, |
142 | .size = 16*1024*1024, | 142 | .size = 16*1024*1024, |
143 | .copy_from = dc21285_copy_from, | 143 | .copy_from = dc21285_copy_from, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | 146 | ||
147 | /* Partition stuff */ | 147 | /* Partition stuff */ |
148 | #ifdef CONFIG_MTD_PARTITIONS | 148 | #ifdef CONFIG_MTD_PARTITIONS |
149 | static struct mtd_partition *dc21285_parts; | 149 | static struct mtd_partition *dc21285_parts; |
150 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 150 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
151 | #endif | 151 | #endif |
152 | 152 | ||
153 | static int __init init_dc21285(void) | 153 | static int __init init_dc21285(void) |
154 | { | 154 | { |
155 | 155 | ||
156 | #ifdef CONFIG_MTD_PARTITIONS | 156 | #ifdef CONFIG_MTD_PARTITIONS |
157 | int nrparts; | 157 | int nrparts; |
158 | #endif | 158 | #endif |
159 | 159 | ||
160 | /* Determine bankwidth */ | 160 | /* Determine bankwidth */ |
161 | switch (*CSR_SA110_CNTL & (3<<14)) { | 161 | switch (*CSR_SA110_CNTL & (3<<14)) { |
162 | case SA110_CNTL_ROMWIDTH_8: | 162 | case SA110_CNTL_ROMWIDTH_8: |
163 | dc21285_map.bankwidth = 1; | 163 | dc21285_map.bankwidth = 1; |
164 | dc21285_map.read = dc21285_read8; | 164 | dc21285_map.read = dc21285_read8; |
165 | dc21285_map.write = dc21285_write8; | 165 | dc21285_map.write = dc21285_write8; |
166 | dc21285_map.copy_to = dc21285_copy_to_8; | 166 | dc21285_map.copy_to = dc21285_copy_to_8; |
167 | break; | 167 | break; |
168 | case SA110_CNTL_ROMWIDTH_16: | 168 | case SA110_CNTL_ROMWIDTH_16: |
169 | dc21285_map.bankwidth = 2; | 169 | dc21285_map.bankwidth = 2; |
170 | dc21285_map.read = dc21285_read16; | 170 | dc21285_map.read = dc21285_read16; |
171 | dc21285_map.write = dc21285_write16; | 171 | dc21285_map.write = dc21285_write16; |
172 | dc21285_map.copy_to = dc21285_copy_to_16; | 172 | dc21285_map.copy_to = dc21285_copy_to_16; |
173 | break; | 173 | break; |
174 | case SA110_CNTL_ROMWIDTH_32: | 174 | case SA110_CNTL_ROMWIDTH_32: |
175 | dc21285_map.bankwidth = 4; | 175 | dc21285_map.bankwidth = 4; |
176 | dc21285_map.read = dc21285_read32; | 176 | dc21285_map.read = dc21285_read32; |
177 | dc21285_map.write = dc21285_write32; | 177 | dc21285_map.write = dc21285_write32; |
178 | dc21285_map.copy_to = dc21285_copy_to_32; | 178 | dc21285_map.copy_to = dc21285_copy_to_32; |
179 | break; | 179 | break; |
180 | default: | 180 | default: |
181 | printk (KERN_ERR "DC21285 flash: undefined bankwidth\n"); | 181 | printk (KERN_ERR "DC21285 flash: undefined bankwidth\n"); |
182 | return -ENXIO; | 182 | return -ENXIO; |
183 | } | 183 | } |
184 | printk (KERN_NOTICE "DC21285 flash support (%d-bit bankwidth)\n", | 184 | printk (KERN_NOTICE "DC21285 flash support (%d-bit bankwidth)\n", |
185 | dc21285_map.bankwidth*8); | 185 | dc21285_map.bankwidth*8); |
186 | 186 | ||
187 | /* Let's map the flash area */ | 187 | /* Let's map the flash area */ |
188 | dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024); | 188 | dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024); |
189 | if (!dc21285_map.virt) { | 189 | if (!dc21285_map.virt) { |
190 | printk("Failed to ioremap\n"); | 190 | printk("Failed to ioremap\n"); |
191 | return -EIO; | 191 | return -EIO; |
192 | } | 192 | } |
193 | 193 | ||
194 | if (machine_is_ebsa285()) { | 194 | if (machine_is_ebsa285()) { |
195 | dc21285_mtd = do_map_probe("cfi_probe", &dc21285_map); | 195 | dc21285_mtd = do_map_probe("cfi_probe", &dc21285_map); |
196 | } else { | 196 | } else { |
197 | dc21285_mtd = do_map_probe("jedec_probe", &dc21285_map); | 197 | dc21285_mtd = do_map_probe("jedec_probe", &dc21285_map); |
198 | } | 198 | } |
199 | 199 | ||
200 | if (!dc21285_mtd) { | 200 | if (!dc21285_mtd) { |
201 | iounmap(dc21285_map.virt); | 201 | iounmap(dc21285_map.virt); |
202 | return -ENXIO; | 202 | return -ENXIO; |
203 | } | 203 | } |
204 | 204 | ||
205 | dc21285_mtd->owner = THIS_MODULE; | 205 | dc21285_mtd->owner = THIS_MODULE; |
206 | 206 | ||
207 | #ifdef CONFIG_MTD_PARTITIONS | 207 | #ifdef CONFIG_MTD_PARTITIONS |
208 | nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); | 208 | nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); |
209 | if (nrparts > 0) | 209 | if (nrparts > 0) |
210 | add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); | 210 | add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); |
211 | else | 211 | else |
212 | #endif | 212 | #endif |
213 | add_mtd_device(dc21285_mtd); | 213 | add_mtd_device(dc21285_mtd); |
214 | 214 | ||
215 | if(machine_is_ebsa285()) { | 215 | if(machine_is_ebsa285()) { |
216 | /* | 216 | /* |
217 | * Flash timing is determined with bits 19-16 of the | 217 | * Flash timing is determined with bits 19-16 of the |
218 | * CSR_SA110_CNTL. The value is the number of wait cycles, or | 218 | * CSR_SA110_CNTL. The value is the number of wait cycles, or |
219 | * 0 for 16 cycles (the default). Cycles are 20 ns. | 219 | * 0 for 16 cycles (the default). Cycles are 20 ns. |
220 | * Here we use 7 for 140 ns flash chips. | 220 | * Here we use 7 for 140 ns flash chips. |
221 | */ | 221 | */ |
222 | /* access time */ | 222 | /* access time */ |
223 | *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16)); | 223 | *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16)); |
224 | /* burst time */ | 224 | /* burst time */ |
225 | *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); | 225 | *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); |
226 | /* tristate time */ | 226 | /* tristate time */ |
227 | *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); | 227 | *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); |
228 | } | 228 | } |
229 | 229 | ||
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | 232 | ||
233 | static void __exit cleanup_dc21285(void) | 233 | static void __exit cleanup_dc21285(void) |
234 | { | 234 | { |
235 | #ifdef CONFIG_MTD_PARTITIONS | 235 | #ifdef CONFIG_MTD_PARTITIONS |
236 | if (dc21285_parts) { | 236 | if (dc21285_parts) { |
237 | del_mtd_partitions(dc21285_mtd); | 237 | del_mtd_partitions(dc21285_mtd); |
238 | kfree(dc21285_parts); | 238 | kfree(dc21285_parts); |
239 | } else | 239 | } else |
240 | #endif | 240 | #endif |
241 | del_mtd_device(dc21285_mtd); | 241 | del_mtd_device(dc21285_mtd); |
242 | 242 | ||
243 | map_destroy(dc21285_mtd); | 243 | map_destroy(dc21285_mtd); |
244 | iounmap(dc21285_map.virt); | 244 | iounmap(dc21285_map.virt); |
245 | } | 245 | } |
246 | 246 | ||
247 | module_init(init_dc21285); | 247 | module_init(init_dc21285); |
248 | module_exit(cleanup_dc21285); | 248 | module_exit(cleanup_dc21285); |
249 | 249 | ||
250 | 250 | ||
251 | MODULE_LICENSE("GPL"); | 251 | MODULE_LICENSE("GPL"); |
252 | MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>"); | 252 | MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net>"); |
253 | MODULE_DESCRIPTION("MTD map driver for DC21285 boards"); | 253 | MODULE_DESCRIPTION("MTD map driver for DC21285 boards"); |
254 | 254 |
drivers/mtd/maps/ipaq-flash.c
1 | /* | 1 | /* |
2 | * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based) | 2 | * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based) |
3 | * | 3 | * |
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@fluxnic.net> |
5 | * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> | 5 | * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> |
6 | * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes | 6 | * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <asm/page.h> | 15 | #include <asm/page.h> |
16 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
18 | #include <asm/errno.h> | 18 | #include <asm/errno.h> |
19 | 19 | ||
20 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
21 | #include <linux/mtd/map.h> | 21 | #include <linux/mtd/map.h> |
22 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
23 | #ifdef CONFIG_MTD_CONCAT | 23 | #ifdef CONFIG_MTD_CONCAT |
24 | #include <linux/mtd/concat.h> | 24 | #include <linux/mtd/concat.h> |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <mach/h3600.h> | 28 | #include <mach/h3600.h> |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | 30 | ||
31 | 31 | ||
32 | #ifndef CONFIG_IPAQ_HANDHELD | 32 | #ifndef CONFIG_IPAQ_HANDHELD |
33 | #error This is for iPAQ Handhelds only | 33 | #error This is for iPAQ Handhelds only |
34 | #endif | 34 | #endif |
35 | #ifdef CONFIG_SA1100_JORNADA56X | 35 | #ifdef CONFIG_SA1100_JORNADA56X |
36 | 36 | ||
37 | static void jornada56x_set_vpp(struct map_info *map, int vpp) | 37 | static void jornada56x_set_vpp(struct map_info *map, int vpp) |
38 | { | 38 | { |
39 | if (vpp) | 39 | if (vpp) |
40 | GPSR = GPIO_GPIO26; | 40 | GPSR = GPIO_GPIO26; |
41 | else | 41 | else |
42 | GPCR = GPIO_GPIO26; | 42 | GPCR = GPIO_GPIO26; |
43 | GPDR |= GPIO_GPIO26; | 43 | GPDR |= GPIO_GPIO26; |
44 | } | 44 | } |
45 | 45 | ||
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #ifdef CONFIG_SA1100_JORNADA720 | 48 | #ifdef CONFIG_SA1100_JORNADA720 |
49 | 49 | ||
50 | static void jornada720_set_vpp(struct map_info *map, int vpp) | 50 | static void jornada720_set_vpp(struct map_info *map, int vpp) |
51 | { | 51 | { |
52 | if (vpp) | 52 | if (vpp) |
53 | PPSR |= 0x80; | 53 | PPSR |= 0x80; |
54 | else | 54 | else |
55 | PPSR &= ~0x80; | 55 | PPSR &= ~0x80; |
56 | PPDR |= 0x80; | 56 | PPDR |= 0x80; |
57 | } | 57 | } |
58 | 58 | ||
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #define MAX_IPAQ_CS 2 /* Number of CS we are going to test */ | 61 | #define MAX_IPAQ_CS 2 /* Number of CS we are going to test */ |
62 | 62 | ||
63 | #define IPAQ_MAP_INIT(X) \ | 63 | #define IPAQ_MAP_INIT(X) \ |
64 | { \ | 64 | { \ |
65 | name: "IPAQ flash " X, \ | 65 | name: "IPAQ flash " X, \ |
66 | } | 66 | } |
67 | 67 | ||
68 | 68 | ||
69 | static struct map_info ipaq_map[MAX_IPAQ_CS] = { | 69 | static struct map_info ipaq_map[MAX_IPAQ_CS] = { |
70 | IPAQ_MAP_INIT("bank 1"), | 70 | IPAQ_MAP_INIT("bank 1"), |
71 | IPAQ_MAP_INIT("bank 2") | 71 | IPAQ_MAP_INIT("bank 2") |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static struct mtd_info *my_sub_mtd[MAX_IPAQ_CS] = { | 74 | static struct mtd_info *my_sub_mtd[MAX_IPAQ_CS] = { |
75 | NULL, | 75 | NULL, |
76 | NULL | 76 | NULL |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * Here are partition information for all known IPAQ-based devices. | 80 | * Here are partition information for all known IPAQ-based devices. |
81 | * See include/linux/mtd/partitions.h for definition of the mtd_partition | 81 | * See include/linux/mtd/partitions.h for definition of the mtd_partition |
82 | * structure. | 82 | * structure. |
83 | * | 83 | * |
84 | * The *_max_flash_size is the maximum possible mapped flash size which | 84 | * The *_max_flash_size is the maximum possible mapped flash size which |
85 | * is not necessarily the actual flash size. It must be no more than | 85 | * is not necessarily the actual flash size. It must be no more than |
86 | * the value specified in the "struct map_desc *_io_desc" mapping | 86 | * the value specified in the "struct map_desc *_io_desc" mapping |
87 | * definition for the corresponding machine. | 87 | * definition for the corresponding machine. |
88 | * | 88 | * |
89 | * Please keep these in alphabetical order, and formatted as per existing | 89 | * Please keep these in alphabetical order, and formatted as per existing |
90 | * entries. Thanks. | 90 | * entries. Thanks. |
91 | */ | 91 | */ |
92 | 92 | ||
93 | #ifdef CONFIG_IPAQ_HANDHELD | 93 | #ifdef CONFIG_IPAQ_HANDHELD |
94 | static unsigned long h3xxx_max_flash_size = 0x04000000; | 94 | static unsigned long h3xxx_max_flash_size = 0x04000000; |
95 | static struct mtd_partition h3xxx_partitions[] = { | 95 | static struct mtd_partition h3xxx_partitions[] = { |
96 | { | 96 | { |
97 | name: "H3XXX boot firmware", | 97 | name: "H3XXX boot firmware", |
98 | #ifndef CONFIG_LAB | 98 | #ifndef CONFIG_LAB |
99 | size: 0x00040000, | 99 | size: 0x00040000, |
100 | #else | 100 | #else |
101 | size: 0x00080000, | 101 | size: 0x00080000, |
102 | #endif | 102 | #endif |
103 | offset: 0, | 103 | offset: 0, |
104 | #ifndef CONFIG_LAB | 104 | #ifndef CONFIG_LAB |
105 | mask_flags: MTD_WRITEABLE, /* force read-only */ | 105 | mask_flags: MTD_WRITEABLE, /* force read-only */ |
106 | #endif | 106 | #endif |
107 | }, | 107 | }, |
108 | { | 108 | { |
109 | name: "H3XXX root jffs2", | 109 | name: "H3XXX root jffs2", |
110 | #ifndef CONFIG_LAB | 110 | #ifndef CONFIG_LAB |
111 | size: 0x2000000 - 2*0x40000, /* Warning, this is fixed later */ | 111 | size: 0x2000000 - 2*0x40000, /* Warning, this is fixed later */ |
112 | offset: 0x00040000, | 112 | offset: 0x00040000, |
113 | #else | 113 | #else |
114 | size: 0x2000000 - 0x40000 - 0x80000, /* Warning, this is fixed later */ | 114 | size: 0x2000000 - 0x40000 - 0x80000, /* Warning, this is fixed later */ |
115 | offset: 0x00080000, | 115 | offset: 0x00080000, |
116 | #endif | 116 | #endif |
117 | }, | 117 | }, |
118 | { | 118 | { |
119 | name: "asset", | 119 | name: "asset", |
120 | size: 0x40000, | 120 | size: 0x40000, |
121 | offset: 0x2000000 - 0x40000, /* Warning, this is fixed later */ | 121 | offset: 0x2000000 - 0x40000, /* Warning, this is fixed later */ |
122 | mask_flags: MTD_WRITEABLE, /* force read-only */ | 122 | mask_flags: MTD_WRITEABLE, /* force read-only */ |
123 | } | 123 | } |
124 | }; | 124 | }; |
125 | 125 | ||
126 | #ifndef CONFIG_MTD_CONCAT | 126 | #ifndef CONFIG_MTD_CONCAT |
127 | static struct mtd_partition h3xxx_partitions_bank2[] = { | 127 | static struct mtd_partition h3xxx_partitions_bank2[] = { |
128 | /* this is used only on 2 CS machines when concat is not present */ | 128 | /* this is used only on 2 CS machines when concat is not present */ |
129 | { | 129 | { |
130 | name: "second H3XXX root jffs2", | 130 | name: "second H3XXX root jffs2", |
131 | size: 0x1000000 - 0x40000, /* Warning, this is fixed later */ | 131 | size: 0x1000000 - 0x40000, /* Warning, this is fixed later */ |
132 | offset: 0x00000000, | 132 | offset: 0x00000000, |
133 | }, | 133 | }, |
134 | { | 134 | { |
135 | name: "second asset", | 135 | name: "second asset", |
136 | size: 0x40000, | 136 | size: 0x40000, |
137 | offset: 0x1000000 - 0x40000, /* Warning, this is fixed later */ | 137 | offset: 0x1000000 - 0x40000, /* Warning, this is fixed later */ |
138 | mask_flags: MTD_WRITEABLE, /* force read-only */ | 138 | mask_flags: MTD_WRITEABLE, /* force read-only */ |
139 | } | 139 | } |
140 | }; | 140 | }; |
141 | #endif | 141 | #endif |
142 | 142 | ||
143 | static DEFINE_SPINLOCK(ipaq_vpp_lock); | 143 | static DEFINE_SPINLOCK(ipaq_vpp_lock); |
144 | 144 | ||
145 | static void h3xxx_set_vpp(struct map_info *map, int vpp) | 145 | static void h3xxx_set_vpp(struct map_info *map, int vpp) |
146 | { | 146 | { |
147 | static int nest = 0; | 147 | static int nest = 0; |
148 | 148 | ||
149 | spin_lock(&ipaq_vpp_lock); | 149 | spin_lock(&ipaq_vpp_lock); |
150 | if (vpp) | 150 | if (vpp) |
151 | nest++; | 151 | nest++; |
152 | else | 152 | else |
153 | nest--; | 153 | nest--; |
154 | if (nest) | 154 | if (nest) |
155 | assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 1); | 155 | assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 1); |
156 | else | 156 | else |
157 | assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 0); | 157 | assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 0); |
158 | spin_unlock(&ipaq_vpp_lock); | 158 | spin_unlock(&ipaq_vpp_lock); |
159 | } | 159 | } |
160 | 160 | ||
161 | #endif | 161 | #endif |
162 | 162 | ||
163 | #if defined(CONFIG_SA1100_JORNADA56X) || defined(CONFIG_SA1100_JORNADA720) | 163 | #if defined(CONFIG_SA1100_JORNADA56X) || defined(CONFIG_SA1100_JORNADA720) |
164 | static unsigned long jornada_max_flash_size = 0x02000000; | 164 | static unsigned long jornada_max_flash_size = 0x02000000; |
165 | static struct mtd_partition jornada_partitions[] = { | 165 | static struct mtd_partition jornada_partitions[] = { |
166 | { | 166 | { |
167 | name: "Jornada boot firmware", | 167 | name: "Jornada boot firmware", |
168 | size: 0x00040000, | 168 | size: 0x00040000, |
169 | offset: 0, | 169 | offset: 0, |
170 | mask_flags: MTD_WRITEABLE, /* force read-only */ | 170 | mask_flags: MTD_WRITEABLE, /* force read-only */ |
171 | }, { | 171 | }, { |
172 | name: "Jornada root jffs2", | 172 | name: "Jornada root jffs2", |
173 | size: MTDPART_SIZ_FULL, | 173 | size: MTDPART_SIZ_FULL, |
174 | offset: 0x00040000, | 174 | offset: 0x00040000, |
175 | } | 175 | } |
176 | }; | 176 | }; |
177 | #endif | 177 | #endif |
178 | 178 | ||
179 | 179 | ||
180 | static struct mtd_partition *parsed_parts; | 180 | static struct mtd_partition *parsed_parts; |
181 | static struct mtd_info *mymtd; | 181 | static struct mtd_info *mymtd; |
182 | 182 | ||
183 | static unsigned long cs_phys[] = { | 183 | static unsigned long cs_phys[] = { |
184 | #ifdef CONFIG_ARCH_SA1100 | 184 | #ifdef CONFIG_ARCH_SA1100 |
185 | SA1100_CS0_PHYS, | 185 | SA1100_CS0_PHYS, |
186 | SA1100_CS1_PHYS, | 186 | SA1100_CS1_PHYS, |
187 | SA1100_CS2_PHYS, | 187 | SA1100_CS2_PHYS, |
188 | SA1100_CS3_PHYS, | 188 | SA1100_CS3_PHYS, |
189 | SA1100_CS4_PHYS, | 189 | SA1100_CS4_PHYS, |
190 | SA1100_CS5_PHYS, | 190 | SA1100_CS5_PHYS, |
191 | #else | 191 | #else |
192 | PXA_CS0_PHYS, | 192 | PXA_CS0_PHYS, |
193 | PXA_CS1_PHYS, | 193 | PXA_CS1_PHYS, |
194 | PXA_CS2_PHYS, | 194 | PXA_CS2_PHYS, |
195 | PXA_CS3_PHYS, | 195 | PXA_CS3_PHYS, |
196 | PXA_CS4_PHYS, | 196 | PXA_CS4_PHYS, |
197 | PXA_CS5_PHYS, | 197 | PXA_CS5_PHYS, |
198 | #endif | 198 | #endif |
199 | }; | 199 | }; |
200 | 200 | ||
201 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; | 201 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; |
202 | 202 | ||
203 | static int __init h1900_special_case(void); | 203 | static int __init h1900_special_case(void); |
204 | 204 | ||
205 | static int __init ipaq_mtd_init(void) | 205 | static int __init ipaq_mtd_init(void) |
206 | { | 206 | { |
207 | struct mtd_partition *parts = NULL; | 207 | struct mtd_partition *parts = NULL; |
208 | int nb_parts = 0; | 208 | int nb_parts = 0; |
209 | int parsed_nr_parts = 0; | 209 | int parsed_nr_parts = 0; |
210 | const char *part_type; | 210 | const char *part_type; |
211 | int i; /* used when we have >1 flash chips */ | 211 | int i; /* used when we have >1 flash chips */ |
212 | unsigned long tot_flashsize = 0; /* used when we have >1 flash chips */ | 212 | unsigned long tot_flashsize = 0; /* used when we have >1 flash chips */ |
213 | 213 | ||
214 | /* Default flash bankwidth */ | 214 | /* Default flash bankwidth */ |
215 | // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; | 215 | // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; |
216 | 216 | ||
217 | if (machine_is_h1900()) | 217 | if (machine_is_h1900()) |
218 | { | 218 | { |
219 | /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */ | 219 | /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */ |
220 | return h1900_special_case(); | 220 | return h1900_special_case(); |
221 | } | 221 | } |
222 | 222 | ||
223 | if (machine_is_h3100() || machine_is_h1900()) | 223 | if (machine_is_h3100() || machine_is_h1900()) |
224 | for(i=0; i<MAX_IPAQ_CS; i++) | 224 | for(i=0; i<MAX_IPAQ_CS; i++) |
225 | ipaq_map[i].bankwidth = 2; | 225 | ipaq_map[i].bankwidth = 2; |
226 | else | 226 | else |
227 | for(i=0; i<MAX_IPAQ_CS; i++) | 227 | for(i=0; i<MAX_IPAQ_CS; i++) |
228 | ipaq_map[i].bankwidth = 4; | 228 | ipaq_map[i].bankwidth = 4; |
229 | 229 | ||
230 | /* | 230 | /* |
231 | * Static partition definition selection | 231 | * Static partition definition selection |
232 | */ | 232 | */ |
233 | part_type = "static"; | 233 | part_type = "static"; |
234 | 234 | ||
235 | simple_map_init(&ipaq_map[0]); | 235 | simple_map_init(&ipaq_map[0]); |
236 | simple_map_init(&ipaq_map[1]); | 236 | simple_map_init(&ipaq_map[1]); |
237 | 237 | ||
238 | #ifdef CONFIG_IPAQ_HANDHELD | 238 | #ifdef CONFIG_IPAQ_HANDHELD |
239 | if (machine_is_ipaq()) { | 239 | if (machine_is_ipaq()) { |
240 | parts = h3xxx_partitions; | 240 | parts = h3xxx_partitions; |
241 | nb_parts = ARRAY_SIZE(h3xxx_partitions); | 241 | nb_parts = ARRAY_SIZE(h3xxx_partitions); |
242 | for(i=0; i<MAX_IPAQ_CS; i++) { | 242 | for(i=0; i<MAX_IPAQ_CS; i++) { |
243 | ipaq_map[i].size = h3xxx_max_flash_size; | 243 | ipaq_map[i].size = h3xxx_max_flash_size; |
244 | ipaq_map[i].set_vpp = h3xxx_set_vpp; | 244 | ipaq_map[i].set_vpp = h3xxx_set_vpp; |
245 | ipaq_map[i].phys = cs_phys[i]; | 245 | ipaq_map[i].phys = cs_phys[i]; |
246 | ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000); | 246 | ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000); |
247 | if (machine_is_h3100 () || machine_is_h1900()) | 247 | if (machine_is_h3100 () || machine_is_h1900()) |
248 | ipaq_map[i].bankwidth = 2; | 248 | ipaq_map[i].bankwidth = 2; |
249 | } | 249 | } |
250 | if (machine_is_h3600()) { | 250 | if (machine_is_h3600()) { |
251 | /* No asset partition here */ | 251 | /* No asset partition here */ |
252 | h3xxx_partitions[1].size += 0x40000; | 252 | h3xxx_partitions[1].size += 0x40000; |
253 | nb_parts--; | 253 | nb_parts--; |
254 | } | 254 | } |
255 | } | 255 | } |
256 | #endif | 256 | #endif |
257 | #ifdef CONFIG_ARCH_H5400 | 257 | #ifdef CONFIG_ARCH_H5400 |
258 | if (machine_is_h5400()) { | 258 | if (machine_is_h5400()) { |
259 | ipaq_map[0].size = 0x02000000; | 259 | ipaq_map[0].size = 0x02000000; |
260 | ipaq_map[1].size = 0x02000000; | 260 | ipaq_map[1].size = 0x02000000; |
261 | ipaq_map[1].phys = 0x02000000; | 261 | ipaq_map[1].phys = 0x02000000; |
262 | ipaq_map[1].virt = ipaq_map[0].virt + 0x02000000; | 262 | ipaq_map[1].virt = ipaq_map[0].virt + 0x02000000; |
263 | } | 263 | } |
264 | #endif | 264 | #endif |
265 | #ifdef CONFIG_ARCH_H1900 | 265 | #ifdef CONFIG_ARCH_H1900 |
266 | if (machine_is_h1900()) { | 266 | if (machine_is_h1900()) { |
267 | ipaq_map[0].size = 0x00400000; | 267 | ipaq_map[0].size = 0x00400000; |
268 | ipaq_map[1].size = 0x02000000; | 268 | ipaq_map[1].size = 0x02000000; |
269 | ipaq_map[1].phys = 0x00080000; | 269 | ipaq_map[1].phys = 0x00080000; |
270 | ipaq_map[1].virt = ipaq_map[0].virt + 0x00080000; | 270 | ipaq_map[1].virt = ipaq_map[0].virt + 0x00080000; |
271 | } | 271 | } |
272 | #endif | 272 | #endif |
273 | 273 | ||
274 | #ifdef CONFIG_SA1100_JORNADA56X | 274 | #ifdef CONFIG_SA1100_JORNADA56X |
275 | if (machine_is_jornada56x()) { | 275 | if (machine_is_jornada56x()) { |
276 | parts = jornada_partitions; | 276 | parts = jornada_partitions; |
277 | nb_parts = ARRAY_SIZE(jornada_partitions); | 277 | nb_parts = ARRAY_SIZE(jornada_partitions); |
278 | ipaq_map[0].size = jornada_max_flash_size; | 278 | ipaq_map[0].size = jornada_max_flash_size; |
279 | ipaq_map[0].set_vpp = jornada56x_set_vpp; | 279 | ipaq_map[0].set_vpp = jornada56x_set_vpp; |
280 | ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000); | 280 | ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000); |
281 | } | 281 | } |
282 | #endif | 282 | #endif |
283 | #ifdef CONFIG_SA1100_JORNADA720 | 283 | #ifdef CONFIG_SA1100_JORNADA720 |
284 | if (machine_is_jornada720()) { | 284 | if (machine_is_jornada720()) { |
285 | parts = jornada_partitions; | 285 | parts = jornada_partitions; |
286 | nb_parts = ARRAY_SIZE(jornada_partitions); | 286 | nb_parts = ARRAY_SIZE(jornada_partitions); |
287 | ipaq_map[0].size = jornada_max_flash_size; | 287 | ipaq_map[0].size = jornada_max_flash_size; |
288 | ipaq_map[0].set_vpp = jornada720_set_vpp; | 288 | ipaq_map[0].set_vpp = jornada720_set_vpp; |
289 | } | 289 | } |
290 | #endif | 290 | #endif |
291 | 291 | ||
292 | 292 | ||
293 | if (machine_is_ipaq()) { /* for iPAQs only */ | 293 | if (machine_is_ipaq()) { /* for iPAQs only */ |
294 | for(i=0; i<MAX_IPAQ_CS; i++) { | 294 | for(i=0; i<MAX_IPAQ_CS; i++) { |
295 | printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with CFI.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt); | 295 | printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with CFI.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt); |
296 | my_sub_mtd[i] = do_map_probe("cfi_probe", &ipaq_map[i]); | 296 | my_sub_mtd[i] = do_map_probe("cfi_probe", &ipaq_map[i]); |
297 | if (!my_sub_mtd[i]) { | 297 | if (!my_sub_mtd[i]) { |
298 | printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt); | 298 | printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt); |
299 | my_sub_mtd[i] = do_map_probe("jedec_probe", &ipaq_map[i]); | 299 | my_sub_mtd[i] = do_map_probe("jedec_probe", &ipaq_map[i]); |
300 | } | 300 | } |
301 | if (!my_sub_mtd[i]) { | 301 | if (!my_sub_mtd[i]) { |
302 | printk(KERN_NOTICE "iPAQ flash: failed to find flash.\n"); | 302 | printk(KERN_NOTICE "iPAQ flash: failed to find flash.\n"); |
303 | if (i) | 303 | if (i) |
304 | break; | 304 | break; |
305 | else | 305 | else |
306 | return -ENXIO; | 306 | return -ENXIO; |
307 | } else | 307 | } else |
308 | printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size); | 308 | printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size); |
309 | 309 | ||
310 | /* do we really need this debugging? --joshua 20030703 */ | 310 | /* do we really need this debugging? --joshua 20030703 */ |
311 | // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]); | 311 | // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]); |
312 | my_sub_mtd[i]->owner = THIS_MODULE; | 312 | my_sub_mtd[i]->owner = THIS_MODULE; |
313 | tot_flashsize += my_sub_mtd[i]->size; | 313 | tot_flashsize += my_sub_mtd[i]->size; |
314 | } | 314 | } |
315 | #ifdef CONFIG_MTD_CONCAT | 315 | #ifdef CONFIG_MTD_CONCAT |
316 | /* fix the asset location */ | 316 | /* fix the asset location */ |
317 | # ifdef CONFIG_LAB | 317 | # ifdef CONFIG_LAB |
318 | h3xxx_partitions[1].size = tot_flashsize - 0x40000 - 0x80000 /* extra big boot block */; | 318 | h3xxx_partitions[1].size = tot_flashsize - 0x40000 - 0x80000 /* extra big boot block */; |
319 | # else | 319 | # else |
320 | h3xxx_partitions[1].size = tot_flashsize - 2 * 0x40000; | 320 | h3xxx_partitions[1].size = tot_flashsize - 2 * 0x40000; |
321 | # endif | 321 | # endif |
322 | h3xxx_partitions[2].offset = tot_flashsize - 0x40000; | 322 | h3xxx_partitions[2].offset = tot_flashsize - 0x40000; |
323 | /* and concat the devices */ | 323 | /* and concat the devices */ |
324 | mymtd = mtd_concat_create(&my_sub_mtd[0], i, | 324 | mymtd = mtd_concat_create(&my_sub_mtd[0], i, |
325 | "ipaq"); | 325 | "ipaq"); |
326 | if (!mymtd) { | 326 | if (!mymtd) { |
327 | printk("Cannot create iPAQ concat device\n"); | 327 | printk("Cannot create iPAQ concat device\n"); |
328 | return -ENXIO; | 328 | return -ENXIO; |
329 | } | 329 | } |
330 | #else | 330 | #else |
331 | mymtd = my_sub_mtd[0]; | 331 | mymtd = my_sub_mtd[0]; |
332 | 332 | ||
333 | /* | 333 | /* |
334 | *In the very near future, command line partition parsing | 334 | *In the very near future, command line partition parsing |
335 | * will use the device name as 'mtd-id' instead of a value | 335 | * will use the device name as 'mtd-id' instead of a value |
336 | * passed to the parse_cmdline_partitions() routine. Since | 336 | * passed to the parse_cmdline_partitions() routine. Since |
337 | * the bootldr says 'ipaq', make sure it continues to work. | 337 | * the bootldr says 'ipaq', make sure it continues to work. |
338 | */ | 338 | */ |
339 | mymtd->name = "ipaq"; | 339 | mymtd->name = "ipaq"; |
340 | 340 | ||
341 | if ((machine_is_h3600())) { | 341 | if ((machine_is_h3600())) { |
342 | # ifdef CONFIG_LAB | 342 | # ifdef CONFIG_LAB |
343 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x80000; | 343 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x80000; |
344 | # else | 344 | # else |
345 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000; | 345 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000; |
346 | # endif | 346 | # endif |
347 | nb_parts = 2; | 347 | nb_parts = 2; |
348 | } else { | 348 | } else { |
349 | # ifdef CONFIG_LAB | 349 | # ifdef CONFIG_LAB |
350 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000 - 0x80000; /* extra big boot block */ | 350 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000 - 0x80000; /* extra big boot block */ |
351 | # else | 351 | # else |
352 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 2*0x40000; | 352 | h3xxx_partitions[1].size = my_sub_mtd[0]->size - 2*0x40000; |
353 | # endif | 353 | # endif |
354 | h3xxx_partitions[2].offset = my_sub_mtd[0]->size - 0x40000; | 354 | h3xxx_partitions[2].offset = my_sub_mtd[0]->size - 0x40000; |
355 | } | 355 | } |
356 | 356 | ||
357 | if (my_sub_mtd[1]) { | 357 | if (my_sub_mtd[1]) { |
358 | # ifdef CONFIG_LAB | 358 | # ifdef CONFIG_LAB |
359 | h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x80000; | 359 | h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x80000; |
360 | # else | 360 | # else |
361 | h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x40000; | 361 | h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x40000; |
362 | # endif | 362 | # endif |
363 | h3xxx_partitions_bank2[1].offset = my_sub_mtd[1]->size - 0x40000; | 363 | h3xxx_partitions_bank2[1].offset = my_sub_mtd[1]->size - 0x40000; |
364 | } | 364 | } |
365 | #endif | 365 | #endif |
366 | } | 366 | } |
367 | else { | 367 | else { |
368 | /* | 368 | /* |
369 | * Now let's probe for the actual flash. Do it here since | 369 | * Now let's probe for the actual flash. Do it here since |
370 | * specific machine settings might have been set above. | 370 | * specific machine settings might have been set above. |
371 | */ | 371 | */ |
372 | printk(KERN_NOTICE "IPAQ flash: probing %d-bit flash bus, window=%lx\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); | 372 | printk(KERN_NOTICE "IPAQ flash: probing %d-bit flash bus, window=%lx\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); |
373 | mymtd = do_map_probe("cfi_probe", &ipaq_map[0]); | 373 | mymtd = do_map_probe("cfi_probe", &ipaq_map[0]); |
374 | if (!mymtd) | 374 | if (!mymtd) |
375 | return -ENXIO; | 375 | return -ENXIO; |
376 | mymtd->owner = THIS_MODULE; | 376 | mymtd->owner = THIS_MODULE; |
377 | } | 377 | } |
378 | 378 | ||
379 | 379 | ||
380 | /* | 380 | /* |
381 | * Dynamic partition selection stuff (might override the static ones) | 381 | * Dynamic partition selection stuff (might override the static ones) |
382 | */ | 382 | */ |
383 | 383 | ||
384 | i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0); | 384 | i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0); |
385 | 385 | ||
386 | if (i > 0) { | 386 | if (i > 0) { |
387 | nb_parts = parsed_nr_parts = i; | 387 | nb_parts = parsed_nr_parts = i; |
388 | parts = parsed_parts; | 388 | parts = parsed_parts; |
389 | part_type = "dynamic"; | 389 | part_type = "dynamic"; |
390 | } | 390 | } |
391 | 391 | ||
392 | if (!parts) { | 392 | if (!parts) { |
393 | printk(KERN_NOTICE "IPAQ flash: no partition info available, registering whole flash at once\n"); | 393 | printk(KERN_NOTICE "IPAQ flash: no partition info available, registering whole flash at once\n"); |
394 | add_mtd_device(mymtd); | 394 | add_mtd_device(mymtd); |
395 | #ifndef CONFIG_MTD_CONCAT | 395 | #ifndef CONFIG_MTD_CONCAT |
396 | if (my_sub_mtd[1]) | 396 | if (my_sub_mtd[1]) |
397 | add_mtd_device(my_sub_mtd[1]); | 397 | add_mtd_device(my_sub_mtd[1]); |
398 | #endif | 398 | #endif |
399 | } else { | 399 | } else { |
400 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 400 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
401 | add_mtd_partitions(mymtd, parts, nb_parts); | 401 | add_mtd_partitions(mymtd, parts, nb_parts); |
402 | #ifndef CONFIG_MTD_CONCAT | 402 | #ifndef CONFIG_MTD_CONCAT |
403 | if (my_sub_mtd[1]) | 403 | if (my_sub_mtd[1]) |
404 | add_mtd_partitions(my_sub_mtd[1], h3xxx_partitions_bank2, ARRAY_SIZE(h3xxx_partitions_bank2)); | 404 | add_mtd_partitions(my_sub_mtd[1], h3xxx_partitions_bank2, ARRAY_SIZE(h3xxx_partitions_bank2)); |
405 | #endif | 405 | #endif |
406 | } | 406 | } |
407 | 407 | ||
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
411 | static void __exit ipaq_mtd_cleanup(void) | 411 | static void __exit ipaq_mtd_cleanup(void) |
412 | { | 412 | { |
413 | int i; | 413 | int i; |
414 | 414 | ||
415 | if (mymtd) { | 415 | if (mymtd) { |
416 | del_mtd_partitions(mymtd); | 416 | del_mtd_partitions(mymtd); |
417 | #ifndef CONFIG_MTD_CONCAT | 417 | #ifndef CONFIG_MTD_CONCAT |
418 | if (my_sub_mtd[1]) | 418 | if (my_sub_mtd[1]) |
419 | del_mtd_partitions(my_sub_mtd[1]); | 419 | del_mtd_partitions(my_sub_mtd[1]); |
420 | #endif | 420 | #endif |
421 | map_destroy(mymtd); | 421 | map_destroy(mymtd); |
422 | #ifdef CONFIG_MTD_CONCAT | 422 | #ifdef CONFIG_MTD_CONCAT |
423 | for(i=0; i<MAX_IPAQ_CS; i++) | 423 | for(i=0; i<MAX_IPAQ_CS; i++) |
424 | #else | 424 | #else |
425 | for(i=1; i<MAX_IPAQ_CS; i++) | 425 | for(i=1; i<MAX_IPAQ_CS; i++) |
426 | #endif | 426 | #endif |
427 | { | 427 | { |
428 | if (my_sub_mtd[i]) | 428 | if (my_sub_mtd[i]) |
429 | map_destroy(my_sub_mtd[i]); | 429 | map_destroy(my_sub_mtd[i]); |
430 | } | 430 | } |
431 | kfree(parsed_parts); | 431 | kfree(parsed_parts); |
432 | } | 432 | } |
433 | } | 433 | } |
434 | 434 | ||
435 | static int __init h1900_special_case(void) | 435 | static int __init h1900_special_case(void) |
436 | { | 436 | { |
437 | /* The iPAQ h1900 is a special case - it has weird ROM. */ | 437 | /* The iPAQ h1900 is a special case - it has weird ROM. */ |
438 | simple_map_init(&ipaq_map[0]); | 438 | simple_map_init(&ipaq_map[0]); |
439 | ipaq_map[0].size = 0x80000; | 439 | ipaq_map[0].size = 0x80000; |
440 | ipaq_map[0].set_vpp = h3xxx_set_vpp; | 440 | ipaq_map[0].set_vpp = h3xxx_set_vpp; |
441 | ipaq_map[0].phys = 0x0; | 441 | ipaq_map[0].phys = 0x0; |
442 | ipaq_map[0].virt = ioremap(0x0, 0x04000000); | 442 | ipaq_map[0].virt = ioremap(0x0, 0x04000000); |
443 | ipaq_map[0].bankwidth = 2; | 443 | ipaq_map[0].bankwidth = 2; |
444 | 444 | ||
445 | printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); | 445 | printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); |
446 | mymtd = do_map_probe("jedec_probe", &ipaq_map[0]); | 446 | mymtd = do_map_probe("jedec_probe", &ipaq_map[0]); |
447 | if (!mymtd) | 447 | if (!mymtd) |
448 | return -ENODEV; | 448 | return -ENODEV; |
449 | add_mtd_device(mymtd); | 449 | add_mtd_device(mymtd); |
450 | printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n"); | 450 | printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n"); |
451 | 451 | ||
452 | return 0; | 452 | return 0; |
453 | } | 453 | } |
454 | 454 | ||
455 | module_init(ipaq_mtd_init); | 455 | module_init(ipaq_mtd_init); |
456 | module_exit(ipaq_mtd_cleanup); | 456 | module_exit(ipaq_mtd_cleanup); |
457 | 457 | ||
458 | MODULE_AUTHOR("Jamey Hicks"); | 458 | MODULE_AUTHOR("Jamey Hicks"); |
459 | MODULE_DESCRIPTION("IPAQ CFI map driver"); | 459 | MODULE_DESCRIPTION("IPAQ CFI map driver"); |
460 | MODULE_LICENSE("MIT"); | 460 | MODULE_LICENSE("MIT"); |
461 | 461 |
drivers/mtd/maps/pxa2xx-flash.c
1 | /* | 1 | /* |
2 | * Map driver for Intel XScale PXA2xx platforms. | 2 | * Map driver for Intel XScale PXA2xx platforms. |
3 | * | 3 | * |
4 | * Author: Nicolas Pitre | 4 | * Author: Nicolas Pitre |
5 | * Copyright: (C) 2001 MontaVista Software Inc. | 5 | * Copyright: (C) 2001 MontaVista Software Inc. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mtd/mtd.h> | 17 | #include <linux/mtd/mtd.h> |
18 | #include <linux/mtd/map.h> | 18 | #include <linux/mtd/map.h> |
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | 20 | ||
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | 24 | ||
25 | #include <asm/mach/flash.h> | 25 | #include <asm/mach/flash.h> |
26 | 26 | ||
27 | static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from, | 27 | static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from, |
28 | ssize_t len) | 28 | ssize_t len) |
29 | { | 29 | { |
30 | flush_ioremap_region(map->phys, map->cached, from, len); | 30 | flush_ioremap_region(map->phys, map->cached, from, len); |
31 | } | 31 | } |
32 | 32 | ||
33 | struct pxa2xx_flash_info { | 33 | struct pxa2xx_flash_info { |
34 | struct mtd_partition *parts; | 34 | struct mtd_partition *parts; |
35 | int nr_parts; | 35 | int nr_parts; |
36 | struct mtd_info *mtd; | 36 | struct mtd_info *mtd; |
37 | struct map_info map; | 37 | struct map_info map; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | 40 | ||
41 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 41 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
42 | 42 | ||
43 | 43 | ||
44 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) | 44 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) |
45 | { | 45 | { |
46 | struct flash_platform_data *flash = pdev->dev.platform_data; | 46 | struct flash_platform_data *flash = pdev->dev.platform_data; |
47 | struct pxa2xx_flash_info *info; | 47 | struct pxa2xx_flash_info *info; |
48 | struct mtd_partition *parts; | 48 | struct mtd_partition *parts; |
49 | struct resource *res; | 49 | struct resource *res; |
50 | int ret = 0; | 50 | int ret = 0; |
51 | 51 | ||
52 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 52 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
53 | if (!res) | 53 | if (!res) |
54 | return -ENODEV; | 54 | return -ENODEV; |
55 | 55 | ||
56 | info = kmalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL); | 56 | info = kmalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL); |
57 | if (!info) | 57 | if (!info) |
58 | return -ENOMEM; | 58 | return -ENOMEM; |
59 | 59 | ||
60 | memset(info, 0, sizeof(struct pxa2xx_flash_info)); | 60 | memset(info, 0, sizeof(struct pxa2xx_flash_info)); |
61 | info->map.name = (char *) flash->name; | 61 | info->map.name = (char *) flash->name; |
62 | info->map.bankwidth = flash->width; | 62 | info->map.bankwidth = flash->width; |
63 | info->map.phys = res->start; | 63 | info->map.phys = res->start; |
64 | info->map.size = res->end - res->start + 1; | 64 | info->map.size = res->end - res->start + 1; |
65 | info->parts = flash->parts; | 65 | info->parts = flash->parts; |
66 | info->nr_parts = flash->nr_parts; | 66 | info->nr_parts = flash->nr_parts; |
67 | 67 | ||
68 | info->map.virt = ioremap(info->map.phys, info->map.size); | 68 | info->map.virt = ioremap(info->map.phys, info->map.size); |
69 | if (!info->map.virt) { | 69 | if (!info->map.virt) { |
70 | printk(KERN_WARNING "Failed to ioremap %s\n", | 70 | printk(KERN_WARNING "Failed to ioremap %s\n", |
71 | info->map.name); | 71 | info->map.name); |
72 | return -ENOMEM; | 72 | return -ENOMEM; |
73 | } | 73 | } |
74 | info->map.cached = | 74 | info->map.cached = |
75 | ioremap_cached(info->map.phys, info->map.size); | 75 | ioremap_cached(info->map.phys, info->map.size); |
76 | if (!info->map.cached) | 76 | if (!info->map.cached) |
77 | printk(KERN_WARNING "Failed to ioremap cached %s\n", | 77 | printk(KERN_WARNING "Failed to ioremap cached %s\n", |
78 | info->map.name); | 78 | info->map.name); |
79 | info->map.inval_cache = pxa2xx_map_inval_cache; | 79 | info->map.inval_cache = pxa2xx_map_inval_cache; |
80 | simple_map_init(&info->map); | 80 | simple_map_init(&info->map); |
81 | 81 | ||
82 | printk(KERN_NOTICE | 82 | printk(KERN_NOTICE |
83 | "Probing %s at physical address 0x%08lx" | 83 | "Probing %s at physical address 0x%08lx" |
84 | " (%d-bit bankwidth)\n", | 84 | " (%d-bit bankwidth)\n", |
85 | info->map.name, (unsigned long)info->map.phys, | 85 | info->map.name, (unsigned long)info->map.phys, |
86 | info->map.bankwidth * 8); | 86 | info->map.bankwidth * 8); |
87 | 87 | ||
88 | info->mtd = do_map_probe(flash->map_name, &info->map); | 88 | info->mtd = do_map_probe(flash->map_name, &info->map); |
89 | 89 | ||
90 | if (!info->mtd) { | 90 | if (!info->mtd) { |
91 | iounmap((void *)info->map.virt); | 91 | iounmap((void *)info->map.virt); |
92 | if (info->map.cached) | 92 | if (info->map.cached) |
93 | iounmap(info->map.cached); | 93 | iounmap(info->map.cached); |
94 | return -EIO; | 94 | return -EIO; |
95 | } | 95 | } |
96 | info->mtd->owner = THIS_MODULE; | 96 | info->mtd->owner = THIS_MODULE; |
97 | 97 | ||
98 | #ifdef CONFIG_MTD_PARTITIONS | 98 | #ifdef CONFIG_MTD_PARTITIONS |
99 | ret = parse_mtd_partitions(info->mtd, probes, &parts, 0); | 99 | ret = parse_mtd_partitions(info->mtd, probes, &parts, 0); |
100 | 100 | ||
101 | if (ret > 0) { | 101 | if (ret > 0) { |
102 | info->nr_parts = ret; | 102 | info->nr_parts = ret; |
103 | info->parts = parts; | 103 | info->parts = parts; |
104 | } | 104 | } |
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | if (info->nr_parts) { | 107 | if (info->nr_parts) { |
108 | add_mtd_partitions(info->mtd, info->parts, | 108 | add_mtd_partitions(info->mtd, info->parts, |
109 | info->nr_parts); | 109 | info->nr_parts); |
110 | } else { | 110 | } else { |
111 | printk("Registering %s as whole device\n", | 111 | printk("Registering %s as whole device\n", |
112 | info->map.name); | 112 | info->map.name); |
113 | add_mtd_device(info->mtd); | 113 | add_mtd_device(info->mtd); |
114 | } | 114 | } |
115 | 115 | ||
116 | platform_set_drvdata(pdev, info); | 116 | platform_set_drvdata(pdev, info); |
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
120 | static int __devexit pxa2xx_flash_remove(struct platform_device *dev) | 120 | static int __devexit pxa2xx_flash_remove(struct platform_device *dev) |
121 | { | 121 | { |
122 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); | 122 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
123 | 123 | ||
124 | platform_set_drvdata(dev, NULL); | 124 | platform_set_drvdata(dev, NULL); |
125 | 125 | ||
126 | #ifdef CONFIG_MTD_PARTITIONS | 126 | #ifdef CONFIG_MTD_PARTITIONS |
127 | if (info->nr_parts) | 127 | if (info->nr_parts) |
128 | del_mtd_partitions(info->mtd); | 128 | del_mtd_partitions(info->mtd); |
129 | else | 129 | else |
130 | #endif | 130 | #endif |
131 | del_mtd_device(info->mtd); | 131 | del_mtd_device(info->mtd); |
132 | 132 | ||
133 | map_destroy(info->mtd); | 133 | map_destroy(info->mtd); |
134 | iounmap(info->map.virt); | 134 | iounmap(info->map.virt); |
135 | if (info->map.cached) | 135 | if (info->map.cached) |
136 | iounmap(info->map.cached); | 136 | iounmap(info->map.cached); |
137 | kfree(info->parts); | 137 | kfree(info->parts); |
138 | kfree(info); | 138 | kfree(info); |
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
141 | 141 | ||
142 | #ifdef CONFIG_PM | 142 | #ifdef CONFIG_PM |
143 | static void pxa2xx_flash_shutdown(struct platform_device *dev) | 143 | static void pxa2xx_flash_shutdown(struct platform_device *dev) |
144 | { | 144 | { |
145 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); | 145 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
146 | 146 | ||
147 | if (info && info->mtd->suspend(info->mtd) == 0) | 147 | if (info && info->mtd->suspend(info->mtd) == 0) |
148 | info->mtd->resume(info->mtd); | 148 | info->mtd->resume(info->mtd); |
149 | } | 149 | } |
150 | #else | 150 | #else |
151 | #define pxa2xx_flash_shutdown NULL | 151 | #define pxa2xx_flash_shutdown NULL |
152 | #endif | 152 | #endif |
153 | 153 | ||
154 | static struct platform_driver pxa2xx_flash_driver = { | 154 | static struct platform_driver pxa2xx_flash_driver = { |
155 | .driver = { | 155 | .driver = { |
156 | .name = "pxa2xx-flash", | 156 | .name = "pxa2xx-flash", |
157 | .owner = THIS_MODULE, | 157 | .owner = THIS_MODULE, |
158 | }, | 158 | }, |
159 | .probe = pxa2xx_flash_probe, | 159 | .probe = pxa2xx_flash_probe, |
160 | .remove = __devexit_p(pxa2xx_flash_remove), | 160 | .remove = __devexit_p(pxa2xx_flash_remove), |
161 | .shutdown = pxa2xx_flash_shutdown, | 161 | .shutdown = pxa2xx_flash_shutdown, |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static int __init init_pxa2xx_flash(void) | 164 | static int __init init_pxa2xx_flash(void) |
165 | { | 165 | { |
166 | return platform_driver_register(&pxa2xx_flash_driver); | 166 | return platform_driver_register(&pxa2xx_flash_driver); |
167 | } | 167 | } |
168 | 168 | ||
169 | static void __exit cleanup_pxa2xx_flash(void) | 169 | static void __exit cleanup_pxa2xx_flash(void) |
170 | { | 170 | { |
171 | platform_driver_unregister(&pxa2xx_flash_driver); | 171 | platform_driver_unregister(&pxa2xx_flash_driver); |
172 | } | 172 | } |
173 | 173 | ||
174 | module_init(init_pxa2xx_flash); | 174 | module_init(init_pxa2xx_flash); |
175 | module_exit(cleanup_pxa2xx_flash); | 175 | module_exit(cleanup_pxa2xx_flash); |
176 | 176 | ||
177 | MODULE_LICENSE("GPL"); | 177 | MODULE_LICENSE("GPL"); |
178 | MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>"); | 178 | MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net>"); |
179 | MODULE_DESCRIPTION("MTD map driver for Intel XScale PXA2xx"); | 179 | MODULE_DESCRIPTION("MTD map driver for Intel XScale PXA2xx"); |
180 | 180 |
drivers/mtd/maps/sa1100-flash.c
1 | /* | 1 | /* |
2 | * Flash memory access on SA11x0 based devices | 2 | * Flash memory access on SA11x0 based devices |
3 | * | 3 | * |
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@fluxnic.net> |
5 | */ | 5 | */ |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/ioport.h> | 8 | #include <linux/ioport.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | 16 | ||
17 | #include <linux/mtd/mtd.h> | 17 | #include <linux/mtd/mtd.h> |
18 | #include <linux/mtd/map.h> | 18 | #include <linux/mtd/map.h> |
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/mtd/concat.h> | 20 | #include <linux/mtd/concat.h> |
21 | 21 | ||
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <asm/sizes.h> | 23 | #include <asm/sizes.h> |
24 | #include <asm/mach/flash.h> | 24 | #include <asm/mach/flash.h> |
25 | 25 | ||
26 | #if 0 | 26 | #if 0 |
27 | /* | 27 | /* |
28 | * This is here for documentation purposes only - until these people | 28 | * This is here for documentation purposes only - until these people |
29 | * submit their machine types. It will be gone January 2005. | 29 | * submit their machine types. It will be gone January 2005. |
30 | */ | 30 | */ |
31 | static struct mtd_partition consus_partitions[] = { | 31 | static struct mtd_partition consus_partitions[] = { |
32 | { | 32 | { |
33 | .name = "Consus boot firmware", | 33 | .name = "Consus boot firmware", |
34 | .offset = 0, | 34 | .offset = 0, |
35 | .size = 0x00040000, | 35 | .size = 0x00040000, |
36 | .mask_flags = MTD_WRITABLE, /* force read-only */ | 36 | .mask_flags = MTD_WRITABLE, /* force read-only */ |
37 | }, { | 37 | }, { |
38 | .name = "Consus kernel", | 38 | .name = "Consus kernel", |
39 | .offset = 0x00040000, | 39 | .offset = 0x00040000, |
40 | .size = 0x00100000, | 40 | .size = 0x00100000, |
41 | .mask_flags = 0, | 41 | .mask_flags = 0, |
42 | }, { | 42 | }, { |
43 | .name = "Consus disk", | 43 | .name = "Consus disk", |
44 | .offset = 0x00140000, | 44 | .offset = 0x00140000, |
45 | /* The rest (up to 16M) for jffs. We could put 0 and | 45 | /* The rest (up to 16M) for jffs. We could put 0 and |
46 | make it find the size automatically, but right now | 46 | make it find the size automatically, but right now |
47 | i have 32 megs. jffs will use all 32 megs if given | 47 | i have 32 megs. jffs will use all 32 megs if given |
48 | the chance, and this leads to horrible problems | 48 | the chance, and this leads to horrible problems |
49 | when you try to re-flash the image because blob | 49 | when you try to re-flash the image because blob |
50 | won't erase the whole partition. */ | 50 | won't erase the whole partition. */ |
51 | .size = 0x01000000 - 0x00140000, | 51 | .size = 0x01000000 - 0x00140000, |
52 | .mask_flags = 0, | 52 | .mask_flags = 0, |
53 | }, { | 53 | }, { |
54 | /* this disk is a secondary disk, which can be used as | 54 | /* this disk is a secondary disk, which can be used as |
55 | needed, for simplicity, make it the size of the other | 55 | needed, for simplicity, make it the size of the other |
56 | consus partition, although realistically it could be | 56 | consus partition, although realistically it could be |
57 | the remainder of the disk (depending on the file | 57 | the remainder of the disk (depending on the file |
58 | system used) */ | 58 | system used) */ |
59 | .name = "Consus disk2", | 59 | .name = "Consus disk2", |
60 | .offset = 0x01000000, | 60 | .offset = 0x01000000, |
61 | .size = 0x01000000 - 0x00140000, | 61 | .size = 0x01000000 - 0x00140000, |
62 | .mask_flags = 0, | 62 | .mask_flags = 0, |
63 | } | 63 | } |
64 | }; | 64 | }; |
65 | 65 | ||
66 | /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */ | 66 | /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */ |
67 | static struct mtd_partition frodo_partitions[] = | 67 | static struct mtd_partition frodo_partitions[] = |
68 | { | 68 | { |
69 | { | 69 | { |
70 | .name = "bootloader", | 70 | .name = "bootloader", |
71 | .size = 0x00040000, | 71 | .size = 0x00040000, |
72 | .offset = 0x00000000, | 72 | .offset = 0x00000000, |
73 | .mask_flags = MTD_WRITEABLE | 73 | .mask_flags = MTD_WRITEABLE |
74 | }, { | 74 | }, { |
75 | .name = "bootloader params", | 75 | .name = "bootloader params", |
76 | .size = 0x00040000, | 76 | .size = 0x00040000, |
77 | .offset = MTDPART_OFS_APPEND, | 77 | .offset = MTDPART_OFS_APPEND, |
78 | .mask_flags = MTD_WRITEABLE | 78 | .mask_flags = MTD_WRITEABLE |
79 | }, { | 79 | }, { |
80 | .name = "kernel", | 80 | .name = "kernel", |
81 | .size = 0x00100000, | 81 | .size = 0x00100000, |
82 | .offset = MTDPART_OFS_APPEND, | 82 | .offset = MTDPART_OFS_APPEND, |
83 | .mask_flags = MTD_WRITEABLE | 83 | .mask_flags = MTD_WRITEABLE |
84 | }, { | 84 | }, { |
85 | .name = "ramdisk", | 85 | .name = "ramdisk", |
86 | .size = 0x00400000, | 86 | .size = 0x00400000, |
87 | .offset = MTDPART_OFS_APPEND, | 87 | .offset = MTDPART_OFS_APPEND, |
88 | .mask_flags = MTD_WRITEABLE | 88 | .mask_flags = MTD_WRITEABLE |
89 | }, { | 89 | }, { |
90 | .name = "file system", | 90 | .name = "file system", |
91 | .size = MTDPART_SIZ_FULL, | 91 | .size = MTDPART_SIZ_FULL, |
92 | .offset = MTDPART_OFS_APPEND | 92 | .offset = MTDPART_OFS_APPEND |
93 | } | 93 | } |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static struct mtd_partition jornada56x_partitions[] = { | 96 | static struct mtd_partition jornada56x_partitions[] = { |
97 | { | 97 | { |
98 | .name = "bootldr", | 98 | .name = "bootldr", |
99 | .size = 0x00040000, | 99 | .size = 0x00040000, |
100 | .offset = 0, | 100 | .offset = 0, |
101 | .mask_flags = MTD_WRITEABLE, | 101 | .mask_flags = MTD_WRITEABLE, |
102 | }, { | 102 | }, { |
103 | .name = "rootfs", | 103 | .name = "rootfs", |
104 | .size = MTDPART_SIZ_FULL, | 104 | .size = MTDPART_SIZ_FULL, |
105 | .offset = MTDPART_OFS_APPEND, | 105 | .offset = MTDPART_OFS_APPEND, |
106 | } | 106 | } |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static void jornada56x_set_vpp(int vpp) | 109 | static void jornada56x_set_vpp(int vpp) |
110 | { | 110 | { |
111 | if (vpp) | 111 | if (vpp) |
112 | GPSR = GPIO_GPIO26; | 112 | GPSR = GPIO_GPIO26; |
113 | else | 113 | else |
114 | GPCR = GPIO_GPIO26; | 114 | GPCR = GPIO_GPIO26; |
115 | GPDR |= GPIO_GPIO26; | 115 | GPDR |= GPIO_GPIO26; |
116 | } | 116 | } |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Machine Phys Size set_vpp | 119 | * Machine Phys Size set_vpp |
120 | * Consus : SA1100_CS0_PHYS SZ_32M | 120 | * Consus : SA1100_CS0_PHYS SZ_32M |
121 | * Frodo : SA1100_CS0_PHYS SZ_32M | 121 | * Frodo : SA1100_CS0_PHYS SZ_32M |
122 | * Jornada56x: SA1100_CS0_PHYS SZ_32M jornada56x_set_vpp | 122 | * Jornada56x: SA1100_CS0_PHYS SZ_32M jornada56x_set_vpp |
123 | */ | 123 | */ |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | struct sa_subdev_info { | 126 | struct sa_subdev_info { |
127 | char name[16]; | 127 | char name[16]; |
128 | struct map_info map; | 128 | struct map_info map; |
129 | struct mtd_info *mtd; | 129 | struct mtd_info *mtd; |
130 | struct flash_platform_data *plat; | 130 | struct flash_platform_data *plat; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | struct sa_info { | 133 | struct sa_info { |
134 | struct mtd_partition *parts; | 134 | struct mtd_partition *parts; |
135 | struct mtd_info *mtd; | 135 | struct mtd_info *mtd; |
136 | int num_subdev; | 136 | int num_subdev; |
137 | unsigned int nr_parts; | 137 | unsigned int nr_parts; |
138 | struct sa_subdev_info subdev[0]; | 138 | struct sa_subdev_info subdev[0]; |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static void sa1100_set_vpp(struct map_info *map, int on) | 141 | static void sa1100_set_vpp(struct map_info *map, int on) |
142 | { | 142 | { |
143 | struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map); | 143 | struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map); |
144 | subdev->plat->set_vpp(on); | 144 | subdev->plat->set_vpp(on); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void sa1100_destroy_subdev(struct sa_subdev_info *subdev) | 147 | static void sa1100_destroy_subdev(struct sa_subdev_info *subdev) |
148 | { | 148 | { |
149 | if (subdev->mtd) | 149 | if (subdev->mtd) |
150 | map_destroy(subdev->mtd); | 150 | map_destroy(subdev->mtd); |
151 | if (subdev->map.virt) | 151 | if (subdev->map.virt) |
152 | iounmap(subdev->map.virt); | 152 | iounmap(subdev->map.virt); |
153 | release_mem_region(subdev->map.phys, subdev->map.size); | 153 | release_mem_region(subdev->map.phys, subdev->map.size); |
154 | } | 154 | } |
155 | 155 | ||
156 | static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *res) | 156 | static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *res) |
157 | { | 157 | { |
158 | unsigned long phys; | 158 | unsigned long phys; |
159 | unsigned int size; | 159 | unsigned int size; |
160 | int ret; | 160 | int ret; |
161 | 161 | ||
162 | phys = res->start; | 162 | phys = res->start; |
163 | size = res->end - phys + 1; | 163 | size = res->end - phys + 1; |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Retrieve the bankwidth from the MSC registers. | 166 | * Retrieve the bankwidth from the MSC registers. |
167 | * We currently only implement CS0 and CS1 here. | 167 | * We currently only implement CS0 and CS1 here. |
168 | */ | 168 | */ |
169 | switch (phys) { | 169 | switch (phys) { |
170 | default: | 170 | default: |
171 | printk(KERN_WARNING "SA1100 flash: unknown base address " | 171 | printk(KERN_WARNING "SA1100 flash: unknown base address " |
172 | "0x%08lx, assuming CS0\n", phys); | 172 | "0x%08lx, assuming CS0\n", phys); |
173 | 173 | ||
174 | case SA1100_CS0_PHYS: | 174 | case SA1100_CS0_PHYS: |
175 | subdev->map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; | 175 | subdev->map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; |
176 | break; | 176 | break; |
177 | 177 | ||
178 | case SA1100_CS1_PHYS: | 178 | case SA1100_CS1_PHYS: |
179 | subdev->map.bankwidth = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4; | 179 | subdev->map.bankwidth = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4; |
180 | break; | 180 | break; |
181 | } | 181 | } |
182 | 182 | ||
183 | if (!request_mem_region(phys, size, subdev->name)) { | 183 | if (!request_mem_region(phys, size, subdev->name)) { |
184 | ret = -EBUSY; | 184 | ret = -EBUSY; |
185 | goto out; | 185 | goto out; |
186 | } | 186 | } |
187 | 187 | ||
188 | if (subdev->plat->set_vpp) | 188 | if (subdev->plat->set_vpp) |
189 | subdev->map.set_vpp = sa1100_set_vpp; | 189 | subdev->map.set_vpp = sa1100_set_vpp; |
190 | 190 | ||
191 | subdev->map.phys = phys; | 191 | subdev->map.phys = phys; |
192 | subdev->map.size = size; | 192 | subdev->map.size = size; |
193 | subdev->map.virt = ioremap(phys, size); | 193 | subdev->map.virt = ioremap(phys, size); |
194 | if (!subdev->map.virt) { | 194 | if (!subdev->map.virt) { |
195 | ret = -ENOMEM; | 195 | ret = -ENOMEM; |
196 | goto err; | 196 | goto err; |
197 | } | 197 | } |
198 | 198 | ||
199 | simple_map_init(&subdev->map); | 199 | simple_map_init(&subdev->map); |
200 | 200 | ||
201 | /* | 201 | /* |
202 | * Now let's probe for the actual flash. Do it here since | 202 | * Now let's probe for the actual flash. Do it here since |
203 | * specific machine settings might have been set above. | 203 | * specific machine settings might have been set above. |
204 | */ | 204 | */ |
205 | subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map); | 205 | subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map); |
206 | if (subdev->mtd == NULL) { | 206 | if (subdev->mtd == NULL) { |
207 | ret = -ENXIO; | 207 | ret = -ENXIO; |
208 | goto err; | 208 | goto err; |
209 | } | 209 | } |
210 | subdev->mtd->owner = THIS_MODULE; | 210 | subdev->mtd->owner = THIS_MODULE; |
211 | 211 | ||
212 | printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, " | 212 | printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, " |
213 | "%d-bit\n", phys, subdev->mtd->size >> 20, | 213 | "%d-bit\n", phys, subdev->mtd->size >> 20, |
214 | subdev->map.bankwidth * 8); | 214 | subdev->map.bankwidth * 8); |
215 | 215 | ||
216 | return 0; | 216 | return 0; |
217 | 217 | ||
218 | err: | 218 | err: |
219 | sa1100_destroy_subdev(subdev); | 219 | sa1100_destroy_subdev(subdev); |
220 | out: | 220 | out: |
221 | return ret; | 221 | return ret; |
222 | } | 222 | } |
223 | 223 | ||
224 | static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat) | 224 | static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat) |
225 | { | 225 | { |
226 | int i; | 226 | int i; |
227 | 227 | ||
228 | if (info->mtd) { | 228 | if (info->mtd) { |
229 | if (info->nr_parts == 0) | 229 | if (info->nr_parts == 0) |
230 | del_mtd_device(info->mtd); | 230 | del_mtd_device(info->mtd); |
231 | #ifdef CONFIG_MTD_PARTITIONS | 231 | #ifdef CONFIG_MTD_PARTITIONS |
232 | else | 232 | else |
233 | del_mtd_partitions(info->mtd); | 233 | del_mtd_partitions(info->mtd); |
234 | #endif | 234 | #endif |
235 | #ifdef CONFIG_MTD_CONCAT | 235 | #ifdef CONFIG_MTD_CONCAT |
236 | if (info->mtd != info->subdev[0].mtd) | 236 | if (info->mtd != info->subdev[0].mtd) |
237 | mtd_concat_destroy(info->mtd); | 237 | mtd_concat_destroy(info->mtd); |
238 | #endif | 238 | #endif |
239 | } | 239 | } |
240 | 240 | ||
241 | kfree(info->parts); | 241 | kfree(info->parts); |
242 | 242 | ||
243 | for (i = info->num_subdev - 1; i >= 0; i--) | 243 | for (i = info->num_subdev - 1; i >= 0; i--) |
244 | sa1100_destroy_subdev(&info->subdev[i]); | 244 | sa1100_destroy_subdev(&info->subdev[i]); |
245 | kfree(info); | 245 | kfree(info); |
246 | 246 | ||
247 | if (plat->exit) | 247 | if (plat->exit) |
248 | plat->exit(); | 248 | plat->exit(); |
249 | } | 249 | } |
250 | 250 | ||
251 | static struct sa_info *__init | 251 | static struct sa_info *__init |
252 | sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) | 252 | sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) |
253 | { | 253 | { |
254 | struct sa_info *info; | 254 | struct sa_info *info; |
255 | int nr, size, i, ret = 0; | 255 | int nr, size, i, ret = 0; |
256 | 256 | ||
257 | /* | 257 | /* |
258 | * Count number of devices. | 258 | * Count number of devices. |
259 | */ | 259 | */ |
260 | for (nr = 0; ; nr++) | 260 | for (nr = 0; ; nr++) |
261 | if (!platform_get_resource(pdev, IORESOURCE_MEM, nr)) | 261 | if (!platform_get_resource(pdev, IORESOURCE_MEM, nr)) |
262 | break; | 262 | break; |
263 | 263 | ||
264 | if (nr == 0) { | 264 | if (nr == 0) { |
265 | ret = -ENODEV; | 265 | ret = -ENODEV; |
266 | goto out; | 266 | goto out; |
267 | } | 267 | } |
268 | 268 | ||
269 | size = sizeof(struct sa_info) + sizeof(struct sa_subdev_info) * nr; | 269 | size = sizeof(struct sa_info) + sizeof(struct sa_subdev_info) * nr; |
270 | 270 | ||
271 | /* | 271 | /* |
272 | * Allocate the map_info structs in one go. | 272 | * Allocate the map_info structs in one go. |
273 | */ | 273 | */ |
274 | info = kzalloc(size, GFP_KERNEL); | 274 | info = kzalloc(size, GFP_KERNEL); |
275 | if (!info) { | 275 | if (!info) { |
276 | ret = -ENOMEM; | 276 | ret = -ENOMEM; |
277 | goto out; | 277 | goto out; |
278 | } | 278 | } |
279 | 279 | ||
280 | if (plat->init) { | 280 | if (plat->init) { |
281 | ret = plat->init(); | 281 | ret = plat->init(); |
282 | if (ret) | 282 | if (ret) |
283 | goto err; | 283 | goto err; |
284 | } | 284 | } |
285 | 285 | ||
286 | /* | 286 | /* |
287 | * Claim and then map the memory regions. | 287 | * Claim and then map the memory regions. |
288 | */ | 288 | */ |
289 | for (i = 0; i < nr; i++) { | 289 | for (i = 0; i < nr; i++) { |
290 | struct sa_subdev_info *subdev = &info->subdev[i]; | 290 | struct sa_subdev_info *subdev = &info->subdev[i]; |
291 | struct resource *res; | 291 | struct resource *res; |
292 | 292 | ||
293 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); | 293 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); |
294 | if (!res) | 294 | if (!res) |
295 | break; | 295 | break; |
296 | 296 | ||
297 | subdev->map.name = subdev->name; | 297 | subdev->map.name = subdev->name; |
298 | sprintf(subdev->name, "%s-%d", plat->name, i); | 298 | sprintf(subdev->name, "%s-%d", plat->name, i); |
299 | subdev->plat = plat; | 299 | subdev->plat = plat; |
300 | 300 | ||
301 | ret = sa1100_probe_subdev(subdev, res); | 301 | ret = sa1100_probe_subdev(subdev, res); |
302 | if (ret) | 302 | if (ret) |
303 | break; | 303 | break; |
304 | } | 304 | } |
305 | 305 | ||
306 | info->num_subdev = i; | 306 | info->num_subdev = i; |
307 | 307 | ||
308 | /* | 308 | /* |
309 | * ENXIO is special. It means we didn't find a chip when we probed. | 309 | * ENXIO is special. It means we didn't find a chip when we probed. |
310 | */ | 310 | */ |
311 | if (ret != 0 && !(ret == -ENXIO && info->num_subdev > 0)) | 311 | if (ret != 0 && !(ret == -ENXIO && info->num_subdev > 0)) |
312 | goto err; | 312 | goto err; |
313 | 313 | ||
314 | /* | 314 | /* |
315 | * If we found one device, don't bother with concat support. If | 315 | * If we found one device, don't bother with concat support. If |
316 | * we found multiple devices, use concat if we have it available, | 316 | * we found multiple devices, use concat if we have it available, |
317 | * otherwise fail. Either way, it'll be called "sa1100". | 317 | * otherwise fail. Either way, it'll be called "sa1100". |
318 | */ | 318 | */ |
319 | if (info->num_subdev == 1) { | 319 | if (info->num_subdev == 1) { |
320 | strcpy(info->subdev[0].name, plat->name); | 320 | strcpy(info->subdev[0].name, plat->name); |
321 | info->mtd = info->subdev[0].mtd; | 321 | info->mtd = info->subdev[0].mtd; |
322 | ret = 0; | 322 | ret = 0; |
323 | } else if (info->num_subdev > 1) { | 323 | } else if (info->num_subdev > 1) { |
324 | #ifdef CONFIG_MTD_CONCAT | 324 | #ifdef CONFIG_MTD_CONCAT |
325 | struct mtd_info *cdev[nr]; | 325 | struct mtd_info *cdev[nr]; |
326 | /* | 326 | /* |
327 | * We detected multiple devices. Concatenate them together. | 327 | * We detected multiple devices. Concatenate them together. |
328 | */ | 328 | */ |
329 | for (i = 0; i < info->num_subdev; i++) | 329 | for (i = 0; i < info->num_subdev; i++) |
330 | cdev[i] = info->subdev[i].mtd; | 330 | cdev[i] = info->subdev[i].mtd; |
331 | 331 | ||
332 | info->mtd = mtd_concat_create(cdev, info->num_subdev, | 332 | info->mtd = mtd_concat_create(cdev, info->num_subdev, |
333 | plat->name); | 333 | plat->name); |
334 | if (info->mtd == NULL) | 334 | if (info->mtd == NULL) |
335 | ret = -ENXIO; | 335 | ret = -ENXIO; |
336 | #else | 336 | #else |
337 | printk(KERN_ERR "SA1100 flash: multiple devices " | 337 | printk(KERN_ERR "SA1100 flash: multiple devices " |
338 | "found but MTD concat support disabled.\n"); | 338 | "found but MTD concat support disabled.\n"); |
339 | ret = -ENXIO; | 339 | ret = -ENXIO; |
340 | #endif | 340 | #endif |
341 | } | 341 | } |
342 | 342 | ||
343 | if (ret == 0) | 343 | if (ret == 0) |
344 | return info; | 344 | return info; |
345 | 345 | ||
346 | err: | 346 | err: |
347 | sa1100_destroy(info, plat); | 347 | sa1100_destroy(info, plat); |
348 | out: | 348 | out: |
349 | return ERR_PTR(ret); | 349 | return ERR_PTR(ret); |
350 | } | 350 | } |
351 | 351 | ||
352 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; | 352 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; |
353 | 353 | ||
354 | static int __devinit sa1100_mtd_probe(struct platform_device *pdev) | 354 | static int __devinit sa1100_mtd_probe(struct platform_device *pdev) |
355 | { | 355 | { |
356 | struct flash_platform_data *plat = pdev->dev.platform_data; | 356 | struct flash_platform_data *plat = pdev->dev.platform_data; |
357 | struct mtd_partition *parts; | 357 | struct mtd_partition *parts; |
358 | const char *part_type = NULL; | 358 | const char *part_type = NULL; |
359 | struct sa_info *info; | 359 | struct sa_info *info; |
360 | int err, nr_parts = 0; | 360 | int err, nr_parts = 0; |
361 | 361 | ||
362 | if (!plat) | 362 | if (!plat) |
363 | return -ENODEV; | 363 | return -ENODEV; |
364 | 364 | ||
365 | info = sa1100_setup_mtd(pdev, plat); | 365 | info = sa1100_setup_mtd(pdev, plat); |
366 | if (IS_ERR(info)) { | 366 | if (IS_ERR(info)) { |
367 | err = PTR_ERR(info); | 367 | err = PTR_ERR(info); |
368 | goto out; | 368 | goto out; |
369 | } | 369 | } |
370 | 370 | ||
371 | /* | 371 | /* |
372 | * Partition selection stuff. | 372 | * Partition selection stuff. |
373 | */ | 373 | */ |
374 | #ifdef CONFIG_MTD_PARTITIONS | 374 | #ifdef CONFIG_MTD_PARTITIONS |
375 | nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0); | 375 | nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0); |
376 | if (nr_parts > 0) { | 376 | if (nr_parts > 0) { |
377 | info->parts = parts; | 377 | info->parts = parts; |
378 | part_type = "dynamic"; | 378 | part_type = "dynamic"; |
379 | } else | 379 | } else |
380 | #endif | 380 | #endif |
381 | { | 381 | { |
382 | parts = plat->parts; | 382 | parts = plat->parts; |
383 | nr_parts = plat->nr_parts; | 383 | nr_parts = plat->nr_parts; |
384 | part_type = "static"; | 384 | part_type = "static"; |
385 | } | 385 | } |
386 | 386 | ||
387 | if (nr_parts == 0) { | 387 | if (nr_parts == 0) { |
388 | printk(KERN_NOTICE "SA1100 flash: no partition info " | 388 | printk(KERN_NOTICE "SA1100 flash: no partition info " |
389 | "available, registering whole flash\n"); | 389 | "available, registering whole flash\n"); |
390 | add_mtd_device(info->mtd); | 390 | add_mtd_device(info->mtd); |
391 | } else { | 391 | } else { |
392 | printk(KERN_NOTICE "SA1100 flash: using %s partition " | 392 | printk(KERN_NOTICE "SA1100 flash: using %s partition " |
393 | "definition\n", part_type); | 393 | "definition\n", part_type); |
394 | add_mtd_partitions(info->mtd, parts, nr_parts); | 394 | add_mtd_partitions(info->mtd, parts, nr_parts); |
395 | } | 395 | } |
396 | 396 | ||
397 | info->nr_parts = nr_parts; | 397 | info->nr_parts = nr_parts; |
398 | 398 | ||
399 | platform_set_drvdata(pdev, info); | 399 | platform_set_drvdata(pdev, info); |
400 | err = 0; | 400 | err = 0; |
401 | 401 | ||
402 | out: | 402 | out: |
403 | return err; | 403 | return err; |
404 | } | 404 | } |
405 | 405 | ||
406 | static int __exit sa1100_mtd_remove(struct platform_device *pdev) | 406 | static int __exit sa1100_mtd_remove(struct platform_device *pdev) |
407 | { | 407 | { |
408 | struct sa_info *info = platform_get_drvdata(pdev); | 408 | struct sa_info *info = platform_get_drvdata(pdev); |
409 | struct flash_platform_data *plat = pdev->dev.platform_data; | 409 | struct flash_platform_data *plat = pdev->dev.platform_data; |
410 | 410 | ||
411 | platform_set_drvdata(pdev, NULL); | 411 | platform_set_drvdata(pdev, NULL); |
412 | sa1100_destroy(info, plat); | 412 | sa1100_destroy(info, plat); |
413 | 413 | ||
414 | return 0; | 414 | return 0; |
415 | } | 415 | } |
416 | 416 | ||
417 | #ifdef CONFIG_PM | 417 | #ifdef CONFIG_PM |
418 | static void sa1100_mtd_shutdown(struct platform_device *dev) | 418 | static void sa1100_mtd_shutdown(struct platform_device *dev) |
419 | { | 419 | { |
420 | struct sa_info *info = platform_get_drvdata(dev); | 420 | struct sa_info *info = platform_get_drvdata(dev); |
421 | if (info && info->mtd->suspend(info->mtd) == 0) | 421 | if (info && info->mtd->suspend(info->mtd) == 0) |
422 | info->mtd->resume(info->mtd); | 422 | info->mtd->resume(info->mtd); |
423 | } | 423 | } |
424 | #else | 424 | #else |
425 | #define sa1100_mtd_shutdown NULL | 425 | #define sa1100_mtd_shutdown NULL |
426 | #endif | 426 | #endif |
427 | 427 | ||
428 | static struct platform_driver sa1100_mtd_driver = { | 428 | static struct platform_driver sa1100_mtd_driver = { |
429 | .probe = sa1100_mtd_probe, | 429 | .probe = sa1100_mtd_probe, |
430 | .remove = __exit_p(sa1100_mtd_remove), | 430 | .remove = __exit_p(sa1100_mtd_remove), |
431 | .shutdown = sa1100_mtd_shutdown, | 431 | .shutdown = sa1100_mtd_shutdown, |
432 | .driver = { | 432 | .driver = { |
433 | .name = "sa1100-mtd", | 433 | .name = "sa1100-mtd", |
434 | .owner = THIS_MODULE, | 434 | .owner = THIS_MODULE, |
435 | }, | 435 | }, |
436 | }; | 436 | }; |
437 | 437 | ||
438 | static int __init sa1100_mtd_init(void) | 438 | static int __init sa1100_mtd_init(void) |
439 | { | 439 | { |
440 | return platform_driver_register(&sa1100_mtd_driver); | 440 | return platform_driver_register(&sa1100_mtd_driver); |
441 | } | 441 | } |
442 | 442 | ||
443 | static void __exit sa1100_mtd_exit(void) | 443 | static void __exit sa1100_mtd_exit(void) |
444 | { | 444 | { |
445 | platform_driver_unregister(&sa1100_mtd_driver); | 445 | platform_driver_unregister(&sa1100_mtd_driver); |
446 | } | 446 | } |
447 | 447 | ||
448 | module_init(sa1100_mtd_init); | 448 | module_init(sa1100_mtd_init); |
449 | module_exit(sa1100_mtd_exit); | 449 | module_exit(sa1100_mtd_exit); |
450 | 450 | ||
451 | MODULE_AUTHOR("Nicolas Pitre"); | 451 | MODULE_AUTHOR("Nicolas Pitre"); |
452 | MODULE_DESCRIPTION("SA1100 CFI map driver"); | 452 | MODULE_DESCRIPTION("SA1100 CFI map driver"); |
453 | MODULE_LICENSE("GPL"); | 453 | MODULE_LICENSE("GPL"); |
454 | MODULE_ALIAS("platform:sa1100-mtd"); | 454 | MODULE_ALIAS("platform:sa1100-mtd"); |
455 | 455 |
drivers/mtd/mtdblock.c
1 | /* | 1 | /* |
2 | * Direct MTD block device access | 2 | * Direct MTD block device access |
3 | * | 3 | * |
4 | * (C) 2000-2003 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000-2003 Nicolas Pitre <nico@fluxnic.net> |
5 | * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> | 5 | * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/vmalloc.h> | 15 | #include <linux/vmalloc.h> |
16 | 16 | ||
17 | #include <linux/mtd/mtd.h> | 17 | #include <linux/mtd/mtd.h> |
18 | #include <linux/mtd/blktrans.h> | 18 | #include <linux/mtd/blktrans.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | 20 | ||
21 | 21 | ||
22 | static struct mtdblk_dev { | 22 | static struct mtdblk_dev { |
23 | struct mtd_info *mtd; | 23 | struct mtd_info *mtd; |
24 | int count; | 24 | int count; |
25 | struct mutex cache_mutex; | 25 | struct mutex cache_mutex; |
26 | unsigned char *cache_data; | 26 | unsigned char *cache_data; |
27 | unsigned long cache_offset; | 27 | unsigned long cache_offset; |
28 | unsigned int cache_size; | 28 | unsigned int cache_size; |
29 | enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state; | 29 | enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state; |
30 | } *mtdblks[MAX_MTD_DEVICES]; | 30 | } *mtdblks[MAX_MTD_DEVICES]; |
31 | 31 | ||
32 | static struct mutex mtdblks_lock; | 32 | static struct mutex mtdblks_lock; |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Cache stuff... | 35 | * Cache stuff... |
36 | * | 36 | * |
37 | * Since typical flash erasable sectors are much larger than what Linux's | 37 | * Since typical flash erasable sectors are much larger than what Linux's |
38 | * buffer cache can handle, we must implement read-modify-write on flash | 38 | * buffer cache can handle, we must implement read-modify-write on flash |
39 | * sectors for each block write requests. To avoid over-erasing flash sectors | 39 | * sectors for each block write requests. To avoid over-erasing flash sectors |
40 | * and to speed things up, we locally cache a whole flash sector while it is | 40 | * and to speed things up, we locally cache a whole flash sector while it is |
41 | * being written to until a different sector is required. | 41 | * being written to until a different sector is required. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | static void erase_callback(struct erase_info *done) | 44 | static void erase_callback(struct erase_info *done) |
45 | { | 45 | { |
46 | wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; | 46 | wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; |
47 | wake_up(wait_q); | 47 | wake_up(wait_q); |
48 | } | 48 | } |
49 | 49 | ||
50 | static int erase_write (struct mtd_info *mtd, unsigned long pos, | 50 | static int erase_write (struct mtd_info *mtd, unsigned long pos, |
51 | int len, const char *buf) | 51 | int len, const char *buf) |
52 | { | 52 | { |
53 | struct erase_info erase; | 53 | struct erase_info erase; |
54 | DECLARE_WAITQUEUE(wait, current); | 54 | DECLARE_WAITQUEUE(wait, current); |
55 | wait_queue_head_t wait_q; | 55 | wait_queue_head_t wait_q; |
56 | size_t retlen; | 56 | size_t retlen; |
57 | int ret; | 57 | int ret; |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * First, let's erase the flash block. | 60 | * First, let's erase the flash block. |
61 | */ | 61 | */ |
62 | 62 | ||
63 | init_waitqueue_head(&wait_q); | 63 | init_waitqueue_head(&wait_q); |
64 | erase.mtd = mtd; | 64 | erase.mtd = mtd; |
65 | erase.callback = erase_callback; | 65 | erase.callback = erase_callback; |
66 | erase.addr = pos; | 66 | erase.addr = pos; |
67 | erase.len = len; | 67 | erase.len = len; |
68 | erase.priv = (u_long)&wait_q; | 68 | erase.priv = (u_long)&wait_q; |
69 | 69 | ||
70 | set_current_state(TASK_INTERRUPTIBLE); | 70 | set_current_state(TASK_INTERRUPTIBLE); |
71 | add_wait_queue(&wait_q, &wait); | 71 | add_wait_queue(&wait_q, &wait); |
72 | 72 | ||
73 | ret = mtd->erase(mtd, &erase); | 73 | ret = mtd->erase(mtd, &erase); |
74 | if (ret) { | 74 | if (ret) { |
75 | set_current_state(TASK_RUNNING); | 75 | set_current_state(TASK_RUNNING); |
76 | remove_wait_queue(&wait_q, &wait); | 76 | remove_wait_queue(&wait_q, &wait); |
77 | printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " | 77 | printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " |
78 | "on \"%s\" failed\n", | 78 | "on \"%s\" failed\n", |
79 | pos, len, mtd->name); | 79 | pos, len, mtd->name); |
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
82 | 82 | ||
83 | schedule(); /* Wait for erase to finish. */ | 83 | schedule(); /* Wait for erase to finish. */ |
84 | remove_wait_queue(&wait_q, &wait); | 84 | remove_wait_queue(&wait_q, &wait); |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * Next, writhe data to flash. | 87 | * Next, writhe data to flash. |
88 | */ | 88 | */ |
89 | 89 | ||
90 | ret = mtd->write(mtd, pos, len, &retlen, buf); | 90 | ret = mtd->write(mtd, pos, len, &retlen, buf); |
91 | if (ret) | 91 | if (ret) |
92 | return ret; | 92 | return ret; |
93 | if (retlen != len) | 93 | if (retlen != len) |
94 | return -EIO; | 94 | return -EIO; |
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
97 | 97 | ||
98 | 98 | ||
99 | static int write_cached_data (struct mtdblk_dev *mtdblk) | 99 | static int write_cached_data (struct mtdblk_dev *mtdblk) |
100 | { | 100 | { |
101 | struct mtd_info *mtd = mtdblk->mtd; | 101 | struct mtd_info *mtd = mtdblk->mtd; |
102 | int ret; | 102 | int ret; |
103 | 103 | ||
104 | if (mtdblk->cache_state != STATE_DIRTY) | 104 | if (mtdblk->cache_state != STATE_DIRTY) |
105 | return 0; | 105 | return 0; |
106 | 106 | ||
107 | DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " | 107 | DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " |
108 | "at 0x%lx, size 0x%x\n", mtd->name, | 108 | "at 0x%lx, size 0x%x\n", mtd->name, |
109 | mtdblk->cache_offset, mtdblk->cache_size); | 109 | mtdblk->cache_offset, mtdblk->cache_size); |
110 | 110 | ||
111 | ret = erase_write (mtd, mtdblk->cache_offset, | 111 | ret = erase_write (mtd, mtdblk->cache_offset, |
112 | mtdblk->cache_size, mtdblk->cache_data); | 112 | mtdblk->cache_size, mtdblk->cache_data); |
113 | if (ret) | 113 | if (ret) |
114 | return ret; | 114 | return ret; |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * Here we could argubly set the cache state to STATE_CLEAN. | 117 | * Here we could argubly set the cache state to STATE_CLEAN. |
118 | * However this could lead to inconsistency since we will not | 118 | * However this could lead to inconsistency since we will not |
119 | * be notified if this content is altered on the flash by other | 119 | * be notified if this content is altered on the flash by other |
120 | * means. Let's declare it empty and leave buffering tasks to | 120 | * means. Let's declare it empty and leave buffering tasks to |
121 | * the buffer cache instead. | 121 | * the buffer cache instead. |
122 | */ | 122 | */ |
123 | mtdblk->cache_state = STATE_EMPTY; | 123 | mtdblk->cache_state = STATE_EMPTY; |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | 126 | ||
127 | 127 | ||
128 | static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, | 128 | static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, |
129 | int len, const char *buf) | 129 | int len, const char *buf) |
130 | { | 130 | { |
131 | struct mtd_info *mtd = mtdblk->mtd; | 131 | struct mtd_info *mtd = mtdblk->mtd; |
132 | unsigned int sect_size = mtdblk->cache_size; | 132 | unsigned int sect_size = mtdblk->cache_size; |
133 | size_t retlen; | 133 | size_t retlen; |
134 | int ret; | 134 | int ret; |
135 | 135 | ||
136 | DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", | 136 | DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", |
137 | mtd->name, pos, len); | 137 | mtd->name, pos, len); |
138 | 138 | ||
139 | if (!sect_size) | 139 | if (!sect_size) |
140 | return mtd->write(mtd, pos, len, &retlen, buf); | 140 | return mtd->write(mtd, pos, len, &retlen, buf); |
141 | 141 | ||
142 | while (len > 0) { | 142 | while (len > 0) { |
143 | unsigned long sect_start = (pos/sect_size)*sect_size; | 143 | unsigned long sect_start = (pos/sect_size)*sect_size; |
144 | unsigned int offset = pos - sect_start; | 144 | unsigned int offset = pos - sect_start; |
145 | unsigned int size = sect_size - offset; | 145 | unsigned int size = sect_size - offset; |
146 | if( size > len ) | 146 | if( size > len ) |
147 | size = len; | 147 | size = len; |
148 | 148 | ||
149 | if (size == sect_size) { | 149 | if (size == sect_size) { |
150 | /* | 150 | /* |
151 | * We are covering a whole sector. Thus there is no | 151 | * We are covering a whole sector. Thus there is no |
152 | * need to bother with the cache while it may still be | 152 | * need to bother with the cache while it may still be |
153 | * useful for other partial writes. | 153 | * useful for other partial writes. |
154 | */ | 154 | */ |
155 | ret = erase_write (mtd, pos, size, buf); | 155 | ret = erase_write (mtd, pos, size, buf); |
156 | if (ret) | 156 | if (ret) |
157 | return ret; | 157 | return ret; |
158 | } else { | 158 | } else { |
159 | /* Partial sector: need to use the cache */ | 159 | /* Partial sector: need to use the cache */ |
160 | 160 | ||
161 | if (mtdblk->cache_state == STATE_DIRTY && | 161 | if (mtdblk->cache_state == STATE_DIRTY && |
162 | mtdblk->cache_offset != sect_start) { | 162 | mtdblk->cache_offset != sect_start) { |
163 | ret = write_cached_data(mtdblk); | 163 | ret = write_cached_data(mtdblk); |
164 | if (ret) | 164 | if (ret) |
165 | return ret; | 165 | return ret; |
166 | } | 166 | } |
167 | 167 | ||
168 | if (mtdblk->cache_state == STATE_EMPTY || | 168 | if (mtdblk->cache_state == STATE_EMPTY || |
169 | mtdblk->cache_offset != sect_start) { | 169 | mtdblk->cache_offset != sect_start) { |
170 | /* fill the cache with the current sector */ | 170 | /* fill the cache with the current sector */ |
171 | mtdblk->cache_state = STATE_EMPTY; | 171 | mtdblk->cache_state = STATE_EMPTY; |
172 | ret = mtd->read(mtd, sect_start, sect_size, | 172 | ret = mtd->read(mtd, sect_start, sect_size, |
173 | &retlen, mtdblk->cache_data); | 173 | &retlen, mtdblk->cache_data); |
174 | if (ret) | 174 | if (ret) |
175 | return ret; | 175 | return ret; |
176 | if (retlen != sect_size) | 176 | if (retlen != sect_size) |
177 | return -EIO; | 177 | return -EIO; |
178 | 178 | ||
179 | mtdblk->cache_offset = sect_start; | 179 | mtdblk->cache_offset = sect_start; |
180 | mtdblk->cache_size = sect_size; | 180 | mtdblk->cache_size = sect_size; |
181 | mtdblk->cache_state = STATE_CLEAN; | 181 | mtdblk->cache_state = STATE_CLEAN; |
182 | } | 182 | } |
183 | 183 | ||
184 | /* write data to our local cache */ | 184 | /* write data to our local cache */ |
185 | memcpy (mtdblk->cache_data + offset, buf, size); | 185 | memcpy (mtdblk->cache_data + offset, buf, size); |
186 | mtdblk->cache_state = STATE_DIRTY; | 186 | mtdblk->cache_state = STATE_DIRTY; |
187 | } | 187 | } |
188 | 188 | ||
189 | buf += size; | 189 | buf += size; |
190 | pos += size; | 190 | pos += size; |
191 | len -= size; | 191 | len -= size; |
192 | } | 192 | } |
193 | 193 | ||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | 197 | ||
198 | static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, | 198 | static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, |
199 | int len, char *buf) | 199 | int len, char *buf) |
200 | { | 200 | { |
201 | struct mtd_info *mtd = mtdblk->mtd; | 201 | struct mtd_info *mtd = mtdblk->mtd; |
202 | unsigned int sect_size = mtdblk->cache_size; | 202 | unsigned int sect_size = mtdblk->cache_size; |
203 | size_t retlen; | 203 | size_t retlen; |
204 | int ret; | 204 | int ret; |
205 | 205 | ||
206 | DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", | 206 | DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", |
207 | mtd->name, pos, len); | 207 | mtd->name, pos, len); |
208 | 208 | ||
209 | if (!sect_size) | 209 | if (!sect_size) |
210 | return mtd->read(mtd, pos, len, &retlen, buf); | 210 | return mtd->read(mtd, pos, len, &retlen, buf); |
211 | 211 | ||
212 | while (len > 0) { | 212 | while (len > 0) { |
213 | unsigned long sect_start = (pos/sect_size)*sect_size; | 213 | unsigned long sect_start = (pos/sect_size)*sect_size; |
214 | unsigned int offset = pos - sect_start; | 214 | unsigned int offset = pos - sect_start; |
215 | unsigned int size = sect_size - offset; | 215 | unsigned int size = sect_size - offset; |
216 | if (size > len) | 216 | if (size > len) |
217 | size = len; | 217 | size = len; |
218 | 218 | ||
219 | /* | 219 | /* |
220 | * Check if the requested data is already cached | 220 | * Check if the requested data is already cached |
221 | * Read the requested amount of data from our internal cache if it | 221 | * Read the requested amount of data from our internal cache if it |
222 | * contains what we want, otherwise we read the data directly | 222 | * contains what we want, otherwise we read the data directly |
223 | * from flash. | 223 | * from flash. |
224 | */ | 224 | */ |
225 | if (mtdblk->cache_state != STATE_EMPTY && | 225 | if (mtdblk->cache_state != STATE_EMPTY && |
226 | mtdblk->cache_offset == sect_start) { | 226 | mtdblk->cache_offset == sect_start) { |
227 | memcpy (buf, mtdblk->cache_data + offset, size); | 227 | memcpy (buf, mtdblk->cache_data + offset, size); |
228 | } else { | 228 | } else { |
229 | ret = mtd->read(mtd, pos, size, &retlen, buf); | 229 | ret = mtd->read(mtd, pos, size, &retlen, buf); |
230 | if (ret) | 230 | if (ret) |
231 | return ret; | 231 | return ret; |
232 | if (retlen != size) | 232 | if (retlen != size) |
233 | return -EIO; | 233 | return -EIO; |
234 | } | 234 | } |
235 | 235 | ||
236 | buf += size; | 236 | buf += size; |
237 | pos += size; | 237 | pos += size; |
238 | len -= size; | 238 | len -= size; |
239 | } | 239 | } |
240 | 240 | ||
241 | return 0; | 241 | return 0; |
242 | } | 242 | } |
243 | 243 | ||
244 | static int mtdblock_readsect(struct mtd_blktrans_dev *dev, | 244 | static int mtdblock_readsect(struct mtd_blktrans_dev *dev, |
245 | unsigned long block, char *buf) | 245 | unsigned long block, char *buf) |
246 | { | 246 | { |
247 | struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; | 247 | struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; |
248 | return do_cached_read(mtdblk, block<<9, 512, buf); | 248 | return do_cached_read(mtdblk, block<<9, 512, buf); |
249 | } | 249 | } |
250 | 250 | ||
251 | static int mtdblock_writesect(struct mtd_blktrans_dev *dev, | 251 | static int mtdblock_writesect(struct mtd_blktrans_dev *dev, |
252 | unsigned long block, char *buf) | 252 | unsigned long block, char *buf) |
253 | { | 253 | { |
254 | struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; | 254 | struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; |
255 | if (unlikely(!mtdblk->cache_data && mtdblk->cache_size)) { | 255 | if (unlikely(!mtdblk->cache_data && mtdblk->cache_size)) { |
256 | mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); | 256 | mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); |
257 | if (!mtdblk->cache_data) | 257 | if (!mtdblk->cache_data) |
258 | return -EINTR; | 258 | return -EINTR; |
259 | /* -EINTR is not really correct, but it is the best match | 259 | /* -EINTR is not really correct, but it is the best match |
260 | * documented in man 2 write for all cases. We could also | 260 | * documented in man 2 write for all cases. We could also |
261 | * return -EAGAIN sometimes, but why bother? | 261 | * return -EAGAIN sometimes, but why bother? |
262 | */ | 262 | */ |
263 | } | 263 | } |
264 | return do_cached_write(mtdblk, block<<9, 512, buf); | 264 | return do_cached_write(mtdblk, block<<9, 512, buf); |
265 | } | 265 | } |
266 | 266 | ||
267 | static int mtdblock_open(struct mtd_blktrans_dev *mbd) | 267 | static int mtdblock_open(struct mtd_blktrans_dev *mbd) |
268 | { | 268 | { |
269 | struct mtdblk_dev *mtdblk; | 269 | struct mtdblk_dev *mtdblk; |
270 | struct mtd_info *mtd = mbd->mtd; | 270 | struct mtd_info *mtd = mbd->mtd; |
271 | int dev = mbd->devnum; | 271 | int dev = mbd->devnum; |
272 | 272 | ||
273 | DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); | 273 | DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); |
274 | 274 | ||
275 | mutex_lock(&mtdblks_lock); | 275 | mutex_lock(&mtdblks_lock); |
276 | if (mtdblks[dev]) { | 276 | if (mtdblks[dev]) { |
277 | mtdblks[dev]->count++; | 277 | mtdblks[dev]->count++; |
278 | mutex_unlock(&mtdblks_lock); | 278 | mutex_unlock(&mtdblks_lock); |
279 | return 0; | 279 | return 0; |
280 | } | 280 | } |
281 | 281 | ||
282 | /* OK, it's not open. Create cache info for it */ | 282 | /* OK, it's not open. Create cache info for it */ |
283 | mtdblk = kzalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); | 283 | mtdblk = kzalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); |
284 | if (!mtdblk) { | 284 | if (!mtdblk) { |
285 | mutex_unlock(&mtdblks_lock); | 285 | mutex_unlock(&mtdblks_lock); |
286 | return -ENOMEM; | 286 | return -ENOMEM; |
287 | } | 287 | } |
288 | 288 | ||
289 | mtdblk->count = 1; | 289 | mtdblk->count = 1; |
290 | mtdblk->mtd = mtd; | 290 | mtdblk->mtd = mtd; |
291 | 291 | ||
292 | mutex_init(&mtdblk->cache_mutex); | 292 | mutex_init(&mtdblk->cache_mutex); |
293 | mtdblk->cache_state = STATE_EMPTY; | 293 | mtdblk->cache_state = STATE_EMPTY; |
294 | if ( !(mtdblk->mtd->flags & MTD_NO_ERASE) && mtdblk->mtd->erasesize) { | 294 | if ( !(mtdblk->mtd->flags & MTD_NO_ERASE) && mtdblk->mtd->erasesize) { |
295 | mtdblk->cache_size = mtdblk->mtd->erasesize; | 295 | mtdblk->cache_size = mtdblk->mtd->erasesize; |
296 | mtdblk->cache_data = NULL; | 296 | mtdblk->cache_data = NULL; |
297 | } | 297 | } |
298 | 298 | ||
299 | mtdblks[dev] = mtdblk; | 299 | mtdblks[dev] = mtdblk; |
300 | mutex_unlock(&mtdblks_lock); | 300 | mutex_unlock(&mtdblks_lock); |
301 | 301 | ||
302 | DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); | 302 | DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); |
303 | 303 | ||
304 | return 0; | 304 | return 0; |
305 | } | 305 | } |
306 | 306 | ||
307 | static int mtdblock_release(struct mtd_blktrans_dev *mbd) | 307 | static int mtdblock_release(struct mtd_blktrans_dev *mbd) |
308 | { | 308 | { |
309 | int dev = mbd->devnum; | 309 | int dev = mbd->devnum; |
310 | struct mtdblk_dev *mtdblk = mtdblks[dev]; | 310 | struct mtdblk_dev *mtdblk = mtdblks[dev]; |
311 | 311 | ||
312 | DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); | 312 | DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); |
313 | 313 | ||
314 | mutex_lock(&mtdblks_lock); | 314 | mutex_lock(&mtdblks_lock); |
315 | 315 | ||
316 | mutex_lock(&mtdblk->cache_mutex); | 316 | mutex_lock(&mtdblk->cache_mutex); |
317 | write_cached_data(mtdblk); | 317 | write_cached_data(mtdblk); |
318 | mutex_unlock(&mtdblk->cache_mutex); | 318 | mutex_unlock(&mtdblk->cache_mutex); |
319 | 319 | ||
320 | if (!--mtdblk->count) { | 320 | if (!--mtdblk->count) { |
321 | /* It was the last usage. Free the device */ | 321 | /* It was the last usage. Free the device */ |
322 | mtdblks[dev] = NULL; | 322 | mtdblks[dev] = NULL; |
323 | if (mtdblk->mtd->sync) | 323 | if (mtdblk->mtd->sync) |
324 | mtdblk->mtd->sync(mtdblk->mtd); | 324 | mtdblk->mtd->sync(mtdblk->mtd); |
325 | vfree(mtdblk->cache_data); | 325 | vfree(mtdblk->cache_data); |
326 | kfree(mtdblk); | 326 | kfree(mtdblk); |
327 | } | 327 | } |
328 | 328 | ||
329 | mutex_unlock(&mtdblks_lock); | 329 | mutex_unlock(&mtdblks_lock); |
330 | 330 | ||
331 | DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); | 331 | DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); |
332 | 332 | ||
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | 335 | ||
336 | static int mtdblock_flush(struct mtd_blktrans_dev *dev) | 336 | static int mtdblock_flush(struct mtd_blktrans_dev *dev) |
337 | { | 337 | { |
338 | struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; | 338 | struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; |
339 | 339 | ||
340 | mutex_lock(&mtdblk->cache_mutex); | 340 | mutex_lock(&mtdblk->cache_mutex); |
341 | write_cached_data(mtdblk); | 341 | write_cached_data(mtdblk); |
342 | mutex_unlock(&mtdblk->cache_mutex); | 342 | mutex_unlock(&mtdblk->cache_mutex); |
343 | 343 | ||
344 | if (mtdblk->mtd->sync) | 344 | if (mtdblk->mtd->sync) |
345 | mtdblk->mtd->sync(mtdblk->mtd); | 345 | mtdblk->mtd->sync(mtdblk->mtd); |
346 | return 0; | 346 | return 0; |
347 | } | 347 | } |
348 | 348 | ||
349 | static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) | 349 | static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) |
350 | { | 350 | { |
351 | struct mtd_blktrans_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 351 | struct mtd_blktrans_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
352 | 352 | ||
353 | if (!dev) | 353 | if (!dev) |
354 | return; | 354 | return; |
355 | 355 | ||
356 | dev->mtd = mtd; | 356 | dev->mtd = mtd; |
357 | dev->devnum = mtd->index; | 357 | dev->devnum = mtd->index; |
358 | 358 | ||
359 | dev->size = mtd->size >> 9; | 359 | dev->size = mtd->size >> 9; |
360 | dev->tr = tr; | 360 | dev->tr = tr; |
361 | 361 | ||
362 | if (!(mtd->flags & MTD_WRITEABLE)) | 362 | if (!(mtd->flags & MTD_WRITEABLE)) |
363 | dev->readonly = 1; | 363 | dev->readonly = 1; |
364 | 364 | ||
365 | add_mtd_blktrans_dev(dev); | 365 | add_mtd_blktrans_dev(dev); |
366 | } | 366 | } |
367 | 367 | ||
368 | static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) | 368 | static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) |
369 | { | 369 | { |
370 | del_mtd_blktrans_dev(dev); | 370 | del_mtd_blktrans_dev(dev); |
371 | kfree(dev); | 371 | kfree(dev); |
372 | } | 372 | } |
373 | 373 | ||
374 | static struct mtd_blktrans_ops mtdblock_tr = { | 374 | static struct mtd_blktrans_ops mtdblock_tr = { |
375 | .name = "mtdblock", | 375 | .name = "mtdblock", |
376 | .major = 31, | 376 | .major = 31, |
377 | .part_bits = 0, | 377 | .part_bits = 0, |
378 | .blksize = 512, | 378 | .blksize = 512, |
379 | .open = mtdblock_open, | 379 | .open = mtdblock_open, |
380 | .flush = mtdblock_flush, | 380 | .flush = mtdblock_flush, |
381 | .release = mtdblock_release, | 381 | .release = mtdblock_release, |
382 | .readsect = mtdblock_readsect, | 382 | .readsect = mtdblock_readsect, |
383 | .writesect = mtdblock_writesect, | 383 | .writesect = mtdblock_writesect, |
384 | .add_mtd = mtdblock_add_mtd, | 384 | .add_mtd = mtdblock_add_mtd, |
385 | .remove_dev = mtdblock_remove_dev, | 385 | .remove_dev = mtdblock_remove_dev, |
386 | .owner = THIS_MODULE, | 386 | .owner = THIS_MODULE, |
387 | }; | 387 | }; |
388 | 388 | ||
389 | static int __init init_mtdblock(void) | 389 | static int __init init_mtdblock(void) |
390 | { | 390 | { |
391 | mutex_init(&mtdblks_lock); | 391 | mutex_init(&mtdblks_lock); |
392 | 392 | ||
393 | return register_mtd_blktrans(&mtdblock_tr); | 393 | return register_mtd_blktrans(&mtdblock_tr); |
394 | } | 394 | } |
395 | 395 | ||
396 | static void __exit cleanup_mtdblock(void) | 396 | static void __exit cleanup_mtdblock(void) |
397 | { | 397 | { |
398 | deregister_mtd_blktrans(&mtdblock_tr); | 398 | deregister_mtd_blktrans(&mtdblock_tr); |
399 | } | 399 | } |
400 | 400 | ||
401 | module_init(init_mtdblock); | 401 | module_init(init_mtdblock); |
402 | module_exit(cleanup_mtdblock); | 402 | module_exit(cleanup_mtdblock); |
403 | 403 | ||
404 | 404 | ||
405 | MODULE_LICENSE("GPL"); | 405 | MODULE_LICENSE("GPL"); |
406 | MODULE_AUTHOR("Nicolas Pitre <nico@cam.org> et al."); | 406 | MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net> et al."); |
407 | MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices"); | 407 | MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices"); |
408 | 408 |
drivers/mtd/mtdpart.c
1 | /* | 1 | /* |
2 | * Simple MTD partitioning layer | 2 | * Simple MTD partitioning layer |
3 | * | 3 | * |
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * This code is GPL | 6 | * This code is GPL |
7 | * | 7 | * |
8 | * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> | 8 | * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> |
9 | * added support for read_oob, write_oob | 9 | * added support for read_oob, write_oob |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/kmod.h> | 17 | #include <linux/kmod.h> |
18 | #include <linux/mtd/mtd.h> | 18 | #include <linux/mtd/mtd.h> |
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/mtd/compatmac.h> | 20 | #include <linux/mtd/compatmac.h> |
21 | 21 | ||
22 | /* Our partition linked list */ | 22 | /* Our partition linked list */ |
23 | static LIST_HEAD(mtd_partitions); | 23 | static LIST_HEAD(mtd_partitions); |
24 | 24 | ||
25 | /* Our partition node structure */ | 25 | /* Our partition node structure */ |
26 | struct mtd_part { | 26 | struct mtd_part { |
27 | struct mtd_info mtd; | 27 | struct mtd_info mtd; |
28 | struct mtd_info *master; | 28 | struct mtd_info *master; |
29 | uint64_t offset; | 29 | uint64_t offset; |
30 | struct list_head list; | 30 | struct list_head list; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Given a pointer to the MTD object in the mtd_part structure, we can retrieve | 34 | * Given a pointer to the MTD object in the mtd_part structure, we can retrieve |
35 | * the pointer to that structure with this macro. | 35 | * the pointer to that structure with this macro. |
36 | */ | 36 | */ |
37 | #define PART(x) ((struct mtd_part *)(x)) | 37 | #define PART(x) ((struct mtd_part *)(x)) |
38 | 38 | ||
39 | 39 | ||
40 | /* | 40 | /* |
41 | * MTD methods which simply translate the effective address and pass through | 41 | * MTD methods which simply translate the effective address and pass through |
42 | * to the _real_ device. | 42 | * to the _real_ device. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | static int part_read(struct mtd_info *mtd, loff_t from, size_t len, | 45 | static int part_read(struct mtd_info *mtd, loff_t from, size_t len, |
46 | size_t *retlen, u_char *buf) | 46 | size_t *retlen, u_char *buf) |
47 | { | 47 | { |
48 | struct mtd_part *part = PART(mtd); | 48 | struct mtd_part *part = PART(mtd); |
49 | struct mtd_ecc_stats stats; | 49 | struct mtd_ecc_stats stats; |
50 | int res; | 50 | int res; |
51 | 51 | ||
52 | stats = part->master->ecc_stats; | 52 | stats = part->master->ecc_stats; |
53 | 53 | ||
54 | if (from >= mtd->size) | 54 | if (from >= mtd->size) |
55 | len = 0; | 55 | len = 0; |
56 | else if (from + len > mtd->size) | 56 | else if (from + len > mtd->size) |
57 | len = mtd->size - from; | 57 | len = mtd->size - from; |
58 | res = part->master->read(part->master, from + part->offset, | 58 | res = part->master->read(part->master, from + part->offset, |
59 | len, retlen, buf); | 59 | len, retlen, buf); |
60 | if (unlikely(res)) { | 60 | if (unlikely(res)) { |
61 | if (res == -EUCLEAN) | 61 | if (res == -EUCLEAN) |
62 | mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected; | 62 | mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected; |
63 | if (res == -EBADMSG) | 63 | if (res == -EBADMSG) |
64 | mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed; | 64 | mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed; |
65 | } | 65 | } |
66 | return res; | 66 | return res; |
67 | } | 67 | } |
68 | 68 | ||
69 | static int part_point(struct mtd_info *mtd, loff_t from, size_t len, | 69 | static int part_point(struct mtd_info *mtd, loff_t from, size_t len, |
70 | size_t *retlen, void **virt, resource_size_t *phys) | 70 | size_t *retlen, void **virt, resource_size_t *phys) |
71 | { | 71 | { |
72 | struct mtd_part *part = PART(mtd); | 72 | struct mtd_part *part = PART(mtd); |
73 | if (from >= mtd->size) | 73 | if (from >= mtd->size) |
74 | len = 0; | 74 | len = 0; |
75 | else if (from + len > mtd->size) | 75 | else if (from + len > mtd->size) |
76 | len = mtd->size - from; | 76 | len = mtd->size - from; |
77 | return part->master->point (part->master, from + part->offset, | 77 | return part->master->point (part->master, from + part->offset, |
78 | len, retlen, virt, phys); | 78 | len, retlen, virt, phys); |
79 | } | 79 | } |
80 | 80 | ||
81 | static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) | 81 | static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
82 | { | 82 | { |
83 | struct mtd_part *part = PART(mtd); | 83 | struct mtd_part *part = PART(mtd); |
84 | 84 | ||
85 | part->master->unpoint(part->master, from + part->offset, len); | 85 | part->master->unpoint(part->master, from + part->offset, len); |
86 | } | 86 | } |
87 | 87 | ||
88 | static unsigned long part_get_unmapped_area(struct mtd_info *mtd, | 88 | static unsigned long part_get_unmapped_area(struct mtd_info *mtd, |
89 | unsigned long len, | 89 | unsigned long len, |
90 | unsigned long offset, | 90 | unsigned long offset, |
91 | unsigned long flags) | 91 | unsigned long flags) |
92 | { | 92 | { |
93 | struct mtd_part *part = PART(mtd); | 93 | struct mtd_part *part = PART(mtd); |
94 | 94 | ||
95 | offset += part->offset; | 95 | offset += part->offset; |
96 | return part->master->get_unmapped_area(part->master, len, offset, | 96 | return part->master->get_unmapped_area(part->master, len, offset, |
97 | flags); | 97 | flags); |
98 | } | 98 | } |
99 | 99 | ||
100 | static int part_read_oob(struct mtd_info *mtd, loff_t from, | 100 | static int part_read_oob(struct mtd_info *mtd, loff_t from, |
101 | struct mtd_oob_ops *ops) | 101 | struct mtd_oob_ops *ops) |
102 | { | 102 | { |
103 | struct mtd_part *part = PART(mtd); | 103 | struct mtd_part *part = PART(mtd); |
104 | int res; | 104 | int res; |
105 | 105 | ||
106 | if (from >= mtd->size) | 106 | if (from >= mtd->size) |
107 | return -EINVAL; | 107 | return -EINVAL; |
108 | if (ops->datbuf && from + ops->len > mtd->size) | 108 | if (ops->datbuf && from + ops->len > mtd->size) |
109 | return -EINVAL; | 109 | return -EINVAL; |
110 | res = part->master->read_oob(part->master, from + part->offset, ops); | 110 | res = part->master->read_oob(part->master, from + part->offset, ops); |
111 | 111 | ||
112 | if (unlikely(res)) { | 112 | if (unlikely(res)) { |
113 | if (res == -EUCLEAN) | 113 | if (res == -EUCLEAN) |
114 | mtd->ecc_stats.corrected++; | 114 | mtd->ecc_stats.corrected++; |
115 | if (res == -EBADMSG) | 115 | if (res == -EBADMSG) |
116 | mtd->ecc_stats.failed++; | 116 | mtd->ecc_stats.failed++; |
117 | } | 117 | } |
118 | return res; | 118 | return res; |
119 | } | 119 | } |
120 | 120 | ||
121 | static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, | 121 | static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, |
122 | size_t len, size_t *retlen, u_char *buf) | 122 | size_t len, size_t *retlen, u_char *buf) |
123 | { | 123 | { |
124 | struct mtd_part *part = PART(mtd); | 124 | struct mtd_part *part = PART(mtd); |
125 | return part->master->read_user_prot_reg(part->master, from, | 125 | return part->master->read_user_prot_reg(part->master, from, |
126 | len, retlen, buf); | 126 | len, retlen, buf); |
127 | } | 127 | } |
128 | 128 | ||
129 | static int part_get_user_prot_info(struct mtd_info *mtd, | 129 | static int part_get_user_prot_info(struct mtd_info *mtd, |
130 | struct otp_info *buf, size_t len) | 130 | struct otp_info *buf, size_t len) |
131 | { | 131 | { |
132 | struct mtd_part *part = PART(mtd); | 132 | struct mtd_part *part = PART(mtd); |
133 | return part->master->get_user_prot_info(part->master, buf, len); | 133 | return part->master->get_user_prot_info(part->master, buf, len); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, | 136 | static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, |
137 | size_t len, size_t *retlen, u_char *buf) | 137 | size_t len, size_t *retlen, u_char *buf) |
138 | { | 138 | { |
139 | struct mtd_part *part = PART(mtd); | 139 | struct mtd_part *part = PART(mtd); |
140 | return part->master->read_fact_prot_reg(part->master, from, | 140 | return part->master->read_fact_prot_reg(part->master, from, |
141 | len, retlen, buf); | 141 | len, retlen, buf); |
142 | } | 142 | } |
143 | 143 | ||
144 | static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, | 144 | static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, |
145 | size_t len) | 145 | size_t len) |
146 | { | 146 | { |
147 | struct mtd_part *part = PART(mtd); | 147 | struct mtd_part *part = PART(mtd); |
148 | return part->master->get_fact_prot_info(part->master, buf, len); | 148 | return part->master->get_fact_prot_info(part->master, buf, len); |
149 | } | 149 | } |
150 | 150 | ||
151 | static int part_write(struct mtd_info *mtd, loff_t to, size_t len, | 151 | static int part_write(struct mtd_info *mtd, loff_t to, size_t len, |
152 | size_t *retlen, const u_char *buf) | 152 | size_t *retlen, const u_char *buf) |
153 | { | 153 | { |
154 | struct mtd_part *part = PART(mtd); | 154 | struct mtd_part *part = PART(mtd); |
155 | if (!(mtd->flags & MTD_WRITEABLE)) | 155 | if (!(mtd->flags & MTD_WRITEABLE)) |
156 | return -EROFS; | 156 | return -EROFS; |
157 | if (to >= mtd->size) | 157 | if (to >= mtd->size) |
158 | len = 0; | 158 | len = 0; |
159 | else if (to + len > mtd->size) | 159 | else if (to + len > mtd->size) |
160 | len = mtd->size - to; | 160 | len = mtd->size - to; |
161 | return part->master->write(part->master, to + part->offset, | 161 | return part->master->write(part->master, to + part->offset, |
162 | len, retlen, buf); | 162 | len, retlen, buf); |
163 | } | 163 | } |
164 | 164 | ||
165 | static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, | 165 | static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, |
166 | size_t *retlen, const u_char *buf) | 166 | size_t *retlen, const u_char *buf) |
167 | { | 167 | { |
168 | struct mtd_part *part = PART(mtd); | 168 | struct mtd_part *part = PART(mtd); |
169 | if (!(mtd->flags & MTD_WRITEABLE)) | 169 | if (!(mtd->flags & MTD_WRITEABLE)) |
170 | return -EROFS; | 170 | return -EROFS; |
171 | if (to >= mtd->size) | 171 | if (to >= mtd->size) |
172 | len = 0; | 172 | len = 0; |
173 | else if (to + len > mtd->size) | 173 | else if (to + len > mtd->size) |
174 | len = mtd->size - to; | 174 | len = mtd->size - to; |
175 | return part->master->panic_write(part->master, to + part->offset, | 175 | return part->master->panic_write(part->master, to + part->offset, |
176 | len, retlen, buf); | 176 | len, retlen, buf); |
177 | } | 177 | } |
178 | 178 | ||
179 | static int part_write_oob(struct mtd_info *mtd, loff_t to, | 179 | static int part_write_oob(struct mtd_info *mtd, loff_t to, |
180 | struct mtd_oob_ops *ops) | 180 | struct mtd_oob_ops *ops) |
181 | { | 181 | { |
182 | struct mtd_part *part = PART(mtd); | 182 | struct mtd_part *part = PART(mtd); |
183 | 183 | ||
184 | if (!(mtd->flags & MTD_WRITEABLE)) | 184 | if (!(mtd->flags & MTD_WRITEABLE)) |
185 | return -EROFS; | 185 | return -EROFS; |
186 | 186 | ||
187 | if (to >= mtd->size) | 187 | if (to >= mtd->size) |
188 | return -EINVAL; | 188 | return -EINVAL; |
189 | if (ops->datbuf && to + ops->len > mtd->size) | 189 | if (ops->datbuf && to + ops->len > mtd->size) |
190 | return -EINVAL; | 190 | return -EINVAL; |
191 | return part->master->write_oob(part->master, to + part->offset, ops); | 191 | return part->master->write_oob(part->master, to + part->offset, ops); |
192 | } | 192 | } |
193 | 193 | ||
194 | static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, | 194 | static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, |
195 | size_t len, size_t *retlen, u_char *buf) | 195 | size_t len, size_t *retlen, u_char *buf) |
196 | { | 196 | { |
197 | struct mtd_part *part = PART(mtd); | 197 | struct mtd_part *part = PART(mtd); |
198 | return part->master->write_user_prot_reg(part->master, from, | 198 | return part->master->write_user_prot_reg(part->master, from, |
199 | len, retlen, buf); | 199 | len, retlen, buf); |
200 | } | 200 | } |
201 | 201 | ||
202 | static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, | 202 | static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, |
203 | size_t len) | 203 | size_t len) |
204 | { | 204 | { |
205 | struct mtd_part *part = PART(mtd); | 205 | struct mtd_part *part = PART(mtd); |
206 | return part->master->lock_user_prot_reg(part->master, from, len); | 206 | return part->master->lock_user_prot_reg(part->master, from, len); |
207 | } | 207 | } |
208 | 208 | ||
209 | static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, | 209 | static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, |
210 | unsigned long count, loff_t to, size_t *retlen) | 210 | unsigned long count, loff_t to, size_t *retlen) |
211 | { | 211 | { |
212 | struct mtd_part *part = PART(mtd); | 212 | struct mtd_part *part = PART(mtd); |
213 | if (!(mtd->flags & MTD_WRITEABLE)) | 213 | if (!(mtd->flags & MTD_WRITEABLE)) |
214 | return -EROFS; | 214 | return -EROFS; |
215 | return part->master->writev(part->master, vecs, count, | 215 | return part->master->writev(part->master, vecs, count, |
216 | to + part->offset, retlen); | 216 | to + part->offset, retlen); |
217 | } | 217 | } |
218 | 218 | ||
219 | static int part_erase(struct mtd_info *mtd, struct erase_info *instr) | 219 | static int part_erase(struct mtd_info *mtd, struct erase_info *instr) |
220 | { | 220 | { |
221 | struct mtd_part *part = PART(mtd); | 221 | struct mtd_part *part = PART(mtd); |
222 | int ret; | 222 | int ret; |
223 | if (!(mtd->flags & MTD_WRITEABLE)) | 223 | if (!(mtd->flags & MTD_WRITEABLE)) |
224 | return -EROFS; | 224 | return -EROFS; |
225 | if (instr->addr >= mtd->size) | 225 | if (instr->addr >= mtd->size) |
226 | return -EINVAL; | 226 | return -EINVAL; |
227 | instr->addr += part->offset; | 227 | instr->addr += part->offset; |
228 | ret = part->master->erase(part->master, instr); | 228 | ret = part->master->erase(part->master, instr); |
229 | if (ret) { | 229 | if (ret) { |
230 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) | 230 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |
231 | instr->fail_addr -= part->offset; | 231 | instr->fail_addr -= part->offset; |
232 | instr->addr -= part->offset; | 232 | instr->addr -= part->offset; |
233 | } | 233 | } |
234 | return ret; | 234 | return ret; |
235 | } | 235 | } |
236 | 236 | ||
237 | void mtd_erase_callback(struct erase_info *instr) | 237 | void mtd_erase_callback(struct erase_info *instr) |
238 | { | 238 | { |
239 | if (instr->mtd->erase == part_erase) { | 239 | if (instr->mtd->erase == part_erase) { |
240 | struct mtd_part *part = PART(instr->mtd); | 240 | struct mtd_part *part = PART(instr->mtd); |
241 | 241 | ||
242 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) | 242 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |
243 | instr->fail_addr -= part->offset; | 243 | instr->fail_addr -= part->offset; |
244 | instr->addr -= part->offset; | 244 | instr->addr -= part->offset; |
245 | } | 245 | } |
246 | if (instr->callback) | 246 | if (instr->callback) |
247 | instr->callback(instr); | 247 | instr->callback(instr); |
248 | } | 248 | } |
249 | EXPORT_SYMBOL_GPL(mtd_erase_callback); | 249 | EXPORT_SYMBOL_GPL(mtd_erase_callback); |
250 | 250 | ||
251 | static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 251 | static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
252 | { | 252 | { |
253 | struct mtd_part *part = PART(mtd); | 253 | struct mtd_part *part = PART(mtd); |
254 | if ((len + ofs) > mtd->size) | 254 | if ((len + ofs) > mtd->size) |
255 | return -EINVAL; | 255 | return -EINVAL; |
256 | return part->master->lock(part->master, ofs + part->offset, len); | 256 | return part->master->lock(part->master, ofs + part->offset, len); |
257 | } | 257 | } |
258 | 258 | ||
259 | static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 259 | static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
260 | { | 260 | { |
261 | struct mtd_part *part = PART(mtd); | 261 | struct mtd_part *part = PART(mtd); |
262 | if ((len + ofs) > mtd->size) | 262 | if ((len + ofs) > mtd->size) |
263 | return -EINVAL; | 263 | return -EINVAL; |
264 | return part->master->unlock(part->master, ofs + part->offset, len); | 264 | return part->master->unlock(part->master, ofs + part->offset, len); |
265 | } | 265 | } |
266 | 266 | ||
267 | static void part_sync(struct mtd_info *mtd) | 267 | static void part_sync(struct mtd_info *mtd) |
268 | { | 268 | { |
269 | struct mtd_part *part = PART(mtd); | 269 | struct mtd_part *part = PART(mtd); |
270 | part->master->sync(part->master); | 270 | part->master->sync(part->master); |
271 | } | 271 | } |
272 | 272 | ||
273 | static int part_suspend(struct mtd_info *mtd) | 273 | static int part_suspend(struct mtd_info *mtd) |
274 | { | 274 | { |
275 | struct mtd_part *part = PART(mtd); | 275 | struct mtd_part *part = PART(mtd); |
276 | return part->master->suspend(part->master); | 276 | return part->master->suspend(part->master); |
277 | } | 277 | } |
278 | 278 | ||
279 | static void part_resume(struct mtd_info *mtd) | 279 | static void part_resume(struct mtd_info *mtd) |
280 | { | 280 | { |
281 | struct mtd_part *part = PART(mtd); | 281 | struct mtd_part *part = PART(mtd); |
282 | part->master->resume(part->master); | 282 | part->master->resume(part->master); |
283 | } | 283 | } |
284 | 284 | ||
285 | static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) | 285 | static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) |
286 | { | 286 | { |
287 | struct mtd_part *part = PART(mtd); | 287 | struct mtd_part *part = PART(mtd); |
288 | if (ofs >= mtd->size) | 288 | if (ofs >= mtd->size) |
289 | return -EINVAL; | 289 | return -EINVAL; |
290 | ofs += part->offset; | 290 | ofs += part->offset; |
291 | return part->master->block_isbad(part->master, ofs); | 291 | return part->master->block_isbad(part->master, ofs); |
292 | } | 292 | } |
293 | 293 | ||
294 | static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) | 294 | static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) |
295 | { | 295 | { |
296 | struct mtd_part *part = PART(mtd); | 296 | struct mtd_part *part = PART(mtd); |
297 | int res; | 297 | int res; |
298 | 298 | ||
299 | if (!(mtd->flags & MTD_WRITEABLE)) | 299 | if (!(mtd->flags & MTD_WRITEABLE)) |
300 | return -EROFS; | 300 | return -EROFS; |
301 | if (ofs >= mtd->size) | 301 | if (ofs >= mtd->size) |
302 | return -EINVAL; | 302 | return -EINVAL; |
303 | ofs += part->offset; | 303 | ofs += part->offset; |
304 | res = part->master->block_markbad(part->master, ofs); | 304 | res = part->master->block_markbad(part->master, ofs); |
305 | if (!res) | 305 | if (!res) |
306 | mtd->ecc_stats.badblocks++; | 306 | mtd->ecc_stats.badblocks++; |
307 | return res; | 307 | return res; |
308 | } | 308 | } |
309 | 309 | ||
310 | /* | 310 | /* |
311 | * This function unregisters and destroy all slave MTD objects which are | 311 | * This function unregisters and destroy all slave MTD objects which are |
312 | * attached to the given master MTD object. | 312 | * attached to the given master MTD object. |
313 | */ | 313 | */ |
314 | 314 | ||
315 | int del_mtd_partitions(struct mtd_info *master) | 315 | int del_mtd_partitions(struct mtd_info *master) |
316 | { | 316 | { |
317 | struct mtd_part *slave, *next; | 317 | struct mtd_part *slave, *next; |
318 | 318 | ||
319 | list_for_each_entry_safe(slave, next, &mtd_partitions, list) | 319 | list_for_each_entry_safe(slave, next, &mtd_partitions, list) |
320 | if (slave->master == master) { | 320 | if (slave->master == master) { |
321 | list_del(&slave->list); | 321 | list_del(&slave->list); |
322 | del_mtd_device(&slave->mtd); | 322 | del_mtd_device(&slave->mtd); |
323 | kfree(slave); | 323 | kfree(slave); |
324 | } | 324 | } |
325 | 325 | ||
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | EXPORT_SYMBOL(del_mtd_partitions); | 328 | EXPORT_SYMBOL(del_mtd_partitions); |
329 | 329 | ||
330 | static struct mtd_part *add_one_partition(struct mtd_info *master, | 330 | static struct mtd_part *add_one_partition(struct mtd_info *master, |
331 | const struct mtd_partition *part, int partno, | 331 | const struct mtd_partition *part, int partno, |
332 | uint64_t cur_offset) | 332 | uint64_t cur_offset) |
333 | { | 333 | { |
334 | struct mtd_part *slave; | 334 | struct mtd_part *slave; |
335 | 335 | ||
336 | /* allocate the partition structure */ | 336 | /* allocate the partition structure */ |
337 | slave = kzalloc(sizeof(*slave), GFP_KERNEL); | 337 | slave = kzalloc(sizeof(*slave), GFP_KERNEL); |
338 | if (!slave) { | 338 | if (!slave) { |
339 | printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n", | 339 | printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n", |
340 | master->name); | 340 | master->name); |
341 | del_mtd_partitions(master); | 341 | del_mtd_partitions(master); |
342 | return NULL; | 342 | return NULL; |
343 | } | 343 | } |
344 | list_add(&slave->list, &mtd_partitions); | 344 | list_add(&slave->list, &mtd_partitions); |
345 | 345 | ||
346 | /* set up the MTD object for this partition */ | 346 | /* set up the MTD object for this partition */ |
347 | slave->mtd.type = master->type; | 347 | slave->mtd.type = master->type; |
348 | slave->mtd.flags = master->flags & ~part->mask_flags; | 348 | slave->mtd.flags = master->flags & ~part->mask_flags; |
349 | slave->mtd.size = part->size; | 349 | slave->mtd.size = part->size; |
350 | slave->mtd.writesize = master->writesize; | 350 | slave->mtd.writesize = master->writesize; |
351 | slave->mtd.oobsize = master->oobsize; | 351 | slave->mtd.oobsize = master->oobsize; |
352 | slave->mtd.oobavail = master->oobavail; | 352 | slave->mtd.oobavail = master->oobavail; |
353 | slave->mtd.subpage_sft = master->subpage_sft; | 353 | slave->mtd.subpage_sft = master->subpage_sft; |
354 | 354 | ||
355 | slave->mtd.name = part->name; | 355 | slave->mtd.name = part->name; |
356 | slave->mtd.owner = master->owner; | 356 | slave->mtd.owner = master->owner; |
357 | slave->mtd.backing_dev_info = master->backing_dev_info; | 357 | slave->mtd.backing_dev_info = master->backing_dev_info; |
358 | 358 | ||
359 | /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone | 359 | /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone |
360 | * to have the same data be in two different partitions. | 360 | * to have the same data be in two different partitions. |
361 | */ | 361 | */ |
362 | slave->mtd.dev.parent = master->dev.parent; | 362 | slave->mtd.dev.parent = master->dev.parent; |
363 | 363 | ||
364 | slave->mtd.read = part_read; | 364 | slave->mtd.read = part_read; |
365 | slave->mtd.write = part_write; | 365 | slave->mtd.write = part_write; |
366 | 366 | ||
367 | if (master->panic_write) | 367 | if (master->panic_write) |
368 | slave->mtd.panic_write = part_panic_write; | 368 | slave->mtd.panic_write = part_panic_write; |
369 | 369 | ||
370 | if (master->point && master->unpoint) { | 370 | if (master->point && master->unpoint) { |
371 | slave->mtd.point = part_point; | 371 | slave->mtd.point = part_point; |
372 | slave->mtd.unpoint = part_unpoint; | 372 | slave->mtd.unpoint = part_unpoint; |
373 | } | 373 | } |
374 | 374 | ||
375 | if (master->get_unmapped_area) | 375 | if (master->get_unmapped_area) |
376 | slave->mtd.get_unmapped_area = part_get_unmapped_area; | 376 | slave->mtd.get_unmapped_area = part_get_unmapped_area; |
377 | if (master->read_oob) | 377 | if (master->read_oob) |
378 | slave->mtd.read_oob = part_read_oob; | 378 | slave->mtd.read_oob = part_read_oob; |
379 | if (master->write_oob) | 379 | if (master->write_oob) |
380 | slave->mtd.write_oob = part_write_oob; | 380 | slave->mtd.write_oob = part_write_oob; |
381 | if (master->read_user_prot_reg) | 381 | if (master->read_user_prot_reg) |
382 | slave->mtd.read_user_prot_reg = part_read_user_prot_reg; | 382 | slave->mtd.read_user_prot_reg = part_read_user_prot_reg; |
383 | if (master->read_fact_prot_reg) | 383 | if (master->read_fact_prot_reg) |
384 | slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; | 384 | slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; |
385 | if (master->write_user_prot_reg) | 385 | if (master->write_user_prot_reg) |
386 | slave->mtd.write_user_prot_reg = part_write_user_prot_reg; | 386 | slave->mtd.write_user_prot_reg = part_write_user_prot_reg; |
387 | if (master->lock_user_prot_reg) | 387 | if (master->lock_user_prot_reg) |
388 | slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; | 388 | slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; |
389 | if (master->get_user_prot_info) | 389 | if (master->get_user_prot_info) |
390 | slave->mtd.get_user_prot_info = part_get_user_prot_info; | 390 | slave->mtd.get_user_prot_info = part_get_user_prot_info; |
391 | if (master->get_fact_prot_info) | 391 | if (master->get_fact_prot_info) |
392 | slave->mtd.get_fact_prot_info = part_get_fact_prot_info; | 392 | slave->mtd.get_fact_prot_info = part_get_fact_prot_info; |
393 | if (master->sync) | 393 | if (master->sync) |
394 | slave->mtd.sync = part_sync; | 394 | slave->mtd.sync = part_sync; |
395 | if (!partno && !master->dev.class && master->suspend && master->resume) { | 395 | if (!partno && !master->dev.class && master->suspend && master->resume) { |
396 | slave->mtd.suspend = part_suspend; | 396 | slave->mtd.suspend = part_suspend; |
397 | slave->mtd.resume = part_resume; | 397 | slave->mtd.resume = part_resume; |
398 | } | 398 | } |
399 | if (master->writev) | 399 | if (master->writev) |
400 | slave->mtd.writev = part_writev; | 400 | slave->mtd.writev = part_writev; |
401 | if (master->lock) | 401 | if (master->lock) |
402 | slave->mtd.lock = part_lock; | 402 | slave->mtd.lock = part_lock; |
403 | if (master->unlock) | 403 | if (master->unlock) |
404 | slave->mtd.unlock = part_unlock; | 404 | slave->mtd.unlock = part_unlock; |
405 | if (master->block_isbad) | 405 | if (master->block_isbad) |
406 | slave->mtd.block_isbad = part_block_isbad; | 406 | slave->mtd.block_isbad = part_block_isbad; |
407 | if (master->block_markbad) | 407 | if (master->block_markbad) |
408 | slave->mtd.block_markbad = part_block_markbad; | 408 | slave->mtd.block_markbad = part_block_markbad; |
409 | slave->mtd.erase = part_erase; | 409 | slave->mtd.erase = part_erase; |
410 | slave->master = master; | 410 | slave->master = master; |
411 | slave->offset = part->offset; | 411 | slave->offset = part->offset; |
412 | 412 | ||
413 | if (slave->offset == MTDPART_OFS_APPEND) | 413 | if (slave->offset == MTDPART_OFS_APPEND) |
414 | slave->offset = cur_offset; | 414 | slave->offset = cur_offset; |
415 | if (slave->offset == MTDPART_OFS_NXTBLK) { | 415 | if (slave->offset == MTDPART_OFS_NXTBLK) { |
416 | slave->offset = cur_offset; | 416 | slave->offset = cur_offset; |
417 | if (mtd_mod_by_eb(cur_offset, master) != 0) { | 417 | if (mtd_mod_by_eb(cur_offset, master) != 0) { |
418 | /* Round up to next erasesize */ | 418 | /* Round up to next erasesize */ |
419 | slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize; | 419 | slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize; |
420 | printk(KERN_NOTICE "Moving partition %d: " | 420 | printk(KERN_NOTICE "Moving partition %d: " |
421 | "0x%012llx -> 0x%012llx\n", partno, | 421 | "0x%012llx -> 0x%012llx\n", partno, |
422 | (unsigned long long)cur_offset, (unsigned long long)slave->offset); | 422 | (unsigned long long)cur_offset, (unsigned long long)slave->offset); |
423 | } | 423 | } |
424 | } | 424 | } |
425 | if (slave->mtd.size == MTDPART_SIZ_FULL) | 425 | if (slave->mtd.size == MTDPART_SIZ_FULL) |
426 | slave->mtd.size = master->size - slave->offset; | 426 | slave->mtd.size = master->size - slave->offset; |
427 | 427 | ||
428 | printk(KERN_NOTICE "0x%012llx-0x%012llx : \"%s\"\n", (unsigned long long)slave->offset, | 428 | printk(KERN_NOTICE "0x%012llx-0x%012llx : \"%s\"\n", (unsigned long long)slave->offset, |
429 | (unsigned long long)(slave->offset + slave->mtd.size), slave->mtd.name); | 429 | (unsigned long long)(slave->offset + slave->mtd.size), slave->mtd.name); |
430 | 430 | ||
431 | /* let's do some sanity checks */ | 431 | /* let's do some sanity checks */ |
432 | if (slave->offset >= master->size) { | 432 | if (slave->offset >= master->size) { |
433 | /* let's register it anyway to preserve ordering */ | 433 | /* let's register it anyway to preserve ordering */ |
434 | slave->offset = 0; | 434 | slave->offset = 0; |
435 | slave->mtd.size = 0; | 435 | slave->mtd.size = 0; |
436 | printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n", | 436 | printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n", |
437 | part->name); | 437 | part->name); |
438 | goto out_register; | 438 | goto out_register; |
439 | } | 439 | } |
440 | if (slave->offset + slave->mtd.size > master->size) { | 440 | if (slave->offset + slave->mtd.size > master->size) { |
441 | slave->mtd.size = master->size - slave->offset; | 441 | slave->mtd.size = master->size - slave->offset; |
442 | printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n", | 442 | printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n", |
443 | part->name, master->name, (unsigned long long)slave->mtd.size); | 443 | part->name, master->name, (unsigned long long)slave->mtd.size); |
444 | } | 444 | } |
445 | if (master->numeraseregions > 1) { | 445 | if (master->numeraseregions > 1) { |
446 | /* Deal with variable erase size stuff */ | 446 | /* Deal with variable erase size stuff */ |
447 | int i, max = master->numeraseregions; | 447 | int i, max = master->numeraseregions; |
448 | u64 end = slave->offset + slave->mtd.size; | 448 | u64 end = slave->offset + slave->mtd.size; |
449 | struct mtd_erase_region_info *regions = master->eraseregions; | 449 | struct mtd_erase_region_info *regions = master->eraseregions; |
450 | 450 | ||
451 | /* Find the first erase regions which is part of this | 451 | /* Find the first erase regions which is part of this |
452 | * partition. */ | 452 | * partition. */ |
453 | for (i = 0; i < max && regions[i].offset <= slave->offset; i++) | 453 | for (i = 0; i < max && regions[i].offset <= slave->offset; i++) |
454 | ; | 454 | ; |
455 | /* The loop searched for the region _behind_ the first one */ | 455 | /* The loop searched for the region _behind_ the first one */ |
456 | i--; | 456 | i--; |
457 | 457 | ||
458 | /* Pick biggest erasesize */ | 458 | /* Pick biggest erasesize */ |
459 | for (; i < max && regions[i].offset < end; i++) { | 459 | for (; i < max && regions[i].offset < end; i++) { |
460 | if (slave->mtd.erasesize < regions[i].erasesize) { | 460 | if (slave->mtd.erasesize < regions[i].erasesize) { |
461 | slave->mtd.erasesize = regions[i].erasesize; | 461 | slave->mtd.erasesize = regions[i].erasesize; |
462 | } | 462 | } |
463 | } | 463 | } |
464 | BUG_ON(slave->mtd.erasesize == 0); | 464 | BUG_ON(slave->mtd.erasesize == 0); |
465 | } else { | 465 | } else { |
466 | /* Single erase size */ | 466 | /* Single erase size */ |
467 | slave->mtd.erasesize = master->erasesize; | 467 | slave->mtd.erasesize = master->erasesize; |
468 | } | 468 | } |
469 | 469 | ||
470 | if ((slave->mtd.flags & MTD_WRITEABLE) && | 470 | if ((slave->mtd.flags & MTD_WRITEABLE) && |
471 | mtd_mod_by_eb(slave->offset, &slave->mtd)) { | 471 | mtd_mod_by_eb(slave->offset, &slave->mtd)) { |
472 | /* Doesn't start on a boundary of major erase size */ | 472 | /* Doesn't start on a boundary of major erase size */ |
473 | /* FIXME: Let it be writable if it is on a boundary of | 473 | /* FIXME: Let it be writable if it is on a boundary of |
474 | * _minor_ erase size though */ | 474 | * _minor_ erase size though */ |
475 | slave->mtd.flags &= ~MTD_WRITEABLE; | 475 | slave->mtd.flags &= ~MTD_WRITEABLE; |
476 | printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", | 476 | printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", |
477 | part->name); | 477 | part->name); |
478 | } | 478 | } |
479 | if ((slave->mtd.flags & MTD_WRITEABLE) && | 479 | if ((slave->mtd.flags & MTD_WRITEABLE) && |
480 | mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) { | 480 | mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) { |
481 | slave->mtd.flags &= ~MTD_WRITEABLE; | 481 | slave->mtd.flags &= ~MTD_WRITEABLE; |
482 | printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", | 482 | printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", |
483 | part->name); | 483 | part->name); |
484 | } | 484 | } |
485 | 485 | ||
486 | slave->mtd.ecclayout = master->ecclayout; | 486 | slave->mtd.ecclayout = master->ecclayout; |
487 | if (master->block_isbad) { | 487 | if (master->block_isbad) { |
488 | uint64_t offs = 0; | 488 | uint64_t offs = 0; |
489 | 489 | ||
490 | while (offs < slave->mtd.size) { | 490 | while (offs < slave->mtd.size) { |
491 | if (master->block_isbad(master, | 491 | if (master->block_isbad(master, |
492 | offs + slave->offset)) | 492 | offs + slave->offset)) |
493 | slave->mtd.ecc_stats.badblocks++; | 493 | slave->mtd.ecc_stats.badblocks++; |
494 | offs += slave->mtd.erasesize; | 494 | offs += slave->mtd.erasesize; |
495 | } | 495 | } |
496 | } | 496 | } |
497 | 497 | ||
498 | out_register: | 498 | out_register: |
499 | /* register our partition */ | 499 | /* register our partition */ |
500 | add_mtd_device(&slave->mtd); | 500 | add_mtd_device(&slave->mtd); |
501 | 501 | ||
502 | return slave; | 502 | return slave; |
503 | } | 503 | } |
504 | 504 | ||
505 | /* | 505 | /* |
506 | * This function, given a master MTD object and a partition table, creates | 506 | * This function, given a master MTD object and a partition table, creates |
507 | * and registers slave MTD objects which are bound to the master according to | 507 | * and registers slave MTD objects which are bound to the master according to |
508 | * the partition definitions. | 508 | * the partition definitions. |
509 | * | 509 | * |
510 | * We don't register the master, or expect the caller to have done so, | 510 | * We don't register the master, or expect the caller to have done so, |
511 | * for reasons of data integrity. | 511 | * for reasons of data integrity. |
512 | */ | 512 | */ |
513 | 513 | ||
514 | int add_mtd_partitions(struct mtd_info *master, | 514 | int add_mtd_partitions(struct mtd_info *master, |
515 | const struct mtd_partition *parts, | 515 | const struct mtd_partition *parts, |
516 | int nbparts) | 516 | int nbparts) |
517 | { | 517 | { |
518 | struct mtd_part *slave; | 518 | struct mtd_part *slave; |
519 | uint64_t cur_offset = 0; | 519 | uint64_t cur_offset = 0; |
520 | int i; | 520 | int i; |
521 | 521 | ||
522 | printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); | 522 | printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); |
523 | 523 | ||
524 | for (i = 0; i < nbparts; i++) { | 524 | for (i = 0; i < nbparts; i++) { |
525 | slave = add_one_partition(master, parts + i, i, cur_offset); | 525 | slave = add_one_partition(master, parts + i, i, cur_offset); |
526 | if (!slave) | 526 | if (!slave) |
527 | return -ENOMEM; | 527 | return -ENOMEM; |
528 | cur_offset = slave->offset + slave->mtd.size; | 528 | cur_offset = slave->offset + slave->mtd.size; |
529 | } | 529 | } |
530 | 530 | ||
531 | return 0; | 531 | return 0; |
532 | } | 532 | } |
533 | EXPORT_SYMBOL(add_mtd_partitions); | 533 | EXPORT_SYMBOL(add_mtd_partitions); |
534 | 534 | ||
535 | static DEFINE_SPINLOCK(part_parser_lock); | 535 | static DEFINE_SPINLOCK(part_parser_lock); |
536 | static LIST_HEAD(part_parsers); | 536 | static LIST_HEAD(part_parsers); |
537 | 537 | ||
538 | static struct mtd_part_parser *get_partition_parser(const char *name) | 538 | static struct mtd_part_parser *get_partition_parser(const char *name) |
539 | { | 539 | { |
540 | struct mtd_part_parser *p, *ret = NULL; | 540 | struct mtd_part_parser *p, *ret = NULL; |
541 | 541 | ||
542 | spin_lock(&part_parser_lock); | 542 | spin_lock(&part_parser_lock); |
543 | 543 | ||
544 | list_for_each_entry(p, &part_parsers, list) | 544 | list_for_each_entry(p, &part_parsers, list) |
545 | if (!strcmp(p->name, name) && try_module_get(p->owner)) { | 545 | if (!strcmp(p->name, name) && try_module_get(p->owner)) { |
546 | ret = p; | 546 | ret = p; |
547 | break; | 547 | break; |
548 | } | 548 | } |
549 | 549 | ||
550 | spin_unlock(&part_parser_lock); | 550 | spin_unlock(&part_parser_lock); |
551 | 551 | ||
552 | return ret; | 552 | return ret; |
553 | } | 553 | } |
554 | 554 | ||
555 | int register_mtd_parser(struct mtd_part_parser *p) | 555 | int register_mtd_parser(struct mtd_part_parser *p) |
556 | { | 556 | { |
557 | spin_lock(&part_parser_lock); | 557 | spin_lock(&part_parser_lock); |
558 | list_add(&p->list, &part_parsers); | 558 | list_add(&p->list, &part_parsers); |
559 | spin_unlock(&part_parser_lock); | 559 | spin_unlock(&part_parser_lock); |
560 | 560 | ||
561 | return 0; | 561 | return 0; |
562 | } | 562 | } |
563 | EXPORT_SYMBOL_GPL(register_mtd_parser); | 563 | EXPORT_SYMBOL_GPL(register_mtd_parser); |
564 | 564 | ||
565 | int deregister_mtd_parser(struct mtd_part_parser *p) | 565 | int deregister_mtd_parser(struct mtd_part_parser *p) |
566 | { | 566 | { |
567 | spin_lock(&part_parser_lock); | 567 | spin_lock(&part_parser_lock); |
568 | list_del(&p->list); | 568 | list_del(&p->list); |
569 | spin_unlock(&part_parser_lock); | 569 | spin_unlock(&part_parser_lock); |
570 | return 0; | 570 | return 0; |
571 | } | 571 | } |
572 | EXPORT_SYMBOL_GPL(deregister_mtd_parser); | 572 | EXPORT_SYMBOL_GPL(deregister_mtd_parser); |
573 | 573 | ||
574 | int parse_mtd_partitions(struct mtd_info *master, const char **types, | 574 | int parse_mtd_partitions(struct mtd_info *master, const char **types, |
575 | struct mtd_partition **pparts, unsigned long origin) | 575 | struct mtd_partition **pparts, unsigned long origin) |
576 | { | 576 | { |
577 | struct mtd_part_parser *parser; | 577 | struct mtd_part_parser *parser; |
578 | int ret = 0; | 578 | int ret = 0; |
579 | 579 | ||
580 | for ( ; ret <= 0 && *types; types++) { | 580 | for ( ; ret <= 0 && *types; types++) { |
581 | parser = get_partition_parser(*types); | 581 | parser = get_partition_parser(*types); |
582 | if (!parser && !request_module("%s", *types)) | 582 | if (!parser && !request_module("%s", *types)) |
583 | parser = get_partition_parser(*types); | 583 | parser = get_partition_parser(*types); |
584 | if (!parser) { | 584 | if (!parser) { |
585 | printk(KERN_NOTICE "%s partition parsing not available\n", | 585 | printk(KERN_NOTICE "%s partition parsing not available\n", |
586 | *types); | 586 | *types); |
587 | continue; | 587 | continue; |
588 | } | 588 | } |
589 | ret = (*parser->parse_fn)(master, pparts, origin); | 589 | ret = (*parser->parse_fn)(master, pparts, origin); |
590 | if (ret > 0) { | 590 | if (ret > 0) { |
591 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", | 591 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", |
592 | ret, parser->name, master->name); | 592 | ret, parser->name, master->name); |
593 | } | 593 | } |
594 | put_partition_parser(parser); | 594 | put_partition_parser(parser); |
595 | } | 595 | } |
596 | return ret; | 596 | return ret; |
597 | } | 597 | } |
598 | EXPORT_SYMBOL_GPL(parse_mtd_partitions); | 598 | EXPORT_SYMBOL_GPL(parse_mtd_partitions); |
599 | 599 |
drivers/net/smc91x.c
1 | /* | 1 | /* |
2 | * smc91x.c | 2 | * smc91x.c |
3 | * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices. | 3 | * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices. |
4 | * | 4 | * |
5 | * Copyright (C) 1996 by Erik Stahlman | 5 | * Copyright (C) 1996 by Erik Stahlman |
6 | * Copyright (C) 2001 Standard Microsystems Corporation | 6 | * Copyright (C) 2001 Standard Microsystems Corporation |
7 | * Developed by Simple Network Magic Corporation | 7 | * Developed by Simple Network Magic Corporation |
8 | * Copyright (C) 2003 Monta Vista Software, Inc. | 8 | * Copyright (C) 2003 Monta Vista Software, Inc. |
9 | * Unified SMC91x driver by Nicolas Pitre | 9 | * Unified SMC91x driver by Nicolas Pitre |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
15 | * | 15 | * |
16 | * This program is distributed in the hope that it will be useful, | 16 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 19 | * GNU General Public License for more details. |
20 | * | 20 | * |
21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | * | 24 | * |
25 | * Arguments: | 25 | * Arguments: |
26 | * io = for the base address | 26 | * io = for the base address |
27 | * irq = for the IRQ | 27 | * irq = for the IRQ |
28 | * nowait = 0 for normal wait states, 1 eliminates additional wait states | 28 | * nowait = 0 for normal wait states, 1 eliminates additional wait states |
29 | * | 29 | * |
30 | * original author: | 30 | * original author: |
31 | * Erik Stahlman <erik@vt.edu> | 31 | * Erik Stahlman <erik@vt.edu> |
32 | * | 32 | * |
33 | * hardware multicast code: | 33 | * hardware multicast code: |
34 | * Peter Cammaert <pc@denkart.be> | 34 | * Peter Cammaert <pc@denkart.be> |
35 | * | 35 | * |
36 | * contributors: | 36 | * contributors: |
37 | * Daris A Nevil <dnevil@snmc.com> | 37 | * Daris A Nevil <dnevil@snmc.com> |
38 | * Nicolas Pitre <nico@cam.org> | 38 | * Nicolas Pitre <nico@fluxnic.net> |
39 | * Russell King <rmk@arm.linux.org.uk> | 39 | * Russell King <rmk@arm.linux.org.uk> |
40 | * | 40 | * |
41 | * History: | 41 | * History: |
42 | * 08/20/00 Arnaldo Melo fix kfree(skb) in smc_hardware_send_packet | 42 | * 08/20/00 Arnaldo Melo fix kfree(skb) in smc_hardware_send_packet |
43 | * 12/15/00 Christian Jullien fix "Warning: kfree_skb on hard IRQ" | 43 | * 12/15/00 Christian Jullien fix "Warning: kfree_skb on hard IRQ" |
44 | * 03/16/01 Daris A Nevil modified smc9194.c for use with LAN91C111 | 44 | * 03/16/01 Daris A Nevil modified smc9194.c for use with LAN91C111 |
45 | * 08/22/01 Scott Anderson merge changes from smc9194 to smc91111 | 45 | * 08/22/01 Scott Anderson merge changes from smc9194 to smc91111 |
46 | * 08/21/01 Pramod B Bhardwaj added support for RevB of LAN91C111 | 46 | * 08/21/01 Pramod B Bhardwaj added support for RevB of LAN91C111 |
47 | * 12/20/01 Jeff Sutherland initial port to Xscale PXA with DMA support | 47 | * 12/20/01 Jeff Sutherland initial port to Xscale PXA with DMA support |
48 | * 04/07/03 Nicolas Pitre unified SMC91x driver, killed irq races, | 48 | * 04/07/03 Nicolas Pitre unified SMC91x driver, killed irq races, |
49 | * more bus abstraction, big cleanup, etc. | 49 | * more bus abstraction, big cleanup, etc. |
50 | * 29/09/03 Russell King - add driver model support | 50 | * 29/09/03 Russell King - add driver model support |
51 | * - ethtool support | 51 | * - ethtool support |
52 | * - convert to use generic MII interface | 52 | * - convert to use generic MII interface |
53 | * - add link up/down notification | 53 | * - add link up/down notification |
54 | * - don't try to handle full negotiation in | 54 | * - don't try to handle full negotiation in |
55 | * smc_phy_configure | 55 | * smc_phy_configure |
56 | * - clean up (and fix stack overrun) in PHY | 56 | * - clean up (and fix stack overrun) in PHY |
57 | * MII read/write functions | 57 | * MII read/write functions |
58 | * 22/09/04 Nicolas Pitre big update (see commit log for details) | 58 | * 22/09/04 Nicolas Pitre big update (see commit log for details) |
59 | */ | 59 | */ |
60 | static const char version[] = | 60 | static const char version[] = |
61 | "smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@cam.org>\n"; | 61 | "smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@fluxnic.net>\n"; |
62 | 62 | ||
63 | /* Debugging level */ | 63 | /* Debugging level */ |
64 | #ifndef SMC_DEBUG | 64 | #ifndef SMC_DEBUG |
65 | #define SMC_DEBUG 0 | 65 | #define SMC_DEBUG 0 |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | 68 | ||
69 | #include <linux/init.h> | 69 | #include <linux/init.h> |
70 | #include <linux/module.h> | 70 | #include <linux/module.h> |
71 | #include <linux/kernel.h> | 71 | #include <linux/kernel.h> |
72 | #include <linux/sched.h> | 72 | #include <linux/sched.h> |
73 | #include <linux/slab.h> | 73 | #include <linux/slab.h> |
74 | #include <linux/delay.h> | 74 | #include <linux/delay.h> |
75 | #include <linux/interrupt.h> | 75 | #include <linux/interrupt.h> |
76 | #include <linux/errno.h> | 76 | #include <linux/errno.h> |
77 | #include <linux/ioport.h> | 77 | #include <linux/ioport.h> |
78 | #include <linux/crc32.h> | 78 | #include <linux/crc32.h> |
79 | #include <linux/platform_device.h> | 79 | #include <linux/platform_device.h> |
80 | #include <linux/spinlock.h> | 80 | #include <linux/spinlock.h> |
81 | #include <linux/ethtool.h> | 81 | #include <linux/ethtool.h> |
82 | #include <linux/mii.h> | 82 | #include <linux/mii.h> |
83 | #include <linux/workqueue.h> | 83 | #include <linux/workqueue.h> |
84 | 84 | ||
85 | #include <linux/netdevice.h> | 85 | #include <linux/netdevice.h> |
86 | #include <linux/etherdevice.h> | 86 | #include <linux/etherdevice.h> |
87 | #include <linux/skbuff.h> | 87 | #include <linux/skbuff.h> |
88 | 88 | ||
89 | #include <asm/io.h> | 89 | #include <asm/io.h> |
90 | 90 | ||
91 | #include "smc91x.h" | 91 | #include "smc91x.h" |
92 | 92 | ||
93 | #ifndef SMC_NOWAIT | 93 | #ifndef SMC_NOWAIT |
94 | # define SMC_NOWAIT 0 | 94 | # define SMC_NOWAIT 0 |
95 | #endif | 95 | #endif |
96 | static int nowait = SMC_NOWAIT; | 96 | static int nowait = SMC_NOWAIT; |
97 | module_param(nowait, int, 0400); | 97 | module_param(nowait, int, 0400); |
98 | MODULE_PARM_DESC(nowait, "set to 1 for no wait state"); | 98 | MODULE_PARM_DESC(nowait, "set to 1 for no wait state"); |
99 | 99 | ||
100 | /* | 100 | /* |
101 | * Transmit timeout, default 5 seconds. | 101 | * Transmit timeout, default 5 seconds. |
102 | */ | 102 | */ |
103 | static int watchdog = 1000; | 103 | static int watchdog = 1000; |
104 | module_param(watchdog, int, 0400); | 104 | module_param(watchdog, int, 0400); |
105 | MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); | 105 | MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); |
106 | 106 | ||
107 | MODULE_LICENSE("GPL"); | 107 | MODULE_LICENSE("GPL"); |
108 | MODULE_ALIAS("platform:smc91x"); | 108 | MODULE_ALIAS("platform:smc91x"); |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * The internal workings of the driver. If you are changing anything | 111 | * The internal workings of the driver. If you are changing anything |
112 | * here with the SMC stuff, you should have the datasheet and know | 112 | * here with the SMC stuff, you should have the datasheet and know |
113 | * what you are doing. | 113 | * what you are doing. |
114 | */ | 114 | */ |
115 | #define CARDNAME "smc91x" | 115 | #define CARDNAME "smc91x" |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * Use power-down feature of the chip | 118 | * Use power-down feature of the chip |
119 | */ | 119 | */ |
120 | #define POWER_DOWN 1 | 120 | #define POWER_DOWN 1 |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * Wait time for memory to be free. This probably shouldn't be | 123 | * Wait time for memory to be free. This probably shouldn't be |
124 | * tuned that much, as waiting for this means nothing else happens | 124 | * tuned that much, as waiting for this means nothing else happens |
125 | * in the system | 125 | * in the system |
126 | */ | 126 | */ |
127 | #define MEMORY_WAIT_TIME 16 | 127 | #define MEMORY_WAIT_TIME 16 |
128 | 128 | ||
129 | /* | 129 | /* |
130 | * The maximum number of processing loops allowed for each call to the | 130 | * The maximum number of processing loops allowed for each call to the |
131 | * IRQ handler. | 131 | * IRQ handler. |
132 | */ | 132 | */ |
133 | #define MAX_IRQ_LOOPS 8 | 133 | #define MAX_IRQ_LOOPS 8 |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * This selects whether TX packets are sent one by one to the SMC91x internal | 136 | * This selects whether TX packets are sent one by one to the SMC91x internal |
137 | * memory and throttled until transmission completes. This may prevent | 137 | * memory and throttled until transmission completes. This may prevent |
138 | * RX overruns a litle by keeping much of the memory free for RX packets | 138 | * RX overruns a litle by keeping much of the memory free for RX packets |
139 | * but to the expense of reduced TX throughput and increased IRQ overhead. | 139 | * but to the expense of reduced TX throughput and increased IRQ overhead. |
140 | * Note this is not a cure for a too slow data bus or too high IRQ latency. | 140 | * Note this is not a cure for a too slow data bus or too high IRQ latency. |
141 | */ | 141 | */ |
142 | #define THROTTLE_TX_PKTS 0 | 142 | #define THROTTLE_TX_PKTS 0 |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * The MII clock high/low times. 2x this number gives the MII clock period | 145 | * The MII clock high/low times. 2x this number gives the MII clock period |
146 | * in microseconds. (was 50, but this gives 6.4ms for each MII transaction!) | 146 | * in microseconds. (was 50, but this gives 6.4ms for each MII transaction!) |
147 | */ | 147 | */ |
148 | #define MII_DELAY 1 | 148 | #define MII_DELAY 1 |
149 | 149 | ||
150 | #if SMC_DEBUG > 0 | 150 | #if SMC_DEBUG > 0 |
151 | #define DBG(n, args...) \ | 151 | #define DBG(n, args...) \ |
152 | do { \ | 152 | do { \ |
153 | if (SMC_DEBUG >= (n)) \ | 153 | if (SMC_DEBUG >= (n)) \ |
154 | printk(args); \ | 154 | printk(args); \ |
155 | } while (0) | 155 | } while (0) |
156 | 156 | ||
157 | #define PRINTK(args...) printk(args) | 157 | #define PRINTK(args...) printk(args) |
158 | #else | 158 | #else |
159 | #define DBG(n, args...) do { } while(0) | 159 | #define DBG(n, args...) do { } while(0) |
160 | #define PRINTK(args...) printk(KERN_DEBUG args) | 160 | #define PRINTK(args...) printk(KERN_DEBUG args) |
161 | #endif | 161 | #endif |
162 | 162 | ||
163 | #if SMC_DEBUG > 3 | 163 | #if SMC_DEBUG > 3 |
164 | static void PRINT_PKT(u_char *buf, int length) | 164 | static void PRINT_PKT(u_char *buf, int length) |
165 | { | 165 | { |
166 | int i; | 166 | int i; |
167 | int remainder; | 167 | int remainder; |
168 | int lines; | 168 | int lines; |
169 | 169 | ||
170 | lines = length / 16; | 170 | lines = length / 16; |
171 | remainder = length % 16; | 171 | remainder = length % 16; |
172 | 172 | ||
173 | for (i = 0; i < lines ; i ++) { | 173 | for (i = 0; i < lines ; i ++) { |
174 | int cur; | 174 | int cur; |
175 | for (cur = 0; cur < 8; cur++) { | 175 | for (cur = 0; cur < 8; cur++) { |
176 | u_char a, b; | 176 | u_char a, b; |
177 | a = *buf++; | 177 | a = *buf++; |
178 | b = *buf++; | 178 | b = *buf++; |
179 | printk("%02x%02x ", a, b); | 179 | printk("%02x%02x ", a, b); |
180 | } | 180 | } |
181 | printk("\n"); | 181 | printk("\n"); |
182 | } | 182 | } |
183 | for (i = 0; i < remainder/2 ; i++) { | 183 | for (i = 0; i < remainder/2 ; i++) { |
184 | u_char a, b; | 184 | u_char a, b; |
185 | a = *buf++; | 185 | a = *buf++; |
186 | b = *buf++; | 186 | b = *buf++; |
187 | printk("%02x%02x ", a, b); | 187 | printk("%02x%02x ", a, b); |
188 | } | 188 | } |
189 | printk("\n"); | 189 | printk("\n"); |
190 | } | 190 | } |
191 | #else | 191 | #else |
192 | #define PRINT_PKT(x...) do { } while(0) | 192 | #define PRINT_PKT(x...) do { } while(0) |
193 | #endif | 193 | #endif |
194 | 194 | ||
195 | 195 | ||
196 | /* this enables an interrupt in the interrupt mask register */ | 196 | /* this enables an interrupt in the interrupt mask register */ |
197 | #define SMC_ENABLE_INT(lp, x) do { \ | 197 | #define SMC_ENABLE_INT(lp, x) do { \ |
198 | unsigned char mask; \ | 198 | unsigned char mask; \ |
199 | unsigned long smc_enable_flags; \ | 199 | unsigned long smc_enable_flags; \ |
200 | spin_lock_irqsave(&lp->lock, smc_enable_flags); \ | 200 | spin_lock_irqsave(&lp->lock, smc_enable_flags); \ |
201 | mask = SMC_GET_INT_MASK(lp); \ | 201 | mask = SMC_GET_INT_MASK(lp); \ |
202 | mask |= (x); \ | 202 | mask |= (x); \ |
203 | SMC_SET_INT_MASK(lp, mask); \ | 203 | SMC_SET_INT_MASK(lp, mask); \ |
204 | spin_unlock_irqrestore(&lp->lock, smc_enable_flags); \ | 204 | spin_unlock_irqrestore(&lp->lock, smc_enable_flags); \ |
205 | } while (0) | 205 | } while (0) |
206 | 206 | ||
207 | /* this disables an interrupt from the interrupt mask register */ | 207 | /* this disables an interrupt from the interrupt mask register */ |
208 | #define SMC_DISABLE_INT(lp, x) do { \ | 208 | #define SMC_DISABLE_INT(lp, x) do { \ |
209 | unsigned char mask; \ | 209 | unsigned char mask; \ |
210 | unsigned long smc_disable_flags; \ | 210 | unsigned long smc_disable_flags; \ |
211 | spin_lock_irqsave(&lp->lock, smc_disable_flags); \ | 211 | spin_lock_irqsave(&lp->lock, smc_disable_flags); \ |
212 | mask = SMC_GET_INT_MASK(lp); \ | 212 | mask = SMC_GET_INT_MASK(lp); \ |
213 | mask &= ~(x); \ | 213 | mask &= ~(x); \ |
214 | SMC_SET_INT_MASK(lp, mask); \ | 214 | SMC_SET_INT_MASK(lp, mask); \ |
215 | spin_unlock_irqrestore(&lp->lock, smc_disable_flags); \ | 215 | spin_unlock_irqrestore(&lp->lock, smc_disable_flags); \ |
216 | } while (0) | 216 | } while (0) |
217 | 217 | ||
218 | /* | 218 | /* |
219 | * Wait while MMU is busy. This is usually in the order of a few nanosecs | 219 | * Wait while MMU is busy. This is usually in the order of a few nanosecs |
220 | * if at all, but let's avoid deadlocking the system if the hardware | 220 | * if at all, but let's avoid deadlocking the system if the hardware |
221 | * decides to go south. | 221 | * decides to go south. |
222 | */ | 222 | */ |
223 | #define SMC_WAIT_MMU_BUSY(lp) do { \ | 223 | #define SMC_WAIT_MMU_BUSY(lp) do { \ |
224 | if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) { \ | 224 | if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) { \ |
225 | unsigned long timeout = jiffies + 2; \ | 225 | unsigned long timeout = jiffies + 2; \ |
226 | while (SMC_GET_MMU_CMD(lp) & MC_BUSY) { \ | 226 | while (SMC_GET_MMU_CMD(lp) & MC_BUSY) { \ |
227 | if (time_after(jiffies, timeout)) { \ | 227 | if (time_after(jiffies, timeout)) { \ |
228 | printk("%s: timeout %s line %d\n", \ | 228 | printk("%s: timeout %s line %d\n", \ |
229 | dev->name, __FILE__, __LINE__); \ | 229 | dev->name, __FILE__, __LINE__); \ |
230 | break; \ | 230 | break; \ |
231 | } \ | 231 | } \ |
232 | cpu_relax(); \ | 232 | cpu_relax(); \ |
233 | } \ | 233 | } \ |
234 | } \ | 234 | } \ |
235 | } while (0) | 235 | } while (0) |
236 | 236 | ||
237 | 237 | ||
238 | /* | 238 | /* |
239 | * this does a soft reset on the device | 239 | * this does a soft reset on the device |
240 | */ | 240 | */ |
241 | static void smc_reset(struct net_device *dev) | 241 | static void smc_reset(struct net_device *dev) |
242 | { | 242 | { |
243 | struct smc_local *lp = netdev_priv(dev); | 243 | struct smc_local *lp = netdev_priv(dev); |
244 | void __iomem *ioaddr = lp->base; | 244 | void __iomem *ioaddr = lp->base; |
245 | unsigned int ctl, cfg; | 245 | unsigned int ctl, cfg; |
246 | struct sk_buff *pending_skb; | 246 | struct sk_buff *pending_skb; |
247 | 247 | ||
248 | DBG(2, "%s: %s\n", dev->name, __func__); | 248 | DBG(2, "%s: %s\n", dev->name, __func__); |
249 | 249 | ||
250 | /* Disable all interrupts, block TX tasklet */ | 250 | /* Disable all interrupts, block TX tasklet */ |
251 | spin_lock_irq(&lp->lock); | 251 | spin_lock_irq(&lp->lock); |
252 | SMC_SELECT_BANK(lp, 2); | 252 | SMC_SELECT_BANK(lp, 2); |
253 | SMC_SET_INT_MASK(lp, 0); | 253 | SMC_SET_INT_MASK(lp, 0); |
254 | pending_skb = lp->pending_tx_skb; | 254 | pending_skb = lp->pending_tx_skb; |
255 | lp->pending_tx_skb = NULL; | 255 | lp->pending_tx_skb = NULL; |
256 | spin_unlock_irq(&lp->lock); | 256 | spin_unlock_irq(&lp->lock); |
257 | 257 | ||
258 | /* free any pending tx skb */ | 258 | /* free any pending tx skb */ |
259 | if (pending_skb) { | 259 | if (pending_skb) { |
260 | dev_kfree_skb(pending_skb); | 260 | dev_kfree_skb(pending_skb); |
261 | dev->stats.tx_errors++; | 261 | dev->stats.tx_errors++; |
262 | dev->stats.tx_aborted_errors++; | 262 | dev->stats.tx_aborted_errors++; |
263 | } | 263 | } |
264 | 264 | ||
265 | /* | 265 | /* |
266 | * This resets the registers mostly to defaults, but doesn't | 266 | * This resets the registers mostly to defaults, but doesn't |
267 | * affect EEPROM. That seems unnecessary | 267 | * affect EEPROM. That seems unnecessary |
268 | */ | 268 | */ |
269 | SMC_SELECT_BANK(lp, 0); | 269 | SMC_SELECT_BANK(lp, 0); |
270 | SMC_SET_RCR(lp, RCR_SOFTRST); | 270 | SMC_SET_RCR(lp, RCR_SOFTRST); |
271 | 271 | ||
272 | /* | 272 | /* |
273 | * Setup the Configuration Register | 273 | * Setup the Configuration Register |
274 | * This is necessary because the CONFIG_REG is not affected | 274 | * This is necessary because the CONFIG_REG is not affected |
275 | * by a soft reset | 275 | * by a soft reset |
276 | */ | 276 | */ |
277 | SMC_SELECT_BANK(lp, 1); | 277 | SMC_SELECT_BANK(lp, 1); |
278 | 278 | ||
279 | cfg = CONFIG_DEFAULT; | 279 | cfg = CONFIG_DEFAULT; |
280 | 280 | ||
281 | /* | 281 | /* |
282 | * Setup for fast accesses if requested. If the card/system | 282 | * Setup for fast accesses if requested. If the card/system |
283 | * can't handle it then there will be no recovery except for | 283 | * can't handle it then there will be no recovery except for |
284 | * a hard reset or power cycle | 284 | * a hard reset or power cycle |
285 | */ | 285 | */ |
286 | if (lp->cfg.flags & SMC91X_NOWAIT) | 286 | if (lp->cfg.flags & SMC91X_NOWAIT) |
287 | cfg |= CONFIG_NO_WAIT; | 287 | cfg |= CONFIG_NO_WAIT; |
288 | 288 | ||
289 | /* | 289 | /* |
290 | * Release from possible power-down state | 290 | * Release from possible power-down state |
291 | * Configuration register is not affected by Soft Reset | 291 | * Configuration register is not affected by Soft Reset |
292 | */ | 292 | */ |
293 | cfg |= CONFIG_EPH_POWER_EN; | 293 | cfg |= CONFIG_EPH_POWER_EN; |
294 | 294 | ||
295 | SMC_SET_CONFIG(lp, cfg); | 295 | SMC_SET_CONFIG(lp, cfg); |
296 | 296 | ||
297 | /* this should pause enough for the chip to be happy */ | 297 | /* this should pause enough for the chip to be happy */ |
298 | /* | 298 | /* |
299 | * elaborate? What does the chip _need_? --jgarzik | 299 | * elaborate? What does the chip _need_? --jgarzik |
300 | * | 300 | * |
301 | * This seems to be undocumented, but something the original | 301 | * This seems to be undocumented, but something the original |
302 | * driver(s) have always done. Suspect undocumented timing | 302 | * driver(s) have always done. Suspect undocumented timing |
303 | * info/determined empirically. --rmk | 303 | * info/determined empirically. --rmk |
304 | */ | 304 | */ |
305 | udelay(1); | 305 | udelay(1); |
306 | 306 | ||
307 | /* Disable transmit and receive functionality */ | 307 | /* Disable transmit and receive functionality */ |
308 | SMC_SELECT_BANK(lp, 0); | 308 | SMC_SELECT_BANK(lp, 0); |
309 | SMC_SET_RCR(lp, RCR_CLEAR); | 309 | SMC_SET_RCR(lp, RCR_CLEAR); |
310 | SMC_SET_TCR(lp, TCR_CLEAR); | 310 | SMC_SET_TCR(lp, TCR_CLEAR); |
311 | 311 | ||
312 | SMC_SELECT_BANK(lp, 1); | 312 | SMC_SELECT_BANK(lp, 1); |
313 | ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE; | 313 | ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE; |
314 | 314 | ||
315 | /* | 315 | /* |
316 | * Set the control register to automatically release successfully | 316 | * Set the control register to automatically release successfully |
317 | * transmitted packets, to make the best use out of our limited | 317 | * transmitted packets, to make the best use out of our limited |
318 | * memory | 318 | * memory |
319 | */ | 319 | */ |
320 | if(!THROTTLE_TX_PKTS) | 320 | if(!THROTTLE_TX_PKTS) |
321 | ctl |= CTL_AUTO_RELEASE; | 321 | ctl |= CTL_AUTO_RELEASE; |
322 | else | 322 | else |
323 | ctl &= ~CTL_AUTO_RELEASE; | 323 | ctl &= ~CTL_AUTO_RELEASE; |
324 | SMC_SET_CTL(lp, ctl); | 324 | SMC_SET_CTL(lp, ctl); |
325 | 325 | ||
326 | /* Reset the MMU */ | 326 | /* Reset the MMU */ |
327 | SMC_SELECT_BANK(lp, 2); | 327 | SMC_SELECT_BANK(lp, 2); |
328 | SMC_SET_MMU_CMD(lp, MC_RESET); | 328 | SMC_SET_MMU_CMD(lp, MC_RESET); |
329 | SMC_WAIT_MMU_BUSY(lp); | 329 | SMC_WAIT_MMU_BUSY(lp); |
330 | } | 330 | } |
331 | 331 | ||
332 | /* | 332 | /* |
333 | * Enable Interrupts, Receive, and Transmit | 333 | * Enable Interrupts, Receive, and Transmit |
334 | */ | 334 | */ |
335 | static void smc_enable(struct net_device *dev) | 335 | static void smc_enable(struct net_device *dev) |
336 | { | 336 | { |
337 | struct smc_local *lp = netdev_priv(dev); | 337 | struct smc_local *lp = netdev_priv(dev); |
338 | void __iomem *ioaddr = lp->base; | 338 | void __iomem *ioaddr = lp->base; |
339 | int mask; | 339 | int mask; |
340 | 340 | ||
341 | DBG(2, "%s: %s\n", dev->name, __func__); | 341 | DBG(2, "%s: %s\n", dev->name, __func__); |
342 | 342 | ||
343 | /* see the header file for options in TCR/RCR DEFAULT */ | 343 | /* see the header file for options in TCR/RCR DEFAULT */ |
344 | SMC_SELECT_BANK(lp, 0); | 344 | SMC_SELECT_BANK(lp, 0); |
345 | SMC_SET_TCR(lp, lp->tcr_cur_mode); | 345 | SMC_SET_TCR(lp, lp->tcr_cur_mode); |
346 | SMC_SET_RCR(lp, lp->rcr_cur_mode); | 346 | SMC_SET_RCR(lp, lp->rcr_cur_mode); |
347 | 347 | ||
348 | SMC_SELECT_BANK(lp, 1); | 348 | SMC_SELECT_BANK(lp, 1); |
349 | SMC_SET_MAC_ADDR(lp, dev->dev_addr); | 349 | SMC_SET_MAC_ADDR(lp, dev->dev_addr); |
350 | 350 | ||
351 | /* now, enable interrupts */ | 351 | /* now, enable interrupts */ |
352 | mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT; | 352 | mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT; |
353 | if (lp->version >= (CHIP_91100 << 4)) | 353 | if (lp->version >= (CHIP_91100 << 4)) |
354 | mask |= IM_MDINT; | 354 | mask |= IM_MDINT; |
355 | SMC_SELECT_BANK(lp, 2); | 355 | SMC_SELECT_BANK(lp, 2); |
356 | SMC_SET_INT_MASK(lp, mask); | 356 | SMC_SET_INT_MASK(lp, mask); |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * From this point the register bank must _NOT_ be switched away | 359 | * From this point the register bank must _NOT_ be switched away |
360 | * to something else than bank 2 without proper locking against | 360 | * to something else than bank 2 without proper locking against |
361 | * races with any tasklet or interrupt handlers until smc_shutdown() | 361 | * races with any tasklet or interrupt handlers until smc_shutdown() |
362 | * or smc_reset() is called. | 362 | * or smc_reset() is called. |
363 | */ | 363 | */ |
364 | } | 364 | } |
365 | 365 | ||
366 | /* | 366 | /* |
367 | * this puts the device in an inactive state | 367 | * this puts the device in an inactive state |
368 | */ | 368 | */ |
369 | static void smc_shutdown(struct net_device *dev) | 369 | static void smc_shutdown(struct net_device *dev) |
370 | { | 370 | { |
371 | struct smc_local *lp = netdev_priv(dev); | 371 | struct smc_local *lp = netdev_priv(dev); |
372 | void __iomem *ioaddr = lp->base; | 372 | void __iomem *ioaddr = lp->base; |
373 | struct sk_buff *pending_skb; | 373 | struct sk_buff *pending_skb; |
374 | 374 | ||
375 | DBG(2, "%s: %s\n", CARDNAME, __func__); | 375 | DBG(2, "%s: %s\n", CARDNAME, __func__); |
376 | 376 | ||
377 | /* no more interrupts for me */ | 377 | /* no more interrupts for me */ |
378 | spin_lock_irq(&lp->lock); | 378 | spin_lock_irq(&lp->lock); |
379 | SMC_SELECT_BANK(lp, 2); | 379 | SMC_SELECT_BANK(lp, 2); |
380 | SMC_SET_INT_MASK(lp, 0); | 380 | SMC_SET_INT_MASK(lp, 0); |
381 | pending_skb = lp->pending_tx_skb; | 381 | pending_skb = lp->pending_tx_skb; |
382 | lp->pending_tx_skb = NULL; | 382 | lp->pending_tx_skb = NULL; |
383 | spin_unlock_irq(&lp->lock); | 383 | spin_unlock_irq(&lp->lock); |
384 | if (pending_skb) | 384 | if (pending_skb) |
385 | dev_kfree_skb(pending_skb); | 385 | dev_kfree_skb(pending_skb); |
386 | 386 | ||
387 | /* and tell the card to stay away from that nasty outside world */ | 387 | /* and tell the card to stay away from that nasty outside world */ |
388 | SMC_SELECT_BANK(lp, 0); | 388 | SMC_SELECT_BANK(lp, 0); |
389 | SMC_SET_RCR(lp, RCR_CLEAR); | 389 | SMC_SET_RCR(lp, RCR_CLEAR); |
390 | SMC_SET_TCR(lp, TCR_CLEAR); | 390 | SMC_SET_TCR(lp, TCR_CLEAR); |
391 | 391 | ||
392 | #ifdef POWER_DOWN | 392 | #ifdef POWER_DOWN |
393 | /* finally, shut the chip down */ | 393 | /* finally, shut the chip down */ |
394 | SMC_SELECT_BANK(lp, 1); | 394 | SMC_SELECT_BANK(lp, 1); |
395 | SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN); | 395 | SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN); |
396 | #endif | 396 | #endif |
397 | } | 397 | } |
398 | 398 | ||
399 | /* | 399 | /* |
400 | * This is the procedure to handle the receipt of a packet. | 400 | * This is the procedure to handle the receipt of a packet. |
401 | */ | 401 | */ |
402 | static inline void smc_rcv(struct net_device *dev) | 402 | static inline void smc_rcv(struct net_device *dev) |
403 | { | 403 | { |
404 | struct smc_local *lp = netdev_priv(dev); | 404 | struct smc_local *lp = netdev_priv(dev); |
405 | void __iomem *ioaddr = lp->base; | 405 | void __iomem *ioaddr = lp->base; |
406 | unsigned int packet_number, status, packet_len; | 406 | unsigned int packet_number, status, packet_len; |
407 | 407 | ||
408 | DBG(3, "%s: %s\n", dev->name, __func__); | 408 | DBG(3, "%s: %s\n", dev->name, __func__); |
409 | 409 | ||
410 | packet_number = SMC_GET_RXFIFO(lp); | 410 | packet_number = SMC_GET_RXFIFO(lp); |
411 | if (unlikely(packet_number & RXFIFO_REMPTY)) { | 411 | if (unlikely(packet_number & RXFIFO_REMPTY)) { |
412 | PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name); | 412 | PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name); |
413 | return; | 413 | return; |
414 | } | 414 | } |
415 | 415 | ||
416 | /* read from start of packet */ | 416 | /* read from start of packet */ |
417 | SMC_SET_PTR(lp, PTR_READ | PTR_RCV | PTR_AUTOINC); | 417 | SMC_SET_PTR(lp, PTR_READ | PTR_RCV | PTR_AUTOINC); |
418 | 418 | ||
419 | /* First two words are status and packet length */ | 419 | /* First two words are status and packet length */ |
420 | SMC_GET_PKT_HDR(lp, status, packet_len); | 420 | SMC_GET_PKT_HDR(lp, status, packet_len); |
421 | packet_len &= 0x07ff; /* mask off top bits */ | 421 | packet_len &= 0x07ff; /* mask off top bits */ |
422 | DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", | 422 | DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", |
423 | dev->name, packet_number, status, | 423 | dev->name, packet_number, status, |
424 | packet_len, packet_len); | 424 | packet_len, packet_len); |
425 | 425 | ||
426 | back: | 426 | back: |
427 | if (unlikely(packet_len < 6 || status & RS_ERRORS)) { | 427 | if (unlikely(packet_len < 6 || status & RS_ERRORS)) { |
428 | if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) { | 428 | if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) { |
429 | /* accept VLAN packets */ | 429 | /* accept VLAN packets */ |
430 | status &= ~RS_TOOLONG; | 430 | status &= ~RS_TOOLONG; |
431 | goto back; | 431 | goto back; |
432 | } | 432 | } |
433 | if (packet_len < 6) { | 433 | if (packet_len < 6) { |
434 | /* bloody hardware */ | 434 | /* bloody hardware */ |
435 | printk(KERN_ERR "%s: fubar (rxlen %u status %x\n", | 435 | printk(KERN_ERR "%s: fubar (rxlen %u status %x\n", |
436 | dev->name, packet_len, status); | 436 | dev->name, packet_len, status); |
437 | status |= RS_TOOSHORT; | 437 | status |= RS_TOOSHORT; |
438 | } | 438 | } |
439 | SMC_WAIT_MMU_BUSY(lp); | 439 | SMC_WAIT_MMU_BUSY(lp); |
440 | SMC_SET_MMU_CMD(lp, MC_RELEASE); | 440 | SMC_SET_MMU_CMD(lp, MC_RELEASE); |
441 | dev->stats.rx_errors++; | 441 | dev->stats.rx_errors++; |
442 | if (status & RS_ALGNERR) | 442 | if (status & RS_ALGNERR) |
443 | dev->stats.rx_frame_errors++; | 443 | dev->stats.rx_frame_errors++; |
444 | if (status & (RS_TOOSHORT | RS_TOOLONG)) | 444 | if (status & (RS_TOOSHORT | RS_TOOLONG)) |
445 | dev->stats.rx_length_errors++; | 445 | dev->stats.rx_length_errors++; |
446 | if (status & RS_BADCRC) | 446 | if (status & RS_BADCRC) |
447 | dev->stats.rx_crc_errors++; | 447 | dev->stats.rx_crc_errors++; |
448 | } else { | 448 | } else { |
449 | struct sk_buff *skb; | 449 | struct sk_buff *skb; |
450 | unsigned char *data; | 450 | unsigned char *data; |
451 | unsigned int data_len; | 451 | unsigned int data_len; |
452 | 452 | ||
453 | /* set multicast stats */ | 453 | /* set multicast stats */ |
454 | if (status & RS_MULTICAST) | 454 | if (status & RS_MULTICAST) |
455 | dev->stats.multicast++; | 455 | dev->stats.multicast++; |
456 | 456 | ||
457 | /* | 457 | /* |
458 | * Actual payload is packet_len - 6 (or 5 if odd byte). | 458 | * Actual payload is packet_len - 6 (or 5 if odd byte). |
459 | * We want skb_reserve(2) and the final ctrl word | 459 | * We want skb_reserve(2) and the final ctrl word |
460 | * (2 bytes, possibly containing the payload odd byte). | 460 | * (2 bytes, possibly containing the payload odd byte). |
461 | * Furthermore, we add 2 bytes to allow rounding up to | 461 | * Furthermore, we add 2 bytes to allow rounding up to |
462 | * multiple of 4 bytes on 32 bit buses. | 462 | * multiple of 4 bytes on 32 bit buses. |
463 | * Hence packet_len - 6 + 2 + 2 + 2. | 463 | * Hence packet_len - 6 + 2 + 2 + 2. |
464 | */ | 464 | */ |
465 | skb = dev_alloc_skb(packet_len); | 465 | skb = dev_alloc_skb(packet_len); |
466 | if (unlikely(skb == NULL)) { | 466 | if (unlikely(skb == NULL)) { |
467 | printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", | 467 | printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", |
468 | dev->name); | 468 | dev->name); |
469 | SMC_WAIT_MMU_BUSY(lp); | 469 | SMC_WAIT_MMU_BUSY(lp); |
470 | SMC_SET_MMU_CMD(lp, MC_RELEASE); | 470 | SMC_SET_MMU_CMD(lp, MC_RELEASE); |
471 | dev->stats.rx_dropped++; | 471 | dev->stats.rx_dropped++; |
472 | return; | 472 | return; |
473 | } | 473 | } |
474 | 474 | ||
475 | /* Align IP header to 32 bits */ | 475 | /* Align IP header to 32 bits */ |
476 | skb_reserve(skb, 2); | 476 | skb_reserve(skb, 2); |
477 | 477 | ||
478 | /* BUG: the LAN91C111 rev A never sets this bit. Force it. */ | 478 | /* BUG: the LAN91C111 rev A never sets this bit. Force it. */ |
479 | if (lp->version == 0x90) | 479 | if (lp->version == 0x90) |
480 | status |= RS_ODDFRAME; | 480 | status |= RS_ODDFRAME; |
481 | 481 | ||
482 | /* | 482 | /* |
483 | * If odd length: packet_len - 5, | 483 | * If odd length: packet_len - 5, |
484 | * otherwise packet_len - 6. | 484 | * otherwise packet_len - 6. |
485 | * With the trailing ctrl byte it's packet_len - 4. | 485 | * With the trailing ctrl byte it's packet_len - 4. |
486 | */ | 486 | */ |
487 | data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6); | 487 | data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6); |
488 | data = skb_put(skb, data_len); | 488 | data = skb_put(skb, data_len); |
489 | SMC_PULL_DATA(lp, data, packet_len - 4); | 489 | SMC_PULL_DATA(lp, data, packet_len - 4); |
490 | 490 | ||
491 | SMC_WAIT_MMU_BUSY(lp); | 491 | SMC_WAIT_MMU_BUSY(lp); |
492 | SMC_SET_MMU_CMD(lp, MC_RELEASE); | 492 | SMC_SET_MMU_CMD(lp, MC_RELEASE); |
493 | 493 | ||
494 | PRINT_PKT(data, packet_len - 4); | 494 | PRINT_PKT(data, packet_len - 4); |
495 | 495 | ||
496 | skb->protocol = eth_type_trans(skb, dev); | 496 | skb->protocol = eth_type_trans(skb, dev); |
497 | netif_rx(skb); | 497 | netif_rx(skb); |
498 | dev->stats.rx_packets++; | 498 | dev->stats.rx_packets++; |
499 | dev->stats.rx_bytes += data_len; | 499 | dev->stats.rx_bytes += data_len; |
500 | } | 500 | } |
501 | } | 501 | } |
502 | 502 | ||
503 | #ifdef CONFIG_SMP | 503 | #ifdef CONFIG_SMP |
504 | /* | 504 | /* |
505 | * On SMP we have the following problem: | 505 | * On SMP we have the following problem: |
506 | * | 506 | * |
507 | * A = smc_hardware_send_pkt() | 507 | * A = smc_hardware_send_pkt() |
508 | * B = smc_hard_start_xmit() | 508 | * B = smc_hard_start_xmit() |
509 | * C = smc_interrupt() | 509 | * C = smc_interrupt() |
510 | * | 510 | * |
511 | * A and B can never be executed simultaneously. However, at least on UP, | 511 | * A and B can never be executed simultaneously. However, at least on UP, |
512 | * it is possible (and even desirable) for C to interrupt execution of | 512 | * it is possible (and even desirable) for C to interrupt execution of |
513 | * A or B in order to have better RX reliability and avoid overruns. | 513 | * A or B in order to have better RX reliability and avoid overruns. |
514 | * C, just like A and B, must have exclusive access to the chip and | 514 | * C, just like A and B, must have exclusive access to the chip and |
515 | * each of them must lock against any other concurrent access. | 515 | * each of them must lock against any other concurrent access. |
516 | * Unfortunately this is not possible to have C suspend execution of A or | 516 | * Unfortunately this is not possible to have C suspend execution of A or |
517 | * B taking place on another CPU. On UP this is no an issue since A and B | 517 | * B taking place on another CPU. On UP this is no an issue since A and B |
518 | * are run from softirq context and C from hard IRQ context, and there is | 518 | * are run from softirq context and C from hard IRQ context, and there is |
519 | * no other CPU where concurrent access can happen. | 519 | * no other CPU where concurrent access can happen. |
520 | * If ever there is a way to force at least B and C to always be executed | 520 | * If ever there is a way to force at least B and C to always be executed |
521 | * on the same CPU then we could use read/write locks to protect against | 521 | * on the same CPU then we could use read/write locks to protect against |
522 | * any other concurrent access and C would always interrupt B. But life | 522 | * any other concurrent access and C would always interrupt B. But life |
523 | * isn't that easy in a SMP world... | 523 | * isn't that easy in a SMP world... |
524 | */ | 524 | */ |
525 | #define smc_special_trylock(lock, flags) \ | 525 | #define smc_special_trylock(lock, flags) \ |
526 | ({ \ | 526 | ({ \ |
527 | int __ret; \ | 527 | int __ret; \ |
528 | local_irq_save(flags); \ | 528 | local_irq_save(flags); \ |
529 | __ret = spin_trylock(lock); \ | 529 | __ret = spin_trylock(lock); \ |
530 | if (!__ret) \ | 530 | if (!__ret) \ |
531 | local_irq_restore(flags); \ | 531 | local_irq_restore(flags); \ |
532 | __ret; \ | 532 | __ret; \ |
533 | }) | 533 | }) |
534 | #define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags) | 534 | #define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags) |
535 | #define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) | 535 | #define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) |
536 | #else | 536 | #else |
537 | #define smc_special_trylock(lock, flags) (1) | 537 | #define smc_special_trylock(lock, flags) (1) |
538 | #define smc_special_lock(lock, flags) do { } while (0) | 538 | #define smc_special_lock(lock, flags) do { } while (0) |
539 | #define smc_special_unlock(lock, flags) do { } while (0) | 539 | #define smc_special_unlock(lock, flags) do { } while (0) |
540 | #endif | 540 | #endif |
541 | 541 | ||
542 | /* | 542 | /* |
543 | * This is called to actually send a packet to the chip. | 543 | * This is called to actually send a packet to the chip. |
544 | */ | 544 | */ |
545 | static void smc_hardware_send_pkt(unsigned long data) | 545 | static void smc_hardware_send_pkt(unsigned long data) |
546 | { | 546 | { |
547 | struct net_device *dev = (struct net_device *)data; | 547 | struct net_device *dev = (struct net_device *)data; |
548 | struct smc_local *lp = netdev_priv(dev); | 548 | struct smc_local *lp = netdev_priv(dev); |
549 | void __iomem *ioaddr = lp->base; | 549 | void __iomem *ioaddr = lp->base; |
550 | struct sk_buff *skb; | 550 | struct sk_buff *skb; |
551 | unsigned int packet_no, len; | 551 | unsigned int packet_no, len; |
552 | unsigned char *buf; | 552 | unsigned char *buf; |
553 | unsigned long flags; | 553 | unsigned long flags; |
554 | 554 | ||
555 | DBG(3, "%s: %s\n", dev->name, __func__); | 555 | DBG(3, "%s: %s\n", dev->name, __func__); |
556 | 556 | ||
557 | if (!smc_special_trylock(&lp->lock, flags)) { | 557 | if (!smc_special_trylock(&lp->lock, flags)) { |
558 | netif_stop_queue(dev); | 558 | netif_stop_queue(dev); |
559 | tasklet_schedule(&lp->tx_task); | 559 | tasklet_schedule(&lp->tx_task); |
560 | return; | 560 | return; |
561 | } | 561 | } |
562 | 562 | ||
563 | skb = lp->pending_tx_skb; | 563 | skb = lp->pending_tx_skb; |
564 | if (unlikely(!skb)) { | 564 | if (unlikely(!skb)) { |
565 | smc_special_unlock(&lp->lock, flags); | 565 | smc_special_unlock(&lp->lock, flags); |
566 | return; | 566 | return; |
567 | } | 567 | } |
568 | lp->pending_tx_skb = NULL; | 568 | lp->pending_tx_skb = NULL; |
569 | 569 | ||
570 | packet_no = SMC_GET_AR(lp); | 570 | packet_no = SMC_GET_AR(lp); |
571 | if (unlikely(packet_no & AR_FAILED)) { | 571 | if (unlikely(packet_no & AR_FAILED)) { |
572 | printk("%s: Memory allocation failed.\n", dev->name); | 572 | printk("%s: Memory allocation failed.\n", dev->name); |
573 | dev->stats.tx_errors++; | 573 | dev->stats.tx_errors++; |
574 | dev->stats.tx_fifo_errors++; | 574 | dev->stats.tx_fifo_errors++; |
575 | smc_special_unlock(&lp->lock, flags); | 575 | smc_special_unlock(&lp->lock, flags); |
576 | goto done; | 576 | goto done; |
577 | } | 577 | } |
578 | 578 | ||
579 | /* point to the beginning of the packet */ | 579 | /* point to the beginning of the packet */ |
580 | SMC_SET_PN(lp, packet_no); | 580 | SMC_SET_PN(lp, packet_no); |
581 | SMC_SET_PTR(lp, PTR_AUTOINC); | 581 | SMC_SET_PTR(lp, PTR_AUTOINC); |
582 | 582 | ||
583 | buf = skb->data; | 583 | buf = skb->data; |
584 | len = skb->len; | 584 | len = skb->len; |
585 | DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", | 585 | DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", |
586 | dev->name, packet_no, len, len, buf); | 586 | dev->name, packet_no, len, len, buf); |
587 | PRINT_PKT(buf, len); | 587 | PRINT_PKT(buf, len); |
588 | 588 | ||
589 | /* | 589 | /* |
590 | * Send the packet length (+6 for status words, length, and ctl. | 590 | * Send the packet length (+6 for status words, length, and ctl. |
591 | * The card will pad to 64 bytes with zeroes if packet is too small. | 591 | * The card will pad to 64 bytes with zeroes if packet is too small. |
592 | */ | 592 | */ |
593 | SMC_PUT_PKT_HDR(lp, 0, len + 6); | 593 | SMC_PUT_PKT_HDR(lp, 0, len + 6); |
594 | 594 | ||
595 | /* send the actual data */ | 595 | /* send the actual data */ |
596 | SMC_PUSH_DATA(lp, buf, len & ~1); | 596 | SMC_PUSH_DATA(lp, buf, len & ~1); |
597 | 597 | ||
598 | /* Send final ctl word with the last byte if there is one */ | 598 | /* Send final ctl word with the last byte if there is one */ |
599 | SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp)); | 599 | SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp)); |
600 | 600 | ||
601 | /* | 601 | /* |
602 | * If THROTTLE_TX_PKTS is set, we stop the queue here. This will | 602 | * If THROTTLE_TX_PKTS is set, we stop the queue here. This will |
603 | * have the effect of having at most one packet queued for TX | 603 | * have the effect of having at most one packet queued for TX |
604 | * in the chip's memory at all time. | 604 | * in the chip's memory at all time. |
605 | * | 605 | * |
606 | * If THROTTLE_TX_PKTS is not set then the queue is stopped only | 606 | * If THROTTLE_TX_PKTS is not set then the queue is stopped only |
607 | * when memory allocation (MC_ALLOC) does not succeed right away. | 607 | * when memory allocation (MC_ALLOC) does not succeed right away. |
608 | */ | 608 | */ |
609 | if (THROTTLE_TX_PKTS) | 609 | if (THROTTLE_TX_PKTS) |
610 | netif_stop_queue(dev); | 610 | netif_stop_queue(dev); |
611 | 611 | ||
612 | /* queue the packet for TX */ | 612 | /* queue the packet for TX */ |
613 | SMC_SET_MMU_CMD(lp, MC_ENQUEUE); | 613 | SMC_SET_MMU_CMD(lp, MC_ENQUEUE); |
614 | smc_special_unlock(&lp->lock, flags); | 614 | smc_special_unlock(&lp->lock, flags); |
615 | 615 | ||
616 | dev->trans_start = jiffies; | 616 | dev->trans_start = jiffies; |
617 | dev->stats.tx_packets++; | 617 | dev->stats.tx_packets++; |
618 | dev->stats.tx_bytes += len; | 618 | dev->stats.tx_bytes += len; |
619 | 619 | ||
620 | SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT); | 620 | SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT); |
621 | 621 | ||
622 | done: if (!THROTTLE_TX_PKTS) | 622 | done: if (!THROTTLE_TX_PKTS) |
623 | netif_wake_queue(dev); | 623 | netif_wake_queue(dev); |
624 | 624 | ||
625 | dev_kfree_skb(skb); | 625 | dev_kfree_skb(skb); |
626 | } | 626 | } |
627 | 627 | ||
628 | /* | 628 | /* |
629 | * Since I am not sure if I will have enough room in the chip's ram | 629 | * Since I am not sure if I will have enough room in the chip's ram |
630 | * to store the packet, I call this routine which either sends it | 630 | * to store the packet, I call this routine which either sends it |
631 | * now, or set the card to generates an interrupt when ready | 631 | * now, or set the card to generates an interrupt when ready |
632 | * for the packet. | 632 | * for the packet. |
633 | */ | 633 | */ |
634 | static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 634 | static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) |
635 | { | 635 | { |
636 | struct smc_local *lp = netdev_priv(dev); | 636 | struct smc_local *lp = netdev_priv(dev); |
637 | void __iomem *ioaddr = lp->base; | 637 | void __iomem *ioaddr = lp->base; |
638 | unsigned int numPages, poll_count, status; | 638 | unsigned int numPages, poll_count, status; |
639 | unsigned long flags; | 639 | unsigned long flags; |
640 | 640 | ||
641 | DBG(3, "%s: %s\n", dev->name, __func__); | 641 | DBG(3, "%s: %s\n", dev->name, __func__); |
642 | 642 | ||
643 | BUG_ON(lp->pending_tx_skb != NULL); | 643 | BUG_ON(lp->pending_tx_skb != NULL); |
644 | 644 | ||
645 | /* | 645 | /* |
646 | * The MMU wants the number of pages to be the number of 256 bytes | 646 | * The MMU wants the number of pages to be the number of 256 bytes |
647 | * 'pages', minus 1 (since a packet can't ever have 0 pages :)) | 647 | * 'pages', minus 1 (since a packet can't ever have 0 pages :)) |
648 | * | 648 | * |
649 | * The 91C111 ignores the size bits, but earlier models don't. | 649 | * The 91C111 ignores the size bits, but earlier models don't. |
650 | * | 650 | * |
651 | * Pkt size for allocating is data length +6 (for additional status | 651 | * Pkt size for allocating is data length +6 (for additional status |
652 | * words, length and ctl) | 652 | * words, length and ctl) |
653 | * | 653 | * |
654 | * If odd size then last byte is included in ctl word. | 654 | * If odd size then last byte is included in ctl word. |
655 | */ | 655 | */ |
656 | numPages = ((skb->len & ~1) + (6 - 1)) >> 8; | 656 | numPages = ((skb->len & ~1) + (6 - 1)) >> 8; |
657 | if (unlikely(numPages > 7)) { | 657 | if (unlikely(numPages > 7)) { |
658 | printk("%s: Far too big packet error.\n", dev->name); | 658 | printk("%s: Far too big packet error.\n", dev->name); |
659 | dev->stats.tx_errors++; | 659 | dev->stats.tx_errors++; |
660 | dev->stats.tx_dropped++; | 660 | dev->stats.tx_dropped++; |
661 | dev_kfree_skb(skb); | 661 | dev_kfree_skb(skb); |
662 | return NETDEV_TX_OK; | 662 | return NETDEV_TX_OK; |
663 | } | 663 | } |
664 | 664 | ||
665 | smc_special_lock(&lp->lock, flags); | 665 | smc_special_lock(&lp->lock, flags); |
666 | 666 | ||
667 | /* now, try to allocate the memory */ | 667 | /* now, try to allocate the memory */ |
668 | SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages); | 668 | SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages); |
669 | 669 | ||
670 | /* | 670 | /* |
671 | * Poll the chip for a short amount of time in case the | 671 | * Poll the chip for a short amount of time in case the |
672 | * allocation succeeds quickly. | 672 | * allocation succeeds quickly. |
673 | */ | 673 | */ |
674 | poll_count = MEMORY_WAIT_TIME; | 674 | poll_count = MEMORY_WAIT_TIME; |
675 | do { | 675 | do { |
676 | status = SMC_GET_INT(lp); | 676 | status = SMC_GET_INT(lp); |
677 | if (status & IM_ALLOC_INT) { | 677 | if (status & IM_ALLOC_INT) { |
678 | SMC_ACK_INT(lp, IM_ALLOC_INT); | 678 | SMC_ACK_INT(lp, IM_ALLOC_INT); |
679 | break; | 679 | break; |
680 | } | 680 | } |
681 | } while (--poll_count); | 681 | } while (--poll_count); |
682 | 682 | ||
683 | smc_special_unlock(&lp->lock, flags); | 683 | smc_special_unlock(&lp->lock, flags); |
684 | 684 | ||
685 | lp->pending_tx_skb = skb; | 685 | lp->pending_tx_skb = skb; |
686 | if (!poll_count) { | 686 | if (!poll_count) { |
687 | /* oh well, wait until the chip finds memory later */ | 687 | /* oh well, wait until the chip finds memory later */ |
688 | netif_stop_queue(dev); | 688 | netif_stop_queue(dev); |
689 | DBG(2, "%s: TX memory allocation deferred.\n", dev->name); | 689 | DBG(2, "%s: TX memory allocation deferred.\n", dev->name); |
690 | SMC_ENABLE_INT(lp, IM_ALLOC_INT); | 690 | SMC_ENABLE_INT(lp, IM_ALLOC_INT); |
691 | } else { | 691 | } else { |
692 | /* | 692 | /* |
693 | * Allocation succeeded: push packet to the chip's own memory | 693 | * Allocation succeeded: push packet to the chip's own memory |
694 | * immediately. | 694 | * immediately. |
695 | */ | 695 | */ |
696 | smc_hardware_send_pkt((unsigned long)dev); | 696 | smc_hardware_send_pkt((unsigned long)dev); |
697 | } | 697 | } |
698 | 698 | ||
699 | return NETDEV_TX_OK; | 699 | return NETDEV_TX_OK; |
700 | } | 700 | } |
701 | 701 | ||
702 | /* | 702 | /* |
703 | * This handles a TX interrupt, which is only called when: | 703 | * This handles a TX interrupt, which is only called when: |
704 | * - a TX error occurred, or | 704 | * - a TX error occurred, or |
705 | * - CTL_AUTO_RELEASE is not set and TX of a packet completed. | 705 | * - CTL_AUTO_RELEASE is not set and TX of a packet completed. |
706 | */ | 706 | */ |
707 | static void smc_tx(struct net_device *dev) | 707 | static void smc_tx(struct net_device *dev) |
708 | { | 708 | { |
709 | struct smc_local *lp = netdev_priv(dev); | 709 | struct smc_local *lp = netdev_priv(dev); |
710 | void __iomem *ioaddr = lp->base; | 710 | void __iomem *ioaddr = lp->base; |
711 | unsigned int saved_packet, packet_no, tx_status, pkt_len; | 711 | unsigned int saved_packet, packet_no, tx_status, pkt_len; |
712 | 712 | ||
713 | DBG(3, "%s: %s\n", dev->name, __func__); | 713 | DBG(3, "%s: %s\n", dev->name, __func__); |
714 | 714 | ||
715 | /* If the TX FIFO is empty then nothing to do */ | 715 | /* If the TX FIFO is empty then nothing to do */ |
716 | packet_no = SMC_GET_TXFIFO(lp); | 716 | packet_no = SMC_GET_TXFIFO(lp); |
717 | if (unlikely(packet_no & TXFIFO_TEMPTY)) { | 717 | if (unlikely(packet_no & TXFIFO_TEMPTY)) { |
718 | PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); | 718 | PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); |
719 | return; | 719 | return; |
720 | } | 720 | } |
721 | 721 | ||
722 | /* select packet to read from */ | 722 | /* select packet to read from */ |
723 | saved_packet = SMC_GET_PN(lp); | 723 | saved_packet = SMC_GET_PN(lp); |
724 | SMC_SET_PN(lp, packet_no); | 724 | SMC_SET_PN(lp, packet_no); |
725 | 725 | ||
726 | /* read the first word (status word) from this packet */ | 726 | /* read the first word (status word) from this packet */ |
727 | SMC_SET_PTR(lp, PTR_AUTOINC | PTR_READ); | 727 | SMC_SET_PTR(lp, PTR_AUTOINC | PTR_READ); |
728 | SMC_GET_PKT_HDR(lp, tx_status, pkt_len); | 728 | SMC_GET_PKT_HDR(lp, tx_status, pkt_len); |
729 | DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n", | 729 | DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n", |
730 | dev->name, tx_status, packet_no); | 730 | dev->name, tx_status, packet_no); |
731 | 731 | ||
732 | if (!(tx_status & ES_TX_SUC)) | 732 | if (!(tx_status & ES_TX_SUC)) |
733 | dev->stats.tx_errors++; | 733 | dev->stats.tx_errors++; |
734 | 734 | ||
735 | if (tx_status & ES_LOSTCARR) | 735 | if (tx_status & ES_LOSTCARR) |
736 | dev->stats.tx_carrier_errors++; | 736 | dev->stats.tx_carrier_errors++; |
737 | 737 | ||
738 | if (tx_status & (ES_LATCOL | ES_16COL)) { | 738 | if (tx_status & (ES_LATCOL | ES_16COL)) { |
739 | PRINTK("%s: %s occurred on last xmit\n", dev->name, | 739 | PRINTK("%s: %s occurred on last xmit\n", dev->name, |
740 | (tx_status & ES_LATCOL) ? | 740 | (tx_status & ES_LATCOL) ? |
741 | "late collision" : "too many collisions"); | 741 | "late collision" : "too many collisions"); |
742 | dev->stats.tx_window_errors++; | 742 | dev->stats.tx_window_errors++; |
743 | if (!(dev->stats.tx_window_errors & 63) && net_ratelimit()) { | 743 | if (!(dev->stats.tx_window_errors & 63) && net_ratelimit()) { |
744 | printk(KERN_INFO "%s: unexpectedly large number of " | 744 | printk(KERN_INFO "%s: unexpectedly large number of " |
745 | "bad collisions. Please check duplex " | 745 | "bad collisions. Please check duplex " |
746 | "setting.\n", dev->name); | 746 | "setting.\n", dev->name); |
747 | } | 747 | } |
748 | } | 748 | } |
749 | 749 | ||
750 | /* kill the packet */ | 750 | /* kill the packet */ |
751 | SMC_WAIT_MMU_BUSY(lp); | 751 | SMC_WAIT_MMU_BUSY(lp); |
752 | SMC_SET_MMU_CMD(lp, MC_FREEPKT); | 752 | SMC_SET_MMU_CMD(lp, MC_FREEPKT); |
753 | 753 | ||
754 | /* Don't restore Packet Number Reg until busy bit is cleared */ | 754 | /* Don't restore Packet Number Reg until busy bit is cleared */ |
755 | SMC_WAIT_MMU_BUSY(lp); | 755 | SMC_WAIT_MMU_BUSY(lp); |
756 | SMC_SET_PN(lp, saved_packet); | 756 | SMC_SET_PN(lp, saved_packet); |
757 | 757 | ||
758 | /* re-enable transmit */ | 758 | /* re-enable transmit */ |
759 | SMC_SELECT_BANK(lp, 0); | 759 | SMC_SELECT_BANK(lp, 0); |
760 | SMC_SET_TCR(lp, lp->tcr_cur_mode); | 760 | SMC_SET_TCR(lp, lp->tcr_cur_mode); |
761 | SMC_SELECT_BANK(lp, 2); | 761 | SMC_SELECT_BANK(lp, 2); |
762 | } | 762 | } |
763 | 763 | ||
764 | 764 | ||
765 | /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ | 765 | /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ |
766 | 766 | ||
767 | static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) | 767 | static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) |
768 | { | 768 | { |
769 | struct smc_local *lp = netdev_priv(dev); | 769 | struct smc_local *lp = netdev_priv(dev); |
770 | void __iomem *ioaddr = lp->base; | 770 | void __iomem *ioaddr = lp->base; |
771 | unsigned int mii_reg, mask; | 771 | unsigned int mii_reg, mask; |
772 | 772 | ||
773 | mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO); | 773 | mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO); |
774 | mii_reg |= MII_MDOE; | 774 | mii_reg |= MII_MDOE; |
775 | 775 | ||
776 | for (mask = 1 << (bits - 1); mask; mask >>= 1) { | 776 | for (mask = 1 << (bits - 1); mask; mask >>= 1) { |
777 | if (val & mask) | 777 | if (val & mask) |
778 | mii_reg |= MII_MDO; | 778 | mii_reg |= MII_MDO; |
779 | else | 779 | else |
780 | mii_reg &= ~MII_MDO; | 780 | mii_reg &= ~MII_MDO; |
781 | 781 | ||
782 | SMC_SET_MII(lp, mii_reg); | 782 | SMC_SET_MII(lp, mii_reg); |
783 | udelay(MII_DELAY); | 783 | udelay(MII_DELAY); |
784 | SMC_SET_MII(lp, mii_reg | MII_MCLK); | 784 | SMC_SET_MII(lp, mii_reg | MII_MCLK); |
785 | udelay(MII_DELAY); | 785 | udelay(MII_DELAY); |
786 | } | 786 | } |
787 | } | 787 | } |
788 | 788 | ||
789 | static unsigned int smc_mii_in(struct net_device *dev, int bits) | 789 | static unsigned int smc_mii_in(struct net_device *dev, int bits) |
790 | { | 790 | { |
791 | struct smc_local *lp = netdev_priv(dev); | 791 | struct smc_local *lp = netdev_priv(dev); |
792 | void __iomem *ioaddr = lp->base; | 792 | void __iomem *ioaddr = lp->base; |
793 | unsigned int mii_reg, mask, val; | 793 | unsigned int mii_reg, mask, val; |
794 | 794 | ||
795 | mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO); | 795 | mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO); |
796 | SMC_SET_MII(lp, mii_reg); | 796 | SMC_SET_MII(lp, mii_reg); |
797 | 797 | ||
798 | for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) { | 798 | for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) { |
799 | if (SMC_GET_MII(lp) & MII_MDI) | 799 | if (SMC_GET_MII(lp) & MII_MDI) |
800 | val |= mask; | 800 | val |= mask; |
801 | 801 | ||
802 | SMC_SET_MII(lp, mii_reg); | 802 | SMC_SET_MII(lp, mii_reg); |
803 | udelay(MII_DELAY); | 803 | udelay(MII_DELAY); |
804 | SMC_SET_MII(lp, mii_reg | MII_MCLK); | 804 | SMC_SET_MII(lp, mii_reg | MII_MCLK); |
805 | udelay(MII_DELAY); | 805 | udelay(MII_DELAY); |
806 | } | 806 | } |
807 | 807 | ||
808 | return val; | 808 | return val; |
809 | } | 809 | } |
810 | 810 | ||
811 | /* | 811 | /* |
812 | * Reads a register from the MII Management serial interface | 812 | * Reads a register from the MII Management serial interface |
813 | */ | 813 | */ |
814 | static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg) | 814 | static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg) |
815 | { | 815 | { |
816 | struct smc_local *lp = netdev_priv(dev); | 816 | struct smc_local *lp = netdev_priv(dev); |
817 | void __iomem *ioaddr = lp->base; | 817 | void __iomem *ioaddr = lp->base; |
818 | unsigned int phydata; | 818 | unsigned int phydata; |
819 | 819 | ||
820 | SMC_SELECT_BANK(lp, 3); | 820 | SMC_SELECT_BANK(lp, 3); |
821 | 821 | ||
822 | /* Idle - 32 ones */ | 822 | /* Idle - 32 ones */ |
823 | smc_mii_out(dev, 0xffffffff, 32); | 823 | smc_mii_out(dev, 0xffffffff, 32); |
824 | 824 | ||
825 | /* Start code (01) + read (10) + phyaddr + phyreg */ | 825 | /* Start code (01) + read (10) + phyaddr + phyreg */ |
826 | smc_mii_out(dev, 6 << 10 | phyaddr << 5 | phyreg, 14); | 826 | smc_mii_out(dev, 6 << 10 | phyaddr << 5 | phyreg, 14); |
827 | 827 | ||
828 | /* Turnaround (2bits) + phydata */ | 828 | /* Turnaround (2bits) + phydata */ |
829 | phydata = smc_mii_in(dev, 18); | 829 | phydata = smc_mii_in(dev, 18); |
830 | 830 | ||
831 | /* Return to idle state */ | 831 | /* Return to idle state */ |
832 | SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); | 832 | SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); |
833 | 833 | ||
834 | DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", | 834 | DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", |
835 | __func__, phyaddr, phyreg, phydata); | 835 | __func__, phyaddr, phyreg, phydata); |
836 | 836 | ||
837 | SMC_SELECT_BANK(lp, 2); | 837 | SMC_SELECT_BANK(lp, 2); |
838 | return phydata; | 838 | return phydata; |
839 | } | 839 | } |
840 | 840 | ||
841 | /* | 841 | /* |
842 | * Writes a register to the MII Management serial interface | 842 | * Writes a register to the MII Management serial interface |
843 | */ | 843 | */ |
844 | static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg, | 844 | static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg, |
845 | int phydata) | 845 | int phydata) |
846 | { | 846 | { |
847 | struct smc_local *lp = netdev_priv(dev); | 847 | struct smc_local *lp = netdev_priv(dev); |
848 | void __iomem *ioaddr = lp->base; | 848 | void __iomem *ioaddr = lp->base; |
849 | 849 | ||
850 | SMC_SELECT_BANK(lp, 3); | 850 | SMC_SELECT_BANK(lp, 3); |
851 | 851 | ||
852 | /* Idle - 32 ones */ | 852 | /* Idle - 32 ones */ |
853 | smc_mii_out(dev, 0xffffffff, 32); | 853 | smc_mii_out(dev, 0xffffffff, 32); |
854 | 854 | ||
855 | /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */ | 855 | /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */ |
856 | smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32); | 856 | smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32); |
857 | 857 | ||
858 | /* Return to idle state */ | 858 | /* Return to idle state */ |
859 | SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); | 859 | SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); |
860 | 860 | ||
861 | DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", | 861 | DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", |
862 | __func__, phyaddr, phyreg, phydata); | 862 | __func__, phyaddr, phyreg, phydata); |
863 | 863 | ||
864 | SMC_SELECT_BANK(lp, 2); | 864 | SMC_SELECT_BANK(lp, 2); |
865 | } | 865 | } |
866 | 866 | ||
867 | /* | 867 | /* |
868 | * Finds and reports the PHY address | 868 | * Finds and reports the PHY address |
869 | */ | 869 | */ |
870 | static void smc_phy_detect(struct net_device *dev) | 870 | static void smc_phy_detect(struct net_device *dev) |
871 | { | 871 | { |
872 | struct smc_local *lp = netdev_priv(dev); | 872 | struct smc_local *lp = netdev_priv(dev); |
873 | int phyaddr; | 873 | int phyaddr; |
874 | 874 | ||
875 | DBG(2, "%s: %s\n", dev->name, __func__); | 875 | DBG(2, "%s: %s\n", dev->name, __func__); |
876 | 876 | ||
877 | lp->phy_type = 0; | 877 | lp->phy_type = 0; |
878 | 878 | ||
879 | /* | 879 | /* |
880 | * Scan all 32 PHY addresses if necessary, starting at | 880 | * Scan all 32 PHY addresses if necessary, starting at |
881 | * PHY#1 to PHY#31, and then PHY#0 last. | 881 | * PHY#1 to PHY#31, and then PHY#0 last. |
882 | */ | 882 | */ |
883 | for (phyaddr = 1; phyaddr < 33; ++phyaddr) { | 883 | for (phyaddr = 1; phyaddr < 33; ++phyaddr) { |
884 | unsigned int id1, id2; | 884 | unsigned int id1, id2; |
885 | 885 | ||
886 | /* Read the PHY identifiers */ | 886 | /* Read the PHY identifiers */ |
887 | id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1); | 887 | id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1); |
888 | id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2); | 888 | id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2); |
889 | 889 | ||
890 | DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", | 890 | DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", |
891 | dev->name, id1, id2); | 891 | dev->name, id1, id2); |
892 | 892 | ||
893 | /* Make sure it is a valid identifier */ | 893 | /* Make sure it is a valid identifier */ |
894 | if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 && | 894 | if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 && |
895 | id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) { | 895 | id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) { |
896 | /* Save the PHY's address */ | 896 | /* Save the PHY's address */ |
897 | lp->mii.phy_id = phyaddr & 31; | 897 | lp->mii.phy_id = phyaddr & 31; |
898 | lp->phy_type = id1 << 16 | id2; | 898 | lp->phy_type = id1 << 16 | id2; |
899 | break; | 899 | break; |
900 | } | 900 | } |
901 | } | 901 | } |
902 | } | 902 | } |
903 | 903 | ||
904 | /* | 904 | /* |
905 | * Sets the PHY to a configuration as determined by the user | 905 | * Sets the PHY to a configuration as determined by the user |
906 | */ | 906 | */ |
907 | static int smc_phy_fixed(struct net_device *dev) | 907 | static int smc_phy_fixed(struct net_device *dev) |
908 | { | 908 | { |
909 | struct smc_local *lp = netdev_priv(dev); | 909 | struct smc_local *lp = netdev_priv(dev); |
910 | void __iomem *ioaddr = lp->base; | 910 | void __iomem *ioaddr = lp->base; |
911 | int phyaddr = lp->mii.phy_id; | 911 | int phyaddr = lp->mii.phy_id; |
912 | int bmcr, cfg1; | 912 | int bmcr, cfg1; |
913 | 913 | ||
914 | DBG(3, "%s: %s\n", dev->name, __func__); | 914 | DBG(3, "%s: %s\n", dev->name, __func__); |
915 | 915 | ||
916 | /* Enter Link Disable state */ | 916 | /* Enter Link Disable state */ |
917 | cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG); | 917 | cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG); |
918 | cfg1 |= PHY_CFG1_LNKDIS; | 918 | cfg1 |= PHY_CFG1_LNKDIS; |
919 | smc_phy_write(dev, phyaddr, PHY_CFG1_REG, cfg1); | 919 | smc_phy_write(dev, phyaddr, PHY_CFG1_REG, cfg1); |
920 | 920 | ||
921 | /* | 921 | /* |
922 | * Set our fixed capabilities | 922 | * Set our fixed capabilities |
923 | * Disable auto-negotiation | 923 | * Disable auto-negotiation |
924 | */ | 924 | */ |
925 | bmcr = 0; | 925 | bmcr = 0; |
926 | 926 | ||
927 | if (lp->ctl_rfduplx) | 927 | if (lp->ctl_rfduplx) |
928 | bmcr |= BMCR_FULLDPLX; | 928 | bmcr |= BMCR_FULLDPLX; |
929 | 929 | ||
930 | if (lp->ctl_rspeed == 100) | 930 | if (lp->ctl_rspeed == 100) |
931 | bmcr |= BMCR_SPEED100; | 931 | bmcr |= BMCR_SPEED100; |
932 | 932 | ||
933 | /* Write our capabilities to the phy control register */ | 933 | /* Write our capabilities to the phy control register */ |
934 | smc_phy_write(dev, phyaddr, MII_BMCR, bmcr); | 934 | smc_phy_write(dev, phyaddr, MII_BMCR, bmcr); |
935 | 935 | ||
936 | /* Re-Configure the Receive/Phy Control register */ | 936 | /* Re-Configure the Receive/Phy Control register */ |
937 | SMC_SELECT_BANK(lp, 0); | 937 | SMC_SELECT_BANK(lp, 0); |
938 | SMC_SET_RPC(lp, lp->rpc_cur_mode); | 938 | SMC_SET_RPC(lp, lp->rpc_cur_mode); |
939 | SMC_SELECT_BANK(lp, 2); | 939 | SMC_SELECT_BANK(lp, 2); |
940 | 940 | ||
941 | return 1; | 941 | return 1; |
942 | } | 942 | } |
943 | 943 | ||
944 | /* | 944 | /* |
945 | * smc_phy_reset - reset the phy | 945 | * smc_phy_reset - reset the phy |
946 | * @dev: net device | 946 | * @dev: net device |
947 | * @phy: phy address | 947 | * @phy: phy address |
948 | * | 948 | * |
949 | * Issue a software reset for the specified PHY and | 949 | * Issue a software reset for the specified PHY and |
950 | * wait up to 100ms for the reset to complete. We should | 950 | * wait up to 100ms for the reset to complete. We should |
951 | * not access the PHY for 50ms after issuing the reset. | 951 | * not access the PHY for 50ms after issuing the reset. |
952 | * | 952 | * |
953 | * The time to wait appears to be dependent on the PHY. | 953 | * The time to wait appears to be dependent on the PHY. |
954 | * | 954 | * |
955 | * Must be called with lp->lock locked. | 955 | * Must be called with lp->lock locked. |
956 | */ | 956 | */ |
957 | static int smc_phy_reset(struct net_device *dev, int phy) | 957 | static int smc_phy_reset(struct net_device *dev, int phy) |
958 | { | 958 | { |
959 | struct smc_local *lp = netdev_priv(dev); | 959 | struct smc_local *lp = netdev_priv(dev); |
960 | unsigned int bmcr; | 960 | unsigned int bmcr; |
961 | int timeout; | 961 | int timeout; |
962 | 962 | ||
963 | smc_phy_write(dev, phy, MII_BMCR, BMCR_RESET); | 963 | smc_phy_write(dev, phy, MII_BMCR, BMCR_RESET); |
964 | 964 | ||
965 | for (timeout = 2; timeout; timeout--) { | 965 | for (timeout = 2; timeout; timeout--) { |
966 | spin_unlock_irq(&lp->lock); | 966 | spin_unlock_irq(&lp->lock); |
967 | msleep(50); | 967 | msleep(50); |
968 | spin_lock_irq(&lp->lock); | 968 | spin_lock_irq(&lp->lock); |
969 | 969 | ||
970 | bmcr = smc_phy_read(dev, phy, MII_BMCR); | 970 | bmcr = smc_phy_read(dev, phy, MII_BMCR); |
971 | if (!(bmcr & BMCR_RESET)) | 971 | if (!(bmcr & BMCR_RESET)) |
972 | break; | 972 | break; |
973 | } | 973 | } |
974 | 974 | ||
975 | return bmcr & BMCR_RESET; | 975 | return bmcr & BMCR_RESET; |
976 | } | 976 | } |
977 | 977 | ||
978 | /* | 978 | /* |
979 | * smc_phy_powerdown - powerdown phy | 979 | * smc_phy_powerdown - powerdown phy |
980 | * @dev: net device | 980 | * @dev: net device |
981 | * | 981 | * |
982 | * Power down the specified PHY | 982 | * Power down the specified PHY |
983 | */ | 983 | */ |
984 | static void smc_phy_powerdown(struct net_device *dev) | 984 | static void smc_phy_powerdown(struct net_device *dev) |
985 | { | 985 | { |
986 | struct smc_local *lp = netdev_priv(dev); | 986 | struct smc_local *lp = netdev_priv(dev); |
987 | unsigned int bmcr; | 987 | unsigned int bmcr; |
988 | int phy = lp->mii.phy_id; | 988 | int phy = lp->mii.phy_id; |
989 | 989 | ||
990 | if (lp->phy_type == 0) | 990 | if (lp->phy_type == 0) |
991 | return; | 991 | return; |
992 | 992 | ||
993 | /* We need to ensure that no calls to smc_phy_configure are | 993 | /* We need to ensure that no calls to smc_phy_configure are |
994 | pending. | 994 | pending. |
995 | */ | 995 | */ |
996 | cancel_work_sync(&lp->phy_configure); | 996 | cancel_work_sync(&lp->phy_configure); |
997 | 997 | ||
998 | bmcr = smc_phy_read(dev, phy, MII_BMCR); | 998 | bmcr = smc_phy_read(dev, phy, MII_BMCR); |
999 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); | 999 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); |
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | /* | 1002 | /* |
1003 | * smc_phy_check_media - check the media status and adjust TCR | 1003 | * smc_phy_check_media - check the media status and adjust TCR |
1004 | * @dev: net device | 1004 | * @dev: net device |
1005 | * @init: set true for initialisation | 1005 | * @init: set true for initialisation |
1006 | * | 1006 | * |
1007 | * Select duplex mode depending on negotiation state. This | 1007 | * Select duplex mode depending on negotiation state. This |
1008 | * also updates our carrier state. | 1008 | * also updates our carrier state. |
1009 | */ | 1009 | */ |
1010 | static void smc_phy_check_media(struct net_device *dev, int init) | 1010 | static void smc_phy_check_media(struct net_device *dev, int init) |
1011 | { | 1011 | { |
1012 | struct smc_local *lp = netdev_priv(dev); | 1012 | struct smc_local *lp = netdev_priv(dev); |
1013 | void __iomem *ioaddr = lp->base; | 1013 | void __iomem *ioaddr = lp->base; |
1014 | 1014 | ||
1015 | if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { | 1015 | if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { |
1016 | /* duplex state has changed */ | 1016 | /* duplex state has changed */ |
1017 | if (lp->mii.full_duplex) { | 1017 | if (lp->mii.full_duplex) { |
1018 | lp->tcr_cur_mode |= TCR_SWFDUP; | 1018 | lp->tcr_cur_mode |= TCR_SWFDUP; |
1019 | } else { | 1019 | } else { |
1020 | lp->tcr_cur_mode &= ~TCR_SWFDUP; | 1020 | lp->tcr_cur_mode &= ~TCR_SWFDUP; |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | SMC_SELECT_BANK(lp, 0); | 1023 | SMC_SELECT_BANK(lp, 0); |
1024 | SMC_SET_TCR(lp, lp->tcr_cur_mode); | 1024 | SMC_SET_TCR(lp, lp->tcr_cur_mode); |
1025 | } | 1025 | } |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | /* | 1028 | /* |
1029 | * Configures the specified PHY through the MII management interface | 1029 | * Configures the specified PHY through the MII management interface |
1030 | * using Autonegotiation. | 1030 | * using Autonegotiation. |
1031 | * Calls smc_phy_fixed() if the user has requested a certain config. | 1031 | * Calls smc_phy_fixed() if the user has requested a certain config. |
1032 | * If RPC ANEG bit is set, the media selection is dependent purely on | 1032 | * If RPC ANEG bit is set, the media selection is dependent purely on |
1033 | * the selection by the MII (either in the MII BMCR reg or the result | 1033 | * the selection by the MII (either in the MII BMCR reg or the result |
1034 | * of autonegotiation.) If the RPC ANEG bit is cleared, the selection | 1034 | * of autonegotiation.) If the RPC ANEG bit is cleared, the selection |
1035 | * is controlled by the RPC SPEED and RPC DPLX bits. | 1035 | * is controlled by the RPC SPEED and RPC DPLX bits. |
1036 | */ | 1036 | */ |
1037 | static void smc_phy_configure(struct work_struct *work) | 1037 | static void smc_phy_configure(struct work_struct *work) |
1038 | { | 1038 | { |
1039 | struct smc_local *lp = | 1039 | struct smc_local *lp = |
1040 | container_of(work, struct smc_local, phy_configure); | 1040 | container_of(work, struct smc_local, phy_configure); |
1041 | struct net_device *dev = lp->dev; | 1041 | struct net_device *dev = lp->dev; |
1042 | void __iomem *ioaddr = lp->base; | 1042 | void __iomem *ioaddr = lp->base; |
1043 | int phyaddr = lp->mii.phy_id; | 1043 | int phyaddr = lp->mii.phy_id; |
1044 | int my_phy_caps; /* My PHY capabilities */ | 1044 | int my_phy_caps; /* My PHY capabilities */ |
1045 | int my_ad_caps; /* My Advertised capabilities */ | 1045 | int my_ad_caps; /* My Advertised capabilities */ |
1046 | int status; | 1046 | int status; |
1047 | 1047 | ||
1048 | DBG(3, "%s:smc_program_phy()\n", dev->name); | 1048 | DBG(3, "%s:smc_program_phy()\n", dev->name); |
1049 | 1049 | ||
1050 | spin_lock_irq(&lp->lock); | 1050 | spin_lock_irq(&lp->lock); |
1051 | 1051 | ||
1052 | /* | 1052 | /* |
1053 | * We should not be called if phy_type is zero. | 1053 | * We should not be called if phy_type is zero. |
1054 | */ | 1054 | */ |
1055 | if (lp->phy_type == 0) | 1055 | if (lp->phy_type == 0) |
1056 | goto smc_phy_configure_exit; | 1056 | goto smc_phy_configure_exit; |
1057 | 1057 | ||
1058 | if (smc_phy_reset(dev, phyaddr)) { | 1058 | if (smc_phy_reset(dev, phyaddr)) { |
1059 | printk("%s: PHY reset timed out\n", dev->name); | 1059 | printk("%s: PHY reset timed out\n", dev->name); |
1060 | goto smc_phy_configure_exit; | 1060 | goto smc_phy_configure_exit; |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | /* | 1063 | /* |
1064 | * Enable PHY Interrupts (for register 18) | 1064 | * Enable PHY Interrupts (for register 18) |
1065 | * Interrupts listed here are disabled | 1065 | * Interrupts listed here are disabled |
1066 | */ | 1066 | */ |
1067 | smc_phy_write(dev, phyaddr, PHY_MASK_REG, | 1067 | smc_phy_write(dev, phyaddr, PHY_MASK_REG, |
1068 | PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD | | 1068 | PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD | |
1069 | PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB | | 1069 | PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB | |
1070 | PHY_INT_SPDDET | PHY_INT_DPLXDET); | 1070 | PHY_INT_SPDDET | PHY_INT_DPLXDET); |
1071 | 1071 | ||
1072 | /* Configure the Receive/Phy Control register */ | 1072 | /* Configure the Receive/Phy Control register */ |
1073 | SMC_SELECT_BANK(lp, 0); | 1073 | SMC_SELECT_BANK(lp, 0); |
1074 | SMC_SET_RPC(lp, lp->rpc_cur_mode); | 1074 | SMC_SET_RPC(lp, lp->rpc_cur_mode); |
1075 | 1075 | ||
1076 | /* If the user requested no auto neg, then go set his request */ | 1076 | /* If the user requested no auto neg, then go set his request */ |
1077 | if (lp->mii.force_media) { | 1077 | if (lp->mii.force_media) { |
1078 | smc_phy_fixed(dev); | 1078 | smc_phy_fixed(dev); |
1079 | goto smc_phy_configure_exit; | 1079 | goto smc_phy_configure_exit; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | /* Copy our capabilities from MII_BMSR to MII_ADVERTISE */ | 1082 | /* Copy our capabilities from MII_BMSR to MII_ADVERTISE */ |
1083 | my_phy_caps = smc_phy_read(dev, phyaddr, MII_BMSR); | 1083 | my_phy_caps = smc_phy_read(dev, phyaddr, MII_BMSR); |
1084 | 1084 | ||
1085 | if (!(my_phy_caps & BMSR_ANEGCAPABLE)) { | 1085 | if (!(my_phy_caps & BMSR_ANEGCAPABLE)) { |
1086 | printk(KERN_INFO "Auto negotiation NOT supported\n"); | 1086 | printk(KERN_INFO "Auto negotiation NOT supported\n"); |
1087 | smc_phy_fixed(dev); | 1087 | smc_phy_fixed(dev); |
1088 | goto smc_phy_configure_exit; | 1088 | goto smc_phy_configure_exit; |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | my_ad_caps = ADVERTISE_CSMA; /* I am CSMA capable */ | 1091 | my_ad_caps = ADVERTISE_CSMA; /* I am CSMA capable */ |
1092 | 1092 | ||
1093 | if (my_phy_caps & BMSR_100BASE4) | 1093 | if (my_phy_caps & BMSR_100BASE4) |
1094 | my_ad_caps |= ADVERTISE_100BASE4; | 1094 | my_ad_caps |= ADVERTISE_100BASE4; |
1095 | if (my_phy_caps & BMSR_100FULL) | 1095 | if (my_phy_caps & BMSR_100FULL) |
1096 | my_ad_caps |= ADVERTISE_100FULL; | 1096 | my_ad_caps |= ADVERTISE_100FULL; |
1097 | if (my_phy_caps & BMSR_100HALF) | 1097 | if (my_phy_caps & BMSR_100HALF) |
1098 | my_ad_caps |= ADVERTISE_100HALF; | 1098 | my_ad_caps |= ADVERTISE_100HALF; |
1099 | if (my_phy_caps & BMSR_10FULL) | 1099 | if (my_phy_caps & BMSR_10FULL) |
1100 | my_ad_caps |= ADVERTISE_10FULL; | 1100 | my_ad_caps |= ADVERTISE_10FULL; |
1101 | if (my_phy_caps & BMSR_10HALF) | 1101 | if (my_phy_caps & BMSR_10HALF) |
1102 | my_ad_caps |= ADVERTISE_10HALF; | 1102 | my_ad_caps |= ADVERTISE_10HALF; |
1103 | 1103 | ||
1104 | /* Disable capabilities not selected by our user */ | 1104 | /* Disable capabilities not selected by our user */ |
1105 | if (lp->ctl_rspeed != 100) | 1105 | if (lp->ctl_rspeed != 100) |
1106 | my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF); | 1106 | my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF); |
1107 | 1107 | ||
1108 | if (!lp->ctl_rfduplx) | 1108 | if (!lp->ctl_rfduplx) |
1109 | my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); | 1109 | my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); |
1110 | 1110 | ||
1111 | /* Update our Auto-Neg Advertisement Register */ | 1111 | /* Update our Auto-Neg Advertisement Register */ |
1112 | smc_phy_write(dev, phyaddr, MII_ADVERTISE, my_ad_caps); | 1112 | smc_phy_write(dev, phyaddr, MII_ADVERTISE, my_ad_caps); |
1113 | lp->mii.advertising = my_ad_caps; | 1113 | lp->mii.advertising = my_ad_caps; |
1114 | 1114 | ||
1115 | /* | 1115 | /* |
1116 | * Read the register back. Without this, it appears that when | 1116 | * Read the register back. Without this, it appears that when |
1117 | * auto-negotiation is restarted, sometimes it isn't ready and | 1117 | * auto-negotiation is restarted, sometimes it isn't ready and |
1118 | * the link does not come up. | 1118 | * the link does not come up. |
1119 | */ | 1119 | */ |
1120 | status = smc_phy_read(dev, phyaddr, MII_ADVERTISE); | 1120 | status = smc_phy_read(dev, phyaddr, MII_ADVERTISE); |
1121 | 1121 | ||
1122 | DBG(2, "%s: phy caps=%x\n", dev->name, my_phy_caps); | 1122 | DBG(2, "%s: phy caps=%x\n", dev->name, my_phy_caps); |
1123 | DBG(2, "%s: phy advertised caps=%x\n", dev->name, my_ad_caps); | 1123 | DBG(2, "%s: phy advertised caps=%x\n", dev->name, my_ad_caps); |
1124 | 1124 | ||
1125 | /* Restart auto-negotiation process in order to advertise my caps */ | 1125 | /* Restart auto-negotiation process in order to advertise my caps */ |
1126 | smc_phy_write(dev, phyaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); | 1126 | smc_phy_write(dev, phyaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); |
1127 | 1127 | ||
1128 | smc_phy_check_media(dev, 1); | 1128 | smc_phy_check_media(dev, 1); |
1129 | 1129 | ||
1130 | smc_phy_configure_exit: | 1130 | smc_phy_configure_exit: |
1131 | SMC_SELECT_BANK(lp, 2); | 1131 | SMC_SELECT_BANK(lp, 2); |
1132 | spin_unlock_irq(&lp->lock); | 1132 | spin_unlock_irq(&lp->lock); |
1133 | } | 1133 | } |
1134 | 1134 | ||
1135 | /* | 1135 | /* |
1136 | * smc_phy_interrupt | 1136 | * smc_phy_interrupt |
1137 | * | 1137 | * |
1138 | * Purpose: Handle interrupts relating to PHY register 18. This is | 1138 | * Purpose: Handle interrupts relating to PHY register 18. This is |
1139 | * called from the "hard" interrupt handler under our private spinlock. | 1139 | * called from the "hard" interrupt handler under our private spinlock. |
1140 | */ | 1140 | */ |
1141 | static void smc_phy_interrupt(struct net_device *dev) | 1141 | static void smc_phy_interrupt(struct net_device *dev) |
1142 | { | 1142 | { |
1143 | struct smc_local *lp = netdev_priv(dev); | 1143 | struct smc_local *lp = netdev_priv(dev); |
1144 | int phyaddr = lp->mii.phy_id; | 1144 | int phyaddr = lp->mii.phy_id; |
1145 | int phy18; | 1145 | int phy18; |
1146 | 1146 | ||
1147 | DBG(2, "%s: %s\n", dev->name, __func__); | 1147 | DBG(2, "%s: %s\n", dev->name, __func__); |
1148 | 1148 | ||
1149 | if (lp->phy_type == 0) | 1149 | if (lp->phy_type == 0) |
1150 | return; | 1150 | return; |
1151 | 1151 | ||
1152 | for(;;) { | 1152 | for(;;) { |
1153 | smc_phy_check_media(dev, 0); | 1153 | smc_phy_check_media(dev, 0); |
1154 | 1154 | ||
1155 | /* Read PHY Register 18, Status Output */ | 1155 | /* Read PHY Register 18, Status Output */ |
1156 | phy18 = smc_phy_read(dev, phyaddr, PHY_INT_REG); | 1156 | phy18 = smc_phy_read(dev, phyaddr, PHY_INT_REG); |
1157 | if ((phy18 & PHY_INT_INT) == 0) | 1157 | if ((phy18 & PHY_INT_INT) == 0) |
1158 | break; | 1158 | break; |
1159 | } | 1159 | } |
1160 | } | 1160 | } |
1161 | 1161 | ||
1162 | /*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/ | 1162 | /*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/ |
1163 | 1163 | ||
1164 | static void smc_10bt_check_media(struct net_device *dev, int init) | 1164 | static void smc_10bt_check_media(struct net_device *dev, int init) |
1165 | { | 1165 | { |
1166 | struct smc_local *lp = netdev_priv(dev); | 1166 | struct smc_local *lp = netdev_priv(dev); |
1167 | void __iomem *ioaddr = lp->base; | 1167 | void __iomem *ioaddr = lp->base; |
1168 | unsigned int old_carrier, new_carrier; | 1168 | unsigned int old_carrier, new_carrier; |
1169 | 1169 | ||
1170 | old_carrier = netif_carrier_ok(dev) ? 1 : 0; | 1170 | old_carrier = netif_carrier_ok(dev) ? 1 : 0; |
1171 | 1171 | ||
1172 | SMC_SELECT_BANK(lp, 0); | 1172 | SMC_SELECT_BANK(lp, 0); |
1173 | new_carrier = (SMC_GET_EPH_STATUS(lp) & ES_LINK_OK) ? 1 : 0; | 1173 | new_carrier = (SMC_GET_EPH_STATUS(lp) & ES_LINK_OK) ? 1 : 0; |
1174 | SMC_SELECT_BANK(lp, 2); | 1174 | SMC_SELECT_BANK(lp, 2); |
1175 | 1175 | ||
1176 | if (init || (old_carrier != new_carrier)) { | 1176 | if (init || (old_carrier != new_carrier)) { |
1177 | if (!new_carrier) { | 1177 | if (!new_carrier) { |
1178 | netif_carrier_off(dev); | 1178 | netif_carrier_off(dev); |
1179 | } else { | 1179 | } else { |
1180 | netif_carrier_on(dev); | 1180 | netif_carrier_on(dev); |
1181 | } | 1181 | } |
1182 | if (netif_msg_link(lp)) | 1182 | if (netif_msg_link(lp)) |
1183 | printk(KERN_INFO "%s: link %s\n", dev->name, | 1183 | printk(KERN_INFO "%s: link %s\n", dev->name, |
1184 | new_carrier ? "up" : "down"); | 1184 | new_carrier ? "up" : "down"); |
1185 | } | 1185 | } |
1186 | } | 1186 | } |
1187 | 1187 | ||
1188 | static void smc_eph_interrupt(struct net_device *dev) | 1188 | static void smc_eph_interrupt(struct net_device *dev) |
1189 | { | 1189 | { |
1190 | struct smc_local *lp = netdev_priv(dev); | 1190 | struct smc_local *lp = netdev_priv(dev); |
1191 | void __iomem *ioaddr = lp->base; | 1191 | void __iomem *ioaddr = lp->base; |
1192 | unsigned int ctl; | 1192 | unsigned int ctl; |
1193 | 1193 | ||
1194 | smc_10bt_check_media(dev, 0); | 1194 | smc_10bt_check_media(dev, 0); |
1195 | 1195 | ||
1196 | SMC_SELECT_BANK(lp, 1); | 1196 | SMC_SELECT_BANK(lp, 1); |
1197 | ctl = SMC_GET_CTL(lp); | 1197 | ctl = SMC_GET_CTL(lp); |
1198 | SMC_SET_CTL(lp, ctl & ~CTL_LE_ENABLE); | 1198 | SMC_SET_CTL(lp, ctl & ~CTL_LE_ENABLE); |
1199 | SMC_SET_CTL(lp, ctl); | 1199 | SMC_SET_CTL(lp, ctl); |
1200 | SMC_SELECT_BANK(lp, 2); | 1200 | SMC_SELECT_BANK(lp, 2); |
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | /* | 1203 | /* |
1204 | * This is the main routine of the driver, to handle the device when | 1204 | * This is the main routine of the driver, to handle the device when |
1205 | * it needs some attention. | 1205 | * it needs some attention. |
1206 | */ | 1206 | */ |
1207 | static irqreturn_t smc_interrupt(int irq, void *dev_id) | 1207 | static irqreturn_t smc_interrupt(int irq, void *dev_id) |
1208 | { | 1208 | { |
1209 | struct net_device *dev = dev_id; | 1209 | struct net_device *dev = dev_id; |
1210 | struct smc_local *lp = netdev_priv(dev); | 1210 | struct smc_local *lp = netdev_priv(dev); |
1211 | void __iomem *ioaddr = lp->base; | 1211 | void __iomem *ioaddr = lp->base; |
1212 | int status, mask, timeout, card_stats; | 1212 | int status, mask, timeout, card_stats; |
1213 | int saved_pointer; | 1213 | int saved_pointer; |
1214 | 1214 | ||
1215 | DBG(3, "%s: %s\n", dev->name, __func__); | 1215 | DBG(3, "%s: %s\n", dev->name, __func__); |
1216 | 1216 | ||
1217 | spin_lock(&lp->lock); | 1217 | spin_lock(&lp->lock); |
1218 | 1218 | ||
1219 | /* A preamble may be used when there is a potential race | 1219 | /* A preamble may be used when there is a potential race |
1220 | * between the interruptible transmit functions and this | 1220 | * between the interruptible transmit functions and this |
1221 | * ISR. */ | 1221 | * ISR. */ |
1222 | SMC_INTERRUPT_PREAMBLE; | 1222 | SMC_INTERRUPT_PREAMBLE; |
1223 | 1223 | ||
1224 | saved_pointer = SMC_GET_PTR(lp); | 1224 | saved_pointer = SMC_GET_PTR(lp); |
1225 | mask = SMC_GET_INT_MASK(lp); | 1225 | mask = SMC_GET_INT_MASK(lp); |
1226 | SMC_SET_INT_MASK(lp, 0); | 1226 | SMC_SET_INT_MASK(lp, 0); |
1227 | 1227 | ||
1228 | /* set a timeout value, so I don't stay here forever */ | 1228 | /* set a timeout value, so I don't stay here forever */ |
1229 | timeout = MAX_IRQ_LOOPS; | 1229 | timeout = MAX_IRQ_LOOPS; |
1230 | 1230 | ||
1231 | do { | 1231 | do { |
1232 | status = SMC_GET_INT(lp); | 1232 | status = SMC_GET_INT(lp); |
1233 | 1233 | ||
1234 | DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", | 1234 | DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", |
1235 | dev->name, status, mask, | 1235 | dev->name, status, mask, |
1236 | ({ int meminfo; SMC_SELECT_BANK(lp, 0); | 1236 | ({ int meminfo; SMC_SELECT_BANK(lp, 0); |
1237 | meminfo = SMC_GET_MIR(lp); | 1237 | meminfo = SMC_GET_MIR(lp); |
1238 | SMC_SELECT_BANK(lp, 2); meminfo; }), | 1238 | SMC_SELECT_BANK(lp, 2); meminfo; }), |
1239 | SMC_GET_FIFO(lp)); | 1239 | SMC_GET_FIFO(lp)); |
1240 | 1240 | ||
1241 | status &= mask; | 1241 | status &= mask; |
1242 | if (!status) | 1242 | if (!status) |
1243 | break; | 1243 | break; |
1244 | 1244 | ||
1245 | if (status & IM_TX_INT) { | 1245 | if (status & IM_TX_INT) { |
1246 | /* do this before RX as it will free memory quickly */ | 1246 | /* do this before RX as it will free memory quickly */ |
1247 | DBG(3, "%s: TX int\n", dev->name); | 1247 | DBG(3, "%s: TX int\n", dev->name); |
1248 | smc_tx(dev); | 1248 | smc_tx(dev); |
1249 | SMC_ACK_INT(lp, IM_TX_INT); | 1249 | SMC_ACK_INT(lp, IM_TX_INT); |
1250 | if (THROTTLE_TX_PKTS) | 1250 | if (THROTTLE_TX_PKTS) |
1251 | netif_wake_queue(dev); | 1251 | netif_wake_queue(dev); |
1252 | } else if (status & IM_RCV_INT) { | 1252 | } else if (status & IM_RCV_INT) { |
1253 | DBG(3, "%s: RX irq\n", dev->name); | 1253 | DBG(3, "%s: RX irq\n", dev->name); |
1254 | smc_rcv(dev); | 1254 | smc_rcv(dev); |
1255 | } else if (status & IM_ALLOC_INT) { | 1255 | } else if (status & IM_ALLOC_INT) { |
1256 | DBG(3, "%s: Allocation irq\n", dev->name); | 1256 | DBG(3, "%s: Allocation irq\n", dev->name); |
1257 | tasklet_hi_schedule(&lp->tx_task); | 1257 | tasklet_hi_schedule(&lp->tx_task); |
1258 | mask &= ~IM_ALLOC_INT; | 1258 | mask &= ~IM_ALLOC_INT; |
1259 | } else if (status & IM_TX_EMPTY_INT) { | 1259 | } else if (status & IM_TX_EMPTY_INT) { |
1260 | DBG(3, "%s: TX empty\n", dev->name); | 1260 | DBG(3, "%s: TX empty\n", dev->name); |
1261 | mask &= ~IM_TX_EMPTY_INT; | 1261 | mask &= ~IM_TX_EMPTY_INT; |
1262 | 1262 | ||
1263 | /* update stats */ | 1263 | /* update stats */ |
1264 | SMC_SELECT_BANK(lp, 0); | 1264 | SMC_SELECT_BANK(lp, 0); |
1265 | card_stats = SMC_GET_COUNTER(lp); | 1265 | card_stats = SMC_GET_COUNTER(lp); |
1266 | SMC_SELECT_BANK(lp, 2); | 1266 | SMC_SELECT_BANK(lp, 2); |
1267 | 1267 | ||
1268 | /* single collisions */ | 1268 | /* single collisions */ |
1269 | dev->stats.collisions += card_stats & 0xF; | 1269 | dev->stats.collisions += card_stats & 0xF; |
1270 | card_stats >>= 4; | 1270 | card_stats >>= 4; |
1271 | 1271 | ||
1272 | /* multiple collisions */ | 1272 | /* multiple collisions */ |
1273 | dev->stats.collisions += card_stats & 0xF; | 1273 | dev->stats.collisions += card_stats & 0xF; |
1274 | } else if (status & IM_RX_OVRN_INT) { | 1274 | } else if (status & IM_RX_OVRN_INT) { |
1275 | DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, | 1275 | DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, |
1276 | ({ int eph_st; SMC_SELECT_BANK(lp, 0); | 1276 | ({ int eph_st; SMC_SELECT_BANK(lp, 0); |
1277 | eph_st = SMC_GET_EPH_STATUS(lp); | 1277 | eph_st = SMC_GET_EPH_STATUS(lp); |
1278 | SMC_SELECT_BANK(lp, 2); eph_st; })); | 1278 | SMC_SELECT_BANK(lp, 2); eph_st; })); |
1279 | SMC_ACK_INT(lp, IM_RX_OVRN_INT); | 1279 | SMC_ACK_INT(lp, IM_RX_OVRN_INT); |
1280 | dev->stats.rx_errors++; | 1280 | dev->stats.rx_errors++; |
1281 | dev->stats.rx_fifo_errors++; | 1281 | dev->stats.rx_fifo_errors++; |
1282 | } else if (status & IM_EPH_INT) { | 1282 | } else if (status & IM_EPH_INT) { |
1283 | smc_eph_interrupt(dev); | 1283 | smc_eph_interrupt(dev); |
1284 | } else if (status & IM_MDINT) { | 1284 | } else if (status & IM_MDINT) { |
1285 | SMC_ACK_INT(lp, IM_MDINT); | 1285 | SMC_ACK_INT(lp, IM_MDINT); |
1286 | smc_phy_interrupt(dev); | 1286 | smc_phy_interrupt(dev); |
1287 | } else if (status & IM_ERCV_INT) { | 1287 | } else if (status & IM_ERCV_INT) { |
1288 | SMC_ACK_INT(lp, IM_ERCV_INT); | 1288 | SMC_ACK_INT(lp, IM_ERCV_INT); |
1289 | PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name); | 1289 | PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name); |
1290 | } | 1290 | } |
1291 | } while (--timeout); | 1291 | } while (--timeout); |
1292 | 1292 | ||
1293 | /* restore register states */ | 1293 | /* restore register states */ |
1294 | SMC_SET_PTR(lp, saved_pointer); | 1294 | SMC_SET_PTR(lp, saved_pointer); |
1295 | SMC_SET_INT_MASK(lp, mask); | 1295 | SMC_SET_INT_MASK(lp, mask); |
1296 | spin_unlock(&lp->lock); | 1296 | spin_unlock(&lp->lock); |
1297 | 1297 | ||
1298 | #ifndef CONFIG_NET_POLL_CONTROLLER | 1298 | #ifndef CONFIG_NET_POLL_CONTROLLER |
1299 | if (timeout == MAX_IRQ_LOOPS) | 1299 | if (timeout == MAX_IRQ_LOOPS) |
1300 | PRINTK("%s: spurious interrupt (mask = 0x%02x)\n", | 1300 | PRINTK("%s: spurious interrupt (mask = 0x%02x)\n", |
1301 | dev->name, mask); | 1301 | dev->name, mask); |
1302 | #endif | 1302 | #endif |
1303 | DBG(3, "%s: Interrupt done (%d loops)\n", | 1303 | DBG(3, "%s: Interrupt done (%d loops)\n", |
1304 | dev->name, MAX_IRQ_LOOPS - timeout); | 1304 | dev->name, MAX_IRQ_LOOPS - timeout); |
1305 | 1305 | ||
1306 | /* | 1306 | /* |
1307 | * We return IRQ_HANDLED unconditionally here even if there was | 1307 | * We return IRQ_HANDLED unconditionally here even if there was |
1308 | * nothing to do. There is a possibility that a packet might | 1308 | * nothing to do. There is a possibility that a packet might |
1309 | * get enqueued into the chip right after TX_EMPTY_INT is raised | 1309 | * get enqueued into the chip right after TX_EMPTY_INT is raised |
1310 | * but just before the CPU acknowledges the IRQ. | 1310 | * but just before the CPU acknowledges the IRQ. |
1311 | * Better take an unneeded IRQ in some occasions than complexifying | 1311 | * Better take an unneeded IRQ in some occasions than complexifying |
1312 | * the code for all cases. | 1312 | * the code for all cases. |
1313 | */ | 1313 | */ |
1314 | return IRQ_HANDLED; | 1314 | return IRQ_HANDLED; |
1315 | } | 1315 | } |
1316 | 1316 | ||
1317 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1317 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1318 | /* | 1318 | /* |
1319 | * Polling receive - used by netconsole and other diagnostic tools | 1319 | * Polling receive - used by netconsole and other diagnostic tools |
1320 | * to allow network i/o with interrupts disabled. | 1320 | * to allow network i/o with interrupts disabled. |
1321 | */ | 1321 | */ |
1322 | static void smc_poll_controller(struct net_device *dev) | 1322 | static void smc_poll_controller(struct net_device *dev) |
1323 | { | 1323 | { |
1324 | disable_irq(dev->irq); | 1324 | disable_irq(dev->irq); |
1325 | smc_interrupt(dev->irq, dev); | 1325 | smc_interrupt(dev->irq, dev); |
1326 | enable_irq(dev->irq); | 1326 | enable_irq(dev->irq); |
1327 | } | 1327 | } |
1328 | #endif | 1328 | #endif |
1329 | 1329 | ||
1330 | /* Our watchdog timed out. Called by the networking layer */ | 1330 | /* Our watchdog timed out. Called by the networking layer */ |
1331 | static void smc_timeout(struct net_device *dev) | 1331 | static void smc_timeout(struct net_device *dev) |
1332 | { | 1332 | { |
1333 | struct smc_local *lp = netdev_priv(dev); | 1333 | struct smc_local *lp = netdev_priv(dev); |
1334 | void __iomem *ioaddr = lp->base; | 1334 | void __iomem *ioaddr = lp->base; |
1335 | int status, mask, eph_st, meminfo, fifo; | 1335 | int status, mask, eph_st, meminfo, fifo; |
1336 | 1336 | ||
1337 | DBG(2, "%s: %s\n", dev->name, __func__); | 1337 | DBG(2, "%s: %s\n", dev->name, __func__); |
1338 | 1338 | ||
1339 | spin_lock_irq(&lp->lock); | 1339 | spin_lock_irq(&lp->lock); |
1340 | status = SMC_GET_INT(lp); | 1340 | status = SMC_GET_INT(lp); |
1341 | mask = SMC_GET_INT_MASK(lp); | 1341 | mask = SMC_GET_INT_MASK(lp); |
1342 | fifo = SMC_GET_FIFO(lp); | 1342 | fifo = SMC_GET_FIFO(lp); |
1343 | SMC_SELECT_BANK(lp, 0); | 1343 | SMC_SELECT_BANK(lp, 0); |
1344 | eph_st = SMC_GET_EPH_STATUS(lp); | 1344 | eph_st = SMC_GET_EPH_STATUS(lp); |
1345 | meminfo = SMC_GET_MIR(lp); | 1345 | meminfo = SMC_GET_MIR(lp); |
1346 | SMC_SELECT_BANK(lp, 2); | 1346 | SMC_SELECT_BANK(lp, 2); |
1347 | spin_unlock_irq(&lp->lock); | 1347 | spin_unlock_irq(&lp->lock); |
1348 | PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x " | 1348 | PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x " |
1349 | "MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n", | 1349 | "MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n", |
1350 | dev->name, status, mask, meminfo, fifo, eph_st ); | 1350 | dev->name, status, mask, meminfo, fifo, eph_st ); |
1351 | 1351 | ||
1352 | smc_reset(dev); | 1352 | smc_reset(dev); |
1353 | smc_enable(dev); | 1353 | smc_enable(dev); |
1354 | 1354 | ||
1355 | /* | 1355 | /* |
1356 | * Reconfiguring the PHY doesn't seem like a bad idea here, but | 1356 | * Reconfiguring the PHY doesn't seem like a bad idea here, but |
1357 | * smc_phy_configure() calls msleep() which calls schedule_timeout() | 1357 | * smc_phy_configure() calls msleep() which calls schedule_timeout() |
1358 | * which calls schedule(). Hence we use a work queue. | 1358 | * which calls schedule(). Hence we use a work queue. |
1359 | */ | 1359 | */ |
1360 | if (lp->phy_type != 0) | 1360 | if (lp->phy_type != 0) |
1361 | schedule_work(&lp->phy_configure); | 1361 | schedule_work(&lp->phy_configure); |
1362 | 1362 | ||
1363 | /* We can accept TX packets again */ | 1363 | /* We can accept TX packets again */ |
1364 | dev->trans_start = jiffies; | 1364 | dev->trans_start = jiffies; |
1365 | netif_wake_queue(dev); | 1365 | netif_wake_queue(dev); |
1366 | } | 1366 | } |
1367 | 1367 | ||
1368 | /* | 1368 | /* |
1369 | * This routine will, depending on the values passed to it, | 1369 | * This routine will, depending on the values passed to it, |
1370 | * either make it accept multicast packets, go into | 1370 | * either make it accept multicast packets, go into |
1371 | * promiscuous mode (for TCPDUMP and cousins) or accept | 1371 | * promiscuous mode (for TCPDUMP and cousins) or accept |
1372 | * a select set of multicast packets | 1372 | * a select set of multicast packets |
1373 | */ | 1373 | */ |
1374 | static void smc_set_multicast_list(struct net_device *dev) | 1374 | static void smc_set_multicast_list(struct net_device *dev) |
1375 | { | 1375 | { |
1376 | struct smc_local *lp = netdev_priv(dev); | 1376 | struct smc_local *lp = netdev_priv(dev); |
1377 | void __iomem *ioaddr = lp->base; | 1377 | void __iomem *ioaddr = lp->base; |
1378 | unsigned char multicast_table[8]; | 1378 | unsigned char multicast_table[8]; |
1379 | int update_multicast = 0; | 1379 | int update_multicast = 0; |
1380 | 1380 | ||
1381 | DBG(2, "%s: %s\n", dev->name, __func__); | 1381 | DBG(2, "%s: %s\n", dev->name, __func__); |
1382 | 1382 | ||
1383 | if (dev->flags & IFF_PROMISC) { | 1383 | if (dev->flags & IFF_PROMISC) { |
1384 | DBG(2, "%s: RCR_PRMS\n", dev->name); | 1384 | DBG(2, "%s: RCR_PRMS\n", dev->name); |
1385 | lp->rcr_cur_mode |= RCR_PRMS; | 1385 | lp->rcr_cur_mode |= RCR_PRMS; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | /* BUG? I never disable promiscuous mode if multicasting was turned on. | 1388 | /* BUG? I never disable promiscuous mode if multicasting was turned on. |
1389 | Now, I turn off promiscuous mode, but I don't do anything to multicasting | 1389 | Now, I turn off promiscuous mode, but I don't do anything to multicasting |
1390 | when promiscuous mode is turned on. | 1390 | when promiscuous mode is turned on. |
1391 | */ | 1391 | */ |
1392 | 1392 | ||
1393 | /* | 1393 | /* |
1394 | * Here, I am setting this to accept all multicast packets. | 1394 | * Here, I am setting this to accept all multicast packets. |
1395 | * I don't need to zero the multicast table, because the flag is | 1395 | * I don't need to zero the multicast table, because the flag is |
1396 | * checked before the table is | 1396 | * checked before the table is |
1397 | */ | 1397 | */ |
1398 | else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) { | 1398 | else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) { |
1399 | DBG(2, "%s: RCR_ALMUL\n", dev->name); | 1399 | DBG(2, "%s: RCR_ALMUL\n", dev->name); |
1400 | lp->rcr_cur_mode |= RCR_ALMUL; | 1400 | lp->rcr_cur_mode |= RCR_ALMUL; |
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | /* | 1403 | /* |
1404 | * This sets the internal hardware table to filter out unwanted | 1404 | * This sets the internal hardware table to filter out unwanted |
1405 | * multicast packets before they take up memory. | 1405 | * multicast packets before they take up memory. |
1406 | * | 1406 | * |
1407 | * The SMC chip uses a hash table where the high 6 bits of the CRC of | 1407 | * The SMC chip uses a hash table where the high 6 bits of the CRC of |
1408 | * address are the offset into the table. If that bit is 1, then the | 1408 | * address are the offset into the table. If that bit is 1, then the |
1409 | * multicast packet is accepted. Otherwise, it's dropped silently. | 1409 | * multicast packet is accepted. Otherwise, it's dropped silently. |
1410 | * | 1410 | * |
1411 | * To use the 6 bits as an offset into the table, the high 3 bits are | 1411 | * To use the 6 bits as an offset into the table, the high 3 bits are |
1412 | * the number of the 8 bit register, while the low 3 bits are the bit | 1412 | * the number of the 8 bit register, while the low 3 bits are the bit |
1413 | * within that register. | 1413 | * within that register. |
1414 | */ | 1414 | */ |
1415 | else if (dev->mc_count) { | 1415 | else if (dev->mc_count) { |
1416 | int i; | 1416 | int i; |
1417 | struct dev_mc_list *cur_addr; | 1417 | struct dev_mc_list *cur_addr; |
1418 | 1418 | ||
1419 | /* table for flipping the order of 3 bits */ | 1419 | /* table for flipping the order of 3 bits */ |
1420 | static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7}; | 1420 | static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7}; |
1421 | 1421 | ||
1422 | /* start with a table of all zeros: reject all */ | 1422 | /* start with a table of all zeros: reject all */ |
1423 | memset(multicast_table, 0, sizeof(multicast_table)); | 1423 | memset(multicast_table, 0, sizeof(multicast_table)); |
1424 | 1424 | ||
1425 | cur_addr = dev->mc_list; | 1425 | cur_addr = dev->mc_list; |
1426 | for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) { | 1426 | for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) { |
1427 | int position; | 1427 | int position; |
1428 | 1428 | ||
1429 | /* do we have a pointer here? */ | 1429 | /* do we have a pointer here? */ |
1430 | if (!cur_addr) | 1430 | if (!cur_addr) |
1431 | break; | 1431 | break; |
1432 | /* make sure this is a multicast address - | 1432 | /* make sure this is a multicast address - |
1433 | shouldn't this be a given if we have it here ? */ | 1433 | shouldn't this be a given if we have it here ? */ |
1434 | if (!(*cur_addr->dmi_addr & 1)) | 1434 | if (!(*cur_addr->dmi_addr & 1)) |
1435 | continue; | 1435 | continue; |
1436 | 1436 | ||
1437 | /* only use the low order bits */ | 1437 | /* only use the low order bits */ |
1438 | position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f; | 1438 | position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f; |
1439 | 1439 | ||
1440 | /* do some messy swapping to put the bit in the right spot */ | 1440 | /* do some messy swapping to put the bit in the right spot */ |
1441 | multicast_table[invert3[position&7]] |= | 1441 | multicast_table[invert3[position&7]] |= |
1442 | (1<<invert3[(position>>3)&7]); | 1442 | (1<<invert3[(position>>3)&7]); |
1443 | } | 1443 | } |
1444 | 1444 | ||
1445 | /* be sure I get rid of flags I might have set */ | 1445 | /* be sure I get rid of flags I might have set */ |
1446 | lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); | 1446 | lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); |
1447 | 1447 | ||
1448 | /* now, the table can be loaded into the chipset */ | 1448 | /* now, the table can be loaded into the chipset */ |
1449 | update_multicast = 1; | 1449 | update_multicast = 1; |
1450 | } else { | 1450 | } else { |
1451 | DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name); | 1451 | DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name); |
1452 | lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); | 1452 | lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); |
1453 | 1453 | ||
1454 | /* | 1454 | /* |
1455 | * since I'm disabling all multicast entirely, I need to | 1455 | * since I'm disabling all multicast entirely, I need to |
1456 | * clear the multicast list | 1456 | * clear the multicast list |
1457 | */ | 1457 | */ |
1458 | memset(multicast_table, 0, sizeof(multicast_table)); | 1458 | memset(multicast_table, 0, sizeof(multicast_table)); |
1459 | update_multicast = 1; | 1459 | update_multicast = 1; |
1460 | } | 1460 | } |
1461 | 1461 | ||
1462 | spin_lock_irq(&lp->lock); | 1462 | spin_lock_irq(&lp->lock); |
1463 | SMC_SELECT_BANK(lp, 0); | 1463 | SMC_SELECT_BANK(lp, 0); |
1464 | SMC_SET_RCR(lp, lp->rcr_cur_mode); | 1464 | SMC_SET_RCR(lp, lp->rcr_cur_mode); |
1465 | if (update_multicast) { | 1465 | if (update_multicast) { |
1466 | SMC_SELECT_BANK(lp, 3); | 1466 | SMC_SELECT_BANK(lp, 3); |
1467 | SMC_SET_MCAST(lp, multicast_table); | 1467 | SMC_SET_MCAST(lp, multicast_table); |
1468 | } | 1468 | } |
1469 | SMC_SELECT_BANK(lp, 2); | 1469 | SMC_SELECT_BANK(lp, 2); |
1470 | spin_unlock_irq(&lp->lock); | 1470 | spin_unlock_irq(&lp->lock); |
1471 | } | 1471 | } |
1472 | 1472 | ||
1473 | 1473 | ||
1474 | /* | 1474 | /* |
1475 | * Open and Initialize the board | 1475 | * Open and Initialize the board |
1476 | * | 1476 | * |
1477 | * Set up everything, reset the card, etc.. | 1477 | * Set up everything, reset the card, etc.. |
1478 | */ | 1478 | */ |
1479 | static int | 1479 | static int |
1480 | smc_open(struct net_device *dev) | 1480 | smc_open(struct net_device *dev) |
1481 | { | 1481 | { |
1482 | struct smc_local *lp = netdev_priv(dev); | 1482 | struct smc_local *lp = netdev_priv(dev); |
1483 | 1483 | ||
1484 | DBG(2, "%s: %s\n", dev->name, __func__); | 1484 | DBG(2, "%s: %s\n", dev->name, __func__); |
1485 | 1485 | ||
1486 | /* | 1486 | /* |
1487 | * Check that the address is valid. If its not, refuse | 1487 | * Check that the address is valid. If its not, refuse |
1488 | * to bring the device up. The user must specify an | 1488 | * to bring the device up. The user must specify an |
1489 | * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx | 1489 | * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx |
1490 | */ | 1490 | */ |
1491 | if (!is_valid_ether_addr(dev->dev_addr)) { | 1491 | if (!is_valid_ether_addr(dev->dev_addr)) { |
1492 | PRINTK("%s: no valid ethernet hw addr\n", __func__); | 1492 | PRINTK("%s: no valid ethernet hw addr\n", __func__); |
1493 | return -EINVAL; | 1493 | return -EINVAL; |
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | /* Setup the default Register Modes */ | 1496 | /* Setup the default Register Modes */ |
1497 | lp->tcr_cur_mode = TCR_DEFAULT; | 1497 | lp->tcr_cur_mode = TCR_DEFAULT; |
1498 | lp->rcr_cur_mode = RCR_DEFAULT; | 1498 | lp->rcr_cur_mode = RCR_DEFAULT; |
1499 | lp->rpc_cur_mode = RPC_DEFAULT | | 1499 | lp->rpc_cur_mode = RPC_DEFAULT | |
1500 | lp->cfg.leda << RPC_LSXA_SHFT | | 1500 | lp->cfg.leda << RPC_LSXA_SHFT | |
1501 | lp->cfg.ledb << RPC_LSXB_SHFT; | 1501 | lp->cfg.ledb << RPC_LSXB_SHFT; |
1502 | 1502 | ||
1503 | /* | 1503 | /* |
1504 | * If we are not using a MII interface, we need to | 1504 | * If we are not using a MII interface, we need to |
1505 | * monitor our own carrier signal to detect faults. | 1505 | * monitor our own carrier signal to detect faults. |
1506 | */ | 1506 | */ |
1507 | if (lp->phy_type == 0) | 1507 | if (lp->phy_type == 0) |
1508 | lp->tcr_cur_mode |= TCR_MON_CSN; | 1508 | lp->tcr_cur_mode |= TCR_MON_CSN; |
1509 | 1509 | ||
1510 | /* reset the hardware */ | 1510 | /* reset the hardware */ |
1511 | smc_reset(dev); | 1511 | smc_reset(dev); |
1512 | smc_enable(dev); | 1512 | smc_enable(dev); |
1513 | 1513 | ||
1514 | /* Configure the PHY, initialize the link state */ | 1514 | /* Configure the PHY, initialize the link state */ |
1515 | if (lp->phy_type != 0) | 1515 | if (lp->phy_type != 0) |
1516 | smc_phy_configure(&lp->phy_configure); | 1516 | smc_phy_configure(&lp->phy_configure); |
1517 | else { | 1517 | else { |
1518 | spin_lock_irq(&lp->lock); | 1518 | spin_lock_irq(&lp->lock); |
1519 | smc_10bt_check_media(dev, 1); | 1519 | smc_10bt_check_media(dev, 1); |
1520 | spin_unlock_irq(&lp->lock); | 1520 | spin_unlock_irq(&lp->lock); |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | netif_start_queue(dev); | 1523 | netif_start_queue(dev); |
1524 | return 0; | 1524 | return 0; |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | /* | 1527 | /* |
1528 | * smc_close | 1528 | * smc_close |
1529 | * | 1529 | * |
1530 | * this makes the board clean up everything that it can | 1530 | * this makes the board clean up everything that it can |
1531 | * and not talk to the outside world. Caused by | 1531 | * and not talk to the outside world. Caused by |
1532 | * an 'ifconfig ethX down' | 1532 | * an 'ifconfig ethX down' |
1533 | */ | 1533 | */ |
1534 | static int smc_close(struct net_device *dev) | 1534 | static int smc_close(struct net_device *dev) |
1535 | { | 1535 | { |
1536 | struct smc_local *lp = netdev_priv(dev); | 1536 | struct smc_local *lp = netdev_priv(dev); |
1537 | 1537 | ||
1538 | DBG(2, "%s: %s\n", dev->name, __func__); | 1538 | DBG(2, "%s: %s\n", dev->name, __func__); |
1539 | 1539 | ||
1540 | netif_stop_queue(dev); | 1540 | netif_stop_queue(dev); |
1541 | netif_carrier_off(dev); | 1541 | netif_carrier_off(dev); |
1542 | 1542 | ||
1543 | /* clear everything */ | 1543 | /* clear everything */ |
1544 | smc_shutdown(dev); | 1544 | smc_shutdown(dev); |
1545 | tasklet_kill(&lp->tx_task); | 1545 | tasklet_kill(&lp->tx_task); |
1546 | smc_phy_powerdown(dev); | 1546 | smc_phy_powerdown(dev); |
1547 | return 0; | 1547 | return 0; |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | /* | 1550 | /* |
1551 | * Ethtool support | 1551 | * Ethtool support |
1552 | */ | 1552 | */ |
1553 | static int | 1553 | static int |
1554 | smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) | 1554 | smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) |
1555 | { | 1555 | { |
1556 | struct smc_local *lp = netdev_priv(dev); | 1556 | struct smc_local *lp = netdev_priv(dev); |
1557 | int ret; | 1557 | int ret; |
1558 | 1558 | ||
1559 | cmd->maxtxpkt = 1; | 1559 | cmd->maxtxpkt = 1; |
1560 | cmd->maxrxpkt = 1; | 1560 | cmd->maxrxpkt = 1; |
1561 | 1561 | ||
1562 | if (lp->phy_type != 0) { | 1562 | if (lp->phy_type != 0) { |
1563 | spin_lock_irq(&lp->lock); | 1563 | spin_lock_irq(&lp->lock); |
1564 | ret = mii_ethtool_gset(&lp->mii, cmd); | 1564 | ret = mii_ethtool_gset(&lp->mii, cmd); |
1565 | spin_unlock_irq(&lp->lock); | 1565 | spin_unlock_irq(&lp->lock); |
1566 | } else { | 1566 | } else { |
1567 | cmd->supported = SUPPORTED_10baseT_Half | | 1567 | cmd->supported = SUPPORTED_10baseT_Half | |
1568 | SUPPORTED_10baseT_Full | | 1568 | SUPPORTED_10baseT_Full | |
1569 | SUPPORTED_TP | SUPPORTED_AUI; | 1569 | SUPPORTED_TP | SUPPORTED_AUI; |
1570 | 1570 | ||
1571 | if (lp->ctl_rspeed == 10) | 1571 | if (lp->ctl_rspeed == 10) |
1572 | cmd->speed = SPEED_10; | 1572 | cmd->speed = SPEED_10; |
1573 | else if (lp->ctl_rspeed == 100) | 1573 | else if (lp->ctl_rspeed == 100) |
1574 | cmd->speed = SPEED_100; | 1574 | cmd->speed = SPEED_100; |
1575 | 1575 | ||
1576 | cmd->autoneg = AUTONEG_DISABLE; | 1576 | cmd->autoneg = AUTONEG_DISABLE; |
1577 | cmd->transceiver = XCVR_INTERNAL; | 1577 | cmd->transceiver = XCVR_INTERNAL; |
1578 | cmd->port = 0; | 1578 | cmd->port = 0; |
1579 | cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF; | 1579 | cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF; |
1580 | 1580 | ||
1581 | ret = 0; | 1581 | ret = 0; |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | return ret; | 1584 | return ret; |
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | static int | 1587 | static int |
1588 | smc_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) | 1588 | smc_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) |
1589 | { | 1589 | { |
1590 | struct smc_local *lp = netdev_priv(dev); | 1590 | struct smc_local *lp = netdev_priv(dev); |
1591 | int ret; | 1591 | int ret; |
1592 | 1592 | ||
1593 | if (lp->phy_type != 0) { | 1593 | if (lp->phy_type != 0) { |
1594 | spin_lock_irq(&lp->lock); | 1594 | spin_lock_irq(&lp->lock); |
1595 | ret = mii_ethtool_sset(&lp->mii, cmd); | 1595 | ret = mii_ethtool_sset(&lp->mii, cmd); |
1596 | spin_unlock_irq(&lp->lock); | 1596 | spin_unlock_irq(&lp->lock); |
1597 | } else { | 1597 | } else { |
1598 | if (cmd->autoneg != AUTONEG_DISABLE || | 1598 | if (cmd->autoneg != AUTONEG_DISABLE || |
1599 | cmd->speed != SPEED_10 || | 1599 | cmd->speed != SPEED_10 || |
1600 | (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || | 1600 | (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || |
1601 | (cmd->port != PORT_TP && cmd->port != PORT_AUI)) | 1601 | (cmd->port != PORT_TP && cmd->port != PORT_AUI)) |
1602 | return -EINVAL; | 1602 | return -EINVAL; |
1603 | 1603 | ||
1604 | // lp->port = cmd->port; | 1604 | // lp->port = cmd->port; |
1605 | lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; | 1605 | lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; |
1606 | 1606 | ||
1607 | // if (netif_running(dev)) | 1607 | // if (netif_running(dev)) |
1608 | // smc_set_port(dev); | 1608 | // smc_set_port(dev); |
1609 | 1609 | ||
1610 | ret = 0; | 1610 | ret = 0; |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | return ret; | 1613 | return ret; |
1614 | } | 1614 | } |
1615 | 1615 | ||
1616 | static void | 1616 | static void |
1617 | smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 1617 | smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
1618 | { | 1618 | { |
1619 | strncpy(info->driver, CARDNAME, sizeof(info->driver)); | 1619 | strncpy(info->driver, CARDNAME, sizeof(info->driver)); |
1620 | strncpy(info->version, version, sizeof(info->version)); | 1620 | strncpy(info->version, version, sizeof(info->version)); |
1621 | strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info)); | 1621 | strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info)); |
1622 | } | 1622 | } |
1623 | 1623 | ||
1624 | static int smc_ethtool_nwayreset(struct net_device *dev) | 1624 | static int smc_ethtool_nwayreset(struct net_device *dev) |
1625 | { | 1625 | { |
1626 | struct smc_local *lp = netdev_priv(dev); | 1626 | struct smc_local *lp = netdev_priv(dev); |
1627 | int ret = -EINVAL; | 1627 | int ret = -EINVAL; |
1628 | 1628 | ||
1629 | if (lp->phy_type != 0) { | 1629 | if (lp->phy_type != 0) { |
1630 | spin_lock_irq(&lp->lock); | 1630 | spin_lock_irq(&lp->lock); |
1631 | ret = mii_nway_restart(&lp->mii); | 1631 | ret = mii_nway_restart(&lp->mii); |
1632 | spin_unlock_irq(&lp->lock); | 1632 | spin_unlock_irq(&lp->lock); |
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | return ret; | 1635 | return ret; |
1636 | } | 1636 | } |
1637 | 1637 | ||
1638 | static u32 smc_ethtool_getmsglevel(struct net_device *dev) | 1638 | static u32 smc_ethtool_getmsglevel(struct net_device *dev) |
1639 | { | 1639 | { |
1640 | struct smc_local *lp = netdev_priv(dev); | 1640 | struct smc_local *lp = netdev_priv(dev); |
1641 | return lp->msg_enable; | 1641 | return lp->msg_enable; |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level) | 1644 | static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level) |
1645 | { | 1645 | { |
1646 | struct smc_local *lp = netdev_priv(dev); | 1646 | struct smc_local *lp = netdev_priv(dev); |
1647 | lp->msg_enable = level; | 1647 | lp->msg_enable = level; |
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word) | 1650 | static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word) |
1651 | { | 1651 | { |
1652 | u16 ctl; | 1652 | u16 ctl; |
1653 | struct smc_local *lp = netdev_priv(dev); | 1653 | struct smc_local *lp = netdev_priv(dev); |
1654 | void __iomem *ioaddr = lp->base; | 1654 | void __iomem *ioaddr = lp->base; |
1655 | 1655 | ||
1656 | spin_lock_irq(&lp->lock); | 1656 | spin_lock_irq(&lp->lock); |
1657 | /* load word into GP register */ | 1657 | /* load word into GP register */ |
1658 | SMC_SELECT_BANK(lp, 1); | 1658 | SMC_SELECT_BANK(lp, 1); |
1659 | SMC_SET_GP(lp, word); | 1659 | SMC_SET_GP(lp, word); |
1660 | /* set the address to put the data in EEPROM */ | 1660 | /* set the address to put the data in EEPROM */ |
1661 | SMC_SELECT_BANK(lp, 2); | 1661 | SMC_SELECT_BANK(lp, 2); |
1662 | SMC_SET_PTR(lp, addr); | 1662 | SMC_SET_PTR(lp, addr); |
1663 | /* tell it to write */ | 1663 | /* tell it to write */ |
1664 | SMC_SELECT_BANK(lp, 1); | 1664 | SMC_SELECT_BANK(lp, 1); |
1665 | ctl = SMC_GET_CTL(lp); | 1665 | ctl = SMC_GET_CTL(lp); |
1666 | SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE)); | 1666 | SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE)); |
1667 | /* wait for it to finish */ | 1667 | /* wait for it to finish */ |
1668 | do { | 1668 | do { |
1669 | udelay(1); | 1669 | udelay(1); |
1670 | } while (SMC_GET_CTL(lp) & CTL_STORE); | 1670 | } while (SMC_GET_CTL(lp) & CTL_STORE); |
1671 | /* clean up */ | 1671 | /* clean up */ |
1672 | SMC_SET_CTL(lp, ctl); | 1672 | SMC_SET_CTL(lp, ctl); |
1673 | SMC_SELECT_BANK(lp, 2); | 1673 | SMC_SELECT_BANK(lp, 2); |
1674 | spin_unlock_irq(&lp->lock); | 1674 | spin_unlock_irq(&lp->lock); |
1675 | return 0; | 1675 | return 0; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word) | 1678 | static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word) |
1679 | { | 1679 | { |
1680 | u16 ctl; | 1680 | u16 ctl; |
1681 | struct smc_local *lp = netdev_priv(dev); | 1681 | struct smc_local *lp = netdev_priv(dev); |
1682 | void __iomem *ioaddr = lp->base; | 1682 | void __iomem *ioaddr = lp->base; |
1683 | 1683 | ||
1684 | spin_lock_irq(&lp->lock); | 1684 | spin_lock_irq(&lp->lock); |
1685 | /* set the EEPROM address to get the data from */ | 1685 | /* set the EEPROM address to get the data from */ |
1686 | SMC_SELECT_BANK(lp, 2); | 1686 | SMC_SELECT_BANK(lp, 2); |
1687 | SMC_SET_PTR(lp, addr | PTR_READ); | 1687 | SMC_SET_PTR(lp, addr | PTR_READ); |
1688 | /* tell it to load */ | 1688 | /* tell it to load */ |
1689 | SMC_SELECT_BANK(lp, 1); | 1689 | SMC_SELECT_BANK(lp, 1); |
1690 | SMC_SET_GP(lp, 0xffff); /* init to known */ | 1690 | SMC_SET_GP(lp, 0xffff); /* init to known */ |
1691 | ctl = SMC_GET_CTL(lp); | 1691 | ctl = SMC_GET_CTL(lp); |
1692 | SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD)); | 1692 | SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD)); |
1693 | /* wait for it to finish */ | 1693 | /* wait for it to finish */ |
1694 | do { | 1694 | do { |
1695 | udelay(1); | 1695 | udelay(1); |
1696 | } while (SMC_GET_CTL(lp) & CTL_RELOAD); | 1696 | } while (SMC_GET_CTL(lp) & CTL_RELOAD); |
1697 | /* read word from GP register */ | 1697 | /* read word from GP register */ |
1698 | *word = SMC_GET_GP(lp); | 1698 | *word = SMC_GET_GP(lp); |
1699 | /* clean up */ | 1699 | /* clean up */ |
1700 | SMC_SET_CTL(lp, ctl); | 1700 | SMC_SET_CTL(lp, ctl); |
1701 | SMC_SELECT_BANK(lp, 2); | 1701 | SMC_SELECT_BANK(lp, 2); |
1702 | spin_unlock_irq(&lp->lock); | 1702 | spin_unlock_irq(&lp->lock); |
1703 | return 0; | 1703 | return 0; |
1704 | } | 1704 | } |
1705 | 1705 | ||
1706 | static int smc_ethtool_geteeprom_len(struct net_device *dev) | 1706 | static int smc_ethtool_geteeprom_len(struct net_device *dev) |
1707 | { | 1707 | { |
1708 | return 0x23 * 2; | 1708 | return 0x23 * 2; |
1709 | } | 1709 | } |
1710 | 1710 | ||
1711 | static int smc_ethtool_geteeprom(struct net_device *dev, | 1711 | static int smc_ethtool_geteeprom(struct net_device *dev, |
1712 | struct ethtool_eeprom *eeprom, u8 *data) | 1712 | struct ethtool_eeprom *eeprom, u8 *data) |
1713 | { | 1713 | { |
1714 | int i; | 1714 | int i; |
1715 | int imax; | 1715 | int imax; |
1716 | 1716 | ||
1717 | DBG(1, "Reading %d bytes at %d(0x%x)\n", | 1717 | DBG(1, "Reading %d bytes at %d(0x%x)\n", |
1718 | eeprom->len, eeprom->offset, eeprom->offset); | 1718 | eeprom->len, eeprom->offset, eeprom->offset); |
1719 | imax = smc_ethtool_geteeprom_len(dev); | 1719 | imax = smc_ethtool_geteeprom_len(dev); |
1720 | for (i = 0; i < eeprom->len; i += 2) { | 1720 | for (i = 0; i < eeprom->len; i += 2) { |
1721 | int ret; | 1721 | int ret; |
1722 | u16 wbuf; | 1722 | u16 wbuf; |
1723 | int offset = i + eeprom->offset; | 1723 | int offset = i + eeprom->offset; |
1724 | if (offset > imax) | 1724 | if (offset > imax) |
1725 | break; | 1725 | break; |
1726 | ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf); | 1726 | ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf); |
1727 | if (ret != 0) | 1727 | if (ret != 0) |
1728 | return ret; | 1728 | return ret; |
1729 | DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1); | 1729 | DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1); |
1730 | data[i] = (wbuf >> 8) & 0xff; | 1730 | data[i] = (wbuf >> 8) & 0xff; |
1731 | data[i+1] = wbuf & 0xff; | 1731 | data[i+1] = wbuf & 0xff; |
1732 | } | 1732 | } |
1733 | return 0; | 1733 | return 0; |
1734 | } | 1734 | } |
1735 | 1735 | ||
1736 | static int smc_ethtool_seteeprom(struct net_device *dev, | 1736 | static int smc_ethtool_seteeprom(struct net_device *dev, |
1737 | struct ethtool_eeprom *eeprom, u8 *data) | 1737 | struct ethtool_eeprom *eeprom, u8 *data) |
1738 | { | 1738 | { |
1739 | int i; | 1739 | int i; |
1740 | int imax; | 1740 | int imax; |
1741 | 1741 | ||
1742 | DBG(1, "Writing %d bytes to %d(0x%x)\n", | 1742 | DBG(1, "Writing %d bytes to %d(0x%x)\n", |
1743 | eeprom->len, eeprom->offset, eeprom->offset); | 1743 | eeprom->len, eeprom->offset, eeprom->offset); |
1744 | imax = smc_ethtool_geteeprom_len(dev); | 1744 | imax = smc_ethtool_geteeprom_len(dev); |
1745 | for (i = 0; i < eeprom->len; i += 2) { | 1745 | for (i = 0; i < eeprom->len; i += 2) { |
1746 | int ret; | 1746 | int ret; |
1747 | u16 wbuf; | 1747 | u16 wbuf; |
1748 | int offset = i + eeprom->offset; | 1748 | int offset = i + eeprom->offset; |
1749 | if (offset > imax) | 1749 | if (offset > imax) |
1750 | break; | 1750 | break; |
1751 | wbuf = (data[i] << 8) | data[i + 1]; | 1751 | wbuf = (data[i] << 8) | data[i + 1]; |
1752 | DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1); | 1752 | DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1); |
1753 | ret = smc_write_eeprom_word(dev, offset >> 1, wbuf); | 1753 | ret = smc_write_eeprom_word(dev, offset >> 1, wbuf); |
1754 | if (ret != 0) | 1754 | if (ret != 0) |
1755 | return ret; | 1755 | return ret; |
1756 | } | 1756 | } |
1757 | return 0; | 1757 | return 0; |
1758 | } | 1758 | } |
1759 | 1759 | ||
1760 | 1760 | ||
1761 | static const struct ethtool_ops smc_ethtool_ops = { | 1761 | static const struct ethtool_ops smc_ethtool_ops = { |
1762 | .get_settings = smc_ethtool_getsettings, | 1762 | .get_settings = smc_ethtool_getsettings, |
1763 | .set_settings = smc_ethtool_setsettings, | 1763 | .set_settings = smc_ethtool_setsettings, |
1764 | .get_drvinfo = smc_ethtool_getdrvinfo, | 1764 | .get_drvinfo = smc_ethtool_getdrvinfo, |
1765 | 1765 | ||
1766 | .get_msglevel = smc_ethtool_getmsglevel, | 1766 | .get_msglevel = smc_ethtool_getmsglevel, |
1767 | .set_msglevel = smc_ethtool_setmsglevel, | 1767 | .set_msglevel = smc_ethtool_setmsglevel, |
1768 | .nway_reset = smc_ethtool_nwayreset, | 1768 | .nway_reset = smc_ethtool_nwayreset, |
1769 | .get_link = ethtool_op_get_link, | 1769 | .get_link = ethtool_op_get_link, |
1770 | .get_eeprom_len = smc_ethtool_geteeprom_len, | 1770 | .get_eeprom_len = smc_ethtool_geteeprom_len, |
1771 | .get_eeprom = smc_ethtool_geteeprom, | 1771 | .get_eeprom = smc_ethtool_geteeprom, |
1772 | .set_eeprom = smc_ethtool_seteeprom, | 1772 | .set_eeprom = smc_ethtool_seteeprom, |
1773 | }; | 1773 | }; |
1774 | 1774 | ||
1775 | static const struct net_device_ops smc_netdev_ops = { | 1775 | static const struct net_device_ops smc_netdev_ops = { |
1776 | .ndo_open = smc_open, | 1776 | .ndo_open = smc_open, |
1777 | .ndo_stop = smc_close, | 1777 | .ndo_stop = smc_close, |
1778 | .ndo_start_xmit = smc_hard_start_xmit, | 1778 | .ndo_start_xmit = smc_hard_start_xmit, |
1779 | .ndo_tx_timeout = smc_timeout, | 1779 | .ndo_tx_timeout = smc_timeout, |
1780 | .ndo_set_multicast_list = smc_set_multicast_list, | 1780 | .ndo_set_multicast_list = smc_set_multicast_list, |
1781 | .ndo_change_mtu = eth_change_mtu, | 1781 | .ndo_change_mtu = eth_change_mtu, |
1782 | .ndo_validate_addr = eth_validate_addr, | 1782 | .ndo_validate_addr = eth_validate_addr, |
1783 | .ndo_set_mac_address = eth_mac_addr, | 1783 | .ndo_set_mac_address = eth_mac_addr, |
1784 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1784 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1785 | .ndo_poll_controller = smc_poll_controller, | 1785 | .ndo_poll_controller = smc_poll_controller, |
1786 | #endif | 1786 | #endif |
1787 | }; | 1787 | }; |
1788 | 1788 | ||
1789 | /* | 1789 | /* |
1790 | * smc_findirq | 1790 | * smc_findirq |
1791 | * | 1791 | * |
1792 | * This routine has a simple purpose -- make the SMC chip generate an | 1792 | * This routine has a simple purpose -- make the SMC chip generate an |
1793 | * interrupt, so an auto-detect routine can detect it, and find the IRQ, | 1793 | * interrupt, so an auto-detect routine can detect it, and find the IRQ, |
1794 | */ | 1794 | */ |
1795 | /* | 1795 | /* |
1796 | * does this still work? | 1796 | * does this still work? |
1797 | * | 1797 | * |
1798 | * I just deleted auto_irq.c, since it was never built... | 1798 | * I just deleted auto_irq.c, since it was never built... |
1799 | * --jgarzik | 1799 | * --jgarzik |
1800 | */ | 1800 | */ |
1801 | static int __devinit smc_findirq(struct smc_local *lp) | 1801 | static int __devinit smc_findirq(struct smc_local *lp) |
1802 | { | 1802 | { |
1803 | void __iomem *ioaddr = lp->base; | 1803 | void __iomem *ioaddr = lp->base; |
1804 | int timeout = 20; | 1804 | int timeout = 20; |
1805 | unsigned long cookie; | 1805 | unsigned long cookie; |
1806 | 1806 | ||
1807 | DBG(2, "%s: %s\n", CARDNAME, __func__); | 1807 | DBG(2, "%s: %s\n", CARDNAME, __func__); |
1808 | 1808 | ||
1809 | cookie = probe_irq_on(); | 1809 | cookie = probe_irq_on(); |
1810 | 1810 | ||
1811 | /* | 1811 | /* |
1812 | * What I try to do here is trigger an ALLOC_INT. This is done | 1812 | * What I try to do here is trigger an ALLOC_INT. This is done |
1813 | * by allocating a small chunk of memory, which will give an interrupt | 1813 | * by allocating a small chunk of memory, which will give an interrupt |
1814 | * when done. | 1814 | * when done. |
1815 | */ | 1815 | */ |
1816 | /* enable ALLOCation interrupts ONLY */ | 1816 | /* enable ALLOCation interrupts ONLY */ |
1817 | SMC_SELECT_BANK(lp, 2); | 1817 | SMC_SELECT_BANK(lp, 2); |
1818 | SMC_SET_INT_MASK(lp, IM_ALLOC_INT); | 1818 | SMC_SET_INT_MASK(lp, IM_ALLOC_INT); |
1819 | 1819 | ||
1820 | /* | 1820 | /* |
1821 | * Allocate 512 bytes of memory. Note that the chip was just | 1821 | * Allocate 512 bytes of memory. Note that the chip was just |
1822 | * reset so all the memory is available | 1822 | * reset so all the memory is available |
1823 | */ | 1823 | */ |
1824 | SMC_SET_MMU_CMD(lp, MC_ALLOC | 1); | 1824 | SMC_SET_MMU_CMD(lp, MC_ALLOC | 1); |
1825 | 1825 | ||
1826 | /* | 1826 | /* |
1827 | * Wait until positive that the interrupt has been generated | 1827 | * Wait until positive that the interrupt has been generated |
1828 | */ | 1828 | */ |
1829 | do { | 1829 | do { |
1830 | int int_status; | 1830 | int int_status; |
1831 | udelay(10); | 1831 | udelay(10); |
1832 | int_status = SMC_GET_INT(lp); | 1832 | int_status = SMC_GET_INT(lp); |
1833 | if (int_status & IM_ALLOC_INT) | 1833 | if (int_status & IM_ALLOC_INT) |
1834 | break; /* got the interrupt */ | 1834 | break; /* got the interrupt */ |
1835 | } while (--timeout); | 1835 | } while (--timeout); |
1836 | 1836 | ||
1837 | /* | 1837 | /* |
1838 | * there is really nothing that I can do here if timeout fails, | 1838 | * there is really nothing that I can do here if timeout fails, |
1839 | * as autoirq_report will return a 0 anyway, which is what I | 1839 | * as autoirq_report will return a 0 anyway, which is what I |
1840 | * want in this case. Plus, the clean up is needed in both | 1840 | * want in this case. Plus, the clean up is needed in both |
1841 | * cases. | 1841 | * cases. |
1842 | */ | 1842 | */ |
1843 | 1843 | ||
1844 | /* and disable all interrupts again */ | 1844 | /* and disable all interrupts again */ |
1845 | SMC_SET_INT_MASK(lp, 0); | 1845 | SMC_SET_INT_MASK(lp, 0); |
1846 | 1846 | ||
1847 | /* and return what I found */ | 1847 | /* and return what I found */ |
1848 | return probe_irq_off(cookie); | 1848 | return probe_irq_off(cookie); |
1849 | } | 1849 | } |
1850 | 1850 | ||
1851 | /* | 1851 | /* |
1852 | * Function: smc_probe(unsigned long ioaddr) | 1852 | * Function: smc_probe(unsigned long ioaddr) |
1853 | * | 1853 | * |
1854 | * Purpose: | 1854 | * Purpose: |
1855 | * Tests to see if a given ioaddr points to an SMC91x chip. | 1855 | * Tests to see if a given ioaddr points to an SMC91x chip. |
1856 | * Returns a 0 on success | 1856 | * Returns a 0 on success |
1857 | * | 1857 | * |
1858 | * Algorithm: | 1858 | * Algorithm: |
1859 | * (1) see if the high byte of BANK_SELECT is 0x33 | 1859 | * (1) see if the high byte of BANK_SELECT is 0x33 |
1860 | * (2) compare the ioaddr with the base register's address | 1860 | * (2) compare the ioaddr with the base register's address |
1861 | * (3) see if I recognize the chip ID in the appropriate register | 1861 | * (3) see if I recognize the chip ID in the appropriate register |
1862 | * | 1862 | * |
1863 | * Here I do typical initialization tasks. | 1863 | * Here I do typical initialization tasks. |
1864 | * | 1864 | * |
1865 | * o Initialize the structure if needed | 1865 | * o Initialize the structure if needed |
1866 | * o print out my vanity message if not done so already | 1866 | * o print out my vanity message if not done so already |
1867 | * o print out what type of hardware is detected | 1867 | * o print out what type of hardware is detected |
1868 | * o print out the ethernet address | 1868 | * o print out the ethernet address |
1869 | * o find the IRQ | 1869 | * o find the IRQ |
1870 | * o set up my private data | 1870 | * o set up my private data |
1871 | * o configure the dev structure with my subroutines | 1871 | * o configure the dev structure with my subroutines |
1872 | * o actually GRAB the irq. | 1872 | * o actually GRAB the irq. |
1873 | * o GRAB the region | 1873 | * o GRAB the region |
1874 | */ | 1874 | */ |
1875 | static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr, | 1875 | static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr, |
1876 | unsigned long irq_flags) | 1876 | unsigned long irq_flags) |
1877 | { | 1877 | { |
1878 | struct smc_local *lp = netdev_priv(dev); | 1878 | struct smc_local *lp = netdev_priv(dev); |
1879 | static int version_printed = 0; | 1879 | static int version_printed = 0; |
1880 | int retval; | 1880 | int retval; |
1881 | unsigned int val, revision_register; | 1881 | unsigned int val, revision_register; |
1882 | const char *version_string; | 1882 | const char *version_string; |
1883 | 1883 | ||
1884 | DBG(2, "%s: %s\n", CARDNAME, __func__); | 1884 | DBG(2, "%s: %s\n", CARDNAME, __func__); |
1885 | 1885 | ||
1886 | /* First, see if the high byte is 0x33 */ | 1886 | /* First, see if the high byte is 0x33 */ |
1887 | val = SMC_CURRENT_BANK(lp); | 1887 | val = SMC_CURRENT_BANK(lp); |
1888 | DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val); | 1888 | DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val); |
1889 | if ((val & 0xFF00) != 0x3300) { | 1889 | if ((val & 0xFF00) != 0x3300) { |
1890 | if ((val & 0xFF) == 0x33) { | 1890 | if ((val & 0xFF) == 0x33) { |
1891 | printk(KERN_WARNING | 1891 | printk(KERN_WARNING |
1892 | "%s: Detected possible byte-swapped interface" | 1892 | "%s: Detected possible byte-swapped interface" |
1893 | " at IOADDR %p\n", CARDNAME, ioaddr); | 1893 | " at IOADDR %p\n", CARDNAME, ioaddr); |
1894 | } | 1894 | } |
1895 | retval = -ENODEV; | 1895 | retval = -ENODEV; |
1896 | goto err_out; | 1896 | goto err_out; |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | /* | 1899 | /* |
1900 | * The above MIGHT indicate a device, but I need to write to | 1900 | * The above MIGHT indicate a device, but I need to write to |
1901 | * further test this. | 1901 | * further test this. |
1902 | */ | 1902 | */ |
1903 | SMC_SELECT_BANK(lp, 0); | 1903 | SMC_SELECT_BANK(lp, 0); |
1904 | val = SMC_CURRENT_BANK(lp); | 1904 | val = SMC_CURRENT_BANK(lp); |
1905 | if ((val & 0xFF00) != 0x3300) { | 1905 | if ((val & 0xFF00) != 0x3300) { |
1906 | retval = -ENODEV; | 1906 | retval = -ENODEV; |
1907 | goto err_out; | 1907 | goto err_out; |
1908 | } | 1908 | } |
1909 | 1909 | ||
1910 | /* | 1910 | /* |
1911 | * well, we've already written once, so hopefully another | 1911 | * well, we've already written once, so hopefully another |
1912 | * time won't hurt. This time, I need to switch the bank | 1912 | * time won't hurt. This time, I need to switch the bank |
1913 | * register to bank 1, so I can access the base address | 1913 | * register to bank 1, so I can access the base address |
1914 | * register | 1914 | * register |
1915 | */ | 1915 | */ |
1916 | SMC_SELECT_BANK(lp, 1); | 1916 | SMC_SELECT_BANK(lp, 1); |
1917 | val = SMC_GET_BASE(lp); | 1917 | val = SMC_GET_BASE(lp); |
1918 | val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; | 1918 | val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; |
1919 | if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { | 1919 | if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { |
1920 | printk("%s: IOADDR %p doesn't match configuration (%x).\n", | 1920 | printk("%s: IOADDR %p doesn't match configuration (%x).\n", |
1921 | CARDNAME, ioaddr, val); | 1921 | CARDNAME, ioaddr, val); |
1922 | } | 1922 | } |
1923 | 1923 | ||
1924 | /* | 1924 | /* |
1925 | * check if the revision register is something that I | 1925 | * check if the revision register is something that I |
1926 | * recognize. These might need to be added to later, | 1926 | * recognize. These might need to be added to later, |
1927 | * as future revisions could be added. | 1927 | * as future revisions could be added. |
1928 | */ | 1928 | */ |
1929 | SMC_SELECT_BANK(lp, 3); | 1929 | SMC_SELECT_BANK(lp, 3); |
1930 | revision_register = SMC_GET_REV(lp); | 1930 | revision_register = SMC_GET_REV(lp); |
1931 | DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register); | 1931 | DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register); |
1932 | version_string = chip_ids[ (revision_register >> 4) & 0xF]; | 1932 | version_string = chip_ids[ (revision_register >> 4) & 0xF]; |
1933 | if (!version_string || (revision_register & 0xff00) != 0x3300) { | 1933 | if (!version_string || (revision_register & 0xff00) != 0x3300) { |
1934 | /* I don't recognize this chip, so... */ | 1934 | /* I don't recognize this chip, so... */ |
1935 | printk("%s: IO %p: Unrecognized revision register 0x%04x" | 1935 | printk("%s: IO %p: Unrecognized revision register 0x%04x" |
1936 | ", Contact author.\n", CARDNAME, | 1936 | ", Contact author.\n", CARDNAME, |
1937 | ioaddr, revision_register); | 1937 | ioaddr, revision_register); |
1938 | 1938 | ||
1939 | retval = -ENODEV; | 1939 | retval = -ENODEV; |
1940 | goto err_out; | 1940 | goto err_out; |
1941 | } | 1941 | } |
1942 | 1942 | ||
1943 | /* At this point I'll assume that the chip is an SMC91x. */ | 1943 | /* At this point I'll assume that the chip is an SMC91x. */ |
1944 | if (version_printed++ == 0) | 1944 | if (version_printed++ == 0) |
1945 | printk("%s", version); | 1945 | printk("%s", version); |
1946 | 1946 | ||
1947 | /* fill in some of the fields */ | 1947 | /* fill in some of the fields */ |
1948 | dev->base_addr = (unsigned long)ioaddr; | 1948 | dev->base_addr = (unsigned long)ioaddr; |
1949 | lp->base = ioaddr; | 1949 | lp->base = ioaddr; |
1950 | lp->version = revision_register & 0xff; | 1950 | lp->version = revision_register & 0xff; |
1951 | spin_lock_init(&lp->lock); | 1951 | spin_lock_init(&lp->lock); |
1952 | 1952 | ||
1953 | /* Get the MAC address */ | 1953 | /* Get the MAC address */ |
1954 | SMC_SELECT_BANK(lp, 1); | 1954 | SMC_SELECT_BANK(lp, 1); |
1955 | SMC_GET_MAC_ADDR(lp, dev->dev_addr); | 1955 | SMC_GET_MAC_ADDR(lp, dev->dev_addr); |
1956 | 1956 | ||
1957 | /* now, reset the chip, and put it into a known state */ | 1957 | /* now, reset the chip, and put it into a known state */ |
1958 | smc_reset(dev); | 1958 | smc_reset(dev); |
1959 | 1959 | ||
1960 | /* | 1960 | /* |
1961 | * If dev->irq is 0, then the device has to be banged on to see | 1961 | * If dev->irq is 0, then the device has to be banged on to see |
1962 | * what the IRQ is. | 1962 | * what the IRQ is. |
1963 | * | 1963 | * |
1964 | * This banging doesn't always detect the IRQ, for unknown reasons. | 1964 | * This banging doesn't always detect the IRQ, for unknown reasons. |
1965 | * a workaround is to reset the chip and try again. | 1965 | * a workaround is to reset the chip and try again. |
1966 | * | 1966 | * |
1967 | * Interestingly, the DOS packet driver *SETS* the IRQ on the card to | 1967 | * Interestingly, the DOS packet driver *SETS* the IRQ on the card to |
1968 | * be what is requested on the command line. I don't do that, mostly | 1968 | * be what is requested on the command line. I don't do that, mostly |
1969 | * because the card that I have uses a non-standard method of accessing | 1969 | * because the card that I have uses a non-standard method of accessing |
1970 | * the IRQs, and because this _should_ work in most configurations. | 1970 | * the IRQs, and because this _should_ work in most configurations. |
1971 | * | 1971 | * |
1972 | * Specifying an IRQ is done with the assumption that the user knows | 1972 | * Specifying an IRQ is done with the assumption that the user knows |
1973 | * what (s)he is doing. No checking is done!!!! | 1973 | * what (s)he is doing. No checking is done!!!! |
1974 | */ | 1974 | */ |
1975 | if (dev->irq < 1) { | 1975 | if (dev->irq < 1) { |
1976 | int trials; | 1976 | int trials; |
1977 | 1977 | ||
1978 | trials = 3; | 1978 | trials = 3; |
1979 | while (trials--) { | 1979 | while (trials--) { |
1980 | dev->irq = smc_findirq(lp); | 1980 | dev->irq = smc_findirq(lp); |
1981 | if (dev->irq) | 1981 | if (dev->irq) |
1982 | break; | 1982 | break; |
1983 | /* kick the card and try again */ | 1983 | /* kick the card and try again */ |
1984 | smc_reset(dev); | 1984 | smc_reset(dev); |
1985 | } | 1985 | } |
1986 | } | 1986 | } |
1987 | if (dev->irq == 0) { | 1987 | if (dev->irq == 0) { |
1988 | printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n", | 1988 | printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n", |
1989 | dev->name); | 1989 | dev->name); |
1990 | retval = -ENODEV; | 1990 | retval = -ENODEV; |
1991 | goto err_out; | 1991 | goto err_out; |
1992 | } | 1992 | } |
1993 | dev->irq = irq_canonicalize(dev->irq); | 1993 | dev->irq = irq_canonicalize(dev->irq); |
1994 | 1994 | ||
1995 | /* Fill in the fields of the device structure with ethernet values. */ | 1995 | /* Fill in the fields of the device structure with ethernet values. */ |
1996 | ether_setup(dev); | 1996 | ether_setup(dev); |
1997 | 1997 | ||
1998 | dev->watchdog_timeo = msecs_to_jiffies(watchdog); | 1998 | dev->watchdog_timeo = msecs_to_jiffies(watchdog); |
1999 | dev->netdev_ops = &smc_netdev_ops; | 1999 | dev->netdev_ops = &smc_netdev_ops; |
2000 | dev->ethtool_ops = &smc_ethtool_ops; | 2000 | dev->ethtool_ops = &smc_ethtool_ops; |
2001 | 2001 | ||
2002 | tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); | 2002 | tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); |
2003 | INIT_WORK(&lp->phy_configure, smc_phy_configure); | 2003 | INIT_WORK(&lp->phy_configure, smc_phy_configure); |
2004 | lp->dev = dev; | 2004 | lp->dev = dev; |
2005 | lp->mii.phy_id_mask = 0x1f; | 2005 | lp->mii.phy_id_mask = 0x1f; |
2006 | lp->mii.reg_num_mask = 0x1f; | 2006 | lp->mii.reg_num_mask = 0x1f; |
2007 | lp->mii.force_media = 0; | 2007 | lp->mii.force_media = 0; |
2008 | lp->mii.full_duplex = 0; | 2008 | lp->mii.full_duplex = 0; |
2009 | lp->mii.dev = dev; | 2009 | lp->mii.dev = dev; |
2010 | lp->mii.mdio_read = smc_phy_read; | 2010 | lp->mii.mdio_read = smc_phy_read; |
2011 | lp->mii.mdio_write = smc_phy_write; | 2011 | lp->mii.mdio_write = smc_phy_write; |
2012 | 2012 | ||
2013 | /* | 2013 | /* |
2014 | * Locate the phy, if any. | 2014 | * Locate the phy, if any. |
2015 | */ | 2015 | */ |
2016 | if (lp->version >= (CHIP_91100 << 4)) | 2016 | if (lp->version >= (CHIP_91100 << 4)) |
2017 | smc_phy_detect(dev); | 2017 | smc_phy_detect(dev); |
2018 | 2018 | ||
2019 | /* then shut everything down to save power */ | 2019 | /* then shut everything down to save power */ |
2020 | smc_shutdown(dev); | 2020 | smc_shutdown(dev); |
2021 | smc_phy_powerdown(dev); | 2021 | smc_phy_powerdown(dev); |
2022 | 2022 | ||
2023 | /* Set default parameters */ | 2023 | /* Set default parameters */ |
2024 | lp->msg_enable = NETIF_MSG_LINK; | 2024 | lp->msg_enable = NETIF_MSG_LINK; |
2025 | lp->ctl_rfduplx = 0; | 2025 | lp->ctl_rfduplx = 0; |
2026 | lp->ctl_rspeed = 10; | 2026 | lp->ctl_rspeed = 10; |
2027 | 2027 | ||
2028 | if (lp->version >= (CHIP_91100 << 4)) { | 2028 | if (lp->version >= (CHIP_91100 << 4)) { |
2029 | lp->ctl_rfduplx = 1; | 2029 | lp->ctl_rfduplx = 1; |
2030 | lp->ctl_rspeed = 100; | 2030 | lp->ctl_rspeed = 100; |
2031 | } | 2031 | } |
2032 | 2032 | ||
2033 | /* Grab the IRQ */ | 2033 | /* Grab the IRQ */ |
2034 | retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev); | 2034 | retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev); |
2035 | if (retval) | 2035 | if (retval) |
2036 | goto err_out; | 2036 | goto err_out; |
2037 | 2037 | ||
2038 | #ifdef CONFIG_ARCH_PXA | 2038 | #ifdef CONFIG_ARCH_PXA |
2039 | # ifdef SMC_USE_PXA_DMA | 2039 | # ifdef SMC_USE_PXA_DMA |
2040 | lp->cfg.flags |= SMC91X_USE_DMA; | 2040 | lp->cfg.flags |= SMC91X_USE_DMA; |
2041 | # endif | 2041 | # endif |
2042 | if (lp->cfg.flags & SMC91X_USE_DMA) { | 2042 | if (lp->cfg.flags & SMC91X_USE_DMA) { |
2043 | int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, | 2043 | int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, |
2044 | smc_pxa_dma_irq, NULL); | 2044 | smc_pxa_dma_irq, NULL); |
2045 | if (dma >= 0) | 2045 | if (dma >= 0) |
2046 | dev->dma = dma; | 2046 | dev->dma = dma; |
2047 | } | 2047 | } |
2048 | #endif | 2048 | #endif |
2049 | 2049 | ||
2050 | retval = register_netdev(dev); | 2050 | retval = register_netdev(dev); |
2051 | if (retval == 0) { | 2051 | if (retval == 0) { |
2052 | /* now, print out the card info, in a short format.. */ | 2052 | /* now, print out the card info, in a short format.. */ |
2053 | printk("%s: %s (rev %d) at %p IRQ %d", | 2053 | printk("%s: %s (rev %d) at %p IRQ %d", |
2054 | dev->name, version_string, revision_register & 0x0f, | 2054 | dev->name, version_string, revision_register & 0x0f, |
2055 | lp->base, dev->irq); | 2055 | lp->base, dev->irq); |
2056 | 2056 | ||
2057 | if (dev->dma != (unsigned char)-1) | 2057 | if (dev->dma != (unsigned char)-1) |
2058 | printk(" DMA %d", dev->dma); | 2058 | printk(" DMA %d", dev->dma); |
2059 | 2059 | ||
2060 | printk("%s%s\n", | 2060 | printk("%s%s\n", |
2061 | lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "", | 2061 | lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "", |
2062 | THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); | 2062 | THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); |
2063 | 2063 | ||
2064 | if (!is_valid_ether_addr(dev->dev_addr)) { | 2064 | if (!is_valid_ether_addr(dev->dev_addr)) { |
2065 | printk("%s: Invalid ethernet MAC address. Please " | 2065 | printk("%s: Invalid ethernet MAC address. Please " |
2066 | "set using ifconfig\n", dev->name); | 2066 | "set using ifconfig\n", dev->name); |
2067 | } else { | 2067 | } else { |
2068 | /* Print the Ethernet address */ | 2068 | /* Print the Ethernet address */ |
2069 | printk("%s: Ethernet addr: %pM\n", | 2069 | printk("%s: Ethernet addr: %pM\n", |
2070 | dev->name, dev->dev_addr); | 2070 | dev->name, dev->dev_addr); |
2071 | } | 2071 | } |
2072 | 2072 | ||
2073 | if (lp->phy_type == 0) { | 2073 | if (lp->phy_type == 0) { |
2074 | PRINTK("%s: No PHY found\n", dev->name); | 2074 | PRINTK("%s: No PHY found\n", dev->name); |
2075 | } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) { | 2075 | } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) { |
2076 | PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name); | 2076 | PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name); |
2077 | } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) { | 2077 | } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) { |
2078 | PRINTK("%s: PHY LAN83C180\n", dev->name); | 2078 | PRINTK("%s: PHY LAN83C180\n", dev->name); |
2079 | } | 2079 | } |
2080 | } | 2080 | } |
2081 | 2081 | ||
2082 | err_out: | 2082 | err_out: |
2083 | #ifdef CONFIG_ARCH_PXA | 2083 | #ifdef CONFIG_ARCH_PXA |
2084 | if (retval && dev->dma != (unsigned char)-1) | 2084 | if (retval && dev->dma != (unsigned char)-1) |
2085 | pxa_free_dma(dev->dma); | 2085 | pxa_free_dma(dev->dma); |
2086 | #endif | 2086 | #endif |
2087 | return retval; | 2087 | return retval; |
2088 | } | 2088 | } |
2089 | 2089 | ||
2090 | static int smc_enable_device(struct platform_device *pdev) | 2090 | static int smc_enable_device(struct platform_device *pdev) |
2091 | { | 2091 | { |
2092 | struct net_device *ndev = platform_get_drvdata(pdev); | 2092 | struct net_device *ndev = platform_get_drvdata(pdev); |
2093 | struct smc_local *lp = netdev_priv(ndev); | 2093 | struct smc_local *lp = netdev_priv(ndev); |
2094 | unsigned long flags; | 2094 | unsigned long flags; |
2095 | unsigned char ecor, ecsr; | 2095 | unsigned char ecor, ecsr; |
2096 | void __iomem *addr; | 2096 | void __iomem *addr; |
2097 | struct resource * res; | 2097 | struct resource * res; |
2098 | 2098 | ||
2099 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); | 2099 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); |
2100 | if (!res) | 2100 | if (!res) |
2101 | return 0; | 2101 | return 0; |
2102 | 2102 | ||
2103 | /* | 2103 | /* |
2104 | * Map the attribute space. This is overkill, but clean. | 2104 | * Map the attribute space. This is overkill, but clean. |
2105 | */ | 2105 | */ |
2106 | addr = ioremap(res->start, ATTRIB_SIZE); | 2106 | addr = ioremap(res->start, ATTRIB_SIZE); |
2107 | if (!addr) | 2107 | if (!addr) |
2108 | return -ENOMEM; | 2108 | return -ENOMEM; |
2109 | 2109 | ||
2110 | /* | 2110 | /* |
2111 | * Reset the device. We must disable IRQs around this | 2111 | * Reset the device. We must disable IRQs around this |
2112 | * since a reset causes the IRQ line become active. | 2112 | * since a reset causes the IRQ line become active. |
2113 | */ | 2113 | */ |
2114 | local_irq_save(flags); | 2114 | local_irq_save(flags); |
2115 | ecor = readb(addr + (ECOR << SMC_IO_SHIFT)) & ~ECOR_RESET; | 2115 | ecor = readb(addr + (ECOR << SMC_IO_SHIFT)) & ~ECOR_RESET; |
2116 | writeb(ecor | ECOR_RESET, addr + (ECOR << SMC_IO_SHIFT)); | 2116 | writeb(ecor | ECOR_RESET, addr + (ECOR << SMC_IO_SHIFT)); |
2117 | readb(addr + (ECOR << SMC_IO_SHIFT)); | 2117 | readb(addr + (ECOR << SMC_IO_SHIFT)); |
2118 | 2118 | ||
2119 | /* | 2119 | /* |
2120 | * Wait 100us for the chip to reset. | 2120 | * Wait 100us for the chip to reset. |
2121 | */ | 2121 | */ |
2122 | udelay(100); | 2122 | udelay(100); |
2123 | 2123 | ||
2124 | /* | 2124 | /* |
2125 | * The device will ignore all writes to the enable bit while | 2125 | * The device will ignore all writes to the enable bit while |
2126 | * reset is asserted, even if the reset bit is cleared in the | 2126 | * reset is asserted, even if the reset bit is cleared in the |
2127 | * same write. Must clear reset first, then enable the device. | 2127 | * same write. Must clear reset first, then enable the device. |
2128 | */ | 2128 | */ |
2129 | writeb(ecor, addr + (ECOR << SMC_IO_SHIFT)); | 2129 | writeb(ecor, addr + (ECOR << SMC_IO_SHIFT)); |
2130 | writeb(ecor | ECOR_ENABLE, addr + (ECOR << SMC_IO_SHIFT)); | 2130 | writeb(ecor | ECOR_ENABLE, addr + (ECOR << SMC_IO_SHIFT)); |
2131 | 2131 | ||
2132 | /* | 2132 | /* |
2133 | * Set the appropriate byte/word mode. | 2133 | * Set the appropriate byte/word mode. |
2134 | */ | 2134 | */ |
2135 | ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; | 2135 | ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; |
2136 | if (!SMC_16BIT(lp)) | 2136 | if (!SMC_16BIT(lp)) |
2137 | ecsr |= ECSR_IOIS8; | 2137 | ecsr |= ECSR_IOIS8; |
2138 | writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); | 2138 | writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); |
2139 | local_irq_restore(flags); | 2139 | local_irq_restore(flags); |
2140 | 2140 | ||
2141 | iounmap(addr); | 2141 | iounmap(addr); |
2142 | 2142 | ||
2143 | /* | 2143 | /* |
2144 | * Wait for the chip to wake up. We could poll the control | 2144 | * Wait for the chip to wake up. We could poll the control |
2145 | * register in the main register space, but that isn't mapped | 2145 | * register in the main register space, but that isn't mapped |
2146 | * yet. We know this is going to take 750us. | 2146 | * yet. We know this is going to take 750us. |
2147 | */ | 2147 | */ |
2148 | msleep(1); | 2148 | msleep(1); |
2149 | 2149 | ||
2150 | return 0; | 2150 | return 0; |
2151 | } | 2151 | } |
2152 | 2152 | ||
2153 | static int smc_request_attrib(struct platform_device *pdev, | 2153 | static int smc_request_attrib(struct platform_device *pdev, |
2154 | struct net_device *ndev) | 2154 | struct net_device *ndev) |
2155 | { | 2155 | { |
2156 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); | 2156 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); |
2157 | struct smc_local *lp __maybe_unused = netdev_priv(ndev); | 2157 | struct smc_local *lp __maybe_unused = netdev_priv(ndev); |
2158 | 2158 | ||
2159 | if (!res) | 2159 | if (!res) |
2160 | return 0; | 2160 | return 0; |
2161 | 2161 | ||
2162 | if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME)) | 2162 | if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME)) |
2163 | return -EBUSY; | 2163 | return -EBUSY; |
2164 | 2164 | ||
2165 | return 0; | 2165 | return 0; |
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | static void smc_release_attrib(struct platform_device *pdev, | 2168 | static void smc_release_attrib(struct platform_device *pdev, |
2169 | struct net_device *ndev) | 2169 | struct net_device *ndev) |
2170 | { | 2170 | { |
2171 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); | 2171 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); |
2172 | struct smc_local *lp __maybe_unused = netdev_priv(ndev); | 2172 | struct smc_local *lp __maybe_unused = netdev_priv(ndev); |
2173 | 2173 | ||
2174 | if (res) | 2174 | if (res) |
2175 | release_mem_region(res->start, ATTRIB_SIZE); | 2175 | release_mem_region(res->start, ATTRIB_SIZE); |
2176 | } | 2176 | } |
2177 | 2177 | ||
2178 | static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) | 2178 | static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) |
2179 | { | 2179 | { |
2180 | if (SMC_CAN_USE_DATACS) { | 2180 | if (SMC_CAN_USE_DATACS) { |
2181 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); | 2181 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); |
2182 | struct smc_local *lp = netdev_priv(ndev); | 2182 | struct smc_local *lp = netdev_priv(ndev); |
2183 | 2183 | ||
2184 | if (!res) | 2184 | if (!res) |
2185 | return; | 2185 | return; |
2186 | 2186 | ||
2187 | if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { | 2187 | if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { |
2188 | printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); | 2188 | printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); |
2189 | return; | 2189 | return; |
2190 | } | 2190 | } |
2191 | 2191 | ||
2192 | lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); | 2192 | lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); |
2193 | } | 2193 | } |
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) | 2196 | static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) |
2197 | { | 2197 | { |
2198 | if (SMC_CAN_USE_DATACS) { | 2198 | if (SMC_CAN_USE_DATACS) { |
2199 | struct smc_local *lp = netdev_priv(ndev); | 2199 | struct smc_local *lp = netdev_priv(ndev); |
2200 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); | 2200 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); |
2201 | 2201 | ||
2202 | if (lp->datacs) | 2202 | if (lp->datacs) |
2203 | iounmap(lp->datacs); | 2203 | iounmap(lp->datacs); |
2204 | 2204 | ||
2205 | lp->datacs = NULL; | 2205 | lp->datacs = NULL; |
2206 | 2206 | ||
2207 | if (res) | 2207 | if (res) |
2208 | release_mem_region(res->start, SMC_DATA_EXTENT); | 2208 | release_mem_region(res->start, SMC_DATA_EXTENT); |
2209 | } | 2209 | } |
2210 | } | 2210 | } |
2211 | 2211 | ||
2212 | /* | 2212 | /* |
2213 | * smc_init(void) | 2213 | * smc_init(void) |
2214 | * Input parameters: | 2214 | * Input parameters: |
2215 | * dev->base_addr == 0, try to find all possible locations | 2215 | * dev->base_addr == 0, try to find all possible locations |
2216 | * dev->base_addr > 0x1ff, this is the address to check | 2216 | * dev->base_addr > 0x1ff, this is the address to check |
2217 | * dev->base_addr == <anything else>, return failure code | 2217 | * dev->base_addr == <anything else>, return failure code |
2218 | * | 2218 | * |
2219 | * Output: | 2219 | * Output: |
2220 | * 0 --> there is a device | 2220 | * 0 --> there is a device |
2221 | * anything else, error | 2221 | * anything else, error |
2222 | */ | 2222 | */ |
2223 | static int __devinit smc_drv_probe(struct platform_device *pdev) | 2223 | static int __devinit smc_drv_probe(struct platform_device *pdev) |
2224 | { | 2224 | { |
2225 | struct smc91x_platdata *pd = pdev->dev.platform_data; | 2225 | struct smc91x_platdata *pd = pdev->dev.platform_data; |
2226 | struct smc_local *lp; | 2226 | struct smc_local *lp; |
2227 | struct net_device *ndev; | 2227 | struct net_device *ndev; |
2228 | struct resource *res, *ires; | 2228 | struct resource *res, *ires; |
2229 | unsigned int __iomem *addr; | 2229 | unsigned int __iomem *addr; |
2230 | unsigned long irq_flags = SMC_IRQ_FLAGS; | 2230 | unsigned long irq_flags = SMC_IRQ_FLAGS; |
2231 | int ret; | 2231 | int ret; |
2232 | 2232 | ||
2233 | ndev = alloc_etherdev(sizeof(struct smc_local)); | 2233 | ndev = alloc_etherdev(sizeof(struct smc_local)); |
2234 | if (!ndev) { | 2234 | if (!ndev) { |
2235 | printk("%s: could not allocate device.\n", CARDNAME); | 2235 | printk("%s: could not allocate device.\n", CARDNAME); |
2236 | ret = -ENOMEM; | 2236 | ret = -ENOMEM; |
2237 | goto out; | 2237 | goto out; |
2238 | } | 2238 | } |
2239 | SET_NETDEV_DEV(ndev, &pdev->dev); | 2239 | SET_NETDEV_DEV(ndev, &pdev->dev); |
2240 | 2240 | ||
2241 | /* get configuration from platform data, only allow use of | 2241 | /* get configuration from platform data, only allow use of |
2242 | * bus width if both SMC_CAN_USE_xxx and SMC91X_USE_xxx are set. | 2242 | * bus width if both SMC_CAN_USE_xxx and SMC91X_USE_xxx are set. |
2243 | */ | 2243 | */ |
2244 | 2244 | ||
2245 | lp = netdev_priv(ndev); | 2245 | lp = netdev_priv(ndev); |
2246 | 2246 | ||
2247 | if (pd) { | 2247 | if (pd) { |
2248 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); | 2248 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); |
2249 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); | 2249 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); |
2250 | } else { | 2250 | } else { |
2251 | lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; | 2251 | lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; |
2252 | lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; | 2252 | lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; |
2253 | lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; | 2253 | lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; |
2254 | lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0; | 2254 | lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0; |
2255 | } | 2255 | } |
2256 | 2256 | ||
2257 | if (!lp->cfg.leda && !lp->cfg.ledb) { | 2257 | if (!lp->cfg.leda && !lp->cfg.ledb) { |
2258 | lp->cfg.leda = RPC_LSA_DEFAULT; | 2258 | lp->cfg.leda = RPC_LSA_DEFAULT; |
2259 | lp->cfg.ledb = RPC_LSB_DEFAULT; | 2259 | lp->cfg.ledb = RPC_LSB_DEFAULT; |
2260 | } | 2260 | } |
2261 | 2261 | ||
2262 | ndev->dma = (unsigned char)-1; | 2262 | ndev->dma = (unsigned char)-1; |
2263 | 2263 | ||
2264 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); | 2264 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); |
2265 | if (!res) | 2265 | if (!res) |
2266 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2266 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2267 | if (!res) { | 2267 | if (!res) { |
2268 | ret = -ENODEV; | 2268 | ret = -ENODEV; |
2269 | goto out_free_netdev; | 2269 | goto out_free_netdev; |
2270 | } | 2270 | } |
2271 | 2271 | ||
2272 | 2272 | ||
2273 | if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) { | 2273 | if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) { |
2274 | ret = -EBUSY; | 2274 | ret = -EBUSY; |
2275 | goto out_free_netdev; | 2275 | goto out_free_netdev; |
2276 | } | 2276 | } |
2277 | 2277 | ||
2278 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 2278 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
2279 | if (!ires) { | 2279 | if (!ires) { |
2280 | ret = -ENODEV; | 2280 | ret = -ENODEV; |
2281 | goto out_release_io; | 2281 | goto out_release_io; |
2282 | } | 2282 | } |
2283 | 2283 | ||
2284 | ndev->irq = ires->start; | 2284 | ndev->irq = ires->start; |
2285 | 2285 | ||
2286 | if (ires->flags & IRQF_TRIGGER_MASK) | 2286 | if (ires->flags & IRQF_TRIGGER_MASK) |
2287 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; | 2287 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; |
2288 | 2288 | ||
2289 | ret = smc_request_attrib(pdev, ndev); | 2289 | ret = smc_request_attrib(pdev, ndev); |
2290 | if (ret) | 2290 | if (ret) |
2291 | goto out_release_io; | 2291 | goto out_release_io; |
2292 | #if defined(CONFIG_SA1100_ASSABET) | 2292 | #if defined(CONFIG_SA1100_ASSABET) |
2293 | NCR_0 |= NCR_ENET_OSC_EN; | 2293 | NCR_0 |= NCR_ENET_OSC_EN; |
2294 | #endif | 2294 | #endif |
2295 | platform_set_drvdata(pdev, ndev); | 2295 | platform_set_drvdata(pdev, ndev); |
2296 | ret = smc_enable_device(pdev); | 2296 | ret = smc_enable_device(pdev); |
2297 | if (ret) | 2297 | if (ret) |
2298 | goto out_release_attrib; | 2298 | goto out_release_attrib; |
2299 | 2299 | ||
2300 | addr = ioremap(res->start, SMC_IO_EXTENT); | 2300 | addr = ioremap(res->start, SMC_IO_EXTENT); |
2301 | if (!addr) { | 2301 | if (!addr) { |
2302 | ret = -ENOMEM; | 2302 | ret = -ENOMEM; |
2303 | goto out_release_attrib; | 2303 | goto out_release_attrib; |
2304 | } | 2304 | } |
2305 | 2305 | ||
2306 | #ifdef CONFIG_ARCH_PXA | 2306 | #ifdef CONFIG_ARCH_PXA |
2307 | { | 2307 | { |
2308 | struct smc_local *lp = netdev_priv(ndev); | 2308 | struct smc_local *lp = netdev_priv(ndev); |
2309 | lp->device = &pdev->dev; | 2309 | lp->device = &pdev->dev; |
2310 | lp->physaddr = res->start; | 2310 | lp->physaddr = res->start; |
2311 | } | 2311 | } |
2312 | #endif | 2312 | #endif |
2313 | 2313 | ||
2314 | ret = smc_probe(ndev, addr, irq_flags); | 2314 | ret = smc_probe(ndev, addr, irq_flags); |
2315 | if (ret != 0) | 2315 | if (ret != 0) |
2316 | goto out_iounmap; | 2316 | goto out_iounmap; |
2317 | 2317 | ||
2318 | smc_request_datacs(pdev, ndev); | 2318 | smc_request_datacs(pdev, ndev); |
2319 | 2319 | ||
2320 | return 0; | 2320 | return 0; |
2321 | 2321 | ||
2322 | out_iounmap: | 2322 | out_iounmap: |
2323 | platform_set_drvdata(pdev, NULL); | 2323 | platform_set_drvdata(pdev, NULL); |
2324 | iounmap(addr); | 2324 | iounmap(addr); |
2325 | out_release_attrib: | 2325 | out_release_attrib: |
2326 | smc_release_attrib(pdev, ndev); | 2326 | smc_release_attrib(pdev, ndev); |
2327 | out_release_io: | 2327 | out_release_io: |
2328 | release_mem_region(res->start, SMC_IO_EXTENT); | 2328 | release_mem_region(res->start, SMC_IO_EXTENT); |
2329 | out_free_netdev: | 2329 | out_free_netdev: |
2330 | free_netdev(ndev); | 2330 | free_netdev(ndev); |
2331 | out: | 2331 | out: |
2332 | printk("%s: not found (%d).\n", CARDNAME, ret); | 2332 | printk("%s: not found (%d).\n", CARDNAME, ret); |
2333 | 2333 | ||
2334 | return ret; | 2334 | return ret; |
2335 | } | 2335 | } |
2336 | 2336 | ||
2337 | static int __devexit smc_drv_remove(struct platform_device *pdev) | 2337 | static int __devexit smc_drv_remove(struct platform_device *pdev) |
2338 | { | 2338 | { |
2339 | struct net_device *ndev = platform_get_drvdata(pdev); | 2339 | struct net_device *ndev = platform_get_drvdata(pdev); |
2340 | struct smc_local *lp = netdev_priv(ndev); | 2340 | struct smc_local *lp = netdev_priv(ndev); |
2341 | struct resource *res; | 2341 | struct resource *res; |
2342 | 2342 | ||
2343 | platform_set_drvdata(pdev, NULL); | 2343 | platform_set_drvdata(pdev, NULL); |
2344 | 2344 | ||
2345 | unregister_netdev(ndev); | 2345 | unregister_netdev(ndev); |
2346 | 2346 | ||
2347 | free_irq(ndev->irq, ndev); | 2347 | free_irq(ndev->irq, ndev); |
2348 | 2348 | ||
2349 | #ifdef CONFIG_ARCH_PXA | 2349 | #ifdef CONFIG_ARCH_PXA |
2350 | if (ndev->dma != (unsigned char)-1) | 2350 | if (ndev->dma != (unsigned char)-1) |
2351 | pxa_free_dma(ndev->dma); | 2351 | pxa_free_dma(ndev->dma); |
2352 | #endif | 2352 | #endif |
2353 | iounmap(lp->base); | 2353 | iounmap(lp->base); |
2354 | 2354 | ||
2355 | smc_release_datacs(pdev,ndev); | 2355 | smc_release_datacs(pdev,ndev); |
2356 | smc_release_attrib(pdev,ndev); | 2356 | smc_release_attrib(pdev,ndev); |
2357 | 2357 | ||
2358 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); | 2358 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); |
2359 | if (!res) | 2359 | if (!res) |
2360 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2360 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2361 | release_mem_region(res->start, SMC_IO_EXTENT); | 2361 | release_mem_region(res->start, SMC_IO_EXTENT); |
2362 | 2362 | ||
2363 | free_netdev(ndev); | 2363 | free_netdev(ndev); |
2364 | 2364 | ||
2365 | return 0; | 2365 | return 0; |
2366 | } | 2366 | } |
2367 | 2367 | ||
2368 | static int smc_drv_suspend(struct platform_device *dev, pm_message_t state) | 2368 | static int smc_drv_suspend(struct platform_device *dev, pm_message_t state) |
2369 | { | 2369 | { |
2370 | struct net_device *ndev = platform_get_drvdata(dev); | 2370 | struct net_device *ndev = platform_get_drvdata(dev); |
2371 | 2371 | ||
2372 | if (ndev) { | 2372 | if (ndev) { |
2373 | if (netif_running(ndev)) { | 2373 | if (netif_running(ndev)) { |
2374 | netif_device_detach(ndev); | 2374 | netif_device_detach(ndev); |
2375 | smc_shutdown(ndev); | 2375 | smc_shutdown(ndev); |
2376 | smc_phy_powerdown(ndev); | 2376 | smc_phy_powerdown(ndev); |
2377 | } | 2377 | } |
2378 | } | 2378 | } |
2379 | return 0; | 2379 | return 0; |
2380 | } | 2380 | } |
2381 | 2381 | ||
2382 | static int smc_drv_resume(struct platform_device *dev) | 2382 | static int smc_drv_resume(struct platform_device *dev) |
2383 | { | 2383 | { |
2384 | struct net_device *ndev = platform_get_drvdata(dev); | 2384 | struct net_device *ndev = platform_get_drvdata(dev); |
2385 | 2385 | ||
2386 | if (ndev) { | 2386 | if (ndev) { |
2387 | struct smc_local *lp = netdev_priv(ndev); | 2387 | struct smc_local *lp = netdev_priv(ndev); |
2388 | smc_enable_device(dev); | 2388 | smc_enable_device(dev); |
2389 | if (netif_running(ndev)) { | 2389 | if (netif_running(ndev)) { |
2390 | smc_reset(ndev); | 2390 | smc_reset(ndev); |
2391 | smc_enable(ndev); | 2391 | smc_enable(ndev); |
2392 | if (lp->phy_type != 0) | 2392 | if (lp->phy_type != 0) |
2393 | smc_phy_configure(&lp->phy_configure); | 2393 | smc_phy_configure(&lp->phy_configure); |
2394 | netif_device_attach(ndev); | 2394 | netif_device_attach(ndev); |
2395 | } | 2395 | } |
2396 | } | 2396 | } |
2397 | return 0; | 2397 | return 0; |
2398 | } | 2398 | } |
2399 | 2399 | ||
2400 | static struct platform_driver smc_driver = { | 2400 | static struct platform_driver smc_driver = { |
2401 | .probe = smc_drv_probe, | 2401 | .probe = smc_drv_probe, |
2402 | .remove = __devexit_p(smc_drv_remove), | 2402 | .remove = __devexit_p(smc_drv_remove), |
2403 | .suspend = smc_drv_suspend, | 2403 | .suspend = smc_drv_suspend, |
2404 | .resume = smc_drv_resume, | 2404 | .resume = smc_drv_resume, |
2405 | .driver = { | 2405 | .driver = { |
2406 | .name = CARDNAME, | 2406 | .name = CARDNAME, |
2407 | .owner = THIS_MODULE, | 2407 | .owner = THIS_MODULE, |
2408 | }, | 2408 | }, |
2409 | }; | 2409 | }; |
2410 | 2410 | ||
2411 | static int __init smc_init(void) | 2411 | static int __init smc_init(void) |
2412 | { | 2412 | { |
2413 | return platform_driver_register(&smc_driver); | 2413 | return platform_driver_register(&smc_driver); |
2414 | } | 2414 | } |
2415 | 2415 | ||
2416 | static void __exit smc_cleanup(void) | 2416 | static void __exit smc_cleanup(void) |
2417 | { | 2417 | { |
2418 | platform_driver_unregister(&smc_driver); | 2418 | platform_driver_unregister(&smc_driver); |
2419 | } | 2419 | } |
2420 | 2420 | ||
2421 | module_init(smc_init); | 2421 | module_init(smc_init); |
2422 | module_exit(smc_cleanup); | 2422 | module_exit(smc_cleanup); |
2423 | 2423 |
drivers/net/smc91x.h
1 | /*------------------------------------------------------------------------ | 1 | /*------------------------------------------------------------------------ |
2 | . smc91x.h - macros for SMSC's 91C9x/91C1xx single-chip Ethernet device. | 2 | . smc91x.h - macros for SMSC's 91C9x/91C1xx single-chip Ethernet device. |
3 | . | 3 | . |
4 | . Copyright (C) 1996 by Erik Stahlman | 4 | . Copyright (C) 1996 by Erik Stahlman |
5 | . Copyright (C) 2001 Standard Microsystems Corporation | 5 | . Copyright (C) 2001 Standard Microsystems Corporation |
6 | . Developed by Simple Network Magic Corporation | 6 | . Developed by Simple Network Magic Corporation |
7 | . Copyright (C) 2003 Monta Vista Software, Inc. | 7 | . Copyright (C) 2003 Monta Vista Software, Inc. |
8 | . Unified SMC91x driver by Nicolas Pitre | 8 | . Unified SMC91x driver by Nicolas Pitre |
9 | . | 9 | . |
10 | . This program is free software; you can redistribute it and/or modify | 10 | . This program is free software; you can redistribute it and/or modify |
11 | . it under the terms of the GNU General Public License as published by | 11 | . it under the terms of the GNU General Public License as published by |
12 | . the Free Software Foundation; either version 2 of the License, or | 12 | . the Free Software Foundation; either version 2 of the License, or |
13 | . (at your option) any later version. | 13 | . (at your option) any later version. |
14 | . | 14 | . |
15 | . This program is distributed in the hope that it will be useful, | 15 | . This program is distributed in the hope that it will be useful, |
16 | . but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | . but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | . GNU General Public License for more details. | 18 | . GNU General Public License for more details. |
19 | . | 19 | . |
20 | . You should have received a copy of the GNU General Public License | 20 | . You should have received a copy of the GNU General Public License |
21 | . along with this program; if not, write to the Free Software | 21 | . along with this program; if not, write to the Free Software |
22 | . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | . | 23 | . |
24 | . Information contained in this file was obtained from the LAN91C111 | 24 | . Information contained in this file was obtained from the LAN91C111 |
25 | . manual from SMC. To get a copy, if you really want one, you can find | 25 | . manual from SMC. To get a copy, if you really want one, you can find |
26 | . information under www.smsc.com. | 26 | . information under www.smsc.com. |
27 | . | 27 | . |
28 | . Authors | 28 | . Authors |
29 | . Erik Stahlman <erik@vt.edu> | 29 | . Erik Stahlman <erik@vt.edu> |
30 | . Daris A Nevil <dnevil@snmc.com> | 30 | . Daris A Nevil <dnevil@snmc.com> |
31 | . Nicolas Pitre <nico@cam.org> | 31 | . Nicolas Pitre <nico@fluxnic.net> |
32 | . | 32 | . |
33 | ---------------------------------------------------------------------------*/ | 33 | ---------------------------------------------------------------------------*/ |
34 | #ifndef _SMC91X_H_ | 34 | #ifndef _SMC91X_H_ |
35 | #define _SMC91X_H_ | 35 | #define _SMC91X_H_ |
36 | 36 | ||
37 | #include <linux/smc91x.h> | 37 | #include <linux/smc91x.h> |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Define your architecture specific bus configuration parameters here. | 40 | * Define your architecture specific bus configuration parameters here. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #if defined(CONFIG_ARCH_LUBBOCK) ||\ | 43 | #if defined(CONFIG_ARCH_LUBBOCK) ||\ |
44 | defined(CONFIG_MACH_MAINSTONE) ||\ | 44 | defined(CONFIG_MACH_MAINSTONE) ||\ |
45 | defined(CONFIG_MACH_ZYLONITE) ||\ | 45 | defined(CONFIG_MACH_ZYLONITE) ||\ |
46 | defined(CONFIG_MACH_LITTLETON) ||\ | 46 | defined(CONFIG_MACH_LITTLETON) ||\ |
47 | defined(CONFIG_MACH_ZYLONITE2) ||\ | 47 | defined(CONFIG_MACH_ZYLONITE2) ||\ |
48 | defined(CONFIG_ARCH_VIPER) ||\ | 48 | defined(CONFIG_ARCH_VIPER) ||\ |
49 | defined(CONFIG_MACH_STARGATE2) | 49 | defined(CONFIG_MACH_STARGATE2) |
50 | 50 | ||
51 | #include <asm/mach-types.h> | 51 | #include <asm/mach-types.h> |
52 | 52 | ||
53 | /* Now the bus width is specified in the platform data | 53 | /* Now the bus width is specified in the platform data |
54 | * pretend here to support all I/O access types | 54 | * pretend here to support all I/O access types |
55 | */ | 55 | */ |
56 | #define SMC_CAN_USE_8BIT 1 | 56 | #define SMC_CAN_USE_8BIT 1 |
57 | #define SMC_CAN_USE_16BIT 1 | 57 | #define SMC_CAN_USE_16BIT 1 |
58 | #define SMC_CAN_USE_32BIT 1 | 58 | #define SMC_CAN_USE_32BIT 1 |
59 | #define SMC_NOWAIT 1 | 59 | #define SMC_NOWAIT 1 |
60 | 60 | ||
61 | #define SMC_IO_SHIFT (lp->io_shift) | 61 | #define SMC_IO_SHIFT (lp->io_shift) |
62 | 62 | ||
63 | #define SMC_inb(a, r) readb((a) + (r)) | 63 | #define SMC_inb(a, r) readb((a) + (r)) |
64 | #define SMC_inw(a, r) readw((a) + (r)) | 64 | #define SMC_inw(a, r) readw((a) + (r)) |
65 | #define SMC_inl(a, r) readl((a) + (r)) | 65 | #define SMC_inl(a, r) readl((a) + (r)) |
66 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 66 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
67 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 67 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
68 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 68 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
69 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 69 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
70 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 70 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
71 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 71 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
72 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 72 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
73 | 73 | ||
74 | /* We actually can't write halfwords properly if not word aligned */ | 74 | /* We actually can't write halfwords properly if not word aligned */ |
75 | static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) | 75 | static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) |
76 | { | 76 | { |
77 | if ((machine_is_mainstone() || machine_is_stargate2()) && reg & 2) { | 77 | if ((machine_is_mainstone() || machine_is_stargate2()) && reg & 2) { |
78 | unsigned int v = val << 16; | 78 | unsigned int v = val << 16; |
79 | v |= readl(ioaddr + (reg & ~2)) & 0xffff; | 79 | v |= readl(ioaddr + (reg & ~2)) & 0xffff; |
80 | writel(v, ioaddr + (reg & ~2)); | 80 | writel(v, ioaddr + (reg & ~2)); |
81 | } else { | 81 | } else { |
82 | writew(val, ioaddr + reg); | 82 | writew(val, ioaddr + reg); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | #elif defined(CONFIG_BLACKFIN) | 86 | #elif defined(CONFIG_BLACKFIN) |
87 | 87 | ||
88 | #define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH | 88 | #define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH |
89 | #define RPC_LSA_DEFAULT RPC_LED_100_10 | 89 | #define RPC_LSA_DEFAULT RPC_LED_100_10 |
90 | #define RPC_LSB_DEFAULT RPC_LED_TX_RX | 90 | #define RPC_LSB_DEFAULT RPC_LED_TX_RX |
91 | 91 | ||
92 | #define SMC_CAN_USE_8BIT 0 | 92 | #define SMC_CAN_USE_8BIT 0 |
93 | #define SMC_CAN_USE_16BIT 1 | 93 | #define SMC_CAN_USE_16BIT 1 |
94 | # if defined(CONFIG_BF561) | 94 | # if defined(CONFIG_BF561) |
95 | #define SMC_CAN_USE_32BIT 1 | 95 | #define SMC_CAN_USE_32BIT 1 |
96 | # else | 96 | # else |
97 | #define SMC_CAN_USE_32BIT 0 | 97 | #define SMC_CAN_USE_32BIT 0 |
98 | # endif | 98 | # endif |
99 | #define SMC_IO_SHIFT 0 | 99 | #define SMC_IO_SHIFT 0 |
100 | #define SMC_NOWAIT 1 | 100 | #define SMC_NOWAIT 1 |
101 | #define SMC_USE_BFIN_DMA 0 | 101 | #define SMC_USE_BFIN_DMA 0 |
102 | 102 | ||
103 | #define SMC_inw(a, r) readw((a) + (r)) | 103 | #define SMC_inw(a, r) readw((a) + (r)) |
104 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 104 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
105 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 105 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
106 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 106 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
107 | # if SMC_CAN_USE_32BIT | 107 | # if SMC_CAN_USE_32BIT |
108 | #define SMC_inl(a, r) readl((a) + (r)) | 108 | #define SMC_inl(a, r) readl((a) + (r)) |
109 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 109 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
110 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 110 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
111 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 111 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
112 | # endif | 112 | # endif |
113 | 113 | ||
114 | #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) | 114 | #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) |
115 | 115 | ||
116 | /* We can only do 16-bit reads and writes in the static memory space. */ | 116 | /* We can only do 16-bit reads and writes in the static memory space. */ |
117 | #define SMC_CAN_USE_8BIT 0 | 117 | #define SMC_CAN_USE_8BIT 0 |
118 | #define SMC_CAN_USE_16BIT 1 | 118 | #define SMC_CAN_USE_16BIT 1 |
119 | #define SMC_CAN_USE_32BIT 0 | 119 | #define SMC_CAN_USE_32BIT 0 |
120 | #define SMC_NOWAIT 1 | 120 | #define SMC_NOWAIT 1 |
121 | 121 | ||
122 | #define SMC_IO_SHIFT 0 | 122 | #define SMC_IO_SHIFT 0 |
123 | 123 | ||
124 | #define SMC_inw(a, r) in_be16((volatile u16 *)((a) + (r))) | 124 | #define SMC_inw(a, r) in_be16((volatile u16 *)((a) + (r))) |
125 | #define SMC_outw(v, a, r) out_be16((volatile u16 *)((a) + (r)), v) | 125 | #define SMC_outw(v, a, r) out_be16((volatile u16 *)((a) + (r)), v) |
126 | #define SMC_insw(a, r, p, l) \ | 126 | #define SMC_insw(a, r, p, l) \ |
127 | do { \ | 127 | do { \ |
128 | unsigned long __port = (a) + (r); \ | 128 | unsigned long __port = (a) + (r); \ |
129 | u16 *__p = (u16 *)(p); \ | 129 | u16 *__p = (u16 *)(p); \ |
130 | int __l = (l); \ | 130 | int __l = (l); \ |
131 | insw(__port, __p, __l); \ | 131 | insw(__port, __p, __l); \ |
132 | while (__l > 0) { \ | 132 | while (__l > 0) { \ |
133 | *__p = swab16(*__p); \ | 133 | *__p = swab16(*__p); \ |
134 | __p++; \ | 134 | __p++; \ |
135 | __l--; \ | 135 | __l--; \ |
136 | } \ | 136 | } \ |
137 | } while (0) | 137 | } while (0) |
138 | #define SMC_outsw(a, r, p, l) \ | 138 | #define SMC_outsw(a, r, p, l) \ |
139 | do { \ | 139 | do { \ |
140 | unsigned long __port = (a) + (r); \ | 140 | unsigned long __port = (a) + (r); \ |
141 | u16 *__p = (u16 *)(p); \ | 141 | u16 *__p = (u16 *)(p); \ |
142 | int __l = (l); \ | 142 | int __l = (l); \ |
143 | while (__l > 0) { \ | 143 | while (__l > 0) { \ |
144 | /* Believe it or not, the swab isn't needed. */ \ | 144 | /* Believe it or not, the swab isn't needed. */ \ |
145 | outw( /* swab16 */ (*__p++), __port); \ | 145 | outw( /* swab16 */ (*__p++), __port); \ |
146 | __l--; \ | 146 | __l--; \ |
147 | } \ | 147 | } \ |
148 | } while (0) | 148 | } while (0) |
149 | #define SMC_IRQ_FLAGS (0) | 149 | #define SMC_IRQ_FLAGS (0) |
150 | 150 | ||
151 | #elif defined(CONFIG_SA1100_PLEB) | 151 | #elif defined(CONFIG_SA1100_PLEB) |
152 | /* We can only do 16-bit reads and writes in the static memory space. */ | 152 | /* We can only do 16-bit reads and writes in the static memory space. */ |
153 | #define SMC_CAN_USE_8BIT 1 | 153 | #define SMC_CAN_USE_8BIT 1 |
154 | #define SMC_CAN_USE_16BIT 1 | 154 | #define SMC_CAN_USE_16BIT 1 |
155 | #define SMC_CAN_USE_32BIT 0 | 155 | #define SMC_CAN_USE_32BIT 0 |
156 | #define SMC_IO_SHIFT 0 | 156 | #define SMC_IO_SHIFT 0 |
157 | #define SMC_NOWAIT 1 | 157 | #define SMC_NOWAIT 1 |
158 | 158 | ||
159 | #define SMC_inb(a, r) readb((a) + (r)) | 159 | #define SMC_inb(a, r) readb((a) + (r)) |
160 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) | 160 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) |
161 | #define SMC_inw(a, r) readw((a) + (r)) | 161 | #define SMC_inw(a, r) readw((a) + (r)) |
162 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 162 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
163 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 163 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
164 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) | 164 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) |
165 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 165 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
166 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 166 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
167 | 167 | ||
168 | #define SMC_IRQ_FLAGS (-1) | 168 | #define SMC_IRQ_FLAGS (-1) |
169 | 169 | ||
170 | #elif defined(CONFIG_SA1100_ASSABET) | 170 | #elif defined(CONFIG_SA1100_ASSABET) |
171 | 171 | ||
172 | #include <mach/neponset.h> | 172 | #include <mach/neponset.h> |
173 | 173 | ||
174 | /* We can only do 8-bit reads and writes in the static memory space. */ | 174 | /* We can only do 8-bit reads and writes in the static memory space. */ |
175 | #define SMC_CAN_USE_8BIT 1 | 175 | #define SMC_CAN_USE_8BIT 1 |
176 | #define SMC_CAN_USE_16BIT 0 | 176 | #define SMC_CAN_USE_16BIT 0 |
177 | #define SMC_CAN_USE_32BIT 0 | 177 | #define SMC_CAN_USE_32BIT 0 |
178 | #define SMC_NOWAIT 1 | 178 | #define SMC_NOWAIT 1 |
179 | 179 | ||
180 | /* The first two address lines aren't connected... */ | 180 | /* The first two address lines aren't connected... */ |
181 | #define SMC_IO_SHIFT 2 | 181 | #define SMC_IO_SHIFT 2 |
182 | 182 | ||
183 | #define SMC_inb(a, r) readb((a) + (r)) | 183 | #define SMC_inb(a, r) readb((a) + (r)) |
184 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 184 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
185 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) | 185 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) |
186 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) | 186 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) |
187 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 187 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
188 | 188 | ||
189 | #elif defined(CONFIG_MACH_LOGICPD_PXA270) \ | 189 | #elif defined(CONFIG_MACH_LOGICPD_PXA270) \ |
190 | || defined(CONFIG_MACH_NOMADIK_8815NHK) | 190 | || defined(CONFIG_MACH_NOMADIK_8815NHK) |
191 | 191 | ||
192 | #define SMC_CAN_USE_8BIT 0 | 192 | #define SMC_CAN_USE_8BIT 0 |
193 | #define SMC_CAN_USE_16BIT 1 | 193 | #define SMC_CAN_USE_16BIT 1 |
194 | #define SMC_CAN_USE_32BIT 0 | 194 | #define SMC_CAN_USE_32BIT 0 |
195 | #define SMC_IO_SHIFT 0 | 195 | #define SMC_IO_SHIFT 0 |
196 | #define SMC_NOWAIT 1 | 196 | #define SMC_NOWAIT 1 |
197 | 197 | ||
198 | #define SMC_inw(a, r) readw((a) + (r)) | 198 | #define SMC_inw(a, r) readw((a) + (r)) |
199 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 199 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
200 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 200 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
201 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 201 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
202 | 202 | ||
203 | #elif defined(CONFIG_ARCH_INNOKOM) || \ | 203 | #elif defined(CONFIG_ARCH_INNOKOM) || \ |
204 | defined(CONFIG_ARCH_PXA_IDP) || \ | 204 | defined(CONFIG_ARCH_PXA_IDP) || \ |
205 | defined(CONFIG_ARCH_RAMSES) || \ | 205 | defined(CONFIG_ARCH_RAMSES) || \ |
206 | defined(CONFIG_ARCH_PCM027) | 206 | defined(CONFIG_ARCH_PCM027) |
207 | 207 | ||
208 | #define SMC_CAN_USE_8BIT 1 | 208 | #define SMC_CAN_USE_8BIT 1 |
209 | #define SMC_CAN_USE_16BIT 1 | 209 | #define SMC_CAN_USE_16BIT 1 |
210 | #define SMC_CAN_USE_32BIT 1 | 210 | #define SMC_CAN_USE_32BIT 1 |
211 | #define SMC_IO_SHIFT 0 | 211 | #define SMC_IO_SHIFT 0 |
212 | #define SMC_NOWAIT 1 | 212 | #define SMC_NOWAIT 1 |
213 | #define SMC_USE_PXA_DMA 1 | 213 | #define SMC_USE_PXA_DMA 1 |
214 | 214 | ||
215 | #define SMC_inb(a, r) readb((a) + (r)) | 215 | #define SMC_inb(a, r) readb((a) + (r)) |
216 | #define SMC_inw(a, r) readw((a) + (r)) | 216 | #define SMC_inw(a, r) readw((a) + (r)) |
217 | #define SMC_inl(a, r) readl((a) + (r)) | 217 | #define SMC_inl(a, r) readl((a) + (r)) |
218 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 218 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
219 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 219 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
220 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 220 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
221 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 221 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
222 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 222 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
223 | 223 | ||
224 | /* We actually can't write halfwords properly if not word aligned */ | 224 | /* We actually can't write halfwords properly if not word aligned */ |
225 | static inline void | 225 | static inline void |
226 | SMC_outw(u16 val, void __iomem *ioaddr, int reg) | 226 | SMC_outw(u16 val, void __iomem *ioaddr, int reg) |
227 | { | 227 | { |
228 | if (reg & 2) { | 228 | if (reg & 2) { |
229 | unsigned int v = val << 16; | 229 | unsigned int v = val << 16; |
230 | v |= readl(ioaddr + (reg & ~2)) & 0xffff; | 230 | v |= readl(ioaddr + (reg & ~2)) & 0xffff; |
231 | writel(v, ioaddr + (reg & ~2)); | 231 | writel(v, ioaddr + (reg & ~2)); |
232 | } else { | 232 | } else { |
233 | writew(val, ioaddr + reg); | 233 | writew(val, ioaddr + reg); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | #elif defined(CONFIG_ARCH_OMAP) | 237 | #elif defined(CONFIG_ARCH_OMAP) |
238 | 238 | ||
239 | /* We can only do 16-bit reads and writes in the static memory space. */ | 239 | /* We can only do 16-bit reads and writes in the static memory space. */ |
240 | #define SMC_CAN_USE_8BIT 0 | 240 | #define SMC_CAN_USE_8BIT 0 |
241 | #define SMC_CAN_USE_16BIT 1 | 241 | #define SMC_CAN_USE_16BIT 1 |
242 | #define SMC_CAN_USE_32BIT 0 | 242 | #define SMC_CAN_USE_32BIT 0 |
243 | #define SMC_IO_SHIFT 0 | 243 | #define SMC_IO_SHIFT 0 |
244 | #define SMC_NOWAIT 1 | 244 | #define SMC_NOWAIT 1 |
245 | 245 | ||
246 | #define SMC_inw(a, r) readw((a) + (r)) | 246 | #define SMC_inw(a, r) readw((a) + (r)) |
247 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 247 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
248 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 248 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
249 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 249 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
250 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 250 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
251 | 251 | ||
252 | #elif defined(CONFIG_SH_SH4202_MICRODEV) | 252 | #elif defined(CONFIG_SH_SH4202_MICRODEV) |
253 | 253 | ||
254 | #define SMC_CAN_USE_8BIT 0 | 254 | #define SMC_CAN_USE_8BIT 0 |
255 | #define SMC_CAN_USE_16BIT 1 | 255 | #define SMC_CAN_USE_16BIT 1 |
256 | #define SMC_CAN_USE_32BIT 0 | 256 | #define SMC_CAN_USE_32BIT 0 |
257 | 257 | ||
258 | #define SMC_inb(a, r) inb((a) + (r) - 0xa0000000) | 258 | #define SMC_inb(a, r) inb((a) + (r) - 0xa0000000) |
259 | #define SMC_inw(a, r) inw((a) + (r) - 0xa0000000) | 259 | #define SMC_inw(a, r) inw((a) + (r) - 0xa0000000) |
260 | #define SMC_inl(a, r) inl((a) + (r) - 0xa0000000) | 260 | #define SMC_inl(a, r) inl((a) + (r) - 0xa0000000) |
261 | #define SMC_outb(v, a, r) outb(v, (a) + (r) - 0xa0000000) | 261 | #define SMC_outb(v, a, r) outb(v, (a) + (r) - 0xa0000000) |
262 | #define SMC_outw(v, a, r) outw(v, (a) + (r) - 0xa0000000) | 262 | #define SMC_outw(v, a, r) outw(v, (a) + (r) - 0xa0000000) |
263 | #define SMC_outl(v, a, r) outl(v, (a) + (r) - 0xa0000000) | 263 | #define SMC_outl(v, a, r) outl(v, (a) + (r) - 0xa0000000) |
264 | #define SMC_insl(a, r, p, l) insl((a) + (r) - 0xa0000000, p, l) | 264 | #define SMC_insl(a, r, p, l) insl((a) + (r) - 0xa0000000, p, l) |
265 | #define SMC_outsl(a, r, p, l) outsl((a) + (r) - 0xa0000000, p, l) | 265 | #define SMC_outsl(a, r, p, l) outsl((a) + (r) - 0xa0000000, p, l) |
266 | #define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l) | 266 | #define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l) |
267 | #define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l) | 267 | #define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l) |
268 | 268 | ||
269 | #define SMC_IRQ_FLAGS (0) | 269 | #define SMC_IRQ_FLAGS (0) |
270 | 270 | ||
271 | #elif defined(CONFIG_M32R) | 271 | #elif defined(CONFIG_M32R) |
272 | 272 | ||
273 | #define SMC_CAN_USE_8BIT 0 | 273 | #define SMC_CAN_USE_8BIT 0 |
274 | #define SMC_CAN_USE_16BIT 1 | 274 | #define SMC_CAN_USE_16BIT 1 |
275 | #define SMC_CAN_USE_32BIT 0 | 275 | #define SMC_CAN_USE_32BIT 0 |
276 | 276 | ||
277 | #define SMC_inb(a, r) inb(((u32)a) + (r)) | 277 | #define SMC_inb(a, r) inb(((u32)a) + (r)) |
278 | #define SMC_inw(a, r) inw(((u32)a) + (r)) | 278 | #define SMC_inw(a, r) inw(((u32)a) + (r)) |
279 | #define SMC_outb(v, a, r) outb(v, ((u32)a) + (r)) | 279 | #define SMC_outb(v, a, r) outb(v, ((u32)a) + (r)) |
280 | #define SMC_outw(v, a, r) outw(v, ((u32)a) + (r)) | 280 | #define SMC_outw(v, a, r) outw(v, ((u32)a) + (r)) |
281 | #define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l) | 281 | #define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l) |
282 | #define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l) | 282 | #define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l) |
283 | 283 | ||
284 | #define SMC_IRQ_FLAGS (0) | 284 | #define SMC_IRQ_FLAGS (0) |
285 | 285 | ||
286 | #define RPC_LSA_DEFAULT RPC_LED_TX_RX | 286 | #define RPC_LSA_DEFAULT RPC_LED_TX_RX |
287 | #define RPC_LSB_DEFAULT RPC_LED_100_10 | 287 | #define RPC_LSB_DEFAULT RPC_LED_100_10 |
288 | 288 | ||
289 | #elif defined(CONFIG_MACH_LPD79520) \ | 289 | #elif defined(CONFIG_MACH_LPD79520) \ |
290 | || defined(CONFIG_MACH_LPD7A400) \ | 290 | || defined(CONFIG_MACH_LPD7A400) \ |
291 | || defined(CONFIG_MACH_LPD7A404) | 291 | || defined(CONFIG_MACH_LPD7A404) |
292 | 292 | ||
293 | /* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the | 293 | /* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the |
294 | * way that the CPU handles chip selects and the way that the SMC chip | 294 | * way that the CPU handles chip selects and the way that the SMC chip |
295 | * expects the chip select to operate. Refer to | 295 | * expects the chip select to operate. Refer to |
296 | * Documentation/arm/Sharp-LH/IOBarrier for details. The read from | 296 | * Documentation/arm/Sharp-LH/IOBarrier for details. The read from |
297 | * IOBARRIER is a byte, in order that we read the least-common | 297 | * IOBARRIER is a byte, in order that we read the least-common |
298 | * denominator. It would be wasteful to read 32 bits from an 8-bit | 298 | * denominator. It would be wasteful to read 32 bits from an 8-bit |
299 | * accessible region. | 299 | * accessible region. |
300 | * | 300 | * |
301 | * There is no explicit protection against interrupts intervening | 301 | * There is no explicit protection against interrupts intervening |
302 | * between the writew and the IOBARRIER. In SMC ISR there is a | 302 | * between the writew and the IOBARRIER. In SMC ISR there is a |
303 | * preamble that performs an IOBARRIER in the extremely unlikely event | 303 | * preamble that performs an IOBARRIER in the extremely unlikely event |
304 | * that the driver interrupts itself between a writew to the chip an | 304 | * that the driver interrupts itself between a writew to the chip an |
305 | * the IOBARRIER that follows *and* the cache is large enough that the | 305 | * the IOBARRIER that follows *and* the cache is large enough that the |
306 | * first off-chip access while handing the interrupt is to the SMC | 306 | * first off-chip access while handing the interrupt is to the SMC |
307 | * chip. Other devices in the same address space as the SMC chip must | 307 | * chip. Other devices in the same address space as the SMC chip must |
308 | * be aware of the potential for trouble and perform a similar | 308 | * be aware of the potential for trouble and perform a similar |
309 | * IOBARRIER on entry to their ISR. | 309 | * IOBARRIER on entry to their ISR. |
310 | */ | 310 | */ |
311 | 311 | ||
312 | #include <mach/constants.h> /* IOBARRIER_VIRT */ | 312 | #include <mach/constants.h> /* IOBARRIER_VIRT */ |
313 | 313 | ||
314 | #define SMC_CAN_USE_8BIT 0 | 314 | #define SMC_CAN_USE_8BIT 0 |
315 | #define SMC_CAN_USE_16BIT 1 | 315 | #define SMC_CAN_USE_16BIT 1 |
316 | #define SMC_CAN_USE_32BIT 0 | 316 | #define SMC_CAN_USE_32BIT 0 |
317 | #define SMC_NOWAIT 0 | 317 | #define SMC_NOWAIT 0 |
318 | #define LPD7X_IOBARRIER readb (IOBARRIER_VIRT) | 318 | #define LPD7X_IOBARRIER readb (IOBARRIER_VIRT) |
319 | 319 | ||
320 | #define SMC_inw(a,r)\ | 320 | #define SMC_inw(a,r)\ |
321 | ({ unsigned short v = readw ((void*) ((a) + (r))); LPD7X_IOBARRIER; v; }) | 321 | ({ unsigned short v = readw ((void*) ((a) + (r))); LPD7X_IOBARRIER; v; }) |
322 | #define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7X_IOBARRIER; }) | 322 | #define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7X_IOBARRIER; }) |
323 | 323 | ||
324 | #define SMC_insw LPD7_SMC_insw | 324 | #define SMC_insw LPD7_SMC_insw |
325 | static inline void LPD7_SMC_insw (unsigned char* a, int r, | 325 | static inline void LPD7_SMC_insw (unsigned char* a, int r, |
326 | unsigned char* p, int l) | 326 | unsigned char* p, int l) |
327 | { | 327 | { |
328 | unsigned short* ps = (unsigned short*) p; | 328 | unsigned short* ps = (unsigned short*) p; |
329 | while (l-- > 0) { | 329 | while (l-- > 0) { |
330 | *ps++ = readw (a + r); | 330 | *ps++ = readw (a + r); |
331 | LPD7X_IOBARRIER; | 331 | LPD7X_IOBARRIER; |
332 | } | 332 | } |
333 | } | 333 | } |
334 | 334 | ||
335 | #define SMC_outsw LPD7_SMC_outsw | 335 | #define SMC_outsw LPD7_SMC_outsw |
336 | static inline void LPD7_SMC_outsw (unsigned char* a, int r, | 336 | static inline void LPD7_SMC_outsw (unsigned char* a, int r, |
337 | unsigned char* p, int l) | 337 | unsigned char* p, int l) |
338 | { | 338 | { |
339 | unsigned short* ps = (unsigned short*) p; | 339 | unsigned short* ps = (unsigned short*) p; |
340 | while (l-- > 0) { | 340 | while (l-- > 0) { |
341 | writew (*ps++, a + r); | 341 | writew (*ps++, a + r); |
342 | LPD7X_IOBARRIER; | 342 | LPD7X_IOBARRIER; |
343 | } | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
346 | #define SMC_INTERRUPT_PREAMBLE LPD7X_IOBARRIER | 346 | #define SMC_INTERRUPT_PREAMBLE LPD7X_IOBARRIER |
347 | 347 | ||
348 | #define RPC_LSA_DEFAULT RPC_LED_TX_RX | 348 | #define RPC_LSA_DEFAULT RPC_LED_TX_RX |
349 | #define RPC_LSB_DEFAULT RPC_LED_100_10 | 349 | #define RPC_LSB_DEFAULT RPC_LED_100_10 |
350 | 350 | ||
351 | #elif defined(CONFIG_ARCH_VERSATILE) | 351 | #elif defined(CONFIG_ARCH_VERSATILE) |
352 | 352 | ||
353 | #define SMC_CAN_USE_8BIT 1 | 353 | #define SMC_CAN_USE_8BIT 1 |
354 | #define SMC_CAN_USE_16BIT 1 | 354 | #define SMC_CAN_USE_16BIT 1 |
355 | #define SMC_CAN_USE_32BIT 1 | 355 | #define SMC_CAN_USE_32BIT 1 |
356 | #define SMC_NOWAIT 1 | 356 | #define SMC_NOWAIT 1 |
357 | 357 | ||
358 | #define SMC_inb(a, r) readb((a) + (r)) | 358 | #define SMC_inb(a, r) readb((a) + (r)) |
359 | #define SMC_inw(a, r) readw((a) + (r)) | 359 | #define SMC_inw(a, r) readw((a) + (r)) |
360 | #define SMC_inl(a, r) readl((a) + (r)) | 360 | #define SMC_inl(a, r) readl((a) + (r)) |
361 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 361 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
362 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 362 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
363 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 363 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
364 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 364 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
365 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 365 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
366 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 366 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
367 | 367 | ||
368 | #elif defined(CONFIG_MN10300) | 368 | #elif defined(CONFIG_MN10300) |
369 | 369 | ||
370 | /* | 370 | /* |
371 | * MN10300/AM33 configuration | 371 | * MN10300/AM33 configuration |
372 | */ | 372 | */ |
373 | 373 | ||
374 | #include <unit/smc91111.h> | 374 | #include <unit/smc91111.h> |
375 | 375 | ||
376 | #else | 376 | #else |
377 | 377 | ||
378 | /* | 378 | /* |
379 | * Default configuration | 379 | * Default configuration |
380 | */ | 380 | */ |
381 | 381 | ||
382 | #define SMC_CAN_USE_8BIT 1 | 382 | #define SMC_CAN_USE_8BIT 1 |
383 | #define SMC_CAN_USE_16BIT 1 | 383 | #define SMC_CAN_USE_16BIT 1 |
384 | #define SMC_CAN_USE_32BIT 1 | 384 | #define SMC_CAN_USE_32BIT 1 |
385 | #define SMC_NOWAIT 1 | 385 | #define SMC_NOWAIT 1 |
386 | 386 | ||
387 | #define SMC_IO_SHIFT (lp->io_shift) | 387 | #define SMC_IO_SHIFT (lp->io_shift) |
388 | 388 | ||
389 | #define SMC_inb(a, r) readb((a) + (r)) | 389 | #define SMC_inb(a, r) readb((a) + (r)) |
390 | #define SMC_inw(a, r) readw((a) + (r)) | 390 | #define SMC_inw(a, r) readw((a) + (r)) |
391 | #define SMC_inl(a, r) readl((a) + (r)) | 391 | #define SMC_inl(a, r) readl((a) + (r)) |
392 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 392 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
393 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 393 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
394 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 394 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
395 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 395 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
396 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 396 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
397 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 397 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
398 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 398 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
399 | 399 | ||
400 | #define RPC_LSA_DEFAULT RPC_LED_100_10 | 400 | #define RPC_LSA_DEFAULT RPC_LED_100_10 |
401 | #define RPC_LSB_DEFAULT RPC_LED_TX_RX | 401 | #define RPC_LSB_DEFAULT RPC_LED_TX_RX |
402 | 402 | ||
403 | #endif | 403 | #endif |
404 | 404 | ||
405 | 405 | ||
406 | /* store this information for the driver.. */ | 406 | /* store this information for the driver.. */ |
407 | struct smc_local { | 407 | struct smc_local { |
408 | /* | 408 | /* |
409 | * If I have to wait until memory is available to send a | 409 | * If I have to wait until memory is available to send a |
410 | * packet, I will store the skbuff here, until I get the | 410 | * packet, I will store the skbuff here, until I get the |
411 | * desired memory. Then, I'll send it out and free it. | 411 | * desired memory. Then, I'll send it out and free it. |
412 | */ | 412 | */ |
413 | struct sk_buff *pending_tx_skb; | 413 | struct sk_buff *pending_tx_skb; |
414 | struct tasklet_struct tx_task; | 414 | struct tasklet_struct tx_task; |
415 | 415 | ||
416 | /* version/revision of the SMC91x chip */ | 416 | /* version/revision of the SMC91x chip */ |
417 | int version; | 417 | int version; |
418 | 418 | ||
419 | /* Contains the current active transmission mode */ | 419 | /* Contains the current active transmission mode */ |
420 | int tcr_cur_mode; | 420 | int tcr_cur_mode; |
421 | 421 | ||
422 | /* Contains the current active receive mode */ | 422 | /* Contains the current active receive mode */ |
423 | int rcr_cur_mode; | 423 | int rcr_cur_mode; |
424 | 424 | ||
425 | /* Contains the current active receive/phy mode */ | 425 | /* Contains the current active receive/phy mode */ |
426 | int rpc_cur_mode; | 426 | int rpc_cur_mode; |
427 | int ctl_rfduplx; | 427 | int ctl_rfduplx; |
428 | int ctl_rspeed; | 428 | int ctl_rspeed; |
429 | 429 | ||
430 | u32 msg_enable; | 430 | u32 msg_enable; |
431 | u32 phy_type; | 431 | u32 phy_type; |
432 | struct mii_if_info mii; | 432 | struct mii_if_info mii; |
433 | 433 | ||
434 | /* work queue */ | 434 | /* work queue */ |
435 | struct work_struct phy_configure; | 435 | struct work_struct phy_configure; |
436 | struct net_device *dev; | 436 | struct net_device *dev; |
437 | int work_pending; | 437 | int work_pending; |
438 | 438 | ||
439 | spinlock_t lock; | 439 | spinlock_t lock; |
440 | 440 | ||
441 | #ifdef CONFIG_ARCH_PXA | 441 | #ifdef CONFIG_ARCH_PXA |
442 | /* DMA needs the physical address of the chip */ | 442 | /* DMA needs the physical address of the chip */ |
443 | u_long physaddr; | 443 | u_long physaddr; |
444 | struct device *device; | 444 | struct device *device; |
445 | #endif | 445 | #endif |
446 | void __iomem *base; | 446 | void __iomem *base; |
447 | void __iomem *datacs; | 447 | void __iomem *datacs; |
448 | 448 | ||
449 | /* the low address lines on some platforms aren't connected... */ | 449 | /* the low address lines on some platforms aren't connected... */ |
450 | int io_shift; | 450 | int io_shift; |
451 | 451 | ||
452 | struct smc91x_platdata cfg; | 452 | struct smc91x_platdata cfg; |
453 | }; | 453 | }; |
454 | 454 | ||
455 | #define SMC_8BIT(p) ((p)->cfg.flags & SMC91X_USE_8BIT) | 455 | #define SMC_8BIT(p) ((p)->cfg.flags & SMC91X_USE_8BIT) |
456 | #define SMC_16BIT(p) ((p)->cfg.flags & SMC91X_USE_16BIT) | 456 | #define SMC_16BIT(p) ((p)->cfg.flags & SMC91X_USE_16BIT) |
457 | #define SMC_32BIT(p) ((p)->cfg.flags & SMC91X_USE_32BIT) | 457 | #define SMC_32BIT(p) ((p)->cfg.flags & SMC91X_USE_32BIT) |
458 | 458 | ||
459 | #ifdef CONFIG_ARCH_PXA | 459 | #ifdef CONFIG_ARCH_PXA |
460 | /* | 460 | /* |
461 | * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is | 461 | * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is |
462 | * always happening in irq context so no need to worry about races. TX is | 462 | * always happening in irq context so no need to worry about races. TX is |
463 | * different and probably not worth it for that reason, and not as critical | 463 | * different and probably not worth it for that reason, and not as critical |
464 | * as RX which can overrun memory and lose packets. | 464 | * as RX which can overrun memory and lose packets. |
465 | */ | 465 | */ |
466 | #include <linux/dma-mapping.h> | 466 | #include <linux/dma-mapping.h> |
467 | #include <mach/dma.h> | 467 | #include <mach/dma.h> |
468 | 468 | ||
469 | #ifdef SMC_insl | 469 | #ifdef SMC_insl |
470 | #undef SMC_insl | 470 | #undef SMC_insl |
471 | #define SMC_insl(a, r, p, l) \ | 471 | #define SMC_insl(a, r, p, l) \ |
472 | smc_pxa_dma_insl(a, lp, r, dev->dma, p, l) | 472 | smc_pxa_dma_insl(a, lp, r, dev->dma, p, l) |
473 | static inline void | 473 | static inline void |
474 | smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, | 474 | smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, |
475 | u_char *buf, int len) | 475 | u_char *buf, int len) |
476 | { | 476 | { |
477 | u_long physaddr = lp->physaddr; | 477 | u_long physaddr = lp->physaddr; |
478 | dma_addr_t dmabuf; | 478 | dma_addr_t dmabuf; |
479 | 479 | ||
480 | /* fallback if no DMA available */ | 480 | /* fallback if no DMA available */ |
481 | if (dma == (unsigned char)-1) { | 481 | if (dma == (unsigned char)-1) { |
482 | readsl(ioaddr + reg, buf, len); | 482 | readsl(ioaddr + reg, buf, len); |
483 | return; | 483 | return; |
484 | } | 484 | } |
485 | 485 | ||
486 | /* 64 bit alignment is required for memory to memory DMA */ | 486 | /* 64 bit alignment is required for memory to memory DMA */ |
487 | if ((long)buf & 4) { | 487 | if ((long)buf & 4) { |
488 | *((u32 *)buf) = SMC_inl(ioaddr, reg); | 488 | *((u32 *)buf) = SMC_inl(ioaddr, reg); |
489 | buf += 4; | 489 | buf += 4; |
490 | len--; | 490 | len--; |
491 | } | 491 | } |
492 | 492 | ||
493 | len *= 4; | 493 | len *= 4; |
494 | dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); | 494 | dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); |
495 | DCSR(dma) = DCSR_NODESC; | 495 | DCSR(dma) = DCSR_NODESC; |
496 | DTADR(dma) = dmabuf; | 496 | DTADR(dma) = dmabuf; |
497 | DSADR(dma) = physaddr + reg; | 497 | DSADR(dma) = physaddr + reg; |
498 | DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | | 498 | DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | |
499 | DCMD_WIDTH4 | (DCMD_LENGTH & len)); | 499 | DCMD_WIDTH4 | (DCMD_LENGTH & len)); |
500 | DCSR(dma) = DCSR_NODESC | DCSR_RUN; | 500 | DCSR(dma) = DCSR_NODESC | DCSR_RUN; |
501 | while (!(DCSR(dma) & DCSR_STOPSTATE)) | 501 | while (!(DCSR(dma) & DCSR_STOPSTATE)) |
502 | cpu_relax(); | 502 | cpu_relax(); |
503 | DCSR(dma) = 0; | 503 | DCSR(dma) = 0; |
504 | dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); | 504 | dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); |
505 | } | 505 | } |
506 | #endif | 506 | #endif |
507 | 507 | ||
508 | #ifdef SMC_insw | 508 | #ifdef SMC_insw |
509 | #undef SMC_insw | 509 | #undef SMC_insw |
510 | #define SMC_insw(a, r, p, l) \ | 510 | #define SMC_insw(a, r, p, l) \ |
511 | smc_pxa_dma_insw(a, lp, r, dev->dma, p, l) | 511 | smc_pxa_dma_insw(a, lp, r, dev->dma, p, l) |
512 | static inline void | 512 | static inline void |
513 | smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, | 513 | smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, |
514 | u_char *buf, int len) | 514 | u_char *buf, int len) |
515 | { | 515 | { |
516 | u_long physaddr = lp->physaddr; | 516 | u_long physaddr = lp->physaddr; |
517 | dma_addr_t dmabuf; | 517 | dma_addr_t dmabuf; |
518 | 518 | ||
519 | /* fallback if no DMA available */ | 519 | /* fallback if no DMA available */ |
520 | if (dma == (unsigned char)-1) { | 520 | if (dma == (unsigned char)-1) { |
521 | readsw(ioaddr + reg, buf, len); | 521 | readsw(ioaddr + reg, buf, len); |
522 | return; | 522 | return; |
523 | } | 523 | } |
524 | 524 | ||
525 | /* 64 bit alignment is required for memory to memory DMA */ | 525 | /* 64 bit alignment is required for memory to memory DMA */ |
526 | while ((long)buf & 6) { | 526 | while ((long)buf & 6) { |
527 | *((u16 *)buf) = SMC_inw(ioaddr, reg); | 527 | *((u16 *)buf) = SMC_inw(ioaddr, reg); |
528 | buf += 2; | 528 | buf += 2; |
529 | len--; | 529 | len--; |
530 | } | 530 | } |
531 | 531 | ||
532 | len *= 2; | 532 | len *= 2; |
533 | dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); | 533 | dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); |
534 | DCSR(dma) = DCSR_NODESC; | 534 | DCSR(dma) = DCSR_NODESC; |
535 | DTADR(dma) = dmabuf; | 535 | DTADR(dma) = dmabuf; |
536 | DSADR(dma) = physaddr + reg; | 536 | DSADR(dma) = physaddr + reg; |
537 | DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | | 537 | DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | |
538 | DCMD_WIDTH2 | (DCMD_LENGTH & len)); | 538 | DCMD_WIDTH2 | (DCMD_LENGTH & len)); |
539 | DCSR(dma) = DCSR_NODESC | DCSR_RUN; | 539 | DCSR(dma) = DCSR_NODESC | DCSR_RUN; |
540 | while (!(DCSR(dma) & DCSR_STOPSTATE)) | 540 | while (!(DCSR(dma) & DCSR_STOPSTATE)) |
541 | cpu_relax(); | 541 | cpu_relax(); |
542 | DCSR(dma) = 0; | 542 | DCSR(dma) = 0; |
543 | dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); | 543 | dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); |
544 | } | 544 | } |
545 | #endif | 545 | #endif |
546 | 546 | ||
547 | static void | 547 | static void |
548 | smc_pxa_dma_irq(int dma, void *dummy) | 548 | smc_pxa_dma_irq(int dma, void *dummy) |
549 | { | 549 | { |
550 | DCSR(dma) = 0; | 550 | DCSR(dma) = 0; |
551 | } | 551 | } |
552 | #endif /* CONFIG_ARCH_PXA */ | 552 | #endif /* CONFIG_ARCH_PXA */ |
553 | 553 | ||
554 | 554 | ||
555 | /* | 555 | /* |
556 | * Everything a particular hardware setup needs should have been defined | 556 | * Everything a particular hardware setup needs should have been defined |
557 | * at this point. Add stubs for the undefined cases, mainly to avoid | 557 | * at this point. Add stubs for the undefined cases, mainly to avoid |
558 | * compilation warnings since they'll be optimized away, or to prevent buggy | 558 | * compilation warnings since they'll be optimized away, or to prevent buggy |
559 | * use of them. | 559 | * use of them. |
560 | */ | 560 | */ |
561 | 561 | ||
562 | #if ! SMC_CAN_USE_32BIT | 562 | #if ! SMC_CAN_USE_32BIT |
563 | #define SMC_inl(ioaddr, reg) ({ BUG(); 0; }) | 563 | #define SMC_inl(ioaddr, reg) ({ BUG(); 0; }) |
564 | #define SMC_outl(x, ioaddr, reg) BUG() | 564 | #define SMC_outl(x, ioaddr, reg) BUG() |
565 | #define SMC_insl(a, r, p, l) BUG() | 565 | #define SMC_insl(a, r, p, l) BUG() |
566 | #define SMC_outsl(a, r, p, l) BUG() | 566 | #define SMC_outsl(a, r, p, l) BUG() |
567 | #endif | 567 | #endif |
568 | 568 | ||
569 | #if !defined(SMC_insl) || !defined(SMC_outsl) | 569 | #if !defined(SMC_insl) || !defined(SMC_outsl) |
570 | #define SMC_insl(a, r, p, l) BUG() | 570 | #define SMC_insl(a, r, p, l) BUG() |
571 | #define SMC_outsl(a, r, p, l) BUG() | 571 | #define SMC_outsl(a, r, p, l) BUG() |
572 | #endif | 572 | #endif |
573 | 573 | ||
574 | #if ! SMC_CAN_USE_16BIT | 574 | #if ! SMC_CAN_USE_16BIT |
575 | 575 | ||
576 | /* | 576 | /* |
577 | * Any 16-bit access is performed with two 8-bit accesses if the hardware | 577 | * Any 16-bit access is performed with two 8-bit accesses if the hardware |
578 | * can't do it directly. Most registers are 16-bit so those are mandatory. | 578 | * can't do it directly. Most registers are 16-bit so those are mandatory. |
579 | */ | 579 | */ |
580 | #define SMC_outw(x, ioaddr, reg) \ | 580 | #define SMC_outw(x, ioaddr, reg) \ |
581 | do { \ | 581 | do { \ |
582 | unsigned int __val16 = (x); \ | 582 | unsigned int __val16 = (x); \ |
583 | SMC_outb( __val16, ioaddr, reg ); \ | 583 | SMC_outb( __val16, ioaddr, reg ); \ |
584 | SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ | 584 | SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ |
585 | } while (0) | 585 | } while (0) |
586 | #define SMC_inw(ioaddr, reg) \ | 586 | #define SMC_inw(ioaddr, reg) \ |
587 | ({ \ | 587 | ({ \ |
588 | unsigned int __val16; \ | 588 | unsigned int __val16; \ |
589 | __val16 = SMC_inb( ioaddr, reg ); \ | 589 | __val16 = SMC_inb( ioaddr, reg ); \ |
590 | __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ | 590 | __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ |
591 | __val16; \ | 591 | __val16; \ |
592 | }) | 592 | }) |
593 | 593 | ||
594 | #define SMC_insw(a, r, p, l) BUG() | 594 | #define SMC_insw(a, r, p, l) BUG() |
595 | #define SMC_outsw(a, r, p, l) BUG() | 595 | #define SMC_outsw(a, r, p, l) BUG() |
596 | 596 | ||
597 | #endif | 597 | #endif |
598 | 598 | ||
599 | #if !defined(SMC_insw) || !defined(SMC_outsw) | 599 | #if !defined(SMC_insw) || !defined(SMC_outsw) |
600 | #define SMC_insw(a, r, p, l) BUG() | 600 | #define SMC_insw(a, r, p, l) BUG() |
601 | #define SMC_outsw(a, r, p, l) BUG() | 601 | #define SMC_outsw(a, r, p, l) BUG() |
602 | #endif | 602 | #endif |
603 | 603 | ||
604 | #if ! SMC_CAN_USE_8BIT | 604 | #if ! SMC_CAN_USE_8BIT |
605 | #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) | 605 | #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) |
606 | #define SMC_outb(x, ioaddr, reg) BUG() | 606 | #define SMC_outb(x, ioaddr, reg) BUG() |
607 | #define SMC_insb(a, r, p, l) BUG() | 607 | #define SMC_insb(a, r, p, l) BUG() |
608 | #define SMC_outsb(a, r, p, l) BUG() | 608 | #define SMC_outsb(a, r, p, l) BUG() |
609 | #endif | 609 | #endif |
610 | 610 | ||
611 | #if !defined(SMC_insb) || !defined(SMC_outsb) | 611 | #if !defined(SMC_insb) || !defined(SMC_outsb) |
612 | #define SMC_insb(a, r, p, l) BUG() | 612 | #define SMC_insb(a, r, p, l) BUG() |
613 | #define SMC_outsb(a, r, p, l) BUG() | 613 | #define SMC_outsb(a, r, p, l) BUG() |
614 | #endif | 614 | #endif |
615 | 615 | ||
616 | #ifndef SMC_CAN_USE_DATACS | 616 | #ifndef SMC_CAN_USE_DATACS |
617 | #define SMC_CAN_USE_DATACS 0 | 617 | #define SMC_CAN_USE_DATACS 0 |
618 | #endif | 618 | #endif |
619 | 619 | ||
620 | #ifndef SMC_IO_SHIFT | 620 | #ifndef SMC_IO_SHIFT |
621 | #define SMC_IO_SHIFT 0 | 621 | #define SMC_IO_SHIFT 0 |
622 | #endif | 622 | #endif |
623 | 623 | ||
624 | #ifndef SMC_IRQ_FLAGS | 624 | #ifndef SMC_IRQ_FLAGS |
625 | #define SMC_IRQ_FLAGS IRQF_TRIGGER_RISING | 625 | #define SMC_IRQ_FLAGS IRQF_TRIGGER_RISING |
626 | #endif | 626 | #endif |
627 | 627 | ||
628 | #ifndef SMC_INTERRUPT_PREAMBLE | 628 | #ifndef SMC_INTERRUPT_PREAMBLE |
629 | #define SMC_INTERRUPT_PREAMBLE | 629 | #define SMC_INTERRUPT_PREAMBLE |
630 | #endif | 630 | #endif |
631 | 631 | ||
632 | 632 | ||
633 | /* Because of bank switching, the LAN91x uses only 16 I/O ports */ | 633 | /* Because of bank switching, the LAN91x uses only 16 I/O ports */ |
634 | #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) | 634 | #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) |
635 | #define SMC_DATA_EXTENT (4) | 635 | #define SMC_DATA_EXTENT (4) |
636 | 636 | ||
637 | /* | 637 | /* |
638 | . Bank Select Register: | 638 | . Bank Select Register: |
639 | . | 639 | . |
640 | . yyyy yyyy 0000 00xx | 640 | . yyyy yyyy 0000 00xx |
641 | . xx = bank number | 641 | . xx = bank number |
642 | . yyyy yyyy = 0x33, for identification purposes. | 642 | . yyyy yyyy = 0x33, for identification purposes. |
643 | */ | 643 | */ |
644 | #define BANK_SELECT (14 << SMC_IO_SHIFT) | 644 | #define BANK_SELECT (14 << SMC_IO_SHIFT) |
645 | 645 | ||
646 | 646 | ||
647 | // Transmit Control Register | 647 | // Transmit Control Register |
648 | /* BANK 0 */ | 648 | /* BANK 0 */ |
649 | #define TCR_REG(lp) SMC_REG(lp, 0x0000, 0) | 649 | #define TCR_REG(lp) SMC_REG(lp, 0x0000, 0) |
650 | #define TCR_ENABLE 0x0001 // When 1 we can transmit | 650 | #define TCR_ENABLE 0x0001 // When 1 we can transmit |
651 | #define TCR_LOOP 0x0002 // Controls output pin LBK | 651 | #define TCR_LOOP 0x0002 // Controls output pin LBK |
652 | #define TCR_FORCOL 0x0004 // When 1 will force a collision | 652 | #define TCR_FORCOL 0x0004 // When 1 will force a collision |
653 | #define TCR_PAD_EN 0x0080 // When 1 will pad tx frames < 64 bytes w/0 | 653 | #define TCR_PAD_EN 0x0080 // When 1 will pad tx frames < 64 bytes w/0 |
654 | #define TCR_NOCRC 0x0100 // When 1 will not append CRC to tx frames | 654 | #define TCR_NOCRC 0x0100 // When 1 will not append CRC to tx frames |
655 | #define TCR_MON_CSN 0x0400 // When 1 tx monitors carrier | 655 | #define TCR_MON_CSN 0x0400 // When 1 tx monitors carrier |
656 | #define TCR_FDUPLX 0x0800 // When 1 enables full duplex operation | 656 | #define TCR_FDUPLX 0x0800 // When 1 enables full duplex operation |
657 | #define TCR_STP_SQET 0x1000 // When 1 stops tx if Signal Quality Error | 657 | #define TCR_STP_SQET 0x1000 // When 1 stops tx if Signal Quality Error |
658 | #define TCR_EPH_LOOP 0x2000 // When 1 enables EPH block loopback | 658 | #define TCR_EPH_LOOP 0x2000 // When 1 enables EPH block loopback |
659 | #define TCR_SWFDUP 0x8000 // When 1 enables Switched Full Duplex mode | 659 | #define TCR_SWFDUP 0x8000 // When 1 enables Switched Full Duplex mode |
660 | 660 | ||
661 | #define TCR_CLEAR 0 /* do NOTHING */ | 661 | #define TCR_CLEAR 0 /* do NOTHING */ |
662 | /* the default settings for the TCR register : */ | 662 | /* the default settings for the TCR register : */ |
663 | #define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN) | 663 | #define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN) |
664 | 664 | ||
665 | 665 | ||
666 | // EPH Status Register | 666 | // EPH Status Register |
667 | /* BANK 0 */ | 667 | /* BANK 0 */ |
668 | #define EPH_STATUS_REG(lp) SMC_REG(lp, 0x0002, 0) | 668 | #define EPH_STATUS_REG(lp) SMC_REG(lp, 0x0002, 0) |
669 | #define ES_TX_SUC 0x0001 // Last TX was successful | 669 | #define ES_TX_SUC 0x0001 // Last TX was successful |
670 | #define ES_SNGL_COL 0x0002 // Single collision detected for last tx | 670 | #define ES_SNGL_COL 0x0002 // Single collision detected for last tx |
671 | #define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx | 671 | #define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx |
672 | #define ES_LTX_MULT 0x0008 // Last tx was a multicast | 672 | #define ES_LTX_MULT 0x0008 // Last tx was a multicast |
673 | #define ES_16COL 0x0010 // 16 Collisions Reached | 673 | #define ES_16COL 0x0010 // 16 Collisions Reached |
674 | #define ES_SQET 0x0020 // Signal Quality Error Test | 674 | #define ES_SQET 0x0020 // Signal Quality Error Test |
675 | #define ES_LTXBRD 0x0040 // Last tx was a broadcast | 675 | #define ES_LTXBRD 0x0040 // Last tx was a broadcast |
676 | #define ES_TXDEFR 0x0080 // Transmit Deferred | 676 | #define ES_TXDEFR 0x0080 // Transmit Deferred |
677 | #define ES_LATCOL 0x0200 // Late collision detected on last tx | 677 | #define ES_LATCOL 0x0200 // Late collision detected on last tx |
678 | #define ES_LOSTCARR 0x0400 // Lost Carrier Sense | 678 | #define ES_LOSTCARR 0x0400 // Lost Carrier Sense |
679 | #define ES_EXC_DEF 0x0800 // Excessive Deferral | 679 | #define ES_EXC_DEF 0x0800 // Excessive Deferral |
680 | #define ES_CTR_ROL 0x1000 // Counter Roll Over indication | 680 | #define ES_CTR_ROL 0x1000 // Counter Roll Over indication |
681 | #define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin | 681 | #define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin |
682 | #define ES_TXUNRN 0x8000 // Tx Underrun | 682 | #define ES_TXUNRN 0x8000 // Tx Underrun |
683 | 683 | ||
684 | 684 | ||
685 | // Receive Control Register | 685 | // Receive Control Register |
686 | /* BANK 0 */ | 686 | /* BANK 0 */ |
687 | #define RCR_REG(lp) SMC_REG(lp, 0x0004, 0) | 687 | #define RCR_REG(lp) SMC_REG(lp, 0x0004, 0) |
688 | #define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted | 688 | #define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted |
689 | #define RCR_PRMS 0x0002 // Enable promiscuous mode | 689 | #define RCR_PRMS 0x0002 // Enable promiscuous mode |
690 | #define RCR_ALMUL 0x0004 // When set accepts all multicast frames | 690 | #define RCR_ALMUL 0x0004 // When set accepts all multicast frames |
691 | #define RCR_RXEN 0x0100 // IFF this is set, we can receive packets | 691 | #define RCR_RXEN 0x0100 // IFF this is set, we can receive packets |
692 | #define RCR_STRIP_CRC 0x0200 // When set strips CRC from rx packets | 692 | #define RCR_STRIP_CRC 0x0200 // When set strips CRC from rx packets |
693 | #define RCR_ABORT_ENB 0x0200 // When set will abort rx on collision | 693 | #define RCR_ABORT_ENB 0x0200 // When set will abort rx on collision |
694 | #define RCR_FILT_CAR 0x0400 // When set filters leading 12 bit s of carrier | 694 | #define RCR_FILT_CAR 0x0400 // When set filters leading 12 bit s of carrier |
695 | #define RCR_SOFTRST 0x8000 // resets the chip | 695 | #define RCR_SOFTRST 0x8000 // resets the chip |
696 | 696 | ||
697 | /* the normal settings for the RCR register : */ | 697 | /* the normal settings for the RCR register : */ |
698 | #define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) | 698 | #define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) |
699 | #define RCR_CLEAR 0x0 // set it to a base state | 699 | #define RCR_CLEAR 0x0 // set it to a base state |
700 | 700 | ||
701 | 701 | ||
702 | // Counter Register | 702 | // Counter Register |
703 | /* BANK 0 */ | 703 | /* BANK 0 */ |
704 | #define COUNTER_REG(lp) SMC_REG(lp, 0x0006, 0) | 704 | #define COUNTER_REG(lp) SMC_REG(lp, 0x0006, 0) |
705 | 705 | ||
706 | 706 | ||
707 | // Memory Information Register | 707 | // Memory Information Register |
708 | /* BANK 0 */ | 708 | /* BANK 0 */ |
709 | #define MIR_REG(lp) SMC_REG(lp, 0x0008, 0) | 709 | #define MIR_REG(lp) SMC_REG(lp, 0x0008, 0) |
710 | 710 | ||
711 | 711 | ||
712 | // Receive/Phy Control Register | 712 | // Receive/Phy Control Register |
713 | /* BANK 0 */ | 713 | /* BANK 0 */ |
714 | #define RPC_REG(lp) SMC_REG(lp, 0x000A, 0) | 714 | #define RPC_REG(lp) SMC_REG(lp, 0x000A, 0) |
715 | #define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. | 715 | #define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. |
716 | #define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode | 716 | #define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode |
717 | #define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode | 717 | #define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode |
718 | #define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb | 718 | #define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb |
719 | #define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb | 719 | #define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb |
720 | 720 | ||
721 | #ifndef RPC_LSA_DEFAULT | 721 | #ifndef RPC_LSA_DEFAULT |
722 | #define RPC_LSA_DEFAULT RPC_LED_100 | 722 | #define RPC_LSA_DEFAULT RPC_LED_100 |
723 | #endif | 723 | #endif |
724 | #ifndef RPC_LSB_DEFAULT | 724 | #ifndef RPC_LSB_DEFAULT |
725 | #define RPC_LSB_DEFAULT RPC_LED_FD | 725 | #define RPC_LSB_DEFAULT RPC_LED_FD |
726 | #endif | 726 | #endif |
727 | 727 | ||
728 | #define RPC_DEFAULT (RPC_ANEG | RPC_SPEED | RPC_DPLX) | 728 | #define RPC_DEFAULT (RPC_ANEG | RPC_SPEED | RPC_DPLX) |
729 | 729 | ||
730 | 730 | ||
731 | /* Bank 0 0x0C is reserved */ | 731 | /* Bank 0 0x0C is reserved */ |
732 | 732 | ||
733 | // Bank Select Register | 733 | // Bank Select Register |
734 | /* All Banks */ | 734 | /* All Banks */ |
735 | #define BSR_REG 0x000E | 735 | #define BSR_REG 0x000E |
736 | 736 | ||
737 | 737 | ||
738 | // Configuration Reg | 738 | // Configuration Reg |
739 | /* BANK 1 */ | 739 | /* BANK 1 */ |
740 | #define CONFIG_REG(lp) SMC_REG(lp, 0x0000, 1) | 740 | #define CONFIG_REG(lp) SMC_REG(lp, 0x0000, 1) |
741 | #define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy | 741 | #define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy |
742 | #define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL | 742 | #define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL |
743 | #define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus | 743 | #define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus |
744 | #define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode. | 744 | #define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode. |
745 | 745 | ||
746 | // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low | 746 | // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low |
747 | #define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) | 747 | #define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) |
748 | 748 | ||
749 | 749 | ||
750 | // Base Address Register | 750 | // Base Address Register |
751 | /* BANK 1 */ | 751 | /* BANK 1 */ |
752 | #define BASE_REG(lp) SMC_REG(lp, 0x0002, 1) | 752 | #define BASE_REG(lp) SMC_REG(lp, 0x0002, 1) |
753 | 753 | ||
754 | 754 | ||
755 | // Individual Address Registers | 755 | // Individual Address Registers |
756 | /* BANK 1 */ | 756 | /* BANK 1 */ |
757 | #define ADDR0_REG(lp) SMC_REG(lp, 0x0004, 1) | 757 | #define ADDR0_REG(lp) SMC_REG(lp, 0x0004, 1) |
758 | #define ADDR1_REG(lp) SMC_REG(lp, 0x0006, 1) | 758 | #define ADDR1_REG(lp) SMC_REG(lp, 0x0006, 1) |
759 | #define ADDR2_REG(lp) SMC_REG(lp, 0x0008, 1) | 759 | #define ADDR2_REG(lp) SMC_REG(lp, 0x0008, 1) |
760 | 760 | ||
761 | 761 | ||
762 | // General Purpose Register | 762 | // General Purpose Register |
763 | /* BANK 1 */ | 763 | /* BANK 1 */ |
764 | #define GP_REG(lp) SMC_REG(lp, 0x000A, 1) | 764 | #define GP_REG(lp) SMC_REG(lp, 0x000A, 1) |
765 | 765 | ||
766 | 766 | ||
767 | // Control Register | 767 | // Control Register |
768 | /* BANK 1 */ | 768 | /* BANK 1 */ |
769 | #define CTL_REG(lp) SMC_REG(lp, 0x000C, 1) | 769 | #define CTL_REG(lp) SMC_REG(lp, 0x000C, 1) |
770 | #define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received | 770 | #define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received |
771 | #define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically | 771 | #define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically |
772 | #define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt | 772 | #define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt |
773 | #define CTL_CR_ENABLE 0x0040 // When 1 enables Counter Rollover interrupt | 773 | #define CTL_CR_ENABLE 0x0040 // When 1 enables Counter Rollover interrupt |
774 | #define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt | 774 | #define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt |
775 | #define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store | 775 | #define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store |
776 | #define CTL_RELOAD 0x0002 // When set reads EEPROM into registers | 776 | #define CTL_RELOAD 0x0002 // When set reads EEPROM into registers |
777 | #define CTL_STORE 0x0001 // When set stores registers into EEPROM | 777 | #define CTL_STORE 0x0001 // When set stores registers into EEPROM |
778 | 778 | ||
779 | 779 | ||
780 | // MMU Command Register | 780 | // MMU Command Register |
781 | /* BANK 2 */ | 781 | /* BANK 2 */ |
782 | #define MMU_CMD_REG(lp) SMC_REG(lp, 0x0000, 2) | 782 | #define MMU_CMD_REG(lp) SMC_REG(lp, 0x0000, 2) |
783 | #define MC_BUSY 1 // When 1 the last release has not completed | 783 | #define MC_BUSY 1 // When 1 the last release has not completed |
784 | #define MC_NOP (0<<5) // No Op | 784 | #define MC_NOP (0<<5) // No Op |
785 | #define MC_ALLOC (1<<5) // OR with number of 256 byte packets | 785 | #define MC_ALLOC (1<<5) // OR with number of 256 byte packets |
786 | #define MC_RESET (2<<5) // Reset MMU to initial state | 786 | #define MC_RESET (2<<5) // Reset MMU to initial state |
787 | #define MC_REMOVE (3<<5) // Remove the current rx packet | 787 | #define MC_REMOVE (3<<5) // Remove the current rx packet |
788 | #define MC_RELEASE (4<<5) // Remove and release the current rx packet | 788 | #define MC_RELEASE (4<<5) // Remove and release the current rx packet |
789 | #define MC_FREEPKT (5<<5) // Release packet in PNR register | 789 | #define MC_FREEPKT (5<<5) // Release packet in PNR register |
790 | #define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit | 790 | #define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit |
791 | #define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs | 791 | #define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs |
792 | 792 | ||
793 | 793 | ||
794 | // Packet Number Register | 794 | // Packet Number Register |
795 | /* BANK 2 */ | 795 | /* BANK 2 */ |
796 | #define PN_REG(lp) SMC_REG(lp, 0x0002, 2) | 796 | #define PN_REG(lp) SMC_REG(lp, 0x0002, 2) |
797 | 797 | ||
798 | 798 | ||
799 | // Allocation Result Register | 799 | // Allocation Result Register |
800 | /* BANK 2 */ | 800 | /* BANK 2 */ |
801 | #define AR_REG(lp) SMC_REG(lp, 0x0003, 2) | 801 | #define AR_REG(lp) SMC_REG(lp, 0x0003, 2) |
802 | #define AR_FAILED 0x80 // Alocation Failed | 802 | #define AR_FAILED 0x80 // Alocation Failed |
803 | 803 | ||
804 | 804 | ||
805 | // TX FIFO Ports Register | 805 | // TX FIFO Ports Register |
806 | /* BANK 2 */ | 806 | /* BANK 2 */ |
807 | #define TXFIFO_REG(lp) SMC_REG(lp, 0x0004, 2) | 807 | #define TXFIFO_REG(lp) SMC_REG(lp, 0x0004, 2) |
808 | #define TXFIFO_TEMPTY 0x80 // TX FIFO Empty | 808 | #define TXFIFO_TEMPTY 0x80 // TX FIFO Empty |
809 | 809 | ||
810 | // RX FIFO Ports Register | 810 | // RX FIFO Ports Register |
811 | /* BANK 2 */ | 811 | /* BANK 2 */ |
812 | #define RXFIFO_REG(lp) SMC_REG(lp, 0x0005, 2) | 812 | #define RXFIFO_REG(lp) SMC_REG(lp, 0x0005, 2) |
813 | #define RXFIFO_REMPTY 0x80 // RX FIFO Empty | 813 | #define RXFIFO_REMPTY 0x80 // RX FIFO Empty |
814 | 814 | ||
815 | #define FIFO_REG(lp) SMC_REG(lp, 0x0004, 2) | 815 | #define FIFO_REG(lp) SMC_REG(lp, 0x0004, 2) |
816 | 816 | ||
817 | // Pointer Register | 817 | // Pointer Register |
818 | /* BANK 2 */ | 818 | /* BANK 2 */ |
819 | #define PTR_REG(lp) SMC_REG(lp, 0x0006, 2) | 819 | #define PTR_REG(lp) SMC_REG(lp, 0x0006, 2) |
820 | #define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area | 820 | #define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area |
821 | #define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access | 821 | #define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access |
822 | #define PTR_READ 0x2000 // When 1 the operation is a read | 822 | #define PTR_READ 0x2000 // When 1 the operation is a read |
823 | 823 | ||
824 | 824 | ||
825 | // Data Register | 825 | // Data Register |
826 | /* BANK 2 */ | 826 | /* BANK 2 */ |
827 | #define DATA_REG(lp) SMC_REG(lp, 0x0008, 2) | 827 | #define DATA_REG(lp) SMC_REG(lp, 0x0008, 2) |
828 | 828 | ||
829 | 829 | ||
830 | // Interrupt Status/Acknowledge Register | 830 | // Interrupt Status/Acknowledge Register |
831 | /* BANK 2 */ | 831 | /* BANK 2 */ |
832 | #define INT_REG(lp) SMC_REG(lp, 0x000C, 2) | 832 | #define INT_REG(lp) SMC_REG(lp, 0x000C, 2) |
833 | 833 | ||
834 | 834 | ||
835 | // Interrupt Mask Register | 835 | // Interrupt Mask Register |
836 | /* BANK 2 */ | 836 | /* BANK 2 */ |
837 | #define IM_REG(lp) SMC_REG(lp, 0x000D, 2) | 837 | #define IM_REG(lp) SMC_REG(lp, 0x000D, 2) |
838 | #define IM_MDINT 0x80 // PHY MI Register 18 Interrupt | 838 | #define IM_MDINT 0x80 // PHY MI Register 18 Interrupt |
839 | #define IM_ERCV_INT 0x40 // Early Receive Interrupt | 839 | #define IM_ERCV_INT 0x40 // Early Receive Interrupt |
840 | #define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section | 840 | #define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section |
841 | #define IM_RX_OVRN_INT 0x10 // Set by Receiver Overruns | 841 | #define IM_RX_OVRN_INT 0x10 // Set by Receiver Overruns |
842 | #define IM_ALLOC_INT 0x08 // Set when allocation request is completed | 842 | #define IM_ALLOC_INT 0x08 // Set when allocation request is completed |
843 | #define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty | 843 | #define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty |
844 | #define IM_TX_INT 0x02 // Transmit Interrupt | 844 | #define IM_TX_INT 0x02 // Transmit Interrupt |
845 | #define IM_RCV_INT 0x01 // Receive Interrupt | 845 | #define IM_RCV_INT 0x01 // Receive Interrupt |
846 | 846 | ||
847 | 847 | ||
848 | // Multicast Table Registers | 848 | // Multicast Table Registers |
849 | /* BANK 3 */ | 849 | /* BANK 3 */ |
850 | #define MCAST_REG1(lp) SMC_REG(lp, 0x0000, 3) | 850 | #define MCAST_REG1(lp) SMC_REG(lp, 0x0000, 3) |
851 | #define MCAST_REG2(lp) SMC_REG(lp, 0x0002, 3) | 851 | #define MCAST_REG2(lp) SMC_REG(lp, 0x0002, 3) |
852 | #define MCAST_REG3(lp) SMC_REG(lp, 0x0004, 3) | 852 | #define MCAST_REG3(lp) SMC_REG(lp, 0x0004, 3) |
853 | #define MCAST_REG4(lp) SMC_REG(lp, 0x0006, 3) | 853 | #define MCAST_REG4(lp) SMC_REG(lp, 0x0006, 3) |
854 | 854 | ||
855 | 855 | ||
856 | // Management Interface Register (MII) | 856 | // Management Interface Register (MII) |
857 | /* BANK 3 */ | 857 | /* BANK 3 */ |
858 | #define MII_REG(lp) SMC_REG(lp, 0x0008, 3) | 858 | #define MII_REG(lp) SMC_REG(lp, 0x0008, 3) |
859 | #define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup | 859 | #define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup |
860 | #define MII_MDOE 0x0008 // MII Output Enable | 860 | #define MII_MDOE 0x0008 // MII Output Enable |
861 | #define MII_MCLK 0x0004 // MII Clock, pin MDCLK | 861 | #define MII_MCLK 0x0004 // MII Clock, pin MDCLK |
862 | #define MII_MDI 0x0002 // MII Input, pin MDI | 862 | #define MII_MDI 0x0002 // MII Input, pin MDI |
863 | #define MII_MDO 0x0001 // MII Output, pin MDO | 863 | #define MII_MDO 0x0001 // MII Output, pin MDO |
864 | 864 | ||
865 | 865 | ||
866 | // Revision Register | 866 | // Revision Register |
867 | /* BANK 3 */ | 867 | /* BANK 3 */ |
868 | /* ( hi: chip id low: rev # ) */ | 868 | /* ( hi: chip id low: rev # ) */ |
869 | #define REV_REG(lp) SMC_REG(lp, 0x000A, 3) | 869 | #define REV_REG(lp) SMC_REG(lp, 0x000A, 3) |
870 | 870 | ||
871 | 871 | ||
872 | // Early RCV Register | 872 | // Early RCV Register |
873 | /* BANK 3 */ | 873 | /* BANK 3 */ |
874 | /* this is NOT on SMC9192 */ | 874 | /* this is NOT on SMC9192 */ |
875 | #define ERCV_REG(lp) SMC_REG(lp, 0x000C, 3) | 875 | #define ERCV_REG(lp) SMC_REG(lp, 0x000C, 3) |
876 | #define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received | 876 | #define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received |
877 | #define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask | 877 | #define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask |
878 | 878 | ||
879 | 879 | ||
880 | // External Register | 880 | // External Register |
881 | /* BANK 7 */ | 881 | /* BANK 7 */ |
882 | #define EXT_REG(lp) SMC_REG(lp, 0x0000, 7) | 882 | #define EXT_REG(lp) SMC_REG(lp, 0x0000, 7) |
883 | 883 | ||
884 | 884 | ||
885 | #define CHIP_9192 3 | 885 | #define CHIP_9192 3 |
886 | #define CHIP_9194 4 | 886 | #define CHIP_9194 4 |
887 | #define CHIP_9195 5 | 887 | #define CHIP_9195 5 |
888 | #define CHIP_9196 6 | 888 | #define CHIP_9196 6 |
889 | #define CHIP_91100 7 | 889 | #define CHIP_91100 7 |
890 | #define CHIP_91100FD 8 | 890 | #define CHIP_91100FD 8 |
891 | #define CHIP_91111FD 9 | 891 | #define CHIP_91111FD 9 |
892 | 892 | ||
893 | static const char * chip_ids[ 16 ] = { | 893 | static const char * chip_ids[ 16 ] = { |
894 | NULL, NULL, NULL, | 894 | NULL, NULL, NULL, |
895 | /* 3 */ "SMC91C90/91C92", | 895 | /* 3 */ "SMC91C90/91C92", |
896 | /* 4 */ "SMC91C94", | 896 | /* 4 */ "SMC91C94", |
897 | /* 5 */ "SMC91C95", | 897 | /* 5 */ "SMC91C95", |
898 | /* 6 */ "SMC91C96", | 898 | /* 6 */ "SMC91C96", |
899 | /* 7 */ "SMC91C100", | 899 | /* 7 */ "SMC91C100", |
900 | /* 8 */ "SMC91C100FD", | 900 | /* 8 */ "SMC91C100FD", |
901 | /* 9 */ "SMC91C11xFD", | 901 | /* 9 */ "SMC91C11xFD", |
902 | NULL, NULL, NULL, | 902 | NULL, NULL, NULL, |
903 | NULL, NULL, NULL}; | 903 | NULL, NULL, NULL}; |
904 | 904 | ||
905 | 905 | ||
906 | /* | 906 | /* |
907 | . Receive status bits | 907 | . Receive status bits |
908 | */ | 908 | */ |
909 | #define RS_ALGNERR 0x8000 | 909 | #define RS_ALGNERR 0x8000 |
910 | #define RS_BRODCAST 0x4000 | 910 | #define RS_BRODCAST 0x4000 |
911 | #define RS_BADCRC 0x2000 | 911 | #define RS_BADCRC 0x2000 |
912 | #define RS_ODDFRAME 0x1000 | 912 | #define RS_ODDFRAME 0x1000 |
913 | #define RS_TOOLONG 0x0800 | 913 | #define RS_TOOLONG 0x0800 |
914 | #define RS_TOOSHORT 0x0400 | 914 | #define RS_TOOSHORT 0x0400 |
915 | #define RS_MULTICAST 0x0001 | 915 | #define RS_MULTICAST 0x0001 |
916 | #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) | 916 | #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) |
917 | 917 | ||
918 | 918 | ||
919 | /* | 919 | /* |
920 | * PHY IDs | 920 | * PHY IDs |
921 | * LAN83C183 == LAN91C111 Internal PHY | 921 | * LAN83C183 == LAN91C111 Internal PHY |
922 | */ | 922 | */ |
923 | #define PHY_LAN83C183 0x0016f840 | 923 | #define PHY_LAN83C183 0x0016f840 |
924 | #define PHY_LAN83C180 0x02821c50 | 924 | #define PHY_LAN83C180 0x02821c50 |
925 | 925 | ||
926 | /* | 926 | /* |
927 | * PHY Register Addresses (LAN91C111 Internal PHY) | 927 | * PHY Register Addresses (LAN91C111 Internal PHY) |
928 | * | 928 | * |
929 | * Generic PHY registers can be found in <linux/mii.h> | 929 | * Generic PHY registers can be found in <linux/mii.h> |
930 | * | 930 | * |
931 | * These phy registers are specific to our on-board phy. | 931 | * These phy registers are specific to our on-board phy. |
932 | */ | 932 | */ |
933 | 933 | ||
934 | // PHY Configuration Register 1 | 934 | // PHY Configuration Register 1 |
935 | #define PHY_CFG1_REG 0x10 | 935 | #define PHY_CFG1_REG 0x10 |
936 | #define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled | 936 | #define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled |
937 | #define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled | 937 | #define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled |
938 | #define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down | 938 | #define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down |
939 | #define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler | 939 | #define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler |
940 | #define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable | 940 | #define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable |
941 | #define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled | 941 | #define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled |
942 | #define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) | 942 | #define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) |
943 | #define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db | 943 | #define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db |
944 | #define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust | 944 | #define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust |
945 | #define PHY_CFG1_TLVL_MASK 0x003C | 945 | #define PHY_CFG1_TLVL_MASK 0x003C |
946 | #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time | 946 | #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time |
947 | 947 | ||
948 | 948 | ||
949 | // PHY Configuration Register 2 | 949 | // PHY Configuration Register 2 |
950 | #define PHY_CFG2_REG 0x11 | 950 | #define PHY_CFG2_REG 0x11 |
951 | #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled | 951 | #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled |
952 | #define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled | 952 | #define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled |
953 | #define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) | 953 | #define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) |
954 | #define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo | 954 | #define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo |
955 | 955 | ||
956 | // PHY Status Output (and Interrupt status) Register | 956 | // PHY Status Output (and Interrupt status) Register |
957 | #define PHY_INT_REG 0x12 // Status Output (Interrupt Status) | 957 | #define PHY_INT_REG 0x12 // Status Output (Interrupt Status) |
958 | #define PHY_INT_INT 0x8000 // 1=bits have changed since last read | 958 | #define PHY_INT_INT 0x8000 // 1=bits have changed since last read |
959 | #define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected | 959 | #define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected |
960 | #define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync | 960 | #define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync |
961 | #define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx | 961 | #define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx |
962 | #define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx | 962 | #define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx |
963 | #define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx | 963 | #define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx |
964 | #define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected | 964 | #define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected |
965 | #define PHY_INT_JAB 0x0100 // 1=Jabber detected | 965 | #define PHY_INT_JAB 0x0100 // 1=Jabber detected |
966 | #define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode | 966 | #define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode |
967 | #define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex | 967 | #define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex |
968 | 968 | ||
969 | // PHY Interrupt/Status Mask Register | 969 | // PHY Interrupt/Status Mask Register |
970 | #define PHY_MASK_REG 0x13 // Interrupt Mask | 970 | #define PHY_MASK_REG 0x13 // Interrupt Mask |
971 | // Uses the same bit definitions as PHY_INT_REG | 971 | // Uses the same bit definitions as PHY_INT_REG |
972 | 972 | ||
973 | 973 | ||
974 | /* | 974 | /* |
975 | * SMC91C96 ethernet config and status registers. | 975 | * SMC91C96 ethernet config and status registers. |
976 | * These are in the "attribute" space. | 976 | * These are in the "attribute" space. |
977 | */ | 977 | */ |
978 | #define ECOR 0x8000 | 978 | #define ECOR 0x8000 |
979 | #define ECOR_RESET 0x80 | 979 | #define ECOR_RESET 0x80 |
980 | #define ECOR_LEVEL_IRQ 0x40 | 980 | #define ECOR_LEVEL_IRQ 0x40 |
981 | #define ECOR_WR_ATTRIB 0x04 | 981 | #define ECOR_WR_ATTRIB 0x04 |
982 | #define ECOR_ENABLE 0x01 | 982 | #define ECOR_ENABLE 0x01 |
983 | 983 | ||
984 | #define ECSR 0x8002 | 984 | #define ECSR 0x8002 |
985 | #define ECSR_IOIS8 0x20 | 985 | #define ECSR_IOIS8 0x20 |
986 | #define ECSR_PWRDWN 0x04 | 986 | #define ECSR_PWRDWN 0x04 |
987 | #define ECSR_INT 0x02 | 987 | #define ECSR_INT 0x02 |
988 | 988 | ||
989 | #define ATTRIB_SIZE ((64*1024) << SMC_IO_SHIFT) | 989 | #define ATTRIB_SIZE ((64*1024) << SMC_IO_SHIFT) |
990 | 990 | ||
991 | 991 | ||
992 | /* | 992 | /* |
993 | * Macros to abstract register access according to the data bus | 993 | * Macros to abstract register access according to the data bus |
994 | * capabilities. Please use those and not the in/out primitives. | 994 | * capabilities. Please use those and not the in/out primitives. |
995 | * Note: the following macros do *not* select the bank -- this must | 995 | * Note: the following macros do *not* select the bank -- this must |
996 | * be done separately as needed in the main code. The SMC_REG() macro | 996 | * be done separately as needed in the main code. The SMC_REG() macro |
997 | * only uses the bank argument for debugging purposes (when enabled). | 997 | * only uses the bank argument for debugging purposes (when enabled). |
998 | * | 998 | * |
999 | * Note: despite inline functions being safer, everything leading to this | 999 | * Note: despite inline functions being safer, everything leading to this |
1000 | * should preferably be macros to let BUG() display the line number in | 1000 | * should preferably be macros to let BUG() display the line number in |
1001 | * the core source code since we're interested in the top call site | 1001 | * the core source code since we're interested in the top call site |
1002 | * not in any inline function location. | 1002 | * not in any inline function location. |
1003 | */ | 1003 | */ |
1004 | 1004 | ||
1005 | #if SMC_DEBUG > 0 | 1005 | #if SMC_DEBUG > 0 |
1006 | #define SMC_REG(lp, reg, bank) \ | 1006 | #define SMC_REG(lp, reg, bank) \ |
1007 | ({ \ | 1007 | ({ \ |
1008 | int __b = SMC_CURRENT_BANK(lp); \ | 1008 | int __b = SMC_CURRENT_BANK(lp); \ |
1009 | if (unlikely((__b & ~0xf0) != (0x3300 | bank))) { \ | 1009 | if (unlikely((__b & ~0xf0) != (0x3300 | bank))) { \ |
1010 | printk( "%s: bank reg screwed (0x%04x)\n", \ | 1010 | printk( "%s: bank reg screwed (0x%04x)\n", \ |
1011 | CARDNAME, __b ); \ | 1011 | CARDNAME, __b ); \ |
1012 | BUG(); \ | 1012 | BUG(); \ |
1013 | } \ | 1013 | } \ |
1014 | reg<<SMC_IO_SHIFT; \ | 1014 | reg<<SMC_IO_SHIFT; \ |
1015 | }) | 1015 | }) |
1016 | #else | 1016 | #else |
1017 | #define SMC_REG(lp, reg, bank) (reg<<SMC_IO_SHIFT) | 1017 | #define SMC_REG(lp, reg, bank) (reg<<SMC_IO_SHIFT) |
1018 | #endif | 1018 | #endif |
1019 | 1019 | ||
1020 | /* | 1020 | /* |
1021 | * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not | 1021 | * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not |
1022 | * aligned to a 32 bit boundary. I tell you that does exist! | 1022 | * aligned to a 32 bit boundary. I tell you that does exist! |
1023 | * Fortunately the affected register accesses can be easily worked around | 1023 | * Fortunately the affected register accesses can be easily worked around |
1024 | * since we can write zeroes to the preceeding 16 bits without adverse | 1024 | * since we can write zeroes to the preceeding 16 bits without adverse |
1025 | * effects and use a 32-bit access. | 1025 | * effects and use a 32-bit access. |
1026 | * | 1026 | * |
1027 | * Enforce it on any 32-bit capable setup for now. | 1027 | * Enforce it on any 32-bit capable setup for now. |
1028 | */ | 1028 | */ |
1029 | #define SMC_MUST_ALIGN_WRITE(lp) SMC_32BIT(lp) | 1029 | #define SMC_MUST_ALIGN_WRITE(lp) SMC_32BIT(lp) |
1030 | 1030 | ||
1031 | #define SMC_GET_PN(lp) \ | 1031 | #define SMC_GET_PN(lp) \ |
1032 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, PN_REG(lp))) \ | 1032 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, PN_REG(lp))) \ |
1033 | : (SMC_inw(ioaddr, PN_REG(lp)) & 0xFF)) | 1033 | : (SMC_inw(ioaddr, PN_REG(lp)) & 0xFF)) |
1034 | 1034 | ||
1035 | #define SMC_SET_PN(lp, x) \ | 1035 | #define SMC_SET_PN(lp, x) \ |
1036 | do { \ | 1036 | do { \ |
1037 | if (SMC_MUST_ALIGN_WRITE(lp)) \ | 1037 | if (SMC_MUST_ALIGN_WRITE(lp)) \ |
1038 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 0, 2)); \ | 1038 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 0, 2)); \ |
1039 | else if (SMC_8BIT(lp)) \ | 1039 | else if (SMC_8BIT(lp)) \ |
1040 | SMC_outb(x, ioaddr, PN_REG(lp)); \ | 1040 | SMC_outb(x, ioaddr, PN_REG(lp)); \ |
1041 | else \ | 1041 | else \ |
1042 | SMC_outw(x, ioaddr, PN_REG(lp)); \ | 1042 | SMC_outw(x, ioaddr, PN_REG(lp)); \ |
1043 | } while (0) | 1043 | } while (0) |
1044 | 1044 | ||
1045 | #define SMC_GET_AR(lp) \ | 1045 | #define SMC_GET_AR(lp) \ |
1046 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, AR_REG(lp))) \ | 1046 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, AR_REG(lp))) \ |
1047 | : (SMC_inw(ioaddr, PN_REG(lp)) >> 8)) | 1047 | : (SMC_inw(ioaddr, PN_REG(lp)) >> 8)) |
1048 | 1048 | ||
1049 | #define SMC_GET_TXFIFO(lp) \ | 1049 | #define SMC_GET_TXFIFO(lp) \ |
1050 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, TXFIFO_REG(lp))) \ | 1050 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, TXFIFO_REG(lp))) \ |
1051 | : (SMC_inw(ioaddr, TXFIFO_REG(lp)) & 0xFF)) | 1051 | : (SMC_inw(ioaddr, TXFIFO_REG(lp)) & 0xFF)) |
1052 | 1052 | ||
1053 | #define SMC_GET_RXFIFO(lp) \ | 1053 | #define SMC_GET_RXFIFO(lp) \ |
1054 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, RXFIFO_REG(lp))) \ | 1054 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, RXFIFO_REG(lp))) \ |
1055 | : (SMC_inw(ioaddr, TXFIFO_REG(lp)) >> 8)) | 1055 | : (SMC_inw(ioaddr, TXFIFO_REG(lp)) >> 8)) |
1056 | 1056 | ||
1057 | #define SMC_GET_INT(lp) \ | 1057 | #define SMC_GET_INT(lp) \ |
1058 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, INT_REG(lp))) \ | 1058 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, INT_REG(lp))) \ |
1059 | : (SMC_inw(ioaddr, INT_REG(lp)) & 0xFF)) | 1059 | : (SMC_inw(ioaddr, INT_REG(lp)) & 0xFF)) |
1060 | 1060 | ||
1061 | #define SMC_ACK_INT(lp, x) \ | 1061 | #define SMC_ACK_INT(lp, x) \ |
1062 | do { \ | 1062 | do { \ |
1063 | if (SMC_8BIT(lp)) \ | 1063 | if (SMC_8BIT(lp)) \ |
1064 | SMC_outb(x, ioaddr, INT_REG(lp)); \ | 1064 | SMC_outb(x, ioaddr, INT_REG(lp)); \ |
1065 | else { \ | 1065 | else { \ |
1066 | unsigned long __flags; \ | 1066 | unsigned long __flags; \ |
1067 | int __mask; \ | 1067 | int __mask; \ |
1068 | local_irq_save(__flags); \ | 1068 | local_irq_save(__flags); \ |
1069 | __mask = SMC_inw(ioaddr, INT_REG(lp)) & ~0xff; \ | 1069 | __mask = SMC_inw(ioaddr, INT_REG(lp)) & ~0xff; \ |
1070 | SMC_outw(__mask | (x), ioaddr, INT_REG(lp)); \ | 1070 | SMC_outw(__mask | (x), ioaddr, INT_REG(lp)); \ |
1071 | local_irq_restore(__flags); \ | 1071 | local_irq_restore(__flags); \ |
1072 | } \ | 1072 | } \ |
1073 | } while (0) | 1073 | } while (0) |
1074 | 1074 | ||
1075 | #define SMC_GET_INT_MASK(lp) \ | 1075 | #define SMC_GET_INT_MASK(lp) \ |
1076 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, IM_REG(lp))) \ | 1076 | (SMC_8BIT(lp) ? (SMC_inb(ioaddr, IM_REG(lp))) \ |
1077 | : (SMC_inw(ioaddr, INT_REG(lp)) >> 8)) | 1077 | : (SMC_inw(ioaddr, INT_REG(lp)) >> 8)) |
1078 | 1078 | ||
1079 | #define SMC_SET_INT_MASK(lp, x) \ | 1079 | #define SMC_SET_INT_MASK(lp, x) \ |
1080 | do { \ | 1080 | do { \ |
1081 | if (SMC_8BIT(lp)) \ | 1081 | if (SMC_8BIT(lp)) \ |
1082 | SMC_outb(x, ioaddr, IM_REG(lp)); \ | 1082 | SMC_outb(x, ioaddr, IM_REG(lp)); \ |
1083 | else \ | 1083 | else \ |
1084 | SMC_outw((x) << 8, ioaddr, INT_REG(lp)); \ | 1084 | SMC_outw((x) << 8, ioaddr, INT_REG(lp)); \ |
1085 | } while (0) | 1085 | } while (0) |
1086 | 1086 | ||
1087 | #define SMC_CURRENT_BANK(lp) SMC_inw(ioaddr, BANK_SELECT) | 1087 | #define SMC_CURRENT_BANK(lp) SMC_inw(ioaddr, BANK_SELECT) |
1088 | 1088 | ||
1089 | #define SMC_SELECT_BANK(lp, x) \ | 1089 | #define SMC_SELECT_BANK(lp, x) \ |
1090 | do { \ | 1090 | do { \ |
1091 | if (SMC_MUST_ALIGN_WRITE(lp)) \ | 1091 | if (SMC_MUST_ALIGN_WRITE(lp)) \ |
1092 | SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \ | 1092 | SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \ |
1093 | else \ | 1093 | else \ |
1094 | SMC_outw(x, ioaddr, BANK_SELECT); \ | 1094 | SMC_outw(x, ioaddr, BANK_SELECT); \ |
1095 | } while (0) | 1095 | } while (0) |
1096 | 1096 | ||
1097 | #define SMC_GET_BASE(lp) SMC_inw(ioaddr, BASE_REG(lp)) | 1097 | #define SMC_GET_BASE(lp) SMC_inw(ioaddr, BASE_REG(lp)) |
1098 | 1098 | ||
1099 | #define SMC_SET_BASE(lp, x) SMC_outw(x, ioaddr, BASE_REG(lp)) | 1099 | #define SMC_SET_BASE(lp, x) SMC_outw(x, ioaddr, BASE_REG(lp)) |
1100 | 1100 | ||
1101 | #define SMC_GET_CONFIG(lp) SMC_inw(ioaddr, CONFIG_REG(lp)) | 1101 | #define SMC_GET_CONFIG(lp) SMC_inw(ioaddr, CONFIG_REG(lp)) |
1102 | 1102 | ||
1103 | #define SMC_SET_CONFIG(lp, x) SMC_outw(x, ioaddr, CONFIG_REG(lp)) | 1103 | #define SMC_SET_CONFIG(lp, x) SMC_outw(x, ioaddr, CONFIG_REG(lp)) |
1104 | 1104 | ||
1105 | #define SMC_GET_COUNTER(lp) SMC_inw(ioaddr, COUNTER_REG(lp)) | 1105 | #define SMC_GET_COUNTER(lp) SMC_inw(ioaddr, COUNTER_REG(lp)) |
1106 | 1106 | ||
1107 | #define SMC_GET_CTL(lp) SMC_inw(ioaddr, CTL_REG(lp)) | 1107 | #define SMC_GET_CTL(lp) SMC_inw(ioaddr, CTL_REG(lp)) |
1108 | 1108 | ||
1109 | #define SMC_SET_CTL(lp, x) SMC_outw(x, ioaddr, CTL_REG(lp)) | 1109 | #define SMC_SET_CTL(lp, x) SMC_outw(x, ioaddr, CTL_REG(lp)) |
1110 | 1110 | ||
1111 | #define SMC_GET_MII(lp) SMC_inw(ioaddr, MII_REG(lp)) | 1111 | #define SMC_GET_MII(lp) SMC_inw(ioaddr, MII_REG(lp)) |
1112 | 1112 | ||
1113 | #define SMC_GET_GP(lp) SMC_inw(ioaddr, GP_REG(lp)) | 1113 | #define SMC_GET_GP(lp) SMC_inw(ioaddr, GP_REG(lp)) |
1114 | 1114 | ||
1115 | #define SMC_SET_GP(lp, x) \ | 1115 | #define SMC_SET_GP(lp, x) \ |
1116 | do { \ | 1116 | do { \ |
1117 | if (SMC_MUST_ALIGN_WRITE(lp)) \ | 1117 | if (SMC_MUST_ALIGN_WRITE(lp)) \ |
1118 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 1)); \ | 1118 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 1)); \ |
1119 | else \ | 1119 | else \ |
1120 | SMC_outw(x, ioaddr, GP_REG(lp)); \ | 1120 | SMC_outw(x, ioaddr, GP_REG(lp)); \ |
1121 | } while (0) | 1121 | } while (0) |
1122 | 1122 | ||
1123 | #define SMC_SET_MII(lp, x) SMC_outw(x, ioaddr, MII_REG(lp)) | 1123 | #define SMC_SET_MII(lp, x) SMC_outw(x, ioaddr, MII_REG(lp)) |
1124 | 1124 | ||
1125 | #define SMC_GET_MIR(lp) SMC_inw(ioaddr, MIR_REG(lp)) | 1125 | #define SMC_GET_MIR(lp) SMC_inw(ioaddr, MIR_REG(lp)) |
1126 | 1126 | ||
1127 | #define SMC_SET_MIR(lp, x) SMC_outw(x, ioaddr, MIR_REG(lp)) | 1127 | #define SMC_SET_MIR(lp, x) SMC_outw(x, ioaddr, MIR_REG(lp)) |
1128 | 1128 | ||
1129 | #define SMC_GET_MMU_CMD(lp) SMC_inw(ioaddr, MMU_CMD_REG(lp)) | 1129 | #define SMC_GET_MMU_CMD(lp) SMC_inw(ioaddr, MMU_CMD_REG(lp)) |
1130 | 1130 | ||
1131 | #define SMC_SET_MMU_CMD(lp, x) SMC_outw(x, ioaddr, MMU_CMD_REG(lp)) | 1131 | #define SMC_SET_MMU_CMD(lp, x) SMC_outw(x, ioaddr, MMU_CMD_REG(lp)) |
1132 | 1132 | ||
1133 | #define SMC_GET_FIFO(lp) SMC_inw(ioaddr, FIFO_REG(lp)) | 1133 | #define SMC_GET_FIFO(lp) SMC_inw(ioaddr, FIFO_REG(lp)) |
1134 | 1134 | ||
1135 | #define SMC_GET_PTR(lp) SMC_inw(ioaddr, PTR_REG(lp)) | 1135 | #define SMC_GET_PTR(lp) SMC_inw(ioaddr, PTR_REG(lp)) |
1136 | 1136 | ||
1137 | #define SMC_SET_PTR(lp, x) \ | 1137 | #define SMC_SET_PTR(lp, x) \ |
1138 | do { \ | 1138 | do { \ |
1139 | if (SMC_MUST_ALIGN_WRITE(lp)) \ | 1139 | if (SMC_MUST_ALIGN_WRITE(lp)) \ |
1140 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 4, 2)); \ | 1140 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 4, 2)); \ |
1141 | else \ | 1141 | else \ |
1142 | SMC_outw(x, ioaddr, PTR_REG(lp)); \ | 1142 | SMC_outw(x, ioaddr, PTR_REG(lp)); \ |
1143 | } while (0) | 1143 | } while (0) |
1144 | 1144 | ||
1145 | #define SMC_GET_EPH_STATUS(lp) SMC_inw(ioaddr, EPH_STATUS_REG(lp)) | 1145 | #define SMC_GET_EPH_STATUS(lp) SMC_inw(ioaddr, EPH_STATUS_REG(lp)) |
1146 | 1146 | ||
1147 | #define SMC_GET_RCR(lp) SMC_inw(ioaddr, RCR_REG(lp)) | 1147 | #define SMC_GET_RCR(lp) SMC_inw(ioaddr, RCR_REG(lp)) |
1148 | 1148 | ||
1149 | #define SMC_SET_RCR(lp, x) SMC_outw(x, ioaddr, RCR_REG(lp)) | 1149 | #define SMC_SET_RCR(lp, x) SMC_outw(x, ioaddr, RCR_REG(lp)) |
1150 | 1150 | ||
1151 | #define SMC_GET_REV(lp) SMC_inw(ioaddr, REV_REG(lp)) | 1151 | #define SMC_GET_REV(lp) SMC_inw(ioaddr, REV_REG(lp)) |
1152 | 1152 | ||
1153 | #define SMC_GET_RPC(lp) SMC_inw(ioaddr, RPC_REG(lp)) | 1153 | #define SMC_GET_RPC(lp) SMC_inw(ioaddr, RPC_REG(lp)) |
1154 | 1154 | ||
1155 | #define SMC_SET_RPC(lp, x) \ | 1155 | #define SMC_SET_RPC(lp, x) \ |
1156 | do { \ | 1156 | do { \ |
1157 | if (SMC_MUST_ALIGN_WRITE(lp)) \ | 1157 | if (SMC_MUST_ALIGN_WRITE(lp)) \ |
1158 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 0)); \ | 1158 | SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 0)); \ |
1159 | else \ | 1159 | else \ |
1160 | SMC_outw(x, ioaddr, RPC_REG(lp)); \ | 1160 | SMC_outw(x, ioaddr, RPC_REG(lp)); \ |
1161 | } while (0) | 1161 | } while (0) |
1162 | 1162 | ||
1163 | #define SMC_GET_TCR(lp) SMC_inw(ioaddr, TCR_REG(lp)) | 1163 | #define SMC_GET_TCR(lp) SMC_inw(ioaddr, TCR_REG(lp)) |
1164 | 1164 | ||
1165 | #define SMC_SET_TCR(lp, x) SMC_outw(x, ioaddr, TCR_REG(lp)) | 1165 | #define SMC_SET_TCR(lp, x) SMC_outw(x, ioaddr, TCR_REG(lp)) |
1166 | 1166 | ||
1167 | #ifndef SMC_GET_MAC_ADDR | 1167 | #ifndef SMC_GET_MAC_ADDR |
1168 | #define SMC_GET_MAC_ADDR(lp, addr) \ | 1168 | #define SMC_GET_MAC_ADDR(lp, addr) \ |
1169 | do { \ | 1169 | do { \ |
1170 | unsigned int __v; \ | 1170 | unsigned int __v; \ |
1171 | __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ | 1171 | __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ |
1172 | addr[0] = __v; addr[1] = __v >> 8; \ | 1172 | addr[0] = __v; addr[1] = __v >> 8; \ |
1173 | __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ | 1173 | __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ |
1174 | addr[2] = __v; addr[3] = __v >> 8; \ | 1174 | addr[2] = __v; addr[3] = __v >> 8; \ |
1175 | __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ | 1175 | __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ |
1176 | addr[4] = __v; addr[5] = __v >> 8; \ | 1176 | addr[4] = __v; addr[5] = __v >> 8; \ |
1177 | } while (0) | 1177 | } while (0) |
1178 | #endif | 1178 | #endif |
1179 | 1179 | ||
1180 | #define SMC_SET_MAC_ADDR(lp, addr) \ | 1180 | #define SMC_SET_MAC_ADDR(lp, addr) \ |
1181 | do { \ | 1181 | do { \ |
1182 | SMC_outw(addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG(lp)); \ | 1182 | SMC_outw(addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG(lp)); \ |
1183 | SMC_outw(addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG(lp)); \ | 1183 | SMC_outw(addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG(lp)); \ |
1184 | SMC_outw(addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG(lp)); \ | 1184 | SMC_outw(addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG(lp)); \ |
1185 | } while (0) | 1185 | } while (0) |
1186 | 1186 | ||
1187 | #define SMC_SET_MCAST(lp, x) \ | 1187 | #define SMC_SET_MCAST(lp, x) \ |
1188 | do { \ | 1188 | do { \ |
1189 | const unsigned char *mt = (x); \ | 1189 | const unsigned char *mt = (x); \ |
1190 | SMC_outw(mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1(lp)); \ | 1190 | SMC_outw(mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1(lp)); \ |
1191 | SMC_outw(mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2(lp)); \ | 1191 | SMC_outw(mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2(lp)); \ |
1192 | SMC_outw(mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3(lp)); \ | 1192 | SMC_outw(mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3(lp)); \ |
1193 | SMC_outw(mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4(lp)); \ | 1193 | SMC_outw(mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4(lp)); \ |
1194 | } while (0) | 1194 | } while (0) |
1195 | 1195 | ||
1196 | #define SMC_PUT_PKT_HDR(lp, status, length) \ | 1196 | #define SMC_PUT_PKT_HDR(lp, status, length) \ |
1197 | do { \ | 1197 | do { \ |
1198 | if (SMC_32BIT(lp)) \ | 1198 | if (SMC_32BIT(lp)) \ |
1199 | SMC_outl((status) | (length)<<16, ioaddr, \ | 1199 | SMC_outl((status) | (length)<<16, ioaddr, \ |
1200 | DATA_REG(lp)); \ | 1200 | DATA_REG(lp)); \ |
1201 | else { \ | 1201 | else { \ |
1202 | SMC_outw(status, ioaddr, DATA_REG(lp)); \ | 1202 | SMC_outw(status, ioaddr, DATA_REG(lp)); \ |
1203 | SMC_outw(length, ioaddr, DATA_REG(lp)); \ | 1203 | SMC_outw(length, ioaddr, DATA_REG(lp)); \ |
1204 | } \ | 1204 | } \ |
1205 | } while (0) | 1205 | } while (0) |
1206 | 1206 | ||
1207 | #define SMC_GET_PKT_HDR(lp, status, length) \ | 1207 | #define SMC_GET_PKT_HDR(lp, status, length) \ |
1208 | do { \ | 1208 | do { \ |
1209 | if (SMC_32BIT(lp)) { \ | 1209 | if (SMC_32BIT(lp)) { \ |
1210 | unsigned int __val = SMC_inl(ioaddr, DATA_REG(lp)); \ | 1210 | unsigned int __val = SMC_inl(ioaddr, DATA_REG(lp)); \ |
1211 | (status) = __val & 0xffff; \ | 1211 | (status) = __val & 0xffff; \ |
1212 | (length) = __val >> 16; \ | 1212 | (length) = __val >> 16; \ |
1213 | } else { \ | 1213 | } else { \ |
1214 | (status) = SMC_inw(ioaddr, DATA_REG(lp)); \ | 1214 | (status) = SMC_inw(ioaddr, DATA_REG(lp)); \ |
1215 | (length) = SMC_inw(ioaddr, DATA_REG(lp)); \ | 1215 | (length) = SMC_inw(ioaddr, DATA_REG(lp)); \ |
1216 | } \ | 1216 | } \ |
1217 | } while (0) | 1217 | } while (0) |
1218 | 1218 | ||
1219 | #define SMC_PUSH_DATA(lp, p, l) \ | 1219 | #define SMC_PUSH_DATA(lp, p, l) \ |
1220 | do { \ | 1220 | do { \ |
1221 | if (SMC_32BIT(lp)) { \ | 1221 | if (SMC_32BIT(lp)) { \ |
1222 | void *__ptr = (p); \ | 1222 | void *__ptr = (p); \ |
1223 | int __len = (l); \ | 1223 | int __len = (l); \ |
1224 | void __iomem *__ioaddr = ioaddr; \ | 1224 | void __iomem *__ioaddr = ioaddr; \ |
1225 | if (__len >= 2 && (unsigned long)__ptr & 2) { \ | 1225 | if (__len >= 2 && (unsigned long)__ptr & 2) { \ |
1226 | __len -= 2; \ | 1226 | __len -= 2; \ |
1227 | SMC_outw(*(u16 *)__ptr, ioaddr, \ | 1227 | SMC_outw(*(u16 *)__ptr, ioaddr, \ |
1228 | DATA_REG(lp)); \ | 1228 | DATA_REG(lp)); \ |
1229 | __ptr += 2; \ | 1229 | __ptr += 2; \ |
1230 | } \ | 1230 | } \ |
1231 | if (SMC_CAN_USE_DATACS && lp->datacs) \ | 1231 | if (SMC_CAN_USE_DATACS && lp->datacs) \ |
1232 | __ioaddr = lp->datacs; \ | 1232 | __ioaddr = lp->datacs; \ |
1233 | SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ | 1233 | SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ |
1234 | if (__len & 2) { \ | 1234 | if (__len & 2) { \ |
1235 | __ptr += (__len & ~3); \ | 1235 | __ptr += (__len & ~3); \ |
1236 | SMC_outw(*((u16 *)__ptr), ioaddr, \ | 1236 | SMC_outw(*((u16 *)__ptr), ioaddr, \ |
1237 | DATA_REG(lp)); \ | 1237 | DATA_REG(lp)); \ |
1238 | } \ | 1238 | } \ |
1239 | } else if (SMC_16BIT(lp)) \ | 1239 | } else if (SMC_16BIT(lp)) \ |
1240 | SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ | 1240 | SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ |
1241 | else if (SMC_8BIT(lp)) \ | 1241 | else if (SMC_8BIT(lp)) \ |
1242 | SMC_outsb(ioaddr, DATA_REG(lp), p, l); \ | 1242 | SMC_outsb(ioaddr, DATA_REG(lp), p, l); \ |
1243 | } while (0) | 1243 | } while (0) |
1244 | 1244 | ||
1245 | #define SMC_PULL_DATA(lp, p, l) \ | 1245 | #define SMC_PULL_DATA(lp, p, l) \ |
1246 | do { \ | 1246 | do { \ |
1247 | if (SMC_32BIT(lp)) { \ | 1247 | if (SMC_32BIT(lp)) { \ |
1248 | void *__ptr = (p); \ | 1248 | void *__ptr = (p); \ |
1249 | int __len = (l); \ | 1249 | int __len = (l); \ |
1250 | void __iomem *__ioaddr = ioaddr; \ | 1250 | void __iomem *__ioaddr = ioaddr; \ |
1251 | if ((unsigned long)__ptr & 2) { \ | 1251 | if ((unsigned long)__ptr & 2) { \ |
1252 | /* \ | 1252 | /* \ |
1253 | * We want 32bit alignment here. \ | 1253 | * We want 32bit alignment here. \ |
1254 | * Since some buses perform a full \ | 1254 | * Since some buses perform a full \ |
1255 | * 32bit fetch even for 16bit data \ | 1255 | * 32bit fetch even for 16bit data \ |
1256 | * we can't use SMC_inw() here. \ | 1256 | * we can't use SMC_inw() here. \ |
1257 | * Back both source (on-chip) and \ | 1257 | * Back both source (on-chip) and \ |
1258 | * destination pointers of 2 bytes. \ | 1258 | * destination pointers of 2 bytes. \ |
1259 | * This is possible since the call to \ | 1259 | * This is possible since the call to \ |
1260 | * SMC_GET_PKT_HDR() already advanced \ | 1260 | * SMC_GET_PKT_HDR() already advanced \ |
1261 | * the source pointer of 4 bytes, and \ | 1261 | * the source pointer of 4 bytes, and \ |
1262 | * the skb_reserve(skb, 2) advanced \ | 1262 | * the skb_reserve(skb, 2) advanced \ |
1263 | * the destination pointer of 2 bytes. \ | 1263 | * the destination pointer of 2 bytes. \ |
1264 | */ \ | 1264 | */ \ |
1265 | __ptr -= 2; \ | 1265 | __ptr -= 2; \ |
1266 | __len += 2; \ | 1266 | __len += 2; \ |
1267 | SMC_SET_PTR(lp, \ | 1267 | SMC_SET_PTR(lp, \ |
1268 | 2|PTR_READ|PTR_RCV|PTR_AUTOINC); \ | 1268 | 2|PTR_READ|PTR_RCV|PTR_AUTOINC); \ |
1269 | } \ | 1269 | } \ |
1270 | if (SMC_CAN_USE_DATACS && lp->datacs) \ | 1270 | if (SMC_CAN_USE_DATACS && lp->datacs) \ |
1271 | __ioaddr = lp->datacs; \ | 1271 | __ioaddr = lp->datacs; \ |
1272 | __len += 2; \ | 1272 | __len += 2; \ |
1273 | SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ | 1273 | SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ |
1274 | } else if (SMC_16BIT(lp)) \ | 1274 | } else if (SMC_16BIT(lp)) \ |
1275 | SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ | 1275 | SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ |
1276 | else if (SMC_8BIT(lp)) \ | 1276 | else if (SMC_8BIT(lp)) \ |
1277 | SMC_insb(ioaddr, DATA_REG(lp), p, l); \ | 1277 | SMC_insb(ioaddr, DATA_REG(lp), p, l); \ |
1278 | } while (0) | 1278 | } while (0) |
1279 | 1279 | ||
1280 | #endif /* _SMC91X_H_ */ | 1280 | #endif /* _SMC91X_H_ */ |
1281 | 1281 |
drivers/rtc/rtc-sa1100.c
1 | /* | 1 | /* |
2 | * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx | 2 | * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx |
3 | * | 3 | * |
4 | * Copyright (c) 2000 Nils Faerber | 4 | * Copyright (c) 2000 Nils Faerber |
5 | * | 5 | * |
6 | * Based on rtc.c by Paul Gortmaker | 6 | * Based on rtc.c by Paul Gortmaker |
7 | * | 7 | * |
8 | * Original Driver by Nils Faerber <nils@kernelconcepts.de> | 8 | * Original Driver by Nils Faerber <nils@kernelconcepts.de> |
9 | * | 9 | * |
10 | * Modifications from: | 10 | * Modifications from: |
11 | * CIH <cih@coventive.com> | 11 | * CIH <cih@coventive.com> |
12 | * Nicolas Pitre <nico@cam.org> | 12 | * Nicolas Pitre <nico@fluxnic.net> |
13 | * Andrew Christian <andrew.christian@hp.com> | 13 | * Andrew Christian <andrew.christian@hp.com> |
14 | * | 14 | * |
15 | * Converted to the RTC subsystem and Driver Model | 15 | * Converted to the RTC subsystem and Driver Model |
16 | * by Richard Purdie <rpurdie@rpsys.net> | 16 | * by Richard Purdie <rpurdie@rpsys.net> |
17 | * | 17 | * |
18 | * This program is free software; you can redistribute it and/or | 18 | * This program is free software; you can redistribute it and/or |
19 | * modify it under the terms of the GNU General Public License | 19 | * modify it under the terms of the GNU General Public License |
20 | * as published by the Free Software Foundation; either version | 20 | * as published by the Free Software Foundation; either version |
21 | * 2 of the License, or (at your option) any later version. | 21 | * 2 of the License, or (at your option) any later version. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/string.h> | 30 | #include <linux/string.h> |
31 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
32 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
33 | 33 | ||
34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
35 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
36 | 36 | ||
37 | #ifdef CONFIG_ARCH_PXA | 37 | #ifdef CONFIG_ARCH_PXA |
38 | #include <mach/regs-rtc.h> | 38 | #include <mach/regs-rtc.h> |
39 | #include <mach/regs-ost.h> | 39 | #include <mach/regs-ost.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #define RTC_DEF_DIVIDER 32768 - 1 | 42 | #define RTC_DEF_DIVIDER 32768 - 1 |
43 | #define RTC_DEF_TRIM 0 | 43 | #define RTC_DEF_TRIM 0 |
44 | 44 | ||
45 | static unsigned long rtc_freq = 1024; | 45 | static unsigned long rtc_freq = 1024; |
46 | static unsigned long timer_freq; | 46 | static unsigned long timer_freq; |
47 | static struct rtc_time rtc_alarm; | 47 | static struct rtc_time rtc_alarm; |
48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
49 | 49 | ||
50 | static inline int rtc_periodic_alarm(struct rtc_time *tm) | 50 | static inline int rtc_periodic_alarm(struct rtc_time *tm) |
51 | { | 51 | { |
52 | return (tm->tm_year == -1) || | 52 | return (tm->tm_year == -1) || |
53 | ((unsigned)tm->tm_mon >= 12) || | 53 | ((unsigned)tm->tm_mon >= 12) || |
54 | ((unsigned)(tm->tm_mday - 1) >= 31) || | 54 | ((unsigned)(tm->tm_mday - 1) >= 31) || |
55 | ((unsigned)tm->tm_hour > 23) || | 55 | ((unsigned)tm->tm_hour > 23) || |
56 | ((unsigned)tm->tm_min > 59) || | 56 | ((unsigned)tm->tm_min > 59) || |
57 | ((unsigned)tm->tm_sec > 59); | 57 | ((unsigned)tm->tm_sec > 59); |
58 | } | 58 | } |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Calculate the next alarm time given the requested alarm time mask | 61 | * Calculate the next alarm time given the requested alarm time mask |
62 | * and the current time. | 62 | * and the current time. |
63 | */ | 63 | */ |
64 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) | 64 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) |
65 | { | 65 | { |
66 | unsigned long next_time; | 66 | unsigned long next_time; |
67 | unsigned long now_time; | 67 | unsigned long now_time; |
68 | 68 | ||
69 | next->tm_year = now->tm_year; | 69 | next->tm_year = now->tm_year; |
70 | next->tm_mon = now->tm_mon; | 70 | next->tm_mon = now->tm_mon; |
71 | next->tm_mday = now->tm_mday; | 71 | next->tm_mday = now->tm_mday; |
72 | next->tm_hour = alrm->tm_hour; | 72 | next->tm_hour = alrm->tm_hour; |
73 | next->tm_min = alrm->tm_min; | 73 | next->tm_min = alrm->tm_min; |
74 | next->tm_sec = alrm->tm_sec; | 74 | next->tm_sec = alrm->tm_sec; |
75 | 75 | ||
76 | rtc_tm_to_time(now, &now_time); | 76 | rtc_tm_to_time(now, &now_time); |
77 | rtc_tm_to_time(next, &next_time); | 77 | rtc_tm_to_time(next, &next_time); |
78 | 78 | ||
79 | if (next_time < now_time) { | 79 | if (next_time < now_time) { |
80 | /* Advance one day */ | 80 | /* Advance one day */ |
81 | next_time += 60 * 60 * 24; | 81 | next_time += 60 * 60 * 24; |
82 | rtc_time_to_tm(next_time, next); | 82 | rtc_time_to_tm(next_time, next); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | static int rtc_update_alarm(struct rtc_time *alrm) | 86 | static int rtc_update_alarm(struct rtc_time *alrm) |
87 | { | 87 | { |
88 | struct rtc_time alarm_tm, now_tm; | 88 | struct rtc_time alarm_tm, now_tm; |
89 | unsigned long now, time; | 89 | unsigned long now, time; |
90 | int ret; | 90 | int ret; |
91 | 91 | ||
92 | do { | 92 | do { |
93 | now = RCNR; | 93 | now = RCNR; |
94 | rtc_time_to_tm(now, &now_tm); | 94 | rtc_time_to_tm(now, &now_tm); |
95 | rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); | 95 | rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); |
96 | ret = rtc_tm_to_time(&alarm_tm, &time); | 96 | ret = rtc_tm_to_time(&alarm_tm, &time); |
97 | if (ret != 0) | 97 | if (ret != 0) |
98 | break; | 98 | break; |
99 | 99 | ||
100 | RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); | 100 | RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); |
101 | RTAR = time; | 101 | RTAR = time; |
102 | } while (now != RCNR); | 102 | } while (now != RCNR); |
103 | 103 | ||
104 | return ret; | 104 | return ret; |
105 | } | 105 | } |
106 | 106 | ||
107 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | 107 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) |
108 | { | 108 | { |
109 | struct platform_device *pdev = to_platform_device(dev_id); | 109 | struct platform_device *pdev = to_platform_device(dev_id); |
110 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 110 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
111 | unsigned int rtsr; | 111 | unsigned int rtsr; |
112 | unsigned long events = 0; | 112 | unsigned long events = 0; |
113 | 113 | ||
114 | spin_lock(&sa1100_rtc_lock); | 114 | spin_lock(&sa1100_rtc_lock); |
115 | 115 | ||
116 | rtsr = RTSR; | 116 | rtsr = RTSR; |
117 | /* clear interrupt sources */ | 117 | /* clear interrupt sources */ |
118 | RTSR = 0; | 118 | RTSR = 0; |
119 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | 119 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); |
120 | 120 | ||
121 | /* clear alarm interrupt if it has occurred */ | 121 | /* clear alarm interrupt if it has occurred */ |
122 | if (rtsr & RTSR_AL) | 122 | if (rtsr & RTSR_AL) |
123 | rtsr &= ~RTSR_ALE; | 123 | rtsr &= ~RTSR_ALE; |
124 | RTSR = rtsr & (RTSR_ALE | RTSR_HZE); | 124 | RTSR = rtsr & (RTSR_ALE | RTSR_HZE); |
125 | 125 | ||
126 | /* update irq data & counter */ | 126 | /* update irq data & counter */ |
127 | if (rtsr & RTSR_AL) | 127 | if (rtsr & RTSR_AL) |
128 | events |= RTC_AF | RTC_IRQF; | 128 | events |= RTC_AF | RTC_IRQF; |
129 | if (rtsr & RTSR_HZ) | 129 | if (rtsr & RTSR_HZ) |
130 | events |= RTC_UF | RTC_IRQF; | 130 | events |= RTC_UF | RTC_IRQF; |
131 | 131 | ||
132 | rtc_update_irq(rtc, 1, events); | 132 | rtc_update_irq(rtc, 1, events); |
133 | 133 | ||
134 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) | 134 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) |
135 | rtc_update_alarm(&rtc_alarm); | 135 | rtc_update_alarm(&rtc_alarm); |
136 | 136 | ||
137 | spin_unlock(&sa1100_rtc_lock); | 137 | spin_unlock(&sa1100_rtc_lock); |
138 | 138 | ||
139 | return IRQ_HANDLED; | 139 | return IRQ_HANDLED; |
140 | } | 140 | } |
141 | 141 | ||
142 | static int rtc_timer1_count; | 142 | static int rtc_timer1_count; |
143 | 143 | ||
144 | static irqreturn_t timer1_interrupt(int irq, void *dev_id) | 144 | static irqreturn_t timer1_interrupt(int irq, void *dev_id) |
145 | { | 145 | { |
146 | struct platform_device *pdev = to_platform_device(dev_id); | 146 | struct platform_device *pdev = to_platform_device(dev_id); |
147 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 147 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
148 | 148 | ||
149 | /* | 149 | /* |
150 | * If we match for the first time, rtc_timer1_count will be 1. | 150 | * If we match for the first time, rtc_timer1_count will be 1. |
151 | * Otherwise, we wrapped around (very unlikely but | 151 | * Otherwise, we wrapped around (very unlikely but |
152 | * still possible) so compute the amount of missed periods. | 152 | * still possible) so compute the amount of missed periods. |
153 | * The match reg is updated only when the data is actually retrieved | 153 | * The match reg is updated only when the data is actually retrieved |
154 | * to avoid unnecessary interrupts. | 154 | * to avoid unnecessary interrupts. |
155 | */ | 155 | */ |
156 | OSSR = OSSR_M1; /* clear match on timer1 */ | 156 | OSSR = OSSR_M1; /* clear match on timer1 */ |
157 | 157 | ||
158 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); | 158 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); |
159 | 159 | ||
160 | if (rtc_timer1_count == 1) | 160 | if (rtc_timer1_count == 1) |
161 | rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); | 161 | rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); |
162 | 162 | ||
163 | return IRQ_HANDLED; | 163 | return IRQ_HANDLED; |
164 | } | 164 | } |
165 | 165 | ||
166 | static int sa1100_rtc_read_callback(struct device *dev, int data) | 166 | static int sa1100_rtc_read_callback(struct device *dev, int data) |
167 | { | 167 | { |
168 | if (data & RTC_PF) { | 168 | if (data & RTC_PF) { |
169 | /* interpolate missed periods and set match for the next */ | 169 | /* interpolate missed periods and set match for the next */ |
170 | unsigned long period = timer_freq / rtc_freq; | 170 | unsigned long period = timer_freq / rtc_freq; |
171 | unsigned long oscr = OSCR; | 171 | unsigned long oscr = OSCR; |
172 | unsigned long osmr1 = OSMR1; | 172 | unsigned long osmr1 = OSMR1; |
173 | unsigned long missed = (oscr - osmr1)/period; | 173 | unsigned long missed = (oscr - osmr1)/period; |
174 | data += missed << 8; | 174 | data += missed << 8; |
175 | OSSR = OSSR_M1; /* clear match on timer 1 */ | 175 | OSSR = OSSR_M1; /* clear match on timer 1 */ |
176 | OSMR1 = osmr1 + (missed + 1)*period; | 176 | OSMR1 = osmr1 + (missed + 1)*period; |
177 | /* Ensure we didn't miss another match in the mean time. | 177 | /* Ensure we didn't miss another match in the mean time. |
178 | * Here we compare (match - OSCR) 8 instead of 0 -- | 178 | * Here we compare (match - OSCR) 8 instead of 0 -- |
179 | * see comment in pxa_timer_interrupt() for explanation. | 179 | * see comment in pxa_timer_interrupt() for explanation. |
180 | */ | 180 | */ |
181 | while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { | 181 | while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { |
182 | data += 0x100; | 182 | data += 0x100; |
183 | OSSR = OSSR_M1; /* clear match on timer 1 */ | 183 | OSSR = OSSR_M1; /* clear match on timer 1 */ |
184 | OSMR1 = osmr1 + period; | 184 | OSMR1 = osmr1 + period; |
185 | } | 185 | } |
186 | } | 186 | } |
187 | return data; | 187 | return data; |
188 | } | 188 | } |
189 | 189 | ||
190 | static int sa1100_rtc_open(struct device *dev) | 190 | static int sa1100_rtc_open(struct device *dev) |
191 | { | 191 | { |
192 | int ret; | 192 | int ret; |
193 | 193 | ||
194 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, | 194 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, |
195 | "rtc 1Hz", dev); | 195 | "rtc 1Hz", dev); |
196 | if (ret) { | 196 | if (ret) { |
197 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); | 197 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
198 | goto fail_ui; | 198 | goto fail_ui; |
199 | } | 199 | } |
200 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, | 200 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, |
201 | "rtc Alrm", dev); | 201 | "rtc Alrm", dev); |
202 | if (ret) { | 202 | if (ret) { |
203 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); | 203 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
204 | goto fail_ai; | 204 | goto fail_ai; |
205 | } | 205 | } |
206 | ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED, | 206 | ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED, |
207 | "rtc timer", dev); | 207 | "rtc timer", dev); |
208 | if (ret) { | 208 | if (ret) { |
209 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); | 209 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); |
210 | goto fail_pi; | 210 | goto fail_pi; |
211 | } | 211 | } |
212 | return 0; | 212 | return 0; |
213 | 213 | ||
214 | fail_pi: | 214 | fail_pi: |
215 | free_irq(IRQ_RTCAlrm, dev); | 215 | free_irq(IRQ_RTCAlrm, dev); |
216 | fail_ai: | 216 | fail_ai: |
217 | free_irq(IRQ_RTC1Hz, dev); | 217 | free_irq(IRQ_RTC1Hz, dev); |
218 | fail_ui: | 218 | fail_ui: |
219 | return ret; | 219 | return ret; |
220 | } | 220 | } |
221 | 221 | ||
222 | static void sa1100_rtc_release(struct device *dev) | 222 | static void sa1100_rtc_release(struct device *dev) |
223 | { | 223 | { |
224 | spin_lock_irq(&sa1100_rtc_lock); | 224 | spin_lock_irq(&sa1100_rtc_lock); |
225 | RTSR = 0; | 225 | RTSR = 0; |
226 | OIER &= ~OIER_E1; | 226 | OIER &= ~OIER_E1; |
227 | OSSR = OSSR_M1; | 227 | OSSR = OSSR_M1; |
228 | spin_unlock_irq(&sa1100_rtc_lock); | 228 | spin_unlock_irq(&sa1100_rtc_lock); |
229 | 229 | ||
230 | free_irq(IRQ_OST1, dev); | 230 | free_irq(IRQ_OST1, dev); |
231 | free_irq(IRQ_RTCAlrm, dev); | 231 | free_irq(IRQ_RTCAlrm, dev); |
232 | free_irq(IRQ_RTC1Hz, dev); | 232 | free_irq(IRQ_RTC1Hz, dev); |
233 | } | 233 | } |
234 | 234 | ||
235 | 235 | ||
236 | static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | 236 | static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, |
237 | unsigned long arg) | 237 | unsigned long arg) |
238 | { | 238 | { |
239 | switch(cmd) { | 239 | switch(cmd) { |
240 | case RTC_AIE_OFF: | 240 | case RTC_AIE_OFF: |
241 | spin_lock_irq(&sa1100_rtc_lock); | 241 | spin_lock_irq(&sa1100_rtc_lock); |
242 | RTSR &= ~RTSR_ALE; | 242 | RTSR &= ~RTSR_ALE; |
243 | spin_unlock_irq(&sa1100_rtc_lock); | 243 | spin_unlock_irq(&sa1100_rtc_lock); |
244 | return 0; | 244 | return 0; |
245 | case RTC_AIE_ON: | 245 | case RTC_AIE_ON: |
246 | spin_lock_irq(&sa1100_rtc_lock); | 246 | spin_lock_irq(&sa1100_rtc_lock); |
247 | RTSR |= RTSR_ALE; | 247 | RTSR |= RTSR_ALE; |
248 | spin_unlock_irq(&sa1100_rtc_lock); | 248 | spin_unlock_irq(&sa1100_rtc_lock); |
249 | return 0; | 249 | return 0; |
250 | case RTC_UIE_OFF: | 250 | case RTC_UIE_OFF: |
251 | spin_lock_irq(&sa1100_rtc_lock); | 251 | spin_lock_irq(&sa1100_rtc_lock); |
252 | RTSR &= ~RTSR_HZE; | 252 | RTSR &= ~RTSR_HZE; |
253 | spin_unlock_irq(&sa1100_rtc_lock); | 253 | spin_unlock_irq(&sa1100_rtc_lock); |
254 | return 0; | 254 | return 0; |
255 | case RTC_UIE_ON: | 255 | case RTC_UIE_ON: |
256 | spin_lock_irq(&sa1100_rtc_lock); | 256 | spin_lock_irq(&sa1100_rtc_lock); |
257 | RTSR |= RTSR_HZE; | 257 | RTSR |= RTSR_HZE; |
258 | spin_unlock_irq(&sa1100_rtc_lock); | 258 | spin_unlock_irq(&sa1100_rtc_lock); |
259 | return 0; | 259 | return 0; |
260 | case RTC_PIE_OFF: | 260 | case RTC_PIE_OFF: |
261 | spin_lock_irq(&sa1100_rtc_lock); | 261 | spin_lock_irq(&sa1100_rtc_lock); |
262 | OIER &= ~OIER_E1; | 262 | OIER &= ~OIER_E1; |
263 | spin_unlock_irq(&sa1100_rtc_lock); | 263 | spin_unlock_irq(&sa1100_rtc_lock); |
264 | return 0; | 264 | return 0; |
265 | case RTC_PIE_ON: | 265 | case RTC_PIE_ON: |
266 | spin_lock_irq(&sa1100_rtc_lock); | 266 | spin_lock_irq(&sa1100_rtc_lock); |
267 | OSMR1 = timer_freq / rtc_freq + OSCR; | 267 | OSMR1 = timer_freq / rtc_freq + OSCR; |
268 | OIER |= OIER_E1; | 268 | OIER |= OIER_E1; |
269 | rtc_timer1_count = 1; | 269 | rtc_timer1_count = 1; |
270 | spin_unlock_irq(&sa1100_rtc_lock); | 270 | spin_unlock_irq(&sa1100_rtc_lock); |
271 | return 0; | 271 | return 0; |
272 | case RTC_IRQP_READ: | 272 | case RTC_IRQP_READ: |
273 | return put_user(rtc_freq, (unsigned long *)arg); | 273 | return put_user(rtc_freq, (unsigned long *)arg); |
274 | case RTC_IRQP_SET: | 274 | case RTC_IRQP_SET: |
275 | if (arg < 1 || arg > timer_freq) | 275 | if (arg < 1 || arg > timer_freq) |
276 | return -EINVAL; | 276 | return -EINVAL; |
277 | rtc_freq = arg; | 277 | rtc_freq = arg; |
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | return -ENOIOCTLCMD; | 280 | return -ENOIOCTLCMD; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) | 283 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
284 | { | 284 | { |
285 | rtc_time_to_tm(RCNR, tm); | 285 | rtc_time_to_tm(RCNR, tm); |
286 | return 0; | 286 | return 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) | 289 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) |
290 | { | 290 | { |
291 | unsigned long time; | 291 | unsigned long time; |
292 | int ret; | 292 | int ret; |
293 | 293 | ||
294 | ret = rtc_tm_to_time(tm, &time); | 294 | ret = rtc_tm_to_time(tm, &time); |
295 | if (ret == 0) | 295 | if (ret == 0) |
296 | RCNR = time; | 296 | RCNR = time; |
297 | return ret; | 297 | return ret; |
298 | } | 298 | } |
299 | 299 | ||
300 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 300 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
301 | { | 301 | { |
302 | u32 rtsr; | 302 | u32 rtsr; |
303 | 303 | ||
304 | memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); | 304 | memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); |
305 | rtsr = RTSR; | 305 | rtsr = RTSR; |
306 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; | 306 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; |
307 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; | 307 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; |
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 311 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
312 | { | 312 | { |
313 | int ret; | 313 | int ret; |
314 | 314 | ||
315 | spin_lock_irq(&sa1100_rtc_lock); | 315 | spin_lock_irq(&sa1100_rtc_lock); |
316 | ret = rtc_update_alarm(&alrm->time); | 316 | ret = rtc_update_alarm(&alrm->time); |
317 | if (ret == 0) { | 317 | if (ret == 0) { |
318 | if (alrm->enabled) | 318 | if (alrm->enabled) |
319 | RTSR |= RTSR_ALE; | 319 | RTSR |= RTSR_ALE; |
320 | else | 320 | else |
321 | RTSR &= ~RTSR_ALE; | 321 | RTSR &= ~RTSR_ALE; |
322 | } | 322 | } |
323 | spin_unlock_irq(&sa1100_rtc_lock); | 323 | spin_unlock_irq(&sa1100_rtc_lock); |
324 | 324 | ||
325 | return ret; | 325 | return ret; |
326 | } | 326 | } |
327 | 327 | ||
328 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) | 328 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
329 | { | 329 | { |
330 | seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR); | 330 | seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR); |
331 | seq_printf(seq, "update_IRQ\t: %s\n", | 331 | seq_printf(seq, "update_IRQ\t: %s\n", |
332 | (RTSR & RTSR_HZE) ? "yes" : "no"); | 332 | (RTSR & RTSR_HZE) ? "yes" : "no"); |
333 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 333 | seq_printf(seq, "periodic_IRQ\t: %s\n", |
334 | (OIER & OIER_E1) ? "yes" : "no"); | 334 | (OIER & OIER_E1) ? "yes" : "no"); |
335 | seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); | 335 | seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); |
336 | 336 | ||
337 | return 0; | 337 | return 0; |
338 | } | 338 | } |
339 | 339 | ||
340 | static const struct rtc_class_ops sa1100_rtc_ops = { | 340 | static const struct rtc_class_ops sa1100_rtc_ops = { |
341 | .open = sa1100_rtc_open, | 341 | .open = sa1100_rtc_open, |
342 | .read_callback = sa1100_rtc_read_callback, | 342 | .read_callback = sa1100_rtc_read_callback, |
343 | .release = sa1100_rtc_release, | 343 | .release = sa1100_rtc_release, |
344 | .ioctl = sa1100_rtc_ioctl, | 344 | .ioctl = sa1100_rtc_ioctl, |
345 | .read_time = sa1100_rtc_read_time, | 345 | .read_time = sa1100_rtc_read_time, |
346 | .set_time = sa1100_rtc_set_time, | 346 | .set_time = sa1100_rtc_set_time, |
347 | .read_alarm = sa1100_rtc_read_alarm, | 347 | .read_alarm = sa1100_rtc_read_alarm, |
348 | .set_alarm = sa1100_rtc_set_alarm, | 348 | .set_alarm = sa1100_rtc_set_alarm, |
349 | .proc = sa1100_rtc_proc, | 349 | .proc = sa1100_rtc_proc, |
350 | }; | 350 | }; |
351 | 351 | ||
352 | static int sa1100_rtc_probe(struct platform_device *pdev) | 352 | static int sa1100_rtc_probe(struct platform_device *pdev) |
353 | { | 353 | { |
354 | struct rtc_device *rtc; | 354 | struct rtc_device *rtc; |
355 | 355 | ||
356 | timer_freq = get_clock_tick_rate(); | 356 | timer_freq = get_clock_tick_rate(); |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * According to the manual we should be able to let RTTR be zero | 359 | * According to the manual we should be able to let RTTR be zero |
360 | * and then a default diviser for a 32.768KHz clock is used. | 360 | * and then a default diviser for a 32.768KHz clock is used. |
361 | * Apparently this doesn't work, at least for my SA1110 rev 5. | 361 | * Apparently this doesn't work, at least for my SA1110 rev 5. |
362 | * If the clock divider is uninitialized then reset it to the | 362 | * If the clock divider is uninitialized then reset it to the |
363 | * default value to get the 1Hz clock. | 363 | * default value to get the 1Hz clock. |
364 | */ | 364 | */ |
365 | if (RTTR == 0) { | 365 | if (RTTR == 0) { |
366 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 366 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
367 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); | 367 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); |
368 | /* The current RTC value probably doesn't make sense either */ | 368 | /* The current RTC value probably doesn't make sense either */ |
369 | RCNR = 0; | 369 | RCNR = 0; |
370 | } | 370 | } |
371 | 371 | ||
372 | device_init_wakeup(&pdev->dev, 1); | 372 | device_init_wakeup(&pdev->dev, 1); |
373 | 373 | ||
374 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 374 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
375 | THIS_MODULE); | 375 | THIS_MODULE); |
376 | 376 | ||
377 | if (IS_ERR(rtc)) | 377 | if (IS_ERR(rtc)) |
378 | return PTR_ERR(rtc); | 378 | return PTR_ERR(rtc); |
379 | 379 | ||
380 | platform_set_drvdata(pdev, rtc); | 380 | platform_set_drvdata(pdev, rtc); |
381 | 381 | ||
382 | return 0; | 382 | return 0; |
383 | } | 383 | } |
384 | 384 | ||
385 | static int sa1100_rtc_remove(struct platform_device *pdev) | 385 | static int sa1100_rtc_remove(struct platform_device *pdev) |
386 | { | 386 | { |
387 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 387 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
388 | 388 | ||
389 | if (rtc) | 389 | if (rtc) |
390 | rtc_device_unregister(rtc); | 390 | rtc_device_unregister(rtc); |
391 | 391 | ||
392 | return 0; | 392 | return 0; |
393 | } | 393 | } |
394 | 394 | ||
395 | #ifdef CONFIG_PM | 395 | #ifdef CONFIG_PM |
396 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 396 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
397 | { | 397 | { |
398 | if (device_may_wakeup(&pdev->dev)) | 398 | if (device_may_wakeup(&pdev->dev)) |
399 | enable_irq_wake(IRQ_RTCAlrm); | 399 | enable_irq_wake(IRQ_RTCAlrm); |
400 | return 0; | 400 | return 0; |
401 | } | 401 | } |
402 | 402 | ||
403 | static int sa1100_rtc_resume(struct platform_device *pdev) | 403 | static int sa1100_rtc_resume(struct platform_device *pdev) |
404 | { | 404 | { |
405 | if (device_may_wakeup(&pdev->dev)) | 405 | if (device_may_wakeup(&pdev->dev)) |
406 | disable_irq_wake(IRQ_RTCAlrm); | 406 | disable_irq_wake(IRQ_RTCAlrm); |
407 | return 0; | 407 | return 0; |
408 | } | 408 | } |
409 | #else | 409 | #else |
410 | #define sa1100_rtc_suspend NULL | 410 | #define sa1100_rtc_suspend NULL |
411 | #define sa1100_rtc_resume NULL | 411 | #define sa1100_rtc_resume NULL |
412 | #endif | 412 | #endif |
413 | 413 | ||
414 | static struct platform_driver sa1100_rtc_driver = { | 414 | static struct platform_driver sa1100_rtc_driver = { |
415 | .probe = sa1100_rtc_probe, | 415 | .probe = sa1100_rtc_probe, |
416 | .remove = sa1100_rtc_remove, | 416 | .remove = sa1100_rtc_remove, |
417 | .suspend = sa1100_rtc_suspend, | 417 | .suspend = sa1100_rtc_suspend, |
418 | .resume = sa1100_rtc_resume, | 418 | .resume = sa1100_rtc_resume, |
419 | .driver = { | 419 | .driver = { |
420 | .name = "sa1100-rtc", | 420 | .name = "sa1100-rtc", |
421 | }, | 421 | }, |
422 | }; | 422 | }; |
423 | 423 | ||
424 | static int __init sa1100_rtc_init(void) | 424 | static int __init sa1100_rtc_init(void) |
425 | { | 425 | { |
426 | return platform_driver_register(&sa1100_rtc_driver); | 426 | return platform_driver_register(&sa1100_rtc_driver); |
427 | } | 427 | } |
428 | 428 | ||
429 | static void __exit sa1100_rtc_exit(void) | 429 | static void __exit sa1100_rtc_exit(void) |
430 | { | 430 | { |
431 | platform_driver_unregister(&sa1100_rtc_driver); | 431 | platform_driver_unregister(&sa1100_rtc_driver); |
432 | } | 432 | } |
433 | 433 | ||
434 | module_init(sa1100_rtc_init); | 434 | module_init(sa1100_rtc_init); |
435 | module_exit(sa1100_rtc_exit); | 435 | module_exit(sa1100_rtc_exit); |
436 | 436 | ||
437 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 437 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
438 | MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); | 438 | MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); |
439 | MODULE_LICENSE("GPL"); | 439 | MODULE_LICENSE("GPL"); |
440 | MODULE_ALIAS("platform:sa1100-rtc"); | 440 | MODULE_ALIAS("platform:sa1100-rtc"); |
441 | 441 |
drivers/video/sa1100fb.c
1 | /* | 1 | /* |
2 | * linux/drivers/video/sa1100fb.c | 2 | * linux/drivers/video/sa1100fb.c |
3 | * | 3 | * |
4 | * Copyright (C) 1999 Eric A. Thomas | 4 | * Copyright (C) 1999 Eric A. Thomas |
5 | * Based on acornfb.c Copyright (C) Russell King. | 5 | * Based on acornfb.c Copyright (C) Russell King. |
6 | * | 6 | * |
7 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
8 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
9 | * more details. | 9 | * more details. |
10 | * | 10 | * |
11 | * StrongARM 1100 LCD Controller Frame Buffer Driver | 11 | * StrongARM 1100 LCD Controller Frame Buffer Driver |
12 | * | 12 | * |
13 | * Please direct your questions and comments on this driver to the following | 13 | * Please direct your questions and comments on this driver to the following |
14 | * email address: | 14 | * email address: |
15 | * | 15 | * |
16 | * linux-arm-kernel@lists.arm.linux.org.uk | 16 | * linux-arm-kernel@lists.arm.linux.org.uk |
17 | * | 17 | * |
18 | * Clean patches should be sent to the ARM Linux Patch System. Please see the | 18 | * Clean patches should be sent to the ARM Linux Patch System. Please see the |
19 | * following web page for more information: | 19 | * following web page for more information: |
20 | * | 20 | * |
21 | * http://www.arm.linux.org.uk/developer/patches/info.shtml | 21 | * http://www.arm.linux.org.uk/developer/patches/info.shtml |
22 | * | 22 | * |
23 | * Thank you. | 23 | * Thank you. |
24 | * | 24 | * |
25 | * Known problems: | 25 | * Known problems: |
26 | * - With the Neponset plugged into an Assabet, LCD powerdown | 26 | * - With the Neponset plugged into an Assabet, LCD powerdown |
27 | * doesn't work (LCD stays powered up). Therefore we shouldn't | 27 | * doesn't work (LCD stays powered up). Therefore we shouldn't |
28 | * blank the screen. | 28 | * blank the screen. |
29 | * - We don't limit the CPU clock rate nor the mode selection | 29 | * - We don't limit the CPU clock rate nor the mode selection |
30 | * according to the available SDRAM bandwidth. | 30 | * according to the available SDRAM bandwidth. |
31 | * | 31 | * |
32 | * Other notes: | 32 | * Other notes: |
33 | * - Linear grayscale palettes and the kernel. | 33 | * - Linear grayscale palettes and the kernel. |
34 | * Such code does not belong in the kernel. The kernel frame buffer | 34 | * Such code does not belong in the kernel. The kernel frame buffer |
35 | * drivers do not expect a linear colourmap, but a colourmap based on | 35 | * drivers do not expect a linear colourmap, but a colourmap based on |
36 | * the VT100 standard mapping. | 36 | * the VT100 standard mapping. |
37 | * | 37 | * |
38 | * If your _userspace_ requires a linear colourmap, then the setup of | 38 | * If your _userspace_ requires a linear colourmap, then the setup of |
39 | * such a colourmap belongs _in userspace_, not in the kernel. Code | 39 | * such a colourmap belongs _in userspace_, not in the kernel. Code |
40 | * to set the colourmap correctly from user space has been sent to | 40 | * to set the colourmap correctly from user space has been sent to |
41 | * David Neuer. It's around 8 lines of C code, plus another 4 to | 41 | * David Neuer. It's around 8 lines of C code, plus another 4 to |
42 | * detect if we are using grayscale. | 42 | * detect if we are using grayscale. |
43 | * | 43 | * |
44 | * - The following must never be specified in a panel definition: | 44 | * - The following must never be specified in a panel definition: |
45 | * LCCR0_LtlEnd, LCCR3_PixClkDiv, LCCR3_VrtSnchL, LCCR3_HorSnchL | 45 | * LCCR0_LtlEnd, LCCR3_PixClkDiv, LCCR3_VrtSnchL, LCCR3_HorSnchL |
46 | * | 46 | * |
47 | * - The following should be specified: | 47 | * - The following should be specified: |
48 | * either LCCR0_Color or LCCR0_Mono | 48 | * either LCCR0_Color or LCCR0_Mono |
49 | * either LCCR0_Sngl or LCCR0_Dual | 49 | * either LCCR0_Sngl or LCCR0_Dual |
50 | * either LCCR0_Act or LCCR0_Pas | 50 | * either LCCR0_Act or LCCR0_Pas |
51 | * either LCCR3_OutEnH or LCCD3_OutEnL | 51 | * either LCCR3_OutEnH or LCCD3_OutEnL |
52 | * either LCCR3_PixRsEdg or LCCR3_PixFlEdg | 52 | * either LCCR3_PixRsEdg or LCCR3_PixFlEdg |
53 | * either LCCR3_ACBsDiv or LCCR3_ACBsCntOff | 53 | * either LCCR3_ACBsDiv or LCCR3_ACBsCntOff |
54 | * | 54 | * |
55 | * Code Status: | 55 | * Code Status: |
56 | * 1999/04/01: | 56 | * 1999/04/01: |
57 | * - Driver appears to be working for Brutus 320x200x8bpp mode. Other | 57 | * - Driver appears to be working for Brutus 320x200x8bpp mode. Other |
58 | * resolutions are working, but only the 8bpp mode is supported. | 58 | * resolutions are working, but only the 8bpp mode is supported. |
59 | * Changes need to be made to the palette encode and decode routines | 59 | * Changes need to be made to the palette encode and decode routines |
60 | * to support 4 and 16 bpp modes. | 60 | * to support 4 and 16 bpp modes. |
61 | * Driver is not designed to be a module. The FrameBuffer is statically | 61 | * Driver is not designed to be a module. The FrameBuffer is statically |
62 | * allocated since dynamic allocation of a 300k buffer cannot be | 62 | * allocated since dynamic allocation of a 300k buffer cannot be |
63 | * guaranteed. | 63 | * guaranteed. |
64 | * | 64 | * |
65 | * 1999/06/17: | 65 | * 1999/06/17: |
66 | * - FrameBuffer memory is now allocated at run-time when the | 66 | * - FrameBuffer memory is now allocated at run-time when the |
67 | * driver is initialized. | 67 | * driver is initialized. |
68 | * | 68 | * |
69 | * 2000/04/10: Nicolas Pitre <nico@cam.org> | 69 | * 2000/04/10: Nicolas Pitre <nico@fluxnic.net> |
70 | * - Big cleanup for dynamic selection of machine type at run time. | 70 | * - Big cleanup for dynamic selection of machine type at run time. |
71 | * | 71 | * |
72 | * 2000/07/19: Jamey Hicks <jamey@crl.dec.com> | 72 | * 2000/07/19: Jamey Hicks <jamey@crl.dec.com> |
73 | * - Support for Bitsy aka Compaq iPAQ H3600 added. | 73 | * - Support for Bitsy aka Compaq iPAQ H3600 added. |
74 | * | 74 | * |
75 | * 2000/08/07: Tak-Shing Chan <tchan.rd@idthk.com> | 75 | * 2000/08/07: Tak-Shing Chan <tchan.rd@idthk.com> |
76 | * Jeff Sutherland <jsutherland@accelent.com> | 76 | * Jeff Sutherland <jsutherland@accelent.com> |
77 | * - Resolved an issue caused by a change made to the Assabet's PLD | 77 | * - Resolved an issue caused by a change made to the Assabet's PLD |
78 | * earlier this year which broke the framebuffer driver for newer | 78 | * earlier this year which broke the framebuffer driver for newer |
79 | * Phase 4 Assabets. Some other parameters were changed to optimize | 79 | * Phase 4 Assabets. Some other parameters were changed to optimize |
80 | * for the Sharp display. | 80 | * for the Sharp display. |
81 | * | 81 | * |
82 | * 2000/08/09: Kunihiko IMAI <imai@vasara.co.jp> | 82 | * 2000/08/09: Kunihiko IMAI <imai@vasara.co.jp> |
83 | * - XP860 support added | 83 | * - XP860 support added |
84 | * | 84 | * |
85 | * 2000/08/19: Mark Huang <mhuang@livetoy.com> | 85 | * 2000/08/19: Mark Huang <mhuang@livetoy.com> |
86 | * - Allows standard options to be passed on the kernel command line | 86 | * - Allows standard options to be passed on the kernel command line |
87 | * for most common passive displays. | 87 | * for most common passive displays. |
88 | * | 88 | * |
89 | * 2000/08/29: | 89 | * 2000/08/29: |
90 | * - s/save_flags_cli/local_irq_save/ | 90 | * - s/save_flags_cli/local_irq_save/ |
91 | * - remove unneeded extra save_flags_cli in sa1100fb_enable_lcd_controller | 91 | * - remove unneeded extra save_flags_cli in sa1100fb_enable_lcd_controller |
92 | * | 92 | * |
93 | * 2000/10/10: Erik Mouw <J.A.K.Mouw@its.tudelft.nl> | 93 | * 2000/10/10: Erik Mouw <J.A.K.Mouw@its.tudelft.nl> |
94 | * - Updated LART stuff. Fixed some minor bugs. | 94 | * - Updated LART stuff. Fixed some minor bugs. |
95 | * | 95 | * |
96 | * 2000/10/30: Murphy Chen <murphy@mail.dialogue.com.tw> | 96 | * 2000/10/30: Murphy Chen <murphy@mail.dialogue.com.tw> |
97 | * - Pangolin support added | 97 | * - Pangolin support added |
98 | * | 98 | * |
99 | * 2000/10/31: Roman Jordan <jor@hoeft-wessel.de> | 99 | * 2000/10/31: Roman Jordan <jor@hoeft-wessel.de> |
100 | * - Huw Webpanel support added | 100 | * - Huw Webpanel support added |
101 | * | 101 | * |
102 | * 2000/11/23: Eric Peng <ericpeng@coventive.com> | 102 | * 2000/11/23: Eric Peng <ericpeng@coventive.com> |
103 | * - Freebird add | 103 | * - Freebird add |
104 | * | 104 | * |
105 | * 2001/02/07: Jamey Hicks <jamey.hicks@compaq.com> | 105 | * 2001/02/07: Jamey Hicks <jamey.hicks@compaq.com> |
106 | * Cliff Brake <cbrake@accelent.com> | 106 | * Cliff Brake <cbrake@accelent.com> |
107 | * - Added PM callback | 107 | * - Added PM callback |
108 | * | 108 | * |
109 | * 2001/05/26: <rmk@arm.linux.org.uk> | 109 | * 2001/05/26: <rmk@arm.linux.org.uk> |
110 | * - Fix 16bpp so that (a) we use the right colours rather than some | 110 | * - Fix 16bpp so that (a) we use the right colours rather than some |
111 | * totally random colour depending on what was in page 0, and (b) | 111 | * totally random colour depending on what was in page 0, and (b) |
112 | * we don't de-reference a NULL pointer. | 112 | * we don't de-reference a NULL pointer. |
113 | * - remove duplicated implementation of consistent_alloc() | 113 | * - remove duplicated implementation of consistent_alloc() |
114 | * - convert dma address types to dma_addr_t | 114 | * - convert dma address types to dma_addr_t |
115 | * - remove unused 'montype' stuff | 115 | * - remove unused 'montype' stuff |
116 | * - remove redundant zero inits of init_var after the initial | 116 | * - remove redundant zero inits of init_var after the initial |
117 | * memset. | 117 | * memset. |
118 | * - remove allow_modeset (acornfb idea does not belong here) | 118 | * - remove allow_modeset (acornfb idea does not belong here) |
119 | * | 119 | * |
120 | * 2001/05/28: <rmk@arm.linux.org.uk> | 120 | * 2001/05/28: <rmk@arm.linux.org.uk> |
121 | * - massive cleanup - move machine dependent data into structures | 121 | * - massive cleanup - move machine dependent data into structures |
122 | * - I've left various #warnings in - if you see one, and know | 122 | * - I've left various #warnings in - if you see one, and know |
123 | * the hardware concerned, please get in contact with me. | 123 | * the hardware concerned, please get in contact with me. |
124 | * | 124 | * |
125 | * 2001/05/31: <rmk@arm.linux.org.uk> | 125 | * 2001/05/31: <rmk@arm.linux.org.uk> |
126 | * - Fix LCCR1 HSW value, fix all machine type specifications to | 126 | * - Fix LCCR1 HSW value, fix all machine type specifications to |
127 | * keep values in line. (Please check your machine type specs) | 127 | * keep values in line. (Please check your machine type specs) |
128 | * | 128 | * |
129 | * 2001/06/10: <rmk@arm.linux.org.uk> | 129 | * 2001/06/10: <rmk@arm.linux.org.uk> |
130 | * - Fiddle with the LCD controller from task context only; mainly | 130 | * - Fiddle with the LCD controller from task context only; mainly |
131 | * so that we can run with interrupts on, and sleep. | 131 | * so that we can run with interrupts on, and sleep. |
132 | * - Convert #warnings into #errors. No pain, no gain. ;) | 132 | * - Convert #warnings into #errors. No pain, no gain. ;) |
133 | * | 133 | * |
134 | * 2001/06/14: <rmk@arm.linux.org.uk> | 134 | * 2001/06/14: <rmk@arm.linux.org.uk> |
135 | * - Make the palette BPS value for 12bpp come out correctly. | 135 | * - Make the palette BPS value for 12bpp come out correctly. |
136 | * - Take notice of "greyscale" on any colour depth. | 136 | * - Take notice of "greyscale" on any colour depth. |
137 | * - Make truecolor visuals use the RGB channel encoding information. | 137 | * - Make truecolor visuals use the RGB channel encoding information. |
138 | * | 138 | * |
139 | * 2001/07/02: <rmk@arm.linux.org.uk> | 139 | * 2001/07/02: <rmk@arm.linux.org.uk> |
140 | * - Fix colourmap problems. | 140 | * - Fix colourmap problems. |
141 | * | 141 | * |
142 | * 2001/07/13: <abraham@2d3d.co.za> | 142 | * 2001/07/13: <abraham@2d3d.co.za> |
143 | * - Added support for the ICP LCD-Kit01 on LART. This LCD is | 143 | * - Added support for the ICP LCD-Kit01 on LART. This LCD is |
144 | * manufactured by Prime View, model no V16C6448AB | 144 | * manufactured by Prime View, model no V16C6448AB |
145 | * | 145 | * |
146 | * 2001/07/23: <rmk@arm.linux.org.uk> | 146 | * 2001/07/23: <rmk@arm.linux.org.uk> |
147 | * - Hand merge version from handhelds.org CVS tree. See patch | 147 | * - Hand merge version from handhelds.org CVS tree. See patch |
148 | * notes for 595/1 for more information. | 148 | * notes for 595/1 for more information. |
149 | * - Drop 12bpp (it's 16bpp with different colour register mappings). | 149 | * - Drop 12bpp (it's 16bpp with different colour register mappings). |
150 | * - This hardware can not do direct colour. Therefore we don't | 150 | * - This hardware can not do direct colour. Therefore we don't |
151 | * support it. | 151 | * support it. |
152 | * | 152 | * |
153 | * 2001/07/27: <rmk@arm.linux.org.uk> | 153 | * 2001/07/27: <rmk@arm.linux.org.uk> |
154 | * - Halve YRES on dual scan LCDs. | 154 | * - Halve YRES on dual scan LCDs. |
155 | * | 155 | * |
156 | * 2001/08/22: <rmk@arm.linux.org.uk> | 156 | * 2001/08/22: <rmk@arm.linux.org.uk> |
157 | * - Add b/w iPAQ pixclock value. | 157 | * - Add b/w iPAQ pixclock value. |
158 | * | 158 | * |
159 | * 2001/10/12: <rmk@arm.linux.org.uk> | 159 | * 2001/10/12: <rmk@arm.linux.org.uk> |
160 | * - Add patch 681/1 and clean up stork definitions. | 160 | * - Add patch 681/1 and clean up stork definitions. |
161 | */ | 161 | */ |
162 | 162 | ||
163 | #include <linux/module.h> | 163 | #include <linux/module.h> |
164 | #include <linux/kernel.h> | 164 | #include <linux/kernel.h> |
165 | #include <linux/sched.h> | 165 | #include <linux/sched.h> |
166 | #include <linux/errno.h> | 166 | #include <linux/errno.h> |
167 | #include <linux/string.h> | 167 | #include <linux/string.h> |
168 | #include <linux/interrupt.h> | 168 | #include <linux/interrupt.h> |
169 | #include <linux/slab.h> | 169 | #include <linux/slab.h> |
170 | #include <linux/mm.h> | 170 | #include <linux/mm.h> |
171 | #include <linux/fb.h> | 171 | #include <linux/fb.h> |
172 | #include <linux/delay.h> | 172 | #include <linux/delay.h> |
173 | #include <linux/init.h> | 173 | #include <linux/init.h> |
174 | #include <linux/ioport.h> | 174 | #include <linux/ioport.h> |
175 | #include <linux/cpufreq.h> | 175 | #include <linux/cpufreq.h> |
176 | #include <linux/platform_device.h> | 176 | #include <linux/platform_device.h> |
177 | #include <linux/dma-mapping.h> | 177 | #include <linux/dma-mapping.h> |
178 | #include <linux/mutex.h> | 178 | #include <linux/mutex.h> |
179 | #include <linux/io.h> | 179 | #include <linux/io.h> |
180 | 180 | ||
181 | #include <mach/hardware.h> | 181 | #include <mach/hardware.h> |
182 | #include <asm/mach-types.h> | 182 | #include <asm/mach-types.h> |
183 | #include <mach/assabet.h> | 183 | #include <mach/assabet.h> |
184 | #include <mach/shannon.h> | 184 | #include <mach/shannon.h> |
185 | 185 | ||
186 | /* | 186 | /* |
187 | * debugging? | 187 | * debugging? |
188 | */ | 188 | */ |
189 | #define DEBUG 0 | 189 | #define DEBUG 0 |
190 | /* | 190 | /* |
191 | * Complain if VAR is out of range. | 191 | * Complain if VAR is out of range. |
192 | */ | 192 | */ |
193 | #define DEBUG_VAR 1 | 193 | #define DEBUG_VAR 1 |
194 | 194 | ||
195 | #undef ASSABET_PAL_VIDEO | 195 | #undef ASSABET_PAL_VIDEO |
196 | 196 | ||
197 | #include "sa1100fb.h" | 197 | #include "sa1100fb.h" |
198 | 198 | ||
199 | extern void (*sa1100fb_backlight_power)(int on); | 199 | extern void (*sa1100fb_backlight_power)(int on); |
200 | extern void (*sa1100fb_lcd_power)(int on); | 200 | extern void (*sa1100fb_lcd_power)(int on); |
201 | 201 | ||
202 | static struct sa1100fb_rgb rgb_4 = { | 202 | static struct sa1100fb_rgb rgb_4 = { |
203 | .red = { .offset = 0, .length = 4, }, | 203 | .red = { .offset = 0, .length = 4, }, |
204 | .green = { .offset = 0, .length = 4, }, | 204 | .green = { .offset = 0, .length = 4, }, |
205 | .blue = { .offset = 0, .length = 4, }, | 205 | .blue = { .offset = 0, .length = 4, }, |
206 | .transp = { .offset = 0, .length = 0, }, | 206 | .transp = { .offset = 0, .length = 0, }, |
207 | }; | 207 | }; |
208 | 208 | ||
209 | static struct sa1100fb_rgb rgb_8 = { | 209 | static struct sa1100fb_rgb rgb_8 = { |
210 | .red = { .offset = 0, .length = 8, }, | 210 | .red = { .offset = 0, .length = 8, }, |
211 | .green = { .offset = 0, .length = 8, }, | 211 | .green = { .offset = 0, .length = 8, }, |
212 | .blue = { .offset = 0, .length = 8, }, | 212 | .blue = { .offset = 0, .length = 8, }, |
213 | .transp = { .offset = 0, .length = 0, }, | 213 | .transp = { .offset = 0, .length = 0, }, |
214 | }; | 214 | }; |
215 | 215 | ||
216 | static struct sa1100fb_rgb def_rgb_16 = { | 216 | static struct sa1100fb_rgb def_rgb_16 = { |
217 | .red = { .offset = 11, .length = 5, }, | 217 | .red = { .offset = 11, .length = 5, }, |
218 | .green = { .offset = 5, .length = 6, }, | 218 | .green = { .offset = 5, .length = 6, }, |
219 | .blue = { .offset = 0, .length = 5, }, | 219 | .blue = { .offset = 0, .length = 5, }, |
220 | .transp = { .offset = 0, .length = 0, }, | 220 | .transp = { .offset = 0, .length = 0, }, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | #ifdef CONFIG_SA1100_ASSABET | 223 | #ifdef CONFIG_SA1100_ASSABET |
224 | #ifndef ASSABET_PAL_VIDEO | 224 | #ifndef ASSABET_PAL_VIDEO |
225 | /* | 225 | /* |
226 | * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually | 226 | * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually |
227 | * takes an RGB666 signal, but we provide it with an RGB565 signal | 227 | * takes an RGB666 signal, but we provide it with an RGB565 signal |
228 | * instead (def_rgb_16). | 228 | * instead (def_rgb_16). |
229 | */ | 229 | */ |
230 | static struct sa1100fb_mach_info lq039q2ds54_info __initdata = { | 230 | static struct sa1100fb_mach_info lq039q2ds54_info __initdata = { |
231 | .pixclock = 171521, .bpp = 16, | 231 | .pixclock = 171521, .bpp = 16, |
232 | .xres = 320, .yres = 240, | 232 | .xres = 320, .yres = 240, |
233 | 233 | ||
234 | .hsync_len = 5, .vsync_len = 1, | 234 | .hsync_len = 5, .vsync_len = 1, |
235 | .left_margin = 61, .upper_margin = 3, | 235 | .left_margin = 61, .upper_margin = 3, |
236 | .right_margin = 9, .lower_margin = 0, | 236 | .right_margin = 9, .lower_margin = 0, |
237 | 237 | ||
238 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 238 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
239 | 239 | ||
240 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 240 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
241 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), | 241 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), |
242 | }; | 242 | }; |
243 | #else | 243 | #else |
244 | static struct sa1100fb_mach_info pal_info __initdata = { | 244 | static struct sa1100fb_mach_info pal_info __initdata = { |
245 | .pixclock = 67797, .bpp = 16, | 245 | .pixclock = 67797, .bpp = 16, |
246 | .xres = 640, .yres = 512, | 246 | .xres = 640, .yres = 512, |
247 | 247 | ||
248 | .hsync_len = 64, .vsync_len = 6, | 248 | .hsync_len = 64, .vsync_len = 6, |
249 | .left_margin = 125, .upper_margin = 70, | 249 | .left_margin = 125, .upper_margin = 70, |
250 | .right_margin = 115, .lower_margin = 36, | 250 | .right_margin = 115, .lower_margin = 36, |
251 | 251 | ||
252 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 252 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
253 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), | 253 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), |
254 | }; | 254 | }; |
255 | #endif | 255 | #endif |
256 | #endif | 256 | #endif |
257 | 257 | ||
258 | #ifdef CONFIG_SA1100_H3600 | 258 | #ifdef CONFIG_SA1100_H3600 |
259 | static struct sa1100fb_mach_info h3600_info __initdata = { | 259 | static struct sa1100fb_mach_info h3600_info __initdata = { |
260 | .pixclock = 174757, .bpp = 16, | 260 | .pixclock = 174757, .bpp = 16, |
261 | .xres = 320, .yres = 240, | 261 | .xres = 320, .yres = 240, |
262 | 262 | ||
263 | .hsync_len = 3, .vsync_len = 3, | 263 | .hsync_len = 3, .vsync_len = 3, |
264 | .left_margin = 12, .upper_margin = 10, | 264 | .left_margin = 12, .upper_margin = 10, |
265 | .right_margin = 17, .lower_margin = 1, | 265 | .right_margin = 17, .lower_margin = 1, |
266 | 266 | ||
267 | .cmap_static = 1, | 267 | .cmap_static = 1, |
268 | 268 | ||
269 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 269 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
270 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), | 270 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), |
271 | }; | 271 | }; |
272 | 272 | ||
273 | static struct sa1100fb_rgb h3600_rgb_16 = { | 273 | static struct sa1100fb_rgb h3600_rgb_16 = { |
274 | .red = { .offset = 12, .length = 4, }, | 274 | .red = { .offset = 12, .length = 4, }, |
275 | .green = { .offset = 7, .length = 4, }, | 275 | .green = { .offset = 7, .length = 4, }, |
276 | .blue = { .offset = 1, .length = 4, }, | 276 | .blue = { .offset = 1, .length = 4, }, |
277 | .transp = { .offset = 0, .length = 0, }, | 277 | .transp = { .offset = 0, .length = 0, }, |
278 | }; | 278 | }; |
279 | #endif | 279 | #endif |
280 | 280 | ||
281 | #ifdef CONFIG_SA1100_H3100 | 281 | #ifdef CONFIG_SA1100_H3100 |
282 | static struct sa1100fb_mach_info h3100_info __initdata = { | 282 | static struct sa1100fb_mach_info h3100_info __initdata = { |
283 | .pixclock = 406977, .bpp = 4, | 283 | .pixclock = 406977, .bpp = 4, |
284 | .xres = 320, .yres = 240, | 284 | .xres = 320, .yres = 240, |
285 | 285 | ||
286 | .hsync_len = 26, .vsync_len = 41, | 286 | .hsync_len = 26, .vsync_len = 41, |
287 | .left_margin = 4, .upper_margin = 0, | 287 | .left_margin = 4, .upper_margin = 0, |
288 | .right_margin = 4, .lower_margin = 0, | 288 | .right_margin = 4, .lower_margin = 0, |
289 | 289 | ||
290 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 290 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
291 | .cmap_greyscale = 1, | 291 | .cmap_greyscale = 1, |
292 | .cmap_inverse = 1, | 292 | .cmap_inverse = 1, |
293 | 293 | ||
294 | .lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas, | 294 | .lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas, |
295 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), | 295 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), |
296 | }; | 296 | }; |
297 | #endif | 297 | #endif |
298 | 298 | ||
299 | #ifdef CONFIG_SA1100_COLLIE | 299 | #ifdef CONFIG_SA1100_COLLIE |
300 | static struct sa1100fb_mach_info collie_info __initdata = { | 300 | static struct sa1100fb_mach_info collie_info __initdata = { |
301 | .pixclock = 171521, .bpp = 16, | 301 | .pixclock = 171521, .bpp = 16, |
302 | .xres = 320, .yres = 240, | 302 | .xres = 320, .yres = 240, |
303 | 303 | ||
304 | .hsync_len = 5, .vsync_len = 1, | 304 | .hsync_len = 5, .vsync_len = 1, |
305 | .left_margin = 11, .upper_margin = 2, | 305 | .left_margin = 11, .upper_margin = 2, |
306 | .right_margin = 30, .lower_margin = 0, | 306 | .right_margin = 30, .lower_margin = 0, |
307 | 307 | ||
308 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 308 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
309 | 309 | ||
310 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 310 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
311 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), | 311 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), |
312 | }; | 312 | }; |
313 | #endif | 313 | #endif |
314 | 314 | ||
315 | #ifdef LART_GREY_LCD | 315 | #ifdef LART_GREY_LCD |
316 | static struct sa1100fb_mach_info lart_grey_info __initdata = { | 316 | static struct sa1100fb_mach_info lart_grey_info __initdata = { |
317 | .pixclock = 150000, .bpp = 4, | 317 | .pixclock = 150000, .bpp = 4, |
318 | .xres = 320, .yres = 240, | 318 | .xres = 320, .yres = 240, |
319 | 319 | ||
320 | .hsync_len = 1, .vsync_len = 1, | 320 | .hsync_len = 1, .vsync_len = 1, |
321 | .left_margin = 4, .upper_margin = 0, | 321 | .left_margin = 4, .upper_margin = 0, |
322 | .right_margin = 2, .lower_margin = 0, | 322 | .right_margin = 2, .lower_margin = 0, |
323 | 323 | ||
324 | .cmap_greyscale = 1, | 324 | .cmap_greyscale = 1, |
325 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 325 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
326 | 326 | ||
327 | .lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono, | 327 | .lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono, |
328 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), | 328 | .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), |
329 | }; | 329 | }; |
330 | #endif | 330 | #endif |
331 | #ifdef LART_COLOR_LCD | 331 | #ifdef LART_COLOR_LCD |
332 | static struct sa1100fb_mach_info lart_color_info __initdata = { | 332 | static struct sa1100fb_mach_info lart_color_info __initdata = { |
333 | .pixclock = 150000, .bpp = 16, | 333 | .pixclock = 150000, .bpp = 16, |
334 | .xres = 320, .yres = 240, | 334 | .xres = 320, .yres = 240, |
335 | 335 | ||
336 | .hsync_len = 2, .vsync_len = 3, | 336 | .hsync_len = 2, .vsync_len = 3, |
337 | .left_margin = 69, .upper_margin = 14, | 337 | .left_margin = 69, .upper_margin = 14, |
338 | .right_margin = 8, .lower_margin = 4, | 338 | .right_margin = 8, .lower_margin = 4, |
339 | 339 | ||
340 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 340 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
341 | .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512), | 341 | .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512), |
342 | }; | 342 | }; |
343 | #endif | 343 | #endif |
344 | #ifdef LART_VIDEO_OUT | 344 | #ifdef LART_VIDEO_OUT |
345 | static struct sa1100fb_mach_info lart_video_info __initdata = { | 345 | static struct sa1100fb_mach_info lart_video_info __initdata = { |
346 | .pixclock = 39721, .bpp = 16, | 346 | .pixclock = 39721, .bpp = 16, |
347 | .xres = 640, .yres = 480, | 347 | .xres = 640, .yres = 480, |
348 | 348 | ||
349 | .hsync_len = 95, .vsync_len = 2, | 349 | .hsync_len = 95, .vsync_len = 2, |
350 | .left_margin = 40, .upper_margin = 32, | 350 | .left_margin = 40, .upper_margin = 32, |
351 | .right_margin = 24, .lower_margin = 11, | 351 | .right_margin = 24, .lower_margin = 11, |
352 | 352 | ||
353 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 353 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
354 | 354 | ||
355 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 355 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
356 | .lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512), | 356 | .lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512), |
357 | }; | 357 | }; |
358 | #endif | 358 | #endif |
359 | 359 | ||
360 | #ifdef LART_KIT01_LCD | 360 | #ifdef LART_KIT01_LCD |
361 | static struct sa1100fb_mach_info lart_kit01_info __initdata = { | 361 | static struct sa1100fb_mach_info lart_kit01_info __initdata = { |
362 | .pixclock = 63291, .bpp = 16, | 362 | .pixclock = 63291, .bpp = 16, |
363 | .xres = 640, .yres = 480, | 363 | .xres = 640, .yres = 480, |
364 | 364 | ||
365 | .hsync_len = 64, .vsync_len = 3, | 365 | .hsync_len = 64, .vsync_len = 3, |
366 | .left_margin = 122, .upper_margin = 45, | 366 | .left_margin = 122, .upper_margin = 45, |
367 | .right_margin = 10, .lower_margin = 10, | 367 | .right_margin = 10, .lower_margin = 10, |
368 | 368 | ||
369 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, | 369 | .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, |
370 | .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | 370 | .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg |
371 | }; | 371 | }; |
372 | #endif | 372 | #endif |
373 | 373 | ||
374 | #ifdef CONFIG_SA1100_SHANNON | 374 | #ifdef CONFIG_SA1100_SHANNON |
375 | static struct sa1100fb_mach_info shannon_info __initdata = { | 375 | static struct sa1100fb_mach_info shannon_info __initdata = { |
376 | .pixclock = 152500, .bpp = 8, | 376 | .pixclock = 152500, .bpp = 8, |
377 | .xres = 640, .yres = 480, | 377 | .xres = 640, .yres = 480, |
378 | 378 | ||
379 | .hsync_len = 4, .vsync_len = 3, | 379 | .hsync_len = 4, .vsync_len = 3, |
380 | .left_margin = 2, .upper_margin = 0, | 380 | .left_margin = 2, .upper_margin = 0, |
381 | .right_margin = 1, .lower_margin = 0, | 381 | .right_margin = 1, .lower_margin = 0, |
382 | 382 | ||
383 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 383 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
384 | 384 | ||
385 | .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas, | 385 | .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas, |
386 | .lccr3 = LCCR3_ACBsDiv(512), | 386 | .lccr3 = LCCR3_ACBsDiv(512), |
387 | }; | 387 | }; |
388 | #endif | 388 | #endif |
389 | 389 | ||
390 | 390 | ||
391 | 391 | ||
392 | static struct sa1100fb_mach_info * __init | 392 | static struct sa1100fb_mach_info * __init |
393 | sa1100fb_get_machine_info(struct sa1100fb_info *fbi) | 393 | sa1100fb_get_machine_info(struct sa1100fb_info *fbi) |
394 | { | 394 | { |
395 | struct sa1100fb_mach_info *inf = NULL; | 395 | struct sa1100fb_mach_info *inf = NULL; |
396 | 396 | ||
397 | /* | 397 | /* |
398 | * R G B T | 398 | * R G B T |
399 | * default {11,5}, { 5,6}, { 0,5}, { 0,0} | 399 | * default {11,5}, { 5,6}, { 0,5}, { 0,0} |
400 | * h3600 {12,4}, { 7,4}, { 1,4}, { 0,0} | 400 | * h3600 {12,4}, { 7,4}, { 1,4}, { 0,0} |
401 | * freebird { 8,4}, { 4,4}, { 0,4}, {12,4} | 401 | * freebird { 8,4}, { 4,4}, { 0,4}, {12,4} |
402 | */ | 402 | */ |
403 | #ifdef CONFIG_SA1100_ASSABET | 403 | #ifdef CONFIG_SA1100_ASSABET |
404 | if (machine_is_assabet()) { | 404 | if (machine_is_assabet()) { |
405 | #ifndef ASSABET_PAL_VIDEO | 405 | #ifndef ASSABET_PAL_VIDEO |
406 | inf = &lq039q2ds54_info; | 406 | inf = &lq039q2ds54_info; |
407 | #else | 407 | #else |
408 | inf = &pal_info; | 408 | inf = &pal_info; |
409 | #endif | 409 | #endif |
410 | } | 410 | } |
411 | #endif | 411 | #endif |
412 | #ifdef CONFIG_SA1100_H3100 | 412 | #ifdef CONFIG_SA1100_H3100 |
413 | if (machine_is_h3100()) { | 413 | if (machine_is_h3100()) { |
414 | inf = &h3100_info; | 414 | inf = &h3100_info; |
415 | } | 415 | } |
416 | #endif | 416 | #endif |
417 | #ifdef CONFIG_SA1100_H3600 | 417 | #ifdef CONFIG_SA1100_H3600 |
418 | if (machine_is_h3600()) { | 418 | if (machine_is_h3600()) { |
419 | inf = &h3600_info; | 419 | inf = &h3600_info; |
420 | fbi->rgb[RGB_16] = &h3600_rgb_16; | 420 | fbi->rgb[RGB_16] = &h3600_rgb_16; |
421 | } | 421 | } |
422 | #endif | 422 | #endif |
423 | #ifdef CONFIG_SA1100_COLLIE | 423 | #ifdef CONFIG_SA1100_COLLIE |
424 | if (machine_is_collie()) { | 424 | if (machine_is_collie()) { |
425 | inf = &collie_info; | 425 | inf = &collie_info; |
426 | } | 426 | } |
427 | #endif | 427 | #endif |
428 | #ifdef CONFIG_SA1100_LART | 428 | #ifdef CONFIG_SA1100_LART |
429 | if (machine_is_lart()) { | 429 | if (machine_is_lart()) { |
430 | #ifdef LART_GREY_LCD | 430 | #ifdef LART_GREY_LCD |
431 | inf = &lart_grey_info; | 431 | inf = &lart_grey_info; |
432 | #endif | 432 | #endif |
433 | #ifdef LART_COLOR_LCD | 433 | #ifdef LART_COLOR_LCD |
434 | inf = &lart_color_info; | 434 | inf = &lart_color_info; |
435 | #endif | 435 | #endif |
436 | #ifdef LART_VIDEO_OUT | 436 | #ifdef LART_VIDEO_OUT |
437 | inf = &lart_video_info; | 437 | inf = &lart_video_info; |
438 | #endif | 438 | #endif |
439 | #ifdef LART_KIT01_LCD | 439 | #ifdef LART_KIT01_LCD |
440 | inf = &lart_kit01_info; | 440 | inf = &lart_kit01_info; |
441 | #endif | 441 | #endif |
442 | } | 442 | } |
443 | #endif | 443 | #endif |
444 | #ifdef CONFIG_SA1100_SHANNON | 444 | #ifdef CONFIG_SA1100_SHANNON |
445 | if (machine_is_shannon()) { | 445 | if (machine_is_shannon()) { |
446 | inf = &shannon_info; | 446 | inf = &shannon_info; |
447 | } | 447 | } |
448 | #endif | 448 | #endif |
449 | return inf; | 449 | return inf; |
450 | } | 450 | } |
451 | 451 | ||
452 | static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *); | 452 | static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *); |
453 | static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state); | 453 | static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state); |
454 | 454 | ||
455 | static inline void sa1100fb_schedule_work(struct sa1100fb_info *fbi, u_int state) | 455 | static inline void sa1100fb_schedule_work(struct sa1100fb_info *fbi, u_int state) |
456 | { | 456 | { |
457 | unsigned long flags; | 457 | unsigned long flags; |
458 | 458 | ||
459 | local_irq_save(flags); | 459 | local_irq_save(flags); |
460 | /* | 460 | /* |
461 | * We need to handle two requests being made at the same time. | 461 | * We need to handle two requests being made at the same time. |
462 | * There are two important cases: | 462 | * There are two important cases: |
463 | * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) | 463 | * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) |
464 | * We must perform the unblanking, which will do our REENABLE for us. | 464 | * We must perform the unblanking, which will do our REENABLE for us. |
465 | * 2. When we are blanking, but immediately unblank before we have | 465 | * 2. When we are blanking, but immediately unblank before we have |
466 | * blanked. We do the "REENABLE" thing here as well, just to be sure. | 466 | * blanked. We do the "REENABLE" thing here as well, just to be sure. |
467 | */ | 467 | */ |
468 | if (fbi->task_state == C_ENABLE && state == C_REENABLE) | 468 | if (fbi->task_state == C_ENABLE && state == C_REENABLE) |
469 | state = (u_int) -1; | 469 | state = (u_int) -1; |
470 | if (fbi->task_state == C_DISABLE && state == C_ENABLE) | 470 | if (fbi->task_state == C_DISABLE && state == C_ENABLE) |
471 | state = C_REENABLE; | 471 | state = C_REENABLE; |
472 | 472 | ||
473 | if (state != (u_int)-1) { | 473 | if (state != (u_int)-1) { |
474 | fbi->task_state = state; | 474 | fbi->task_state = state; |
475 | schedule_work(&fbi->task); | 475 | schedule_work(&fbi->task); |
476 | } | 476 | } |
477 | local_irq_restore(flags); | 477 | local_irq_restore(flags); |
478 | } | 478 | } |
479 | 479 | ||
480 | static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) | 480 | static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) |
481 | { | 481 | { |
482 | chan &= 0xffff; | 482 | chan &= 0xffff; |
483 | chan >>= 16 - bf->length; | 483 | chan >>= 16 - bf->length; |
484 | return chan << bf->offset; | 484 | return chan << bf->offset; |
485 | } | 485 | } |
486 | 486 | ||
487 | /* | 487 | /* |
488 | * Convert bits-per-pixel to a hardware palette PBS value. | 488 | * Convert bits-per-pixel to a hardware palette PBS value. |
489 | */ | 489 | */ |
490 | static inline u_int palette_pbs(struct fb_var_screeninfo *var) | 490 | static inline u_int palette_pbs(struct fb_var_screeninfo *var) |
491 | { | 491 | { |
492 | int ret = 0; | 492 | int ret = 0; |
493 | switch (var->bits_per_pixel) { | 493 | switch (var->bits_per_pixel) { |
494 | case 4: ret = 0 << 12; break; | 494 | case 4: ret = 0 << 12; break; |
495 | case 8: ret = 1 << 12; break; | 495 | case 8: ret = 1 << 12; break; |
496 | case 16: ret = 2 << 12; break; | 496 | case 16: ret = 2 << 12; break; |
497 | } | 497 | } |
498 | return ret; | 498 | return ret; |
499 | } | 499 | } |
500 | 500 | ||
501 | static int | 501 | static int |
502 | sa1100fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, | 502 | sa1100fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, |
503 | u_int trans, struct fb_info *info) | 503 | u_int trans, struct fb_info *info) |
504 | { | 504 | { |
505 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 505 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
506 | u_int val, ret = 1; | 506 | u_int val, ret = 1; |
507 | 507 | ||
508 | if (regno < fbi->palette_size) { | 508 | if (regno < fbi->palette_size) { |
509 | val = ((red >> 4) & 0xf00); | 509 | val = ((red >> 4) & 0xf00); |
510 | val |= ((green >> 8) & 0x0f0); | 510 | val |= ((green >> 8) & 0x0f0); |
511 | val |= ((blue >> 12) & 0x00f); | 511 | val |= ((blue >> 12) & 0x00f); |
512 | 512 | ||
513 | if (regno == 0) | 513 | if (regno == 0) |
514 | val |= palette_pbs(&fbi->fb.var); | 514 | val |= palette_pbs(&fbi->fb.var); |
515 | 515 | ||
516 | fbi->palette_cpu[regno] = val; | 516 | fbi->palette_cpu[regno] = val; |
517 | ret = 0; | 517 | ret = 0; |
518 | } | 518 | } |
519 | return ret; | 519 | return ret; |
520 | } | 520 | } |
521 | 521 | ||
522 | static int | 522 | static int |
523 | sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | 523 | sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, |
524 | u_int trans, struct fb_info *info) | 524 | u_int trans, struct fb_info *info) |
525 | { | 525 | { |
526 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 526 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
527 | unsigned int val; | 527 | unsigned int val; |
528 | int ret = 1; | 528 | int ret = 1; |
529 | 529 | ||
530 | /* | 530 | /* |
531 | * If inverse mode was selected, invert all the colours | 531 | * If inverse mode was selected, invert all the colours |
532 | * rather than the register number. The register number | 532 | * rather than the register number. The register number |
533 | * is what you poke into the framebuffer to produce the | 533 | * is what you poke into the framebuffer to produce the |
534 | * colour you requested. | 534 | * colour you requested. |
535 | */ | 535 | */ |
536 | if (fbi->cmap_inverse) { | 536 | if (fbi->cmap_inverse) { |
537 | red = 0xffff - red; | 537 | red = 0xffff - red; |
538 | green = 0xffff - green; | 538 | green = 0xffff - green; |
539 | blue = 0xffff - blue; | 539 | blue = 0xffff - blue; |
540 | } | 540 | } |
541 | 541 | ||
542 | /* | 542 | /* |
543 | * If greyscale is true, then we convert the RGB value | 543 | * If greyscale is true, then we convert the RGB value |
544 | * to greyscale no mater what visual we are using. | 544 | * to greyscale no mater what visual we are using. |
545 | */ | 545 | */ |
546 | if (fbi->fb.var.grayscale) | 546 | if (fbi->fb.var.grayscale) |
547 | red = green = blue = (19595 * red + 38470 * green + | 547 | red = green = blue = (19595 * red + 38470 * green + |
548 | 7471 * blue) >> 16; | 548 | 7471 * blue) >> 16; |
549 | 549 | ||
550 | switch (fbi->fb.fix.visual) { | 550 | switch (fbi->fb.fix.visual) { |
551 | case FB_VISUAL_TRUECOLOR: | 551 | case FB_VISUAL_TRUECOLOR: |
552 | /* | 552 | /* |
553 | * 12 or 16-bit True Colour. We encode the RGB value | 553 | * 12 or 16-bit True Colour. We encode the RGB value |
554 | * according to the RGB bitfield information. | 554 | * according to the RGB bitfield information. |
555 | */ | 555 | */ |
556 | if (regno < 16) { | 556 | if (regno < 16) { |
557 | u32 *pal = fbi->fb.pseudo_palette; | 557 | u32 *pal = fbi->fb.pseudo_palette; |
558 | 558 | ||
559 | val = chan_to_field(red, &fbi->fb.var.red); | 559 | val = chan_to_field(red, &fbi->fb.var.red); |
560 | val |= chan_to_field(green, &fbi->fb.var.green); | 560 | val |= chan_to_field(green, &fbi->fb.var.green); |
561 | val |= chan_to_field(blue, &fbi->fb.var.blue); | 561 | val |= chan_to_field(blue, &fbi->fb.var.blue); |
562 | 562 | ||
563 | pal[regno] = val; | 563 | pal[regno] = val; |
564 | ret = 0; | 564 | ret = 0; |
565 | } | 565 | } |
566 | break; | 566 | break; |
567 | 567 | ||
568 | case FB_VISUAL_STATIC_PSEUDOCOLOR: | 568 | case FB_VISUAL_STATIC_PSEUDOCOLOR: |
569 | case FB_VISUAL_PSEUDOCOLOR: | 569 | case FB_VISUAL_PSEUDOCOLOR: |
570 | ret = sa1100fb_setpalettereg(regno, red, green, blue, trans, info); | 570 | ret = sa1100fb_setpalettereg(regno, red, green, blue, trans, info); |
571 | break; | 571 | break; |
572 | } | 572 | } |
573 | 573 | ||
574 | return ret; | 574 | return ret; |
575 | } | 575 | } |
576 | 576 | ||
577 | #ifdef CONFIG_CPU_FREQ | 577 | #ifdef CONFIG_CPU_FREQ |
578 | /* | 578 | /* |
579 | * sa1100fb_display_dma_period() | 579 | * sa1100fb_display_dma_period() |
580 | * Calculate the minimum period (in picoseconds) between two DMA | 580 | * Calculate the minimum period (in picoseconds) between two DMA |
581 | * requests for the LCD controller. If we hit this, it means we're | 581 | * requests for the LCD controller. If we hit this, it means we're |
582 | * doing nothing but LCD DMA. | 582 | * doing nothing but LCD DMA. |
583 | */ | 583 | */ |
584 | static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) | 584 | static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) |
585 | { | 585 | { |
586 | /* | 586 | /* |
587 | * Period = pixclock * bits_per_byte * bytes_per_transfer | 587 | * Period = pixclock * bits_per_byte * bytes_per_transfer |
588 | * / memory_bits_per_pixel; | 588 | * / memory_bits_per_pixel; |
589 | */ | 589 | */ |
590 | return var->pixclock * 8 * 16 / var->bits_per_pixel; | 590 | return var->pixclock * 8 * 16 / var->bits_per_pixel; |
591 | } | 591 | } |
592 | #endif | 592 | #endif |
593 | 593 | ||
594 | /* | 594 | /* |
595 | * sa1100fb_check_var(): | 595 | * sa1100fb_check_var(): |
596 | * Round up in the following order: bits_per_pixel, xres, | 596 | * Round up in the following order: bits_per_pixel, xres, |
597 | * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, | 597 | * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, |
598 | * bitfields, horizontal timing, vertical timing. | 598 | * bitfields, horizontal timing, vertical timing. |
599 | */ | 599 | */ |
600 | static int | 600 | static int |
601 | sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 601 | sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
602 | { | 602 | { |
603 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 603 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
604 | int rgbidx; | 604 | int rgbidx; |
605 | 605 | ||
606 | if (var->xres < MIN_XRES) | 606 | if (var->xres < MIN_XRES) |
607 | var->xres = MIN_XRES; | 607 | var->xres = MIN_XRES; |
608 | if (var->yres < MIN_YRES) | 608 | if (var->yres < MIN_YRES) |
609 | var->yres = MIN_YRES; | 609 | var->yres = MIN_YRES; |
610 | if (var->xres > fbi->max_xres) | 610 | if (var->xres > fbi->max_xres) |
611 | var->xres = fbi->max_xres; | 611 | var->xres = fbi->max_xres; |
612 | if (var->yres > fbi->max_yres) | 612 | if (var->yres > fbi->max_yres) |
613 | var->yres = fbi->max_yres; | 613 | var->yres = fbi->max_yres; |
614 | var->xres_virtual = max(var->xres_virtual, var->xres); | 614 | var->xres_virtual = max(var->xres_virtual, var->xres); |
615 | var->yres_virtual = max(var->yres_virtual, var->yres); | 615 | var->yres_virtual = max(var->yres_virtual, var->yres); |
616 | 616 | ||
617 | DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); | 617 | DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); |
618 | switch (var->bits_per_pixel) { | 618 | switch (var->bits_per_pixel) { |
619 | case 4: | 619 | case 4: |
620 | rgbidx = RGB_4; | 620 | rgbidx = RGB_4; |
621 | break; | 621 | break; |
622 | case 8: | 622 | case 8: |
623 | rgbidx = RGB_8; | 623 | rgbidx = RGB_8; |
624 | break; | 624 | break; |
625 | case 16: | 625 | case 16: |
626 | rgbidx = RGB_16; | 626 | rgbidx = RGB_16; |
627 | break; | 627 | break; |
628 | default: | 628 | default: |
629 | return -EINVAL; | 629 | return -EINVAL; |
630 | } | 630 | } |
631 | 631 | ||
632 | /* | 632 | /* |
633 | * Copy the RGB parameters for this display | 633 | * Copy the RGB parameters for this display |
634 | * from the machine specific parameters. | 634 | * from the machine specific parameters. |
635 | */ | 635 | */ |
636 | var->red = fbi->rgb[rgbidx]->red; | 636 | var->red = fbi->rgb[rgbidx]->red; |
637 | var->green = fbi->rgb[rgbidx]->green; | 637 | var->green = fbi->rgb[rgbidx]->green; |
638 | var->blue = fbi->rgb[rgbidx]->blue; | 638 | var->blue = fbi->rgb[rgbidx]->blue; |
639 | var->transp = fbi->rgb[rgbidx]->transp; | 639 | var->transp = fbi->rgb[rgbidx]->transp; |
640 | 640 | ||
641 | DPRINTK("RGBT length = %d:%d:%d:%d\n", | 641 | DPRINTK("RGBT length = %d:%d:%d:%d\n", |
642 | var->red.length, var->green.length, var->blue.length, | 642 | var->red.length, var->green.length, var->blue.length, |
643 | var->transp.length); | 643 | var->transp.length); |
644 | 644 | ||
645 | DPRINTK("RGBT offset = %d:%d:%d:%d\n", | 645 | DPRINTK("RGBT offset = %d:%d:%d:%d\n", |
646 | var->red.offset, var->green.offset, var->blue.offset, | 646 | var->red.offset, var->green.offset, var->blue.offset, |
647 | var->transp.offset); | 647 | var->transp.offset); |
648 | 648 | ||
649 | #ifdef CONFIG_CPU_FREQ | 649 | #ifdef CONFIG_CPU_FREQ |
650 | printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n", | 650 | printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n", |
651 | sa1100fb_display_dma_period(var), | 651 | sa1100fb_display_dma_period(var), |
652 | cpufreq_get(smp_processor_id())); | 652 | cpufreq_get(smp_processor_id())); |
653 | #endif | 653 | #endif |
654 | 654 | ||
655 | return 0; | 655 | return 0; |
656 | } | 656 | } |
657 | 657 | ||
658 | static inline void sa1100fb_set_truecolor(u_int is_true_color) | 658 | static inline void sa1100fb_set_truecolor(u_int is_true_color) |
659 | { | 659 | { |
660 | if (machine_is_assabet()) { | 660 | if (machine_is_assabet()) { |
661 | #if 1 // phase 4 or newer Assabet's | 661 | #if 1 // phase 4 or newer Assabet's |
662 | if (is_true_color) | 662 | if (is_true_color) |
663 | ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); | 663 | ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); |
664 | else | 664 | else |
665 | ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); | 665 | ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); |
666 | #else | 666 | #else |
667 | // older Assabet's | 667 | // older Assabet's |
668 | if (is_true_color) | 668 | if (is_true_color) |
669 | ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); | 669 | ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); |
670 | else | 670 | else |
671 | ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); | 671 | ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); |
672 | #endif | 672 | #endif |
673 | } | 673 | } |
674 | } | 674 | } |
675 | 675 | ||
676 | /* | 676 | /* |
677 | * sa1100fb_set_par(): | 677 | * sa1100fb_set_par(): |
678 | * Set the user defined part of the display for the specified console | 678 | * Set the user defined part of the display for the specified console |
679 | */ | 679 | */ |
680 | static int sa1100fb_set_par(struct fb_info *info) | 680 | static int sa1100fb_set_par(struct fb_info *info) |
681 | { | 681 | { |
682 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 682 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
683 | struct fb_var_screeninfo *var = &info->var; | 683 | struct fb_var_screeninfo *var = &info->var; |
684 | unsigned long palette_mem_size; | 684 | unsigned long palette_mem_size; |
685 | 685 | ||
686 | DPRINTK("set_par\n"); | 686 | DPRINTK("set_par\n"); |
687 | 687 | ||
688 | if (var->bits_per_pixel == 16) | 688 | if (var->bits_per_pixel == 16) |
689 | fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; | 689 | fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; |
690 | else if (!fbi->cmap_static) | 690 | else if (!fbi->cmap_static) |
691 | fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; | 691 | fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; |
692 | else { | 692 | else { |
693 | /* | 693 | /* |
694 | * Some people have weird ideas about wanting static | 694 | * Some people have weird ideas about wanting static |
695 | * pseudocolor maps. I suspect their user space | 695 | * pseudocolor maps. I suspect their user space |
696 | * applications are broken. | 696 | * applications are broken. |
697 | */ | 697 | */ |
698 | fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; | 698 | fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; |
699 | } | 699 | } |
700 | 700 | ||
701 | fbi->fb.fix.line_length = var->xres_virtual * | 701 | fbi->fb.fix.line_length = var->xres_virtual * |
702 | var->bits_per_pixel / 8; | 702 | var->bits_per_pixel / 8; |
703 | fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; | 703 | fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; |
704 | 704 | ||
705 | palette_mem_size = fbi->palette_size * sizeof(u16); | 705 | palette_mem_size = fbi->palette_size * sizeof(u16); |
706 | 706 | ||
707 | DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); | 707 | DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); |
708 | 708 | ||
709 | fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); | 709 | fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); |
710 | fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; | 710 | fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; |
711 | 711 | ||
712 | /* | 712 | /* |
713 | * Set (any) board control register to handle new color depth | 713 | * Set (any) board control register to handle new color depth |
714 | */ | 714 | */ |
715 | sa1100fb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR); | 715 | sa1100fb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR); |
716 | sa1100fb_activate_var(var, fbi); | 716 | sa1100fb_activate_var(var, fbi); |
717 | 717 | ||
718 | return 0; | 718 | return 0; |
719 | } | 719 | } |
720 | 720 | ||
721 | #if 0 | 721 | #if 0 |
722 | static int | 722 | static int |
723 | sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, | 723 | sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, |
724 | struct fb_info *info) | 724 | struct fb_info *info) |
725 | { | 725 | { |
726 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 726 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
727 | 727 | ||
728 | /* | 728 | /* |
729 | * Make sure the user isn't doing something stupid. | 729 | * Make sure the user isn't doing something stupid. |
730 | */ | 730 | */ |
731 | if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->cmap_static)) | 731 | if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->cmap_static)) |
732 | return -EINVAL; | 732 | return -EINVAL; |
733 | 733 | ||
734 | return gen_set_cmap(cmap, kspc, con, info); | 734 | return gen_set_cmap(cmap, kspc, con, info); |
735 | } | 735 | } |
736 | #endif | 736 | #endif |
737 | 737 | ||
738 | /* | 738 | /* |
739 | * Formal definition of the VESA spec: | 739 | * Formal definition of the VESA spec: |
740 | * On | 740 | * On |
741 | * This refers to the state of the display when it is in full operation | 741 | * This refers to the state of the display when it is in full operation |
742 | * Stand-By | 742 | * Stand-By |
743 | * This defines an optional operating state of minimal power reduction with | 743 | * This defines an optional operating state of minimal power reduction with |
744 | * the shortest recovery time | 744 | * the shortest recovery time |
745 | * Suspend | 745 | * Suspend |
746 | * This refers to a level of power management in which substantial power | 746 | * This refers to a level of power management in which substantial power |
747 | * reduction is achieved by the display. The display can have a longer | 747 | * reduction is achieved by the display. The display can have a longer |
748 | * recovery time from this state than from the Stand-by state | 748 | * recovery time from this state than from the Stand-by state |
749 | * Off | 749 | * Off |
750 | * This indicates that the display is consuming the lowest level of power | 750 | * This indicates that the display is consuming the lowest level of power |
751 | * and is non-operational. Recovery from this state may optionally require | 751 | * and is non-operational. Recovery from this state may optionally require |
752 | * the user to manually power on the monitor | 752 | * the user to manually power on the monitor |
753 | * | 753 | * |
754 | * Now, the fbdev driver adds an additional state, (blank), where they | 754 | * Now, the fbdev driver adds an additional state, (blank), where they |
755 | * turn off the video (maybe by colormap tricks), but don't mess with the | 755 | * turn off the video (maybe by colormap tricks), but don't mess with the |
756 | * video itself: think of it semantically between on and Stand-By. | 756 | * video itself: think of it semantically between on and Stand-By. |
757 | * | 757 | * |
758 | * So here's what we should do in our fbdev blank routine: | 758 | * So here's what we should do in our fbdev blank routine: |
759 | * | 759 | * |
760 | * VESA_NO_BLANKING (mode 0) Video on, front/back light on | 760 | * VESA_NO_BLANKING (mode 0) Video on, front/back light on |
761 | * VESA_VSYNC_SUSPEND (mode 1) Video on, front/back light off | 761 | * VESA_VSYNC_SUSPEND (mode 1) Video on, front/back light off |
762 | * VESA_HSYNC_SUSPEND (mode 2) Video on, front/back light off | 762 | * VESA_HSYNC_SUSPEND (mode 2) Video on, front/back light off |
763 | * VESA_POWERDOWN (mode 3) Video off, front/back light off | 763 | * VESA_POWERDOWN (mode 3) Video off, front/back light off |
764 | * | 764 | * |
765 | * This will match the matrox implementation. | 765 | * This will match the matrox implementation. |
766 | */ | 766 | */ |
767 | /* | 767 | /* |
768 | * sa1100fb_blank(): | 768 | * sa1100fb_blank(): |
769 | * Blank the display by setting all palette values to zero. Note, the | 769 | * Blank the display by setting all palette values to zero. Note, the |
770 | * 12 and 16 bpp modes don't really use the palette, so this will not | 770 | * 12 and 16 bpp modes don't really use the palette, so this will not |
771 | * blank the display in all modes. | 771 | * blank the display in all modes. |
772 | */ | 772 | */ |
773 | static int sa1100fb_blank(int blank, struct fb_info *info) | 773 | static int sa1100fb_blank(int blank, struct fb_info *info) |
774 | { | 774 | { |
775 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 775 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
776 | int i; | 776 | int i; |
777 | 777 | ||
778 | DPRINTK("sa1100fb_blank: blank=%d\n", blank); | 778 | DPRINTK("sa1100fb_blank: blank=%d\n", blank); |
779 | 779 | ||
780 | switch (blank) { | 780 | switch (blank) { |
781 | case FB_BLANK_POWERDOWN: | 781 | case FB_BLANK_POWERDOWN: |
782 | case FB_BLANK_VSYNC_SUSPEND: | 782 | case FB_BLANK_VSYNC_SUSPEND: |
783 | case FB_BLANK_HSYNC_SUSPEND: | 783 | case FB_BLANK_HSYNC_SUSPEND: |
784 | case FB_BLANK_NORMAL: | 784 | case FB_BLANK_NORMAL: |
785 | if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || | 785 | if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || |
786 | fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) | 786 | fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) |
787 | for (i = 0; i < fbi->palette_size; i++) | 787 | for (i = 0; i < fbi->palette_size; i++) |
788 | sa1100fb_setpalettereg(i, 0, 0, 0, 0, info); | 788 | sa1100fb_setpalettereg(i, 0, 0, 0, 0, info); |
789 | sa1100fb_schedule_work(fbi, C_DISABLE); | 789 | sa1100fb_schedule_work(fbi, C_DISABLE); |
790 | break; | 790 | break; |
791 | 791 | ||
792 | case FB_BLANK_UNBLANK: | 792 | case FB_BLANK_UNBLANK: |
793 | if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || | 793 | if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || |
794 | fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) | 794 | fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) |
795 | fb_set_cmap(&fbi->fb.cmap, info); | 795 | fb_set_cmap(&fbi->fb.cmap, info); |
796 | sa1100fb_schedule_work(fbi, C_ENABLE); | 796 | sa1100fb_schedule_work(fbi, C_ENABLE); |
797 | } | 797 | } |
798 | return 0; | 798 | return 0; |
799 | } | 799 | } |
800 | 800 | ||
801 | static int sa1100fb_mmap(struct fb_info *info, | 801 | static int sa1100fb_mmap(struct fb_info *info, |
802 | struct vm_area_struct *vma) | 802 | struct vm_area_struct *vma) |
803 | { | 803 | { |
804 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; | 804 | struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; |
805 | unsigned long start, len, off = vma->vm_pgoff << PAGE_SHIFT; | 805 | unsigned long start, len, off = vma->vm_pgoff << PAGE_SHIFT; |
806 | 806 | ||
807 | if (off < info->fix.smem_len) { | 807 | if (off < info->fix.smem_len) { |
808 | vma->vm_pgoff += 1; /* skip over the palette */ | 808 | vma->vm_pgoff += 1; /* skip over the palette */ |
809 | return dma_mmap_writecombine(fbi->dev, vma, fbi->map_cpu, | 809 | return dma_mmap_writecombine(fbi->dev, vma, fbi->map_cpu, |
810 | fbi->map_dma, fbi->map_size); | 810 | fbi->map_dma, fbi->map_size); |
811 | } | 811 | } |
812 | 812 | ||
813 | start = info->fix.mmio_start; | 813 | start = info->fix.mmio_start; |
814 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 814 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); |
815 | 815 | ||
816 | if ((vma->vm_end - vma->vm_start + off) > len) | 816 | if ((vma->vm_end - vma->vm_start + off) > len) |
817 | return -EINVAL; | 817 | return -EINVAL; |
818 | 818 | ||
819 | off += start & PAGE_MASK; | 819 | off += start & PAGE_MASK; |
820 | vma->vm_pgoff = off >> PAGE_SHIFT; | 820 | vma->vm_pgoff = off >> PAGE_SHIFT; |
821 | vma->vm_flags |= VM_IO; | 821 | vma->vm_flags |= VM_IO; |
822 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 822 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
823 | return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 823 | return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, |
824 | vma->vm_end - vma->vm_start, | 824 | vma->vm_end - vma->vm_start, |
825 | vma->vm_page_prot); | 825 | vma->vm_page_prot); |
826 | } | 826 | } |
827 | 827 | ||
828 | static struct fb_ops sa1100fb_ops = { | 828 | static struct fb_ops sa1100fb_ops = { |
829 | .owner = THIS_MODULE, | 829 | .owner = THIS_MODULE, |
830 | .fb_check_var = sa1100fb_check_var, | 830 | .fb_check_var = sa1100fb_check_var, |
831 | .fb_set_par = sa1100fb_set_par, | 831 | .fb_set_par = sa1100fb_set_par, |
832 | // .fb_set_cmap = sa1100fb_set_cmap, | 832 | // .fb_set_cmap = sa1100fb_set_cmap, |
833 | .fb_setcolreg = sa1100fb_setcolreg, | 833 | .fb_setcolreg = sa1100fb_setcolreg, |
834 | .fb_fillrect = cfb_fillrect, | 834 | .fb_fillrect = cfb_fillrect, |
835 | .fb_copyarea = cfb_copyarea, | 835 | .fb_copyarea = cfb_copyarea, |
836 | .fb_imageblit = cfb_imageblit, | 836 | .fb_imageblit = cfb_imageblit, |
837 | .fb_blank = sa1100fb_blank, | 837 | .fb_blank = sa1100fb_blank, |
838 | .fb_mmap = sa1100fb_mmap, | 838 | .fb_mmap = sa1100fb_mmap, |
839 | }; | 839 | }; |
840 | 840 | ||
841 | /* | 841 | /* |
842 | * Calculate the PCD value from the clock rate (in picoseconds). | 842 | * Calculate the PCD value from the clock rate (in picoseconds). |
843 | * We take account of the PPCR clock setting. | 843 | * We take account of the PPCR clock setting. |
844 | */ | 844 | */ |
845 | static inline unsigned int get_pcd(unsigned int pixclock, unsigned int cpuclock) | 845 | static inline unsigned int get_pcd(unsigned int pixclock, unsigned int cpuclock) |
846 | { | 846 | { |
847 | unsigned int pcd = cpuclock / 100; | 847 | unsigned int pcd = cpuclock / 100; |
848 | 848 | ||
849 | pcd *= pixclock; | 849 | pcd *= pixclock; |
850 | pcd /= 10000000; | 850 | pcd /= 10000000; |
851 | 851 | ||
852 | return pcd + 1; /* make up for integer math truncations */ | 852 | return pcd + 1; /* make up for integer math truncations */ |
853 | } | 853 | } |
854 | 854 | ||
855 | /* | 855 | /* |
856 | * sa1100fb_activate_var(): | 856 | * sa1100fb_activate_var(): |
857 | * Configures LCD Controller based on entries in var parameter. Settings are | 857 | * Configures LCD Controller based on entries in var parameter. Settings are |
858 | * only written to the controller if changes were made. | 858 | * only written to the controller if changes were made. |
859 | */ | 859 | */ |
860 | static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi) | 860 | static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi) |
861 | { | 861 | { |
862 | struct sa1100fb_lcd_reg new_regs; | 862 | struct sa1100fb_lcd_reg new_regs; |
863 | u_int half_screen_size, yres, pcd; | 863 | u_int half_screen_size, yres, pcd; |
864 | u_long flags; | 864 | u_long flags; |
865 | 865 | ||
866 | DPRINTK("Configuring SA1100 LCD\n"); | 866 | DPRINTK("Configuring SA1100 LCD\n"); |
867 | 867 | ||
868 | DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n", | 868 | DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n", |
869 | var->xres, var->hsync_len, | 869 | var->xres, var->hsync_len, |
870 | var->left_margin, var->right_margin); | 870 | var->left_margin, var->right_margin); |
871 | DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n", | 871 | DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n", |
872 | var->yres, var->vsync_len, | 872 | var->yres, var->vsync_len, |
873 | var->upper_margin, var->lower_margin); | 873 | var->upper_margin, var->lower_margin); |
874 | 874 | ||
875 | #if DEBUG_VAR | 875 | #if DEBUG_VAR |
876 | if (var->xres < 16 || var->xres > 1024) | 876 | if (var->xres < 16 || var->xres > 1024) |
877 | printk(KERN_ERR "%s: invalid xres %d\n", | 877 | printk(KERN_ERR "%s: invalid xres %d\n", |
878 | fbi->fb.fix.id, var->xres); | 878 | fbi->fb.fix.id, var->xres); |
879 | if (var->hsync_len < 1 || var->hsync_len > 64) | 879 | if (var->hsync_len < 1 || var->hsync_len > 64) |
880 | printk(KERN_ERR "%s: invalid hsync_len %d\n", | 880 | printk(KERN_ERR "%s: invalid hsync_len %d\n", |
881 | fbi->fb.fix.id, var->hsync_len); | 881 | fbi->fb.fix.id, var->hsync_len); |
882 | if (var->left_margin < 1 || var->left_margin > 255) | 882 | if (var->left_margin < 1 || var->left_margin > 255) |
883 | printk(KERN_ERR "%s: invalid left_margin %d\n", | 883 | printk(KERN_ERR "%s: invalid left_margin %d\n", |
884 | fbi->fb.fix.id, var->left_margin); | 884 | fbi->fb.fix.id, var->left_margin); |
885 | if (var->right_margin < 1 || var->right_margin > 255) | 885 | if (var->right_margin < 1 || var->right_margin > 255) |
886 | printk(KERN_ERR "%s: invalid right_margin %d\n", | 886 | printk(KERN_ERR "%s: invalid right_margin %d\n", |
887 | fbi->fb.fix.id, var->right_margin); | 887 | fbi->fb.fix.id, var->right_margin); |
888 | if (var->yres < 1 || var->yres > 1024) | 888 | if (var->yres < 1 || var->yres > 1024) |
889 | printk(KERN_ERR "%s: invalid yres %d\n", | 889 | printk(KERN_ERR "%s: invalid yres %d\n", |
890 | fbi->fb.fix.id, var->yres); | 890 | fbi->fb.fix.id, var->yres); |
891 | if (var->vsync_len < 1 || var->vsync_len > 64) | 891 | if (var->vsync_len < 1 || var->vsync_len > 64) |
892 | printk(KERN_ERR "%s: invalid vsync_len %d\n", | 892 | printk(KERN_ERR "%s: invalid vsync_len %d\n", |
893 | fbi->fb.fix.id, var->vsync_len); | 893 | fbi->fb.fix.id, var->vsync_len); |
894 | if (var->upper_margin < 0 || var->upper_margin > 255) | 894 | if (var->upper_margin < 0 || var->upper_margin > 255) |
895 | printk(KERN_ERR "%s: invalid upper_margin %d\n", | 895 | printk(KERN_ERR "%s: invalid upper_margin %d\n", |
896 | fbi->fb.fix.id, var->upper_margin); | 896 | fbi->fb.fix.id, var->upper_margin); |
897 | if (var->lower_margin < 0 || var->lower_margin > 255) | 897 | if (var->lower_margin < 0 || var->lower_margin > 255) |
898 | printk(KERN_ERR "%s: invalid lower_margin %d\n", | 898 | printk(KERN_ERR "%s: invalid lower_margin %d\n", |
899 | fbi->fb.fix.id, var->lower_margin); | 899 | fbi->fb.fix.id, var->lower_margin); |
900 | #endif | 900 | #endif |
901 | 901 | ||
902 | new_regs.lccr0 = fbi->lccr0 | | 902 | new_regs.lccr0 = fbi->lccr0 | |
903 | LCCR0_LEN | LCCR0_LDM | LCCR0_BAM | | 903 | LCCR0_LEN | LCCR0_LDM | LCCR0_BAM | |
904 | LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0); | 904 | LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0); |
905 | 905 | ||
906 | new_regs.lccr1 = | 906 | new_regs.lccr1 = |
907 | LCCR1_DisWdth(var->xres) + | 907 | LCCR1_DisWdth(var->xres) + |
908 | LCCR1_HorSnchWdth(var->hsync_len) + | 908 | LCCR1_HorSnchWdth(var->hsync_len) + |
909 | LCCR1_BegLnDel(var->left_margin) + | 909 | LCCR1_BegLnDel(var->left_margin) + |
910 | LCCR1_EndLnDel(var->right_margin); | 910 | LCCR1_EndLnDel(var->right_margin); |
911 | 911 | ||
912 | /* | 912 | /* |
913 | * If we have a dual scan LCD, then we need to halve | 913 | * If we have a dual scan LCD, then we need to halve |
914 | * the YRES parameter. | 914 | * the YRES parameter. |
915 | */ | 915 | */ |
916 | yres = var->yres; | 916 | yres = var->yres; |
917 | if (fbi->lccr0 & LCCR0_Dual) | 917 | if (fbi->lccr0 & LCCR0_Dual) |
918 | yres /= 2; | 918 | yres /= 2; |
919 | 919 | ||
920 | new_regs.lccr2 = | 920 | new_regs.lccr2 = |
921 | LCCR2_DisHght(yres) + | 921 | LCCR2_DisHght(yres) + |
922 | LCCR2_VrtSnchWdth(var->vsync_len) + | 922 | LCCR2_VrtSnchWdth(var->vsync_len) + |
923 | LCCR2_BegFrmDel(var->upper_margin) + | 923 | LCCR2_BegFrmDel(var->upper_margin) + |
924 | LCCR2_EndFrmDel(var->lower_margin); | 924 | LCCR2_EndFrmDel(var->lower_margin); |
925 | 925 | ||
926 | pcd = get_pcd(var->pixclock, cpufreq_get(0)); | 926 | pcd = get_pcd(var->pixclock, cpufreq_get(0)); |
927 | new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->lccr3 | | 927 | new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->lccr3 | |
928 | (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | | 928 | (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | |
929 | (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); | 929 | (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); |
930 | 930 | ||
931 | DPRINTK("nlccr0 = 0x%08lx\n", new_regs.lccr0); | 931 | DPRINTK("nlccr0 = 0x%08lx\n", new_regs.lccr0); |
932 | DPRINTK("nlccr1 = 0x%08lx\n", new_regs.lccr1); | 932 | DPRINTK("nlccr1 = 0x%08lx\n", new_regs.lccr1); |
933 | DPRINTK("nlccr2 = 0x%08lx\n", new_regs.lccr2); | 933 | DPRINTK("nlccr2 = 0x%08lx\n", new_regs.lccr2); |
934 | DPRINTK("nlccr3 = 0x%08lx\n", new_regs.lccr3); | 934 | DPRINTK("nlccr3 = 0x%08lx\n", new_regs.lccr3); |
935 | 935 | ||
936 | half_screen_size = var->bits_per_pixel; | 936 | half_screen_size = var->bits_per_pixel; |
937 | half_screen_size = half_screen_size * var->xres * var->yres / 16; | 937 | half_screen_size = half_screen_size * var->xres * var->yres / 16; |
938 | 938 | ||
939 | /* Update shadow copy atomically */ | 939 | /* Update shadow copy atomically */ |
940 | local_irq_save(flags); | 940 | local_irq_save(flags); |
941 | fbi->dbar1 = fbi->palette_dma; | 941 | fbi->dbar1 = fbi->palette_dma; |
942 | fbi->dbar2 = fbi->screen_dma + half_screen_size; | 942 | fbi->dbar2 = fbi->screen_dma + half_screen_size; |
943 | 943 | ||
944 | fbi->reg_lccr0 = new_regs.lccr0; | 944 | fbi->reg_lccr0 = new_regs.lccr0; |
945 | fbi->reg_lccr1 = new_regs.lccr1; | 945 | fbi->reg_lccr1 = new_regs.lccr1; |
946 | fbi->reg_lccr2 = new_regs.lccr2; | 946 | fbi->reg_lccr2 = new_regs.lccr2; |
947 | fbi->reg_lccr3 = new_regs.lccr3; | 947 | fbi->reg_lccr3 = new_regs.lccr3; |
948 | local_irq_restore(flags); | 948 | local_irq_restore(flags); |
949 | 949 | ||
950 | /* | 950 | /* |
951 | * Only update the registers if the controller is enabled | 951 | * Only update the registers if the controller is enabled |
952 | * and something has changed. | 952 | * and something has changed. |
953 | */ | 953 | */ |
954 | if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) || | 954 | if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) || |
955 | (LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) || | 955 | (LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) || |
956 | (DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2)) | 956 | (DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2)) |
957 | sa1100fb_schedule_work(fbi, C_REENABLE); | 957 | sa1100fb_schedule_work(fbi, C_REENABLE); |
958 | 958 | ||
959 | return 0; | 959 | return 0; |
960 | } | 960 | } |
961 | 961 | ||
962 | /* | 962 | /* |
963 | * NOTE! The following functions are purely helpers for set_ctrlr_state. | 963 | * NOTE! The following functions are purely helpers for set_ctrlr_state. |
964 | * Do not call them directly; set_ctrlr_state does the correct serialisation | 964 | * Do not call them directly; set_ctrlr_state does the correct serialisation |
965 | * to ensure that things happen in the right way 100% of time time. | 965 | * to ensure that things happen in the right way 100% of time time. |
966 | * -- rmk | 966 | * -- rmk |
967 | */ | 967 | */ |
968 | static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on) | 968 | static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on) |
969 | { | 969 | { |
970 | DPRINTK("backlight o%s\n", on ? "n" : "ff"); | 970 | DPRINTK("backlight o%s\n", on ? "n" : "ff"); |
971 | 971 | ||
972 | if (sa1100fb_backlight_power) | 972 | if (sa1100fb_backlight_power) |
973 | sa1100fb_backlight_power(on); | 973 | sa1100fb_backlight_power(on); |
974 | } | 974 | } |
975 | 975 | ||
976 | static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on) | 976 | static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on) |
977 | { | 977 | { |
978 | DPRINTK("LCD power o%s\n", on ? "n" : "ff"); | 978 | DPRINTK("LCD power o%s\n", on ? "n" : "ff"); |
979 | 979 | ||
980 | if (sa1100fb_lcd_power) | 980 | if (sa1100fb_lcd_power) |
981 | sa1100fb_lcd_power(on); | 981 | sa1100fb_lcd_power(on); |
982 | } | 982 | } |
983 | 983 | ||
984 | static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) | 984 | static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) |
985 | { | 985 | { |
986 | u_int mask = 0; | 986 | u_int mask = 0; |
987 | 987 | ||
988 | /* | 988 | /* |
989 | * Enable GPIO<9:2> for LCD use if: | 989 | * Enable GPIO<9:2> for LCD use if: |
990 | * 1. Active display, or | 990 | * 1. Active display, or |
991 | * 2. Color Dual Passive display | 991 | * 2. Color Dual Passive display |
992 | * | 992 | * |
993 | * see table 11.8 on page 11-27 in the SA1100 manual | 993 | * see table 11.8 on page 11-27 in the SA1100 manual |
994 | * -- Erik. | 994 | * -- Erik. |
995 | * | 995 | * |
996 | * SA1110 spec update nr. 25 says we can and should | 996 | * SA1110 spec update nr. 25 says we can and should |
997 | * clear LDD15 to 12 for 4 or 8bpp modes with active | 997 | * clear LDD15 to 12 for 4 or 8bpp modes with active |
998 | * panels. | 998 | * panels. |
999 | */ | 999 | */ |
1000 | if ((fbi->reg_lccr0 & LCCR0_CMS) == LCCR0_Color && | 1000 | if ((fbi->reg_lccr0 & LCCR0_CMS) == LCCR0_Color && |
1001 | (fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) != 0) { | 1001 | (fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) != 0) { |
1002 | mask = GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8; | 1002 | mask = GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8; |
1003 | 1003 | ||
1004 | if (fbi->fb.var.bits_per_pixel > 8 || | 1004 | if (fbi->fb.var.bits_per_pixel > 8 || |
1005 | (fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) == LCCR0_Dual) | 1005 | (fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) == LCCR0_Dual) |
1006 | mask |= GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12; | 1006 | mask |= GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12; |
1007 | 1007 | ||
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | if (mask) { | 1010 | if (mask) { |
1011 | GPDR |= mask; | 1011 | GPDR |= mask; |
1012 | GAFR |= mask; | 1012 | GAFR |= mask; |
1013 | } | 1013 | } |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) | 1016 | static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) |
1017 | { | 1017 | { |
1018 | DPRINTK("Enabling LCD controller\n"); | 1018 | DPRINTK("Enabling LCD controller\n"); |
1019 | 1019 | ||
1020 | /* | 1020 | /* |
1021 | * Make sure the mode bits are present in the first palette entry | 1021 | * Make sure the mode bits are present in the first palette entry |
1022 | */ | 1022 | */ |
1023 | fbi->palette_cpu[0] &= 0xcfff; | 1023 | fbi->palette_cpu[0] &= 0xcfff; |
1024 | fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var); | 1024 | fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var); |
1025 | 1025 | ||
1026 | /* Sequence from 11.7.10 */ | 1026 | /* Sequence from 11.7.10 */ |
1027 | LCCR3 = fbi->reg_lccr3; | 1027 | LCCR3 = fbi->reg_lccr3; |
1028 | LCCR2 = fbi->reg_lccr2; | 1028 | LCCR2 = fbi->reg_lccr2; |
1029 | LCCR1 = fbi->reg_lccr1; | 1029 | LCCR1 = fbi->reg_lccr1; |
1030 | LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN; | 1030 | LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN; |
1031 | DBAR1 = fbi->dbar1; | 1031 | DBAR1 = fbi->dbar1; |
1032 | DBAR2 = fbi->dbar2; | 1032 | DBAR2 = fbi->dbar2; |
1033 | LCCR0 |= LCCR0_LEN; | 1033 | LCCR0 |= LCCR0_LEN; |
1034 | 1034 | ||
1035 | if (machine_is_shannon()) { | 1035 | if (machine_is_shannon()) { |
1036 | GPDR |= SHANNON_GPIO_DISP_EN; | 1036 | GPDR |= SHANNON_GPIO_DISP_EN; |
1037 | GPSR |= SHANNON_GPIO_DISP_EN; | 1037 | GPSR |= SHANNON_GPIO_DISP_EN; |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | DPRINTK("DBAR1 = 0x%08x\n", DBAR1); | 1040 | DPRINTK("DBAR1 = 0x%08x\n", DBAR1); |
1041 | DPRINTK("DBAR2 = 0x%08x\n", DBAR2); | 1041 | DPRINTK("DBAR2 = 0x%08x\n", DBAR2); |
1042 | DPRINTK("LCCR0 = 0x%08x\n", LCCR0); | 1042 | DPRINTK("LCCR0 = 0x%08x\n", LCCR0); |
1043 | DPRINTK("LCCR1 = 0x%08x\n", LCCR1); | 1043 | DPRINTK("LCCR1 = 0x%08x\n", LCCR1); |
1044 | DPRINTK("LCCR2 = 0x%08x\n", LCCR2); | 1044 | DPRINTK("LCCR2 = 0x%08x\n", LCCR2); |
1045 | DPRINTK("LCCR3 = 0x%08x\n", LCCR3); | 1045 | DPRINTK("LCCR3 = 0x%08x\n", LCCR3); |
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) | 1048 | static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) |
1049 | { | 1049 | { |
1050 | DECLARE_WAITQUEUE(wait, current); | 1050 | DECLARE_WAITQUEUE(wait, current); |
1051 | 1051 | ||
1052 | DPRINTK("Disabling LCD controller\n"); | 1052 | DPRINTK("Disabling LCD controller\n"); |
1053 | 1053 | ||
1054 | if (machine_is_shannon()) { | 1054 | if (machine_is_shannon()) { |
1055 | GPCR |= SHANNON_GPIO_DISP_EN; | 1055 | GPCR |= SHANNON_GPIO_DISP_EN; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | set_current_state(TASK_UNINTERRUPTIBLE); | 1058 | set_current_state(TASK_UNINTERRUPTIBLE); |
1059 | add_wait_queue(&fbi->ctrlr_wait, &wait); | 1059 | add_wait_queue(&fbi->ctrlr_wait, &wait); |
1060 | 1060 | ||
1061 | LCSR = 0xffffffff; /* Clear LCD Status Register */ | 1061 | LCSR = 0xffffffff; /* Clear LCD Status Register */ |
1062 | LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ | 1062 | LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ |
1063 | LCCR0 &= ~LCCR0_LEN; /* Disable LCD Controller */ | 1063 | LCCR0 &= ~LCCR0_LEN; /* Disable LCD Controller */ |
1064 | 1064 | ||
1065 | schedule_timeout(20 * HZ / 1000); | 1065 | schedule_timeout(20 * HZ / 1000); |
1066 | remove_wait_queue(&fbi->ctrlr_wait, &wait); | 1066 | remove_wait_queue(&fbi->ctrlr_wait, &wait); |
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | /* | 1069 | /* |
1070 | * sa1100fb_handle_irq: Handle 'LCD DONE' interrupts. | 1070 | * sa1100fb_handle_irq: Handle 'LCD DONE' interrupts. |
1071 | */ | 1071 | */ |
1072 | static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id) | 1072 | static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id) |
1073 | { | 1073 | { |
1074 | struct sa1100fb_info *fbi = dev_id; | 1074 | struct sa1100fb_info *fbi = dev_id; |
1075 | unsigned int lcsr = LCSR; | 1075 | unsigned int lcsr = LCSR; |
1076 | 1076 | ||
1077 | if (lcsr & LCSR_LDD) { | 1077 | if (lcsr & LCSR_LDD) { |
1078 | LCCR0 |= LCCR0_LDM; | 1078 | LCCR0 |= LCCR0_LDM; |
1079 | wake_up(&fbi->ctrlr_wait); | 1079 | wake_up(&fbi->ctrlr_wait); |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | LCSR = lcsr; | 1082 | LCSR = lcsr; |
1083 | return IRQ_HANDLED; | 1083 | return IRQ_HANDLED; |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | /* | 1086 | /* |
1087 | * This function must be called from task context only, since it will | 1087 | * This function must be called from task context only, since it will |
1088 | * sleep when disabling the LCD controller, or if we get two contending | 1088 | * sleep when disabling the LCD controller, or if we get two contending |
1089 | * processes trying to alter state. | 1089 | * processes trying to alter state. |
1090 | */ | 1090 | */ |
1091 | static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) | 1091 | static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) |
1092 | { | 1092 | { |
1093 | u_int old_state; | 1093 | u_int old_state; |
1094 | 1094 | ||
1095 | mutex_lock(&fbi->ctrlr_lock); | 1095 | mutex_lock(&fbi->ctrlr_lock); |
1096 | 1096 | ||
1097 | old_state = fbi->state; | 1097 | old_state = fbi->state; |
1098 | 1098 | ||
1099 | /* | 1099 | /* |
1100 | * Hack around fbcon initialisation. | 1100 | * Hack around fbcon initialisation. |
1101 | */ | 1101 | */ |
1102 | if (old_state == C_STARTUP && state == C_REENABLE) | 1102 | if (old_state == C_STARTUP && state == C_REENABLE) |
1103 | state = C_ENABLE; | 1103 | state = C_ENABLE; |
1104 | 1104 | ||
1105 | switch (state) { | 1105 | switch (state) { |
1106 | case C_DISABLE_CLKCHANGE: | 1106 | case C_DISABLE_CLKCHANGE: |
1107 | /* | 1107 | /* |
1108 | * Disable controller for clock change. If the | 1108 | * Disable controller for clock change. If the |
1109 | * controller is already disabled, then do nothing. | 1109 | * controller is already disabled, then do nothing. |
1110 | */ | 1110 | */ |
1111 | if (old_state != C_DISABLE && old_state != C_DISABLE_PM) { | 1111 | if (old_state != C_DISABLE && old_state != C_DISABLE_PM) { |
1112 | fbi->state = state; | 1112 | fbi->state = state; |
1113 | sa1100fb_disable_controller(fbi); | 1113 | sa1100fb_disable_controller(fbi); |
1114 | } | 1114 | } |
1115 | break; | 1115 | break; |
1116 | 1116 | ||
1117 | case C_DISABLE_PM: | 1117 | case C_DISABLE_PM: |
1118 | case C_DISABLE: | 1118 | case C_DISABLE: |
1119 | /* | 1119 | /* |
1120 | * Disable controller | 1120 | * Disable controller |
1121 | */ | 1121 | */ |
1122 | if (old_state != C_DISABLE) { | 1122 | if (old_state != C_DISABLE) { |
1123 | fbi->state = state; | 1123 | fbi->state = state; |
1124 | 1124 | ||
1125 | __sa1100fb_backlight_power(fbi, 0); | 1125 | __sa1100fb_backlight_power(fbi, 0); |
1126 | if (old_state != C_DISABLE_CLKCHANGE) | 1126 | if (old_state != C_DISABLE_CLKCHANGE) |
1127 | sa1100fb_disable_controller(fbi); | 1127 | sa1100fb_disable_controller(fbi); |
1128 | __sa1100fb_lcd_power(fbi, 0); | 1128 | __sa1100fb_lcd_power(fbi, 0); |
1129 | } | 1129 | } |
1130 | break; | 1130 | break; |
1131 | 1131 | ||
1132 | case C_ENABLE_CLKCHANGE: | 1132 | case C_ENABLE_CLKCHANGE: |
1133 | /* | 1133 | /* |
1134 | * Enable the controller after clock change. Only | 1134 | * Enable the controller after clock change. Only |
1135 | * do this if we were disabled for the clock change. | 1135 | * do this if we were disabled for the clock change. |
1136 | */ | 1136 | */ |
1137 | if (old_state == C_DISABLE_CLKCHANGE) { | 1137 | if (old_state == C_DISABLE_CLKCHANGE) { |
1138 | fbi->state = C_ENABLE; | 1138 | fbi->state = C_ENABLE; |
1139 | sa1100fb_enable_controller(fbi); | 1139 | sa1100fb_enable_controller(fbi); |
1140 | } | 1140 | } |
1141 | break; | 1141 | break; |
1142 | 1142 | ||
1143 | case C_REENABLE: | 1143 | case C_REENABLE: |
1144 | /* | 1144 | /* |
1145 | * Re-enable the controller only if it was already | 1145 | * Re-enable the controller only if it was already |
1146 | * enabled. This is so we reprogram the control | 1146 | * enabled. This is so we reprogram the control |
1147 | * registers. | 1147 | * registers. |
1148 | */ | 1148 | */ |
1149 | if (old_state == C_ENABLE) { | 1149 | if (old_state == C_ENABLE) { |
1150 | sa1100fb_disable_controller(fbi); | 1150 | sa1100fb_disable_controller(fbi); |
1151 | sa1100fb_setup_gpio(fbi); | 1151 | sa1100fb_setup_gpio(fbi); |
1152 | sa1100fb_enable_controller(fbi); | 1152 | sa1100fb_enable_controller(fbi); |
1153 | } | 1153 | } |
1154 | break; | 1154 | break; |
1155 | 1155 | ||
1156 | case C_ENABLE_PM: | 1156 | case C_ENABLE_PM: |
1157 | /* | 1157 | /* |
1158 | * Re-enable the controller after PM. This is not | 1158 | * Re-enable the controller after PM. This is not |
1159 | * perfect - think about the case where we were doing | 1159 | * perfect - think about the case where we were doing |
1160 | * a clock change, and we suspended half-way through. | 1160 | * a clock change, and we suspended half-way through. |
1161 | */ | 1161 | */ |
1162 | if (old_state != C_DISABLE_PM) | 1162 | if (old_state != C_DISABLE_PM) |
1163 | break; | 1163 | break; |
1164 | /* fall through */ | 1164 | /* fall through */ |
1165 | 1165 | ||
1166 | case C_ENABLE: | 1166 | case C_ENABLE: |
1167 | /* | 1167 | /* |
1168 | * Power up the LCD screen, enable controller, and | 1168 | * Power up the LCD screen, enable controller, and |
1169 | * turn on the backlight. | 1169 | * turn on the backlight. |
1170 | */ | 1170 | */ |
1171 | if (old_state != C_ENABLE) { | 1171 | if (old_state != C_ENABLE) { |
1172 | fbi->state = C_ENABLE; | 1172 | fbi->state = C_ENABLE; |
1173 | sa1100fb_setup_gpio(fbi); | 1173 | sa1100fb_setup_gpio(fbi); |
1174 | __sa1100fb_lcd_power(fbi, 1); | 1174 | __sa1100fb_lcd_power(fbi, 1); |
1175 | sa1100fb_enable_controller(fbi); | 1175 | sa1100fb_enable_controller(fbi); |
1176 | __sa1100fb_backlight_power(fbi, 1); | 1176 | __sa1100fb_backlight_power(fbi, 1); |
1177 | } | 1177 | } |
1178 | break; | 1178 | break; |
1179 | } | 1179 | } |
1180 | mutex_unlock(&fbi->ctrlr_lock); | 1180 | mutex_unlock(&fbi->ctrlr_lock); |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | /* | 1183 | /* |
1184 | * Our LCD controller task (which is called when we blank or unblank) | 1184 | * Our LCD controller task (which is called when we blank or unblank) |
1185 | * via keventd. | 1185 | * via keventd. |
1186 | */ | 1186 | */ |
1187 | static void sa1100fb_task(struct work_struct *w) | 1187 | static void sa1100fb_task(struct work_struct *w) |
1188 | { | 1188 | { |
1189 | struct sa1100fb_info *fbi = container_of(w, struct sa1100fb_info, task); | 1189 | struct sa1100fb_info *fbi = container_of(w, struct sa1100fb_info, task); |
1190 | u_int state = xchg(&fbi->task_state, -1); | 1190 | u_int state = xchg(&fbi->task_state, -1); |
1191 | 1191 | ||
1192 | set_ctrlr_state(fbi, state); | 1192 | set_ctrlr_state(fbi, state); |
1193 | } | 1193 | } |
1194 | 1194 | ||
1195 | #ifdef CONFIG_CPU_FREQ | 1195 | #ifdef CONFIG_CPU_FREQ |
1196 | /* | 1196 | /* |
1197 | * Calculate the minimum DMA period over all displays that we own. | 1197 | * Calculate the minimum DMA period over all displays that we own. |
1198 | * This, together with the SDRAM bandwidth defines the slowest CPU | 1198 | * This, together with the SDRAM bandwidth defines the slowest CPU |
1199 | * frequency that can be selected. | 1199 | * frequency that can be selected. |
1200 | */ | 1200 | */ |
1201 | static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) | 1201 | static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) |
1202 | { | 1202 | { |
1203 | #if 0 | 1203 | #if 0 |
1204 | unsigned int min_period = (unsigned int)-1; | 1204 | unsigned int min_period = (unsigned int)-1; |
1205 | int i; | 1205 | int i; |
1206 | 1206 | ||
1207 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 1207 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
1208 | struct display *disp = &fb_display[i]; | 1208 | struct display *disp = &fb_display[i]; |
1209 | unsigned int period; | 1209 | unsigned int period; |
1210 | 1210 | ||
1211 | /* | 1211 | /* |
1212 | * Do we own this display? | 1212 | * Do we own this display? |
1213 | */ | 1213 | */ |
1214 | if (disp->fb_info != &fbi->fb) | 1214 | if (disp->fb_info != &fbi->fb) |
1215 | continue; | 1215 | continue; |
1216 | 1216 | ||
1217 | /* | 1217 | /* |
1218 | * Ok, calculate its DMA period | 1218 | * Ok, calculate its DMA period |
1219 | */ | 1219 | */ |
1220 | period = sa1100fb_display_dma_period(&disp->var); | 1220 | period = sa1100fb_display_dma_period(&disp->var); |
1221 | if (period < min_period) | 1221 | if (period < min_period) |
1222 | min_period = period; | 1222 | min_period = period; |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | return min_period; | 1225 | return min_period; |
1226 | #else | 1226 | #else |
1227 | /* | 1227 | /* |
1228 | * FIXME: we need to verify _all_ consoles. | 1228 | * FIXME: we need to verify _all_ consoles. |
1229 | */ | 1229 | */ |
1230 | return sa1100fb_display_dma_period(&fbi->fb.var); | 1230 | return sa1100fb_display_dma_period(&fbi->fb.var); |
1231 | #endif | 1231 | #endif |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | /* | 1234 | /* |
1235 | * CPU clock speed change handler. We need to adjust the LCD timing | 1235 | * CPU clock speed change handler. We need to adjust the LCD timing |
1236 | * parameters when the CPU clock is adjusted by the power management | 1236 | * parameters when the CPU clock is adjusted by the power management |
1237 | * subsystem. | 1237 | * subsystem. |
1238 | */ | 1238 | */ |
1239 | static int | 1239 | static int |
1240 | sa1100fb_freq_transition(struct notifier_block *nb, unsigned long val, | 1240 | sa1100fb_freq_transition(struct notifier_block *nb, unsigned long val, |
1241 | void *data) | 1241 | void *data) |
1242 | { | 1242 | { |
1243 | struct sa1100fb_info *fbi = TO_INF(nb, freq_transition); | 1243 | struct sa1100fb_info *fbi = TO_INF(nb, freq_transition); |
1244 | struct cpufreq_freqs *f = data; | 1244 | struct cpufreq_freqs *f = data; |
1245 | u_int pcd; | 1245 | u_int pcd; |
1246 | 1246 | ||
1247 | switch (val) { | 1247 | switch (val) { |
1248 | case CPUFREQ_PRECHANGE: | 1248 | case CPUFREQ_PRECHANGE: |
1249 | set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); | 1249 | set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); |
1250 | break; | 1250 | break; |
1251 | 1251 | ||
1252 | case CPUFREQ_POSTCHANGE: | 1252 | case CPUFREQ_POSTCHANGE: |
1253 | pcd = get_pcd(fbi->fb.var.pixclock, f->new); | 1253 | pcd = get_pcd(fbi->fb.var.pixclock, f->new); |
1254 | fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); | 1254 | fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); |
1255 | set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); | 1255 | set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); |
1256 | break; | 1256 | break; |
1257 | } | 1257 | } |
1258 | return 0; | 1258 | return 0; |
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | static int | 1261 | static int |
1262 | sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val, | 1262 | sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val, |
1263 | void *data) | 1263 | void *data) |
1264 | { | 1264 | { |
1265 | struct sa1100fb_info *fbi = TO_INF(nb, freq_policy); | 1265 | struct sa1100fb_info *fbi = TO_INF(nb, freq_policy); |
1266 | struct cpufreq_policy *policy = data; | 1266 | struct cpufreq_policy *policy = data; |
1267 | 1267 | ||
1268 | switch (val) { | 1268 | switch (val) { |
1269 | case CPUFREQ_ADJUST: | 1269 | case CPUFREQ_ADJUST: |
1270 | case CPUFREQ_INCOMPATIBLE: | 1270 | case CPUFREQ_INCOMPATIBLE: |
1271 | printk(KERN_DEBUG "min dma period: %d ps, " | 1271 | printk(KERN_DEBUG "min dma period: %d ps, " |
1272 | "new clock %d kHz\n", sa1100fb_min_dma_period(fbi), | 1272 | "new clock %d kHz\n", sa1100fb_min_dma_period(fbi), |
1273 | policy->max); | 1273 | policy->max); |
1274 | /* todo: fill in min/max values */ | 1274 | /* todo: fill in min/max values */ |
1275 | break; | 1275 | break; |
1276 | case CPUFREQ_NOTIFY: | 1276 | case CPUFREQ_NOTIFY: |
1277 | do {} while(0); | 1277 | do {} while(0); |
1278 | /* todo: panic if min/max values aren't fulfilled | 1278 | /* todo: panic if min/max values aren't fulfilled |
1279 | * [can't really happen unless there's a bug in the | 1279 | * [can't really happen unless there's a bug in the |
1280 | * CPU policy verififcation process * | 1280 | * CPU policy verififcation process * |
1281 | */ | 1281 | */ |
1282 | break; | 1282 | break; |
1283 | } | 1283 | } |
1284 | return 0; | 1284 | return 0; |
1285 | } | 1285 | } |
1286 | #endif | 1286 | #endif |
1287 | 1287 | ||
1288 | #ifdef CONFIG_PM | 1288 | #ifdef CONFIG_PM |
1289 | /* | 1289 | /* |
1290 | * Power management hooks. Note that we won't be called from IRQ context, | 1290 | * Power management hooks. Note that we won't be called from IRQ context, |
1291 | * unlike the blank functions above, so we may sleep. | 1291 | * unlike the blank functions above, so we may sleep. |
1292 | */ | 1292 | */ |
1293 | static int sa1100fb_suspend(struct platform_device *dev, pm_message_t state) | 1293 | static int sa1100fb_suspend(struct platform_device *dev, pm_message_t state) |
1294 | { | 1294 | { |
1295 | struct sa1100fb_info *fbi = platform_get_drvdata(dev); | 1295 | struct sa1100fb_info *fbi = platform_get_drvdata(dev); |
1296 | 1296 | ||
1297 | set_ctrlr_state(fbi, C_DISABLE_PM); | 1297 | set_ctrlr_state(fbi, C_DISABLE_PM); |
1298 | return 0; | 1298 | return 0; |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | static int sa1100fb_resume(struct platform_device *dev) | 1301 | static int sa1100fb_resume(struct platform_device *dev) |
1302 | { | 1302 | { |
1303 | struct sa1100fb_info *fbi = platform_get_drvdata(dev); | 1303 | struct sa1100fb_info *fbi = platform_get_drvdata(dev); |
1304 | 1304 | ||
1305 | set_ctrlr_state(fbi, C_ENABLE_PM); | 1305 | set_ctrlr_state(fbi, C_ENABLE_PM); |
1306 | return 0; | 1306 | return 0; |
1307 | } | 1307 | } |
1308 | #else | 1308 | #else |
1309 | #define sa1100fb_suspend NULL | 1309 | #define sa1100fb_suspend NULL |
1310 | #define sa1100fb_resume NULL | 1310 | #define sa1100fb_resume NULL |
1311 | #endif | 1311 | #endif |
1312 | 1312 | ||
1313 | /* | 1313 | /* |
1314 | * sa1100fb_map_video_memory(): | 1314 | * sa1100fb_map_video_memory(): |
1315 | * Allocates the DRAM memory for the frame buffer. This buffer is | 1315 | * Allocates the DRAM memory for the frame buffer. This buffer is |
1316 | * remapped into a non-cached, non-buffered, memory region to | 1316 | * remapped into a non-cached, non-buffered, memory region to |
1317 | * allow palette and pixel writes to occur without flushing the | 1317 | * allow palette and pixel writes to occur without flushing the |
1318 | * cache. Once this area is remapped, all virtual memory | 1318 | * cache. Once this area is remapped, all virtual memory |
1319 | * access to the video memory should occur at the new region. | 1319 | * access to the video memory should occur at the new region. |
1320 | */ | 1320 | */ |
1321 | static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) | 1321 | static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) |
1322 | { | 1322 | { |
1323 | /* | 1323 | /* |
1324 | * We reserve one page for the palette, plus the size | 1324 | * We reserve one page for the palette, plus the size |
1325 | * of the framebuffer. | 1325 | * of the framebuffer. |
1326 | */ | 1326 | */ |
1327 | fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE); | 1327 | fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE); |
1328 | fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, | 1328 | fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, |
1329 | &fbi->map_dma, GFP_KERNEL); | 1329 | &fbi->map_dma, GFP_KERNEL); |
1330 | 1330 | ||
1331 | if (fbi->map_cpu) { | 1331 | if (fbi->map_cpu) { |
1332 | fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE; | 1332 | fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE; |
1333 | fbi->screen_dma = fbi->map_dma + PAGE_SIZE; | 1333 | fbi->screen_dma = fbi->map_dma + PAGE_SIZE; |
1334 | /* | 1334 | /* |
1335 | * FIXME: this is actually the wrong thing to place in | 1335 | * FIXME: this is actually the wrong thing to place in |
1336 | * smem_start. But fbdev suffers from the problem that | 1336 | * smem_start. But fbdev suffers from the problem that |
1337 | * it needs an API which doesn't exist (in this case, | 1337 | * it needs an API which doesn't exist (in this case, |
1338 | * dma_writecombine_mmap) | 1338 | * dma_writecombine_mmap) |
1339 | */ | 1339 | */ |
1340 | fbi->fb.fix.smem_start = fbi->screen_dma; | 1340 | fbi->fb.fix.smem_start = fbi->screen_dma; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | return fbi->map_cpu ? 0 : -ENOMEM; | 1343 | return fbi->map_cpu ? 0 : -ENOMEM; |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | /* Fake monspecs to fill in fbinfo structure */ | 1346 | /* Fake monspecs to fill in fbinfo structure */ |
1347 | static struct fb_monspecs monspecs __initdata = { | 1347 | static struct fb_monspecs monspecs __initdata = { |
1348 | .hfmin = 30000, | 1348 | .hfmin = 30000, |
1349 | .hfmax = 70000, | 1349 | .hfmax = 70000, |
1350 | .vfmin = 50, | 1350 | .vfmin = 50, |
1351 | .vfmax = 65, | 1351 | .vfmax = 65, |
1352 | }; | 1352 | }; |
1353 | 1353 | ||
1354 | 1354 | ||
1355 | static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) | 1355 | static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) |
1356 | { | 1356 | { |
1357 | struct sa1100fb_mach_info *inf; | 1357 | struct sa1100fb_mach_info *inf; |
1358 | struct sa1100fb_info *fbi; | 1358 | struct sa1100fb_info *fbi; |
1359 | 1359 | ||
1360 | fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16, | 1360 | fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16, |
1361 | GFP_KERNEL); | 1361 | GFP_KERNEL); |
1362 | if (!fbi) | 1362 | if (!fbi) |
1363 | return NULL; | 1363 | return NULL; |
1364 | 1364 | ||
1365 | memset(fbi, 0, sizeof(struct sa1100fb_info)); | 1365 | memset(fbi, 0, sizeof(struct sa1100fb_info)); |
1366 | fbi->dev = dev; | 1366 | fbi->dev = dev; |
1367 | 1367 | ||
1368 | strcpy(fbi->fb.fix.id, SA1100_NAME); | 1368 | strcpy(fbi->fb.fix.id, SA1100_NAME); |
1369 | 1369 | ||
1370 | fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; | 1370 | fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; |
1371 | fbi->fb.fix.type_aux = 0; | 1371 | fbi->fb.fix.type_aux = 0; |
1372 | fbi->fb.fix.xpanstep = 0; | 1372 | fbi->fb.fix.xpanstep = 0; |
1373 | fbi->fb.fix.ypanstep = 0; | 1373 | fbi->fb.fix.ypanstep = 0; |
1374 | fbi->fb.fix.ywrapstep = 0; | 1374 | fbi->fb.fix.ywrapstep = 0; |
1375 | fbi->fb.fix.accel = FB_ACCEL_NONE; | 1375 | fbi->fb.fix.accel = FB_ACCEL_NONE; |
1376 | 1376 | ||
1377 | fbi->fb.var.nonstd = 0; | 1377 | fbi->fb.var.nonstd = 0; |
1378 | fbi->fb.var.activate = FB_ACTIVATE_NOW; | 1378 | fbi->fb.var.activate = FB_ACTIVATE_NOW; |
1379 | fbi->fb.var.height = -1; | 1379 | fbi->fb.var.height = -1; |
1380 | fbi->fb.var.width = -1; | 1380 | fbi->fb.var.width = -1; |
1381 | fbi->fb.var.accel_flags = 0; | 1381 | fbi->fb.var.accel_flags = 0; |
1382 | fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; | 1382 | fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; |
1383 | 1383 | ||
1384 | fbi->fb.fbops = &sa1100fb_ops; | 1384 | fbi->fb.fbops = &sa1100fb_ops; |
1385 | fbi->fb.flags = FBINFO_DEFAULT; | 1385 | fbi->fb.flags = FBINFO_DEFAULT; |
1386 | fbi->fb.monspecs = monspecs; | 1386 | fbi->fb.monspecs = monspecs; |
1387 | fbi->fb.pseudo_palette = (fbi + 1); | 1387 | fbi->fb.pseudo_palette = (fbi + 1); |
1388 | 1388 | ||
1389 | fbi->rgb[RGB_4] = &rgb_4; | 1389 | fbi->rgb[RGB_4] = &rgb_4; |
1390 | fbi->rgb[RGB_8] = &rgb_8; | 1390 | fbi->rgb[RGB_8] = &rgb_8; |
1391 | fbi->rgb[RGB_16] = &def_rgb_16; | 1391 | fbi->rgb[RGB_16] = &def_rgb_16; |
1392 | 1392 | ||
1393 | inf = sa1100fb_get_machine_info(fbi); | 1393 | inf = sa1100fb_get_machine_info(fbi); |
1394 | 1394 | ||
1395 | /* | 1395 | /* |
1396 | * People just don't seem to get this. We don't support | 1396 | * People just don't seem to get this. We don't support |
1397 | * anything but correct entries now, so panic if someone | 1397 | * anything but correct entries now, so panic if someone |
1398 | * does something stupid. | 1398 | * does something stupid. |
1399 | */ | 1399 | */ |
1400 | if (inf->lccr3 & (LCCR3_VrtSnchL|LCCR3_HorSnchL|0xff) || | 1400 | if (inf->lccr3 & (LCCR3_VrtSnchL|LCCR3_HorSnchL|0xff) || |
1401 | inf->pixclock == 0) | 1401 | inf->pixclock == 0) |
1402 | panic("sa1100fb error: invalid LCCR3 fields set or zero " | 1402 | panic("sa1100fb error: invalid LCCR3 fields set or zero " |
1403 | "pixclock."); | 1403 | "pixclock."); |
1404 | 1404 | ||
1405 | fbi->max_xres = inf->xres; | 1405 | fbi->max_xres = inf->xres; |
1406 | fbi->fb.var.xres = inf->xres; | 1406 | fbi->fb.var.xres = inf->xres; |
1407 | fbi->fb.var.xres_virtual = inf->xres; | 1407 | fbi->fb.var.xres_virtual = inf->xres; |
1408 | fbi->max_yres = inf->yres; | 1408 | fbi->max_yres = inf->yres; |
1409 | fbi->fb.var.yres = inf->yres; | 1409 | fbi->fb.var.yres = inf->yres; |
1410 | fbi->fb.var.yres_virtual = inf->yres; | 1410 | fbi->fb.var.yres_virtual = inf->yres; |
1411 | fbi->max_bpp = inf->bpp; | 1411 | fbi->max_bpp = inf->bpp; |
1412 | fbi->fb.var.bits_per_pixel = inf->bpp; | 1412 | fbi->fb.var.bits_per_pixel = inf->bpp; |
1413 | fbi->fb.var.pixclock = inf->pixclock; | 1413 | fbi->fb.var.pixclock = inf->pixclock; |
1414 | fbi->fb.var.hsync_len = inf->hsync_len; | 1414 | fbi->fb.var.hsync_len = inf->hsync_len; |
1415 | fbi->fb.var.left_margin = inf->left_margin; | 1415 | fbi->fb.var.left_margin = inf->left_margin; |
1416 | fbi->fb.var.right_margin = inf->right_margin; | 1416 | fbi->fb.var.right_margin = inf->right_margin; |
1417 | fbi->fb.var.vsync_len = inf->vsync_len; | 1417 | fbi->fb.var.vsync_len = inf->vsync_len; |
1418 | fbi->fb.var.upper_margin = inf->upper_margin; | 1418 | fbi->fb.var.upper_margin = inf->upper_margin; |
1419 | fbi->fb.var.lower_margin = inf->lower_margin; | 1419 | fbi->fb.var.lower_margin = inf->lower_margin; |
1420 | fbi->fb.var.sync = inf->sync; | 1420 | fbi->fb.var.sync = inf->sync; |
1421 | fbi->fb.var.grayscale = inf->cmap_greyscale; | 1421 | fbi->fb.var.grayscale = inf->cmap_greyscale; |
1422 | fbi->cmap_inverse = inf->cmap_inverse; | 1422 | fbi->cmap_inverse = inf->cmap_inverse; |
1423 | fbi->cmap_static = inf->cmap_static; | 1423 | fbi->cmap_static = inf->cmap_static; |
1424 | fbi->lccr0 = inf->lccr0; | 1424 | fbi->lccr0 = inf->lccr0; |
1425 | fbi->lccr3 = inf->lccr3; | 1425 | fbi->lccr3 = inf->lccr3; |
1426 | fbi->state = C_STARTUP; | 1426 | fbi->state = C_STARTUP; |
1427 | fbi->task_state = (u_char)-1; | 1427 | fbi->task_state = (u_char)-1; |
1428 | fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * | 1428 | fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * |
1429 | fbi->max_bpp / 8; | 1429 | fbi->max_bpp / 8; |
1430 | 1430 | ||
1431 | init_waitqueue_head(&fbi->ctrlr_wait); | 1431 | init_waitqueue_head(&fbi->ctrlr_wait); |
1432 | INIT_WORK(&fbi->task, sa1100fb_task); | 1432 | INIT_WORK(&fbi->task, sa1100fb_task); |
1433 | mutex_init(&fbi->ctrlr_lock); | 1433 | mutex_init(&fbi->ctrlr_lock); |
1434 | 1434 | ||
1435 | return fbi; | 1435 | return fbi; |
1436 | } | 1436 | } |
1437 | 1437 | ||
1438 | static int __init sa1100fb_probe(struct platform_device *pdev) | 1438 | static int __init sa1100fb_probe(struct platform_device *pdev) |
1439 | { | 1439 | { |
1440 | struct sa1100fb_info *fbi; | 1440 | struct sa1100fb_info *fbi; |
1441 | int ret, irq; | 1441 | int ret, irq; |
1442 | 1442 | ||
1443 | irq = platform_get_irq(pdev, 0); | 1443 | irq = platform_get_irq(pdev, 0); |
1444 | if (irq < 0) | 1444 | if (irq < 0) |
1445 | return -EINVAL; | 1445 | return -EINVAL; |
1446 | 1446 | ||
1447 | if (!request_mem_region(0xb0100000, 0x10000, "LCD")) | 1447 | if (!request_mem_region(0xb0100000, 0x10000, "LCD")) |
1448 | return -EBUSY; | 1448 | return -EBUSY; |
1449 | 1449 | ||
1450 | fbi = sa1100fb_init_fbinfo(&pdev->dev); | 1450 | fbi = sa1100fb_init_fbinfo(&pdev->dev); |
1451 | ret = -ENOMEM; | 1451 | ret = -ENOMEM; |
1452 | if (!fbi) | 1452 | if (!fbi) |
1453 | goto failed; | 1453 | goto failed; |
1454 | 1454 | ||
1455 | /* Initialize video memory */ | 1455 | /* Initialize video memory */ |
1456 | ret = sa1100fb_map_video_memory(fbi); | 1456 | ret = sa1100fb_map_video_memory(fbi); |
1457 | if (ret) | 1457 | if (ret) |
1458 | goto failed; | 1458 | goto failed; |
1459 | 1459 | ||
1460 | ret = request_irq(irq, sa1100fb_handle_irq, IRQF_DISABLED, | 1460 | ret = request_irq(irq, sa1100fb_handle_irq, IRQF_DISABLED, |
1461 | "LCD", fbi); | 1461 | "LCD", fbi); |
1462 | if (ret) { | 1462 | if (ret) { |
1463 | printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); | 1463 | printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); |
1464 | goto failed; | 1464 | goto failed; |
1465 | } | 1465 | } |
1466 | 1466 | ||
1467 | #ifdef ASSABET_PAL_VIDEO | 1467 | #ifdef ASSABET_PAL_VIDEO |
1468 | if (machine_is_assabet()) | 1468 | if (machine_is_assabet()) |
1469 | ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); | 1469 | ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); |
1470 | #endif | 1470 | #endif |
1471 | 1471 | ||
1472 | /* | 1472 | /* |
1473 | * This makes sure that our colour bitfield | 1473 | * This makes sure that our colour bitfield |
1474 | * descriptors are correctly initialised. | 1474 | * descriptors are correctly initialised. |
1475 | */ | 1475 | */ |
1476 | sa1100fb_check_var(&fbi->fb.var, &fbi->fb); | 1476 | sa1100fb_check_var(&fbi->fb.var, &fbi->fb); |
1477 | 1477 | ||
1478 | platform_set_drvdata(pdev, fbi); | 1478 | platform_set_drvdata(pdev, fbi); |
1479 | 1479 | ||
1480 | ret = register_framebuffer(&fbi->fb); | 1480 | ret = register_framebuffer(&fbi->fb); |
1481 | if (ret < 0) | 1481 | if (ret < 0) |
1482 | goto err_free_irq; | 1482 | goto err_free_irq; |
1483 | 1483 | ||
1484 | #ifdef CONFIG_CPU_FREQ | 1484 | #ifdef CONFIG_CPU_FREQ |
1485 | fbi->freq_transition.notifier_call = sa1100fb_freq_transition; | 1485 | fbi->freq_transition.notifier_call = sa1100fb_freq_transition; |
1486 | fbi->freq_policy.notifier_call = sa1100fb_freq_policy; | 1486 | fbi->freq_policy.notifier_call = sa1100fb_freq_policy; |
1487 | cpufreq_register_notifier(&fbi->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); | 1487 | cpufreq_register_notifier(&fbi->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); |
1488 | cpufreq_register_notifier(&fbi->freq_policy, CPUFREQ_POLICY_NOTIFIER); | 1488 | cpufreq_register_notifier(&fbi->freq_policy, CPUFREQ_POLICY_NOTIFIER); |
1489 | #endif | 1489 | #endif |
1490 | 1490 | ||
1491 | /* This driver cannot be unloaded at the moment */ | 1491 | /* This driver cannot be unloaded at the moment */ |
1492 | return 0; | 1492 | return 0; |
1493 | 1493 | ||
1494 | err_free_irq: | 1494 | err_free_irq: |
1495 | free_irq(irq, fbi); | 1495 | free_irq(irq, fbi); |
1496 | failed: | 1496 | failed: |
1497 | platform_set_drvdata(pdev, NULL); | 1497 | platform_set_drvdata(pdev, NULL); |
1498 | kfree(fbi); | 1498 | kfree(fbi); |
1499 | release_mem_region(0xb0100000, 0x10000); | 1499 | release_mem_region(0xb0100000, 0x10000); |
1500 | return ret; | 1500 | return ret; |
1501 | } | 1501 | } |
1502 | 1502 | ||
1503 | static struct platform_driver sa1100fb_driver = { | 1503 | static struct platform_driver sa1100fb_driver = { |
1504 | .probe = sa1100fb_probe, | 1504 | .probe = sa1100fb_probe, |
1505 | .suspend = sa1100fb_suspend, | 1505 | .suspend = sa1100fb_suspend, |
1506 | .resume = sa1100fb_resume, | 1506 | .resume = sa1100fb_resume, |
1507 | .driver = { | 1507 | .driver = { |
1508 | .name = "sa11x0-fb", | 1508 | .name = "sa11x0-fb", |
1509 | }, | 1509 | }, |
1510 | }; | 1510 | }; |
1511 | 1511 | ||
1512 | int __init sa1100fb_init(void) | 1512 | int __init sa1100fb_init(void) |
1513 | { | 1513 | { |
1514 | if (fb_get_options("sa1100fb", NULL)) | 1514 | if (fb_get_options("sa1100fb", NULL)) |
1515 | return -ENODEV; | 1515 | return -ENODEV; |
1516 | 1516 | ||
1517 | return platform_driver_register(&sa1100fb_driver); | 1517 | return platform_driver_register(&sa1100fb_driver); |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | int __init sa1100fb_setup(char *options) | 1520 | int __init sa1100fb_setup(char *options) |
1521 | { | 1521 | { |
1522 | #if 0 | 1522 | #if 0 |
1523 | char *this_opt; | 1523 | char *this_opt; |
1524 | 1524 | ||
1525 | if (!options || !*options) | 1525 | if (!options || !*options) |
1526 | return 0; | 1526 | return 0; |
1527 | 1527 | ||
1528 | while ((this_opt = strsep(&options, ",")) != NULL) { | 1528 | while ((this_opt = strsep(&options, ",")) != NULL) { |
1529 | 1529 | ||
1530 | if (!strncmp(this_opt, "bpp:", 4)) | 1530 | if (!strncmp(this_opt, "bpp:", 4)) |
1531 | current_par.max_bpp = | 1531 | current_par.max_bpp = |
1532 | simple_strtoul(this_opt + 4, NULL, 0); | 1532 | simple_strtoul(this_opt + 4, NULL, 0); |
1533 | 1533 | ||
1534 | if (!strncmp(this_opt, "lccr0:", 6)) | 1534 | if (!strncmp(this_opt, "lccr0:", 6)) |
1535 | lcd_shadow.lccr0 = | 1535 | lcd_shadow.lccr0 = |
1536 | simple_strtoul(this_opt + 6, NULL, 0); | 1536 | simple_strtoul(this_opt + 6, NULL, 0); |
1537 | if (!strncmp(this_opt, "lccr1:", 6)) { | 1537 | if (!strncmp(this_opt, "lccr1:", 6)) { |
1538 | lcd_shadow.lccr1 = | 1538 | lcd_shadow.lccr1 = |
1539 | simple_strtoul(this_opt + 6, NULL, 0); | 1539 | simple_strtoul(this_opt + 6, NULL, 0); |
1540 | current_par.max_xres = | 1540 | current_par.max_xres = |
1541 | (lcd_shadow.lccr1 & 0x3ff) + 16; | 1541 | (lcd_shadow.lccr1 & 0x3ff) + 16; |
1542 | } | 1542 | } |
1543 | if (!strncmp(this_opt, "lccr2:", 6)) { | 1543 | if (!strncmp(this_opt, "lccr2:", 6)) { |
1544 | lcd_shadow.lccr2 = | 1544 | lcd_shadow.lccr2 = |
1545 | simple_strtoul(this_opt + 6, NULL, 0); | 1545 | simple_strtoul(this_opt + 6, NULL, 0); |
1546 | current_par.max_yres = | 1546 | current_par.max_yres = |
1547 | (lcd_shadow. | 1547 | (lcd_shadow. |
1548 | lccr0 & LCCR0_SDS) ? ((lcd_shadow. | 1548 | lccr0 & LCCR0_SDS) ? ((lcd_shadow. |
1549 | lccr2 & 0x3ff) + | 1549 | lccr2 & 0x3ff) + |
1550 | 1) * | 1550 | 1) * |
1551 | 2 : ((lcd_shadow.lccr2 & 0x3ff) + 1); | 1551 | 2 : ((lcd_shadow.lccr2 & 0x3ff) + 1); |
1552 | } | 1552 | } |
1553 | if (!strncmp(this_opt, "lccr3:", 6)) | 1553 | if (!strncmp(this_opt, "lccr3:", 6)) |
1554 | lcd_shadow.lccr3 = | 1554 | lcd_shadow.lccr3 = |
1555 | simple_strtoul(this_opt + 6, NULL, 0); | 1555 | simple_strtoul(this_opt + 6, NULL, 0); |
1556 | } | 1556 | } |
1557 | #endif | 1557 | #endif |
1558 | return 0; | 1558 | return 0; |
1559 | } | 1559 | } |
1560 | 1560 | ||
1561 | module_init(sa1100fb_init); | 1561 | module_init(sa1100fb_init); |
1562 | MODULE_DESCRIPTION("StrongARM-1100/1110 framebuffer driver"); | 1562 | MODULE_DESCRIPTION("StrongARM-1100/1110 framebuffer driver"); |
1563 | MODULE_LICENSE("GPL"); | 1563 | MODULE_LICENSE("GPL"); |
1564 | 1564 |
include/linux/mtd/partitions.h
1 | /* | 1 | /* |
2 | * MTD partitioning layer definitions | 2 | * MTD partitioning layer definitions |
3 | * | 3 | * |
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@fluxnic.net> |
5 | * | 5 | * |
6 | * This code is GPL | 6 | * This code is GPL |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef MTD_PARTITIONS_H | 9 | #ifndef MTD_PARTITIONS_H |
10 | #define MTD_PARTITIONS_H | 10 | #define MTD_PARTITIONS_H |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | 13 | ||
14 | 14 | ||
15 | /* | 15 | /* |
16 | * Partition definition structure: | 16 | * Partition definition structure: |
17 | * | 17 | * |
18 | * An array of struct partition is passed along with a MTD object to | 18 | * An array of struct partition is passed along with a MTD object to |
19 | * add_mtd_partitions() to create them. | 19 | * add_mtd_partitions() to create them. |
20 | * | 20 | * |
21 | * For each partition, these fields are available: | 21 | * For each partition, these fields are available: |
22 | * name: string that will be used to label the partition's MTD device. | 22 | * name: string that will be used to label the partition's MTD device. |
23 | * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition | 23 | * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition |
24 | * will extend to the end of the master MTD device. | 24 | * will extend to the end of the master MTD device. |
25 | * offset: absolute starting position within the master MTD device; if | 25 | * offset: absolute starting position within the master MTD device; if |
26 | * defined as MTDPART_OFS_APPEND, the partition will start where the | 26 | * defined as MTDPART_OFS_APPEND, the partition will start where the |
27 | * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. | 27 | * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. |
28 | * mask_flags: contains flags that have to be masked (removed) from the | 28 | * mask_flags: contains flags that have to be masked (removed) from the |
29 | * master MTD flag set for the corresponding MTD partition. | 29 | * master MTD flag set for the corresponding MTD partition. |
30 | * For example, to force a read-only partition, simply adding | 30 | * For example, to force a read-only partition, simply adding |
31 | * MTD_WRITEABLE to the mask_flags will do the trick. | 31 | * MTD_WRITEABLE to the mask_flags will do the trick. |
32 | * | 32 | * |
33 | * Note: writeable partitions require their size and offset be | 33 | * Note: writeable partitions require their size and offset be |
34 | * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). | 34 | * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). |
35 | */ | 35 | */ |
36 | 36 | ||
37 | struct mtd_partition { | 37 | struct mtd_partition { |
38 | char *name; /* identifier string */ | 38 | char *name; /* identifier string */ |
39 | uint64_t size; /* partition size */ | 39 | uint64_t size; /* partition size */ |
40 | uint64_t offset; /* offset within the master MTD space */ | 40 | uint64_t offset; /* offset within the master MTD space */ |
41 | uint32_t mask_flags; /* master MTD flags to mask out for this partition */ | 41 | uint32_t mask_flags; /* master MTD flags to mask out for this partition */ |
42 | struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ | 42 | struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #define MTDPART_OFS_NXTBLK (-2) | 45 | #define MTDPART_OFS_NXTBLK (-2) |
46 | #define MTDPART_OFS_APPEND (-1) | 46 | #define MTDPART_OFS_APPEND (-1) |
47 | #define MTDPART_SIZ_FULL (0) | 47 | #define MTDPART_SIZ_FULL (0) |
48 | 48 | ||
49 | 49 | ||
50 | struct mtd_info; | 50 | struct mtd_info; |
51 | 51 | ||
52 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); | 52 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); |
53 | int del_mtd_partitions(struct mtd_info *); | 53 | int del_mtd_partitions(struct mtd_info *); |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Functions dealing with the various ways of partitioning the space | 56 | * Functions dealing with the various ways of partitioning the space |
57 | */ | 57 | */ |
58 | 58 | ||
59 | struct mtd_part_parser { | 59 | struct mtd_part_parser { |
60 | struct list_head list; | 60 | struct list_head list; |
61 | struct module *owner; | 61 | struct module *owner; |
62 | const char *name; | 62 | const char *name; |
63 | int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); | 63 | int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); |
64 | }; | 64 | }; |
65 | 65 | ||
66 | extern int register_mtd_parser(struct mtd_part_parser *parser); | 66 | extern int register_mtd_parser(struct mtd_part_parser *parser); |
67 | extern int deregister_mtd_parser(struct mtd_part_parser *parser); | 67 | extern int deregister_mtd_parser(struct mtd_part_parser *parser); |
68 | extern int parse_mtd_partitions(struct mtd_info *master, const char **types, | 68 | extern int parse_mtd_partitions(struct mtd_info *master, const char **types, |
69 | struct mtd_partition **pparts, unsigned long origin); | 69 | struct mtd_partition **pparts, unsigned long origin); |
70 | 70 | ||
71 | #define put_partition_parser(p) do { module_put((p)->owner); } while(0) | 71 | #define put_partition_parser(p) do { module_put((p)->owner); } while(0) |
72 | 72 | ||
73 | struct device; | 73 | struct device; |
74 | struct device_node; | 74 | struct device_node; |
75 | 75 | ||
76 | int __devinit of_mtd_parse_partitions(struct device *dev, | 76 | int __devinit of_mtd_parse_partitions(struct device *dev, |
77 | struct device_node *node, | 77 | struct device_node *node, |
78 | struct mtd_partition **pparts); | 78 | struct mtd_partition **pparts); |
79 | 79 | ||
80 | #ifdef CONFIG_MTD_PARTITIONS | 80 | #ifdef CONFIG_MTD_PARTITIONS |
81 | static inline int mtd_has_partitions(void) { return 1; } | 81 | static inline int mtd_has_partitions(void) { return 1; } |
82 | #else | 82 | #else |
83 | static inline int mtd_has_partitions(void) { return 0; } | 83 | static inline int mtd_has_partitions(void) { return 0; } |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 86 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
87 | static inline int mtd_has_cmdlinepart(void) { return 1; } | 87 | static inline int mtd_has_cmdlinepart(void) { return 1; } |
88 | #else | 88 | #else |
89 | static inline int mtd_has_cmdlinepart(void) { return 0; } | 89 | static inline int mtd_has_cmdlinepart(void) { return 0; } |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #endif | 92 | #endif |
93 | 93 |
lib/inflate.c
1 | #define DEBG(x) | 1 | #define DEBG(x) |
2 | #define DEBG1(x) | 2 | #define DEBG1(x) |
3 | /* inflate.c -- Not copyrighted 1992 by Mark Adler | 3 | /* inflate.c -- Not copyrighted 1992 by Mark Adler |
4 | version c10p1, 10 January 1993 */ | 4 | version c10p1, 10 January 1993 */ |
5 | 5 | ||
6 | /* | 6 | /* |
7 | * Adapted for booting Linux by Hannu Savolainen 1993 | 7 | * Adapted for booting Linux by Hannu Savolainen 1993 |
8 | * based on gzip-1.0.3 | 8 | * based on gzip-1.0.3 |
9 | * | 9 | * |
10 | * Nicolas Pitre <nico@cam.org>, 1999/04/14 : | 10 | * Nicolas Pitre <nico@fluxnic.net>, 1999/04/14 : |
11 | * Little mods for all variable to reside either into rodata or bss segments | 11 | * Little mods for all variable to reside either into rodata or bss segments |
12 | * by marking constant variables with 'const' and initializing all the others | 12 | * by marking constant variables with 'const' and initializing all the others |
13 | * at run-time only. This allows for the kernel uncompressor to run | 13 | * at run-time only. This allows for the kernel uncompressor to run |
14 | * directly from Flash or ROM memory on embedded systems. | 14 | * directly from Flash or ROM memory on embedded systems. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* | 17 | /* |
18 | Inflate deflated (PKZIP's method 8 compressed) data. The compression | 18 | Inflate deflated (PKZIP's method 8 compressed) data. The compression |
19 | method searches for as much of the current string of bytes (up to a | 19 | method searches for as much of the current string of bytes (up to a |
20 | length of 258) in the previous 32 K bytes. If it doesn't find any | 20 | length of 258) in the previous 32 K bytes. If it doesn't find any |
21 | matches (of at least length 3), it codes the next byte. Otherwise, it | 21 | matches (of at least length 3), it codes the next byte. Otherwise, it |
22 | codes the length of the matched string and its distance backwards from | 22 | codes the length of the matched string and its distance backwards from |
23 | the current position. There is a single Huffman code that codes both | 23 | the current position. There is a single Huffman code that codes both |
24 | single bytes (called "literals") and match lengths. A second Huffman | 24 | single bytes (called "literals") and match lengths. A second Huffman |
25 | code codes the distance information, which follows a length code. Each | 25 | code codes the distance information, which follows a length code. Each |
26 | length or distance code actually represents a base value and a number | 26 | length or distance code actually represents a base value and a number |
27 | of "extra" (sometimes zero) bits to get to add to the base value. At | 27 | of "extra" (sometimes zero) bits to get to add to the base value. At |
28 | the end of each deflated block is a special end-of-block (EOB) literal/ | 28 | the end of each deflated block is a special end-of-block (EOB) literal/ |
29 | length code. The decoding process is basically: get a literal/length | 29 | length code. The decoding process is basically: get a literal/length |
30 | code; if EOB then done; if a literal, emit the decoded byte; if a | 30 | code; if EOB then done; if a literal, emit the decoded byte; if a |
31 | length then get the distance and emit the referred-to bytes from the | 31 | length then get the distance and emit the referred-to bytes from the |
32 | sliding window of previously emitted data. | 32 | sliding window of previously emitted data. |
33 | 33 | ||
34 | There are (currently) three kinds of inflate blocks: stored, fixed, and | 34 | There are (currently) three kinds of inflate blocks: stored, fixed, and |
35 | dynamic. The compressor deals with some chunk of data at a time, and | 35 | dynamic. The compressor deals with some chunk of data at a time, and |
36 | decides which method to use on a chunk-by-chunk basis. A chunk might | 36 | decides which method to use on a chunk-by-chunk basis. A chunk might |
37 | typically be 32 K or 64 K. If the chunk is incompressible, then the | 37 | typically be 32 K or 64 K. If the chunk is incompressible, then the |
38 | "stored" method is used. In this case, the bytes are simply stored as | 38 | "stored" method is used. In this case, the bytes are simply stored as |
39 | is, eight bits per byte, with none of the above coding. The bytes are | 39 | is, eight bits per byte, with none of the above coding. The bytes are |
40 | preceded by a count, since there is no longer an EOB code. | 40 | preceded by a count, since there is no longer an EOB code. |
41 | 41 | ||
42 | If the data is compressible, then either the fixed or dynamic methods | 42 | If the data is compressible, then either the fixed or dynamic methods |
43 | are used. In the dynamic method, the compressed data is preceded by | 43 | are used. In the dynamic method, the compressed data is preceded by |
44 | an encoding of the literal/length and distance Huffman codes that are | 44 | an encoding of the literal/length and distance Huffman codes that are |
45 | to be used to decode this block. The representation is itself Huffman | 45 | to be used to decode this block. The representation is itself Huffman |
46 | coded, and so is preceded by a description of that code. These code | 46 | coded, and so is preceded by a description of that code. These code |
47 | descriptions take up a little space, and so for small blocks, there is | 47 | descriptions take up a little space, and so for small blocks, there is |
48 | a predefined set of codes, called the fixed codes. The fixed method is | 48 | a predefined set of codes, called the fixed codes. The fixed method is |
49 | used if the block codes up smaller that way (usually for quite small | 49 | used if the block codes up smaller that way (usually for quite small |
50 | chunks), otherwise the dynamic method is used. In the latter case, the | 50 | chunks), otherwise the dynamic method is used. In the latter case, the |
51 | codes are customized to the probabilities in the current block, and so | 51 | codes are customized to the probabilities in the current block, and so |
52 | can code it much better than the pre-determined fixed codes. | 52 | can code it much better than the pre-determined fixed codes. |
53 | 53 | ||
54 | The Huffman codes themselves are decoded using a multi-level table | 54 | The Huffman codes themselves are decoded using a multi-level table |
55 | lookup, in order to maximize the speed of decoding plus the speed of | 55 | lookup, in order to maximize the speed of decoding plus the speed of |
56 | building the decoding tables. See the comments below that precede the | 56 | building the decoding tables. See the comments below that precede the |
57 | lbits and dbits tuning parameters. | 57 | lbits and dbits tuning parameters. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | 60 | ||
61 | /* | 61 | /* |
62 | Notes beyond the 1.93a appnote.txt: | 62 | Notes beyond the 1.93a appnote.txt: |
63 | 63 | ||
64 | 1. Distance pointers never point before the beginning of the output | 64 | 1. Distance pointers never point before the beginning of the output |
65 | stream. | 65 | stream. |
66 | 2. Distance pointers can point back across blocks, up to 32k away. | 66 | 2. Distance pointers can point back across blocks, up to 32k away. |
67 | 3. There is an implied maximum of 7 bits for the bit length table and | 67 | 3. There is an implied maximum of 7 bits for the bit length table and |
68 | 15 bits for the actual data. | 68 | 15 bits for the actual data. |
69 | 4. If only one code exists, then it is encoded using one bit. (Zero | 69 | 4. If only one code exists, then it is encoded using one bit. (Zero |
70 | would be more efficient, but perhaps a little confusing.) If two | 70 | would be more efficient, but perhaps a little confusing.) If two |
71 | codes exist, they are coded using one bit each (0 and 1). | 71 | codes exist, they are coded using one bit each (0 and 1). |
72 | 5. There is no way of sending zero distance codes--a dummy must be | 72 | 5. There is no way of sending zero distance codes--a dummy must be |
73 | sent if there are none. (History: a pre 2.0 version of PKZIP would | 73 | sent if there are none. (History: a pre 2.0 version of PKZIP would |
74 | store blocks with no distance codes, but this was discovered to be | 74 | store blocks with no distance codes, but this was discovered to be |
75 | too harsh a criterion.) Valid only for 1.93a. 2.04c does allow | 75 | too harsh a criterion.) Valid only for 1.93a. 2.04c does allow |
76 | zero distance codes, which is sent as one code of zero bits in | 76 | zero distance codes, which is sent as one code of zero bits in |
77 | length. | 77 | length. |
78 | 6. There are up to 286 literal/length codes. Code 256 represents the | 78 | 6. There are up to 286 literal/length codes. Code 256 represents the |
79 | end-of-block. Note however that the static length tree defines | 79 | end-of-block. Note however that the static length tree defines |
80 | 288 codes just to fill out the Huffman codes. Codes 286 and 287 | 80 | 288 codes just to fill out the Huffman codes. Codes 286 and 287 |
81 | cannot be used though, since there is no length base or extra bits | 81 | cannot be used though, since there is no length base or extra bits |
82 | defined for them. Similarly, there are up to 30 distance codes. | 82 | defined for them. Similarly, there are up to 30 distance codes. |
83 | However, static trees define 32 codes (all 5 bits) to fill out the | 83 | However, static trees define 32 codes (all 5 bits) to fill out the |
84 | Huffman codes, but the last two had better not show up in the data. | 84 | Huffman codes, but the last two had better not show up in the data. |
85 | 7. Unzip can check dynamic Huffman blocks for complete code sets. | 85 | 7. Unzip can check dynamic Huffman blocks for complete code sets. |
86 | The exception is that a single code would not be complete (see #4). | 86 | The exception is that a single code would not be complete (see #4). |
87 | 8. The five bits following the block type is really the number of | 87 | 8. The five bits following the block type is really the number of |
88 | literal codes sent minus 257. | 88 | literal codes sent minus 257. |
89 | 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits | 89 | 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits |
90 | (1+6+6). Therefore, to output three times the length, you output | 90 | (1+6+6). Therefore, to output three times the length, you output |
91 | three codes (1+1+1), whereas to output four times the same length, | 91 | three codes (1+1+1), whereas to output four times the same length, |
92 | you only need two codes (1+3). Hmm. | 92 | you only need two codes (1+3). Hmm. |
93 | 10. In the tree reconstruction algorithm, Code = Code + Increment | 93 | 10. In the tree reconstruction algorithm, Code = Code + Increment |
94 | only if BitLength(i) is not zero. (Pretty obvious.) | 94 | only if BitLength(i) is not zero. (Pretty obvious.) |
95 | 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) | 95 | 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) |
96 | 12. Note: length code 284 can represent 227-258, but length code 285 | 96 | 12. Note: length code 284 can represent 227-258, but length code 285 |
97 | really is 258. The last length deserves its own, short code | 97 | really is 258. The last length deserves its own, short code |
98 | since it gets used a lot in very redundant files. The length | 98 | since it gets used a lot in very redundant files. The length |
99 | 258 is special since 258 - 3 (the min match length) is 255. | 99 | 258 is special since 258 - 3 (the min match length) is 255. |
100 | 13. The literal/length and distance code bit lengths are read as a | 100 | 13. The literal/length and distance code bit lengths are read as a |
101 | single stream of lengths. It is possible (and advantageous) for | 101 | single stream of lengths. It is possible (and advantageous) for |
102 | a repeat code (16, 17, or 18) to go across the boundary between | 102 | a repeat code (16, 17, or 18) to go across the boundary between |
103 | the two sets of lengths. | 103 | the two sets of lengths. |
104 | */ | 104 | */ |
105 | #include <linux/compiler.h> | 105 | #include <linux/compiler.h> |
106 | 106 | ||
107 | #ifdef RCSID | 107 | #ifdef RCSID |
108 | static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #"; | 108 | static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #"; |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #ifndef STATIC | 111 | #ifndef STATIC |
112 | 112 | ||
113 | #if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) | 113 | #if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) |
114 | # include <sys/types.h> | 114 | # include <sys/types.h> |
115 | # include <stdlib.h> | 115 | # include <stdlib.h> |
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | #include "gzip.h" | 118 | #include "gzip.h" |
119 | #define STATIC | 119 | #define STATIC |
120 | #endif /* !STATIC */ | 120 | #endif /* !STATIC */ |
121 | 121 | ||
122 | #ifndef INIT | 122 | #ifndef INIT |
123 | #define INIT | 123 | #define INIT |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | #define slide window | 126 | #define slide window |
127 | 127 | ||
128 | /* Huffman code lookup table entry--this entry is four bytes for machines | 128 | /* Huffman code lookup table entry--this entry is four bytes for machines |
129 | that have 16-bit pointers (e.g. PC's in the small or medium model). | 129 | that have 16-bit pointers (e.g. PC's in the small or medium model). |
130 | Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 | 130 | Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 |
131 | means that v is a literal, 16 < e < 32 means that v is a pointer to | 131 | means that v is a literal, 16 < e < 32 means that v is a pointer to |
132 | the next table, which codes e - 16 bits, and lastly e == 99 indicates | 132 | the next table, which codes e - 16 bits, and lastly e == 99 indicates |
133 | an unused code. If a code with e == 99 is looked up, this implies an | 133 | an unused code. If a code with e == 99 is looked up, this implies an |
134 | error in the data. */ | 134 | error in the data. */ |
135 | struct huft { | 135 | struct huft { |
136 | uch e; /* number of extra bits or operation */ | 136 | uch e; /* number of extra bits or operation */ |
137 | uch b; /* number of bits in this code or subcode */ | 137 | uch b; /* number of bits in this code or subcode */ |
138 | union { | 138 | union { |
139 | ush n; /* literal, length base, or distance base */ | 139 | ush n; /* literal, length base, or distance base */ |
140 | struct huft *t; /* pointer to next level of table */ | 140 | struct huft *t; /* pointer to next level of table */ |
141 | } v; | 141 | } v; |
142 | }; | 142 | }; |
143 | 143 | ||
144 | 144 | ||
145 | /* Function prototypes */ | 145 | /* Function prototypes */ |
146 | STATIC int INIT huft_build OF((unsigned *, unsigned, unsigned, | 146 | STATIC int INIT huft_build OF((unsigned *, unsigned, unsigned, |
147 | const ush *, const ush *, struct huft **, int *)); | 147 | const ush *, const ush *, struct huft **, int *)); |
148 | STATIC int INIT huft_free OF((struct huft *)); | 148 | STATIC int INIT huft_free OF((struct huft *)); |
149 | STATIC int INIT inflate_codes OF((struct huft *, struct huft *, int, int)); | 149 | STATIC int INIT inflate_codes OF((struct huft *, struct huft *, int, int)); |
150 | STATIC int INIT inflate_stored OF((void)); | 150 | STATIC int INIT inflate_stored OF((void)); |
151 | STATIC int INIT inflate_fixed OF((void)); | 151 | STATIC int INIT inflate_fixed OF((void)); |
152 | STATIC int INIT inflate_dynamic OF((void)); | 152 | STATIC int INIT inflate_dynamic OF((void)); |
153 | STATIC int INIT inflate_block OF((int *)); | 153 | STATIC int INIT inflate_block OF((int *)); |
154 | STATIC int INIT inflate OF((void)); | 154 | STATIC int INIT inflate OF((void)); |
155 | 155 | ||
156 | 156 | ||
157 | /* The inflate algorithm uses a sliding 32 K byte window on the uncompressed | 157 | /* The inflate algorithm uses a sliding 32 K byte window on the uncompressed |
158 | stream to find repeated byte strings. This is implemented here as a | 158 | stream to find repeated byte strings. This is implemented here as a |
159 | circular buffer. The index is updated simply by incrementing and then | 159 | circular buffer. The index is updated simply by incrementing and then |
160 | ANDing with 0x7fff (32K-1). */ | 160 | ANDing with 0x7fff (32K-1). */ |
161 | /* It is left to other modules to supply the 32 K area. It is assumed | 161 | /* It is left to other modules to supply the 32 K area. It is assumed |
162 | to be usable as if it were declared "uch slide[32768];" or as just | 162 | to be usable as if it were declared "uch slide[32768];" or as just |
163 | "uch *slide;" and then malloc'ed in the latter case. The definition | 163 | "uch *slide;" and then malloc'ed in the latter case. The definition |
164 | must be in unzip.h, included above. */ | 164 | must be in unzip.h, included above. */ |
165 | /* unsigned wp; current position in slide */ | 165 | /* unsigned wp; current position in slide */ |
166 | #define wp outcnt | 166 | #define wp outcnt |
167 | #define flush_output(w) (wp=(w),flush_window()) | 167 | #define flush_output(w) (wp=(w),flush_window()) |
168 | 168 | ||
169 | /* Tables for deflate from PKZIP's appnote.txt. */ | 169 | /* Tables for deflate from PKZIP's appnote.txt. */ |
170 | static const unsigned border[] = { /* Order of the bit length code lengths */ | 170 | static const unsigned border[] = { /* Order of the bit length code lengths */ |
171 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | 171 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; |
172 | static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ | 172 | static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ |
173 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | 173 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, |
174 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; | 174 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; |
175 | /* note: see note #13 above about the 258 in this list. */ | 175 | /* note: see note #13 above about the 258 in this list. */ |
176 | static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ | 176 | static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ |
177 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | 177 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, |
178 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ | 178 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ |
179 | static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ | 179 | static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ |
180 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | 180 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
181 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | 181 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, |
182 | 8193, 12289, 16385, 24577}; | 182 | 8193, 12289, 16385, 24577}; |
183 | static const ush cpdext[] = { /* Extra bits for distance codes */ | 183 | static const ush cpdext[] = { /* Extra bits for distance codes */ |
184 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | 184 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, |
185 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | 185 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, |
186 | 12, 12, 13, 13}; | 186 | 12, 12, 13, 13}; |
187 | 187 | ||
188 | 188 | ||
189 | 189 | ||
190 | /* Macros for inflate() bit peeking and grabbing. | 190 | /* Macros for inflate() bit peeking and grabbing. |
191 | The usage is: | 191 | The usage is: |
192 | 192 | ||
193 | NEEDBITS(j) | 193 | NEEDBITS(j) |
194 | x = b & mask_bits[j]; | 194 | x = b & mask_bits[j]; |
195 | DUMPBITS(j) | 195 | DUMPBITS(j) |
196 | 196 | ||
197 | where NEEDBITS makes sure that b has at least j bits in it, and | 197 | where NEEDBITS makes sure that b has at least j bits in it, and |
198 | DUMPBITS removes the bits from b. The macros use the variable k | 198 | DUMPBITS removes the bits from b. The macros use the variable k |
199 | for the number of bits in b. Normally, b and k are register | 199 | for the number of bits in b. Normally, b and k are register |
200 | variables for speed, and are initialized at the beginning of a | 200 | variables for speed, and are initialized at the beginning of a |
201 | routine that uses these macros from a global bit buffer and count. | 201 | routine that uses these macros from a global bit buffer and count. |
202 | 202 | ||
203 | If we assume that EOB will be the longest code, then we will never | 203 | If we assume that EOB will be the longest code, then we will never |
204 | ask for bits with NEEDBITS that are beyond the end of the stream. | 204 | ask for bits with NEEDBITS that are beyond the end of the stream. |
205 | So, NEEDBITS should not read any more bytes than are needed to | 205 | So, NEEDBITS should not read any more bytes than are needed to |
206 | meet the request. Then no bytes need to be "returned" to the buffer | 206 | meet the request. Then no bytes need to be "returned" to the buffer |
207 | at the end of the last block. | 207 | at the end of the last block. |
208 | 208 | ||
209 | However, this assumption is not true for fixed blocks--the EOB code | 209 | However, this assumption is not true for fixed blocks--the EOB code |
210 | is 7 bits, but the other literal/length codes can be 8 or 9 bits. | 210 | is 7 bits, but the other literal/length codes can be 8 or 9 bits. |
211 | (The EOB code is shorter than other codes because fixed blocks are | 211 | (The EOB code is shorter than other codes because fixed blocks are |
212 | generally short. So, while a block always has an EOB, many other | 212 | generally short. So, while a block always has an EOB, many other |
213 | literal/length codes have a significantly lower probability of | 213 | literal/length codes have a significantly lower probability of |
214 | showing up at all.) However, by making the first table have a | 214 | showing up at all.) However, by making the first table have a |
215 | lookup of seven bits, the EOB code will be found in that first | 215 | lookup of seven bits, the EOB code will be found in that first |
216 | lookup, and so will not require that too many bits be pulled from | 216 | lookup, and so will not require that too many bits be pulled from |
217 | the stream. | 217 | the stream. |
218 | */ | 218 | */ |
219 | 219 | ||
220 | STATIC ulg bb; /* bit buffer */ | 220 | STATIC ulg bb; /* bit buffer */ |
221 | STATIC unsigned bk; /* bits in bit buffer */ | 221 | STATIC unsigned bk; /* bits in bit buffer */ |
222 | 222 | ||
223 | STATIC const ush mask_bits[] = { | 223 | STATIC const ush mask_bits[] = { |
224 | 0x0000, | 224 | 0x0000, |
225 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | 225 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, |
226 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | 226 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff |
227 | }; | 227 | }; |
228 | 228 | ||
229 | #define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; }) | 229 | #define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; }) |
230 | #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} | 230 | #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} |
231 | #define DUMPBITS(n) {b>>=(n);k-=(n);} | 231 | #define DUMPBITS(n) {b>>=(n);k-=(n);} |
232 | 232 | ||
233 | #ifndef NO_INFLATE_MALLOC | 233 | #ifndef NO_INFLATE_MALLOC |
234 | /* A trivial malloc implementation, adapted from | 234 | /* A trivial malloc implementation, adapted from |
235 | * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 | 235 | * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 |
236 | */ | 236 | */ |
237 | 237 | ||
238 | static unsigned long malloc_ptr; | 238 | static unsigned long malloc_ptr; |
239 | static int malloc_count; | 239 | static int malloc_count; |
240 | 240 | ||
241 | static void *malloc(int size) | 241 | static void *malloc(int size) |
242 | { | 242 | { |
243 | void *p; | 243 | void *p; |
244 | 244 | ||
245 | if (size < 0) | 245 | if (size < 0) |
246 | error("Malloc error"); | 246 | error("Malloc error"); |
247 | if (!malloc_ptr) | 247 | if (!malloc_ptr) |
248 | malloc_ptr = free_mem_ptr; | 248 | malloc_ptr = free_mem_ptr; |
249 | 249 | ||
250 | malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ | 250 | malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ |
251 | 251 | ||
252 | p = (void *)malloc_ptr; | 252 | p = (void *)malloc_ptr; |
253 | malloc_ptr += size; | 253 | malloc_ptr += size; |
254 | 254 | ||
255 | if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) | 255 | if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) |
256 | error("Out of memory"); | 256 | error("Out of memory"); |
257 | 257 | ||
258 | malloc_count++; | 258 | malloc_count++; |
259 | return p; | 259 | return p; |
260 | } | 260 | } |
261 | 261 | ||
262 | static void free(void *where) | 262 | static void free(void *where) |
263 | { | 263 | { |
264 | malloc_count--; | 264 | malloc_count--; |
265 | if (!malloc_count) | 265 | if (!malloc_count) |
266 | malloc_ptr = free_mem_ptr; | 266 | malloc_ptr = free_mem_ptr; |
267 | } | 267 | } |
268 | #else | 268 | #else |
269 | #define malloc(a) kmalloc(a, GFP_KERNEL) | 269 | #define malloc(a) kmalloc(a, GFP_KERNEL) |
270 | #define free(a) kfree(a) | 270 | #define free(a) kfree(a) |
271 | #endif | 271 | #endif |
272 | 272 | ||
273 | /* | 273 | /* |
274 | Huffman code decoding is performed using a multi-level table lookup. | 274 | Huffman code decoding is performed using a multi-level table lookup. |
275 | The fastest way to decode is to simply build a lookup table whose | 275 | The fastest way to decode is to simply build a lookup table whose |
276 | size is determined by the longest code. However, the time it takes | 276 | size is determined by the longest code. However, the time it takes |
277 | to build this table can also be a factor if the data being decoded | 277 | to build this table can also be a factor if the data being decoded |
278 | is not very long. The most common codes are necessarily the | 278 | is not very long. The most common codes are necessarily the |
279 | shortest codes, so those codes dominate the decoding time, and hence | 279 | shortest codes, so those codes dominate the decoding time, and hence |
280 | the speed. The idea is you can have a shorter table that decodes the | 280 | the speed. The idea is you can have a shorter table that decodes the |
281 | shorter, more probable codes, and then point to subsidiary tables for | 281 | shorter, more probable codes, and then point to subsidiary tables for |
282 | the longer codes. The time it costs to decode the longer codes is | 282 | the longer codes. The time it costs to decode the longer codes is |
283 | then traded against the time it takes to make longer tables. | 283 | then traded against the time it takes to make longer tables. |
284 | 284 | ||
285 | This results of this trade are in the variables lbits and dbits | 285 | This results of this trade are in the variables lbits and dbits |
286 | below. lbits is the number of bits the first level table for literal/ | 286 | below. lbits is the number of bits the first level table for literal/ |
287 | length codes can decode in one step, and dbits is the same thing for | 287 | length codes can decode in one step, and dbits is the same thing for |
288 | the distance codes. Subsequent tables are also less than or equal to | 288 | the distance codes. Subsequent tables are also less than or equal to |
289 | those sizes. These values may be adjusted either when all of the | 289 | those sizes. These values may be adjusted either when all of the |
290 | codes are shorter than that, in which case the longest code length in | 290 | codes are shorter than that, in which case the longest code length in |
291 | bits is used, or when the shortest code is *longer* than the requested | 291 | bits is used, or when the shortest code is *longer* than the requested |
292 | table size, in which case the length of the shortest code in bits is | 292 | table size, in which case the length of the shortest code in bits is |
293 | used. | 293 | used. |
294 | 294 | ||
295 | There are two different values for the two tables, since they code a | 295 | There are two different values for the two tables, since they code a |
296 | different number of possibilities each. The literal/length table | 296 | different number of possibilities each. The literal/length table |
297 | codes 286 possible values, or in a flat code, a little over eight | 297 | codes 286 possible values, or in a flat code, a little over eight |
298 | bits. The distance table codes 30 possible values, or a little less | 298 | bits. The distance table codes 30 possible values, or a little less |
299 | than five bits, flat. The optimum values for speed end up being | 299 | than five bits, flat. The optimum values for speed end up being |
300 | about one bit more than those, so lbits is 8+1 and dbits is 5+1. | 300 | about one bit more than those, so lbits is 8+1 and dbits is 5+1. |
301 | The optimum values may differ though from machine to machine, and | 301 | The optimum values may differ though from machine to machine, and |
302 | possibly even between compilers. Your mileage may vary. | 302 | possibly even between compilers. Your mileage may vary. |
303 | */ | 303 | */ |
304 | 304 | ||
305 | 305 | ||
306 | STATIC const int lbits = 9; /* bits in base literal/length lookup table */ | 306 | STATIC const int lbits = 9; /* bits in base literal/length lookup table */ |
307 | STATIC const int dbits = 6; /* bits in base distance lookup table */ | 307 | STATIC const int dbits = 6; /* bits in base distance lookup table */ |
308 | 308 | ||
309 | 309 | ||
310 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ | 310 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ |
311 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ | 311 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ |
312 | #define N_MAX 288 /* maximum number of codes in any set */ | 312 | #define N_MAX 288 /* maximum number of codes in any set */ |
313 | 313 | ||
314 | 314 | ||
315 | STATIC unsigned hufts; /* track memory usage */ | 315 | STATIC unsigned hufts; /* track memory usage */ |
316 | 316 | ||
317 | 317 | ||
318 | STATIC int INIT huft_build( | 318 | STATIC int INIT huft_build( |
319 | unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ | 319 | unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ |
320 | unsigned n, /* number of codes (assumed <= N_MAX) */ | 320 | unsigned n, /* number of codes (assumed <= N_MAX) */ |
321 | unsigned s, /* number of simple-valued codes (0..s-1) */ | 321 | unsigned s, /* number of simple-valued codes (0..s-1) */ |
322 | const ush *d, /* list of base values for non-simple codes */ | 322 | const ush *d, /* list of base values for non-simple codes */ |
323 | const ush *e, /* list of extra bits for non-simple codes */ | 323 | const ush *e, /* list of extra bits for non-simple codes */ |
324 | struct huft **t, /* result: starting table */ | 324 | struct huft **t, /* result: starting table */ |
325 | int *m /* maximum lookup bits, returns actual */ | 325 | int *m /* maximum lookup bits, returns actual */ |
326 | ) | 326 | ) |
327 | /* Given a list of code lengths and a maximum table size, make a set of | 327 | /* Given a list of code lengths and a maximum table size, make a set of |
328 | tables to decode that set of codes. Return zero on success, one if | 328 | tables to decode that set of codes. Return zero on success, one if |
329 | the given code set is incomplete (the tables are still built in this | 329 | the given code set is incomplete (the tables are still built in this |
330 | case), two if the input is invalid (all zero length codes or an | 330 | case), two if the input is invalid (all zero length codes or an |
331 | oversubscribed set of lengths), and three if not enough memory. */ | 331 | oversubscribed set of lengths), and three if not enough memory. */ |
332 | { | 332 | { |
333 | unsigned a; /* counter for codes of length k */ | 333 | unsigned a; /* counter for codes of length k */ |
334 | unsigned f; /* i repeats in table every f entries */ | 334 | unsigned f; /* i repeats in table every f entries */ |
335 | int g; /* maximum code length */ | 335 | int g; /* maximum code length */ |
336 | int h; /* table level */ | 336 | int h; /* table level */ |
337 | register unsigned i; /* counter, current code */ | 337 | register unsigned i; /* counter, current code */ |
338 | register unsigned j; /* counter */ | 338 | register unsigned j; /* counter */ |
339 | register int k; /* number of bits in current code */ | 339 | register int k; /* number of bits in current code */ |
340 | int l; /* bits per table (returned in m) */ | 340 | int l; /* bits per table (returned in m) */ |
341 | register unsigned *p; /* pointer into c[], b[], or v[] */ | 341 | register unsigned *p; /* pointer into c[], b[], or v[] */ |
342 | register struct huft *q; /* points to current table */ | 342 | register struct huft *q; /* points to current table */ |
343 | struct huft r; /* table entry for structure assignment */ | 343 | struct huft r; /* table entry for structure assignment */ |
344 | register int w; /* bits before this table == (l * h) */ | 344 | register int w; /* bits before this table == (l * h) */ |
345 | unsigned *xp; /* pointer into x */ | 345 | unsigned *xp; /* pointer into x */ |
346 | int y; /* number of dummy codes added */ | 346 | int y; /* number of dummy codes added */ |
347 | unsigned z; /* number of entries in current table */ | 347 | unsigned z; /* number of entries in current table */ |
348 | struct { | 348 | struct { |
349 | unsigned c[BMAX+1]; /* bit length count table */ | 349 | unsigned c[BMAX+1]; /* bit length count table */ |
350 | struct huft *u[BMAX]; /* table stack */ | 350 | struct huft *u[BMAX]; /* table stack */ |
351 | unsigned v[N_MAX]; /* values in order of bit length */ | 351 | unsigned v[N_MAX]; /* values in order of bit length */ |
352 | unsigned x[BMAX+1]; /* bit offsets, then code stack */ | 352 | unsigned x[BMAX+1]; /* bit offsets, then code stack */ |
353 | } *stk; | 353 | } *stk; |
354 | unsigned *c, *v, *x; | 354 | unsigned *c, *v, *x; |
355 | struct huft **u; | 355 | struct huft **u; |
356 | int ret; | 356 | int ret; |
357 | 357 | ||
358 | DEBG("huft1 "); | 358 | DEBG("huft1 "); |
359 | 359 | ||
360 | stk = malloc(sizeof(*stk)); | 360 | stk = malloc(sizeof(*stk)); |
361 | if (stk == NULL) | 361 | if (stk == NULL) |
362 | return 3; /* out of memory */ | 362 | return 3; /* out of memory */ |
363 | 363 | ||
364 | c = stk->c; | 364 | c = stk->c; |
365 | v = stk->v; | 365 | v = stk->v; |
366 | x = stk->x; | 366 | x = stk->x; |
367 | u = stk->u; | 367 | u = stk->u; |
368 | 368 | ||
369 | /* Generate counts for each bit length */ | 369 | /* Generate counts for each bit length */ |
370 | memzero(stk->c, sizeof(stk->c)); | 370 | memzero(stk->c, sizeof(stk->c)); |
371 | p = b; i = n; | 371 | p = b; i = n; |
372 | do { | 372 | do { |
373 | Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), | 373 | Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), |
374 | n-i, *p)); | 374 | n-i, *p)); |
375 | c[*p]++; /* assume all entries <= BMAX */ | 375 | c[*p]++; /* assume all entries <= BMAX */ |
376 | p++; /* Can't combine with above line (Solaris bug) */ | 376 | p++; /* Can't combine with above line (Solaris bug) */ |
377 | } while (--i); | 377 | } while (--i); |
378 | if (c[0] == n) /* null input--all zero length codes */ | 378 | if (c[0] == n) /* null input--all zero length codes */ |
379 | { | 379 | { |
380 | *t = (struct huft *)NULL; | 380 | *t = (struct huft *)NULL; |
381 | *m = 0; | 381 | *m = 0; |
382 | ret = 2; | 382 | ret = 2; |
383 | goto out; | 383 | goto out; |
384 | } | 384 | } |
385 | 385 | ||
386 | DEBG("huft2 "); | 386 | DEBG("huft2 "); |
387 | 387 | ||
388 | /* Find minimum and maximum length, bound *m by those */ | 388 | /* Find minimum and maximum length, bound *m by those */ |
389 | l = *m; | 389 | l = *m; |
390 | for (j = 1; j <= BMAX; j++) | 390 | for (j = 1; j <= BMAX; j++) |
391 | if (c[j]) | 391 | if (c[j]) |
392 | break; | 392 | break; |
393 | k = j; /* minimum code length */ | 393 | k = j; /* minimum code length */ |
394 | if ((unsigned)l < j) | 394 | if ((unsigned)l < j) |
395 | l = j; | 395 | l = j; |
396 | for (i = BMAX; i; i--) | 396 | for (i = BMAX; i; i--) |
397 | if (c[i]) | 397 | if (c[i]) |
398 | break; | 398 | break; |
399 | g = i; /* maximum code length */ | 399 | g = i; /* maximum code length */ |
400 | if ((unsigned)l > i) | 400 | if ((unsigned)l > i) |
401 | l = i; | 401 | l = i; |
402 | *m = l; | 402 | *m = l; |
403 | 403 | ||
404 | DEBG("huft3 "); | 404 | DEBG("huft3 "); |
405 | 405 | ||
406 | /* Adjust last length count to fill out codes, if needed */ | 406 | /* Adjust last length count to fill out codes, if needed */ |
407 | for (y = 1 << j; j < i; j++, y <<= 1) | 407 | for (y = 1 << j; j < i; j++, y <<= 1) |
408 | if ((y -= c[j]) < 0) { | 408 | if ((y -= c[j]) < 0) { |
409 | ret = 2; /* bad input: more codes than bits */ | 409 | ret = 2; /* bad input: more codes than bits */ |
410 | goto out; | 410 | goto out; |
411 | } | 411 | } |
412 | if ((y -= c[i]) < 0) { | 412 | if ((y -= c[i]) < 0) { |
413 | ret = 2; | 413 | ret = 2; |
414 | goto out; | 414 | goto out; |
415 | } | 415 | } |
416 | c[i] += y; | 416 | c[i] += y; |
417 | 417 | ||
418 | DEBG("huft4 "); | 418 | DEBG("huft4 "); |
419 | 419 | ||
420 | /* Generate starting offsets into the value table for each length */ | 420 | /* Generate starting offsets into the value table for each length */ |
421 | x[1] = j = 0; | 421 | x[1] = j = 0; |
422 | p = c + 1; xp = x + 2; | 422 | p = c + 1; xp = x + 2; |
423 | while (--i) { /* note that i == g from above */ | 423 | while (--i) { /* note that i == g from above */ |
424 | *xp++ = (j += *p++); | 424 | *xp++ = (j += *p++); |
425 | } | 425 | } |
426 | 426 | ||
427 | DEBG("huft5 "); | 427 | DEBG("huft5 "); |
428 | 428 | ||
429 | /* Make a table of values in order of bit lengths */ | 429 | /* Make a table of values in order of bit lengths */ |
430 | p = b; i = 0; | 430 | p = b; i = 0; |
431 | do { | 431 | do { |
432 | if ((j = *p++) != 0) | 432 | if ((j = *p++) != 0) |
433 | v[x[j]++] = i; | 433 | v[x[j]++] = i; |
434 | } while (++i < n); | 434 | } while (++i < n); |
435 | n = x[g]; /* set n to length of v */ | 435 | n = x[g]; /* set n to length of v */ |
436 | 436 | ||
437 | DEBG("h6 "); | 437 | DEBG("h6 "); |
438 | 438 | ||
439 | /* Generate the Huffman codes and for each, make the table entries */ | 439 | /* Generate the Huffman codes and for each, make the table entries */ |
440 | x[0] = i = 0; /* first Huffman code is zero */ | 440 | x[0] = i = 0; /* first Huffman code is zero */ |
441 | p = v; /* grab values in bit order */ | 441 | p = v; /* grab values in bit order */ |
442 | h = -1; /* no tables yet--level -1 */ | 442 | h = -1; /* no tables yet--level -1 */ |
443 | w = -l; /* bits decoded == (l * h) */ | 443 | w = -l; /* bits decoded == (l * h) */ |
444 | u[0] = (struct huft *)NULL; /* just to keep compilers happy */ | 444 | u[0] = (struct huft *)NULL; /* just to keep compilers happy */ |
445 | q = (struct huft *)NULL; /* ditto */ | 445 | q = (struct huft *)NULL; /* ditto */ |
446 | z = 0; /* ditto */ | 446 | z = 0; /* ditto */ |
447 | DEBG("h6a "); | 447 | DEBG("h6a "); |
448 | 448 | ||
449 | /* go through the bit lengths (k already is bits in shortest code) */ | 449 | /* go through the bit lengths (k already is bits in shortest code) */ |
450 | for (; k <= g; k++) | 450 | for (; k <= g; k++) |
451 | { | 451 | { |
452 | DEBG("h6b "); | 452 | DEBG("h6b "); |
453 | a = c[k]; | 453 | a = c[k]; |
454 | while (a--) | 454 | while (a--) |
455 | { | 455 | { |
456 | DEBG("h6b1 "); | 456 | DEBG("h6b1 "); |
457 | /* here i is the Huffman code of length k bits for value *p */ | 457 | /* here i is the Huffman code of length k bits for value *p */ |
458 | /* make tables up to required level */ | 458 | /* make tables up to required level */ |
459 | while (k > w + l) | 459 | while (k > w + l) |
460 | { | 460 | { |
461 | DEBG1("1 "); | 461 | DEBG1("1 "); |
462 | h++; | 462 | h++; |
463 | w += l; /* previous table always l bits */ | 463 | w += l; /* previous table always l bits */ |
464 | 464 | ||
465 | /* compute minimum size table less than or equal to l bits */ | 465 | /* compute minimum size table less than or equal to l bits */ |
466 | z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ | 466 | z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ |
467 | if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ | 467 | if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ |
468 | { /* too few codes for k-w bit table */ | 468 | { /* too few codes for k-w bit table */ |
469 | DEBG1("2 "); | 469 | DEBG1("2 "); |
470 | f -= a + 1; /* deduct codes from patterns left */ | 470 | f -= a + 1; /* deduct codes from patterns left */ |
471 | xp = c + k; | 471 | xp = c + k; |
472 | if (j < z) | 472 | if (j < z) |
473 | while (++j < z) /* try smaller tables up to z bits */ | 473 | while (++j < z) /* try smaller tables up to z bits */ |
474 | { | 474 | { |
475 | if ((f <<= 1) <= *++xp) | 475 | if ((f <<= 1) <= *++xp) |
476 | break; /* enough codes to use up j bits */ | 476 | break; /* enough codes to use up j bits */ |
477 | f -= *xp; /* else deduct codes from patterns */ | 477 | f -= *xp; /* else deduct codes from patterns */ |
478 | } | 478 | } |
479 | } | 479 | } |
480 | DEBG1("3 "); | 480 | DEBG1("3 "); |
481 | z = 1 << j; /* table entries for j-bit table */ | 481 | z = 1 << j; /* table entries for j-bit table */ |
482 | 482 | ||
483 | /* allocate and link in new table */ | 483 | /* allocate and link in new table */ |
484 | if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == | 484 | if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == |
485 | (struct huft *)NULL) | 485 | (struct huft *)NULL) |
486 | { | 486 | { |
487 | if (h) | 487 | if (h) |
488 | huft_free(u[0]); | 488 | huft_free(u[0]); |
489 | ret = 3; /* not enough memory */ | 489 | ret = 3; /* not enough memory */ |
490 | goto out; | 490 | goto out; |
491 | } | 491 | } |
492 | DEBG1("4 "); | 492 | DEBG1("4 "); |
493 | hufts += z + 1; /* track memory usage */ | 493 | hufts += z + 1; /* track memory usage */ |
494 | *t = q + 1; /* link to list for huft_free() */ | 494 | *t = q + 1; /* link to list for huft_free() */ |
495 | *(t = &(q->v.t)) = (struct huft *)NULL; | 495 | *(t = &(q->v.t)) = (struct huft *)NULL; |
496 | u[h] = ++q; /* table starts after link */ | 496 | u[h] = ++q; /* table starts after link */ |
497 | 497 | ||
498 | DEBG1("5 "); | 498 | DEBG1("5 "); |
499 | /* connect to last table, if there is one */ | 499 | /* connect to last table, if there is one */ |
500 | if (h) | 500 | if (h) |
501 | { | 501 | { |
502 | x[h] = i; /* save pattern for backing up */ | 502 | x[h] = i; /* save pattern for backing up */ |
503 | r.b = (uch)l; /* bits to dump before this table */ | 503 | r.b = (uch)l; /* bits to dump before this table */ |
504 | r.e = (uch)(16 + j); /* bits in this table */ | 504 | r.e = (uch)(16 + j); /* bits in this table */ |
505 | r.v.t = q; /* pointer to this table */ | 505 | r.v.t = q; /* pointer to this table */ |
506 | j = i >> (w - l); /* (get around Turbo C bug) */ | 506 | j = i >> (w - l); /* (get around Turbo C bug) */ |
507 | u[h-1][j] = r; /* connect to last table */ | 507 | u[h-1][j] = r; /* connect to last table */ |
508 | } | 508 | } |
509 | DEBG1("6 "); | 509 | DEBG1("6 "); |
510 | } | 510 | } |
511 | DEBG("h6c "); | 511 | DEBG("h6c "); |
512 | 512 | ||
513 | /* set up table entry in r */ | 513 | /* set up table entry in r */ |
514 | r.b = (uch)(k - w); | 514 | r.b = (uch)(k - w); |
515 | if (p >= v + n) | 515 | if (p >= v + n) |
516 | r.e = 99; /* out of values--invalid code */ | 516 | r.e = 99; /* out of values--invalid code */ |
517 | else if (*p < s) | 517 | else if (*p < s) |
518 | { | 518 | { |
519 | r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ | 519 | r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ |
520 | r.v.n = (ush)(*p); /* simple code is just the value */ | 520 | r.v.n = (ush)(*p); /* simple code is just the value */ |
521 | p++; /* one compiler does not like *p++ */ | 521 | p++; /* one compiler does not like *p++ */ |
522 | } | 522 | } |
523 | else | 523 | else |
524 | { | 524 | { |
525 | r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ | 525 | r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ |
526 | r.v.n = d[*p++ - s]; | 526 | r.v.n = d[*p++ - s]; |
527 | } | 527 | } |
528 | DEBG("h6d "); | 528 | DEBG("h6d "); |
529 | 529 | ||
530 | /* fill code-like entries with r */ | 530 | /* fill code-like entries with r */ |
531 | f = 1 << (k - w); | 531 | f = 1 << (k - w); |
532 | for (j = i >> w; j < z; j += f) | 532 | for (j = i >> w; j < z; j += f) |
533 | q[j] = r; | 533 | q[j] = r; |
534 | 534 | ||
535 | /* backwards increment the k-bit code i */ | 535 | /* backwards increment the k-bit code i */ |
536 | for (j = 1 << (k - 1); i & j; j >>= 1) | 536 | for (j = 1 << (k - 1); i & j; j >>= 1) |
537 | i ^= j; | 537 | i ^= j; |
538 | i ^= j; | 538 | i ^= j; |
539 | 539 | ||
540 | /* backup over finished tables */ | 540 | /* backup over finished tables */ |
541 | while ((i & ((1 << w) - 1)) != x[h]) | 541 | while ((i & ((1 << w) - 1)) != x[h]) |
542 | { | 542 | { |
543 | h--; /* don't need to update q */ | 543 | h--; /* don't need to update q */ |
544 | w -= l; | 544 | w -= l; |
545 | } | 545 | } |
546 | DEBG("h6e "); | 546 | DEBG("h6e "); |
547 | } | 547 | } |
548 | DEBG("h6f "); | 548 | DEBG("h6f "); |
549 | } | 549 | } |
550 | 550 | ||
551 | DEBG("huft7 "); | 551 | DEBG("huft7 "); |
552 | 552 | ||
553 | /* Return true (1) if we were given an incomplete table */ | 553 | /* Return true (1) if we were given an incomplete table */ |
554 | ret = y != 0 && g != 1; | 554 | ret = y != 0 && g != 1; |
555 | 555 | ||
556 | out: | 556 | out: |
557 | free(stk); | 557 | free(stk); |
558 | return ret; | 558 | return ret; |
559 | } | 559 | } |
560 | 560 | ||
561 | 561 | ||
562 | 562 | ||
563 | STATIC int INIT huft_free( | 563 | STATIC int INIT huft_free( |
564 | struct huft *t /* table to free */ | 564 | struct huft *t /* table to free */ |
565 | ) | 565 | ) |
566 | /* Free the malloc'ed tables built by huft_build(), which makes a linked | 566 | /* Free the malloc'ed tables built by huft_build(), which makes a linked |
567 | list of the tables it made, with the links in a dummy first entry of | 567 | list of the tables it made, with the links in a dummy first entry of |
568 | each table. */ | 568 | each table. */ |
569 | { | 569 | { |
570 | register struct huft *p, *q; | 570 | register struct huft *p, *q; |
571 | 571 | ||
572 | 572 | ||
573 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ | 573 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ |
574 | p = t; | 574 | p = t; |
575 | while (p != (struct huft *)NULL) | 575 | while (p != (struct huft *)NULL) |
576 | { | 576 | { |
577 | q = (--p)->v.t; | 577 | q = (--p)->v.t; |
578 | free((char*)p); | 578 | free((char*)p); |
579 | p = q; | 579 | p = q; |
580 | } | 580 | } |
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | 584 | ||
585 | STATIC int INIT inflate_codes( | 585 | STATIC int INIT inflate_codes( |
586 | struct huft *tl, /* literal/length decoder tables */ | 586 | struct huft *tl, /* literal/length decoder tables */ |
587 | struct huft *td, /* distance decoder tables */ | 587 | struct huft *td, /* distance decoder tables */ |
588 | int bl, /* number of bits decoded by tl[] */ | 588 | int bl, /* number of bits decoded by tl[] */ |
589 | int bd /* number of bits decoded by td[] */ | 589 | int bd /* number of bits decoded by td[] */ |
590 | ) | 590 | ) |
591 | /* inflate (decompress) the codes in a deflated (compressed) block. | 591 | /* inflate (decompress) the codes in a deflated (compressed) block. |
592 | Return an error code or zero if it all goes ok. */ | 592 | Return an error code or zero if it all goes ok. */ |
593 | { | 593 | { |
594 | register unsigned e; /* table entry flag/number of extra bits */ | 594 | register unsigned e; /* table entry flag/number of extra bits */ |
595 | unsigned n, d; /* length and index for copy */ | 595 | unsigned n, d; /* length and index for copy */ |
596 | unsigned w; /* current window position */ | 596 | unsigned w; /* current window position */ |
597 | struct huft *t; /* pointer to table entry */ | 597 | struct huft *t; /* pointer to table entry */ |
598 | unsigned ml, md; /* masks for bl and bd bits */ | 598 | unsigned ml, md; /* masks for bl and bd bits */ |
599 | register ulg b; /* bit buffer */ | 599 | register ulg b; /* bit buffer */ |
600 | register unsigned k; /* number of bits in bit buffer */ | 600 | register unsigned k; /* number of bits in bit buffer */ |
601 | 601 | ||
602 | 602 | ||
603 | /* make local copies of globals */ | 603 | /* make local copies of globals */ |
604 | b = bb; /* initialize bit buffer */ | 604 | b = bb; /* initialize bit buffer */ |
605 | k = bk; | 605 | k = bk; |
606 | w = wp; /* initialize window position */ | 606 | w = wp; /* initialize window position */ |
607 | 607 | ||
608 | /* inflate the coded data */ | 608 | /* inflate the coded data */ |
609 | ml = mask_bits[bl]; /* precompute masks for speed */ | 609 | ml = mask_bits[bl]; /* precompute masks for speed */ |
610 | md = mask_bits[bd]; | 610 | md = mask_bits[bd]; |
611 | for (;;) /* do until end of block */ | 611 | for (;;) /* do until end of block */ |
612 | { | 612 | { |
613 | NEEDBITS((unsigned)bl) | 613 | NEEDBITS((unsigned)bl) |
614 | if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) | 614 | if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) |
615 | do { | 615 | do { |
616 | if (e == 99) | 616 | if (e == 99) |
617 | return 1; | 617 | return 1; |
618 | DUMPBITS(t->b) | 618 | DUMPBITS(t->b) |
619 | e -= 16; | 619 | e -= 16; |
620 | NEEDBITS(e) | 620 | NEEDBITS(e) |
621 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); | 621 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); |
622 | DUMPBITS(t->b) | 622 | DUMPBITS(t->b) |
623 | if (e == 16) /* then it's a literal */ | 623 | if (e == 16) /* then it's a literal */ |
624 | { | 624 | { |
625 | slide[w++] = (uch)t->v.n; | 625 | slide[w++] = (uch)t->v.n; |
626 | Tracevv((stderr, "%c", slide[w-1])); | 626 | Tracevv((stderr, "%c", slide[w-1])); |
627 | if (w == WSIZE) | 627 | if (w == WSIZE) |
628 | { | 628 | { |
629 | flush_output(w); | 629 | flush_output(w); |
630 | w = 0; | 630 | w = 0; |
631 | } | 631 | } |
632 | } | 632 | } |
633 | else /* it's an EOB or a length */ | 633 | else /* it's an EOB or a length */ |
634 | { | 634 | { |
635 | /* exit if end of block */ | 635 | /* exit if end of block */ |
636 | if (e == 15) | 636 | if (e == 15) |
637 | break; | 637 | break; |
638 | 638 | ||
639 | /* get length of block to copy */ | 639 | /* get length of block to copy */ |
640 | NEEDBITS(e) | 640 | NEEDBITS(e) |
641 | n = t->v.n + ((unsigned)b & mask_bits[e]); | 641 | n = t->v.n + ((unsigned)b & mask_bits[e]); |
642 | DUMPBITS(e); | 642 | DUMPBITS(e); |
643 | 643 | ||
644 | /* decode distance of block to copy */ | 644 | /* decode distance of block to copy */ |
645 | NEEDBITS((unsigned)bd) | 645 | NEEDBITS((unsigned)bd) |
646 | if ((e = (t = td + ((unsigned)b & md))->e) > 16) | 646 | if ((e = (t = td + ((unsigned)b & md))->e) > 16) |
647 | do { | 647 | do { |
648 | if (e == 99) | 648 | if (e == 99) |
649 | return 1; | 649 | return 1; |
650 | DUMPBITS(t->b) | 650 | DUMPBITS(t->b) |
651 | e -= 16; | 651 | e -= 16; |
652 | NEEDBITS(e) | 652 | NEEDBITS(e) |
653 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); | 653 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); |
654 | DUMPBITS(t->b) | 654 | DUMPBITS(t->b) |
655 | NEEDBITS(e) | 655 | NEEDBITS(e) |
656 | d = w - t->v.n - ((unsigned)b & mask_bits[e]); | 656 | d = w - t->v.n - ((unsigned)b & mask_bits[e]); |
657 | DUMPBITS(e) | 657 | DUMPBITS(e) |
658 | Tracevv((stderr,"\\[%d,%d]", w-d, n)); | 658 | Tracevv((stderr,"\\[%d,%d]", w-d, n)); |
659 | 659 | ||
660 | /* do the copy */ | 660 | /* do the copy */ |
661 | do { | 661 | do { |
662 | n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); | 662 | n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); |
663 | #if !defined(NOMEMCPY) && !defined(DEBUG) | 663 | #if !defined(NOMEMCPY) && !defined(DEBUG) |
664 | if (w - d >= e) /* (this test assumes unsigned comparison) */ | 664 | if (w - d >= e) /* (this test assumes unsigned comparison) */ |
665 | { | 665 | { |
666 | memcpy(slide + w, slide + d, e); | 666 | memcpy(slide + w, slide + d, e); |
667 | w += e; | 667 | w += e; |
668 | d += e; | 668 | d += e; |
669 | } | 669 | } |
670 | else /* do it slow to avoid memcpy() overlap */ | 670 | else /* do it slow to avoid memcpy() overlap */ |
671 | #endif /* !NOMEMCPY */ | 671 | #endif /* !NOMEMCPY */ |
672 | do { | 672 | do { |
673 | slide[w++] = slide[d++]; | 673 | slide[w++] = slide[d++]; |
674 | Tracevv((stderr, "%c", slide[w-1])); | 674 | Tracevv((stderr, "%c", slide[w-1])); |
675 | } while (--e); | 675 | } while (--e); |
676 | if (w == WSIZE) | 676 | if (w == WSIZE) |
677 | { | 677 | { |
678 | flush_output(w); | 678 | flush_output(w); |
679 | w = 0; | 679 | w = 0; |
680 | } | 680 | } |
681 | } while (n); | 681 | } while (n); |
682 | } | 682 | } |
683 | } | 683 | } |
684 | 684 | ||
685 | 685 | ||
686 | /* restore the globals from the locals */ | 686 | /* restore the globals from the locals */ |
687 | wp = w; /* restore global window pointer */ | 687 | wp = w; /* restore global window pointer */ |
688 | bb = b; /* restore global bit buffer */ | 688 | bb = b; /* restore global bit buffer */ |
689 | bk = k; | 689 | bk = k; |
690 | 690 | ||
691 | /* done */ | 691 | /* done */ |
692 | return 0; | 692 | return 0; |
693 | 693 | ||
694 | underrun: | 694 | underrun: |
695 | return 4; /* Input underrun */ | 695 | return 4; /* Input underrun */ |
696 | } | 696 | } |
697 | 697 | ||
698 | 698 | ||
699 | 699 | ||
700 | STATIC int INIT inflate_stored(void) | 700 | STATIC int INIT inflate_stored(void) |
701 | /* "decompress" an inflated type 0 (stored) block. */ | 701 | /* "decompress" an inflated type 0 (stored) block. */ |
702 | { | 702 | { |
703 | unsigned n; /* number of bytes in block */ | 703 | unsigned n; /* number of bytes in block */ |
704 | unsigned w; /* current window position */ | 704 | unsigned w; /* current window position */ |
705 | register ulg b; /* bit buffer */ | 705 | register ulg b; /* bit buffer */ |
706 | register unsigned k; /* number of bits in bit buffer */ | 706 | register unsigned k; /* number of bits in bit buffer */ |
707 | 707 | ||
708 | DEBG("<stor"); | 708 | DEBG("<stor"); |
709 | 709 | ||
710 | /* make local copies of globals */ | 710 | /* make local copies of globals */ |
711 | b = bb; /* initialize bit buffer */ | 711 | b = bb; /* initialize bit buffer */ |
712 | k = bk; | 712 | k = bk; |
713 | w = wp; /* initialize window position */ | 713 | w = wp; /* initialize window position */ |
714 | 714 | ||
715 | 715 | ||
716 | /* go to byte boundary */ | 716 | /* go to byte boundary */ |
717 | n = k & 7; | 717 | n = k & 7; |
718 | DUMPBITS(n); | 718 | DUMPBITS(n); |
719 | 719 | ||
720 | 720 | ||
721 | /* get the length and its complement */ | 721 | /* get the length and its complement */ |
722 | NEEDBITS(16) | 722 | NEEDBITS(16) |
723 | n = ((unsigned)b & 0xffff); | 723 | n = ((unsigned)b & 0xffff); |
724 | DUMPBITS(16) | 724 | DUMPBITS(16) |
725 | NEEDBITS(16) | 725 | NEEDBITS(16) |
726 | if (n != (unsigned)((~b) & 0xffff)) | 726 | if (n != (unsigned)((~b) & 0xffff)) |
727 | return 1; /* error in compressed data */ | 727 | return 1; /* error in compressed data */ |
728 | DUMPBITS(16) | 728 | DUMPBITS(16) |
729 | 729 | ||
730 | 730 | ||
731 | /* read and output the compressed data */ | 731 | /* read and output the compressed data */ |
732 | while (n--) | 732 | while (n--) |
733 | { | 733 | { |
734 | NEEDBITS(8) | 734 | NEEDBITS(8) |
735 | slide[w++] = (uch)b; | 735 | slide[w++] = (uch)b; |
736 | if (w == WSIZE) | 736 | if (w == WSIZE) |
737 | { | 737 | { |
738 | flush_output(w); | 738 | flush_output(w); |
739 | w = 0; | 739 | w = 0; |
740 | } | 740 | } |
741 | DUMPBITS(8) | 741 | DUMPBITS(8) |
742 | } | 742 | } |
743 | 743 | ||
744 | 744 | ||
745 | /* restore the globals from the locals */ | 745 | /* restore the globals from the locals */ |
746 | wp = w; /* restore global window pointer */ | 746 | wp = w; /* restore global window pointer */ |
747 | bb = b; /* restore global bit buffer */ | 747 | bb = b; /* restore global bit buffer */ |
748 | bk = k; | 748 | bk = k; |
749 | 749 | ||
750 | DEBG(">"); | 750 | DEBG(">"); |
751 | return 0; | 751 | return 0; |
752 | 752 | ||
753 | underrun: | 753 | underrun: |
754 | return 4; /* Input underrun */ | 754 | return 4; /* Input underrun */ |
755 | } | 755 | } |
756 | 756 | ||
757 | 757 | ||
758 | /* | 758 | /* |
759 | * We use `noinline' here to prevent gcc-3.5 from using too much stack space | 759 | * We use `noinline' here to prevent gcc-3.5 from using too much stack space |
760 | */ | 760 | */ |
761 | STATIC int noinline INIT inflate_fixed(void) | 761 | STATIC int noinline INIT inflate_fixed(void) |
762 | /* decompress an inflated type 1 (fixed Huffman codes) block. We should | 762 | /* decompress an inflated type 1 (fixed Huffman codes) block. We should |
763 | either replace this with a custom decoder, or at least precompute the | 763 | either replace this with a custom decoder, or at least precompute the |
764 | Huffman tables. */ | 764 | Huffman tables. */ |
765 | { | 765 | { |
766 | int i; /* temporary variable */ | 766 | int i; /* temporary variable */ |
767 | struct huft *tl; /* literal/length code table */ | 767 | struct huft *tl; /* literal/length code table */ |
768 | struct huft *td; /* distance code table */ | 768 | struct huft *td; /* distance code table */ |
769 | int bl; /* lookup bits for tl */ | 769 | int bl; /* lookup bits for tl */ |
770 | int bd; /* lookup bits for td */ | 770 | int bd; /* lookup bits for td */ |
771 | unsigned *l; /* length list for huft_build */ | 771 | unsigned *l; /* length list for huft_build */ |
772 | 772 | ||
773 | DEBG("<fix"); | 773 | DEBG("<fix"); |
774 | 774 | ||
775 | l = malloc(sizeof(*l) * 288); | 775 | l = malloc(sizeof(*l) * 288); |
776 | if (l == NULL) | 776 | if (l == NULL) |
777 | return 3; /* out of memory */ | 777 | return 3; /* out of memory */ |
778 | 778 | ||
779 | /* set up literal table */ | 779 | /* set up literal table */ |
780 | for (i = 0; i < 144; i++) | 780 | for (i = 0; i < 144; i++) |
781 | l[i] = 8; | 781 | l[i] = 8; |
782 | for (; i < 256; i++) | 782 | for (; i < 256; i++) |
783 | l[i] = 9; | 783 | l[i] = 9; |
784 | for (; i < 280; i++) | 784 | for (; i < 280; i++) |
785 | l[i] = 7; | 785 | l[i] = 7; |
786 | for (; i < 288; i++) /* make a complete, but wrong code set */ | 786 | for (; i < 288; i++) /* make a complete, but wrong code set */ |
787 | l[i] = 8; | 787 | l[i] = 8; |
788 | bl = 7; | 788 | bl = 7; |
789 | if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) { | 789 | if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) { |
790 | free(l); | 790 | free(l); |
791 | return i; | 791 | return i; |
792 | } | 792 | } |
793 | 793 | ||
794 | /* set up distance table */ | 794 | /* set up distance table */ |
795 | for (i = 0; i < 30; i++) /* make an incomplete code set */ | 795 | for (i = 0; i < 30; i++) /* make an incomplete code set */ |
796 | l[i] = 5; | 796 | l[i] = 5; |
797 | bd = 5; | 797 | bd = 5; |
798 | if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) | 798 | if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) |
799 | { | 799 | { |
800 | huft_free(tl); | 800 | huft_free(tl); |
801 | free(l); | 801 | free(l); |
802 | 802 | ||
803 | DEBG(">"); | 803 | DEBG(">"); |
804 | return i; | 804 | return i; |
805 | } | 805 | } |
806 | 806 | ||
807 | 807 | ||
808 | /* decompress until an end-of-block code */ | 808 | /* decompress until an end-of-block code */ |
809 | if (inflate_codes(tl, td, bl, bd)) { | 809 | if (inflate_codes(tl, td, bl, bd)) { |
810 | free(l); | 810 | free(l); |
811 | return 1; | 811 | return 1; |
812 | } | 812 | } |
813 | 813 | ||
814 | /* free the decoding tables, return */ | 814 | /* free the decoding tables, return */ |
815 | free(l); | 815 | free(l); |
816 | huft_free(tl); | 816 | huft_free(tl); |
817 | huft_free(td); | 817 | huft_free(td); |
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | 821 | ||
822 | /* | 822 | /* |
823 | * We use `noinline' here to prevent gcc-3.5 from using too much stack space | 823 | * We use `noinline' here to prevent gcc-3.5 from using too much stack space |
824 | */ | 824 | */ |
825 | STATIC int noinline INIT inflate_dynamic(void) | 825 | STATIC int noinline INIT inflate_dynamic(void) |
826 | /* decompress an inflated type 2 (dynamic Huffman codes) block. */ | 826 | /* decompress an inflated type 2 (dynamic Huffman codes) block. */ |
827 | { | 827 | { |
828 | int i; /* temporary variables */ | 828 | int i; /* temporary variables */ |
829 | unsigned j; | 829 | unsigned j; |
830 | unsigned l; /* last length */ | 830 | unsigned l; /* last length */ |
831 | unsigned m; /* mask for bit lengths table */ | 831 | unsigned m; /* mask for bit lengths table */ |
832 | unsigned n; /* number of lengths to get */ | 832 | unsigned n; /* number of lengths to get */ |
833 | struct huft *tl; /* literal/length code table */ | 833 | struct huft *tl; /* literal/length code table */ |
834 | struct huft *td; /* distance code table */ | 834 | struct huft *td; /* distance code table */ |
835 | int bl; /* lookup bits for tl */ | 835 | int bl; /* lookup bits for tl */ |
836 | int bd; /* lookup bits for td */ | 836 | int bd; /* lookup bits for td */ |
837 | unsigned nb; /* number of bit length codes */ | 837 | unsigned nb; /* number of bit length codes */ |
838 | unsigned nl; /* number of literal/length codes */ | 838 | unsigned nl; /* number of literal/length codes */ |
839 | unsigned nd; /* number of distance codes */ | 839 | unsigned nd; /* number of distance codes */ |
840 | unsigned *ll; /* literal/length and distance code lengths */ | 840 | unsigned *ll; /* literal/length and distance code lengths */ |
841 | register ulg b; /* bit buffer */ | 841 | register ulg b; /* bit buffer */ |
842 | register unsigned k; /* number of bits in bit buffer */ | 842 | register unsigned k; /* number of bits in bit buffer */ |
843 | int ret; | 843 | int ret; |
844 | 844 | ||
845 | DEBG("<dyn"); | 845 | DEBG("<dyn"); |
846 | 846 | ||
847 | #ifdef PKZIP_BUG_WORKAROUND | 847 | #ifdef PKZIP_BUG_WORKAROUND |
848 | ll = malloc(sizeof(*ll) * (288+32)); /* literal/length and distance code lengths */ | 848 | ll = malloc(sizeof(*ll) * (288+32)); /* literal/length and distance code lengths */ |
849 | #else | 849 | #else |
850 | ll = malloc(sizeof(*ll) * (286+30)); /* literal/length and distance code lengths */ | 850 | ll = malloc(sizeof(*ll) * (286+30)); /* literal/length and distance code lengths */ |
851 | #endif | 851 | #endif |
852 | 852 | ||
853 | if (ll == NULL) | 853 | if (ll == NULL) |
854 | return 1; | 854 | return 1; |
855 | 855 | ||
856 | /* make local bit buffer */ | 856 | /* make local bit buffer */ |
857 | b = bb; | 857 | b = bb; |
858 | k = bk; | 858 | k = bk; |
859 | 859 | ||
860 | 860 | ||
861 | /* read in table lengths */ | 861 | /* read in table lengths */ |
862 | NEEDBITS(5) | 862 | NEEDBITS(5) |
863 | nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ | 863 | nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ |
864 | DUMPBITS(5) | 864 | DUMPBITS(5) |
865 | NEEDBITS(5) | 865 | NEEDBITS(5) |
866 | nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ | 866 | nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ |
867 | DUMPBITS(5) | 867 | DUMPBITS(5) |
868 | NEEDBITS(4) | 868 | NEEDBITS(4) |
869 | nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ | 869 | nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ |
870 | DUMPBITS(4) | 870 | DUMPBITS(4) |
871 | #ifdef PKZIP_BUG_WORKAROUND | 871 | #ifdef PKZIP_BUG_WORKAROUND |
872 | if (nl > 288 || nd > 32) | 872 | if (nl > 288 || nd > 32) |
873 | #else | 873 | #else |
874 | if (nl > 286 || nd > 30) | 874 | if (nl > 286 || nd > 30) |
875 | #endif | 875 | #endif |
876 | { | 876 | { |
877 | ret = 1; /* bad lengths */ | 877 | ret = 1; /* bad lengths */ |
878 | goto out; | 878 | goto out; |
879 | } | 879 | } |
880 | 880 | ||
881 | DEBG("dyn1 "); | 881 | DEBG("dyn1 "); |
882 | 882 | ||
883 | /* read in bit-length-code lengths */ | 883 | /* read in bit-length-code lengths */ |
884 | for (j = 0; j < nb; j++) | 884 | for (j = 0; j < nb; j++) |
885 | { | 885 | { |
886 | NEEDBITS(3) | 886 | NEEDBITS(3) |
887 | ll[border[j]] = (unsigned)b & 7; | 887 | ll[border[j]] = (unsigned)b & 7; |
888 | DUMPBITS(3) | 888 | DUMPBITS(3) |
889 | } | 889 | } |
890 | for (; j < 19; j++) | 890 | for (; j < 19; j++) |
891 | ll[border[j]] = 0; | 891 | ll[border[j]] = 0; |
892 | 892 | ||
893 | DEBG("dyn2 "); | 893 | DEBG("dyn2 "); |
894 | 894 | ||
895 | /* build decoding table for trees--single level, 7 bit lookup */ | 895 | /* build decoding table for trees--single level, 7 bit lookup */ |
896 | bl = 7; | 896 | bl = 7; |
897 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) | 897 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) |
898 | { | 898 | { |
899 | if (i == 1) | 899 | if (i == 1) |
900 | huft_free(tl); | 900 | huft_free(tl); |
901 | ret = i; /* incomplete code set */ | 901 | ret = i; /* incomplete code set */ |
902 | goto out; | 902 | goto out; |
903 | } | 903 | } |
904 | 904 | ||
905 | DEBG("dyn3 "); | 905 | DEBG("dyn3 "); |
906 | 906 | ||
907 | /* read in literal and distance code lengths */ | 907 | /* read in literal and distance code lengths */ |
908 | n = nl + nd; | 908 | n = nl + nd; |
909 | m = mask_bits[bl]; | 909 | m = mask_bits[bl]; |
910 | i = l = 0; | 910 | i = l = 0; |
911 | while ((unsigned)i < n) | 911 | while ((unsigned)i < n) |
912 | { | 912 | { |
913 | NEEDBITS((unsigned)bl) | 913 | NEEDBITS((unsigned)bl) |
914 | j = (td = tl + ((unsigned)b & m))->b; | 914 | j = (td = tl + ((unsigned)b & m))->b; |
915 | DUMPBITS(j) | 915 | DUMPBITS(j) |
916 | j = td->v.n; | 916 | j = td->v.n; |
917 | if (j < 16) /* length of code in bits (0..15) */ | 917 | if (j < 16) /* length of code in bits (0..15) */ |
918 | ll[i++] = l = j; /* save last length in l */ | 918 | ll[i++] = l = j; /* save last length in l */ |
919 | else if (j == 16) /* repeat last length 3 to 6 times */ | 919 | else if (j == 16) /* repeat last length 3 to 6 times */ |
920 | { | 920 | { |
921 | NEEDBITS(2) | 921 | NEEDBITS(2) |
922 | j = 3 + ((unsigned)b & 3); | 922 | j = 3 + ((unsigned)b & 3); |
923 | DUMPBITS(2) | 923 | DUMPBITS(2) |
924 | if ((unsigned)i + j > n) { | 924 | if ((unsigned)i + j > n) { |
925 | ret = 1; | 925 | ret = 1; |
926 | goto out; | 926 | goto out; |
927 | } | 927 | } |
928 | while (j--) | 928 | while (j--) |
929 | ll[i++] = l; | 929 | ll[i++] = l; |
930 | } | 930 | } |
931 | else if (j == 17) /* 3 to 10 zero length codes */ | 931 | else if (j == 17) /* 3 to 10 zero length codes */ |
932 | { | 932 | { |
933 | NEEDBITS(3) | 933 | NEEDBITS(3) |
934 | j = 3 + ((unsigned)b & 7); | 934 | j = 3 + ((unsigned)b & 7); |
935 | DUMPBITS(3) | 935 | DUMPBITS(3) |
936 | if ((unsigned)i + j > n) { | 936 | if ((unsigned)i + j > n) { |
937 | ret = 1; | 937 | ret = 1; |
938 | goto out; | 938 | goto out; |
939 | } | 939 | } |
940 | while (j--) | 940 | while (j--) |
941 | ll[i++] = 0; | 941 | ll[i++] = 0; |
942 | l = 0; | 942 | l = 0; |
943 | } | 943 | } |
944 | else /* j == 18: 11 to 138 zero length codes */ | 944 | else /* j == 18: 11 to 138 zero length codes */ |
945 | { | 945 | { |
946 | NEEDBITS(7) | 946 | NEEDBITS(7) |
947 | j = 11 + ((unsigned)b & 0x7f); | 947 | j = 11 + ((unsigned)b & 0x7f); |
948 | DUMPBITS(7) | 948 | DUMPBITS(7) |
949 | if ((unsigned)i + j > n) { | 949 | if ((unsigned)i + j > n) { |
950 | ret = 1; | 950 | ret = 1; |
951 | goto out; | 951 | goto out; |
952 | } | 952 | } |
953 | while (j--) | 953 | while (j--) |
954 | ll[i++] = 0; | 954 | ll[i++] = 0; |
955 | l = 0; | 955 | l = 0; |
956 | } | 956 | } |
957 | } | 957 | } |
958 | 958 | ||
959 | DEBG("dyn4 "); | 959 | DEBG("dyn4 "); |
960 | 960 | ||
961 | /* free decoding table for trees */ | 961 | /* free decoding table for trees */ |
962 | huft_free(tl); | 962 | huft_free(tl); |
963 | 963 | ||
964 | DEBG("dyn5 "); | 964 | DEBG("dyn5 "); |
965 | 965 | ||
966 | /* restore the global bit buffer */ | 966 | /* restore the global bit buffer */ |
967 | bb = b; | 967 | bb = b; |
968 | bk = k; | 968 | bk = k; |
969 | 969 | ||
970 | DEBG("dyn5a "); | 970 | DEBG("dyn5a "); |
971 | 971 | ||
972 | /* build the decoding tables for literal/length and distance codes */ | 972 | /* build the decoding tables for literal/length and distance codes */ |
973 | bl = lbits; | 973 | bl = lbits; |
974 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) | 974 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) |
975 | { | 975 | { |
976 | DEBG("dyn5b "); | 976 | DEBG("dyn5b "); |
977 | if (i == 1) { | 977 | if (i == 1) { |
978 | error("incomplete literal tree"); | 978 | error("incomplete literal tree"); |
979 | huft_free(tl); | 979 | huft_free(tl); |
980 | } | 980 | } |
981 | ret = i; /* incomplete code set */ | 981 | ret = i; /* incomplete code set */ |
982 | goto out; | 982 | goto out; |
983 | } | 983 | } |
984 | DEBG("dyn5c "); | 984 | DEBG("dyn5c "); |
985 | bd = dbits; | 985 | bd = dbits; |
986 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) | 986 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) |
987 | { | 987 | { |
988 | DEBG("dyn5d "); | 988 | DEBG("dyn5d "); |
989 | if (i == 1) { | 989 | if (i == 1) { |
990 | error("incomplete distance tree"); | 990 | error("incomplete distance tree"); |
991 | #ifdef PKZIP_BUG_WORKAROUND | 991 | #ifdef PKZIP_BUG_WORKAROUND |
992 | i = 0; | 992 | i = 0; |
993 | } | 993 | } |
994 | #else | 994 | #else |
995 | huft_free(td); | 995 | huft_free(td); |
996 | } | 996 | } |
997 | huft_free(tl); | 997 | huft_free(tl); |
998 | ret = i; /* incomplete code set */ | 998 | ret = i; /* incomplete code set */ |
999 | goto out; | 999 | goto out; |
1000 | #endif | 1000 | #endif |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | DEBG("dyn6 "); | 1003 | DEBG("dyn6 "); |
1004 | 1004 | ||
1005 | /* decompress until an end-of-block code */ | 1005 | /* decompress until an end-of-block code */ |
1006 | if (inflate_codes(tl, td, bl, bd)) { | 1006 | if (inflate_codes(tl, td, bl, bd)) { |
1007 | ret = 1; | 1007 | ret = 1; |
1008 | goto out; | 1008 | goto out; |
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | DEBG("dyn7 "); | 1011 | DEBG("dyn7 "); |
1012 | 1012 | ||
1013 | /* free the decoding tables, return */ | 1013 | /* free the decoding tables, return */ |
1014 | huft_free(tl); | 1014 | huft_free(tl); |
1015 | huft_free(td); | 1015 | huft_free(td); |
1016 | 1016 | ||
1017 | DEBG(">"); | 1017 | DEBG(">"); |
1018 | ret = 0; | 1018 | ret = 0; |
1019 | out: | 1019 | out: |
1020 | free(ll); | 1020 | free(ll); |
1021 | return ret; | 1021 | return ret; |
1022 | 1022 | ||
1023 | underrun: | 1023 | underrun: |
1024 | ret = 4; /* Input underrun */ | 1024 | ret = 4; /* Input underrun */ |
1025 | goto out; | 1025 | goto out; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | 1028 | ||
1029 | 1029 | ||
1030 | STATIC int INIT inflate_block( | 1030 | STATIC int INIT inflate_block( |
1031 | int *e /* last block flag */ | 1031 | int *e /* last block flag */ |
1032 | ) | 1032 | ) |
1033 | /* decompress an inflated block */ | 1033 | /* decompress an inflated block */ |
1034 | { | 1034 | { |
1035 | unsigned t; /* block type */ | 1035 | unsigned t; /* block type */ |
1036 | register ulg b; /* bit buffer */ | 1036 | register ulg b; /* bit buffer */ |
1037 | register unsigned k; /* number of bits in bit buffer */ | 1037 | register unsigned k; /* number of bits in bit buffer */ |
1038 | 1038 | ||
1039 | DEBG("<blk"); | 1039 | DEBG("<blk"); |
1040 | 1040 | ||
1041 | /* make local bit buffer */ | 1041 | /* make local bit buffer */ |
1042 | b = bb; | 1042 | b = bb; |
1043 | k = bk; | 1043 | k = bk; |
1044 | 1044 | ||
1045 | 1045 | ||
1046 | /* read in last block bit */ | 1046 | /* read in last block bit */ |
1047 | NEEDBITS(1) | 1047 | NEEDBITS(1) |
1048 | *e = (int)b & 1; | 1048 | *e = (int)b & 1; |
1049 | DUMPBITS(1) | 1049 | DUMPBITS(1) |
1050 | 1050 | ||
1051 | 1051 | ||
1052 | /* read in block type */ | 1052 | /* read in block type */ |
1053 | NEEDBITS(2) | 1053 | NEEDBITS(2) |
1054 | t = (unsigned)b & 3; | 1054 | t = (unsigned)b & 3; |
1055 | DUMPBITS(2) | 1055 | DUMPBITS(2) |
1056 | 1056 | ||
1057 | 1057 | ||
1058 | /* restore the global bit buffer */ | 1058 | /* restore the global bit buffer */ |
1059 | bb = b; | 1059 | bb = b; |
1060 | bk = k; | 1060 | bk = k; |
1061 | 1061 | ||
1062 | /* inflate that block type */ | 1062 | /* inflate that block type */ |
1063 | if (t == 2) | 1063 | if (t == 2) |
1064 | return inflate_dynamic(); | 1064 | return inflate_dynamic(); |
1065 | if (t == 0) | 1065 | if (t == 0) |
1066 | return inflate_stored(); | 1066 | return inflate_stored(); |
1067 | if (t == 1) | 1067 | if (t == 1) |
1068 | return inflate_fixed(); | 1068 | return inflate_fixed(); |
1069 | 1069 | ||
1070 | DEBG(">"); | 1070 | DEBG(">"); |
1071 | 1071 | ||
1072 | /* bad block type */ | 1072 | /* bad block type */ |
1073 | return 2; | 1073 | return 2; |
1074 | 1074 | ||
1075 | underrun: | 1075 | underrun: |
1076 | return 4; /* Input underrun */ | 1076 | return 4; /* Input underrun */ |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | 1079 | ||
1080 | 1080 | ||
1081 | STATIC int INIT inflate(void) | 1081 | STATIC int INIT inflate(void) |
1082 | /* decompress an inflated entry */ | 1082 | /* decompress an inflated entry */ |
1083 | { | 1083 | { |
1084 | int e; /* last block flag */ | 1084 | int e; /* last block flag */ |
1085 | int r; /* result code */ | 1085 | int r; /* result code */ |
1086 | unsigned h; /* maximum struct huft's malloc'ed */ | 1086 | unsigned h; /* maximum struct huft's malloc'ed */ |
1087 | 1087 | ||
1088 | /* initialize window, bit buffer */ | 1088 | /* initialize window, bit buffer */ |
1089 | wp = 0; | 1089 | wp = 0; |
1090 | bk = 0; | 1090 | bk = 0; |
1091 | bb = 0; | 1091 | bb = 0; |
1092 | 1092 | ||
1093 | 1093 | ||
1094 | /* decompress until the last block */ | 1094 | /* decompress until the last block */ |
1095 | h = 0; | 1095 | h = 0; |
1096 | do { | 1096 | do { |
1097 | hufts = 0; | 1097 | hufts = 0; |
1098 | #ifdef ARCH_HAS_DECOMP_WDOG | 1098 | #ifdef ARCH_HAS_DECOMP_WDOG |
1099 | arch_decomp_wdog(); | 1099 | arch_decomp_wdog(); |
1100 | #endif | 1100 | #endif |
1101 | r = inflate_block(&e); | 1101 | r = inflate_block(&e); |
1102 | if (r) | 1102 | if (r) |
1103 | return r; | 1103 | return r; |
1104 | if (hufts > h) | 1104 | if (hufts > h) |
1105 | h = hufts; | 1105 | h = hufts; |
1106 | } while (!e); | 1106 | } while (!e); |
1107 | 1107 | ||
1108 | /* Undo too much lookahead. The next read will be byte aligned so we | 1108 | /* Undo too much lookahead. The next read will be byte aligned so we |
1109 | * can discard unused bits in the last meaningful byte. | 1109 | * can discard unused bits in the last meaningful byte. |
1110 | */ | 1110 | */ |
1111 | while (bk >= 8) { | 1111 | while (bk >= 8) { |
1112 | bk -= 8; | 1112 | bk -= 8; |
1113 | inptr--; | 1113 | inptr--; |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | /* flush out slide */ | 1116 | /* flush out slide */ |
1117 | flush_output(wp); | 1117 | flush_output(wp); |
1118 | 1118 | ||
1119 | 1119 | ||
1120 | /* return success */ | 1120 | /* return success */ |
1121 | #ifdef DEBUG | 1121 | #ifdef DEBUG |
1122 | fprintf(stderr, "<%u> ", h); | 1122 | fprintf(stderr, "<%u> ", h); |
1123 | #endif /* DEBUG */ | 1123 | #endif /* DEBUG */ |
1124 | return 0; | 1124 | return 0; |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | /********************************************************************** | 1127 | /********************************************************************** |
1128 | * | 1128 | * |
1129 | * The following are support routines for inflate.c | 1129 | * The following are support routines for inflate.c |
1130 | * | 1130 | * |
1131 | **********************************************************************/ | 1131 | **********************************************************************/ |
1132 | 1132 | ||
1133 | static ulg crc_32_tab[256]; | 1133 | static ulg crc_32_tab[256]; |
1134 | static ulg crc; /* initialized in makecrc() so it'll reside in bss */ | 1134 | static ulg crc; /* initialized in makecrc() so it'll reside in bss */ |
1135 | #define CRC_VALUE (crc ^ 0xffffffffUL) | 1135 | #define CRC_VALUE (crc ^ 0xffffffffUL) |
1136 | 1136 | ||
1137 | /* | 1137 | /* |
1138 | * Code to compute the CRC-32 table. Borrowed from | 1138 | * Code to compute the CRC-32 table. Borrowed from |
1139 | * gzip-1.0.3/makecrc.c. | 1139 | * gzip-1.0.3/makecrc.c. |
1140 | */ | 1140 | */ |
1141 | 1141 | ||
1142 | static void INIT | 1142 | static void INIT |
1143 | makecrc(void) | 1143 | makecrc(void) |
1144 | { | 1144 | { |
1145 | /* Not copyrighted 1990 Mark Adler */ | 1145 | /* Not copyrighted 1990 Mark Adler */ |
1146 | 1146 | ||
1147 | unsigned long c; /* crc shift register */ | 1147 | unsigned long c; /* crc shift register */ |
1148 | unsigned long e; /* polynomial exclusive-or pattern */ | 1148 | unsigned long e; /* polynomial exclusive-or pattern */ |
1149 | int i; /* counter for all possible eight bit values */ | 1149 | int i; /* counter for all possible eight bit values */ |
1150 | int k; /* byte being shifted into crc apparatus */ | 1150 | int k; /* byte being shifted into crc apparatus */ |
1151 | 1151 | ||
1152 | /* terms of polynomial defining this crc (except x^32): */ | 1152 | /* terms of polynomial defining this crc (except x^32): */ |
1153 | static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; | 1153 | static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; |
1154 | 1154 | ||
1155 | /* Make exclusive-or pattern from polynomial */ | 1155 | /* Make exclusive-or pattern from polynomial */ |
1156 | e = 0; | 1156 | e = 0; |
1157 | for (i = 0; i < sizeof(p)/sizeof(int); i++) | 1157 | for (i = 0; i < sizeof(p)/sizeof(int); i++) |
1158 | e |= 1L << (31 - p[i]); | 1158 | e |= 1L << (31 - p[i]); |
1159 | 1159 | ||
1160 | crc_32_tab[0] = 0; | 1160 | crc_32_tab[0] = 0; |
1161 | 1161 | ||
1162 | for (i = 1; i < 256; i++) | 1162 | for (i = 1; i < 256; i++) |
1163 | { | 1163 | { |
1164 | c = 0; | 1164 | c = 0; |
1165 | for (k = i | 256; k != 1; k >>= 1) | 1165 | for (k = i | 256; k != 1; k >>= 1) |
1166 | { | 1166 | { |
1167 | c = c & 1 ? (c >> 1) ^ e : c >> 1; | 1167 | c = c & 1 ? (c >> 1) ^ e : c >> 1; |
1168 | if (k & 1) | 1168 | if (k & 1) |
1169 | c ^= e; | 1169 | c ^= e; |
1170 | } | 1170 | } |
1171 | crc_32_tab[i] = c; | 1171 | crc_32_tab[i] = c; |
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | /* this is initialized here so this code could reside in ROM */ | 1174 | /* this is initialized here so this code could reside in ROM */ |
1175 | crc = (ulg)0xffffffffUL; /* shift register contents */ | 1175 | crc = (ulg)0xffffffffUL; /* shift register contents */ |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | /* gzip flag byte */ | 1178 | /* gzip flag byte */ |
1179 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ | 1179 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ |
1180 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ | 1180 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ |
1181 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ | 1181 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ |
1182 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ | 1182 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ |
1183 | #define COMMENT 0x10 /* bit 4 set: file comment present */ | 1183 | #define COMMENT 0x10 /* bit 4 set: file comment present */ |
1184 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | 1184 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ |
1185 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | 1185 | #define RESERVED 0xC0 /* bit 6,7: reserved */ |
1186 | 1186 | ||
1187 | /* | 1187 | /* |
1188 | * Do the uncompression! | 1188 | * Do the uncompression! |
1189 | */ | 1189 | */ |
1190 | static int INIT gunzip(void) | 1190 | static int INIT gunzip(void) |
1191 | { | 1191 | { |
1192 | uch flags; | 1192 | uch flags; |
1193 | unsigned char magic[2]; /* magic header */ | 1193 | unsigned char magic[2]; /* magic header */ |
1194 | char method; | 1194 | char method; |
1195 | ulg orig_crc = 0; /* original crc */ | 1195 | ulg orig_crc = 0; /* original crc */ |
1196 | ulg orig_len = 0; /* original uncompressed length */ | 1196 | ulg orig_len = 0; /* original uncompressed length */ |
1197 | int res; | 1197 | int res; |
1198 | 1198 | ||
1199 | magic[0] = NEXTBYTE(); | 1199 | magic[0] = NEXTBYTE(); |
1200 | magic[1] = NEXTBYTE(); | 1200 | magic[1] = NEXTBYTE(); |
1201 | method = NEXTBYTE(); | 1201 | method = NEXTBYTE(); |
1202 | 1202 | ||
1203 | if (magic[0] != 037 || | 1203 | if (magic[0] != 037 || |
1204 | ((magic[1] != 0213) && (magic[1] != 0236))) { | 1204 | ((magic[1] != 0213) && (magic[1] != 0236))) { |
1205 | error("bad gzip magic numbers"); | 1205 | error("bad gzip magic numbers"); |
1206 | return -1; | 1206 | return -1; |
1207 | } | 1207 | } |
1208 | 1208 | ||
1209 | /* We only support method #8, DEFLATED */ | 1209 | /* We only support method #8, DEFLATED */ |
1210 | if (method != 8) { | 1210 | if (method != 8) { |
1211 | error("internal error, invalid method"); | 1211 | error("internal error, invalid method"); |
1212 | return -1; | 1212 | return -1; |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | flags = (uch)get_byte(); | 1215 | flags = (uch)get_byte(); |
1216 | if ((flags & ENCRYPTED) != 0) { | 1216 | if ((flags & ENCRYPTED) != 0) { |
1217 | error("Input is encrypted"); | 1217 | error("Input is encrypted"); |
1218 | return -1; | 1218 | return -1; |
1219 | } | 1219 | } |
1220 | if ((flags & CONTINUATION) != 0) { | 1220 | if ((flags & CONTINUATION) != 0) { |
1221 | error("Multi part input"); | 1221 | error("Multi part input"); |
1222 | return -1; | 1222 | return -1; |
1223 | } | 1223 | } |
1224 | if ((flags & RESERVED) != 0) { | 1224 | if ((flags & RESERVED) != 0) { |
1225 | error("Input has invalid flags"); | 1225 | error("Input has invalid flags"); |
1226 | return -1; | 1226 | return -1; |
1227 | } | 1227 | } |
1228 | NEXTBYTE(); /* Get timestamp */ | 1228 | NEXTBYTE(); /* Get timestamp */ |
1229 | NEXTBYTE(); | 1229 | NEXTBYTE(); |
1230 | NEXTBYTE(); | 1230 | NEXTBYTE(); |
1231 | NEXTBYTE(); | 1231 | NEXTBYTE(); |
1232 | 1232 | ||
1233 | (void)NEXTBYTE(); /* Ignore extra flags for the moment */ | 1233 | (void)NEXTBYTE(); /* Ignore extra flags for the moment */ |
1234 | (void)NEXTBYTE(); /* Ignore OS type for the moment */ | 1234 | (void)NEXTBYTE(); /* Ignore OS type for the moment */ |
1235 | 1235 | ||
1236 | if ((flags & EXTRA_FIELD) != 0) { | 1236 | if ((flags & EXTRA_FIELD) != 0) { |
1237 | unsigned len = (unsigned)NEXTBYTE(); | 1237 | unsigned len = (unsigned)NEXTBYTE(); |
1238 | len |= ((unsigned)NEXTBYTE())<<8; | 1238 | len |= ((unsigned)NEXTBYTE())<<8; |
1239 | while (len--) (void)NEXTBYTE(); | 1239 | while (len--) (void)NEXTBYTE(); |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | /* Get original file name if it was truncated */ | 1242 | /* Get original file name if it was truncated */ |
1243 | if ((flags & ORIG_NAME) != 0) { | 1243 | if ((flags & ORIG_NAME) != 0) { |
1244 | /* Discard the old name */ | 1244 | /* Discard the old name */ |
1245 | while (NEXTBYTE() != 0) /* null */ ; | 1245 | while (NEXTBYTE() != 0) /* null */ ; |
1246 | } | 1246 | } |
1247 | 1247 | ||
1248 | /* Discard file comment if any */ | 1248 | /* Discard file comment if any */ |
1249 | if ((flags & COMMENT) != 0) { | 1249 | if ((flags & COMMENT) != 0) { |
1250 | while (NEXTBYTE() != 0) /* null */ ; | 1250 | while (NEXTBYTE() != 0) /* null */ ; |
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | /* Decompress */ | 1253 | /* Decompress */ |
1254 | if ((res = inflate())) { | 1254 | if ((res = inflate())) { |
1255 | switch (res) { | 1255 | switch (res) { |
1256 | case 0: | 1256 | case 0: |
1257 | break; | 1257 | break; |
1258 | case 1: | 1258 | case 1: |
1259 | error("invalid compressed format (err=1)"); | 1259 | error("invalid compressed format (err=1)"); |
1260 | break; | 1260 | break; |
1261 | case 2: | 1261 | case 2: |
1262 | error("invalid compressed format (err=2)"); | 1262 | error("invalid compressed format (err=2)"); |
1263 | break; | 1263 | break; |
1264 | case 3: | 1264 | case 3: |
1265 | error("out of memory"); | 1265 | error("out of memory"); |
1266 | break; | 1266 | break; |
1267 | case 4: | 1267 | case 4: |
1268 | error("out of input data"); | 1268 | error("out of input data"); |
1269 | break; | 1269 | break; |
1270 | default: | 1270 | default: |
1271 | error("invalid compressed format (other)"); | 1271 | error("invalid compressed format (other)"); |
1272 | } | 1272 | } |
1273 | return -1; | 1273 | return -1; |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | /* Get the crc and original length */ | 1276 | /* Get the crc and original length */ |
1277 | /* crc32 (see algorithm.doc) | 1277 | /* crc32 (see algorithm.doc) |
1278 | * uncompressed input size modulo 2^32 | 1278 | * uncompressed input size modulo 2^32 |
1279 | */ | 1279 | */ |
1280 | orig_crc = (ulg) NEXTBYTE(); | 1280 | orig_crc = (ulg) NEXTBYTE(); |
1281 | orig_crc |= (ulg) NEXTBYTE() << 8; | 1281 | orig_crc |= (ulg) NEXTBYTE() << 8; |
1282 | orig_crc |= (ulg) NEXTBYTE() << 16; | 1282 | orig_crc |= (ulg) NEXTBYTE() << 16; |
1283 | orig_crc |= (ulg) NEXTBYTE() << 24; | 1283 | orig_crc |= (ulg) NEXTBYTE() << 24; |
1284 | 1284 | ||
1285 | orig_len = (ulg) NEXTBYTE(); | 1285 | orig_len = (ulg) NEXTBYTE(); |
1286 | orig_len |= (ulg) NEXTBYTE() << 8; | 1286 | orig_len |= (ulg) NEXTBYTE() << 8; |
1287 | orig_len |= (ulg) NEXTBYTE() << 16; | 1287 | orig_len |= (ulg) NEXTBYTE() << 16; |
1288 | orig_len |= (ulg) NEXTBYTE() << 24; | 1288 | orig_len |= (ulg) NEXTBYTE() << 24; |
1289 | 1289 | ||
1290 | /* Validate decompression */ | 1290 | /* Validate decompression */ |
1291 | if (orig_crc != CRC_VALUE) { | 1291 | if (orig_crc != CRC_VALUE) { |
1292 | error("crc error"); | 1292 | error("crc error"); |
1293 | return -1; | 1293 | return -1; |
1294 | } | 1294 | } |
1295 | if (orig_len != bytes_out) { | 1295 | if (orig_len != bytes_out) { |
1296 | error("length error"); | 1296 | error("length error"); |
1297 | return -1; | 1297 | return -1; |
1298 | } | 1298 | } |
1299 | return 0; | 1299 | return 0; |
1300 | 1300 | ||
1301 | underrun: /* NEXTBYTE() goto's here if needed */ | 1301 | underrun: /* NEXTBYTE() goto's here if needed */ |
1302 | error("out of input data"); | 1302 | error("out of input data"); |
1303 | return -1; | 1303 | return -1; |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | 1306 | ||
1307 | 1307 |